mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
Merge branch 'master' into feature/transferOwnership
This commit is contained in:
commit
204c5645b8
@ -24,9 +24,9 @@ before_script:
|
|||||||
- git clone https://github.com/oceanprotocol/barge
|
- git clone https://github.com/oceanprotocol/barge
|
||||||
- cd barge
|
- cd barge
|
||||||
- export AQUARIUS_VERSION=unstable
|
- export AQUARIUS_VERSION=unstable
|
||||||
- export BRIZO_VERSION=v0.8.1
|
- export BRIZO_VERSION=v0.9.3
|
||||||
- export KEEPER_VERSION=v0.13.2
|
- export KEEPER_VERSION=v0.13.2
|
||||||
- export EVENTS_HANDLER_VERSION=v0.4.4
|
- export EVENTS_HANDLER_VERSION=v0.4.5
|
||||||
- export KEEPER_OWNER_ROLE_ADDRESS="0xe2DD09d719Da89e5a3D0F2549c7E24566e947260"
|
- export KEEPER_OWNER_ROLE_ADDRESS="0xe2DD09d719Da89e5a3D0F2549c7E24566e947260"
|
||||||
- rm -rf "${HOME}/.ocean/keeper-contracts/artifacts"
|
- rm -rf "${HOME}/.ocean/keeper-contracts/artifacts"
|
||||||
- bash -x start_ocean.sh --no-commons --no-dashboard 2>&1 > start_ocean.log &
|
- bash -x start_ocean.sh --no-commons --no-dashboard 2>&1 > start_ocean.log &
|
||||||
|
58
CHANGELOG.md
58
CHANGELOG.md
@ -4,24 +4,70 @@ 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).
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||||
|
|
||||||
#### [v1.3.0](https://github.com/oceanprotocol/squid-js/compare/v1.2.0...v1.3.0)
|
#### [v2.0.0-beta.5](https://github.com/oceanprotocol/squid-js/compare/2.0.0-beta.4...v2.0.0-beta.5)
|
||||||
|
|
||||||
|
> 10 March 2020
|
||||||
|
|
||||||
|
- Update the compute condition name in ddo jason definition. [`#380`](https://github.com/oceanprotocol/squid-js/pull/380)
|
||||||
|
|
||||||
|
#### [2.0.0-beta.4](https://github.com/oceanprotocol/squid-js/compare/v2.0.0-beta.3...2.0.0-beta.4)
|
||||||
|
|
||||||
|
> 6 March 2020
|
||||||
|
|
||||||
|
- v2: Compute to Data [`#350`](https://github.com/oceanprotocol/squid-js/pull/350)
|
||||||
|
- Fix style issues and failing unit tests. [`c26ae88`](https://github.com/oceanprotocol/squid-js/commit/c26ae88fa3d63a65b7cba38224cbdcb23cbe6685)
|
||||||
|
- Fix publishing compute service (fill in parameters value in agreement conditions). Update agreement template events and conditions in the sample json. [`75a0ef0`](https://github.com/oceanprotocol/squid-js/commit/75a0ef05d9789a9358180707b28bad95a84d6499)
|
||||||
|
- Return proper value from the compute endpoints. [`e2ed974`](https://github.com/oceanprotocol/squid-js/commit/e2ed974af27c7b828980919cb2846fc514fda142)
|
||||||
|
|
||||||
|
#### [v2.0.0-beta.3](https://github.com/oceanprotocol/squid-js/compare/v2.0.0-beta.2...v2.0.0-beta.3)
|
||||||
|
|
||||||
|
> 20 February 2020
|
||||||
|
|
||||||
|
- Adding output section [`#372`](https://github.com/oceanprotocol/squid-js/pull/372)
|
||||||
|
- add Output Object passed to brizo [`a60e415`](https://github.com/oceanprotocol/squid-js/commit/a60e4159255aadeba00bec2e72cf0fbb4b71489c)
|
||||||
|
- lint fix [`6e2289b`](https://github.com/oceanprotocol/squid-js/commit/6e2289b27ddc8643076385ee3fe8cfb743d4ecfb)
|
||||||
|
- add Output interface [`9cf716e`](https://github.com/oceanprotocol/squid-js/commit/9cf716ebe472ec24603c1bcf052848ad4464d9dd)
|
||||||
|
|
||||||
|
#### [v2.0.0-beta.2](https://github.com/oceanprotocol/squid-js/compare/v1.3.0...v2.0.0-beta.2)
|
||||||
|
|
||||||
|
> 31 January 2020
|
||||||
|
|
||||||
|
- Release 2.0.0-beta.2 [`4e45a77`](https://github.com/oceanprotocol/squid-js/commit/4e45a773d67b0f4199ffd5eae00b06213ba5622f)
|
||||||
|
|
||||||
|
#### [v2.0.0-beta.1](https://github.com/oceanprotocol/squid-js/compare/v2.0.0-beta.0...v2.0.0-beta.1)
|
||||||
|
|
||||||
|
> 28 January 2020
|
||||||
|
|
||||||
|
- remove `index` parameter from ocean.assets.consume() [`138a6bf`](https://github.com/oceanprotocol/squid-js/commit/138a6bf75abc402396606fab3bc3701875d7a393)
|
||||||
|
- Release 2.0.0-beta.1 [`1d7105c`](https://github.com/oceanprotocol/squid-js/commit/1d7105cfb1e80cb45711517ae6840d9ac22e80a6)
|
||||||
|
|
||||||
|
#### [v2.0.0-beta.0](https://github.com/oceanprotocol/squid-js/compare/v1.2.0...v2.0.0-beta.0)
|
||||||
|
|
||||||
|
> 28 January 2020
|
||||||
|
|
||||||
|
- Update cross-env to the latest version 🚀 [`#363`](https://github.com/oceanprotocol/squid-js/pull/363)
|
||||||
|
- Update mocha to the latest version 🚀 [`#364`](https://github.com/oceanprotocol/squid-js/pull/364)
|
||||||
|
- new ocean.utils.services [`40754ca`](https://github.com/oceanprotocol/squid-js/commit/40754ca46a10578cfdf0f460a7c33ba37bb2ffde)
|
||||||
|
- DDO & compute test tweaks [`e7acadb`](https://github.com/oceanprotocol/squid-js/commit/e7acadb2fe91739eee1bff3589801f12c7ab0b1b)
|
||||||
|
- test data consolidation [`ac39369`](https://github.com/oceanprotocol/squid-js/commit/ac39369543779370b9be6f00b0f2063a7e50c763)
|
||||||
|
|
||||||
|
#### [v1.3.0](https://github.com/oceanprotocol/squid-js/compare/v2.0.0-beta.1...v1.3.0)
|
||||||
|
|
||||||
> 31 January 2020
|
> 31 January 2020
|
||||||
|
|
||||||
- switch to @ethereum-navigator for network lookup [`#366`](https://github.com/oceanprotocol/squid-js/pull/366)
|
- switch to @ethereum-navigator for network lookup [`#366`](https://github.com/oceanprotocol/squid-js/pull/366)
|
||||||
- consolidate test files [`#371`](https://github.com/oceanprotocol/squid-js/pull/371)
|
- consolidate test files [`#371`](https://github.com/oceanprotocol/squid-js/pull/371)
|
||||||
- package updates [`#368`](https://github.com/oceanprotocol/squid-js/pull/368)
|
- package updates [`#368`](https://github.com/oceanprotocol/squid-js/pull/368)
|
||||||
- Update cross-env to the latest version 🚀 [`#363`](https://github.com/oceanprotocol/squid-js/pull/363)
|
- service interface refactor and cleanup [`768c69b`](https://github.com/oceanprotocol/squid-js/commit/768c69bdbdc0591e2e747d87082e859bc52cd7d2)
|
||||||
- Update mocha to the latest version 🚀 [`#364`](https://github.com/oceanprotocol/squid-js/pull/364)
|
- fix compute unit tests [`e37420d`](https://github.com/oceanprotocol/squid-js/commit/e37420dabfd23d5f307be695992cac7324d47dd0)
|
||||||
- chore(package): update lockfile package-lock.json [`46c4def`](https://github.com/oceanprotocol/squid-js/commit/46c4defee5beb43fbea41006c5957d086721aff9)
|
- job status cleanup [`f11eaca`](https://github.com/oceanprotocol/squid-js/commit/f11eacaabdc15285ba78a8096e492fd8863c933a)
|
||||||
- switch to @ethereum-navigator/navigator for network lookup [`92dbaae`](https://github.com/oceanprotocol/squid-js/commit/92dbaaeb25b26e28df644be356c347058ca1256a)
|
|
||||||
- chore(package): update lockfile package-lock.json [`eb141a6`](https://github.com/oceanprotocol/squid-js/commit/eb141a6d3d3131a65e4385f781568d015dac8429)
|
|
||||||
|
|
||||||
#### [v1.2.0](https://github.com/oceanprotocol/squid-js/compare/v1.1.0...v1.2.0)
|
#### [v1.2.0](https://github.com/oceanprotocol/squid-js/compare/v1.1.0...v1.2.0)
|
||||||
|
|
||||||
> 23 January 2020
|
> 23 January 2020
|
||||||
|
|
||||||
- Decouple aquarius from ocean [`#354`](https://github.com/oceanprotocol/squid-js/pull/354)
|
- Decouple aquarius from ocean [`#354`](https://github.com/oceanprotocol/squid-js/pull/354)
|
||||||
|
- merge fixes [`c8ea5f7`](https://github.com/oceanprotocol/squid-js/commit/c8ea5f77c2ec541fdbfb6f77cdabcd5691e4bffa)
|
||||||
- Release 1.2.0 [`56f7d11`](https://github.com/oceanprotocol/squid-js/commit/56f7d1113a6aa1f3318040fb32cfdcc22f5dc13b)
|
- Release 1.2.0 [`56f7d11`](https://github.com/oceanprotocol/squid-js/commit/56f7d1113a6aa1f3318040fb32cfdcc22f5dc13b)
|
||||||
|
|
||||||
#### [v1.1.0](https://github.com/oceanprotocol/squid-js/compare/v1.1.0-beta.0...v1.1.0)
|
#### [v1.1.0](https://github.com/oceanprotocol/squid-js/compare/v1.1.0-beta.0...v1.1.0)
|
||||||
|
30
MIGRATION.md
30
MIGRATION.md
@ -1,6 +1,34 @@
|
|||||||
# Migration Guide
|
# Migration Guide
|
||||||
|
|
||||||
Instructions on how to migrate between breaking versions.
|
Instructions on how to migrate between versions with breaking changes.
|
||||||
|
|
||||||
|
## v1.2.0 → v2.0.0
|
||||||
|
|
||||||
|
### Ocean Protocol Components Requirements
|
||||||
|
|
||||||
|
squid-js v2.0.0 only works against:
|
||||||
|
|
||||||
|
- Aquarius v1.0.7+
|
||||||
|
- Brizo v0.9.3+
|
||||||
|
- Events Handler v0.4.5+
|
||||||
|
- Keeper Contracts v0.13.2+
|
||||||
|
|
||||||
|
### Service index parameter removal from `ocean.assets` methods
|
||||||
|
|
||||||
|
Removes the need to get the respective service from the DDO, the `ocean.assets` methods will now do this on their own automatically.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// old
|
||||||
|
const service = ddo.findServiceByType('access')
|
||||||
|
const did = ddo.id
|
||||||
|
const agreementId = await ocean.assets.order(did, service.index, account)
|
||||||
|
const path = await ocean.assets.consume(agreementId, did, service.index, account, folder)
|
||||||
|
|
||||||
|
// NEW
|
||||||
|
const did = ddo.id
|
||||||
|
const agreementId = await ocean.assets.order(did, account)
|
||||||
|
const path = await ocean.assets.consume(agreementId, did, account, folder)
|
||||||
|
```
|
||||||
|
|
||||||
## v0.8.3 → v1.0.0
|
## v0.8.3 → v1.0.0
|
||||||
|
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "brizo",
|
"name": "brizo",
|
||||||
"version": "~0.8.1"
|
"version": "~0.9.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "aquarius",
|
"name": "aquarius",
|
||||||
"version": "~1.0.5"
|
"version": "~1.0.7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "events-handler",
|
"name": "events-handler",
|
||||||
"version": "~0.4.1"
|
"version": "~0.4.4"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
2641
package-lock.json
generated
2641
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@oceanprotocol/squid",
|
"name": "@oceanprotocol/squid",
|
||||||
"version": "1.3.0",
|
"version": "2.0.0-beta.5",
|
||||||
"description": "JavaScript client library for Ocean Protocol",
|
"description": "JavaScript client library for Ocean Protocol",
|
||||||
"main": "./dist/node/squid.js",
|
"main": "./dist/node/squid.js",
|
||||||
"typings": "./dist/node/squid.d.ts",
|
"typings": "./dist/node/squid.d.ts",
|
||||||
@ -58,41 +58,43 @@
|
|||||||
"deprecated-decorator": "^0.1.6",
|
"deprecated-decorator": "^0.1.6",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^2.6.0",
|
||||||
"save-file": "^2.3.1",
|
"save-file": "^2.3.1",
|
||||||
"uuid": "^3.4.0",
|
"uuid": "^7.0.2",
|
||||||
"web3": "^1.2.5",
|
"web3": "^1.2.6",
|
||||||
"whatwg-url": "^8.0.0"
|
"whatwg-url": "^8.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@release-it/bumper": "^1.0.5",
|
"@release-it/bumper": "^1.1.0",
|
||||||
"@truffle/hdwallet-provider": "^1.0.29",
|
"@truffle/hdwallet-provider": "^1.0.33",
|
||||||
"@types/chai": "^4.2.8",
|
"@types/chai": "^4.2.11",
|
||||||
"@types/chai-spies": "^1.0.1",
|
"@types/chai-spies": "^1.0.1",
|
||||||
"@types/mocha": "^7.0.1",
|
"@types/mocha": "^7.0.2",
|
||||||
"@types/node": "^13.5.1",
|
"@types/node": "^13.9.1",
|
||||||
"@types/node-fetch": "^2.5.4",
|
"@types/node-fetch": "^2.5.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.18.0",
|
"@types/sinon": "^7.5.2",
|
||||||
"@typescript-eslint/parser": "^2.18.0",
|
"@typescript-eslint/eslint-plugin": "^2.23.0",
|
||||||
|
"@typescript-eslint/parser": "^2.23.0",
|
||||||
"auto-changelog": "^1.16.2",
|
"auto-changelog": "^1.16.2",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"chai-spies": "^1.0.0",
|
"chai-spies": "^1.0.0",
|
||||||
"cross-env": "^7.0.0",
|
"cross-env": "^7.0.2",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-config-oceanprotocol": "^1.5.0",
|
"eslint-config-oceanprotocol": "^1.5.0",
|
||||||
"eslint-config-prettier": "^6.10.0",
|
"eslint-config-prettier": "^6.10.0",
|
||||||
"eslint-plugin-prettier": "^3.1.2",
|
"eslint-plugin-prettier": "^3.1.2",
|
||||||
"lcov-result-merger": "^3.1.0",
|
"lcov-result-merger": "^3.1.0",
|
||||||
"mocha": "^7.0.1",
|
"mocha": "^7.1.0",
|
||||||
"mock-local-storage": "^1.1.11",
|
"mock-local-storage": "^1.1.11",
|
||||||
"nyc": "^15.0.0",
|
"nyc": "^15.0.0",
|
||||||
"ora": "^4.0.2",
|
"ora": "^4.0.2",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
|
"sinon": "^9.0.1",
|
||||||
"source-map-support": "^0.5.16",
|
"source-map-support": "^0.5.16",
|
||||||
"ts-node": "^8.6.2",
|
"ts-node": "^8.6.2",
|
||||||
"typedoc": "^0.16.9",
|
"typedoc": "^0.17.1",
|
||||||
"typescript": "^3.7.5",
|
"typescript": "^3.8.3",
|
||||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||||
"webpack": "^4.41.5",
|
"webpack": "^4.42.0",
|
||||||
"webpack-cli": "^3.3.10",
|
"webpack-cli": "^3.3.11",
|
||||||
"webpack-merge": "^4.2.2"
|
"webpack-merge": "^4.2.2"
|
||||||
},
|
},
|
||||||
"nyc": {
|
"nyc": {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { File } from '../ddo/MetaData'
|
import { File, MetaDataAlgorithm } from '../ddo/MetaData'
|
||||||
import Account from '../ocean/Account'
|
import Account from '../ocean/Account'
|
||||||
import { noZeroX } from '../utils'
|
import { noZeroX } from '../utils'
|
||||||
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||||
|
import { DDO } from '../ddo/DDO'
|
||||||
|
import { ServiceType } from '../ddo/Service'
|
||||||
|
import { ComputeJob, Output } from '../ocean/OceanCompute'
|
||||||
|
|
||||||
const apiPath = '/api/v1/brizo/services'
|
const apiPath = '/api/v1/brizo/services'
|
||||||
|
|
||||||
@ -35,15 +38,22 @@ export class Brizo extends Instantiable {
|
|||||||
return `${this.url}${apiPath}/publish`
|
return `${this.url}${apiPath}/publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
public getComputeEndpoint(
|
public getComputeEndpoint() {
|
||||||
pubKey: string,
|
|
||||||
serviceIndex: number,
|
|
||||||
_notUsed: string,
|
|
||||||
container: string
|
|
||||||
) {
|
|
||||||
return `${this.url}${apiPath}/compute`
|
return `${this.url}${apiPath}/compute`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getEndpointFromAgreement(
|
||||||
|
type: ServiceType,
|
||||||
|
agreementId: string
|
||||||
|
): Promise<string> {
|
||||||
|
const { assets, keeper } = this.ocean
|
||||||
|
const { did } = await keeper.agreementStoreManager.getAgreement(agreementId)
|
||||||
|
const ddo: DDO = await assets.resolve(did)
|
||||||
|
const { serviceEndpoint } = ddo.findServiceByType(type)
|
||||||
|
|
||||||
|
return serviceEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
public async initializeServiceAgreement(
|
public async initializeServiceAgreement(
|
||||||
did: string,
|
did: string,
|
||||||
serviceAgreementId: string,
|
serviceAgreementId: string,
|
||||||
@ -78,12 +88,7 @@ export class Brizo extends Instantiable {
|
|||||||
destination: string,
|
destination: string,
|
||||||
index: number = -1
|
index: number = -1
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const signature =
|
const signature = await this.createSignature(account, agreementId)
|
||||||
(await account.getToken()) ||
|
|
||||||
(await this.ocean.utils.signature.signText(
|
|
||||||
noZeroX(agreementId),
|
|
||||||
account.getId()
|
|
||||||
))
|
|
||||||
const filesPromises = files
|
const filesPromises = files
|
||||||
.filter((_, i) => index === -1 || i === index)
|
.filter((_, i) => index === -1 || i === index)
|
||||||
.map(async ({ index: i }) => {
|
.map(async ({ index: i }) => {
|
||||||
@ -105,6 +110,93 @@ export class Brizo extends Instantiable {
|
|||||||
return destination
|
return destination
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async compute(
|
||||||
|
method: string,
|
||||||
|
serviceAgreementId: string,
|
||||||
|
consumerAccount: Account,
|
||||||
|
algorithmDid?: string,
|
||||||
|
algorithmMeta?: MetaDataAlgorithm,
|
||||||
|
jobId?: string,
|
||||||
|
output?: Output
|
||||||
|
): Promise<ComputeJob | ComputeJob[]> {
|
||||||
|
const signature = await this.createSignature(consumerAccount, serviceAgreementId)
|
||||||
|
const address = consumerAccount.getId()
|
||||||
|
const serviceEndpoint = await this.getEndpointFromAgreement(
|
||||||
|
'compute',
|
||||||
|
serviceAgreementId
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!serviceEndpoint) {
|
||||||
|
throw new Error(
|
||||||
|
'Computing on asset failed, service definition is missing the `serviceEndpoint`.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct Brizo URL
|
||||||
|
let url = serviceEndpoint
|
||||||
|
url += `?signature=${signature}`
|
||||||
|
url += `&consumerAddress=${address}`
|
||||||
|
url += `&serviceAgreementId=${noZeroX(serviceAgreementId)}`
|
||||||
|
url += (algorithmDid && `&algorithmDid=${algorithmDid}`) || ''
|
||||||
|
url +=
|
||||||
|
(algorithmMeta &&
|
||||||
|
`&algorithmMeta=${encodeURIComponent(JSON.stringify(algorithmMeta))}`) ||
|
||||||
|
''
|
||||||
|
url += (output && `&output=${JSON.stringify(output)}`) || ''
|
||||||
|
url += (jobId && `&jobId=${jobId}`) || ''
|
||||||
|
|
||||||
|
// switch fetch method
|
||||||
|
let fetch
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case 'post':
|
||||||
|
fetch = this.ocean.utils.fetch.post(url, '')
|
||||||
|
break
|
||||||
|
case 'put':
|
||||||
|
fetch = this.ocean.utils.fetch.put(url, '')
|
||||||
|
break
|
||||||
|
case 'delete':
|
||||||
|
fetch = this.ocean.utils.fetch.delete(url)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
fetch = this.ocean.utils.fetch.get(url)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await fetch
|
||||||
|
.then((response: any) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.error(
|
||||||
|
'Compute job failed:',
|
||||||
|
response.status,
|
||||||
|
response.statusText
|
||||||
|
)
|
||||||
|
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
.catch((error: Error) => {
|
||||||
|
this.logger.error('Error with compute job')
|
||||||
|
this.logger.error(error.message)
|
||||||
|
throw error
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
public async createSignature(account: Account, agreementId: string): Promise<string> {
|
||||||
|
const signature =
|
||||||
|
(await account.getToken()) ||
|
||||||
|
(await this.ocean.utils.signature.signText(
|
||||||
|
noZeroX(agreementId),
|
||||||
|
account.getId()
|
||||||
|
))
|
||||||
|
|
||||||
|
return signature
|
||||||
|
}
|
||||||
|
|
||||||
public async encrypt(
|
public async encrypt(
|
||||||
did: string,
|
did: string,
|
||||||
signature: string,
|
signature: string,
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
export interface Provider {
|
|
||||||
type: string
|
|
||||||
description: string
|
|
||||||
environment: {
|
|
||||||
cluster: {
|
|
||||||
type: string
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
supportedContainers: {
|
|
||||||
image: string
|
|
||||||
tag: string
|
|
||||||
checksum: string
|
|
||||||
}[]
|
|
||||||
supportedServers: {
|
|
||||||
serverId: string
|
|
||||||
serverType: string
|
|
||||||
price: string
|
|
||||||
cpu: string
|
|
||||||
gpu: string
|
|
||||||
memory: string
|
|
||||||
disk: string
|
|
||||||
maxExecutionTime: number
|
|
||||||
}[]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +1,3 @@
|
|||||||
export interface StageRequirements {
|
|
||||||
container: {
|
|
||||||
image: string
|
|
||||||
tag: string
|
|
||||||
checksum: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StageInput {
|
|
||||||
index: number
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StageTransformation {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StageOutput {
|
|
||||||
metadataUrl: string
|
|
||||||
secretStoreUrl: string
|
|
||||||
accessProxyUrl: string
|
|
||||||
metadata: MetaDataMain
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Stage {
|
|
||||||
index: number
|
|
||||||
stageType?: string
|
|
||||||
requirements: StageRequirements
|
|
||||||
input: StageInput
|
|
||||||
transformation: StageTransformation
|
|
||||||
output: StageOutput
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Workflow {
|
|
||||||
stages: Stage[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Algorithm {
|
|
||||||
language: string
|
|
||||||
format?: string
|
|
||||||
version?: string
|
|
||||||
entrypoint: string
|
|
||||||
requirements: {
|
|
||||||
requirement: string
|
|
||||||
version: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ServiceDefinition {
|
|
||||||
auth: {
|
|
||||||
type: string
|
|
||||||
user?: string
|
|
||||||
password?: string
|
|
||||||
token?: string
|
|
||||||
}
|
|
||||||
endpoints: {
|
|
||||||
index: number
|
|
||||||
url: string
|
|
||||||
method: string
|
|
||||||
contentTypes: string[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Service {
|
|
||||||
spec?: string
|
|
||||||
specChecksum?: string
|
|
||||||
definition: ServiceDefinition
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface File {
|
export interface File {
|
||||||
/**
|
/**
|
||||||
* File name.
|
* File name.
|
||||||
@ -132,6 +63,19 @@ export interface File {
|
|||||||
compression?: string
|
compression?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MetaDataAlgorithm {
|
||||||
|
url?: string
|
||||||
|
rawcode?: string
|
||||||
|
language?: string
|
||||||
|
format?: string
|
||||||
|
version?: string
|
||||||
|
container: {
|
||||||
|
entrypoint: string
|
||||||
|
image: string
|
||||||
|
tag: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main attributes of assets metadata.
|
* Main attributes of assets metadata.
|
||||||
* @see https://github.com/oceanprotocol/OEPs/tree/master/8
|
* @see https://github.com/oceanprotocol/OEPs/tree/master/8
|
||||||
@ -145,12 +89,11 @@ export interface MetaDataMain {
|
|||||||
name: string
|
name: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of the Asset. Helps to filter by the type of asset,
|
* Type of the Asset. Helps to filter by the type of asset ("dataset" or "algorithm").
|
||||||
* initially ("dataset", "algorithm", "container", "workflow", "other").
|
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @example "dataset"
|
* @example "dataset"
|
||||||
*/
|
*/
|
||||||
type: 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other'
|
type: 'dataset' | 'algorithm'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The date on which the asset was created by the originator in
|
* The date on which the asset was created by the originator in
|
||||||
@ -185,7 +128,7 @@ export interface MetaDataMain {
|
|||||||
license: string
|
license: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Price of the asset.
|
* Price of the asset in vodka (attoOCEAN). It must be an integer encoded as a string.
|
||||||
* @type {string}
|
* @type {string}
|
||||||
* @example "1000000000000000000"
|
* @example "1000000000000000000"
|
||||||
*/
|
*/
|
||||||
@ -197,13 +140,11 @@ export interface MetaDataMain {
|
|||||||
*/
|
*/
|
||||||
files: File[]
|
files: File[]
|
||||||
|
|
||||||
encryptedService?: any
|
/**
|
||||||
|
* Metadata used only for assets with type `algorithm`.
|
||||||
workflow?: Workflow
|
* @type {MetaDataAlgorithm}
|
||||||
|
*/
|
||||||
algorithm?: Algorithm
|
algorithm?: MetaDataAlgorithm
|
||||||
|
|
||||||
service?: Service
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,21 +1,65 @@
|
|||||||
import { MetaData } from './MetaData'
|
import { MetaData } from './MetaData'
|
||||||
import { ServiceAgreementTemplate } from './ServiceAgreementTemplate'
|
import { ServiceAgreementTemplate } from './ServiceAgreementTemplate'
|
||||||
import { Provider } from './ComputingProvider'
|
|
||||||
|
|
||||||
export type ServiceType =
|
export type ServiceType = 'authorization' | 'metadata' | 'access' | 'compute'
|
||||||
| 'authorization'
|
|
||||||
| 'metadata'
|
|
||||||
| 'access'
|
|
||||||
| 'compute'
|
|
||||||
| 'computing'
|
|
||||||
| 'fitchainCompute'
|
|
||||||
|
|
||||||
export interface ServiceCommon {
|
export interface ServiceCommon {
|
||||||
type: ServiceType
|
type: ServiceType
|
||||||
index: number
|
index: number
|
||||||
serviceEndpoint?: string
|
serviceEndpoint?: string
|
||||||
attributes: any & {
|
attributes: ServiceCommonAttributes
|
||||||
main: { [key: string]: any }
|
}
|
||||||
|
|
||||||
|
export interface ServiceCommonAttributes {
|
||||||
|
main: { [key: string]: any }
|
||||||
|
additionalInformation?: { [key: string]: any }
|
||||||
|
serviceAgreementTemplate?: ServiceAgreementTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceAccessAttributes extends ServiceCommonAttributes {
|
||||||
|
main: {
|
||||||
|
creator: string
|
||||||
|
name: string
|
||||||
|
datePublished: string
|
||||||
|
price: string
|
||||||
|
timeout: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceComputeAttributes extends ServiceCommonAttributes {
|
||||||
|
main: {
|
||||||
|
creator: string
|
||||||
|
datePublished: string
|
||||||
|
price: string
|
||||||
|
timeout: number
|
||||||
|
provider?: ServiceComputeProvider
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceComputeProvider {
|
||||||
|
type: string
|
||||||
|
description: string
|
||||||
|
environment: {
|
||||||
|
cluster: {
|
||||||
|
type: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
supportedContainers: {
|
||||||
|
image: string
|
||||||
|
tag: string
|
||||||
|
checksum: string
|
||||||
|
}[]
|
||||||
|
supportedServers: {
|
||||||
|
serverId: string
|
||||||
|
serverType: string
|
||||||
|
price: string
|
||||||
|
cpu: string
|
||||||
|
gpu: string
|
||||||
|
memory: string
|
||||||
|
disk: string
|
||||||
|
maxExecutionTime: number
|
||||||
|
}[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,30 +76,13 @@ export interface ServiceMetadata extends ServiceCommon {
|
|||||||
export interface ServiceAccess extends ServiceCommon {
|
export interface ServiceAccess extends ServiceCommon {
|
||||||
type: 'access'
|
type: 'access'
|
||||||
templateId?: string
|
templateId?: string
|
||||||
attributes: {
|
attributes: ServiceAccessAttributes
|
||||||
main: {
|
|
||||||
creator: string
|
|
||||||
name: string
|
|
||||||
datePublished: string
|
|
||||||
price: string
|
|
||||||
timeout: number
|
|
||||||
}
|
|
||||||
serviceAgreementTemplate?: ServiceAgreementTemplate
|
|
||||||
additionalInformation: {
|
|
||||||
description: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ServiceComputing extends ServiceCommon {
|
|
||||||
type: 'computing'
|
|
||||||
templateId?: string
|
|
||||||
provider?: Provider
|
|
||||||
serviceAgreementTemplate?: ServiceAgreementTemplate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServiceCompute extends ServiceCommon {
|
export interface ServiceCompute extends ServiceCommon {
|
||||||
|
type: 'compute'
|
||||||
templateId?: string
|
templateId?: string
|
||||||
|
attributes: ServiceComputeAttributes
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Service<
|
export type Service<
|
||||||
@ -64,8 +91,6 @@ export type Service<
|
|||||||
? ServiceAuthorization
|
? ServiceAuthorization
|
||||||
: T extends 'metadata'
|
: T extends 'metadata'
|
||||||
? ServiceMetadata
|
? ServiceMetadata
|
||||||
: T extends 'computing'
|
|
||||||
? ServiceComputing
|
|
||||||
: T extends 'access'
|
: T extends 'access'
|
||||||
? ServiceAccess
|
? ServiceAccess
|
||||||
: T extends 'compute'
|
: T extends 'compute'
|
||||||
|
@ -95,24 +95,19 @@ export class Keeper extends Instantiable {
|
|||||||
computeExecutionCondition: keeper.instances.computeExecutionCondition
|
computeExecutionCondition: keeper.instances.computeExecutionCondition
|
||||||
}
|
}
|
||||||
// Templates
|
// Templates
|
||||||
keeper.instances.escrowAccessSecretStoreTemplate = new EscrowAccessSecretStoreTemplate(
|
keeper.templates = Object()
|
||||||
|
keeper.templates.escrowAccessSecretStoreTemplate = new EscrowAccessSecretStoreTemplate(
|
||||||
keeper.templateStoreManager,
|
keeper.templateStoreManager,
|
||||||
keeper.agreementStoreManager,
|
keeper.agreementStoreManager,
|
||||||
keeper.didRegistry,
|
keeper.didRegistry,
|
||||||
keeper.conditions
|
keeper.conditions
|
||||||
)
|
)
|
||||||
keeper.instances.escrowComputeExecutionTemplate = new EscrowComputeExecutionTemplate(
|
keeper.templates.escrowComputeExecutionTemplate = new EscrowComputeExecutionTemplate(
|
||||||
keeper.templateStoreManager,
|
keeper.templateStoreManager,
|
||||||
keeper.agreementStoreManager,
|
keeper.agreementStoreManager,
|
||||||
keeper.didRegistry,
|
keeper.didRegistry,
|
||||||
keeper.conditions
|
keeper.conditions
|
||||||
)
|
)
|
||||||
keeper.templates = {
|
|
||||||
escrowAccessSecretStoreTemplate:
|
|
||||||
keeper.instances.escrowAccessSecretStoreTemplate,
|
|
||||||
escrowComputeExecutionTemplate:
|
|
||||||
keeper.instances.escrowComputeExecutionTemplate
|
|
||||||
}
|
|
||||||
// Utils
|
// Utils
|
||||||
keeper.utils = {
|
keeper.utils = {
|
||||||
eventHandler: new EventHandler(config)
|
eventHandler: new EventHandler(config)
|
||||||
|
@ -4,10 +4,10 @@ export const escrowAccessServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
contractName: 'EscrowAccessSecretStoreTemplate',
|
contractName: 'EscrowAccessSecretStoreTemplate',
|
||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'AgreementCreated',
|
name: 'AgreementActorAdded',
|
||||||
actorType: 'consumer',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'escrowAccessSecretStoreTemplate',
|
moduleName: '',
|
||||||
functionName: 'fulfillLockRewardCondition',
|
functionName: 'fulfillLockRewardCondition',
|
||||||
version: '0.1'
|
version: '0.1'
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ export const escrowAccessServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'Fulfilled',
|
name: 'Fulfilled',
|
||||||
actorType: 'publisher',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'lockRewardCondition',
|
moduleName: 'lockRewardCondition',
|
||||||
functionName: 'fulfillAccessSecretStoreCondition',
|
functionName: 'fulfillAccessSecretStoreCondition',
|
||||||
@ -75,7 +75,7 @@ export const escrowAccessServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'Fulfilled',
|
name: 'Fulfilled',
|
||||||
actorType: 'publisher',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'accessSecretStore',
|
moduleName: 'accessSecretStore',
|
||||||
functionName: 'fulfillEscrowRewardCondition',
|
functionName: 'fulfillEscrowRewardCondition',
|
||||||
@ -87,7 +87,7 @@ export const escrowAccessServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
actorType: 'consumer',
|
actorType: 'consumer',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'accessSecretStore',
|
moduleName: 'accessSecretStore',
|
||||||
functionName: 'fulfillEscrowRewardCondition',
|
functionName: 'refundReward',
|
||||||
version: '0.1'
|
version: '0.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ export const escrowAccessServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'Fulfilled',
|
name: 'Fulfilled',
|
||||||
actorType: 'publisher',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'escrowRewardCondition',
|
moduleName: 'escrowRewardCondition',
|
||||||
functionName: 'verifyRewardTokens',
|
functionName: 'verifyRewardTokens',
|
||||||
|
@ -4,10 +4,10 @@ export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
contractName: 'EscrowComputeExecutionTemplate',
|
contractName: 'EscrowComputeExecutionTemplate',
|
||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'AgreementCreated',
|
name: 'AgreementActorAdded',
|
||||||
actorType: 'consumer',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'serviceExecutionTemplate',
|
moduleName: '',
|
||||||
functionName: 'fulfillLockRewardCondition',
|
functionName: 'fulfillLockRewardCondition',
|
||||||
version: '0.1'
|
version: '0.1'
|
||||||
}
|
}
|
||||||
@ -15,13 +15,13 @@ export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
],
|
],
|
||||||
fulfillmentOrder: [
|
fulfillmentOrder: [
|
||||||
'lockReward.fulfill',
|
'lockReward.fulfill',
|
||||||
'serviceExecution.fulfill',
|
'computeExecution.fulfill',
|
||||||
'escrowReward.fulfill'
|
'escrowReward.fulfill'
|
||||||
],
|
],
|
||||||
conditionDependency: {
|
conditionDependency: {
|
||||||
lockReward: [],
|
lockReward: [],
|
||||||
serviceExecution: [],
|
computeExecution: [],
|
||||||
escrowReward: ['lockReward', 'serviceExecution']
|
escrowReward: ['lockReward', 'computeExecution']
|
||||||
},
|
},
|
||||||
conditions: [
|
conditions: [
|
||||||
{
|
{
|
||||||
@ -45,17 +45,17 @@ export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'Fulfilled',
|
name: 'Fulfilled',
|
||||||
actorType: 'publisher',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'lockRewardCondition',
|
moduleName: 'lockRewardExecutionCondition',
|
||||||
functionName: 'fulfillServiceExecutionCondition',
|
functionName: 'fulfillComputeExecutionCondition',
|
||||||
version: '0.1'
|
version: '0.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'serviceExecution',
|
name: 'computeExecution',
|
||||||
timelock: 0,
|
timelock: 0,
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
contractName: 'ComputeExecutionCondition',
|
contractName: 'ComputeExecutionCondition',
|
||||||
@ -75,10 +75,10 @@ export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'Fulfilled',
|
name: 'Fulfilled',
|
||||||
actorType: 'publisher',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'serviceExecution',
|
moduleName: 'accessSecretStore',
|
||||||
functionName: 'fulfillServiceExecutionCondition',
|
functionName: 'fulfillEscrowRewardCondition',
|
||||||
version: '0.1'
|
version: '0.1'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -86,8 +86,8 @@ export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
name: 'TimedOut',
|
name: 'TimedOut',
|
||||||
actorType: 'consumer',
|
actorType: 'consumer',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'serviceExec',
|
moduleName: 'accessSecretStore',
|
||||||
functionName: 'fulfillServiceExecutionCondition',
|
functionName: 'refundReward',
|
||||||
version: '0.1'
|
version: '0.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
|||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
name: 'Fulfilled',
|
name: 'Fulfilled',
|
||||||
actorType: 'publisher',
|
actorType: 'provider',
|
||||||
handler: {
|
handler: {
|
||||||
moduleName: 'escrowRewardCondition',
|
moduleName: 'escrowRewardCondition',
|
||||||
functionName: 'verifyRewardTokens',
|
functionName: 'verifyRewardTokens',
|
||||||
|
@ -2,6 +2,7 @@ import { OceanAccounts } from './OceanAccounts'
|
|||||||
import { OceanAgreements } from './OceanAgreements'
|
import { OceanAgreements } from './OceanAgreements'
|
||||||
import { OceanAssets } from './OceanAssets'
|
import { OceanAssets } from './OceanAssets'
|
||||||
import { OceanAuth } from './OceanAuth'
|
import { OceanAuth } from './OceanAuth'
|
||||||
|
import { OceanCompute } from './OceanCompute'
|
||||||
import { OceanSecretStore } from './OceanSecretStore'
|
import { OceanSecretStore } from './OceanSecretStore'
|
||||||
import { OceanTokens } from './OceanTokens'
|
import { OceanTokens } from './OceanTokens'
|
||||||
import { OceanVersions } from './OceanVersions'
|
import { OceanVersions } from './OceanVersions'
|
||||||
@ -49,6 +50,7 @@ export class Ocean extends Instantiable {
|
|||||||
instance.accounts = await OceanAccounts.getInstance(instanceConfig)
|
instance.accounts = await OceanAccounts.getInstance(instanceConfig)
|
||||||
instance.auth = await OceanAuth.getInstance(instanceConfig)
|
instance.auth = await OceanAuth.getInstance(instanceConfig)
|
||||||
instance.assets = await OceanAssets.getInstance(instanceConfig)
|
instance.assets = await OceanAssets.getInstance(instanceConfig)
|
||||||
|
instance.compute = await OceanCompute.getInstance(instanceConfig)
|
||||||
instance.agreements = await OceanAgreements.getInstance(instanceConfig)
|
instance.agreements = await OceanAgreements.getInstance(instanceConfig)
|
||||||
instance.secretStore = await OceanSecretStore.getInstance(instanceConfig)
|
instance.secretStore = await OceanSecretStore.getInstance(instanceConfig)
|
||||||
instance.tokens = await OceanTokens.getInstance(instanceConfig)
|
instance.tokens = await OceanTokens.getInstance(instanceConfig)
|
||||||
@ -99,6 +101,12 @@ export class Ocean extends Instantiable {
|
|||||||
*/
|
*/
|
||||||
public agreements: OceanAgreements
|
public agreements: OceanAgreements
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ocean compute submodule
|
||||||
|
* @type {OceanCompute}
|
||||||
|
*/
|
||||||
|
public compute: OceanCompute
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ocean secretStore submodule
|
* Ocean secretStore submodule
|
||||||
* @type {OceanSecretStore}
|
* @type {OceanSecretStore}
|
||||||
|
@ -7,6 +7,7 @@ import { AgreementConditionsStatus } from '../keeper/contracts/templates/Agreeme
|
|||||||
import { ConditionState } from '../keeper/contracts/conditions/Condition.abstract'
|
import { ConditionState } from '../keeper/contracts/conditions/Condition.abstract'
|
||||||
|
|
||||||
import { OceanAgreementsConditions } from './OceanAgreementsConditions'
|
import { OceanAgreementsConditions } from './OceanAgreementsConditions'
|
||||||
|
import { Service } from '../ddo/Service'
|
||||||
|
|
||||||
export interface AgreementPrepareResult {
|
export interface AgreementPrepareResult {
|
||||||
agreementId: string
|
agreementId: string
|
||||||
@ -121,7 +122,7 @@ export class OceanAgreements extends Instantiable {
|
|||||||
) {
|
) {
|
||||||
const d: DID = DID.parse(did)
|
const d: DID = DID.parse(did)
|
||||||
const ddo = await this.ocean.aquarius.retrieveDDO(d)
|
const ddo = await this.ocean.aquarius.retrieveDDO(d)
|
||||||
const service = ddo.findServiceById(index)
|
const service: Service = ddo.findServiceById(index)
|
||||||
const templateName = service.attributes.serviceAgreementTemplate.contractName
|
const templateName = service.attributes.serviceAgreementTemplate.contractName
|
||||||
return this.ocean.keeper
|
return this.ocean.keeper
|
||||||
.getTemplateByName(templateName)
|
.getTemplateByName(templateName)
|
||||||
|
@ -81,13 +81,13 @@ export class OceanAgreementsConditions extends Instantiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorize the consumer defined in the agreement to execute a remote service associated with this asset.
|
* Authorize the consumer defined in the agreement to compute on this asset.
|
||||||
* @param {string} agreementId Agreement ID.
|
* @param {string} agreementId Agreement ID.
|
||||||
* @param {string} did Asset ID.
|
* @param {string} did Asset ID.
|
||||||
* @param {string} grantee Consumer address.
|
* @param {string} grantee Consumer address.
|
||||||
* @param {Account} from Account of sender.
|
* @param {Account} from Account of sender.
|
||||||
*/
|
*/
|
||||||
public async grantServiceExecution(
|
public async grantCompute(
|
||||||
agreementId: string,
|
agreementId: string,
|
||||||
did: string,
|
did: string,
|
||||||
grantee: string,
|
grantee: string,
|
||||||
|
@ -2,11 +2,12 @@ import { TransactionReceipt } from 'web3-core'
|
|||||||
import { SearchQuery } from '../aquarius/Aquarius'
|
import { SearchQuery } from '../aquarius/Aquarius'
|
||||||
import { DDO } from '../ddo/DDO'
|
import { DDO } from '../ddo/DDO'
|
||||||
import { MetaData } from '../ddo/MetaData'
|
import { MetaData } from '../ddo/MetaData'
|
||||||
import { Service } from '../ddo/Service'
|
import { Service, ServiceAccess } from '../ddo/Service'
|
||||||
import Account from './Account'
|
import Account from './Account'
|
||||||
import DID from './DID'
|
import DID from './DID'
|
||||||
import { fillConditionsWithDDO, SubscribablePromise, generateId, zeroX } from '../utils'
|
import { fillConditionsWithDDO, SubscribablePromise } from '../utils'
|
||||||
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||||
|
import { OrderProgressStep } from './utils/ServiceUtils'
|
||||||
|
|
||||||
export enum CreateProgressStep {
|
export enum CreateProgressStep {
|
||||||
EncryptingFiles,
|
EncryptingFiles,
|
||||||
@ -19,13 +20,6 @@ export enum CreateProgressStep {
|
|||||||
DdoStored
|
DdoStored
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OrderProgressStep {
|
|
||||||
CreatingAgreement,
|
|
||||||
AgreementInitialized,
|
|
||||||
LockingPayment,
|
|
||||||
LockedPayment
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assets submodule of Ocean Protocol.
|
* Assets submodule of Ocean Protocol.
|
||||||
*/
|
*/
|
||||||
@ -82,6 +76,16 @@ export class OceanAssets extends Instantiable {
|
|||||||
this.logger.log('Files encrypted')
|
this.logger.log('Files encrypted')
|
||||||
observer.next(CreateProgressStep.FilesEncrypted)
|
observer.next(CreateProgressStep.FilesEncrypted)
|
||||||
|
|
||||||
|
// make sure that access service is defined if services is empty
|
||||||
|
if (services.length === 0) {
|
||||||
|
const accessService = await this.createAccessServiceAttributes(
|
||||||
|
publisher,
|
||||||
|
metadata.main.price,
|
||||||
|
metadata.main.datePublished
|
||||||
|
)
|
||||||
|
services.push(accessService)
|
||||||
|
}
|
||||||
|
|
||||||
const serviceAgreementTemplate = await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplate()
|
const serviceAgreementTemplate = await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplate()
|
||||||
|
|
||||||
const serviceEndpoint = this.ocean.aquarius.getServiceEndpoint(did)
|
const serviceEndpoint = this.ocean.aquarius.getServiceEndpoint(did)
|
||||||
@ -104,21 +108,6 @@ export class OceanAssets extends Instantiable {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
service: [
|
service: [
|
||||||
{
|
|
||||||
type: 'access',
|
|
||||||
serviceEndpoint: this.ocean.brizo.getConsumeEndpoint(),
|
|
||||||
templateId: templates.escrowAccessSecretStoreTemplate.getId(),
|
|
||||||
attributes: {
|
|
||||||
main: {
|
|
||||||
creator: publisher.getId(),
|
|
||||||
datePublished: metadata.main.datePublished,
|
|
||||||
name: 'dataAssetAccessServiceAgreement',
|
|
||||||
price: metadata.main.price,
|
|
||||||
timeout: 3600
|
|
||||||
},
|
|
||||||
serviceAgreementTemplate
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type: 'authorization',
|
type: 'authorization',
|
||||||
service: 'SecretStore',
|
service: 'SecretStore',
|
||||||
@ -165,9 +154,18 @@ export class OceanAssets extends Instantiable {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Overwrite initial service agreement conditions
|
// Overwrite initial service agreement conditions
|
||||||
const rawConditions = await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplateConditions()
|
serviceAgreementTemplate.conditions = fillConditionsWithDDO(
|
||||||
const conditions = fillConditionsWithDDO(rawConditions, ddo)
|
await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplateConditions(),
|
||||||
serviceAgreementTemplate.conditions = conditions
|
ddo
|
||||||
|
)
|
||||||
|
for (const service of services) {
|
||||||
|
if (service.type === 'compute') {
|
||||||
|
service.attributes.serviceAgreementTemplate.conditions = fillConditionsWithDDO(
|
||||||
|
await templates.escrowComputeExecutionTemplate.getServiceAgreementTemplateConditions(),
|
||||||
|
ddo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.log('Generating proof')
|
this.logger.log('Generating proof')
|
||||||
observer.next(CreateProgressStep.GeneratingProof)
|
observer.next(CreateProgressStep.GeneratingProof)
|
||||||
@ -200,17 +198,16 @@ export class OceanAssets extends Instantiable {
|
|||||||
public async consume(
|
public async consume(
|
||||||
agreementId: string,
|
agreementId: string,
|
||||||
did: string,
|
did: string,
|
||||||
serviceIndex: number,
|
|
||||||
consumerAccount: Account,
|
consumerAccount: Account,
|
||||||
resultPath: string,
|
resultPath: string,
|
||||||
index?: number,
|
index?: number,
|
||||||
useSecretStore?: boolean
|
useSecretStore?: boolean
|
||||||
): Promise<string>
|
): Promise<string>
|
||||||
|
|
||||||
|
/* eslint-disable no-dupe-class-members */
|
||||||
public async consume(
|
public async consume(
|
||||||
agreementId: string,
|
agreementId: string,
|
||||||
did: string,
|
did: string,
|
||||||
serviceIndex: number,
|
|
||||||
consumerAccount: Account,
|
consumerAccount: Account,
|
||||||
resultPath?: undefined | null,
|
resultPath?: undefined | null,
|
||||||
index?: number,
|
index?: number,
|
||||||
@ -220,7 +217,6 @@ export class OceanAssets extends Instantiable {
|
|||||||
public async consume(
|
public async consume(
|
||||||
agreementId: string,
|
agreementId: string,
|
||||||
did: string,
|
did: string,
|
||||||
serviceIndex: number,
|
|
||||||
consumerAccount: Account,
|
consumerAccount: Account,
|
||||||
resultPath?: string,
|
resultPath?: string,
|
||||||
index: number = -1,
|
index: number = -1,
|
||||||
@ -228,8 +224,7 @@ export class OceanAssets extends Instantiable {
|
|||||||
): Promise<string | true> {
|
): Promise<string | true> {
|
||||||
const ddo = await this.resolve(did)
|
const ddo = await this.resolve(did)
|
||||||
const { attributes } = ddo.findServiceByType('metadata')
|
const { attributes } = ddo.findServiceByType('metadata')
|
||||||
|
const accessService = ddo.findServiceByType('access')
|
||||||
const accessService = ddo.findServiceById(serviceIndex)
|
|
||||||
|
|
||||||
const { files } = attributes.main
|
const { files } = attributes.main
|
||||||
|
|
||||||
@ -244,7 +239,7 @@ export class OceanAssets extends Instantiable {
|
|||||||
this.logger.log('Consuming files')
|
this.logger.log('Consuming files')
|
||||||
|
|
||||||
resultPath = resultPath
|
resultPath = resultPath
|
||||||
? `${resultPath}/datafile.${ddo.shortId()}.${serviceIndex}/`
|
? `${resultPath}/datafile.${ddo.shortId()}.${accessService.index}/`
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
if (!useSecretStore) {
|
if (!useSecretStore) {
|
||||||
@ -277,109 +272,43 @@ export class OceanAssets extends Instantiable {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
/* eslint-enable no-dupe-class-members */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the purchase/order of an asset's service. Starts by signing the service agreement
|
* Start the purchase/order of an asset's service. Starts by signing the service agreement
|
||||||
* then sends the request to the publisher via the service endpoint (Brizo http service).
|
* then sends the request to the publisher via the service endpoint (Brizo http service).
|
||||||
* @param {string} did Decentralized ID.
|
* @param {string} did Decentralized ID.
|
||||||
* @param {number} index Service index.
|
* @param {Account} consumerAccount Consumer account.
|
||||||
* @param {Account} consumer Consumer account.
|
|
||||||
* @param {string} provider ethereum address of service provider (optional)
|
* @param {string} provider ethereum address of service provider (optional)
|
||||||
* @return {Promise<string>} Returns Agreement ID
|
* @return {Promise<string>} Returns Agreement ID
|
||||||
*/
|
*/
|
||||||
public order(
|
public order(
|
||||||
did: string,
|
did: string,
|
||||||
index: number,
|
consumerAccount: Account,
|
||||||
consumer: Account,
|
|
||||||
provider?: string
|
provider?: string
|
||||||
): SubscribablePromise<OrderProgressStep, string> {
|
): SubscribablePromise<OrderProgressStep, string> {
|
||||||
return new SubscribablePromise(async observer => {
|
return new SubscribablePromise(async observer => {
|
||||||
const oceanAgreements = this.ocean.agreements
|
const { keeper, utils } = this.ocean
|
||||||
|
const ddo: DDO = await this.resolve(did)
|
||||||
|
const condition = keeper.conditions.accessSecretStoreCondition
|
||||||
|
|
||||||
const agreementId = zeroX(generateId())
|
const agreementId = await utils.services.order(
|
||||||
const ddo = await this.resolve(did)
|
'access',
|
||||||
|
condition,
|
||||||
const { keeper } = this.ocean
|
observer,
|
||||||
const templateName = ddo.findServiceByType('access').attributes
|
consumerAccount,
|
||||||
.serviceAgreementTemplate.contractName
|
ddo,
|
||||||
const template = keeper.getTemplateByName(templateName)
|
provider
|
||||||
const accessCondition = keeper.conditions.accessSecretStoreCondition
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-async-promise-executor
|
|
||||||
const paymentFlow = new Promise(async (resolve, reject) => {
|
|
||||||
await template.getAgreementCreatedEvent(agreementId).once()
|
|
||||||
|
|
||||||
this.logger.log('Agreement initialized')
|
|
||||||
observer.next(OrderProgressStep.AgreementInitialized)
|
|
||||||
|
|
||||||
const { attributes } = ddo.findServiceByType('metadata')
|
|
||||||
|
|
||||||
this.logger.log('Locking payment')
|
|
||||||
|
|
||||||
const accessGranted = accessCondition
|
|
||||||
.getConditionFulfilledEvent(agreementId)
|
|
||||||
.once()
|
|
||||||
|
|
||||||
observer.next(OrderProgressStep.LockingPayment)
|
|
||||||
const paid = await oceanAgreements.conditions.lockReward(
|
|
||||||
agreementId,
|
|
||||||
attributes.main.price,
|
|
||||||
consumer
|
|
||||||
)
|
|
||||||
observer.next(OrderProgressStep.LockedPayment)
|
|
||||||
|
|
||||||
if (paid) {
|
|
||||||
this.logger.log('Payment was OK')
|
|
||||||
} else {
|
|
||||||
this.logger.error('Payment was KO')
|
|
||||||
this.logger.error('Agreement ID: ', agreementId)
|
|
||||||
this.logger.error('DID: ', ddo.id)
|
|
||||||
reject(new Error('Error on payment'))
|
|
||||||
}
|
|
||||||
|
|
||||||
await accessGranted
|
|
||||||
|
|
||||||
this.logger.log('Access granted')
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
|
|
||||||
observer.next(OrderProgressStep.CreatingAgreement)
|
|
||||||
this.logger.log('Creating agreement')
|
|
||||||
|
|
||||||
// Get provider from didRegistry if not given in arguments
|
|
||||||
let _provider = provider
|
|
||||||
if (!provider) {
|
|
||||||
const providers = await keeper.didRegistry.getDIDProviders(ddo.shortId())
|
|
||||||
if (providers) {
|
|
||||||
_provider = providers[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await oceanAgreements.create(
|
|
||||||
did,
|
|
||||||
agreementId,
|
|
||||||
index,
|
|
||||||
undefined,
|
|
||||||
consumer,
|
|
||||||
_provider,
|
|
||||||
consumer
|
|
||||||
)
|
)
|
||||||
this.logger.log('Agreement created')
|
|
||||||
|
|
||||||
try {
|
|
||||||
await paymentFlow
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('Error paying the asset.')
|
|
||||||
}
|
|
||||||
|
|
||||||
return agreementId
|
return agreementId
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the owner of a asset.
|
* Returns the owner of an asset.
|
||||||
* @param {string} did Decentralized ID.
|
* @param {string} did Decentralized ID.
|
||||||
* @return {Promise<string>} Returns eth address
|
* @return {Promise<string>} Returns Account ID
|
||||||
*/
|
*/
|
||||||
public async owner(did: string): Promise<string> {
|
public async owner(did: string): Promise<string> {
|
||||||
const ddo = await this.resolve(did)
|
const ddo = await this.resolve(did)
|
||||||
@ -495,4 +424,29 @@ export class OceanAssets extends Instantiable {
|
|||||||
}
|
}
|
||||||
} as SearchQuery)
|
} as SearchQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async createAccessServiceAttributes(
|
||||||
|
consumerAccount: Account,
|
||||||
|
price: string,
|
||||||
|
datePublished: string
|
||||||
|
): Promise<ServiceAccess> {
|
||||||
|
const { templates } = this.ocean.keeper
|
||||||
|
const serviceAgreementTemplate = await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplate()
|
||||||
|
return {
|
||||||
|
type: 'access',
|
||||||
|
index: 2,
|
||||||
|
serviceEndpoint: this.ocean.brizo.getConsumeEndpoint(),
|
||||||
|
templateId: templates.escrowAccessSecretStoreTemplate.getId(),
|
||||||
|
attributes: {
|
||||||
|
main: {
|
||||||
|
creator: consumerAccount.getId(),
|
||||||
|
datePublished,
|
||||||
|
price,
|
||||||
|
timeout: 3600,
|
||||||
|
name: 'dataAssetAccessServiceAgreement'
|
||||||
|
},
|
||||||
|
serviceAgreementTemplate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
291
src/ocean/OceanCompute.ts
Normal file
291
src/ocean/OceanCompute.ts
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||||
|
import { MetaData, MetaDataAlgorithm } from '../ddo/MetaData'
|
||||||
|
import Account from './Account'
|
||||||
|
import { DDO } from '../ddo/DDO'
|
||||||
|
import { SubscribablePromise } from '../utils'
|
||||||
|
import { OrderProgressStep } from './utils/ServiceUtils'
|
||||||
|
import { DID } from '../squid'
|
||||||
|
import { ServiceCompute } from '../ddo/Service'
|
||||||
|
|
||||||
|
export const ComputeJobStatus = Object.freeze({
|
||||||
|
Started: 10,
|
||||||
|
ConfiguringVolumes: 20,
|
||||||
|
ProvisioningSuccess: 30,
|
||||||
|
DataProvisioningFailed: 31,
|
||||||
|
AlgorithmProvisioningFailed: 32,
|
||||||
|
RunningAlgorithm: 40,
|
||||||
|
FilteringResults: 50,
|
||||||
|
PublishingResult: 60,
|
||||||
|
Completed: 70,
|
||||||
|
Stopped: 80,
|
||||||
|
Deleted: 90
|
||||||
|
})
|
||||||
|
|
||||||
|
export interface Output {
|
||||||
|
publishAlgorithmLog?: boolean
|
||||||
|
publishOutput?: boolean
|
||||||
|
brizoAddress?: string
|
||||||
|
brizoUri?: string
|
||||||
|
metadata?: MetaData
|
||||||
|
metadataUri?: string
|
||||||
|
nodeUri?: string
|
||||||
|
owner?: string
|
||||||
|
secretStoreUri?: string
|
||||||
|
whitelist?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ComputeJob {
|
||||||
|
owner: string
|
||||||
|
agreementId: string
|
||||||
|
jobId: string
|
||||||
|
dateCreated: string
|
||||||
|
dateFinished: string
|
||||||
|
status: number
|
||||||
|
statusText: string
|
||||||
|
algorithmLogUrl: string
|
||||||
|
resultsUrls: string[]
|
||||||
|
resultsDid?: DID
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute submodule of Ocean Protocol.
|
||||||
|
*/
|
||||||
|
export class OceanCompute extends Instantiable {
|
||||||
|
/**
|
||||||
|
* Returns the instance of OceanCompute.
|
||||||
|
* @return {Promise<OceanCompute>}
|
||||||
|
*/
|
||||||
|
public static async getInstance(config: InstantiableConfig): Promise<OceanCompute> {
|
||||||
|
const instance = new OceanCompute()
|
||||||
|
instance.setInstanceConfig(config)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an order of a compute service that is defined in an asset's services.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} datasetDid The DID of the dataset asset (of type `dataset`) to run the algorithm on.
|
||||||
|
* @return {Promise<string>} Returns the Service Agreement ID, representation of `bytes32` ID.
|
||||||
|
*/
|
||||||
|
public order(
|
||||||
|
consumerAccount: Account,
|
||||||
|
datasetDid: string,
|
||||||
|
provider?: string
|
||||||
|
): SubscribablePromise<OrderProgressStep, string> {
|
||||||
|
return new SubscribablePromise(async observer => {
|
||||||
|
const { assets, keeper, utils } = this.ocean
|
||||||
|
const ddo: DDO = await assets.resolve(datasetDid)
|
||||||
|
const condition = keeper.conditions.computeExecutionCondition
|
||||||
|
|
||||||
|
const agreementId = await utils.services.order(
|
||||||
|
'compute',
|
||||||
|
condition,
|
||||||
|
observer,
|
||||||
|
consumerAccount,
|
||||||
|
ddo,
|
||||||
|
provider
|
||||||
|
)
|
||||||
|
|
||||||
|
return agreementId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the output object and add default properties if needed
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {Output} output Output section used for publishing the result.
|
||||||
|
* @return {Promise<Output>} Returns output object
|
||||||
|
*/
|
||||||
|
public checkOutput(consumerAccount: Account, output?: Output): Output {
|
||||||
|
const isDefault =
|
||||||
|
!output || (!output.publishAlgorithmLog && !output.publishOutput)
|
||||||
|
|
||||||
|
if (isDefault) {
|
||||||
|
return {
|
||||||
|
publishAlgorithmLog: false,
|
||||||
|
publishOutput: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
publishAlgorithmLog: output.publishAlgorithmLog,
|
||||||
|
publishOutput: output.publishOutput,
|
||||||
|
brizoAddress: output.brizoAddress || this.config.brizoAddress,
|
||||||
|
brizoUri: output.brizoUri || this.config.brizoUri,
|
||||||
|
metadataUri: output.metadataUri || this.config.aquariusUri,
|
||||||
|
nodeUri: output.nodeUri || this.config.nodeUri,
|
||||||
|
owner: output.owner || consumerAccount.getId(),
|
||||||
|
secretStoreUri: output.secretStoreUri || this.config.secretStoreUri
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the execution of a compute job.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} agreementId The service agreement ID.
|
||||||
|
* @param {string} algorithmDid The DID of the algorithm asset (of type `algorithm`) to run on the asset.
|
||||||
|
* @param {MetaData} algorithmMeta Metadata about the algorithm being run if `algorithm` is being used. This is ignored when `algorithmDid` is specified.
|
||||||
|
* @param {Output} output Define algorithm output publishing. Publishing the result of a compute job is turned off by default.
|
||||||
|
* @return {Promise<ComputeJob>} Returns compute job ID under status.jobId
|
||||||
|
*/
|
||||||
|
public async start(
|
||||||
|
consumerAccount: Account,
|
||||||
|
agreementId: string,
|
||||||
|
algorithmDid?: string,
|
||||||
|
algorithmMeta?: MetaDataAlgorithm,
|
||||||
|
output?: Output
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
output = this.checkOutput(consumerAccount, output)
|
||||||
|
const computeJobsList = await this.ocean.brizo.compute(
|
||||||
|
'post',
|
||||||
|
agreementId,
|
||||||
|
consumerAccount,
|
||||||
|
algorithmDid,
|
||||||
|
algorithmMeta,
|
||||||
|
undefined,
|
||||||
|
output
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends a running compute job.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} agreementId The service agreement ID.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped
|
||||||
|
* @return {Promise<ComputeJob>} Returns the new status of a job
|
||||||
|
*/
|
||||||
|
public async stop(
|
||||||
|
consumerAccount: Account,
|
||||||
|
agreementId: string,
|
||||||
|
jobId: string
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
const computeJobsList = await this.ocean.brizo.compute(
|
||||||
|
'put',
|
||||||
|
agreementId,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a compute job and all resources associated with the job. If job is running it will be stopped first.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} agreementId The service agreement ID.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped
|
||||||
|
* @return {Promise<ComputeJob>} Returns the new status of a job
|
||||||
|
*/
|
||||||
|
public async delete(
|
||||||
|
consumerAccount: Account,
|
||||||
|
agreementId: string,
|
||||||
|
jobId: string
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
const computeJobsList = await this.ocean.brizo.compute(
|
||||||
|
'delete',
|
||||||
|
agreementId,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends a running compute job and starts it again.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} agreementId The service agreement ID.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped
|
||||||
|
* @return {Promise<ComputeJob>} Returns the new status of a job
|
||||||
|
*/
|
||||||
|
public async restart(
|
||||||
|
consumerAccount: Account,
|
||||||
|
agreementId: string,
|
||||||
|
jobId: string
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
await this.stop(consumerAccount, agreementId, jobId)
|
||||||
|
const result = await this.start(consumerAccount, agreementId, jobId)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about the status of all compute jobs, or a single compute job.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} agreementId The service agreement ID.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped
|
||||||
|
* @return {Promise<ComputeJob[]>} Returns the status
|
||||||
|
*/
|
||||||
|
public async status(
|
||||||
|
consumerAccount: Account,
|
||||||
|
agreementId?: string,
|
||||||
|
jobId?: string
|
||||||
|
): Promise<ComputeJob[]> {
|
||||||
|
const computeJobsList = await this.ocean.brizo.compute(
|
||||||
|
'get',
|
||||||
|
agreementId,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList as ComputeJob[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the final result of a specific compute job published as an asset.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} agreementId The service agreement ID.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped.
|
||||||
|
* @return {Promise<ComputeJob>} Returns the DDO of the result asset.
|
||||||
|
*/
|
||||||
|
public async result(
|
||||||
|
consumerAccount: Account,
|
||||||
|
agreementId: string,
|
||||||
|
jobId: string
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
const computeJobsList = await this.ocean.brizo.compute(
|
||||||
|
'get',
|
||||||
|
agreementId,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
}
|
||||||
|
|
||||||
|
public async createComputeServiceAttributes(
|
||||||
|
consumerAccount: Account,
|
||||||
|
price: string,
|
||||||
|
datePublished: string
|
||||||
|
): Promise<ServiceCompute> {
|
||||||
|
const { templates } = this.ocean.keeper
|
||||||
|
const serviceAgreementTemplate = await templates.escrowComputeExecutionTemplate.getServiceAgreementTemplate()
|
||||||
|
const name = 'dataAssetComputingServiceAgreement'
|
||||||
|
return {
|
||||||
|
type: 'compute',
|
||||||
|
index: 3,
|
||||||
|
serviceEndpoint: this.ocean.brizo.getComputeEndpoint(),
|
||||||
|
templateId: templates.escrowComputeExecutionTemplate.getId(),
|
||||||
|
attributes: {
|
||||||
|
main: {
|
||||||
|
creator: consumerAccount.getId(),
|
||||||
|
datePublished,
|
||||||
|
price,
|
||||||
|
timeout: 3600,
|
||||||
|
name
|
||||||
|
},
|
||||||
|
serviceAgreementTemplate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract'
|
import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract'
|
||||||
|
|
||||||
|
import { ServiceUtils } from './ServiceUtils'
|
||||||
import { ServiceAgreement } from './ServiceAgreement'
|
import { ServiceAgreement } from './ServiceAgreement'
|
||||||
import { SignatureUtils } from './SignatureUtils'
|
import { SignatureUtils } from './SignatureUtils'
|
||||||
import { WebServiceConnector } from './WebServiceConnector'
|
import { WebServiceConnector } from './WebServiceConnector'
|
||||||
@ -21,6 +22,7 @@ export class OceanUtils extends Instantiable {
|
|||||||
config.logger,
|
config.logger,
|
||||||
config.web3
|
config.web3
|
||||||
)
|
)
|
||||||
|
instance.services = new ServiceUtils(config.ocean, config.logger)
|
||||||
instance.signature = new SignatureUtils(config.web3, config.logger)
|
instance.signature = new SignatureUtils(config.web3, config.logger)
|
||||||
instance.fetch = new WebServiceConnector(config.logger)
|
instance.fetch = new WebServiceConnector(config.logger)
|
||||||
|
|
||||||
@ -33,6 +35,12 @@ export class OceanUtils extends Instantiable {
|
|||||||
*/
|
*/
|
||||||
public agreements: ServiceAgreement
|
public agreements: ServiceAgreement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service utils.
|
||||||
|
* @type {ServiceUtils}
|
||||||
|
*/
|
||||||
|
public services: ServiceUtils
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature utils.
|
* Signature utils.
|
||||||
* @type {SignatureUtils}
|
* @type {SignatureUtils}
|
||||||
|
115
src/ocean/utils/ServiceUtils.ts
Normal file
115
src/ocean/utils/ServiceUtils.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { DDO } from '../../ddo/DDO'
|
||||||
|
import Account from '../Account'
|
||||||
|
import { zeroX, Logger, generateId } from '../../utils'
|
||||||
|
import { Ocean } from '../../squid'
|
||||||
|
import { Condition } from '../../keeper/contracts/conditions'
|
||||||
|
import { ServiceType, Service } from '../../ddo/Service'
|
||||||
|
|
||||||
|
export enum OrderProgressStep {
|
||||||
|
CreatingAgreement,
|
||||||
|
AgreementInitialized,
|
||||||
|
LockingPayment,
|
||||||
|
LockedPayment
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ServiceUtils {
|
||||||
|
private ocean: Ocean
|
||||||
|
private logger: Logger
|
||||||
|
|
||||||
|
constructor(ocean: Ocean, logger: Logger) {
|
||||||
|
this.ocean = ocean
|
||||||
|
this.logger = logger
|
||||||
|
}
|
||||||
|
|
||||||
|
public async order(
|
||||||
|
type: ServiceType,
|
||||||
|
condition: Condition,
|
||||||
|
observer: any,
|
||||||
|
consumerAccount: Account,
|
||||||
|
ddo: DDO,
|
||||||
|
provider?: string
|
||||||
|
): Promise<string> {
|
||||||
|
const { keeper, agreements } = this.ocean
|
||||||
|
|
||||||
|
const agreementId = zeroX(generateId())
|
||||||
|
const service: Service = ddo.findServiceByType(type)
|
||||||
|
const metadata = ddo.findServiceByType('metadata')
|
||||||
|
|
||||||
|
const templateName = service.attributes.serviceAgreementTemplate.contractName
|
||||||
|
const template = keeper.getTemplateByName(templateName)
|
||||||
|
|
||||||
|
// use price from compute service,
|
||||||
|
// otherwise always take the price from metadata
|
||||||
|
const price =
|
||||||
|
type === 'compute'
|
||||||
|
? service.attributes.main.price
|
||||||
|
: metadata.attributes.main.price
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-async-promise-executor
|
||||||
|
const paymentFlow = new Promise(async (resolve, reject) => {
|
||||||
|
await template.getAgreementCreatedEvent(agreementId).once()
|
||||||
|
|
||||||
|
this.logger.log('Agreement initialized')
|
||||||
|
observer.next(OrderProgressStep.AgreementInitialized)
|
||||||
|
|
||||||
|
this.logger.log('Locking payment')
|
||||||
|
|
||||||
|
const serviceGranted = condition
|
||||||
|
.getConditionFulfilledEvent(agreementId)
|
||||||
|
.once()
|
||||||
|
|
||||||
|
observer.next(OrderProgressStep.LockingPayment)
|
||||||
|
const paid = await agreements.conditions.lockReward(
|
||||||
|
agreementId,
|
||||||
|
price,
|
||||||
|
consumerAccount
|
||||||
|
)
|
||||||
|
observer.next(OrderProgressStep.LockedPayment)
|
||||||
|
|
||||||
|
if (paid) {
|
||||||
|
this.logger.log('Payment was OK')
|
||||||
|
} else {
|
||||||
|
this.logger.error('Payment was KO')
|
||||||
|
this.logger.error('Agreement ID: ', agreementId)
|
||||||
|
this.logger.error('DID: ', ddo.id)
|
||||||
|
reject(new Error('Error on payment'))
|
||||||
|
}
|
||||||
|
|
||||||
|
await serviceGranted
|
||||||
|
|
||||||
|
this.logger.log(`Service ${type} granted`)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
observer.next(OrderProgressStep.CreatingAgreement)
|
||||||
|
this.logger.log('Creating agreement')
|
||||||
|
|
||||||
|
// Get provider from didRegistry if not given in arguments
|
||||||
|
let _provider = provider
|
||||||
|
if (!provider) {
|
||||||
|
const providers = await keeper.didRegistry.getDIDProviders(ddo.shortId())
|
||||||
|
if (providers) {
|
||||||
|
_provider = providers[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await agreements.create(
|
||||||
|
ddo.id,
|
||||||
|
agreementId,
|
||||||
|
service.index,
|
||||||
|
undefined,
|
||||||
|
consumerAccount,
|
||||||
|
_provider,
|
||||||
|
consumerAccount
|
||||||
|
)
|
||||||
|
this.logger.log('Agreement created')
|
||||||
|
|
||||||
|
try {
|
||||||
|
await paymentFlow
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Error paying the ${type} service.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return agreementId
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,15 @@ export class WebServiceConnector {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delete(url: string): Promise<Response> {
|
||||||
|
return this.fetch(url, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public async downloadFile(
|
public async downloadFile(
|
||||||
url: string,
|
url: string,
|
||||||
destination?: string,
|
destination?: string,
|
||||||
|
@ -14,7 +14,9 @@ import * as utils from './utils'
|
|||||||
export * from './ddo/DDO'
|
export * from './ddo/DDO'
|
||||||
export * from './ddo/MetaData'
|
export * from './ddo/MetaData'
|
||||||
|
|
||||||
export { OrderProgressStep, CreateProgressStep } from './ocean/OceanAssets'
|
export { CreateProgressStep } from './ocean/OceanAssets'
|
||||||
|
export { ComputeJob, ComputeJobStatus } from './ocean/OceanCompute'
|
||||||
|
export { OrderProgressStep } from './ocean/utils/ServiceUtils'
|
||||||
export {
|
export {
|
||||||
OceanPlatformTechStatus,
|
OceanPlatformTechStatus,
|
||||||
OceanPlatformTech,
|
OceanPlatformTech,
|
||||||
|
@ -85,12 +85,15 @@ describe('Asset Owners', () => {
|
|||||||
// Granting access
|
// Granting access
|
||||||
try {
|
try {
|
||||||
await account2.requestTokens(
|
await account2.requestTokens(
|
||||||
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
|
parseInt(
|
||||||
|
(
|
||||||
|
+metadata.main.price *
|
||||||
|
10 ** -(await ocean.keeper.token.decimals())
|
||||||
|
).toString()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
} catch {}
|
} catch {}
|
||||||
const { index } = ddo.findServiceByType('access')
|
await ocean.assets.order(ddo.id, account2)
|
||||||
|
|
||||||
await ocean.assets.order(ddo.id, index, account2)
|
|
||||||
// Access granted
|
// Access granted
|
||||||
const { length: finalLength2 } = await ocean.assets.consumerAssets(
|
const { length: finalLength2 } = await ocean.assets.consumerAssets(
|
||||||
account2.getId()
|
account2.getId()
|
||||||
|
121
test/integration/ocean/Compute.test.ts
Normal file
121
test/integration/ocean/Compute.test.ts
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { config } from '../config'
|
||||||
|
import {
|
||||||
|
Ocean,
|
||||||
|
Account,
|
||||||
|
DDO,
|
||||||
|
MetaData,
|
||||||
|
ComputeJobStatus,
|
||||||
|
Config,
|
||||||
|
MetaDataAlgorithm
|
||||||
|
} from '../../../src'
|
||||||
|
import { getMetadata } from '../utils'
|
||||||
|
import { ServiceCompute } from '../../../src/ddo/Service'
|
||||||
|
|
||||||
|
const metadataAsset = getMetadata()
|
||||||
|
const metadataAlgorithm = getMetadata(0, 'algorithm')
|
||||||
|
|
||||||
|
const customConfig: Config = {
|
||||||
|
...config,
|
||||||
|
// nodeUri: 'https://nile.dev-ocean.com',
|
||||||
|
// aquariusUri: 'https://aquarius.nile.dev-ocean.com',
|
||||||
|
// brizoUri: 'http://89.46.156.10:8030',
|
||||||
|
// secretStoreUri: 'https://secret-store.nile.dev-ocean.com',
|
||||||
|
// brizoAddress: '0x413c9ba0a05b8a600899b41b0c62dd661e689354',
|
||||||
|
verbose: true
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Compute', () => {
|
||||||
|
let ocean: Ocean
|
||||||
|
let account: Account
|
||||||
|
let agreementId: string
|
||||||
|
let dataset: DDO
|
||||||
|
let algorithm: DDO
|
||||||
|
let computeService: ServiceCompute
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
ocean = await Ocean.getInstance(customConfig)
|
||||||
|
;[account] = await ocean.accounts.list()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should authenticate the consumer account', async () => {
|
||||||
|
await account.authenticate()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should publish a dataset with a compute service object', async () => {
|
||||||
|
const stepsAsset = []
|
||||||
|
computeService = await ocean.compute.createComputeServiceAttributes(
|
||||||
|
account,
|
||||||
|
'1000',
|
||||||
|
metadataAsset.main.datePublished
|
||||||
|
)
|
||||||
|
dataset = await ocean.assets
|
||||||
|
.create(metadataAsset as MetaData, account, [computeService])
|
||||||
|
.next(step => stepsAsset.push(step))
|
||||||
|
|
||||||
|
assert.instanceOf(dataset, DDO)
|
||||||
|
assert.isDefined(
|
||||||
|
dataset.findServiceByType('compute'),
|
||||||
|
`DDO compute service doesn't exist`
|
||||||
|
)
|
||||||
|
assert.deepEqual(stepsAsset, [0, 1, 2, 3, 4, 5, 6, 7])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should publish an algorithm', async () => {
|
||||||
|
const stepsAlgorithm = []
|
||||||
|
algorithm = await ocean.assets
|
||||||
|
.create(metadataAlgorithm as MetaData, account)
|
||||||
|
.next(step => stepsAlgorithm.push(step))
|
||||||
|
|
||||||
|
assert.instanceOf(algorithm, DDO)
|
||||||
|
assert.deepEqual(stepsAlgorithm, [0, 1, 2, 3, 4, 5, 6, 7])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should order the compute service of the dataset', async () => {
|
||||||
|
const steps = []
|
||||||
|
try {
|
||||||
|
await account.requestTokens(
|
||||||
|
parseInt(
|
||||||
|
(
|
||||||
|
+computeService.attributes.main.price *
|
||||||
|
10 ** -(await ocean.keeper.token.decimals())
|
||||||
|
).toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
agreementId = await ocean.compute
|
||||||
|
.order(account, dataset.id)
|
||||||
|
.next(step => steps.push(step))
|
||||||
|
|
||||||
|
console.log(agreementId)
|
||||||
|
assert.isDefined(agreementId)
|
||||||
|
assert.deepEqual(steps, [0, 1, 2, 3])
|
||||||
|
} catch {}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should start a compute job with a published algo', async () => {
|
||||||
|
const response = await ocean.compute.start(account, agreementId, algorithm.id)
|
||||||
|
|
||||||
|
assert.equal(response.status, ComputeJobStatus.Started)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should start a compute job with a rawcode algo', async () => {
|
||||||
|
const algoMeta: MetaDataAlgorithm = {
|
||||||
|
rawcode: `console.log('Hello world!')`,
|
||||||
|
container: {
|
||||||
|
entrypoint: 'node $ALGO',
|
||||||
|
image: 'node',
|
||||||
|
tag: '10'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const response = await ocean.compute.start(
|
||||||
|
account,
|
||||||
|
agreementId,
|
||||||
|
undefined,
|
||||||
|
algoMeta
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.equal(response.status, ComputeJobStatus.Started)
|
||||||
|
})
|
||||||
|
})
|
@ -45,8 +45,12 @@ describe('Consume Asset', () => {
|
|||||||
|
|
||||||
it('should be able to request tokens for consumer', async () => {
|
it('should be able to request tokens for consumer', async () => {
|
||||||
const initialBalance = (await consumer.getBalance()).ocn
|
const initialBalance = (await consumer.getBalance()).ocn
|
||||||
const claimedTokens =
|
const claimedTokens = parseInt(
|
||||||
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
|
(
|
||||||
|
+metadata.main.price *
|
||||||
|
10 ** -(await ocean.keeper.token.decimals())
|
||||||
|
).toString()
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await consumer.requestTokens(claimedTokens)
|
await consumer.requestTokens(claimedTokens)
|
||||||
@ -156,13 +160,10 @@ describe('Consume Asset', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should consume and store the assets', async () => {
|
it('should consume and store the assets', async () => {
|
||||||
const accessService = ddo.findServiceByType('access')
|
|
||||||
|
|
||||||
const folder = '/tmp/ocean/squid-js-1'
|
const folder = '/tmp/ocean/squid-js-1'
|
||||||
const path = await ocean.assets.consume(
|
const path = await ocean.assets.consume(
|
||||||
serviceAgreementSignatureResult.agreementId,
|
serviceAgreementSignatureResult.agreementId,
|
||||||
ddo.id,
|
ddo.id,
|
||||||
accessService.index,
|
|
||||||
consumer,
|
consumer,
|
||||||
folder
|
folder
|
||||||
)
|
)
|
||||||
@ -183,13 +184,10 @@ describe('Consume Asset', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should consume and store one asset', async () => {
|
it('should consume and store one asset', async () => {
|
||||||
const accessService = ddo.findServiceByType('access')
|
|
||||||
|
|
||||||
const folder = '/tmp/ocean/squid-js-2'
|
const folder = '/tmp/ocean/squid-js-2'
|
||||||
const path = await ocean.assets.consume(
|
const path = await ocean.assets.consume(
|
||||||
serviceAgreementSignatureResult.agreementId,
|
serviceAgreementSignatureResult.agreementId,
|
||||||
ddo.id,
|
ddo.id,
|
||||||
accessService.index,
|
|
||||||
consumer,
|
consumer,
|
||||||
folder,
|
folder,
|
||||||
1
|
1
|
||||||
|
@ -50,34 +50,30 @@ describe('Consume Asset (Brizo)', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should order the asset', async () => {
|
it('should order the asset', async () => {
|
||||||
const accessService = ddo.findServiceByType('access')
|
const steps = []
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await consumer.requestTokens(
|
await consumer.requestTokens(
|
||||||
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
|
parseInt(
|
||||||
|
(
|
||||||
|
+metadata.main.price *
|
||||||
|
10 ** -(await ocean.keeper.token.decimals())
|
||||||
|
).toString()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
} catch {}
|
|
||||||
|
|
||||||
const steps = []
|
agreementId = await ocean.assets
|
||||||
agreementId = await ocean.assets
|
.order(ddo.id, consumer)
|
||||||
.order(ddo.id, accessService.index, consumer)
|
.next(step => steps.push(step))
|
||||||
.next(step => steps.push(step))
|
} catch {}
|
||||||
|
|
||||||
assert.isDefined(agreementId)
|
assert.isDefined(agreementId)
|
||||||
assert.deepEqual(steps, [0, 1, 2, 3])
|
assert.deepEqual(steps, [0, 1, 2, 3])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should consume and store the assets', async () => {
|
it('should consume and store the assets', async () => {
|
||||||
const accessService = ddo.findServiceByType('access')
|
|
||||||
|
|
||||||
const folder = '/tmp/ocean/squid-js'
|
const folder = '/tmp/ocean/squid-js'
|
||||||
const path = await ocean.assets.consume(
|
const path = await ocean.assets.consume(agreementId, ddo.id, consumer, folder)
|
||||||
agreementId,
|
|
||||||
ddo.id,
|
|
||||||
accessService.index,
|
|
||||||
consumer,
|
|
||||||
folder
|
|
||||||
)
|
|
||||||
|
|
||||||
assert.include(path, folder, 'The storage path is not correct.')
|
assert.include(path, folder, 'The storage path is not correct.')
|
||||||
|
|
||||||
|
@ -50,30 +50,25 @@ xdescribe('Consume Asset (Large size)', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should order the asset', async () => {
|
it('should order the asset', async () => {
|
||||||
const accessService = ddo.findServiceByType('access')
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await consumer.requestTokens(
|
await consumer.requestTokens(
|
||||||
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
|
parseInt(
|
||||||
|
(
|
||||||
|
+metadata.main.price *
|
||||||
|
10 ** -(await ocean.keeper.token.decimals())
|
||||||
|
).toString()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
agreementId = await ocean.assets.order(ddo.id, accessService.index, consumer)
|
agreementId = await ocean.assets.order(ddo.id, consumer)
|
||||||
|
|
||||||
assert.isDefined(agreementId)
|
assert.isDefined(agreementId)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should consume and store the assets', async () => {
|
it('should consume and store the assets', async () => {
|
||||||
const accessService = ddo.findServiceByType('access')
|
|
||||||
|
|
||||||
const folder = '/tmp/ocean/squid-js'
|
const folder = '/tmp/ocean/squid-js'
|
||||||
const path = await ocean.assets.consume(
|
const path = await ocean.assets.consume(agreementId, ddo.id, consumer, folder)
|
||||||
agreementId,
|
|
||||||
ddo.id,
|
|
||||||
accessService.index,
|
|
||||||
consumer,
|
|
||||||
folder
|
|
||||||
)
|
|
||||||
|
|
||||||
assert.include(path, folder, 'The storage path is not correct.')
|
assert.include(path, folder, 'The storage path is not correct.')
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ describe('Register Escrow Compute Execution Template', () => {
|
|||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
ocean = await Ocean.getInstance(config)
|
ocean = await Ocean.getInstance(config)
|
||||||
keeper = ocean.keeper
|
;({ keeper } = ocean)
|
||||||
|
|
||||||
template = keeper.templates.escrowComputeExecutionTemplate
|
template = keeper.templates.escrowComputeExecutionTemplate
|
||||||
|
|
||||||
@ -36,9 +36,11 @@ describe('Register Escrow Compute Execution Template', () => {
|
|||||||
consumer = (await ocean.accounts.list())[2]
|
consumer = (await ocean.accounts.list())[2]
|
||||||
|
|
||||||
// Conditions
|
// Conditions
|
||||||
computeExecutionCondition = keeper.conditions.computeExecutionCondition
|
;({
|
||||||
lockRewardCondition = keeper.conditions.lockRewardCondition
|
computeExecutionCondition,
|
||||||
escrowReward = keeper.conditions.escrowReward
|
lockRewardCondition,
|
||||||
|
escrowReward
|
||||||
|
} = keeper.conditions)
|
||||||
|
|
||||||
if (!ocean.keeper.dispenser) {
|
if (!ocean.keeper.dispenser) {
|
||||||
escrowAmount = 0
|
escrowAmount = 0
|
||||||
@ -274,7 +276,7 @@ describe('Register Escrow Compute Execution Template', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should fulfill the conditions from computing side', async () => {
|
it('should fulfill the conditions from computing side', async () => {
|
||||||
await ocean.agreements.conditions.grantServiceExecution(
|
await ocean.agreements.conditions.grantCompute(
|
||||||
agreementId,
|
agreementId,
|
||||||
did,
|
did,
|
||||||
consumer.getId(),
|
consumer.getId(),
|
||||||
|
@ -11,18 +11,17 @@ describe('Versions', () => {
|
|||||||
ocean = await Ocean.getInstance(config)
|
ocean = await Ocean.getInstance(config)
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: enable again after new versions of Brizo
|
it('should return the versions', async () => {
|
||||||
xit('should return the versions', async () => {
|
|
||||||
const versions = await ocean.versions.get()
|
const versions = await ocean.versions.get()
|
||||||
|
|
||||||
assert.equal(versions.aquarius.status, OceanPlatformTechStatus.Working)
|
assert.equal(versions.aquarius.status, OceanPlatformTechStatus.Working)
|
||||||
assert.equal(versions.brizo.status, OceanPlatformTechStatus.Working)
|
assert.equal(versions.brizo.status, OceanPlatformTechStatus.Working)
|
||||||
assert.equal(versions.squid.status, OceanPlatformTechStatus.Working)
|
assert.equal(versions.squid.status, OceanPlatformTechStatus.Working)
|
||||||
|
|
||||||
assert.deepEqual(versions.status, {
|
// assert.deepEqual(versions.status, {
|
||||||
ok: true,
|
// ok: true,
|
||||||
contracts: true,
|
// contracts: true,
|
||||||
network: true
|
// network: true
|
||||||
})
|
// })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { MetaData } from '../../../src' // @oceanprotocol/squid
|
import { MetaData, MetaDataAlgorithm, Ocean, Account } from '../../../src' // @oceanprotocol/squid
|
||||||
|
import { ServiceCompute } from '../../../src/ddo/Service'
|
||||||
|
|
||||||
const metadata: Partial<MetaData> = {
|
const metadata: Partial<MetaData> = {
|
||||||
main: {
|
main: {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
type: 'dataset',
|
type: undefined,
|
||||||
dateCreated: '2012-10-10T17:00:00Z',
|
dateCreated: '2012-10-10T17:00:00Z',
|
||||||
datePublished: '2012-10-10T17:00:00Z',
|
datePublished: '2012-10-10T17:00:00Z',
|
||||||
author: 'Met Office',
|
author: 'Met Office',
|
||||||
@ -46,16 +47,33 @@ const metadata: Partial<MetaData> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generateMetadata = (name: string, price?: number): Partial<MetaData> => ({
|
const algorithmMeta: MetaDataAlgorithm = {
|
||||||
...metadata,
|
language: 'scala',
|
||||||
|
format: 'docker-image',
|
||||||
|
version: '0.1',
|
||||||
|
container: {
|
||||||
|
entrypoint: 'ocean-entrypoint.sh',
|
||||||
|
image: 'node',
|
||||||
|
tag: '10'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = (
|
||||||
|
name: string,
|
||||||
|
type?: 'dataset' | 'algorithm',
|
||||||
|
price?: number
|
||||||
|
): Partial<MetaData> => ({
|
||||||
main: {
|
main: {
|
||||||
...metadata.main,
|
...metadata.main,
|
||||||
name,
|
name,
|
||||||
price: (price || 21) + '0'.repeat(18)
|
type: type || 'dataset',
|
||||||
|
price: (price || 21) + '0'.repeat(18),
|
||||||
|
algorithm: type === 'algorithm' ? algorithmMeta : undefined
|
||||||
},
|
},
|
||||||
additionalInformation: {
|
additionalInformation: {
|
||||||
...metadata.additionalInformation
|
...metadata.additionalInformation
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getMetadata = (price?: number) => generateMetadata('TestAsset', price)
|
export const getMetadata = (price?: number, type?: 'dataset' | 'algorithm') =>
|
||||||
|
generateMetadata('TestAsset', type, price)
|
||||||
|
459
test/unit/__fixtures__/ddo.json
Normal file
459
test/unit/__fixtures__/ddo.json
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
{
|
||||||
|
"@context": "https://w3id.org/future-method/v1",
|
||||||
|
"id": "did:op:08a429b8529856d59867503f8056903a680935a76950bb9649785cc97869a43d",
|
||||||
|
"publicKey": [
|
||||||
|
{
|
||||||
|
"id": "did:op:123456789abcdefghi#keys-1",
|
||||||
|
"type": "RsaVerificationKey2018",
|
||||||
|
"owner": "did:op:123456789abcdefghi",
|
||||||
|
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "did:op:123456789abcdefghi#keys-2",
|
||||||
|
"type": "Ed25519VerificationKey2018",
|
||||||
|
"owner": "did:op:123456789abcdefghi",
|
||||||
|
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "did:op:123456789abcdefghi#keys-3",
|
||||||
|
"type": "RsaPublicKeyExchangeKey2018",
|
||||||
|
"owner": "did:op:123456789abcdefghi",
|
||||||
|
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"authentication": [
|
||||||
|
{
|
||||||
|
"type": "RsaSignatureAuthentication2018",
|
||||||
|
"publicKey": "did:op:123456789abcdefghi#keys-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ieee2410Authentication2018",
|
||||||
|
"publicKey": "did:op:123456789abcdefghi#keys-2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"proof": {
|
||||||
|
"type": "UUIDSignature",
|
||||||
|
"created": "2016-02-08T16:02:20Z",
|
||||||
|
"creator": "did:example:8uQhQMGzWxR8vw5P3UWH1ja",
|
||||||
|
"signatureValue": "QNB13Y7Q9...1tzjn4w=="
|
||||||
|
},
|
||||||
|
"service": [
|
||||||
|
{
|
||||||
|
"type": "access",
|
||||||
|
"index": 0,
|
||||||
|
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}",
|
||||||
|
"templateId": "044852b2a670ade5407e78fb2863c51000000000000000000000000000000000",
|
||||||
|
"attributes": {
|
||||||
|
"main": {
|
||||||
|
"name": "dataAssetAccessServiceAgreement",
|
||||||
|
"creator": "0x36A7f3383A63279cDaF4DfC0F3ABc07d90252C6b",
|
||||||
|
"datePublished": "2019-11-15T14:11:23Z",
|
||||||
|
"price": "",
|
||||||
|
"timeout": 36000
|
||||||
|
},
|
||||||
|
"serviceAgreementTemplate": {
|
||||||
|
"contractName": "EscrowAccessSecretStoreTemplate",
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "AgreementCreated",
|
||||||
|
"actorType": "consumer",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "escrowAccessSecretStoreTemplate",
|
||||||
|
"functionName": "fulfillLockRewardCondition",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fulfillmentOrder": [
|
||||||
|
"lockReward.fulfill",
|
||||||
|
"accessSecretStore.fulfill",
|
||||||
|
"escrowReward.fulfill"
|
||||||
|
],
|
||||||
|
"conditionDependency": {
|
||||||
|
"lockReward": [],
|
||||||
|
"accessSecretStore": [],
|
||||||
|
"escrowReward": ["lockReward", "accessSecretStore"]
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"name": "lockReward",
|
||||||
|
"timelock": 0,
|
||||||
|
"timeout": 0,
|
||||||
|
"contractName": "LockRewardCondition",
|
||||||
|
"functionName": "fulfill",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "_rewardAddress",
|
||||||
|
"type": "address",
|
||||||
|
"value": "0x36A7f3383A63279cDaF4DfC0F3ABc07d90252C6b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_amount",
|
||||||
|
"type": "uint256",
|
||||||
|
"value": "0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Fulfilled",
|
||||||
|
"actorType": "publisher",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "lockRewardCondition",
|
||||||
|
"functionName": "fulfillAccessSecretStoreCondition",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "accessSecretStore",
|
||||||
|
"timelock": 0,
|
||||||
|
"timeout": 0,
|
||||||
|
"contractName": "AccessSecretStoreCondition",
|
||||||
|
"functionName": "fulfill",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "_documentId",
|
||||||
|
"type": "bytes32",
|
||||||
|
"value": "c678e7e5963d4fdc99afea49ac221d4d4177790f30204417823319d4d35f851f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_grantee",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Fulfilled",
|
||||||
|
"actorType": "publisher",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "accessSecretStore",
|
||||||
|
"functionName": "fulfillEscrowRewardCondition",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TimedOut",
|
||||||
|
"actorType": "consumer",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "accessSecretStore",
|
||||||
|
"functionName": "refundReward",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "escrowReward",
|
||||||
|
"timelock": 0,
|
||||||
|
"timeout": 0,
|
||||||
|
"contractName": "EscrowReward",
|
||||||
|
"functionName": "fulfill",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "_amount",
|
||||||
|
"type": "uint256",
|
||||||
|
"value": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_receiver",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_sender",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_lockCondition",
|
||||||
|
"type": "bytes32",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_releaseCondition",
|
||||||
|
"type": "bytes32",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Fulfilled",
|
||||||
|
"actorType": "publisher",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "escrowRewardCondition",
|
||||||
|
"functionName": "verifyRewardTokens",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "compute",
|
||||||
|
"index": 1,
|
||||||
|
"serviceEndpoint": "http://localhost:8030/api/v1/brizo/services/compute",
|
||||||
|
"templateId": "",
|
||||||
|
"attributes": {
|
||||||
|
"main": {
|
||||||
|
"name": "dataAssetComputingServiceAgreement",
|
||||||
|
"creator": "0x36A7f3383A63279cDaF4DfC0F3ABc07d90252C6b",
|
||||||
|
"datePublished": "2019-04-09T19:02:11Z",
|
||||||
|
"price": "10",
|
||||||
|
"timeout": 86400,
|
||||||
|
"provider": {
|
||||||
|
"type": "Azure",
|
||||||
|
"description": "",
|
||||||
|
"environment": {
|
||||||
|
"cluster": {
|
||||||
|
"type": "Kubernetes",
|
||||||
|
"url": "http://10.0.0.17/xxx"
|
||||||
|
},
|
||||||
|
"supportedContainers": [
|
||||||
|
{
|
||||||
|
"image": "tensorflow/tensorflow",
|
||||||
|
"tag": "latest",
|
||||||
|
"checksum": "sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image": "tensorflow/tensorflow",
|
||||||
|
"tag": "latest",
|
||||||
|
"checksum": "sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"supportedServers": [
|
||||||
|
{
|
||||||
|
"serverId": "1",
|
||||||
|
"serverType": "xlsize",
|
||||||
|
"price": "50",
|
||||||
|
"cpu": "16",
|
||||||
|
"gpu": "0",
|
||||||
|
"memory": "128gb",
|
||||||
|
"disk": "160gb",
|
||||||
|
"maxExecutionTime": 86400
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"serverId": "2",
|
||||||
|
"serverType": "medium",
|
||||||
|
"price": "10",
|
||||||
|
"cpu": "2",
|
||||||
|
"gpu": "0",
|
||||||
|
"memory": "8gb",
|
||||||
|
"disk": "80gb",
|
||||||
|
"maxExecutionTime": 86400
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalInformation": {},
|
||||||
|
"serviceAgreementTemplate": {
|
||||||
|
"contractName": "EscrowComputeExecutionTemplate",
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "AgreementActorAdded",
|
||||||
|
"actorType": "provider",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "",
|
||||||
|
"functionName": "fulfillLockRewardCondition",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fulfillmentOrder": [
|
||||||
|
"lockReward.fulfill",
|
||||||
|
"computeExecution.fulfill",
|
||||||
|
"escrowReward.fulfill"
|
||||||
|
],
|
||||||
|
"conditionDependency": {
|
||||||
|
"lockReward": [],
|
||||||
|
"computeExecution": [],
|
||||||
|
"releaseReward": ["lockReward", "computeExecution"]
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"name": "lockReward",
|
||||||
|
"timelock": 0,
|
||||||
|
"timeout": 0,
|
||||||
|
"contractName": "LockRewardCondition",
|
||||||
|
"functionName": "fulfill",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "_rewardAddress",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_amount",
|
||||||
|
"type": "uint256",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Fulfilled",
|
||||||
|
"actorType": "provider",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "lockRewardExecutionCondition",
|
||||||
|
"functionName": "fulfillComputeExecutionCondition",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "computeExecution",
|
||||||
|
"timelock": 0,
|
||||||
|
"timeout": 0,
|
||||||
|
"contractName": "ComputeExecutionCondition",
|
||||||
|
"functionName": "fulfill",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "_documentId",
|
||||||
|
"type": "bytes32",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_grantee",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Fulfilled",
|
||||||
|
"actorType": "provider",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "accessSecretStore",
|
||||||
|
"functionName": "fulfillEscrowRewardCondition",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TimedOut",
|
||||||
|
"actorType": "consumer",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "accessSecretStore",
|
||||||
|
"functionName": "refundReward",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "escrowReward",
|
||||||
|
"timelock": 0,
|
||||||
|
"timeout": 0,
|
||||||
|
"contractName": "EscrowReward",
|
||||||
|
"functionName": "fulfill",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "_amount",
|
||||||
|
"type": "uint256",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_receiver",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_sender",
|
||||||
|
"type": "address",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_lockCondition",
|
||||||
|
"type": "bytes32",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_releaseCondition",
|
||||||
|
"type": "bytes32",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "Fulfilled",
|
||||||
|
"actorType": "provider",
|
||||||
|
"handler": {
|
||||||
|
"moduleName": "escrowRewardCondition",
|
||||||
|
"functionName": "verifyRewardTokens",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "metadata",
|
||||||
|
"index": 2,
|
||||||
|
"serviceEndpoint": "http://myaquarius.org/api/v1/provider/assets/metadata/{did}",
|
||||||
|
"attributes": {
|
||||||
|
"main": {
|
||||||
|
"name": "UK Weather information 2011",
|
||||||
|
"type": "dataset",
|
||||||
|
"dateCreated": "2012-10-10T17:00:000Z",
|
||||||
|
"author": "Met Office",
|
||||||
|
"license": "CC-BY",
|
||||||
|
"price": "1000000000000000000",
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||||
|
"checksum": "085340abffh21495345af97c6b0e761",
|
||||||
|
"contentLength": "12324"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp2.zip"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"curation": {
|
||||||
|
"rating": 0.93,
|
||||||
|
"numVotes": 123,
|
||||||
|
"schema": "Binary Voting"
|
||||||
|
},
|
||||||
|
"additionalInformation": {
|
||||||
|
"description": "Weather information of UK including temperature and humidity",
|
||||||
|
"copyrightHolder": "Met Office",
|
||||||
|
"workExample": "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"name": "Sample of Asset Data",
|
||||||
|
"type": "sample",
|
||||||
|
"url": "https://foo.com/sample.csv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Data Format Definition",
|
||||||
|
"type": "format",
|
||||||
|
"AssetID": "4d517500da0acb0d65a716f61330969334630363ce4a6a9d39691026ac7908ea"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inLanguage": "en",
|
||||||
|
"categories": ["Economy", "Data Science"],
|
||||||
|
"tags": ["weather", "uk", "2011", "temperature", "humidity"],
|
||||||
|
"updateFrequency": "yearly",
|
||||||
|
"structuredMarkup": [
|
||||||
|
{
|
||||||
|
"uri": "http://skos.um.es/unescothes/C01194/jsonld",
|
||||||
|
"mediaType": "application/ld+json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "http://skos.um.es/unescothes/C01194/turtle",
|
||||||
|
"mediaType": "text/turtle"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import WebServiceConnector from '../../src/utils/WebServiceConnector'
|
import { WebServiceConnector } from '../../src/ocean/utils/WebServiceConnector'
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export default class WebServiceConnectorMock extends WebServiceConnector {
|
export default class WebServiceConnectorMock extends WebServiceConnector {
|
@ -7,7 +7,7 @@ import { Ocean } from '../../../src/ocean/Ocean'
|
|||||||
import config from '../config'
|
import config from '../config'
|
||||||
import TestContractHandler from '../keeper/TestContractHandler'
|
import TestContractHandler from '../keeper/TestContractHandler'
|
||||||
|
|
||||||
import * as jsonDDO from '../testdata/ddo.json'
|
import * as jsonDDO from '../__fixtures__/ddo.json'
|
||||||
|
|
||||||
use(spies)
|
use(spies)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { assert } from 'chai'
|
|||||||
import Account from '../../../src/ocean/Account'
|
import Account from '../../../src/ocean/Account'
|
||||||
import { Ocean } from '../../../src/ocean/Ocean'
|
import { Ocean } from '../../../src/ocean/Ocean'
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
import ContractBaseMock from '../mocks/ContractBase.Mock'
|
import ContractBaseMock from '../__mocks__/ContractBase.Mock'
|
||||||
import TestContractHandler from './TestContractHandler'
|
import TestContractHandler from './TestContractHandler'
|
||||||
|
|
||||||
const wrappedContract = new ContractBaseMock('OceanToken')
|
const wrappedContract = new ContractBaseMock('OceanToken')
|
||||||
|
@ -7,6 +7,13 @@ import config from '../config'
|
|||||||
interface ContractTest extends Contract {
|
interface ContractTest extends Contract {
|
||||||
testContract?: boolean
|
testContract?: boolean
|
||||||
$initialized?: boolean
|
$initialized?: boolean
|
||||||
|
options?: {
|
||||||
|
address: string
|
||||||
|
}
|
||||||
|
methods?: {
|
||||||
|
addMinter(address: string): any
|
||||||
|
initialize(...args: any[]): any
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TestContractHandler extends ContractHandler {
|
export default class TestContractHandler extends ContractHandler {
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { Brizo } from '../../../src/brizo/Brizo'
|
|
||||||
|
|
||||||
export default class BrizoMock extends Brizo {
|
|
||||||
public async initializeServiceAgreement(
|
|
||||||
did: string,
|
|
||||||
serviceAgreementId: string,
|
|
||||||
index: number,
|
|
||||||
signature: string,
|
|
||||||
consumerPublicKey: string
|
|
||||||
): Promise<any> {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
131
test/unit/ocean/OceanCompute.test.ts
Normal file
131
test/unit/ocean/OceanCompute.test.ts
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
import sinon from 'sinon'
|
||||||
|
|
||||||
|
import { Ocean } from '../../../src/ocean/Ocean'
|
||||||
|
import config from '../config'
|
||||||
|
import { Account } from '../../../src/squid'
|
||||||
|
import { OceanCompute, ComputeJobStatus } from '../../../src/ocean/OceanCompute'
|
||||||
|
import TestIdGenerator from '../TestIdGenerator'
|
||||||
|
|
||||||
|
describe('OceanCompute', () => {
|
||||||
|
let ocean: Ocean
|
||||||
|
let account: Account
|
||||||
|
let compute: OceanCompute
|
||||||
|
let agreementId: string
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
ocean = await Ocean.getInstance(config)
|
||||||
|
;[account] = await ocean.accounts.list()
|
||||||
|
compute = ocean.compute // eslint-disable-line prefer-destructuring
|
||||||
|
agreementId = TestIdGenerator.generatePrefixedId()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sinon.reset()
|
||||||
|
sinon.restore()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#start()', () => {
|
||||||
|
it('should start a new job', async () => {
|
||||||
|
sinon.stub(ocean.brizo, 'compute').returns([{ jobId: 'my-job-id' }] as any)
|
||||||
|
const response = await compute.start(account, agreementId, 'did:op:0xxx')
|
||||||
|
assert(response.jobId === 'my-job-id')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#stop()', () => {
|
||||||
|
it('should stop a job', async () => {
|
||||||
|
sinon
|
||||||
|
.stub(ocean.brizo, 'compute')
|
||||||
|
.returns([{ status: ComputeJobStatus.Completed }] as any)
|
||||||
|
|
||||||
|
const response = await compute.stop(account, agreementId, 'xxx')
|
||||||
|
assert(response.status === ComputeJobStatus.Completed)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#restart()', () => {
|
||||||
|
it('should restart a job', async () => {
|
||||||
|
sinon
|
||||||
|
.stub(ocean.brizo, 'compute')
|
||||||
|
.returns([
|
||||||
|
{ status: ComputeJobStatus.Started, jobId: 'my-job-id' }
|
||||||
|
] as any)
|
||||||
|
|
||||||
|
const response = await compute.restart(account, agreementId, 'xxx')
|
||||||
|
assert(response.jobId === 'my-job-id')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#delete()', () => {
|
||||||
|
it('should delete a job', async () => {
|
||||||
|
sinon
|
||||||
|
.stub(ocean.brizo, 'compute')
|
||||||
|
.returns([{ status: ComputeJobStatus.Deleted }] as any)
|
||||||
|
|
||||||
|
const response = await compute.delete(account, agreementId, 'xxx')
|
||||||
|
assert(response.status === ComputeJobStatus.Deleted)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#status()', () => {
|
||||||
|
it('should get the status of one job', async () => {
|
||||||
|
sinon
|
||||||
|
.stub(ocean.brizo, 'compute')
|
||||||
|
.returns([{ status: ComputeJobStatus.Started }] as any)
|
||||||
|
|
||||||
|
const response = await compute.status(account, agreementId, 'xxx')
|
||||||
|
assert(response.length === 1)
|
||||||
|
assert(response[0].status === ComputeJobStatus.Started)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should get the status of multiple jobs', async () => {
|
||||||
|
sinon
|
||||||
|
.stub(ocean.brizo, 'compute')
|
||||||
|
.returns([
|
||||||
|
{ status: ComputeJobStatus.Started },
|
||||||
|
{ status: ComputeJobStatus.Started }
|
||||||
|
] as any)
|
||||||
|
|
||||||
|
const response = await compute.status(account, agreementId)
|
||||||
|
assert(response.length === 2)
|
||||||
|
assert(response[0].status === ComputeJobStatus.Started)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should get all jobs for one owner', async () => {
|
||||||
|
sinon
|
||||||
|
.stub(ocean.brizo, 'compute')
|
||||||
|
.returns([
|
||||||
|
{ status: ComputeJobStatus.Started },
|
||||||
|
{ status: ComputeJobStatus.Started }
|
||||||
|
] as any)
|
||||||
|
|
||||||
|
const response = await compute.status(account)
|
||||||
|
assert(response.length === 2)
|
||||||
|
assert(response[0].status === ComputeJobStatus.Started)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#checkOutput()', () => {
|
||||||
|
it('should return default values', async () => {
|
||||||
|
const defaultOutput = { publishAlgorithmLog: false, publishOutput: false }
|
||||||
|
const output = compute.checkOutput(account, undefined)
|
||||||
|
assert.deepEqual(output, defaultOutput)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return output values', async () => {
|
||||||
|
const newOutput = {
|
||||||
|
publishAlgorithmLog: true,
|
||||||
|
publishOutput: true,
|
||||||
|
brizoAddress: 'hello',
|
||||||
|
brizoUri: 'hello',
|
||||||
|
metadataUri: 'hello',
|
||||||
|
nodeUri: 'hello',
|
||||||
|
owner: '0xhello',
|
||||||
|
secretStoreUri: 'hello'
|
||||||
|
}
|
||||||
|
const output = compute.checkOutput(account, newOutput)
|
||||||
|
assert.deepEqual(output, newOutput)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
215
test/unit/testdata/ddo.json
vendored
215
test/unit/testdata/ddo.json
vendored
@ -1,215 +0,0 @@
|
|||||||
{
|
|
||||||
"@context": "https://w3id.org/future-method/v1",
|
|
||||||
"id": "did:op:08a429b8529856d59867503f8056903a680935a76950bb9649785cc97869a43d",
|
|
||||||
"publicKey": [
|
|
||||||
{
|
|
||||||
"id": "did:op:123456789abcdefghi#keys-1",
|
|
||||||
"type": "RsaVerificationKey2018",
|
|
||||||
"owner": "did:op:123456789abcdefghi",
|
|
||||||
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:op:123456789abcdefghi#keys-2",
|
|
||||||
"type": "Ed25519VerificationKey2018",
|
|
||||||
"owner": "did:op:123456789abcdefghi",
|
|
||||||
"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:op:123456789abcdefghi#keys-3",
|
|
||||||
"type": "RsaPublicKeyExchangeKey2018",
|
|
||||||
"owner": "did:op:123456789abcdefghi",
|
|
||||||
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"authentication": [
|
|
||||||
{
|
|
||||||
"type": "RsaSignatureAuthentication2018",
|
|
||||||
"publicKey": "did:op:123456789abcdefghi#keys-1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ieee2410Authentication2018",
|
|
||||||
"publicKey": "did:op:123456789abcdefghi#keys-2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"proof": {
|
|
||||||
"type": "UUIDSignature",
|
|
||||||
"created": "2016-02-08T16:02:20Z",
|
|
||||||
"creator": "did:example:8uQhQMGzWxR8vw5P3UWH1ja",
|
|
||||||
"signatureValue": "QNB13Y7Q9...1tzjn4w=="
|
|
||||||
},
|
|
||||||
"service": [
|
|
||||||
{
|
|
||||||
"type": "access",
|
|
||||||
"index": 0,
|
|
||||||
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}",
|
|
||||||
"purchaseEndpoint": "http://mybrizo.org/api/v1/brizo/services/access/purchase?",
|
|
||||||
"templateId": "044852b2a670ade5407e78fb2863c51000000000000000000000000000000000",
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"name": "lockPayment",
|
|
||||||
"timeout": 0,
|
|
||||||
"conditionKey": {
|
|
||||||
"contractAddress": "0x...",
|
|
||||||
"fingerprint": "0x..."
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"assetId": "bytes32",
|
|
||||||
"price": "integer"
|
|
||||||
},
|
|
||||||
"events": {
|
|
||||||
"PaymentLocked": {
|
|
||||||
"actorType": ["publisher"],
|
|
||||||
"handlers": [
|
|
||||||
{
|
|
||||||
"moduleName": "accessControl",
|
|
||||||
"functionName": "grantAccess",
|
|
||||||
"version": "0.1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "releasePayment",
|
|
||||||
"timeout": 0,
|
|
||||||
"conditionKey": {
|
|
||||||
"contractAddress": "0x...",
|
|
||||||
"fingerprint": "0xXXXXXXXX"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"assetId": "bytes32",
|
|
||||||
"price": "integer"
|
|
||||||
},
|
|
||||||
"events": {
|
|
||||||
"PaymentReleased": {
|
|
||||||
"actorType": ["publisher"],
|
|
||||||
"handlers": [
|
|
||||||
{
|
|
||||||
"moduleName": "serviceAgreement",
|
|
||||||
"functionName": "fulfillAgreement",
|
|
||||||
"version": "0.1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "grantAccess",
|
|
||||||
"timeout": 0,
|
|
||||||
"conditionKey": {
|
|
||||||
"contractAddress": "0x",
|
|
||||||
"fingerprint": "0xXXXXXXXX"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"assetId": "bytes32",
|
|
||||||
"documentKeyId": "bytes32"
|
|
||||||
},
|
|
||||||
"events": {
|
|
||||||
"AccessGranted": {
|
|
||||||
"actorType": ["consumer"],
|
|
||||||
"handlers": [
|
|
||||||
{
|
|
||||||
"moduleName": "asset",
|
|
||||||
"functionName": "consumeService",
|
|
||||||
"version": "0.1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "refundPayment",
|
|
||||||
"timeout": 1,
|
|
||||||
"condition_key": {
|
|
||||||
"contractAddress": "0x...",
|
|
||||||
"fingerprint": "0xXXXXXXXX"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"assetId": "bytes32",
|
|
||||||
"price": "int"
|
|
||||||
},
|
|
||||||
"events": {
|
|
||||||
"PaymentRefund": {
|
|
||||||
"actorType": ["consumer"],
|
|
||||||
"handlers": [
|
|
||||||
{
|
|
||||||
"moduleName": "serviceAgreement",
|
|
||||||
"functionName": "fulfillAgreement",
|
|
||||||
"version": "0.1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "compute",
|
|
||||||
"index": 1,
|
|
||||||
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/compute?pubKey=${pubKey}&serviceId={serviceId}&algo={algo}&container={container}",
|
|
||||||
"templateId": "044852b2a670ade5407e78fb2863c51000000000000000000000000000000002"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "metadata",
|
|
||||||
"index": 2,
|
|
||||||
"serviceEndpoint": "http://myaquarius.org/api/v1/provider/assets/metadata/{did}",
|
|
||||||
"attributes": {
|
|
||||||
"main": {
|
|
||||||
"name": "UK Weather information 2011",
|
|
||||||
"type": "dataset",
|
|
||||||
"dateCreated": "2012-10-10T17:00:000Z",
|
|
||||||
"author": "Met Office",
|
|
||||||
"license": "CC-BY",
|
|
||||||
"price": 10,
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
|
||||||
"checksum": "085340abffh21495345af97c6b0e761",
|
|
||||||
"contentLength": "12324"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp2.zip"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"curation": {
|
|
||||||
"rating": 0.93,
|
|
||||||
"numVotes": 123,
|
|
||||||
"schema": "Binary Voting"
|
|
||||||
},
|
|
||||||
"additionalInformation": {
|
|
||||||
"description": "Weather information of UK including temperature and humidity",
|
|
||||||
"copyrightHolder": "Met Office",
|
|
||||||
"workExample": "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"name": "Sample of Asset Data",
|
|
||||||
"type": "sample",
|
|
||||||
"url": "https://foo.com/sample.csv"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Data Format Definition",
|
|
||||||
"type": "format",
|
|
||||||
"AssetID": "4d517500da0acb0d65a716f61330969334630363ce4a6a9d39691026ac7908ea"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inLanguage": "en",
|
|
||||||
"categories": ["Economy", "Data Science"],
|
|
||||||
"tags": ["weather", "uk", "2011", "temperature", "humidity"],
|
|
||||||
"updateFrequency": "yearly",
|
|
||||||
"structuredMarkup": [
|
|
||||||
{
|
|
||||||
"uri": "http://skos.um.es/unescothes/C01194/jsonld",
|
|
||||||
"mediaType": "application/ld+json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"uri": "http://skos.um.es/unescothes/C01194/turtle",
|
|
||||||
"mediaType": "text/turtle"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user