Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
fix: Update for fetching LSP8 metadata based on token id type (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
dzbo authored Nov 16, 2023
1 parent 047f4bb commit 0e3cfa5
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 128 deletions.
4 changes: 2 additions & 2 deletions models/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class AssetModel extends BaseModel {
description: this.string(''),
links: this.attr([]),
tokenId: this.string(''),
tokenIdType: this.string(''),
tokenIdType: this.number(null),
isNativeToken: this.boolean(false),
hash: this.string(''),
verification: this.attr({}),
Expand All @@ -46,7 +46,7 @@ export class AssetModel extends BaseModel {
declare description?: string
declare links?: LinkMetadata[]
declare tokenId?: string
declare tokenIdType?: string
declare tokenIdType?: number
declare isNativeToken?: boolean
declare hash: string
declare verification?: ImageMetadata['verification']
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"typechain": "typechain --target web3-v1 --out-dir types/contracts/ './node_modules/@lukso/lsp-smart-contracts/artifacts/*.json'"
},
"devDependencies": {
"@erc725/erc725.js": "0.21.2",
"@erc725/erc725.js": "0.21.1",
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@formatjs/intl": "^2.9.6",
"@lukso/lsp-smart-contracts": "0.12.1",
Expand Down
2 changes: 1 addition & 1 deletion repositories/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class AssetRepository extends Repository<AssetModel> {
}

if (storageAsset.standard === 'LSP8IdentifiableDigitalAsset') {
assetData = await fetchLsp8Data(
assetData = await getLsp8Data(
assetAddress,
storageAsset?.tokenIdType,
storageAsset?.tokenId
Expand Down
51 changes: 0 additions & 51 deletions shared/schemas/LSP8IdentifiableDigitalAsset.json

This file was deleted.

18 changes: 12 additions & 6 deletions types/assets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { INTERFACE_IDS, ImageMetadata } from '@lukso/lsp-smart-contracts'
import {
INTERFACE_IDS,
ImageMetadata,
LSP8_TOKEN_ID_TYPES,
} from '@lukso/lsp-smart-contracts'

export type InterfaceId = keyof typeof INTERFACE_IDS

Expand All @@ -16,11 +20,13 @@ export enum AssetFilter {
created = 'created',
}

export enum Lsp8TokenIdType {
address = '1',
number = '2',
bytes32 = '3',
}
export const Lsp8TokenIdType = {
NUMBER: 0,
STRING: 1,
UNIQUE_ID: 2,
HASH: 3,
ADDRESS: 4,
} as typeof LSP8_TOKEN_ID_TYPES

export type Base64EncodedImage = `data:image/jpeg;base64${string}`

Expand Down
5 changes: 2 additions & 3 deletions utils/fetchAsset.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Asset } from '@/models/asset'

export const fetchAsset = async (
address: Address,
profileAddress?: Address,
tokenIds?: string[]
): Promise<Asset[]> => {
) => {
const standard = await detectStandard(address)

switch (standard) {
Expand All @@ -16,6 +14,7 @@ export const fetchAsset = async (
}

default:
console.warn(`Asset ${address} standard is not supported`)
return []
}
}
3 changes: 2 additions & 1 deletion utils/fetchLSP7Assets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import LSP7DigitalAsset from '@lukso/lsp-smart-contracts/artifacts/LSP7DigitalAsset.json'
import { AbiItem } from 'web3-utils'

import { ImageMetadataEncoded } from '@/types/assets'
import { LSP7DigitalAsset as LSP7DigitalAssetInterface } from '@/types/contracts'
Expand All @@ -13,7 +14,7 @@ export const fetchLsp7Assets = async (

const { contract } = useWeb3(PROVIDERS.RPC)
const lsp7Contract = contract<LSP7DigitalAssetInterface>(
LSP7DigitalAsset.abi as any,
LSP7DigitalAsset.abi as AbiItem[],
address
)
let balance = ''
Expand Down
5 changes: 3 additions & 2 deletions utils/fetchLSP8Assets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import LSP8IdentifiableDigitalAsset from '@lukso/lsp-smart-contracts/artifacts/LSP8IdentifiableDigitalAsset.json'
import { AbiItem } from 'web3-utils'

import { LSP8IdentifiableDigitalAsset as LSP8IdentifiableDigitalAssetInterface } from '@/types/contracts/LSP8IdentifiableDigitalAsset'
import { Asset } from '@/models/asset'
Expand All @@ -11,7 +12,7 @@ export const fetchLsp8Assets = async (
): Promise<Asset[]> => {
const { contract } = useWeb3(PROVIDERS.RPC)
const lsp8Contract = contract<LSP8IdentifiableDigitalAssetInterface>(
LSP8IdentifiableDigitalAsset.abi as any,
LSP8IdentifiableDigitalAsset.abi as AbiItem[],
address
)
const tokenSupply = await lsp8Contract.methods.totalSupply().call()
Expand All @@ -36,7 +37,7 @@ export const fetchLsp8Assets = async (
tokenId,
address
)
const getData = await fetchLsp8Data(address, tokenIdType, tokenId)
const getData = await getLsp8Data(address, tokenIdType, tokenId)
const {
description,
images: metadataImages,
Expand Down
3 changes: 2 additions & 1 deletion utils/fetchLsp7Balance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import LSP7DigitalAsset from '@lukso/lsp-smart-contracts/artifacts/LSP7DigitalAsset.json'
import { AbiItem } from 'web3-utils'

import { LSP7DigitalAsset as LSP7DigitalAssetInterface } from '@/types/contracts'

Expand All @@ -8,7 +9,7 @@ export const fetchLsp7Balance = async (
) => {
const { contract } = useWeb3(PROVIDERS.RPC)
const lsp7Contract = contract<LSP7DigitalAssetInterface>(
LSP7DigitalAsset.abi as any,
LSP7DigitalAsset.abi as AbiItem[],
assetAddress
)

Expand Down
95 changes: 52 additions & 43 deletions utils/fetchLsp8Metadata.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,46 @@
import { LSP4DigitalAssetMetadataJSON } from '@lukso/lsp-smart-contracts'
import { ERC725JSONSchema } from '@erc725/erc725.js'
import ERC725, { ERC725JSONSchema } from '@erc725/erc725.js'
import LSP8IdentifiableDigitalAsset from '@erc725/erc725.js/schemas/LSP8IdentifiableDigitalAsset.json'

import { Lsp8TokenIdType } from '@/types/assets'
import LSP8IdentifiableDigitalAsset from '@/shared/schemas/LSP8IdentifiableDigitalAsset.json'

export const fetchLsp8Metadata = async (
tokenId: string,
assetAddress: Address
): Promise<[LSP4DigitalAssetMetadataJSON, string]> => {
const lsp8MetadataGetter = async (
tokenIdType: string,
tokenId: string
): Promise<LSP4DigitalAssetMetadataJSON> => {
const lsp8Metadata = await erc725.fetchData({
keyName: `LSP8MetadataJSON:<${tokenIdType}>`,
dynamicKeyParts: tokenId,
})
return validateLsp4MetaData(lsp8Metadata.value)
}

): Promise<[LSP4DigitalAssetMetadataJSON, number]> => {
const { getInstance } = useErc725()
const erc725 = getInstance(
assetAddress,
LSP8IdentifiableDigitalAsset as ERC725JSONSchema[]
)

try {
const lsp8DigitalAsset = await erc725.fetchData(['LSP8TokenIdType'])
const tokenIdType = lsp8DigitalAsset[0].value?.toString()
const lsp8DigitalAsset = await erc725.fetchData('LSP8TokenIdType')
const tokenIdType = Number(lsp8DigitalAsset.value)

// fetch LSP8MetadataJSON depending on tokenIdType
// fetch metadata depending on tokenIdType
switch (tokenIdType) {
case Lsp8TokenIdType.address:
case Lsp8TokenIdType.NUMBER:
return [
await lsp8MetadataGetter(
'address',
// ethers.utils.hexDataSlice(tokenId.toString(), 12)
tokenId.toString()
),
await getMetadata(tokenIdType, parseInt(tokenId).toString(), erc725),
tokenIdType,
]
case Lsp8TokenIdType.number:
case Lsp8TokenIdType.STRING:
case Lsp8TokenIdType.UNIQUE_ID:
case Lsp8TokenIdType.HASH:
return [
await lsp8MetadataGetter('uint256', parseInt(tokenId).toString()),
await getMetadata(tokenIdType, tokenId.toString(), erc725),
tokenIdType,
]
case Lsp8TokenIdType.bytes32:
case Lsp8TokenIdType.ADDRESS:
return [
await lsp8MetadataGetter('bytes32', tokenId.toString()),
await getMetadata(tokenIdType, tokenId.slice(0, 42), erc725),
tokenIdType,
]
default:
return [
{
LSP4Metadata: {
description: '',
links: [],
images: [[]],
icon: [],
assets: [],
},
},
'',
]
throw new Error(
`Unsupported LSP8 tokenIdType '${tokenIdType}' for '${assetAddress}' asset`
)
}
} catch (error) {
console.error(error)
Expand All @@ -76,14 +54,31 @@ export const fetchLsp8Metadata = async (
assets: [],
},
},
'',
-1,
]
}
}

export const fetchLsp8Data = async (
const tokenIdTypeString = (tokenIdType: number) => {
switch (tokenIdType) {
case Lsp8TokenIdType.NUMBER:
return 'uint256'
case Lsp8TokenIdType.STRING:
return 'string'
case Lsp8TokenIdType.UNIQUE_ID:
return 'bytes32'
case Lsp8TokenIdType.HASH:
return 'bytes32'
case Lsp8TokenIdType.ADDRESS:
return 'address'
default:
throw new Error(`Unsupported LSP8 tokenIdType '${tokenIdType}'`)
}
}

export const getLsp8Data = async (
assetAddress: string,
tokenIdType?: string,
tokenIdType?: number,
tokenId?: string
) => {
if (!tokenIdType || !tokenId) {
Expand All @@ -96,9 +91,23 @@ export const fetchLsp8Data = async (
LSP8IdentifiableDigitalAsset as ERC725JSONSchema[]
)
const metaData = await erc725.getData({
keyName: `LSP8MetadataJSON:<${tokenIdType}>`,
keyName: `LSP8MetadataTokenURI:<${tokenIdTypeString(tokenIdType)}>`,
dynamicKeyParts: tokenId,
})

return metaData
}

const getMetadata = async (
tokenIdType: number,
tokenIdValue: string,
erc725: ERC725
) => {
const lsp8Metadata = await erc725.fetchData([
{
keyName: `LSP8MetadataTokenURI:<${tokenIdTypeString(tokenIdType)}>`,
dynamicKeyParts: tokenIdValue,
},
])
return validateLsp4MetaData(lsp8Metadata[0].value)
}
4 changes: 3 additions & 1 deletion utils/supportInterface.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AbiItem } from 'web3-utils'

import { LSP0ERC725Account } from '@/types/contracts'

/**
Expand All @@ -16,7 +18,7 @@ export const supportInterface = async (

try {
const eip165Contract = contract<LSP0ERC725Account>(
eip165ABI as any,
eip165ABI as AbiItem[],
address
)
return await eip165Contract.methods.supportsInterface(interfaceId).call()
Expand Down
8 changes: 5 additions & 3 deletions utils/validateLSP4Metadata.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Verification } from '@erc725/erc725.js/build/main/src/types'
import { LSP4DigitalAssetMetadataJSON } from '@lukso/lsp-smart-contracts'
import {
LSP4DigitalAssetMetadataJSON,
AssetMetadata,
} from '@lukso/lsp-smart-contracts'

export const validateLsp4MetaData = (
LSP4MetadataJSON: any
Expand Down Expand Up @@ -142,6 +144,6 @@ export const validateVerification = (getDataObject: any) => {
'verification' in getDataObject?.value &&
'data' in getDataObject?.value?.verification &&
'method' in getDataObject?.value?.verification
? (getDataObject.value?.verification as Verification)
? (getDataObject.value?.verification as AssetMetadata['verification'])
: undefined
}
Loading

0 comments on commit 0e3cfa5

Please sign in to comment.