mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
integrate DDO more
This commit is contained in:
parent
a32d6cbdbf
commit
6e2b270a1f
6
package-lock.json
generated
6
package-lock.json
generated
@ -120,9 +120,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@oceanprotocol/keeper-contracts": {
|
"@oceanprotocol/keeper-contracts": {
|
||||||
"version": "0.3.11",
|
"version": "0.3.12",
|
||||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.3.12.tgz",
|
||||||
"integrity": "sha512-4xJtXc77Rw1pO9yt1NryFypx3KOzQcKX6Iv7c5dKXIh+FigSmrOPgVFtbFj0bwtLwpmt2+2JIYd/iiN943q/fw=="
|
"integrity": "sha512-mJAldSLxyAhfhEI0IB5o3HVLGeZ65dz69331COPrsOoEsy288bhX1QMwdJS4B1C5nO3cvf41Xgp8qgCpTouNvA=="
|
||||||
},
|
},
|
||||||
"@oceanprotocol/secret-store-client": {
|
"@oceanprotocol/secret-store-client": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"build": "npm run clean && npm run lint && tsc && npm run doc",
|
"build": "npm run clean && npm run lint && tsc && npm run doc",
|
||||||
"build:watch": "tsc -w",
|
"build:watch": "tsc -w",
|
||||||
"doc": "typedoc --mode modules --out ./doc/ ./src/",
|
"doc": "typedoc --mode modules --out ./doc/ ./src/",
|
||||||
|
"run": "ts-node",
|
||||||
"release": "./node_modules/release-it/bin/release-it.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release": "./node_modules/release-it/bin/release-it.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"release-minor": "./node_modules/release-it/bin/release-it.js minor --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release-minor": "./node_modules/release-it/bin/release-it.js minor --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"release-major": "./node_modules/release-it/bin/release-it.js major --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release-major": "./node_modules/release-it/bin/release-it.js major --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
@ -50,8 +51,8 @@
|
|||||||
"node": ">=8 <10"
|
"node": ">=8 <10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oceanprotocol/keeper-contracts": "^0.3.11",
|
"@oceanprotocol/keeper-contracts": "^0.3.12",
|
||||||
"@oceanprotocol/secret-store-client": "^0.0.7",
|
"@oceanprotocol/secret-store-client": "0.0.7",
|
||||||
"bignumber.js": "^8.0.1",
|
"bignumber.js": "^8.0.1",
|
||||||
"eth-crypto": "^1.2.5",
|
"eth-crypto": "^1.2.5",
|
||||||
"eth-ecies": "^1.0.3",
|
"eth-ecies": "^1.0.3",
|
||||||
|
6
src/ddo/Condition.ts
Normal file
6
src/ddo/Condition.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default class Condition {
|
||||||
|
public name: string = "lockPayment"
|
||||||
|
public timeout: number = 0
|
||||||
|
public conditionKey: string
|
||||||
|
public parameters: any
|
||||||
|
}
|
@ -1,8 +1,13 @@
|
|||||||
|
import Condition from "./Condition"
|
||||||
import MetaData from "./MetaData"
|
import MetaData from "./MetaData"
|
||||||
|
|
||||||
export default class Service {
|
export default class Service {
|
||||||
public type: string = "OpenIdConnectVersion1.0Service"
|
public type: string = "OpenIdConnectVersion1.0Service"
|
||||||
|
public serviceDefinitionId?: string
|
||||||
|
public templateId?: string
|
||||||
public serviceEndpoint: string = "https://openid.example.com/"
|
public serviceEndpoint: string = "https://openid.example.com/"
|
||||||
|
public purchaseEndpoint?: string
|
||||||
public description?: string = "My public social inbox"
|
public description?: string = "My public social inbox"
|
||||||
public metadata?: MetaData = {} as MetaData
|
public metadata?: MetaData = {} as MetaData
|
||||||
|
public conditions?: Condition[] = []
|
||||||
}
|
}
|
||||||
|
33
src/examples/GrantAccess.ts
Normal file
33
src/examples/GrantAccess.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import ServiceAgreement from "../ocean/ServiceAgreement"
|
||||||
|
import {Account, Asset, 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 consumer: Account = (await ocean.getAccounts())[0]
|
||||||
|
|
||||||
|
const asset: Asset = new Asset(
|
||||||
|
"Fancy Car Data",
|
||||||
|
"nice data",
|
||||||
|
100, publisher)
|
||||||
|
|
||||||
|
const assetDid = await ocean.register(asset)
|
||||||
|
Logger.log("asset did:", assetDid)
|
||||||
|
|
||||||
|
const serviceAgreement: ServiceAgreement = await asset.purchase(consumer)
|
||||||
|
Logger.log("service defintion id:", serviceAgreement.getId())
|
||||||
|
|
||||||
|
const accessGranted: boolean =
|
||||||
|
await serviceAgreement.grantAccess(asset.getId(), "321721938712931283")
|
||||||
|
|
||||||
|
Logger.log("access granted:", accessGranted)
|
||||||
|
})()
|
28
src/examples/Purchase.ts
Normal file
28
src/examples/Purchase.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import {Account, Asset, Logger, Ocean} from "../squid"
|
||||||
|
import ServiceAgreement from "../ocean/ServiceAgreement"
|
||||||
|
|
||||||
|
(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 consumer: Account = (await ocean.getAccounts())[1]
|
||||||
|
|
||||||
|
const asset: Asset = new Asset(
|
||||||
|
"Fancy Car Data",
|
||||||
|
"nice data",
|
||||||
|
100, publisher)
|
||||||
|
|
||||||
|
const assetDid = await ocean.register(asset)
|
||||||
|
Logger.log(assetDid)
|
||||||
|
|
||||||
|
const serviceAgreement: ServiceAgreement = await asset.purchase(consumer)
|
||||||
|
Logger.log(serviceAgreement.getId())
|
||||||
|
})()
|
22
src/examples/Register.ts
Normal file
22
src/examples/Register.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import {Account, Asset, 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 asset: Asset = new Asset(
|
||||||
|
"Fancy Car Data",
|
||||||
|
"nice data", 100,
|
||||||
|
publisher)
|
||||||
|
const assetDid = await ocean.register(asset)
|
||||||
|
|
||||||
|
Logger.log(assetDid)
|
||||||
|
})()
|
@ -24,18 +24,19 @@ export default class ServiceAgreement extends ContractBase {
|
|||||||
return this.call("getTemplateStatus", [templateId])
|
return this.call("getTemplateStatus", [templateId])
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAgreementStatus(serviceAgreementId: string) {
|
public async getAgreementStatus(serviceDefinitionId: string) {
|
||||||
|
|
||||||
return this.call("getAgreementStatus", ["0x" + serviceAgreementId])
|
return this.call("getAgreementStatus", [serviceDefinitionId])
|
||||||
}
|
}
|
||||||
|
|
||||||
public async executeAgreement(serviceAgreementTemplateId: string, serviceAgreementSignatureHash: string,
|
public async executeAgreement(serviceAgreementTemplateId: string, serviceAgreementSignatureHash: string,
|
||||||
consumerAddress: string, valueHashes: string[], timeoutValues: number[],
|
consumerAddress: string, valueHashes: string[], timeoutValues: number[],
|
||||||
serviceAgreementId: string, did: string, publisherAddress: string): Promise<Receipt> {
|
serviceAgreementId: string, did: string, publisherAddress: string):
|
||||||
|
Promise<Receipt> {
|
||||||
|
|
||||||
return this.send("executeAgreement", publisherAddress, [
|
return this.send("executeAgreement", publisherAddress, [
|
||||||
serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes,
|
serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes,
|
||||||
timeoutValues, "0x" + serviceAgreementId, "0x" + did,
|
timeoutValues, "0x" + serviceAgreementId, "0x" + did.replace("did:op:", ""),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ export default class AccessConditions extends ContractBase {
|
|||||||
return accessConditions
|
return accessConditions
|
||||||
}
|
}
|
||||||
|
|
||||||
public async grantAccess(serviceAgreementId: any, assetId: any, documentKeyId: any, publisherAddress: string)
|
public async grantAccess(serviceDefinitionId: any, assetId: any, documentKeyId: any, publisherAddress: string)
|
||||||
: Promise<Receipt> {
|
: Promise<Receipt> {
|
||||||
return this.send("grantAccess", publisherAddress, [
|
return this.send("grantAccess", publisherAddress, [
|
||||||
"0x" + serviceAgreementId, "0x" + assetId, "0x" + documentKeyId,
|
serviceDefinitionId, "0x" + assetId, "0x" + documentKeyId,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ export default class Config {
|
|||||||
|
|
||||||
/* Keeper Config */
|
/* Keeper Config */
|
||||||
// the uri to the node we want to connect to, not need if web3Provider is set
|
// the uri to the node we want to connect to, not need if web3Provider is set
|
||||||
public nodeUri: string
|
public nodeUri?: string
|
||||||
// from outside eg. metamask
|
// from outside eg. metamask
|
||||||
public web3Provider: any
|
public web3Provider?: any
|
||||||
|
|
||||||
/* Secret Store Config */
|
/* Secret Store Config */
|
||||||
// the uri of the secret store to connect to
|
// the uri of the secret store to connect to
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import * as EthCrypto from "eth-crypto"
|
import AquariusProvider from "../aquarius/AquariusProvider"
|
||||||
import * as EthjsUtil from "ethereumjs-util"
|
|
||||||
import Keeper from "../keeper/Keeper"
|
|
||||||
import Logger from "../utils/Logger"
|
|
||||||
import Account from "./Account"
|
import Account from "./Account"
|
||||||
|
import IdGenerator from "./IdGenerator"
|
||||||
import OceanBase from "./OceanBase"
|
import OceanBase from "./OceanBase"
|
||||||
import Order from "./Order"
|
import ServiceAgreement from "./ServiceAgreement"
|
||||||
|
|
||||||
export default class Asset extends OceanBase {
|
export default class Asset extends OceanBase {
|
||||||
|
|
||||||
@ -15,42 +13,15 @@ export default class Asset extends OceanBase {
|
|||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
public async purchase(consumer: Account, timeout: number): Promise<Order> {
|
public async purchase(consumer: Account): Promise<ServiceAgreement> {
|
||||||
const {token, market, auth} = await Keeper.getInstance()
|
|
||||||
|
|
||||||
const key = EthCrypto.createIdentity()
|
const did = `did:op:${this.getId()}`
|
||||||
const publicKey = EthjsUtil.privateToPublic(key.privateKey).toString("hex")
|
const ddo = await AquariusProvider.getAquarius().retrieveDDO(did)
|
||||||
const price = await market.getAssetPrice(this.getId())
|
|
||||||
const isValid = await market.isAssetActive(this.getId())
|
|
||||||
|
|
||||||
Logger.log("The asset:", this.getId(), "is it valid?", isValid, "it's price is:", price)
|
const serviceAgreementId: string = IdGenerator.generateId()
|
||||||
|
const serviceAgreement: ServiceAgreement = await ServiceAgreement.createServiceAgreement(this.getId(),
|
||||||
|
ddo, serviceAgreementId, consumer, this.publisher)
|
||||||
|
|
||||||
if (!isValid) {
|
return serviceAgreement
|
||||||
throw new Error("The Asset is not valid!")
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const marketAddr = market.getAddress()
|
|
||||||
// Allow market contract to transfer funds on the consumer"s behalf
|
|
||||||
await token.approve(marketAddr, price, consumer.getId())
|
|
||||||
Logger.log(`${price} tokens approved on market with id: ${marketAddr}`)
|
|
||||||
} catch (err) {
|
|
||||||
Logger.error("token.approve failed", err)
|
|
||||||
}
|
|
||||||
let order: Order
|
|
||||||
try {
|
|
||||||
// Submit the access request
|
|
||||||
const initiateAccessRequestReceipt = await auth.initiateAccessRequest(this,
|
|
||||||
publicKey, timeout, consumer.getId())
|
|
||||||
|
|
||||||
const {returnValues} = initiateAccessRequestReceipt.events.AccessConsentRequested
|
|
||||||
Logger.log(`Keeper AccessConsentRequested event received on asset: ${this.getId()}`)
|
|
||||||
order = new Order(this, returnValues._timeout, returnValues._pubKey, key)
|
|
||||||
order.setId(returnValues._id)
|
|
||||||
} catch (err) {
|
|
||||||
Logger.error("auth.initiateAccessRequest failed", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return order
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import AquariusProvider from "../aquarius/AquariusProvider"
|
import AquariusProvider from "../aquarius/AquariusProvider"
|
||||||
|
import SearchQuery from "../aquarius/query/SearchQuery"
|
||||||
import ConfigProvider from "../ConfigProvider"
|
import ConfigProvider from "../ConfigProvider"
|
||||||
|
import Condition from "../ddo/Condition"
|
||||||
|
import DDO from "../ddo/DDO"
|
||||||
|
import Service from "../ddo/Service"
|
||||||
import Keeper from "../keeper/Keeper"
|
import Keeper from "../keeper/Keeper"
|
||||||
import Web3Provider from "../keeper/Web3Provider"
|
import Web3Provider from "../keeper/Web3Provider"
|
||||||
import Config from "../models/Config"
|
import Config from "../models/Config"
|
||||||
import SecretStoreProvider from "../secretstore/SecretStoreProvider"
|
|
||||||
import Logger from "../utils/Logger"
|
|
||||||
import Account from "./Account"
|
import Account from "./Account"
|
||||||
import Asset from "./Asset"
|
import Asset from "./Asset"
|
||||||
import IdGenerator from "./IdGenerator"
|
import IdGenerator from "./IdGenerator"
|
||||||
import Order from "./Order"
|
import ServiceAgreementTemplate from "./ServiceAgreementTemplate"
|
||||||
|
|
||||||
export default class Ocean {
|
export default class Ocean {
|
||||||
|
|
||||||
@ -37,71 +39,71 @@ export default class Ocean {
|
|||||||
return ethAccounts.map((address: string) => new Account(address))
|
return ethAccounts.map((address: string) => new Account(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
public async register(asset: Asset): Promise<string> {
|
public async register(asset: Asset): Promise<DDO> {
|
||||||
|
|
||||||
const {market} = this.keeper
|
const {market} = this.keeper
|
||||||
|
|
||||||
const secretStore = SecretStoreProvider.getSecretStore()
|
const assetId: string = IdGenerator.generateId()
|
||||||
|
const did: string = `did:op:${assetId}`
|
||||||
|
|
||||||
const assetId = IdGenerator.generateId()
|
const methods: string[] = [
|
||||||
|
"PaymentConditions.lockPayment",
|
||||||
|
"AccessConditions.grantAccess",
|
||||||
|
"PaymentConditions.releasePayment",
|
||||||
|
"PaymentConditions.refundPayment",
|
||||||
|
]
|
||||||
|
// tslint:disable
|
||||||
|
const dependencyMatrix = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
||||||
|
|
||||||
const encryptedDocument = await secretStore.encryptDocument(assetId, asset)
|
const serviceName = "Access"
|
||||||
|
const saTemplate: ServiceAgreementTemplate =
|
||||||
|
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(serviceName, methods, dependencyMatrix,
|
||||||
|
asset.publisher)
|
||||||
|
|
||||||
const decryptedDocument = await secretStore.decryptDocument(assetId, encryptedDocument)
|
// get condition keys from template
|
||||||
|
const conditionKeys: string[] = saTemplate.getConditionKeys()
|
||||||
|
|
||||||
Logger.log(decryptedDocument, encryptedDocument)
|
// create ddo conditions out of the keys
|
||||||
|
const conditions: Condition[] = conditionKeys.map((conditionKey, i): Condition => {
|
||||||
// generate an id
|
return {
|
||||||
Logger.log(`Registering: ${assetId} with price ${asset.price} for ${asset.publisher.getId()}`)
|
name: methods[i].split(".")[1],
|
||||||
asset.setId(assetId)
|
timeout: 100,
|
||||||
const isAssetActive = await market.isAssetActive(assetId)
|
conditionKey: conditionKey,
|
||||||
// register asset in the market
|
parameters: {
|
||||||
if (!isAssetActive) {
|
// todo wtf?
|
||||||
const result = await market.register(asset.getId(), asset.price, asset.publisher.getId())
|
assetId: "bytes32",
|
||||||
Logger.log("Registered:", assetId, "in block", result.blockNumber)
|
price: "integer"
|
||||||
} else {
|
|
||||||
throw new Error("Asset already registered")
|
|
||||||
}
|
|
||||||
return assetId
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getOrdersByAccount(consumer: Account): Promise<Order[]> {
|
|
||||||
const {auth} = this.keeper
|
|
||||||
|
|
||||||
Logger.log("Getting orders")
|
|
||||||
|
|
||||||
const accessConsentRequestedData = await auth.getEventData(
|
|
||||||
"AccessConsentRequested", {
|
|
||||||
filter: {
|
|
||||||
_consumer: consumer.getId(),
|
|
||||||
},
|
},
|
||||||
fromBlock: 0,
|
} as Condition
|
||||||
toBlock: "latest",
|
})
|
||||||
})
|
|
||||||
|
|
||||||
const orders = await Promise.all(
|
// create ddo itself
|
||||||
accessConsentRequestedData
|
const ddo: DDO = new DDO({
|
||||||
.map(async (event: any) => {
|
id: did,
|
||||||
|
service: [
|
||||||
|
{
|
||||||
|
type: serviceName,
|
||||||
|
// tslint:disable
|
||||||
|
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?",
|
||||||
|
// the id of the service agreement?
|
||||||
|
serviceDefinitionId: "0x" + IdGenerator.generateId(),
|
||||||
|
// the id of the service agreement template
|
||||||
|
templateId: saTemplate.getId(),
|
||||||
|
conditions,
|
||||||
|
} as Service,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
const {returnValues} = event
|
|
||||||
|
|
||||||
const order: Order = new Order(
|
await AquariusProvider.getAquarius().storeDDO(ddo)
|
||||||
null,
|
asset.setId(assetId)
|
||||||
parseInt(returnValues._timeout, 10),
|
|
||||||
null, null)
|
|
||||||
|
|
||||||
order.setId(returnValues._id)
|
await market.register(assetId, asset.price, asset.publisher.getId())
|
||||||
|
return ddo
|
||||||
return order
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logger.log("Got orders:", JSON.stringify(orders, null, 2))
|
|
||||||
Logger.log(`Got ${Object.keys(orders).length} orders`)
|
|
||||||
|
|
||||||
return orders
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async searchAssets(query): Promise<any[]> {
|
public async searchAssets(query: SearchQuery): Promise<any[]> {
|
||||||
return AquariusProvider.getAquarius().queryMetadata(query)
|
return AquariusProvider.getAquarius().queryMetadata(query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,57 +1,86 @@
|
|||||||
|
import DDO from "../ddo/DDO"
|
||||||
import AccessConditions from "../keeper/contracts/conditions/AccessConditions"
|
import AccessConditions from "../keeper/contracts/conditions/AccessConditions"
|
||||||
import ServiceAgreementContract from "../keeper/contracts/ServiceAgreement"
|
import ServiceAgreementContract from "../keeper/contracts/ServiceAgreement"
|
||||||
import Web3Provider from "../keeper/Web3Provider"
|
import Web3Provider from "../keeper/Web3Provider"
|
||||||
import Account from "./Account"
|
import Account from "./Account"
|
||||||
import IdGenerator from "./IdGenerator"
|
|
||||||
import OceanBase from "./OceanBase"
|
import OceanBase from "./OceanBase"
|
||||||
import ServiceAgreementTemplate from "./ServiceAgreementTemplate"
|
|
||||||
|
|
||||||
export default class ServiceAgreement extends OceanBase {
|
export default class ServiceAgreement extends OceanBase {
|
||||||
|
|
||||||
public static async createServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, assetId: string,
|
public static async createServiceAgreement(assetId: string, ddo: DDO, serviceAgreementId: string, consumer: Account,
|
||||||
did: string, consumer: Account, publisher: Account) {
|
publisher: Account):
|
||||||
|
Promise<ServiceAgreement> {
|
||||||
|
|
||||||
|
const timeoutValues: number[] = ddo.service[0].conditions.map((condition) => {
|
||||||
|
return condition.timeout
|
||||||
|
})
|
||||||
|
|
||||||
// todo: this should come from ddo
|
// todo: this should come from ddo
|
||||||
const serviceAgreementId = IdGenerator.generateId()
|
|
||||||
const timeoutValues = [0, 0, 0, 500] // timeout 500 blocks @ condition 4
|
|
||||||
const values = [
|
const values = [
|
||||||
{type: "bool", value: true},
|
{type: "bool", value: true},
|
||||||
{type: "bool", value: false},
|
{type: "bool", value: false},
|
||||||
{type: "uint", value: 120},
|
{type: "uint", value: 120},
|
||||||
{type: "string", value: assetId},
|
{type: "string", value: serviceAgreementId},
|
||||||
]
|
]
|
||||||
|
|
||||||
const saHashSig = await ServiceAgreement.createSAHashSignature(serviceAgreementTemplate, serviceAgreementId,
|
const serviceAgreementHashSignature = await ServiceAgreement.createSAHashSignature(ddo, serviceAgreementId,
|
||||||
values, timeoutValues, consumer)
|
consumer)
|
||||||
|
|
||||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.signServiceAgreement(serviceAgreementTemplate,
|
const serviceAgreement: ServiceAgreement = await ServiceAgreement.signServiceAgreement(ddo,
|
||||||
serviceAgreementId, assetId, did, values, timeoutValues, saHashSig, consumer, publisher)
|
serviceAgreementId, values, timeoutValues, serviceAgreementHashSignature, consumer, publisher)
|
||||||
|
|
||||||
return serviceAgreement
|
return serviceAgreement
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async signServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate,
|
public static async createSAHashSignature(ddo: DDO, serviceAgreementId: string, consumer: Account):
|
||||||
serviceAgreementId: string, assetId: string, did: string, values: any[],
|
Promise<string> {
|
||||||
|
|
||||||
|
// todo get from ddo
|
||||||
|
const values = [
|
||||||
|
{type: "bool", value: true},
|
||||||
|
{type: "bool", value: false},
|
||||||
|
{type: "uint", value: 120},
|
||||||
|
{type: "string", value: serviceAgreementId},
|
||||||
|
]
|
||||||
|
|
||||||
|
const valueHashes = ServiceAgreement.createValueHashes(values)
|
||||||
|
|
||||||
|
const conditionKeys: string[] = ddo.service[0].conditions.map((condition) => {
|
||||||
|
return condition.conditionKey
|
||||||
|
})
|
||||||
|
|
||||||
|
const timeoutValues: number[] = ddo.service[0].conditions.map((condition) => {
|
||||||
|
return condition.timeout
|
||||||
|
})
|
||||||
|
|
||||||
|
const serviceAgreementHash = ServiceAgreement.hashServiceAgreement(ddo.service[0].templateId,
|
||||||
|
serviceAgreementId, conditionKeys, valueHashes, timeoutValues)
|
||||||
|
|
||||||
|
const serviceAgreementHashSignature =
|
||||||
|
await Web3Provider.getWeb3().eth.sign(serviceAgreementHash, consumer.getId())
|
||||||
|
|
||||||
|
return serviceAgreementHashSignature
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async signServiceAgreement(ddo: DDO, serviceAgreementId: string, values: any[],
|
||||||
timeoutValues: number[], serviceAgreementHashSignature: string,
|
timeoutValues: number[], serviceAgreementHashSignature: string,
|
||||||
consumer: Account, publisher: Account):
|
consumer: Account, publisher: Account):
|
||||||
Promise<ServiceAgreement> {
|
Promise<ServiceAgreement> {
|
||||||
|
|
||||||
const valueHashes = ServiceAgreement.createValueHashes(values)
|
const valueHashes = ServiceAgreement.createValueHashes(values)
|
||||||
|
|
||||||
const serviceAgreement: ServiceAgreementContract = await ServiceAgreementContract.getInstance()
|
const serviceAgreement: ServiceAgreementContract = await ServiceAgreementContract.getInstance()
|
||||||
|
|
||||||
const executeAgreementReceipt = await serviceAgreement.executeAgreement(
|
const executeAgreementReceipt = await serviceAgreement.executeAgreement(
|
||||||
serviceAgreementTemplate.getId(), serviceAgreementHashSignature, consumer.getId(), valueHashes,
|
ddo.service[0].templateId, serviceAgreementHashSignature, consumer.getId(), valueHashes,
|
||||||
timeoutValues, serviceAgreementId, did, publisher.getId())
|
timeoutValues, serviceAgreementId, ddo.id, publisher.getId())
|
||||||
|
|
||||||
if (executeAgreementReceipt.events.ExecuteAgreement.returnValues.state === false) {
|
if (executeAgreementReceipt.events.ExecuteAgreement.returnValues.state === false) {
|
||||||
throw new Error("signing service agreement failed.")
|
throw new Error("signing service agreement failed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ServiceAgreement(
|
return new ServiceAgreement(
|
||||||
serviceAgreementId,
|
executeAgreementReceipt.events.ExecuteAgreement.returnValues.serviceAgreementId,
|
||||||
|
ddo,
|
||||||
publisher,
|
publisher,
|
||||||
serviceAgreementTemplate,
|
|
||||||
consumer,
|
consumer,
|
||||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.state,
|
executeAgreementReceipt.events.ExecuteAgreement.returnValues.state,
|
||||||
executeAgreementReceipt.events.ExecuteAgreement.returnValues.status,
|
executeAgreementReceipt.events.ExecuteAgreement.returnValues.status,
|
||||||
@ -69,43 +98,30 @@ export default class ServiceAgreement extends OceanBase {
|
|||||||
return Web3Provider.getWeb3().utils.soliditySha3(args).toString("hex")
|
return Web3Provider.getWeb3().utils.soliditySha3(args).toString("hex")
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async createSAHashSignature(serviceAgreementTemplate: ServiceAgreementTemplate,
|
private static hashServiceAgreement(serviceAgreementTemplateId: string, serviceAgreementId: string,
|
||||||
serviceAgreementId: string, values: any[], timeoutValues: number[],
|
conditionKeys: string[], valueHashes: string[], timeouts: number[]) {
|
||||||
consumer: Account): Promise<string> {
|
|
||||||
|
|
||||||
const valueHashes = ServiceAgreement.createValueHashes(values)
|
|
||||||
|
|
||||||
const serviceAgreementHash = ServiceAgreement.hashServiceAgreement(serviceAgreementTemplate, valueHashes,
|
|
||||||
timeoutValues, serviceAgreementId)
|
|
||||||
const serviceAgreementHashSignature =
|
|
||||||
await Web3Provider.getWeb3().eth.sign(serviceAgreementHash, consumer.getId())
|
|
||||||
|
|
||||||
return serviceAgreementHashSignature
|
|
||||||
}
|
|
||||||
|
|
||||||
private static hashServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, valueHashes: string[],
|
|
||||||
timeouts: number[], serviceAgreementId: string) {
|
|
||||||
const args = [
|
const args = [
|
||||||
{type: "bytes32", value: serviceAgreementTemplate.getId()},
|
{type: "bytes32", value: serviceAgreementTemplateId},
|
||||||
{type: "bytes32[]", value: serviceAgreementTemplate.getConditionKeys()},
|
{type: "bytes32[]", value: conditionKeys},
|
||||||
{type: "bytes32[]", value: valueHashes},
|
{type: "bytes32[]", value: valueHashes},
|
||||||
{type: "uint256[]", value: timeouts},
|
{type: "uint256[]", value: timeouts},
|
||||||
{type: "bytes32", value: "0x" + serviceAgreementId},
|
{type: "bytes32", value: serviceAgreementId},
|
||||||
]
|
]
|
||||||
|
|
||||||
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
|
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(id: string, private publisher: Account, serviceAgreementTemplate: ServiceAgreementTemplate,
|
private constructor(serviceAgreementId: string, ddo: DDO, private publisher: Account, consumer: Account,
|
||||||
consumer: Account, state: boolean, status: boolean) {
|
state: boolean, status: boolean) {
|
||||||
super(id)
|
super(serviceAgreementId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async grantAccess(assetId: string, documentId: string): Promise<boolean> {
|
public async grantAccess(assetId: string, documentId: string): Promise<boolean> {
|
||||||
const accessConditions: AccessConditions = await AccessConditions.getInstance()
|
const accessConditions: AccessConditions = await AccessConditions.getInstance()
|
||||||
|
|
||||||
const grantAccessReceipt =
|
const grantAccessReceipt =
|
||||||
await accessConditions.grantAccess(this.getId(), assetId, documentId, this.publisher.getId())
|
await accessConditions.grantAccess(this.getId(), assetId, documentId,
|
||||||
|
this.publisher.getId())
|
||||||
|
|
||||||
return grantAccessReceipt.status
|
return grantAccessReceipt.status
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,12 @@ export default class ServiceAgreementTemplate extends OceanBase {
|
|||||||
Web3Provider.getWeb3().utils.fromAscii(serviceName),
|
Web3Provider.getWeb3().utils.fromAscii(serviceName),
|
||||||
templateOwner.getId())
|
templateOwner.getId())
|
||||||
|
|
||||||
const id = receipt.events.SetupAgreementTemplate.returnValues.serviceTemplateId
|
const serviceAgreementTemplateId =
|
||||||
|
receipt.events.SetupAgreementTemplate.returnValues.serviceTemplateId
|
||||||
|
|
||||||
return new ServiceAgreementTemplate(
|
return new ServiceAgreementTemplate(
|
||||||
id,
|
serviceAgreementTemplateId,
|
||||||
ServiceAgreementTemplate.generateConditionsKeys(id, methodReflections),
|
ServiceAgreementTemplate.generateConditionsKeys(serviceAgreementTemplateId, methodReflections),
|
||||||
templateOwner)
|
templateOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,17 +48,15 @@ export default class ServiceAgreementTemplate extends OceanBase {
|
|||||||
return conditions
|
return conditions
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(id, private conditionKeys: string[], private owner: Account) {
|
private constructor(serviceAgreementTemplateId, private conditionKeys: string[], private owner: Account) {
|
||||||
super(id)
|
super(serviceAgreementTemplateId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the status of a service agreement template
|
* gets the status of a service agreement template
|
||||||
*/
|
*/
|
||||||
public async getStatus(): Promise<boolean> {
|
public async getStatus(): Promise<boolean> {
|
||||||
|
|
||||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
||||||
|
|
||||||
return serviceAgreement.getTemplateStatus(this.getId())
|
return serviceAgreement.getTemplateStatus(this.getId())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ export default class SecretStoreProvider {
|
|||||||
SecretStoreProvider.secretStore = secretStore
|
SecretStoreProvider.secretStore = secretStore
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getSecretStore() {
|
public static getSecretStore(): SecretStore {
|
||||||
|
|
||||||
if (!SecretStoreProvider.secretStore) {
|
if (!SecretStoreProvider.secretStore) {
|
||||||
SecretStoreProvider.secretStore = new SecretStore(ConfigProvider.getConfig())
|
SecretStoreProvider.secretStore = new SecretStore(ConfigProvider.getConfig())
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Account from "./ocean/Account"
|
||||||
import Asset from "./ocean/Asset"
|
import Asset from "./ocean/Asset"
|
||||||
import Ocean from "./ocean/Ocean"
|
import Ocean from "./ocean/Ocean"
|
||||||
import Order from "./ocean/Order"
|
import Order from "./ocean/Order"
|
||||||
@ -8,4 +9,5 @@ export {
|
|||||||
Order,
|
Order,
|
||||||
Asset,
|
Asset,
|
||||||
Logger,
|
Logger,
|
||||||
|
Account,
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
import {assert} from "chai"
|
import {assert} from "chai"
|
||||||
|
import AquariusConnectorProvider from "../../src/aquarius/AquariusConnectorProvider"
|
||||||
import AquariusProvider from "../../src/aquarius/AquariusProvider"
|
import AquariusProvider from "../../src/aquarius/AquariusProvider"
|
||||||
import ConfigProvider from "../../src/ConfigProvider"
|
import ConfigProvider from "../../src/ConfigProvider"
|
||||||
|
import DDO from "../../src/ddo/DDO"
|
||||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||||
import Account from "../../src/ocean/Account"
|
import Account from "../../src/ocean/Account"
|
||||||
import Asset from "../../src/ocean/Asset"
|
import Asset from "../../src/ocean/Asset"
|
||||||
import Ocean from "../../src/ocean/Ocean"
|
import Ocean from "../../src/ocean/Ocean"
|
||||||
import Order from "../../src/ocean/Order"
|
import ServiceAgreement from "../../src/ocean/ServiceAgreement"
|
||||||
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
||||||
import config from "../config"
|
import config from "../config"
|
||||||
import AquariusMock from "../mocks/Aquarius.mock"
|
import AquariusMock from "../mocks/Aquarius.mock"
|
||||||
|
import AquariusConnectorMock from "../mocks/AquariusConnector.mock"
|
||||||
import SecretStoreMock from "../mocks/SecretStore.mock"
|
import SecretStoreMock from "../mocks/SecretStore.mock"
|
||||||
|
|
||||||
const testName = "Test Asset 2"
|
const testName = "Test Asset 2"
|
||||||
const testDescription = "This asset is pure owange"
|
const testDescription = "This asset is pure owange"
|
||||||
const testPrice = 100
|
const testPrice = 100
|
||||||
const timeout = 100000
|
|
||||||
|
|
||||||
let ocean: Ocean
|
let ocean: Ocean
|
||||||
let testAsset: Asset
|
let testAsset: Asset
|
||||||
let accounts: Account[]
|
let accounts: Account[]
|
||||||
let testPublisher: Account
|
let testPublisher: Account
|
||||||
|
let ddo: DDO
|
||||||
|
|
||||||
describe("Asset", () => {
|
describe("Asset", () => {
|
||||||
|
|
||||||
@ -33,17 +36,30 @@ describe("Asset", () => {
|
|||||||
testPublisher = accounts[0]
|
testPublisher = accounts[0]
|
||||||
testAsset = new Asset(testName, testDescription, testPrice, testPublisher)
|
testAsset = new Asset(testName, testDescription, testPrice, testPublisher)
|
||||||
|
|
||||||
await ocean.register(testAsset)
|
ddo = await ocean.register(testAsset)
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#purchase()", () => {
|
describe("#purchase()", () => {
|
||||||
|
|
||||||
it("should purchase an asset", async () => {
|
it("should purchase an asset", async () => {
|
||||||
|
|
||||||
// todo
|
|
||||||
const consumerAccount = accounts[5]
|
const consumerAccount = accounts[5]
|
||||||
const order: Order = await testAsset.purchase(consumerAccount, timeout)
|
const serviceAgreement: ServiceAgreement = await testAsset.purchase(consumerAccount)
|
||||||
assert(order)
|
assert(serviceAgreement)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should purchase an asset from two different customers", async () => {
|
||||||
|
|
||||||
|
const consumerAccount1 = accounts[5]
|
||||||
|
const serviceAgreement1: ServiceAgreement = await testAsset.purchase(consumerAccount1)
|
||||||
|
assert(serviceAgreement1)
|
||||||
|
|
||||||
|
const consumerAccount2 = accounts[6]
|
||||||
|
const serviceAgreement2: ServiceAgreement = await testAsset.purchase(consumerAccount2)
|
||||||
|
assert(serviceAgreement2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import {assert} from "chai"
|
import {assert} from "chai"
|
||||||
import AquariusProvider from "../../src/aquarius/AquariusProvider"
|
import AquariusProvider from "../../src/aquarius/AquariusProvider"
|
||||||
|
import SearchQuery from "../../src/aquarius/query/SearchQuery"
|
||||||
import ConfigProvider from "../../src/ConfigProvider"
|
import ConfigProvider from "../../src/ConfigProvider"
|
||||||
|
import DDO from "../../src/ddo/DDO"
|
||||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||||
import Account from "../../src/ocean/Account"
|
import Account from "../../src/ocean/Account"
|
||||||
import Asset from "../../src/ocean/Asset"
|
import Asset from "../../src/ocean/Asset"
|
||||||
import Ocean from "../../src/ocean/Ocean"
|
import Ocean from "../../src/ocean/Ocean"
|
||||||
import Order from "../../src/ocean/Order"
|
|
||||||
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
import SecretStoreProvider from "../../src/secretstore/SecretStoreProvider"
|
||||||
import config from "../config"
|
import config from "../config"
|
||||||
import AquariusMock from "../mocks/Aquarius.mock"
|
import AquariusMock from "../mocks/Aquarius.mock"
|
||||||
@ -13,13 +14,11 @@ import SecretStoreMock from "../mocks/SecretStore.mock"
|
|||||||
|
|
||||||
let ocean: Ocean
|
let ocean: Ocean
|
||||||
let accounts: Account[]
|
let accounts: Account[]
|
||||||
let testAsset: Asset
|
|
||||||
let testPublisher: Account
|
let testPublisher: Account
|
||||||
|
|
||||||
const name = "Test Asset 3"
|
const name = "Test Asset 3" + Math.random().toString()
|
||||||
const description = "This asset is pure owange"
|
const description = "This asset is pure owange"
|
||||||
const price = 100
|
const price = 100
|
||||||
const timeout = 100000000
|
|
||||||
|
|
||||||
describe("Ocean", () => {
|
describe("Ocean", () => {
|
||||||
|
|
||||||
@ -32,18 +31,16 @@ describe("Ocean", () => {
|
|||||||
accounts = await ocean.getAccounts()
|
accounts = await ocean.getAccounts()
|
||||||
|
|
||||||
testPublisher = accounts[0]
|
testPublisher = accounts[0]
|
||||||
testAsset = new Asset(name, description, price, testPublisher)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#getInstance()", () => {
|
describe("#getInstance()", () => {
|
||||||
|
|
||||||
it("should list accounts", async () => {
|
it("should get an instance of cean", async () => {
|
||||||
|
|
||||||
const ocn = Ocean.getInstance(config)
|
const oceanInstance: Ocean = await Ocean.getInstance(config)
|
||||||
|
|
||||||
assert(ocn)
|
assert(oceanInstance)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#getAccounts()", () => {
|
describe("#getAccounts()", () => {
|
||||||
@ -63,31 +60,13 @@ describe("Ocean", () => {
|
|||||||
|
|
||||||
it("should register an asset", async () => {
|
it("should register an asset", async () => {
|
||||||
|
|
||||||
const assetId: string = await ocean.register(testAsset)
|
const asset: Asset = new Asset(name, description, price, testPublisher)
|
||||||
|
const ddo: DDO = await ocean.register(asset)
|
||||||
|
|
||||||
assert(assetId.length === 64)
|
assert(ddo.id.startsWith("did:op:"))
|
||||||
assert(!assetId.startsWith("0x"))
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#getOrdersByConsumer()", () => {
|
|
||||||
|
|
||||||
it("should list orders", async () => {
|
|
||||||
|
|
||||||
const testConsumer = accounts[1]
|
|
||||||
const asset: Asset = new Asset("getOrdersByConsumer test", description, price, testPublisher)
|
|
||||||
|
|
||||||
await ocean.register(asset)
|
|
||||||
|
|
||||||
const order: Order = await asset.purchase(testConsumer, timeout)
|
|
||||||
const orders = await ocean.getOrdersByAccount(testConsumer)
|
|
||||||
|
|
||||||
assert(orders.length === 1)
|
|
||||||
assert(orders[0].getId() === order.getId())
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#searchAssets()", () => {
|
describe("#searchAssets()", () => {
|
||||||
|
|
||||||
it("should search for assets", async () => {
|
it("should search for assets", async () => {
|
||||||
@ -102,7 +81,7 @@ describe("Ocean", () => {
|
|||||||
value: 1,
|
value: 1,
|
||||||
},
|
},
|
||||||
text: "Office",
|
text: "Office",
|
||||||
}
|
} as SearchQuery
|
||||||
|
|
||||||
const assets: any[] = await ocean.searchAssets(query)
|
const assets: any[] = await ocean.searchAssets(query)
|
||||||
|
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
import {assert} from "chai"
|
|
||||||
import AquariusProvider from "../../src/aquarius/AquariusProvider"
|
|
||||||
import ConfigProvider from "../../src/ConfigProvider"
|
|
||||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
|
||||||
import AccessStatus from "../../src/models/AccessStatus"
|
|
||||||
import Account from "../../src/ocean/Account"
|
|
||||||
import Asset from "../../src/ocean/Asset"
|
|
||||||
import Ocean from "../../src/ocean/Ocean"
|
|
||||||
import Order from "../../src/ocean/Order"
|
|
||||||
import config from "../config"
|
|
||||||
import AquariusMock from "../mocks/Aquarius.mock"
|
|
||||||
import * as AccessToken from "../testdata/AccessToken.json"
|
|
||||||
|
|
||||||
const testName = "Order Test Asset"
|
|
||||||
const testDescription = "This asset is pure owange"
|
|
||||||
const testPrice = 100
|
|
||||||
const timeout = 1000000
|
|
||||||
|
|
||||||
let ocean: Ocean
|
|
||||||
let testAsset: Asset
|
|
||||||
let accounts: Account[]
|
|
||||||
let testPublisher: Account
|
|
||||||
let testConsumer: Account
|
|
||||||
|
|
||||||
describe("Order", () => {
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
ConfigProvider.setConfig(config)
|
|
||||||
AquariusProvider.setAquarius(new AquariusMock(config))
|
|
||||||
await ContractHandler.deployContracts()
|
|
||||||
ocean = await Ocean.getInstance(config)
|
|
||||||
accounts = await ocean.getAccounts()
|
|
||||||
testPublisher = accounts[0]
|
|
||||||
testConsumer = accounts[1]
|
|
||||||
// register an asset to play around with
|
|
||||||
testAsset = new Asset(testName, testDescription, testPrice, testPublisher)
|
|
||||||
await ocean.register(testAsset)
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#pay()", async () => {
|
|
||||||
|
|
||||||
it("should pay for an order", async () => {
|
|
||||||
|
|
||||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
|
||||||
assert(order)
|
|
||||||
|
|
||||||
await order.commit(AccessToken.toString())
|
|
||||||
await testConsumer.requestTokens(testAsset.price)
|
|
||||||
const paymentId: string = await order.pay(testConsumer)
|
|
||||||
assert(paymentId)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#commit()", async () => {
|
|
||||||
|
|
||||||
it("should commit the order", async () => {
|
|
||||||
|
|
||||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
|
||||||
assert(order)
|
|
||||||
|
|
||||||
await order.commit(AccessToken.toString())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#getStatus()", async () => {
|
|
||||||
|
|
||||||
it("should get status Requested on new order", async () => {
|
|
||||||
|
|
||||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
|
||||||
assert(order)
|
|
||||||
|
|
||||||
const status: AccessStatus = await order.getStatus()
|
|
||||||
assert(status === AccessStatus.Requested)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should get status Delivered on commited order", async () => {
|
|
||||||
|
|
||||||
const order: Order = await testAsset.purchase(testConsumer, timeout)
|
|
||||||
assert(order)
|
|
||||||
|
|
||||||
await order.commit(AccessToken.toString())
|
|
||||||
|
|
||||||
const status: AccessStatus = await order.getStatus()
|
|
||||||
assert(status === AccessStatus.Delivered)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("#consume()", () => {
|
|
||||||
|
|
||||||
it("should consume an asset", async () => {
|
|
||||||
const consumerAccount = accounts[5]
|
|
||||||
await consumerAccount.requestTokens(testAsset.price)
|
|
||||||
// place order - consumer
|
|
||||||
const order: Order = await testAsset.purchase(consumerAccount, timeout)
|
|
||||||
// commit order - provider
|
|
||||||
await order.commit(AccessToken.toString())
|
|
||||||
// pay order - consumer
|
|
||||||
await order.pay(consumerAccount)
|
|
||||||
const url = await order.consume(consumerAccount)
|
|
||||||
assert(url)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,5 +1,7 @@
|
|||||||
import {assert} from "chai"
|
import {assert} from "chai"
|
||||||
|
import AquariusConnectorProvider from "../../src/aquarius/AquariusConnectorProvider"
|
||||||
import ConfigProvider from "../../src/ConfigProvider"
|
import ConfigProvider from "../../src/ConfigProvider"
|
||||||
|
import DDO from "../../src/ddo/DDO"
|
||||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||||
import Account from "../../src/ocean/Account"
|
import Account from "../../src/ocean/Account"
|
||||||
import IdGenerator from "../../src/ocean/IdGenerator"
|
import IdGenerator from "../../src/ocean/IdGenerator"
|
||||||
@ -7,6 +9,9 @@ import Ocean from "../../src/ocean/Ocean"
|
|||||||
import ServiceAgreement from "../../src/ocean/ServiceAgreement"
|
import ServiceAgreement from "../../src/ocean/ServiceAgreement"
|
||||||
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreementTemplate"
|
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreementTemplate"
|
||||||
import config from "../config"
|
import config from "../config"
|
||||||
|
import AquariusConnectorMock from "../mocks/AquariusConnector.mock"
|
||||||
|
import Service from "../../src/ddo/Service"
|
||||||
|
import Condition from "../../src/ddo/Condition"
|
||||||
|
|
||||||
let ocean: Ocean
|
let ocean: Ocean
|
||||||
let accounts: Account[]
|
let accounts: Account[]
|
||||||
@ -15,6 +20,7 @@ let templateOwnerAccount: Account
|
|||||||
let consumerAccount: Account
|
let consumerAccount: Account
|
||||||
|
|
||||||
let testServiceAgreementTemplate: ServiceAgreementTemplate
|
let testServiceAgreementTemplate: ServiceAgreementTemplate
|
||||||
|
let serviceDefintion
|
||||||
|
|
||||||
describe("ServiceAgreement", () => {
|
describe("ServiceAgreement", () => {
|
||||||
|
|
||||||
@ -35,42 +41,79 @@ describe("ServiceAgreement", () => {
|
|||||||
"PaymentConditions.releasePayment",
|
"PaymentConditions.releasePayment",
|
||||||
"PaymentConditions.refundPayment",
|
"PaymentConditions.refundPayment",
|
||||||
]
|
]
|
||||||
|
|
||||||
// tslint:disable
|
// tslint:disable
|
||||||
const dependencyMatrix = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
const dependencyMatrix = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
||||||
|
|
||||||
testServiceAgreementTemplate =
|
testServiceAgreementTemplate =
|
||||||
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, methods,
|
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, methods,
|
||||||
dependencyMatrix, templateOwnerAccount)
|
dependencyMatrix, templateOwnerAccount)
|
||||||
|
|
||||||
|
// get condition keys from template
|
||||||
|
const conditionKeys: string[] = testServiceAgreementTemplate.getConditionKeys()
|
||||||
|
|
||||||
|
// create ddo conditions out of the keys
|
||||||
|
const conditions: Condition[] = conditionKeys.map((conditionKey, i): Condition => {
|
||||||
|
return {
|
||||||
|
name: methods[i].split(".")[1],
|
||||||
|
timeout: 100,
|
||||||
|
conditionKey: conditionKey,
|
||||||
|
parameters: {
|
||||||
|
// todo wtf?
|
||||||
|
assetId: "bytes32",
|
||||||
|
price: "integer"
|
||||||
|
},
|
||||||
|
} as Condition
|
||||||
|
})
|
||||||
|
|
||||||
|
serviceDefintion = [
|
||||||
|
{
|
||||||
|
serviceDefinitionId: IdGenerator.generateId(),
|
||||||
|
templateId: testServiceAgreementTemplate.getId(),
|
||||||
|
conditions,
|
||||||
|
} as Service
|
||||||
|
]
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#createServiceAgreement()", () => {
|
describe("#createServiceAgreement()", () => {
|
||||||
it("should execute an service agreement", async () => {
|
it("should execute an service agreement", async () => {
|
||||||
|
|
||||||
const did: string = IdGenerator.generateId()
|
const id: string = IdGenerator.generateId()
|
||||||
|
const did: string = `did:op:${id}`
|
||||||
|
const ddo = new DDO({id: did, service: serviceDefintion})
|
||||||
const assetId: string = IdGenerator.generateId()
|
const assetId: string = IdGenerator.generateId()
|
||||||
|
const serviceAgreementId: string = IdGenerator.generateId()
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||||
const serviceAgreement: ServiceAgreement =
|
const serviceAgreement: ServiceAgreement =
|
||||||
await ServiceAgreement.createServiceAgreement(testServiceAgreementTemplate, assetId, did,
|
await ServiceAgreement.createServiceAgreement(assetId, ddo, serviceAgreementId, consumerAccount,
|
||||||
consumerAccount, publisherAccount)
|
publisherAccount)
|
||||||
|
|
||||||
assert(serviceAgreement)
|
assert(serviceAgreement)
|
||||||
const id = serviceAgreement.getId()
|
|
||||||
assert(id)
|
const serviceDefinitionId = serviceAgreement.getId()
|
||||||
assert(id !== did)
|
assert(serviceDefinitionId)
|
||||||
|
assert(serviceDefinitionId !== did)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#getStatus()", () => {
|
describe("#getStatus()", () => {
|
||||||
it("should get the status of a newly created service agreement", async () => {
|
it("should get the status of a newly created service agreement", async () => {
|
||||||
|
|
||||||
const did: string = IdGenerator.generateId()
|
const id: string = IdGenerator.generateId()
|
||||||
|
const did: string = `did:op:${id}`
|
||||||
|
const ddo = new DDO({id: did, service: serviceDefintion})
|
||||||
const assetId: string = IdGenerator.generateId()
|
const assetId: string = IdGenerator.generateId()
|
||||||
|
const serviceAgreementId: string = IdGenerator.generateId()
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||||
const serviceAgreement: ServiceAgreement =
|
const serviceAgreement: ServiceAgreement =
|
||||||
await ServiceAgreement.createServiceAgreement(testServiceAgreementTemplate, assetId, did,
|
await ServiceAgreement.createServiceAgreement(assetId, ddo, serviceAgreementId, consumerAccount,
|
||||||
consumerAccount, publisherAccount)
|
publisherAccount)
|
||||||
|
|
||||||
assert(serviceAgreement)
|
assert(serviceAgreement)
|
||||||
|
|
||||||
const status = await serviceAgreement.getStatus()
|
const status = await serviceAgreement.getStatus()
|
||||||
assert(status === false)
|
assert(status === false)
|
||||||
})
|
})
|
||||||
@ -79,15 +122,20 @@ describe("ServiceAgreement", () => {
|
|||||||
describe("#grantAccess()", () => {
|
describe("#grantAccess()", () => {
|
||||||
it("should grant access in that service agreement", async () => {
|
it("should grant access in that service agreement", async () => {
|
||||||
|
|
||||||
const did: string = IdGenerator.generateId()
|
const id: string = IdGenerator.generateId()
|
||||||
|
const did: string = `did:op:${id}`
|
||||||
|
const ddo = new DDO({id: did, service: serviceDefintion})
|
||||||
const assetId: string = IdGenerator.generateId()
|
const assetId: string = IdGenerator.generateId()
|
||||||
|
const serviceAgreementId: string = IdGenerator.generateId()
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
AquariusConnectorProvider.setConnector(new AquariusConnectorMock(ddo))
|
||||||
const serviceAgreement: ServiceAgreement =
|
const serviceAgreement: ServiceAgreement =
|
||||||
await ServiceAgreement.createServiceAgreement(testServiceAgreementTemplate, assetId, did,
|
await ServiceAgreement.createServiceAgreement(assetId, ddo, serviceAgreementId, consumerAccount,
|
||||||
consumerAccount, publisherAccount)
|
publisherAccount)
|
||||||
assert(serviceAgreement)
|
assert(serviceAgreement)
|
||||||
|
|
||||||
const fulfilled: boolean = await serviceAgreement.grantAccess(did, IdGenerator.generateId())
|
const fulfilled: boolean = await serviceAgreement.grantAccess(assetId, IdGenerator.generateId())
|
||||||
assert(fulfilled)
|
assert(fulfilled)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
175
test/testdata/ddo.json
vendored
175
test/testdata/ddo.json
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"@context": "https://w3id.org/future-method/v1",
|
"@context": "https://w3id.org/future-method/v1",
|
||||||
"id": "did:op:123456789abcdefghi",
|
"id": "did:op:08a429b8529856d59867503f8056903a680935a76950bb9649785cc97869a43d",
|
||||||
"publicKey": [
|
"publicKey": [
|
||||||
{
|
{
|
||||||
"id": "did:op:123456789abcdefghi#keys-1",
|
"id": "did:op:123456789abcdefghi#keys-1",
|
||||||
@ -31,51 +31,135 @@
|
|||||||
"publicKey": "did:op:123456789abcdefghi#keys-2"
|
"publicKey": "did:op:123456789abcdefghi#keys-2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"proof": {
|
||||||
|
"type": "UUIDSignature",
|
||||||
|
"created": "2016-02-08T16:02:20Z",
|
||||||
|
"creator": "did:example:8uQhQMGzWxR8vw5P3UWH1ja",
|
||||||
|
"signatureValue": "QNB13Y7Q9...1tzjn4w=="
|
||||||
|
},
|
||||||
"service": [
|
"service": [
|
||||||
{
|
{
|
||||||
"type": "OpenIdConnectVersion1.0Service",
|
"type": "Access",
|
||||||
"serviceEndpoint": "https://openid.example.com/"
|
"serviceDefinitionId": "0",
|
||||||
|
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}",
|
||||||
|
"purchaseEndpoint": "http://mybrizo.org/api/v1/brizo/services/access/purchase?",
|
||||||
|
"templateId": "044852b2a670ade5407e78fb2863c51000000000000000000000000000000000",
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"name": "lockPayment",
|
||||||
|
"timeout": 0,
|
||||||
|
"conditionKey": {
|
||||||
|
"contractAddress": "0x...",
|
||||||
|
"fingerprint": "0x..."
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"assetId": "bytes32",
|
||||||
|
"price": "integer"
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"PaymentLocked": {
|
||||||
|
"actorType": [
|
||||||
|
"publisher"
|
||||||
|
],
|
||||||
|
"handlers": [
|
||||||
|
{
|
||||||
|
"moduleName": "accessControl",
|
||||||
|
"functionName": "grantAccess",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "releasePayment",
|
||||||
|
"timeout": 0,
|
||||||
|
"conditionKey": {
|
||||||
|
"contractAddress": "0x...",
|
||||||
|
"fingerprint": "0xXXXXXXXX"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"assetId": "bytes32",
|
||||||
|
"price": "integer"
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"PaymentReleased": {
|
||||||
|
"actorType": [
|
||||||
|
"publisher"
|
||||||
|
],
|
||||||
|
"handlers": [
|
||||||
|
{
|
||||||
|
"moduleName": "serviceAgreement",
|
||||||
|
"functionName": "fulfillAgreement",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "grantAccess",
|
||||||
|
"timeout": 0,
|
||||||
|
"conditionKey": {
|
||||||
|
"contractAddress": "0x",
|
||||||
|
"fingerprint": "0xXXXXXXXX"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"assetId": "bytes32",
|
||||||
|
"documentKeyId": "bytes32"
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"AccessGranted": {
|
||||||
|
"actorType": [
|
||||||
|
"consumer"
|
||||||
|
],
|
||||||
|
"handlers": [
|
||||||
|
{
|
||||||
|
"moduleName": "asset",
|
||||||
|
"functionName": "consumeService",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "refundPayment",
|
||||||
|
"timeout": 1,
|
||||||
|
"condition_key": {
|
||||||
|
"contractAddress": "0x...",
|
||||||
|
"fingerprint": "0xXXXXXXXX"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"assetId": "bytes32",
|
||||||
|
"price": "int"
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"PaymentRefund": {
|
||||||
|
"actorType": [
|
||||||
|
"consumer"
|
||||||
|
],
|
||||||
|
"handlers": [
|
||||||
|
{
|
||||||
|
"moduleName": "serviceAgreement",
|
||||||
|
"functionName": "fulfillAgreement",
|
||||||
|
"version": "0.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "CredentialRepositoryService",
|
"type": "CloudCompute",
|
||||||
"serviceEndpoint": "https://repository.example.com/service/8377464"
|
"serviceDefinitionId": "1",
|
||||||
},
|
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/compute?pubKey=${pubKey}&serviceId={serviceId}&algo={algo}&container={container}",
|
||||||
{
|
"templateId": "044852b2a670ade5407e78fb2863c51000000000000000000000000000000002"
|
||||||
"type": "XdiService",
|
|
||||||
"serviceEndpoint": "https://xdi.example.com/8377464"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "HubService",
|
|
||||||
"serviceEndpoint": "https://hub.example.com/.identity/did:op:0123456789abcdef/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "MessagingService",
|
|
||||||
"serviceEndpoint": "https://example.com/messages/8377464"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "SocialWebInboxService",
|
|
||||||
"serviceEndpoint": "https://social.example.com/83hfh37dj",
|
|
||||||
"description": "My public social inbox",
|
|
||||||
"spamCost": {
|
|
||||||
"amount": "0.50",
|
|
||||||
"currency": "USD"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "did:op:123456789abcdefghi;bops",
|
|
||||||
"type": "BopsService",
|
|
||||||
"serviceEndpoint": "https://bops.example.com/enterprise/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Consume",
|
|
||||||
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/consume?pubKey=${pubKey}&serviceId={serviceId}&url={url}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Compute",
|
|
||||||
"serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/compute?pubKey=${pubKey}&serviceId={serviceId}&algo={algo}&container={container}"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Metadata",
|
"type": "Metadata",
|
||||||
|
"serviceDefinitionId": "2",
|
||||||
"serviceEndpoint": "http://myaquarius.org/api/v1/provider/assets/metadata/{did}",
|
"serviceEndpoint": "http://myaquarius.org/api/v1/provider/assets/metadata/{did}",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"base": {
|
"base": {
|
||||||
@ -96,13 +180,14 @@
|
|||||||
],
|
],
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"sample1": "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/"
|
"name": "Sample of Asset Data",
|
||||||
|
"type": "sample",
|
||||||
|
"url": "https://foo.com/sample.csv"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sample2": "http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/"
|
"name": "Data Format Definition",
|
||||||
},
|
"type": "format",
|
||||||
{
|
"AssetID": "4d517500da0acb0d65a716f61330969334630363ce4a6a9d39691026ac7908ea"
|
||||||
"fieldsDescription": "http://data.ceda.ac.uk/badc/ukcp09/"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"inLanguage": "en",
|
"inLanguage": "en",
|
||||||
@ -130,4 +215,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user