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
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
```Typescript
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
import { assert } from 'chai'
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 {
Config,
@ -24,56 +14,43 @@ import {
Aquarius,
NftFactory,
NftCreateData,
Datatoken,
getHash,
ZERO_ADDRESS,
Nft
Nft,
downloadFile
} from '../../src'
```
import { ProviderFees, Erc20CreateParams } from '../../src/@types'
Here we define some variables that we will use later
```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 = [
const assetUrl = [
{
type: 'url',
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
method: 'GET'
}
]
```
Next, we define the metadata that will describe our data asset. This is what we call the DDO
```Typescript
const genericAsset: DDO = {
const ddo = {
'@context': ['https://w3id.org/did/v1'],
id: 'testFakeDid',
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',
name: 'dataset-name',
type: 'dataset',
description: 'Ocean protocol test dataset description',
author: 'oceanprotocol-team',
license: 'MIT',
tags: ['white-papers'],
additionalInformation: { 'test-key': 'test-value' },
links: ['http://data.ceda.ac.uk/badc/ukcp09/']
name: 'dfgdfgdg',
description: 'd dfgd fgd dfg dfgdfgd dfgdf',
tags: [''],
author: 'dd',
license: 'https://market.oceanprotocol.com/terms',
additionalInformation: {
termsAndConditions: true
}
},
services: [
{
id: 'testFakeId',
id: 'notAnId',
type: 'access',
description: 'Download service',
files: '',
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
@ -81,10 +58,8 @@ const genericAsset: DDO = {
}
]
}
```
## Publishing a dataset
```Typescript
## Simple Publish & consume test
let config: Config
let addresses: any
let aquarius: Aquarius
@ -95,247 +70,56 @@ const genericAsset: DDO = {
addresses = getAddresses()
aquarius = new Aquarius(config.metadataCacheUri)
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
```Typescript
const poolDdo: DDO = { ...genericAsset }
### should publish a dataset (create NFT + ERC20)
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: 'testNftPool',
symbol: 'TSTP',
name: 'testNFT',
symbol: 'TST',
templateIndex: 1,
tokenURI: '',
transferable: true,
owner: accounts[0]
owner: publisherAccount
}
const erc20Params: Erc20CreateParams = {
templateIndex: 1,
cap: '100000',
feeAmount: '0',
paymentCollector: ZERO_ADDRESS,
feeToken: ZERO_ADDRESS,
minter: accounts[0],
mpFeeAddress: ZERO_ADDRESS
paymentCollector: '0x0000000000000000000000000000000000000000',
feeToken: '0x0000000000000000000000000000000000000000',
minter: publisherAccount,
mpFeeAddress: '0x0000000000000000000000000000000000000000'
}
const poolParams: PoolCreationParams = {
ssContract: addresses.Staking,
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],
const result = await Factory.createNftWithErc20(
publisherAccount,
nftParams,
erc20Params,
poolParams
erc20Params
)
const erc721Address = result.events.NFTCreated.returnValues[0]
const datatokenAddress = result.events.TokenCreated.returnValues[0]
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0]
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0]
const poolAdress = bundleNFT.events.NewPool.returnValues[0]
const encryptedFiles = await ProviderInstance.encrypt(files, providerUrl)
poolDdo.metadata.name = 'test-dataset-pool'
poolDdo.services[0].files = await encryptedFiles
poolDdo.services[0].datatokenAddress = datatokenAddress
poolDdo.nftAddress = nftAddress
// 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()
poolDdo.chainId = chain
poolDdo.id =
'did:op:' + SHA256(web3.utils.toChecksumAddress(nftAddress) + chain.toString(10))
ddo.id =
'did:op:' + SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
const AssetValidation: ValidateMetadata = await aquarius.validate(poolDdo)
assert(AssetValidation.valid === true, 'Published asset is not valid')
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
providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
const encryptedResponse = await providerResponse
const metadataHash = getHash(JSON.stringify(ddo))
const res = await nft.setMetadata(
nftAddress,
accounts[0],
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],
erc721Address,
publisherAccount,
0,
providerUrl,
'',
@ -343,7 +127,51 @@ const genericAsset: DDO = {
encryptedResponse,
'0x' + metadataHash
)
const resolvedDDO = await aquarius.waitForAqua(dispenserDdo.id)
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

@ -1,6 +1,10 @@
#!/bin/bash
# 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
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 () => {
/// ```Typescript
/// ```Typescript
let config: Config
let addresses: any
let aquarius: Aquarius
@ -98,7 +98,7 @@ describe('Publishing a dataset', async () => {
}) /// ```
it('initialise testes classes', async () => {
/// ```Typescript
/// ```Typescript
nft = new Nft(web3)
factory = new NftFactory(addresses.ERC721Factory, web3)
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 () => {
/// ```Typescript
/// ```Typescript
const poolDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = {
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 () => {
/// ```Typescript
/// ```Typescript
const fixedPriceDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = {
name: 'testNftFre',
@ -272,9 +272,8 @@ describe('Publishing a dataset', async () => {
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
}) /// ```
it('should publish a dataset with dispenser (create NFT + ERC20 + dispenser) with no defined MetadataProof', async () => {
/// ```Typescript
/// ```Typescript
const dispenserDdo: DDO = { ...genericAsset }
const nftParams: NftCreateData = {
name: 'testNftDispenser',
@ -344,4 +343,4 @@ describe('Publishing a dataset', async () => {
const resolvedDDO = await aquarius.waitForAqua(dispenserDdo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
}) /// ```
}) ///
}) ///