mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
merge main and fixed conflicts
This commit is contained in:
commit
452bf22855
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@ -113,6 +113,7 @@ jobs:
|
||||
working-directory: ${{ github.workspace }}/barge
|
||||
run: |
|
||||
bash -x start_ocean.sh --with-provider2 --no-dashboard --with-c2d 2>&1 > start_ocean.log &
|
||||
|
||||
- run: npm ci
|
||||
- run: npm run build:metadata
|
||||
|
||||
|
104
CHANGELOG.md
104
CHANGELOG.md
@ -4,8 +4,112 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v1.1.8](https://github.com/oceanprotocol/ocean.js/compare/v1.1.7...v1.1.8)
|
||||
|
||||
- Let do any query in Aquarius [`#1576`](https://github.com/oceanprotocol/ocean.js/pull/1576)
|
||||
- let do any query in Aquarius [`02b805a`](https://github.com/oceanprotocol/ocean.js/commit/02b805a45ddbc77a0d4675a06e73b31d0494d55f)
|
||||
|
||||
#### [v1.1.7](https://github.com/oceanprotocol/ocean.js/compare/v1.1.6...v1.1.7)
|
||||
|
||||
> 2 August 2022
|
||||
|
||||
- Issue-#1556: Add nft.setData() function [`#1558`](https://github.com/oceanprotocol/ocean.js/pull/1558)
|
||||
- Bump terser from 5.10.0 to 5.14.2 [`#1564`](https://github.com/oceanprotocol/ocean.js/pull/1564)
|
||||
- Issue-#1557: Add Aquarius.getAssetMetadata() and Aquarius.querySearch() functions [`#1560`](https://github.com/oceanprotocol/ocean.js/pull/1560)
|
||||
- fix download [`#1563`](https://github.com/oceanprotocol/ocean.js/pull/1563)
|
||||
- add querySearch() function [`8b952c6`](https://github.com/oceanprotocol/ocean.js/commit/8b952c6b05c50f3f29f2e4b44ace443adf07f10e)
|
||||
- add getAssetMetadata() function [`76471f3`](https://github.com/oceanprotocol/ocean.js/commit/76471f367784360725ff05784a0b017be7c947c9)
|
||||
- add setData function to NFT [`fc78894`](https://github.com/oceanprotocol/ocean.js/commit/fc78894753e2f24dd167a8e90401b56b1af938f8)
|
||||
|
||||
#### [v1.1.6](https://github.com/oceanprotocol/ocean.js/compare/v1.1.5...v1.1.6)
|
||||
|
||||
> 11 July 2022
|
||||
|
||||
- get files checksum using fileInfo helper [`#1555`](https://github.com/oceanprotocol/ocean.js/pull/1555)
|
||||
- review provider URL [`#1554`](https://github.com/oceanprotocol/ocean.js/pull/1554)
|
||||
- CI updates [`#1503`](https://github.com/oceanprotocol/ocean.js/pull/1503)
|
||||
- Bump @typescript-eslint/eslint-plugin from 5.30.4 to 5.30.5 [`#1551`](https://github.com/oceanprotocol/ocean.js/pull/1551)
|
||||
- Bump @typescript-eslint/parser from 5.30.4 to 5.30.5 [`#1550`](https://github.com/oceanprotocol/ocean.js/pull/1550)
|
||||
- add digest [`#1549`](https://github.com/oceanprotocol/ocean.js/pull/1549)
|
||||
- Bump @typescript-eslint/eslint-plugin from 5.30.0 to 5.30.4 [`#1548`](https://github.com/oceanprotocol/ocean.js/pull/1548)
|
||||
- Bump @types/node from 18.0.0 to 18.0.1 [`#1547`](https://github.com/oceanprotocol/ocean.js/pull/1547)
|
||||
- Bump typedoc from 0.23.2 to 0.23.5 [`#1542`](https://github.com/oceanprotocol/ocean.js/pull/1542)
|
||||
- Bump eslint from 8.18.0 to 8.19.0 [`#1543`](https://github.com/oceanprotocol/ocean.js/pull/1543)
|
||||
- Bump @truffle/hdwallet-provider from 2.0.9 to 2.0.10 [`#1544`](https://github.com/oceanprotocol/ocean.js/pull/1544)
|
||||
- Bump @typescript-eslint/parser from 5.30.0 to 5.30.4 [`#1545`](https://github.com/oceanprotocol/ocean.js/pull/1545)
|
||||
- Bump ts-node from 10.8.0 to 10.8.2 [`#1546`](https://github.com/oceanprotocol/ocean.js/pull/1546)
|
||||
- Bump eslint-plugin-prettier from 4.1.0 to 4.2.1 [`#1541`](https://github.com/oceanprotocol/ocean.js/pull/1541)
|
||||
- Release 1.1.6 [`bbab53c`](https://github.com/oceanprotocol/ocean.js/commit/bbab53c7bfe81b2c6bcbbcd9b02a1023dc59a5fb)
|
||||
- add checksum param when fetching fileinfo and checksum aatribute to fileinfo interface [`00f776d`](https://github.com/oceanprotocol/ocean.js/commit/00f776d5404e0f5c8f7eec36460a65e258a69d81)
|
||||
|
||||
#### [v1.1.5](https://github.com/oceanprotocol/ocean.js/compare/v1.1.4...v1.1.5)
|
||||
|
||||
> 30 June 2022
|
||||
|
||||
- changed consume with orders [`#1540`](https://github.com/oceanprotocol/ocean.js/pull/1540)
|
||||
- Release 1.1.5 [`db6c0b5`](https://github.com/oceanprotocol/ocean.js/commit/db6c0b5e98b61264f7ee58bfc9b9fe4db71f4d2b)
|
||||
|
||||
#### [v1.1.4](https://github.com/oceanprotocol/ocean.js/compare/v1.1.3...v1.1.4)
|
||||
|
||||
> 29 June 2022
|
||||
|
||||
- fix conversion [`#1538`](https://github.com/oceanprotocol/ocean.js/pull/1538)
|
||||
- Bump release-it from 15.1.0 to 15.1.1 [`#1536`](https://github.com/oceanprotocol/ocean.js/pull/1536)
|
||||
- Bump eslint-plugin-prettier from 4.0.0 to 4.1.0 [`#1531`](https://github.com/oceanprotocol/ocean.js/pull/1531)
|
||||
- Bump @typescript-eslint/eslint-plugin from 5.29.0 to 5.30.0 [`#1533`](https://github.com/oceanprotocol/ocean.js/pull/1533)
|
||||
- Bump typedoc from 0.22.17 to 0.23.2 [`#1535`](https://github.com/oceanprotocol/ocean.js/pull/1535)
|
||||
- Bump @typescript-eslint/parser from 5.29.0 to 5.30.0 [`#1534`](https://github.com/oceanprotocol/ocean.js/pull/1534)
|
||||
- Release 1.1.4 [`ecc7226`](https://github.com/oceanprotocol/ocean.js/commit/ecc7226781fceaddb45612ef11ad08e36ef08eb2)
|
||||
|
||||
#### [v1.1.3](https://github.com/oceanprotocol/ocean.js/compare/v1.1.2...v1.1.3)
|
||||
|
||||
> 24 June 2022
|
||||
|
||||
- Proper conversion to wei of base token when ordering [`#1527`](https://github.com/oceanprotocol/ocean.js/pull/1527)
|
||||
- Bump release-it from 15.0.0 to 15.1.0 [`#1526`](https://github.com/oceanprotocol/ocean.js/pull/1526)
|
||||
- Bump @typescript-eslint/parser from 5.28.0 to 5.29.0 [`#1523`](https://github.com/oceanprotocol/ocean.js/pull/1523)
|
||||
- Bump @typescript-eslint/eslint-plugin from 5.28.0 to 5.29.0 [`#1522`](https://github.com/oceanprotocol/ocean.js/pull/1522)
|
||||
- Bump typescript from 4.6.4 to 4.7.4 [`#1520`](https://github.com/oceanprotocol/ocean.js/pull/1520)
|
||||
- Bump eslint from 8.17.0 to 8.18.0 [`#1521`](https://github.com/oceanprotocol/ocean.js/pull/1521)
|
||||
- Bump web3 from 1.7.3 to 1.7.4 [`#1525`](https://github.com/oceanprotocol/ocean.js/pull/1525)
|
||||
- Bump prettier from 2.7.0 to 2.7.1 [`#1519`](https://github.com/oceanprotocol/ocean.js/pull/1519)
|
||||
- Bump @types/node from 17.0.44 to 18.0.0 [`#1515`](https://github.com/oceanprotocol/ocean.js/pull/1515)
|
||||
- Bump @truffle/hdwallet-provider from 2.0.8 to 2.0.9 [`#1516`](https://github.com/oceanprotocol/ocean.js/pull/1516)
|
||||
- Bump eslint-config-oceanprotocol from 2.0.1 to 2.0.3 [`#1518`](https://github.com/oceanprotocol/ocean.js/pull/1518)
|
||||
- Bump prettier from 2.6.2 to 2.7.0 [`#1517`](https://github.com/oceanprotocol/ocean.js/pull/1517)
|
||||
- Bump typedoc from 0.22.15 to 0.22.17 [`#1514`](https://github.com/oceanprotocol/ocean.js/pull/1514)
|
||||
- Release 1.1.3 [`7772e93`](https://github.com/oceanprotocol/ocean.js/commit/7772e9387ef9d63f98ea80cfd4eefbea963dd0ad)
|
||||
|
||||
#### [v1.1.2](https://github.com/oceanprotocol/ocean.js/compare/v1.1.1...v1.1.2)
|
||||
|
||||
> 15 June 2022
|
||||
|
||||
- Release 1.1.2 [`85bf271`](https://github.com/oceanprotocol/ocean.js/commit/85bf2716e26d8691aeb9d5504e563d557419dc2e)
|
||||
- manual bump fix [`5674a54`](https://github.com/oceanprotocol/ocean.js/commit/5674a547d1d367ce88b3595f0be8ebbf12274266)
|
||||
|
||||
#### [v1.1.1](https://github.com/oceanprotocol/ocean.js/compare/v1.1.0...v1.1.1)
|
||||
|
||||
> 15 June 2022
|
||||
|
||||
- Release 1.1.1 [`ea48e01`](https://github.com/oceanprotocol/ocean.js/commit/ea48e015ac8299f71d57a929f8f30c5d1a8446e7)
|
||||
- manual bump fix [`a362410`](https://github.com/oceanprotocol/ocean.js/commit/a36241004b1d9578ec5c02d9d6e64d9750c53a7b)
|
||||
|
||||
#### [v1.1.0](https://github.com/oceanprotocol/ocean.js/compare/v1.0.0...v1.1.0)
|
||||
|
||||
> 15 June 2022
|
||||
|
||||
- Issue-#1485: Remove imports of ABIs in the tests and use utility tranfer(), mint(), balance() functions [`#1486`](https://github.com/oceanprotocol/ocean.js/pull/1486)
|
||||
- Bump @types/node from 17.0.35 to 17.0.44 [`#1513`](https://github.com/oceanprotocol/ocean.js/pull/1513)
|
||||
- Bump eslint-config-oceanprotocol from 1.5.0 to 2.0.1 [`#1466`](https://github.com/oceanprotocol/ocean.js/pull/1466)
|
||||
- update to new schema & compute fixes [`#1510`](https://github.com/oceanprotocol/ocean.js/pull/1510)
|
||||
- Release 1.1.0 [`112c27e`](https://github.com/oceanprotocol/ocean.js/commit/112c27edab58ef0681ea3e87fb09978411924753)
|
||||
|
||||
#### [v1.0.0](https://github.com/oceanprotocol/ocean.js/compare/v1.0.0-next.45...v1.0.0)
|
||||
|
||||
> 8 June 2022
|
||||
|
||||
- Release 1.0.0 [`04735dd`](https://github.com/oceanprotocol/ocean.js/commit/04735dd8243f4aa292e4550f83f11bf41ba11997)
|
||||
|
||||
#### [v1.0.0-next.45](https://github.com/oceanprotocol/ocean.js/compare/v1.0.0-next.44...v1.0.0-next.45)
|
||||
|
||||
> 5 June 2022
|
||||
|
201
CodeExamples.md
201
CodeExamples.md
@ -28,7 +28,9 @@ Here are the steps:
|
||||
8. [Publish Data NFT and a Datatoken with a dispenser](#-publish-data-nft-and-a-datatoken-with-a-dispenser)
|
||||
|
||||
## 0. Prerequisites
|
||||
|
||||
Before we start it is important that you have all of the necessary prerequisites installed on your computer.
|
||||
|
||||
- **A Unix based operating system (Linux or Mac)**. If you are a Windows user you can try to run linux inside a virtual machine but this is outside of the scope of this article.
|
||||
- **Git**. Instructions for installing Git can be found here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
|
||||
- **Node.js** can be downloaded from here: https://nodejs.org/en/download/
|
||||
@ -98,6 +100,7 @@ import {
|
||||
DispenserCreationParams,
|
||||
downloadFile,
|
||||
DatatokenCreateParams,
|
||||
Files,
|
||||
FixedRateExchange,
|
||||
FreCreationParams,
|
||||
getHash,
|
||||
@ -142,6 +145,7 @@ Now we define the variables which we will need later
|
||||
```
|
||||
|
||||
We also define some constants that we will use:
|
||||
|
||||
```Typescript
|
||||
const POOL_NFT_NAME = 'Datatoken 1'
|
||||
const POOL_NFT_SYMBOL = 'DT1'
|
||||
@ -151,23 +155,29 @@ We also define some constants that we will use:
|
||||
const DISP_NFT_SYMBOL = 'DT3'
|
||||
```
|
||||
|
||||
We will need a file to publish, so here we define the file that we intend to publish.
|
||||
We will need a file to publish, so here we define the file that we intend to publish.
|
||||
|
||||
```Typescript
|
||||
const ASSET_URL = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const ASSET_URL: Files = {
|
||||
datatokenAddress: '0x0',
|
||||
nftAddress: '0x0',
|
||||
files: [
|
||||
{
|
||||
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 DDO = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: '',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -185,7 +195,7 @@ Next, we define the metadata that will describe our data asset. This is what we
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0x0',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
@ -193,53 +203,63 @@ Next, we define the metadata that will describe our data asset. This is what we
|
||||
```
|
||||
|
||||
We load the configuration:
|
||||
|
||||
```Typescript
|
||||
|
||||
|
||||
config = await getTestConfig(web3)
|
||||
aquarius = new Aquarius(config.metadataCacheUri)
|
||||
providerUrl = config.providerUri
|
||||
```
|
||||
|
||||
As we go along it's a good idea to console log the values so that you check they are right
|
||||
|
||||
```Typescript
|
||||
console.log(`Aquarius URL: ${config.metadataCacheUri}`)
|
||||
console.log(`Provider URL: ${providerUrl}`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 5. Initialize accounts and deploy contracts
|
||||
### 5.1 Initialize accounts
|
||||
|
||||
### 5.1 Initialize accounts
|
||||
|
||||
```Typescript
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
publisherAccount = accounts[0]
|
||||
consumerAccount = accounts[1]
|
||||
stakerAccount = accounts[2]
|
||||
```
|
||||
|
||||
Again, lets console log the values so that we can check that they have been saved properly
|
||||
|
||||
```Typescript
|
||||
console.log(`Publisher account address: ${publisherAccount}`)
|
||||
console.log(`Consumer account address: ${consumerAccount}`)
|
||||
console.log(`Staker account address: ${stakerAccount}`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 5.2 Next, lets get the address of the deployed contracts
|
||||
### 5.2 Next, lets get the address of the deployed contracts
|
||||
|
||||
```Typescript
|
||||
addresses = getAddresses()
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 5.3 We send some OCEAN to consumer and staker accounts
|
||||
### 5.3 We send some OCEAN to consumer and staker accounts
|
||||
|
||||
```Typescript
|
||||
transfer(web3, publisherAccount, addresses.Ocean, consumerAccount, '100')
|
||||
transfer(web3, publisherAccount, addresses.Ocean, stakerAccount, '100')
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 6. Publish Data NFT and a Datatoken with a liquidity pool
|
||||
|
||||
For pool creation, the OCEAN token is used as the base token. The base token can be changed into something else, such as USDC, DAI etc., but it will require an extra fee.
|
||||
|
||||
### 6.1 Publish a dataset (create NFT + Datatoken) with a liquidity pool
|
||||
### 6.1 Publish a dataset (create NFT + Datatoken) with a liquidity pool
|
||||
|
||||
```Typescript
|
||||
const factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
|
||||
@ -278,7 +298,9 @@ For pool creation, the OCEAN token is used as the base token. The base token can
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
```
|
||||
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
|
||||
```Typescript
|
||||
await approve(
|
||||
web3,
|
||||
@ -289,7 +311,9 @@ Before we call the contract we have to call `approve` so that the contract can m
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
Now we can make the contract call
|
||||
|
||||
```Typescript
|
||||
const tx = await factory.createNftWithDatatokenWithPool(
|
||||
publisherAccount,
|
||||
@ -302,19 +326,24 @@ Now we can make the contract call
|
||||
poolDatatokenAddress = tx.events.TokenCreated.returnValues[0]
|
||||
poolAddress = tx.events.NewPool.returnValues[0]
|
||||
```
|
||||
|
||||
Now, we did quite a few things there. Let's check that we successfully published a dataset (create NFT + Datatoken) with a liquidity pool
|
||||
|
||||
```Typescript
|
||||
console.log(`Pool NFT address: ${poolNftAddress}`)
|
||||
console.log(`Pool Datatoken address: ${poolDatatokenAddress}`)
|
||||
console.log(`Pool address: ${poolAddress}`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 6.2 Set metadata in the pool NFT
|
||||
### 6.2 Set metadata in the pool NFT
|
||||
|
||||
```Typescript
|
||||
const nft = new Nft(web3)
|
||||
```
|
||||
|
||||
Now we update the ddo and set the right did
|
||||
|
||||
```Typescript
|
||||
DDO.chainId = await web3.eth.getChainId()
|
||||
DDO.id =
|
||||
@ -322,13 +351,19 @@ Now we update the ddo and set the right did
|
||||
SHA256(web3.utils.toChecksumAddress(poolNftAddress) + DDO.chainId.toString(10))
|
||||
DDO.nftAddress = poolNftAddress
|
||||
```
|
||||
|
||||
Next we encrypt the file or files using Ocean Provider. The provider is an off chain proxy built specifically for this task
|
||||
|
||||
```Typescript
|
||||
ASSET_URL.datatokenAddress = poolDatatokenAddress
|
||||
ASSET_URL.nftAddress = poolNftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = poolDatatokenAddress
|
||||
```
|
||||
|
||||
Now let's console log the result to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`DID: ${DDO.id}`)
|
||||
|
||||
@ -345,26 +380,32 @@ Now let's console log the result to check everything is working
|
||||
encryptedDDO,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 6.3 User should add liquidity to the pool, receiving LP tokens
|
||||
### 6.3 User should add liquidity to the pool, receiving LP tokens
|
||||
|
||||
```Typescript
|
||||
const pool = new Pool(web3)
|
||||
|
||||
```
|
||||
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
|
||||
```Typescript
|
||||
await approve(web3, stakerAccount, addresses.Ocean, poolAddress, '5', true)
|
||||
|
||||
```
|
||||
|
||||
Now we can make the contract call
|
||||
|
||||
```Typescript
|
||||
await pool.joinswapExternAmountIn(stakerAccount, poolAddress, '5', '0.1')
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 6.4 Marketplace displays pool asset for sale
|
||||
### 6.4 Marketplace displays pool asset for sale
|
||||
|
||||
```Typescript
|
||||
const pool = new Pool(web3)
|
||||
const prices = await pool.getAmountInExactOut(
|
||||
@ -375,34 +416,45 @@ Now we can make the contract call
|
||||
'0.01'
|
||||
)
|
||||
```
|
||||
|
||||
Now let's console log the result to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Price of 1 ${POOL_NFT_SYMBOL} is ${prices.tokenAmount} OCEAN`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 6.5 Consumer buys a pool data asset, and downloads it
|
||||
### 6.5 Consumer buys a pool data asset, and downloads it
|
||||
|
||||
```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
|
||||
const consumerETHBalance = await web3.eth.getBalance(consumerAccount)
|
||||
```
|
||||
|
||||
Now let's console log the result to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer ETH balance: ${consumerETHBalance}`)
|
||||
let consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
```
|
||||
|
||||
Now let's console log consumerOCEANBalance to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer OCEAN balance before swap: ${consumerOCEANBalance}`)
|
||||
let consumerDTBalance = await balance(web3, poolDatatokenAddress, consumerAccount)
|
||||
```
|
||||
|
||||
Now let's console log POOL_NFT_SYMBOL and consumerDTBalance to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance before swap: ${consumerDTBalance}`)
|
||||
|
||||
```
|
||||
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
|
||||
```Typescript
|
||||
await approve(web3, consumerAccount, addresses.Ocean, poolAddress, '100')
|
||||
|
||||
@ -419,7 +471,9 @@ Before we call the contract we have to call `approve` so that the contract can m
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now we can make the contract call
|
||||
|
||||
```Typescript
|
||||
await pool.swapExactAmountOut(
|
||||
consumerAccount,
|
||||
@ -430,12 +484,16 @@ Now we can make the contract call
|
||||
|
||||
consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
```
|
||||
|
||||
Now let's console log the Consumer OCEAN balance after swap to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer OCEAN balance after swap: ${consumerOCEANBalance}`)
|
||||
consumerDTBalance = await balance(web3, poolDatatokenAddress, consumerAccount)
|
||||
```
|
||||
|
||||
Next let's console log the POOL_NFT_SYMBOL and consumerDTBalance
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance after swap: ${consumerDTBalance}`)
|
||||
|
||||
@ -443,7 +501,9 @@ Next let's console log the POOL_NFT_SYMBOL and consumerDTBalance
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
||||
```
|
||||
|
||||
The next step is to initialize the provider instance
|
||||
|
||||
```Typescript
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
@ -465,7 +525,9 @@ The next step is to initialize the provider instance
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now let's make a payment
|
||||
|
||||
```Typescript
|
||||
const tx = await datatoken.startOrder(
|
||||
poolDatatokenAddress,
|
||||
@ -476,7 +538,9 @@ Now let's make a payment
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
Next up, let's get the URL
|
||||
|
||||
```Typescript
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
DDO.id,
|
||||
@ -489,7 +553,9 @@ Next up, let's get the URL
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
Now let's console log the Download URL to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Download URL: ${downloadURL}`)
|
||||
|
||||
@ -498,7 +564,9 @@ Now let's console log the Download URL to check everything is working
|
||||
consumerDTBalance = await balance(web3, poolDatatokenAddress, consumerAccount)
|
||||
|
||||
```
|
||||
|
||||
Now let's console log the Consumer balance after order to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance after order: ${consumerDTBalance}`)
|
||||
|
||||
@ -508,12 +576,13 @@ Now let's console log the Consumer balance after order to check everything is wo
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 7. Publish Data NFT and a Datatoken with a fixed rate exchange
|
||||
|
||||
### 7.1 Publish a dataset (create NFT + Datatoken) with a fixed rate exchange
|
||||
### 7.1 Publish a dataset (create NFT + Datatoken) with a fixed rate exchange
|
||||
|
||||
```Typescript
|
||||
const factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
|
||||
@ -562,21 +631,26 @@ Now let's console log the Consumer balance after order to check everything is wo
|
||||
freId = tx.events.NewFixedRate.returnValues.exchangeId
|
||||
|
||||
```
|
||||
|
||||
Now let's console log each of those values to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`Fixed rate exchange NFT address: ${freNftAddress}`)
|
||||
console.log(`Fixed rate exchange Datatoken address: ${freDatatokenAddress}`)
|
||||
console.log(`Fixed rate exchange address: ${freAddress}`)
|
||||
console.log(`Fixed rate exchange Id: ${freId}`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 7.2 Set metadata in the fixed rate exchange NFT
|
||||
### 7.2 Set metadata in the fixed rate exchange NFT
|
||||
|
||||
```Typescript
|
||||
const nft = new Nft(web3)
|
||||
|
||||
```
|
||||
|
||||
Now we are going to update the ddo and set the did
|
||||
|
||||
```Typescript
|
||||
DDO.chainId = await web3.eth.getChainId()
|
||||
DDO.id =
|
||||
@ -585,14 +659,20 @@ Now we are going to update the ddo and set the did
|
||||
DDO.nftAddress = freNftAddress
|
||||
|
||||
```
|
||||
|
||||
Next, let's encrypt the file(s) using provider
|
||||
|
||||
```Typescript
|
||||
ASSET_URL.datatokenAddress = freDatatokenAddress
|
||||
ASSET_URL.nftAddress = freNftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = freDatatokenAddress
|
||||
|
||||
```
|
||||
|
||||
Now let's console log the DID to check everything is working
|
||||
|
||||
```Typescript
|
||||
console.log(`DID: ${DDO.id}`)
|
||||
|
||||
@ -612,20 +692,24 @@ Now let's console log the DID to check everything is working
|
||||
})
|
||||
```
|
||||
|
||||
### 7.3 Marketplace displays fixed rate asset for sale
|
||||
### 7.3 Marketplace displays fixed rate asset for sale
|
||||
|
||||
```Typescript
|
||||
const fixedRate = new FixedRateExchange(freAddress, web3)
|
||||
const oceanAmount = await (
|
||||
await fixedRate.calcBaseInGivenDatatokensOut(freId, '1')
|
||||
).baseTokenAmount
|
||||
```
|
||||
|
||||
Now that the market has fetched those values it can display the asset on the front end. In our case we will just console log the results:
|
||||
|
||||
```Typescript
|
||||
console.log(`Price of 1 ${FRE_NFT_SYMBOL} is ${oceanAmount} OCEAN`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 7.4 Consumer buys a fixed rate asset data asset, and downloads it
|
||||
### 7.4 Consumer buys a fixed rate asset data asset, and downloads it
|
||||
|
||||
```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
const DATATOKEN_AMOUNT = '10000'
|
||||
@ -635,7 +719,9 @@ Now that the market has fetched those values it can display the asset on the fro
|
||||
const consumerETHBalance = await web3.eth.getBalance(consumerAccount)
|
||||
|
||||
```
|
||||
|
||||
Let's do a quick check of the consumer ETH balance before the swap
|
||||
|
||||
```Typescript
|
||||
console.log(`Consumer ETH balance: ${consumerETHBalance}`)
|
||||
let consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
@ -644,7 +730,9 @@ Let's do a quick check of the consumer ETH balance before the swap
|
||||
console.log(`Consumer ${FRE_NFT_SYMBOL} balance before swap: ${consumerDTBalance}`)
|
||||
|
||||
```
|
||||
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
|
||||
```Typescript
|
||||
await approve(web3, consumerAccount, addresses.Ocean, freAddress, '100')
|
||||
await approve(
|
||||
@ -657,7 +745,9 @@ Before we call the contract we have to call `approve` so that the contract can m
|
||||
|
||||
const fixedRate = new FixedRateExchange(freAddress, web3)
|
||||
```
|
||||
|
||||
Now we can make the contract call
|
||||
|
||||
```Typescript
|
||||
await fixedRate.buyDatatokens(consumerAccount, freId, '1', '2')
|
||||
|
||||
@ -670,7 +760,9 @@ Now we can make the contract call
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
||||
```
|
||||
|
||||
Next, we need to initialize the provider
|
||||
|
||||
```Typescript
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
@ -692,7 +784,9 @@ Next, we need to initialize the provider
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Lets now make the payment
|
||||
|
||||
```Typescript
|
||||
const tx = await datatoken.startOrder(
|
||||
freDatatokenAddress,
|
||||
@ -702,7 +796,9 @@ Lets now make the payment
|
||||
providerFees
|
||||
)
|
||||
```
|
||||
|
||||
Now we can get the url
|
||||
|
||||
```Typescript
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
DDO.id,
|
||||
@ -715,7 +811,9 @@ Now we can get the url
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
Lets check that the download URL was successfully received
|
||||
|
||||
```Typescript
|
||||
console.log(`Download URL: ${downloadURL}`)
|
||||
|
||||
@ -730,12 +828,13 @@ Lets check that the download URL was successfully received
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 8. Publish Data NFT and a Datatoken with a dispenser
|
||||
|
||||
### 8.1 Publish a dataset (create NFT + Datatoken) with a dispenser
|
||||
### 8.1 Publish a dataset (create NFT + Datatoken) with a dispenser
|
||||
|
||||
```Typescript
|
||||
const factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
|
||||
@ -777,20 +876,25 @@ Lets check that the download URL was successfully received
|
||||
dispenserDatatokenAddress = tx.events.TokenCreated.returnValues[0]
|
||||
dispenserAddress = tx.events.DispenserCreated.returnValues[0]
|
||||
```
|
||||
|
||||
Lets check that we managed to received all of those values without any problems
|
||||
|
||||
```Typescript
|
||||
console.log(`Dispenser NFT address: ${dispenserNftAddress}`)
|
||||
console.log(`Dispenser Datatoken address: ${dispenserDatatokenAddress}`)
|
||||
console.log(`Dispenser address: ${dispenserAddress}`)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 8.2 Set metadata in the dispenser NFT
|
||||
### 8.2 Set metadata in the dispenser NFT
|
||||
|
||||
```Typescript
|
||||
const nft = new Nft(web3)
|
||||
|
||||
```
|
||||
|
||||
Lets start by updating the ddo and setting the did
|
||||
|
||||
```Typescript
|
||||
DDO.chainId = await web3.eth.getChainId()
|
||||
DDO.id =
|
||||
@ -799,8 +903,12 @@ Lets start by updating the ddo and setting the did
|
||||
DDO.nftAddress = dispenserNftAddress
|
||||
|
||||
```
|
||||
|
||||
Now we need to encrypt file(s) using provider
|
||||
|
||||
```Typescript
|
||||
ASSET_URL.datatokenAddress = dispenserDatatokenAddress
|
||||
ASSET_URL.nftAddress = dispenserNftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = dispenserDatatokenAddress
|
||||
@ -820,10 +928,11 @@ Now we need to encrypt file(s) using provider
|
||||
encryptedDDO,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 8.3 Consumer gets a dispenser data asset, and downloads it
|
||||
### 8.3 Consumer gets a dispenser data asset, and downloads it
|
||||
|
||||
```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
const dispenser = new Dispenser(addresses.Dispenser, web3)
|
||||
@ -852,7 +961,9 @@ Now we need to encrypt file(s) using provider
|
||||
const resolvedDDO = await aquarius.waitForAqua(DDO.id)
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
```
|
||||
|
||||
At this point we need to encrypt file(s) using provider
|
||||
|
||||
```Typescript
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
@ -873,7 +984,9 @@ At this point we need to encrypt file(s) using provider
|
||||
validUntil: initializeData.providerFee.validUntil
|
||||
}
|
||||
```
|
||||
|
||||
Now we need to make the payment
|
||||
|
||||
```Typescript
|
||||
const tx = await datatoken.startOrder(
|
||||
dispenserDatatokenAddress,
|
||||
@ -883,7 +996,9 @@ Now we need to make the payment
|
||||
providerFees
|
||||
)
|
||||
```
|
||||
|
||||
Now we can get the download URL
|
||||
|
||||
```Typescript
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
DDO.id,
|
||||
@ -895,7 +1010,9 @@ Now we can get the download URL
|
||||
web3
|
||||
)
|
||||
```
|
||||
|
||||
Let's check we received the download URL ok
|
||||
|
||||
```Typescript
|
||||
console.log(`Download URL: ${downloadURL}`)
|
||||
|
||||
@ -908,11 +1025,11 @@ Let's check we received the download URL ok
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Editing this file
|
||||
|
||||
Please note that CodeExamples.md is an autogenerated file, you should not edit it directly.
|
||||
Updates should be done in `test/integration/CodeExamples.test.ts` and all markdown should have three forward slashes before it
|
||||
e.g. `/// # H1 Title`
|
||||
|
7727
package-lock.json
generated
7727
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@oceanprotocol/lib",
|
||||
"source": "./src/index.ts",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.8",
|
||||
"description": "JavaScript client library for Ocean Protocol",
|
||||
"main": "./dist/lib.js",
|
||||
"umd:main": "dist/lib.umd.js",
|
||||
@ -39,10 +39,10 @@
|
||||
"test:examples": "npm run mocha -- 'test/integration/CodeExamples.test.ts'",
|
||||
"test:provider": "npm run mocha -- 'test/integration/Provider.test.ts'",
|
||||
"test:unit": "npm run mocha -- 'test/unit/**/*.test.ts'",
|
||||
"test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit",
|
||||
"test:unit:cover": "nyc --report-dir coverage/unit --exclude 'src/@types/**/*' npm run test:unit",
|
||||
"test:integration": "npm run mocha -- 'test/integration/**/*.test.ts'",
|
||||
"test:compute": "npm run mocha -- 'test/integration/ComputeFlow.test.ts'",
|
||||
"test:integration:cover": "nyc --report-dir coverage/integration --no-clean npm run test:integration",
|
||||
"test:integration:cover": "nyc --report-dir coverage/integration --exclude 'src/@types/**/*' --no-clean npm run test:integration",
|
||||
"create:guide": "chmod +x ./scripts/createCodeExamples.sh && ./scripts/createCodeExamples.sh",
|
||||
"create:guide:mac": "chmod +x ./scripts/createCodeExamples-mac.sh && ./scripts/createCodeExamples-mac.sh",
|
||||
"commit:guide": "chmod +x scripts/commitChanges.sh && scripts/commitChanges.sh"
|
||||
@ -59,7 +59,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/oceanprotocol/ocean.js#readme",
|
||||
"peerDependencies": {
|
||||
"web3": "^1.7.3"
|
||||
"web3": "^1.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/contracts": "^1.0.0",
|
||||
@ -67,41 +67,41 @@
|
||||
"cross-fetch": "^3.1.5",
|
||||
"crypto-js": "^4.1.1",
|
||||
"decimal.js": "^10.3.1",
|
||||
"web3": "^1.7.3",
|
||||
"web3": "^1.7.4",
|
||||
"web3-core": "^1.7.1",
|
||||
"web3-eth-contract": "^1.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@truffle/hdwallet-provider": "^2.0.8",
|
||||
"@truffle/hdwallet-provider": "^2.0.10",
|
||||
"@types/chai": "^4.3.1",
|
||||
"@types/chai-spies": "^1.0.3",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^17.0.35",
|
||||
"@types/node": "^18.0.1",
|
||||
"@types/node-fetch": "^3.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
"auto-changelog": "^2.4.0",
|
||||
"chai": "^4.3.6",
|
||||
"chai-spies": "^1.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^7.17.0",
|
||||
"eslint-config-oceanprotocol": "^1.5.0",
|
||||
"eslint": "^8.19.0",
|
||||
"eslint-config-oceanprotocol": "^2.0.3",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"fs": "0.0.1-security",
|
||||
"microbundle": "0.14.2",
|
||||
"mocha": "^10.0.0",
|
||||
"mock-local-storage": "^1.1.21",
|
||||
"nyc": "^15.1.0",
|
||||
"ora": "5.4.1",
|
||||
"prettier": "^2.6.2",
|
||||
"release-it": "^15.0.0",
|
||||
"prettier": "^2.7.1",
|
||||
"release-it": "^15.1.1",
|
||||
"source-map-support": "^0.5.19",
|
||||
"ts-node": "^10.8.0",
|
||||
"ts-node": "^10.8.2",
|
||||
"ts-node-register": "^1.0.0",
|
||||
"typedoc": "0.22.15",
|
||||
"typescript": "^4.6.4"
|
||||
"typedoc": "0.23.5",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"nyc": {
|
||||
"include": [
|
||||
|
@ -125,7 +125,7 @@ export interface Asset extends DDO {
|
||||
* How often an asset was consumed, meaning how often it was either downloaded or used as part of a compute job.
|
||||
* @type {string}
|
||||
*/
|
||||
consume: number
|
||||
orders: number
|
||||
}
|
||||
|
||||
/**
|
||||
|
27
src/@types/File.ts
Normal file
27
src/@types/File.ts
Normal file
@ -0,0 +1,27 @@
|
||||
export interface UrlFile {
|
||||
type: 'url'
|
||||
|
||||
/**
|
||||
* File index.
|
||||
* @type {number}
|
||||
*/
|
||||
index?: number
|
||||
|
||||
/**
|
||||
* File URL.
|
||||
* @type {string}
|
||||
*/
|
||||
url: string
|
||||
|
||||
/**
|
||||
* HTTP method used
|
||||
* @type {string}
|
||||
*/
|
||||
method: string
|
||||
}
|
||||
|
||||
export interface Files {
|
||||
nftAddress: string
|
||||
datatokenAddress: string
|
||||
files: UrlFile[]
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export interface FileMetadata {
|
||||
export interface FileInfo {
|
||||
/**
|
||||
* File URL.
|
||||
* @type {string}
|
||||
@ -36,6 +36,12 @@ export interface FileMetadata {
|
||||
*/
|
||||
method?: string
|
||||
|
||||
/**
|
||||
* Computed file checksum
|
||||
* @type {string}
|
||||
*/
|
||||
checksum?: string
|
||||
|
||||
/**
|
||||
* check if file exists
|
||||
* @type {boolean}
|
@ -15,6 +15,8 @@ export interface FreOrderParams {
|
||||
exchangeContract: string
|
||||
exchangeId: string
|
||||
maxBaseTokenAmount: string
|
||||
baseTokenAddress: string
|
||||
baseTokenDecimals?: number
|
||||
swapMarketFee: string
|
||||
marketFeeAddress: string
|
||||
}
|
||||
|
@ -4,11 +4,12 @@ export * from './DDO/Event'
|
||||
export * from './DDO/Metadata'
|
||||
export * from './DDO/Service'
|
||||
export * from './Asset'
|
||||
export * from './File'
|
||||
export * from './FileInfo'
|
||||
export * from './Compute'
|
||||
export * from './Datatoken'
|
||||
export * from './Dispenser'
|
||||
export * from './DownloadResponse'
|
||||
export * from './FileMetadata'
|
||||
export * from './FixedPrice'
|
||||
export * from './NFT'
|
||||
export * from './NFTFactory'
|
||||
|
@ -2,6 +2,15 @@ import fetch from 'cross-fetch'
|
||||
import { LoggerInstance, sleep } from '../utils'
|
||||
import { Asset, DDO, ValidateMetadata } from '../@types'
|
||||
|
||||
export interface SearchQuery {
|
||||
from?: number
|
||||
size?: number
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
query: any
|
||||
sort?: { [jsonPath: string]: string }
|
||||
aggs?: any
|
||||
}
|
||||
|
||||
export class Aquarius {
|
||||
public aquariusURL
|
||||
/**
|
||||
@ -122,4 +131,65 @@ export class Aquarius {
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
/**
|
||||
* Search over the DDOs using a query.
|
||||
* @param {string} did DID of the asset
|
||||
* @param {AbortSignal} signal abort signal
|
||||
* @return {Promise<QueryResult>}
|
||||
*/
|
||||
public async getAssetMetadata(did: string, signal?: AbortSignal): Promise<any> {
|
||||
const path = this.aquariusURL + '/api/aquarius/assets/metadata/' + did
|
||||
|
||||
try {
|
||||
const response = await fetch(path, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
signal: signal
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
throw new Error(
|
||||
'getAssetMetadata failed: ' + response.status + response.statusText
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
LoggerInstance.error('Error getting metadata: ', error)
|
||||
throw new Error('Error getting metadata: ' + error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search over the DDOs using a query.
|
||||
* @param {SearchQuery} query Query to filter the DDOs.
|
||||
* @param {AbortSignal} signal abort signal
|
||||
* @return {Promise<QueryResult>}
|
||||
*/
|
||||
public async querySearch(query: SearchQuery, signal?: AbortSignal): Promise<any> {
|
||||
const path = this.aquariusURL + '/api/aquarius/assets/query'
|
||||
|
||||
try {
|
||||
const response = await fetch(path, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(query),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
signal: signal
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
} else {
|
||||
throw new Error('querySearch failed: ' + response.status + response.statusText)
|
||||
}
|
||||
} catch (error) {
|
||||
LoggerInstance.error('Error querying metadata: ', error)
|
||||
throw new Error('Error querying metadata: ' + error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import Web3 from 'web3'
|
||||
import fetch from 'cross-fetch'
|
||||
import { LoggerInstance } from '../utils'
|
||||
import {
|
||||
FileMetadata,
|
||||
FileInfo,
|
||||
ComputeJob,
|
||||
ComputeOutput,
|
||||
ComputeAlgorithm,
|
||||
@ -153,21 +153,22 @@ export class Provider {
|
||||
* @param {number} serviceId the id of the service for which to check the files
|
||||
* @param {string} providerUri uri of the provider that will be used to check the file
|
||||
* @param {AbortSignal} signal abort signal
|
||||
* @return {Promise<FileMetadata[]>} urlDetails
|
||||
* @return {Promise<FileInfo[]>} urlDetails
|
||||
*/
|
||||
public async checkDidFiles(
|
||||
did: string,
|
||||
serviceId: number,
|
||||
serviceId: string,
|
||||
providerUri: string,
|
||||
withChecksum: boolean = false,
|
||||
signal?: AbortSignal
|
||||
): Promise<FileMetadata[]> {
|
||||
): Promise<FileInfo[]> {
|
||||
const providerEndpoints = await this.getEndpoints(providerUri)
|
||||
const serviceEndpoints = await this.getServiceEndpoints(
|
||||
providerUri,
|
||||
providerEndpoints
|
||||
)
|
||||
const args = { did: did, serviceId: serviceId }
|
||||
const files: FileMetadata[] = []
|
||||
const args = { did: did, serviceId: serviceId, checksum: withChecksum }
|
||||
const files: FileInfo[] = []
|
||||
const path = this.getEndpointURL(serviceEndpoints, 'fileinfo')
|
||||
? this.getEndpointURL(serviceEndpoints, 'fileinfo').urlPath
|
||||
: null
|
||||
@ -181,7 +182,7 @@ export class Provider {
|
||||
},
|
||||
signal: signal
|
||||
})
|
||||
const results: FileMetadata[] = await response.json()
|
||||
const results: FileInfo[] = await response.json()
|
||||
for (const result of results) {
|
||||
files.push(result)
|
||||
}
|
||||
@ -196,20 +197,20 @@ export class Provider {
|
||||
* @param {string} url or did
|
||||
* @param {string} providerUri uri of the provider that will be used to check the file
|
||||
* @param {AbortSignal} signal abort signal
|
||||
* @return {Promise<FileMetadata[]>} urlDetails
|
||||
* @return {Promise<FileInfo[]>} urlDetails
|
||||
*/
|
||||
public async checkFileUrl(
|
||||
url: string,
|
||||
providerUri: string,
|
||||
signal?: AbortSignal
|
||||
): Promise<FileMetadata[]> {
|
||||
): Promise<FileInfo[]> {
|
||||
const providerEndpoints = await this.getEndpoints(providerUri)
|
||||
const serviceEndpoints = await this.getServiceEndpoints(
|
||||
providerUri,
|
||||
providerEndpoints
|
||||
)
|
||||
const args = { url: url, type: 'url' }
|
||||
const files: FileMetadata[] = []
|
||||
const files: FileInfo[] = []
|
||||
const path = this.getEndpointURL(serviceEndpoints, 'fileinfo')
|
||||
? this.getEndpointURL(serviceEndpoints, 'fileinfo').urlPath
|
||||
: null
|
||||
@ -223,7 +224,7 @@ export class Provider {
|
||||
},
|
||||
signal: signal
|
||||
})
|
||||
const results: FileMetadata[] = await response.json()
|
||||
const results: FileInfo[] = await response.json()
|
||||
for (const result of results) {
|
||||
files.push(result)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import Web3 from 'web3'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import { Config } from '../config'
|
||||
import { minAbi, GASLIMIT_DEFAULT } from '.'
|
||||
import { minAbi, GASLIMIT_DEFAULT, LoggerInstance } from '.'
|
||||
|
||||
export function setContractDefaults(contract: Contract, config: Config): Contract {
|
||||
if (config) {
|
||||
@ -58,12 +58,14 @@ export async function amountToUnits(
|
||||
decimals = 18
|
||||
}
|
||||
BigNumber.config({ EXPONENTIAL_AT: 50 })
|
||||
|
||||
const amountFormatted = new BigNumber(amount).times(
|
||||
new BigNumber(10).exponentiatedBy(decimals)
|
||||
)
|
||||
|
||||
return amountFormatted.toString()
|
||||
try {
|
||||
const amountFormatted = new BigNumber(amount).times(
|
||||
new BigNumber(10).exponentiatedBy(decimals)
|
||||
)
|
||||
return amountFormatted.toFixed(0)
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: FAILED TO CALL DECIMALS(), USING 18', ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,10 +2,23 @@ import fetch from 'cross-fetch'
|
||||
import { DownloadResponse } from '../@types'
|
||||
|
||||
export async function downloadFileBrowser(url: string): Promise<void> {
|
||||
const anchor = document.createElement('a')
|
||||
anchor.download = ''
|
||||
anchor.href = url
|
||||
anchor.click()
|
||||
const headResponse = await fetch(url, { method: 'HEAD' })
|
||||
const contentHeader = headResponse.headers.get('content-disposition')
|
||||
const fileName = contentHeader.split('=')[1]
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.responseType = 'blob'
|
||||
xhr.open('GET', url)
|
||||
xhr.onload = () => {
|
||||
const blobURL = window.URL.createObjectURL(xhr.response)
|
||||
const a = document.createElement('a')
|
||||
a.href = blobURL
|
||||
a.setAttribute('download', fileName)
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
a.remove()
|
||||
window.URL.revokeObjectURL(blobURL)
|
||||
}
|
||||
xhr.send(null)
|
||||
}
|
||||
|
||||
export async function downloadFile(
|
||||
|
@ -98,6 +98,7 @@ import {
|
||||
DispenserCreationParams,
|
||||
downloadFile,
|
||||
DatatokenCreateParams,
|
||||
Files,
|
||||
FixedRateExchange,
|
||||
FreCreationParams,
|
||||
getHash,
|
||||
@ -153,13 +154,17 @@ describe('Marketplace flow tests', async () => {
|
||||
|
||||
/// We will need a file to publish, so here we define the file that we intend to publish.
|
||||
/// ```Typescript
|
||||
const ASSET_URL = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const ASSET_URL: Files = {
|
||||
datatokenAddress: '0x0',
|
||||
nftAddress: '0x0',
|
||||
files: [
|
||||
{
|
||||
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
|
||||
@ -167,7 +172,7 @@ describe('Marketplace flow tests', async () => {
|
||||
const DDO = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: '',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -185,7 +190,7 @@ describe('Marketplace flow tests', async () => {
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0x0',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
@ -324,6 +329,8 @@ describe('Marketplace flow tests', async () => {
|
||||
/// ```
|
||||
/// Next we encrypt the file or files using Ocean Provider. The provider is an off chain proxy built specifically for this task
|
||||
/// ```Typescript
|
||||
ASSET_URL.datatokenAddress = poolDatatokenAddress
|
||||
ASSET_URL.nftAddress = poolNftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = poolDatatokenAddress
|
||||
@ -587,6 +594,8 @@ describe('Marketplace flow tests', async () => {
|
||||
/// ```
|
||||
/// Next, let's encrypt the file(s) using provider
|
||||
/// ```Typescript
|
||||
ASSET_URL.datatokenAddress = freDatatokenAddress
|
||||
ASSET_URL.nftAddress = freNftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = freDatatokenAddress
|
||||
@ -801,6 +810,8 @@ describe('Marketplace flow tests', async () => {
|
||||
/// ```
|
||||
/// Now we need to encrypt file(s) using provider
|
||||
/// ```Typescript
|
||||
ASSET_URL.datatokenAddress = dispenserDatatokenAddress
|
||||
ASSET_URL.nftAddress = dispenserNftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = dispenserDatatokenAddress
|
||||
|
@ -10,7 +10,8 @@ import {
|
||||
Datatoken,
|
||||
Nft,
|
||||
sleep,
|
||||
ZERO_ADDRESS
|
||||
ZERO_ADDRESS,
|
||||
approveWei
|
||||
} from '../../src'
|
||||
import {
|
||||
DatatokenCreateParams,
|
||||
@ -18,7 +19,8 @@ import {
|
||||
ComputeAsset,
|
||||
ComputeAlgorithm,
|
||||
ProviderComputeInitialize,
|
||||
ConsumeMarketFee
|
||||
ConsumeMarketFee,
|
||||
Files
|
||||
} from '../../src/@types'
|
||||
|
||||
let config: Config
|
||||
@ -42,17 +44,32 @@ let resolvedDdoWithNoTimeout
|
||||
let resolvedAlgoDdoWith1mTimeout
|
||||
let resolvedAlgoDdoWithNoTimeout
|
||||
|
||||
const assetUrl = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
let freeEnvDatasetTxId
|
||||
let freeEnvAlgoTxId
|
||||
let paidEnvDatasetTxId
|
||||
let paidEnvAlgoTxId
|
||||
|
||||
// let's have 2 minutes of compute access
|
||||
const mytime = new Date()
|
||||
const computeMinutes = 1
|
||||
mytime.setMinutes(mytime.getMinutes() + computeMinutes)
|
||||
let computeValidUntil = Math.floor(mytime.getTime() / 1000)
|
||||
|
||||
const assetUrl: Files = {
|
||||
datatokenAddress: '0x0',
|
||||
nftAddress: '0x0',
|
||||
files: [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
}
|
||||
const ddoWithNoTimeout = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -74,7 +91,7 @@ const ddoWithNoTimeout = {
|
||||
type: 'compute',
|
||||
files: '',
|
||||
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 0,
|
||||
compute: {
|
||||
publisherTrustedAlgorithmPublishers: [],
|
||||
@ -89,7 +106,7 @@ const ddoWithNoTimeout = {
|
||||
const ddoWith1mTimeout = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -111,7 +128,7 @@ const ddoWith1mTimeout = {
|
||||
type: 'compute',
|
||||
files: '',
|
||||
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 60,
|
||||
compute: {
|
||||
publisherTrustedAlgorithmPublishers: [],
|
||||
@ -122,17 +139,21 @@ const ddoWith1mTimeout = {
|
||||
}
|
||||
]
|
||||
}
|
||||
const algoAssetUrl = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/test-algorithm/master/javascript/algo.js',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const algoAssetUrl: Files = {
|
||||
datatokenAddress: '0x0',
|
||||
nftAddress: '0x0',
|
||||
files: [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/test-algorithm/master/javascript/algo.js',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
}
|
||||
const algoDdoWithNoTimeout = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -155,7 +176,7 @@ const algoDdoWithNoTimeout = {
|
||||
image: 'ubuntu',
|
||||
tag: 'latest',
|
||||
checksum:
|
||||
'sha256:bace9fb0d5923a675c894d5c815da75ffe35e24970166a48a4460a48ae6e0d19'
|
||||
'sha256:42ba2dfce475de1113d55602d40af18415897167d47c2045ec7b6d9746ff148f'
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -165,7 +186,7 @@ const algoDdoWithNoTimeout = {
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
@ -174,7 +195,7 @@ const algoDdoWithNoTimeout = {
|
||||
const algoDdoWith1mTimeout = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -197,7 +218,7 @@ const algoDdoWith1mTimeout = {
|
||||
image: 'ubuntu',
|
||||
tag: 'latest',
|
||||
checksum:
|
||||
'sha256:bace9fb0d5923a675c894d5c815da75ffe35e24970166a48a4460a48ae6e0d19'
|
||||
'sha256:42ba2dfce475de1113d55602d40af18415897167d47c2045ec7b6d9746ff148f'
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -207,7 +228,7 @@ const algoDdoWith1mTimeout = {
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 60
|
||||
}
|
||||
]
|
||||
@ -252,7 +273,10 @@ async function createAsset(
|
||||
|
||||
const nftAddress = result.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddressAsset = result.events.TokenCreated.returnValues[0]
|
||||
ddo.nftAddress = web3.utils.toChecksumAddress(nftAddress)
|
||||
// create the files encrypted string
|
||||
assetUrl.datatokenAddress = datatokenAddressAsset
|
||||
assetUrl.nftAddress = ddo.nftAddress
|
||||
let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddressAsset
|
||||
@ -292,11 +316,12 @@ async function handleOrder(
|
||||
- no validOrder -> we need to call startOrder, to pay 1 DT & providerFees
|
||||
*/
|
||||
if (order.providerFee && order.providerFee.providerFeeAmount) {
|
||||
await datatoken.approve(
|
||||
await approveWei(
|
||||
web3,
|
||||
payerAccount,
|
||||
order.providerFee.providerFeeToken,
|
||||
datatokenAddress,
|
||||
order.providerFee.providerFeeAmount,
|
||||
payerAccount
|
||||
order.providerFee.providerFeeAmount
|
||||
)
|
||||
}
|
||||
if (order.validOrder) {
|
||||
@ -413,14 +438,11 @@ describe('Simple compute tests', async () => {
|
||||
assert(computeEnvs, 'No Compute environments found')
|
||||
})
|
||||
|
||||
it('should start a computeJob', async () => {
|
||||
// we choose the first env
|
||||
const computeEnv = computeEnvs[0].id
|
||||
const computeConsumerAddress = computeEnvs[0].consumerAddress
|
||||
// let's have 10 minutesof compute access
|
||||
const mytime = new Date()
|
||||
mytime.setMinutes(mytime.getMinutes() + 19)
|
||||
const computeValidUntil = Math.floor(mytime.getTime() / 1000)
|
||||
it('should start a computeJob using the free environment', async () => {
|
||||
// we choose the free env
|
||||
const computeEnv = computeEnvs.find((ce) => ce.priceMin === 0)
|
||||
assert(computeEnv, 'Cannot find the free compute env')
|
||||
|
||||
const assets: ComputeAsset[] = [
|
||||
{
|
||||
documentId: resolvedDdoWith1mTimeout.id,
|
||||
@ -436,7 +458,7 @@ describe('Simple compute tests', async () => {
|
||||
providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
||||
assets,
|
||||
algo,
|
||||
computeEnv,
|
||||
computeEnv.id,
|
||||
computeValidUntil,
|
||||
providerUrl,
|
||||
consumerAccount
|
||||
@ -449,7 +471,7 @@ describe('Simple compute tests', async () => {
|
||||
providerInitializeComputeResults.algorithm,
|
||||
resolvedAlgoDdoWith1mTimeout.services[0].datatokenAddress,
|
||||
consumerAccount,
|
||||
computeConsumerAddress,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
for (let i = 0; i < providerInitializeComputeResults.datasets.length; i++) {
|
||||
@ -457,7 +479,7 @@ describe('Simple compute tests', async () => {
|
||||
providerInitializeComputeResults.datasets[i],
|
||||
dtAddressArray[i],
|
||||
consumerAccount,
|
||||
computeConsumerAddress,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
}
|
||||
@ -465,10 +487,365 @@ describe('Simple compute tests', async () => {
|
||||
providerUrl,
|
||||
web3,
|
||||
consumerAccount,
|
||||
computeEnv,
|
||||
computeEnv.id,
|
||||
assets[0],
|
||||
algo
|
||||
)
|
||||
freeEnvDatasetTxId = assets[0].transferTxId
|
||||
freeEnvAlgoTxId = algo.transferTxId
|
||||
assert(computeJobs, 'Cannot start compute job')
|
||||
computeJobId = computeJobs[0].jobId
|
||||
})
|
||||
|
||||
it('should restart a computeJob without paying anything, because order is valid and providerFees are still valid', async () => {
|
||||
// we choose the free env
|
||||
const computeEnv = computeEnvs.find((ce) => ce.priceMin === 0)
|
||||
assert(computeEnv, 'Cannot find the free compute env')
|
||||
|
||||
const assets: ComputeAsset[] = [
|
||||
{
|
||||
documentId: resolvedDdoWith1mTimeout.id,
|
||||
serviceId: resolvedDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: freeEnvDatasetTxId
|
||||
}
|
||||
]
|
||||
const algo: ComputeAlgorithm = {
|
||||
documentId: resolvedAlgoDdoWith1mTimeout.id,
|
||||
serviceId: resolvedAlgoDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: freeEnvAlgoTxId
|
||||
}
|
||||
|
||||
providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
||||
assets,
|
||||
algo,
|
||||
computeEnv.id,
|
||||
computeValidUntil,
|
||||
providerUrl,
|
||||
consumerAccount
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.algorithm.validOrder,
|
||||
'We should have a valid order for algorithm'
|
||||
)
|
||||
assert(
|
||||
!providerInitializeComputeResults.algorithm.providerFee,
|
||||
'We should not pay providerFees again for algorithm'
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.datasets[0].validOrder,
|
||||
'We should have a valid order for dataset'
|
||||
)
|
||||
assert(
|
||||
!providerInitializeComputeResults.datasets[0].providerFee,
|
||||
'We should not pay providerFees again for dataset'
|
||||
)
|
||||
algo.transferTxId = providerInitializeComputeResults.algorithm.validOrder
|
||||
assets[0].transferTxId = providerInitializeComputeResults.datasets[0].validOrder
|
||||
assert(
|
||||
algo.transferTxId === freeEnvAlgoTxId &&
|
||||
assets[0].transferTxId === freeEnvDatasetTxId,
|
||||
'We should use the same orders, because no fess must be paid'
|
||||
)
|
||||
const computeJobs = await ProviderInstance.computeStart(
|
||||
providerUrl,
|
||||
web3,
|
||||
consumerAccount,
|
||||
computeEnv.id,
|
||||
assets[0],
|
||||
algo
|
||||
)
|
||||
assert(computeJobs, 'Cannot start compute job')
|
||||
computeJobId = computeJobs[0].jobId
|
||||
})
|
||||
|
||||
// moving to paid environments
|
||||
|
||||
it('should start a computeJob on a paid environment', async () => {
|
||||
// we choose the paid env
|
||||
const computeEnv = computeEnvs.find((ce) => ce.priceMin !== 0)
|
||||
assert(computeEnv, 'Cannot find the paid compute env')
|
||||
|
||||
const assets: ComputeAsset[] = [
|
||||
{
|
||||
documentId: resolvedDdoWith1mTimeout.id,
|
||||
serviceId: resolvedDdoWith1mTimeout.services[0].id
|
||||
}
|
||||
]
|
||||
const dtAddressArray = [resolvedDdoWith1mTimeout.services[0].datatokenAddress]
|
||||
const algo: ComputeAlgorithm = {
|
||||
documentId: resolvedAlgoDdoWith1mTimeout.id,
|
||||
serviceId: resolvedAlgoDdoWith1mTimeout.services[0].id
|
||||
}
|
||||
|
||||
providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
||||
assets,
|
||||
algo,
|
||||
computeEnv.id,
|
||||
computeValidUntil,
|
||||
providerUrl,
|
||||
consumerAccount
|
||||
)
|
||||
assert(
|
||||
!('error' in providerInitializeComputeResults.algorithm),
|
||||
'Cannot order algorithm'
|
||||
)
|
||||
algo.transferTxId = await handleOrder(
|
||||
providerInitializeComputeResults.algorithm,
|
||||
resolvedAlgoDdoWith1mTimeout.services[0].datatokenAddress,
|
||||
consumerAccount,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
for (let i = 0; i < providerInitializeComputeResults.datasets.length; i++) {
|
||||
assets[i].transferTxId = await handleOrder(
|
||||
providerInitializeComputeResults.datasets[i],
|
||||
dtAddressArray[i],
|
||||
consumerAccount,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
const computeJobs = await ProviderInstance.computeStart(
|
||||
providerUrl,
|
||||
web3,
|
||||
consumerAccount,
|
||||
computeEnv.id,
|
||||
assets[0],
|
||||
algo
|
||||
)
|
||||
paidEnvDatasetTxId = assets[0].transferTxId
|
||||
paidEnvAlgoTxId = algo.transferTxId
|
||||
assert(computeJobs, 'Cannot start compute job')
|
||||
computeJobId = computeJobs[0].jobId
|
||||
})
|
||||
|
||||
it('should restart a computeJob on paid environment, without paying anything, because order is valid and providerFees are still valid', async () => {
|
||||
// we choose the paid env
|
||||
const computeEnv = computeEnvs.find((ce) => ce.priceMin !== 0)
|
||||
assert(computeEnv, 'Cannot find the free compute env')
|
||||
|
||||
const assets: ComputeAsset[] = [
|
||||
{
|
||||
documentId: resolvedDdoWith1mTimeout.id,
|
||||
serviceId: resolvedDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: paidEnvDatasetTxId
|
||||
}
|
||||
]
|
||||
const algo: ComputeAlgorithm = {
|
||||
documentId: resolvedAlgoDdoWith1mTimeout.id,
|
||||
serviceId: resolvedAlgoDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: paidEnvAlgoTxId
|
||||
}
|
||||
|
||||
providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
||||
assets,
|
||||
algo,
|
||||
computeEnv.id,
|
||||
computeValidUntil,
|
||||
providerUrl,
|
||||
consumerAccount
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.algorithm.validOrder,
|
||||
'We should have a valid order for algorithm'
|
||||
)
|
||||
assert(
|
||||
!providerInitializeComputeResults.algorithm.providerFee,
|
||||
'We should not pay providerFees again for algorithm'
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.datasets[0].validOrder,
|
||||
'We should have a valid order for dataset'
|
||||
)
|
||||
assert(
|
||||
!providerInitializeComputeResults.datasets[0].providerFee,
|
||||
'We should not pay providerFees again for dataset'
|
||||
)
|
||||
algo.transferTxId = providerInitializeComputeResults.algorithm.validOrder
|
||||
assets[0].transferTxId = providerInitializeComputeResults.datasets[0].validOrder
|
||||
assert(
|
||||
algo.transferTxId === paidEnvAlgoTxId &&
|
||||
assets[0].transferTxId === paidEnvDatasetTxId,
|
||||
'We should use the same orders, because no fess must be paid'
|
||||
)
|
||||
const computeJobs = await ProviderInstance.computeStart(
|
||||
providerUrl,
|
||||
web3,
|
||||
consumerAccount,
|
||||
computeEnv.id,
|
||||
assets[0],
|
||||
algo
|
||||
)
|
||||
assert(computeJobs, 'Cannot start compute job')
|
||||
computeJobId = computeJobs[0].jobId
|
||||
})
|
||||
|
||||
// move to reuse Orders
|
||||
it('Should fast forward time and set a new computeValidUntil', async () => {
|
||||
const mytime = new Date()
|
||||
const computeMinutes = 5
|
||||
mytime.setMinutes(mytime.getMinutes() + computeMinutes)
|
||||
computeValidUntil = Math.floor(mytime.getTime() / 1000)
|
||||
})
|
||||
|
||||
it('should start a computeJob using the free environment, by paying only providerFee (reuseOrder)', async () => {
|
||||
// we choose the free env
|
||||
const computeEnv = computeEnvs.find((ce) => ce.priceMin === 0)
|
||||
assert(computeEnv, 'Cannot find the free compute env')
|
||||
|
||||
const assets: ComputeAsset[] = [
|
||||
{
|
||||
documentId: resolvedDdoWith1mTimeout.id,
|
||||
serviceId: resolvedDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: freeEnvDatasetTxId
|
||||
}
|
||||
]
|
||||
const dtAddressArray = [resolvedDdoWith1mTimeout.services[0].datatokenAddress]
|
||||
const algo: ComputeAlgorithm = {
|
||||
documentId: resolvedAlgoDdoWith1mTimeout.id,
|
||||
serviceId: resolvedAlgoDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: freeEnvAlgoTxId
|
||||
}
|
||||
|
||||
providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
||||
assets,
|
||||
algo,
|
||||
computeEnv.id,
|
||||
computeValidUntil,
|
||||
providerUrl,
|
||||
consumerAccount
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.algorithm.validOrder,
|
||||
'We should have a valid order for algorithm'
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.datasets[0].validOrder,
|
||||
'We should have a valid order for dataset'
|
||||
)
|
||||
|
||||
assert(
|
||||
providerInitializeComputeResults.algorithm.providerFee ||
|
||||
providerInitializeComputeResults.datasets[0].providerFee,
|
||||
'We should pay providerFees again for algorithm or dataset. Cannot have empty for both'
|
||||
)
|
||||
|
||||
assert(
|
||||
!('error' in providerInitializeComputeResults.algorithm),
|
||||
'Cannot order algorithm'
|
||||
)
|
||||
algo.transferTxId = await handleOrder(
|
||||
providerInitializeComputeResults.algorithm,
|
||||
resolvedAlgoDdoWith1mTimeout.services[0].datatokenAddress,
|
||||
consumerAccount,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
for (let i = 0; i < providerInitializeComputeResults.datasets.length; i++) {
|
||||
assets[i].transferTxId = await handleOrder(
|
||||
providerInitializeComputeResults.datasets[i],
|
||||
dtAddressArray[i],
|
||||
consumerAccount,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
}
|
||||
assert(
|
||||
algo.transferTxId !== freeEnvAlgoTxId ||
|
||||
assets[0].transferTxId !== freeEnvDatasetTxId,
|
||||
'We should not use the same orders, because providerFee must be paid'
|
||||
)
|
||||
const computeJobs = await ProviderInstance.computeStart(
|
||||
providerUrl,
|
||||
web3,
|
||||
consumerAccount,
|
||||
computeEnv.id,
|
||||
assets[0],
|
||||
algo
|
||||
)
|
||||
freeEnvDatasetTxId = assets[0].transferTxId
|
||||
freeEnvAlgoTxId = algo.transferTxId
|
||||
assert(computeJobs, 'Cannot start compute job')
|
||||
computeJobId = computeJobs[0].jobId
|
||||
})
|
||||
|
||||
it('should start a computeJob using the paid environment, by paying only providerFee (reuseOrder)', async () => {
|
||||
// we choose the paid env
|
||||
const computeEnv = computeEnvs.find((ce) => ce.priceMin !== 0)
|
||||
assert(computeEnv, 'Cannot find the free compute env')
|
||||
|
||||
const assets: ComputeAsset[] = [
|
||||
{
|
||||
documentId: resolvedDdoWith1mTimeout.id,
|
||||
serviceId: resolvedDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: paidEnvDatasetTxId
|
||||
}
|
||||
]
|
||||
const dtAddressArray = [resolvedDdoWith1mTimeout.services[0].datatokenAddress]
|
||||
const algo: ComputeAlgorithm = {
|
||||
documentId: resolvedAlgoDdoWith1mTimeout.id,
|
||||
serviceId: resolvedAlgoDdoWith1mTimeout.services[0].id,
|
||||
transferTxId: paidEnvAlgoTxId
|
||||
}
|
||||
|
||||
providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
||||
assets,
|
||||
algo,
|
||||
computeEnv.id,
|
||||
computeValidUntil,
|
||||
providerUrl,
|
||||
consumerAccount
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.algorithm.validOrder,
|
||||
'We should have a valid order for algorithm'
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.datasets[0].validOrder,
|
||||
'We should have a valid order for dataset'
|
||||
)
|
||||
assert(
|
||||
providerInitializeComputeResults.algorithm.providerFee ||
|
||||
providerInitializeComputeResults.datasets[0].providerFee,
|
||||
'We should pay providerFees again for algorithm or dataset. Cannot have empty for both'
|
||||
)
|
||||
|
||||
assert(
|
||||
!('error' in providerInitializeComputeResults.algorithm),
|
||||
'Cannot order algorithm'
|
||||
)
|
||||
algo.transferTxId = await handleOrder(
|
||||
providerInitializeComputeResults.algorithm,
|
||||
resolvedAlgoDdoWith1mTimeout.services[0].datatokenAddress,
|
||||
consumerAccount,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
for (let i = 0; i < providerInitializeComputeResults.datasets.length; i++) {
|
||||
assets[i].transferTxId = await handleOrder(
|
||||
providerInitializeComputeResults.datasets[i],
|
||||
dtAddressArray[i],
|
||||
consumerAccount,
|
||||
computeEnv.consumerAddress,
|
||||
0
|
||||
)
|
||||
}
|
||||
assert(
|
||||
algo.transferTxId !== paidEnvAlgoTxId ||
|
||||
assets[0].transferTxId !== paidEnvDatasetTxId,
|
||||
'We should not use the same orders, because providerFee must be paid'
|
||||
)
|
||||
const computeJobs = await ProviderInstance.computeStart(
|
||||
providerUrl,
|
||||
web3,
|
||||
consumerAccount,
|
||||
computeEnv.id,
|
||||
assets[0],
|
||||
algo
|
||||
)
|
||||
freeEnvDatasetTxId = assets[0].transferTxId
|
||||
freeEnvAlgoTxId = algo.transferTxId
|
||||
assert(computeJobs, 'Cannot start compute job')
|
||||
computeJobId = computeJobs[0].jobId
|
||||
})
|
||||
@ -484,7 +861,7 @@ describe('Simple compute tests', async () => {
|
||||
})
|
||||
|
||||
it('Get download compute results url', async () => {
|
||||
sleep(10000)
|
||||
await sleep(10000)
|
||||
const downloadURL = await ProviderInstance.getComputeResultUrl(
|
||||
providerUrl,
|
||||
web3,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { assert } from 'chai'
|
||||
import { web3, getTestConfig } from '../config'
|
||||
import { Config, Provider } from '../../src'
|
||||
import { FileMetadata } from '../../src/@types'
|
||||
import { FileInfo } from '../../src/@types'
|
||||
|
||||
describe('Provider tests', async () => {
|
||||
let config: Config
|
||||
@ -26,7 +26,7 @@ describe('Provider tests', async () => {
|
||||
})
|
||||
|
||||
it('Alice checks fileinfo', async () => {
|
||||
const fileinfo: FileMetadata[] = await providerInstance.checkFileUrl(
|
||||
const fileinfo: FileInfo[] = await providerInstance.checkFileUrl(
|
||||
'https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-abstract.xml.gz-rss.xml',
|
||||
config.providerUri
|
||||
)
|
||||
|
@ -18,7 +18,8 @@ import {
|
||||
DatatokenCreateParams,
|
||||
PoolCreationParams,
|
||||
FreCreationParams,
|
||||
DispenserCreationParams
|
||||
DispenserCreationParams,
|
||||
Files
|
||||
} from '../../src/@types'
|
||||
|
||||
describe('Publish tests', async () => {
|
||||
@ -30,18 +31,22 @@ describe('Publish tests', async () => {
|
||||
let factory: NftFactory
|
||||
let publisherAccount: string
|
||||
|
||||
const assetUrl = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const assetUrl: Files = {
|
||||
datatokenAddress: '0x0',
|
||||
nftAddress: '0x0',
|
||||
files: [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const genericAsset: DDO = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: '',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -63,7 +68,7 @@ describe('Publish tests', async () => {
|
||||
description: 'Download service',
|
||||
files: '',
|
||||
datatokenAddress: '0x0',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
@ -142,7 +147,8 @@ describe('Publish tests', async () => {
|
||||
|
||||
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0]
|
||||
|
||||
assetUrl.datatokenAddress = datatokenAddress
|
||||
assetUrl.nftAddress = nftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
|
||||
poolDdo.metadata.name = 'test-dataset-pool'
|
||||
@ -223,7 +229,8 @@ describe('Publish tests', async () => {
|
||||
|
||||
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0]
|
||||
|
||||
assetUrl.datatokenAddress = datatokenAddress
|
||||
assetUrl.nftAddress = nftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
|
||||
fixedPriceDdo.metadata.name = 'test-dataset-fixedPrice'
|
||||
@ -297,7 +304,8 @@ describe('Publish tests', async () => {
|
||||
|
||||
const nftAddress = bundleNFT.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddress = bundleNFT.events.TokenCreated.returnValues[0]
|
||||
|
||||
assetUrl.datatokenAddress = datatokenAddress
|
||||
assetUrl.nftAddress = nftAddress
|
||||
const encryptedFiles = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
dispenserDdo.metadata.name = 'test-dataset-dispenser'
|
||||
dispenserDdo.services[0].files = await encryptedFiles
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
downloadFile,
|
||||
ZERO_ADDRESS
|
||||
} from '../../src'
|
||||
import { ProviderFees, DatatokenCreateParams, DDO } from '../../src/@types'
|
||||
import { ProviderFees, DatatokenCreateParams, DDO, Files } from '../../src/@types'
|
||||
|
||||
describe('Simple Publish & consume test', async () => {
|
||||
let config: Config
|
||||
@ -23,18 +23,22 @@ describe('Simple Publish & consume test', async () => {
|
||||
let publisherAccount: string
|
||||
let consumerAccount: string
|
||||
|
||||
const assetUrl = [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
const assetUrl: Files = {
|
||||
datatokenAddress: '0x0',
|
||||
nftAddress: '0x0',
|
||||
files: [
|
||||
{
|
||||
type: 'url',
|
||||
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const ddo: DDO = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: '',
|
||||
version: '4.0.0',
|
||||
version: '4.1.0',
|
||||
chainId: 4,
|
||||
nftAddress: '0x0',
|
||||
metadata: {
|
||||
@ -52,7 +56,7 @@ describe('Simple Publish & consume test', async () => {
|
||||
type: 'access',
|
||||
files: '',
|
||||
datatokenAddress: '0x0',
|
||||
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
|
||||
serviceEndpoint: 'https://v4.provider.rinkeby.oceanprotocol.com',
|
||||
timeout: 0
|
||||
}
|
||||
]
|
||||
@ -105,6 +109,8 @@ describe('Simple Publish & consume test', async () => {
|
||||
const datatokenAddress = tx.events.TokenCreated.returnValues[0]
|
||||
|
||||
// create the files encrypted string
|
||||
assetUrl.datatokenAddress = datatokenAddress
|
||||
assetUrl.nftAddress = nftAddress
|
||||
let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddress
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { deployContracts, Addresses } from '../../TestContractHandler'
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||
import { web3 } from '../../config'
|
||||
import {
|
||||
NftFactory,
|
||||
@ -11,7 +9,9 @@ import {
|
||||
signHash,
|
||||
Nft,
|
||||
transfer,
|
||||
approve
|
||||
approve,
|
||||
balance,
|
||||
Datatoken
|
||||
} from '../../../src'
|
||||
import {
|
||||
ProviderFees,
|
||||
@ -31,7 +31,7 @@ describe('Nft Factory test', () => {
|
||||
let dtAddress2: string
|
||||
let nftAddress: string
|
||||
|
||||
const DATA_TOKEN_AMOUNT = web3.utils.toWei('1')
|
||||
const DATA_TOKEN_AMOUNT = '1'
|
||||
const FEE = '0.001'
|
||||
|
||||
const nftData: NftCreateData = {
|
||||
@ -238,31 +238,26 @@ describe('Nft Factory test', () => {
|
||||
const consumeFeeToken = contracts.daiAddress // token address for the feeAmount, in this case DAI
|
||||
|
||||
// we reuse a DT created in a previous test
|
||||
const dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
||||
expect(await dtContract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||
|
||||
// dt owner mint DATA_TOKEN_AMOUNT to user1
|
||||
await dtContract.methods.mint(user1, DATA_TOKEN_AMOUNT).send({ from: nftOwner })
|
||||
const datatoken = new Datatoken(web3)
|
||||
datatoken.mint(dtAddress, nftOwner, DATA_TOKEN_AMOUNT, user1)
|
||||
|
||||
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
||||
await dtContract.methods
|
||||
.approve(contracts.nftFactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
.send({ from: user1 })
|
||||
await approve(web3, user1, dtAddress, contracts.nftFactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
|
||||
// we reuse another DT created in a previous test
|
||||
const dtContract2 = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress2)
|
||||
expect(await dtContract2.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await balance(web3, dtAddress2, user1)).to.equal('0')
|
||||
|
||||
// dt owner mint DATA_TOKEN_AMOUNT to user1
|
||||
await dtContract2.methods.mint(user1, DATA_TOKEN_AMOUNT).send({ from: nftOwner })
|
||||
datatoken.mint(dtAddress2, nftOwner, DATA_TOKEN_AMOUNT, user1)
|
||||
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
||||
await dtContract2.methods
|
||||
.approve(contracts.nftFactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
.send({ from: user1 })
|
||||
await approve(web3, user1, dtAddress2, contracts.nftFactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
|
||||
// we check user1 has enought DTs
|
||||
expect(await dtContract.methods.balanceOf(user1).call()).to.equal(DATA_TOKEN_AMOUNT)
|
||||
expect(await dtContract2.methods.balanceOf(user1).call()).to.equal(DATA_TOKEN_AMOUNT)
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal(DATA_TOKEN_AMOUNT)
|
||||
expect(await balance(web3, dtAddress2, user1)).to.equal(DATA_TOKEN_AMOUNT)
|
||||
|
||||
const providerData = JSON.stringify({ timeout: 0 })
|
||||
const providerValidUntil = '0'
|
||||
@ -309,8 +304,8 @@ describe('Nft Factory test', () => {
|
||||
]
|
||||
await nftFactory.startMultipleTokenOrder(user1, orders)
|
||||
// we check user1 has no more DTs
|
||||
expect(await dtContract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await dtContract2.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||
expect(await balance(web3, dtAddress2, user1)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#checkDatatoken - should confirm if DT is from the factory', async () => {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { deployContracts, Addresses } from '../../TestContractHandler'
|
||||
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||
import { web3 } from '../../config'
|
||||
import {
|
||||
NftFactory,
|
||||
@ -9,7 +7,8 @@ import {
|
||||
Router,
|
||||
balance,
|
||||
approve,
|
||||
ZERO_ADDRESS
|
||||
ZERO_ADDRESS,
|
||||
transfer
|
||||
} from '../../../src'
|
||||
import { DatatokenCreateParams, PoolCreationParams, Operation } from '../../../src/@types'
|
||||
|
||||
@ -123,14 +122,7 @@ describe('Router unit test', () => {
|
||||
|
||||
it('#buyDatatokenBatch - should buy multiple DT in one call', async () => {
|
||||
// APPROVE DAI
|
||||
const daiContract = new web3.eth.Contract(
|
||||
MockERC20.abi as AbiItem[],
|
||||
contracts.daiAddress
|
||||
)
|
||||
|
||||
await daiContract.methods
|
||||
.transfer(user1, web3.utils.toWei(DAI_AMOUNT))
|
||||
.send({ from: factoryOwner })
|
||||
await transfer(web3, factoryOwner, contracts.daiAddress, user1, DAI_AMOUNT)
|
||||
|
||||
await approve(web3, user1, contracts.daiAddress, contracts.routerAddress, DAI_AMOUNT)
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||
import { deployContracts, Addresses } from '../../../TestContractHandler'
|
||||
import { web3 } from '../../../config'
|
||||
import {
|
||||
@ -13,7 +10,8 @@ import {
|
||||
approve,
|
||||
transfer,
|
||||
balance,
|
||||
unitsToAmount
|
||||
unitsToAmount,
|
||||
Datatoken
|
||||
} from '../../../../src'
|
||||
import { FreCreationParams, DatatokenCreateParams } from '../../../../src/@types'
|
||||
|
||||
@ -26,7 +24,6 @@ describe('Fixed Rate unit test', () => {
|
||||
let contracts: Addresses
|
||||
let fixedRate: FixedRateExchange
|
||||
let dtAddress: string
|
||||
let dtContract: Contract
|
||||
|
||||
const nftData: NftCreateData = {
|
||||
name: '72120Bundle',
|
||||
@ -96,7 +93,6 @@ describe('Fixed Rate unit test', () => {
|
||||
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
|
||||
|
||||
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||
|
||||
@ -194,9 +190,8 @@ describe('Fixed Rate unit test', () => {
|
||||
|
||||
it('#buyDatatokens - user1 should buy some dt', async () => {
|
||||
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
||||
await dtContract.methods
|
||||
.mint(exchangeOwner, web3.utils.toWei('1000'))
|
||||
.send({ from: exchangeOwner })
|
||||
const datatoken = new Datatoken(web3)
|
||||
await datatoken.mint(dtAddress, exchangeOwner, '1000', exchangeOwner)
|
||||
await approve(web3, exchangeOwner, dtAddress, contracts.fixedRateAddress, '1000')
|
||||
// user1 gets 100 DAI so he can buy DTs
|
||||
await transfer(web3, exchangeOwner, contracts.daiAddress, user1, '100')
|
||||
@ -409,7 +404,6 @@ describe('Fixed Rate unit test', () => {
|
||||
dtAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
exchangeId = txReceipt.events.NewFixedRate.returnValues.exchangeId
|
||||
|
||||
dtContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], dtAddress)
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||
|
||||
@ -503,9 +497,8 @@ describe('Fixed Rate unit test', () => {
|
||||
|
||||
it('#buyDatatokens - user1 should buy some dt', async () => {
|
||||
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
||||
await dtContract.methods
|
||||
.mint(exchangeOwner, web3.utils.toWei('1000'))
|
||||
.send({ from: exchangeOwner })
|
||||
const datatoken = new Datatoken(web3)
|
||||
await datatoken.mint(dtAddress, exchangeOwner, '1000', exchangeOwner)
|
||||
await approve(web3, exchangeOwner, dtAddress, contracts.fixedRateAddress, '1000')
|
||||
// user1 gets 100 USDC so he can buy DTs
|
||||
await transfer(web3, exchangeOwner, contracts.usdcAddress, user1, '100')
|
||||
|
@ -1,9 +1,5 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||
import MockERC20 from '@oceanprotocol/contracts/artifacts/contracts/utils/mock/MockERC20Decimals.sol/MockERC20Decimals.json'
|
||||
import { deployContracts, Addresses } from '../../../TestContractHandler'
|
||||
import { web3 } from '../../../config'
|
||||
import {
|
||||
@ -15,7 +11,10 @@ import {
|
||||
Pool,
|
||||
SideStaking,
|
||||
unitsToAmount,
|
||||
ZERO_ADDRESS
|
||||
ZERO_ADDRESS,
|
||||
balance,
|
||||
transfer,
|
||||
decimals
|
||||
} from '../../../../src'
|
||||
import {
|
||||
DatatokenCreateParams,
|
||||
@ -24,6 +23,7 @@ import {
|
||||
AmountsInMaxFee,
|
||||
AmountsOutMaxFee
|
||||
} from '../../../../src/@types'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
|
||||
describe('SideStaking unit test', () => {
|
||||
let factoryOwner: string
|
||||
@ -86,12 +86,6 @@ describe('SideStaking unit test', () => {
|
||||
sideStaking = new SideStaking(web3, 8996)
|
||||
assert(sideStaking != null)
|
||||
|
||||
daiContract = new web3.eth.Contract(MockERC20.abi as AbiItem[], contracts.daiAddress)
|
||||
usdcContract = new web3.eth.Contract(
|
||||
MockERC20.abi as AbiItem[],
|
||||
contracts.usdcAddress
|
||||
)
|
||||
|
||||
await approve(
|
||||
web3,
|
||||
factoryOwner,
|
||||
@ -164,9 +158,10 @@ describe('SideStaking unit test', () => {
|
||||
datatoken = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
datatokenContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], datatoken)
|
||||
// user1 has no dt1
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, datatoken, user1)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getRouter - should get Router address', async () => {
|
||||
@ -251,9 +246,7 @@ describe('SideStaking unit test', () => {
|
||||
})
|
||||
|
||||
it('#swapExactAmountIn - should swap', async () => {
|
||||
await daiContract.methods
|
||||
.transfer(user1, web3.utils.toWei('1000'))
|
||||
.send({ from: factoryOwner })
|
||||
await transfer(web3, factoryOwner, contracts.daiAddress, user1, '1000')
|
||||
await approve(web3, user1, contracts.daiAddress, poolAddress, '10')
|
||||
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
@ -275,8 +268,12 @@ describe('SideStaking unit test', () => {
|
||||
amountsInOutMaxFee
|
||||
)
|
||||
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal(
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
expect(await balance(web3, datatoken, user1)).to.equal(
|
||||
await unitsToAmount(
|
||||
web3,
|
||||
datatoken,
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
@ -359,7 +356,7 @@ describe('SideStaking unit test', () => {
|
||||
marketFeeCollector: factoryOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
rate: '1',
|
||||
baseTokenDecimals: await usdcContract.methods.decimals().call(),
|
||||
baseTokenDecimals: await decimals(web3, contracts.usdcAddress),
|
||||
vestingAmount: VESTING_AMOUNT,
|
||||
vestedBlocks: VESTED_BLOCKS,
|
||||
initialBaseTokenLiquidity: await unitsToAmount(
|
||||
@ -386,9 +383,8 @@ describe('SideStaking unit test', () => {
|
||||
datatoken = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
datatokenContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], datatoken)
|
||||
// user1 has no dt1
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await balance(web3, datatoken, user1)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getBasetokenBalance ', async () => {
|
||||
@ -431,12 +427,9 @@ describe('SideStaking unit test', () => {
|
||||
})
|
||||
|
||||
it('#swapExactAmountIn - should swap', async () => {
|
||||
const transferAmount = await amountToUnits(web3, contracts.usdcAddress, '1000') // 1000 USDC
|
||||
await usdcContract.methods
|
||||
.transfer(user1, transferAmount)
|
||||
.send({ from: factoryOwner })
|
||||
|
||||
await transfer(web3, factoryOwner, contracts.usdcAddress, user1, '1000') // 1000 USDC
|
||||
await approve(web3, user1, contracts.usdcAddress, poolAddress, '10')
|
||||
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.usdcAddress,
|
||||
tokenOut: datatoken,
|
||||
@ -453,8 +446,13 @@ describe('SideStaking unit test', () => {
|
||||
tokenInOutMarket,
|
||||
amountsInOutMaxFee
|
||||
)
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal(
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
|
||||
expect(await balance(web3, datatoken, user1)).to.equal(
|
||||
await unitsToAmount(
|
||||
web3,
|
||||
datatoken,
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -486,6 +486,8 @@ describe('Datatoken', () => {
|
||||
exchangeContract: fixedRateAddress,
|
||||
exchangeId: exchangeId,
|
||||
maxBaseTokenAmount: '1',
|
||||
baseTokenAddress: contracts.daiAddress,
|
||||
baseTokenDecimals: 18,
|
||||
swapMarketFee: '0.1',
|
||||
marketFeeAddress: ZERO_ADDRESS
|
||||
}
|
||||
@ -544,20 +546,19 @@ describe('Datatoken', () => {
|
||||
assert(address, 'Not able to get the parent NFT address')
|
||||
})
|
||||
|
||||
it('#setData - should set a value into 725Y standard, if Caller has DatatokenDeployer permission', async () => {
|
||||
const data = web3.utils.asciiToHex('SomeData')
|
||||
it('#setData - should set a value into 725Y standard, if Caller has ERC20Deployer permission', async () => {
|
||||
const data = 'SomeData'
|
||||
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === true)
|
||||
|
||||
await datatoken.setData(datatokenAddress, nftOwner, data)
|
||||
|
||||
const key = web3.utils.keccak256(datatokenAddress)
|
||||
assert((await nftDatatoken.getData(nftAddress, key)) === data)
|
||||
assert((await nftDatatoken.getData(nftAddress, datatokenAddress)) === data)
|
||||
})
|
||||
|
||||
it('#setData - should FAIL to set a value into 725Y standard, if Caller has NOT DatatokenDeployer permission', async () => {
|
||||
const data = web3.utils.asciiToHex('NewData')
|
||||
const OldData = web3.utils.asciiToHex('SomeData')
|
||||
it('#setData - should FAIL to set a value into 725Y standard, if Caller has NOT ERC20Deployer permission', async () => {
|
||||
const data = 'NewData'
|
||||
const OldData = 'SomeData'
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === false)
|
||||
|
||||
try {
|
||||
@ -566,8 +567,7 @@ describe('Datatoken', () => {
|
||||
} catch (e) {
|
||||
assert(e.message === 'User is not Datatoken Deployer')
|
||||
}
|
||||
const key = web3.utils.keccak256(datatokenAddress)
|
||||
assert((await nftDatatoken.getData(nftAddress, key)) === OldData)
|
||||
assert((await nftDatatoken.getData(nftAddress, datatokenAddress)) === OldData)
|
||||
})
|
||||
|
||||
it('#getDecimals - should return the number of decimals of the datatoken', async () => {
|
||||
|
@ -433,4 +433,31 @@ describe('NFT', () => {
|
||||
assert(metadata[0] === metadataAndTokenURI.metaDataDecryptorUrl)
|
||||
assert(metadata[1] === metadataAndTokenURI.metaDataDecryptorAddress)
|
||||
})
|
||||
|
||||
it('#setData - should FAIL to set a value into 725Y standard, if Caller has NOT store updater permission', async () => {
|
||||
const key = 'KEY'
|
||||
const data = 'NewData'
|
||||
assert((await nftDatatoken.getNftPermissions(nftAddress, user1)).store === false)
|
||||
|
||||
try {
|
||||
await nftDatatoken.setData(nftAddress, user1, key, data)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'User is not ERC20 store updater')
|
||||
}
|
||||
assert((await nftDatatoken.getData(nftAddress, key)) === null)
|
||||
})
|
||||
|
||||
it('#setData - should set a value into 725Y standard, if Caller has store updater permission', async () => {
|
||||
const key = 'KEY'
|
||||
const data = 'NewData'
|
||||
|
||||
// add store updater permission
|
||||
await nftDatatoken.addStoreUpdater(nftAddress, user1, user1)
|
||||
assert((await nftDatatoken.getNftPermissions(nftAddress, user1)).store === true)
|
||||
|
||||
await nftDatatoken.setData(nftAddress, user1, key, data)
|
||||
|
||||
assert((await nftDatatoken.getData(nftAddress, key)) === data)
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user