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

publish tests (#1184)

* publish tests

* update to latest contracts

* fix unit tests
This commit is contained in:
Alex Coseru 2022-01-03 17:34:28 +02:00 committed by GitHub
parent bfddea15d5
commit f23e65f61b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 334 additions and 91 deletions

View File

@ -27,6 +27,7 @@ jobs:
key: ${{ runner.os }}-lint-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-lint-${{ env.cache-name }}-
- run: npm ci
- run: npm i --verbose --force @oceanprotocol/contracts@"github:oceanprotocol/contracts#v4main_postaudit"
- run: npm run lint
test_unit:
@ -51,6 +52,7 @@ jobs:
with:
repository: 'oceanprotocol/barge'
path: 'barge'
ref: v4
- name: Run Ganache with Barge
working-directory: ${{ github.workspace }}/barge
@ -59,6 +61,7 @@ jobs:
cd ..
- run: npm ci
- run: npm i --verbose --force @oceanprotocol/contracts@"github:oceanprotocol/contracts#v4main_postaudit"
- run: npm run build:metadata
- run: npm run test:unit:cover
- uses: actions/upload-artifact@v2
@ -83,6 +86,7 @@ jobs:
key: ${{ runner.os }}-test-integration-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-test-integration-${{ env.cache-name }}-
- run: npm ci
- run: npm i --verbose --force @oceanprotocol/contracts@"github:oceanprotocol/contracts#v4main_postaudit"
- run: npm run build:metadata
# Env var expansion workaround
@ -95,6 +99,7 @@ jobs:
with:
repository: 'oceanprotocol/barge'
path: 'barge'
ref: v4
- name: Login to Docker Hub
if: ${{ env.DOCKERHUB_PASSWORD && env.DOCKERHUB_USERNAME }}
@ -110,9 +115,13 @@ jobs:
bash -x start_ocean.sh --with-provider2 --no-dashboard 2>&1 > start_ocean.log &
cd .. && ./scripts/waitforcontracts.sh
- run: npm run test:integration:cover
- uses: actions/upload-artifact@v2
- name: integration
run: npm run test:integration:cover
- name: docker logs
run: docker logs ocean_aquarius_1
if: ${{ failure() }}
- name: Upload coverage
uses: actions/upload-artifact@v2
with:
name: coverage
path: coverage/
@ -140,6 +149,7 @@ jobs:
key: ${{ runner.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-
- run: npm ci
- run: npm i --verbose --force @oceanprotocol/contracts@"github:oceanprotocol/contracts#v4main_postaudit"
- run: npm run build
- run: npm run doc:json

View File

@ -1,4 +1,4 @@
import { DDO } from './DDO'
import { DDO } from './DDO/DDO'
export interface AssetNft {
/**

View File

@ -1,4 +1,4 @@
import { Metadata, MetadataAlgorithm } from './Metadata'
import { Metadata, MetadataAlgorithm } from './DDO/Metadata'
export type ComputeResultType = 'algorithmLog' | 'output'

View File

@ -1,6 +1,7 @@
import { Service } from './Service'
import { Metadata } from './Metadata'
import { Credentials } from './Credentials'
import { Event } from './Event'
/**
* DID Descriptor Object.
@ -27,6 +28,12 @@ export interface DDO {
*/
version: string
/**
* NFT contract address
* @type {string}
*/
nftAddress: string
/**
* ChainId of the network the DDO was published to.
* @type {number}
@ -51,4 +58,10 @@ export interface DDO {
* @type {Credentials}
*/
credentials?: Credentials
/**
* Describes the event of last metadata event
* @type {Event}
*/
event?: Event
}

31
src/@types/DDO/Event.ts Normal file
View File

@ -0,0 +1,31 @@
export interface Event {
/**
* TX id of the last create/update
* @type {string}
*/
txid?: string
/**
* Block of txid
* @type {number}
*/
block?: number
/**
* Sender of tx
* @type {String}
*/
from?: string
/**
* Contract
* @type {String}
*/
contract?: string
/**
* datetime of tx
* @type {String}
*/
datetime?: string
}

View File

@ -1,7 +1,7 @@
export * from './DDO'
export * from './DDO/DDO'
export * from './Asset'
export * from './Service'
export * from './Credentials'
export * from './Metadata'
export * from './DDO/Service'
export * from './DDO/Credentials'
export * from './DDO/Metadata'
export * from './FileMetadata'
export * from './Compute'

76
src/aquarius/Aquarius.ts Normal file
View File

@ -0,0 +1,76 @@
import { LoggerInstance } from '../utils'
import { DDO } from '../@types/'
export class Aquarius {
public aquariusURL
/**
* Instantiate Aquarius
* @param {String} aquariusURL
*/
constructor(aquariusURL: string) {
this.aquariusURL = aquariusURL
}
/** Resolves a DID
* @param {string} did
* @param {string} fetchMethod fetch client instance
* @return {Promise<DDO>} DDO
*/
public async resolve(did: string, fetchMethod: any): Promise<DDO> {
const path = this.aquariusURL + '/api/aquarius/assets/ddo/' + did
try {
console.log(path)
const response = await fetchMethod(path)
if (response.ok) {
const raw = await response.json()
console.log(raw)
return raw as DDO
} else {
throw new Error('HTTP request failed with status ' + response.status)
}
} catch (e) {
LoggerInstance.error(e)
throw new Error('HTTP request failed')
}
}
/**
* Simple blocking sleep function
*/
public sleep(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
}
/**
* Blocks until Aqua will cache the did (or the update for that did) or timeouts
* @param {string} did DID of the asset.
* @param {string} txid used when the did exists and we expect an update with that txid.
* @param {string} fetchMethod fetch client instance
* @return {Promise<DDO>} DDO of the asset.
*/
public async waitForAqua(fetchMethod: any, did: string, txid?: string): Promise<DDO> {
let tries = 0
do {
try {
const path = this.aquariusURL + '/api/aquarius/assets/ddo/' + did
const response = await fetchMethod(path)
if (response.ok) {
const ddo = await response.json()
if (txid) {
// check tx
if (ddo.event && ddo.event.txid === txid) return ddo as DDO
} else return ddo as DDO
}
} catch (e) {
// do nothing
}
await this.sleep(1500)
tries++
} while (tries < 100)
return null
}
}
export default Aquarius

1
src/aquarius/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './Aquarius'

View File

@ -30,7 +30,7 @@ export interface TokenOrder {
providerFeeAddress: string
providerFeeToken: string
providerFeeAmount: string
v: number // v of provider signed message
v: string // v of provider signed message
r: string // r of provider signed message
s: string // s of provider signed message
providerData: string // data encoded by provider

View File

@ -21,8 +21,8 @@ export interface OrderParams {
serviceIndex: number
providerFeeAddress: string
providerFeeToken: string
providerFeeAmount: string
v: number // v of provider signed message
providerFeeAmount: string // this is in WEI
v: string // v of provider signed message
r: string // r of provider signed message
s: string // s of provider signed message
providerData: string // data encoded by provider
@ -855,7 +855,7 @@ export class Datatoken {
providerFeeAddress: string,
providerFeeToken: string,
providerFeeAmount: string,
v: number,
v: string,
r: string,
s: string,
providerDatas: string,
@ -874,7 +874,7 @@ export class Datatoken {
serviceIndex,
providerFeeAddress,
providerFeeToken,
this.web3.utils.toWei(providerFeeAmount),
providerFeeAmount,
v,
r,
s,
@ -894,7 +894,7 @@ export class Datatoken {
* @param {Number} serviceIndex Service index in the metadata
* @param {String} providerFeeAddress Consume marketplace fee address
* @param {String} providerFeeToken address of the token marketplace wants to add fee on top
* @param {String} providerFeeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI
* @param {String} providerFeeAmount amount of feeToken to be transferred to mpFeeAddress on top, expressed in Wei
* @param {String} v // v of provider signed message
* @param {String} r // r of provider signed message
* @param {String} s // s of provider signed message
@ -909,7 +909,7 @@ export class Datatoken {
providerFeeAddress: string,
providerFeeToken: string,
providerFeeAmount: string,
v: number,
v: string,
r: string,
s: string,
providerDatas: string
@ -940,7 +940,7 @@ export class Datatoken {
serviceIndex,
providerFeeAddress,
providerFeeToken,
this.web3.utils.toWei(providerFeeAmount),
providerFeeAmount,
v,
r,
s,

View File

@ -927,7 +927,8 @@ export class Nft {
metaDataDecryptorAddress,
flags,
data,
metadataHash
metadataHash,
[]
)
.estimateGas({ from: metadataUpdater }, (err, estGas) =>
err ? gasLimitDefault : estGas
@ -973,8 +974,6 @@ export class Nft {
metadataHash,
nftContract
)
// Call transferFrom function of the contract
const trxReceipt = await nftContract.methods
.setMetaData(
metadataState,
@ -982,7 +981,8 @@ export class Nft {
metaDataDecryptorAddress,
flags,
data,
metadataHash
metadataHash,
[]
)
.send({
from: address,

View File

@ -27,6 +27,18 @@ export async function signText(
}
}
export async function signHash(web3: Web3, message: string, address: string) {
let signedMessage = await web3.eth.sign(message, address)
signedMessage = signedMessage.substr(2) // remove 0x
const r = '0x' + signedMessage.slice(0, 64)
const s = '0x' + signedMessage.slice(64, 128)
let v = '0x' + signedMessage.slice(128, 130)
// make sure we obey 27 and 28 standards
if (v === '0x00') v = '0x1b'
if (v === '0x01') v = '0x1c'
return { v, r, s }
}
export async function signWithHash(
web3: Web3,
text: string,

View File

@ -6,3 +6,4 @@ export * from './FetchHelper'
export * from './ConfigHelper'
export * from './DdoHelpers'
export * from './Constants'
export * from './SignatureUtils'

View File

@ -0,0 +1,124 @@
import config from './config'
import ProviderInstance, { Provider } from '../../src/provider/Provider'
import Aquarius from '../../src/aquarius/Aquarius'
import { assert } from 'chai'
import { NftFactory, NftCreateData } from '../../src/factories/index'
import { Erc20CreateParams } from '../../src/interfaces'
import { getHash } from '../../src/utils'
import { Nft } from '../../src/tokens/NFT'
import Web3 from 'web3'
import fetch from 'cross-fetch'
import { SHA256 } from 'crypto-js'
import { homedir } from 'os'
import fs from 'fs'
import console from 'console'
const data = JSON.parse(
fs.readFileSync(
process.env.ADDRESS_FILE ||
`${homedir}/.ocean/ocean-contracts/artifacts/address.json`,
'utf8'
)
)
const addresses = data.development
console.log(addresses)
const aquarius = new Aquarius('http://127.0.0.1:5000')
const web3 = new Web3('http://127.0.0.1:8545')
const ddo = {
'@context': ['https://w3id.org/did/v1'],
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
version: '4.0.0',
chainId: 4,
nftAddress: '0x0',
metadata: {
created: '2021-12-20T14:35:20Z',
updated: '2021-12-20T14:35:20Z',
type: 'dataset',
name: 'dfgdfgdg',
description: 'd dfgd fgd dfg dfgdfgd dfgdf',
tags: [''],
author: 'dd',
license: 'https://market.oceanprotocol.com/terms',
additionalInformation: {
termsAndConditions: true
}
},
services: [
{
id: 'notAnId',
type: 'download',
files:
'0x04b69c2363b360cad8bffe1c681910598757d9ed8b7a79d1caff5efcfbb656cb9862b9068fa24462b20c5740d0c24db69c93657d261edf1123ed2300b34f8f652f53cf2862cdc2b0b201c5881f39151bfaabbd39c69f51fafc2965987be2bbe90dae10dbdd30f262404896feb7a8043bb62b72c0bc5d1525f07067ed42af7020ce96de634c6e23fd28947932b8adb6fc34c97eee2c0d441ad5eced00bed84633de5bcf6812dcd7f865bebdd5f9ae32efcf22aaca53c6ee3bb46c1566835d26a4263e5e82c65f29d701e37f47f1102b0afb48d07dea3dcdfaa37bca7d471b8833bfc20c25ee681e3f2670a451b635decf1550003339e32cf9bd75d4f331b35ae3362fead77e30594723dd8c6dbf4141fbd681a18e72786bfeb2216dd137a0cfe0ec8519760843e2114b3a3ed46d9319e2e9f9c58c78a916328324f77d62abac6719f3b88d2da4e60699bb159a8deabd53d003',
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
serviceEndpoint: 'https://providerv4.rinkeby.oceanprotocol.com',
timeout: 0
}
]
}
describe('Publish tests', async () => {
it('should publish a dataset (create NFT + ERC20)', async () => {
const nft = new Nft(web3)
const Factory = new NftFactory(addresses.ERC721Factory, web3)
const accounts = await web3.eth.getAccounts()
const accountId = accounts[0]
const nftParams: NftCreateData = {
name: 'testNFT',
symbol: 'TST',
templateIndex: 1,
tokenURI: ''
}
const erc20Params: Erc20CreateParams = {
templateIndex: 1,
cap: '100000',
feeAmount: '0',
feeManager: '0x0000000000000000000000000000000000000000',
feeToken: '0x0000000000000000000000000000000000000000',
minter: accountId,
mpFeeAddress: '0x0000000000000000000000000000000000000000'
}
const result = await Factory.createNftWithErc(accountId, nftParams, erc20Params)
const erc721Address = result.events.NFTCreated.returnValues[0]
const datatokenAddress = result.events.TokenCreated.returnValues[0]
// update ddo and set the right did
ddo.nftAddress = erc721Address
const chain = await web3.eth.getChainId()
ddo.id =
'did:op:' + SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
const providerResponse = await ProviderInstance.encrypt(
ddo,
'http://172.15.0.4:8030',
(url: string, body: string) => {
// replace with fetch
return fetch(url, {
method: 'POST',
body: body,
headers: { 'Content-Type': 'application/octet-stream' }
})
}
)
const encryptedResponse = await providerResponse.text()
const metadataHash = getHash(JSON.stringify(ddo))
const res = await nft.setMetadata(
erc721Address,
accountId,
0,
'http://172.15.0.4:8030',
'',
'0x2',
encryptedResponse,
'0x' + metadataHash
)
const resolvedDDO = await aquarius.waitForAqua((url: string, body: string) => {
// replace with fetch
return fetch(url, {
method: 'GET',
body: body
})
}, ddo.id)
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
})
})

View File

@ -18,16 +18,9 @@ import {
Erc20CreateParams,
PoolCreationParams
} from '../../src/interfaces'
import { ZERO_ADDRESS } from '../../src/utils'
import { ZERO_ADDRESS, signHash } from '../../src/utils'
const web3 = new Web3('http://127.0.0.1:8545')
function signMessage(message, privateKey) {
const { v, r, s } = ecsign(
Buffer.from(message.slice(2), 'hex'),
Buffer.from(privateKey, 'hex')
)
return { v, r, s }
}
describe('Nft Factory test', () => {
let factoryOwner: string
@ -386,15 +379,11 @@ describe('Nft Factory test', () => {
const providerData = JSON.stringify({ timeout: 0 })
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
{ t: 'address', v: consumeFeeAddress },
{ t: 'address', v: consumeFeeToken },
{ t: 'uint256', v: web3.utils.toWei(consumeFeeAmount) }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const { v, r, s } = await signHash(web3, message, consumeFeeAddress)
const orders: TokenOrder[] = [
{
tokenAddress: dtAddress,
@ -403,9 +392,9 @@ describe('Nft Factory test', () => {
providerFeeAddress: consumeFeeAddress,
providerFeeToken: consumeFeeToken,
providerFeeAmount: consumeFeeAmount,
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
v,
r,
s,
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
},
{
@ -415,15 +404,13 @@ describe('Nft Factory test', () => {
providerFeeAddress: consumeFeeAddress,
providerFeeToken: consumeFeeToken,
providerFeeAmount: consumeFeeAmount,
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
v,
r,
s,
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
}
]
console.log('orders', orders)
await nftFactory.startMultipleTokenOrder(user2, orders)
// we check user2 has no more DTs
expect(await dtContract.methods.balanceOf(user2).call()).to.equal('0')
expect(await dtContract2.methods.balanceOf(user2).call()).to.equal('0')

View File

@ -17,17 +17,10 @@ import { NftFactory, NftCreateData } from '../../../src/factories/NFTFactory'
import { Datatoken, Nft, OrderParams, DispenserParams } from '../../../src/tokens'
import { AbiItem } from 'web3-utils'
import { FreCreationParams, FreOrderParams } from '../../../src/interfaces'
import { ZERO_ADDRESS, signHash } from '../../../src/utils'
const web3 = new Web3('http://127.0.0.1:8545')
function signMessage(message, privateKey) {
const { v, r, s } = ecsign(
Buffer.from(message.slice(2), 'hex'),
Buffer.from(privateKey, 'hex')
)
return { v, r, s }
}
describe('Datatoken', () => {
let nftOwner: string
let user1: string
@ -350,28 +343,26 @@ describe('Datatoken', () => {
)
const providerData = JSON.stringify({ timeout: 0 })
const providerFeeToken = ZERO_ADDRESS
const providerFeeAmount = '0'
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
{ t: 'address', v: providerFeeToken },
{ t: 'uint256', v: providerFeeAmount }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const { v, r, s } = await signHash(web3, message, user3)
const order = await datatoken.startOrder(
datatokenAddress,
user1,
user2,
1,
user3,
'0x0000000000000000000000000000000000000000',
'0',
signedMessage.v,
web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerFeeToken,
providerFeeAmount,
v,
r,
s,
web3.utils.toHex(web3.utils.asciiToHex(providerData))
)
assert(order !== null)
@ -391,26 +382,24 @@ describe('Datatoken', () => {
it('#buyFromDispenserAndOrder- Enterprise method', async () => {
const providerData = JSON.stringify({ timeout: 0 })
const providerFeeToken = ZERO_ADDRESS
const providerFeeAmount = '0'
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
{ t: 'address', v: providerFeeToken },
{ t: 'uint256', v: providerFeeAmount }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const { v, r, s } = await signHash(web3, message, user3)
const order: OrderParams = {
consumer: user1,
serviceIndex: 1,
providerFeeAddress: user3,
providerFeeToken: '0x0000000000000000000000000000000000000000',
providerFeeAmount: '0',
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerFeeToken,
providerFeeAmount,
v,
r,
s,
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
}
console.log('order', order)
@ -425,26 +414,24 @@ describe('Datatoken', () => {
it('#buyFromFreAndOrder - Enterprise method ', async () => {
const providerData = JSON.stringify({ timeout: 0 })
const providerFeeToken = ZERO_ADDRESS
const providerFeeAmount = '0'
const message = web3.utils.soliditySha3(
{ t: 'bytes', v: web3.utils.toHex(web3.utils.asciiToHex(providerData)) },
{ t: 'address', v: user3 },
{ t: 'address', v: '0x0000000000000000000000000000000000000000' },
{ t: 'uint256', v: '1' }
{ t: 'address', v: providerFeeToken },
{ t: 'uint256', v: providerFeeAmount }
)
const signedMessage = signMessage(
message,
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'
)
const { v, r, s } = await signHash(web3, message, user3)
const order: OrderParams = {
consumer: user1,
serviceIndex: 1,
providerFeeAddress: user1,
providerFeeToken: '0x0000000000000000000000000000000000000000',
providerFeeAmount: '0',
v: signedMessage.v,
r: web3.utils.asciiToHex(signedMessage.r.toString('ascii')),
s: web3.utils.asciiToHex(signedMessage.s.toString('ascii')),
providerFeeToken,
providerFeeAmount,
v,
r,
s,
providerData: web3.utils.toHex(web3.utils.asciiToHex(providerData))
}

View File

@ -13,6 +13,7 @@ import { TestContractHandler } from '../../TestContractHandler'
import { NftFactory, NftCreateData } from '../../../src/factories/NFTFactory'
import { Nft } from '../../../src/tokens/NFT'
import { AbiItem } from 'web3-utils'
import sha256 from 'crypto-js/sha256'
const web3 = new Web3('http://127.0.0.1:8545')
@ -333,7 +334,7 @@ describe('NFT', () => {
const metaDataDecryptorAddress = '0x123'
const metaDataState = 1
const data = web3.utils.asciiToHex(user2)
const dataHash = web3.utils.asciiToHex(user2)
const dataHash = '0x' + sha256(data).toString()
const flags = web3.utils.asciiToHex(user2)
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user1)).updateMetadata === true
@ -359,7 +360,7 @@ describe('NFT', () => {
const metaDataDecryptorAddress = '0x123'
const metaDataState = 1
const data = web3.utils.asciiToHex(user2)
const dataHash = web3.utils.asciiToHex(user2)
const dataHash = '0x' + sha256(data).toString()
const flags = web3.utils.asciiToHex(user2)
assert(
(await nftDatatoken.getNftPermissions(nftAddress, user3)).updateMetadata === false