@zoralabs/nft-metadata
Advanced tools
Comparing version 1.1.1 to 1.2.1
@@ -32,2 +32,4 @@ import { JsonRpcProvider } from '@ethersproject/providers'; | ||
} | ||
export declare class ChainFetchError extends Error { | ||
} | ||
export declare class Agent { | ||
@@ -39,3 +41,6 @@ timeout: number; | ||
constructor(options: AgentOptions); | ||
fetchTokenURI(tokenAddress: string, tokenId: string): Promise<string | undefined>; | ||
fetchTokenURI(tokenAddress: string, tokenId: string): Promise<{ | ||
uri: any; | ||
type: string; | ||
}>; | ||
fetchURIData(tokenAddress: string, tokenId: string, tokenURI: string, ipfsGateway: string): Promise<any>; | ||
@@ -42,0 +47,0 @@ private parseURIData; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Agent = void 0; | ||
exports.Agent = exports.ChainFetchError = void 0; | ||
const providers_1 = require("@ethersproject/providers"); | ||
@@ -11,3 +11,10 @@ const address_1 = require("@ethersproject/address"); | ||
const providers_2 = require("./constants/providers"); | ||
const ethers_1 = require("ethers"); | ||
const addresses_1 = require("./utils/addresses"); | ||
const token_types_1 = require("./constants/token-types"); | ||
const mime_1 = require("./constants/mime"); | ||
class ChainFetchError extends Error { | ||
} | ||
exports.ChainFetchError = ChainFetchError; | ||
; | ||
class Agent { | ||
@@ -19,3 +26,3 @@ constructor(options) { | ||
else { | ||
this.provider = new providers_1.JsonRpcProvider(options.networkUrl || providers_2.CLOUDFLARE_RPC_DEFAULT, options.network); | ||
this.provider = new providers_1.StaticJsonRpcProvider(options.networkUrl || providers_2.CLOUDFLARE_RPC_DEFAULT, options.network); | ||
} | ||
@@ -32,13 +39,29 @@ this.ipfsGatewayUrl = options.ipfsGatewayUrl || providers_2.IPFS_IO_GATEWAY; | ||
} | ||
const alternateMethod = uri_1.getAlternateContractCall(this.provider.network.name, tokenAddress, tokenId, this.provider); | ||
const alternateMethod = await uri_1.getAlternateContractCall(this.provider.network.name, tokenAddress, tokenId, this.provider); | ||
if (alternateMethod) { | ||
return alternateMethod; | ||
} | ||
const contract = typechain_1.Erc721Factory.connect(tokenAddress, this.provider); | ||
try { | ||
return contract.tokenURI(tokenId); | ||
const erc721Contract = typechain_1.Erc721Factory.connect(tokenAddress, this.provider); | ||
const uri = await erc721Contract.tokenURI(tokenId); | ||
return { | ||
uri, | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
}; | ||
} | ||
catch (e) { | ||
return; | ||
// if this fails, attempt 1155 fetch | ||
} | ||
try { | ||
const erc1155Contract = new ethers_1.Contract(tokenAddress, ['function uri(uint256 index) public view returns (string memory)'], this.provider); | ||
let uri = await erc1155Contract.uri(tokenId); | ||
if (uri.includes('{id}')) { | ||
uri = uri.replace('{id}', addresses_1.normalizeTokenID1155(tokenId)); | ||
} | ||
return { uri, type: token_types_1.ERC1155_TOKEN_TYPE }; | ||
} | ||
catch (e) { | ||
// if this fails, fail function | ||
} | ||
throw new ChainFetchError('Cannot fetch uri from contract'); | ||
} | ||
@@ -104,22 +127,30 @@ async fetchURIData(tokenAddress, tokenId, tokenURI, ipfsGateway) { | ||
const tokenAddress = address_1.getAddress(rawAddress); | ||
const tokenURI = await this.fetchTokenURI(tokenAddress, tokenId); | ||
if (!tokenURI) { | ||
throw new Error(`Failed to get tokenURI token: ${tokenAddress} is unsupported by @zoralabs/nft-metadata`); | ||
try { | ||
const uriFetchResult = await this.fetchTokenURI(tokenAddress, tokenId); | ||
const { uri: tokenURI, type: tokenType } = uriFetchResult; | ||
const ipfsGateway = uri_1.getPrivateGateway(this.provider.network.name, tokenAddress) || | ||
this.ipfsGatewayUrl; | ||
const URIData = await this.fetchURIData(tokenAddress, tokenId, tokenURI, ipfsGateway); | ||
// console.log('fetched uri data: ', { URIData }) | ||
const metadata = await this.parseURIData(tokenAddress, tokenId, tokenURI, URIData, ipfsGateway); | ||
// console.log('parsed metadata: ', { metadata }) | ||
return { | ||
tokenId, | ||
tokenAddress, | ||
metadata: URIData, | ||
tokenURI, | ||
tokenType, | ||
...metadata, | ||
}; | ||
} | ||
console.log('fetched uri: ', { tokenURI }); | ||
const ipfsGateway = uri_1.getPrivateGateway(this.provider.network.name, tokenAddress) || | ||
this.ipfsGatewayUrl; | ||
const URIData = await this.fetchURIData(tokenAddress, tokenId, tokenURI, ipfsGateway); | ||
console.log('fetched uri data: ', { URIData }); | ||
const metadata = await this.parseURIData(tokenAddress, tokenId, tokenURI, URIData, ipfsGateway); | ||
console.log('parsed metadata: ', { metadata }); | ||
return { | ||
tokenId, | ||
tokenAddress, | ||
metadata: URIData, | ||
tokenURI, | ||
...metadata, | ||
}; | ||
catch (err) { | ||
if (err instanceof ChainFetchError) { | ||
console.error(err); | ||
throw new Error(`Failed to get tokenURI token: ${tokenAddress} is unsupported by @zoralabs/nft-metadata`); | ||
} | ||
throw err; | ||
} | ||
// console.log('fetched uri: ', { tokenURI, tokenType }) | ||
} | ||
} | ||
exports.Agent = Agent; |
@@ -39,3 +39,3 @@ "use strict"; | ||
function normaliseURIData(chainName, tokenAddress, data) { | ||
var _a, _b, _c, _d; | ||
var _a, _b, _c, _d, _e; | ||
let normalisedData = data; | ||
@@ -52,2 +52,11 @@ if (addresses_2.isAddressMatch(chainName, tokenAddress, addresses_1.MAKERSPLACE_TOKEN_ADDRESS)) { | ||
} | ||
// Fix for foundation: normalize content-type in animation for files ending in glb. | ||
if (addresses_2.isAddressMatch(chainName, tokenAddress, addresses_1.FOUNDATION_TOKEN_ADDRESS)) { | ||
normalisedData = { | ||
...normalisedData, | ||
contentURLMimeType: ((_e = normalisedData.animation_url) === null || _e === void 0 ? void 0 : _e.endsWith('glb')) | ||
? 'model/gltf-binary' | ||
: undefined, | ||
}; | ||
} | ||
if (addresses_2.isAddressMatch(chainName, tokenAddress, addresses_1.ZORA_TOKEN_ADDRESS)) { | ||
@@ -54,0 +63,0 @@ normalisedData = translateZoraMetadataSchema(normalisedData); |
import { JsonRpcProvider } from '@ethersproject/providers'; | ||
export declare function getAlternateContractCall(networkName: string, tokenAddress: string, tokenId: string, provider: JsonRpcProvider): Promise<string> | undefined; | ||
export declare function getAlternateContractCall(networkName: string, tokenAddress: string, tokenId: string, provider: JsonRpcProvider): Promise<{ | ||
type: string; | ||
uri: string; | ||
} | undefined>; |
@@ -7,5 +7,9 @@ "use strict"; | ||
const addresses_2 = require("../utils/addresses"); | ||
function getAlternateContractCall(networkName, tokenAddress, tokenId, provider) { | ||
const token_types_1 = require("../constants/token-types"); | ||
async function getAlternateContractCall(networkName, tokenAddress, tokenId, provider) { | ||
if (addresses_2.isAddressMatch(networkName, tokenAddress, addresses_1.ZORA_TOKEN_ADDRESS)) { | ||
return typechain_1.MediaFactory.connect(tokenAddress, provider).tokenMetadataURI(tokenId); | ||
return { | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
uri: await typechain_1.MediaFactory.connect(tokenAddress, provider).tokenMetadataURI(tokenId), | ||
}; | ||
} | ||
@@ -12,0 +16,0 @@ return; |
@@ -6,4 +6,4 @@ "use strict"; | ||
const dataBuffer = Buffer.from(data, 'utf-8'); | ||
return `${mime};base64,${dataBuffer.toString('base64')}`; | ||
return `data:${mime};base64,${dataBuffer.toString('base64')}`; | ||
} | ||
exports.createDataURI = createDataURI; |
@@ -1,2 +0,5 @@ | ||
export declare function getStaticURI(chainName: string, tokenAddress: string, tokenId: string): string | undefined; | ||
export declare function getStaticURI(chainName: string, tokenAddress: string, tokenId: string): { | ||
type: string; | ||
uri: string; | ||
} | undefined; | ||
export declare function getURIData(chainName: string, tokenAddress: string, tokenId: string): Promise<{ | ||
@@ -3,0 +6,0 @@ title: string; |
@@ -6,8 +6,15 @@ "use strict"; | ||
const addresses_2 = require("../constants/addresses"); | ||
const token_types_1 = require("../constants/token-types"); | ||
function getStaticURI(chainName, tokenAddress, tokenId) { | ||
if (addresses_1.isAddressMatch(chainName, tokenAddress, addresses_2.DECENTRALAND_TOKEN_ADDRESS)) { | ||
return `https://api.decentraland.org/v2/contracts/${tokenAddress.toLowerCase()}/tokens/${tokenId}`; | ||
return { | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
uri: `https://api.decentraland.org/v2/contracts/${tokenAddress.toLowerCase()}/tokens/${tokenId}`, | ||
}; | ||
} | ||
if (addresses_1.isAddressMatch(chainName, tokenAddress, addresses_2.HASHMASKS_TOKEN_ADDRESS)) { | ||
return `https://hashmap.azurewebsites.net/getMask/${tokenId}`; | ||
return { | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
uri: `https://hashmap.azurewebsites.net/getMask/${tokenId}`, | ||
}; | ||
} | ||
@@ -19,6 +26,18 @@ if (addresses_1.isAddressMatch(chainName, tokenAddress, addresses_2.ENS_TOKEN_ADDRESS)) { | ||
} | ||
return `https://metadata.ens.domains/${ensChainName}/${tokenAddress.toLowerCase()}/${tokenId}/`; | ||
return { | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
uri: `https://metadata.ens.domains/${ensChainName}/${tokenAddress.toLowerCase()}/${tokenId}/`, | ||
}; | ||
} | ||
if (addresses_1.isAddressMatch(chainName, tokenAddress, addresses_2.FOUNDATION_TOKEN_ADDRESS)) { | ||
return { | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
uri: `https://api.foundation.app/opensea/${tokenId}`, | ||
}; | ||
} | ||
if (addresses_1.isAddressMatch(chainName, tokenAddress, addresses_2.WRAPPED_CRYPTOPUNKS_TOKEN_ADDRESS)) { | ||
return `data:application/json,{}`; | ||
return { | ||
type: token_types_1.ERC721_TOKEN_TYPE, | ||
uri: `data:application/json,{}`, | ||
}; | ||
} | ||
@@ -25,0 +44,0 @@ return; |
export declare function isAddressMatch(chainName: string, address: string, addressByNetwork: { | ||
[address: string]: string; | ||
}): boolean; | ||
export declare function normalizeTokenID1155(tokenId: string): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isAddressMatch = void 0; | ||
exports.normalizeTokenID1155 = exports.isAddressMatch = void 0; | ||
const address_1 = require("@ethersproject/address"); | ||
const ethers_1 = require("ethers"); | ||
function isAddressMatch(chainName, address, addressByNetwork) { | ||
@@ -12,1 +13,7 @@ if (!addressByNetwork[chainName]) { | ||
exports.isAddressMatch = isAddressMatch; | ||
function normalizeTokenID1155(tokenId) { | ||
return ethers_1.utils | ||
.hexlify(ethers_1.utils.zeroPad(ethers_1.utils.arrayify(ethers_1.ethers.BigNumber.from(tokenId).toHexString()), 64)) | ||
.substr(4); | ||
} | ||
exports.normalizeTokenID1155 = normalizeTokenID1155; |
{ | ||
"name": "@zoralabs/nft-metadata", | ||
"version": "1.1.1", | ||
"version": "1.2.1", | ||
"description": "Generic nft metadata parsers", | ||
@@ -5,0 +5,0 @@ "author": "Zora", |
65153
50
1672