1
0
mirror of https://github.com/oceanprotocol/ocean.js.git synced 2024-11-26 20:39:05 +01:00

Creating markdown guide from simple publish consume flow

This commit is contained in:
Jamie Hewitt 2022-04-25 13:45:06 +02:00
parent d1a6b54ebf
commit f935f9f8a5
4 changed files with 286 additions and 278 deletions

View File

@ -1,22 +1,12 @@
# Ocean.js Code Examples # Ocean.js Code Examples
The following guide runs you through the process of using ocean.js in a publish flow. The code examples below are all working and you can learn how to publish by following along. The following guide runs you through the process of using ocean.js to publish and then consume a dataset. The code examples below are all working and you can learn how to publish by following along.
Start by importing all of the necessary dependencies Start by importing all of the necessary dependencies
```Typescript ```Typescript
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
import { assert } from 'chai'
import { SHA256 } from 'crypto-js' import { SHA256 } from 'crypto-js'
import { AbiItem } from 'web3-utils'
import {
ValidateMetadata,
DDO,
Erc20CreateParams,
PoolCreationParams,
FreCreationParams,
DispenserCreationParams
} from '../../src/@types'
import { web3, getTestConfig, getAddresses } from '../config' import { web3, getTestConfig, getAddresses } from '../config'
import { import {
Config, Config,
@ -24,56 +14,43 @@ import {
Aquarius, Aquarius,
NftFactory, NftFactory,
NftCreateData, NftCreateData,
Datatoken,
getHash, getHash,
ZERO_ADDRESS, Nft,
Nft downloadFile
} from '../../src' } from '../../src'
``` import { ProviderFees, Erc20CreateParams } from '../../src/@types'
Here we define some variables that we will use later const assetUrl = [
```Typescript
let nft: Nft
let factory: NftFactory
let accounts: string[]
```
We will need a file to publish, so here we define the file that we intend to publish.
```Typescript
const files = [
{ {
type: 'url', type: 'url',
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt', url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
method: 'GET' method: 'GET'
} }
] ]
``` const ddo = {
Next, we define the metadata that will describe our data asset. This is what we call the DDO
```Typescript
const genericAsset: DDO = {
'@context': ['https://w3id.org/did/v1'], '@context': ['https://w3id.org/did/v1'],
id: 'testFakeDid', id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
version: '4.0.0', version: '4.0.0',
chainId: 4, chainId: 4,
nftAddress: '0x0', nftAddress: '0x0',
metadata: { metadata: {
created: '2021-12-20T14:35:20Z', created: '2021-12-20T14:35:20Z',
updated: '2021-12-20T14:35:20Z', updated: '2021-12-20T14:35:20Z',
name: 'dataset-name',
type: 'dataset', type: 'dataset',
description: 'Ocean protocol test dataset description', name: 'dfgdfgdg',
author: 'oceanprotocol-team', description: 'd dfgd fgd dfg dfgdfgd dfgdf',
license: 'MIT', tags: [''],
tags: ['white-papers'], author: 'dd',
additionalInformation: { 'test-key': 'test-value' }, license: 'https://market.oceanprotocol.com/terms',
links: ['http://data.ceda.ac.uk/badc/ukcp09/'] additionalInformation: {
termsAndConditions: true
}
}, },
services: [ services: [
{ {
id: 'testFakeId', id: 'notAnId',
type: 'access', type: 'access',
description: 'Download service',
files: '', files: '',
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3', datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com', serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
@ -81,10 +58,8 @@ const genericAsset: DDO = {
} }
] ]
} }
```
## Publishing a dataset ## Simple Publish & consume test
```Typescript
let config: Config let config: Config
let addresses: any let addresses: any
let aquarius: Aquarius let aquarius: Aquarius
@ -95,247 +70,56 @@ const genericAsset: DDO = {
addresses = getAddresses() addresses = getAddresses()
aquarius = new Aquarius(config.metadataCacheUri) aquarius = new Aquarius(config.metadataCacheUri)
providerUrl = config.providerUri providerUrl = config.providerUri
```
### initialise testes classes
```Typescript
nft = new Nft(web3)
factory = new NftFactory(addresses.ERC721Factory, web3)
accounts = await web3.eth.getAccounts()
const daiContract = new web3.eth.Contract(
MockERC20.abi as AbiItem[],
addresses.MockDAI
)
await daiContract.methods
.approve(addresses.ERC721Factory, web3.utils.toWei('100000'))
.send({ from: accounts[0] })
}) })
```
### should publish a dataset with pool (create NFT + ERC20 + pool) and with Metdata proof ### should publish a dataset (create NFT + ERC20)
```Typescript const nft = new Nft(web3)
const poolDdo: DDO = { ...genericAsset } const datatoken = new Datatoken(web3)
const Factory = new NftFactory(addresses.ERC721Factory, web3)
const accounts = await web3.eth.getAccounts()
const publisherAccount = accounts[0]
const consumerAccount = accounts[1]
const nftParams: NftCreateData = { const nftParams: NftCreateData = {
name: 'testNftPool', name: 'testNFT',
symbol: 'TSTP', symbol: 'TST',
templateIndex: 1, templateIndex: 1,
tokenURI: '', tokenURI: '',
transferable: true, transferable: true,
owner: accounts[0] owner: publisherAccount
} }
const erc20Params: Erc20CreateParams = { const erc20Params: Erc20CreateParams = {
templateIndex: 1, templateIndex: 1,
cap: '100000', cap: '100000',
feeAmount: '0', feeAmount: '0',
paymentCollector: ZERO_ADDRESS, paymentCollector: '0x0000000000000000000000000000000000000000',
feeToken: ZERO_ADDRESS, feeToken: '0x0000000000000000000000000000000000000000',
minter: accounts[0], minter: publisherAccount,
mpFeeAddress: ZERO_ADDRESS mpFeeAddress: '0x0000000000000000000000000000000000000000'
} }
const poolParams: PoolCreationParams = { const result = await Factory.createNftWithErc20(
ssContract: addresses.Staking, publisherAccount,
baseTokenAddress: addresses.MockDAI,
baseTokenSender: addresses.ERC721Factory,
publisherAddress: accounts[0],
marketFeeCollector: accounts[0],
poolTemplateAddress: addresses.poolTemplate,
rate: '1',
baseTokenDecimals: 18,
vestingAmount: '10000',
vestedBlocks: 2500000,
initialBaseTokenLiquidity: '2000',
swapFeeLiquidityProvider: '0.001',
swapFeeMarketRunner: '0.001'
}
const bundleNFT = await factory.createNftErc20WithPool(
accounts[0],
nftParams, nftParams,
erc20Params, erc20Params
poolParams
) )
const erc721Address = result.events.NFTCreated.returnValues[0]
const datatokenAddress = result.events.TokenCreated.returnValues[0]
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0] // create the files encrypted string
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0] let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
const poolAdress = bundleNFT.events.NewPool.returnValues[0] ddo.services[0].files = await providerResponse
ddo.services[0].datatokenAddress = datatokenAddress
const encryptedFiles = await ProviderInstance.encrypt(files, providerUrl) // update ddo and set the right did
ddo.nftAddress = erc721Address
poolDdo.metadata.name = 'test-dataset-pool'
poolDdo.services[0].files = await encryptedFiles
poolDdo.services[0].datatokenAddress = datatokenAddress
poolDdo.nftAddress = nftAddress
const chain = await web3.eth.getChainId() const chain = await web3.eth.getChainId()
poolDdo.chainId = chain ddo.id =
poolDdo.id = 'did:op:' + SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
'did:op:' + SHA256(web3.utils.toChecksumAddress(nftAddress) + chain.toString(10))
const AssetValidation: ValidateMetadata = await aquarius.validate(poolDdo) providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
assert(AssetValidation.valid === true, 'Published asset is not valid') const encryptedResponse = await providerResponse
const metadataHash = getHash(JSON.stringify(ddo))
const encryptedDdo = await ProviderInstance.encrypt(poolDdo, providerUrl)
const encryptedResponse = await encryptedDdo
const metadataHash = getHash(JSON.stringify(poolDdo))
// just to make sure that our hash matches one computed by aquarius
assert(AssetValidation.hash === '0x' + metadataHash, 'Metadata hash is a missmatch')
const tx = await nft.setMetadata(
nftAddress,
accounts[0],
0,
providerUrl,
'',
'0x2',
encryptedResponse,
'0x' + metadataHash,
[AssetValidation.proof]
)
const resolvedDDO = await aquarius.waitForAqua(poolDdo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
})
```
### should publish a dataset with fixed price (create NFT + ERC20 + fixed price) with an explicit empty Metadata Proof
```Typescript
const fixedPriceDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = {
name: 'testNftFre',
symbol: 'TSTF',
templateIndex: 1,
tokenURI: '',
transferable: true,
owner: accounts[0]
}
const erc20Params: Erc20CreateParams = {
templateIndex: 1,
cap: '100000',
feeAmount: '0',
paymentCollector: ZERO_ADDRESS,
feeToken: ZERO_ADDRESS,
minter: accounts[0],
mpFeeAddress: ZERO_ADDRESS
}
const fixedPriceParams: FreCreationParams = {
fixedRateAddress: addresses.FixedPrice,
baseTokenAddress: addresses.MockDAI,
owner: accounts[0],
marketFeeCollector: accounts[0],
baseTokenDecimals: 18,
datatokenDecimals: 18,
fixedRate: '1',
marketFee: '0',
allowedConsumer: accounts[0],
withMint: false
}
const bundleNFT = await factory.createNftErc20WithFixedRate(
accounts[0],
nftParams,
erc20Params,
fixedPriceParams
)
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0]
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0]
const fixedPrice = bundleNFT.events.NewFixedRate.returnValues[0]
const encryptedFiles = await ProviderInstance.encrypt(files, providerUrl)
fixedPriceDdo.metadata.name = 'test-dataset-fixedPrice'
fixedPriceDdo.services[0].files = await encryptedFiles
fixedPriceDdo.services[0].datatokenAddress = datatokenAddress
fixedPriceDdo.nftAddress = nftAddress
const chain = await web3.eth.getChainId()
fixedPriceDdo.chainId = chain
fixedPriceDdo.id =
'did:op:' + SHA256(web3.utils.toChecksumAddress(nftAddress) + chain.toString(10))
const isAssetValid: ValidateMetadata = await aquarius.validate(fixedPriceDdo)
assert(isAssetValid.valid === true, 'Published asset is not valid')
const encryptedDdo = await ProviderInstance.encrypt(fixedPriceDdo, providerUrl)
const encryptedResponse = await encryptedDdo
const metadataHash = getHash(JSON.stringify(fixedPriceDdo))
// this is publishing with an explicit empty metadataProofs
const res = await nft.setMetadata( const res = await nft.setMetadata(
nftAddress, erc721Address,
accounts[0], publisherAccount,
0,
providerUrl,
'',
'0x2',
encryptedResponse,
'0x' + metadataHash,
[]
)
const resolvedDDO = await aquarius.waitForAqua(fixedPriceDdo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
```
### should publish a dataset with dispenser (create NFT + ERC20 + dispenser) with no defined MetadataProof
```Typescript
const dispenserDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = {
name: 'testNftDispenser',
symbol: 'TSTD',
templateIndex: 1,
tokenURI: '',
transferable: true,
owner: accounts[0]
}
const erc20Params: Erc20CreateParams = {
templateIndex: 1,
cap: '100000',
feeAmount: '0',
paymentCollector: ZERO_ADDRESS,
feeToken: ZERO_ADDRESS,
minter: accounts[0],
mpFeeAddress: ZERO_ADDRESS
}
const dispenserParams: DispenserCreationParams = {
dispenserAddress: addresses.Dispenser,
maxTokens: '1',
maxBalance: '1',
withMint: true,
allowedSwapper: ZERO_ADDRESS
}
const bundleNFT = await factory.createNftErc20WithDispenser(
accounts[0],
nftParams,
erc20Params,
dispenserParams
)
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0]
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0]
const dispenserAddress = bundleNFT.events.DispenserCreated.returnValues[0]
const encryptedFiles = await ProviderInstance.encrypt(files, providerUrl)
dispenserDdo.metadata.name = 'test-dataset-dispenser'
dispenserDdo.services[0].files = await encryptedFiles
dispenserDdo.services[0].datatokenAddress = datatokenAddress
dispenserDdo.nftAddress = nftAddress
const chain = await web3.eth.getChainId()
dispenserDdo.chainId = chain
dispenserDdo.id =
'did:op:' + SHA256(web3.utils.toChecksumAddress(nftAddress) + chain.toString(10))
const isAssetValid: ValidateMetadata = await aquarius.validate(dispenserDdo)
assert(isAssetValid.valid === true, 'Published asset is not valid')
const encryptedDdo = await ProviderInstance.encrypt(dispenserDdo, providerUrl)
const encryptedResponse = await encryptedDdo
const metadataHash = getHash(JSON.stringify(dispenserDdo))
// this is publishing with any explicit metadataProofs
const res = await nft.setMetadata(
nftAddress,
accounts[0],
0, 0,
providerUrl, providerUrl,
'', '',
@ -343,7 +127,51 @@ const genericAsset: DDO = {
encryptedResponse, encryptedResponse,
'0x' + metadataHash '0x' + metadataHash
) )
const resolvedDDO = await aquarius.waitForAqua(dispenserDdo.id) const resolvedDDO = await aquarius.waitForAqua(ddo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius') assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
``` // mint 1 ERC20 and send it to the consumer
await datatoken.mint(datatokenAddress, publisherAccount, '1', consumerAccount)
// initialize provider
const initializeData = await ProviderInstance.initialize(
resolvedDDO.id,
resolvedDDO.services[0].id,
0,
consumerAccount,
providerUrl
)
const providerFees: ProviderFees = {
providerFeeAddress: initializeData.providerFee.providerFeeAddress,
providerFeeToken: initializeData.providerFee.providerFeeToken,
providerFeeAmount: initializeData.providerFee.providerFeeAmount,
v: initializeData.providerFee.v,
r: initializeData.providerFee.r,
s: initializeData.providerFee.s,
providerData: initializeData.providerFee.providerData,
validUntil: initializeData.providerFee.validUntil
}
// make the payment
const txid = await datatoken.startOrder(
datatokenAddress,
consumerAccount,
consumerAccount,
0,
providerFees
)
// get the url
const downloadURL = await ProviderInstance.getDownloadUrl(
ddo.id,
consumerAccount,
ddo.services[0].id,
0,
txid.transactionHash,
providerUrl,
web3
)
assert(downloadURL, 'Provider getDownloadUrl failed')
try {
const fileData = await downloadFile(downloadURL)
} catch (e) {
assert.fail('Download failed')
}
})
})

View File

@ -1,6 +1,10 @@
#!/bin/bash #!/bin/bash
# Create markdown file # Create markdown file
cp test/integration/ReameFlow.test.ts CodeExamples.md cp test/integration/ReadmeFlow.test.ts CodeExamples.md
# Remove unneccessay imports
sed -i "s/import { assert } from 'chai'//" CodeExamples.md
# Replace comments # Replace comments
sed -i 's/}) \/\/\/ //' CodeExamples.md sed -i 's/}) \/\/\/ //' CodeExamples.md

View File

@ -0,0 +1,177 @@
/// # Ocean.js Code Examples
/// The following guide runs you through the process of using ocean.js to publish and then consume a dataset. The code examples below are all working and you can learn how to publish by following along.
/// Start by importing all of the necessary dependencies
/// ```Typescript
import { assert } from 'chai'
import { SHA256 } from 'crypto-js'
import { web3, getTestConfig, getAddresses } from '../config'
import {
Config,
ProviderInstance,
Aquarius,
NftFactory,
NftCreateData,
Datatoken,
getHash,
Nft,
downloadFile
} from '../../src'
import { ProviderFees, Erc20CreateParams } from '../../src/@types'
const assetUrl = [
{
type: 'url',
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
method: 'GET'
}
]
const ddo = {
'@context': ['https://w3id.org/did/v1'],
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
version: '4.0.0',
chainId: 4,
nftAddress: '0x0',
metadata: {
created: '2021-12-20T14:35:20Z',
updated: '2021-12-20T14:35:20Z',
type: 'dataset',
name: 'dfgdfgdg',
description: 'd dfgd fgd dfg dfgdfgd dfgdf',
tags: [''],
author: 'dd',
license: 'https://market.oceanprotocol.com/terms',
additionalInformation: {
termsAndConditions: true
}
},
services: [
{
id: 'notAnId',
type: 'access',
files: '',
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
timeout: 0
}
]
}
describe('Simple Publish & consume test', async () => {
let config: Config
let addresses: any
let aquarius: Aquarius
let providerUrl: any
before(async () => {
config = await getTestConfig(web3)
addresses = getAddresses()
aquarius = new Aquarius(config.metadataCacheUri)
providerUrl = config.providerUri
})
it('should publish a dataset (create NFT + ERC20)', async () => {
const nft = new Nft(web3)
const datatoken = new Datatoken(web3)
const Factory = new NftFactory(addresses.ERC721Factory, web3)
const accounts = await web3.eth.getAccounts()
const publisherAccount = accounts[0]
const consumerAccount = accounts[1]
const nftParams: NftCreateData = {
name: 'testNFT',
symbol: 'TST',
templateIndex: 1,
tokenURI: '',
transferable: true,
owner: publisherAccount
}
const erc20Params: Erc20CreateParams = {
templateIndex: 1,
cap: '100000',
feeAmount: '0',
paymentCollector: '0x0000000000000000000000000000000000000000',
feeToken: '0x0000000000000000000000000000000000000000',
minter: publisherAccount,
mpFeeAddress: '0x0000000000000000000000000000000000000000'
}
const result = await Factory.createNftWithErc20(
publisherAccount,
nftParams,
erc20Params
)
const erc721Address = result.events.NFTCreated.returnValues[0]
const datatokenAddress = result.events.TokenCreated.returnValues[0]
// create the files encrypted string
let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
ddo.services[0].files = await providerResponse
ddo.services[0].datatokenAddress = datatokenAddress
// update ddo and set the right did
ddo.nftAddress = erc721Address
const chain = await web3.eth.getChainId()
ddo.id =
'did:op:' + SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
const encryptedResponse = await providerResponse
const metadataHash = getHash(JSON.stringify(ddo))
const res = await nft.setMetadata(
erc721Address,
publisherAccount,
0,
providerUrl,
'',
'0x2',
encryptedResponse,
'0x' + metadataHash
)
const resolvedDDO = await aquarius.waitForAqua(ddo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
// mint 1 ERC20 and send it to the consumer
await datatoken.mint(datatokenAddress, publisherAccount, '1', consumerAccount)
// initialize provider
const initializeData = await ProviderInstance.initialize(
resolvedDDO.id,
resolvedDDO.services[0].id,
0,
consumerAccount,
providerUrl
)
const providerFees: ProviderFees = {
providerFeeAddress: initializeData.providerFee.providerFeeAddress,
providerFeeToken: initializeData.providerFee.providerFeeToken,
providerFeeAmount: initializeData.providerFee.providerFeeAmount,
v: initializeData.providerFee.v,
r: initializeData.providerFee.r,
s: initializeData.providerFee.s,
providerData: initializeData.providerFee.providerData,
validUntil: initializeData.providerFee.validUntil
}
// make the payment
const txid = await datatoken.startOrder(
datatokenAddress,
consumerAccount,
consumerAccount,
0,
providerFees
)
// get the url
const downloadURL = await ProviderInstance.getDownloadUrl(
ddo.id,
consumerAccount,
ddo.services[0].id,
0,
txid.transactionHash,
providerUrl,
web3
)
assert(downloadURL, 'Provider getDownloadUrl failed')
try {
const fileData = await downloadFile(downloadURL)
} catch (e) {
assert.fail('Download failed')
}
})
})

View File

@ -84,7 +84,7 @@ const genericAsset: DDO = {
/// ``` /// ```
describe('Publishing a dataset', async () => { describe('Publishing a dataset', async () => {
/// ```Typescript /// ```Typescript
let config: Config let config: Config
let addresses: any let addresses: any
let aquarius: Aquarius let aquarius: Aquarius
@ -98,7 +98,7 @@ describe('Publishing a dataset', async () => {
}) /// ``` }) /// ```
it('initialise testes classes', async () => { it('initialise testes classes', async () => {
/// ```Typescript /// ```Typescript
nft = new Nft(web3) nft = new Nft(web3)
factory = new NftFactory(addresses.ERC721Factory, web3) factory = new NftFactory(addresses.ERC721Factory, web3)
accounts = await web3.eth.getAccounts() accounts = await web3.eth.getAccounts()
@ -112,7 +112,7 @@ describe('Publishing a dataset', async () => {
}) /// ``` }) /// ```
it('should publish a dataset with pool (create NFT + ERC20 + pool) and with Metdata proof', async () => { it('should publish a dataset with pool (create NFT + ERC20 + pool) and with Metdata proof', async () => {
/// ```Typescript /// ```Typescript
const poolDdo: DDO = { ...genericAsset } const poolDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = { const nftParams: NftCreateData = {
name: 'testNftPool', name: 'testNftPool',
@ -194,7 +194,7 @@ describe('Publishing a dataset', async () => {
}) /// ``` }) /// ```
it('should publish a dataset with fixed price (create NFT + ERC20 + fixed price) with an explicit empty Metadata Proof', async () => { it('should publish a dataset with fixed price (create NFT + ERC20 + fixed price) with an explicit empty Metadata Proof', async () => {
/// ```Typescript /// ```Typescript
const fixedPriceDdo: DDO = { ...genericAsset } const fixedPriceDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = { const nftParams: NftCreateData = {
name: 'testNftFre', name: 'testNftFre',
@ -272,9 +272,8 @@ describe('Publishing a dataset', async () => {
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius') assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
}) /// ``` }) /// ```
it('should publish a dataset with dispenser (create NFT + ERC20 + dispenser) with no defined MetadataProof', async () => { it('should publish a dataset with dispenser (create NFT + ERC20 + dispenser) with no defined MetadataProof', async () => {
/// ```Typescript /// ```Typescript
const dispenserDdo: DDO = { ...genericAsset } const dispenserDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = { const nftParams: NftCreateData = {
name: 'testNftDispenser', name: 'testNftDispenser',
@ -344,4 +343,4 @@ describe('Publishing a dataset', async () => {
const resolvedDDO = await aquarius.waitForAqua(dispenserDdo.id) const resolvedDDO = await aquarius.waitForAqua(dispenserDdo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius') assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
}) /// ``` }) /// ```
}) /// }) ///