From 09191fab5922b738da4150d34c94b7661180f0ec Mon Sep 17 00:00:00 2001 From: Sebastian Gerske Date: Mon, 17 Dec 2018 14:17:35 +0100 Subject: [PATCH 1/3] rollback did containing 0x --- src/keeper/contracts/DIDRegistry.ts | 6 +++--- src/keeper/contracts/ServiceAgreement.ts | 2 +- src/keeper/contracts/conditions/AccessConditions.ts | 2 +- src/keeper/contracts/conditions/PaymentConditions.ts | 2 +- src/ocean/IdGenerator.ts | 2 +- src/ocean/Ocean.ts | 2 +- test/keeper/DIDRegistry.test.ts | 10 +++++----- test/ocean/ServiceAgreement.test.ts | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/keeper/contracts/DIDRegistry.ts b/src/keeper/contracts/DIDRegistry.ts index 2608d5f..d60d16d 100644 --- a/src/keeper/contracts/DIDRegistry.ts +++ b/src/keeper/contracts/DIDRegistry.ts @@ -15,21 +15,21 @@ export default class DIDRegistry extends ContractBase { value: string, ownerAddress: string): Promise { return this.send("registerAttribute", - ownerAddress, [did, type, Web3Provider.getWeb3().utils.fromAscii(key), value], + ownerAddress, ["0x" + did, type, Web3Provider.getWeb3().utils.fromAscii(key), value], ) } public async getOwner(did: string): Promise { return this.call("getOwner", - [did], + ["0x" + did], ) } public async getUpdateAt(did: string): Promise { const blockNum = await this.call("getUpdateAt", - [did], + ["0x" + did], ) return parseInt(blockNum, 10) diff --git a/src/keeper/contracts/ServiceAgreement.ts b/src/keeper/contracts/ServiceAgreement.ts index 0b5d624..c2637b4 100644 --- a/src/keeper/contracts/ServiceAgreement.ts +++ b/src/keeper/contracts/ServiceAgreement.ts @@ -49,7 +49,7 @@ export default class ServiceAgreement extends ContractBase { return this.send("executeAgreement", publisherAddress, [ serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes, - timeoutValues, serviceAgreementId, did.replace("did:op:", ""), + timeoutValues, serviceAgreementId, "0x" + did.replace("did:op:", ""), ]) } } diff --git a/src/keeper/contracts/conditions/AccessConditions.ts b/src/keeper/contracts/conditions/AccessConditions.ts index b02f998..9eacfea 100644 --- a/src/keeper/contracts/conditions/AccessConditions.ts +++ b/src/keeper/contracts/conditions/AccessConditions.ts @@ -14,7 +14,7 @@ export default class AccessConditions extends ContractBase { public async grantAccess(serviceAgreementId: any, assetId: any, documentKeyId: any, publisherAddress: string) : Promise { return this.send("grantAccess", publisherAddress, [ - serviceAgreementId, assetId, documentKeyId, + serviceAgreementId, "0x" + assetId, "0x" + documentKeyId, ]) } } diff --git a/src/keeper/contracts/conditions/PaymentConditions.ts b/src/keeper/contracts/conditions/PaymentConditions.ts index 7cc045a..40656cc 100644 --- a/src/keeper/contracts/conditions/PaymentConditions.ts +++ b/src/keeper/contracts/conditions/PaymentConditions.ts @@ -12,7 +12,7 @@ export default class PaymentConditions extends ContractBase { public async lockPayment(serviceAgreementId: string, assetId: string, price: number, consumerAddress: string) : Promise { return this.send("lockPayment", consumerAddress, [ - serviceAgreementId, assetId, price, + serviceAgreementId, "0x" + assetId, price, ]) } } diff --git a/src/ocean/IdGenerator.ts b/src/ocean/IdGenerator.ts index a740f6d..9fc37f9 100644 --- a/src/ocean/IdGenerator.ts +++ b/src/ocean/IdGenerator.ts @@ -1,4 +1,4 @@ -import { v4 } from "uuid" +import {v4} from "uuid" export default class IdGenerator { public static generateId(): string { diff --git a/src/ocean/Ocean.ts b/src/ocean/Ocean.ts index d51808a..8c29fae 100644 --- a/src/ocean/Ocean.ts +++ b/src/ocean/Ocean.ts @@ -66,7 +66,7 @@ export default class Ocean { const aquarius = AquariusProvider.getAquarius() const brizo = BrizoProvider.getBrizo() - const assetId: string = IdGenerator.generatePrefixedId() + const assetId: string = IdGenerator.generateId() const did: string = `did:op:${assetId}` const accessServiceDefinitionId: string = "0" const computeServiceDefintionId: string = "1" diff --git a/test/keeper/DIDRegistry.test.ts b/test/keeper/DIDRegistry.test.ts index 6768cd7..3b9b17b 100644 --- a/test/keeper/DIDRegistry.test.ts +++ b/test/keeper/DIDRegistry.test.ts @@ -26,7 +26,7 @@ describe("DIDRegistry", () => { it("should register an attribute in a new did", async () => { const ownerAccount: Account = (await ocean.getAccounts())[0] - const did = IdGenerator.generatePrefixedId() + const did = IdGenerator.generateId() const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider") const data = "my nice provider, is nice" const receipt = await didRegistry.registerAttribute(did, ValueType.DID, providerKey, @@ -37,7 +37,7 @@ describe("DIDRegistry", () => { it("should register another attribute in the same did", async () => { const ownerAccount: Account = (await ocean.getAccounts())[0] - const did = IdGenerator.generatePrefixedId() + const did = IdGenerator.generateId() { // register the first attribute const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider") @@ -62,7 +62,7 @@ describe("DIDRegistry", () => { it("should get the owner of a did properly", async () => { const ownerAccount: Account = (await ocean.getAccounts())[0] - const did = IdGenerator.generatePrefixedId() + const did = IdGenerator.generateId() const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider") const data = "my nice provider, is nice" await didRegistry.registerAttribute(did, ValueType.DID, providerKey, @@ -74,7 +74,7 @@ describe("DIDRegistry", () => { }) it("should get 0x00.. for a not registered did", async () => { - const owner = await didRegistry.getOwner("0x1234") + const owner = await didRegistry.getOwner("1234") assert(owner === "0x0000000000000000000000000000000000000000") }) @@ -84,7 +84,7 @@ describe("DIDRegistry", () => { it("should the block number of the last update of the did attribute", async () => { const ownerAccount: Account = (await ocean.getAccounts())[0] - const did = IdGenerator.generatePrefixedId() + const did = IdGenerator.generateId() const providerKey = Web3Provider.getWeb3().utils.fromAscii("provider") const data = "my nice provider, is nice" await didRegistry.registerAttribute(did, ValueType.DID, providerKey, diff --git a/test/ocean/ServiceAgreement.test.ts b/test/ocean/ServiceAgreement.test.ts index d8a64c4..c68ba7e 100644 --- a/test/ocean/ServiceAgreement.test.ts +++ b/test/ocean/ServiceAgreement.test.ts @@ -23,7 +23,7 @@ let consumerAccount: Account let accessService: Service let metaDataService: Service -const assetId: string = IdGenerator.generatePrefixedId() +const assetId: string = IdGenerator.generateId() describe("ServiceAgreement", () => { From a0648b4b84bf3a0d8c84911c8712822691f24be4 Mon Sep 17 00:00:00 2001 From: Sebastian Gerske Date: Mon, 17 Dec 2018 14:29:09 +0100 Subject: [PATCH 2/3] remove 0x prefix from serviceAgreementId --- src/keeper/contracts/ServiceAgreement.ts | 2 +- src/ocean/IdGenerator.ts | 4 --- src/ocean/Ocean.ts | 2 +- .../ServiceAgreements/ServiceAgreement.ts | 2 +- src/squid.ts | 2 +- test/TestIdGenerator.ts | 7 +++++ test/aquarius/Aquarius.test.ts | 4 +-- test/ocean/IdGenerator.test.ts | 27 ------------------- test/ocean/ServiceAgreement.test.ts | 12 ++++----- test/ocean/ServiceAgreementTemplate.test.ts | 11 ++++---- 10 files changed, 25 insertions(+), 48 deletions(-) create mode 100644 test/TestIdGenerator.ts diff --git a/src/keeper/contracts/ServiceAgreement.ts b/src/keeper/contracts/ServiceAgreement.ts index c2637b4..9b55c69 100644 --- a/src/keeper/contracts/ServiceAgreement.ts +++ b/src/keeper/contracts/ServiceAgreement.ts @@ -49,7 +49,7 @@ export default class ServiceAgreement extends ContractBase { return this.send("executeAgreement", publisherAddress, [ serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes, - timeoutValues, serviceAgreementId, "0x" + did.replace("did:op:", ""), + timeoutValues, "0x" + serviceAgreementId, "0x" + did.replace("did:op:", ""), ]) } } diff --git a/src/ocean/IdGenerator.ts b/src/ocean/IdGenerator.ts index 9fc37f9..d8d8b8a 100644 --- a/src/ocean/IdGenerator.ts +++ b/src/ocean/IdGenerator.ts @@ -5,8 +5,4 @@ export default class IdGenerator { const id = `${v4()}${v4()}` return id.replace(/-/g, "") } - - public static generatePrefixedId() { - return "0x" + this.generateId() - } } diff --git a/src/ocean/Ocean.ts b/src/ocean/Ocean.ts index 8c29fae..1364fd0 100644 --- a/src/ocean/Ocean.ts +++ b/src/ocean/Ocean.ts @@ -158,7 +158,7 @@ export default class Ocean { const ddo = await AquariusProvider.getAquarius().retrieveDDO(did) const id = did.replace("did:op:", "") - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() try { const serviceAgreementSignature: string = await ServiceAgreement.signServiceAgreement(id, diff --git a/src/ocean/ServiceAgreements/ServiceAgreement.ts b/src/ocean/ServiceAgreements/ServiceAgreement.ts index c5e6f37..2427271 100644 --- a/src/ocean/ServiceAgreements/ServiceAgreement.ts +++ b/src/ocean/ServiceAgreements/ServiceAgreement.ts @@ -172,7 +172,7 @@ export default class ServiceAgreement extends OceanBase { {type: "bytes32[]", value: conditionKeys} as ValuePair, {type: "bytes32[]", value: valueHashes} as ValuePair, {type: "uint256[]", value: timeouts} as ValuePair, - {type: "bytes32", value: serviceAgreementId} as ValuePair, + {type: "bytes32", value: "0x" + serviceAgreementId} as ValuePair, ] return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex") diff --git a/src/squid.ts b/src/squid.ts index 0ba2029..6968386 100644 --- a/src/squid.ts +++ b/src/squid.ts @@ -1,3 +1,4 @@ +import EventListener from "./keeper/EventListener" import Account from "./ocean/Account" import Ocean from "./ocean/Ocean" import ServiceAgreement from "./ocean/ServiceAgreements/ServiceAgreement" @@ -5,7 +6,6 @@ import ServiceAgreementTemplate from "./ocean/ServiceAgreements/ServiceAgreement import Access from "./ocean/ServiceAgreements/Templates/Access" import FitchainCompute from "./ocean/ServiceAgreements/Templates/FitchainCompute" import Logger from "./utils/Logger" -import EventListener from "./keeper/EventListener" const Templates = {Access, FitchainCompute} diff --git a/test/TestIdGenerator.ts b/test/TestIdGenerator.ts new file mode 100644 index 0000000..7742b22 --- /dev/null +++ b/test/TestIdGenerator.ts @@ -0,0 +1,7 @@ +import IdGenerator from "../src/ocean/IdGenerator" + +export default class TestIdGenerator extends IdGenerator { + public static generatePrefixedId() { + return "0x" + this.generateId() + } +} diff --git a/test/aquarius/Aquarius.test.ts b/test/aquarius/Aquarius.test.ts index cb8d8b8..8b8a031 100644 --- a/test/aquarius/Aquarius.test.ts +++ b/test/aquarius/Aquarius.test.ts @@ -85,7 +85,7 @@ describe("Aquarius", () => { it("should store a ddo", async () => { - const did: string = `did:op:${IdGenerator.generatePrefixedId()}` + const did: string = `did:op:${IdGenerator.generateId()}` const ddo: DDO = new DDO({ id: did, }) @@ -103,7 +103,7 @@ describe("Aquarius", () => { it("should store a ddo", async () => { - const did: string = `did:op:${IdGenerator.generatePrefixedId()}` + const did: string = `did:op:${IdGenerator.generateId()}` const ddo: DDO = new DDO({ id: did, }) diff --git a/test/ocean/IdGenerator.test.ts b/test/ocean/IdGenerator.test.ts index db42746..2154bee 100644 --- a/test/ocean/IdGenerator.test.ts +++ b/test/ocean/IdGenerator.test.ts @@ -23,31 +23,4 @@ describe("IdGenerator", () => { assert(id.indexOf("-") === -1) }) }) - - describe("#generatePrefixedId()", () => { - - it("should generate an id", async () => { - - const id = IdGenerator.generatePrefixedId() - assert(id) - }) - - it("should generate an id that is 64 chars long", async () => { - - const id: string = IdGenerator.generatePrefixedId() - assert(id.length === 66, id) - }) - - it("should be prefixed", async () => { - - const id: string = IdGenerator.generatePrefixedId() - assert(id.startsWith("0x")) - }) - - it("should not contain -", async () => { - - const id: string = IdGenerator.generatePrefixedId() - assert(id.indexOf("-") === -1) - }) - }) }) diff --git a/test/ocean/ServiceAgreement.test.ts b/test/ocean/ServiceAgreement.test.ts index c68ba7e..d2349e1 100644 --- a/test/ocean/ServiceAgreement.test.ts +++ b/test/ocean/ServiceAgreement.test.ts @@ -60,7 +60,7 @@ describe("ServiceAgreement", () => { const did: string = `did:op:${assetId}` const ddo = new DDO({id: did, service: [accessService]}) - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) @@ -80,7 +80,7 @@ describe("ServiceAgreement", () => { const did: string = `did:op:${assetId}` const ddo = new DDO({id: did, service: [accessService]}) - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) @@ -104,7 +104,7 @@ describe("ServiceAgreement", () => { const did: string = `did:op:${assetId}` const ddo = new DDO({id: did, service: [accessService]}) - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) @@ -128,7 +128,7 @@ describe("ServiceAgreement", () => { const did: string = `did:op:${assetId}` const ddo = new DDO({id: did, service: [accessService, metaDataService]}) - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) @@ -157,7 +157,7 @@ describe("ServiceAgreement", () => { const did: string = `did:op:${assetId}` const ddo = new DDO({id: did, service: [accessService]}) - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) @@ -187,7 +187,7 @@ describe("ServiceAgreement", () => { const did: string = `did:op:${assetId}` const ddo = new DDO({id: did, service: [accessService]}) - const serviceAgreementId: string = IdGenerator.generatePrefixedId() + const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) diff --git a/test/ocean/ServiceAgreementTemplate.test.ts b/test/ocean/ServiceAgreementTemplate.test.ts index f351f50..8a7cc27 100644 --- a/test/ocean/ServiceAgreementTemplate.test.ts +++ b/test/ocean/ServiceAgreementTemplate.test.ts @@ -2,13 +2,13 @@ import {assert} from "chai" import ConfigProvider from "../../src/ConfigProvider" import MetaData from "../../src/ddo/MetaData" import Account from "../../src/ocean/Account" -import IdGenerator from "../../src/ocean/IdGenerator" import Ocean from "../../src/ocean/Ocean" import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreements/ServiceAgreementTemplate" import Access from "../../src/ocean/ServiceAgreements/Templates/Access" import TemplateBase from "../../src/ocean/ServiceAgreements/Templates/TemplateBase" import config from "../config" import TestContractHandler from "../keeper/TestContractHandler" +import TestIdGenerator from "../TestIdGenerator" let ocean: Ocean let accounts: Account[] @@ -27,7 +27,7 @@ describe("ServiceAgreementTemplate", () => { const templateOwner = accounts[0] const access: TemplateBase = new Access() - access.id = IdGenerator.generatePrefixedId() + access.id = TestIdGenerator.generatePrefixedId() const serviceAgreementTemplate: ServiceAgreementTemplate = new ServiceAgreementTemplate(access) assert(serviceAgreementTemplate) @@ -44,12 +44,13 @@ describe("ServiceAgreementTemplate", () => { it("should setup an Access agreement template correctly", async () => { const access: TemplateBase = new Access() - access.id = IdGenerator.generatePrefixedId() + access.id = TestIdGenerator.generatePrefixedId() const serviceAgreementTemplate: ServiceAgreementTemplate = new ServiceAgreementTemplate(access) assert(serviceAgreementTemplate) - const conds = await serviceAgreementTemplate.getConditions(new MetaData(), IdGenerator.generatePrefixedId()) + const conds = await serviceAgreementTemplate.getConditions(new MetaData(), + TestIdGenerator.generatePrefixedId()) assert(conds) }) }) @@ -59,7 +60,7 @@ describe("ServiceAgreementTemplate", () => { const publisherAccount = accounts[0] const access: TemplateBase = new Access() - access.id = IdGenerator.generatePrefixedId() + access.id = TestIdGenerator.generatePrefixedId() const serviceAgreementTemplate: ServiceAgreementTemplate = new ServiceAgreementTemplate(access) assert(serviceAgreementTemplate) From 6ea480fd47752e0e6cca2657e01a6fd7f87cb5cb Mon Sep 17 00:00:00 2001 From: Sebastian Gerske Date: Mon, 17 Dec 2018 15:54:58 +0100 Subject: [PATCH 3/3] enhanced did handling --- src/aquarius/Aquarius.ts | 9 +-- src/examples/BuyAsset.ts | 5 +- src/examples/GrantAccess.ts | 7 +- src/keeper/contracts/ServiceAgreement.ts | 5 +- src/ocean/DID.ts | 41 ++++++++++++ src/ocean/Ocean.ts | 46 ++++++------- .../ServiceAgreements/ServiceAgreement.ts | 13 ++-- test/aquarius/Aquarius.test.ts | 14 ++-- test/mocks/Aquarius.mock.ts | 5 +- test/ocean/DID.test.ts | 66 +++++++++++++++++++ test/ocean/ServiceAgreement.test.ts | 57 ++++++++-------- 11 files changed, 190 insertions(+), 78 deletions(-) create mode 100644 src/ocean/DID.ts create mode 100644 test/ocean/DID.test.ts diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index c6c24c0..fba0110 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -1,6 +1,7 @@ import {URL} from "whatwg-url" import DDO from "../ddo/DDO" import Config from "../models/Config" +import DID from "../ocean/DID" import Logger from "../utils/Logger" import WebServiceConnectorProvider from "../utils/WebServiceConnectorProvider" import SearchQuery from "./query/SearchQuery" @@ -114,8 +115,8 @@ export default class Aquarius { return result } - public async retrieveDDO(did: string): Promise { - const fullUrl = `${this.url}${apiPath}/${did}` + public async retrieveDDO(did: DID): Promise { + const fullUrl = `${this.url}${apiPath}/${did.getDid()}` const result = await WebServiceConnectorProvider.getConnector() .get(fullUrl) .then((response: any) => { @@ -136,7 +137,7 @@ export default class Aquarius { return result } - public getServiceEndpoint(did) { - return `${this.url}/api/v1/aquarius/assets/metadata/${did}` + public getServiceEndpoint(did: DID) { + return `${this.url}/api/v1/aquarius/assets/metadata/${did.getId()}` } } diff --git a/src/examples/BuyAsset.ts b/src/examples/BuyAsset.ts index 53b1376..983e4ff 100644 --- a/src/examples/BuyAsset.ts +++ b/src/examples/BuyAsset.ts @@ -2,6 +2,7 @@ import DDO from "../ddo/DDO" import MetaData from "../ddo/MetaData" import MetaDataBase from "../ddo/MetaDataBase" import Service from "../ddo/Service" +import DID from "../ocean/DID" import {Account, Logger, Ocean, ServiceAgreement} from "../squid" import config from "./config" @@ -43,7 +44,7 @@ import config from "./config" const ddo: DDO = await ocean.registerAsset(metaData, publisher) Logger.log("did", ddo.id) - const assetId = ddo.id.replace("did:op:", "") + const did: DID = DID.parse(ddo.id) const accessService = ddo.findServiceByType("Access") @@ -65,6 +66,6 @@ import config from "./config" publisher) Logger.log("ServiceAgreement Id:", serviceAgreement.getId()) - const paid = await serviceAgreement.payAsset(assetId, metaData.base.price, consumer) + const paid = await serviceAgreement.payAsset(did.getId(), metaData.base.price, consumer) Logger.log(`Asset paid: ${paid}`) })() diff --git a/src/examples/GrantAccess.ts b/src/examples/GrantAccess.ts index 5da474a..f9e3b97 100644 --- a/src/examples/GrantAccess.ts +++ b/src/examples/GrantAccess.ts @@ -2,6 +2,7 @@ import DDO from "../ddo/DDO" import MetaData from "../ddo/MetaData" import MetaDataBase from "../ddo/MetaDataBase" import Service from "../ddo/Service" +import DID from "../ocean/DID" import {Account, Logger, Ocean, ServiceAgreement} from "../squid" import config from "./config" @@ -43,7 +44,7 @@ import config from "./config" const ddo: DDO = await ocean.registerAsset(metaData, publisher) Logger.log("did", ddo.id) - const assetId = ddo.id.replace("did:op:", "") + const did: DID = DID.parse(ddo.id) const accessService = ddo.findServiceByType("Access") @@ -65,9 +66,9 @@ import config from "./config" await consumer.requestTokens(metaData.base.price) - const paid = await serviceAgreement.payAsset(assetId, metaData.base.price, consumer) + const paid = await serviceAgreement.payAsset(did.getId(), metaData.base.price, consumer) Logger.log(`Asset paid: ${paid}`) - const accessGranted = await serviceAgreement.grantAccess(assetId, assetId, publisher) + const accessGranted = await serviceAgreement.grantAccess(did.getId(), did.getId(), publisher) Logger.log(`Asset access granted: ${accessGranted}`) })() diff --git a/src/keeper/contracts/ServiceAgreement.ts b/src/keeper/contracts/ServiceAgreement.ts index 9b55c69..caea20b 100644 --- a/src/keeper/contracts/ServiceAgreement.ts +++ b/src/keeper/contracts/ServiceAgreement.ts @@ -1,5 +1,6 @@ import {Receipt} from "web3-utils" import MethodReflection from "../../models/MethodReflection" +import DID from "../../ocean/DID" import ContractBase from "./ContractBase" export default class ServiceAgreement extends ContractBase { @@ -44,12 +45,12 @@ export default class ServiceAgreement extends ContractBase { public async executeAgreement(serviceAgreementTemplateId: string, serviceAgreementSignatureHash: string, consumerAddress: string, valueHashes: string[], timeoutValues: number[], - serviceAgreementId: string, did: string, publisherAddress: string): + serviceAgreementId: string, did: DID, publisherAddress: string): Promise { return this.send("executeAgreement", publisherAddress, [ serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes, - timeoutValues, "0x" + serviceAgreementId, "0x" + did.replace("did:op:", ""), + timeoutValues, "0x" + serviceAgreementId, "0x" + did.getId(), ]) } } diff --git a/src/ocean/DID.ts b/src/ocean/DID.ts new file mode 100644 index 0000000..608ec37 --- /dev/null +++ b/src/ocean/DID.ts @@ -0,0 +1,41 @@ +import IdGenerator from "./IdGenerator" + +const prefix = "did:op:" + +export default class DID { + + public static parse(didString: string): DID { + let did: DID + if (didString.startsWith(prefix)) { + const id = didString.split(prefix)[1] + if (!id.startsWith("0x")) { + did = new DID(id) + } + } + + if (!did) { + throw new Error(`Parsing DID failed, ${didString}`) + } + + return did + } + + public static generate(): DID { + return new DID(IdGenerator.generateId()) + } + + private id: string + + private constructor(id: string) { + + this.id = id + } + + public getDid(): string { + return `${prefix}${this.id}` + } + + public getId(): string { + return this.id + } +} diff --git a/src/ocean/Ocean.ts b/src/ocean/Ocean.ts index 1364fd0..3131e65 100644 --- a/src/ocean/Ocean.ts +++ b/src/ocean/Ocean.ts @@ -18,14 +18,15 @@ import Config from "../models/Config" import ValueType from "../models/ValueType" import SecretStoreProvider from "../secretstore/SecretStoreProvider" import Logger from "../utils/Logger" +import WebServiceConnectorProvider from "../utils/WebServiceConnectorProvider" import Account from "./Account" +import DID from "./DID" import IdGenerator from "./IdGenerator" import ServiceAgreement from "./ServiceAgreements/ServiceAgreement" import ServiceAgreementTemplate from "./ServiceAgreements/ServiceAgreementTemplate" import Access from "./ServiceAgreements/Templates/Access" import EventListener from "../keeper/EventListener" -import WebServiceConnectorProvider from "../utils/WebServiceConnectorProvider" export default class Ocean { @@ -55,9 +56,10 @@ export default class Ocean { return ethAccounts.map((address: string) => new Account(address)) } - public async resolveDID(did): Promise { + public async resolveDID(did: string): Promise { - return AquariusProvider.getAquarius().retrieveDDO(did) + const d: DID = DID.parse(did) + return AquariusProvider.getAquarius().retrieveDDO(d) } public async registerAsset(metadata: MetaData, publisher: Account): Promise { @@ -66,19 +68,19 @@ export default class Ocean { const aquarius = AquariusProvider.getAquarius() const brizo = BrizoProvider.getBrizo() - const assetId: string = IdGenerator.generateId() - const did: string = `did:op:${assetId}` + const did: DID = DID.generate() const accessServiceDefinitionId: string = "0" const computeServiceDefintionId: string = "1" const metadataServiceDefinitionId: string = "2" metadata.base.contentUrls = - [await SecretStoreProvider.getSecretStore().encryptDocument(assetId, metadata.base.contentUrls)] + [await SecretStoreProvider.getSecretStore() + .encryptDocument(did.getId(), metadata.base.contentUrls)] const template = new Access() const serviceAgreementTemplate = new ServiceAgreementTemplate(template) - const conditions: Condition[] = await serviceAgreementTemplate.getConditions(metadata, assetId) + const conditions: Condition[] = await serviceAgreementTemplate.getConditions(metadata, did.getId()) const serviceEndpoint = aquarius.getServiceEndpoint(did) @@ -86,14 +88,14 @@ export default class Ocean { const ddo: DDO = new DDO({ authentication: [{ type: "RsaSignatureAuthentication2018", - publicKey: did + "#keys-1", + publicKey: did.getDid() + "#keys-1", } as Authentication], - id: did, + id: did.getDid(), publicKey: [ { - id: did + "#keys-1", + id: did.getDid() + "#keys-1", type: "Ed25519VerificationKey2018", - owner: did, + owner: did.getDid(), publicKeyBase58: await publisher.getPublicKey(), } as PublicKey, ], @@ -143,7 +145,7 @@ export default class Ocean { // Logger.log(JSON.stringify(storedDdo, null, 2)) await didRegistry.registerAttribute( - assetId, + did.getId(), ValueType.URL, "Metadata", serviceEndpoint, @@ -156,12 +158,12 @@ export default class Ocean { serviceDefinitionId: string, consumer: Account): Promise { - const ddo = await AquariusProvider.getAquarius().retrieveDDO(did) - const id = did.replace("did:op:", "") + const d: DID = DID.parse(did as string) + const ddo = await AquariusProvider.getAquarius().retrieveDDO(d) const serviceAgreementId: string = IdGenerator.generateId() try { - const serviceAgreementSignature: string = await ServiceAgreement.signServiceAgreement(id, + const serviceAgreementSignature: string = await ServiceAgreement.signServiceAgreement( ddo, serviceDefinitionId, serviceAgreementId, consumer) const accessService: Service = ddo.findServiceByType("Access") @@ -183,7 +185,7 @@ export default class Ocean { const sa: ServiceAgreement = new ServiceAgreement(data.returnValues.serviceAgreementId) await sa.payAsset( - id, + d.getId(), metadataService.metadata.base.price, consumer, ) @@ -207,8 +209,8 @@ export default class Ocean { cb, consumer: Account) { - const ddo = await AquariusProvider.getAquarius().retrieveDDO(did) - const id = did.replace("did:op:", "") + const d: DID = DID.parse(did) + const ddo = await AquariusProvider.getAquarius().retrieveDDO(d) const accessService: Service = ddo.findServiceByType("Access") const metadataService: Service = ddo.findServiceByType("Metadata") @@ -222,7 +224,7 @@ export default class Ocean { const webConnector = WebServiceConnectorProvider.getConnector() const contentUrls = await SecretStoreProvider .getSecretStore() - .decryptDocument(id, metadataService.metadata.base.contentUrls[0]) + .decryptDocument(d.getId(), metadataService.metadata.base.contentUrls[0]) const serviceUrl: string = accessService.serviceEndpoint Logger.log("Consuming asset files using service url: ", serviceUrl) const files = [] @@ -261,12 +263,12 @@ export default class Ocean { consumer: Account, publisher: Account): Promise { - const ddo = await AquariusProvider.getAquarius().retrieveDDO(did) - const id = did.replace("did:op:", "") + const d: DID = DID.parse(did) + const ddo = await AquariusProvider.getAquarius().retrieveDDO(d) const serviceAgreement: ServiceAgreement = await ServiceAgreement .executeServiceAgreement( - id, + d, ddo, serviceDefinitionId, serviceAgreementId, diff --git a/src/ocean/ServiceAgreements/ServiceAgreement.ts b/src/ocean/ServiceAgreements/ServiceAgreement.ts index 2427271..bf64454 100644 --- a/src/ocean/ServiceAgreements/ServiceAgreement.ts +++ b/src/ocean/ServiceAgreements/ServiceAgreement.ts @@ -7,12 +7,12 @@ import Web3Provider from "../../keeper/Web3Provider" import ValuePair from "../../models/ValuePair" import Logger from "../../utils/Logger" import Account from "../Account" +import DID from "../DID" import OceanBase from "../OceanBase" export default class ServiceAgreement extends OceanBase { - public static async signServiceAgreement(assetId: string, - ddo: DDO, + public static async signServiceAgreement(ddo: DDO, serviceDefinitionId: string, serviceAgreementId: string, consumer: Account): Promise { @@ -36,7 +36,7 @@ export default class ServiceAgreement extends OceanBase { return serviceAgreementHashSignature } - public static async executeServiceAgreement(assetId: string, + public static async executeServiceAgreement(did: DID, ddo: DDO, serviceDefinitionId: string, serviceAgreementId: string, @@ -54,7 +54,7 @@ export default class ServiceAgreement extends OceanBase { const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromService(service) // todo get consumer from ddo - const serviceAgreement: ServiceAgreement = await ServiceAgreement.executeAgreement(ddo, + const serviceAgreement: ServiceAgreement = await ServiceAgreement.executeAgreement(did, ddo, serviceDefinitionId, serviceAgreementId, valueHashes, timeoutValues, serviceAgreementHashSignature, consumer.getId(), publisher) @@ -92,7 +92,8 @@ export default class ServiceAgreement extends OceanBase { return serviceAgreementHashSignature } - private static async executeAgreement(ddo: DDO, + private static async executeAgreement(did: DID, + ddo: DDO, serviceDefinitionId: string, serviceAgreementId: string, valueHashes: string[], @@ -123,7 +124,7 @@ export default class ServiceAgreement extends OceanBase { valueHashes, timeoutValues, serviceAgreementId, - ddo.id, + did, publisher.getId()) if (executeAgreementReceipt.events.ExecuteAgreement.returnValues.state === false) { diff --git a/test/aquarius/Aquarius.test.ts b/test/aquarius/Aquarius.test.ts index 8b8a031..f3a2868 100644 --- a/test/aquarius/Aquarius.test.ts +++ b/test/aquarius/Aquarius.test.ts @@ -2,7 +2,7 @@ import * as assert from "assert" import Aquarius from "../../src/aquarius/Aquarius" import SearchQuery from "../../src/aquarius/query/SearchQuery" import DDO from "../../src/ddo/DDO" -import IdGenerator from "../../src/ocean/IdGenerator" +import DID from "../../src/ocean/DID" import WebServiceConnectorProvider from "../../src/utils/WebServiceConnectorProvider" import config from "../config" import WebServiceConnectorMock from "../mocks/WebServiceConnector.mock" @@ -85,9 +85,9 @@ describe("Aquarius", () => { it("should store a ddo", async () => { - const did: string = `did:op:${IdGenerator.generateId()}` + const did: DID = DID.generate() const ddo: DDO = new DDO({ - id: did, + id: did.getId(), }) // @ts-ignore @@ -103,9 +103,9 @@ describe("Aquarius", () => { it("should store a ddo", async () => { - const did: string = `did:op:${IdGenerator.generateId()}` + const did: DID = DID.generate() const ddo: DDO = new DDO({ - id: did, + id: did.getId(), }) // @ts-ignore @@ -114,12 +114,12 @@ describe("Aquarius", () => { const storageResult: DDO = await aquarius.storeDDO(ddo) assert(storageResult) - assert(storageResult.id === did) + assert(storageResult.id === did.getId()) const restrieveResult: DDO = await aquarius.retrieveDDO(did) assert(restrieveResult) - assert(restrieveResult.id === did) + assert(restrieveResult.id === did.getId()) assert(restrieveResult.id === storageResult.id) }) }) diff --git a/test/mocks/Aquarius.mock.ts b/test/mocks/Aquarius.mock.ts index a8e3fad..5418c9d 100644 --- a/test/mocks/Aquarius.mock.ts +++ b/test/mocks/Aquarius.mock.ts @@ -1,5 +1,6 @@ import Aquarius from "../../src/aquarius/Aquarius" import DDO from "../../src/ddo/DDO" +import DID from "../../src/ocean/DID" const ddoStore: Map = new Map() @@ -14,7 +15,7 @@ export default class AquariusMock extends Aquarius { return ddo } - public async retrieveDDO(did: string): Promise { - return ddoStore.get(did) + public async retrieveDDO(did: DID): Promise { + return ddoStore.get(did.getDid()) } } diff --git a/test/ocean/DID.test.ts b/test/ocean/DID.test.ts new file mode 100644 index 0000000..9fb7bfa --- /dev/null +++ b/test/ocean/DID.test.ts @@ -0,0 +1,66 @@ +import * as assert from "assert" +import DID from "../../src/ocean/DID" + +describe("DID", () => { + + describe("#generate()", () => { + it("should generate a new did", () => { + const did: DID = DID.generate() + assert(did) + }) + }) + + describe("#parse()", () => { + it("should parse a valid did", () => { + + const id = "1234" + const did: DID = DID.parse(`did:op:${id}`) + assert(did) + + assert(did.getId() === id, did.getId()) + }) + + it("should throw if prefix does not match", (done) => { + + const id = "1234" + try { + const did: DID = DID.parse(`did:xxx:${id}`) + assert(!did) + } catch { + done() + } + }) + + it("should throw if id does not match", (done) => { + + const id = "0x1234" + try { + const did: DID = DID.parse(`did:op:${id}`) + assert(!did) + } catch { + done() + } + }) + }) + + describe("#getDid()", () => { + it("should return the full did", () => { + + const did: DID = DID.generate() + assert(did) + + assert(did.getDid().startsWith("did:op:")) + }) + }) + + describe("#getDid()", () => { + it("should return only the id part of the did", () => { + + const id = "1234" + const did: DID = DID.parse(`did:op:${id}`) + assert(did) + + assert(did.getId() === id) + }) + }) +}) diff --git a/test/ocean/ServiceAgreement.test.ts b/test/ocean/ServiceAgreement.test.ts index d2349e1..715b874 100644 --- a/test/ocean/ServiceAgreement.test.ts +++ b/test/ocean/ServiceAgreement.test.ts @@ -5,6 +5,7 @@ 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 DID from "../../src/ocean/DID" import IdGenerator from "../../src/ocean/IdGenerator" import Ocean from "../../src/ocean/Ocean" import ServiceAgreement from "../../src/ocean/ServiceAgreements/ServiceAgreement" @@ -23,7 +24,7 @@ let consumerAccount: Account let accessService: Service let metaDataService: Service -const assetId: string = IdGenerator.generateId() +const did: DID = DID.generate() describe("ServiceAgreement", () => { @@ -40,7 +41,7 @@ describe("ServiceAgreement", () => { const serviceAgreementTemplate: ServiceAgreementTemplate = new ServiceAgreementTemplate(new Access()) - const conditions: Condition[] = await serviceAgreementTemplate.getConditions(metadata, assetId) + const conditions: Condition[] = await serviceAgreementTemplate.getConditions(metadata, did.getId()) accessService = { type: "Access", @@ -58,15 +59,14 @@ describe("ServiceAgreement", () => { describe("#signServiceAgreement()", () => { it("should sign an service agreement", async () => { - const did: string = `did:op:${assetId}` - const ddo = new DDO({id: did, service: [accessService]}) + const ddo = new DDO({id: did.getDid(), service: [accessService]}) const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) const serviceAgreementSignature: string = - await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.signServiceAgreement(ddo, accessService.serviceDefinitionId, serviceAgreementId, consumerAccount) assert(serviceAgreementSignature) @@ -78,43 +78,41 @@ describe("ServiceAgreement", () => { describe("#executeServiceAgreement()", () => { it("should execute an service agreement", async () => { - const did: string = `did:op:${assetId}` - const ddo = new DDO({id: did, service: [accessService]}) + const ddo = new DDO({id: did.getDid(), service: [accessService]}) const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) const serviceAgreementSignature: string = - await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.signServiceAgreement(ddo, accessService.serviceDefinitionId, serviceAgreementId, consumerAccount) const serviceAgreement: ServiceAgreement = - await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.executeServiceAgreement(did, ddo, accessService.serviceDefinitionId, serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) assert(serviceAgreement) const serviceDefinitionId = serviceAgreement.getId() assert(serviceDefinitionId) - assert(serviceDefinitionId !== did) + assert(serviceDefinitionId !== did.getId()) }) }) describe("#getStatus()", () => { it("should get the status of a newly created service agreement", async () => { - const did: string = `did:op:${assetId}` - const ddo = new DDO({id: did, service: [accessService]}) + const ddo = new DDO({id: did.getDid(), service: [accessService]}) const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) const serviceAgreementSignature: string = - await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.signServiceAgreement(ddo, accessService.serviceDefinitionId, serviceAgreementId, consumerAccount) assert(serviceAgreementSignature) const serviceAgreement: ServiceAgreement = - await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.executeServiceAgreement(did, ddo, accessService.serviceDefinitionId, serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) assert(serviceAgreement) @@ -126,27 +124,26 @@ describe("ServiceAgreement", () => { describe("#payAsset()", () => { it("should lock the payment in that service agreement", async () => { - const did: string = `did:op:${assetId}` - const ddo = new DDO({id: did, service: [accessService, metaDataService]}) + const ddo = new DDO({id: did.getDid(), service: [accessService, metaDataService]}) const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) const serviceAgreementSignature: string = - await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.signServiceAgreement(ddo, accessService.serviceDefinitionId, serviceAgreementId, consumerAccount) assert(serviceAgreementSignature) const serviceAgreement: ServiceAgreement = - await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.executeServiceAgreement(did, ddo, accessService.serviceDefinitionId, serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) assert(serviceAgreement) // get funds await consumerAccount.requestTokens(metaDataService.metadata.base.price) - const paid: boolean = await serviceAgreement.payAsset(assetId, metaDataService.metadata.base.price, + const paid: boolean = await serviceAgreement.payAsset(did.getId(), metaDataService.metadata.base.price, consumerAccount) assert(paid) }) @@ -155,54 +152,54 @@ describe("ServiceAgreement", () => { describe("#grantAccess()", () => { it("should grant access in that service agreement", async () => { - const did: string = `did:op:${assetId}` - const ddo = new DDO({id: did, service: [accessService]}) + const ddo = new DDO({id: did.getDid(), service: [accessService]}) const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) const serviceAgreementSignature: string = - await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.signServiceAgreement(ddo, accessService.serviceDefinitionId, serviceAgreementId, consumerAccount) assert(serviceAgreementSignature) const serviceAgreement: ServiceAgreement = - await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.executeServiceAgreement(did, ddo, accessService.serviceDefinitionId, serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) assert(serviceAgreement) // get funds await consumerAccount.requestTokens(metaDataService.metadata.base.price) - const paid: boolean = await serviceAgreement.payAsset(assetId, metaDataService.metadata.base.price, + const paid: boolean = await serviceAgreement.payAsset(did.getId(), metaDataService.metadata.base.price, consumerAccount) assert(paid) // todo: use document id - const accessGranted: boolean = await serviceAgreement.grantAccess(assetId, assetId, publisherAccount) + const accessGranted: boolean = await serviceAgreement.grantAccess(did.getId(), did.getId(), + publisherAccount) assert(accessGranted) }) it("should fail to grant grant access if there is no payment", async () => { - const did: string = `did:op:${assetId}` - const ddo = new DDO({id: did, service: [accessService]}) + const ddo = new DDO({id: did.getDid(), service: [accessService]}) const serviceAgreementId: string = IdGenerator.generateId() // @ts-ignore WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) const serviceAgreementSignature: string = - await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.signServiceAgreement(ddo, accessService.serviceDefinitionId, serviceAgreementId, consumerAccount) assert(serviceAgreementSignature) const serviceAgreement: ServiceAgreement = - await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId, + await ServiceAgreement.executeServiceAgreement(did, ddo, accessService.serviceDefinitionId, serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) assert(serviceAgreement) // todo: use document id - const accessGranted: boolean = await serviceAgreement.grantAccess(assetId, assetId, publisherAccount) + const accessGranted: boolean = await serviceAgreement.grantAccess(did.getId(), did.getId(), + publisherAccount) assert(!accessGranted) }) })