mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
Merge remote-tracking branch 'origin/feature/secret_store' into greenkeeper/bignumber.js-8.0.0
# Conflicts: # package.json
This commit is contained in:
commit
f6ac9fc323
@ -33,7 +33,7 @@
|
||||
Start by adding the package to your dependencies:
|
||||
|
||||
```bash
|
||||
npm i @oceanprotocol/squid
|
||||
npm i @oceanprotocol/squid --save
|
||||
```
|
||||
|
||||
The package exposes `Ocean` and `Logger` which you can import in your code like this:
|
||||
@ -46,10 +46,13 @@ import { Ocean, Logger } from '@oceanprotocol/squid'
|
||||
const { Ocean, Logger } = require('@oceanprotocol/squid')
|
||||
```
|
||||
|
||||
You can then connect to a running [Keeper](https://github.com/oceanprotocol/keeper-contracts) & [Provider](https://github.com/oceanprotocol/provider) instance, e.g.:
|
||||
You can then connect to a running [Keeper](https://github.com/oceanprotocol/keeper-contracts) & [Aquarius](https://github.com/oceanprotocol/aquarius) instance, e.g.:
|
||||
|
||||
```js
|
||||
const ocean = await new Ocean({nodeUri: 'http://localhost:8545', network: 'development', providerUri: 'http://localhost:5000'})
|
||||
const ocean = await new Ocean({
|
||||
nodeUri: 'http://localhost:8545',
|
||||
aquariusUri: 'http://localhost:5000'
|
||||
})
|
||||
```
|
||||
|
||||
## Development
|
||||
|
84
package-lock.json
generated
84
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oceanprotocol/squid",
|
||||
"version": "0.1.0-beta.17",
|
||||
"version": "0.1.0-beta.20",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -120,14 +120,22 @@
|
||||
}
|
||||
},
|
||||
"@oceanprotocol/keeper-contracts": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.4.1.tgz",
|
||||
"integrity": "sha512-UmgPsJul9ZJb5BPIa1qfMpokJWzdROni/wisd4Dnm+wwHUA7/ymsr34zVn+4v+uAcMLHAYPKbsROBT5xlbiKAQ=="
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.3.7.tgz",
|
||||
"integrity": "sha512-Yx+ucPIjLsn/Rvs0G8sPpjKWmmUQv5x9YBdO6pHutSGO82PkVBCydV4mB5Wx3Pqr3KmW0S34ve07KmUN3qtc7A=="
|
||||
},
|
||||
"@oceanprotocol/secret-store-client": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/secret-store-client/-/secret-store-client-0.0.7.tgz",
|
||||
"integrity": "sha512-NaqJJ0AlgIbV4WIIRbetjd6PCXux8sT2kZgw1GGmky9b7PZvG4AWm/rPN/1lmJJ2ccx3gwUpQTPrP2SLHRBTuw==",
|
||||
"requires": {
|
||||
"node-fetch": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.6.tgz",
|
||||
"integrity": "sha512-CBk7KTZt3FhPsEkYioG6kuCIpWISw+YI8o+3op4+NXwTpvAPxE1ES8+PY8zfaK2L98b1z5oq03UHa4VYpeUxnw==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz",
|
||||
"integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/events": {
|
||||
@ -1969,6 +1977,11 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
|
||||
"integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2495,13 +2508,11 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -2514,18 +2525,15 @@
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -2628,8 +2636,7 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -2639,7 +2646,6 @@
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -2652,20 +2658,17 @@
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@ -2682,7 +2685,6 @@
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@ -2755,8 +2757,7 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -2766,7 +2767,6 @@
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -2873,7 +2873,6 @@
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -4341,7 +4340,6 @@
|
||||
"version": "0.1.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2",
|
||||
"longest": "^1.0.1",
|
||||
@ -4666,8 +4664,7 @@
|
||||
"is-buffer": {
|
||||
"version": "1.1.6",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"is-builtin-module": {
|
||||
"version": "1.0.0",
|
||||
@ -4751,7 +4748,6 @@
|
||||
"version": "3.2.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@ -4798,8 +4794,7 @@
|
||||
"longest": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.3",
|
||||
@ -5065,8 +5060,7 @@
|
||||
"repeat-string": {
|
||||
"version": "1.6.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
@ -7365,9 +7359,9 @@
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
|
||||
"integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.0.2",
|
||||
@ -7556,6 +7550,13 @@
|
||||
"setimmediate": "1.0.4",
|
||||
"uuid": "2.0.1",
|
||||
"xmlhttprequest": "1.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
|
||||
"integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
|
||||
}
|
||||
}
|
||||
},
|
||||
"hash.js": {
|
||||
@ -7595,6 +7596,11 @@
|
||||
"elliptic": "^6.4.0",
|
||||
"xhr-request-promise": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
|
||||
"integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
15
package.json
15
package.json
@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "@oceanprotocol/squid",
|
||||
"version": "0.1.0-beta.17",
|
||||
"version": "0.1.0-beta.20",
|
||||
"description": "JavaScript client library for Ocean Protocol",
|
||||
"main": "dist/squid.js",
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"test:watch": "mocha -w --watch-extensions js,ts",
|
||||
"test:watch": "mocha -w --watch-extensions js,ts,json",
|
||||
"test:cover": "nyc mocha",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"start": "npm link @oceanprotocol/keeper-contracts && npm run build:watch",
|
||||
"build": "npm run lint && tsc && npm run doc",
|
||||
"clean": "rm -rf ./dist/ ./doc/ ./coverage ./.nyc_output",
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'",
|
||||
"start": "npm link @oceanprotocol/keeper-contracts @oceanprotocol/secret-store-client && npm run build:watch",
|
||||
"build": "npm run clean && npm run lint && tsc && npm run doc",
|
||||
"build:watch": "tsc -w",
|
||||
"doc": "typedoc --mode modules --out ./doc/ src/",
|
||||
"release": "./node_modules/release-it/bin/release-it.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||
@ -50,17 +51,19 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/keeper-contracts": "^0.4.1",
|
||||
"@oceanprotocol/secret-store-client": "^0.0.7",
|
||||
"bignumber.js": "^8.0.0",
|
||||
"eth-crypto": "^1.2.4",
|
||||
"eth-ecies": "^1.0.3",
|
||||
"ethereumjs-util": "^6.0.0",
|
||||
"jsonwebtoken": "^8.3.0",
|
||||
"node-fetch": "^2.2.0",
|
||||
"uuid": "^3.3.2",
|
||||
"web3": "1.0.0-beta.36",
|
||||
"web3-utils": "1.0.0-beta.36"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.1.6",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^8.10.36",
|
||||
"chai": "^4.2.0",
|
||||
|
@ -1,6 +1,9 @@
|
||||
import {URL} from "url"
|
||||
import DDO from "../ddo/DDO"
|
||||
import Config from "../models/Config"
|
||||
import Logger from "../utils/Logger"
|
||||
import AquariusConnectorProvider from "./AquariusConnectorProvider"
|
||||
import SearchQuery from "./query/SearchQuery"
|
||||
|
||||
export default class Aquarius {
|
||||
|
||||
@ -13,31 +16,30 @@ export default class Aquarius {
|
||||
|
||||
public async getAccessUrl(accessToken: any, payload: any): Promise<string> {
|
||||
|
||||
const accessUrl = await AquariusConnectorProvider.getConnector().post(
|
||||
`${accessToken.service_endpoint}/${accessToken.resource_id}`,
|
||||
payload)
|
||||
.then((response: any) => {
|
||||
const accessUrl: string = await AquariusConnectorProvider.getConnector()
|
||||
.post(`${accessToken.service_endpoint}/${accessToken.resource_id}`, payload)
|
||||
.then((response: any): string => {
|
||||
if (response.ok) {
|
||||
return response.text()
|
||||
}
|
||||
Logger.log("Failed: ", response.status, response.statusText)
|
||||
Logger.error("Failed: ", response.status, response.statusText)
|
||||
})
|
||||
.then((consumptionUrl: string) => {
|
||||
.then((consumptionUrl: string): string => {
|
||||
Logger.log("Success accessing consume endpoint: ", consumptionUrl)
|
||||
return consumptionUrl
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching the data asset consumption url: ", error)
|
||||
return null
|
||||
})
|
||||
|
||||
return accessUrl
|
||||
}
|
||||
|
||||
public async queryMetadata(query): Promise<any[]> {
|
||||
public async queryMetadata(query: SearchQuery): Promise<any[]> {
|
||||
|
||||
const result = await AquariusConnectorProvider.getConnector().post(
|
||||
this.url + "/api/v1/aquarius/assets/ddo/query",
|
||||
JSON.stringify(query))
|
||||
const result = await AquariusConnectorProvider.getConnector()
|
||||
.post(this.url + "/api/v1/aquarius/assets/ddo/query", JSON.stringify(query))
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
@ -51,11 +53,15 @@ export default class Aquarius {
|
||||
return result
|
||||
}
|
||||
|
||||
public async queryMetadataByText(query): Promise<any[]> {
|
||||
public async queryMetadataByText(query: SearchQuery): Promise<any[]> {
|
||||
|
||||
const result = await AquariusConnectorProvider.getConnector().get(
|
||||
this.url + "/api/v1/aquarius/assets/ddo/query",
|
||||
JSON.stringify(query))
|
||||
const fullUrl = new URL(this.url + "/api/v1/aquarius/assets/ddo/query")
|
||||
fullUrl.searchParams.append("text", query.text)
|
||||
fullUrl.searchParams.append("sort", JSON.stringify(query.sort))
|
||||
fullUrl.searchParams.append("offset", query.offset.toString())
|
||||
fullUrl.searchParams.append("page", query.page.toString())
|
||||
const result = await AquariusConnectorProvider.getConnector()
|
||||
.get(fullUrl)
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
@ -68,4 +74,38 @@ export default class Aquarius {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public async storeDDO(ddo: DDO): Promise<DDO> {
|
||||
const fullUrl = this.url + `/api/v1/aquarius/assets/ddo`
|
||||
const result: DDO = await AquariusConnectorProvider.getConnector()
|
||||
.post(fullUrl, DDO.serialize(ddo))
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
Logger.log("Failed:", response.status, response.statusText)
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching querying metadata: ", error)
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public async retrieveDDO(did: string): Promise<DDO> {
|
||||
const fullUrl = this.url + `/api/v1/aquarius/assets/ddo/${did}`
|
||||
const result = await AquariusConnectorProvider.getConnector()
|
||||
.get(fullUrl)
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
Logger.log("Failed:", response.status, response.statusText)
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching querying metadata: ", error)
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
import fetch from "node-fetch"
|
||||
import { URL } from "url"
|
||||
|
||||
export default class AquariusConnector {
|
||||
|
||||
public post(url, payload) {
|
||||
return fetch(url, {
|
||||
public async post(url, payload): Promise<any> {
|
||||
return this.fetch(url, {
|
||||
method: "POST",
|
||||
body: payload,
|
||||
headers: {
|
||||
@ -13,17 +12,26 @@ export default class AquariusConnector {
|
||||
})
|
||||
}
|
||||
|
||||
public get(url, payload) {
|
||||
const fullUrl = new URL(url)
|
||||
for (const key of Object.keys(payload)) {
|
||||
fullUrl.searchParams.append(key, payload[key])
|
||||
}
|
||||
return fetch(fullUrl, {
|
||||
public async get(url): Promise<any> {
|
||||
return this.fetch(url, {
|
||||
method: "GET",
|
||||
body: null,
|
||||
headers: {
|
||||
"Content-type": "application/json",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
public async put(url, payload): Promise<any> {
|
||||
return this.fetch(url, {
|
||||
method: "PUT",
|
||||
body: payload,
|
||||
headers: {
|
||||
"Content-type": "application/json",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
private async fetch(url, opts): Promise<any> {
|
||||
return fetch(url, opts)
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,17 @@
|
||||
import Logger from "../utils/Logger"
|
||||
import AquariusConnector from "./AquariusConnector"
|
||||
|
||||
export default class AquariusConnectorProvider {
|
||||
|
||||
public static setConnector(connector: AquariusConnector) {
|
||||
|
||||
Logger.log("setting", typeof connector.constructor.name)
|
||||
|
||||
AquariusConnectorProvider.connector = connector
|
||||
}
|
||||
|
||||
public static getConnector() {
|
||||
public static getConnector(): AquariusConnector {
|
||||
|
||||
if (!AquariusConnectorProvider.connector) {
|
||||
AquariusConnectorProvider.connector = new AquariusConnector()
|
||||
}
|
||||
Logger.log("getting", typeof AquariusConnectorProvider.connector.constructor.name)
|
||||
return AquariusConnectorProvider.connector
|
||||
}
|
||||
|
||||
|
3
src/aquarius/query/Query.ts
Normal file
3
src/aquarius/query/Query.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default class Query {
|
||||
public value: number = 1
|
||||
}
|
14
src/aquarius/query/SearchQuery.ts
Normal file
14
src/aquarius/query/SearchQuery.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import Query from "./Query"
|
||||
import Sort from "./Sort"
|
||||
|
||||
export default class SearchQuery {
|
||||
public offset: number = 100
|
||||
public page: number = 0
|
||||
public query: Query = {
|
||||
value: 1,
|
||||
} as Query
|
||||
public sort: Sort = {
|
||||
value: 1,
|
||||
} as Sort
|
||||
public text: string = "Office"
|
||||
}
|
3
src/aquarius/query/Sort.ts
Normal file
3
src/aquarius/query/Sort.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default class Sort {
|
||||
public value: number = 1
|
||||
}
|
15
src/ddo/AdditionalInformation.ts
Normal file
15
src/ddo/AdditionalInformation.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import StructuredMarkup from "./StructuredMarkup"
|
||||
|
||||
export default class AdditionalInformation {
|
||||
public updateFrecuency: string = "yearly"
|
||||
public structuredMarkup: StructuredMarkup[] = [
|
||||
{
|
||||
uri: "http://skos.um.es/unescothes/C01194/jsonld",
|
||||
mediaType: "application/ld+json",
|
||||
} as StructuredMarkup,
|
||||
{
|
||||
uri: "http://skos.um.es/unescothes/C01194/turtle",
|
||||
mediaType: "text/turtle",
|
||||
}as StructuredMarkup,
|
||||
]
|
||||
}
|
4
src/ddo/Authentication.ts
Normal file
4
src/ddo/Authentication.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default class Authentication {
|
||||
public type: string = "RsaSignatureAuthentication2018"
|
||||
public publicKey: string = "did:op:123456789abcdefghi#keys-1"
|
||||
}
|
5
src/ddo/Curation.ts
Normal file
5
src/ddo/Curation.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export default class Curation {
|
||||
public rating: number = 0.93
|
||||
public numVotes: number = 123
|
||||
public schema: string = "Binary Votting"
|
||||
}
|
37
src/ddo/DDO.ts
Normal file
37
src/ddo/DDO.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import Authentication from "./Authentication"
|
||||
import PublicKey from "./PublicKey"
|
||||
import Service from "./Service"
|
||||
|
||||
export default class DDO {
|
||||
|
||||
public static serialize(ddo: DDO): string {
|
||||
return JSON.stringify(ddo, null, 2)
|
||||
}
|
||||
|
||||
public static deserialize(ddoString: string): DDO {
|
||||
const ddo = JSON.parse(ddoString)
|
||||
|
||||
return ddo as DDO
|
||||
}
|
||||
|
||||
public "@context": string = "https://w3id.org/future-method/v1"
|
||||
public id: string
|
||||
public publicKey: PublicKey[]
|
||||
public authentication: Authentication[]
|
||||
public service: Service[]
|
||||
|
||||
// @ts-ignore
|
||||
private assa: string
|
||||
|
||||
public constructor(ddo?: {
|
||||
id?: string,
|
||||
publicKey?: PublicKey[],
|
||||
authentication?: Authentication[],
|
||||
service?: Service[],
|
||||
}) {
|
||||
this.id = ddo ? ddo.id ? ddo.id : null : null
|
||||
this.publicKey = ddo ? ddo.publicKey ? ddo.publicKey : [] : []
|
||||
this.authentication = ddo ? ddo.authentication ? ddo.authentication : [] : []
|
||||
this.service = ddo ? ddo.service ? ddo.service : [] : []
|
||||
}
|
||||
}
|
59
src/ddo/MetaData.ts
Normal file
59
src/ddo/MetaData.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import AdditionalInformation from "./AdditionalInformation"
|
||||
import Curation from "./Curation"
|
||||
import MetaDataBase from "./MetaDataBase"
|
||||
import StructuredMarkup from "./StructuredMarkup"
|
||||
|
||||
export default class MetaData {
|
||||
|
||||
public base: MetaDataBase = {
|
||||
name: "UK Weather information 2011",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-10-10T17:00:000Z",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
workExample: "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
],
|
||||
links: [
|
||||
{
|
||||
sample1: "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/",
|
||||
},
|
||||
{
|
||||
sample2: "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/",
|
||||
},
|
||||
{
|
||||
fieldsDescription: "http://data.ceda.ac.uk/badc/ukcp09/",
|
||||
},
|
||||
],
|
||||
inLanguage: "en",
|
||||
tags: "weather, uk, 2011, temperature, humidity",
|
||||
price: 10,
|
||||
} as MetaDataBase
|
||||
|
||||
public curation: Curation = {
|
||||
rating: 0.93,
|
||||
numVotes: 123,
|
||||
schema: "Binary Votting",
|
||||
} as Curation
|
||||
|
||||
public additionalInformation: AdditionalInformation = {
|
||||
updateFrecuency: "yearly",
|
||||
structuredMarkup: [
|
||||
{
|
||||
uri: "http://skos.um.es/unescothes/C01194/jsonld",
|
||||
mediaType: "application/ld+json",
|
||||
} as StructuredMarkup,
|
||||
{
|
||||
uri: "http://skos.um.es/unescothes/C01194/turtle",
|
||||
mediaType: "text/turtle",
|
||||
} as StructuredMarkup,
|
||||
],
|
||||
} as AdditionalInformation
|
||||
}
|
31
src/ddo/MetaDataBase.ts
Normal file
31
src/ddo/MetaDataBase.ts
Normal file
@ -0,0 +1,31 @@
|
||||
export default class MetaDataBase {
|
||||
public name: string = "UK Weather information 2011"
|
||||
public type: string = "dataset"
|
||||
public description: string = "Weather information of UK including temperature and humidity"
|
||||
public size: string = "3.1gb"
|
||||
public dateCreated: string = "2012-10-10T17:00:000Z"
|
||||
public author: string = "Met Office"
|
||||
public license: string = "CC-BY"
|
||||
public copyrightHolder: string = "Met Office"
|
||||
public encoding: string = "UTF-8"
|
||||
public compression: string = "zip"
|
||||
public contentType: string = "text/csv"
|
||||
public workExample: string = "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68"
|
||||
public contentUrls: string[] = [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
]
|
||||
public links: any[] = [
|
||||
{
|
||||
sample1: "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/",
|
||||
},
|
||||
{
|
||||
sample2: "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/",
|
||||
},
|
||||
{
|
||||
fieldsDescription: "http://data.ceda.ac.uk/badc/ukcp09/",
|
||||
},
|
||||
]
|
||||
public inLanguage: string = "en"
|
||||
public tags: string = "weather, uk, 2011, temperature, humidity"
|
||||
public price: number = 10
|
||||
}
|
7
src/ddo/PublicKey.ts
Normal file
7
src/ddo/PublicKey.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export default class PublicKey {
|
||||
public id: string = "did:op:123456789abcdefghi#keys-1"
|
||||
public type: string = "RsaVerificationKey2018"
|
||||
public owner: string = "did:op:123456789abcdefghi"
|
||||
public publicKeyPem?: string = "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
|
||||
public publicKeyBase58?: string = "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
|
||||
}
|
8
src/ddo/Service.ts
Normal file
8
src/ddo/Service.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import MetaData from "./MetaData"
|
||||
|
||||
export default class Service {
|
||||
public type: string = "OpenIdConnectVersion1.0Service"
|
||||
public serviceEndpoint: string = "https://openid.example.com/"
|
||||
public description?: string = "My public social inbox"
|
||||
public metadata?: MetaData = {} as MetaData
|
||||
}
|
4
src/ddo/StructuredMarkup.ts
Normal file
4
src/ddo/StructuredMarkup.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default class StructuredMarkup {
|
||||
public uri: string = "http://skos.um.es/unescothes/C01194/jsonld"
|
||||
public mediaType: string = "application/ld+json"
|
||||
}
|
@ -3,14 +3,12 @@ import Logger from "../utils/Logger"
|
||||
import Keeper from "./Keeper"
|
||||
import Web3Provider from "./Web3Provider"
|
||||
|
||||
const contracts: Map<string, Contract> = new Map<string, Contract>()
|
||||
|
||||
export default class ContractHandler {
|
||||
|
||||
public static async get(what: string): Contract {
|
||||
const where = (await (await Keeper.getInstance()).getNetworkName()).toLowerCase()
|
||||
try {
|
||||
return contracts.get(what) || await ContractHandler.load(what, where)
|
||||
return ContractHandler.contracts.get(what) || await ContractHandler.load(what, where)
|
||||
} catch (err) {
|
||||
Logger.error("Failed to load", what, "from", where, err)
|
||||
throw err
|
||||
@ -50,6 +48,20 @@ export default class ContractHandler {
|
||||
const market = await ContractHandler.deployContract("OceanMarket", deployerAddress, {
|
||||
args: [token.options.address],
|
||||
})
|
||||
|
||||
const sa = await ContractHandler.deployContract("ServiceAgreement", deployerAddress, {
|
||||
args: [],
|
||||
})
|
||||
|
||||
await ContractHandler.deployContract("AccessConditions", deployerAddress, {
|
||||
args: [sa.options.address],
|
||||
})
|
||||
|
||||
await ContractHandler.deployContract("PaymentConditions", deployerAddress, {
|
||||
args: [sa.options.address, token.options.address],
|
||||
})
|
||||
|
||||
await ContractHandler.deployContract("DIDRegistry", deployerAddress, {})
|
||||
/* not part of trilobite
|
||||
const dispute = await ContractHandler.deployContract("OceanDispute", deployerAddress, {
|
||||
args: [market.options.address, registry.options.address, plcrVoting.options.address],
|
||||
@ -60,6 +72,8 @@ export default class ContractHandler {
|
||||
})
|
||||
}
|
||||
|
||||
private static contracts: Map<string, Contract> = new Map<string, Contract>()
|
||||
|
||||
private static async load(what: string, where: string): Promise<Contract> {
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
// Logger.log("Loading", what, "from", where)
|
||||
@ -73,8 +87,8 @@ export default class ContractHandler {
|
||||
// Logger.log("Getting instance of", what, "from", where, "at", artifact.address)
|
||||
const contract = new web3.eth.Contract(artifact.abi, artifact.address)
|
||||
Logger.log("Loaded", what, "from", where)
|
||||
contracts.set(what, contract)
|
||||
return contracts.get(what)
|
||||
ContractHandler.contracts.set(what, contract)
|
||||
return ContractHandler.contracts.get(what)
|
||||
}
|
||||
|
||||
// todo: reactivate for tethys
|
||||
@ -94,8 +108,8 @@ export default class ContractHandler {
|
||||
private static async deployContract(name: string, from: string, params?): Promise<Contract> {
|
||||
|
||||
// dont redeploy if there is already something loaded
|
||||
if (contracts.has(name)) {
|
||||
return contracts.get(name)
|
||||
if (ContractHandler.contracts.has(name)) {
|
||||
return ContractHandler.contracts.get(name)
|
||||
}
|
||||
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
@ -116,7 +130,7 @@ export default class ContractHandler {
|
||||
gas: 3000000,
|
||||
gasPrice: 10000000000,
|
||||
})
|
||||
contracts.set(name, contractInstance)
|
||||
ContractHandler.contracts.set(name, contractInstance)
|
||||
// Logger.log("Deployed", name, "at", contractInstance.options.address);
|
||||
} catch (err) {
|
||||
Logger.error("Deployment failed for", name, "with params", JSON.stringify(params, null, 2), err.message)
|
||||
|
17
src/keeper/ContractReflector.ts
Normal file
17
src/keeper/ContractReflector.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import MethodReflection from "../models/MethodReflection"
|
||||
import GenericContract from "./contracts/GenericContract"
|
||||
|
||||
export default class ContractReflector {
|
||||
|
||||
public static async reflectContractMethod(pathToMethod: string): Promise<MethodReflection> {
|
||||
const parts: string[] = pathToMethod.split(".")
|
||||
|
||||
const contract = await GenericContract.getInstance(parts[0])
|
||||
return {
|
||||
contractName: parts[0],
|
||||
methodName: parts[1],
|
||||
address: contract.getAddress(),
|
||||
signature: contract.getSignatureOfMethod(parts[1]),
|
||||
} as MethodReflection
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import OceanAuth from "./Auth"
|
||||
import OceanMarket from "./Market"
|
||||
import OceanToken from "./Token"
|
||||
import OceanAuth from "./contracts/Auth"
|
||||
import OceanMarket from "./contracts/Market"
|
||||
import ServiceAgreement from "./contracts/ServiceAgreement"
|
||||
import OceanToken from "./contracts/Token"
|
||||
import Web3Provider from "./Web3Provider"
|
||||
|
||||
export default class Keeper {
|
||||
@ -13,6 +14,7 @@ export default class Keeper {
|
||||
Keeper.instance.market = await OceanMarket.getInstance()
|
||||
Keeper.instance.auth = await OceanAuth.getInstance()
|
||||
Keeper.instance.token = await OceanToken.getInstance()
|
||||
Keeper.instance.serviceAgreement = await ServiceAgreement.getInstance()
|
||||
}
|
||||
return Keeper.instance
|
||||
}
|
||||
@ -22,6 +24,7 @@ export default class Keeper {
|
||||
public token: OceanToken
|
||||
public market: OceanMarket
|
||||
public auth: OceanAuth
|
||||
public serviceAgreement: ServiceAgreement
|
||||
|
||||
public async getNetworkName(): Promise<string> {
|
||||
return Web3Provider.getWeb3().eth.net.getId()
|
||||
|
@ -1,8 +1,5 @@
|
||||
import * as Web3 from "web3"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Logger from "../utils/Logger"
|
||||
|
||||
Logger.log("using web3", Web3.version)
|
||||
|
||||
export default class Web3Provider {
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Receipt} from "web3-utils"
|
||||
import AccessStatus from "../models/AccessStatus"
|
||||
import Asset from "../ocean/Asset"
|
||||
import Order from "../ocean/Order"
|
||||
import AccessStatus from "../../models/AccessStatus"
|
||||
import Asset from "../../ocean/Asset"
|
||||
import Order from "../../ocean/Order"
|
||||
import ContractBase from "./ContractBase"
|
||||
|
||||
export default class OceanAuth extends ContractBase {
|
||||
@ -27,13 +27,13 @@ export default class OceanAuth extends ContractBase {
|
||||
|
||||
public async initiateAccessRequest(asset: Asset, publicKey: string,
|
||||
timeout: number, buyerAddress: string): Promise<Receipt> {
|
||||
const args = [asset.getId(), asset.publisher.getId(), publicKey, timeout]
|
||||
return this.sendTransaction("initiateAccessRequest", buyerAddress, args)
|
||||
const args = ["0x" + asset.getId(), asset.publisher.getId(), publicKey, timeout]
|
||||
return this.send("initiateAccessRequest", buyerAddress, args)
|
||||
}
|
||||
|
||||
public async commitAccessRequest(order: Order, publisherAddress: string) {
|
||||
const args = [order.getId(), true, 9999999999, "discovery", "read", "slaLink", "slaType"]
|
||||
return this.sendTransaction("commitAccessRequest", publisherAddress, args)
|
||||
return this.send("commitAccessRequest", publisherAddress, args)
|
||||
}
|
||||
|
||||
public async getTempPubKey(orderId: string) {
|
||||
@ -41,7 +41,7 @@ export default class OceanAuth extends ContractBase {
|
||||
}
|
||||
|
||||
public async deliverAccessToken(orderId: string, accessToken: string, publisherAddress: string) {
|
||||
return this.sendTransaction("deliverAccessToken", publisherAddress, [orderId, accessToken])
|
||||
return this.send("deliverAccessToken", publisherAddress, [orderId, accessToken])
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
import Event from "web3"
|
||||
import Contract from "web3-eth-contract"
|
||||
import Logger from "../utils/Logger"
|
||||
import ContractHandler from "./ContractHandler"
|
||||
import {Receipt} from "web3-utils"
|
||||
import Logger from "../../utils/Logger"
|
||||
import ContractHandler from "../ContractHandler"
|
||||
|
||||
export default abstract class ContractBase {
|
||||
|
||||
@ -32,7 +33,7 @@ export default abstract class ContractBase {
|
||||
|
||||
public async getEventData(eventName: any, options: any): Promise<Event[]> {
|
||||
if (!this.contract.events[eventName]) {
|
||||
throw new Error(`Event ${eventName} not found on contract ${this.contractName}`)
|
||||
throw new Error(`Event "${eventName}" not found on contract "${this.contractName}"`)
|
||||
}
|
||||
return this.contract.getPastEvents(eventName, options)
|
||||
}
|
||||
@ -41,13 +42,28 @@ export default abstract class ContractBase {
|
||||
return this.contract.options.address
|
||||
}
|
||||
|
||||
public getSignatureOfMethod(methodName: string): string {
|
||||
|
||||
const foundMethod = this.contract.options.jsonInterface.find((method) => {
|
||||
if (method.name === methodName) {
|
||||
return method
|
||||
}
|
||||
})
|
||||
|
||||
if (!foundMethod) {
|
||||
throw new Error(`Method "${methodName}" is not part of contract "${this.contractName}"`)
|
||||
}
|
||||
|
||||
return foundMethod.signature
|
||||
}
|
||||
|
||||
protected async init() {
|
||||
this.contract = await ContractHandler.get(this.contractName)
|
||||
}
|
||||
|
||||
protected async sendTransaction(name: string, from: string, args: any[]) {
|
||||
protected async send(name: string, from: string, args: any[]): Promise<Receipt> {
|
||||
if (!this.contract.methods[name]) {
|
||||
throw new Error(`Method ${name} is not part of contract ${this.contractName}`)
|
||||
throw new Error(`Method "${name}" is not part of contract "${this.contractName}"`)
|
||||
}
|
||||
try {
|
||||
const tx = this.contract.methods[name](...args)
|
||||
@ -60,13 +76,13 @@ export default abstract class ContractBase {
|
||||
})
|
||||
} catch (err) {
|
||||
const argString = JSON.stringify(args, null, 2)
|
||||
Logger.error(`Sending transaction ${name} on contract ${this.contractName} failed.`)
|
||||
Logger.error(`Sending transaction "${name}" on contract "${this.contractName}" failed.`)
|
||||
Logger.error(`Args: ${argString} From: ${from}`)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
protected async call(name: string, args: any[], from?: string) {
|
||||
protected async call(name: string, args: any[], from?: string): Promise<any> {
|
||||
if (!this.contract.methods[name]) {
|
||||
throw new Error(`Method ${name} is not part of contract ${this.contractName}`)
|
||||
}
|
||||
@ -74,7 +90,7 @@ export default abstract class ContractBase {
|
||||
const method = this.contract.methods[name](...args)
|
||||
return method.call(from ? {from} : null)
|
||||
} catch (err) {
|
||||
Logger.error(`Calling method ${name} on contract ${this.contractName} failed. Args: ${args}`, err)
|
||||
Logger.error(`Calling method "${name}" on contract "${this.contractName}" failed. Args: ${args}`, err)
|
||||
throw err
|
||||
}
|
||||
}
|
37
src/keeper/contracts/DIDRegistry.ts
Normal file
37
src/keeper/contracts/DIDRegistry.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import {Receipt} from "web3-utils"
|
||||
import ValueType from "../../models/ValueType"
|
||||
import ContractBase from "./ContractBase"
|
||||
|
||||
export default class DIDRegistry extends ContractBase {
|
||||
|
||||
public static async getInstance(): Promise<DIDRegistry> {
|
||||
const didRegistry: DIDRegistry = new DIDRegistry("DIDRegistry")
|
||||
await didRegistry.init()
|
||||
return didRegistry
|
||||
}
|
||||
|
||||
public async registerAttribute(did: string, type: ValueType, key: string,
|
||||
value: string, ownerAddress: string): Promise<Receipt> {
|
||||
|
||||
return this.send("registerAttribute",
|
||||
ownerAddress, ["0x" + did, type, key, value],
|
||||
)
|
||||
}
|
||||
|
||||
public async getOwner(did: string): Promise<string> {
|
||||
|
||||
return this.call("getOwner",
|
||||
["0x" + did],
|
||||
)
|
||||
}
|
||||
|
||||
public async getUpdateAt(did: string): Promise<number> {
|
||||
|
||||
const blockNum = await this.call("getUpdateAt",
|
||||
["0x" + did],
|
||||
)
|
||||
|
||||
return parseInt(blockNum, 10)
|
||||
}
|
||||
|
||||
}
|
14
src/keeper/contracts/GenericContract.ts
Normal file
14
src/keeper/contracts/GenericContract.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import ContractBase from "./ContractBase"
|
||||
|
||||
export default class GenericContract extends ContractBase {
|
||||
|
||||
public static async getInstance(contractName: string) {
|
||||
const contract: GenericContract = new GenericContract(contractName)
|
||||
await contract.init()
|
||||
return contract
|
||||
}
|
||||
|
||||
private constructor(contractName: string) {
|
||||
super(contractName)
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import BigNumber from "bignumber.js"
|
||||
import {Receipt} from "web3-utils"
|
||||
import Order from "../ocean/Order"
|
||||
import Order from "../../ocean/Order"
|
||||
import ContractBase from "./ContractBase"
|
||||
|
||||
export default class OceanMarket extends ContractBase {
|
||||
@ -13,7 +13,7 @@ export default class OceanMarket extends ContractBase {
|
||||
|
||||
// call functions (costs no gas)
|
||||
public async isAssetActive(assetId: string): Promise<boolean> {
|
||||
return this.call("checkAsset", [assetId])
|
||||
return this.call("checkAsset", ["0x" + assetId])
|
||||
}
|
||||
|
||||
public async verifyOrderPayment(orderId: string): Promise<boolean> {
|
||||
@ -21,12 +21,12 @@ export default class OceanMarket extends ContractBase {
|
||||
}
|
||||
|
||||
public async getAssetPrice(assetId: string): Promise<number> {
|
||||
return this.call("getAssetPrice", [assetId])
|
||||
return this.call("getAssetPrice", ["0x" + assetId])
|
||||
.then((price: string) => new BigNumber(price).toNumber())
|
||||
}
|
||||
|
||||
public async requestTokens(amount: number, receiverAddress: string): Promise<Receipt> {
|
||||
return this.sendTransaction("requestTokens", receiverAddress, [amount])
|
||||
return this.send("requestTokens", receiverAddress, [amount])
|
||||
}
|
||||
|
||||
public async generateId(input: string): Promise<string> {
|
||||
@ -34,13 +34,13 @@ export default class OceanMarket extends ContractBase {
|
||||
}
|
||||
|
||||
public async register(assetId: string, price: number, publisherAddress: string): Promise<Receipt> {
|
||||
return this.sendTransaction("register", publisherAddress, [assetId, price])
|
||||
return this.send("register", publisherAddress, ["0x" + assetId, price])
|
||||
}
|
||||
|
||||
public async payOrder(order: Order, publisherAddress: string,
|
||||
price: number, consumerAddress: string,
|
||||
timeout: number): Promise<Receipt> {
|
||||
return this.sendTransaction("sendPayment", consumerAddress, [
|
||||
return this.send("sendPayment", consumerAddress, [
|
||||
order.getId(), publisherAddress, price, timeout,
|
||||
])
|
||||
}
|
41
src/keeper/contracts/ServiceAgreement.ts
Normal file
41
src/keeper/contracts/ServiceAgreement.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import {Receipt} from "web3-utils"
|
||||
import MethodReflection from "../../models/MethodReflection"
|
||||
import ContractBase from "./ContractBase"
|
||||
|
||||
export default class ServiceAgreement extends ContractBase {
|
||||
|
||||
public static async getInstance(): Promise<ServiceAgreement> {
|
||||
const serviceAgreement: ServiceAgreement = new ServiceAgreement("ServiceAgreement")
|
||||
await serviceAgreement.init()
|
||||
return serviceAgreement
|
||||
}
|
||||
|
||||
public async setupAgreementTemplate(methodReflections: MethodReflection[], dependencyMatrix: number[], name: any,
|
||||
ownerAddress: string): Promise<Receipt> {
|
||||
|
||||
return this.send("setupAgreementTemplate", ownerAddress, [
|
||||
methodReflections.map((r) => r.address), methodReflections.map((r) => r.signature),
|
||||
dependencyMatrix, name,
|
||||
])
|
||||
}
|
||||
|
||||
public async getTemplateStatus(templateId: string) {
|
||||
|
||||
return this.call("getTemplateStatus", [templateId])
|
||||
}
|
||||
|
||||
public async getAgreementStatus(serviceAgreementId: string) {
|
||||
|
||||
return this.call("getAgreementStatus", ["0x" + serviceAgreementId])
|
||||
}
|
||||
|
||||
public async executeAgreement(serviceAgreementTemplateId: string, serviceAgreementSignatureHash: string,
|
||||
consumerAddress: string, valueHashes: string[], timeoutValues: number[],
|
||||
serviceAgreementId: string, did: string, publisherAddress: string): Promise<Receipt> {
|
||||
|
||||
return this.send("executeAgreement", publisherAddress, [
|
||||
serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes,
|
||||
timeoutValues, "0x" + serviceAgreementId, "0x" + did,
|
||||
])
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ export default class OceanToken extends ContractBase {
|
||||
}
|
||||
|
||||
public async approve(marketAddress: string, price: number, buyerAddress: string): Promise<Receipt> {
|
||||
return this.sendTransaction("approve", buyerAddress, [marketAddress, price])
|
||||
return this.send("approve", buyerAddress, [marketAddress, price])
|
||||
}
|
||||
|
||||
public async balanceOf(address: string): Promise<number> {
|
18
src/keeper/contracts/conditions/AccessConditions.ts
Normal file
18
src/keeper/contracts/conditions/AccessConditions.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {Receipt} from "web3-utils"
|
||||
import ContractBase from "../ContractBase"
|
||||
|
||||
export default class AccessConditions extends ContractBase {
|
||||
|
||||
public static async getInstance(): Promise<AccessConditions> {
|
||||
const accessConditions: AccessConditions = new AccessConditions("AccessConditions")
|
||||
await accessConditions.init()
|
||||
return accessConditions
|
||||
}
|
||||
|
||||
public async grantAccess(serviceAgreementId: any, assetId: any, documentKeyId: any, publisherAddress: string)
|
||||
: Promise<Receipt> {
|
||||
return this.send("grantAccess", publisherAddress, [
|
||||
"0x" + serviceAgreementId, "0x" + assetId, "0x" + documentKeyId,
|
||||
])
|
||||
}
|
||||
}
|
10
src/keeper/contracts/conditions/PaymentConditions.ts
Normal file
10
src/keeper/contracts/conditions/PaymentConditions.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import ContractBase from "../ContractBase"
|
||||
|
||||
export default class PaymentConditions extends ContractBase {
|
||||
|
||||
public static async getInstance(): Promise<PaymentConditions> {
|
||||
const paymentConditions: PaymentConditions = new PaymentConditions("PaymentConditions")
|
||||
await paymentConditions.init()
|
||||
return paymentConditions
|
||||
}
|
||||
}
|
@ -1,5 +1,23 @@
|
||||
export default class Config {
|
||||
/* Aquarius Config */
|
||||
// the url to the aquarius
|
||||
public aquariusUri: string
|
||||
|
||||
/* Keeper Config */
|
||||
// the uri to the node we want to connect to, not need if web3Provider is set
|
||||
public nodeUri: string
|
||||
// from outside eg. metamask
|
||||
public web3Provider: any
|
||||
|
||||
/* Secret Store Config */
|
||||
// the uri of the secret store to connect to
|
||||
public secretStoreUri: string
|
||||
// the uri of the parity node to connect to
|
||||
public parityUri: string
|
||||
// the password of the account in the local parity node to sign the serverKeyId
|
||||
public password: string
|
||||
// the address of the account in the local parity node to sign the serverKeyId
|
||||
public address: string
|
||||
// the number of nodes in the secret store that have to agree on changes
|
||||
public threshold: number
|
||||
}
|
||||
|
6
src/models/MethodReflection.ts
Normal file
6
src/models/MethodReflection.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export default class MethodReflection {
|
||||
public contractName: string
|
||||
public methodName: string
|
||||
public address: string
|
||||
public signature: string
|
||||
}
|
8
src/models/ValueType.ts
Normal file
8
src/models/ValueType.ts
Normal file
@ -0,0 +1,8 @@
|
||||
enum ValueType {
|
||||
DID, // DID string e.g. 'did:op:xxx'
|
||||
DIDRef, // hash of DID same as in parameter (bytes32 _did) in text 0x0123abc.. or 0123abc..
|
||||
URL, // URL string e.g. 'http(s)://xx'
|
||||
DDO, // DDO string in JSON e.g. '{ "id": "did:op:xxx"...
|
||||
}
|
||||
|
||||
export default ValueType
|
8
src/ocean/IdGenerator.ts
Normal file
8
src/ocean/IdGenerator.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import * as v4 from "uuid/v4"
|
||||
|
||||
export default class IdGenerator {
|
||||
public static generateId(): string {
|
||||
const id = `${v4()}${v4()}`
|
||||
return id.replace(/-/g, "")
|
||||
}
|
||||
}
|
@ -2,14 +2,17 @@ import AquariusProvider from "../aquarius/AquariusProvider"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Keeper from "../keeper/Keeper"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import Config from "../models/Config"
|
||||
import SecretStoreProvider from "../secretstore/SecretStoreProvider"
|
||||
import Logger from "../utils/Logger"
|
||||
import Account from "./Account"
|
||||
import Asset from "./Asset"
|
||||
import IdGenerator from "./IdGenerator"
|
||||
import Order from "./Order"
|
||||
|
||||
export default class Ocean {
|
||||
|
||||
public static async getInstance(config) {
|
||||
public static async getInstance(config: Config) {
|
||||
|
||||
if (!Ocean.instance) {
|
||||
ConfigProvider.setConfig(config)
|
||||
@ -37,8 +40,17 @@ export default class Ocean {
|
||||
public async register(asset: Asset): Promise<string> {
|
||||
const {market} = this.keeper
|
||||
|
||||
const secretStore = SecretStoreProvider.getSecretStore()
|
||||
|
||||
const assetId = IdGenerator.generateId()
|
||||
|
||||
const encryptedDocument = await secretStore.encryptDocument(assetId, asset)
|
||||
|
||||
const decryptedDocument = await secretStore.decryptDocument(assetId, encryptedDocument)
|
||||
|
||||
Logger.log(decryptedDocument, encryptedDocument)
|
||||
|
||||
// generate an id
|
||||
const assetId = await market.generateId(asset.name + asset.description)
|
||||
Logger.log(`Registering: ${assetId} with price ${asset.price} for ${asset.publisher.getId()}`)
|
||||
asset.setId(assetId)
|
||||
const isAssetActive = await market.isAssetActive(assetId)
|
||||
|
117
src/ocean/ServiceAgreement.ts
Normal file
117
src/ocean/ServiceAgreement.ts
Normal file
@ -0,0 +1,117 @@
|
||||
import AccessConditions from "../keeper/contracts/conditions/AccessConditions"
|
||||
import ServiceAgreementContract from "../keeper/contracts/ServiceAgreement"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import Account from "./Account"
|
||||
import IdGenerator from "./IdGenerator"
|
||||
import OceanBase from "./OceanBase"
|
||||
import ServiceAgreementTemplate from "./ServiceAgreementTemplate"
|
||||
|
||||
export default class ServiceAgreement extends OceanBase {
|
||||
|
||||
public static async createServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, assetId: string,
|
||||
did: string, consumer: Account, publisher: Account) {
|
||||
|
||||
// todo: this should come from ddo
|
||||
const serviceAgreementId = IdGenerator.generateId()
|
||||
const timeoutValues = [0, 0, 0, 500] // timeout 500 blocks @ condition 4
|
||||
const values = [
|
||||
{type: "bool", value: true},
|
||||
{type: "bool", value: false},
|
||||
{type: "uint", value: 120},
|
||||
{type: "string", value: assetId},
|
||||
]
|
||||
|
||||
const saHashSig = await ServiceAgreement.createSAHashSignature(serviceAgreementTemplate, serviceAgreementId,
|
||||
values, timeoutValues, consumer)
|
||||
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.signServiceAgreement(serviceAgreementTemplate,
|
||||
serviceAgreementId, assetId, did, values, timeoutValues, saHashSig, consumer, publisher)
|
||||
|
||||
return serviceAgreement
|
||||
}
|
||||
|
||||
private static async signServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate,
|
||||
serviceAgreementId: string, assetId: string, did: string, values: any[],
|
||||
timeoutValues: number[], serviceAgreementHashSignature: string,
|
||||
consumer: Account, publisher: Account):
|
||||
Promise<ServiceAgreement> {
|
||||
|
||||
const valueHashes = ServiceAgreement.createValueHashes(values)
|
||||
|
||||
const serviceAgreement: ServiceAgreementContract = await ServiceAgreementContract.getInstance()
|
||||
|
||||
const executeAgreementReceipt = await serviceAgreement.executeAgreement(
|
||||
serviceAgreementTemplate.getId(), serviceAgreementHashSignature, consumer.getId(), valueHashes,
|
||||
timeoutValues, serviceAgreementId, did, publisher.getId())
|
||||
|
||||
if (executeAgreementReceipt.events.ExecuteAgreement.returnValues.state === false) {
|
||||
throw new Error("signing service agreement failed.")
|
||||
}
|
||||
|
||||
return new ServiceAgreement(
|
||||
serviceAgreementId,
|
||||
publisher,
|
||||
serviceAgreementTemplate,
|
||||
consumer,
|
||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.state,
|
||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.status,
|
||||
)
|
||||
}
|
||||
|
||||
private static createValueHashes(values: any[]): any[] {
|
||||
return values.map((value) => {
|
||||
return ServiceAgreement.hashSingleValue(value.type, value.value)
|
||||
})
|
||||
}
|
||||
|
||||
private static hashSingleValue(type: string, value: any): string {
|
||||
const args = {type, value}
|
||||
return Web3Provider.getWeb3().utils.soliditySha3(args).toString("hex")
|
||||
}
|
||||
|
||||
private static async createSAHashSignature(serviceAgreementTemplate: ServiceAgreementTemplate,
|
||||
serviceAgreementId: string, values: any[], timeoutValues: number[],
|
||||
consumer: Account): Promise<string> {
|
||||
|
||||
const valueHashes = ServiceAgreement.createValueHashes(values)
|
||||
|
||||
const serviceAgreementHash = ServiceAgreement.hashServiceAgreement(serviceAgreementTemplate, valueHashes,
|
||||
timeoutValues, serviceAgreementId)
|
||||
const serviceAgreementHashSignature =
|
||||
await Web3Provider.getWeb3().eth.sign(serviceAgreementHash, consumer.getId())
|
||||
|
||||
return serviceAgreementHashSignature
|
||||
}
|
||||
|
||||
private static hashServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, valueHashes: string[],
|
||||
timeouts: number[], serviceAgreementId: string) {
|
||||
const args = [
|
||||
{type: "bytes32", value: serviceAgreementTemplate.getId()},
|
||||
{type: "bytes32[]", value: serviceAgreementTemplate.getConditionKeys()},
|
||||
{type: "bytes32[]", value: valueHashes},
|
||||
{type: "uint256[]", value: timeouts},
|
||||
{type: "bytes32", value: "0x" + serviceAgreementId},
|
||||
]
|
||||
|
||||
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
|
||||
}
|
||||
|
||||
private constructor(id: string, private publisher: Account, serviceAgreementTemplate: ServiceAgreementTemplate,
|
||||
consumer: Account, state: boolean, status: boolean) {
|
||||
super(id)
|
||||
}
|
||||
|
||||
public async grantAccess(assetId: string, documentId: string): Promise<boolean> {
|
||||
const accessConditions: AccessConditions = await AccessConditions.getInstance()
|
||||
|
||||
const grantAccessReceipt =
|
||||
await accessConditions.grantAccess(this.getId(), assetId, documentId, this.publisher.getId())
|
||||
|
||||
return grantAccessReceipt.status
|
||||
}
|
||||
|
||||
public async getStatus() {
|
||||
const serviceAgreement = await ServiceAgreementContract.getInstance()
|
||||
return serviceAgreement.getAgreementStatus(this.getId())
|
||||
}
|
||||
}
|
71
src/ocean/ServiceAgreementTemplate.ts
Normal file
71
src/ocean/ServiceAgreementTemplate.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import ContractReflector from "../keeper/ContractReflector"
|
||||
import ServiceAgreement from "../keeper/contracts/ServiceAgreement"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import MethodReflection from "../models/MethodReflection"
|
||||
import Account from "./Account"
|
||||
import OceanBase from "./OceanBase"
|
||||
|
||||
export default class ServiceAgreementTemplate extends OceanBase {
|
||||
|
||||
public static async registerServiceAgreementsTemplate(serviceName: string, methods: string[],
|
||||
dependencyMatrix: number[], templateOwner: Account):
|
||||
Promise<ServiceAgreementTemplate> {
|
||||
|
||||
const methodReflections: MethodReflection[] =
|
||||
await Promise.all(methods.map(async (method) => {
|
||||
const methodReflection = await
|
||||
ContractReflector.reflectContractMethod(method)
|
||||
return methodReflection
|
||||
}))
|
||||
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
||||
|
||||
const receipt = await serviceAgreement.setupAgreementTemplate(
|
||||
methodReflections, dependencyMatrix,
|
||||
Web3Provider.getWeb3().utils.fromAscii(serviceName),
|
||||
templateOwner.getId())
|
||||
|
||||
const id = receipt.events.SetupAgreementTemplate.returnValues.serviceTemplateId
|
||||
|
||||
return new ServiceAgreementTemplate(
|
||||
id,
|
||||
ServiceAgreementTemplate.generateConditionsKeys(id, methodReflections),
|
||||
templateOwner)
|
||||
}
|
||||
|
||||
private static generateConditionsKeys(serviceAgreementTemplateId: string, methodReflections: MethodReflection[]):
|
||||
string[] {
|
||||
const conditions = []
|
||||
for (const methodReflection of methodReflections) {
|
||||
const values = [
|
||||
{type: "bytes32", value: serviceAgreementTemplateId},
|
||||
{type: "address", value: methodReflection.address},
|
||||
{type: "bytes4", value: methodReflection.signature},
|
||||
]
|
||||
conditions.push(Web3Provider.getWeb3().utils.soliditySha3(...values).toString("hex"))
|
||||
}
|
||||
return conditions
|
||||
}
|
||||
|
||||
private constructor(id, private conditionKeys: string[], private owner: Account) {
|
||||
super(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the status of a service agreement template
|
||||
*/
|
||||
public async getStatus(): Promise<boolean> {
|
||||
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
||||
|
||||
return serviceAgreement.getTemplateStatus(this.getId())
|
||||
}
|
||||
|
||||
public getOwner(): Account {
|
||||
return this.owner
|
||||
}
|
||||
|
||||
public getConditionKeys(): string[] {
|
||||
return this.conditionKeys
|
||||
}
|
||||
}
|
21
src/secretstore/SecretStoreProvider.ts
Normal file
21
src/secretstore/SecretStoreProvider.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import SecretStore from "@oceanprotocol/secret-store-client"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
|
||||
export default class SecretStoreProvider {
|
||||
|
||||
public static setSecretStore(secretStore: SecretStore) {
|
||||
|
||||
SecretStoreProvider.secretStore = secretStore
|
||||
}
|
||||
|
||||
public static getSecretStore() {
|
||||
|
||||
if (!SecretStoreProvider.secretStore) {
|
||||
SecretStoreProvider.secretStore = new SecretStore(ConfigProvider.getConfig())
|
||||
}
|
||||
|
||||
return SecretStoreProvider.secretStore
|
||||
}
|
||||
|
||||
private static secretStore: SecretStore
|
||||
}
|
@ -1,21 +1,20 @@
|
||||
import * as assert from "assert"
|
||||
import Aquarius from "../../src/aquarius/Aquarius"
|
||||
import AquariusConnectorProvider from "../../src/aquarius/AquariusConnectorProvider"
|
||||
import SearchQuery from "../../src/aquarius/query/SearchQuery"
|
||||
import DDO from "../../src/ddo/DDO"
|
||||
import IdGenerator from "../../src/ocean/IdGenerator"
|
||||
import config from "../config"
|
||||
import AquariusConnectorMock from "../mocks/AquariusConnector.mock"
|
||||
|
||||
before(() => {
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock())
|
||||
})
|
||||
// import * as jsonDDO from "../testdata/ddo.json"
|
||||
|
||||
describe("Aquarius", () => {
|
||||
|
||||
const aquarius: Aquarius = new Aquarius(config)
|
||||
describe("#queryMetadata()", () => {
|
||||
|
||||
it("should query metadata", async () => {
|
||||
|
||||
const aquarius: Aquarius = new Aquarius(config)
|
||||
|
||||
const query = {
|
||||
offset: 100,
|
||||
page: 0,
|
||||
@ -26,11 +25,84 @@ describe("Aquarius", () => {
|
||||
value: 1,
|
||||
},
|
||||
text: "Office",
|
||||
}
|
||||
} as SearchQuery
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock())
|
||||
|
||||
const result: any[] = await aquarius.queryMetadata(query)
|
||||
assert(result)
|
||||
assert(result.length !== null)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#queryMetadataByText()", () => {
|
||||
|
||||
it("should query metadata by text", async () => {
|
||||
|
||||
const query = {
|
||||
offset: 100,
|
||||
page: 0,
|
||||
query: {
|
||||
value: 1,
|
||||
},
|
||||
sort: {
|
||||
value: 1,
|
||||
},
|
||||
text: "Office",
|
||||
} as SearchQuery
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock())
|
||||
|
||||
const result: any[] = await aquarius.queryMetadataByText(query)
|
||||
assert(result)
|
||||
assert(result.length !== null)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#storeDDO()", () => {
|
||||
|
||||
it("should store a ddo", async () => {
|
||||
|
||||
const did: string = `did:op:${IdGenerator.generateId()}`
|
||||
const ddo: DDO = new DDO({
|
||||
id: did,
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
|
||||
const result: DDO = await aquarius.storeDDO(ddo)
|
||||
assert(result)
|
||||
assert(result.id === ddo.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#retrieveDDO()", () => {
|
||||
|
||||
it("should store a ddo", async () => {
|
||||
|
||||
const did: string = `did:op:${IdGenerator.generateId()}`
|
||||
const ddo: DDO = new DDO({
|
||||
id: did,
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
|
||||
const storageResult: DDO = await aquarius.storeDDO(ddo)
|
||||
assert(storageResult)
|
||||
|
||||
assert(storageResult.id === did)
|
||||
|
||||
const restrieveResult: DDO = await aquarius.retrieveDDO(did)
|
||||
assert(restrieveResult)
|
||||
|
||||
assert(restrieveResult.id === did)
|
||||
assert(restrieveResult.id === storageResult.id)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -3,5 +3,10 @@ import Config from "../src/models/Config"
|
||||
export default {
|
||||
aquariusUri: "http://localhost:5000",
|
||||
nodeUri: "http://localhost:8545",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "https://secret-store.dev-ocean.com",
|
||||
threshold: 2,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
web3Provider: null,
|
||||
} as Config
|
||||
|
213
test/ddo/DDO.test.ts
Normal file
213
test/ddo/DDO.test.ts
Normal file
@ -0,0 +1,213 @@
|
||||
import {assert} from "chai"
|
||||
import AdditionalInformation from "../../src/ddo/AdditionalInformation"
|
||||
import Authentication from "../../src/ddo/Authentication"
|
||||
import Curation from "../../src/ddo/Curation"
|
||||
import DDO from "../../src/ddo/DDO"
|
||||
import MetaData from "../../src/ddo/MetaData"
|
||||
import MetaDataBase from "../../src/ddo/MetaDataBase"
|
||||
import PublicKey from "../../src/ddo/PublicKey"
|
||||
import Service from "../../src/ddo/Service"
|
||||
import StructuredMarkup from "../../src/ddo/StructuredMarkup"
|
||||
import * as jsonDDO from "../testdata/ddo.json"
|
||||
|
||||
describe("DDO", () => {
|
||||
|
||||
const testDDO: DDO = new DDO({
|
||||
publicKey: [
|
||||
{
|
||||
id: "did:op:123456789abcdefghi#keys-1",
|
||||
type: "RsaVerificationKey2018",
|
||||
owner: "did:op:123456789abcdefghi",
|
||||
publicKeyPem: "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n",
|
||||
} as PublicKey,
|
||||
{
|
||||
id: "did:op:123456789abcdefghi#keys-2",
|
||||
type: "Ed25519VerificationKey2018",
|
||||
owner: "did:op:123456789abcdefghi",
|
||||
publicKeyBase58: "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV",
|
||||
} as PublicKey,
|
||||
{
|
||||
id: "did:op:123456789abcdefghi#keys-3",
|
||||
type: "RsaPublicKeyExchangeKey2018",
|
||||
owner: "did:op:123456789abcdefghi",
|
||||
publicKeyPem: "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n",
|
||||
} as PublicKey,
|
||||
],
|
||||
authentication: [
|
||||
{
|
||||
type: "RsaSignatureAuthentication2018",
|
||||
publicKey: "did:op:123456789abcdefghi#keys-1",
|
||||
} as Authentication,
|
||||
{
|
||||
type: "ieee2410Authentication2018",
|
||||
publicKey: "did:op:123456789abcdefghi#keys-2",
|
||||
} as Authentication,
|
||||
],
|
||||
service: [
|
||||
{
|
||||
type: "OpenIdConnectVersion1.0Service",
|
||||
serviceEndpoint: "https://openid.example.com/",
|
||||
} as Service,
|
||||
{
|
||||
type: "CredentialRepositoryService",
|
||||
serviceEndpoint: "https://repository.example.com/service/8377464",
|
||||
} as Service,
|
||||
{
|
||||
type: "XdiService",
|
||||
serviceEndpoint: "https://xdi.example.com/8377464",
|
||||
} as Service,
|
||||
{
|
||||
type: "HubService",
|
||||
serviceEndpoint: "https://hub.example.com/.identity/did:op:0123456789abcdef/",
|
||||
} as Service,
|
||||
{
|
||||
type: "MessagingService",
|
||||
serviceEndpoint: "https://example.com/messages/8377464",
|
||||
} as Service,
|
||||
{
|
||||
type: "SocialWebInboxService",
|
||||
serviceEndpoint: "https://social.example.com/83hfh37dj",
|
||||
description: "My public social inbox",
|
||||
spamCost: {
|
||||
amount: "0.50",
|
||||
currency: "USD",
|
||||
},
|
||||
} as Service,
|
||||
{
|
||||
id: "did:op:123456789abcdefghi;bops",
|
||||
type: "BopsService",
|
||||
serviceEndpoint: "https://bops.example.com/enterprise/",
|
||||
} as Service,
|
||||
{
|
||||
type: "Consume",
|
||||
// tslint:disable
|
||||
serviceEndpoint: "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}",
|
||||
} as Service,
|
||||
{
|
||||
type: "Compute",
|
||||
serviceEndpoint: "http://mybrizo.org/api/v1/brizo/services/compute?pubKey=${pubKey}&serviceId={serviceId}&algo={algo}&container={container}",
|
||||
} as Service,
|
||||
{
|
||||
type: "Metadata",
|
||||
serviceEndpoint: "http://myaquarius.org/api/v1/provider/assets/metadata/{did}",
|
||||
metadata: {
|
||||
base: {
|
||||
name: "UK Weather information 2011",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-10-10T17:00:000Z",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
workExample: "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip"
|
||||
],
|
||||
links: [
|
||||
{
|
||||
sample1: "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/"
|
||||
},
|
||||
{
|
||||
sample2: "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/"
|
||||
},
|
||||
{
|
||||
fieldsDescription: "http://data.ceda.ac.uk/badc/ukcp09/"
|
||||
}
|
||||
],
|
||||
inLanguage: "en",
|
||||
tags: "weather, uk, 2011, temperature, humidity",
|
||||
price: 10
|
||||
} as MetaDataBase,
|
||||
curation: {
|
||||
"rating": 0.93,
|
||||
"numVotes": 123,
|
||||
"schema": "Binary Votting"
|
||||
} as Curation,
|
||||
additionalInformation: {
|
||||
updateFrecuency: "yearly",
|
||||
structuredMarkup: [
|
||||
{
|
||||
"uri": "http://skos.um.es/unescothes/C01194/jsonld",
|
||||
"mediaType": "application/ld+json"
|
||||
} as StructuredMarkup,
|
||||
{
|
||||
"uri": "http://skos.um.es/unescothes/C01194/turtle",
|
||||
"mediaType": "text/turtle"
|
||||
} as StructuredMarkup
|
||||
]
|
||||
} as AdditionalInformation
|
||||
} as MetaData
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
describe("#serialize()", () => {
|
||||
|
||||
it("should properly serialize", async () => {
|
||||
|
||||
const ddoString = DDO.serialize(testDDO)
|
||||
assert(ddoString)
|
||||
assert(ddoString.startsWith("{"))
|
||||
})
|
||||
})
|
||||
|
||||
describe("#constructor()", () => {
|
||||
|
||||
it("should create an empty ddo", async () => {
|
||||
|
||||
const ddo = new DDO()
|
||||
assert(ddo)
|
||||
|
||||
assert(ddo.service.length === 0)
|
||||
assert(ddo.authentication.length === 0)
|
||||
assert(ddo.publicKey.length === 0)
|
||||
})
|
||||
|
||||
it("should create an predefined ddo", async () => {
|
||||
|
||||
const service: Service = {
|
||||
serviceEndpoint: "http://",
|
||||
description: "nice service"
|
||||
} as Service
|
||||
|
||||
const ddo = new DDO({
|
||||
service: [service]
|
||||
})
|
||||
assert(ddo)
|
||||
|
||||
assert(ddo.service.length === 1)
|
||||
assert(ddo.service[0].description === service.description)
|
||||
|
||||
assert(ddo.authentication.length === 0)
|
||||
assert(ddo.publicKey.length === 0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#deserialize()", () => {
|
||||
|
||||
it("should properly deserialize from serialized object", async () => {
|
||||
|
||||
const ddoString = DDO.serialize(testDDO)
|
||||
assert(ddoString)
|
||||
|
||||
const ddo: DDO = DDO.deserialize(ddoString)
|
||||
assert(ddo)
|
||||
|
||||
assert(ddo.id == testDDO.id)
|
||||
assert(ddo.publicKey[0].publicKeyPem == testDDO.publicKey[0].publicKeyPem)
|
||||
})
|
||||
|
||||
it("should properly deserialize from json file", async () => {
|
||||
|
||||
const ddo: DDO = DDO.deserialize(JSON.stringify(jsonDDO))
|
||||
assert(ddo)
|
||||
|
||||
assert(ddo.id == jsonDDO.id)
|
||||
assert(ddo.publicKey[0].publicKeyPem == jsonDDO.publicKey[0].publicKeyPem)
|
||||
})
|
||||
})
|
||||
})
|
@ -1,16 +1,22 @@
|
||||
import {assert} from "chai"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import config from "../config"
|
||||
import ContractBaseMock from "../mocks/ContractBase.Mock"
|
||||
|
||||
const wrappedContract = new ContractBaseMock("OceanToken")
|
||||
let accounts: Account[]
|
||||
|
||||
describe("ContractWrapperBase", () => {
|
||||
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
await ContractHandler.deployContracts()
|
||||
wrappedContract.initMock()
|
||||
await wrappedContract.initMock()
|
||||
const ocean: Ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
})
|
||||
|
||||
describe("#call()", () => {
|
||||
@ -52,6 +58,29 @@ describe("ContractWrapperBase", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#send()", () => {
|
||||
|
||||
it("should fail to call on an unknown contract function", (done) => {
|
||||
|
||||
wrappedContract.sendMock("transferxxx", accounts[0].getId(), [])
|
||||
.catch(() => {
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getSignatureOfMethod()", () => {
|
||||
|
||||
it("should a signature of the function", async () => {
|
||||
|
||||
const sig = wrappedContract.getSignatureOfMethod("name")
|
||||
assert(sig)
|
||||
assert(typeof sig === "string")
|
||||
assert(sig.startsWith("0x"))
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getEventData()", () => {
|
||||
|
||||
it("should fail on unknown event", (done) => {
|
||||
|
101
test/keeper/DIDRegistry.test.ts
Normal file
101
test/keeper/DIDRegistry.test.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import {assert} from "chai"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import DIDRegistry from "../../src/keeper/contracts/DIDRegistry"
|
||||
import Web3Provider from "../../src/keeper/Web3Provider"
|
||||
import ValueType from "../../src/models/ValueType"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import IdGenerator from "../../src/ocean/IdGenerator"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import Logger from "../../src/utils/Logger"
|
||||
import config from "../config"
|
||||
|
||||
let ocean: Ocean
|
||||
let didRegistry: DIDRegistry
|
||||
|
||||
describe("DIDRegistry", () => {
|
||||
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
didRegistry = await DIDRegistry.getInstance()
|
||||
})
|
||||
|
||||
describe("#registerAttribute()", () => {
|
||||
|
||||
it("should register an attribute in a new did", async () => {
|
||||
const ownerAccount: Account = (await ocean.getAccounts())[0]
|
||||
const did = IdGenerator.generateId()
|
||||
const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider")
|
||||
const data = "my nice provider, is nice"
|
||||
const receipt = await didRegistry.registerAttribute(did, ValueType.DID, providerKey,
|
||||
data, ownerAccount.getId())
|
||||
assert(receipt.status)
|
||||
assert(receipt.events.DIDAttributeRegistered)
|
||||
})
|
||||
|
||||
it("should register another attribute in the same did", async () => {
|
||||
const ownerAccount: Account = (await ocean.getAccounts())[0]
|
||||
const did = IdGenerator.generateId()
|
||||
{
|
||||
// register the first attribute
|
||||
const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider")
|
||||
const data = "my nice provider, is nice"
|
||||
await didRegistry.registerAttribute(did, ValueType.DID, providerKey,
|
||||
data, ownerAccount.getId())
|
||||
}
|
||||
{
|
||||
// register the second attribute with the same did
|
||||
const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider2")
|
||||
const data = "asdsad"
|
||||
const receipt = await didRegistry.registerAttribute(did, ValueType.DID, providerKey,
|
||||
data, ownerAccount.getId())
|
||||
assert(receipt.status)
|
||||
assert(receipt.events.DIDAttributeRegistered)
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#getOwner()", () => {
|
||||
|
||||
it("should get the owner of a did properly", async () => {
|
||||
const ownerAccount: Account = (await ocean.getAccounts())[0]
|
||||
const did = IdGenerator.generateId()
|
||||
const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider")
|
||||
const data = "my nice provider, is nice"
|
||||
await didRegistry.registerAttribute(did, ValueType.DID, providerKey,
|
||||
data, ownerAccount.getId())
|
||||
|
||||
const owner = await didRegistry.getOwner(did)
|
||||
|
||||
assert(owner === ownerAccount.getId(), `Got ${owner} but expected ${ownerAccount.getId()}`)
|
||||
})
|
||||
|
||||
it("should get 0x00.. for a not registered did", async () => {
|
||||
const owner = await didRegistry.getOwner("1234")
|
||||
assert(owner === "0x0000000000000000000000000000000000000000")
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#getUpdateAt()", () => {
|
||||
|
||||
it("should the block number of the last update of the did attribute", async () => {
|
||||
const ownerAccount: Account = (await ocean.getAccounts())[0]
|
||||
const did = IdGenerator.generateId()
|
||||
const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider")
|
||||
const data = "my nice provider, is nice"
|
||||
await didRegistry.registerAttribute(did, ValueType.DID, providerKey,
|
||||
data, ownerAccount.getId())
|
||||
|
||||
const updatedAt: number = await didRegistry.getUpdateAt(did)
|
||||
|
||||
assert(updatedAt > 0)
|
||||
Logger.log(typeof updatedAt)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
@ -13,7 +13,7 @@ describe("Keeper", () => {
|
||||
await ContractHandler.deployContracts()
|
||||
keeper = await Keeper.getInstance()
|
||||
})
|
||||
|
||||
|
||||
describe("public interface", () => {
|
||||
|
||||
it("should have market", () => {
|
||||
|
@ -1,17 +1,25 @@
|
||||
import AquariusConnector from "../../src/aquarius/AquariusConnector"
|
||||
|
||||
// @ts-ignore
|
||||
export default class AquariusConnectorMock extends AquariusConnector {
|
||||
|
||||
public async post(url: string, payload: any) {
|
||||
constructor(private returnData: any) {
|
||||
super()
|
||||
}
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
json: () => {
|
||||
return []
|
||||
},
|
||||
text: () => {
|
||||
return ""
|
||||
},
|
||||
}
|
||||
// @ts-ignore
|
||||
private async fetch(url, opts): Promise<any> {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({
|
||||
ok: true,
|
||||
json: () => {
|
||||
return this.returnData ? this.returnData : []
|
||||
},
|
||||
text: () => {
|
||||
return this.returnData ? this.returnData.toString() : ""
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import ContractBase from "../../src/keeper/ContractBase"
|
||||
import ContractBase from "../../src/keeper/contracts/ContractBase"
|
||||
|
||||
export default class ContractBaseMock extends ContractBase {
|
||||
public async initMock() {
|
||||
this.init()
|
||||
await this.init()
|
||||
}
|
||||
|
||||
public async callMock(name: string, args: any[], from?: string) {
|
||||
@ -10,6 +10,6 @@ export default class ContractBaseMock extends ContractBase {
|
||||
}
|
||||
|
||||
public async sendMock(name: string, from: string, args: any[]) {
|
||||
return this.sendTransaction(name, from, args)
|
||||
return this.send(name, from, args)
|
||||
}
|
||||
}
|
||||
|
16
test/mocks/SecretStore.mock.ts
Normal file
16
test/mocks/SecretStore.mock.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import SecretStore from "@oceanprotocol/secret-store-client"
|
||||
|
||||
export default class SecretStoreMock extends SecretStore {
|
||||
|
||||
public async encryptDocument(documentId, document: any) {
|
||||
|
||||
return "0x283asdgahd1t371t23h"
|
||||
}
|
||||
|
||||
public async decryptDocument(documentId, encryptedDocument: any) {
|
||||
|
||||
return {
|
||||
doc: "test",
|
||||
}
|
||||
}
|
||||
}
|
@ -6,8 +6,10 @@ import Account from "../../src/ocean/Account"
|
||||
import Asset from "../../src/ocean/Asset"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import Order from "../../src/ocean/Order"
|
||||
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
||||
import config from "../config"
|
||||
import AquariusMock from "../mocks/Aquarius.mock"
|
||||
import SecretStoreMock from "../mocks/SecretStore.mock"
|
||||
|
||||
const testName = "Test Asset 2"
|
||||
const testDescription = "This asset is pure owange"
|
||||
@ -24,7 +26,7 @@ describe("Asset", () => {
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
AquariusProvider.setAquarius(new AquariusMock(config))
|
||||
|
||||
SecretStoreProvider.setSecretStore(new SecretStoreMock(config))
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
|
26
test/ocean/IdGenerator.test.ts
Normal file
26
test/ocean/IdGenerator.test.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as assert from "assert"
|
||||
import IdGenerator from "../../src/ocean/IdGenerator"
|
||||
|
||||
describe("IdGenerator", () => {
|
||||
|
||||
describe("#generateId()", () => {
|
||||
|
||||
it("should generate an id", async () => {
|
||||
|
||||
const id = IdGenerator.generateId()
|
||||
assert(id)
|
||||
})
|
||||
|
||||
it("should generate an id that is 64 chars long", async () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
assert(id.length === 64, id)
|
||||
})
|
||||
|
||||
it("should not contain -", async () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
assert(id.indexOf("-") === -1)
|
||||
})
|
||||
})
|
||||
})
|
@ -6,8 +6,10 @@ import Account from "../../src/ocean/Account"
|
||||
import Asset from "../../src/ocean/Asset"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import Order from "../../src/ocean/Order"
|
||||
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
||||
import config from "../config"
|
||||
import AquariusMock from "../mocks/Aquarius.mock"
|
||||
import SecretStoreMock from "../mocks/SecretStore.mock"
|
||||
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
@ -24,6 +26,7 @@ describe("Ocean", () => {
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
AquariusProvider.setAquarius(new AquariusMock(config))
|
||||
SecretStoreProvider.setSecretStore(new SecretStoreMock(config))
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
@ -62,10 +65,9 @@ describe("Ocean", () => {
|
||||
|
||||
const assetId: string = await ocean.register(testAsset)
|
||||
|
||||
assert(assetId.length === 66)
|
||||
assert(assetId.startsWith("0x"))
|
||||
assert(assetId.length === 64)
|
||||
assert(!assetId.startsWith("0x"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#getOrdersByConsumer()", () => {
|
||||
@ -82,7 +84,6 @@ describe("Ocean", () => {
|
||||
|
||||
assert(orders.length === 1)
|
||||
assert(orders[0].getId() === order.getId())
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -9,12 +9,12 @@ import Ocean from "../../src/ocean/Ocean"
|
||||
import Order from "../../src/ocean/Order"
|
||||
import config from "../config"
|
||||
import AquariusMock from "../mocks/Aquarius.mock"
|
||||
import * as AccessToken from "../testdata/AccessToken.json"
|
||||
|
||||
const testName = "Order Test Asset"
|
||||
const testDescription = "This asset is pure owange"
|
||||
const testPrice = 100
|
||||
const timeout = 1000000
|
||||
const accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1Mzk3ODcxMDEsImV4cCI6NDcyNjk5NjcwNCwiYXVkIjoiIiwic3ViIjoiIiwic2VydmljZV9lbmRwb2ludCI6Imh0dHA6Ly9hZGFzZCIsInJlc291cmNlX2lkIjoiMTIzNDUifQ.2H3TRC3CAToVE9divSckwHi_HNvgOHKrtJPo8128qrKBHTk7YYb0UNfVCuYqwhGR"
|
||||
|
||||
let ocean: Ocean
|
||||
let testAsset: Asset
|
||||
@ -44,7 +44,7 @@ describe("Order", () => {
|
||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
||||
assert(order)
|
||||
|
||||
await order.commit(accessToken)
|
||||
await order.commit(AccessToken.toString())
|
||||
await testConsumer.requestTokens(testAsset.price)
|
||||
const paymentId: string = await order.pay(testConsumer)
|
||||
assert(paymentId)
|
||||
@ -59,7 +59,7 @@ describe("Order", () => {
|
||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
||||
assert(order)
|
||||
|
||||
await order.commit(accessToken)
|
||||
await order.commit(AccessToken.toString())
|
||||
})
|
||||
})
|
||||
|
||||
@ -79,7 +79,7 @@ describe("Order", () => {
|
||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
||||
assert(order)
|
||||
|
||||
await order.commit(accessToken)
|
||||
await order.commit(AccessToken.toString())
|
||||
|
||||
const status: AccessStatus = await order.getStatus()
|
||||
assert(status === AccessStatus.Delivered)
|
||||
@ -94,7 +94,7 @@ describe("Order", () => {
|
||||
// place order - consumer
|
||||
const order: Order = await testAsset.purchase(consumerAccount, timeout)
|
||||
// commit order - provider
|
||||
await order.commit(accessToken)
|
||||
await order.commit(AccessToken.toString())
|
||||
// pay order - consumer
|
||||
await order.pay(consumerAccount)
|
||||
const url = await order.consume(consumerAccount)
|
||||
|
94
test/ocean/ServiceAgreement.test.ts
Normal file
94
test/ocean/ServiceAgreement.test.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import {assert} from "chai"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import IdGenerator from "../../src/ocean/IdGenerator"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import ServiceAgreement from "../../src/ocean/ServiceAgreement"
|
||||
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreementTemplate"
|
||||
import config from "../config"
|
||||
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
let publisherAccount: Account
|
||||
let templateOwnerAccount: Account
|
||||
let consumerAccount: Account
|
||||
|
||||
let testServiceAgreementTemplate: ServiceAgreementTemplate
|
||||
|
||||
describe("ServiceAgreement", () => {
|
||||
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
|
||||
templateOwnerAccount = accounts[0]
|
||||
publisherAccount = accounts[1]
|
||||
consumerAccount = accounts[2]
|
||||
|
||||
const resourceName = "superb car data"
|
||||
const methods: string[] = [
|
||||
"PaymentConditions.lockPayment",
|
||||
"AccessConditions.grantAccess",
|
||||
"PaymentConditions.releasePayment",
|
||||
"PaymentConditions.refundPayment",
|
||||
]
|
||||
// tslint:disable
|
||||
const dependencyMatrix = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
||||
|
||||
testServiceAgreementTemplate =
|
||||
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, methods,
|
||||
dependencyMatrix, templateOwnerAccount)
|
||||
})
|
||||
|
||||
describe("#createServiceAgreement()", () => {
|
||||
it("should execute an service agreement", async () => {
|
||||
|
||||
const did: string = IdGenerator.generateId()
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.createServiceAgreement(testServiceAgreementTemplate, assetId, did,
|
||||
consumerAccount, publisherAccount)
|
||||
|
||||
assert(serviceAgreement)
|
||||
const id = serviceAgreement.getId()
|
||||
assert(id)
|
||||
assert(id !== did)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getStatus()", () => {
|
||||
it("should get the status of a newly created service agreement", async () => {
|
||||
|
||||
const did: string = IdGenerator.generateId()
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.createServiceAgreement(testServiceAgreementTemplate, assetId, did,
|
||||
consumerAccount, publisherAccount)
|
||||
|
||||
assert(serviceAgreement)
|
||||
const status = await serviceAgreement.getStatus()
|
||||
assert(status === false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#grantAccess()", () => {
|
||||
it("should grant access in that service agreement", async () => {
|
||||
|
||||
const did: string = IdGenerator.generateId()
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.createServiceAgreement(testServiceAgreementTemplate, assetId, did,
|
||||
consumerAccount, publisherAccount)
|
||||
assert(serviceAgreement)
|
||||
|
||||
const fulfilled: boolean = await serviceAgreement.grantAccess(did, IdGenerator.generateId())
|
||||
assert(fulfilled)
|
||||
})
|
||||
})
|
||||
})
|
60
test/ocean/ServiceAgreementTemplate.test.ts
Normal file
60
test/ocean/ServiceAgreementTemplate.test.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import {assert} from "chai"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreementTemplate"
|
||||
import config from "../config"
|
||||
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
const methods: string[] = [
|
||||
"PaymentConditions.lockPayment",
|
||||
"AccessConditions.grantAccess",
|
||||
"PaymentConditions.releasePayment",
|
||||
"PaymentConditions.refundPayment",
|
||||
]
|
||||
// tslint:disable
|
||||
const dependencyMatrix = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
||||
|
||||
describe("ServiceAgreementTemplate", () => {
|
||||
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
})
|
||||
|
||||
describe("#registerServiceAgreementsTemplate()", () => {
|
||||
it("should setup an agreement template", async () => {
|
||||
|
||||
const templateOwner = accounts[0]
|
||||
const resourceName = "consume"
|
||||
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
||||
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, methods,
|
||||
dependencyMatrix, templateOwner)
|
||||
|
||||
assert(serviceAgreementTemplate)
|
||||
assert(serviceAgreementTemplate.getId())
|
||||
assert(serviceAgreementTemplate.getOwner().getId() === templateOwner.getId())
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getStatus()", () => {
|
||||
it("should get the status of a newly deployed agreement template", async () => {
|
||||
|
||||
const publisherAccount = accounts[0]
|
||||
const resourceName = "consume"
|
||||
|
||||
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
||||
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, methods,
|
||||
dependencyMatrix, publisherAccount)
|
||||
assert(serviceAgreementTemplate)
|
||||
|
||||
const templateStatus = await serviceAgreementTemplate.getStatus()
|
||||
assert(templateStatus === true)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
1
test/testdata/AccessToken.json
vendored
Normal file
1
test/testdata/AccessToken.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1Mzk3ODcxMDEsImV4cCI6NDcyNjk5NjcwNCwiYXVkIjoiIiwic3ViIjoiIiwic2VydmljZV9lbmRwb2ludCI6Imh0dHA6Ly9hZGFzZCIsInJlc291cmNlX2lkIjoiMTIzNDUifQ.2H3TRC3CAToVE9divSckwHi_HNvgOHKrtJPo8128qrKBHTk7YYb0UNfVCuYqwhGR"
|
133
test/testdata/ddo.json
vendored
Normal file
133
test/testdata/ddo.json
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
{
|
||||
"@context": "https://w3id.org/future-method/v1",
|
||||
"id": "did:op:123456789abcdefghi",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"service": [
|
||||
{
|
||||
"type": "OpenIdConnectVersion1.0Service",
|
||||
"serviceEndpoint": "https://openid.example.com/"
|
||||
},
|
||||
{
|
||||
"type": "CredentialRepositoryService",
|
||||
"serviceEndpoint": "https://repository.example.com/service/8377464"
|
||||
},
|
||||
{
|
||||
"type": "XdiService",
|
||||
"serviceEndpoint": "https://xdi.example.com/8377464"
|
||||
},
|
||||
{
|
||||
"type": "HubService",
|
||||
"serviceEndpoint": "https://hub.example.com/.identity/did:op:0123456789abcdef/"
|
||||
},
|
||||
{
|
||||
"type": "MessagingService",
|
||||
"serviceEndpoint": "https://example.com/messages/8377464"
|
||||
},
|
||||
{
|
||||
"type": "SocialWebInboxService",
|
||||
"serviceEndpoint": "https://social.example.com/83hfh37dj",
|
||||
"description": "My public social inbox",
|
||||
"spamCost": {
|
||||
"amount": "0.50",
|
||||
"currency": "USD"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "did:op:123456789abcdefghi;bops",
|
||||
"type": "BopsService",
|
||||
"serviceEndpoint": "https://bops.example.com/enterprise/"
|
||||
},
|
||||
{
|
||||
"type": "Consume",
|
||||
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}"
|
||||
},
|
||||
{
|
||||
"type": "Compute",
|
||||
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/compute?pubKey=${pubKey}&serviceId={serviceId}&algo={algo}&container={container}"
|
||||
},
|
||||
{
|
||||
"type": "Metadata",
|
||||
"serviceEndpoint": "http://myaquarius.org/api/v1/provider/assets/metadata/{did}",
|
||||
"metadata": {
|
||||
"base": {
|
||||
"name": "UK Weather information 2011",
|
||||
"type": "dataset",
|
||||
"description": "Weather information of UK including temperature and humidity",
|
||||
"size": "3.1gb",
|
||||
"dateCreated": "2012-10-10T17:00:000Z",
|
||||
"author": "Met Office",
|
||||
"license": "CC-BY",
|
||||
"copyrightHolder": "Met Office",
|
||||
"encoding": "UTF-8",
|
||||
"compression": "zip",
|
||||
"contentType": "text/csv",
|
||||
"workExample": "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
"contentUrls": [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"sample1": "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/"
|
||||
},
|
||||
{
|
||||
"sample2": "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/"
|
||||
},
|
||||
{
|
||||
"fieldsDescription": "http://data.ceda.ac.uk/badc/ukcp09/"
|
||||
}
|
||||
],
|
||||
"inLanguage": "en",
|
||||
"tags": "weather, uk, 2011, temperature, humidity",
|
||||
"price": 10
|
||||
},
|
||||
"curation": {
|
||||
"rating": 0.93,
|
||||
"numVotes": 123,
|
||||
"schema": "Binary Votting"
|
||||
},
|
||||
"additionalInformation": {
|
||||
"updateFrecuency": "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,5 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true,
|
||||
"lib": [
|
||||
"es6",
|
||||
"es7"
|
||||
|
Loading…
Reference in New Issue
Block a user