UNPKG

@unstoppabledomains/resolution

Version:
997 lines (996 loc) 66.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; 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()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Resolution = void 0; var bn_js_1 = __importDefault(require("bn.js")); var Ens_1 = __importDefault(require("./Ens")); var Zns_1 = __importDefault(require("./Zns")); var Uns_1 = __importDefault(require("./Uns")); var UdApi_1 = __importDefault(require("./UdApi")); var publicTypes_1 = require("./types/publicTypes"); var resolutionError_1 = __importStar(require("./errors/resolutionError")); var DnsUtils_1 = __importDefault(require("./utils/DnsUtils")); var utils_1 = require("./utils"); var Eip1993Factories_1 = require("./utils/Eip1993Factories"); var configurationError_1 = __importDefault(require("./errors/configurationError")); var configurationError_2 = require("./errors/configurationError"); var Networking_1 = __importDefault(require("./utils/Networking")); var prepareAndValidate_1 = require("./utils/prepareAndValidate"); var namehash_1 = require("./utils/namehash"); var DEFAULT_UNS_PROXY_SERVICE_URL = 'https://api.unstoppabledomains.com/resolve'; /** * Blockchain domain Resolution library - Resolution. * @example * ``` * import Resolution from '@unstoppabledomains/resolution'; * * let resolution = new Resolution({ blockchain: { * uns: { * url: "https://mainnet.infura.io/v3/<infura_api_key>", * network: "mainnet" * } * } * }); * * let domain = "brad.zil"; * resolution.addr(domain, "eth").then(addr => console.log(addr));; * ``` */ var Resolution = /** @class */ (function () { function Resolution(config) { var _a; if (config === void 0) { config = {}; } var uns = this.getUnsConfig(config); var unsBase = this.getUnsBaseConfig(config); var zns = this.getZnsConfig(config); var ens = this.getEnsConfig(config); // If both UNS and ZNS use the same UdApi providers, we don't want to call the API twice as it would return same // responses. It should be enough to compare just the URLs, as the network param isn't actually used in the calls. var equalUdApiProviders = uns instanceof UdApi_1.default && zns instanceof UdApi_1.default && uns.url === zns.url; // If a user configures the lib with an API source, we still want to initialise native blockchain services to access // some non-async methods such as namehash, as they are unavailable in the UdApi service. this.serviceMap = (_a = {}, _a[publicTypes_1.NamingServiceName.UNS] = { usedServices: [uns], native: uns instanceof Uns_1.default ? uns : new Uns_1.default(), }, _a[publicTypes_1.NamingServiceName.ZNS] = { usedServices: equalUdApiProviders ? [uns] : [uns, zns], native: zns instanceof Zns_1.default ? zns : new Zns_1.default(), }, _a[publicTypes_1.NamingServiceName.ENS] = { usedServices: [ens], native: ens instanceof Ens_1.default ? ens : new Ens_1.default(), }, _a); if (unsBase) { this.serviceMap[publicTypes_1.NamingServiceName.UNS_BASE] = { usedServices: [unsBase], native: unsBase instanceof Uns_1.default ? unsBase : new Uns_1.default(), }; } } Resolution.prototype.getService = function (serviceName) { var entry = this.serviceMap[serviceName]; if (!entry) { throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.NetworkConfigMissing, { method: serviceName, config: serviceName === publicTypes_1.NamingServiceName.UNS_BASE ? "sourceConfig.uns.base" : "sourceConfig.".concat(serviceName.toLowerCase()), }); } return entry; }; /** * AutoConfigure the blockchain network between different testnets for ENS and UNS * We make a "net_version" JSON RPC call to the blockchain either via url or with the help of given provider. * @param sourceConfig - configuration object for ens and uns * @returns configured Resolution object */ Resolution.autoNetwork = function (sourceConfig) { return __awaiter(this, void 0, void 0, function () { var resolution, uns, ens; return __generator(this, function (_a) { switch (_a.label) { case 0: resolution = new this(); if (!sourceConfig.uns && !sourceConfig.ens) { throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.UnsupportedNetwork); } if (!sourceConfig.uns) return [3 /*break*/, 2]; return [4 /*yield*/, Uns_1.default.autoNetwork(sourceConfig.uns)]; case 1: uns = _a.sent(); resolution.serviceMap[publicTypes_1.NamingServiceName.UNS] = { usedServices: [uns], native: uns, }; _a.label = 2; case 2: if (!sourceConfig.ens) return [3 /*break*/, 4]; return [4 /*yield*/, Ens_1.default.autoNetwork(sourceConfig.ens)]; case 3: ens = _a.sent(); resolution.serviceMap[publicTypes_1.NamingServiceName.ENS] = { usedServices: [ens], native: ens, }; _a.label = 4; case 4: return [2 /*return*/, resolution]; } }); }); }; /** * Creates a resolution with configured infura id for ens and uns * @param infura - infura project id * @param networks - an optional object that describes what network to use when connecting ENS or UNS default is mainnet */ Resolution.infura = function (infura, networks) { var _a, _b, _c, _d, _e, _f; return new this({ sourceConfig: { ens: { url: (0, utils_1.signedInfuraLink)(infura, (_a = networks === null || networks === void 0 ? void 0 : networks.ens) === null || _a === void 0 ? void 0 : _a.network), network: ((_b = networks === null || networks === void 0 ? void 0 : networks.ens) === null || _b === void 0 ? void 0 : _b.network) || 'mainnet', }, uns: { locations: { Layer1: { url: (0, utils_1.signedLink)(infura, ((_c = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _c === void 0 ? void 0 : _c.locations.Layer1.network) || 'mainnet', 'infura'), network: ((_d = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _d === void 0 ? void 0 : _d.locations.Layer1.network) || 'mainnet', }, Layer2: { url: (0, utils_1.signedLink)(infura, ((_e = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _e === void 0 ? void 0 : _e.locations.Layer2.network) || 'polygon-mainnet', 'infura'), network: ((_f = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _f === void 0 ? void 0 : _f.locations.Layer2.network) || 'polygon-mainnet', }, }, }, }, }); }; /** * Creates a resolution with configured alchemy API keys for uns * @param alchemy - alchemy API keys * @param networks - an optional object that describes what network to use when connecting UNS default is mainnet */ Resolution.alchemy = function (alchemy, networks) { var _a, _b, _c, _d; return new this({ sourceConfig: { uns: { locations: { Layer1: { url: (0, utils_1.signedLink)(alchemy, ((_a = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _a === void 0 ? void 0 : _a.locations.Layer1.network) || 'mainnet'), network: ((_b = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _b === void 0 ? void 0 : _b.locations.Layer1.network) || 'mainnet', }, Layer2: { url: (0, utils_1.signedLink)(alchemy, ((_c = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _c === void 0 ? void 0 : _c.locations.Layer2.network) || 'polygon-mainnet'), network: ((_d = networks === null || networks === void 0 ? void 0 : networks.uns) === null || _d === void 0 ? void 0 : _d.locations.Layer2.network) || 'polygon-mainnet', }, }, }, }, }); }; /** * Creates a resolution instance with configured provider * @param networks - an object that describes what network to use when connecting UNS, ENS, or ZNS default is mainnet * @see https://eips.ethereum.org/EIPS/eip-1193 */ Resolution.fromResolutionProvider = function (networks) { if (networks.ens || networks.uns) { return this.fromEthereumEip1193Provider({ ens: networks.ens, uns: networks.uns, }); } if (networks.zns) { return this.fromZilliqaProvider(networks.zns.provider, networks); } throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.ServiceProviderError, { providerMessage: 'Must specify network for uns, ens, or zns', }); }; /** * Creates a resolution instance with configured provider * @param networks - an object that describes what network to use when connecting UNS and ENS default is mainnet * @see https://eips.ethereum.org/EIPS/eip-1193 */ Resolution.fromEthereumEip1193Provider = function (networks) { var _a; var sourceConfig = {}; if (networks.ens) { sourceConfig.ens = { provider: networks.ens.provider, network: ((_a = networks === null || networks === void 0 ? void 0 : networks.ens) === null || _a === void 0 ? void 0 : _a.network) || 'mainnet', }; } if (networks.uns) { sourceConfig.uns = { locations: { Layer1: { provider: networks.uns.locations.Layer1.provider, network: networks.uns.locations.Layer1.network || 'mainnet', }, Layer2: { provider: networks.uns.locations.Layer2.provider, network: networks.uns.locations.Layer2.network || 'polygon-mainnet', }, }, }; } return new this({ sourceConfig: sourceConfig, }); }; /** * Creates a resolution instance with configured provider * @param provider - any provider compatible with EIP-1193 * @param networks - an optional object that describes what network to use when connecting ZNS default is mainnet * @see https://eips.ethereum.org/EIPS/eip-1193 */ Resolution.fromZilliqaProvider = function (provider, networks) { var _a; return new this({ sourceConfig: { zns: { provider: provider, network: ((_a = networks === null || networks === void 0 ? void 0 : networks.zns) === null || _a === void 0 ? void 0 : _a.network) || 'mainnet' }, }, }); }; /** * Create a resolution instance from web3 0.x version provider * @param networks - Ethereum network configuration with 0.x version provider from web3 ( must implement sendAsync(payload, callback) ) * @see https://github.com/ethereum/web3.js/blob/0.20.7/lib/web3/httpprovider.js#L116 */ Resolution.fromWeb3Version0Provider = function (networks) { return this.fromEthereumEip1193Provider({ ens: networks.ens ? { network: networks.ens.network, provider: Eip1993Factories_1.Eip1993Factories.fromWeb3Version0Provider(networks.ens.provider), } : undefined, uns: networks.uns ? { locations: { Layer1: { network: networks.uns.locations.Layer1.network, provider: Eip1993Factories_1.Eip1993Factories.fromWeb3Version0Provider(networks.uns.locations.Layer1.provider), }, Layer2: { network: networks.uns.locations.Layer2.network, provider: Eip1993Factories_1.Eip1993Factories.fromWeb3Version0Provider(networks.uns.locations.Layer2.provider), }, }, } : undefined, }); }; /** * Create a resolution instance from web3 1.x version provider * @param networks - an optional object with 1.x version provider from web3 ( must implement send(payload, callback) ) that describes what network to use when connecting ENS or UNS default is mainnet * @see https://github.com/ethereum/web3.js/blob/1.x/packages/web3-core-helpers/types/index.d.ts#L165 * @see https://github.com/ethereum/web3.js/blob/1.x/packages/web3-providers-http/src/index.js#L95 */ Resolution.fromWeb3Version1Provider = function (networks) { return this.fromEthereumEip1193Provider({ ens: networks.ens ? { network: networks.ens.network, provider: Eip1993Factories_1.Eip1993Factories.fromWeb3Version1Provider(networks.ens.provider), } : undefined, uns: networks.uns ? { locations: { Layer1: { network: networks.uns.locations.Layer1.network, provider: Eip1993Factories_1.Eip1993Factories.fromWeb3Version1Provider(networks.uns.locations.Layer1.provider), }, Layer2: { network: networks.uns.locations.Layer2.network, provider: Eip1993Factories_1.Eip1993Factories.fromWeb3Version1Provider(networks.uns.locations.Layer2.provider), }, }, } : undefined, }); }; /** * Creates instance of resolution from provider that implements Ethers Provider#call interface. * This wrapper support only `eth_call` method for now, which is enough for all the current Resolution functionality * @param networks - an object that describes what network to use when connecting ENS or UNS default is mainnet * @see https://github.com/ethers-io/ethers.js/blob/v4-legacy/providers/abstract-provider.d.ts#L91 * @see https://github.com/ethers-io/ethers.js/blob/v5.0.4/packages/abstract-provider/src.ts/index.ts#L224 * @see https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#jsonrpcprovider-inherits-from-provider * @see https://github.com/ethers-io/ethers.js/blob/master/packages/providers/src.ts/json-rpc-provider.ts */ Resolution.fromEthersProvider = function (networks) { return this.fromEthereumEip1193Provider({ ens: networks.ens ? { network: networks.ens.network, provider: Eip1993Factories_1.Eip1993Factories.fromEthersProvider(networks.ens.provider), } : undefined, uns: networks.uns ? { locations: { Layer1: { network: networks.uns.locations.Layer1.network, provider: Eip1993Factories_1.Eip1993Factories.fromEthersProvider(networks.uns.locations.Layer1.provider), }, Layer2: { network: networks.uns.locations.Layer2.network, provider: Eip1993Factories_1.Eip1993Factories.fromEthersProvider(networks.uns.locations.Layer2.provider), }, }, } : undefined, }); }; /** * Resolves given domain name to a specific currency address if exists * @async * @param domain - domain name to be resolved * @param ticker - currency ticker like BTC, ETH, ZIL * @throws [[ResolutionError]] if address is not found * @returns A promise that resolves in an address */ Resolution.prototype.addr = function (domain, ticker) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [4 /*yield*/, this.callServiceForDomain(domain, function (service) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(service instanceof Ens_1.default)) return [3 /*break*/, 2]; return [4 /*yield*/, service.addr(domain, ticker)]; case 1: return [2 /*return*/, _a.sent()]; case 2: return [4 /*yield*/, this.record(domain, "crypto.".concat(ticker.toUpperCase(), ".address"))]; case 3: return [2 /*return*/, _a.sent()]; } }); }); })]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Read multi-chain currency address if exists * @async * @param domain - domain name to be resolved * @param ticker - currency ticker (USDT, FTM, etc.) * @param chain - chain version, usually means blockchain ( ERC20, BEP2, OMNI, etc. ) * @throws [[ResolutionError]] if address is not found * @returns A promise that resolves in an adress */ Resolution.prototype.multiChainAddr = function (domain, ticker, chain) { return __awaiter(this, void 0, void 0, function () { var recordKey; var _this = this; return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); recordKey = "crypto.".concat(ticker.toUpperCase(), ".version.").concat(chain.toUpperCase(), ".address"); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (service instanceof Ens_1.default) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnsupportedMethod, { methodName: 'multiChainAddr', domain: domain, method: service.name, }); } return [4 /*yield*/, service.record(domain, recordKey)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); })]; }); }); }; /** * Resolves given domain name to a verified twitter handle * @async * @param domain - domain name to be resolved * @throws [[ResolutionError]] if twitter is not found * @returns A promise that resolves in a verified twitter handle */ Resolution.prototype.twitter = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.twitter(domain); })]; }); }); }; /** * Resolve a chat id from the domain record * @param domain - domain name to be resolved * @throws [[ResolutionError]] * @returns A promise that resolves in chatId */ Resolution.prototype.chatId = function (domain) { return __awaiter(this, void 0, void 0, function () { var err_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.record(domain, 'gundb.username.value')]; case 1: return [2 /*return*/, _a.sent()]; case 2: err_1 = _a.sent(); if (err_1.code === resolutionError_1.ResolutionErrorCode.RecordNotFound) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.RecordNotFound, { domain: domain, method: err_1.method, methodName: 'chatId', recordName: err_1.recordName, }); } throw err_1; case 3: return [2 /*return*/]; } }); }); }; /** * Resolve a gundb public key from the domain record * @param domain - domain name to be resolved * @throws [[ResolutionError]] * @returns a promise that resolves in gundb public key */ Resolution.prototype.chatPk = function (domain) { return __awaiter(this, void 0, void 0, function () { var err_2; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.record(domain, 'gundb.public_key.value')]; case 1: return [2 /*return*/, _a.sent()]; case 2: err_2 = _a.sent(); if (err_2.code === resolutionError_1.ResolutionErrorCode.RecordNotFound) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.RecordNotFound, { domain: domain, method: err_2.method, methodName: 'chatId', recordName: err_2.recordName, }); } throw err_2; case 3: return [2 /*return*/]; } }); }); }; /** * Resolves the IPFS hash configured for domain records on ZNS * @param domain - domain name * @throws [[ResolutionError]] */ Resolution.prototype.ipfsHash = function (domain) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [4 /*yield*/, this.callServiceForDomain(domain, function (service) { return __awaiter(_this, void 0, void 0, function () { var contentHash; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(service instanceof Ens_1.default)) return [3 /*break*/, 2]; return [4 /*yield*/, service.record(domain, 'contenthash')]; case 1: contentHash = _a.sent(); return [2 /*return*/, "ipfs://".concat(contentHash)]; case 2: return [4 /*yield*/, this.getPreferableNewRecord(domain, 'dweb.ipfs.hash', 'ipfs.html.value')]; case 3: return [2 /*return*/, _a.sent()]; } }); }); })]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Resolves the httpUrl attached to domain * @param domain - domain name */ Resolution.prototype.httpUrl = function (domain) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [4 /*yield*/, this.callServiceForDomain(domain, function (service) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(service instanceof Ens_1.default)) return [3 /*break*/, 2]; return [4 /*yield*/, service.record(domain, 'url')]; case 1: return [2 /*return*/, _a.sent()]; case 2: return [4 /*yield*/, this.getPreferableNewRecord(domain, 'browser.redirect_url', 'ipfs.redirect_domain.value')]; case 3: return [2 /*return*/, _a.sent()]; } }); }); })]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Resolves the ipfs email field from whois configurations * @param domain - domain name * @throws [[ResolutionError]] * @returns A Promise that resolves in an email address configured for this domain whois */ Resolution.prototype.email = function (domain) { return __awaiter(this, void 0, void 0, function () { var key, serviceName, err_3; return __generator(this, function (_a) { switch (_a.label) { case 0: domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); key = 'whois.email.value'; return [4 /*yield*/, (0, utils_1.findNamingServiceName)(domain)]; case 1: serviceName = _a.sent(); if (serviceName === 'ENS') { key = 'email'; } _a.label = 2; case 2: _a.trys.push([2, 4, , 5]); return [4 /*yield*/, this.record(domain, key)]; case 3: return [2 /*return*/, _a.sent()]; case 4: err_3 = _a.sent(); throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.RecordNotFound, { domain: domain, method: err_3.method, methodName: 'email', recordName: err_3.recordName, }); case 5: return [2 /*return*/]; } }); }); }; /** * @returns the resolver address for a specific domain * @param domain - domain to look for */ Resolution.prototype.resolver = function (domain) { return __awaiter(this, void 0, void 0, function () { var resolver; return __generator(this, function (_a) { switch (_a.label) { case 0: domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [4 /*yield*/, this.callServiceForDomain(domain, function (service) { return service.resolver(domain); })]; case 1: resolver = _a.sent(); if (!resolver) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnspecifiedResolver, { domain: domain, }); } return [2 /*return*/, resolver]; } }); }); }; /** * @param domain - domain name * @returns An owner address of the domain */ Resolution.prototype.owner = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.owner(domain); })]; }); }); }; /** * @param domain - domain name * @param network - network name * @param token - token ticker * @returns An owner address of the domain */ Resolution.prototype.getAddress = function (domain, network, token) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.getAddress(domain, network, token); })]; }); }); }; /** * @param domain - domain name * @param recordKey - a name of a record to be resolved * @returns A record value promise for a given record name */ Resolution.prototype.record = function (domain, recordKey) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.record(domain, recordKey); })]; }); }); }; /** * @param domain domain name * @param keys Array of record keys to be resolved * @returns A Promise with key-value mapping of domain records */ Resolution.prototype.records = function (domain, keys) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.records(domain, keys); })]; }); }); }; /** * @param domain domain name * @returns A Promise of whether or not the domain belongs to a wallet */ Resolution.prototype.isRegistered = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomainBoolean(domain, function (service) { return service.isRegistered(domain); }, { throwIfUnsupportedDomain: true, expectedValue: true, })]; }); }); }; /** * @param domain domain name * @returns A Promise of whether or not the domain is available */ Resolution.prototype.isAvailable = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomainBoolean(domain, function (service) { return service.isAvailable(domain); }, { throwIfUnsupportedDomain: true, expectedValue: false, })]; }); }); }; /** * @returns Produces a namehash from supported naming service in hex format with 0x prefix. * Corresponds to ERC721 token id in case of Ethereum based naming service like ENS or UNS. * @param domain domain name to be converted * @param namingService "UNS" or "ZNS" (uses keccak256 or sha256 algorithm respectively) * @param options formatting options * @throws [[ResolutionError]] with UnsupportedDomain error code if domain extension is unknown */ Resolution.prototype.namehash = function (domain, namingService, options) { if (options === void 0) { options = publicTypes_1.NamehashOptionsDefault; } var service = this.getService(namingService); if (!service) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnsupportedService, { namingService: namingService, }); } domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return this.formatNamehash(service.native.namehash(domain), options); }; /** * @returns a namehash of a subdomain with name label * @param parent namehash of a parent domain * @param label subdomain name * @param namingService "ENS", "UNS" or "ZNS" (uses keccak256 or sha256 algorithm respectively) * @param options formatting options */ Resolution.prototype.childhash = function (parent, label, namingService, options) { if (options === void 0) { options = publicTypes_1.NamehashOptionsDefault; } try { var service = this.getService(namingService); return this.formatNamehash(service.native.childhash(parent, label), options); } catch (error) { if (error instanceof configurationError_1.default && error.code === configurationError_2.ConfigurationErrorCode.NetworkConfigMissing) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnsupportedService, { namingService: namingService, }); } throw error; } }; Resolution.prototype.formatNamehash = function (hash, options) { hash = hash.replace('0x', ''); if (options.format === 'dec') { return new bn_js_1.default(hash, 'hex').toString(10); } else { return options.prefix ? '0x' + hash : hash; } }; /** * Checks weather the domain name matches the hash * @param domain - domain name to check against * @param hash - hash obtained from the blockchain * @param namingService - "UNS" or "ZNS" (uses keccak256 or sha256 algorithm respectively) */ Resolution.prototype.isValidHash = function (domain, hash, namingService) { var service = this.getService(namingService); if (!service) { throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnsupportedService, { namingService: namingService, }); } domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return service.native.namehash(domain) === hash; }; /** * Checks if the domain name is valid according to naming service rules * for valid domain names. * Example: ENS doesn't allow domains that start from '-' symbol. * @param domain - domain name to be checked */ Resolution.prototype.isSupportedDomain = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomainBoolean(domain, function (service) { return service.isSupportedDomain(domain); }, { throwIfUnsupportedDomain: false, expectedValue: true, })]; }); }); }; /** * Returns all record keys of the domain. * This method is strongly unrecommended for production use due to lack of support for many ethereum service providers and low performance * Method is not supported by ENS * @param domain - domain name * @deprecated */ Resolution.prototype.allRecords = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.allRecords(domain); })]; }); }); }; Resolution.prototype.dns = function (domain, types) { return __awaiter(this, void 0, void 0, function () { var dnsUtils, dnsRecordKeys, blockchainData; return __generator(this, function (_a) { switch (_a.label) { case 0: dnsUtils = new DnsUtils_1.default(); domain = (0, prepareAndValidate_1.prepareAndValidateDomain)(domain); dnsRecordKeys = this.getDnsRecordKeys(types); return [4 /*yield*/, this.callServiceForDomain(domain, function (service) { return service.records(domain, dnsRecordKeys); })]; case 1: blockchainData = _a.sent(); return [2 /*return*/, dnsUtils.toList(blockchainData)]; } }); }); }; /** * Retrieves the tokenURI from the registry smart contract. * @returns the ERC721Metadata#tokenURI contract method result * @param domain - domain name */ Resolution.prototype.tokenURI = function (domain) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { // The `getTokenUri` method isn't supported in ZNS (it'll throw in the next call) return [2 /*return*/, this.callServiceForDomain(domain, function (service) { if (service.name === publicTypes_1.NamingServiceName.UNS) { var namehash_2 = _this.namehash(domain, publicTypes_1.NamingServiceName.UNS); return service.getTokenUri(namehash_2); } else if (service.name === publicTypes_1.NamingServiceName.ENS) { return service.getTokenUri(domain); } var namehash = _this.namehash(domain, publicTypes_1.NamingServiceName.ZNS); return service.getTokenUri(namehash); })]; }); }); }; /** * Retrieves the data from the endpoint provided by tokenURI from the registry smart contract. * @returns the JSON response of the token URI endpoint * @param domain - domain name */ Resolution.prototype.tokenURIMetadata = function (domain) { return __awaiter(this, void 0, void 0, function () { var tokenUri; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.tokenURI(domain)]; case 1: tokenUri = _a.sent(); return [2 /*return*/, this.getMetadataFromTokenURI(tokenUri)]; } }); }); }; /** * Retrieves address of registry contract used for domain * @param domain - domain name * @returns Registry contract address */ Resolution.prototype.registryAddress = function (domain) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.callServiceForDomain(domain, function (service) { return service.registryAddress(domain); })]; }); }); }; /** * Retrieves the domain name from tokenId by parsing registry smart contract event logs. * @throws {ResolutionError} if returned domain name doesn't match the original namehash. * @returns the domain name retrieved from token metadata. * @param hash - domain name hash or label hash. * @param service - name service which is used for lookup. */ Resolution.prototype.unhash = function (hash, service) { return __awaiter(this, void 0, void 0, function () { var services, method; return __generator(this, function (_a) { hash = (0, namehash_1.fromDecStringToHex)(hash); services = this.getService(service).usedServices; method = services[services.length - 1]; return [2 /*return*/, method.getDomainFromTokenId(hash)]; }); }); }; /** * Retrieves address of registry contract used for domain * @param domains - domain name * @returns Promise<Locations> - A map of domain name and Location (a set of attributes like blockchain, */ Resolution.prototype.locations = function (domains) { return __awaiter(this, void 0, void 0, function () { var zilDomains, ensDomains, nonEnsDomains, unsPromise, unsLocations, znsServices, znsService_1, znsPromise, emptyZilEntries, znsLocations, _i, emptyZilEntries_1, domain, ensLocations, ensDomain; return __generator(this, function (_a) { switch (_a.label) { case 0: zilDomains = domains.filter(function (domain) { return domain.endsWith('.zil'); }); ensDomains = domains.filter(function (domain) { return domain.match(/^([^\s\\.]+\.)+(eth)+$/); }); nonEnsDomains = domains.filter(function (domain) { return !domain.match(/^([^\s\\.]+\.)+(eth)+$/); }); unsPromise = this.getService(publicTypes_1.NamingServiceName.UNS).usedServices[0].locations(nonEnsDomains); return [4 /*yield*/, unsPromise]; case 1: unsLocations = _a.sent(); if (!zilDomains.length) return [3 /*break*/, 3]; znsServices = this.getService(publicTypes_1.NamingServiceName.ZNS).usedServices; znsService_1 = znsServices[znsServices.length - 1]; znsPromise = (0, utils_1.wrapResult)(function () { return znsService_1.locations(zilDomains); }); emptyZilEntries = Object.entries(unsLocations).filter(function (_a) { var domain = _a[0], location = _a[1]; return domain.endsWith('.zil') && !location; }); return [4 /*yield*/, znsPromise.then(utils_1.unwrapResult)]; case 2: znsLocations = _a.sent(); for (_i = 0, emptyZilEntries_1 = emptyZilEntries; _i < emptyZilEntries_1.length; _i++) { domain = emptyZilEntries_1[_i][0]; unsLocations[domain] = znsLocations[domain]; } _a.label = 3; case 3: if (!ensDomains.length) return [3 /*break*/, 5]; return [4 /*yield*/, this.getService(publicTypes_1.NamingServiceName.ENS).usedServices[0].locations(ensDomains)]; case 4: ensLocations = _a.sent(); for (ensDomain in ensLocations) { unsLocations[ensDomain] = ensLocations[ensDomain]; } _a.label = 5; case 5: return [2 /*return*/, unsLocations]; } });