mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
Merge pull request #45 from oceanprotocol/feature/sa_register
Feature/sa register
This commit is contained in:
commit
484ec08d61
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.1.7
|
||||
current_version = 0.1.21
|
||||
|
||||
[bumpversion:file:package.json]
|
||||
|
||||
|
@ -14,7 +14,7 @@ matrix:
|
||||
|
||||
before_install:
|
||||
- npm install -g npm
|
||||
- npm install -g release-it greenkeeper-lockfile ganache-cli
|
||||
- npm install -g release-it greenkeeper-lockfile ganache-cli@~6.1.8
|
||||
|
||||
before_script:
|
||||
- greenkeeper-lockfile-update
|
||||
|
77
README.md
77
README.md
@ -21,6 +21,7 @@
|
||||
## Table of Contents
|
||||
|
||||
- [Get started](#get-started)
|
||||
- [Examples](#examples)
|
||||
- [Development](#development)
|
||||
- [Production build](#production-build)
|
||||
- [npm releases](#npm-releases)
|
||||
@ -49,12 +50,31 @@ const { Ocean, Logger } = require('@oceanprotocol/squid')
|
||||
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',
|
||||
aquariusUri: 'http://localhost:5000'
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
// the node of the blockchain to connect to, could also be infura
|
||||
nodeUri: "http://localhost:8545",
|
||||
// the uri of aquarius
|
||||
aquariusUri: "http://localhost:5000",
|
||||
// the uri of brizo
|
||||
brizoUri: "http://localhost:8030",
|
||||
// the uri to the parity node you want to use for encryption and decryption
|
||||
parityUri: "http://localhost:9545",
|
||||
// the uri of the secret store that holds the keys
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
// the threshold of nodes from the secre store that have to agree to the decrypt
|
||||
threshold: 0,
|
||||
// the password for the account (in the local parity node) used to sign messages for secret store
|
||||
password: "unittest",
|
||||
// the address of the account (in the local parity node) used to sign messages for secret store
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
* [Examples](/src/examples/squid)
|
||||
* [Tuna](https://github.com/oceanprotocol/tuna/examples/squid)
|
||||
|
||||
## Development
|
||||
|
||||
To start development you need to:
|
||||
@ -64,6 +84,29 @@ npm i
|
||||
npm start
|
||||
```
|
||||
|
||||
### Test
|
||||
|
||||
To start unit tests you need to:
|
||||
|
||||
```bash
|
||||
ganache-cli &
|
||||
npm run test
|
||||
```
|
||||
|
||||
or to watch for changes
|
||||
|
||||
```bash
|
||||
ganache-cli &
|
||||
npm run test:watch
|
||||
```
|
||||
|
||||
to create code coverage
|
||||
|
||||
```bash
|
||||
ganache-cli &
|
||||
npm run test:cover
|
||||
```
|
||||
|
||||
This will start a watcher for changes of the code.
|
||||
|
||||
### Production build
|
||||
@ -77,34 +120,10 @@ npm run build
|
||||
For a new **patch release**, execute on the machine where you're logged into your npm account:
|
||||
|
||||
```bash
|
||||
npm run release
|
||||
./bumpversion path
|
||||
```
|
||||
|
||||
In case you have 2FA setup on npm.js, pass a code as One Time Password:
|
||||
|
||||
```bash
|
||||
npm run release --otp <yourcode>
|
||||
```
|
||||
|
||||
Command is powered by [`release-it`](https://github.com/webpro/release-it) package, defined in the `package.json`.
|
||||
|
||||
That's what the command does without any user interaction:
|
||||
|
||||
- create release commit by updating version in `package.json`
|
||||
- create tag for that release commit
|
||||
- push commit & tag
|
||||
- create a new release on GitHub, with change log auto-generated from commit messages
|
||||
- publish to npm as a new release
|
||||
|
||||
If you want to create a **minor** or **major release**, use these commands:
|
||||
|
||||
```bash
|
||||
npm run release-minor
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run release-major
|
||||
```
|
||||
git tag with the latest version and `git push`
|
||||
|
||||
## License
|
||||
|
||||
|
2746
package-lock.json
generated
2746
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oceanprotocol/squid",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.21",
|
||||
"description": "JavaScript client library for Ocean Protocol",
|
||||
"main": "dist/squid.js",
|
||||
"scripts": {
|
||||
@ -47,18 +47,15 @@
|
||||
"url": "https://github.com/oceanprotocol/squid-js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/oceanprotocol/squid-js#readme",
|
||||
"engines": {
|
||||
"node": ">=8 <10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/keeper-contracts": "0.3.19",
|
||||
"@oceanprotocol/secret-store-client": "0.0.11",
|
||||
"@oceanprotocol/keeper-contracts": "0.3.22",
|
||||
"@oceanprotocol/secret-store-client": "0.0.12",
|
||||
"bignumber.js": "^8.0.1",
|
||||
"eth-crypto": "^1.2.5",
|
||||
"eth-crypto": "^1.2.7",
|
||||
"eth-ecies": "^1.0.3",
|
||||
"ethereumjs-util": "^6.0.0",
|
||||
"jsonwebtoken": "^8.3.0",
|
||||
"node-fetch": "^2.2.1",
|
||||
"jsonwebtoken": "^8.4.0",
|
||||
"node-fetch": "^2.3.0",
|
||||
"uuid": "^3.3.2",
|
||||
"web3": "1.0.0-beta.36",
|
||||
"web3-utils": "1.0.0-beta.36",
|
||||
@ -67,7 +64,7 @@
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.12.6",
|
||||
"@types/node": "^10.12.7",
|
||||
"chai": "^4.2.0",
|
||||
"mocha": "^5.2.0",
|
||||
"nyc": "^13.1.0",
|
||||
|
@ -2,9 +2,11 @@ import {URL} from "whatwg-url"
|
||||
import DDO from "../ddo/DDO"
|
||||
import Config from "../models/Config"
|
||||
import Logger from "../utils/Logger"
|
||||
import AquariusConnectorProvider from "./AquariusConnectorProvider"
|
||||
import WebServiceConnectorProvider from "../utils/WebServiceConnectorProvider"
|
||||
import SearchQuery from "./query/SearchQuery"
|
||||
|
||||
const apiPath = "/api/v1/aquarius/assets/ddo"
|
||||
|
||||
export default class Aquarius {
|
||||
|
||||
private url: string
|
||||
@ -16,7 +18,7 @@ export default class Aquarius {
|
||||
|
||||
public async getAccessUrl(accessToken: any, payload: any): Promise<string> {
|
||||
|
||||
const accessUrl: string = await AquariusConnectorProvider.getConnector()
|
||||
const accessUrl: string = await WebServiceConnectorProvider.getConnector()
|
||||
.post(`${accessToken.service_endpoint}/${accessToken.resource_id}`, payload)
|
||||
.then((response: any): string => {
|
||||
if (response.ok) {
|
||||
@ -37,78 +39,98 @@ export default class Aquarius {
|
||||
return accessUrl
|
||||
}
|
||||
|
||||
public async queryMetadata(query: SearchQuery): Promise<any[]> {
|
||||
public async queryMetadata(query: SearchQuery): Promise<DDO[]> {
|
||||
|
||||
const result = await AquariusConnectorProvider.getConnector()
|
||||
.post(this.url + "/api/v1/aquarius/assets/ddo/query", JSON.stringify(query))
|
||||
const result: DDO[] = await WebServiceConnectorProvider.getConnector()
|
||||
.post(`${this.url}${apiPath}/query`, JSON.stringify(query))
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
return response.json() as DDO[]
|
||||
}
|
||||
Logger.error("queryMetadata failed:", response.status, response.statusText)
|
||||
return null
|
||||
return [] as DDO[]
|
||||
})
|
||||
.then((ddos) => {
|
||||
return ddos.map((ddo): DDO => {
|
||||
return new DDO(ddo as DDO)
|
||||
})
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching querying metadata: ", error)
|
||||
return [] as DDO[]
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public async queryMetadataByText(query: SearchQuery): Promise<any[]> {
|
||||
public async queryMetadataByText(query: SearchQuery): Promise<DDO[]> {
|
||||
|
||||
const fullUrl = new URL(this.url + "/api/v1/aquarius/assets/ddo/query")
|
||||
const fullUrl = new URL(`${this.url}${apiPath}/query`)
|
||||
fullUrl.searchParams.append("text", query.text)
|
||||
fullUrl.searchParams.append("sort", JSON.stringify(query.sort))
|
||||
fullUrl.searchParams.append("sort", decodeURIComponent(JSON.stringify(query.sort)))
|
||||
fullUrl.searchParams.append("offset", query.offset.toString())
|
||||
fullUrl.searchParams.append("page", query.page.toString())
|
||||
const result = await AquariusConnectorProvider.getConnector()
|
||||
const result: DDO[] = await WebServiceConnectorProvider.getConnector()
|
||||
.get(fullUrl)
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
return response.json() as DDO[]
|
||||
}
|
||||
Logger.log("queryMetadataByText failed:", response.status, response.statusText)
|
||||
return null
|
||||
return [] as DDO[]
|
||||
})
|
||||
.then((ddos) => {
|
||||
return ddos.map((ddo): DDO => {
|
||||
return new DDO(ddo as DDO)
|
||||
})
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching querying metadata: ", error)
|
||||
Logger.error("Error fetching querying metadata by text: ", error)
|
||||
return [] as DDO[]
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public async storeDDO(ddo: DDO): Promise<DDO> {
|
||||
const fullUrl = this.url + `/api/v1/aquarius/assets/ddo`
|
||||
const result: DDO = await AquariusConnectorProvider.getConnector()
|
||||
const fullUrl = `${this.url}${apiPath}`
|
||||
const result: DDO = await WebServiceConnectorProvider.getConnector()
|
||||
.post(fullUrl, DDO.serialize(ddo))
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
Logger.error("storeDDO failed:", response.status, response.statusText)
|
||||
return null
|
||||
Logger.error("storeDDO failed:", response.status, response.statusText, ddo)
|
||||
return null as DDO
|
||||
})
|
||||
.then((response: DDO) => {
|
||||
return new DDO(response) as DDO
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching querying metadata: ", error)
|
||||
return null as DDO
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public async retrieveDDO(did: string): Promise<DDO> {
|
||||
const fullUrl = this.url + `/api/v1/aquarius/assets/ddo/${did}`
|
||||
const result = await AquariusConnectorProvider.getConnector()
|
||||
const fullUrl = `${this.url}${apiPath}/${did}`
|
||||
const result = await WebServiceConnectorProvider.getConnector()
|
||||
.get(fullUrl)
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
Logger.log("retrieveDDO failed:", response.status, response.statusText)
|
||||
return null
|
||||
Logger.log("retrieveDDO failed:", response.status, response.statusText, did)
|
||||
return null as DDO
|
||||
})
|
||||
.then((response: DDO) => {
|
||||
return new DDO(response) as DDO
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching querying metadata: ", error)
|
||||
return null as DDO
|
||||
})
|
||||
|
||||
return result
|
||||
|
@ -1,19 +0,0 @@
|
||||
import AquariusConnector from "./AquariusConnector"
|
||||
|
||||
export default class AquariusConnectorProvider {
|
||||
|
||||
public static setConnector(connector: AquariusConnector) {
|
||||
|
||||
AquariusConnectorProvider.connector = connector
|
||||
}
|
||||
|
||||
public static getConnector(): AquariusConnector {
|
||||
|
||||
if (!AquariusConnectorProvider.connector) {
|
||||
AquariusConnectorProvider.connector = new AquariusConnector()
|
||||
}
|
||||
return AquariusConnectorProvider.connector
|
||||
}
|
||||
|
||||
private static connector: AquariusConnector = null
|
||||
}
|
43
src/brizo/Brizo.ts
Normal file
43
src/brizo/Brizo.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import Config from "../models/Config"
|
||||
import WebServiceConnectorProvider from "../utils/WebServiceConnectorProvider"
|
||||
|
||||
export default class Brizo {
|
||||
private url: string
|
||||
|
||||
constructor(config: Config) {
|
||||
|
||||
this.url = config.brizoUri
|
||||
}
|
||||
|
||||
public getPurchaseEndpoint() {
|
||||
return `${this.url}/api/v1/brizo/services/access/purchase?`
|
||||
}
|
||||
|
||||
public getConsumeEndpoint(pubKey: string, serviceId: string, url: string) {
|
||||
return `${this.url}/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId=${serviceId}&url=${url}`
|
||||
}
|
||||
|
||||
public getComputeEndpoint(pubKey: string, serviceId: string, algo: string, container: string) {
|
||||
// tslint:disable-next-line
|
||||
return `${this.url}/api/v1/brizo/services/compute?pubKey=${pubKey}&serviceId=${serviceId}&algo=${algo}&container=${container}"`
|
||||
}
|
||||
|
||||
public async initializeServiceAgreement(
|
||||
did: string,
|
||||
serviceAgreementId: string,
|
||||
serviceDefinitionId: string,
|
||||
signature: string,
|
||||
consumerPublicKey: string): Promise<any> {
|
||||
|
||||
return WebServiceConnectorProvider.getConnector().post(
|
||||
`${this.url}/api/v1/brizo/services/access/initialize`,
|
||||
{
|
||||
did,
|
||||
serviceAgreementId,
|
||||
serviceDefinitionId,
|
||||
signature,
|
||||
consumerPublicKey,
|
||||
})
|
||||
|
||||
}
|
||||
}
|
20
src/brizo/BrizoProvider.ts
Normal file
20
src/brizo/BrizoProvider.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Brizo from "./Brizo"
|
||||
|
||||
export default class BrizoProvider {
|
||||
|
||||
public static setBrizo(brizo: Brizo) {
|
||||
|
||||
BrizoProvider.brizo = brizo
|
||||
}
|
||||
|
||||
public static getBrizo() {
|
||||
|
||||
if (!BrizoProvider.brizo) {
|
||||
BrizoProvider.brizo = new Brizo(ConfigProvider.getConfig())
|
||||
}
|
||||
return BrizoProvider.brizo
|
||||
}
|
||||
|
||||
private static brizo: Brizo = null
|
||||
}
|
@ -12,4 +12,5 @@ export default class AdditionalInformation {
|
||||
mediaType: "text/turtle",
|
||||
}as StructuredMarkup,
|
||||
]
|
||||
public checksum: string
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
import Event from "./Event"
|
||||
import Parameter from "./Parameter"
|
||||
|
||||
export default class Condition {
|
||||
public name: string = "lockPayment"
|
||||
public contractName: string = "AccessCondition"
|
||||
public methodName: string = "lockPayment"
|
||||
public timeout: number = 0
|
||||
public conditionKey: string
|
||||
public conditionKey: string = "0x12122434"
|
||||
public parameters: Parameter[]
|
||||
public events: Event[]
|
||||
public dependencies: string[] = []
|
||||
public dependencyTimeoutFlags: number[] = []
|
||||
public isTerminalCondition: boolean = false
|
||||
}
|
||||
|
@ -20,18 +20,37 @@ export default class DDO {
|
||||
public authentication: Authentication[]
|
||||
public service: Service[]
|
||||
|
||||
// @ts-ignore
|
||||
private assa: string
|
||||
|
||||
public constructor(ddo?: {
|
||||
id?: string,
|
||||
publicKey?: PublicKey[],
|
||||
publicKey?: any[],
|
||||
authentication?: Authentication[],
|
||||
service?: Service[],
|
||||
}) {
|
||||
this.authentication = ddo ? ddo.authentication ? ddo.authentication : [] : []
|
||||
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 : [] : []
|
||||
}
|
||||
|
||||
public findServiceById(serviceDefinitionId: string): Service {
|
||||
|
||||
if (!serviceDefinitionId) {
|
||||
throw new Error("serviceDefinitionId not set")
|
||||
}
|
||||
|
||||
const service: Service = this.service.find((s) => s.serviceDefinitionId === serviceDefinitionId)
|
||||
|
||||
return service
|
||||
}
|
||||
|
||||
public findServiceByType(serviceType: string): Service {
|
||||
|
||||
if (!serviceType) {
|
||||
throw new Error("serviceType not set")
|
||||
}
|
||||
|
||||
const service: Service = this.service.find((s) => s.type === serviceType)
|
||||
|
||||
return service
|
||||
}
|
||||
}
|
||||
|
7
src/ddo/Event.ts
Normal file
7
src/ddo/Event.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import EventHandlers from "./EventHandlers"
|
||||
|
||||
export default class Event {
|
||||
public name: string
|
||||
public actorType: string[]
|
||||
public handlers: EventHandlers
|
||||
}
|
5
src/ddo/EventHandlers.ts
Normal file
5
src/ddo/EventHandlers.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export default class EventHandlers {
|
||||
public moduleName: string = "serviceAgreement"
|
||||
public functionName: string = "fulfillAgreement"
|
||||
public version: string = "0.1"
|
||||
}
|
@ -3,52 +3,66 @@ import Curation from "./Curation"
|
||||
import MetaDataBase from "./MetaDataBase"
|
||||
import StructuredMarkup from "./StructuredMarkup"
|
||||
|
||||
const base: MetaDataBase = {
|
||||
name: "UK Weather information 2011",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"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
|
||||
|
||||
const curation: Curation = {
|
||||
rating: 0.93,
|
||||
numVotes: 123,
|
||||
schema: "Binary Votting",
|
||||
} as Curation
|
||||
|
||||
const 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
|
||||
|
||||
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-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,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 additionalInformation: AdditionalInformation
|
||||
public base: MetaDataBase
|
||||
public curation: Curation
|
||||
|
||||
public curation: Curation = {
|
||||
rating: 0.93,
|
||||
numVotes: 123,
|
||||
schema: "Binary Votting",
|
||||
} as Curation
|
||||
constructor(metaData?: MetaData) {
|
||||
this.additionalInformation = metaData ?
|
||||
metaData.additionalInformation ? metaData.additionalInformation :
|
||||
additionalInformation : additionalInformation
|
||||
this.base = metaData ? metaData.base ? metaData.base : base : base
|
||||
this.curation = metaData ? metaData.curation ? metaData.curation : curation : 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
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ export default class MetaDataBase {
|
||||
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[] = [
|
||||
public contentUrls: string | string[] = [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
]
|
||||
public links: any[] = [
|
||||
|
73
src/examples/ExecuteAgreement.ts
Normal file
73
src/examples/ExecuteAgreement.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import DDO from "../ddo/DDO"
|
||||
import MetaData from "../ddo/MetaData"
|
||||
import MetaDataBase from "../ddo/MetaDataBase"
|
||||
import Service from "../ddo/Service"
|
||||
import {Account, Logger, Ocean, ServiceAgreement} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:8030",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const publisher: Account = (await ocean.getAccounts())[0]
|
||||
const consumer: Account = (await ocean.getAccounts())[1]
|
||||
|
||||
const metaData = new MetaData({
|
||||
base: {
|
||||
name: "Office Humidity",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"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,
|
||||
} as MetaData)
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(metaData, publisher)
|
||||
Logger.log("did", ddo.id)
|
||||
|
||||
const accessService = ddo.findServiceByType("Access")
|
||||
|
||||
const serviceAgreementSignatureResult: any = await ocean.signServiceAgreement(ddo.id,
|
||||
accessService.serviceDefinitionId, consumer)
|
||||
Logger.log("ServiceAgreement Id:", serviceAgreementSignatureResult.serviceAgreementId)
|
||||
Logger.log("ServiceAgreement Signature:", serviceAgreementSignatureResult.serviceAgreementSignature)
|
||||
|
||||
const service: Service = ddo.findServiceByType("Access")
|
||||
|
||||
const serviceAgreement: ServiceAgreement = await ocean.executeServiceAgreement(
|
||||
ddo.id,
|
||||
service.serviceDefinitionId,
|
||||
serviceAgreementSignatureResult.serviceAgreementId,
|
||||
serviceAgreementSignatureResult.serviceAgreementSignature,
|
||||
consumer,
|
||||
publisher)
|
||||
Logger.log("ServiceAgreement Id:", serviceAgreement.getId())
|
||||
|
||||
})()
|
75
src/examples/InitializeAgreement.ts
Normal file
75
src/examples/InitializeAgreement.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import DDO from "../ddo/DDO"
|
||||
import MetaData from "../ddo/MetaData"
|
||||
import MetaDataBase from "../ddo/MetaDataBase"
|
||||
import Service from "../ddo/Service"
|
||||
import {Account, Logger, Ocean} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:8030",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const publisher: Account = (await ocean.getAccounts())[0]
|
||||
const consumer: Account = (await ocean.getAccounts())[1]
|
||||
|
||||
const metaData = new MetaData({
|
||||
base: {
|
||||
name: "Office Humidity",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"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,
|
||||
} as MetaData)
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(metaData, publisher)
|
||||
Logger.log("did", ddo.id)
|
||||
|
||||
const accessService = ddo.findServiceByType("Access")
|
||||
|
||||
const serviceAgreementSignatureResult: any = await ocean
|
||||
.signServiceAgreement(
|
||||
ddo.id,
|
||||
accessService.serviceDefinitionId,
|
||||
consumer)
|
||||
Logger.log("ServiceAgreement Id:", serviceAgreementSignatureResult.serviceAgreementId)
|
||||
Logger.log("ServiceAgreement Signature:", serviceAgreementSignatureResult.serviceAgreementSignature)
|
||||
|
||||
const service: Service = ddo.findServiceByType("Access")
|
||||
|
||||
await ocean
|
||||
.initializeServiceAgreement(
|
||||
ddo.id,
|
||||
service.serviceDefinitionId,
|
||||
serviceAgreementSignatureResult.serviceAgreementId,
|
||||
serviceAgreementSignatureResult.serviceAgreementSignature,
|
||||
consumer)
|
||||
|
||||
})()
|
@ -1,20 +0,0 @@
|
||||
import DDO from "../ddo/DDO"
|
||||
import MetaData from "../ddo/MetaData"
|
||||
import {Account, Logger, Ocean} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "https://secret-store.dev-ocean.com",
|
||||
threshold: 2,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const publisher: Account = (await ocean.getAccounts())[0]
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(new MetaData(), publisher)
|
||||
Logger.log(ddo.id)
|
||||
})()
|
52
src/examples/RegisterAsset.ts
Normal file
52
src/examples/RegisterAsset.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import DDO from "../ddo/DDO"
|
||||
import MetaData from "../ddo/MetaData"
|
||||
import MetaDataBase from "../ddo/MetaDataBase"
|
||||
import {Account, Logger, Ocean} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:8030",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const publisher: Account = (await ocean.getAccounts())[0]
|
||||
|
||||
const metaData = new MetaData({
|
||||
base: {
|
||||
name: "Office Humidity",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"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,
|
||||
} as MetaData)
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(metaData, publisher)
|
||||
Logger.log(ddo.id)
|
||||
})()
|
22
src/examples/RegisterServiceAgreementTemplates.ts
Normal file
22
src/examples/RegisterServiceAgreementTemplates.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import {Account, Logger, Ocean, ServiceAgreementTemplate, Templates} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:8030",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const templateOwner: Account = (await ocean.getAccounts())[5]
|
||||
|
||||
const serviceAgreementTemplate: ServiceAgreementTemplate = new ServiceAgreementTemplate(new Templates.Access())
|
||||
const serviceAgreementRegistered: boolean = await serviceAgreementTemplate.register(templateOwner.getId())
|
||||
|
||||
Logger.log("ServiceAgreement registered:", serviceAgreementRegistered,
|
||||
"templateId:", serviceAgreementTemplate.getId())
|
||||
})()
|
25
src/examples/Search.ts
Normal file
25
src/examples/Search.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import DDO from "../ddo/DDO"
|
||||
import {Logger, Ocean} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:8030",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const result: DDO[] = await ocean.searchAssetsByText("Office Humidity")
|
||||
const names: string[] = result.map((ddo: DDO): string => {
|
||||
const service = ddo.findServiceByType("Metadata")
|
||||
if (service && service.metadata) {
|
||||
return service.metadata.base.name
|
||||
}
|
||||
})
|
||||
|
||||
Logger.log(names.length, names)
|
||||
})()
|
85
src/examples/SignAgreement.ts
Normal file
85
src/examples/SignAgreement.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import AdditionalInformation from "../ddo/AdditionalInformation"
|
||||
import Curation from "../ddo/Curation"
|
||||
import DDO from "../ddo/DDO"
|
||||
import MetaData from "../ddo/MetaData"
|
||||
import MetaDataBase from "../ddo/MetaDataBase"
|
||||
import Service from "../ddo/Service"
|
||||
import {Account, Logger, Ocean} from "../squid"
|
||||
|
||||
(async () => {
|
||||
const ocean: Ocean = await Ocean.getInstance({
|
||||
nodeUri: "http://localhost:8545",
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:8030",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
})
|
||||
|
||||
const publisher: Account = (await ocean.getAccounts())[0]
|
||||
const consumer: Account = (await ocean.getAccounts())[1]
|
||||
|
||||
const metaData = {
|
||||
additionalInformation: {
|
||||
structuredMarkup: [
|
||||
{
|
||||
mediaType: "application/ld+json",
|
||||
uri: "http://skos.um.es/unescothes/C01194/jsonld",
|
||||
},
|
||||
{
|
||||
mediaType: "text/turtle",
|
||||
uri: "http://skos.um.es/unescothes/C01194/turtle",
|
||||
},
|
||||
],
|
||||
updateFrecuency: "yearly",
|
||||
checksum: "efdd14d39feb726e321931f408b3454d26f1a4899bcc608a68b5397f23203174",
|
||||
} as AdditionalInformation,
|
||||
base: {
|
||||
name: "Office Humidity",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"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.94,
|
||||
numVotes: 124,
|
||||
schema: "Binary Votting",
|
||||
} as Curation,
|
||||
}
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(metaData as MetaData, publisher)
|
||||
Logger.log("did", ddo.id)
|
||||
|
||||
const accessService: Service = ddo.findServiceByType("Access")
|
||||
const serviceAgreementResult: any = await ocean
|
||||
.signServiceAgreement(
|
||||
ddo.id,
|
||||
accessService.serviceDefinitionId,
|
||||
consumer)
|
||||
|
||||
Logger.log("ServiceAgreement Id:", serviceAgreementResult.serviceAgreementId)
|
||||
Logger.log("ServiceAgreement Signature:", serviceAgreementResult.serviceAgreementSignature)
|
||||
})()
|
9
src/examples/fire_lazers.sh
Executable file
9
src/examples/fire_lazers.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
npm run run src/examples/RegisterServiceAgreementTemplates.ts
|
||||
npm run run src/examples/RegisterAsset.ts
|
||||
npm run run src/examples/Search.ts
|
||||
npm run run src/examples/SignAgreement.ts
|
||||
npm run run src/examples/ExecuteAgreement.ts
|
@ -15,11 +15,11 @@ export default class ContractHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public static set(name: string, contractInstance: Contract) {
|
||||
protected static set(name: string, contractInstance: Contract) {
|
||||
ContractHandler.contracts.set(name, contractInstance)
|
||||
}
|
||||
|
||||
public static has(name: string): boolean {
|
||||
protected static has(name: string): boolean {
|
||||
return ContractHandler.contracts.has(name)
|
||||
}
|
||||
|
||||
|
@ -3,16 +3,14 @@ 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])
|
||||
public static async reflectContractMethod(contractName: string, methodName: string): Promise<MethodReflection> {
|
||||
const contract = await GenericContract.getInstance(contractName)
|
||||
return {
|
||||
contractName: parts[0],
|
||||
methodName: parts[1],
|
||||
contractName,
|
||||
methodName,
|
||||
address: contract.getAddress(),
|
||||
signature: contract.getSignatureOfMethod(parts[1]),
|
||||
inputs: contract.getInputsOfMethod(parts[1]),
|
||||
signature: contract.getSignatureOfMethod(methodName),
|
||||
inputs: contract.getInputsOfMethod(methodName),
|
||||
} as MethodReflection
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import OceanAuth from "./contracts/Auth"
|
||||
import AccessConditions from "./contracts/conditions/AccessConditions"
|
||||
import PaymentConditions from "./contracts/conditions/PaymentConditions"
|
||||
import DIDRegistry from "./contracts/DIDRegistry"
|
||||
import OceanMarket from "./contracts/Market"
|
||||
import ServiceAgreement from "./contracts/ServiceAgreement"
|
||||
@ -18,6 +19,7 @@ export default class Keeper {
|
||||
Keeper.instance.token = await OceanToken.getInstance()
|
||||
Keeper.instance.serviceAgreement = await ServiceAgreement.getInstance()
|
||||
Keeper.instance.accessConditions = await AccessConditions.getInstance()
|
||||
Keeper.instance.paymentConditions = await PaymentConditions.getInstance()
|
||||
Keeper.instance.didRegistry = await DIDRegistry.getInstance()
|
||||
}
|
||||
return Keeper.instance
|
||||
@ -30,12 +32,13 @@ export default class Keeper {
|
||||
public auth: OceanAuth
|
||||
public serviceAgreement: ServiceAgreement
|
||||
public accessConditions: AccessConditions
|
||||
public paymentConditions: PaymentConditions
|
||||
public didRegistry: DIDRegistry
|
||||
|
||||
public async getNetworkName(): Promise<string> {
|
||||
return Web3Provider.getWeb3().eth.net.getId()
|
||||
.then((networkId) => {
|
||||
let network: string = "unknown"
|
||||
let network: string = "Unknown"
|
||||
|
||||
switch (networkId) {
|
||||
case 1:
|
||||
@ -53,8 +56,11 @@ export default class Keeper {
|
||||
case 42:
|
||||
network = "Kovan"
|
||||
break
|
||||
case 8995:
|
||||
network = "Ocean_POA_AWS"
|
||||
break
|
||||
default:
|
||||
network = "development"
|
||||
network = "Development"
|
||||
}
|
||||
return network
|
||||
})
|
||||
|
@ -60,19 +60,25 @@ export default abstract class ContractBase {
|
||||
if (!this.contract.methods[name]) {
|
||||
throw new Error(`Method "${name}" is not part of contract "${this.contractName}"`)
|
||||
}
|
||||
const method = this.contract.methods[name]
|
||||
try {
|
||||
const tx = this.contract.methods[name](...args)
|
||||
const gas = await tx.estimateGas(args, {
|
||||
const tx = method(...args)
|
||||
const estimatedGas = await tx.estimateGas(args, {
|
||||
from,
|
||||
})
|
||||
return tx.send({
|
||||
from,
|
||||
gas,
|
||||
gas: estimatedGas,
|
||||
})
|
||||
} catch (err) {
|
||||
const argString = JSON.stringify(args, null, 2)
|
||||
const mappedArgs = this.searchMethod(name).inputs.map((input, i) => {
|
||||
return {
|
||||
name: input.name,
|
||||
value: args[i],
|
||||
}
|
||||
})
|
||||
Logger.error(`Sending transaction "${name}" on contract "${this.contractName}" failed.`)
|
||||
Logger.error(`Args: ${argString} From: ${from}`)
|
||||
Logger.error(`Parameters: ${JSON.stringify(mappedArgs, null, 2)} from: ${from}`)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,14 @@ export default class ServiceAgreement extends ContractBase {
|
||||
}
|
||||
|
||||
public async setupAgreementTemplate(templateId: string, methodReflections: MethodReflection[],
|
||||
dependencyMatrix: number[], name: any, ownerAddress: string)
|
||||
dependencyMatrix: number[], name: any, fulfillmentIndices: number[],
|
||||
fulfillmentOperator: number,
|
||||
ownerAddress: string)
|
||||
: Promise<Receipt> {
|
||||
|
||||
return this.send("setupAgreementTemplate", ownerAddress, [
|
||||
templateId, methodReflections.map((r) => r.address),
|
||||
methodReflections.map((r) => r.signature), dependencyMatrix, name, [0], 0,
|
||||
methodReflections.map((r) => r.signature), dependencyMatrix, name, fulfillmentIndices, fulfillmentOperator,
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import {Receipt} from "web3-utils"
|
||||
import ContractBase from "../ContractBase"
|
||||
|
||||
export default class PaymentConditions extends ContractBase {
|
||||
@ -7,4 +8,11 @@ export default class PaymentConditions extends ContractBase {
|
||||
await paymentConditions.init()
|
||||
return paymentConditions
|
||||
}
|
||||
|
||||
public async lockPayment(serviceAgreementId: string, assetId: string, price: number, consumerAddress: string)
|
||||
: Promise<Receipt> {
|
||||
return this.send("lockPayment", consumerAddress, [
|
||||
serviceAgreementId, "0x" + assetId, price,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,10 @@ export default class Config {
|
||||
// the url to the aquarius
|
||||
public aquariusUri: string
|
||||
|
||||
/* Brizo Config */
|
||||
// the url to the brizo
|
||||
public brizoUri: string
|
||||
|
||||
/* Keeper Config */
|
||||
// the uri to the node we want to connect to, not need if web3Provider is set
|
||||
public nodeUri?: string
|
||||
|
4
src/models/InputType.ts
Normal file
4
src/models/InputType.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default class InputType {
|
||||
public name: string
|
||||
public type: string
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
import InputType from "./InputType"
|
||||
|
||||
export default class MethodReflection {
|
||||
public contractName: string
|
||||
public methodName: string
|
||||
public address: string
|
||||
public signature: string
|
||||
public inputs: any[]
|
||||
public inputs: InputType[]
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import BigNumber from "bignumber.js"
|
||||
import * as EthJsUtils from "ethereumjs-util"
|
||||
import Keeper from "../keeper/Keeper"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import Balance from "../models/Balance"
|
||||
@ -33,9 +34,19 @@ export default class Account extends OceanBase {
|
||||
return this.balance
|
||||
}
|
||||
|
||||
// Transactions with gas cost
|
||||
public async requestTokens(amount: number): Promise<number> {
|
||||
await (await Keeper.getInstance()).market.requestTokens(amount, this.id)
|
||||
return amount
|
||||
}
|
||||
|
||||
public async getPublicKey(): Promise<string> {
|
||||
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
|
||||
const msg = web3.utils.sha3(this.getId())
|
||||
const sig = await web3.eth.sign(msg, this.getId())
|
||||
const {v, r, s} = EthJsUtils.fromRpcSig(sig)
|
||||
|
||||
return EthJsUtils.ecrecover(EthJsUtils.toBuffer(msg), v, r, s).toString("hex")
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,21 @@
|
||||
import Aquarius from "../aquarius/Aquarius"
|
||||
import AquariusProvider from "../aquarius/AquariusProvider"
|
||||
import SearchQuery from "../aquarius/query/SearchQuery"
|
||||
import BrizoProvider from "../brizo/BrizoProvider"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Authentication from "../ddo/Authentication"
|
||||
import DDOCondition from "../ddo/Condition"
|
||||
import DDO from "../ddo/DDO"
|
||||
import Event from "../ddo/Event"
|
||||
import EventHandlers from "../ddo/EventHandlers"
|
||||
import MetaData from "../ddo/MetaData"
|
||||
import Parameter from "../ddo/Parameter"
|
||||
import Service from "../ddo/Service"
|
||||
import Keeper from "../keeper/Keeper"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import Config from "../models/Config"
|
||||
import ValuePair from "../models/ValuePair"
|
||||
import InputType from "../models/InputType"
|
||||
import ValueType from "../models/ValueType"
|
||||
import SecretStoreProvider from "../secretstore/SecretStoreProvider"
|
||||
import Logger from "../utils/Logger"
|
||||
import Account from "./Account"
|
||||
import IdGenerator from "./IdGenerator"
|
||||
@ -28,7 +32,6 @@ export default class Ocean {
|
||||
ConfigProvider.setConfig(config)
|
||||
Ocean.instance = new Ocean()
|
||||
Ocean.instance.keeper = await Keeper.getInstance()
|
||||
Ocean.instance.aquarius = await AquariusProvider.getAquarius()
|
||||
}
|
||||
|
||||
return Ocean.instance
|
||||
@ -37,7 +40,6 @@ export default class Ocean {
|
||||
private static instance = null
|
||||
|
||||
private keeper: Keeper
|
||||
private aquarius: Aquarius
|
||||
|
||||
private constructor() {
|
||||
}
|
||||
@ -50,20 +52,23 @@ export default class Ocean {
|
||||
return ethAccounts.map((address: string) => new Account(address))
|
||||
}
|
||||
|
||||
public async resolveDID(did): Promise<DDO> {
|
||||
|
||||
return AquariusProvider.getAquarius().retrieveDDO(did)
|
||||
}
|
||||
|
||||
public async registerAsset(metadata: MetaData, publisher: Account): Promise<DDO> {
|
||||
|
||||
const {didRegistry} = this.keeper
|
||||
const aquarius = AquariusProvider.getAquarius()
|
||||
const brizo = BrizoProvider.getBrizo()
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
const did: string = `did:op:${id}`
|
||||
const serviceDefinitionId: string = IdGenerator.generatePrefixedId()
|
||||
|
||||
metadata.base.contentUrls = metadata.base.contentUrls.map((contentUrl) => {
|
||||
|
||||
// todo encrypt url in secret store
|
||||
Logger.log(contentUrl)
|
||||
return "0x00000"
|
||||
})
|
||||
metadata.base.contentUrls =
|
||||
await SecretStoreProvider.getSecretStore().encryptDocument(id, metadata.base.contentUrls)
|
||||
|
||||
const template = new Access()
|
||||
const serviceAgreementTemplate = new ServiceAgreementTemplate(template)
|
||||
@ -72,31 +77,90 @@ export default class Ocean {
|
||||
const conditions: Condition[] = await serviceAgreementTemplate.getConditions()
|
||||
|
||||
// create ddo conditions out of the keys
|
||||
const ddoConditions: DDOCondition[] = conditions.map((condition: Condition): DDOCondition => {
|
||||
return {
|
||||
name: condition.methodReflection.methodName,
|
||||
timeout: condition.timeout,
|
||||
conditionKey: condition.condtionKey,
|
||||
parameters: condition.methodReflection.inputs.map((input: ValuePair) => {
|
||||
return {
|
||||
...input,
|
||||
value: "xxx",
|
||||
} as Parameter
|
||||
}),
|
||||
const ddoConditions: DDOCondition[] = conditions
|
||||
.map((condition: Condition, index: number): DDOCondition => {
|
||||
const events: Event[] = [
|
||||
{
|
||||
name: "PaymentReleased",
|
||||
actorType: [
|
||||
"consumer",
|
||||
],
|
||||
handlers: {
|
||||
moduleName: "serviceAgreement",
|
||||
functionName: "fulfillAgreement",
|
||||
version: "0.1",
|
||||
} as EventHandlers,
|
||||
} as Event,
|
||||
]
|
||||
|
||||
} as DDOCondition
|
||||
})
|
||||
const serviceEndpoint = this.aquarius.getServiceEndpoint(did)
|
||||
const mapParameterValueToName = (name) => {
|
||||
|
||||
switch (name) {
|
||||
case "price":
|
||||
return metadata.base.price
|
||||
case "assetId":
|
||||
return "0x" + id
|
||||
case "documentKeyId":
|
||||
return "0x1234"
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const parameters: Parameter[] = condition.methodReflection.inputs.map((input: InputType) => {
|
||||
return {
|
||||
name: input.name,
|
||||
type: input.type,
|
||||
value: mapParameterValueToName(input.name),
|
||||
} as Parameter
|
||||
})
|
||||
|
||||
// Logger.log(`${condition.methodReflection.contractName}.${condition.methodReflection.methodName}`,
|
||||
// JSON.stringify(parameters, null, 2))
|
||||
|
||||
return {
|
||||
contractName: condition.methodReflection.contractName,
|
||||
methodName: condition.methodReflection.methodName,
|
||||
timeout: condition.timeout,
|
||||
index,
|
||||
conditionKey: condition.condtionKey,
|
||||
parameters,
|
||||
events,
|
||||
dependencies: condition.dependencies,
|
||||
dependencyTimeoutFlags: condition.dependencyTimeoutFlags,
|
||||
isTerminalCondition: condition.isTerminalCondition,
|
||||
} as DDOCondition
|
||||
})
|
||||
|
||||
const serviceEndpoint = aquarius.getServiceEndpoint(did)
|
||||
|
||||
// create ddo itself
|
||||
const ddo: DDO = new DDO({
|
||||
authentication: [{
|
||||
type: "RsaSignatureAuthentication2018",
|
||||
publicKey: did + "#keys-1",
|
||||
} as Authentication],
|
||||
id: did,
|
||||
publicKey: [
|
||||
{
|
||||
id: did + "#keys-1",
|
||||
},
|
||||
{
|
||||
type: "Ed25519VerificationKey2018",
|
||||
},
|
||||
{
|
||||
owner: did,
|
||||
},
|
||||
{
|
||||
publicKeyBase58: await publisher.getPublicKey(),
|
||||
},
|
||||
],
|
||||
service: [
|
||||
{
|
||||
type: template.templateName,
|
||||
// tslint:disable-next-line
|
||||
serviceEndpoint: "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}",
|
||||
purchaseEndpoint: "http://mybrizo.org/api/v1/brizo/services/access/purchase?",
|
||||
purchaseEndpoint: brizo.getPurchaseEndpoint(),
|
||||
serviceEndpoint: brizo.getConsumeEndpoint(publisher.getId(),
|
||||
serviceDefinitionId, metadata.base.contentUrls[0]),
|
||||
// the id of the service agreement?
|
||||
serviceDefinitionId,
|
||||
// the id of the service agreement template
|
||||
@ -104,41 +168,99 @@ export default class Ocean {
|
||||
conditions: ddoConditions,
|
||||
} as Service,
|
||||
{
|
||||
type: "Compute",
|
||||
serviceEndpoint: brizo.getComputeEndpoint(publisher.getId(),
|
||||
serviceDefinitionId, "xxx", "xxx"),
|
||||
} as Service,
|
||||
{
|
||||
type: "Metadata",
|
||||
serviceEndpoint,
|
||||
metadata,
|
||||
} as Service,
|
||||
],
|
||||
})
|
||||
|
||||
const storedDdo = await this.aquarius.storeDDO(ddo)
|
||||
const storedDdo = await aquarius.storeDDO(ddo)
|
||||
|
||||
await didRegistry.registerAttribute(id, ValueType.DID, "Metadata", serviceEndpoint,
|
||||
await didRegistry.registerAttribute(
|
||||
id,
|
||||
ValueType.DID,
|
||||
"Metadata",
|
||||
serviceEndpoint,
|
||||
publisher.getId())
|
||||
|
||||
return storedDdo
|
||||
}
|
||||
|
||||
public async purchase(did: string, consumer: Account): Promise<ServiceAgreement> {
|
||||
public async signServiceAgreement(did: string,
|
||||
serviceDefinitionId: string,
|
||||
consumer: Account): Promise<any> {
|
||||
|
||||
const ddo = await AquariusProvider.getAquarius().retrieveDDO(did)
|
||||
const id = did.replace("did:op:", "")
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
|
||||
try {
|
||||
const serviceAgreementSignature: string = await ServiceAgreement.signServiceAgreement(id,
|
||||
ddo, serviceDefinitionId, serviceAgreementId, consumer)
|
||||
return {
|
||||
serviceAgreementId,
|
||||
serviceAgreementSignature,
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Logger.error("Signing ServiceAgreement failed!", err)
|
||||
}
|
||||
}
|
||||
|
||||
public async initializeServiceAgreement(did: string,
|
||||
serviceDefinitionId: string,
|
||||
serviceAgreementId: string,
|
||||
serviceAgreementSignature: string,
|
||||
consumer: Account) {
|
||||
const result = await BrizoProvider
|
||||
.getBrizo()
|
||||
.initializeServiceAgreement(
|
||||
did,
|
||||
serviceAgreementId,
|
||||
serviceDefinitionId,
|
||||
serviceAgreementSignature,
|
||||
await consumer.getPublicKey())
|
||||
|
||||
Logger.log(result)
|
||||
}
|
||||
|
||||
public async executeServiceAgreement(did: string,
|
||||
serviceDefinitionId: string,
|
||||
serviceAgreementId: string,
|
||||
serviceAgreementSignature: string,
|
||||
consumer: Account,
|
||||
publisher: Account): Promise<ServiceAgreement> {
|
||||
|
||||
const ddo = await AquariusProvider.getAquarius().retrieveDDO(did)
|
||||
const id = did.replace("did:op:", "")
|
||||
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.signServiceAgreement(id,
|
||||
// todo get publisher from ddo
|
||||
ddo, serviceAgreementId, consumer, new Account())
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement
|
||||
.executeServiceAgreement(
|
||||
id,
|
||||
ddo,
|
||||
serviceDefinitionId,
|
||||
serviceAgreementId,
|
||||
serviceAgreementSignature,
|
||||
consumer,
|
||||
publisher)
|
||||
|
||||
return serviceAgreement
|
||||
}
|
||||
|
||||
public async searchAssets(query: SearchQuery): Promise<any[]> {
|
||||
return this.aquarius.queryMetadata(query)
|
||||
public async searchAssets(query: SearchQuery): Promise<DDO[]> {
|
||||
return AquariusProvider.getAquarius().queryMetadata(query)
|
||||
}
|
||||
|
||||
public async searchAssetsByText(text: string): Promise<any[]> {
|
||||
return this.aquarius.queryMetadataByText({
|
||||
public async searchAssetsByText(text: string): Promise<DDO[]> {
|
||||
return AquariusProvider.getAquarius().queryMetadataByText({
|
||||
text,
|
||||
page: 1,
|
||||
page: 0,
|
||||
offset: 100,
|
||||
query: {
|
||||
value: 1,
|
||||
|
@ -3,5 +3,8 @@ import MethodReflection from "../../models/MethodReflection"
|
||||
export default class Condition {
|
||||
public methodReflection: MethodReflection
|
||||
public condtionKey: string
|
||||
public dependencies: string[]
|
||||
public dependencyTimeoutFlags: number[]
|
||||
public isTerminalCondition: boolean
|
||||
public timeout: number
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
export default class Method {
|
||||
public path: string
|
||||
public dependency: number
|
||||
public name: string
|
||||
public contractName: string
|
||||
public methodName: string
|
||||
public timeout: number
|
||||
public dependencies: string[]
|
||||
public dependencyTimeoutFlags: number[]
|
||||
public isTerminalCondition: boolean
|
||||
}
|
||||
|
@ -1,66 +1,130 @@
|
||||
import Condition from "../../ddo/Condition"
|
||||
import DDO from "../../ddo/DDO"
|
||||
import Service from "../../ddo/Service"
|
||||
import Keeper from "../../keeper/Keeper"
|
||||
import Web3Provider from "../../keeper/Web3Provider"
|
||||
import ValuePair from "../../models/ValuePair"
|
||||
import Logger from "../../utils/Logger"
|
||||
import Account from "../Account"
|
||||
import OceanBase from "../OceanBase"
|
||||
|
||||
export default class ServiceAgreement extends OceanBase {
|
||||
|
||||
public static async signServiceAgreement(assetId: string, ddo: DDO, serviceAgreementId: string, consumer: Account,
|
||||
publisher: Account):
|
||||
Promise<ServiceAgreement> {
|
||||
public static async signServiceAgreement(assetId: string,
|
||||
ddo: DDO,
|
||||
serviceDefinitionId: string,
|
||||
serviceAgreementId: string,
|
||||
consumer: Account): Promise<string> {
|
||||
|
||||
const values: ValuePair[] = ServiceAgreement.getValuesFromDDO(ddo, serviceAgreementId)
|
||||
// Logger.log("signing SA", serviceAgreementId)
|
||||
|
||||
const service: Service = ddo.findServiceById(serviceDefinitionId)
|
||||
const values: ValuePair[] = ServiceAgreement.getValuesFromService(service, serviceAgreementId)
|
||||
const valueHashes = ServiceAgreement.createValueHashes(values)
|
||||
const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromDDO(ddo)
|
||||
const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromService(service)
|
||||
|
||||
const serviceAgreementHashSignature = await ServiceAgreement.createSAHashSignature(ddo, serviceAgreementId,
|
||||
values, valueHashes, timeoutValues, consumer)
|
||||
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.executeAgreement(ddo,
|
||||
serviceAgreementId, values, valueHashes, timeoutValues, serviceAgreementHashSignature, consumer, publisher)
|
||||
|
||||
return serviceAgreement
|
||||
}
|
||||
|
||||
public static async createSAHashSignature(ddo: DDO, serviceAgreementId: string, values: ValuePair[],
|
||||
valueHashes: string[], timeoutValues: number[], consumer: Account):
|
||||
Promise<string> {
|
||||
|
||||
const conditionKeys: string[] = ddo.service[0].conditions.map((condition) => {
|
||||
return condition.conditionKey
|
||||
})
|
||||
|
||||
const serviceAgreementHash = ServiceAgreement.hashServiceAgreement(ddo.service[0].templateId,
|
||||
serviceAgreementId, conditionKeys, valueHashes, timeoutValues)
|
||||
|
||||
const serviceAgreementHashSignature =
|
||||
await Web3Provider.getWeb3().eth.sign(serviceAgreementHash, consumer.getId())
|
||||
const serviceAgreementHashSignature = await ServiceAgreement
|
||||
.createSAHashSignature(
|
||||
service,
|
||||
serviceAgreementId,
|
||||
values,
|
||||
valueHashes,
|
||||
timeoutValues,
|
||||
consumer)
|
||||
|
||||
return serviceAgreementHashSignature
|
||||
}
|
||||
|
||||
private static async executeAgreement(ddo: DDO, serviceAgreementId: string, values: ValuePair[],
|
||||
valueHashes: string[], timeoutValues: number[],
|
||||
serviceAgreementHashSignature: string, consumer: Account,
|
||||
public static async executeServiceAgreement(assetId: string,
|
||||
ddo: DDO,
|
||||
serviceDefinitionId: string,
|
||||
serviceAgreementId: string,
|
||||
serviceAgreementHashSignature: string,
|
||||
consumer: Account,
|
||||
publisher: Account): Promise<ServiceAgreement> {
|
||||
|
||||
// Logger.log("executing SA", serviceAgreementId)
|
||||
|
||||
const service: Service = ddo.findServiceById(serviceDefinitionId)
|
||||
const values: ValuePair[] = ServiceAgreement.getValuesFromService(service, serviceAgreementId)
|
||||
const valueHashes = ServiceAgreement.createValueHashes(values)
|
||||
const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromService(service)
|
||||
|
||||
// todo get consumer from ddo
|
||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.executeAgreement(ddo,
|
||||
serviceDefinitionId, serviceAgreementId, valueHashes, timeoutValues, serviceAgreementHashSignature,
|
||||
consumer.getId(), publisher)
|
||||
|
||||
return serviceAgreement
|
||||
}
|
||||
|
||||
private static async createSAHashSignature(service: Service,
|
||||
serviceAgreementId: string,
|
||||
values: ValuePair[],
|
||||
valueHashes: string[],
|
||||
timeoutValues: number[],
|
||||
consumer: Account):
|
||||
Promise<string> {
|
||||
|
||||
if (!service.templateId) {
|
||||
throw new Error("TemplateId not found in ddo.")
|
||||
}
|
||||
|
||||
const conditionKeys: string[] = service.conditions.map((condition) => {
|
||||
return condition.conditionKey
|
||||
})
|
||||
|
||||
const serviceAgreementHash = ServiceAgreement
|
||||
.hashServiceAgreement(
|
||||
service.templateId,
|
||||
serviceAgreementId,
|
||||
conditionKeys,
|
||||
valueHashes,
|
||||
timeoutValues)
|
||||
|
||||
const serviceAgreementHashSignature = await Web3Provider
|
||||
.getWeb3().eth.sign(serviceAgreementHash, consumer.getId())
|
||||
|
||||
return serviceAgreementHashSignature
|
||||
}
|
||||
|
||||
private static async executeAgreement(ddo: DDO,
|
||||
serviceDefinitionId: string,
|
||||
serviceAgreementId: string,
|
||||
valueHashes: string[],
|
||||
timeoutValues: number[],
|
||||
serviceAgreementHashSignature: string,
|
||||
consumerAddress: string,
|
||||
publisher: Account): Promise<ServiceAgreement> {
|
||||
|
||||
const {serviceAgreement} = await Keeper.getInstance()
|
||||
const executeAgreementReceipt = await serviceAgreement.executeAgreement(
|
||||
ddo.service[0].templateId, serviceAgreementHashSignature, consumer.getId(), valueHashes,
|
||||
timeoutValues, serviceAgreementId, ddo.id, publisher.getId())
|
||||
|
||||
const service: Service = ddo.findServiceById(serviceDefinitionId)
|
||||
|
||||
if (!service.templateId) {
|
||||
throw new Error(`TemplateId not found in service "${service.type}" ddo.`)
|
||||
}
|
||||
|
||||
const executeAgreementReceipt = await serviceAgreement
|
||||
.executeAgreement(
|
||||
service.templateId,
|
||||
serviceAgreementHashSignature,
|
||||
consumerAddress,
|
||||
valueHashes,
|
||||
timeoutValues,
|
||||
serviceAgreementId,
|
||||
ddo.id,
|
||||
publisher.getId())
|
||||
|
||||
if (executeAgreementReceipt.events.ExecuteAgreement.returnValues.state === false) {
|
||||
throw new Error("signing service agreement failed.")
|
||||
throw new Error("executing service agreement failed.")
|
||||
}
|
||||
|
||||
return new ServiceAgreement(
|
||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.serviceAgreementId,
|
||||
ddo,
|
||||
publisher,
|
||||
consumer,
|
||||
new Account(consumerAddress),
|
||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.state,
|
||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.status,
|
||||
)
|
||||
@ -73,12 +137,18 @@ export default class ServiceAgreement extends OceanBase {
|
||||
}
|
||||
|
||||
private static hashSingleValue(data: ValuePair): string {
|
||||
return Web3Provider.getWeb3().utils.soliditySha3(data).toString("hex")
|
||||
try {
|
||||
return Web3Provider.getWeb3().utils.soliditySha3(data).toString("hex")
|
||||
} catch (err) {
|
||||
Logger.error(`Hashing of ${JSON.stringify(data, null, 2)} failed.`)
|
||||
}
|
||||
}
|
||||
|
||||
private static hashServiceAgreement(serviceAgreementTemplateId: string, serviceAgreementId: string,
|
||||
conditionKeys: string[], valueHashes: string[], timeouts: number[])
|
||||
: string {
|
||||
private static hashServiceAgreement(serviceAgreementTemplateId: string,
|
||||
serviceAgreementId: string,
|
||||
conditionKeys: string[],
|
||||
valueHashes: string[],
|
||||
timeouts: number[]): string {
|
||||
const args = [
|
||||
{type: "bytes32", value: serviceAgreementTemplateId} as ValuePair,
|
||||
{type: "bytes32[]", value: conditionKeys} as ValuePair,
|
||||
@ -90,31 +160,51 @@ export default class ServiceAgreement extends OceanBase {
|
||||
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
|
||||
}
|
||||
|
||||
private static getTimeoutValuesFromDDO(ddo: DDO): number[] {
|
||||
const timeoutValues: number[] = ddo.service[0].conditions.map((condition: Condition) => {
|
||||
private static getTimeoutValuesFromService(service: Service): number[] {
|
||||
const timeoutValues: number[] = service.conditions.map((condition: Condition) => {
|
||||
return condition.timeout
|
||||
})
|
||||
|
||||
return timeoutValues
|
||||
}
|
||||
|
||||
private static getValuesFromDDO(ddo: DDO, serviceAgreementId: string): ValuePair[] {
|
||||
const values: ValuePair[] = [
|
||||
{type: "bool", value: true} as ValuePair,
|
||||
{type: "bool", value: false} as ValuePair,
|
||||
{type: "bool", value: false} as ValuePair,
|
||||
{type: "uint", value: 120} as ValuePair,
|
||||
{type: "string", value: serviceAgreementId} as ValuePair,
|
||||
]
|
||||
private static getValuesFromService(service: Service, serviceAgreementId: string): ValuePair[] {
|
||||
|
||||
const values: ValuePair[] = []
|
||||
|
||||
service.conditions.forEach((condition) => {
|
||||
condition.parameters.forEach((parameter) => {
|
||||
values.push({
|
||||
type: parameter.type,
|
||||
value: parameter.name === "serviceId" ? "0x" + serviceAgreementId : parameter.value,
|
||||
} as ValuePair)
|
||||
})
|
||||
})
|
||||
|
||||
// Logger.log("Values", JSON.stringify(values, null, 2))
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
private constructor(serviceAgreementId: string, ddo: DDO, private publisher: Account, consumer: Account,
|
||||
state: boolean, status: boolean) {
|
||||
private constructor(serviceAgreementId: string,
|
||||
ddo: DDO,
|
||||
private publisher: Account,
|
||||
consumer: Account,
|
||||
state: boolean,
|
||||
status: boolean) {
|
||||
super(serviceAgreementId)
|
||||
}
|
||||
|
||||
public async lockPayment(assetId: string, price: number, consumer: Account): Promise<boolean> {
|
||||
const {paymentConditions} = await Keeper.getInstance()
|
||||
|
||||
const lockPaymentRceipt =
|
||||
await paymentConditions.lockPayment(this.getId(), assetId, price,
|
||||
consumer.getId())
|
||||
|
||||
return lockPaymentRceipt.status
|
||||
}
|
||||
|
||||
public async grantAccess(assetId: string, documentId: string): Promise<boolean> {
|
||||
const {accessConditions} = await Keeper.getInstance()
|
||||
|
||||
|
@ -31,35 +31,54 @@ export default class ServiceAgreementTemplate extends OceanBase {
|
||||
|
||||
const dependencyMatrix: number[] =
|
||||
await Promise.all(this.template.Methods.map(async (method: Method) => {
|
||||
// tslint:disable-next-line
|
||||
return method.dependency | method.timeout
|
||||
return this.compressDependencies(method.dependencies, method.dependencyTimeoutFlags)
|
||||
}))
|
||||
|
||||
const fulfillmentIndices: number[] = this.template.Methods
|
||||
.map((method: Method, i: number) => method.isTerminalCondition ? i : undefined)
|
||||
.filter((index: number) => index !== undefined)
|
||||
|
||||
const {serviceAgreement} = await Keeper.getInstance()
|
||||
|
||||
const methodReflections = await this.getMethodReflections()
|
||||
|
||||
const owner = await this.getOwner()
|
||||
|
||||
if (!owner.getId().startsWith("0x0")) {
|
||||
Logger.error(`Template with id "${this.template.id}" already registered.`)
|
||||
if (owner.getId() === templateOwnerAddress) {
|
||||
// tslint:disable-next-line
|
||||
Logger.error(`Template with id "${this.template.id}" is already registered to your account "${templateOwnerAddress}".`)
|
||||
return false
|
||||
}
|
||||
|
||||
const receipt = await serviceAgreement.setupAgreementTemplate(
|
||||
this.template.id, methodReflections, dependencyMatrix,
|
||||
Web3Provider.getWeb3().utils.fromAscii(this.template.templateName),
|
||||
templateOwnerAddress)
|
||||
|
||||
const templateId = receipt.events.SetupAgreementTemplate.returnValues.serviceTemplateId
|
||||
|
||||
if (templateId !== this.template.id) {
|
||||
// tslint:disable-next-line
|
||||
throw new Error(`TemplateId missmatch on ${this.template.templateName}! Should be "${this.template.id}" but is ${templateId}`)
|
||||
if (!owner.getId().startsWith("0x0")) {
|
||||
Logger.error(`Template with id "${this.template.id}" already registered by someone else.`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (receipt.status) {
|
||||
Logger.error("Registering template failed")
|
||||
const receipt = await serviceAgreement
|
||||
.setupAgreementTemplate(
|
||||
this.template.id,
|
||||
methodReflections,
|
||||
dependencyMatrix,
|
||||
Web3Provider.getWeb3().utils.fromAscii(this.template.templateName),
|
||||
fulfillmentIndices,
|
||||
this.template.fulfillmentOperator,
|
||||
templateOwnerAddress)
|
||||
|
||||
const {serviceTemplateId, provider} = receipt.events.SetupAgreementTemplate.returnValues
|
||||
|
||||
if (serviceTemplateId !== this.template.id) {
|
||||
// tslint:disable-next-line
|
||||
throw new Error(`TemplateId missmatch on ${this.template.templateName}! Should be "${this.template.id}" but is ${serviceTemplateId}`)
|
||||
}
|
||||
|
||||
if (provider !== templateOwnerAddress) {
|
||||
// tslint:disable-next-line
|
||||
throw new Error(`Template owner missmatch on ${this.template.templateName}! Should be "${templateOwnerAddress}" but is ${provider}`)
|
||||
}
|
||||
|
||||
if (!receipt.status) {
|
||||
Logger.error(`Registering template failed, status was "false".`)
|
||||
}
|
||||
|
||||
return receipt.status
|
||||
@ -83,23 +102,54 @@ export default class ServiceAgreementTemplate extends OceanBase {
|
||||
const methodReflections = await this.getMethodReflections()
|
||||
|
||||
const conditions: Condition[] = methodReflections.map((methodReflection, i) => {
|
||||
const method: Method = this.template.Methods[i]
|
||||
return {
|
||||
methodReflection,
|
||||
timeout: this.template.Methods[i].timeout,
|
||||
condtionKey: ServiceAgreementTemplate.generateConditionsKey(this.getId(),
|
||||
methodReflection),
|
||||
timeout: method.timeout,
|
||||
dependencies: method.dependencies,
|
||||
dependencyTimeoutFlags: method.dependencyTimeoutFlags,
|
||||
isTerminalCondition: method.isTerminalCondition,
|
||||
condtionKey: ServiceAgreementTemplate
|
||||
.generateConditionsKey(this.getId(), methodReflection),
|
||||
} as Condition
|
||||
})
|
||||
|
||||
return conditions
|
||||
}
|
||||
|
||||
private compressDependencies(dependencies: string[], dependencyTimeoutFlags: number[]): number {
|
||||
|
||||
if (dependencies.length !== dependencyTimeoutFlags.length) {
|
||||
throw new Error("Deps and timeouts need the same length")
|
||||
}
|
||||
|
||||
// map name to index
|
||||
const mappedDependencies: number[] = dependencies.map((dep: string) => {
|
||||
return this.template.Methods.findIndex((m) => m.name === dep)
|
||||
})
|
||||
|
||||
let compressedDependencyValue = 0
|
||||
const numBits = 2 // 1st for dependency, 2nd for timeout flag
|
||||
for (let i = 0; i < mappedDependencies.length; i++) {
|
||||
const dependencyIndex = mappedDependencies[i]
|
||||
const timeout = dependencyTimeoutFlags[i]
|
||||
const offset = i * numBits
|
||||
// tslint:disable-next-line
|
||||
compressedDependencyValue |= dependencyIndex * 2 ** (offset + 0) // the dependency bit
|
||||
// tslint:disable-next-line
|
||||
compressedDependencyValue |= timeout * 2 ** (offset + 1) // the timeout bit
|
||||
}
|
||||
|
||||
return compressedDependencyValue
|
||||
}
|
||||
|
||||
private async getMethodReflections(): Promise<MethodReflection[]> {
|
||||
const methodReflections: MethodReflection[] =
|
||||
await Promise.all(this.template.Methods.map(async (method: Method) => {
|
||||
const methodReflection = await ContractReflector.reflectContractMethod(method.path)
|
||||
return methodReflection
|
||||
}))
|
||||
const methodReflections: MethodReflection[] = []
|
||||
for (const method of this.template.Methods) {
|
||||
methodReflections.push(
|
||||
await ContractReflector.reflectContractMethod(method.contractName, method.methodName),
|
||||
)
|
||||
}
|
||||
return methodReflections
|
||||
}
|
||||
}
|
||||
|
@ -7,24 +7,40 @@ export default class Access extends TemplateBase {
|
||||
public id: string = "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"
|
||||
public Methods: Method[] = [
|
||||
{
|
||||
path: "PaymentConditions.lockPayment",
|
||||
dependency: 0,
|
||||
name: "lockPayment",
|
||||
contractName: "PaymentConditions",
|
||||
methodName: "lockPayment",
|
||||
timeout: 0,
|
||||
dependencies: [],
|
||||
dependencyTimeoutFlags: [],
|
||||
isTerminalCondition: false,
|
||||
} as Method,
|
||||
{
|
||||
name: "grantAccess",
|
||||
contractName: "AccessConditions",
|
||||
methodName: "grantAccess",
|
||||
timeout: 10,
|
||||
dependencies: ["lockPayment"],
|
||||
dependencyTimeoutFlags: [0],
|
||||
isTerminalCondition: false,
|
||||
} as Method,
|
||||
{
|
||||
path: "AccessConditions.grantAccess",
|
||||
dependency: 1,
|
||||
timeout: 500,
|
||||
name: "releasePayment",
|
||||
contractName: "PaymentConditions",
|
||||
methodName: "releasePayment",
|
||||
timeout: 10,
|
||||
dependencies: ["grantAccess"],
|
||||
dependencyTimeoutFlags: [0],
|
||||
isTerminalCondition: true,
|
||||
} as Method,
|
||||
{
|
||||
path: "PaymentConditions.releasePayment",
|
||||
dependency: 4,
|
||||
timeout: 17,
|
||||
} as Method,
|
||||
{
|
||||
path: "PaymentConditions.refundPayment",
|
||||
dependency: 1,
|
||||
timeout: 40,
|
||||
name: "refundPayment",
|
||||
contractName: "PaymentConditions",
|
||||
methodName: "refundPayment",
|
||||
timeout: 10,
|
||||
dependencies: ["lockPayment", "grantAccess"],
|
||||
dependencyTimeoutFlags: [0, 1],
|
||||
isTerminalCondition: true,
|
||||
} as Method,
|
||||
]
|
||||
}
|
||||
|
@ -7,24 +7,40 @@ export default class FitchainCompute extends TemplateBase {
|
||||
public id: string = "0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6"
|
||||
public Methods: Method[] = [
|
||||
{
|
||||
path: "PaymentConditions.lockPayment",
|
||||
dependency: 0,
|
||||
name: "lockPayment",
|
||||
contractName: "PaymentConditions",
|
||||
methodName: "lockPayment",
|
||||
timeout: 0,
|
||||
dependencies: [],
|
||||
dependencyTimeoutFlags: [],
|
||||
isTerminalCondition: false,
|
||||
} as Method,
|
||||
{
|
||||
name: "grantAccess",
|
||||
contractName: "AccessConditions",
|
||||
methodName: "grantAccess",
|
||||
timeout: 10,
|
||||
dependencies: ["lockPayment"],
|
||||
dependencyTimeoutFlags: [0],
|
||||
isTerminalCondition: false,
|
||||
} as Method,
|
||||
{
|
||||
path: "AccessConditions.grantAccess",
|
||||
dependency: 1,
|
||||
timeout: 500,
|
||||
name: "releasePayment",
|
||||
contractName: "PaymentConditions",
|
||||
methodName: "releasePayment",
|
||||
timeout: 10,
|
||||
dependencies: ["grantAccess"],
|
||||
dependencyTimeoutFlags: [0],
|
||||
isTerminalCondition: true,
|
||||
} as Method,
|
||||
{
|
||||
path: "PaymentConditions.releasePayment",
|
||||
dependency: 4,
|
||||
timeout: 17,
|
||||
} as Method,
|
||||
{
|
||||
path: "PaymentConditions.refundPayment",
|
||||
dependency: 1,
|
||||
timeout: 40,
|
||||
name: "refundPayment",
|
||||
contractName: "PaymentConditions",
|
||||
methodName: "refundPayment",
|
||||
timeout: 10,
|
||||
dependencies: ["lockPayment", "grantAccess"],
|
||||
dependencyTimeoutFlags: [0, 1],
|
||||
isTerminalCondition: true,
|
||||
} as Method,
|
||||
]
|
||||
}
|
||||
|
@ -3,5 +3,6 @@ import Method from "../Method"
|
||||
export default abstract class TemplateBase {
|
||||
public Methods: Method[]
|
||||
public templateName: string
|
||||
public fulfillmentOperator: number = 1
|
||||
public id: string = "0x00000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
|
@ -1,11 +1,18 @@
|
||||
import Account from "./ocean/Account"
|
||||
import Ocean from "./ocean/Ocean"
|
||||
import ServiceAgreement from "./ocean/ServiceAgreements/ServiceAgreement"
|
||||
import ServiceAgreementTemplate from "./ocean/ServiceAgreements/ServiceAgreementTemplate"
|
||||
import Access from "./ocean/ServiceAgreements/Templates/Access"
|
||||
import FitchainCompute from "./ocean/ServiceAgreements/Templates/FitchainCompute"
|
||||
import Logger from "./utils/Logger"
|
||||
|
||||
const Templates = {Access, FitchainCompute}
|
||||
|
||||
export {
|
||||
Ocean,
|
||||
ServiceAgreement,
|
||||
ServiceAgreementTemplate,
|
||||
Logger,
|
||||
Templates,
|
||||
Account,
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import fetch from "node-fetch"
|
||||
|
||||
export default class AquariusConnector {
|
||||
export default class WebServiceConnector {
|
||||
|
||||
public async post(url, payload): Promise<any> {
|
||||
return this.fetch(url, {
|
19
src/utils/WebServiceConnectorProvider.ts
Normal file
19
src/utils/WebServiceConnectorProvider.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import WebServiceConnector from "./WebServiceConnector"
|
||||
|
||||
export default class WebServiceConnectorProvider {
|
||||
|
||||
public static setConnector(connector: WebServiceConnector) {
|
||||
|
||||
WebServiceConnectorProvider.instance = connector
|
||||
}
|
||||
|
||||
public static getConnector(): WebServiceConnector {
|
||||
|
||||
if (!WebServiceConnectorProvider.instance) {
|
||||
WebServiceConnectorProvider.instance = new WebServiceConnector()
|
||||
}
|
||||
return WebServiceConnectorProvider.instance
|
||||
}
|
||||
|
||||
private static instance: WebServiceConnector = null
|
||||
}
|
@ -1,66 +1,84 @@
|
||||
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 WebServiceConnectorProvider from "../../src/utils/WebServiceConnectorProvider"
|
||||
import config from "../config"
|
||||
import AquariusConnectorMock from "../mocks/AquariusConnector.mock"
|
||||
// import * as jsonDDO from "../testdata/ddo.json"
|
||||
import WebServiceConnectorMock from "../mocks/WebServiceConnector.mock"
|
||||
|
||||
describe("Aquarius", () => {
|
||||
|
||||
const aquarius: Aquarius = new Aquarius(config)
|
||||
describe("#queryMetadata()", () => {
|
||||
|
||||
const query = {
|
||||
offset: 100,
|
||||
page: 0,
|
||||
query: {
|
||||
value: 1,
|
||||
},
|
||||
sort: {
|
||||
value: 1,
|
||||
},
|
||||
text: "Office",
|
||||
} as SearchQuery
|
||||
|
||||
it("should query metadata", async () => {
|
||||
|
||||
const query = {
|
||||
offset: 100,
|
||||
page: 0,
|
||||
query: {
|
||||
value: 1,
|
||||
},
|
||||
sort: {
|
||||
value: 1,
|
||||
},
|
||||
text: "Office",
|
||||
} as SearchQuery
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock())
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock([new DDO()]))
|
||||
|
||||
const result: any[] = await aquarius.queryMetadata(query)
|
||||
const result: DDO[] = await aquarius.queryMetadata(query)
|
||||
assert(result)
|
||||
assert(result.length !== null)
|
||||
})
|
||||
|
||||
it("should query metadata and return real ddo", async () => {
|
||||
|
||||
// @ts-ignore
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock([new DDO()]))
|
||||
|
||||
const result: DDO[] = await aquarius.queryMetadata(query)
|
||||
assert(result)
|
||||
assert(result[0].findServiceById)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#queryMetadataByText()", () => {
|
||||
|
||||
const query = {
|
||||
offset: 100,
|
||||
page: 0,
|
||||
query: {
|
||||
value: 1,
|
||||
},
|
||||
sort: {
|
||||
value: 1,
|
||||
},
|
||||
text: "Office",
|
||||
} as SearchQuery
|
||||
|
||||
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())
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock([new DDO()]))
|
||||
|
||||
const result: any[] = await aquarius.queryMetadataByText(query)
|
||||
const result: DDO[] = await aquarius.queryMetadataByText(query)
|
||||
assert(result)
|
||||
assert(result.length !== null)
|
||||
})
|
||||
|
||||
it("should query metadata and return real ddo", async () => {
|
||||
|
||||
// @ts-ignore
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock([new DDO()]))
|
||||
|
||||
const result: DDO[] = await aquarius.queryMetadataByText(query)
|
||||
assert(result)
|
||||
assert(result[0].findServiceById)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#storeDDO()", () => {
|
||||
@ -73,7 +91,7 @@ describe("Aquarius", () => {
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
|
||||
const result: DDO = await aquarius.storeDDO(ddo)
|
||||
assert(result)
|
||||
@ -91,7 +109,7 @@ describe("Aquarius", () => {
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
|
||||
const storageResult: DDO = await aquarius.storeDDO(ddo)
|
||||
assert(storageResult)
|
||||
|
@ -2,10 +2,11 @@ import Config from "../src/models/Config"
|
||||
|
||||
export default {
|
||||
aquariusUri: "http://localhost:5000",
|
||||
brizoUri: "http://localhost:3000",
|
||||
nodeUri: "http://localhost:8545",
|
||||
parityUri: "http://localhost:9545",
|
||||
secretStoreUri: "https://secret-store.dev-ocean.com",
|
||||
threshold: 2,
|
||||
secretStoreUri: "http://localhost:12001",
|
||||
threshold: 0,
|
||||
password: "unittest",
|
||||
address: "0xed243adfb84a6626eba46178ccb567481c6e655d",
|
||||
web3Provider: null,
|
||||
|
@ -107,6 +107,7 @@ describe("DDO", () => {
|
||||
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",
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
],
|
||||
links: [
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ describe("Keeper", () => {
|
||||
|
||||
it("should get development as default", async () => {
|
||||
const networkName: string = await keeper.getNetworkName()
|
||||
assert(networkName === "development")
|
||||
assert(networkName === "Development")
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -17,7 +17,9 @@ export default class TestContractHandler extends ContractHandler {
|
||||
await TestContractHandler.deployContracts(deployerAddress)
|
||||
|
||||
// register templates
|
||||
Logger.log(`Registering Access Template from ${deployerAddress}`)
|
||||
await new ServiceAgreementTemplate(new Access()).register(deployerAddress)
|
||||
Logger.log(`Registering FitchainCompute Template from ${deployerAddress}`)
|
||||
await new ServiceAgreementTemplate(new FitchainCompute()).register(deployerAddress)
|
||||
}
|
||||
|
||||
@ -78,7 +80,7 @@ export default class TestContractHandler extends ContractHandler {
|
||||
|
||||
// dont redeploy if there is already something loaded
|
||||
if (ContractHandler.has(name)) {
|
||||
return ContractHandler.get(name)
|
||||
return await ContractHandler.get(name)
|
||||
}
|
||||
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
|
@ -1,8 +1,20 @@
|
||||
import Aquarius from "../../src/aquarius/Aquarius"
|
||||
import DDO from "../../src/ddo/DDO"
|
||||
|
||||
const ddoStore: Map<string, any> = new Map<string, any>()
|
||||
|
||||
export default class AquariusMock extends Aquarius {
|
||||
|
||||
public async getAccessUrl(accessToken: any, payload: any): Promise<string> {
|
||||
return "http://test/test"
|
||||
}
|
||||
|
||||
public async storeDDO(ddo: DDO): Promise<DDO> {
|
||||
ddoStore.set(ddo.id, ddo)
|
||||
return ddo
|
||||
}
|
||||
|
||||
public async retrieveDDO(did: string): Promise<DDO> {
|
||||
return ddoStore.get(did)
|
||||
}
|
||||
}
|
||||
|
10
test/mocks/Brizo.mock.ts
Normal file
10
test/mocks/Brizo.mock.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import Brizo from "../../src/brizo/Brizo"
|
||||
|
||||
export default class BrizoMock extends Brizo {
|
||||
|
||||
public async initializeServiceAgreement(did: string, serviceAgreementId: string, serviceDefinitionId: string,
|
||||
signature: string, consumerPublicKey: string): Promise<any> {
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import AquariusConnector from "../../src/aquarius/AquariusConnector"
|
||||
import WebServiceConnector from "../../src/utils/WebServiceConnector"
|
||||
|
||||
// @ts-ignore
|
||||
export default class AquariusConnectorMock extends AquariusConnector {
|
||||
export default class WebServiceConnectorMock extends WebServiceConnector {
|
||||
|
||||
constructor(private returnData: any) {
|
||||
super()
|
||||
@ -14,10 +14,10 @@ export default class AquariusConnectorMock extends AquariusConnector {
|
||||
resolve({
|
||||
ok: true,
|
||||
json: () => {
|
||||
return this.returnData ? this.returnData : []
|
||||
return this.returnData ? this.returnData : {}
|
||||
},
|
||||
text: () => {
|
||||
return this.returnData ? this.returnData.toString() : ""
|
||||
return this.returnData ? JSON.stringify(this.returnData.toString()) : ""
|
||||
},
|
||||
})
|
||||
})
|
@ -75,4 +75,14 @@ describe("Account", () => {
|
||||
assert(tokensGranted === tokens)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getPublicKey()", () => {
|
||||
|
||||
it("should get the public key of an account", async () => {
|
||||
const publicKey = await accounts[1].getPublicKey()
|
||||
assert(publicKey)
|
||||
|
||||
assert(publicKey.length === 128)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,16 +1,22 @@
|
||||
import {assert} from "chai"
|
||||
import AquariusProvider from "../../src/aquarius/AquariusProvider"
|
||||
import SearchQuery from "../../src/aquarius/query/SearchQuery"
|
||||
import BrizoProvider from "../../src/brizo/BrizoProvider"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import DDO from "../../src/ddo/DDO"
|
||||
import MetaData from "../../src/ddo/MetaData"
|
||||
import Service from "../../src/ddo/Service"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import ServiceAgreement from "../../src/ocean/ServiceAgreements/ServiceAgreement"
|
||||
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
||||
import WebServiceConnectorProvider from "../../src/utils/WebServiceConnectorProvider"
|
||||
import config from "../config"
|
||||
import TestContractHandler from "../keeper/TestContractHandler"
|
||||
import AquariusMock from "../mocks/Aquarius.mock"
|
||||
import BrizoMock from "../mocks/Brizo.mock"
|
||||
import SecretStoreMock from "../mocks/SecretStore.mock"
|
||||
import WebServiceConnectorMock from "../mocks/WebServiceConnector.mock"
|
||||
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
@ -21,6 +27,7 @@ describe("Ocean", () => {
|
||||
before(async () => {
|
||||
ConfigProvider.setConfig(config)
|
||||
AquariusProvider.setAquarius(new AquariusMock(config))
|
||||
BrizoProvider.setBrizo(new BrizoMock(config))
|
||||
SecretStoreProvider.setSecretStore(new SecretStoreMock(config))
|
||||
await TestContractHandler.prepareContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
@ -52,6 +59,21 @@ describe("Ocean", () => {
|
||||
|
||||
})
|
||||
|
||||
describe("#resolveDID()", () => {
|
||||
|
||||
it("should resolve a did to a ddo", async () => {
|
||||
|
||||
const metaData: MetaData = new MetaData()
|
||||
const ddo: DDO = await ocean.registerAsset(metaData, testPublisher)
|
||||
|
||||
const resolvedDDO: DDO = await ocean.resolveDID(ddo.id)
|
||||
|
||||
assert(resolvedDDO)
|
||||
assert(resolvedDDO.id === ddo.id)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#registerAsset()", () => {
|
||||
|
||||
it("should register an asset", async () => {
|
||||
@ -97,4 +119,54 @@ describe("Ocean", () => {
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#signServiceAgreement()", () => {
|
||||
|
||||
it("should sign an service agreement", async () => {
|
||||
|
||||
const publisher = accounts[0]
|
||||
const consumer = accounts[1]
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(new MetaData(), publisher)
|
||||
|
||||
const service: Service = ddo.findServiceByType("Access")
|
||||
|
||||
// @ts-ignore
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
|
||||
const serviceAgreementSignature: any = await ocean.signServiceAgreement(ddo.id,
|
||||
service.serviceDefinitionId, consumer)
|
||||
|
||||
assert(serviceAgreementSignature)
|
||||
assert(serviceAgreementSignature.serviceAgreementId)
|
||||
assert(serviceAgreementSignature.serviceAgreementSignature)
|
||||
assert(serviceAgreementSignature.serviceAgreementSignature.startsWith("0x"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#executeServiceAgreement()", () => {
|
||||
|
||||
it("should execute an service agreement", async () => {
|
||||
|
||||
const publisher = accounts[0]
|
||||
const consumer = accounts[1]
|
||||
|
||||
const ddo: DDO = await ocean.registerAsset(new MetaData(), publisher)
|
||||
const service: Service = ddo.findServiceByType("Access")
|
||||
|
||||
// @ts-ignore
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
|
||||
const signServiceAgreementResult: any = await ocean.signServiceAgreement(ddo.id,
|
||||
service.serviceDefinitionId, consumer)
|
||||
|
||||
const serviceAgreement: ServiceAgreement = await ocean.executeServiceAgreement(ddo.id,
|
||||
service.serviceDefinitionId, signServiceAgreementResult.serviceAgreementId,
|
||||
signServiceAgreementResult.serviceAgreementSignature, consumer, publisher)
|
||||
|
||||
assert(serviceAgreement)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
@ -1,10 +1,13 @@
|
||||
import {assert} from "chai"
|
||||
import AquariusConnectorProvider from "../../src/aquarius/AquariusConnectorProvider"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import DDOCondition from "../../src/ddo/Condition"
|
||||
import DDO from "../../src/ddo/DDO"
|
||||
import Event from "../../src/ddo/Event"
|
||||
import EventHandlers from "../../src/ddo/EventHandlers"
|
||||
import MetaData from "../../src/ddo/MetaData"
|
||||
import Parameter from "../../src/ddo/Parameter"
|
||||
import Service from "../../src/ddo/Service"
|
||||
import InputType from "../../src/models/InputType"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import IdGenerator from "../../src/ocean/IdGenerator"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
@ -12,16 +15,20 @@ import Condition from "../../src/ocean/ServiceAgreements/Condition"
|
||||
import ServiceAgreement from "../../src/ocean/ServiceAgreements/ServiceAgreement"
|
||||
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreements/ServiceAgreementTemplate"
|
||||
import Access from "../../src/ocean/ServiceAgreements/Templates/Access"
|
||||
import WebServiceConnectorProvider from "../../src/utils/WebServiceConnectorProvider"
|
||||
import config from "../config"
|
||||
import TestContractHandler from "../keeper/TestContractHandler"
|
||||
import AquariusConnectorMock from "../mocks/AquariusConnector.mock"
|
||||
import WebServiceConnectorMock from "../mocks/WebServiceConnector.mock"
|
||||
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
let publisherAccount: Account
|
||||
let consumerAccount: Account
|
||||
|
||||
let serviceDefinition
|
||||
let accessService: Service
|
||||
let metaDataService: Service
|
||||
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
|
||||
describe("ServiceAgreement", () => {
|
||||
|
||||
@ -34,6 +41,7 @@ describe("ServiceAgreement", () => {
|
||||
publisherAccount = accounts[1]
|
||||
consumerAccount = accounts[2]
|
||||
|
||||
const metadata = new MetaData()
|
||||
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
||||
new ServiceAgreementTemplate(new Access())
|
||||
|
||||
@ -41,44 +49,108 @@ describe("ServiceAgreement", () => {
|
||||
const conditions: Condition[] = await serviceAgreementTemplate.getConditions()
|
||||
|
||||
// create ddo conditions out of the keys
|
||||
const ddoConditions: DDOCondition[] = conditions.map((condition): DDOCondition => {
|
||||
const ddoConditions: DDOCondition[] = conditions.map((condition, index): DDOCondition => {
|
||||
|
||||
const events: Event[] = [
|
||||
{
|
||||
name: "PaymentReleased",
|
||||
actorType: [
|
||||
"consumer",
|
||||
],
|
||||
handlers: {
|
||||
moduleName: "serviceAgreement",
|
||||
functionName: "fulfillAgreement",
|
||||
version: "0.1",
|
||||
} as EventHandlers,
|
||||
} as Event,
|
||||
]
|
||||
|
||||
const mapParameterValueToName = (name) => {
|
||||
|
||||
switch (name) {
|
||||
case "price":
|
||||
return metadata.base.price
|
||||
case "assetId":
|
||||
return "0x" + assetId
|
||||
case "documentKeyId":
|
||||
return "0x1234"
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const parameters: Parameter[] = condition.methodReflection.inputs.map((input: InputType) => {
|
||||
return {
|
||||
name: input.name,
|
||||
type: input.type,
|
||||
value: mapParameterValueToName(input.name),
|
||||
} as Parameter
|
||||
})
|
||||
|
||||
return {
|
||||
name: condition.methodReflection.methodName,
|
||||
contractName: condition.methodReflection.contractName,
|
||||
methodName: condition.methodReflection.methodName,
|
||||
timeout: condition.timeout,
|
||||
index,
|
||||
conditionKey: condition.condtionKey,
|
||||
parameters: condition.methodReflection.inputs.map((input) => {
|
||||
return {
|
||||
...input,
|
||||
value: "xx",
|
||||
}as Parameter
|
||||
}),
|
||||
parameters,
|
||||
events,
|
||||
dependencies: condition.dependencies,
|
||||
dependencyTimeoutFlags: condition.dependencyTimeoutFlags,
|
||||
isTerminalCondition: condition.isTerminalCondition,
|
||||
} as DDOCondition
|
||||
})
|
||||
|
||||
serviceDefinition = [
|
||||
{
|
||||
serviceDefinitionId: IdGenerator.generateId(),
|
||||
templateId: serviceAgreementTemplate.getId(),
|
||||
conditions: ddoConditions,
|
||||
} as Service,
|
||||
]
|
||||
accessService = {
|
||||
type: "Access",
|
||||
serviceDefinitionId: IdGenerator.generateId(),
|
||||
templateId: serviceAgreementTemplate.getId(),
|
||||
conditions: ddoConditions,
|
||||
} as Service
|
||||
|
||||
metaDataService = {
|
||||
type: "MetaData",
|
||||
metadata,
|
||||
} as Service
|
||||
})
|
||||
|
||||
describe("#signServiceAgreement()", () => {
|
||||
it("should sign an service agreement", async () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
const did: string = `did:op:${id}`
|
||||
const ddo = new DDO({id: did, service: [accessService]})
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
|
||||
// @ts-ignore
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
|
||||
const serviceAgreementSignature: string =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, consumerAccount)
|
||||
|
||||
assert(serviceAgreementSignature)
|
||||
assert(serviceAgreementSignature.startsWith("0x"))
|
||||
})
|
||||
})
|
||||
|
||||
describe("#executeServiceAgreement()", () => {
|
||||
it("should execute an service agreement", async () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
const did: string = `did:op:${id}`
|
||||
const ddo = new DDO({id: did, service: serviceDefinition})
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
const ddo = new DDO({id: did, service: [accessService]})
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
const serviceAgreementSignature: string =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, consumerAccount)
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, serviceAgreementId, consumerAccount,
|
||||
publisherAccount)
|
||||
await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
|
||||
assert(serviceAgreement)
|
||||
|
||||
const serviceDefinitionId = serviceAgreement.getId()
|
||||
@ -92,15 +164,19 @@ describe("ServiceAgreement", () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
const did: string = `did:op:${id}`
|
||||
const ddo = new DDO({id: did, service: serviceDefinition})
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
const ddo = new DDO({id: did, service: [accessService]})
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
const serviceAgreementSignature: string =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, consumerAccount)
|
||||
assert(serviceAgreementSignature)
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, serviceAgreementId, consumerAccount,
|
||||
publisherAccount)
|
||||
await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
|
||||
assert(serviceAgreement)
|
||||
|
||||
const status = await serviceAgreement.getStatus()
|
||||
@ -108,24 +184,57 @@ describe("ServiceAgreement", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#grantAccess()", () => {
|
||||
it("should grant access in that service agreement", async () => {
|
||||
describe("#lockPayment()", () => {
|
||||
xit("should lock the payment in that service agreement", async () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
const did: string = `did:op:${id}`
|
||||
const ddo = new DDO({id: did, service: serviceDefinition})
|
||||
const assetId: string = IdGenerator.generateId()
|
||||
const ddo = new DDO({id: did, service: [accessService, metaDataService]})
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
|
||||
// @ts-ignore
|
||||
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
const serviceAgreementSignature: string =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, consumerAccount)
|
||||
assert(serviceAgreementSignature)
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, serviceAgreementId, consumerAccount,
|
||||
publisherAccount)
|
||||
await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
|
||||
assert(serviceAgreement)
|
||||
|
||||
const fulfilled: boolean = await serviceAgreement.grantAccess(assetId, IdGenerator.generateId())
|
||||
assert(fulfilled)
|
||||
const paid: boolean = await serviceAgreement.lockPayment(assetId, metaDataService.metadata.base.price,
|
||||
consumerAccount)
|
||||
assert(paid)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#grantAccess()", () => {
|
||||
xit("should grant access in that service agreement", async () => {
|
||||
|
||||
const id: string = IdGenerator.generateId()
|
||||
const did: string = `did:op:${id}`
|
||||
const ddo = new DDO({id: did, service: [accessService]})
|
||||
const serviceAgreementId: string = IdGenerator.generateId()
|
||||
|
||||
// @ts-ignore
|
||||
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
|
||||
const serviceAgreementSignature: string =
|
||||
await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, consumerAccount)
|
||||
assert(serviceAgreementSignature)
|
||||
|
||||
const serviceAgreement: ServiceAgreement =
|
||||
await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
|
||||
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
|
||||
assert(serviceAgreement)
|
||||
|
||||
const paid: boolean = await serviceAgreement.lockPayment(assetId, 10, consumerAccount)
|
||||
assert(paid)
|
||||
|
||||
const accessGranted: boolean = await serviceAgreement.grantAccess(assetId, IdGenerator.generateId())
|
||||
assert(accessGranted)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -39,6 +39,20 @@ describe("ServiceAgreementTemplate", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getConditions()", () => {
|
||||
it("should setup an Access agreement template correctly", async () => {
|
||||
|
||||
const access: TemplateBase = new Access()
|
||||
access.id = IdGenerator.generatePrefixedId()
|
||||
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
||||
new ServiceAgreementTemplate(access)
|
||||
assert(serviceAgreementTemplate)
|
||||
|
||||
const conds = await serviceAgreementTemplate.getConditions()
|
||||
assert(conds)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getStatus()", () => {
|
||||
it("should get the status of a newly deployed agreement template", async () => {
|
||||
|
||||
|
34
test/testdata/MetaData.ts
vendored
Normal file
34
test/testdata/MetaData.ts
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import MetaDataModel from "../../src/ddo/MetaData"
|
||||
import MetaDataBase from "../../src/ddo/MetaDataBase"
|
||||
|
||||
const MetaData = new MetaDataModel({
|
||||
base: {
|
||||
name: "Office Humidity",
|
||||
type: "dataset",
|
||||
description: "Weather information of UK including temperature and humidity",
|
||||
size: "3.1gb",
|
||||
dateCreated: "2012-02-01T10:55:11+00:00",
|
||||
author: "Met Office",
|
||||
license: "CC-BY",
|
||||
copyrightHolder: "Met Office",
|
||||
encoding: "UTF-8",
|
||||
compression: "zip",
|
||||
contentType: "text/csv",
|
||||
// tslint:disable-next-line
|
||||
workExample: "stationId,latitude,longitude,datetime,temperature,humidity423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68",
|
||||
contentUrls: [
|
||||
"https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip",
|
||||
"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,
|
||||
} as MetaDataModel)
|
||||
|
||||
export default MetaData
|
Loading…
Reference in New Issue
Block a user