From 364e38460d176b0a50da1124c31d27a1ea0579e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Sat, 9 Jul 2022 15:48:52 +0200 Subject: [PATCH 1/6] feat: add NFT resolver --- package.json | 3 + src/api.ts | 12 +- src/constants.json | 3 +- src/resolvers/index.ts | 4 +- src/resolvers/nft.ts | 89 ++++++++++++ src/utils.ts | 7 +- test/unit/resolvers/nft.test.ts | 46 +++++++ yarn.lock | 233 +++++++++++++++++++++++++++++++- 8 files changed, 389 insertions(+), 8 deletions(-) create mode 100644 src/resolvers/nft.ts create mode 100644 test/unit/resolvers/nft.test.ts diff --git a/package.json b/package.json index 901fa635..ade8d3fa 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "dependencies": { "@aws-sdk/client-s3": "^3.51.0", "@download/blockies": "^1.0.3", + "@ethersproject/contracts": "^5.6.2", + "@ethersproject/providers": "^5.6.8", "@metamask/jazzicon": "^2.0.0", "@self.id/core": "^0.3.0", "@snapshot-labs/snapshot.js": "^0.3.75", @@ -19,6 +21,7 @@ "canvas": "^2.9.0", "compression": "^1.7.4", "cors": "^2.8.5", + "data-urls": "^3.0.2", "dotenv": "^16.0.0", "eslint": "^6.7.2", "ethers": "^5.5.4", diff --git a/src/api.ts b/src/api.ts index 88c42531..e96c8ab7 100644 --- a/src/api.ts +++ b/src/api.ts @@ -21,14 +21,15 @@ router.get('/clear/:type/:id', async (req, res) => { } }); -router.get('/:type/:id', async (req, res) => { - const { type, id } = req.params; +router.get('/:type/:id/:subId?', async (req, res) => { + const { type, id, subId } = req.params; const { address, network, w, h, fallback } = await parseQuery(id, type, req.query); const key1 = getCacheKey({ type, network, address, + subId, w: constants.max, h: constants.max, fallback @@ -37,6 +38,7 @@ router.get('/:type/:id', async (req, res) => { let currentResolvers = constants.resolvers.avatar; if (type === 'token') currentResolvers = constants.resolvers.token; if (type === 'space') currentResolvers = constants.resolvers.space; + if (type === 'nft') currentResolvers = constants.resolvers.nft; currentResolvers = [fallback, ...currentResolvers]; // Check resized cache @@ -55,7 +57,11 @@ router.get('/:type/:id', async (req, res) => { // console.log('Got base cache'); } else { console.log('No cache for', key1, base); - const p = currentResolvers.map(r => resolvers[r](address, network)); + + const extraArgs: any[] = []; + if (type === 'nft') extraArgs.push(subId); + + const p = currentResolvers.map(r => resolvers[r](address, ...extraArgs, network)); const files = await Promise.all(p); files.forEach(file => { if (file) file1 = file; diff --git a/src/constants.json b/src/constants.json index 798dd6b7..3fd967b5 100644 --- a/src/constants.json +++ b/src/constants.json @@ -4,6 +4,7 @@ "resolvers": { "avatar": ["selfid", "lens", "ens", "snapshot"], "token": ["trustwallet", "zapper"], - "space": ["space"] + "space": ["space"], + "nft": ["nft"] } } diff --git a/src/resolvers/index.ts b/src/resolvers/index.ts index 895d5b6f..5cf54f56 100644 --- a/src/resolvers/index.ts +++ b/src/resolvers/index.ts @@ -7,6 +7,7 @@ import space from './space'; import selfid from './selfid'; import lens from './lens'; import zapper from './zapper'; +import nft from './nft'; export default { blockie, @@ -17,5 +18,6 @@ export default { space, selfid, lens, - zapper + zapper, + nft }; diff --git a/src/resolvers/nft.ts b/src/resolvers/nft.ts new file mode 100644 index 00000000..8a997329 --- /dev/null +++ b/src/resolvers/nft.ts @@ -0,0 +1,89 @@ +import axios from 'axios'; +import parseDataURL from 'data-urls'; +import { getAddress } from '@ethersproject/address'; +import { Contract } from '@ethersproject/contracts'; +import { getDefaultProvider } from '@ethersproject/providers'; +import { getUrl, resize } from '../utils'; +import { max } from '../constants.json'; + +const abis = { + erc721: ['function tokenURI(uint256 tokenId) view returns (string)'], + erc1155: ['function uri(uint256 id) view returns (string)'] +}; + +async function resolveErc721(address: string, tokenId: string) { + const contract = new Contract(getAddress(address), abis.erc721, getDefaultProvider()); + const data = await contract.tokenURI(tokenId); + + const parsedMetadata = parseDataURL(data); + + let metadata; + if (parsedMetadata && parsedMetadata.mimeType.toString() === 'application/json') { + metadata = JSON.parse(Buffer.from(parsedMetadata.body).toString('utf-8')); + } else { + const url = getUrl(data); + metadata = (await axios.get(url)).data; + } + + if (!metadata.image) { + throw new Error('Image not found'); + } + + const parsedImage = parseDataURL(metadata.image); + if (parsedImage) { + return Buffer.from(parsedImage.body); + } + + const url = getUrl(metadata.image); + return (await axios({ url, responseType: 'arraybuffer' })).data as Buffer; +} + +async function resolveErc1155(address: string, tokenId: string) { + const contract = new Contract(getAddress(address), abis.erc1155, getDefaultProvider()); + const data = await contract.uri(tokenId); + + const replacementId = + tokenId.length === 64 + ? tokenId + : parseInt(tokenId, 10) + .toString(16) + .padStart(64, '0'); + + const parsedMetadata = parseDataURL(data); + + let metadataString; + if (parsedMetadata && parsedMetadata.mimeType.toString() === 'application/json') { + metadataString = Buffer.from(parsedMetadata.body).toString('utf-8'); + } else { + const uniqueData = data.replaceAll('{id}', replacementId); + const url = getUrl(uniqueData); + metadataString = JSON.stringify((await axios.get(url)).data); + } + + const metadata = JSON.parse(metadataString.replaceAll('{id}', replacementId)); + + if (!metadata.image) { + throw new Error('Image not found'); + } + + const parsedImage = parseDataURL(metadata.image); + if (parsedImage) { + return Buffer.from(parsedImage.body); + } + + const url = getUrl(metadata.image); + return (await axios({ url, responseType: 'arraybuffer' })).data as Buffer; +} + +export default async function resolve(address: string, tokenId: string) { + try { + const input = await Promise.any([ + resolveErc721(address, tokenId), + resolveErc1155(address, tokenId) + ]); + + return await resize(input, max, max); + } catch (e) { + return false; + } +} diff --git a/src/utils.ts b/src/utils.ts index 03df3528..10b7b8bf 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -82,6 +82,7 @@ export function getCacheKey({ type, network, address, + subId, w, h, fallback @@ -89,12 +90,16 @@ export function getCacheKey({ type: string; network: string; address: string; + subId?: string; w: number; h: number; fallback: string; }) { if (fallback === 'blockie') return sha256(JSON.stringify({ type, network, address, w, h })); - return sha256(JSON.stringify({ type, network, address, w, h, fallback })); + const blob: Record = { type, network, address, w, h, fallback }; + if (type === 'nft') blob.tokenId = subId; + + return sha256(JSON.stringify(blob)); } export function setHeader(res) { diff --git a/test/unit/resolvers/nft.test.ts b/test/unit/resolvers/nft.test.ts new file mode 100644 index 00000000..96385a33 --- /dev/null +++ b/test/unit/resolvers/nft.test.ts @@ -0,0 +1,46 @@ +import resolvers from '../../../src/resolvers'; + +describe('resolvers', () => { + describe('nft', () => { + describe('erc721', () => { + it('should resolve on-chain metadata', async () => { + const result = await resolvers.nft('0x29b4ea6b1164c7cd8a3a0a1dc4ad88d1e0589124', '6364'); + + expect(result).toBeInstanceOf(Buffer); + expect(result.length).toBeGreaterThan(500); + }); + + it('should resolve IPFS metadata', async () => { + const result = await resolvers.nft('0x7f8162f4ffe3db46cd3b0626dab699506c0ff63a', '6386'); + + expect(result).toBeInstanceOf(Buffer); + expect(result.length).toBeGreaterThan(500); + }); + }); + + describe('erc1155', () => { + it('should resolve IPFS metadata', async () => { + const result = await resolvers.nft('0x3b1417c1f204607deda4767929497256e4ff540c', '1'); + + expect(result).toBeInstanceOf(Buffer); + expect(result.length).toBeGreaterThan(500); + }); + + it.skip('should resolve OpeanSea metadata', async () => { + // TODO: for some reason URL for metadata returns 404 every time + // -> https://api.opensea.io/api/v1/metadata/0x495f947276749Ce646f68AC8c248420045cb7b5e/0x{id} + // -> https://api.opensea.io/api/v1/metadata/0x495f947276749Ce646f68AC8c248420045cb7b5e/0x9dbe56e659611800000000000000000000000000000000000000000000000000 + // + // 9dbe56e659611800000000000000000000000000000000000000000000000000 is hex from 71349417930267003648058267821921373972951788320258492784107927381794011217921 + + const result = await resolvers.nft( + '0x495f947276749Ce646f68AC8c248420045cb7b5e', + '71349417930267003648058267821921373972951788320258492784107927381794011217921' + ); + + expect(result).toBeInstanceOf(Buffer); + expect(result.length).toBeGreaterThan(500); + }); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 92b85849..397d786f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1253,6 +1253,21 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" +"@ethersproject/abi@^5.6.3": + version "5.6.4" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362" + integrity sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg== + dependencies: + "@ethersproject/address" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/constants" "^5.6.1" + "@ethersproject/hash" "^5.6.1" + "@ethersproject/keccak256" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/strings" "^5.6.1" + "@ethersproject/abstract-provider@5.5.1", "@ethersproject/abstract-provider@^5.5.0": version "5.5.1" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5" @@ -1279,6 +1294,19 @@ "@ethersproject/transactions" "^5.6.0" "@ethersproject/web" "^5.6.0" +"@ethersproject/abstract-provider@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz#02ddce150785caf0c77fe036a0ebfcee61878c59" + integrity sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ== + dependencies: + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/networks" "^5.6.3" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/transactions" "^5.6.2" + "@ethersproject/web" "^5.6.1" + "@ethersproject/abstract-signer@5.5.0", "@ethersproject/abstract-signer@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz#590ff6693370c60ae376bf1c7ada59eb2a8dd08d" @@ -1301,6 +1329,17 @@ "@ethersproject/logger" "^5.6.0" "@ethersproject/properties" "^5.6.0" +"@ethersproject/abstract-signer@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz#491f07fc2cbd5da258f46ec539664713950b0b33" + integrity sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ== + dependencies: + "@ethersproject/abstract-provider" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/address@5.5.0", "@ethersproject/address@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.5.0.tgz#bcc6f576a553f21f3dd7ba17248f81b473c9c78f" @@ -1323,6 +1362,17 @@ "@ethersproject/logger" "^5.6.0" "@ethersproject/rlp" "^5.6.0" +"@ethersproject/address@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.1.tgz#ab57818d9aefee919c5721d28cd31fd95eff413d" + integrity sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q== + dependencies: + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/keccak256" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/rlp" "^5.6.1" + "@ethersproject/base64@5.5.0", "@ethersproject/base64@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090" @@ -1337,6 +1387,13 @@ dependencies: "@ethersproject/bytes" "^5.6.0" +"@ethersproject/base64@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.1.tgz#2c40d8a0310c9d1606c2c37ae3092634b41d87cb" + integrity sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/basex@5.5.0", "@ethersproject/basex@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.5.0.tgz#e40a53ae6d6b09ab4d977bd037010d4bed21b4d3" @@ -1353,6 +1410,14 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/properties" "^5.6.0" +"@ethersproject/basex@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.6.1.tgz#badbb2f1d4a6f52ce41c9064f01eab19cc4c5305" + integrity sha512-a52MkVz4vuBXR06nvflPMotld1FJWSj2QT0985v7P/emPZO00PucFAkbcmq2vpVU7Ts7umKiSI6SppiLykVWsA== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/bignumber@5.5.0", "@ethersproject/bignumber@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527" @@ -1371,6 +1436,15 @@ "@ethersproject/logger" "^5.6.0" bn.js "^4.11.9" +"@ethersproject/bignumber@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.2.tgz#72a0717d6163fab44c47bcc82e0c550ac0315d66" + integrity sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + bn.js "^5.2.1" + "@ethersproject/bytes@5.5.0", "@ethersproject/bytes@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" @@ -1378,7 +1452,7 @@ dependencies: "@ethersproject/logger" "^5.5.0" -"@ethersproject/bytes@^5.0.8", "@ethersproject/bytes@^5.6.0": +"@ethersproject/bytes@^5.0.8", "@ethersproject/bytes@^5.6.0", "@ethersproject/bytes@^5.6.1": version "5.6.1" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7" integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g== @@ -1399,6 +1473,13 @@ dependencies: "@ethersproject/bignumber" "^5.6.0" +"@ethersproject/constants@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.1.tgz#e2e974cac160dd101cf79fdf879d7d18e8cb1370" + integrity sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg== + dependencies: + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/contracts@5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.5.0.tgz#b735260d4bd61283a670a82d5275e2a38892c197" @@ -1431,6 +1512,22 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/transactions" "^5.6.0" +"@ethersproject/contracts@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.2.tgz#20b52e69ebc1b74274ff8e3d4e508de971c287bc" + integrity sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g== + dependencies: + "@ethersproject/abi" "^5.6.3" + "@ethersproject/abstract-provider" "^5.6.1" + "@ethersproject/abstract-signer" "^5.6.2" + "@ethersproject/address" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/constants" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/transactions" "^5.6.2" + "@ethersproject/hash@5.5.0", "@ethersproject/hash@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9" @@ -1459,6 +1556,20 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" +"@ethersproject/hash@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.1.tgz#224572ea4de257f05b4abf8ae58b03a67e99b0f4" + integrity sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA== + dependencies: + "@ethersproject/abstract-signer" "^5.6.2" + "@ethersproject/address" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/keccak256" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/strings" "^5.6.1" + "@ethersproject/hdnode@5.5.0", "@ethersproject/hdnode@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.5.0.tgz#4a04e28f41c546f7c978528ea1575206a200ddf6" @@ -1549,6 +1660,14 @@ "@ethersproject/bytes" "^5.6.0" js-sha3 "0.8.0" +"@ethersproject/keccak256@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.1.tgz#b867167c9b50ba1b1a92bccdd4f2d6bd168a91cc" + integrity sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA== + dependencies: + "@ethersproject/bytes" "^5.6.1" + js-sha3 "0.8.0" + "@ethersproject/logger@5.5.0", "@ethersproject/logger@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" @@ -1573,6 +1692,13 @@ dependencies: "@ethersproject/logger" "^5.6.0" +"@ethersproject/networks@^5.6.3": + version "5.6.4" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.4.tgz#51296d8fec59e9627554f5a8a9c7791248c8dc07" + integrity sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ== + dependencies: + "@ethersproject/logger" "^5.6.0" + "@ethersproject/pbkdf2@5.5.0", "@ethersproject/pbkdf2@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz#e25032cdf02f31505d47afbf9c3e000d95c4a050" @@ -1653,6 +1779,32 @@ bech32 "1.1.4" ws "7.4.6" +"@ethersproject/providers@^5.6.8": + version "5.6.8" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.8.tgz#22e6c57be215ba5545d3a46cf759d265bb4e879d" + integrity sha512-Wf+CseT/iOJjrGtAOf3ck9zS7AgPmr2fZ3N97r4+YXN3mBePTG2/bJ8DApl9mVwYL+RpYbNxMEkEp4mPGdwG/w== + dependencies: + "@ethersproject/abstract-provider" "^5.6.1" + "@ethersproject/abstract-signer" "^5.6.2" + "@ethersproject/address" "^5.6.1" + "@ethersproject/base64" "^5.6.1" + "@ethersproject/basex" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/constants" "^5.6.1" + "@ethersproject/hash" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/networks" "^5.6.3" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/random" "^5.6.1" + "@ethersproject/rlp" "^5.6.1" + "@ethersproject/sha2" "^5.6.1" + "@ethersproject/strings" "^5.6.1" + "@ethersproject/transactions" "^5.6.2" + "@ethersproject/web" "^5.6.1" + bech32 "1.1.4" + ws "7.4.6" + "@ethersproject/random@5.5.1", "@ethersproject/random@^5.5.0": version "5.5.1" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.5.1.tgz#7cdf38ea93dc0b1ed1d8e480ccdaf3535c555415" @@ -1669,6 +1821,14 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/logger" "^5.6.0" +"@ethersproject/random@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.1.tgz#66915943981bcd3e11bbd43733f5c3ba5a790255" + integrity sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/rlp@5.5.0", "@ethersproject/rlp@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.5.0.tgz#530f4f608f9ca9d4f89c24ab95db58ab56ab99a0" @@ -1685,6 +1845,14 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/logger" "^5.6.0" +"@ethersproject/rlp@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.1.tgz#df8311e6f9f24dcb03d59a2bac457a28a4fe2bd8" + integrity sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/sha2@5.5.0", "@ethersproject/sha2@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.5.0.tgz#a40a054c61f98fd9eee99af2c3cc6ff57ec24db7" @@ -1703,6 +1871,15 @@ "@ethersproject/logger" "^5.6.0" hash.js "1.1.7" +"@ethersproject/sha2@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.6.1.tgz#211f14d3f5da5301c8972a8827770b6fd3e51656" + integrity sha512-5K2GyqcW7G4Yo3uenHegbXRPDgARpWUiXc6RiF7b6i/HXUoWlb7uCARh7BAHg7/qT/Q5ydofNwiZcim9qpjB6g== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + hash.js "1.1.7" + "@ethersproject/signing-key@5.5.0", "@ethersproject/signing-key@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.5.0.tgz#2aa37169ce7e01e3e80f2c14325f624c29cedbe0" @@ -1727,6 +1904,18 @@ elliptic "6.5.4" hash.js "1.1.7" +"@ethersproject/signing-key@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.2.tgz#8a51b111e4d62e5a62aee1da1e088d12de0614a3" + integrity sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + "@ethersproject/solidity@5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.5.0.tgz#2662eb3e5da471b85a20531e420054278362f93f" @@ -1757,6 +1946,15 @@ "@ethersproject/constants" "^5.6.0" "@ethersproject/logger" "^5.6.0" +"@ethersproject/strings@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.1.tgz#dbc1b7f901db822b5cafd4ebf01ca93c373f8952" + integrity sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw== + dependencies: + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/constants" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/transactions@5.5.0", "@ethersproject/transactions@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.5.0.tgz#7e9bf72e97bcdf69db34fe0d59e2f4203c7a2908" @@ -1787,6 +1985,21 @@ "@ethersproject/rlp" "^5.6.0" "@ethersproject/signing-key" "^5.6.0" +"@ethersproject/transactions@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.2.tgz#793a774c01ced9fe7073985bb95a4b4e57a6370b" + integrity sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q== + dependencies: + "@ethersproject/address" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/constants" "^5.6.1" + "@ethersproject/keccak256" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/rlp" "^5.6.1" + "@ethersproject/signing-key" "^5.6.2" + "@ethersproject/units@5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.5.0.tgz#104d02db5b5dc42cc672cc4587bafb87a95ee45e" @@ -1860,6 +2073,17 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" +"@ethersproject/web@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.1.tgz#6e2bd3ebadd033e6fe57d072db2b69ad2c9bdf5d" + integrity sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA== + dependencies: + "@ethersproject/base64" "^5.6.1" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/strings" "^5.6.1" + "@ethersproject/wordlists@5.5.0", "@ethersproject/wordlists@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.5.0.tgz#aac74963aa43e643638e5172353d931b347d584f" @@ -2871,6 +3095,11 @@ bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -3403,7 +3632,7 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -data-urls@^3.0.1: +data-urls@^3.0.1, data-urls@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== From 152d66f0ff2e2c44823d42694ba3261304b4fc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Sat, 9 Jul 2022 15:54:33 +0200 Subject: [PATCH 2/6] feat: use Brovider --- src/resolvers/nft.ts | 8 +++++--- test/unit/resolvers/nft.test.ts | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/resolvers/nft.ts b/src/resolvers/nft.ts index 8a997329..100172f6 100644 --- a/src/resolvers/nft.ts +++ b/src/resolvers/nft.ts @@ -2,17 +2,19 @@ import axios from 'axios'; import parseDataURL from 'data-urls'; import { getAddress } from '@ethersproject/address'; import { Contract } from '@ethersproject/contracts'; -import { getDefaultProvider } from '@ethersproject/providers'; +import { StaticJsonRpcProvider } from '@ethersproject/providers'; import { getUrl, resize } from '../utils'; import { max } from '../constants.json'; +const provider = new StaticJsonRpcProvider('https://brovider.xyz/1'); + const abis = { erc721: ['function tokenURI(uint256 tokenId) view returns (string)'], erc1155: ['function uri(uint256 id) view returns (string)'] }; async function resolveErc721(address: string, tokenId: string) { - const contract = new Contract(getAddress(address), abis.erc721, getDefaultProvider()); + const contract = new Contract(getAddress(address), abis.erc721, provider); const data = await contract.tokenURI(tokenId); const parsedMetadata = parseDataURL(data); @@ -39,7 +41,7 @@ async function resolveErc721(address: string, tokenId: string) { } async function resolveErc1155(address: string, tokenId: string) { - const contract = new Contract(getAddress(address), abis.erc1155, getDefaultProvider()); + const contract = new Contract(getAddress(address), abis.erc1155, provider); const data = await contract.uri(tokenId); const replacementId = diff --git a/test/unit/resolvers/nft.test.ts b/test/unit/resolvers/nft.test.ts index 96385a33..428c2bc1 100644 --- a/test/unit/resolvers/nft.test.ts +++ b/test/unit/resolvers/nft.test.ts @@ -8,14 +8,14 @@ describe('resolvers', () => { expect(result).toBeInstanceOf(Buffer); expect(result.length).toBeGreaterThan(500); - }); + }, 15000); it('should resolve IPFS metadata', async () => { const result = await resolvers.nft('0x7f8162f4ffe3db46cd3b0626dab699506c0ff63a', '6386'); expect(result).toBeInstanceOf(Buffer); expect(result.length).toBeGreaterThan(500); - }); + }, 15000); }); describe('erc1155', () => { @@ -24,7 +24,7 @@ describe('resolvers', () => { expect(result).toBeInstanceOf(Buffer); expect(result.length).toBeGreaterThan(500); - }); + }, 15000); it.skip('should resolve OpeanSea metadata', async () => { // TODO: for some reason URL for metadata returns 404 every time @@ -40,7 +40,7 @@ describe('resolvers', () => { expect(result).toBeInstanceOf(Buffer); expect(result.length).toBeGreaterThan(500); - }); + }, 15000); }); }); }); From 07f4ac7ed88506901698d10aec772090b39b6b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Sat, 9 Jul 2022 15:56:58 +0200 Subject: [PATCH 3/6] chore: remove explicit ethers deps --- package.json | 2 - yarn.lock | 231 +-------------------------------------------------- 2 files changed, 1 insertion(+), 232 deletions(-) diff --git a/package.json b/package.json index ade8d3fa..0be17764 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,6 @@ "dependencies": { "@aws-sdk/client-s3": "^3.51.0", "@download/blockies": "^1.0.3", - "@ethersproject/contracts": "^5.6.2", - "@ethersproject/providers": "^5.6.8", "@metamask/jazzicon": "^2.0.0", "@self.id/core": "^0.3.0", "@snapshot-labs/snapshot.js": "^0.3.75", diff --git a/yarn.lock b/yarn.lock index 397d786f..2e57ef08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1253,21 +1253,6 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/abi@^5.6.3": - version "5.6.4" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362" - integrity sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg== - dependencies: - "@ethersproject/address" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/constants" "^5.6.1" - "@ethersproject/hash" "^5.6.1" - "@ethersproject/keccak256" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.1" - "@ethersproject/abstract-provider@5.5.1", "@ethersproject/abstract-provider@^5.5.0": version "5.5.1" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5" @@ -1294,19 +1279,6 @@ "@ethersproject/transactions" "^5.6.0" "@ethersproject/web" "^5.6.0" -"@ethersproject/abstract-provider@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz#02ddce150785caf0c77fe036a0ebfcee61878c59" - integrity sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ== - dependencies: - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks" "^5.6.3" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/transactions" "^5.6.2" - "@ethersproject/web" "^5.6.1" - "@ethersproject/abstract-signer@5.5.0", "@ethersproject/abstract-signer@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz#590ff6693370c60ae376bf1c7ada59eb2a8dd08d" @@ -1329,17 +1301,6 @@ "@ethersproject/logger" "^5.6.0" "@ethersproject/properties" "^5.6.0" -"@ethersproject/abstract-signer@^5.6.2": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz#491f07fc2cbd5da258f46ec539664713950b0b33" - integrity sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ== - dependencies: - "@ethersproject/abstract-provider" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/address@5.5.0", "@ethersproject/address@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.5.0.tgz#bcc6f576a553f21f3dd7ba17248f81b473c9c78f" @@ -1362,17 +1323,6 @@ "@ethersproject/logger" "^5.6.0" "@ethersproject/rlp" "^5.6.0" -"@ethersproject/address@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.1.tgz#ab57818d9aefee919c5721d28cd31fd95eff413d" - integrity sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q== - dependencies: - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/keccak256" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/rlp" "^5.6.1" - "@ethersproject/base64@5.5.0", "@ethersproject/base64@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090" @@ -1387,13 +1337,6 @@ dependencies: "@ethersproject/bytes" "^5.6.0" -"@ethersproject/base64@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.1.tgz#2c40d8a0310c9d1606c2c37ae3092634b41d87cb" - integrity sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/basex@5.5.0", "@ethersproject/basex@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.5.0.tgz#e40a53ae6d6b09ab4d977bd037010d4bed21b4d3" @@ -1410,14 +1353,6 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/properties" "^5.6.0" -"@ethersproject/basex@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.6.1.tgz#badbb2f1d4a6f52ce41c9064f01eab19cc4c5305" - integrity sha512-a52MkVz4vuBXR06nvflPMotld1FJWSj2QT0985v7P/emPZO00PucFAkbcmq2vpVU7Ts7umKiSI6SppiLykVWsA== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/bignumber@5.5.0", "@ethersproject/bignumber@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527" @@ -1436,15 +1371,6 @@ "@ethersproject/logger" "^5.6.0" bn.js "^4.11.9" -"@ethersproject/bignumber@^5.6.2": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.2.tgz#72a0717d6163fab44c47bcc82e0c550ac0315d66" - integrity sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - bn.js "^5.2.1" - "@ethersproject/bytes@5.5.0", "@ethersproject/bytes@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" @@ -1452,7 +1378,7 @@ dependencies: "@ethersproject/logger" "^5.5.0" -"@ethersproject/bytes@^5.0.8", "@ethersproject/bytes@^5.6.0", "@ethersproject/bytes@^5.6.1": +"@ethersproject/bytes@^5.0.8", "@ethersproject/bytes@^5.6.0": version "5.6.1" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7" integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g== @@ -1473,13 +1399,6 @@ dependencies: "@ethersproject/bignumber" "^5.6.0" -"@ethersproject/constants@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.1.tgz#e2e974cac160dd101cf79fdf879d7d18e8cb1370" - integrity sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg== - dependencies: - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/contracts@5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.5.0.tgz#b735260d4bd61283a670a82d5275e2a38892c197" @@ -1512,22 +1431,6 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/transactions" "^5.6.0" -"@ethersproject/contracts@^5.6.2": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.2.tgz#20b52e69ebc1b74274ff8e3d4e508de971c287bc" - integrity sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g== - dependencies: - "@ethersproject/abi" "^5.6.3" - "@ethersproject/abstract-provider" "^5.6.1" - "@ethersproject/abstract-signer" "^5.6.2" - "@ethersproject/address" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/constants" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/transactions" "^5.6.2" - "@ethersproject/hash@5.5.0", "@ethersproject/hash@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9" @@ -1556,20 +1459,6 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/hash@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.1.tgz#224572ea4de257f05b4abf8ae58b03a67e99b0f4" - integrity sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA== - dependencies: - "@ethersproject/abstract-signer" "^5.6.2" - "@ethersproject/address" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/keccak256" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.1" - "@ethersproject/hdnode@5.5.0", "@ethersproject/hdnode@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.5.0.tgz#4a04e28f41c546f7c978528ea1575206a200ddf6" @@ -1660,14 +1549,6 @@ "@ethersproject/bytes" "^5.6.0" js-sha3 "0.8.0" -"@ethersproject/keccak256@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.1.tgz#b867167c9b50ba1b1a92bccdd4f2d6bd168a91cc" - integrity sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA== - dependencies: - "@ethersproject/bytes" "^5.6.1" - js-sha3 "0.8.0" - "@ethersproject/logger@5.5.0", "@ethersproject/logger@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" @@ -1692,13 +1573,6 @@ dependencies: "@ethersproject/logger" "^5.6.0" -"@ethersproject/networks@^5.6.3": - version "5.6.4" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.4.tgz#51296d8fec59e9627554f5a8a9c7791248c8dc07" - integrity sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ== - dependencies: - "@ethersproject/logger" "^5.6.0" - "@ethersproject/pbkdf2@5.5.0", "@ethersproject/pbkdf2@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz#e25032cdf02f31505d47afbf9c3e000d95c4a050" @@ -1779,32 +1653,6 @@ bech32 "1.1.4" ws "7.4.6" -"@ethersproject/providers@^5.6.8": - version "5.6.8" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.8.tgz#22e6c57be215ba5545d3a46cf759d265bb4e879d" - integrity sha512-Wf+CseT/iOJjrGtAOf3ck9zS7AgPmr2fZ3N97r4+YXN3mBePTG2/bJ8DApl9mVwYL+RpYbNxMEkEp4mPGdwG/w== - dependencies: - "@ethersproject/abstract-provider" "^5.6.1" - "@ethersproject/abstract-signer" "^5.6.2" - "@ethersproject/address" "^5.6.1" - "@ethersproject/base64" "^5.6.1" - "@ethersproject/basex" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/constants" "^5.6.1" - "@ethersproject/hash" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks" "^5.6.3" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.1" - "@ethersproject/rlp" "^5.6.1" - "@ethersproject/sha2" "^5.6.1" - "@ethersproject/strings" "^5.6.1" - "@ethersproject/transactions" "^5.6.2" - "@ethersproject/web" "^5.6.1" - bech32 "1.1.4" - ws "7.4.6" - "@ethersproject/random@5.5.1", "@ethersproject/random@^5.5.0": version "5.5.1" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.5.1.tgz#7cdf38ea93dc0b1ed1d8e480ccdaf3535c555415" @@ -1821,14 +1669,6 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/random@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.1.tgz#66915943981bcd3e11bbd43733f5c3ba5a790255" - integrity sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/rlp@5.5.0", "@ethersproject/rlp@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.5.0.tgz#530f4f608f9ca9d4f89c24ab95db58ab56ab99a0" @@ -1845,14 +1685,6 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/rlp@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.1.tgz#df8311e6f9f24dcb03d59a2bac457a28a4fe2bd8" - integrity sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/sha2@5.5.0", "@ethersproject/sha2@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.5.0.tgz#a40a054c61f98fd9eee99af2c3cc6ff57ec24db7" @@ -1871,15 +1703,6 @@ "@ethersproject/logger" "^5.6.0" hash.js "1.1.7" -"@ethersproject/sha2@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.6.1.tgz#211f14d3f5da5301c8972a8827770b6fd3e51656" - integrity sha512-5K2GyqcW7G4Yo3uenHegbXRPDgARpWUiXc6RiF7b6i/HXUoWlb7uCARh7BAHg7/qT/Q5ydofNwiZcim9qpjB6g== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - hash.js "1.1.7" - "@ethersproject/signing-key@5.5.0", "@ethersproject/signing-key@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.5.0.tgz#2aa37169ce7e01e3e80f2c14325f624c29cedbe0" @@ -1904,18 +1727,6 @@ elliptic "6.5.4" hash.js "1.1.7" -"@ethersproject/signing-key@^5.6.2": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.2.tgz#8a51b111e4d62e5a62aee1da1e088d12de0614a3" - integrity sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - "@ethersproject/solidity@5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.5.0.tgz#2662eb3e5da471b85a20531e420054278362f93f" @@ -1946,15 +1757,6 @@ "@ethersproject/constants" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/strings@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.1.tgz#dbc1b7f901db822b5cafd4ebf01ca93c373f8952" - integrity sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/constants" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/transactions@5.5.0", "@ethersproject/transactions@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.5.0.tgz#7e9bf72e97bcdf69db34fe0d59e2f4203c7a2908" @@ -1985,21 +1787,6 @@ "@ethersproject/rlp" "^5.6.0" "@ethersproject/signing-key" "^5.6.0" -"@ethersproject/transactions@^5.6.2": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.2.tgz#793a774c01ced9fe7073985bb95a4b4e57a6370b" - integrity sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q== - dependencies: - "@ethersproject/address" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/constants" "^5.6.1" - "@ethersproject/keccak256" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/rlp" "^5.6.1" - "@ethersproject/signing-key" "^5.6.2" - "@ethersproject/units@5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.5.0.tgz#104d02db5b5dc42cc672cc4587bafb87a95ee45e" @@ -2073,17 +1860,6 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/web@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.1.tgz#6e2bd3ebadd033e6fe57d072db2b69ad2c9bdf5d" - integrity sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA== - dependencies: - "@ethersproject/base64" "^5.6.1" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.1" - "@ethersproject/wordlists@5.5.0", "@ethersproject/wordlists@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.5.0.tgz#aac74963aa43e643638e5172353d931b347d584f" @@ -3095,11 +2871,6 @@ bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" From 768d07eaa3d47410e177c84f435a15191297dee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Wed, 13 Jul 2022 22:22:17 +0200 Subject: [PATCH 4/6] fix: remove max crop --- src/resolvers/nft.ts | 10 ++-------- test/unit/resolvers/nft.test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/resolvers/nft.ts b/src/resolvers/nft.ts index 100172f6..12771a5a 100644 --- a/src/resolvers/nft.ts +++ b/src/resolvers/nft.ts @@ -3,8 +3,7 @@ import parseDataURL from 'data-urls'; import { getAddress } from '@ethersproject/address'; import { Contract } from '@ethersproject/contracts'; import { StaticJsonRpcProvider } from '@ethersproject/providers'; -import { getUrl, resize } from '../utils'; -import { max } from '../constants.json'; +import { getUrl } from '../utils'; const provider = new StaticJsonRpcProvider('https://brovider.xyz/1'); @@ -79,12 +78,7 @@ async function resolveErc1155(address: string, tokenId: string) { export default async function resolve(address: string, tokenId: string) { try { - const input = await Promise.any([ - resolveErc721(address, tokenId), - resolveErc1155(address, tokenId) - ]); - - return await resize(input, max, max); + return await Promise.any([resolveErc721(address, tokenId), resolveErc1155(address, tokenId)]); } catch (e) { return false; } diff --git a/test/unit/resolvers/nft.test.ts b/test/unit/resolvers/nft.test.ts index 428c2bc1..ef360508 100644 --- a/test/unit/resolvers/nft.test.ts +++ b/test/unit/resolvers/nft.test.ts @@ -7,14 +7,14 @@ describe('resolvers', () => { const result = await resolvers.nft('0x29b4ea6b1164c7cd8a3a0a1dc4ad88d1e0589124', '6364'); expect(result).toBeInstanceOf(Buffer); - expect(result.length).toBeGreaterThan(500); + expect((result as Buffer).length).toBeGreaterThan(500); }, 15000); it('should resolve IPFS metadata', async () => { const result = await resolvers.nft('0x7f8162f4ffe3db46cd3b0626dab699506c0ff63a', '6386'); expect(result).toBeInstanceOf(Buffer); - expect(result.length).toBeGreaterThan(500); + expect((result as Buffer).length).toBeGreaterThan(500); }, 15000); }); @@ -23,7 +23,7 @@ describe('resolvers', () => { const result = await resolvers.nft('0x3b1417c1f204607deda4767929497256e4ff540c', '1'); expect(result).toBeInstanceOf(Buffer); - expect(result.length).toBeGreaterThan(500); + expect((result as Buffer).length).toBeGreaterThan(500); }, 15000); it.skip('should resolve OpeanSea metadata', async () => { @@ -39,7 +39,7 @@ describe('resolvers', () => { ); expect(result).toBeInstanceOf(Buffer); - expect(result.length).toBeGreaterThan(500); + expect((result as Buffer).length).toBeGreaterThan(500); }, 15000); }); }); From 8f63e6c63c6f4ca3a119b1f8d4527b70fcff6966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Wed, 13 Jul 2022 22:45:27 +0200 Subject: [PATCH 5/6] fix: properly handle tokenId conversion to hex --- src/resolvers/nft.ts | 2 +- test/unit/resolvers/nft.test.ts | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/resolvers/nft.ts b/src/resolvers/nft.ts index 12771a5a..23b00519 100644 --- a/src/resolvers/nft.ts +++ b/src/resolvers/nft.ts @@ -46,7 +46,7 @@ async function resolveErc1155(address: string, tokenId: string) { const replacementId = tokenId.length === 64 ? tokenId - : parseInt(tokenId, 10) + : BigInt(tokenId) .toString(16) .padStart(64, '0'); diff --git a/test/unit/resolvers/nft.test.ts b/test/unit/resolvers/nft.test.ts index ef360508..a75cb93a 100644 --- a/test/unit/resolvers/nft.test.ts +++ b/test/unit/resolvers/nft.test.ts @@ -26,13 +26,7 @@ describe('resolvers', () => { expect((result as Buffer).length).toBeGreaterThan(500); }, 15000); - it.skip('should resolve OpeanSea metadata', async () => { - // TODO: for some reason URL for metadata returns 404 every time - // -> https://api.opensea.io/api/v1/metadata/0x495f947276749Ce646f68AC8c248420045cb7b5e/0x{id} - // -> https://api.opensea.io/api/v1/metadata/0x495f947276749Ce646f68AC8c248420045cb7b5e/0x9dbe56e659611800000000000000000000000000000000000000000000000000 - // - // 9dbe56e659611800000000000000000000000000000000000000000000000000 is hex from 71349417930267003648058267821921373972951788320258492784107927381794011217921 - + it('should resolve OpeanSea metadata', async () => { const result = await resolvers.nft( '0x495f947276749Ce646f68AC8c248420045cb7b5e', '71349417930267003648058267821921373972951788320258492784107927381794011217921' From 00c61f95242e7d13b5d5e38f4d47ea3ef911a4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Tkaczy=C5=84ski?= Date: Sat, 23 Jul 2022 17:52:28 +0200 Subject: [PATCH 6/6] fix: max-crop source image with contain --- src/resolvers/nft.ts | 10 ++++++++-- src/utils.ts | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/resolvers/nft.ts b/src/resolvers/nft.ts index 23b00519..4c5d9272 100644 --- a/src/resolvers/nft.ts +++ b/src/resolvers/nft.ts @@ -3,7 +3,8 @@ import parseDataURL from 'data-urls'; import { getAddress } from '@ethersproject/address'; import { Contract } from '@ethersproject/contracts'; import { StaticJsonRpcProvider } from '@ethersproject/providers'; -import { getUrl } from '../utils'; +import { getUrl, resize } from '../utils'; +import { max } from '../constants.json'; const provider = new StaticJsonRpcProvider('https://brovider.xyz/1'); @@ -78,7 +79,12 @@ async function resolveErc1155(address: string, tokenId: string) { export default async function resolve(address: string, tokenId: string) { try { - return await Promise.any([resolveErc721(address, tokenId), resolveErc1155(address, tokenId)]); + const input = await Promise.any([ + resolveErc721(address, tokenId), + resolveErc1155(address, tokenId) + ]); + + return await resize(input, max, max, 'contain'); } catch (e) { return false; } diff --git a/src/utils.ts b/src/utils.ts index 10b7b8bf..c78dfd41 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,9 +10,11 @@ export function sha256(str) { .digest('hex'); } -export async function resize(input, w, h) { +export async function resize(input, w, h, fit = 'cover') { return sharp(input) - .resize(w, h) + .resize(w, h, { + fit + }) .webp({ lossless: true }) .toBuffer(); }