Skip to content

Commit

Permalink
feat: add tests for misc contracts, add blitmap svg support
Browse files Browse the repository at this point in the history
  • Loading branch information
ethandaya committed Aug 26, 2021
1 parent 80890f4 commit d40c488
Show file tree
Hide file tree
Showing 14 changed files with 425 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zoralabs/nft-metadata",
"version": "0.0.16",
"version": "0.0.17",
"description": "generic nft metadata parsers",
"author": "Zora",
"license": "MIT",
Expand Down
9 changes: 9 additions & 0 deletions src/constants/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,12 @@ export const ART_BLOCKS_TOKEN_ADDRESS =

export const FOUNDATION_TOKEN_ADDRESS =
'0x3B3ee1931Dc30C1957379FAc9aba94D1C48a5405'

export const WRAPPED_CRYPTOPUNKS_TOKEN_ADDRESS =
'0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6'

export const BLITMAP_TOKEN_ADDRESS =
'0x8d04a8c79cEB0889Bdd12acdF3Fa9D207eD3Ff63'

export const KNOWN_ORIGIN_TOKEN_ADDRESS =
'0xFBeef911Dc5821886e1dda71586d90eD28174B7d'
31 changes: 31 additions & 0 deletions src/parsers/blitmapMetadataParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ParserConfig, ParserResponse } from './index'
import { NftMetadata } from '../agent'
import { Contract } from '@ethersproject/contracts'

export async function blitmapMetadataParser(
config: ParserConfig,
): Promise<ParserResponse> {
const { baseMeta, contractData, provider } = config
const { tokenId, tokenAddress } = contractData

const BMContract = new Contract(
tokenAddress,
[
'function tokenSvgDataOf(uint256 tokenId) public view returns (string memory)',
],
provider,
)

const svg = await BMContract.tokenSvgDataOf(tokenId)
let meta: Partial<NftMetadata> = {
contentURL: svg,
contentURLMimeType: 'image/svg+xml',
}

return {
...baseMeta,
imageURL: baseMeta.contentURL,
imageURLMimeType: baseMeta.contentURLMimeType,
...meta,
}
}
12 changes: 10 additions & 2 deletions src/parsers/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { getAddress } from '@ethersproject/address'
import {
BLITMAP_TOKEN_ADDRESS,
HASHMASKS_TOKEN_ADDRESS,
KNOWN_ORIGIN_TOKEN_ADDRESS,
MAKERSPLACE_TOKEN_ADDRESS,
ZORA_TOKEN_ADDRESS,
} from '../constants'
import { additionalMetadataParser } from './additionalMetadataParser'
import { zoraMetadataParser } from './zoraMetadataParser'
import { parseMakersplaceMetadata } from './makersplaceMetadataParser'
import { parseHashmasksMetadata } from './hashmasksMetadataParser'
import { JsonRpcProvider } from '@ethersproject/providers'
import { NftMetadata, TokenContractData, TokenData } from '../agent'
import { blitmapMetadataParser } from './blitmapMetadataParser'
import { parseKnownOriginMetadata } from './knownOrigin'

export type ParserResponse = Partial<NftMetadata>

Expand Down Expand Up @@ -39,7 +43,11 @@ export function parserLookup(
case MAKERSPLACE_TOKEN_ADDRESS:
return parseMakersplaceMetadata
case ZORA_TOKEN_ADDRESS:
return additionalMetadataParser
return zoraMetadataParser
case BLITMAP_TOKEN_ADDRESS:
return blitmapMetadataParser
case KNOWN_ORIGIN_TOKEN_ADDRESS:
return parseKnownOriginMetadata
default:
return
}
Expand Down
14 changes: 14 additions & 0 deletions src/parsers/knownOrigin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ParserConfig } from './index'

export async function parseKnownOriginMetadata(config: ParserConfig) {
const { baseMeta } = config
const baseAttributes: Record<string, any> = baseMeta.attributes || {}
const attributes = Object.keys(baseAttributes).map((trait_type) => ({
trait_type,
value: baseAttributes[trait_type],
}))

return {
attributes,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function translateMetadataSchema(schema: any) {
return schema
}

export async function additionalMetadataParser(
export async function zoraMetadataParser(
config: ParserConfig,
): Promise<ParserResponse> {
const { ipfsGateway, baseMeta, fetchTimeout, contractData } = config
Expand Down
7 changes: 7 additions & 0 deletions src/utils/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Erc721, Erc721Factory } from '@zoralabs/core/dist/typechain'
import { AddressZero } from '@ethersproject/constants'
import {
MAKERSPLACE_TOKEN_ADDRESS,
WRAPPED_CRYPTOPUNKS_TOKEN_ADDRESS,
ZORA_RINKEBY_TOKEN_ADDRESS,
ZORA_TOKEN_ADDRESS,
} from '../constants'
Expand Down Expand Up @@ -32,6 +33,11 @@ const registeredContracts: {
erc721Metadata: false,
erc721Enumerable: true,
},
[WRAPPED_CRYPTOPUNKS_TOKEN_ADDRESS]: {
erc721: true,
erc721Metadata: true,
erc721Enumerable: false,
},
}

export async function getSupportedInterfaces(
Expand Down Expand Up @@ -80,6 +86,7 @@ export async function fetchOwnerOf(
if (!canCatch) {
throw e
}
console.log(e)
const totalSupply = await contract.totalSupply()
if (
totalSupply.gte(tokenId) &&
Expand Down
71 changes: 71 additions & 0 deletions tests/contracts/__snapshots__/blitmap.int.test.ts.snap

Large diffs are not rendered by default.

135 changes: 135 additions & 0 deletions tests/contracts/__snapshots__/known-origin.int.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Known Origin ERC721 should be able to fetch and parse metadata for token id: 159330 on network: 1: 0xFBeef911Dc5821886e1dda71586d90eD28174B7d-159330 1`] = `
Object {
"attributes": Array [
Object {
"trait_type": "artist",
"value": "Brad Damico",
},
Object {
"trait_type": "scarcity",
"value": "rare",
},
Object {
"trait_type": "tags",
"value": Array [
"abstract",
"digital",
"generative",
"sine",
"waves",
"Wave Pool Series",
"artplusbrad",
"trigonometry",
"processing",
],
},
Object {
"trait_type": "asset_type",
"value": "image/jpeg",
},
],
"contentURL": "https://ipfs.infura.io/ipfs/QmQP1oirX9Vgq4Cm6frDo5tLB1UcSjVFXD4aTBCagdx842/asset.jpeg",
"contentURLMimeType": "image/jpeg",
"description": "Wave Pool Series
Generated with Processing",
"metadata": Object {
"attributes": Object {
"artist": "Brad Damico",
"asset_type": "image/jpeg",
"scarcity": "rare",
"tags": Array [
"abstract",
"digital",
"generative",
"sine",
"waves",
"Wave Pool Series",
"artplusbrad",
"trigonometry",
"processing",
],
},
"description": "Wave Pool Series
Generated with Processing",
"external_uri": "https://knownorigin.io/artists/0xd7e1bc51cd3f30e21b17bab33d77078e3fb7cc26",
"image": "https://ipfs.infura.io/ipfs/QmQP1oirX9Vgq4Cm6frDo5tLB1UcSjVFXD4aTBCagdx842/asset.jpeg",
"name": "Wave Pool 05 (2002 ON05)",
},
"name": "Wave Pool 05 (2002 ON05)",
"networkId": 1,
"tokenAddress": "0xFBeef911Dc5821886e1dda71586d90eD28174B7d",
"tokenId": "159330",
"tokenURI": "https://ipfs.infura.io/ipfs/QmUh8La6vxFTZqkwwe65Wcvx1CPHm7JWpf9Wm56DTVoCtQ",
"tokenURL": "https://ipfs.infura.io/ipfs/QmUh8La6vxFTZqkwwe65Wcvx1CPHm7JWpf9Wm56DTVoCtQ",
"tokenURLMimeType": "application/json",
}
`;

exports[`Known Origin ERC721 should be able to fetch and parse metadata for token id: 219184 on network: 1: 0xFBeef911Dc5821886e1dda71586d90eD28174B7d-219184 1`] = `
Object {
"attributes": Array [
Object {
"trait_type": "artist",
"value": "XCOPY",
},
Object {
"trait_type": "scarcity",
"value": "rare",
},
Object {
"trait_type": "tags",
"value": Array [
"doomed",
"KnownOrigin",
"cryptoart",
"hope",
"skull",
"technology",
],
},
Object {
"trait_type": "asset_type",
"value": "image/gif",
},
Object {
"trait_type": "asset_size_in_bytes",
"value": 621118,
},
],
"contentURL": "https://ipfs.infura.io/ipfs/QmXKQXNLe16vjuBPAAkw8fWaFBwAPjrVJtijvovbJv7tTJ/asset.gif",
"contentURLMimeType": "image/gif",
"description": "Tech still won't save us",
"metadata": Object {
"artist": "0x3768225622d53ffcc1e00eac53a2a870ecd825c8",
"attributes": Object {
"artist": "XCOPY",
"asset_size_in_bytes": 621118,
"asset_type": "image/gif",
"scarcity": "rare",
"tags": Array [
"doomed",
"KnownOrigin",
"cryptoart",
"hope",
"skull",
"technology",
],
},
"description": "Tech still won't save us",
"external_uri": "https://knownorigin.io/0x3768225622d53ffcc1e00eac53a2a870ecd825c8",
"image": "https://ipfs.infura.io/ipfs/QmXKQXNLe16vjuBPAAkw8fWaFBwAPjrVJtijvovbJv7tTJ/asset.gif",
"name": "The Doomed (red)",
},
"name": "The Doomed (red)",
"networkId": 1,
"tokenAddress": "0xFBeef911Dc5821886e1dda71586d90eD28174B7d",
"tokenId": "219184",
"tokenURI": "https://ipfs.infura.io/ipfs/QmYHU3Yc5QLiNHCDGA9Wn5cEW6hiRb64JGLdvUis9xrb8L",
"tokenURL": "https://ipfs.infura.io/ipfs/QmYHU3Yc5QLiNHCDGA9Wn5cEW6hiRb64JGLdvUis9xrb8L",
"tokenURLMimeType": "application/json",
}
`;
33 changes: 33 additions & 0 deletions tests/contracts/__snapshots__/wrapped-cryptopunks.int.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Wrapped Cryptopunks ERC721 should be able to fetch and parse metadata for token id: 18 on network: 1: 0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6-18 1`] = `
Object {
"networkId": 1,
"tokenAddress": "0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6",
"tokenId": "18",
"tokenURI": undefined,
}
`;

exports[`Wrapped Cryptopunks ERC721 should be able to fetch and parse metadata for token id: 5586 on network: 1: 0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6-5586 1`] = `
Object {
"contentURL": "https://wrappedpunks.com:3000/images/punks/5586.png",
"contentURLMimeType": "image/png",
"description": "This Punk was wrapped using Wrapped Punks contract, accessible from https://wrappedpunks.com",
"externalURL": "https://wrappedpunks.com",
"metadata": Object {
"description": "This Punk was wrapped using Wrapped Punks contract, accessible from https://wrappedpunks.com",
"external_url": "https://wrappedpunks.com",
"image": "https://wrappedpunks.com:3000/images/punks/5586.png",
"name": "W#5586",
"title": "W#5586",
},
"name": "W#5586",
"networkId": 1,
"tokenAddress": "0xb7F7F6C52F2e2fdb1963Eab30438024864c313F6",
"tokenId": "5586",
"tokenURI": "https://wrappedpunks.com:3000/api/punks/metadata/5586",
"tokenURL": "https://wrappedpunks.com:3000/api/punks/metadata/5586",
"tokenURLMimeType": "application/json; charset=utf-8",
}
`;
37 changes: 37 additions & 0 deletions tests/contracts/blitmap.int.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Agent, BLITMAP_TOKEN_ADDRESS } from '../../src'
import { testProvider } from '../setupProvider'
import { isAddress } from '@ethersproject/address'

const BLITMAP_CRITERIA = {
input: {
tokenId: '565',
tokenAddress: BLITMAP_TOKEN_ADDRESS,
networkId: 1,
},
}

describe('Blitmap ERC721', () => {
const parser = new Agent({
providers: {
1: testProvider,
},
ipfsGateway: 'https://ipfs.fleek.co',
fetchTimeout: 60000,
})

beforeEach(() => {
jest.setTimeout(120000)
})

it(`should be able to fetch and parse metadata for token id: ${BLITMAP_CRITERIA.input.tokenId} on network: ${BLITMAP_CRITERIA.input.networkId}`, async () => {
const { ownerAddress, ...meta } = await parser.fetchAndParseTokenData(
1,
BLITMAP_CRITERIA.input.tokenAddress,
BLITMAP_CRITERIA.input.tokenId,
)
expect(meta).toMatchSnapshot(
`${BLITMAP_CRITERIA.input.tokenAddress}-${BLITMAP_CRITERIA.input.tokenId}`,
)
expect(isAddress(ownerAddress)).toBeTruthy()
})
})
37 changes: 37 additions & 0 deletions tests/contracts/known-origin.int.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Agent, KNOWN_ORIGIN_TOKEN_ADDRESS } from '../../src'
import { testProvider } from '../setupProvider'
import { isAddress } from '@ethersproject/address'

const KO_CRITERIA = {
input: {
tokenId: '219184',
tokenAddress: KNOWN_ORIGIN_TOKEN_ADDRESS,
networkId: 1,
},
}

describe('Known Origin ERC721', () => {
const parser = new Agent({
providers: {
1: testProvider,
},
ipfsGateway: 'https://ipfs.fleek.co',
fetchTimeout: 60000,
})

beforeEach(() => {
jest.setTimeout(120000)
})

it(`should be able to fetch and parse metadata for token id: ${KO_CRITERIA.input.tokenId} on network: ${KO_CRITERIA.input.networkId}`, async () => {
const { ownerAddress, ...meta } = await parser.fetchAndParseTokenData(
1,
KO_CRITERIA.input.tokenAddress,
KO_CRITERIA.input.tokenId,
)
expect(meta).toMatchSnapshot(
`${KO_CRITERIA.input.tokenAddress}-${KO_CRITERIA.input.tokenId}`,
)
expect(isAddress(ownerAddress)).toBeTruthy()
})
})
Loading

0 comments on commit d40c488

Please sign in to comment.