diff --git a/.travis.yml b/.travis.yml index e84a163..c8b8eec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ script: - npm run report-coverage - npm run build - npm run doc - - ./src/examples/fire_lazers.sh + - npm run integration after_script: - greenkeeper-lockfile-upload diff --git a/package.json b/package.json index 9dab4c7..14290a4 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "test": "mocha", "test:watch": "mocha -w --watch-extensions js,ts,json", "test:cover": "nyc mocha", + "integration": "./src/examples/fire_lazers.sh", "clean": "rm -rf ./dist/ ./doc/ ./coverage ./.nyc_output", "lint": "tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'", "start": "npm link @oceanprotocol/keeper-contracts @oceanprotocol/secret-store-client && npm run build:watch", diff --git a/src/brizo/Brizo.ts b/src/brizo/Brizo.ts index 58c97f1..b92ac60 100644 --- a/src/brizo/Brizo.ts +++ b/src/brizo/Brizo.ts @@ -42,12 +42,15 @@ export default class Brizo { consumerAddress, } - return WebServiceConnectorProvider - .getConnector() - .post( - this.getPurchaseEndpoint(), - decodeURI(JSON.stringify(args)), - ) - + try { + return await WebServiceConnectorProvider + .getConnector() + .post( + this.getPurchaseEndpoint(), + decodeURI(JSON.stringify(args)), + ) + } catch (e) { + throw new Error("HTTP request failed") + } } } diff --git a/src/examples/BuyAsset.ts b/src/examples/BuyAsset.ts index 9d59078..a50c0fb 100644 --- a/src/examples/BuyAsset.ts +++ b/src/examples/BuyAsset.ts @@ -5,8 +5,9 @@ import Service from "../ddo/Service" import DID from "../ocean/DID" import {Account, Logger, Ocean, ServiceAgreement} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const publisher: Account = (await ocean.getAccounts())[0] @@ -68,6 +69,6 @@ import config from "./config" const paid = await serviceAgreement.payAsset(did.getId(), metaData.base.price, consumer) Logger.log(`Asset paid: ${paid}`) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/ExecuteAgreement.ts b/src/examples/ExecuteAgreement.ts index 7dd5d8d..9a3fe2b 100644 --- a/src/examples/ExecuteAgreement.ts +++ b/src/examples/ExecuteAgreement.ts @@ -4,8 +4,9 @@ import MetaDataBase from "../ddo/MetaDataBase" import Service from "../ddo/Service" import {Account, Logger, Ocean, ServiceAgreement} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const publisher: Account = (await ocean.getAccounts())[0] @@ -63,6 +64,6 @@ import config from "./config" consumer, publisher) Logger.log("ServiceAgreement Id:", serviceAgreement.getId()) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/GetAccounts.ts b/src/examples/GetAccounts.ts index 9f14d23..94639b9 100644 --- a/src/examples/GetAccounts.ts +++ b/src/examples/GetAccounts.ts @@ -1,12 +1,13 @@ import {Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const accounts = await ocean.getAccounts() Logger.log(JSON.stringify(accounts, null, 2)) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/GetBalance.ts b/src/examples/GetBalance.ts index 308f8b4..58619a1 100644 --- a/src/examples/GetBalance.ts +++ b/src/examples/GetBalance.ts @@ -1,12 +1,13 @@ import {Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const accounts = await ocean.getAccounts() Logger.log(await accounts[0].getBalance()) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/GetHDWalletAccounts.ts b/src/examples/GetHDWalletAccounts.ts index 9f14d23..94639b9 100644 --- a/src/examples/GetHDWalletAccounts.ts +++ b/src/examples/GetHDWalletAccounts.ts @@ -1,12 +1,13 @@ import {Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const accounts = await ocean.getAccounts() Logger.log(JSON.stringify(accounts, null, 2)) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/GrantAccess.ts b/src/examples/GrantAccess.ts index ecc2237..1430d55 100644 --- a/src/examples/GrantAccess.ts +++ b/src/examples/GrantAccess.ts @@ -5,8 +5,9 @@ import Service from "../ddo/Service" import DID from "../ocean/DID" import {Account, Logger, Ocean, ServiceAgreement} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const publisher: Account = (await ocean.getAccounts())[0] @@ -71,6 +72,6 @@ import config from "./config" const accessGranted = await serviceAgreement.grantAccess(did.getId(), did.getId(), publisher) Logger.log(`Asset access granted: ${accessGranted}`) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/InitializeAgreement.ts b/src/examples/InitializeAgreement.ts index e936312..541d637 100644 --- a/src/examples/InitializeAgreement.ts +++ b/src/examples/InitializeAgreement.ts @@ -4,8 +4,9 @@ import MetaDataBase from "../ddo/MetaDataBase" import Service from "../ddo/Service" import {Account, Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const publisher: Account = (await ocean.getAccounts())[1] @@ -57,15 +58,19 @@ import config from "./config" const service: Service = ddo.findServiceByType("Access") - await ocean - .initializeServiceAgreement( - ddo.id, - service.serviceDefinitionId, - serviceAgreementSignatureResult.serviceAgreementId, - serviceAgreementSignatureResult.serviceAgreementSignature, - (files) => Logger.log(`Got files, first files length in bytes: ${files[0].length}`), - consumer, - ) + try { + await ocean + .initializeServiceAgreement( + ddo.id, + service.serviceDefinitionId, + serviceAgreementSignatureResult.serviceAgreementId, + serviceAgreementSignatureResult.serviceAgreementSignature, + (files) => Logger.log(`Got files, first files length in bytes: ${files[0].length}`), + consumer, + ) + } catch (e) { + throw new Error(`"Error on initializeServiceAgreement: ${e}`) + } +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/RegisterAsset.ts b/src/examples/RegisterAsset.ts index 2b91a8e..483b089 100644 --- a/src/examples/RegisterAsset.ts +++ b/src/examples/RegisterAsset.ts @@ -3,8 +3,9 @@ import MetaData from "../ddo/MetaData" import MetaDataBase from "../ddo/MetaDataBase" import {Account, Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const publisher: Account = (await ocean.getAccounts())[0] @@ -41,6 +42,6 @@ import config from "./config" const ddo: DDO = await ocean.registerAsset(metaData, publisher) Logger.log(ddo.id) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/RegisterServiceAgreementTemplates.ts b/src/examples/RegisterServiceAgreementTemplates.ts index 3a3e03f..e54d84c 100644 --- a/src/examples/RegisterServiceAgreementTemplates.ts +++ b/src/examples/RegisterServiceAgreementTemplates.ts @@ -1,7 +1,8 @@ import {Account, Logger, Ocean, ServiceAgreementTemplate, Templates} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const templateOwner: Account = (await ocean.getAccounts())[0] @@ -11,6 +12,6 @@ import config from "./config" Logger.log("ServiceAgreementTemplate registered:", serviceAgreementRegistered, "templateId:", serviceAgreementTemplate.getId()) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/Search.ts b/src/examples/Search.ts index 8f41312..edb9e89 100644 --- a/src/examples/Search.ts +++ b/src/examples/Search.ts @@ -1,8 +1,9 @@ import DDO from "../ddo/DDO" import {Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const result: DDO[] = await ocean.searchAssetsByText("Office Humidity") @@ -14,6 +15,6 @@ import config from "./config" }) Logger.log(names.length, names) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/SignAgreement.ts b/src/examples/SignAgreement.ts index 0b9d792..a1e8d2a 100644 --- a/src/examples/SignAgreement.ts +++ b/src/examples/SignAgreement.ts @@ -6,8 +6,9 @@ import MetaDataBase from "../ddo/MetaDataBase" import Service from "../ddo/Service" import {Account, Logger, Ocean} from "../squid" import config from "./config" +import {runner} from "./runner" -(async () => { +async function exec() { const ocean: Ocean = await Ocean.getInstance(config) const publisher: Account = (await ocean.getAccounts())[0] @@ -77,6 +78,6 @@ import config from "./config" Logger.log("ServiceAgreement Id:", serviceAgreementResult.serviceAgreementId) Logger.log("ServiceAgreement Signature:", serviceAgreementResult.serviceAgreementSignature) +} - process.exit(0) -})() +runner(exec) diff --git a/src/examples/runner.ts b/src/examples/runner.ts new file mode 100644 index 0000000..0d0a631 --- /dev/null +++ b/src/examples/runner.ts @@ -0,0 +1,10 @@ +import {Logger} from "../squid" + +export function runner(fn: () => Promise) { + fn() + .then(() => process.exit(0)) + .catch((e) => { + Logger.error(e) + process.exit(1) + }) +} diff --git a/src/keeper/Event.ts b/src/keeper/Event.ts index 6dc4207..cf30fa6 100644 --- a/src/keeper/Event.ts +++ b/src/keeper/Event.ts @@ -1,7 +1,7 @@ +import Logger from "../utils/Logger" import GenericContract from "./contracts/GenericContract" import EventListener from "./EventListener" import Web3Provider from "./Web3Provider" -// import Logger from "../utils/Logger" export default class Event { @@ -40,6 +40,9 @@ export default class Event { private async handler(callback: any) { const contract = await GenericContract.getInstance(this.contractName) + if (this.lastBlock > await Web3Provider.getWeb3().eth.getBlockNumber()) { + return + } try { const events = await contract.getEventData(this.eventName, { filter: this.filter, @@ -52,7 +55,7 @@ export default class Event { callback(events) } } catch (err) { - // Logger.log("err") + Logger.log(err) } } } diff --git a/src/keeper/contracts/ContractBase.ts b/src/keeper/contracts/ContractBase.ts index 1b23262..2dc88fc 100644 --- a/src/keeper/contracts/ContractBase.ts +++ b/src/keeper/contracts/ContractBase.ts @@ -63,8 +63,12 @@ export default abstract class ContractBase { value: args[i], } }) + Logger.error("-".repeat(40)) Logger.error(`Sending transaction "${name}" on contract "${this.contractName}" failed.`) - Logger.error(`Parameters: ${JSON.stringify(mappedArgs, null, 2)} from: ${from}`) + Logger.error(`Error: ${err.message}`) + Logger.error(`From: ${from}`) + Logger.error(`Parameters: ${JSON.stringify(mappedArgs, null, 2)}`) + Logger.error("-".repeat(40)) throw err } } diff --git a/src/ocean/Account.ts b/src/ocean/Account.ts index 4a44188..1473488 100644 --- a/src/ocean/Account.ts +++ b/src/ocean/Account.ts @@ -3,6 +3,7 @@ import * as EthJsUtils from "ethereumjs-util" import Keeper from "../keeper/Keeper" import Web3Provider from "../keeper/Web3Provider" import Balance from "../models/Balance" +import Logger from "../utils/Logger" import OceanBase from "./OceanBase" /** @@ -57,9 +58,15 @@ export default class Account extends OceanBase { * @return {Promise} */ public async requestTokens(amount: number): Promise { - await (await Keeper.getInstance()) - .market - .requestTokens(amount, this.id) + try { + await (await Keeper.getInstance()) + .market + .requestTokens(amount, this.id) + } catch (e) { + Logger.error(e) + throw new Error("Error requesting tokens") + + } return amount } diff --git a/src/ocean/Ocean.ts b/src/ocean/Ocean.ts index c06d592..5045f1e 100644 --- a/src/ocean/Ocean.ts +++ b/src/ocean/Ocean.ts @@ -245,11 +245,10 @@ export default class Ocean { const event: ContractEvent = EventListener.subscribe( accessService.serviceAgreementContract.contractName, accessService.serviceAgreementContract.events[0].name, { - serviceAgreementId, + serviceAgreementId: `0x${serviceAgreementId}`, }) event.listenOnce(async (data) => { - const sa: ServiceAgreement = new ServiceAgreement(data.returnValues.serviceAgreementId) await sa.payAsset( d.getId(), @@ -263,7 +262,6 @@ export default class Ocean { serviceAgreementId, serviceAgreementSignature, } - } catch (err) { Logger.error("Signing ServiceAgreement failed!", err) } @@ -296,24 +294,26 @@ export default class Ocean { const accessEvent: ContractEvent = EventListener.subscribe( accessService.conditions[1].contractName, accessService.conditions[1].events[1].name, {}) + const filesPromise = new Promise((resolve) => { + accessEvent.listenOnce(async () => { + Logger.log("Awesome; got a AccessGranted Event. Let's download the asset files.") + const contentUrls = await SecretStoreProvider + .getSecretStore() + .decryptDocument(d.getId(), metadataService.metadata.base.contentUrls[0]) + const serviceUrl: string = accessService.serviceEndpoint + Logger.log("Consuming asset files using service url: ", serviceUrl) + const files = [] - accessEvent.listenOnce(async () => { - Logger.log("Awesome; got a AccessGranted Event. Let's download the asset files.") - const contentUrls = await SecretStoreProvider - .getSecretStore() - .decryptDocument(d.getId(), metadataService.metadata.base.contentUrls[0]) - const serviceUrl: string = accessService.serviceEndpoint - Logger.log("Consuming asset files using service url: ", serviceUrl) - const files = [] + for (const cUrl of contentUrls) { + let url: string = serviceUrl + `?url=${cUrl}` + url = url + `&serviceAgreementId=${serviceAgreementId}` + url = url + `&consumerAddress=${consumer.getId()}` + files.push(url) + } - for (const cUrl of contentUrls) { - let url: string = serviceUrl + `?url=${cUrl}` - url = url + `&serviceAgreementId=${serviceAgreementId}` - url = url + `&consumerAddress=${consumer.getId()}` - files.push(url) - } - - cb(files) + cb(files) + resolve(files) + }) }) await BrizoProvider @@ -324,6 +324,8 @@ export default class Ocean { serviceDefinitionId, serviceAgreementSignature, consumer.getId()) + + await filesPromise } /** diff --git a/src/ocean/ServiceAgreements/ServiceAgreementTemplate.ts b/src/ocean/ServiceAgreements/ServiceAgreementTemplate.ts index ae6423d..9621ae8 100644 --- a/src/ocean/ServiceAgreements/ServiceAgreementTemplate.ts +++ b/src/ocean/ServiceAgreements/ServiceAgreementTemplate.ts @@ -58,15 +58,21 @@ export default class ServiceAgreementTemplate extends OceanBase { return false } - const receipt = await serviceAgreement - .setupAgreementTemplate( - this.template.id, - await this.getMethodReflections(), - dependencyMatrix, - Web3Provider.getWeb3().utils.fromAscii(this.template.templateName), - fulfillmentIndices, - this.template.fulfillmentOperator, - templateOwnerAddress) + let receipt + try { + receipt = await serviceAgreement + .setupAgreementTemplate( + this.template.id, + await this.getMethodReflections(), + dependencyMatrix, + Web3Provider.getWeb3().utils.fromAscii(this.template.templateName), + fulfillmentIndices, + this.template.fulfillmentOperator, + templateOwnerAddress) + } catch (e) { + Logger.error(e) + throw new Error(`Is not possible to setup the agreement template`) + } const {serviceTemplateId, provider} = receipt.events.SetupAgreementTemplate.returnValues diff --git a/src/utils/WebServiceConnector.ts b/src/utils/WebServiceConnector.ts index ae73194..3566e0c 100644 --- a/src/utils/WebServiceConnector.ts +++ b/src/utils/WebServiceConnector.ts @@ -1,11 +1,12 @@ import fetch, { BodyInit, RequestInit, Response } from "node-fetch" +import Logger from "./Logger" /** * Provides a common interface to web services. */ export default class WebServiceConnector { - public async post(url: string, payload: BodyInit): Promise { + public post(url: string, payload: BodyInit): Promise { return this.fetch(url, { method: "POST", body: payload, @@ -15,7 +16,7 @@ export default class WebServiceConnector { }) } - public async get(url: string): Promise { + public get(url: string): Promise { return this.fetch(url, { method: "GET", headers: { @@ -24,7 +25,7 @@ export default class WebServiceConnector { }) } - public async put(url: string, payload: BodyInit): Promise { + public put(url: string, payload: BodyInit): Promise { return this.fetch(url, { method: "PUT", body: payload, @@ -35,6 +36,12 @@ export default class WebServiceConnector { } private async fetch(url: string, opts: RequestInit): Promise { - return fetch(url, opts) + const result = await fetch(url, opts) + if (!result.ok) { + Logger.error(`Error requesting [${opts.method}] ${url}`) + Logger.error(`Response message: \n${await result.text()}`) + throw result + } + return result } }