diff --git a/src/keeper/Auth.ts b/src/keeper/Auth.ts index 5e1eaf7..fa1161b 100644 --- a/src/keeper/Auth.ts +++ b/src/keeper/Auth.ts @@ -1,4 +1,3 @@ -import BigNumber from "bignumber.js" import {Receipt} from "web3-utils" import Asset from "../models/Asset" import Config from "../models/Config" @@ -7,8 +6,8 @@ import Web3Helper from "./Web3Helper" export default class OceanAuth extends ContractBaseWrapper { - public static async getInstance(config: Config, web3Helper: Web3Helper) { - const auth = new OceanAuth(config, "OceanAuth", web3Helper) + public static async getInstance(config: Config, web3Helper: Web3Helper): Promise { + const auth: OceanAuth = new OceanAuth(config, "OceanAuth", web3Helper) await auth.init() return auth } @@ -16,7 +15,7 @@ export default class OceanAuth extends ContractBaseWrapper { public async getOrderStatus(orderId: string): Promise { return this.contract.methods.statusOfAccessRequest(orderId) .call() - .then((status: BigNumber) => status.toNumber()) + .then((status: string) => parseInt(status, 10)) } public async cancelAccessRequest(orderId: string, senderAddress: string): Promise { diff --git a/src/keeper/ContractHandler.ts b/src/keeper/ContractHandler.ts index 9357833..bcca578 100644 --- a/src/keeper/ContractHandler.ts +++ b/src/keeper/ContractHandler.ts @@ -53,7 +53,7 @@ export default class ContractHandler { try { const artifact = require(`@oceanprotocol/keeper-contracts/artifacts/${what}.${where}`) // Logger.log('Loaded artifact', artifact) - Logger.log("Getting instance of", what, "from", where, "at", artifact.address) + // Logger.log("Getting instance of", what, "from", where, "at", artifact.address) const web3 = web3Helper.getWeb3() const contract = new web3.eth.Contract(artifact.abi, artifact.address) Logger.log("Loaded", what, "from", where) diff --git a/src/keeper/ContractWrapperBase.ts b/src/keeper/ContractWrapperBase.ts index e7aa9d4..3a559bc 100644 --- a/src/keeper/ContractWrapperBase.ts +++ b/src/keeper/ContractWrapperBase.ts @@ -1,3 +1,4 @@ +import Event from "web3" import Contract from "web3-eth-contract" import Config from "../models/Config" import Logger from "../utils/Logger" @@ -6,6 +7,10 @@ import Web3Helper from "./Web3Helper" export default class ContractWrapperBase { + public static async getInstance(config: Config, web3Helper: Web3Helper): Promise { + // stub + } + protected contract: Contract = null protected config: Config protected web3Helper: Web3Helper @@ -23,38 +28,28 @@ export default class ContractWrapperBase { if (!this.contract.events[eventName]) { throw new Error(`Event ${eventName} not found on contract ${this.contractName}`) } - this.contract.once(eventName, options, (error: any, eventData: any) => { - if (error) { - Logger.log(`Error in keeper ${eventName} event: `, error) - return reject(error) - } - resolve(eventData) + this.contract.events[eventName](options, (err) => { + reject(err) }) - }) - } - - public async getEventData(eventName: any, options: any): Promise { - return new Promise((resolve, reject) => { - if (!this.contract.events[eventName]) { - throw new Error(`Event ${eventName} not found on contract ${this.contractName}`) - } - this.contract.events[eventName](options) - .on("data", (eventData: any[]) => { - Logger.log(eventData) + .on("data", (eventData: any) => { resolve(eventData) }) - .on("error", (error) => { - return reject(error) - }) }) } - public async init() { - this.contract = await ContractHandler.get(this.contractName, this.web3Helper) + public async getEventData(eventName: any, options: any): Promise { + if (!this.contract.events[eventName]) { + throw new Error(`Event ${eventName} not found on contract ${this.contractName}`) + } + return this.contract.getPastEvents(eventName, options) } public getAddress() { return this.contract.options.address } + protected async init() { + this.contract = await ContractHandler.get(this.contractName, this.web3Helper) + } + } diff --git a/src/keeper/Market.ts b/src/keeper/Market.ts index 6564efe..81a0772 100644 --- a/src/keeper/Market.ts +++ b/src/keeper/Market.ts @@ -9,9 +9,8 @@ import Web3Helper from "./Web3Helper" export default class OceanMarket extends ContractWrapperBase { - public static async getInstance(config: Config, web3Helper: Web3Helper) { - - const market = new OceanMarket(config, "OceanMarket", web3Helper) + public static async getInstance(config: Config, web3Helper: Web3Helper): Promise { + const market: OceanMarket = new OceanMarket(config, "OceanMarket", web3Helper) await market.init() return market } diff --git a/src/keeper/Token.ts b/src/keeper/Token.ts index a25c20e..d9f6b39 100644 --- a/src/keeper/Token.ts +++ b/src/keeper/Token.ts @@ -6,8 +6,8 @@ import Web3Helper from "./Web3Helper" export default class OceanToken extends ContractBaseWrapper { - public static async getInstance(config: Config, web3Helper: Web3Helper) { - const token = new OceanToken(config, "OceanToken", web3Helper) + public static async getInstance(config: Config, web3Helper: Web3Helper): Promise { + const token: OceanToken = new OceanToken(config, "OceanToken", web3Helper) await token.init() return token } diff --git a/src/ocean/Account.ts b/src/ocean/Account.ts index 3b6b289..9c300bd 100644 --- a/src/ocean/Account.ts +++ b/src/ocean/Account.ts @@ -1,14 +1,8 @@ import BigNumber from "bignumber.js" import Keeper from "../keeper/Keeper" -import Web3Helper from "../keeper/Web3Helper" +import OceanBase from "./OceanBase" -export default class Account { - - private keeper: Keeper - - constructor(keeper: Keeper) { - this.keeper = keeper - } +export default class Account extends OceanBase { public async getTokenBalance(accountAddress: string): Promise { return this.keeper.token.balanceOf(accountAddress) diff --git a/src/ocean/Asset.ts b/src/ocean/Asset.ts index 9cead00..bf36c06 100644 --- a/src/ocean/Asset.ts +++ b/src/ocean/Asset.ts @@ -1,13 +1,8 @@ import Keeper from "../keeper/Keeper" import Logger from "../utils/Logger" +import OceanBase from "./OceanBase" -export default class Asset { - - private keeper: Keeper - - constructor(keeper: Keeper) { - this.keeper = keeper - } +export default class Asset extends OceanBase { public async isAssetActive(assetId: string): Promise { const {market} = this.keeper diff --git a/src/ocean/OceanBase.ts b/src/ocean/OceanBase.ts new file mode 100644 index 0000000..e8fd3eb --- /dev/null +++ b/src/ocean/OceanBase.ts @@ -0,0 +1,10 @@ +import Keeper from "../keeper/Keeper" + +export default class OceanBase { + + protected keeper: Keeper + + constructor(keeper: Keeper) { + this.keeper = keeper + } +} \ No newline at end of file diff --git a/src/ocean/Order.ts b/src/ocean/Order.ts index 147beb4..eb3d111 100644 --- a/src/ocean/Order.ts +++ b/src/ocean/Order.ts @@ -2,17 +2,16 @@ import * as EthCrypto from "eth-crypto" import EthEcies from "eth-ecies" import * as EthjsUtil from "ethereumjs-util" import JWT from "jsonwebtoken" -import Keeper from "../keeper/Keeper" import Asset from "../models/Asset" import OrderModel from "../models/Order" import Logger from "../utils/Logger" +import OceanBase from "./OceanBase" declare var fetch -export default class Order { +export default class Order extends OceanBase { private static create(asset: Asset, args, key): OrderModel { - Logger.log("keeper AccessConsentRequested event received on asset: ", asset.assetId, "\nevent:", args) const accessId = args._id Logger.log("got new access request id: ", accessId) return { @@ -25,39 +24,39 @@ export default class Order { } as OrderModel } - private keeper: Keeper - - constructor(keeper: Keeper) { - this.keeper = keeper - } - public async getOrdersByConsumer(consumerAddress: string) { const {auth, market} = this.keeper - const accessConsentRequestedData = await auth.getEventData("AccessConsentRequested", { - filter: { - _consumer: consumerAddress, - }, - fromBlock: 0, - }) + Logger.log("Getting orders") - Logger.log("wai", accessConsentRequestedData) + const accessConsentRequestedData = await auth.getEventData( + "AccessConsentRequested", { + filter: { + _consumer: consumerAddress, + }, + fromBlock: 0, + toBlock: "latest", + }) const orders = await Promise.all( accessConsentRequestedData - .filter((event: any) => (event.args._consumer === consumerAddress)) + .filter((event: any) => { + return event.returnValues._consumer === consumerAddress + }) .map(async (event: any) => ({ - ...event.args, - timeout: event.args._timeout.toNumber(), - status: await auth.getOrderStatus(event.args._id), - paid: await market.verifyOrderPayment(event.args._id), + ...event.returnValues, + timeout: parseInt(event.returnValues._timeout, 10), + status: await auth.getOrderStatus(event.returnValues._id), + paid: await market.verifyOrderPayment(event.returnValues._id), key: null, } as Order ), ), ) - Logger.log("Got orders: ", orders) + // Logger.log("Got orders:", JSON.stringify(orders, null, 2)) + Logger.log(`Got ${Object.keys(orders).length} orders`) + return orders } @@ -78,49 +77,53 @@ export default class Order { // Allow market contract to transfer funds on the consumer"s behalf await token.approve(market.getAddress(), price, buyerAddress) } catch (err) { - Logger.log("token approve", err) + Logger.error("token.approve failed", err) } + let order: OrderModel try { // Submit the access request - await auth.initiateAccessRequest(asset, publicKey, timeout, buyerAddress) + const initiateAccessRequestReceipt = await auth.initiateAccessRequest(asset, + publicKey, timeout, buyerAddress) + + const args = initiateAccessRequestReceipt.events.AccessConsentRequested.returnValues + Logger.log("keeper AccessConsentRequested event received on asset: ", asset.assetId, "\nevent:", args) + order = Order.create(asset, args, key) + Logger.log("Created order", order) + } catch (err) { - Logger.log("initiateAccessRequest", err) + Logger.error("auth.initiateAccessRequest failed", err) } - let order: OrderModel - const finalOrder: OrderModel = await auth.listenToEventOnce( - "AccessConsentRequested", { - filter: { - _resourceId: asset.assetId, - _consumer: buyerAddress, - }, - }) - .then((accessConsentRequestedResult) => { - order = Order.create(asset, accessConsentRequestedResult.args, key) - - return auth.listenToEventOnce("AccessRequestCommitted", { + return order + if (false) { + // todo: AccessRequestCommitted event is not emitted in this flow + const finalOrder: OrderModel = await auth.listenToEventOnce( + "AccessRequestCommitted", { filter: { _id: order.id, }, }) - }) - .then((accessRequestCommittedResult) => { - return this.payAsset(asset, accessRequestCommittedResult.args, order, buyerAddress) - }) - .then(() => { - return auth.listenToEventOnce("EncryptedTokenPublished", { - filter: { - _id: order.id, - }, - }) - }) - .then((result) => { - return this.finalizePurchaseAsset( - result, order, key, buyerAddress, - ) - }) + .then((accessRequestCommittedResult) => { + Logger.log("Got AccessRequestCommitted Event") - return finalOrder + return this.payAsset(asset, accessRequestCommittedResult.returnValues, order, buyerAddress) + }) + .then((payAssetReceipt) => { + return auth.listenToEventOnce( + "EncryptedTokenPublished", { + filter: { + _id: order.id, + }, + }) + }) + .then((result) => { + Logger.log("Got EncryptedTokenPublished Event") + + return this.finalizePurchaseAsset( + result, order, key, buyerAddress, + ) + }) + } } private async payAsset(asset: Asset, args, order, buyerAddress) { @@ -134,8 +137,6 @@ export default class Order { private async finalizePurchaseAsset(args, order, key, buyerAddress): Promise { const {auth, web3Helper} = this.keeper - // Logger.log('keeper EncryptedTokenPublished event received: ', order.id, eventResult.args) - const encryptedAccessToken = await auth.getEncryptedAccessToken(args._id, buyerAddress) // grab the access token from acl contract