UNPKG

@massalabs/massa-web3

Version:
162 lines 7.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MNS = exports.MNS_CONTRACTS = void 0; const basicElements_1 = require("../basicElements"); const smartContracts_1 = require("../smartContracts"); const tokens_1 = require("./tokens"); const dataEntryNotFound_1 = require("../errors/dataEntryNotFound"); const utils_1 = require("../utils"); exports.MNS_CONTRACTS = { mainnet: 'AS1q5hUfxLXNXLKsYQVXZLK7MPUZcWaNZZsK7e9QzqhGdAgLpUGT', buildnet: 'AS12qKAVjU1nr66JSkQ6N4Lqu4iwuVc6rAbRTrxFoynPrPdP1sj3G', }; /** * @class MNS * @extends SmartContract * * The MNS class provides methods to interact with the Massa Name System (MNS) smart contract. * It allows resolving domain names, reverse resolving addresses, allocating domains, freeing domains, * and updating domain targets. * MNS contract is available here: https://github.com/massalabs/massa-name-system/blob/main/smart-contract/assembly/contracts/main.ts * * @example * ```typescript * const mns = await MNS.mainnet(provider); * const address = await mns.resolve("example"); * ``` * */ // Constants are taken from the smart contract // https://github.com/massalabs/massa-name-service/blob/main/smart-contract/assembly/contracts/main.ts // eslint-disable-next-line @typescript-eslint/no-magic-numbers const DOMAIN_SEPARATOR_KEY = [0x42]; const TOKEN_ID_KEY_PREFIX = [0x1]; // eslint-disable-next-line @typescript-eslint/no-magic-numbers const TARGET_KEY_PREFIX = [0x02]; // eslint-disable-next-line @typescript-eslint/no-magic-numbers const DOMAIN_KEY_PREFIX = [0x3]; // eslint-disable-next-line @typescript-eslint/no-magic-numbers const ADDRESS_KEY_PREFIX_V2 = [0x6]; const OWNED_TOKENS_KEY = (0, basicElements_1.strToBytes)('ownedTokens'); class MNS extends smartContracts_1.SmartContract { constructor(provider, chainId) { const address = chainId === utils_1.CHAIN_ID.Mainnet ? exports.MNS_CONTRACTS.mainnet : exports.MNS_CONTRACTS.buildnet; super(provider, address); } static async init(provider) { const { chainId } = await provider.networkInfos(); return new MNS(provider, chainId); } static mainnet(provider) { (0, tokens_1.checkNetwork)(provider, true); return new MNS(provider, utils_1.CHAIN_ID.Mainnet); } static buildnet(provider) { (0, tokens_1.checkNetwork)(provider, false); return new MNS(provider, utils_1.CHAIN_ID.Buildnet); } // Resolve domain name (without ".massa") to address async resolve(name, options) { const res = await this.read('dnsResolve', new basicElements_1.Args().addString(name), options); return (0, basicElements_1.bytesToStr)(res.value); } // deprecated. Use getDomainsFromTarget instead async fromAddress(address, options) { const res = await this.read('dnsReverseResolve', new basicElements_1.Args().addString(address), options); return (0, basicElements_1.bytesToStr)(res.value).split(','); } async getDomainsFromTarget(target, final = false) { const targetBytes = (0, basicElements_1.strToBytes)(target); const filter = Uint8Array.from([ ...DOMAIN_SEPARATOR_KEY, ...ADDRESS_KEY_PREFIX_V2, targetBytes.length, ...targetBytes, ]); const keys = await this.provider.getStorageKeys(this.address, filter, final); return keys.map((key) => (0, basicElements_1.bytesToStr)(key.slice(filter.length))); } async alloc(name, owner, options) { return this.call('dnsAlloc', new basicElements_1.Args().addString(name).addString(owner), options); } async getTokenId(name) { const key = Uint8Array.from([ ...DOMAIN_SEPARATOR_KEY, ...TOKEN_ID_KEY_PREFIX, ...(0, basicElements_1.strToBytes)(name), ]); const data = await this.provider.readStorage(this.address, [key], true); if (data[0] == null) { throw new dataEntryNotFound_1.ErrorDataEntryNotFound({ key: key, address: this.address, details: `mns Domain ${name} not found`, }); } return basicElements_1.U256.fromBytes(data[0]); } async free(name, options) { const tokenId = await this.getTokenId(name); return this.call('dnsFree', new basicElements_1.Args().addU256(tokenId), options); } async updateTarget(name, newTarget, options) { return this.call('dnsUpdateTarget', new basicElements_1.Args().addString(name).addString(newTarget), options); } async getOwnedDomains(address, final = false) { const filter = Uint8Array.from([ ...OWNED_TOKENS_KEY, ...(0, basicElements_1.strToBytes)(address), ]); const ownedKeys = await this.provider.getStorageKeys(this.address, filter, final); const domainKeys = ownedKeys.map((k) => { const tokenIdBytes = k.slice(filter.length); return Uint8Array.from([ ...DOMAIN_SEPARATOR_KEY, ...DOMAIN_KEY_PREFIX, ...tokenIdBytes, ]); }); const domainsBytes = await this.provider.readStorage(this.address, domainKeys, final); return domainsBytes.map((d, i) => { if (!d) { throw new dataEntryNotFound_1.ErrorDataEntryNotFound({ key: ownedKeys[i], address: this.address, details: `Domain with tokenId ${basicElements_1.U256.fromBytes(ownedKeys[i].slice(filter.length))} not found`, }); } return (0, basicElements_1.bytesToStr)(d); }); } async getTargets(domains, final = false) { const targetDataStoreEntries = domains.map((name) => Uint8Array.from([ ...DOMAIN_SEPARATOR_KEY, ...TARGET_KEY_PREFIX, ...(0, basicElements_1.strToBytes)(name), ])); const targetsBytes = await this.provider.readStorage(this.address, targetDataStoreEntries, final); return targetsBytes.map(basicElements_1.bytesToStr); } async dnsAllocCost(domain, options) { const res = await this.read('dnsAllocCost', new basicElements_1.Args().addString(domain), options); if (res.info.error) throw new Error(res.info.error); return basicElements_1.U64.fromBytes(res.value); } async transferFrom(domain, currentOwner, newOwner, options) { const tokenId = await this.getTokenId(domain); const args = new basicElements_1.Args() .addString(currentOwner) .addString(newOwner) .addU256(tokenId); return await this.call('transferFrom', args, options); } async balanceOf(owner, options) { const res = await this.read('balanceOf', new basicElements_1.Args().addString(owner), options); return basicElements_1.U256.fromBytes(res.value); } } exports.MNS = MNS; //# sourceMappingURL=mns.js.map