UNPKG

@filfox/fnsjs

Version:

Library For FNS

433 lines (432 loc) 17.5 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { utils, providers } from 'ethers'; import { keccak256, toUtf8Bytes, toUtf8String, namehash } from 'ethers/lib/utils'; import { useContract } from './hooks'; import { trimSuffix, labelhash, formatTime, isTimeBefore, formatUnits, getFilMarketPrice, formatAssetValue, convertToEthAddr } from './utils'; import { COIN_IDS, COIN_NAMES, TEXT_KEYS, getNetwork } from './constant'; class Name { constructor(name, fns) { this.name = name; this.fns = fns; } /* read methods */ getBase() { return this.fns.getNameBase(this.name); } getInfo() { return this.fns.getNameInfo(this.name); } getAddrs() { return this.fns.getNameAddrs(this.name); } getTexts() { return this.fns.getNameTexts(this.name); } getAvailable() { return this.fns.getAvailable(this.name); } getPrice(months, unit) { return this.fns.getPrice(this.name, months, unit); } getRegistrant() { return this.fns.getRegistrant(this.name); } getExpires(format) { return this.fns.getExpires(this.name, format); } getExpired() { return this.fns.getExpired(this.name); } getController() { return this.fns.getController(this.name); } getContent() { return this.fns.getContent(this.name); } getText(key) { return this.fns.getText(this.name, key); } getAddr() { return this.fns.getAddr(this.name); } getAddrOf(coin) { return this.fns.getAddrOf(this.name, coin); } /* write methods */ register(owner, months) { return this.fns.register(this.name, owner, months); } renew(months) { return this.fns.renew(this.name, months); } transferControlTo(addr) { return this.fns.transferControl(this.name, addr); } transferOwnershipTo(to) { return this.fns.transferOwnership(this.name, to); } setController(addr) { return this.fns.setController(this.name, addr); } setContent(content) { return this.fns.setContent(this.name, content); } setText(key, val) { return this.fns.setText(this.name, key, val); } setTexts(texts) { return this.fns.setTexts(this.name, texts); } setAddrOf(coin, addr) { return this.fns.setAddrOf(this.name, coin, addr); } setAddrs(addrMap) { return this.fns.setAddrs(this.name, addrMap); } setPrimaryName() { return this.fns.setPrimaryName(this.name); } setSubName(subname, owner) { return this.fns.setSubName(this.name, subname, owner); } } class Address { constructor(address, fns) { this.address = address; this.fns = fns; } getName() { return this.fns.lookupAddress(this.address); } getPrimaryName() { return this.fns.getPrimaryName(this.address); } getOwnershipNames() { return this.fns.getOwnershipNames(this.address); } } export default class FNS { constructor(network) { this.network = null; this.provider = null; this.signer = null; this.network = getNetwork(network); const defaultProvider = providers.getDefaultProvider(this.network.rpc); this.setProvider(defaultProvider); } setProvider(provider) { if (providers.Provider.isProvider(provider)) { this.provider = provider; } else { this.provider = new providers.Web3Provider(provider); } this.signer = this.provider.getSigner(); } getProvider() { return this.provider; } setSigner(signer) { this.signer = signer; } getSigner() { return this.signer; } /*** name api ***/ name(name) { return new Name(name, this); } /*** address api ***/ address(address) { return new Address(address, this); } /*** readonly api ***/ getResolver() { return this.network.contractAddress['PublicResolver']; } getNameBase(name) { var _a, _b, _c, _d, _e; return __awaiter(this, void 0, void 0, function* () { const requests = [ this.getAvailable(name), this.getExpires(name, 'YYYY-MM-DD HH:mm'), this.getExpired(name), this.getRegistrant(name), this.getController(name) ]; const results = yield Promise.allSettled(requests); return { name, available: (_a = results[0].value) !== null && _a !== void 0 ? _a : false, expires: (_b = results[1].value) !== null && _b !== void 0 ? _b : 0, expired: (_c = results[2].value) !== null && _c !== void 0 ? _c : true, registrant: (_d = results[3].value) !== null && _d !== void 0 ? _d : '', controller: (_e = results[4].value) !== null && _e !== void 0 ? _e : '', resolver: this.getResolver() }; }); } getNameAddrs(name) { return __awaiter(this, void 0, void 0, function* () { const coins = COIN_NAMES; const requests = coins.map(c => this.getAddrOf(name, c)); const results = yield Promise.allSettled(requests); const addrs = {}; coins.forEach((c, i) => { var _a; return addrs[c] = (_a = results[i].value) !== null && _a !== void 0 ? _a : ''; }); return addrs; }); } getNameTexts(name) { return __awaiter(this, void 0, void 0, function* () { const textKeys = TEXT_KEYS; const requests = textKeys.map(k => this.getText(name, k)); const results = yield Promise.allSettled(requests); const texts = {}; textKeys.forEach((k, i) => { var _a; return texts[k] = (_a = results[i].value) !== null && _a !== void 0 ? _a : ''; }); return texts; }); } getNameInfo(name) { var _a, _b, _c, _d; return __awaiter(this, void 0, void 0, function* () { const requests = [ this.getNameBase(name), this.getNameAddrs(name), this.getNameTexts(name), this.getContent(name) ]; const results = yield Promise.allSettled(requests); return Object.assign(Object.assign({}, ((_a = results[0].value) !== null && _a !== void 0 ? _a : {})), { addrs: (_b = results[1].value) !== null && _b !== void 0 ? _b : {}, texts: (_c = results[2].value) !== null && _c !== void 0 ? _c : {}, content: (_d = results[3].value) !== null && _d !== void 0 ? _d : '' }); }); } getAvailable(name) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('RegistrarController', this.provider, this.network.name); const available = yield contract.available(trimSuffix(name)); return available; }); } getPrice(name, months = 12, unit) { return __awaiter(this, void 0, void 0, function* () { const duration = months * 30 * 86400; const contract = useContract('RegistrarController', this.provider, this.network.name); const { base } = yield contract.rentPrice(trimSuffix(name), duration); switch (unit) { case 'fil': return formatUnits(base); case 'usd': const price = yield getFilMarketPrice(); return formatAssetValue(base, price); default: return base; } }); } getRegistrant(name) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('Registrar', this.provider, this.network.name); const tokenId = keccak256(toUtf8Bytes(trimSuffix(name))); const registrant = yield contract.ownerOf(tokenId); return registrant; }); } getExpires(name, format) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('RegistrarController', this.provider, this.network.name); const expires = yield contract.nameExpires(trimSuffix(name)); const timestamp = expires.toNumber(); return format ? formatTime(timestamp, format) : timestamp; }); } getExpired(name) { return __awaiter(this, void 0, void 0, function* () { const curTimestamp = (yield this.provider.getBlock()).timestamp; const nameExpiresTimestamp = yield this.getExpires(name); return isTimeBefore(nameExpiresTimestamp, curTimestamp); }); } getController(name) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('FNSRegistry', this.provider, this.network.name); const node = namehash(name); const controller = yield contract.owner(node); return controller == 0x0 ? '' : controller; }); } getContent(name) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.provider, this.network.name); const node = namehash(name); const contenthash = yield contract.contenthash(node); return toUtf8String(contenthash); }); } getText(name, key) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.provider, this.network.name); const node = namehash(name); const val = yield contract.text(node, key); return val; }); } getAddr(name) { return __awaiter(this, void 0, void 0, function* () { return this.getAddrOf(name, 'fil'); }); } getAddrOf(name, coin) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.provider, this.network.name); const coinCode = COIN_IDS[coin]; const addr = yield contract['addr(bytes32,uint256)'](namehash(name), coinCode); return toUtf8String(addr); }); } lookupAddress(addr) { return __awaiter(this, void 0, void 0, function* () { const ethAddr = convertToEthAddr(addr); const primaryName = yield this.getPrimaryName(ethAddr); const filAddr = convertToEthAddr(yield this.getAddr(primaryName)); return ethAddr == filAddr ? primaryName : ''; }); } getPrimaryName(addr) { return __awaiter(this, void 0, void 0, function* () { const ethAddr = convertToEthAddr(addr); const contract = useContract('PublicResolver', this.provider, this.network.name); const node = namehash(`${ethAddr.substring(2).toLowerCase()}.addr.reverse`); const name = yield contract.name(node); return name; }); } getOwnershipNames(addr) { return __awaiter(this, void 0, void 0, function* () { const ethAddr = convertToEthAddr(addr); const contract = useContract('Registrar', this.provider, this.network.name); const count = yield contract.balanceOf(ethAddr); const tokenIds = yield Promise.all(Array.from({ length: count }).map((_, index) => contract.tokenOfOwnerByIndex(ethAddr, index))); const list = yield Promise.all(tokenIds.map(tokenId => contract.nameOf(tokenId))); const names = list.map(name => `${name}.fil`); return names; }); } /*** write api ***/ register(name, owner, months, reverseRecord = true, resolver = this.network.contractAddress['PublicResolver'], data = []) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('RegistrarController', this.getSigner(), this.network.name); const duration = months * 30 * 86400; const price = yield this.getPrice(name, months); const tx = yield contract.register(trimSuffix(name), owner, duration, resolver, data, reverseRecord, { value: price }); return tx; }); } renew(name, months) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('RegistrarController', this.getSigner(), this.network.name); const duration = months * 30 * 86400; const price = yield this.getPrice(name, months); const tx = yield contract.renew(trimSuffix(name), duration, { value: price }); return tx; }); } /* Only called by registrant */ transferControl(name, addr) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('Registrar', this.getSigner(), this.network.name); const id = labelhash(trimSuffix(name)); const tx = yield contract.reclaim(id, addr); return tx; }); } /* Only called by registrant */ transferOwnership(name, to) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('Registrar', this.getSigner(), this.network.name); const id = labelhash(trimSuffix(name)); const from = yield this.getRegistrant(name); const tx = yield contract.transferFrom(from, to, id); return tx; }); } /* Only called by controller */ setController(name, addr) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('FNSRegistry', this.getSigner(), this.network.name); const node = namehash(name); const tx = yield contract.setOwner(node, addr); return tx; }); } setContent(name, content) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.getSigner(), this.network.name); const node = namehash(name); const tx = yield contract.setContenthash(node, toUtf8Bytes(content)); return tx; }); } setText(name, key, val) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.getSigner(), this.network.name); const node = namehash(name); const tx = yield contract.setText(node, key, val); return tx; }); } setTexts(name, texts) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.getSigner(), this.network.name); const node = namehash(name); const keys = Object.keys(texts); const vals = Object.values(texts); const tx = yield contract.setTexts(node, keys, vals); return tx; }); } setAddrOf(name, coin, addr) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.getSigner(), this.network.name); const tx = yield contract['setAddr(bytes32,uint256,bytes)'](namehash(name), COIN_IDS[coin], utils.toUtf8Bytes(addr), { value: 0 }); return tx; }); } setAddrs(name, addrMap) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('PublicResolver', this.getSigner(), this.network.name); const node = namehash(name); const coins = Object.keys(addrMap).map(c => COIN_IDS[c]); const addrs = Object.values(addrMap).map(a => utils.toUtf8Bytes(a)); const tx = yield contract.setAddrs(node, coins, addrs, { value: 0 }); return tx; }); } setPrimaryName(name) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('ReverseRegistrar', this.getSigner(), this.network.name); const tx = yield contract.setName(name); return tx; }); } setSubName(name, subname, owner) { return __awaiter(this, void 0, void 0, function* () { const contract = useContract('FNSRegistry', this.getSigner(), this.network.name); const node = namehash(name); const label = labelhash(subname); const resolver = this.network.contractAddress['PublicResolver']; const tx = yield contract.setSubnodeRecord(node, label, owner, resolver, 0); return tx; }); } }