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 + } + + } }