mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Feat: add final did to tokenURI in NFT metadata (#1167)
* feat: set NFT metadata and tokenURI in a single transaction * feat: move token uri encoding in second publish transaction * feat: add final asset did in tokenURI * fix: edit metadata and computeDataset submit functions * feat: extract decodeTokenURI function * fix: revert to previous metadata edit flow * fix: revert to generateNftCreateData * feat: add final asset link in tokenURI description
This commit is contained in:
parent
ecad0ebb50
commit
bea8635a53
@ -5,7 +5,8 @@ import {
|
|||||||
getHash,
|
getHash,
|
||||||
Nft,
|
Nft,
|
||||||
ProviderInstance,
|
ProviderInstance,
|
||||||
DDO
|
DDO,
|
||||||
|
MetadataAndTokenURI
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
import { TransactionReceipt } from 'web3-core'
|
import { TransactionReceipt } from 'web3-core'
|
||||||
@ -45,17 +46,12 @@ function encodeSvg(svgString: string): string {
|
|||||||
export function generateNftMetadata(): NftMetadata {
|
export function generateNftMetadata(): NftMetadata {
|
||||||
const waves = new SvgWaves()
|
const waves = new SvgWaves()
|
||||||
const svg = waves.generateSvg()
|
const svg = waves.generateSvg()
|
||||||
|
|
||||||
// TODO: figure out if also image URI needs base64 encoding
|
|
||||||
// e.g. 'data:image/svg+xml;base64,'
|
|
||||||
// generated SVG embedded as 'data:image/svg+xml' and encoded characters
|
|
||||||
const imageData = `data:image/svg+xml,${encodeSvg(svg.outerHTML)}`
|
const imageData = `data:image/svg+xml,${encodeSvg(svg.outerHTML)}`
|
||||||
|
|
||||||
const newNft: NftMetadata = {
|
const newNft: NftMetadata = {
|
||||||
name: 'Ocean Asset NFT',
|
name: 'Ocean Asset NFT',
|
||||||
symbol: 'OCEAN-NFT',
|
symbol: 'OCEAN-NFT',
|
||||||
description: `This NFT represents an asset in the Ocean Protocol v4 ecosystem.`,
|
description: `This NFT represents an asset in the Ocean Protocol v4 ecosystem.`,
|
||||||
// TODO: ideally this includes the final DID
|
|
||||||
external_url: 'https://market.oceanprotocol.com',
|
external_url: 'https://market.oceanprotocol.com',
|
||||||
background_color: '141414', // dark background
|
background_color: '141414', // dark background
|
||||||
image_data: imageData
|
image_data: imageData
|
||||||
@ -65,18 +61,11 @@ export function generateNftMetadata(): NftMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function generateNftCreateData(nftMetadata: NftMetadata): any {
|
export function generateNftCreateData(nftMetadata: NftMetadata): any {
|
||||||
// TODO: figure out if Buffer.from method is working in browser in final build
|
|
||||||
// as BTOA is deprecated.
|
|
||||||
// tokenURI: window?.btoa(JSON.stringify(nftMetadata))
|
|
||||||
const encodedMetadata = Buffer.from(JSON.stringify(nftMetadata)).toString(
|
|
||||||
'base64'
|
|
||||||
)
|
|
||||||
|
|
||||||
const nftCreateData = {
|
const nftCreateData = {
|
||||||
name: nftMetadata.name,
|
name: nftMetadata.name,
|
||||||
symbol: nftMetadata.symbol,
|
symbol: nftMetadata.symbol,
|
||||||
templateIndex: 1,
|
templateIndex: 1,
|
||||||
tokenURI: `data:application/json;base64,${encodedMetadata}`
|
tokenURI: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
return nftCreateData
|
return nftCreateData
|
||||||
@ -129,3 +118,66 @@ export async function setNftMetadata(
|
|||||||
|
|
||||||
return setMetadataTx
|
return setMetadataTx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setNFTMetadataAndTokenURI(
|
||||||
|
asset: Asset | DDO,
|
||||||
|
accountId: string,
|
||||||
|
web3: Web3,
|
||||||
|
nftMetadata: NftMetadata,
|
||||||
|
signal: AbortSignal
|
||||||
|
): Promise<TransactionReceipt> {
|
||||||
|
const encryptedDdo = await ProviderInstance.encrypt(
|
||||||
|
asset,
|
||||||
|
asset.services[0].serviceEndpoint,
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
LoggerInstance.log(
|
||||||
|
'[setNFTMetadataAndTokenURI] Got encrypted DDO',
|
||||||
|
encryptedDdo
|
||||||
|
)
|
||||||
|
|
||||||
|
const metadataHash = getHash(JSON.stringify(asset))
|
||||||
|
|
||||||
|
// add final did to external_url and asset link to description in nftMetadata before encoding
|
||||||
|
const externalUrl = `${nftMetadata.external_url}/asset/${asset.id}`
|
||||||
|
const encodedMetadata = Buffer.from(
|
||||||
|
JSON.stringify({
|
||||||
|
...nftMetadata,
|
||||||
|
description: `${nftMetadata.description}\n\nView on Ocean Market: ${externalUrl}`,
|
||||||
|
external_url: externalUrl
|
||||||
|
})
|
||||||
|
).toString('base64')
|
||||||
|
const nft = new Nft(web3)
|
||||||
|
|
||||||
|
// theoretically used by aquarius or provider, not implemented yet, will remain hardcoded
|
||||||
|
const flags = '0x02'
|
||||||
|
|
||||||
|
const metadataAndTokenURI: MetadataAndTokenURI = {
|
||||||
|
metaDataState: 0,
|
||||||
|
metaDataDecryptorUrl: asset.services[0].serviceEndpoint,
|
||||||
|
metaDataDecryptorAddress: '',
|
||||||
|
flags,
|
||||||
|
data: encryptedDdo,
|
||||||
|
metaDataHash: '0x' + metadataHash,
|
||||||
|
tokenId: 1,
|
||||||
|
tokenURI: `data:application/json;base64,${encodedMetadata}`,
|
||||||
|
metadataProofs: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const estGasSetMetadataAndTokenURI = await nft.estGasSetMetadataAndTokenURI(
|
||||||
|
asset.nftAddress,
|
||||||
|
accountId,
|
||||||
|
metadataAndTokenURI
|
||||||
|
)
|
||||||
|
LoggerInstance.log(
|
||||||
|
'[setNFTMetadataAndTokenURI] est Gas set metadata and token uri --',
|
||||||
|
estGasSetMetadataAndTokenURI
|
||||||
|
)
|
||||||
|
const setMetadataAndTokenURITx = await nft.setMetadataAndTokenURI(
|
||||||
|
asset.nftAddress,
|
||||||
|
accountId,
|
||||||
|
metadataAndTokenURI
|
||||||
|
)
|
||||||
|
|
||||||
|
return setMetadataAndTokenURITx
|
||||||
|
}
|
||||||
|
@ -24,7 +24,7 @@ import {
|
|||||||
import { getOceanConfig } from '@utils/ocean'
|
import { getOceanConfig } from '@utils/ocean'
|
||||||
import { validationSchema } from './_validation'
|
import { validationSchema } from './_validation'
|
||||||
import { useAbortController } from '@hooks/useAbortController'
|
import { useAbortController } from '@hooks/useAbortController'
|
||||||
import { setNftMetadata } from '@utils/nft'
|
import { setNFTMetadataAndTokenURI } from '@utils/nft'
|
||||||
|
|
||||||
// TODO: restore FormikPersist, add back clear form action
|
// TODO: restore FormikPersist, add back clear form action
|
||||||
const formName = 'ocean-publish-form'
|
const formName = 'ocean-publish-form'
|
||||||
@ -173,10 +173,11 @@ export default function PublishPage({
|
|||||||
|
|
||||||
if (!_ddo || !_encryptedDdo) throw new Error('No DDO received.')
|
if (!_ddo || !_encryptedDdo) throw new Error('No DDO received.')
|
||||||
|
|
||||||
const res = await setNftMetadata(
|
const res = await setNFTMetadataAndTokenURI(
|
||||||
_ddo,
|
_ddo,
|
||||||
accountId,
|
accountId,
|
||||||
web3,
|
web3,
|
||||||
|
values.metadata.nft,
|
||||||
newAbortController()
|
newAbortController()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user