From dc53af095c319998449e7ffffc900a9466e6f22d Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Tue, 11 Feb 2020 22:11:37 +0200 Subject: [PATCH 1/8] add transferOwnership & related --- src/aquarius/Aquarius.ts | 69 +++++++++++++++++++++++++++++++ src/ddo/DDO.ts | 2 + src/ocean/OceanAssets.ts | 21 ++++++++-- src/ocean/utils/SignatureUtils.ts | 28 +++++++++++++ 4 files changed, 117 insertions(+), 3 deletions(-) diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index cd52a2f..8a757d2 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -3,6 +3,7 @@ import { DDO } from '../ddo/DDO' import DID from '../ocean/DID' import { Logger } from '../utils' import { WebServiceConnector } from '../ocean/utils/WebServiceConnector' +import { Account } from '../squid' const apiPath = '/api/v1/aquarius/assets/ddo' @@ -215,6 +216,74 @@ export class Aquarius { return this.retrieveDDO(undefined, metadataServiceEndpoint) } + /** + * Updates a DDO. + * @param {DID | string} did DID of the asset to update. + * @param {DDO} newDdo New DDO of the asset. + * @return {Promise} Updated DDO of the asset. + */ + public async updateDDO(did: DID | string, newDdo: DDO): Promise { + did = did && DID.parse(did) + const fullUrl = `${this.url}${apiPath}/${did.getDid()}` + const result = await this.fetch + .put(fullUrl, DDO.serialize(newDdo)) + .then((response: any) => { + if (response.ok) { + return response.json() + } + this.logger.log( + 'updateDDO failed:', + response.status, + response.statusText, + did + ) + return null as DDO + }) + .then((response: DDO) => { + return new DDO(response) as DDO + }) + .catch(error => { + this.logger.error('Error updating metadata: ', error) + return null as DDO + }) + + return result + } + + + /** + * Transfer ownership of a DDO + * @param {DID | string} did DID of the asset to update. + * @param {String} newOwner New owner of the DDO + * @param {String} updated Updated field of the DDO + * @param {String} signature Signature using updated field to verify that the consumer has rights + * @return {Promise} Result. + */ + public async transferOwnership(did: DID | string, newOwner: string, updated: string, signature: string): Promise { + did = did && DID.parse(did) + const fullUrl = `${this.url}${apiPath}/transferownership/${did.getDid()}` + const result = await this.fetch + .put(fullUrl, JSON.stringify({signature: signature, updated: updated, newowner: newOwner})) + .then((response: any) => { + if (response.ok) { + return response.text + } + this.logger.log( + 'transferownership failed:', + response.status, + response.statusText + ) + return null + }) + + .catch(error => { + this.logger.error('Error updating metadata: ', error) + return null + }) + + return result + } + public getServiceEndpoint(did: DID) { return `${this.url}/api/v1/aquarius/assets/ddo/did:op:${did.getId()}` } diff --git a/src/ddo/DDO.ts b/src/ddo/DDO.ts index 4692294..8f56cb7 100644 --- a/src/ddo/DDO.ts +++ b/src/ddo/DDO.ts @@ -40,6 +40,8 @@ export class DDO { public created: string + public updated: string + public publicKey: PublicKey[] = [] public authentication: Authentication[] = [] diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 537fd8b..7a25689 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -412,14 +412,29 @@ export class OceanAssets extends Instantiable { * Transfer ownership of an asset. * @param {string} did Asset DID. * @param {string} newOwner Ethereum address of the new owner of the DID. + * @param {Account} account Ethereum account to sign and prove the ownership. * @return {Promise} Returns Web3 transaction receipt. */ public async transferOwnership( did: string, - newOwner: string + newOwner: string, + account: Account ): Promise { - const owner = await this.ocean.assets.owner(did) - return this.ocean.keeper.didRegistry.transferDIDOwnership(did, newOwner, owner) + const oldOwner = await this.ocean.assets.owner(did) + const oldDdo = await this.ocean.aquarius.retrieveDDO(did) + + // update owner on-chain + const txReceipt = this.ocean.keeper.didRegistry.transferDIDOwnership( + did, + newOwner, + oldOwner + ) + //get a signature + const signature=await this.ocean.utils.signature.signForAquarius(oldDdo.updated, account) + if(signature!=null) + await this.ocean.aquarius.transferOwnership(did,newOwner,oldDdo.updated,signature) + + return txReceipt } /** diff --git a/src/ocean/utils/SignatureUtils.ts b/src/ocean/utils/SignatureUtils.ts index 9da6072..23d7beb 100644 --- a/src/ocean/utils/SignatureUtils.ts +++ b/src/ocean/utils/SignatureUtils.ts @@ -1,5 +1,6 @@ import Web3 from 'web3' import { Logger } from '../../utils' +import { Account } from '../../squid' export class SignatureUtils { private web3: Web3 @@ -40,4 +41,31 @@ export class SignatureUtils { public async verifyText(text: string, signature: string): Promise { return this.web3.eth.personal.ecRecover(text, signature) } + + public async getHash(message:string): Promise { + var hex = '' + for(var i=0;i { + const hash=await this.getHash(message) + const isMetaMask = + this.web3 && + this.web3.currentProvider && + (this.web3.currentProvider as any).isMetaMask + try { + return this.web3.eth.personal.sign(hash, account.getId(),account.getPassword()) + } catch (e) { + if (isMetaMask) { + throw e + } + this.logger.warn('Error on personal sign.') + this.logger.warn(e) + return null + } + + } } From b29ac25de1a6a8f568a141067b0398d748e30985 Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Tue, 11 Feb 2020 22:15:42 +0200 Subject: [PATCH 2/8] lint --- src/aquarius/Aquarius.ts | 22 ++++++++++++++++------ src/ocean/OceanAssets.ts | 16 ++++++++++++---- src/ocean/utils/SignatureUtils.ts | 22 +++++++++++++--------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index 8a757d2..dbaa6a8 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -3,7 +3,6 @@ import { DDO } from '../ddo/DDO' import DID from '../ocean/DID' import { Logger } from '../utils' import { WebServiceConnector } from '../ocean/utils/WebServiceConnector' -import { Account } from '../squid' const apiPath = '/api/v1/aquarius/assets/ddo' @@ -250,7 +249,6 @@ export class Aquarius { return result } - /** * Transfer ownership of a DDO * @param {DID | string} did DID of the asset to update. @@ -259,11 +257,23 @@ export class Aquarius { * @param {String} signature Signature using updated field to verify that the consumer has rights * @return {Promise} Result. */ - public async transferOwnership(did: DID | string, newOwner: string, updated: string, signature: string): Promise { + public async transferOwnership( + did: DID | string, + newOwner: string, + updated: string, + signature: string + ): Promise { did = did && DID.parse(did) const fullUrl = `${this.url}${apiPath}/transferownership/${did.getDid()}` const result = await this.fetch - .put(fullUrl, JSON.stringify({signature: signature, updated: updated, newowner: newOwner})) + .put( + fullUrl, + JSON.stringify({ + signature: signature, + updated: updated, + newowner: newOwner + }) + ) .then((response: any) => { if (response.ok) { return response.text @@ -273,9 +283,9 @@ export class Aquarius { response.status, response.statusText ) - return null + return null }) - + .catch(error => { this.logger.error('Error updating metadata: ', error) return null diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 7a25689..69db15d 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -429,10 +429,18 @@ export class OceanAssets extends Instantiable { newOwner, oldOwner ) - //get a signature - const signature=await this.ocean.utils.signature.signForAquarius(oldDdo.updated, account) - if(signature!=null) - await this.ocean.aquarius.transferOwnership(did,newOwner,oldDdo.updated,signature) + // get a signature + const signature = await this.ocean.utils.signature.signForAquarius( + oldDdo.updated, + account + ) + if (signature != null) + await this.ocean.aquarius.transferOwnership( + did, + newOwner, + oldDdo.updated, + signature + ) return txReceipt } diff --git a/src/ocean/utils/SignatureUtils.ts b/src/ocean/utils/SignatureUtils.ts index 23d7beb..2f269ae 100644 --- a/src/ocean/utils/SignatureUtils.ts +++ b/src/ocean/utils/SignatureUtils.ts @@ -42,22 +42,27 @@ export class SignatureUtils { return this.web3.eth.personal.ecRecover(text, signature) } - public async getHash(message:string): Promise { - var hex = '' - for(var i=0;i { + let hex = '' + for (let i = 0; i < message.length; i++) { + hex += '' + message.charCodeAt(i).toString(16) } - var hexMessage = "0x" + hex + const hexMessage = '0x' + hex return hexMessage as string } - public async signForAquarius(message:string, account:Account): Promise { - const hash=await this.getHash(message) + + public async signForAquarius(message: string, account: Account): Promise { + const hash = await this.getHash(message) const isMetaMask = this.web3 && this.web3.currentProvider && (this.web3.currentProvider as any).isMetaMask try { - return this.web3.eth.personal.sign(hash, account.getId(),account.getPassword()) + return this.web3.eth.personal.sign( + hash, + account.getId(), + account.getPassword() + ) } catch (e) { if (isMetaMask) { throw e @@ -66,6 +71,5 @@ export class SignatureUtils { this.logger.warn(e) return null } - } } From 4cbbcbbb8431f43e5020621faa05e7aff24f15f4 Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Tue, 11 Feb 2020 22:26:12 +0200 Subject: [PATCH 3/8] remove updateDDO function --- src/aquarius/Aquarius.ts | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index dbaa6a8..1df4005 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -215,40 +215,6 @@ export class Aquarius { return this.retrieveDDO(undefined, metadataServiceEndpoint) } - /** - * Updates a DDO. - * @param {DID | string} did DID of the asset to update. - * @param {DDO} newDdo New DDO of the asset. - * @return {Promise} Updated DDO of the asset. - */ - public async updateDDO(did: DID | string, newDdo: DDO): Promise { - did = did && DID.parse(did) - const fullUrl = `${this.url}${apiPath}/${did.getDid()}` - const result = await this.fetch - .put(fullUrl, DDO.serialize(newDdo)) - .then((response: any) => { - if (response.ok) { - return response.json() - } - this.logger.log( - 'updateDDO failed:', - response.status, - response.statusText, - did - ) - return null as DDO - }) - .then((response: DDO) => { - return new DDO(response) as DDO - }) - .catch(error => { - this.logger.error('Error updating metadata: ', error) - return null as DDO - }) - - return result - } - /** * Transfer ownership of a DDO * @param {DID | string} did DID of the asset to update. From 55b03da4c6b772b52db78ae82c4d14ce9a725f7f Mon Sep 17 00:00:00 2001 From: Alex Coseru Date: Wed, 4 Mar 2020 15:33:05 +0200 Subject: [PATCH 4/8] Update OceanAssets.ts --- src/ocean/OceanAssets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 69db15d..71d1500 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -412,7 +412,7 @@ export class OceanAssets extends Instantiable { * Transfer ownership of an asset. * @param {string} did Asset DID. * @param {string} newOwner Ethereum address of the new owner of the DID. - * @param {Account} account Ethereum account to sign and prove the ownership. + * @param {Account} account Ethereum account of original/old owner to sign and prove the ownership. * @return {Promise} Returns Web3 transaction receipt. */ public async transferOwnership( From 3ff0e87778d3c26c3036e205e72c6484fdc5df9f Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Wed, 25 Mar 2020 11:21:03 +0200 Subject: [PATCH 5/8] fix transferOwnership --- .travis.yml | 2 +- src/aquarius/Aquarius.ts | 6 +++--- src/ocean/OceanAssets.ts | 12 +++++++++++- test/integration/ocean/AssetOwners.test.ts | 12 +++++------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 33a8834..71f42b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_script: - ganache-cli --port 18545 > ganache-cli.log & - git clone https://github.com/oceanprotocol/barge - cd barge - - export AQUARIUS_VERSION=v1.0.5 + - export AQUARIUS_VERSION=unstable - export BRIZO_VERSION=v0.8.1 - export KEEPER_VERSION=v0.13.2 - export EVENTS_HANDLER_VERSION=v0.4.4 diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index 1df4005..f1b3063 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -230,14 +230,14 @@ export class Aquarius { signature: string ): Promise { did = did && DID.parse(did) - const fullUrl = `${this.url}${apiPath}/transferownership/${did.getDid()}` + const fullUrl = `${this.url}${apiPath}/owner/update//${did.getDid()}` const result = await this.fetch .put( fullUrl, JSON.stringify({ signature: signature, updated: updated, - newowner: newOwner + newOwner: newOwner }) ) .then((response: any) => { @@ -253,7 +253,7 @@ export class Aquarius { }) .catch(error => { - this.logger.error('Error updating metadata: ', error) + this.logger.error('Error transfering ownership metadata: ', error) return null }) diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 71d1500..ed7fb4a 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -379,9 +379,19 @@ export class OceanAssets extends Instantiable { /** * Returns the owner of a asset. * @param {string} did Decentralized ID. - * @return {Promise} Returns Agreement ID + * @return {Promise} Returns eth address */ public async owner(did: string): Promise { + const ddo = await this.resolve(did) + return ddo.publicKey[0].owner + } + + /** + * Returns the creator of a asset. + * @param {string} did Decentralized ID. + * @return {Promise} Returns eth address + */ + public async creator(did: string): Promise { const ddo = await this.resolve(did) const checksum = ddo.getChecksum() const { creator, signatureValue } = ddo.proof diff --git a/test/integration/ocean/AssetOwners.test.ts b/test/integration/ocean/AssetOwners.test.ts index 798971c..b97853e 100644 --- a/test/integration/ocean/AssetOwners.test.ts +++ b/test/integration/ocean/AssetOwners.test.ts @@ -75,9 +75,8 @@ describe('Asset Owners', () => { const { length: initialLength } = await ocean.assets.consumerAssets( account2.getId() ) - + const ddo = await ocean.assets.create(metadata as any, account1) - const { length: finalLength1 } = await ocean.assets.consumerAssets( account2.getId() ) @@ -89,12 +88,10 @@ describe('Asset Owners', () => { +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) ) } catch {} - const { index } = ddo.findServiceByType('access') await ocean.assets.order(ddo.id, index, account2) // Access granted - const { length: finalLength2 } = await ocean.assets.consumerAssets( account2.getId() ) @@ -103,11 +100,12 @@ describe('Asset Owners', () => { it('should be able to transfer ownership', async () => { const { id } = await ocean.assets.create(metadata as any, account1) - // transfer - await ocean.assets.transferOwnership(id, account2.getId()) + await ocean.assets.transferOwnership(id, account2.getId(), account1) const newOwner = await ocean.keeper.didRegistry.getDIDOwner(id) - assert.equal(newOwner, account2.getId()) + // check aquarius + const aquariusOwner = await ocean.assets.owner(id) + assert.equal(aquariusOwner, account2.getId()) }) }) From 58a1345e362ccc1fe13b292b4b0e30f5840c9051 Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Wed, 25 Mar 2020 11:57:50 +0200 Subject: [PATCH 6/8] fix asset.owner to get owner from chain --- src/ocean/OceanAssets.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 6c74b62..7faaf3c 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -311,8 +311,8 @@ export class OceanAssets extends Instantiable { * @return {Promise} Returns Account ID */ public async owner(did: string): Promise { - const ddo = await this.resolve(did) - return ddo.publicKey[0].owner + return await this.ocean.keeper.didRegistry.getDIDOwner(did) + } /** From ee3529b4fe4aad40e6f32e2960cdad25feb61a34 Mon Sep 17 00:00:00 2001 From: alexcos20 Date: Wed, 25 Mar 2020 14:07:51 +0200 Subject: [PATCH 7/8] fix --- src/ocean/OceanAssets.ts | 4 ++-- test/integration/ocean/AssetOwners.test.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 7faaf3c..719d362 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -311,8 +311,8 @@ export class OceanAssets extends Instantiable { * @return {Promise} Returns Account ID */ public async owner(did: string): Promise { - return await this.ocean.keeper.didRegistry.getDIDOwner(did) - + const owner = await this.ocean.keeper.didRegistry.getDIDOwner(did) + return owner } /** diff --git a/test/integration/ocean/AssetOwners.test.ts b/test/integration/ocean/AssetOwners.test.ts index 22fd0e7..e20d739 100644 --- a/test/integration/ocean/AssetOwners.test.ts +++ b/test/integration/ocean/AssetOwners.test.ts @@ -75,7 +75,7 @@ describe('Asset Owners', () => { const { length: initialLength } = await ocean.assets.consumerAssets( account2.getId() ) - + const ddo = await ocean.assets.create(metadata as any, account1) const { length: finalLength1 } = await ocean.assets.consumerAssets( account2.getId() From d0d7ee71cc61871b6bc725c91c0683161c2bdc36 Mon Sep 17 00:00:00 2001 From: Alex Coseru Date: Wed, 25 Mar 2020 20:18:07 +0200 Subject: [PATCH 8/8] Update src/aquarius/Aquarius.ts Co-Authored-By: Matthias Kretschmann --- src/aquarius/Aquarius.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index f1b3063..e082394 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -230,7 +230,7 @@ export class Aquarius { signature: string ): Promise { did = did && DID.parse(did) - const fullUrl = `${this.url}${apiPath}/owner/update//${did.getDid()}` + const fullUrl = `${this.url}${apiPath}/owner/update/${did.getDid()}` const result = await this.fetch .put( fullUrl,