@unstoppabledomains/resolution
Version:
Domain Resolution for blockchain domains
349 lines (348 loc) • 16.9 kB
JavaScript
"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 __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var types_1 = require("./types");
var configurationError_1 = __importDefault(require("./errors/configurationError"));
var configurationError_2 = require("./errors/configurationError");
var utils_1 = require("./utils");
var FetchProvider_1 = __importDefault(require("./FetchProvider"));
var EthereumContract_1 = __importDefault(require("./contracts/EthereumContract"));
var proxyReader_1 = __importDefault(require("./contracts/uns/proxyReader"));
var uns_config_json_1 = __importDefault(require("./config/uns-config.json"));
var resolutionError_1 = __importStar(require("./errors/resolutionError"));
var namehash_1 = require("./utils/namehash");
var UnsInternal = /** @class */ (function () {
function UnsInternal(unsLocation, source, blockchain) {
this.unsLocation = unsLocation;
this.checkNetworkConfig(unsLocation, source);
this.network = source.network;
this.blockchain = blockchain;
this.url = source['url'];
this.provider =
source['provider'] || new FetchProvider_1.default(this.unsLocation, this.url);
this.readerContract = new EthereumContract_1.default(proxyReader_1.default, source.proxyReaderAddress ||
UnsInternal.ProxyReaderMap[utils_1.EthereumNetworks[this.network]], this.provider, source['proxyServiceApiKey']);
}
UnsInternal.prototype.exists = function (domain) {
return __awaiter(this, void 0, void 0, function () {
var exists;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.readerContract.call('exists', [
this.namehash(domain),
])];
case 1:
exists = (_a.sent())[0];
return [2 /*return*/, exists];
}
});
});
};
UnsInternal.prototype.reverseOf = function (addr) {
return __awaiter(this, void 0, void 0, function () {
var reverseHash;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.readerContract.call('reverseOf', [addr])];
case 1:
reverseHash = (_a.sent())[0];
return [2 /*return*/, reverseHash];
}
});
});
};
UnsInternal.prototype.getAddress = function (domain, network, token) {
return __awaiter(this, void 0, void 0, function () {
var tokenId, addr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
tokenId = this.namehash(domain);
return [4 /*yield*/, this.readerContract.call('getAddress', [
network,
token,
tokenId,
])];
case 1:
addr = (_a.sent())[0];
return [2 /*return*/, addr];
}
});
});
};
UnsInternal.prototype.getTokenUri = function (tokenId) {
return __awaiter(this, void 0, void 0, function () {
var tokenURI;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.readerContract.call('tokenURI', [tokenId])];
case 1:
tokenURI = (_a.sent())[0];
return [2 /*return*/, tokenURI];
}
});
});
};
UnsInternal.prototype.registryAddress = function (domainOrNamehash) {
return __awaiter(this, void 0, void 0, function () {
var isNamehash, namehash, address;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
isNamehash = !domainOrNamehash.includes('.');
if (!this.checkDomain(domainOrNamehash, isNamehash)) {
throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnsupportedDomain, {
domain: domainOrNamehash,
});
}
namehash = isNamehash
? domainOrNamehash
: this.namehash(domainOrNamehash);
return [4 /*yield*/, this.readerContract.call('registryOf', [namehash])];
case 1:
address = (_a.sent())[0];
if ((0, utils_1.isNullAddress)(address)) {
throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnregisteredDomain, {
domain: domainOrNamehash,
});
}
return [2 /*return*/, address];
}
});
});
};
UnsInternal.prototype.resolver = function (domain) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getVerifiedData(domain)];
case 1: return [2 /*return*/, (_a.sent()).resolver];
}
});
});
};
UnsInternal.prototype.get = function (tokenId, keys) {
if (keys === void 0) { keys = []; }
return __awaiter(this, void 0, void 0, function () {
var _a, resolver, owner, values;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.readerContract.call('getData', [keys, tokenId])];
case 1:
_a = _b.sent(), resolver = _a[0], owner = _a[1], values = _a[2];
return [2 /*return*/, {
owner: owner,
resolver: resolver,
records: (0, utils_1.constructRecords)(keys, values),
location: this.unsLocation,
}];
}
});
});
};
UnsInternal.prototype.locations = function (domains) {
return __awaiter(this, void 0, void 0, function () {
var tokenIds, _a, _b, resolvers, owners, registries, locations;
var _this = this;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
tokenIds = domains.map(function (d) { return _this.namehash(d); });
return [4 /*yield*/, this.readerContract.multicall(__spreadArray([
{
method: 'getDataForMany',
args: [[], tokenIds],
}
], tokenIds.map(function (id) { return ({
method: 'registryOf',
args: [id],
}); }), true))];
case 1:
_a = _c.sent(), _b = _a[0], resolvers = _b[0], owners = _b[1], registries = _a.slice(1);
locations = domains.reduce(function (locations, domain, i) {
locations[domain] = null;
if (owners && owners[i] !== types_1.NullAddress) {
locations[domain] = {
resolverAddress: resolvers[i],
registryAddress: registries[i][0],
ownerAddress: owners[i],
networkId: utils_1.EthereumNetworks[_this.network],
blockchain: _this.blockchain,
blockchainProviderUrl: _this.url,
};
}
return locations;
}, {});
return [2 /*return*/, locations];
}
});
});
};
UnsInternal.prototype.namehash = function (domain) {
if (!this.checkDomain(domain)) {
throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnsupportedDomain, {
domain: domain,
});
}
return (0, namehash_1.eip137Namehash)(domain);
};
UnsInternal.prototype.checkDomain = function (domain, passIfTokenID) {
if (passIfTokenID === void 0) { passIfTokenID = false; }
if (passIfTokenID) {
return true;
}
var tokens = domain.split('.');
return (!!tokens.length &&
!(domain === 'eth' || /^[^-]*[^-]*\.(eth|addr\.reverse)$/.test(domain)) &&
tokens.every(function (v) { return !!v.length; }));
};
UnsInternal.prototype.getVerifiedData = function (domain, keys) {
return __awaiter(this, void 0, void 0, function () {
var tokenId, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
tokenId = this.namehash(domain);
return [4 /*yield*/, this.get(tokenId, keys)];
case 1:
data = _a.sent();
if ((0, utils_1.isNullAddress)(data.resolver)) {
if ((0, utils_1.isNullAddress)(data.owner)) {
throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnregisteredDomain, {
domain: domain,
});
}
throw new resolutionError_1.default(resolutionError_1.ResolutionErrorCode.UnspecifiedResolver, {
location: this.unsLocation,
domain: domain,
});
}
return [2 /*return*/, data];
}
});
});
};
UnsInternal.prototype.checkNetworkConfig = function (location, source) {
if (!source.network) {
throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.UnsupportedNetwork, {
method: location,
});
}
if (source.proxyReaderAddress &&
!this.isValidProxyReader(source.proxyReaderAddress)) {
throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.InvalidConfigurationField, {
method: this.unsLocation,
field: 'proxyReaderAddress',
});
}
if (!types_1.UnsSupportedNetwork.guard(source.network)) {
this.checkCustomNetworkConfig(source);
}
};
UnsInternal.prototype.checkCustomNetworkConfig = function (source) {
if (!this.isValidProxyReader(source.proxyReaderAddress)) {
throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.InvalidConfigurationField, {
method: this.unsLocation,
field: 'proxyReaderAddress',
});
}
if (!source['url'] && !source['provider']) {
throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.CustomNetworkConfigMissing, {
method: this.unsLocation,
config: 'url or provider',
});
}
};
UnsInternal.prototype.isValidProxyReader = function (address) {
if (!address) {
throw new configurationError_1.default(configurationError_2.ConfigurationErrorCode.CustomNetworkConfigMissing, {
method: this.unsLocation,
config: 'proxyReaderAddress',
});
}
var ethLikePattern = new RegExp('^0x[a-fA-F0-9]{40}$');
return ethLikePattern.test(address);
};
UnsInternal.ProxyReaderMap = getProxyReaderMap();
return UnsInternal;
}());
exports.default = UnsInternal;
function getProxyReaderMap() {
var map = {};
for (var _i = 0, _a = Object.keys(uns_config_json_1.default.networks); _i < _a.length; _i++) {
var id = _a[_i];
map[id] =
uns_config_json_1.default.networks[id].contracts.ProxyReader.address.toLowerCase();
}
return map;
}