1
0
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:
Luca Milanese 2022-03-16 14:19:08 +01:00 committed by GitHub
parent ecad0ebb50
commit bea8635a53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 16 deletions

View File

@ -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
}

View File

@ -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()
) )