admin: updated dist files

This commit is contained in:
Richard Moore 2021-10-19 00:01:37 -04:00
parent ecce86125d
commit d3079745c5
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651
27 changed files with 858 additions and 149 deletions

@ -4,9 +4,10 @@ Changelog
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
ethers/v5.5.0 (2021-10-17 23:02)
ethers/v5.5.0 (2021-10-19 00:01)
--------------------------------
- Added ENS avatar support to provider. ([#2185](https://github.com/ethers-io/ethers.js/issues/2185); [ecce861](https://github.com/ethers-io/ethers.js/commit/ecce86125d87ef5258406bde2fff5bc8c9ff3141))
- Fixed splitSignature logic for verifying EIP-2930 and EIP-1559 v. ([#2084](https://github.com/ethers-io/ethers.js/issues/2084); [3de1b81](https://github.com/ethers-io/ethers.js/commit/3de1b815014b10d223a42e524fe9c25f9087293b))
- Include events on ContractFactory deployment transactions. ([#1334](https://github.com/ethers-io/ethers.js/issues/1334); [ab319f2](https://github.com/ethers-io/ethers.js/commit/ab319f2f4c365d4cd1b1e17e577ecd18a7a89276))
- admin: fixed alias script. ([#1494](https://github.com/ethers-io/ethers.js/issues/1494); [8f3d71d](https://github.com/ethers-io/ethers.js/commit/8f3d71dc5fd0e91407737a4b82c58c31269ed2be))

@ -22,7 +22,7 @@ const Words = fs_1.default.readFileSync("/usr/share/dict/words").toString().spli
}, {});
`
// Words missing from the dictionary
accessing addresses aligned autofill called cancelled changed censored
accessing addresses aligned autofill avatar called cancelled changed censored
clamping compiled computed configured consumed creating decoded decoding
decreased decrypt decrypted decrypting deployed deploying deprecated detected
discontinued earliest email emitted enabled encoded encoder encoding encrypt
@ -58,9 +58,9 @@ ABIEncoder testcase numberish Wordlist
abi addr api app arg arrayify asm backend basex bigint bignumber bn byte
bytecode callback calldata charset checksum ciphertext cli codepoint
commify config
contenthash ctr ctrl debug dd dklen eexist encseed eof eq ethaddr
contenthash ctr ctrl debug dd dklen eexist encseed eof eq erc ethaddr
ethseed ethers eval exec filename func gz gzip hid http https hw iv
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
info init ipc json kdf kdfparams labelhash lang lib metadata mm multihash nfc
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
pragma pre prf recid repl rpc sighash topichash solc stdin stdout subclasses
subnode timeout todo txt typeof ufixed utc utf util url urlencoded uuid vm
@ -79,6 +79,7 @@ ropsten testnet lb maticmum
// Demo words
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
brantly
// nameprep tags
ALCat BiDi LCat nameprep

@ -13,7 +13,7 @@ const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").re
`
// Words missing from the dictionary
accessing addresses aligned autofill called cancelled changed censored
accessing addresses aligned autofill avatar called cancelled changed censored
clamping compiled computed configured consumed creating decoded decoding
decreased decrypt decrypted decrypting deployed deploying deprecated detected
discontinued earliest email emitted enabled encoded encoder encoding encrypt
@ -49,9 +49,9 @@ ABIEncoder testcase numberish Wordlist
abi addr api app arg arrayify asm backend basex bigint bignumber bn byte
bytecode callback calldata charset checksum ciphertext cli codepoint
commify config
contenthash ctr ctrl debug dd dklen eexist encseed eof eq ethaddr
contenthash ctr ctrl debug dd dklen eexist encseed eof eq erc ethaddr
ethseed ethers eval exec filename func gz gzip hid http https hw iv
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
info init ipc json kdf kdfparams labelhash lang lib metadata mm multihash nfc
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
pragma pre prf recid repl rpc sighash topichash solc stdin stdout subclasses
subnode timeout todo txt typeof ufixed utc utf util url urlencoded uuid vm
@ -70,6 +70,7 @@ ropsten testnet lb maticmum
// Demo words
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
brantly
// nameprep tags
ALCat BiDi LCat nameprep

12
package-lock.json generated

@ -1773,9 +1773,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.3.871",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz",
"integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==",
"version": "1.3.872",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.872.tgz",
"integrity": "sha512-qG96atLFY0agKyEETiBFNhpRLSXGSXOBuhXWpbkYqrLKKASpRyRBUtfkn0ZjIf/yXfA7FA4nScVOMpXSHFlUCQ==",
"dev": true
},
"elliptic": {
@ -2637,9 +2637,9 @@
"dev": true
},
"istanbul-lib-coverage": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.1.0.tgz",
"integrity": "sha512-OFSPP1Csv3GxruycNA1iRJPnc5pon+N4Q89EUz8KYOFbdsqCoHRh0J8jwRdna5thveVcMTdgY27kUl/lZuAWdw==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
"integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
"dev": true
},
"istanbul-lib-hook": {

@ -18705,27 +18705,44 @@ function bytes32ify(value) {
function base58Encode(data) {
return Base58.encode(concat([data, hexDataSlice(sha256$1(sha256$1(data)), 0, 4)]));
}
const matchers = [
new RegExp("^(https):/\/(.*)$", "i"),
new RegExp("^(data):(.*)$", "i"),
new RegExp("^(ipfs):/\/(.*)$", "i"),
new RegExp("^eip155:[0-9]+/(erc[0-9]+):(.*)$", "i"),
];
function _parseString(result) {
try {
return toUtf8String(_parseBytes(result));
}
catch (error) { }
return null;
}
function _parseBytes(result) {
if (result === "0x") {
return null;
}
const offset = BigNumber.from(hexDataSlice(result, 0, 32)).toNumber();
const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber();
return hexDataSlice(result, offset + 32, offset + 32 + length);
}
class Resolver {
constructor(provider, address, name) {
// The resolvedAddress is only for creating a ReverseLookup resolver
constructor(provider, address, name, resolvedAddress) {
defineReadOnly(this, "provider", provider);
defineReadOnly(this, "name", name);
defineReadOnly(this, "address", provider.formatter.address(address));
defineReadOnly(this, "_resolvedAddress", resolvedAddress);
}
_fetchBytes(selector, parameters) {
return __awaiter$9(this, void 0, void 0, function* () {
// keccak256("addr(bytes32,uint256)")
const transaction = {
// e.g. keccak256("addr(bytes32,uint256)")
const tx = {
to: this.address,
data: hexConcat([selector, namehash(this.name), (parameters || "0x")])
};
try {
const result = yield this.provider.call(transaction);
if (result === "0x") {
return null;
}
const offset = BigNumber.from(hexDataSlice(result, 0, 32)).toNumber();
const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber();
return hexDataSlice(result, offset + 32, offset + 32 + length);
return _parseBytes(yield this.provider.call(tx));
}
catch (error) {
if (error.code === Logger.errors.CALL_EXCEPTION) {
@ -18832,6 +18849,94 @@ class Resolver {
return address;
});
}
getAvatar() {
return __awaiter$9(this, void 0, void 0, function* () {
const linkage = [];
try {
const avatar = yield this.getText("avatar");
if (avatar == null) {
return null;
}
for (let i = 0; i < matchers.length; i++) {
const match = avatar.match(matchers[i]);
if (match == null) {
continue;
}
switch (match[1]) {
case "https":
linkage.push({ type: "url", content: avatar });
return { linkage, url: avatar };
case "data":
linkage.push({ type: "data", content: avatar });
return { linkage, url: avatar };
case "ipfs":
linkage.push({ type: "ipfs", content: avatar });
return { linkage, url: `https:/\/gateway.ipfs.io/ipfs/${avatar.substring(7)}` };
case "erc721":
case "erc1155": {
// Depending on the ERC type, use tokenURI(uint256) or url(uint256)
const selector = (match[1] === "erc721") ? "0xc87b56dd" : "0x0e89341c";
linkage.push({ type: match[1], content: avatar });
// The owner of this name
const owner = (this._resolvedAddress || (yield this.getAddress()));
const comps = (match[2] || "").split("/");
if (comps.length !== 2) {
return null;
}
const addr = yield this.provider.formatter.address(comps[0]);
const tokenId = hexZeroPad(BigNumber.from(comps[1]).toHexString(), 32);
// Check that this account owns the token
if (match[1] === "erc721") {
// ownerOf(uint256 tokenId)
const tokenOwner = this.provider.formatter.callAddress(yield this.provider.call({
to: addr, data: hexConcat(["0x6352211e", tokenId])
}));
if (owner !== tokenOwner) {
return null;
}
linkage.push({ type: "owner", content: tokenOwner });
}
else if (match[1] === "erc1155") {
// balanceOf(address owner, uint256 tokenId)
const balance = BigNumber.from(yield this.provider.call({
to: addr, data: hexConcat(["0x00fdd58e", hexZeroPad(owner, 32), tokenId])
}));
if (balance.isZero()) {
return null;
}
linkage.push({ type: "balance", content: balance.toString() });
}
// Call the token contract for the metadata URL
const tx = {
to: this.provider.formatter.address(comps[0]),
data: hexConcat([selector, tokenId])
};
let metadataUrl = _parseString(yield this.provider.call(tx));
if (metadataUrl == null) {
return null;
}
linkage.push({ type: "metadata-url", content: metadataUrl });
// ERC-1155 allows a generic {id} in the URL
if (match[1] === "erc1155") {
metadataUrl = metadataUrl.replace("{id}", tokenId.substring(2));
}
// Get the token metadata
const metadata = yield fetchJson(metadataUrl);
// Pull the image URL out
if (!metadata || typeof (metadata.image) !== "string" || !metadata.image.match(/^https:\/\//i)) {
return null;
}
linkage.push({ type: "metadata", content: JSON.stringify(metadata) });
linkage.push({ type: "url", content: metadata.image });
return { linkage, url: metadata.image };
}
}
}
}
catch (error) { }
return null;
});
}
getContentHash() {
return __awaiter$9(this, void 0, void 0, function* () {
// keccak256("contenthash()")
@ -19994,6 +20099,30 @@ class BaseProvider extends Provider {
return name;
});
}
getAvatar(nameOrAddress) {
return __awaiter$9(this, void 0, void 0, function* () {
let resolver = null;
if (isHexString(nameOrAddress)) {
// Address; reverse lookup
const address = this.formatter.address(nameOrAddress);
const reverseName = address.substring(2).toLowerCase() + ".addr.reverse";
const resolverAddress = yield this._getResolver(reverseName);
if (!resolverAddress) {
return null;
}
resolver = new Resolver(this, resolverAddress, "_", address);
}
else {
// ENS name; forward lookup
resolver = yield this.getResolver(nameOrAddress);
}
const avatar = yield resolver.getAvatar();
if (avatar == null) {
return null;
}
return avatar.url;
});
}
perform(method, params) {
return logger$t.throwError(method + " not implemented", Logger.errors.NOT_IMPLEMENTED, { operation: method });
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -20938,36 +20938,53 @@
function base58Encode(data) {
return lib$g.Base58.encode((0, lib$1.concat)([data, (0, lib$1.hexDataSlice)((0, lib$h.sha256)((0, lib$h.sha256)(data)), 0, 4)]));
}
var matchers = [
new RegExp("^(https):/\/(.*)$", "i"),
new RegExp("^(data):(.*)$", "i"),
new RegExp("^(ipfs):/\/(.*)$", "i"),
new RegExp("^eip155:[0-9]+/(erc[0-9]+):(.*)$", "i"),
];
function _parseString(result) {
try {
return (0, lib$8.toUtf8String)(_parseBytes(result));
}
catch (error) { }
return null;
}
function _parseBytes(result) {
if (result === "0x") {
return null;
}
var offset = lib$2.BigNumber.from((0, lib$1.hexDataSlice)(result, 0, 32)).toNumber();
var length = lib$2.BigNumber.from((0, lib$1.hexDataSlice)(result, offset, offset + 32)).toNumber();
return (0, lib$1.hexDataSlice)(result, offset + 32, offset + 32 + length);
}
var Resolver = /** @class */ (function () {
function Resolver(provider, address, name) {
// The resolvedAddress is only for creating a ReverseLookup resolver
function Resolver(provider, address, name, resolvedAddress) {
(0, lib$3.defineReadOnly)(this, "provider", provider);
(0, lib$3.defineReadOnly)(this, "name", name);
(0, lib$3.defineReadOnly)(this, "address", provider.formatter.address(address));
(0, lib$3.defineReadOnly)(this, "_resolvedAddress", resolvedAddress);
}
Resolver.prototype._fetchBytes = function (selector, parameters) {
return __awaiter(this, void 0, void 0, function () {
var transaction, result, offset, length_1, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
var tx, _a, error_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
transaction = {
tx = {
to: this.address,
data: (0, lib$1.hexConcat)([selector, (0, lib$9.namehash)(this.name), (parameters || "0x")])
};
_a.label = 1;
_b.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this.provider.call(transaction)];
case 2:
result = _a.sent();
if (result === "0x") {
return [2 /*return*/, null];
}
offset = lib$2.BigNumber.from((0, lib$1.hexDataSlice)(result, 0, 32)).toNumber();
length_1 = lib$2.BigNumber.from((0, lib$1.hexDataSlice)(result, offset, offset + 32)).toNumber();
return [2 /*return*/, (0, lib$1.hexDataSlice)(result, offset + 32, offset + 32 + length_1)];
_b.trys.push([1, 3, , 4]);
_a = _parseBytes;
return [4 /*yield*/, this.provider.call(tx)];
case 2: return [2 /*return*/, _a.apply(void 0, [_b.sent()])];
case 3:
error_1 = _a.sent();
error_1 = _b.sent();
if (error_1.code === lib.Logger.errors.CALL_EXCEPTION) {
return [2 /*return*/, null];
}
@ -20992,8 +21009,8 @@
if (coinInfo.p2pkh != null) {
var p2pkh = hexBytes.match(/^0x76a9([0-9a-f][0-9a-f])([0-9a-f]*)88ac$/);
if (p2pkh) {
var length_2 = parseInt(p2pkh[1], 16);
if (p2pkh[2].length === length_2 * 2 && length_2 >= 1 && length_2 <= 75) {
var length_1 = parseInt(p2pkh[1], 16);
if (p2pkh[2].length === length_1 * 2 && length_1 >= 1 && length_1 <= 75) {
return base58Encode((0, lib$1.concat)([[coinInfo.p2pkh], ("0x" + p2pkh[2])]));
}
}
@ -21002,26 +21019,26 @@
if (coinInfo.p2sh != null) {
var p2sh = hexBytes.match(/^0xa9([0-9a-f][0-9a-f])([0-9a-f]*)87$/);
if (p2sh) {
var length_3 = parseInt(p2sh[1], 16);
if (p2sh[2].length === length_3 * 2 && length_3 >= 1 && length_3 <= 75) {
var length_2 = parseInt(p2sh[1], 16);
if (p2sh[2].length === length_2 * 2 && length_2 >= 1 && length_2 <= 75) {
return base58Encode((0, lib$1.concat)([[coinInfo.p2sh], ("0x" + p2sh[2])]));
}
}
}
// Bech32
if (coinInfo.prefix != null) {
var length_4 = bytes[1];
var length_3 = bytes[1];
// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
var version_1 = bytes[0];
if (version_1 === 0x00) {
if (length_4 !== 20 && length_4 !== 32) {
if (length_3 !== 20 && length_3 !== 32) {
version_1 = -1;
}
}
else {
version_1 = -1;
}
if (version_1 >= 0 && bytes.length === 2 + length_4 && length_4 >= 1 && length_4 <= 75) {
if (version_1 >= 0 && bytes.length === 2 + length_3 && length_3 >= 1 && length_3 <= 75) {
var words = bech32_1.default.toWords(bytes.slice(2));
words.unshift(version_1);
return bech32_1.default.encode(coinInfo.prefix, words);
@ -21080,9 +21097,134 @@
});
});
};
Resolver.prototype.getAvatar = function () {
return __awaiter(this, void 0, void 0, function () {
var linkage, avatar, i, match, _a, selector, owner, _b, comps, addr, tokenId, tokenOwner, _c, _d, balance, _e, _f, tx, metadataUrl, _g, metadata, error_3;
return __generator(this, function (_h) {
switch (_h.label) {
case 0:
linkage = [];
_h.label = 1;
case 1:
_h.trys.push([1, 19, , 20]);
return [4 /*yield*/, this.getText("avatar")];
case 2:
avatar = _h.sent();
if (avatar == null) {
return [2 /*return*/, null];
}
i = 0;
_h.label = 3;
case 3:
if (!(i < matchers.length)) return [3 /*break*/, 18];
match = avatar.match(matchers[i]);
if (match == null) {
return [3 /*break*/, 17];
}
_a = match[1];
switch (_a) {
case "https": return [3 /*break*/, 4];
case "data": return [3 /*break*/, 5];
case "ipfs": return [3 /*break*/, 6];
case "erc721": return [3 /*break*/, 7];
case "erc1155": return [3 /*break*/, 7];
}
return [3 /*break*/, 17];
case 4:
linkage.push({ type: "url", content: avatar });
return [2 /*return*/, { linkage: linkage, url: avatar }];
case 5:
linkage.push({ type: "data", content: avatar });
return [2 /*return*/, { linkage: linkage, url: avatar }];
case 6:
linkage.push({ type: "ipfs", content: avatar });
return [2 /*return*/, { linkage: linkage, url: "https://gateway.ipfs.io/ipfs/" + avatar.substring(7) }];
case 7:
selector = (match[1] === "erc721") ? "0xc87b56dd" : "0x0e89341c";
linkage.push({ type: match[1], content: avatar });
_b = this._resolvedAddress;
if (_b) return [3 /*break*/, 9];
return [4 /*yield*/, this.getAddress()];
case 8:
_b = (_h.sent());
_h.label = 9;
case 9:
owner = (_b);
comps = (match[2] || "").split("/");
if (comps.length !== 2) {
return [2 /*return*/, null];
}
return [4 /*yield*/, this.provider.formatter.address(comps[0])];
case 10:
addr = _h.sent();
tokenId = (0, lib$1.hexZeroPad)(lib$2.BigNumber.from(comps[1]).toHexString(), 32);
if (!(match[1] === "erc721")) return [3 /*break*/, 12];
_d = (_c = this.provider.formatter).callAddress;
return [4 /*yield*/, this.provider.call({
to: addr, data: (0, lib$1.hexConcat)(["0x6352211e", tokenId])
})];
case 11:
tokenOwner = _d.apply(_c, [_h.sent()]);
if (owner !== tokenOwner) {
return [2 /*return*/, null];
}
linkage.push({ type: "owner", content: tokenOwner });
return [3 /*break*/, 14];
case 12:
if (!(match[1] === "erc1155")) return [3 /*break*/, 14];
_f = (_e = lib$2.BigNumber).from;
return [4 /*yield*/, this.provider.call({
to: addr, data: (0, lib$1.hexConcat)(["0x00fdd58e", (0, lib$1.hexZeroPad)(owner, 32), tokenId])
})];
case 13:
balance = _f.apply(_e, [_h.sent()]);
if (balance.isZero()) {
return [2 /*return*/, null];
}
linkage.push({ type: "balance", content: balance.toString() });
_h.label = 14;
case 14:
tx = {
to: this.provider.formatter.address(comps[0]),
data: (0, lib$1.hexConcat)([selector, tokenId])
};
_g = _parseString;
return [4 /*yield*/, this.provider.call(tx)];
case 15:
metadataUrl = _g.apply(void 0, [_h.sent()]);
if (metadataUrl == null) {
return [2 /*return*/, null];
}
linkage.push({ type: "metadata-url", content: metadataUrl });
// ERC-1155 allows a generic {id} in the URL
if (match[1] === "erc1155") {
metadataUrl = metadataUrl.replace("{id}", tokenId.substring(2));
}
return [4 /*yield*/, (0, lib$q.fetchJson)(metadataUrl)];
case 16:
metadata = _h.sent();
// Pull the image URL out
if (!metadata || typeof (metadata.image) !== "string" || !metadata.image.match(/^https:\/\//i)) {
return [2 /*return*/, null];
}
linkage.push({ type: "metadata", content: JSON.stringify(metadata) });
linkage.push({ type: "url", content: metadata.image });
return [2 /*return*/, { linkage: linkage, url: metadata.image }];
case 17:
i++;
return [3 /*break*/, 3];
case 18: return [3 /*break*/, 20];
case 19:
error_3 = _h.sent();
return [3 /*break*/, 20];
case 20: return [2 /*return*/, null];
}
});
});
};
Resolver.prototype.getContentHash = function () {
return __awaiter(this, void 0, void 0, function () {
var hexBytes, ipfs, length_5, swarm;
var hexBytes, ipfs, length_4, swarm;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._fetchBytes("0xbc1c58d1")];
@ -21094,8 +21236,8 @@
}
ipfs = hexBytes.match(/^0xe3010170(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
if (ipfs) {
length_5 = parseInt(ipfs[3], 16);
if (ipfs[4].length === length_5 * 2) {
length_4 = parseInt(ipfs[3], 16);
if (ipfs[4].length === length_4 * 2) {
return [2 /*return*/, "ipfs:/\/" + lib$g.Base58.encode("0x" + ipfs[1])];
}
}
@ -21195,7 +21337,7 @@
}
BaseProvider.prototype._ready = function () {
return __awaiter(this, void 0, void 0, function () {
var network, error_3;
var network, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -21210,7 +21352,7 @@
network = _a.sent();
return [3 /*break*/, 4];
case 3:
error_3 = _a.sent();
error_4 = _a.sent();
return [3 /*break*/, 4];
case 4:
if (!(network == null)) return [3 /*break*/, 6];
@ -21276,7 +21418,7 @@
// than maxAge old or has been requested since the last request
BaseProvider.prototype._getInternalBlockNumber = function (maxAge) {
return __awaiter(this, void 0, void 0, function () {
var internalBlockNumber, result, error_4, reqTime, checkInternalBlockNumber;
var internalBlockNumber, result, error_5, reqTime, checkInternalBlockNumber;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
@ -21300,7 +21442,7 @@
// Too old; fetch a new value
return [3 /*break*/, 7];
case 5:
error_4 = _a.sent();
error_5 = _a.sent();
// The fetch rejected; if we are the first to get the
// rejection, drop through so we replace it with a new
// fetch; all others blocked will then get that fetch
@ -21349,7 +21491,7 @@
};
BaseProvider.prototype.poll = function () {
return __awaiter(this, void 0, void 0, function () {
var pollId, runners, blockNumber, error_5, i;
var pollId, runners, blockNumber, error_6, i;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
@ -21365,8 +21507,8 @@
blockNumber = _a.sent();
return [3 /*break*/, 4];
case 3:
error_5 = _a.sent();
this.emit("error", error_5);
error_6 = _a.sent();
this.emit("error", error_6);
return [2 /*return*/];
case 4:
this._setFastBlockNumber(blockNumber);
@ -22032,7 +22174,7 @@
};
BaseProvider.prototype.sendTransaction = function (signedTransaction) {
return __awaiter(this, void 0, void 0, function () {
var hexTx, tx, blockNumber, hash, error_6;
var hexTx, tx, blockNumber, hash, error_7;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getNetwork()];
@ -22056,10 +22198,10 @@
hash = _a.sent();
return [2 /*return*/, this._wrapTransaction(tx, hash, blockNumber)];
case 6:
error_6 = _a.sent();
error_6.transaction = tx;
error_6.transactionHash = tx.hash;
throw error_6;
error_7 = _a.sent();
error_7.transaction = tx;
error_7.transactionHash = tx.hash;
throw error_7;
case 7: return [2 /*return*/];
}
});
@ -22232,7 +22374,7 @@
};
BaseProvider.prototype._getBlock = function (blockHashOrBlockTag, includeTransactions) {
return __awaiter(this, void 0, void 0, function () {
var blockNumber, params, _a, error_7;
var blockNumber, params, _a, error_8;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
@ -22260,7 +22402,7 @@
}
return [3 /*break*/, 6];
case 5:
error_7 = _b.sent();
error_8 = _b.sent();
logger.throwArgumentError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
return [3 /*break*/, 6];
case 6: return [2 /*return*/, (0, lib$q.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
@ -22500,7 +22642,7 @@
};
BaseProvider.prototype.getResolver = function (name) {
return __awaiter(this, void 0, void 0, function () {
var address, error_8;
var address, error_9;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -22513,8 +22655,8 @@
}
return [2 /*return*/, new Resolver(this, address, name)];
case 2:
error_8 = _a.sent();
if (error_8.code === lib.Logger.errors.CALL_EXCEPTION) {
error_9 = _a.sent();
if (error_9.code === lib.Logger.errors.CALL_EXCEPTION) {
return [2 /*return*/, null];
}
return [2 /*return*/, null];
@ -22525,7 +22667,7 @@
};
BaseProvider.prototype._getResolver = function (name) {
return __awaiter(this, void 0, void 0, function () {
var network, transaction, _a, _b, error_9;
var network, transaction, _a, _b, error_10;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, this.getNetwork()];
@ -22546,11 +22688,11 @@
return [4 /*yield*/, this.call(transaction)];
case 3: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
case 4:
error_9 = _c.sent();
if (error_9.code === lib.Logger.errors.CALL_EXCEPTION) {
error_10 = _c.sent();
if (error_10.code === lib.Logger.errors.CALL_EXCEPTION) {
return [2 /*return*/, null];
}
throw error_9;
throw error_10;
case 5: return [2 /*return*/];
}
});
@ -22639,6 +22781,40 @@
});
});
};
BaseProvider.prototype.getAvatar = function (nameOrAddress) {
return __awaiter(this, void 0, void 0, function () {
var resolver, address, reverseName, resolverAddress, avatar;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
resolver = null;
if (!(0, lib$1.isHexString)(nameOrAddress)) return [3 /*break*/, 2];
address = this.formatter.address(nameOrAddress);
reverseName = address.substring(2).toLowerCase() + ".addr.reverse";
return [4 /*yield*/, this._getResolver(reverseName)];
case 1:
resolverAddress = _a.sent();
if (!resolverAddress) {
return [2 /*return*/, null];
}
resolver = new Resolver(this, resolverAddress, "_", address);
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.getResolver(nameOrAddress)];
case 3:
// ENS name; forward lookup
resolver = _a.sent();
_a.label = 4;
case 4: return [4 /*yield*/, resolver.getAvatar()];
case 5:
avatar = _a.sent();
if (avatar == null) {
return [2 /*return*/, null];
}
return [2 /*return*/, avatar.url];
}
});
});
};
BaseProvider.prototype.perform = function (method, params) {
return logger.throwError(method + " not implemented", lib.Logger.errors.NOT_IMPLEMENTED, { operation: method });
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -62,7 +62,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"sideEffects": false,
"tarballHash": "0xeff2edda162cc8c614be4033bbfb44a66180be60cca1ef05615b4491da8cea55",
"tarballHash": "0xc76a974e38ab47fcb6e1b8341db9a6827710b073c30a4d5066b34dbb655be7d7",
"types": "./lib/index.d.ts",
"version": "5.5.0"
}

@ -28,14 +28,23 @@ export interface EnsProvider {
lookupAddress(address: string): Promise<null | string>;
getResolver(name: string): Promise<null | EnsResolver>;
}
export interface Avatar {
url: string;
linkage: Array<{
type: string;
content: string;
}>;
}
export declare class Resolver implements EnsResolver {
readonly provider: BaseProvider;
readonly name: string;
readonly address: string;
constructor(provider: BaseProvider, address: string, name: string);
_fetchBytes(selector: string, parameters?: string): Promise<string>;
readonly _resolvedAddress: null | string;
constructor(provider: BaseProvider, address: string, name: string, resolvedAddress?: string);
_fetchBytes(selector: string, parameters?: string): Promise<null | string>;
_getAddress(coinType: number, hexBytes: string): string;
getAddress(coinType?: number): Promise<string>;
getAvatar(): Promise<null | Avatar>;
getContentHash(): Promise<string>;
getText(key: string): Promise<string>;
}
@ -122,6 +131,7 @@ export declare class BaseProvider extends Provider implements EnsProvider {
_getResolver(name: string): Promise<string>;
resolveName(name: string | Promise<string>): Promise<null | string>;
lookupAddress(address: string | Promise<string>): Promise<null | string>;
getAvatar(nameOrAddress: string): Promise<null | string>;
perform(method: string, params: any): Promise<any>;
_startEvent(event: Event): void;
_stopEvent(event: Event): void;

File diff suppressed because one or more lines are too long

@ -18,7 +18,7 @@ import { getNetwork } from "@ethersproject/networks";
import { defineReadOnly, getStatic, resolveProperties } from "@ethersproject/properties";
import { sha256 } from "@ethersproject/sha2";
import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
import { poll } from "@ethersproject/web";
import { fetchJson, poll } from "@ethersproject/web";
import bech32 from "bech32";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
@ -181,27 +181,44 @@ function bytes32ify(value) {
function base58Encode(data) {
return Base58.encode(concat([data, hexDataSlice(sha256(sha256(data)), 0, 4)]));
}
const matchers = [
new RegExp("^(https):/\/(.*)$", "i"),
new RegExp("^(data):(.*)$", "i"),
new RegExp("^(ipfs):/\/(.*)$", "i"),
new RegExp("^eip155:[0-9]+/(erc[0-9]+):(.*)$", "i"),
];
function _parseString(result) {
try {
return toUtf8String(_parseBytes(result));
}
catch (error) { }
return null;
}
function _parseBytes(result) {
if (result === "0x") {
return null;
}
const offset = BigNumber.from(hexDataSlice(result, 0, 32)).toNumber();
const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber();
return hexDataSlice(result, offset + 32, offset + 32 + length);
}
export class Resolver {
constructor(provider, address, name) {
// The resolvedAddress is only for creating a ReverseLookup resolver
constructor(provider, address, name, resolvedAddress) {
defineReadOnly(this, "provider", provider);
defineReadOnly(this, "name", name);
defineReadOnly(this, "address", provider.formatter.address(address));
defineReadOnly(this, "_resolvedAddress", resolvedAddress);
}
_fetchBytes(selector, parameters) {
return __awaiter(this, void 0, void 0, function* () {
// keccak256("addr(bytes32,uint256)")
const transaction = {
// e.g. keccak256("addr(bytes32,uint256)")
const tx = {
to: this.address,
data: hexConcat([selector, namehash(this.name), (parameters || "0x")])
};
try {
const result = yield this.provider.call(transaction);
if (result === "0x") {
return null;
}
const offset = BigNumber.from(hexDataSlice(result, 0, 32)).toNumber();
const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber();
return hexDataSlice(result, offset + 32, offset + 32 + length);
return _parseBytes(yield this.provider.call(tx));
}
catch (error) {
if (error.code === Logger.errors.CALL_EXCEPTION) {
@ -308,6 +325,94 @@ export class Resolver {
return address;
});
}
getAvatar() {
return __awaiter(this, void 0, void 0, function* () {
const linkage = [];
try {
const avatar = yield this.getText("avatar");
if (avatar == null) {
return null;
}
for (let i = 0; i < matchers.length; i++) {
const match = avatar.match(matchers[i]);
if (match == null) {
continue;
}
switch (match[1]) {
case "https":
linkage.push({ type: "url", content: avatar });
return { linkage, url: avatar };
case "data":
linkage.push({ type: "data", content: avatar });
return { linkage, url: avatar };
case "ipfs":
linkage.push({ type: "ipfs", content: avatar });
return { linkage, url: `https:/\/gateway.ipfs.io/ipfs/${avatar.substring(7)}` };
case "erc721":
case "erc1155": {
// Depending on the ERC type, use tokenURI(uint256) or url(uint256)
const selector = (match[1] === "erc721") ? "0xc87b56dd" : "0x0e89341c";
linkage.push({ type: match[1], content: avatar });
// The owner of this name
const owner = (this._resolvedAddress || (yield this.getAddress()));
const comps = (match[2] || "").split("/");
if (comps.length !== 2) {
return null;
}
const addr = yield this.provider.formatter.address(comps[0]);
const tokenId = hexZeroPad(BigNumber.from(comps[1]).toHexString(), 32);
// Check that this account owns the token
if (match[1] === "erc721") {
// ownerOf(uint256 tokenId)
const tokenOwner = this.provider.formatter.callAddress(yield this.provider.call({
to: addr, data: hexConcat(["0x6352211e", tokenId])
}));
if (owner !== tokenOwner) {
return null;
}
linkage.push({ type: "owner", content: tokenOwner });
}
else if (match[1] === "erc1155") {
// balanceOf(address owner, uint256 tokenId)
const balance = BigNumber.from(yield this.provider.call({
to: addr, data: hexConcat(["0x00fdd58e", hexZeroPad(owner, 32), tokenId])
}));
if (balance.isZero()) {
return null;
}
linkage.push({ type: "balance", content: balance.toString() });
}
// Call the token contract for the metadata URL
const tx = {
to: this.provider.formatter.address(comps[0]),
data: hexConcat([selector, tokenId])
};
let metadataUrl = _parseString(yield this.provider.call(tx));
if (metadataUrl == null) {
return null;
}
linkage.push({ type: "metadata-url", content: metadataUrl });
// ERC-1155 allows a generic {id} in the URL
if (match[1] === "erc1155") {
metadataUrl = metadataUrl.replace("{id}", tokenId.substring(2));
}
// Get the token metadata
const metadata = yield fetchJson(metadataUrl);
// Pull the image URL out
if (!metadata || typeof (metadata.image) !== "string" || !metadata.image.match(/^https:\/\//i)) {
return null;
}
linkage.push({ type: "metadata", content: JSON.stringify(metadata) });
linkage.push({ type: "url", content: metadata.image });
return { linkage, url: metadata.image };
}
}
}
}
catch (error) { }
return null;
});
}
getContentHash() {
return __awaiter(this, void 0, void 0, function* () {
// keccak256("contenthash()")
@ -1470,6 +1575,30 @@ export class BaseProvider extends Provider {
return name;
});
}
getAvatar(nameOrAddress) {
return __awaiter(this, void 0, void 0, function* () {
let resolver = null;
if (isHexString(nameOrAddress)) {
// Address; reverse lookup
const address = this.formatter.address(nameOrAddress);
const reverseName = address.substring(2).toLowerCase() + ".addr.reverse";
const resolverAddress = yield this._getResolver(reverseName);
if (!resolverAddress) {
return null;
}
resolver = new Resolver(this, resolverAddress, "_", address);
}
else {
// ENS name; forward lookup
resolver = yield this.getResolver(nameOrAddress);
}
const avatar = yield resolver.getAvatar();
if (avatar == null) {
return null;
}
return avatar.url;
});
}
perform(method, params) {
return logger.throwError(method + " not implemented", Logger.errors.NOT_IMPLEMENTED, { operation: method });
}

File diff suppressed because one or more lines are too long

@ -28,14 +28,23 @@ export interface EnsProvider {
lookupAddress(address: string): Promise<null | string>;
getResolver(name: string): Promise<null | EnsResolver>;
}
export interface Avatar {
url: string;
linkage: Array<{
type: string;
content: string;
}>;
}
export declare class Resolver implements EnsResolver {
readonly provider: BaseProvider;
readonly name: string;
readonly address: string;
constructor(provider: BaseProvider, address: string, name: string);
_fetchBytes(selector: string, parameters?: string): Promise<string>;
readonly _resolvedAddress: null | string;
constructor(provider: BaseProvider, address: string, name: string, resolvedAddress?: string);
_fetchBytes(selector: string, parameters?: string): Promise<null | string>;
_getAddress(coinType: number, hexBytes: string): string;
getAddress(coinType?: number): Promise<string>;
getAvatar(): Promise<null | Avatar>;
getContentHash(): Promise<string>;
getText(key: string): Promise<string>;
}
@ -122,6 +131,7 @@ export declare class BaseProvider extends Provider implements EnsProvider {
_getResolver(name: string): Promise<string>;
resolveName(name: string | Promise<string>): Promise<null | string>;
lookupAddress(address: string | Promise<string>): Promise<null | string>;
getAvatar(nameOrAddress: string): Promise<null | string>;
perform(method: string, params: any): Promise<any>;
_startEvent(event: Event): void;
_stopEvent(event: Event): void;

File diff suppressed because one or more lines are too long

@ -246,36 +246,53 @@ function bytes32ify(value) {
function base58Encode(data) {
return basex_1.Base58.encode((0, bytes_1.concat)([data, (0, bytes_1.hexDataSlice)((0, sha2_1.sha256)((0, sha2_1.sha256)(data)), 0, 4)]));
}
var matchers = [
new RegExp("^(https):/\/(.*)$", "i"),
new RegExp("^(data):(.*)$", "i"),
new RegExp("^(ipfs):/\/(.*)$", "i"),
new RegExp("^eip155:[0-9]+/(erc[0-9]+):(.*)$", "i"),
];
function _parseString(result) {
try {
return (0, strings_1.toUtf8String)(_parseBytes(result));
}
catch (error) { }
return null;
}
function _parseBytes(result) {
if (result === "0x") {
return null;
}
var offset = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, 0, 32)).toNumber();
var length = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, offset, offset + 32)).toNumber();
return (0, bytes_1.hexDataSlice)(result, offset + 32, offset + 32 + length);
}
var Resolver = /** @class */ (function () {
function Resolver(provider, address, name) {
// The resolvedAddress is only for creating a ReverseLookup resolver
function Resolver(provider, address, name, resolvedAddress) {
(0, properties_1.defineReadOnly)(this, "provider", provider);
(0, properties_1.defineReadOnly)(this, "name", name);
(0, properties_1.defineReadOnly)(this, "address", provider.formatter.address(address));
(0, properties_1.defineReadOnly)(this, "_resolvedAddress", resolvedAddress);
}
Resolver.prototype._fetchBytes = function (selector, parameters) {
return __awaiter(this, void 0, void 0, function () {
var transaction, result, offset, length_1, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
var tx, _a, error_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
transaction = {
tx = {
to: this.address,
data: (0, bytes_1.hexConcat)([selector, (0, hash_1.namehash)(this.name), (parameters || "0x")])
};
_a.label = 1;
_b.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this.provider.call(transaction)];
case 2:
result = _a.sent();
if (result === "0x") {
return [2 /*return*/, null];
}
offset = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, 0, 32)).toNumber();
length_1 = bignumber_1.BigNumber.from((0, bytes_1.hexDataSlice)(result, offset, offset + 32)).toNumber();
return [2 /*return*/, (0, bytes_1.hexDataSlice)(result, offset + 32, offset + 32 + length_1)];
_b.trys.push([1, 3, , 4]);
_a = _parseBytes;
return [4 /*yield*/, this.provider.call(tx)];
case 2: return [2 /*return*/, _a.apply(void 0, [_b.sent()])];
case 3:
error_1 = _a.sent();
error_1 = _b.sent();
if (error_1.code === logger_1.Logger.errors.CALL_EXCEPTION) {
return [2 /*return*/, null];
}
@ -300,8 +317,8 @@ var Resolver = /** @class */ (function () {
if (coinInfo.p2pkh != null) {
var p2pkh = hexBytes.match(/^0x76a9([0-9a-f][0-9a-f])([0-9a-f]*)88ac$/);
if (p2pkh) {
var length_2 = parseInt(p2pkh[1], 16);
if (p2pkh[2].length === length_2 * 2 && length_2 >= 1 && length_2 <= 75) {
var length_1 = parseInt(p2pkh[1], 16);
if (p2pkh[2].length === length_1 * 2 && length_1 >= 1 && length_1 <= 75) {
return base58Encode((0, bytes_1.concat)([[coinInfo.p2pkh], ("0x" + p2pkh[2])]));
}
}
@ -310,26 +327,26 @@ var Resolver = /** @class */ (function () {
if (coinInfo.p2sh != null) {
var p2sh = hexBytes.match(/^0xa9([0-9a-f][0-9a-f])([0-9a-f]*)87$/);
if (p2sh) {
var length_3 = parseInt(p2sh[1], 16);
if (p2sh[2].length === length_3 * 2 && length_3 >= 1 && length_3 <= 75) {
var length_2 = parseInt(p2sh[1], 16);
if (p2sh[2].length === length_2 * 2 && length_2 >= 1 && length_2 <= 75) {
return base58Encode((0, bytes_1.concat)([[coinInfo.p2sh], ("0x" + p2sh[2])]));
}
}
}
// Bech32
if (coinInfo.prefix != null) {
var length_4 = bytes[1];
var length_3 = bytes[1];
// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
var version_1 = bytes[0];
if (version_1 === 0x00) {
if (length_4 !== 20 && length_4 !== 32) {
if (length_3 !== 20 && length_3 !== 32) {
version_1 = -1;
}
}
else {
version_1 = -1;
}
if (version_1 >= 0 && bytes.length === 2 + length_4 && length_4 >= 1 && length_4 <= 75) {
if (version_1 >= 0 && bytes.length === 2 + length_3 && length_3 >= 1 && length_3 <= 75) {
var words = bech32_1.default.toWords(bytes.slice(2));
words.unshift(version_1);
return bech32_1.default.encode(coinInfo.prefix, words);
@ -388,9 +405,134 @@ var Resolver = /** @class */ (function () {
});
});
};
Resolver.prototype.getAvatar = function () {
return __awaiter(this, void 0, void 0, function () {
var linkage, avatar, i, match, _a, selector, owner, _b, comps, addr, tokenId, tokenOwner, _c, _d, balance, _e, _f, tx, metadataUrl, _g, metadata, error_3;
return __generator(this, function (_h) {
switch (_h.label) {
case 0:
linkage = [];
_h.label = 1;
case 1:
_h.trys.push([1, 19, , 20]);
return [4 /*yield*/, this.getText("avatar")];
case 2:
avatar = _h.sent();
if (avatar == null) {
return [2 /*return*/, null];
}
i = 0;
_h.label = 3;
case 3:
if (!(i < matchers.length)) return [3 /*break*/, 18];
match = avatar.match(matchers[i]);
if (match == null) {
return [3 /*break*/, 17];
}
_a = match[1];
switch (_a) {
case "https": return [3 /*break*/, 4];
case "data": return [3 /*break*/, 5];
case "ipfs": return [3 /*break*/, 6];
case "erc721": return [3 /*break*/, 7];
case "erc1155": return [3 /*break*/, 7];
}
return [3 /*break*/, 17];
case 4:
linkage.push({ type: "url", content: avatar });
return [2 /*return*/, { linkage: linkage, url: avatar }];
case 5:
linkage.push({ type: "data", content: avatar });
return [2 /*return*/, { linkage: linkage, url: avatar }];
case 6:
linkage.push({ type: "ipfs", content: avatar });
return [2 /*return*/, { linkage: linkage, url: "https://gateway.ipfs.io/ipfs/" + avatar.substring(7) }];
case 7:
selector = (match[1] === "erc721") ? "0xc87b56dd" : "0x0e89341c";
linkage.push({ type: match[1], content: avatar });
_b = this._resolvedAddress;
if (_b) return [3 /*break*/, 9];
return [4 /*yield*/, this.getAddress()];
case 8:
_b = (_h.sent());
_h.label = 9;
case 9:
owner = (_b);
comps = (match[2] || "").split("/");
if (comps.length !== 2) {
return [2 /*return*/, null];
}
return [4 /*yield*/, this.provider.formatter.address(comps[0])];
case 10:
addr = _h.sent();
tokenId = (0, bytes_1.hexZeroPad)(bignumber_1.BigNumber.from(comps[1]).toHexString(), 32);
if (!(match[1] === "erc721")) return [3 /*break*/, 12];
_d = (_c = this.provider.formatter).callAddress;
return [4 /*yield*/, this.provider.call({
to: addr, data: (0, bytes_1.hexConcat)(["0x6352211e", tokenId])
})];
case 11:
tokenOwner = _d.apply(_c, [_h.sent()]);
if (owner !== tokenOwner) {
return [2 /*return*/, null];
}
linkage.push({ type: "owner", content: tokenOwner });
return [3 /*break*/, 14];
case 12:
if (!(match[1] === "erc1155")) return [3 /*break*/, 14];
_f = (_e = bignumber_1.BigNumber).from;
return [4 /*yield*/, this.provider.call({
to: addr, data: (0, bytes_1.hexConcat)(["0x00fdd58e", (0, bytes_1.hexZeroPad)(owner, 32), tokenId])
})];
case 13:
balance = _f.apply(_e, [_h.sent()]);
if (balance.isZero()) {
return [2 /*return*/, null];
}
linkage.push({ type: "balance", content: balance.toString() });
_h.label = 14;
case 14:
tx = {
to: this.provider.formatter.address(comps[0]),
data: (0, bytes_1.hexConcat)([selector, tokenId])
};
_g = _parseString;
return [4 /*yield*/, this.provider.call(tx)];
case 15:
metadataUrl = _g.apply(void 0, [_h.sent()]);
if (metadataUrl == null) {
return [2 /*return*/, null];
}
linkage.push({ type: "metadata-url", content: metadataUrl });
// ERC-1155 allows a generic {id} in the URL
if (match[1] === "erc1155") {
metadataUrl = metadataUrl.replace("{id}", tokenId.substring(2));
}
return [4 /*yield*/, (0, web_1.fetchJson)(metadataUrl)];
case 16:
metadata = _h.sent();
// Pull the image URL out
if (!metadata || typeof (metadata.image) !== "string" || !metadata.image.match(/^https:\/\//i)) {
return [2 /*return*/, null];
}
linkage.push({ type: "metadata", content: JSON.stringify(metadata) });
linkage.push({ type: "url", content: metadata.image });
return [2 /*return*/, { linkage: linkage, url: metadata.image }];
case 17:
i++;
return [3 /*break*/, 3];
case 18: return [3 /*break*/, 20];
case 19:
error_3 = _h.sent();
return [3 /*break*/, 20];
case 20: return [2 /*return*/, null];
}
});
});
};
Resolver.prototype.getContentHash = function () {
return __awaiter(this, void 0, void 0, function () {
var hexBytes, ipfs, length_5, swarm;
var hexBytes, ipfs, length_4, swarm;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._fetchBytes("0xbc1c58d1")];
@ -402,8 +544,8 @@ var Resolver = /** @class */ (function () {
}
ipfs = hexBytes.match(/^0xe3010170(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
if (ipfs) {
length_5 = parseInt(ipfs[3], 16);
if (ipfs[4].length === length_5 * 2) {
length_4 = parseInt(ipfs[3], 16);
if (ipfs[4].length === length_4 * 2) {
return [2 /*return*/, "ipfs:/\/" + basex_1.Base58.encode("0x" + ipfs[1])];
}
}
@ -503,7 +645,7 @@ var BaseProvider = /** @class */ (function (_super) {
}
BaseProvider.prototype._ready = function () {
return __awaiter(this, void 0, void 0, function () {
var network, error_3;
var network, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -518,7 +660,7 @@ var BaseProvider = /** @class */ (function (_super) {
network = _a.sent();
return [3 /*break*/, 4];
case 3:
error_3 = _a.sent();
error_4 = _a.sent();
return [3 /*break*/, 4];
case 4:
if (!(network == null)) return [3 /*break*/, 6];
@ -584,7 +726,7 @@ var BaseProvider = /** @class */ (function (_super) {
// than maxAge old or has been requested since the last request
BaseProvider.prototype._getInternalBlockNumber = function (maxAge) {
return __awaiter(this, void 0, void 0, function () {
var internalBlockNumber, result, error_4, reqTime, checkInternalBlockNumber;
var internalBlockNumber, result, error_5, reqTime, checkInternalBlockNumber;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
@ -608,7 +750,7 @@ var BaseProvider = /** @class */ (function (_super) {
// Too old; fetch a new value
return [3 /*break*/, 7];
case 5:
error_4 = _a.sent();
error_5 = _a.sent();
// The fetch rejected; if we are the first to get the
// rejection, drop through so we replace it with a new
// fetch; all others blocked will then get that fetch
@ -657,7 +799,7 @@ var BaseProvider = /** @class */ (function (_super) {
};
BaseProvider.prototype.poll = function () {
return __awaiter(this, void 0, void 0, function () {
var pollId, runners, blockNumber, error_5, i;
var pollId, runners, blockNumber, error_6, i;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
@ -673,8 +815,8 @@ var BaseProvider = /** @class */ (function (_super) {
blockNumber = _a.sent();
return [3 /*break*/, 4];
case 3:
error_5 = _a.sent();
this.emit("error", error_5);
error_6 = _a.sent();
this.emit("error", error_6);
return [2 /*return*/];
case 4:
this._setFastBlockNumber(blockNumber);
@ -1340,7 +1482,7 @@ var BaseProvider = /** @class */ (function (_super) {
};
BaseProvider.prototype.sendTransaction = function (signedTransaction) {
return __awaiter(this, void 0, void 0, function () {
var hexTx, tx, blockNumber, hash, error_6;
var hexTx, tx, blockNumber, hash, error_7;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getNetwork()];
@ -1364,10 +1506,10 @@ var BaseProvider = /** @class */ (function (_super) {
hash = _a.sent();
return [2 /*return*/, this._wrapTransaction(tx, hash, blockNumber)];
case 6:
error_6 = _a.sent();
error_6.transaction = tx;
error_6.transactionHash = tx.hash;
throw error_6;
error_7 = _a.sent();
error_7.transaction = tx;
error_7.transactionHash = tx.hash;
throw error_7;
case 7: return [2 /*return*/];
}
});
@ -1540,7 +1682,7 @@ var BaseProvider = /** @class */ (function (_super) {
};
BaseProvider.prototype._getBlock = function (blockHashOrBlockTag, includeTransactions) {
return __awaiter(this, void 0, void 0, function () {
var blockNumber, params, _a, error_7;
var blockNumber, params, _a, error_8;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
@ -1568,7 +1710,7 @@ var BaseProvider = /** @class */ (function (_super) {
}
return [3 /*break*/, 6];
case 5:
error_7 = _b.sent();
error_8 = _b.sent();
logger.throwArgumentError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
return [3 /*break*/, 6];
case 6: return [2 /*return*/, (0, web_1.poll)(function () { return __awaiter(_this, void 0, void 0, function () {
@ -1808,7 +1950,7 @@ var BaseProvider = /** @class */ (function (_super) {
};
BaseProvider.prototype.getResolver = function (name) {
return __awaiter(this, void 0, void 0, function () {
var address, error_8;
var address, error_9;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -1821,8 +1963,8 @@ var BaseProvider = /** @class */ (function (_super) {
}
return [2 /*return*/, new Resolver(this, address, name)];
case 2:
error_8 = _a.sent();
if (error_8.code === logger_1.Logger.errors.CALL_EXCEPTION) {
error_9 = _a.sent();
if (error_9.code === logger_1.Logger.errors.CALL_EXCEPTION) {
return [2 /*return*/, null];
}
return [2 /*return*/, null];
@ -1833,7 +1975,7 @@ var BaseProvider = /** @class */ (function (_super) {
};
BaseProvider.prototype._getResolver = function (name) {
return __awaiter(this, void 0, void 0, function () {
var network, transaction, _a, _b, error_9;
var network, transaction, _a, _b, error_10;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, this.getNetwork()];
@ -1854,11 +1996,11 @@ var BaseProvider = /** @class */ (function (_super) {
return [4 /*yield*/, this.call(transaction)];
case 3: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
case 4:
error_9 = _c.sent();
if (error_9.code === logger_1.Logger.errors.CALL_EXCEPTION) {
error_10 = _c.sent();
if (error_10.code === logger_1.Logger.errors.CALL_EXCEPTION) {
return [2 /*return*/, null];
}
throw error_9;
throw error_10;
case 5: return [2 /*return*/];
}
});
@ -1947,6 +2089,40 @@ var BaseProvider = /** @class */ (function (_super) {
});
});
};
BaseProvider.prototype.getAvatar = function (nameOrAddress) {
return __awaiter(this, void 0, void 0, function () {
var resolver, address, reverseName, resolverAddress, avatar;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
resolver = null;
if (!(0, bytes_1.isHexString)(nameOrAddress)) return [3 /*break*/, 2];
address = this.formatter.address(nameOrAddress);
reverseName = address.substring(2).toLowerCase() + ".addr.reverse";
return [4 /*yield*/, this._getResolver(reverseName)];
case 1:
resolverAddress = _a.sent();
if (!resolverAddress) {
return [2 /*return*/, null];
}
resolver = new Resolver(this, resolverAddress, "_", address);
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.getResolver(nameOrAddress)];
case 3:
// ENS name; forward lookup
resolver = _a.sent();
_a.label = 4;
case 4: return [4 /*yield*/, resolver.getAvatar()];
case 5:
avatar = _a.sent();
if (avatar == null) {
return [2 /*return*/, null];
}
return [2 /*return*/, avatar.url];
}
});
});
};
BaseProvider.prototype.perform = function (method, params) {
return logger.throwError(method + " not implemented", logger_1.Logger.errors.NOT_IMPLEMENTED, { operation: method });
};

File diff suppressed because one or more lines are too long

@ -66,7 +66,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"sideEffects": false,
"tarballHash": "0x6eb17a79ea2bef48e97650022ace2089035811b7620d80efc121c26df3121b99",
"tarballHash": "0x2582ad9a43f5113ef9143cf4f5b35cc5fe0cc709861834d5f5236ab06b2f4476",
"types": "./lib/index.d.ts",
"version": "5.5.0"
}

@ -1237,4 +1237,33 @@ describe("Bad ENS resolution", function () {
});
});
});
describe("Resolve ENS avatar", function () {
[
{ title: "data", name: "data-avatar.tests.eth", value: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAMAAACeL25MAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyVpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NUQ4NTEyNUIyOEIwMTFFQzg0NTBDNTU2RDk1NTA5NzgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NUQ4NTEyNUMyOEIwMTFFQzg0NTBDNTU2RDk1NTA5NzgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1RDg1MTI1OTI4QjAxMUVDODQ1MEM1NTZEOTU1MDk3OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1RDg1MTI1QTI4QjAxMUVDODQ1MEM1NTZEOTU1MDk3OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkbM0uMAAAAGUExURQAA/wAAAHtivz4AAAAOSURBVHjaYmDABAABBgAAFAABaEkyYwAAAABJRU5ErkJggg==" },
{ title: "ipfs", name: "ipfs-avatar.tests.eth", value: "https:/\/gateway.ipfs.io/ipfs/QmQsQgpda6JAYkFoeVcj5iPbwV3xRcvaiXv3bhp1VuYUqw" },
{ title: "url", name: "url-avatar.tests.eth", value: "https:/\/ethers.org/static/logo.png" },
].forEach((test) => {
it(`Resolves avatar for ${test.title}`, function () {
return __awaiter(this, void 0, void 0, function* () {
this.timeout(60000);
const provider = ethers.getDefaultProvider("ropsten", getApiKeys("ropsten"));
const avatar = yield provider.getAvatar(test.name);
assert.equal(test.value, avatar, "avatar url");
});
});
});
[
{ title: "ERC-1155", name: "nick.eth", value: "https:/\/lh3.googleusercontent.com/hKHZTZSTmcznonu8I6xcVZio1IF76fq0XmcxnvUykC-FGuVJ75UPdLDlKJsfgVXH9wOSmkyHw0C39VAYtsGyxT7WNybjQ6s3fM3macE" },
{ title: "ERC-721", name: "brantly.eth", value: "https:/\/wrappedpunks.com:3000/images/punks/2430.png" },
].forEach((test) => {
it(`Resolves avatar for ${test.title}`, function () {
return __awaiter(this, void 0, void 0, function* () {
this.timeout(60000);
const provider = ethers.getDefaultProvider("homestead", getApiKeys("homestead"));
const avatar = yield provider.getAvatar(test.name);
assert.equal(test.value, avatar, "avatar url");
});
});
});
});
//# sourceMappingURL=test-providers.js.map

File diff suppressed because one or more lines are too long

@ -1494,4 +1494,51 @@ describe("Bad ENS resolution", function () {
});
});
});
describe("Resolve ENS avatar", function () {
[
{ title: "data", name: "data-avatar.tests.eth", value: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAMAAACeL25MAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyVpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NUQ4NTEyNUIyOEIwMTFFQzg0NTBDNTU2RDk1NTA5NzgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NUQ4NTEyNUMyOEIwMTFFQzg0NTBDNTU2RDk1NTA5NzgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1RDg1MTI1OTI4QjAxMUVDODQ1MEM1NTZEOTU1MDk3OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1RDg1MTI1QTI4QjAxMUVDODQ1MEM1NTZEOTU1MDk3OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkbM0uMAAAAGUExURQAA/wAAAHtivz4AAAAOSURBVHjaYmDABAABBgAAFAABaEkyYwAAAABJRU5ErkJggg==" },
{ title: "ipfs", name: "ipfs-avatar.tests.eth", value: "https:/\/gateway.ipfs.io/ipfs/QmQsQgpda6JAYkFoeVcj5iPbwV3xRcvaiXv3bhp1VuYUqw" },
{ title: "url", name: "url-avatar.tests.eth", value: "https:/\/ethers.org/static/logo.png" },
].forEach(function (test) {
it("Resolves avatar for " + test.title, function () {
return __awaiter(this, void 0, void 0, function () {
var provider, avatar;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.timeout(60000);
provider = ethers_1.ethers.getDefaultProvider("ropsten", getApiKeys("ropsten"));
return [4 /*yield*/, provider.getAvatar(test.name)];
case 1:
avatar = _a.sent();
assert_1.default.equal(test.value, avatar, "avatar url");
return [2 /*return*/];
}
});
});
});
});
[
{ title: "ERC-1155", name: "nick.eth", value: "https:/\/lh3.googleusercontent.com/hKHZTZSTmcznonu8I6xcVZio1IF76fq0XmcxnvUykC-FGuVJ75UPdLDlKJsfgVXH9wOSmkyHw0C39VAYtsGyxT7WNybjQ6s3fM3macE" },
{ title: "ERC-721", name: "brantly.eth", value: "https:/\/wrappedpunks.com:3000/images/punks/2430.png" },
].forEach(function (test) {
it("Resolves avatar for " + test.title, function () {
return __awaiter(this, void 0, void 0, function () {
var provider, avatar;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.timeout(60000);
provider = ethers_1.ethers.getDefaultProvider("homestead", getApiKeys("homestead"));
return [4 /*yield*/, provider.getAvatar(test.name)];
case 1:
avatar = _a.sent();
assert_1.default.equal(test.value, avatar, "avatar url");
return [2 /*return*/];
}
});
});
});
});
});
//# sourceMappingURL=test-providers.js.map

File diff suppressed because one or more lines are too long

@ -37,7 +37,7 @@
"scripts": {
"test": "exit 1"
},
"tarballHash": "0xd193ab66984342ed08d11241a3b69d6188d133e7607b665bfeee26d72fcc0518",
"tarballHash": "0xd2cbf0d358a3fb5f6c1e9794c6b0caa74ff17536eba8974eac16d24962edc478",
"types": "./lib/index.d.ts",
"version": "5.5.0"
}