diff --git a/integration/ocean/AssetOwners.test.ts b/integration/ocean/AssetOwners.test.ts index 03165df..eb514e9 100644 --- a/integration/ocean/AssetOwners.test.ts +++ b/integration/ocean/AssetOwners.test.ts @@ -72,7 +72,7 @@ describe('Asset Owners', () => { // Granting access try { await account2.requestTokens( - +metadata.base.price * + +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) ) } catch {} diff --git a/integration/ocean/ConsumeAsset.test.ts b/integration/ocean/ConsumeAsset.test.ts index 7635e22..bca25c0 100644 --- a/integration/ocean/ConsumeAsset.test.ts +++ b/integration/ocean/ConsumeAsset.test.ts @@ -31,7 +31,7 @@ describe('Consume Asset', () => { } }) - it('should regiester a asset', async () => { + it('should register an asset', async () => { ddo = await ocean.assets.create(metadata as any, publisher) assert.isDefined(ddo, 'Register has not returned a DDO') @@ -50,7 +50,7 @@ describe('Consume Asset', () => { it('should be able to request tokens for consumer', async () => { const initialBalance = (await consumer.getBalance()).ocn const claimedTokens = - +metadata.base.price * 10 ** -(await ocean.keeper.token.decimals()) + +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) try { await consumer.requestTokens(claimedTokens) @@ -115,7 +115,7 @@ describe('Consume Asset', () => { it('should lock the payment by the consumer', async () => { const paid = await ocean.agreements.conditions.lockReward( serviceAgreementSignatureResult.agreementId, - ddo.findServiceByType('Metadata').metadata.base.price, + ddo.findServiceByType('Metadata').metadata.main.price, consumer ) @@ -182,7 +182,7 @@ describe('Consume Asset', () => { ) }) - it('should consume and store one assets', async () => { + it('should consume and store one asset', async () => { const accessService = ddo.findServiceByType('Access') const folder = '/tmp/ocean/squid-js-2' diff --git a/integration/ocean/ConsumeAssetBrizo.test.ts b/integration/ocean/ConsumeAssetBrizo.test.ts index fe82d10..dac6736 100644 --- a/integration/ocean/ConsumeAssetBrizo.test.ts +++ b/integration/ocean/ConsumeAssetBrizo.test.ts @@ -54,7 +54,7 @@ describe('Consume Asset (Brizo)', () => { try { await consumer.requestTokens( - +metadata.base.price * + +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) ) } catch {} diff --git a/integration/ocean/ConsumeBigAsset.test.ts b/integration/ocean/ConsumeBigAsset.test.ts index 19d07ef..3580207 100644 --- a/integration/ocean/ConsumeBigAsset.test.ts +++ b/integration/ocean/ConsumeBigAsset.test.ts @@ -30,8 +30,8 @@ xdescribe('Consume Asset (Large size)', () => { } metadata = { ...baseMetadata, - base: { - ...baseMetadata.base, + main: { + ...baseMetadata.main, files: [ { url: 'https://speed.hetzner.de/1GB.bin' @@ -52,7 +52,7 @@ xdescribe('Consume Asset (Large size)', () => { try { await consumer.requestTokens( - +metadata.base.price * + +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) ) } catch {} diff --git a/integration/ocean/SearchAsset.test.ts b/integration/ocean/SearchAsset.test.ts index 640f7d5..dc30fc3 100644 --- a/integration/ocean/SearchAsset.test.ts +++ b/integration/ocean/SearchAsset.test.ts @@ -45,7 +45,7 @@ describe('Search Asset', () => { } }) - it('should regiester some a asset', async () => { + it('should register an asset', async () => { assert.instanceOf( await ocean.assets.create( metadataGenerator('Test1') as any, diff --git a/integration/ocean/Signature.test.ts b/integration/ocean/Signature.test.ts index e2dc6e1..e78b39d 100644 --- a/integration/ocean/Signature.test.ts +++ b/integration/ocean/Signature.test.ts @@ -64,7 +64,7 @@ describe('Signature', () => { { type: 'Metadata', metadata: { - base: { + main: { price: 10 } } diff --git a/integration/ocean/Versions.test.ts b/integration/ocean/Versions.test.ts index 621b8f6..5021171 100644 --- a/integration/ocean/Versions.test.ts +++ b/integration/ocean/Versions.test.ts @@ -11,7 +11,7 @@ describe('Versions', () => { ocean = await Ocean.getInstance(config) }) - it('should returns the versions', async () => { + it('should return the versions', async () => { const versions = await ocean.versions.get() assert.equal(versions.aquarius.status, OceanPlatformTechStatus.Working) diff --git a/integration/utils/ddo-metadata-generator.ts b/integration/utils/ddo-metadata-generator.ts index f7db412..57311d2 100644 --- a/integration/utils/ddo-metadata-generator.ts +++ b/integration/utils/ddo-metadata-generator.ts @@ -1,15 +1,30 @@ import { MetaData } from '../../src' // @oceanprotocol/squid const metadata: Partial = { - base: { + main: { name: undefined, type: 'dataset', - description: - 'Weather information of UK including temperature and humidity', dateCreated: '2012-10-10T17:00:00Z', datePublished: '2012-10-10T17:00:00Z', author: 'Met Office', license: 'CC-BY', + price: '21' + '0'.repeat(18), + files: [ + { + index: 0, + url: + 'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/package.json' + }, + { + index: 1, + url: + 'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/README.md' + } + ] + }, + additionalInformation: { + description: + 'Weather information of UK including temperature and humidity', copyrightHolder: 'Met Office', workExample: '423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68', @@ -27,20 +42,7 @@ const metadata: Partial = { ], inLanguage: 'en', categories: ['Economy', 'Data Science'], - tags: ['weather', 'uk', '2011', 'temperature', 'humidity'], - price: '21' + '0'.repeat(18), - files: [ - { - index: 0, - url: - 'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/package.json' - }, - { - index: 1, - url: - 'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/README.md' - } - ] + tags: ['weather', 'uk', '2011', 'temperature', 'humidity'] } } @@ -49,10 +51,13 @@ export const generateMetadata = ( price?: number ): Partial => ({ ...metadata, - base: { - ...metadata.base, + main: { + ...metadata.main, name, price: (price || 21) + '0'.repeat(18) + }, + additionalInformation: { + ...metadata.additionalInformation } }) diff --git a/src/ddo/DDO.ts b/src/ddo/DDO.ts index 6baf9a2..9736d07 100644 --- a/src/ddo/DDO.ts +++ b/src/ddo/DDO.ts @@ -102,7 +102,7 @@ export class DDO { */ public getChecksum(): string { const { metadata } = this.findServiceByType('Metadata') - const { files, name, author, license } = metadata.base + const { files, name, author, license } = metadata.main const values = [ ...(files || []).map(({ checksum }) => checksum).filter(_ => !!_), @@ -121,7 +121,7 @@ export class DDO { * Generates proof using personal sing. * @param {Web3} web3 Web3 instance. * @param {string} publicKey Public key to be used on personal sign. - * @param {string} password Password if it's requirted. + * @param {string} password Password if it's required. * @return {Promise} Proof object. */ public async generateProof( @@ -150,11 +150,11 @@ export class DDO { */ public addChecksum(): void { const metadataService = this.findServiceByType('Metadata') - if (metadataService.metadata.base.checksum) { + if (metadataService.metadata.main.checksum) { LoggerInstance.log('Checksum already exists') return } - metadataService.metadata.base.checksum = this.getChecksum() + metadataService.metadata.main.checksum = this.getChecksum() } /** diff --git a/src/ddo/MetaData.ts b/src/ddo/MetaData.ts index 2b316ea..fe192b0 100644 --- a/src/ddo/MetaData.ts +++ b/src/ddo/MetaData.ts @@ -1,8 +1,4 @@ export interface StageRequirements { - computeServiceId?: string - serviceDefinitionId?: string - serverId?: string - serverInstances?: string container: { image: string tag: string @@ -23,7 +19,7 @@ export interface StageOutput { metadataUrl: string secretStoreUrl: string accessProxyUrl: string - metadata: MetaDataBase + metadata: MetaDataMain } export interface Stage { @@ -39,6 +35,38 @@ export interface Workflow { stages: Stage[] } +export interface Algorithm { + language: string + format?: string + version?: string + entrypoint: string + requirements: { + requirement: string + version: string + } +} + +export interface ServiceDefinition { + auth: { + type: string + user?: string + password?: string + token?: string + } + endpoints: { + index: number + url: string + method: string + contentTypes: string[] + } +} + +export interface Service { + spec?: string + specChecksum?: string + definition: ServiceDefinition +} + export interface File { /** * File name. @@ -105,10 +133,10 @@ export interface File { } /** - * Base attributes of Assets Metadata. - * @see https://github.com/oceanprotocol/OEPs/tree/master/8#base-attributes + * Main attributes of assets metadata. + * @see https://github.com/oceanprotocol/OEPs/tree/master/8 */ -export interface MetaDataBase { +export interface MetaDataMain { /** * Descriptive name of the Asset. * @type {string} @@ -124,14 +152,6 @@ export interface MetaDataBase { */ type: 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other' - /** - * Details of what the resource is. For a dataset, this attribute - * explains what the data represents and what it can be used for. - * @type {string} - * @example "Weather information of UK including temperature and humidity" - */ - description?: string - /** * The date on which the asset was created by the originator in * ISO 8601 format, Coordinated Universal Time. @@ -164,6 +184,83 @@ export interface MetaDataBase { */ license: string + /** + * Price of the asset. + * @type {string} + * @example "1000000000000000000" + */ + price: string + + /** + * Array of File objects including the encrypted file urls and some additional information. + * @type {File[]} + */ + files: File[] + + /** + * SHA3 hash of concatenated values: [list of all file checksums] + name + author + license + did + * @type {string} + */ + checksum?: string + + encryptedFiles?: any + + encryptedService?: any + + workflow?: Workflow + + algorithm?: Algorithm + + service?: Service +} + +/** + * Curation attributes of Assets Metadata. + * @see https://github.com/oceanprotocol/OEPs/tree/master/8 + */ +export interface Curation { + /** + * Decimal value between 0 and 1. 0 is the default value. + * @type {number} + * @example 0.93 + */ + rating: number + + /** + * Number of votes. 0 is the default value. + * @type {number} + * @example 123 + */ + numVotes: number + + /** + * Schema applied to calculate the rating. + * @type {string} + * @example "Binary Voting" + */ + schema?: string + + /** + * Flag unsuitable content. + * @type {boolean} + * @example true + */ + isListed?: boolean +} + +/** + * Additional Information of Assets Metadata. + * @see https://github.com/oceanprotocol/OEPs/tree/master/8#additional-information + */ +export interface AdditionalInformation { + /** + * Details of what the resource is. For a dataset, this attribute + * explains what the data represents and what it can be used for. + * @type {string} + * @example "Weather information of UK including temperature and humidity" + */ + description?: string + /** * The party holding the legal copyright. Empty by default. * @type {string} @@ -220,62 +317,6 @@ export interface MetaDataBase { */ tags?: string[] - /** - * Price of the asset. - * @type {string} - * @example "1000000000000000000" - */ - price: string - - /** - * Array of File objects including the encrypted file urls and some additional information. - * @type {File[]} - */ - files: File[] - - /** - * SHA3 hash of concatenated values: [list of all file checksums] + name + author + license + did - * @type {string} - */ - checksum?: string - - encryptedFiles?: any - - workflow?: Workflow -} - -/** - * Curation attributes of Assets Metadata. - * @see https://github.com/oceanprotocol/OEPs/tree/master/8#curation-attributes - */ -export interface Curation { - /** - * Decimal value between 0 and 1. 0 is the default value. - * @type {number} - * @example 0.93 - */ - rating: number - - /** - * Number of votes. 0 is the default value. - * @type {number} - * @example 123 - */ - numVotes: number - - /** - * Schema applied to calculate the rating. - * @type {string} - * @example "Binary Voting" - */ - schema?: string -} - -/** - * Additional Information of Assets Metadata. - * @see https://github.com/oceanprotocol/OEPs/tree/master/8#additional-information - */ -export interface AdditionalInformation { /** * An indication of update latency - i.e. How often are updates expected (seldom, * annually, quarterly, etc.), or is the resource static that is never expected @@ -283,28 +324,21 @@ export interface AdditionalInformation { * @type {string} * @example "yearly" */ - updateFrequency: string + updateFrequency?: string /** * A link to machine-readable structured markup (such as ttl/json-ld/rdf) * describing the dataset. * @type {StructuredMarkup[]} */ - structuredMarkup: { + structuredMarkup?: { uri: string mediaType: string }[] - - /** - * Checksum of attributes to be able to compare if there are changes in - * the asset that you are purchasing. - * @type {string} - */ - checksum: string } export interface MetaData { + main: MetaDataMain additionalInformation?: AdditionalInformation - base: MetaDataBase curation?: Curation } diff --git a/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts b/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts index c5a256a..2c4dcc1 100644 --- a/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts +++ b/src/keeper/contracts/templates/EscrowAccessSecretStoreTemplate.ts @@ -59,7 +59,7 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate { ) { return !!(await this.createFullAgreement( ddo.shortId(), - ddo.findServiceByType('Metadata').metadata.base.price, + ddo.findServiceByType('Metadata').metadata.main.price, consumer, from, agreementId @@ -79,7 +79,7 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate { } = await this.createFullAgreementData( agreementId, ddo.shortId(), - ddo.findServiceByType('Metadata').metadata.base.price, + ddo.findServiceByType('Metadata').metadata.main.price, consumer ) return [ diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 0ec933c..f45c7eb 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -81,7 +81,7 @@ export class OceanAssets extends Instantiable { observer.next(CreateProgressStep.EncryptingFiles) const encryptedFiles = await this.ocean.secretStore.encrypt( did.getId(), - metadata.base.files, + metadata.main.files, publisher ) this.logger.log('Files encrypted') @@ -135,11 +135,11 @@ export class OceanAssets extends Instantiable { // Overwrites defaults ...metadata, // Cleaning not needed information - base: { - ...metadata.base, + main: { + ...metadata.main, contentUrls: undefined, encryptedFiles, - files: metadata.base.files.map( + files: metadata.main.files.map( (file, index) => ({ ...file, index, @@ -165,7 +165,7 @@ export class OceanAssets extends Instantiable { })) as Service[] }) - // Overwritte initial service agreement conditions + // Overwrite initial service agreement conditions const rawConditions = await templates.escrowAccessSecretStoreTemplate.getServiceAgreementTemplateConditions() const conditions = fillConditionsWithDDO(rawConditions, ddo) serviceAgreementTemplate.conditions = conditions @@ -237,7 +237,7 @@ export class OceanAssets extends Instantiable { const accessService = ddo.findServiceById(serviceDefinitionId) - const { files } = metadata.base + const { files } = metadata.main const { serviceEndpoint } = accessService @@ -265,7 +265,7 @@ export class OceanAssets extends Instantiable { } else { const files = await this.ocean.secretStore.decrypt( did, - ddo.findServiceByType('Metadata').metadata.base.encryptedFiles, + ddo.findServiceByType('Metadata').metadata.main.encryptedFiles, consumerAccount, ddo.findServiceByType('Authorization').serviceEndpoint ) @@ -327,7 +327,7 @@ export class OceanAssets extends Instantiable { observer.next(OrderProgressStep.LockingPayment) const paid = await oceanAgreements.conditions.lockReward( agreementId, - metadata.base.price, + metadata.main.price, consumer ) observer.next(OrderProgressStep.LockedPayment) diff --git a/src/utils/DDOHelpers.ts b/src/utils/DDOHelpers.ts index 3a27c1a..1a68198 100644 --- a/src/utils/DDOHelpers.ts +++ b/src/utils/DDOHelpers.ts @@ -13,7 +13,7 @@ function fillParameterWithDDO( case 'amount': case 'price': return String( - ddo.findServiceByType('Metadata').metadata.base.price + ddo.findServiceByType('Metadata').metadata.main.price ) case 'assetId': case 'documentId': diff --git a/test/ddo/DDO.test.ts b/test/ddo/DDO.test.ts index 0a35b82..20b7726 100644 --- a/test/ddo/DDO.test.ts +++ b/test/ddo/DDO.test.ts @@ -91,41 +91,13 @@ describe('DDO', () => { serviceEndpoint: 'http://myaquarius.org/api/v1/provider/assets/metadata/{did}', metadata: { - base: { + main: { name: 'UK Weather information 2011', type: 'dataset', - description: - 'Weather information of UK including temperature and humidity', dateCreated: '2012-10-10T17:00:000Z', datePublished: '2012-10-10T17:00:000Z', author: 'Met Office', license: 'CC-BY', - copyrightHolder: 'Met Office', - workExample: - '423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68', - links: [ - { - sample1: - 'http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/' - }, - { - sample2: - 'http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/' - }, - { - fieldsDescription: - 'http://data.ceda.ac.uk/badc/ukcp09/' - } - ], - inLanguage: 'en', - categories: ['Economy', 'Data Science'], - tags: [ - 'weather', - 'uk', - '2011', - 'temperature', - 'humidity' - ], price: 10, files: [ { @@ -152,7 +124,35 @@ describe('DDO', () => { schema: 'Binary Voting' }, additionalInformation: { - updateFrecuency: 'yearly', + description: + 'Weather information of UK including temperature and humidity', + copyrightHolder: 'Met Office', + workExample: + '423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68', + links: [ + { + sample1: + 'http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-daily/' + }, + { + sample2: + 'http://data.ceda.ac.uk/badc/ukcp09/data/gridded-land-obs/gridded-land-obs-averages-25km/' + }, + { + fieldsDescription: + 'http://data.ceda.ac.uk/badc/ukcp09/' + } + ], + inLanguage: 'en', + categories: ['Economy', 'Data Science'], + tags: [ + 'weather', + 'uk', + '2011', + 'temperature', + 'humidity' + ], + updateFrequency: 'yearly', structuredMarkup: [ { uri: diff --git a/test/testdata/ddo.json b/test/testdata/ddo.json index cd53e6b..1388d2b 100644 --- a/test/testdata/ddo.json +++ b/test/testdata/ddo.json @@ -58,9 +58,7 @@ }, "events": { "PaymentLocked": { - "actorType": [ - "publisher" - ], + "actorType": ["publisher"], "handlers": [ { "moduleName": "accessControl", @@ -84,9 +82,7 @@ }, "events": { "PaymentReleased": { - "actorType": [ - "publisher" - ], + "actorType": ["publisher"], "handlers": [ { "moduleName": "serviceAgreement", @@ -110,9 +106,7 @@ }, "events": { "AccessGranted": { - "actorType": [ - "consumer" - ], + "actorType": ["consumer"], "handlers": [ { "moduleName": "asset", @@ -136,9 +130,7 @@ }, "events": { "PaymentRefund": { - "actorType": [ - "consumer" - ], + "actorType": ["consumer"], "handlers": [ { "moduleName": "serviceAgreement", @@ -165,26 +157,34 @@ "base": { "name": "UK Weather information 2011", "type": "dataset", - "description": "Weather information of UK including temperature and humidity", "dateCreated": "2012-10-10T17:00:000Z", "author": "Met Office", "license": "CC-BY", + "price": 10, + "files": [ + { + "index": 0, + "url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip", + "checksum": "085340abffh21495345af97c6b0e761", + "contentLength": 12324 + }, + { + "url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp2.zip" + } + ] + }, + "curation": { + "rating": 0.93, + "numVotes": 123, + "schema": "Binary Voting" + }, + "additionalInformation": { + "description": "Weather information of UK including temperature and humidity", "copyrightHolder": "Met Office", "workExample": "423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68", "contentUrls": [ "https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip" ], - "files": [ - { - "index": 0, - "url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp.zip", - "checksum": "085340abffh21495345af97c6b0e761", - "contentLength": 12324 - }, - { - "url": "https://testocnfiles.blob.core.windows.net/testfiles/testzkp2.zip" - } - ], "links": [ { "name": "Sample of Asset Data", @@ -200,14 +200,6 @@ "inLanguage": "en", "categories": ["Economy", "Data Science"], "tags": ["weather", "uk", "2011", "temperature", "humidity"], - "price": 10 - }, - "curation": { - "rating": 0.93, - "numVotes": 123, - "schema": "Binary Voting" - }, - "additionalInformation": { "updateFrequency": "yearly", "structuredMarkup": [ {