mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
Merge branch 'master' into feature/compute
# Conflicts: # src/ocean/OceanAssets.ts
This commit is contained in:
commit
e31aa81dcc
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ test/**/*.js
|
||||
src/**/*.js
|
||||
|
||||
src/metadata\.json
|
||||
.idea
|
||||
.vscode
|
14
.travis.yml
14
.travis.yml
@ -15,6 +15,8 @@ matrix:
|
||||
before_install:
|
||||
- npm install -g npm
|
||||
- npm install -g codacy-coverage release-it greenkeeper-lockfile ganache-cli@~6.5.1
|
||||
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||
- chmod +x ./cc-test-reporter
|
||||
|
||||
before_script:
|
||||
- greenkeeper-lockfile-update
|
||||
@ -22,9 +24,9 @@ before_script:
|
||||
- git clone https://github.com/oceanprotocol/barge
|
||||
- cd barge
|
||||
- export AQUARIUS_VERSION=v1.0.5
|
||||
- export BRIZO_VERSION=v0.7.2
|
||||
- export KEEPER_VERSION=v0.12.7
|
||||
- export EVENTS_HANDLER_VERSION=v0.3.4
|
||||
- export BRIZO_VERSION=v0.8.1
|
||||
- export KEEPER_VERSION=v0.13.2
|
||||
- export EVENTS_HANDLER_VERSION=v0.4.4
|
||||
- export KEEPER_OWNER_ROLE_ADDRESS="0xe2DD09d719Da89e5a3D0F2549c7E24566e947260"
|
||||
- rm -rf "${HOME}/.ocean/keeper-contracts/artifacts"
|
||||
- bash -x start_ocean.sh --no-commons --no-dashboard 2>&1 > start_ocean.log &
|
||||
@ -37,9 +39,13 @@ script:
|
||||
- npm run build
|
||||
- npm run doc
|
||||
- npm run integration:cover
|
||||
- npm run report-coverage
|
||||
|
||||
after_script:
|
||||
- npm run report-codacy
|
||||
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.unit.json coverage/unit/lcov.info # Format unit test coverage
|
||||
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.integration.json coverage/integration/lcov.info # Format integration test coverage
|
||||
- ./cc-test-reporter sum-coverage coverage/codeclimate.*.json -p 2 # Sum both coverage parts into coverage/codeclimate.json
|
||||
- if [[ "$TRAVIS_TEST_RESULT" == 0 ]]; then ./cc-test-reporter upload-coverage; fi # Upload coverage/codeclimate.json
|
||||
- greenkeeper-lockfile-upload
|
||||
|
||||
notifications:
|
||||
|
25
CHANGELOG.md
25
CHANGELOG.md
@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v1.1.0](https://github.com/oceanprotocol/squid-js/compare/v1.1.0-beta.0...v1.1.0)
|
||||
|
||||
> 22 January 2020
|
||||
|
||||
- add codeclimate coverage reporting [`#359`](https://github.com/oceanprotocol/squid-js/pull/359)
|
||||
- Update to keeper-contracts v0.13 [`#344`](https://github.com/oceanprotocol/squid-js/pull/344)
|
||||
- Greenkeeper/typedoc 0.16.5 [`#356`](https://github.com/oceanprotocol/squid-js/pull/356)
|
||||
- Update whatwg-url to the latest version 🚀 [`#349`](https://github.com/oceanprotocol/squid-js/pull/349)
|
||||
- Update @types/node to the latest version 🚀 [`#348`](https://github.com/oceanprotocol/squid-js/pull/348)
|
||||
- Update nyc to the latest version 🚀 [`#347`](https://github.com/oceanprotocol/squid-js/pull/347)
|
||||
- chore(package): update typedoc to version 0.16.5 [`#352`](https://github.com/oceanprotocol/squid-js/issues/352)
|
||||
- Fix tests. [`48c4f64`](https://github.com/oceanprotocol/squid-js/commit/48c4f6459910069c79424ac67fc6a0d28a9d1839)
|
||||
- Remove all .js files that were unintentionally committed. [`7ccac88`](https://github.com/oceanprotocol/squid-js/commit/7ccac889ed20b9dabe9358e4e4989eed55245d52)
|
||||
- package updates [`216ae33`](https://github.com/oceanprotocol/squid-js/commit/216ae3330e3ffa147ca0d8417a901fa9f5a0d4cf)
|
||||
|
||||
#### [v1.1.0-beta.0](https://github.com/oceanprotocol/squid-js/compare/v1.0.0...v1.1.0-beta.0)
|
||||
|
||||
> 17 December 2019
|
||||
|
||||
- package updates [`eb23b04`](https://github.com/oceanprotocol/squid-js/commit/eb23b04ffec69a0f9f31f09985bc1012f3a386d2)
|
||||
- Release 1.1.0-beta.0 [`86c6a5a`](https://github.com/oceanprotocol/squid-js/commit/86c6a5a176203b222f2dc1f215c0c5fa6a418728)
|
||||
- bump to keeper-contracts v0.13.0 [`21a0815`](https://github.com/oceanprotocol/squid-js/commit/21a08152d2a33f73b9bfc6509ef19731904bbd9b)
|
||||
|
||||
#### [v1.0.0](https://github.com/oceanprotocol/squid-js/compare/v1.0.0-beta.7...v1.0.0)
|
||||
|
||||
> 9 December 2019
|
||||
@ -11,7 +34,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- v2 release: new DDO [`#328`](https://github.com/oceanprotocol/squid-js/pull/328)
|
||||
- package updates [`ccf7250`](https://github.com/oceanprotocol/squid-js/commit/ccf7250af87abf986d94c5023ac960fd155d0789)
|
||||
- lint fixes, bump Ocean components [`414c885`](https://github.com/oceanprotocol/squid-js/commit/414c885163325a69eb315b20f8fe3837bc557656)
|
||||
- typos [`d6a233e`](https://github.com/oceanprotocol/squid-js/commit/d6a233e590631087ba1302ac44f1e597b512c34e)
|
||||
- Release 1.0.0 [`df53099`](https://github.com/oceanprotocol/squid-js/commit/df530992a1e578ecb4459d54d2669972479ccb5b)
|
||||
|
||||
#### [v1.0.0-beta.7](https://github.com/oceanprotocol/squid-js/compare/v0.8.3...v1.0.0-beta.7)
|
||||
|
||||
|
18
README.md
18
README.md
@ -8,7 +8,8 @@
|
||||
[![npm](https://img.shields.io/npm/v/@oceanprotocol/squid.svg)](https://www.npmjs.com/package/@oceanprotocol/squid)
|
||||
[![Travis (.com)](https://img.shields.io/travis/com/oceanprotocol/squid-js.svg)](https://travis-ci.com/oceanprotocol/squid-js)
|
||||
[![GitHub contributors](https://img.shields.io/github/contributors/oceanprotocol/squid-js.svg)](https://github.com/oceanprotocol/squid-js/graphs/contributors)
|
||||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8508313231b44b0997ec84898cd6f9db)](https://app.codacy.com/app/ocean-protocol/squid-js?utm_source=github.com&utm_medium=referral&utm_content=oceanprotocol/squid-js&utm_campaign=Badge_Grade_Settings)
|
||||
[![Maintainability](https://api.codeclimate.com/v1/badges/ff173cf1c7adc6b21ae5/maintainability)](https://codeclimate.com/github/oceanprotocol/squid-js/maintainability)
|
||||
[![Test Coverage](https://api.codeclimate.com/v1/badges/ff173cf1c7adc6b21ae5/test_coverage)](https://codeclimate.com/github/oceanprotocol/squid-js/test_coverage)
|
||||
[![js oceanprotocol](https://img.shields.io/badge/js-oceanprotocol-7b1173.svg)](https://github.com/oceanprotocol/eslint-config-oceanprotocol)
|
||||
[![Greenkeeper badge](https://badges.greenkeeper.io/oceanprotocol/squid-js.svg)](https://greenkeeper.io/)
|
||||
|
||||
@ -72,6 +73,19 @@ const ocean: Ocean = await Ocean.getInstance({
|
||||
|
||||
For an overview of endpoint configurations making up various Ocean networks, please refer to [`.env.local.example`](https://github.com/oceanprotocol/commons/blob/master/client/.env.local.example) from commons.
|
||||
|
||||
Optionally, you can initialize an Aquarius connection without relying on the rest of Ocean to be loaded. This is useful for outputting asset metadata stored in Aquarius without the need to configure Web3 and all other Ocean Protocol network connections.
|
||||
|
||||
```js
|
||||
import { Ocean, Aquarius, Logger } from 'squid'
|
||||
|
||||
const aquarius = new Aquarius('http://localhost:5000', Logger)
|
||||
const asset = aquarius.retrieveDDO('did:op:e6fda48e8d814d5d9655645aac3c046cc87528dbc1a9449799e579d7b83d1360')
|
||||
|
||||
const ocean = await Ocean.getInstance({ ... })
|
||||
// Aquarius will still be available under ocean.aquarius, just later
|
||||
const asset = ocean.aquarius.retrieveDDO('did:op:e6fda48e8d814d5d9655645aac3c046cc87528dbc1a9449799e579d7b83d1360')
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
You can see how `squid-js` is used on:
|
||||
@ -160,6 +174,8 @@ export SEED_WORDS="taxi music thumb unique chat sand crew more leg another off l
|
||||
Once everything is up, run the integration tests:
|
||||
|
||||
```bash
|
||||
# integration tests work with the spree network and the SEED_WORDS in previous step are required.
|
||||
# Make sure to reset `ETH_PORT` to 8545 (or whatever port is used in `spree1)
|
||||
npm run integration
|
||||
```
|
||||
|
||||
|
@ -6,7 +6,7 @@ const configJson: Config = {
|
||||
aquariusUri: 'http://aquarius:5000',
|
||||
brizoUri: 'http://localhost:8030',
|
||||
secretStoreUri: 'http://localhost:12001',
|
||||
brizoAddress: '0x068ed00cf0441e4829d9784fcbe7b9e26d4bd8d0',
|
||||
brizoAddress: '0x068Ed00cF0441e4829D9784fCBe7b9e26D4BD8d0',
|
||||
verbose: false
|
||||
}
|
||||
|
||||
|
@ -90,13 +90,17 @@ describe('Consume Asset', () => {
|
||||
accessService.index,
|
||||
serviceAgreementSignatureResult.signature,
|
||||
consumer,
|
||||
publisher
|
||||
config.brizoAddress,
|
||||
consumer
|
||||
)
|
||||
|
||||
assert.isTrue(success)
|
||||
})
|
||||
|
||||
it('should get the agreement conditions status not fulfilled', async () => {
|
||||
// Wait for the agreement event
|
||||
// await ocean.keeper.agreementStoreManager
|
||||
// .getAgreementCreatedEvent(serviceAgreementSignatureResult.agreementId).once()
|
||||
const status = await ocean.agreements.status(
|
||||
serviceAgreementSignatureResult.agreementId
|
||||
)
|
||||
|
@ -39,7 +39,7 @@ describe('Consume Asset (Brizo)', () => {
|
||||
await consumer.authenticate()
|
||||
})
|
||||
|
||||
it('should regiester an asset', async () => {
|
||||
it('should register an asset', async () => {
|
||||
const steps = []
|
||||
ddo = await ocean.assets
|
||||
.create(metadata as any, publisher)
|
||||
|
@ -43,7 +43,7 @@ xdescribe('Consume Asset (Large size)', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('should regiester an asset', async () => {
|
||||
it('should register an asset', async () => {
|
||||
ddo = await ocean.assets.create(metadata as any, publisher)
|
||||
|
||||
assert.instanceOf(ddo, DDO)
|
||||
|
@ -48,7 +48,7 @@ describe('Register Escrow Access Secret Store Template', () => {
|
||||
describe('Propose and approve template', () => {
|
||||
it('should propose the template', async () => {
|
||||
await keeper.templateStoreManager.proposeTemplate(
|
||||
template.getAddress(),
|
||||
template.getId(),
|
||||
consumer.getId(),
|
||||
true
|
||||
)
|
||||
@ -58,7 +58,7 @@ describe('Register Escrow Access Secret Store Template', () => {
|
||||
|
||||
it('should approve the template', async () => {
|
||||
await keeper.templateStoreManager.approveTemplate(
|
||||
template.getAddress(),
|
||||
template.getId(),
|
||||
templateManagerOwner.getId(),
|
||||
true
|
||||
)
|
||||
@ -122,7 +122,9 @@ describe('Register Escrow Access Secret Store Template', () => {
|
||||
})
|
||||
|
||||
it('should have condition instances asociated', async () => {
|
||||
const conditionInstances = await template.getConditions()
|
||||
const conditionInstances = (await template.getConditionTypes()).map(address =>
|
||||
keeper.getConditionByAddress(address)
|
||||
)
|
||||
|
||||
assert.equal(conditionInstances.length, 3, 'Expected 3 conditions.')
|
||||
|
||||
@ -145,14 +147,15 @@ describe('Register Escrow Access Secret Store Template', () => {
|
||||
})
|
||||
|
||||
it('should create a new agreement', async () => {
|
||||
const agreement = await template.createAgreement(
|
||||
const agreement = await keeper.agreementStoreManager.createAgreement(
|
||||
agreementId,
|
||||
did,
|
||||
[conditionIdAccess, conditionIdLock, conditionIdEscrow],
|
||||
template.getId(),
|
||||
[conditionIdLock, conditionIdAccess, conditionIdEscrow],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
consumer.getId(),
|
||||
publisher.getId()
|
||||
[consumer.getId(), config.brizoAddress],
|
||||
consumer.getId()
|
||||
)
|
||||
|
||||
assert.isTrue(agreement.status)
|
||||
@ -244,7 +247,8 @@ describe('Register Escrow Access Secret Store Template', () => {
|
||||
did,
|
||||
escrowAmount,
|
||||
consumer.getId(),
|
||||
publisher.getId()
|
||||
config.brizoAddress,
|
||||
consumer.getId()
|
||||
)
|
||||
|
||||
assert.match(agreementId, /^0x[a-f0-9]{64}$/i)
|
||||
|
@ -48,7 +48,7 @@ describe('Register Escrow Compute Execution Template', () => {
|
||||
describe('Propose and approve template', () => {
|
||||
it('should propose the template', async () => {
|
||||
await keeper.templateStoreManager.proposeTemplate(
|
||||
template.getAddress(),
|
||||
template.getId(),
|
||||
consumer.getId(),
|
||||
true
|
||||
)
|
||||
@ -58,7 +58,7 @@ describe('Register Escrow Compute Execution Template', () => {
|
||||
|
||||
it('should approve the template', async () => {
|
||||
await keeper.templateStoreManager.approveTemplate(
|
||||
template.getAddress(),
|
||||
template.getId(),
|
||||
templateManagerOwner.getId(),
|
||||
true
|
||||
)
|
||||
@ -145,14 +145,15 @@ describe('Register Escrow Compute Execution Template', () => {
|
||||
})
|
||||
|
||||
it('should create a new agreement', async () => {
|
||||
const agreement = await template.createAgreement(
|
||||
const agreement = await keeper.agreementStoreManager.createAgreement(
|
||||
agreementId,
|
||||
did,
|
||||
[conditionIdCompute, conditionIdLock, conditionIdEscrow],
|
||||
template.getId(),
|
||||
[conditionIdLock, conditionIdCompute, conditionIdEscrow],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
consumer.getId(),
|
||||
publisher.getId()
|
||||
[consumer.getId(), config.brizoAddress],
|
||||
consumer.getId()
|
||||
)
|
||||
|
||||
assert.isTrue(agreement.status)
|
||||
@ -244,7 +245,8 @@ describe('Register Escrow Compute Execution Template', () => {
|
||||
did,
|
||||
escrowAmount,
|
||||
consumer.getId(),
|
||||
publisher.getId()
|
||||
config.brizoAddress,
|
||||
consumer.getId()
|
||||
)
|
||||
|
||||
assert.match(agreementId, /^0x[a-f0-9]{64}$/i)
|
||||
|
@ -18,7 +18,7 @@ describe('Signature', () => {
|
||||
})
|
||||
|
||||
it('hashServiceAgreement should generate the correct signature', () => {
|
||||
const templateId = `0x${'f'.repeat(40)}`
|
||||
const templateId = `0x${'f'.repeat(64)}`
|
||||
const agreementId = `0x${'e'.repeat(64)}`
|
||||
|
||||
const accessId = `0x${'a'.repeat(64)}`
|
||||
@ -28,14 +28,14 @@ describe('Signature', () => {
|
||||
const hash = ocean.utils.agreements.hashServiceAgreement(
|
||||
templateId,
|
||||
agreementId,
|
||||
[accessId, lockId, escrowId],
|
||||
[lockId, accessId, escrowId],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]
|
||||
)
|
||||
|
||||
assert.equal(
|
||||
hash,
|
||||
'0x67901517c18a3d23e05806fff7f04235cc8ae3b1f82345b8bfb3e4b02b5800c7',
|
||||
'0x464dac3b79a47f8acad54f67a0f4473249330f025c69687531e58c2e43b36437',
|
||||
'The signature is not correct.'
|
||||
)
|
||||
})
|
||||
@ -44,7 +44,7 @@ describe('Signature', () => {
|
||||
const { templates } = ocean.keeper
|
||||
|
||||
const did = `did:op:${'c'.repeat(64)}`
|
||||
const templateId = `0x${'f'.repeat(40)}`
|
||||
const templateId = `0x${'f'.repeat(64)}`
|
||||
const agreementId = `0x${'e'.repeat(64)}`
|
||||
|
||||
const serviceAgreementTemplate = await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplate()
|
||||
@ -84,7 +84,7 @@ describe('Signature', () => {
|
||||
|
||||
assert.equal(
|
||||
signature,
|
||||
'0x3aa8a1c48b8e582d694bbd4ba3a29fde573b78da9720dc48baeb831b2163e1fa6e10e983882ebf8a00f4124de2505136354fd146934053f0d58bba4eced5f8d01b',
|
||||
'0xa04568fccdda7e1594e3e615f8d71b14733705aabe5294af0b7f46f0aedb9d5906a2caa6142ee4de10534a47c5a7083b21b2d3e9a96ac462bc0b9d25070e981e1c',
|
||||
'The signature is not correct.'
|
||||
)
|
||||
})
|
||||
|
@ -7,11 +7,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "keeper-contracts",
|
||||
"version": "~0.12.7"
|
||||
"version": "~0.13.2"
|
||||
},
|
||||
{
|
||||
"name": "brizo",
|
||||
"version": "~0.7.2"
|
||||
"version": "~0.8.1"
|
||||
},
|
||||
{
|
||||
"name": "aquarius",
|
||||
@ -19,7 +19,7 @@
|
||||
},
|
||||
{
|
||||
"name": "events-handler",
|
||||
"version": "~0.3.4"
|
||||
"version": "~0.4.1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
1508
package-lock.json
generated
1508
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oceanprotocol/squid",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"description": "JavaScript client library for Ocean Protocol",
|
||||
"main": "./dist/node/squid.js",
|
||||
"typings": "./dist/node/squid.d.ts",
|
||||
@ -26,10 +26,9 @@
|
||||
"format": "prettier --parser typescript --ignore-path .gitignore --write '**/*.{js,jsx,ts,tsx}'",
|
||||
"doc": "typedoc --mode modules --out ./doc/ ./src/",
|
||||
"doc:json": "./scripts/typedoc.js",
|
||||
"merge-coverages": "npx lcov-result-merger \"coverage/*/lcov.info\" coverage/lcov.info",
|
||||
"report-coverage": "npm run report-coverage:unit && npm run report-coverage:integration",
|
||||
"report-coverage:unit": "cat coverage/unit/lcov.info | codacy-coverage --token 71ef0d15f6f04ac29b31d704b28f866a",
|
||||
"report-coverage:integration": "cat coverage/integration/lcov.info | codacy-coverage --token 71ef0d15f6f04ac29b31d704b28f866a",
|
||||
"report-codacy": "npm run report-coverage:unit && npm run report-coverage:integration",
|
||||
"report-codacy:unit": "cat coverage/unit/lcov.info | codacy-coverage --token 71ef0d15f6f04ac29b31d704b28f866a",
|
||||
"report-codacy:integration": "cat coverage/integration/lcov.info | codacy-coverage --token 71ef0d15f6f04ac29b31d704b28f866a",
|
||||
"run": "ts-node",
|
||||
"release": "release-it --non-interactive",
|
||||
"changelog": "auto-changelog -p",
|
||||
@ -52,7 +51,7 @@
|
||||
"web3": "^1.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/keeper-contracts": "^0.12.7",
|
||||
"@oceanprotocol/keeper-contracts": "^0.13.2",
|
||||
"@oceanprotocol/secret-store-client": "^0.0.15",
|
||||
"bignumber.js": "^9.0.0",
|
||||
"deprecated-decorator": "^0.1.6",
|
||||
@ -64,14 +63,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@release-it/bumper": "^1.0.5",
|
||||
"@truffle/hdwallet-provider": "^1.0.26",
|
||||
"@types/chai": "^4.2.6",
|
||||
"@truffle/hdwallet-provider": "^1.0.27",
|
||||
"@types/chai": "^4.2.7",
|
||||
"@types/chai-spies": "^1.0.1",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^13.1.0",
|
||||
"@types/node-fetch": "^2.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "^2.10.0",
|
||||
"@typescript-eslint/parser": "^2.10.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.12.0",
|
||||
"@typescript-eslint/parser": "^2.12.0",
|
||||
"auto-changelog": "^1.16.2",
|
||||
"chai": "^4.2.0",
|
||||
"chai-spies": "^1.0.0",
|
||||
@ -79,7 +78,7 @@
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-config-oceanprotocol": "^1.5.0",
|
||||
"eslint-config-prettier": "^6.7.0",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"lcov-result-merger": "^3.1.0",
|
||||
"mocha": "^6.2.2",
|
||||
"mock-local-storage": "^1.1.11",
|
||||
@ -88,10 +87,10 @@
|
||||
"prettier": "^1.19.1",
|
||||
"source-map-support": "^0.5.16",
|
||||
"ts-node": "^8.5.4",
|
||||
"typedoc": "^0.15.3",
|
||||
"typescript": "^3.7.3",
|
||||
"typedoc": "^0.16.8",
|
||||
"typescript": "^3.7.5",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack": "^4.41.3",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-merge": "^4.2.2"
|
||||
},
|
||||
|
@ -3,7 +3,7 @@
|
||||
/* eslint-disable security/detect-non-literal-fs-filename */
|
||||
|
||||
const fs = require('fs')
|
||||
const typedoc = require('typedoc')
|
||||
const TypeDoc = require('typedoc')
|
||||
const typescript = require('typescript')
|
||||
const ora = require('ora')
|
||||
const squidJsPackage = require('../package.json')
|
||||
@ -21,7 +21,11 @@ const generateJson = () => {
|
||||
const spinnerTypedoc = ora('Generating TypeDoc json...').start()
|
||||
|
||||
// Setup our TypeDoc app
|
||||
const app = new typedoc.Application({
|
||||
const app = new TypeDoc.Application()
|
||||
app.options.addReader(new TypeDoc.TSConfigReader())
|
||||
app.options.addReader(new TypeDoc.TypeDocReader())
|
||||
|
||||
app.bootstrap({
|
||||
tsconfig: config
|
||||
})
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { URL } from 'whatwg-url'
|
||||
import { DDO } from '../ddo/DDO'
|
||||
import DID from '../ocean/DID'
|
||||
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||
import { Logger } from '../utils'
|
||||
import { WebServiceConnector } from '../ocean/utils/WebServiceConnector'
|
||||
|
||||
const apiPath = '/api/v1/aquarius/assets/ddo'
|
||||
|
||||
@ -21,25 +22,35 @@ export interface SearchQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a interface with Aquarius.
|
||||
* Provides an interface with Aquarius.
|
||||
* Aquarius provides an off-chain database store for metadata about data assets.
|
||||
*/
|
||||
export class Aquarius extends Instantiable {
|
||||
export class Aquarius {
|
||||
public fetch: WebServiceConnector
|
||||
private logger: Logger
|
||||
private aquariusUri: string
|
||||
|
||||
private get url() {
|
||||
return this.config.aquariusUri
|
||||
return this.aquariusUri
|
||||
}
|
||||
|
||||
constructor(config: InstantiableConfig) {
|
||||
super()
|
||||
this.setInstanceConfig(config)
|
||||
/**
|
||||
* Instantiate Aquarius (independently of Ocean) for off-chain interaction.
|
||||
* @param {String} aquariusUri
|
||||
* @param {Logger} logger
|
||||
*/
|
||||
constructor(aquariusUri: string, logger: Logger) {
|
||||
this.fetch = new WebServiceConnector(logger)
|
||||
this.logger = logger
|
||||
this.aquariusUri = aquariusUri
|
||||
}
|
||||
|
||||
public async getVersionInfo() {
|
||||
return (await this.ocean.utils.fetch.get(this.url)).json()
|
||||
return (await this.fetch.get(this.url)).json()
|
||||
}
|
||||
|
||||
public async getAccessUrl(accessToken: any, payload: any): Promise<string> {
|
||||
const accessUrl: string = await this.ocean.utils.fetch
|
||||
const accessUrl: string = await this.fetch
|
||||
.post(`${accessToken.service_endpoint}/${accessToken.resource_id}`, payload)
|
||||
.then((response: any): string => {
|
||||
if (response.ok) {
|
||||
@ -69,7 +80,7 @@ export class Aquarius extends Instantiable {
|
||||
* @return {Promise<QueryResult>}
|
||||
*/
|
||||
public async queryMetadata(query: SearchQuery): Promise<QueryResult> {
|
||||
const result: QueryResult = await this.ocean.utils.fetch
|
||||
const result: QueryResult = await this.fetch
|
||||
.post(`${this.url}${apiPath}/query`, JSON.stringify(query))
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
@ -107,7 +118,8 @@ export class Aquarius extends Instantiable {
|
||||
)
|
||||
fullUrl.searchParams.append('offset', query.offset.toString())
|
||||
fullUrl.searchParams.append('page', query.page.toString())
|
||||
const result: QueryResult = await this.ocean.utils.fetch
|
||||
|
||||
const result: QueryResult = await this.fetch
|
||||
.get(fullUrl)
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
@ -138,7 +150,7 @@ export class Aquarius extends Instantiable {
|
||||
*/
|
||||
public async storeDDO(ddo: DDO): Promise<DDO> {
|
||||
const fullUrl = `${this.url}${apiPath}`
|
||||
const result: DDO = await this.ocean.utils.fetch
|
||||
const result: DDO = await this.fetch
|
||||
.post(fullUrl, DDO.serialize(ddo))
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
@ -174,7 +186,7 @@ export class Aquarius extends Instantiable {
|
||||
): Promise<DDO> {
|
||||
did = did && DID.parse(did)
|
||||
const fullUrl = metadataServiceEndpoint || `${this.url}${apiPath}/${did.getDid()}`
|
||||
const result = await this.ocean.utils.fetch
|
||||
const result = await this.fetch
|
||||
.get(fullUrl)
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
|
@ -11,7 +11,6 @@ import {
|
||||
ComputeExecutionCondition
|
||||
} from './contracts/conditions'
|
||||
import {
|
||||
AgreementTemplate,
|
||||
EscrowAccessSecretStoreTemplate,
|
||||
EscrowComputeExecutionTemplate
|
||||
} from './contracts/templates'
|
||||
@ -25,6 +24,7 @@ import { objectPromiseAll } from '../utils'
|
||||
import { EventHandler } from './EventHandler'
|
||||
|
||||
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||
import { AgreementTemplateBase } from './contracts/templates/AgreementTemplateBase'
|
||||
|
||||
/**
|
||||
* Interface with Ocean Keeper contracts.
|
||||
@ -62,14 +62,7 @@ export class Keeper extends Instantiable {
|
||||
accessSecretStoreCondition: AccessSecretStoreCondition.getInstance(
|
||||
config
|
||||
),
|
||||
computeExecutionCondition: ComputeExecutionCondition.getInstance(config),
|
||||
// Templates
|
||||
escrowAccessSecretStoreTemplate: EscrowAccessSecretStoreTemplate.getInstance(
|
||||
config
|
||||
),
|
||||
escrowComputeExecutionTemplate: EscrowComputeExecutionTemplate.getInstance(
|
||||
config
|
||||
)
|
||||
computeExecutionCondition: ComputeExecutionCondition.getInstance(config)
|
||||
})
|
||||
|
||||
keeper.connected = true
|
||||
@ -100,7 +93,19 @@ export class Keeper extends Instantiable {
|
||||
accessSecretStoreCondition: keeper.instances.accessSecretStoreCondition,
|
||||
computeExecutionCondition: keeper.instances.computeExecutionCondition
|
||||
}
|
||||
// Conditions
|
||||
// Templates
|
||||
keeper.instances.escrowAccessSecretStoreTemplate = new EscrowAccessSecretStoreTemplate(
|
||||
keeper.templateStoreManager,
|
||||
keeper.agreementStoreManager,
|
||||
keeper.didRegistry,
|
||||
keeper.conditions
|
||||
)
|
||||
keeper.instances.escrowComputeExecutionTemplate = new EscrowComputeExecutionTemplate(
|
||||
keeper.templateStoreManager,
|
||||
keeper.agreementStoreManager,
|
||||
keeper.didRegistry,
|
||||
keeper.conditions
|
||||
)
|
||||
keeper.templates = {
|
||||
escrowAccessSecretStoreTemplate:
|
||||
keeper.instances.escrowAccessSecretStoreTemplate,
|
||||
@ -198,22 +203,22 @@ export class Keeper extends Instantiable {
|
||||
/**
|
||||
* Returns a template by name.
|
||||
* @param {string} name Template name.
|
||||
* @return {AgreementTemplate} Agreement template instance.
|
||||
* @return {AgreementTemplateBase} AgreementTemplateBase instance.
|
||||
*/
|
||||
public getTemplateByName(name: string): AgreementTemplate {
|
||||
public getTemplateByName(name: string): AgreementTemplateBase {
|
||||
return Object.values(this.templates).find(
|
||||
template => template.contractName === name
|
||||
template => template.templateName === name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a template by address.
|
||||
* @param {string} address Template address.
|
||||
* @return {AgreementTemplate} Agreement template instance.
|
||||
* @param {string} templateId Template id (hex representation of bytes32).
|
||||
* @return {AgreementTemplateBase} AgreementTemplateBase instance.
|
||||
*/
|
||||
public getTemplateByAddress(address: string): AgreementTemplate {
|
||||
public getTemplateById(templateId: string): AgreementTemplateBase {
|
||||
return Object.values(this.templates).find(
|
||||
template => template.getAddress() === address
|
||||
template => template.getId() === templateId
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,11 @@ export default class DIDRegistry extends ContractBase {
|
||||
return this.call('isDIDProvider', [didZeroX(did), zeroX(provider)])
|
||||
}
|
||||
|
||||
public async getDIDProviders(did: string): Promise<string[]> {
|
||||
const { providers } = await this.call('getDIDRegister', [didZeroX(did)])
|
||||
return providers
|
||||
}
|
||||
|
||||
public async getAttributesByOwner(owner: string): Promise<string[]> {
|
||||
return (
|
||||
await this.getPastEvents('DIDAttributeRegistered', {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Condition } from './Condition.abstract'
|
||||
import { zeroX, didZeroX, didPrefixed } from '../../../utils'
|
||||
import { zeroX, didZeroX } from '../../../utils'
|
||||
import { InstantiableConfig } from '../../../Instantiable.abstract'
|
||||
|
||||
export class ComputeExecutionCondition extends Condition {
|
||||
|
@ -15,11 +15,11 @@ export class AgreementStoreManager extends ContractBase {
|
||||
public static async getInstance(
|
||||
config: InstantiableConfig
|
||||
): Promise<AgreementStoreManager> {
|
||||
const templateStoreManeger: AgreementStoreManager = new AgreementStoreManager(
|
||||
const templateStoreManager: AgreementStoreManager = new AgreementStoreManager(
|
||||
'AgreementStoreManager'
|
||||
)
|
||||
await templateStoreManeger.init(config)
|
||||
return templateStoreManeger
|
||||
await templateStoreManager.init(config)
|
||||
return templateStoreManager
|
||||
}
|
||||
|
||||
public getOwner(): Promise<string> {
|
||||
@ -44,4 +44,59 @@ export class AgreementStoreManager extends ContractBase {
|
||||
blockNumberUpdated: +blockNumberUpdated
|
||||
} as AgreementData
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a agreement using EscrowComputeExecutionTemplate.
|
||||
* @param {string} agreementId Generated agreement ID.
|
||||
* @param {string} did Asset DID.
|
||||
* @param {string} templateId Template ID.
|
||||
* @param {string[]} conditionIds List of conditions IDs.
|
||||
* @param {number[]} timeLocks Timelocks.
|
||||
* @param {number[]} timeOuts Timeouts.
|
||||
* @param {string[]} actors ETH account addresses of provider, consumer, etc.
|
||||
* @param {string} from Action sender.
|
||||
*
|
||||
* @return {any} Transaction receipt.
|
||||
*/
|
||||
public async createAgreement(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
templateId: string,
|
||||
conditionIds: string[],
|
||||
timeLocks: number[],
|
||||
timeOuts: number[],
|
||||
actors: string[],
|
||||
from?: string
|
||||
): Promise<any> {
|
||||
return this.sendFrom(
|
||||
'createAgreement',
|
||||
[
|
||||
zeroX(agreementId),
|
||||
zeroX(did),
|
||||
zeroX(templateId),
|
||||
conditionIds.map(zeroX),
|
||||
timeLocks,
|
||||
timeOuts,
|
||||
actors
|
||||
],
|
||||
from
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and returns the agreement creation event.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @return {Event} Agreement created event.
|
||||
*/
|
||||
public getAgreementCreatedEvent(agreementId: string) {
|
||||
return this.getEvent('AgreementCreated', {
|
||||
agreementId: zeroX(agreementId)
|
||||
})
|
||||
}
|
||||
|
||||
public getAgreementActorAddedEvent(agreementId: string) {
|
||||
return this.getEvent('AgreementActorAdded', {
|
||||
agreementId: zeroX(agreementId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ export interface TemplateMetadata {
|
||||
owner: string
|
||||
lastUpdatedBy: string
|
||||
blockNumberUpdated: number
|
||||
conditionTypes: string[]
|
||||
actorTypeIds: string[]
|
||||
}
|
||||
|
||||
export class TemplateStoreManager extends ContractBase {
|
||||
@ -27,54 +29,83 @@ export class TemplateStoreManager extends ContractBase {
|
||||
return templateStoreManeger
|
||||
}
|
||||
|
||||
public generateId(templateName: string) {
|
||||
const args: any = [{ type: 'string', value: templateName }]
|
||||
return this.web3.utils.soliditySha3(...args)
|
||||
}
|
||||
|
||||
public getOwner(): Promise<string> {
|
||||
return this.call('owner', [])
|
||||
}
|
||||
|
||||
public async proposeTemplate(address: string, from?: string, ignoreExists?: boolean) {
|
||||
const template = await this.getTemplate(address)
|
||||
public async proposeTemplate(
|
||||
templateId: string,
|
||||
from?: string,
|
||||
ignoreExists?: boolean
|
||||
) {
|
||||
const template = await this.getTemplate(templateId)
|
||||
if (template.blockNumberUpdated !== 0) {
|
||||
this.logger.warn(`Template "${address}" already exist.`)
|
||||
this.logger.warn(`Template "${templateId}" already exist.`)
|
||||
if (!ignoreExists) {
|
||||
throw new Error('Template already exist.')
|
||||
}
|
||||
} else {
|
||||
return this.sendFrom('proposeTemplate', [zeroX(address)], from)
|
||||
return this.sendFrom('proposeTemplate', [zeroX(templateId)], from)
|
||||
}
|
||||
}
|
||||
|
||||
public async approveTemplate(
|
||||
address: string,
|
||||
templateId: string,
|
||||
from?: string,
|
||||
ignoreApproved?: boolean
|
||||
) {
|
||||
const template = await this.getTemplate(address)
|
||||
const template = await this.getTemplate(templateId)
|
||||
if (template.state !== TemplateState.Proposed) {
|
||||
this.logger.warn(`Template "${address}" is not in "proposed" state.`)
|
||||
this.logger.warn(`Template "${templateId}" is not in "proposed" state.`)
|
||||
if (!ignoreApproved) {
|
||||
throw new Error(`Template not in "proposed" state.`)
|
||||
}
|
||||
} else {
|
||||
return this.sendFrom('approveTemplate', [zeroX(address)], from)
|
||||
return this.sendFrom('approveTemplate', [zeroX(templateId)], from)
|
||||
}
|
||||
}
|
||||
|
||||
public revokeTemplate(address: string, from?: string) {
|
||||
return this.sendFrom('revokeTemplate', [zeroX(address)], from)
|
||||
public revokeTemplate(templateId: string, from?: string) {
|
||||
return this.sendFrom('revokeTemplate', [zeroX(templateId)], from)
|
||||
}
|
||||
|
||||
public async getTemplate(address: string) {
|
||||
public async getConditionTypes(templateId: string): Promise<string[]> {
|
||||
const { conditionTypes } = await this.getTemplate(templateId)
|
||||
return conditionTypes
|
||||
}
|
||||
|
||||
public getConditions(conditionTypes: string[]) {
|
||||
return conditionTypes.map(address =>
|
||||
this.ocean.keeper.getConditionByAddress(address)
|
||||
)
|
||||
}
|
||||
|
||||
public async getActorTypeValue(actorTypeId: string) {
|
||||
const typeValue = await this.call('getTemplateActorTypeValue', [actorTypeId])
|
||||
return typeValue
|
||||
}
|
||||
|
||||
public async getTemplate(templateId: string) {
|
||||
const {
|
||||
state,
|
||||
owner,
|
||||
lastUpdatedBy,
|
||||
blockNumberUpdated
|
||||
} = await this.call('getTemplate', [zeroX(address)])
|
||||
blockNumberUpdated,
|
||||
conditionTypes,
|
||||
actorTypeIds
|
||||
} = await this.call('getTemplate', [zeroX(templateId)])
|
||||
return {
|
||||
state: +state,
|
||||
owner,
|
||||
lastUpdatedBy,
|
||||
blockNumberUpdated: +blockNumberUpdated
|
||||
blockNumberUpdated: +blockNumberUpdated,
|
||||
conditionTypes,
|
||||
actorTypeIds
|
||||
} as TemplateMetadata
|
||||
}
|
||||
}
|
||||
|
@ -1,235 +0,0 @@
|
||||
import ContractBase from '../ContractBase'
|
||||
import {
|
||||
Condition,
|
||||
ConditionState,
|
||||
conditionStateNames
|
||||
} from '../conditions/Condition.abstract'
|
||||
import { DDO } from '../../../ddo/DDO'
|
||||
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
|
||||
import { zeroX } from '../../../utils'
|
||||
import { InstantiableConfig } from '../../../Instantiable.abstract'
|
||||
|
||||
export interface AgreementConditionsStatus {
|
||||
[condition: string]: {
|
||||
condition: string
|
||||
contractName: string
|
||||
state: ConditionState
|
||||
blocked: boolean
|
||||
blockedBy: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class AgreementTemplate extends ContractBase {
|
||||
public static async getInstance(
|
||||
config: InstantiableConfig,
|
||||
conditionName: string,
|
||||
templateClass: any
|
||||
): Promise<AgreementTemplate & any> {
|
||||
const condition: AgreementTemplate = new (templateClass as any)(conditionName)
|
||||
await condition.init(config)
|
||||
return condition
|
||||
}
|
||||
|
||||
protected constructor(contractName: string) {
|
||||
super(contractName)
|
||||
}
|
||||
|
||||
public createAgreement(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
conditionIds: string[],
|
||||
timeLocks: number[],
|
||||
timeOuts: number[],
|
||||
...args: any[]
|
||||
)
|
||||
|
||||
public createAgreement(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
conditionIds: string[],
|
||||
timeLocks: number[],
|
||||
timeOuts: number[],
|
||||
extraArgs: any[],
|
||||
from?: string
|
||||
) {
|
||||
return this.sendFrom(
|
||||
'createAgreement',
|
||||
[
|
||||
zeroX(agreementId),
|
||||
zeroX(did),
|
||||
conditionIds.map(zeroX),
|
||||
timeLocks,
|
||||
timeOuts,
|
||||
...extraArgs
|
||||
],
|
||||
from
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditions address list.
|
||||
* @return {Promise<string[]>} Conditions address.
|
||||
*/
|
||||
public getConditionTypes(): Promise<string[]> {
|
||||
return this.call('getConditionTypes', [])
|
||||
}
|
||||
|
||||
/**
|
||||
* List of condition contracts.
|
||||
* @return {Promise<Condition[]>} Conditions contracts.
|
||||
*/
|
||||
public async getConditions(): Promise<Condition[]> {
|
||||
return (await this.getConditionTypes()).map(address =>
|
||||
this.ocean.keeper.getConditionByAddress(address)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get agreement conditions IDs.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @param {DDO} ddo DDO.
|
||||
* @param {string} from Consumer address.
|
||||
* @return {Promise<string[]>} Condition IDs.
|
||||
*/
|
||||
public abstract getAgreementIdsFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
): Promise<string[]>
|
||||
|
||||
/**
|
||||
* Create a new agreement using the data of a DDO.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @param {DDO} ddo DDO.
|
||||
* @param {string} from Creator address.
|
||||
* @return {Promise<boolean>} Success.
|
||||
*/
|
||||
public abstract createAgreementFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
): Promise<boolean>
|
||||
|
||||
public abstract async getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate>
|
||||
|
||||
public async getServiceAgreementTemplateConditions() {
|
||||
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
||||
return serviceAgreementTemplate.conditions
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplateConditionByRef(ref: string) {
|
||||
const name = (await this.getServiceAgreementTemplateConditions()).find(
|
||||
({ name: conditionRef }) => conditionRef === ref
|
||||
).contractName
|
||||
return (await this.getConditions()).find(
|
||||
condition => condition.contractName === name
|
||||
)
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplateDependencies() {
|
||||
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
||||
return serviceAgreementTemplate.conditionDependency
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the conditions.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @return {Promise} Conditions status.
|
||||
*/
|
||||
public async getAgreementStatus(
|
||||
agreementId: string
|
||||
): Promise<AgreementConditionsStatus | false> {
|
||||
const agreementStore = this.ocean.keeper.agreementStoreManager
|
||||
const conditionStore = this.ocean.keeper.conditionStoreManager
|
||||
|
||||
const dependencies = await this.getServiceAgreementTemplateDependencies()
|
||||
const { conditionIds } = await agreementStore.getAgreement(agreementId)
|
||||
|
||||
if (!conditionIds.length) {
|
||||
this.logger.error(`Agreement not creeated yet: "${agreementId}"`)
|
||||
return false
|
||||
}
|
||||
|
||||
const conditionIdByConddition = (await this.getConditions()).reduce(
|
||||
(acc, { contractName }, i) => ({
|
||||
...acc,
|
||||
[contractName]: conditionIds[i]
|
||||
}),
|
||||
{}
|
||||
)
|
||||
|
||||
const statesPromises = Object.keys(dependencies).map(async (ref, i) => {
|
||||
const { contractName } = await this.getServiceAgreementTemplateConditionByRef(
|
||||
ref
|
||||
)
|
||||
return {
|
||||
ref,
|
||||
contractName,
|
||||
state: (
|
||||
await conditionStore.getCondition(
|
||||
conditionIdByConddition[contractName]
|
||||
)
|
||||
).state
|
||||
}
|
||||
})
|
||||
const states = await Promise.all(statesPromises)
|
||||
|
||||
return states.reduce((acc, { contractName, ref, state }) => {
|
||||
const blockers = dependencies[ref]
|
||||
.map(dependency => states.find(_ => _.ref === dependency))
|
||||
.filter(condition => condition.state !== ConditionState.Fulfilled)
|
||||
return {
|
||||
...acc,
|
||||
[ref]: {
|
||||
condition: ref,
|
||||
contractName,
|
||||
state,
|
||||
blocked: !!blockers.length,
|
||||
blockedBy: blockers.map(_ => _.ref)
|
||||
}
|
||||
}
|
||||
}, {})
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the agreement status.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
*/
|
||||
public async printAgreementStatus(agreementId: string) {
|
||||
const status = await this.getAgreementStatus(agreementId)
|
||||
|
||||
this.logger.bypass('-'.repeat(80))
|
||||
this.logger.bypass('Template:', this.contractName)
|
||||
this.logger.bypass('Agreement ID:', agreementId)
|
||||
this.logger.bypass('-'.repeat(40))
|
||||
if (!status) {
|
||||
this.logger.bypass('Agreement not created yet!')
|
||||
}
|
||||
Object.values(status || []).forEach(
|
||||
({ condition, contractName, state, blocked, blockedBy }, i) => {
|
||||
if (i) {
|
||||
this.logger.bypass('-'.repeat(20))
|
||||
}
|
||||
this.logger.bypass(`${condition} (${contractName})`)
|
||||
this.logger.bypass(' Status:', state, `(${conditionStateNames[state]})`)
|
||||
if (blocked) {
|
||||
this.logger.bypass(' Blocked by:', blockedBy)
|
||||
}
|
||||
}
|
||||
)
|
||||
this.logger.bypass('-'.repeat(80))
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and returns the agreement creation event.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @return {Event} Agreement created event.
|
||||
*/
|
||||
public getAgreementCreatedEvent(agreementId: string) {
|
||||
return this.getEvent('AgreementCreated', {
|
||||
agreementId: zeroX(agreementId)
|
||||
})
|
||||
}
|
||||
}
|
314
src/keeper/contracts/templates/AgreementTemplateBase.ts
Normal file
314
src/keeper/contracts/templates/AgreementTemplateBase.ts
Normal file
@ -0,0 +1,314 @@
|
||||
import {
|
||||
TemplateStoreManager,
|
||||
AgreementStoreManager,
|
||||
ConditionStoreManager
|
||||
} from '../managers'
|
||||
import DIDRegistry from '../DIDRegistry'
|
||||
import { LockRewardCondition } from '../conditions/LockRewardCondition'
|
||||
import { AccessSecretStoreCondition } from '../conditions/AccessSecretStoreCondition'
|
||||
import { EscrowReward } from '../conditions/EscrowReward'
|
||||
import { DDO } from '../../../ddo/DDO'
|
||||
import { generateId, LoggerInstance, Logger, zeroX } from '../../../utils'
|
||||
|
||||
import {
|
||||
ComputeExecutionCondition,
|
||||
Condition,
|
||||
ConditionState,
|
||||
conditionStateNames
|
||||
} from '../conditions'
|
||||
import { ServiceType } from '../../../ddo/Service'
|
||||
|
||||
export interface Conditions {
|
||||
lockRewardCondition: LockRewardCondition
|
||||
accessSecretStoreCondition?: AccessSecretStoreCondition
|
||||
computeExecutionCondition?: ComputeExecutionCondition
|
||||
escrowReward: EscrowReward
|
||||
}
|
||||
|
||||
export interface AgreementConditionsStatus {
|
||||
[condition: string]: {
|
||||
condition: string
|
||||
contractName: string
|
||||
state: ConditionState
|
||||
blocked: boolean
|
||||
blockedBy: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export class AgreementTemplateBase {
|
||||
public templateName: string
|
||||
|
||||
public templateManager: TemplateStoreManager
|
||||
|
||||
public agreementStoreManager: AgreementStoreManager
|
||||
|
||||
public didRegistry: DIDRegistry
|
||||
|
||||
public conditions: Conditions
|
||||
|
||||
private logger: Logger
|
||||
|
||||
public constructor(
|
||||
templateManager: TemplateStoreManager,
|
||||
agreementStoreManager: AgreementStoreManager,
|
||||
didRegistry: DIDRegistry,
|
||||
conditions: Conditions
|
||||
) {
|
||||
this.templateManager = templateManager
|
||||
this.agreementStoreManager = agreementStoreManager
|
||||
this.didRegistry = didRegistry
|
||||
this.conditions = conditions
|
||||
|
||||
this.logger = LoggerInstance
|
||||
this.templateName = 'invalid'
|
||||
}
|
||||
|
||||
public async createAgreementFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
serviceType: ServiceType,
|
||||
consumer: string,
|
||||
provider: string,
|
||||
from?: string
|
||||
) {
|
||||
return !!(await this.createFullAgreement(
|
||||
ddo.shortId(),
|
||||
ddo.findServiceByType(serviceType).attributes.main.price,
|
||||
consumer,
|
||||
provider,
|
||||
from,
|
||||
agreementId
|
||||
))
|
||||
}
|
||||
|
||||
public async getConditionIdsFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
) {
|
||||
return this.createFullAgreementData(
|
||||
agreementId,
|
||||
ddo.shortId(),
|
||||
ddo.findServiceByType('metadata').attributes.main.price,
|
||||
consumer
|
||||
)
|
||||
}
|
||||
|
||||
public getName() {
|
||||
return this.templateName
|
||||
}
|
||||
|
||||
public getId() {
|
||||
return this.templateManager.generateId(this.getName())
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a agreement using EscrowAccessSecretStoreTemplate using only the most important information.
|
||||
* @param {string} did Asset DID.
|
||||
* @param {number} amount Asset price.
|
||||
* @param {string} consumer ethereum address of consumer.
|
||||
* @param {string} provider ethereum address of service provider (brizo address)
|
||||
* @param {string} from Consumer address.
|
||||
* @param {string} agreementId bytes32 agreement id.
|
||||
*
|
||||
* @return {Promise<string>} Agreement ID.
|
||||
*/
|
||||
public async createFullAgreement(
|
||||
did: string,
|
||||
amount: number | string,
|
||||
consumer: string,
|
||||
provider: string,
|
||||
from?: string,
|
||||
agreementId: string = generateId()
|
||||
): Promise<string> {
|
||||
const conditionIds = await this.createFullAgreementData(
|
||||
agreementId,
|
||||
did,
|
||||
amount,
|
||||
consumer
|
||||
)
|
||||
|
||||
const timeouts = [0, 0, 0]
|
||||
const timelocks = [0, 0, 0]
|
||||
await this.agreementStoreManager.createAgreement(
|
||||
agreementId,
|
||||
did,
|
||||
this.getId(),
|
||||
conditionIds,
|
||||
timelocks,
|
||||
timeouts,
|
||||
[consumer, provider],
|
||||
from
|
||||
)
|
||||
return zeroX(agreementId)
|
||||
}
|
||||
|
||||
protected async createFullAgreementData(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
amount: number | string,
|
||||
consumer: string
|
||||
): Promise<string[]> {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditions address list.
|
||||
* @return {Promise<string[]>} Conditions address.
|
||||
*/
|
||||
public async getConditionTypes(): Promise<string[]> {
|
||||
return this.templateManager.getConditionTypes(this.getId())
|
||||
}
|
||||
|
||||
/**
|
||||
* List of condition contracts.
|
||||
* @return {Promise<Condition[]>} Conditions contracts.
|
||||
*/
|
||||
public async getConditions(): Promise<Condition[]> {
|
||||
return this.templateManager.getConditions(await this.getConditionTypes())
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplate() {
|
||||
return null
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplateConditions() {
|
||||
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
||||
return serviceAgreementTemplate.conditions
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplateConditionByRef(ref: string) {
|
||||
const name = (await this.getServiceAgreementTemplateConditions()).find(
|
||||
({ name: conditionRef }) => conditionRef === ref
|
||||
).contractName
|
||||
return (await this.getConditions()).find(
|
||||
condition => condition.contractName === name
|
||||
)
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplateDependencies() {
|
||||
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
||||
return serviceAgreementTemplate.conditionDependency
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the conditions.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @param {ConditionStoreManager} conditionStoreManager
|
||||
* @return {Promise} Conditions status.
|
||||
*/
|
||||
public async getAgreementStatus(
|
||||
agreementId: string,
|
||||
conditionStoreManager: ConditionStoreManager
|
||||
): Promise<AgreementConditionsStatus | false> {
|
||||
const dependencies = await this.getServiceAgreementTemplateDependencies()
|
||||
const { conditionIds } = await this.agreementStoreManager.getAgreement(
|
||||
agreementId
|
||||
)
|
||||
if (!conditionIds.length) {
|
||||
// this.logger.error(`Agreement not creeated yet: "${agreementId}"`)
|
||||
return false
|
||||
}
|
||||
|
||||
const conditionIdByCondition = (await this.getConditions()).reduce(
|
||||
(acc, { contractName }, i) => ({
|
||||
...acc,
|
||||
[contractName]: conditionIds[i]
|
||||
}),
|
||||
{}
|
||||
)
|
||||
|
||||
const statesPromises = Object.keys(dependencies).map(async (ref, i) => {
|
||||
const { contractName } = await this.getServiceAgreementTemplateConditionByRef(
|
||||
ref
|
||||
)
|
||||
return {
|
||||
ref,
|
||||
contractName,
|
||||
state: (
|
||||
await conditionStoreManager.getCondition(
|
||||
conditionIdByCondition[contractName]
|
||||
)
|
||||
).state
|
||||
}
|
||||
})
|
||||
const states = await Promise.all(statesPromises)
|
||||
|
||||
return states.reduce((acc, { contractName, ref, state }) => {
|
||||
const blockers = dependencies[ref]
|
||||
.map(dependency => states.find(_ => _.ref === dependency))
|
||||
.filter(condition => condition.state !== ConditionState.Fulfilled)
|
||||
return {
|
||||
...acc,
|
||||
[ref]: {
|
||||
condition: ref,
|
||||
contractName,
|
||||
state,
|
||||
blocked: !!blockers.length,
|
||||
blockedBy: blockers.map(_ => _.ref)
|
||||
}
|
||||
}
|
||||
}, {})
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the agreement status.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @param {ConditionStoreManager} conditionStoreManager
|
||||
*/
|
||||
public async printAgreementStatus(
|
||||
agreementId: string,
|
||||
conditionStoreManager: ConditionStoreManager
|
||||
) {
|
||||
const status = await this.getAgreementStatus(agreementId, conditionStoreManager)
|
||||
|
||||
this.logger.bypass('-'.repeat(80))
|
||||
this.logger.bypass('Template:', this.templateName)
|
||||
this.logger.bypass('Agreement ID:', agreementId)
|
||||
this.logger.bypass('-'.repeat(40))
|
||||
if (!status) {
|
||||
this.logger.bypass('Agreement not created yet!')
|
||||
}
|
||||
Object.values(status || []).forEach(
|
||||
({ condition, contractName, state, blocked, blockedBy }, i) => {
|
||||
if (i) {
|
||||
this.logger.bypass('-'.repeat(20))
|
||||
}
|
||||
this.logger.bypass(`${condition} (${contractName})`)
|
||||
this.logger.bypass(' Status:', state, `(${conditionStateNames[state]})`)
|
||||
if (blocked) {
|
||||
this.logger.bypass(' Blocked by:', blockedBy)
|
||||
}
|
||||
}
|
||||
)
|
||||
this.logger.bypass('-'.repeat(80))
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and returns the agreement creation event.
|
||||
* @param {string} agreementId Agreement ID.
|
||||
* @return {Event} Agreement created event.
|
||||
*/
|
||||
public getAgreementCreatedEvent(agreementId: string) {
|
||||
return this.agreementStoreManager.getAgreementCreatedEvent(agreementId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return actor type ids for this template (specified by subclass)
|
||||
*
|
||||
*/
|
||||
public async getActorTypeIds() {
|
||||
const { actorTypeIds } = await this.templateManager.getTemplate(this.getId())
|
||||
return actorTypeIds
|
||||
}
|
||||
|
||||
/**
|
||||
* Return actor types (strings) for this template (specified by subclass)
|
||||
*
|
||||
*/
|
||||
public async getActorTypes() {
|
||||
const actorTypeIds = await this.getActorTypeIds()
|
||||
return actorTypeIds.map(typeId => this.templateManager.getActorTypeValue(typeId))
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
import { AgreementTemplate } from './AgreementTemplate.abstract'
|
||||
import { DDO } from '../../../ddo/DDO'
|
||||
import { generateId, zeroX } from '../../../utils'
|
||||
import { InstantiableConfig } from '../../../Instantiable.abstract'
|
||||
|
||||
// import { EscrowComputeExecutionTemplateServiceAgreementTemplate } from './EscrowComputeExecutionTemplate.serviceAgreementTemplate'
|
||||
|
||||
export abstract class BaseEscrowTemplate extends AgreementTemplate {
|
||||
/**
|
||||
* Create a agreement using EscrowComputeExecutionTemplate.
|
||||
* @param {string} agreementId Generated agreement ID.
|
||||
* @param {string} did Asset DID.
|
||||
* @param {string[]} conditionIds List of conditions IDs.
|
||||
* @param {number[]} timeLocks Timelocks.
|
||||
* @param {number[]} timeOuts Timeouts.
|
||||
* @param {string} accessConsumer Consumer address.
|
||||
* @param {string} from Action sender.
|
||||
* @param {any} Transaction receipt.
|
||||
*/
|
||||
public createAgreement(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
conditionIds: string[],
|
||||
timeLocks: number[],
|
||||
timeOuts: number[],
|
||||
accessConsumer: string,
|
||||
from?: string
|
||||
) {
|
||||
return super.createAgreement(
|
||||
agreementId,
|
||||
did,
|
||||
conditionIds,
|
||||
timeLocks,
|
||||
timeOuts,
|
||||
[accessConsumer],
|
||||
from
|
||||
)
|
||||
}
|
||||
|
||||
public async getAgreementData(agreementId: string) {
|
||||
return this.call<any>('getAgreementData', [zeroX(agreementId)])
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
|
||||
|
||||
export const escrowAccessSecretStoreTemplateServiceAgreementTemplate: ServiceAgreementTemplate = {
|
||||
export const escrowAccessServiceAgreementTemplate: ServiceAgreementTemplate = {
|
||||
contractName: 'EscrowAccessSecretStoreTemplate',
|
||||
events: [
|
||||
{
|
@ -1,113 +1,40 @@
|
||||
import { AgreementTemplate } from './AgreementTemplate.abstract'
|
||||
import { BaseEscrowTemplate } from './BaseEscrowTemplate.abstract'
|
||||
import { DDO } from '../../../ddo/DDO'
|
||||
import { generateId, zeroX } from '../../../utils'
|
||||
import { InstantiableConfig } from '../../../Instantiable.abstract'
|
||||
import { AgreementTemplateBase, Conditions } from './AgreementTemplateBase'
|
||||
import { escrowAccessServiceAgreementTemplate } from './EscrowAccess.serviceAgreementTemplate'
|
||||
import { AgreementStoreManager, TemplateStoreManager } from '../managers'
|
||||
import DIDRegistry from '../DIDRegistry'
|
||||
|
||||
import { escrowAccessSecretStoreTemplateServiceAgreementTemplate } from './EscrowAccessSecretStoreTemplate.serviceAgreementTemplate'
|
||||
|
||||
export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate {
|
||||
public static async getInstance(
|
||||
config: InstantiableConfig
|
||||
): Promise<EscrowAccessSecretStoreTemplate> {
|
||||
return AgreementTemplate.getInstance(
|
||||
config,
|
||||
'EscrowAccessSecretStoreTemplate',
|
||||
EscrowAccessSecretStoreTemplate
|
||||
)
|
||||
export class EscrowAccessSecretStoreTemplate extends AgreementTemplateBase {
|
||||
public constructor(
|
||||
templateManager: TemplateStoreManager,
|
||||
agreementStoreManager: AgreementStoreManager,
|
||||
didRegistry: DIDRegistry,
|
||||
conditions: Conditions
|
||||
) {
|
||||
super(templateManager, agreementStoreManager, didRegistry, conditions)
|
||||
this.templateName = 'EscrowAccessSecretStoreTemplate'
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplate() {
|
||||
return escrowAccessSecretStoreTemplateServiceAgreementTemplate
|
||||
return escrowAccessServiceAgreementTemplate
|
||||
}
|
||||
|
||||
public async createAgreementFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
) {
|
||||
return !!(await this.createFullAgreement(
|
||||
ddo.shortId(),
|
||||
ddo.findServiceByType('metadata').attributes.main.price,
|
||||
consumer,
|
||||
from,
|
||||
agreementId
|
||||
))
|
||||
}
|
||||
|
||||
public async getAgreementIdsFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
) {
|
||||
const {
|
||||
accessSecretStoreConditionId,
|
||||
lockRewardConditionId,
|
||||
escrowRewardId
|
||||
} = await this.createFullAgreementData(
|
||||
agreementId,
|
||||
ddo.shortId(),
|
||||
ddo.findServiceByType('metadata').attributes.main.price,
|
||||
consumer
|
||||
)
|
||||
return [accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId]
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a agreement using EscrowAccessSecretStoreTemplate using only the most important information.
|
||||
* @param {string} did Asset DID.
|
||||
* @param {number} amount Asset price.
|
||||
* @param {string} from Consumer address.
|
||||
* @return {Promise<string>} Agreement ID.
|
||||
*/
|
||||
public async createFullAgreement(
|
||||
did: string,
|
||||
amount: number | string,
|
||||
consumer: string,
|
||||
from?: string,
|
||||
agreementId: string = generateId()
|
||||
): Promise<string> {
|
||||
const {
|
||||
accessSecretStoreConditionId,
|
||||
lockRewardConditionId,
|
||||
escrowRewardId
|
||||
} = await this.createFullAgreementData(agreementId, did, amount, consumer)
|
||||
|
||||
await this.createAgreement(
|
||||
agreementId,
|
||||
did,
|
||||
[accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
consumer,
|
||||
from
|
||||
)
|
||||
|
||||
return zeroX(agreementId)
|
||||
}
|
||||
|
||||
private async createFullAgreementData(
|
||||
protected async createFullAgreementData(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
amount: number | string,
|
||||
consumer: string
|
||||
) {
|
||||
const { didRegistry, conditions } = this.ocean.keeper
|
||||
|
||||
const {
|
||||
accessSecretStoreCondition,
|
||||
lockRewardCondition,
|
||||
accessSecretStoreCondition,
|
||||
escrowReward
|
||||
} = conditions
|
||||
|
||||
const publisher = await didRegistry.getDIDOwner(did)
|
||||
} = this.conditions
|
||||
|
||||
const publisher = await this.didRegistry.getDIDOwner(did)
|
||||
const lockRewardConditionId = await lockRewardCondition.generateIdHash(
|
||||
agreementId,
|
||||
await escrowReward.getAddress(),
|
||||
amount
|
||||
String(amount)
|
||||
)
|
||||
const accessSecretStoreConditionId = await accessSecretStoreCondition.generateIdHash(
|
||||
agreementId,
|
||||
@ -122,11 +49,6 @@ export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate {
|
||||
lockRewardConditionId,
|
||||
accessSecretStoreConditionId
|
||||
)
|
||||
|
||||
return {
|
||||
lockRewardConditionId,
|
||||
accessSecretStoreConditionId,
|
||||
escrowRewardId
|
||||
}
|
||||
return [lockRewardConditionId, accessSecretStoreConditionId, escrowRewardId]
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
|
||||
|
||||
export const escrowComputeExecutionTemplateServiceAgreementTemplate: ServiceAgreementTemplate = {
|
||||
export const escrowComputeServiceAgreementTemplate: ServiceAgreementTemplate = {
|
||||
contractName: 'EscrowComputeExecutionTemplate',
|
||||
events: [
|
||||
{
|
@ -1,108 +1,36 @@
|
||||
import { AgreementTemplate } from './AgreementTemplate.abstract'
|
||||
import { BaseEscrowTemplate } from './BaseEscrowTemplate.abstract'
|
||||
import { DDO } from '../../../ddo/DDO'
|
||||
import { generateId, zeroX } from '../../../utils'
|
||||
import { InstantiableConfig } from '../../../Instantiable.abstract'
|
||||
import { AgreementTemplateBase, Conditions } from './AgreementTemplateBase'
|
||||
import { escrowComputeServiceAgreementTemplate } from './EscrowCompute.serviceAgreementTemplate'
|
||||
import { AgreementStoreManager, TemplateStoreManager } from '../managers'
|
||||
import DIDRegistry from '../DIDRegistry'
|
||||
|
||||
import { escrowComputeExecutionTemplateServiceAgreementTemplate } from './EscrowComputeExecutionTemplate.serviceAgreementTemplate'
|
||||
|
||||
export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate {
|
||||
public static async getInstance(
|
||||
config: InstantiableConfig
|
||||
): Promise<EscrowComputeExecutionTemplate> {
|
||||
return AgreementTemplate.getInstance(
|
||||
config,
|
||||
'EscrowComputeExecutionTemplate',
|
||||
EscrowComputeExecutionTemplate
|
||||
)
|
||||
export class EscrowComputeExecutionTemplate extends AgreementTemplateBase {
|
||||
public constructor(
|
||||
templateManager: TemplateStoreManager,
|
||||
agreementStoreManager: AgreementStoreManager,
|
||||
didRegistry: DIDRegistry,
|
||||
conditions: Conditions
|
||||
) {
|
||||
super(templateManager, agreementStoreManager, didRegistry, conditions)
|
||||
this.templateName = 'EscrowComputeExecutionTemplate'
|
||||
}
|
||||
|
||||
public async getServiceAgreementTemplate() {
|
||||
return escrowComputeExecutionTemplateServiceAgreementTemplate
|
||||
return escrowComputeServiceAgreementTemplate
|
||||
}
|
||||
|
||||
public async createAgreementFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
) {
|
||||
return !!(await this.createFullAgreement(
|
||||
ddo.shortId(),
|
||||
ddo.findServiceByType('metadata').attributes.main.price,
|
||||
consumer,
|
||||
from,
|
||||
agreementId
|
||||
))
|
||||
}
|
||||
|
||||
public async getAgreementIdsFromDDO(
|
||||
agreementId: string,
|
||||
ddo: DDO,
|
||||
consumer: string,
|
||||
from?: string
|
||||
) {
|
||||
const {
|
||||
computeExecutionConditionId,
|
||||
lockRewardConditionId,
|
||||
escrowRewardId
|
||||
} = await this.createFullAgreementData(
|
||||
agreementId,
|
||||
ddo.shortId(),
|
||||
ddo.findServiceByType('metadata').attributes.main.price,
|
||||
consumer
|
||||
)
|
||||
return [computeExecutionConditionId, lockRewardConditionId, escrowRewardId]
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a agreement using EscrowAccess____SecretStoreTemplate using only the most important information.
|
||||
* @param {string} did Asset DID.
|
||||
* @param {number} amount Asset price.
|
||||
* @param {string} from Consumer address.
|
||||
* @return {Promise<string>} Agreement ID.
|
||||
*/
|
||||
public async createFullAgreement(
|
||||
did: string,
|
||||
amount: number | string,
|
||||
consumer: string,
|
||||
from?: string,
|
||||
agreementId: string = generateId()
|
||||
): Promise<string> {
|
||||
const {
|
||||
computeExecutionConditionId,
|
||||
lockRewardConditionId,
|
||||
escrowRewardId
|
||||
} = await this.createFullAgreementData(agreementId, did, amount, consumer)
|
||||
|
||||
await this.createAgreement(
|
||||
agreementId,
|
||||
did,
|
||||
[computeExecutionConditionId, lockRewardConditionId, escrowRewardId],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
consumer,
|
||||
from
|
||||
)
|
||||
|
||||
return zeroX(agreementId)
|
||||
}
|
||||
|
||||
private async createFullAgreementData(
|
||||
protected async createFullAgreementData(
|
||||
agreementId: string,
|
||||
did: string,
|
||||
amount: number | string,
|
||||
consumer: string
|
||||
) {
|
||||
const { didRegistry, conditions } = this.ocean.keeper
|
||||
|
||||
const {
|
||||
computeExecutionCondition,
|
||||
lockRewardCondition,
|
||||
computeExecutionCondition,
|
||||
escrowReward
|
||||
} = conditions
|
||||
} = this.conditions
|
||||
|
||||
const publisher = await didRegistry.getDIDOwner(did)
|
||||
const publisher = await this.didRegistry.getDIDOwner(did)
|
||||
|
||||
const lockRewardConditionId = await lockRewardCondition.generateIdHash(
|
||||
agreementId,
|
||||
@ -122,11 +50,6 @@ export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate {
|
||||
lockRewardConditionId,
|
||||
computeExecutionConditionId
|
||||
)
|
||||
|
||||
return {
|
||||
lockRewardConditionId,
|
||||
computeExecutionConditionId,
|
||||
escrowRewardId
|
||||
}
|
||||
return [lockRewardConditionId, computeExecutionConditionId, escrowRewardId]
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
export * from './AgreementTemplate.abstract'
|
||||
export { BaseEscrowTemplate } from './BaseEscrowTemplate.abstract'
|
||||
export * from './AgreementTemplateBase'
|
||||
export { EscrowAccessSecretStoreTemplate } from './EscrowAccessSecretStoreTemplate'
|
||||
export { EscrowComputeExecutionTemplate } from './EscrowComputeExecutionTemplate'
|
||||
|
@ -38,10 +38,14 @@ export class Ocean extends Instantiable {
|
||||
}
|
||||
instance.setInstanceConfig(instanceConfig)
|
||||
|
||||
instance.utils = await OceanUtils.getInstance(instanceConfig)
|
||||
instance.keeper = await Keeper.getInstance(instanceConfig)
|
||||
|
||||
instance.brizo = new Brizo(instanceConfig)
|
||||
instance.aquarius = new Aquarius(instanceConfig)
|
||||
instance.aquarius = new Aquarius(
|
||||
instanceConfig.config.aquariusUri,
|
||||
instanceConfig.logger
|
||||
)
|
||||
|
||||
instance.accounts = await OceanAccounts.getInstance(instanceConfig)
|
||||
instance.auth = await OceanAuth.getInstance(instanceConfig)
|
||||
@ -52,8 +56,6 @@ export class Ocean extends Instantiable {
|
||||
instance.tokens = await OceanTokens.getInstance(instanceConfig)
|
||||
instance.versions = await OceanVersions.getInstance(instanceConfig)
|
||||
|
||||
instance.utils = await OceanUtils.getInstance(instanceConfig)
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ import Account from './Account'
|
||||
import DID from './DID'
|
||||
import { zeroX, didPrefixed } from '../utils'
|
||||
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||
import { AgreementConditionsStatus } from '../keeper/contracts/templates/AgreementTemplate.abstract'
|
||||
import { AgreementConditionsStatus } from '../keeper/contracts/templates/AgreementTemplateBase'
|
||||
import { ConditionState } from '../keeper/contracts/conditions/Condition.abstract'
|
||||
|
||||
import { OceanAgreementsConditions } from './OceanAgreementsConditions'
|
||||
@ -57,7 +57,7 @@ export class OceanAgreements extends Instantiable {
|
||||
.serviceAgreementTemplate.contractName
|
||||
const agreementConditionsIds = await this.ocean.keeper
|
||||
.getTemplateByName(templateName)
|
||||
.getAgreementIdsFromDDO(agreementId, ddo, consumer.getId(), consumer.getId())
|
||||
.getConditionIdsFromDDO(agreementId, ddo, consumer.getId(), consumer.getId())
|
||||
|
||||
const signature = await this.ocean.utils.agreements.signServiceAgreement(
|
||||
ddo,
|
||||
@ -106,7 +106,8 @@ export class OceanAgreements extends Instantiable {
|
||||
* @param {number} index Service index.
|
||||
* @param {string} signature Service agreement signature.
|
||||
* @param {Account} consumer Consumer account.
|
||||
* @param {Account} publisher Publisher account.
|
||||
* @param {string} provider ethereum address of service provider
|
||||
* @param {Account} from account of party creating the agreement (usually the consumer).
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
public async create(
|
||||
@ -115,18 +116,23 @@ export class OceanAgreements extends Instantiable {
|
||||
index: number,
|
||||
signature: string,
|
||||
consumer: Account,
|
||||
publisher: Account
|
||||
provider: string,
|
||||
from: Account
|
||||
) {
|
||||
const d: DID = DID.parse(did)
|
||||
const ddo = await this.ocean.aquarius.retrieveDDO(d)
|
||||
|
||||
const templateName = ddo.findServiceById<'access'>(index).attributes
|
||||
.serviceAgreementTemplate.contractName
|
||||
await this.ocean.keeper
|
||||
const service = ddo.findServiceById(index)
|
||||
const templateName = service.attributes.serviceAgreementTemplate.contractName
|
||||
return this.ocean.keeper
|
||||
.getTemplateByName(templateName)
|
||||
.createAgreementFromDDO(agreementId, ddo, consumer.getId(), publisher.getId())
|
||||
|
||||
return true
|
||||
.createAgreementFromDDO(
|
||||
agreementId,
|
||||
ddo,
|
||||
service.type,
|
||||
consumer.getId(),
|
||||
provider,
|
||||
from.getId()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,9 +155,17 @@ export class OceanAgreements extends Instantiable {
|
||||
const { templateId } = await this.ocean.keeper.agreementStoreManager.getAgreement(
|
||||
agreementId
|
||||
)
|
||||
|
||||
if (templateId === `0x${'0'.repeat(64)}`) {
|
||||
this.logger.error(
|
||||
`agreement ${agreementId} is not found, templateId is ${templateId}`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const fullStatus = await this.ocean.keeper
|
||||
.getTemplateByAddress(templateId)
|
||||
.getAgreementStatus(agreementId)
|
||||
.getTemplateById(templateId)
|
||||
.getAgreementStatus(agreementId, this.ocean.keeper.conditionStoreManager)
|
||||
|
||||
if (!fullStatus) {
|
||||
return
|
||||
|
@ -56,7 +56,8 @@ export class OceanAssets extends Instantiable {
|
||||
/**
|
||||
* Creates a new DDO.
|
||||
* @param {MetaData} metadata DDO metadata.
|
||||
* @param {Account} publisher Publisher account.
|
||||
* @param {Account} publisher Publisher account.
|
||||
* @param {list} services list of Service description documents
|
||||
* @return {Promise<DDO>}
|
||||
*/
|
||||
public create(
|
||||
@ -106,7 +107,7 @@ export class OceanAssets extends Instantiable {
|
||||
{
|
||||
type: 'access',
|
||||
serviceEndpoint: this.ocean.brizo.getConsumeEndpoint(),
|
||||
templateId: templates.escrowAccessSecretStoreTemplate.getAddress(),
|
||||
templateId: templates.escrowAccessSecretStoreTemplate.getId(),
|
||||
attributes: {
|
||||
main: {
|
||||
creator: publisher.getId(),
|
||||
@ -285,12 +286,14 @@ export class OceanAssets extends Instantiable {
|
||||
* @param {string} did Decentralized ID.
|
||||
* @param {number} index Service index.
|
||||
* @param {Account} consumerAccount Consumer account.
|
||||
* @param {string} provider ethereum address of service provider (optional)
|
||||
* @return {Promise<string>} Returns Agreement ID
|
||||
*/
|
||||
public order(
|
||||
did: string,
|
||||
index: number,
|
||||
consumerAccount: Account
|
||||
provider?: string
|
||||
): SubscribablePromise<OrderProgressStep, string> {
|
||||
return new SubscribablePromise(async observer => {
|
||||
const oceanAgreements = this.ocean.agreements
|
||||
@ -344,12 +347,23 @@ export class OceanAssets extends Instantiable {
|
||||
|
||||
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,
|
||||
consumerAccount,
|
||||
_provider,
|
||||
consumerAccount
|
||||
)
|
||||
this.logger.log('Agreement created')
|
||||
|
@ -16,9 +16,13 @@ export class OceanUtils extends Instantiable {
|
||||
const instance = new OceanUtils()
|
||||
instance.setInstanceConfig(config)
|
||||
|
||||
instance.agreements = new ServiceAgreement(config)
|
||||
instance.signature = new SignatureUtils(config)
|
||||
instance.fetch = new WebServiceConnector(config)
|
||||
instance.agreements = new ServiceAgreement(
|
||||
config.ocean,
|
||||
config.logger,
|
||||
config.web3
|
||||
)
|
||||
instance.signature = new SignatureUtils(config.web3, config.logger)
|
||||
instance.fetch = new WebServiceConnector(config.logger)
|
||||
|
||||
return instance
|
||||
}
|
||||
|
@ -2,13 +2,18 @@ import { ServiceAgreementTemplateCondition } from '../../ddo/ServiceAgreementTem
|
||||
import { DDO } from '../../ddo/DDO'
|
||||
import { ServiceAccess } from '../../ddo/Service'
|
||||
import Account from '../Account'
|
||||
import { zeroX } from '../../utils'
|
||||
import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract'
|
||||
import { zeroX, Logger } from '../../utils'
|
||||
import { Ocean } from '../../squid'
|
||||
import Web3 from 'web3'
|
||||
|
||||
export class ServiceAgreement extends Instantiable {
|
||||
constructor(config: InstantiableConfig) {
|
||||
super()
|
||||
this.setInstanceConfig(config)
|
||||
export class ServiceAgreement {
|
||||
private ocean: Ocean
|
||||
private logger: Logger
|
||||
private web3: Web3
|
||||
constructor(ocean: Ocean, logger: Logger, web3: Web3) {
|
||||
this.ocean = ocean
|
||||
this.logger = logger
|
||||
this.web3 = web3
|
||||
}
|
||||
|
||||
public async signServiceAgreement(
|
||||
@ -76,7 +81,7 @@ export class ServiceAgreement extends Instantiable {
|
||||
timeouts: number[]
|
||||
): string {
|
||||
const args: any = [
|
||||
{ type: 'address', value: zeroX(serviceAgreementTemplateId) },
|
||||
{ type: 'bytes32', value: zeroX(serviceAgreementTemplateId) },
|
||||
{ type: 'bytes32[]', value: valueHashes.map(zeroX) },
|
||||
{ type: 'uint256[]', value: timelocks },
|
||||
{ type: 'uint256[]', value: timeouts },
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract'
|
||||
import Web3 from 'web3'
|
||||
import { Logger } from '../../utils'
|
||||
|
||||
export class SignatureUtils extends Instantiable {
|
||||
constructor(config: InstantiableConfig) {
|
||||
super()
|
||||
this.setInstanceConfig(config)
|
||||
export class SignatureUtils {
|
||||
private web3: Web3
|
||||
private logger: Logger
|
||||
|
||||
constructor(web3: Web3, logger: Logger) {
|
||||
this.web3 = web3
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
public async signText(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BodyInit, RequestInit, Response } from 'node-fetch'
|
||||
import fs from 'fs'
|
||||
import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract'
|
||||
import { Logger } from '../../utils'
|
||||
|
||||
const fetch = require('node-fetch')
|
||||
import save = require('save-file')
|
||||
@ -8,10 +8,10 @@ import save = require('save-file')
|
||||
/**
|
||||
* Provides a common interface to web services.
|
||||
*/
|
||||
export class WebServiceConnector extends Instantiable {
|
||||
constructor(config: InstantiableConfig) {
|
||||
super()
|
||||
this.setInstanceConfig(config)
|
||||
export class WebServiceConnector {
|
||||
public logger: Logger
|
||||
constructor(logger: Logger) {
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
public post(url: string, payload: BodyInit): Promise<Response> {
|
||||
|
15
src/squid.ts
15
src/squid.ts
@ -4,6 +4,7 @@ import DID from './ocean/DID'
|
||||
import { Ocean } from './ocean/Ocean'
|
||||
import { LoggerInstance as Logger } from './utils/Logger'
|
||||
import Keeper from './keeper/Keeper'
|
||||
import { Aquarius } from './aquarius/Aquarius'
|
||||
|
||||
import * as templates from './keeper/contracts/templates'
|
||||
import * as conditions from './keeper/contracts/conditions'
|
||||
@ -21,7 +22,17 @@ export {
|
||||
OceanPlatformVersions
|
||||
} from './ocean/OceanVersions'
|
||||
|
||||
export { AgreementTemplate } from './keeper/contracts/templates'
|
||||
export { Condition, ConditionState } from './keeper/contracts/conditions'
|
||||
|
||||
export { Ocean, Account, Config, DID, Logger, Keeper, conditions, templates, utils }
|
||||
export {
|
||||
Ocean,
|
||||
Account,
|
||||
Config,
|
||||
DID,
|
||||
Logger,
|
||||
Keeper,
|
||||
Aquarius,
|
||||
conditions,
|
||||
templates,
|
||||
utils
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { Aquarius, SearchQuery } from '../../src/aquarius/Aquarius'
|
||||
import { DDO } from '../../src/ddo/DDO'
|
||||
import DID from '../../src/ocean/DID'
|
||||
import config from '../config'
|
||||
import { LoggerInstance } from '../../src/utils'
|
||||
|
||||
use(spies)
|
||||
|
||||
@ -53,7 +54,7 @@ describe('Aquarius', () => {
|
||||
} as SearchQuery
|
||||
|
||||
it('should query metadata', async () => {
|
||||
spy.on(ocean.utils.fetch, 'post', () => reponsify(getResults([new DDO()])))
|
||||
spy.on(aquarius.fetch, 'post', () => reponsify(getResults([new DDO()])))
|
||||
|
||||
const result = await aquarius.queryMetadata(query)
|
||||
assert.typeOf(result.results, 'array')
|
||||
@ -64,7 +65,7 @@ describe('Aquarius', () => {
|
||||
})
|
||||
|
||||
it('should query metadata and return real ddo', async () => {
|
||||
spy.on(ocean.utils.fetch, 'post', () => reponsify(getResults([new DDO()])))
|
||||
spy.on(aquarius.fetch, 'post', () => reponsify(getResults([new DDO()])))
|
||||
|
||||
const result = await aquarius.queryMetadata(query)
|
||||
assert.typeOf(result.results, 'array')
|
||||
@ -87,7 +88,7 @@ describe('Aquarius', () => {
|
||||
} as SearchQuery
|
||||
|
||||
it('should query metadata by text', async () => {
|
||||
spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()])))
|
||||
spy.on(aquarius.fetch, 'get', () => reponsify(getResults([new DDO()])))
|
||||
|
||||
const result = await aquarius.queryMetadataByText(query)
|
||||
assert.typeOf(result.results, 'array')
|
||||
@ -97,8 +98,20 @@ describe('Aquarius', () => {
|
||||
assert.equal(result.totalResults, 1)
|
||||
})
|
||||
|
||||
it('should query metadata by text with a new instance', async () => {
|
||||
const aquariusNew = new Aquarius(config.aquariusUri, LoggerInstance)
|
||||
spy.on(aquariusNew.fetch, 'get', () => reponsify(getResults([new DDO()])))
|
||||
|
||||
const result = await aquariusNew.queryMetadataByText(query)
|
||||
assert.typeOf(result.results, 'array')
|
||||
assert.lengthOf(result.results, 1)
|
||||
assert.equal(result.page, 0)
|
||||
assert.equal(result.totalPages, 1)
|
||||
assert.equal(result.totalResults, 1)
|
||||
})
|
||||
|
||||
it('should query metadata and return real ddo', async () => {
|
||||
spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()])))
|
||||
spy.on(aquarius.fetch, 'get', () => reponsify(getResults([new DDO()])))
|
||||
|
||||
const result = await aquarius.queryMetadataByText(query)
|
||||
assert.typeOf(result.results, 'array')
|
||||
@ -114,7 +127,7 @@ describe('Aquarius', () => {
|
||||
id: did.getId()
|
||||
})
|
||||
|
||||
spy.on(ocean.utils.fetch, 'post', () => reponsify(ddo))
|
||||
spy.on(aquarius.fetch, 'post', () => reponsify(ddo))
|
||||
|
||||
const result: DDO = await aquarius.storeDDO(ddo)
|
||||
assert(result)
|
||||
@ -129,8 +142,8 @@ describe('Aquarius', () => {
|
||||
id: did.getId()
|
||||
})
|
||||
|
||||
spy.on(ocean.utils.fetch, 'post', () => reponsify(ddo))
|
||||
spy.on(ocean.utils.fetch, 'get', () => reponsify(ddo))
|
||||
spy.on(aquarius.fetch, 'post', () => reponsify(ddo))
|
||||
spy.on(aquarius.fetch, 'get', () => reponsify(ddo))
|
||||
|
||||
const storageResult: DDO = await aquarius.storeDDO(ddo)
|
||||
assert(storageResult)
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { assert, expect, spy, use } from 'chai'
|
||||
import spies from 'chai-spies'
|
||||
import Web3 from 'web3'
|
||||
|
||||
import { DDO } from '../../src/ddo/DDO'
|
||||
import { Service } from '../../src/ddo/Service'
|
||||
@ -164,13 +163,11 @@ describe('DDO', () => {
|
||||
]
|
||||
})
|
||||
|
||||
let web3: Web3
|
||||
let ocean: Ocean
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestContractHandler.prepareContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
;({ web3 } = ocean as any)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -87,9 +87,8 @@ export default class TestContractHandler extends ContractHandler {
|
||||
didRegistry.options.address
|
||||
]
|
||||
)
|
||||
|
||||
// Conditions
|
||||
const lockRewardCondition = await TestContractHandler.deployContract(
|
||||
const lockCondition = await TestContractHandler.deployContract(
|
||||
'LockRewardCondition',
|
||||
deployerAddress,
|
||||
[
|
||||
@ -98,7 +97,7 @@ export default class TestContractHandler extends ContractHandler {
|
||||
token.options.address
|
||||
]
|
||||
)
|
||||
const accessSecretStoreCondition = await TestContractHandler.deployContract(
|
||||
const accessCondition = await TestContractHandler.deployContract(
|
||||
'AccessSecretStoreCondition',
|
||||
deployerAddress,
|
||||
[
|
||||
@ -107,9 +106,8 @@ export default class TestContractHandler extends ContractHandler {
|
||||
agreementStoreManager.options.address
|
||||
]
|
||||
)
|
||||
|
||||
// Conditions rewards
|
||||
const escrowReward = await TestContractHandler.deployContract(
|
||||
const escrowCondition = await TestContractHandler.deployContract(
|
||||
'EscrowReward',
|
||||
deployerAddress,
|
||||
[
|
||||
@ -118,20 +116,7 @@ export default class TestContractHandler extends ContractHandler {
|
||||
token.options.address
|
||||
]
|
||||
)
|
||||
|
||||
// Templates
|
||||
await TestContractHandler.deployContract(
|
||||
'EscrowAccessSecretStoreTemplate',
|
||||
deployerAddress,
|
||||
[
|
||||
deployerAddress,
|
||||
agreementStoreManager.options.address,
|
||||
didRegistry.options.address,
|
||||
accessSecretStoreCondition.options.address,
|
||||
lockRewardCondition.options.address,
|
||||
escrowReward.options.address
|
||||
]
|
||||
)
|
||||
Logger.log(lockCondition, accessCondition, escrowCondition)
|
||||
}
|
||||
|
||||
private static async deployContract(
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { assert } from 'chai'
|
||||
import { EscrowAccessSecretStoreTemplate } from '../../../src/keeper/contracts/templates'
|
||||
import config from '../../config'
|
||||
import TestContractHandler from '../TestContractHandler'
|
||||
import { Ocean } from '../../../src/ocean/Ocean'
|
||||
|
||||
let condition: EscrowAccessSecretStoreTemplate
|
||||
|
||||
describe('EscrowAccessSecretStoreTemplate', () => {
|
||||
before(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance(config)
|
||||
await TestContractHandler.prepareContracts()
|
||||
condition = ocean.keeper.templates.escrowAccessSecretStoreTemplate
|
||||
})
|
||||
|
||||
// describe("#hashValues()", () => {
|
||||
// it("should hash the values", async () => {
|
||||
// const address = `0x${"a".repeat(40)}`
|
||||
// const hash = await condition.hashValues(address, 15)
|
||||
|
||||
// assert.match(hash, /^0x[a-f0-9]{64}$/i)
|
||||
// })
|
||||
// })
|
||||
})
|
Loading…
Reference in New Issue
Block a user