mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
migrated to typescript
This commit is contained in:
parent
2e18f8e411
commit
20c10a8ef5
4251
package-lock.json
generated
4251
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
@ -5,8 +5,8 @@
|
|||||||
"main": "dist/squid.js",
|
"main": "dist/squid.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "eslint ./src",
|
"test": "eslint ./src",
|
||||||
"start": "babel ./src/ --watch --out-dir ./dist/",
|
"start": "tsc -w",
|
||||||
"build": "babel ./src/ --out-dir ./dist/",
|
"build": "tsc",
|
||||||
"release": "./node_modules/release-it/bin/release-it.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release": "./node_modules/release-it/bin/release-it.js --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"release-minor": "./node_modules/release-it/bin/release-it.js minor --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release-minor": "./node_modules/release-it/bin/release-it.js minor --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
"release-major": "./node_modules/release-it/bin/release-it.js major --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
"release-major": "./node_modules/release-it/bin/release-it.js major --src.tagName='v%s' --github.release --npm.publish --non-interactive",
|
||||||
@ -24,27 +24,16 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/oceanprotocol/squid-js#readme",
|
"homepage": "https://github.com/oceanprotocol/squid-js#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.0.0",
|
|
||||||
"@oceanprotocol/keeper-contracts": "^0.2.0",
|
"@oceanprotocol/keeper-contracts": "^0.2.0",
|
||||||
|
"bn.js": "^4.11.8",
|
||||||
"truffle-contract": "^3.0.6",
|
"truffle-contract": "^3.0.6",
|
||||||
"web3": "0.20.6"
|
"web3": "0.20.6",
|
||||||
},
|
"whatwg-fetch": "^3.0.0"
|
||||||
"devDependencies": {
|
|
||||||
"@babel/cli": "^7.0.0",
|
|
||||||
"@babel/core": "^7.0.1",
|
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-runtime": "^7.0.0",
|
|
||||||
"@babel/preset-env": "^7.0.0",
|
|
||||||
"eslint": "^5.5.0",
|
|
||||||
"eslint-config-oceanprotocol": "^1.2.0",
|
|
||||||
"eslint-config-standard": "^12.0.0",
|
|
||||||
"eslint-plugin-import": "^2.14.0",
|
|
||||||
"eslint-plugin-node": "^7.0.1",
|
|
||||||
"eslint-plugin-promise": "^4.0.0",
|
|
||||||
"eslint-plugin-security": "^1.4.0",
|
|
||||||
"eslint-plugin-standard": "^4.0.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8 <10"
|
"node": ">=8 <10"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/web3": "^1.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/* global fetch */
|
|
||||||
import Logger from '../utils/logger'
|
|
||||||
|
|
||||||
export default class OceanAgent {
|
|
||||||
constructor(connectionUrl) {
|
|
||||||
this.assetsUrl = connectionUrl + '/assets'
|
|
||||||
|
|
||||||
Logger.warn('OceanAgent is deprecated use the Ocean object from squid instead')
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetsMetadata() {
|
|
||||||
return fetch(this.assetsUrl + '/metadata', { method: 'GET' })
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(data => JSON.parse(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
publishDataAsset(asset) {
|
|
||||||
return fetch(this.assetsUrl + '/metadata',
|
|
||||||
{
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify(asset),
|
|
||||||
headers: { 'Content-type': 'application/json' }
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
Logger.log('Success:', response)
|
|
||||||
if (response.ok) {
|
|
||||||
Logger.log('Success:', response)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
Logger.log('Failed: ', response.status, response.statusText)
|
|
||||||
return false
|
|
||||||
// throw new Error(response.statusText ? response.statusText : `publish asset failed with status ${response.status}`)
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
Logger.log(`Publish asset to ocean database could not be completed: ${error.message()}`)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,181 +0,0 @@
|
|||||||
import Web3 from 'web3'
|
|
||||||
import ContractLoader from '../keeper/contractLoader'
|
|
||||||
import Logger from '../utils/logger'
|
|
||||||
|
|
||||||
const DEFAULT_GAS = 300000
|
|
||||||
|
|
||||||
export default class OceanKeeper {
|
|
||||||
constructor(uri, network) {
|
|
||||||
const web3Provider = new Web3.providers.HttpProvider(uri)
|
|
||||||
this.web3 = new Web3(web3Provider)
|
|
||||||
this.defaultGas = DEFAULT_GAS
|
|
||||||
this.network = network || 'development'
|
|
||||||
|
|
||||||
Logger.warn('OceanKeeper is deprecated use the Ocean object from squid instead')
|
|
||||||
}
|
|
||||||
|
|
||||||
async initContracts() {
|
|
||||||
this.oceanToken = await ContractLoader.load('OceanToken', this.network, this.web3)
|
|
||||||
this.oceanMarket = await ContractLoader.load('OceanMarket', this.network, this.web3)
|
|
||||||
this.oceanAuth = await ContractLoader.load('OceanAuth', this.network, this.web3)
|
|
||||||
|
|
||||||
return {
|
|
||||||
oceanToken: this.oceanToken,
|
|
||||||
oceanMarket: this.oceanMarket,
|
|
||||||
oceanAuth: this.oceanAuth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// web3 wrappers
|
|
||||||
sign(accountAddress, message) {
|
|
||||||
return this.web3.eth.sign(accountAddress, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
getMessageHash(message) {
|
|
||||||
return this.web3.sha3(`\x19Ethereum Signed Message:\n${message.length}${message}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// call functions (costs no gas)
|
|
||||||
checkAsset(assetId) {
|
|
||||||
return this.oceanMarket.checkAsset(assetId)
|
|
||||||
}
|
|
||||||
|
|
||||||
getBalance(accountAddress) {
|
|
||||||
return this.oceanToken.balanceOf.call(accountAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetPrice(assetId) {
|
|
||||||
return this.oceanMarket.getAssetPrice(assetId).then((price) => price.toNumber())
|
|
||||||
}
|
|
||||||
|
|
||||||
getOrderStatus(orderId) {
|
|
||||||
return this.oceanAuth.statusOfAccessRequest(orderId)
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyOrderPayment(orderId) {
|
|
||||||
return this.oceanMarket.verifyPaymentReceived(orderId)
|
|
||||||
}
|
|
||||||
|
|
||||||
getEncryptedAccessToken(orderId, senderAddress) {
|
|
||||||
return this.oceanAuth.getEncryptedAccessToken(orderId, { from: senderAddress })
|
|
||||||
}
|
|
||||||
|
|
||||||
async getConsumerOrders(consumerAddress) {
|
|
||||||
let accessConsentEvent = this.oceanAuth.AccessConsentRequested({ _consumer: consumerAddress }, {
|
|
||||||
fromBlock: 0,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
|
|
||||||
let _resolve = null
|
|
||||||
let _reject = null
|
|
||||||
const promise = new Promise((resolve, reject) => {
|
|
||||||
_resolve = resolve
|
|
||||||
_reject = reject
|
|
||||||
})
|
|
||||||
|
|
||||||
const getEvents = () => {
|
|
||||||
accessConsentEvent.get((error, logs) => {
|
|
||||||
if (error) {
|
|
||||||
_reject(error)
|
|
||||||
throw new Error(error)
|
|
||||||
} else {
|
|
||||||
_resolve(logs)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
const events = await getEvents().then((events) => events)
|
|
||||||
// let orders = await this.buildOrdersFromEvents(events, consumerAddress).then((result) => result)
|
|
||||||
let orders = events
|
|
||||||
.filter(obj => (obj.args._consumer === consumerAddress))
|
|
||||||
.map(async (event) => ({
|
|
||||||
...event.args,
|
|
||||||
timeout: event.args._timeout.toNumber(),
|
|
||||||
status: await this.getOrderStatus(event.args._id).then((status) => status.toNumber()),
|
|
||||||
paid: await this.verifyOrderPayment(event.args._id).then((received) => received),
|
|
||||||
key: null
|
|
||||||
}))
|
|
||||||
Logger.debug('got orders: ', orders)
|
|
||||||
return orders
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transactions with gas cost
|
|
||||||
requestTokens(senderAddress, numTokens) {
|
|
||||||
return this.oceanMarket.requestTokens(numTokens, { from: senderAddress })
|
|
||||||
}
|
|
||||||
|
|
||||||
async registerDataAsset(name, description, price, publisherAddress) {
|
|
||||||
const assetId = await this.oceanMarket.generateId(name + description)
|
|
||||||
const result = await this.oceanMarket.register(
|
|
||||||
assetId,
|
|
||||||
price,
|
|
||||||
{ from: publisherAddress, gas: this.defaultGas }
|
|
||||||
)
|
|
||||||
Logger.log('registered: ', result)
|
|
||||||
return assetId
|
|
||||||
}
|
|
||||||
|
|
||||||
async sendPayment(assetId, order, publisherAddress, senderAddress) {
|
|
||||||
let assetPrice = await this.oceanMarket.getAssetPrice(assetId).then((price) => price.toNumber())
|
|
||||||
this.oceanMarket.sendPayment(order.id, publisherAddress, assetPrice, order.timeout, {
|
|
||||||
from: senderAddress,
|
|
||||||
gas: 2000000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelAccessRequest(orderId, senderAddress) {
|
|
||||||
return this.oceanAuth.cancelAccessRequest(orderId, { from: senderAddress })
|
|
||||||
}
|
|
||||||
|
|
||||||
orchestrateResourcePurchase(
|
|
||||||
assetId, publisherId, price, privateKey, publicKey, timeout, senderAddress,
|
|
||||||
initialRequestEventHandler, accessCommittedEventHandler, tokenPublishedEventHandler) {
|
|
||||||
const { oceanToken, oceanMarket, oceanAuth } = this
|
|
||||||
// Allow OceanMarket contract to transfer funds on the consumer's behalf
|
|
||||||
oceanToken.approve(oceanMarket.address, price, { from: senderAddress, gas: 2000000 })
|
|
||||||
// Submit the access request
|
|
||||||
oceanAuth.initiateAccessRequest(
|
|
||||||
assetId, publisherId, publicKey,
|
|
||||||
timeout, { from: senderAddress, gas: 1000000 }
|
|
||||||
)
|
|
||||||
|
|
||||||
const resourceFilter = { _resourceId: assetId, _consumer: senderAddress }
|
|
||||||
const initRequestEvent = oceanAuth.AccessConsentRequested(resourceFilter)
|
|
||||||
let order = {}
|
|
||||||
this._listenOnce(
|
|
||||||
initRequestEvent,
|
|
||||||
'AccessConsentRequested',
|
|
||||||
(result, error) => {
|
|
||||||
order = initialRequestEventHandler(result, error)
|
|
||||||
const requestIdFilter = { _id: order.id }
|
|
||||||
const accessCommittedEvent = oceanAuth.AccessRequestCommitted(requestIdFilter)
|
|
||||||
const tokenPublishedEvent = oceanAuth.EncryptedTokenPublished(requestIdFilter)
|
|
||||||
this._listenOnce(
|
|
||||||
accessCommittedEvent,
|
|
||||||
'AccessRequestCommitted',
|
|
||||||
(result, error) => {
|
|
||||||
accessCommittedEventHandler(result, order, error)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
this._listenOnce(
|
|
||||||
tokenPublishedEvent,
|
|
||||||
'EncryptedTokenPublished',
|
|
||||||
(result, error) => {
|
|
||||||
tokenPublishedEventHandler(result, order, error)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
return order
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions (private)
|
|
||||||
_listenOnce(event, eventName, callback) {
|
|
||||||
event.watch((error, result) => { // eslint-disable-line security/detect-non-literal-fs-filename
|
|
||||||
event.stopWatching()
|
|
||||||
if (error) {
|
|
||||||
Logger.log(`Error in keeper ${eventName} event: `, error)
|
|
||||||
}
|
|
||||||
callback(result, error)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import ContractLoader from './contractLoader'
|
|
||||||
import KeeperBase from './keeper-base'
|
|
||||||
|
|
||||||
export default class OceanAuth extends KeeperBase {
|
|
||||||
constructor(web3Helper) {
|
|
||||||
super(web3Helper)
|
|
||||||
|
|
||||||
return (async () => {
|
|
||||||
this.contract = await ContractLoader.load('OceanAuth', this._web3Helper)
|
|
||||||
return this
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelAccessRequest(orderId, senderAddress) {
|
|
||||||
return this.contract.cancelAccessRequest(orderId, { from: senderAddress })
|
|
||||||
}
|
|
||||||
|
|
||||||
getOrderStatus(orderId) {
|
|
||||||
return this.contract.statusOfAccessRequest(orderId)
|
|
||||||
}
|
|
||||||
|
|
||||||
getEncryptedAccessToken(orderId, senderAddress) {
|
|
||||||
return this.contract.getEncryptedAccessToken(orderId, { from: senderAddress })
|
|
||||||
}
|
|
||||||
}
|
|
30
src/keeper/auth.ts
Normal file
30
src/keeper/auth.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import ContractLoader from './contractLoader'
|
||||||
|
import KeeperBase from './keeper-base'
|
||||||
|
import Web3Helper from "../utils/Web3Helper";
|
||||||
|
import Config from "../utils/config";
|
||||||
|
|
||||||
|
export default class OceanAuth extends KeeperBase {
|
||||||
|
|
||||||
|
private constructor(config: Config, web3Helper: Web3Helper) {
|
||||||
|
super(config, web3Helper)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getInstance(config: Config, web3Helper) {
|
||||||
|
const auth = new OceanAuth(config, web3Helper);
|
||||||
|
|
||||||
|
auth.contract = await ContractLoader.load('OceanAuth', auth._web3Helper)
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelAccessRequest(orderId: string, senderAddress: string) {
|
||||||
|
return this.contract.cancelAccessRequest(orderId, {from: senderAddress})
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrderStatus(orderId: string) {
|
||||||
|
return this.contract.statusOfAccessRequest(orderId)
|
||||||
|
}
|
||||||
|
|
||||||
|
getEncryptedAccessToken(orderId: string, senderAddress: string) {
|
||||||
|
return this.contract.getEncryptedAccessToken(orderId, {from: senderAddress})
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
import TruffleContract from 'truffle-contract'
|
import * as TruffleContract from 'truffle-contract'
|
||||||
import Logger from '../utils/logger'
|
import Logger from '../utils/logger'
|
||||||
|
import Web3Helper from '../utils/Web3Helper'
|
||||||
|
|
||||||
const contracts = []
|
const contracts: Map<string, object> = new Map<string, object>()
|
||||||
|
|
||||||
export default class ContractLoader {
|
export default class ContractLoader {
|
||||||
static async _doLoad(what, web3Helper) {
|
static async _doLoad(what: string, web3Helper: Web3Helper): Promise<object> {
|
||||||
const where = (await web3Helper.getNetworkName()).toLowerCase()
|
const where = (await web3Helper.getNetworkName()).toLowerCase()
|
||||||
Logger.log('Loading', what, 'from', where)
|
Logger.log('Loading', what, 'from', where)
|
||||||
try {
|
try {
|
||||||
@ -15,14 +16,14 @@ export default class ContractLoader {
|
|||||||
const contract = TruffleContract(artifact)
|
const contract = TruffleContract(artifact)
|
||||||
Logger.log('Getting instance of', what, 'from', where, 'at', artifact.address)
|
Logger.log('Getting instance of', what, 'from', where, 'at', artifact.address)
|
||||||
contract.setProvider(web3Helper.web3.currentProvider)
|
contract.setProvider(web3Helper.web3.currentProvider)
|
||||||
contracts[what] = await contract.at(artifact.address)
|
contracts.set(what, await contract.at(artifact.address))
|
||||||
return contracts[what]
|
return contracts.get(what)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error('Failed to load', what, 'from', where)
|
Logger.error('Failed to load', what, 'from', where)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async load(what, where, provider) {
|
static async load(what: string, web3Helper: Web3Helper) {
|
||||||
return contracts[what] || ContractLoader._doLoad(what, where, provider)
|
return contracts.get(what) || await ContractLoader._doLoad(what, web3Helper)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +0,0 @@
|
|||||||
export default class KeeperBase {
|
|
||||||
constructor(web3Helper) {
|
|
||||||
this._web3Helper = web3Helper
|
|
||||||
this.contract = null
|
|
||||||
}
|
|
||||||
}
|
|
14
src/keeper/keeper-base.ts
Normal file
14
src/keeper/keeper-base.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import Web3Helper from '../utils/Web3Helper'
|
||||||
|
import Config from "../utils/config";
|
||||||
|
|
||||||
|
export default class KeeperBase {
|
||||||
|
|
||||||
|
protected _config: Config
|
||||||
|
protected _web3Helper: Web3Helper;
|
||||||
|
public contract: any = null;
|
||||||
|
|
||||||
|
constructor(config: Config, web3Helper: Web3Helper) {
|
||||||
|
this._config = config;
|
||||||
|
this._web3Helper = web3Helper
|
||||||
|
}
|
||||||
|
}
|
@ -1,53 +0,0 @@
|
|||||||
import ContractLoader from './contractLoader'
|
|
||||||
import KeeperBase from './keeper-base'
|
|
||||||
|
|
||||||
import Logger from '../utils/logger'
|
|
||||||
|
|
||||||
export default class OceanMarket extends KeeperBase {
|
|
||||||
constructor(web3Helper) {
|
|
||||||
super(web3Helper)
|
|
||||||
|
|
||||||
return (async () => {
|
|
||||||
this.contract = await ContractLoader.load('OceanMarket', this._web3Helper)
|
|
||||||
return this
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
|
|
||||||
// call functions (costs no gas)
|
|
||||||
checkAsset(assetId) {
|
|
||||||
return this.contract.checkAsset(assetId)
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyOrderPayment(orderId) {
|
|
||||||
return this.contract.verifyPaymentReceived(orderId)
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetPrice(assetId) {
|
|
||||||
return this.contract.getAssetPrice(assetId)
|
|
||||||
.then((price) => price.toNumber())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transactions with gas cost
|
|
||||||
requestTokens(amount, address) {
|
|
||||||
return this.contract.requestTokens(amount, { from: address })
|
|
||||||
}
|
|
||||||
|
|
||||||
async registerAsset(name, description, price, publisherAddress) {
|
|
||||||
const assetId = await this.contract.generateId(name + description)
|
|
||||||
const result = await this.contract.register(
|
|
||||||
assetId,
|
|
||||||
price,
|
|
||||||
{ from: publisherAddress, gas: this.defaultGas }
|
|
||||||
)
|
|
||||||
Logger.log('registered: ', result)
|
|
||||||
return assetId
|
|
||||||
}
|
|
||||||
|
|
||||||
async payAsset(assetId, order, publisherAddress, senderAddress) {
|
|
||||||
let assetPrice = await this.contract.getAssetPrice(assetId).then((price) => price.toNumber())
|
|
||||||
this.contract.sendPayment(order.id, publisherAddress, assetPrice, order.timeout, {
|
|
||||||
from: senderAddress,
|
|
||||||
gas: 2000000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
61
src/keeper/market.ts
Normal file
61
src/keeper/market.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import ContractLoader from './contractLoader'
|
||||||
|
import KeeperBase from './keeper-base'
|
||||||
|
import Logger from '../utils/logger'
|
||||||
|
import Web3Helper from "../utils/Web3Helper";
|
||||||
|
import BigNumber from "bignumber.js";
|
||||||
|
import Config from "../utils/config";
|
||||||
|
|
||||||
|
export default class OceanMarket extends KeeperBase {
|
||||||
|
|
||||||
|
private constructor(config: Config, web3Helper: Web3Helper) {
|
||||||
|
super(config, web3Helper)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getInstance(config: Config, web3Helper: Web3Helper) {
|
||||||
|
|
||||||
|
const market = new OceanMarket(config, web3Helper);
|
||||||
|
market.contract = await ContractLoader.load('OceanMarket', market._web3Helper)
|
||||||
|
return market;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call functions (costs no gas)
|
||||||
|
checkAsset(assetId: string) {
|
||||||
|
return this.contract.checkAsset(assetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyOrderPayment(orderId: string): boolean {
|
||||||
|
return this.contract.verifyPaymentReceived(orderId)
|
||||||
|
}
|
||||||
|
|
||||||
|
getAssetPrice(assetId: string) {
|
||||||
|
return this.contract.getAssetPrice(assetId)
|
||||||
|
.then((price: BigNumber) => price.toNumber())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transactions with gas cost
|
||||||
|
requestTokens(amount: number, address: string) {
|
||||||
|
return this.contract.requestTokens(amount, {from: address})
|
||||||
|
}
|
||||||
|
|
||||||
|
async registerAsset(name: string, description: string, price: number, publisherAddress: string) {
|
||||||
|
const assetId = await this.contract.generateId(name + description)
|
||||||
|
const result = await this.contract.register(
|
||||||
|
assetId,
|
||||||
|
price, {
|
||||||
|
from: publisherAddress, gas:
|
||||||
|
this._config.defaultGas
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Logger.log('registered: ', result)
|
||||||
|
return assetId
|
||||||
|
}
|
||||||
|
|
||||||
|
async payAsset(assetId: string, order: any, publisherAddress: string, senderAddress: string) {
|
||||||
|
let assetPrice = await this.contract.getAssetPrice(assetId)
|
||||||
|
.then((price: BigNumber) => price.toNumber())
|
||||||
|
this.contract.sendPayment(order.id, publisherAddress, assetPrice, order.timeout, {
|
||||||
|
from: senderAddress,
|
||||||
|
gas: 2000000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
import ContractLoader from './contractLoader'
|
|
||||||
import KeeperBase from './keeper-base'
|
|
||||||
import Logger from '../utils/logger'
|
|
||||||
|
|
||||||
export default class OceanToken extends KeeperBase {
|
|
||||||
constructor(web3Helper) {
|
|
||||||
super(web3Helper)
|
|
||||||
|
|
||||||
return (async () => {
|
|
||||||
this.contract = await ContractLoader.load('OceanToken', this._web3Helper)
|
|
||||||
|
|
||||||
return this
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
|
|
||||||
getTokenBalance(accountAddress) {
|
|
||||||
return this.contract.balanceOf.call(accountAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
async getEthBalance(account) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Logger.log('getting balance for', account)
|
|
||||||
this._web3Helper.web3.eth.getBalance(account, 'latest', (err, balance) => {
|
|
||||||
if (err) return reject(err)
|
|
||||||
Logger.log('balance', balance)
|
|
||||||
resolve(balance)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
34
src/keeper/token.ts
Normal file
34
src/keeper/token.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import ContractLoader from './contractLoader'
|
||||||
|
import KeeperBase from './keeper-base'
|
||||||
|
import Logger from '../utils/logger'
|
||||||
|
import Web3Helper from "../utils/Web3Helper"
|
||||||
|
import Config from "../utils/config";
|
||||||
|
|
||||||
|
export default class OceanToken extends KeeperBase {
|
||||||
|
|
||||||
|
private constructor(config: Config, web3Helper: Web3Helper) {
|
||||||
|
super(config, web3Helper)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getInstance(config: Config, web3Helper: Web3Helper) {
|
||||||
|
const token = new OceanToken(config, web3Helper)
|
||||||
|
token.contract = await ContractLoader.load('OceanToken', token._web3Helper)
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTokenBalance(accountAddress: string) {
|
||||||
|
return this.contract.balanceOf.call(accountAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
async getEthBalance(account: string): Promise<number> {
|
||||||
|
return new Promise<number>((resolve, reject) => {
|
||||||
|
Logger.log('getting balance for', account)
|
||||||
|
this._web3Helper.web3.eth.getBalance(account, 'latest', (err: any, balance: number) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
Logger.log('balance', balance)
|
||||||
|
resolve(balance)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,15 @@
|
|||||||
/* global fetch */
|
|
||||||
import Logger from './utils/logger'
|
import Logger from './utils/logger'
|
||||||
|
import Config from "./utils/config";
|
||||||
|
|
||||||
|
declare var fetch
|
||||||
|
|
||||||
export default class MetaData {
|
export default class MetaData {
|
||||||
constructor(providerUri) {
|
|
||||||
|
private assetsUrl: string;
|
||||||
|
|
||||||
|
constructor(config: Config) {
|
||||||
|
const providerUri = config.providerUri || null
|
||||||
|
|
||||||
this.assetsUrl = providerUri + '/assets'
|
this.assetsUrl = providerUri + '/assets'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,14 +19,14 @@ export default class MetaData {
|
|||||||
.then(data => JSON.parse(data))
|
.then(data => JSON.parse(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
publishDataAsset(asset) {
|
publishDataAsset(asset: object) {
|
||||||
return fetch(this.assetsUrl + '/metadata',
|
return fetch(this.assetsUrl + '/metadata',
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(asset),
|
body: JSON.stringify(asset),
|
||||||
headers: { 'Content-type': 'application/json' }
|
headers: { 'Content-type': 'application/json' }
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then((response: any) => {
|
||||||
Logger.log('Success:', response)
|
Logger.log('Success:', response)
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
Logger.log('Success:', response)
|
Logger.log('Success:', response)
|
||||||
@ -29,8 +36,8 @@ export default class MetaData {
|
|||||||
return false
|
return false
|
||||||
// throw new Error(response.statusText ? response.statusText : `publish asset failed with status ${response.status}`)
|
// throw new Error(response.statusText ? response.statusText : `publish asset failed with status ${response.status}`)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error: Error) => {
|
||||||
Logger.log(`Publish asset to ocean database could not be completed: ${error.message()}`)
|
Logger.log(`Publish asset to ocean database could not be completed: ${error.message}`)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
@ -1,36 +1,43 @@
|
|||||||
import Web3 from 'web3'
|
|
||||||
import OceanMarket from './keeper/market'
|
import OceanMarket from './keeper/market'
|
||||||
import OceanAuth from './keeper/auth'
|
import OceanAuth from './keeper/auth'
|
||||||
import OceanToken from './keeper/token'
|
import OceanToken from './keeper/token'
|
||||||
import Logger from './utils/logger'
|
import Logger from './utils/logger'
|
||||||
import Web3Helper from './utils/Web3Helper'
|
import Web3Helper from './utils/Web3Helper'
|
||||||
import MetaData from './metadata'
|
import MetaData from './metadata'
|
||||||
|
import BigNumber = require("bn.js")
|
||||||
const DEFAULT_GAS = 300000
|
import Config from "./utils/config";
|
||||||
|
|
||||||
export default class Ocean {
|
export default class Ocean {
|
||||||
constructor(config) {
|
|
||||||
const web3Provider = config.web3Provider || new Web3.providers.HttpProvider(config.nodeUri)
|
|
||||||
this._web3 = new Web3(web3Provider)
|
|
||||||
this._defaultGas = config.gas || DEFAULT_GAS
|
|
||||||
this._providerUri = config.providerUri || null
|
|
||||||
|
|
||||||
this.helper = new Web3Helper(this._web3)
|
private _config: Config;
|
||||||
this.metadata = new MetaData(this._providerUri)
|
|
||||||
|
|
||||||
return (async () => {
|
public token: OceanToken;
|
||||||
this._network = config.network || (await this.helper.getNetworkName()).toLowerCase() || 'development'
|
public market: OceanMarket;
|
||||||
|
public auth: OceanAuth;
|
||||||
|
public helper: Web3Helper;
|
||||||
|
public metadata: MetaData;
|
||||||
|
|
||||||
this.market = await new OceanMarket(this.helper)
|
private constructor(config: Config) {
|
||||||
this.auth = await new OceanAuth(this.helper)
|
|
||||||
this.token = await new OceanToken(this.helper)
|
|
||||||
|
|
||||||
return this
|
this._config = config;
|
||||||
})()
|
|
||||||
|
this.helper = new Web3Helper(config)
|
||||||
|
this.metadata = new MetaData(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getInstance(config) {
|
||||||
|
|
||||||
|
const ocean = new Ocean(config);
|
||||||
|
|
||||||
|
ocean.market = await OceanMarket.getInstance(config, ocean.helper)
|
||||||
|
ocean.auth = await OceanAuth.getInstance(config, ocean.helper)
|
||||||
|
ocean.token = await OceanToken.getInstance(config, ocean.helper)
|
||||||
|
|
||||||
|
return ocean;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccounts() {
|
async getAccounts() {
|
||||||
return Promise.all((await this.helper.getAccounts()).map(async (account) => {
|
return Promise.all((await this.helper.getAccounts()).map(async (account: string) => {
|
||||||
// await ocean.market.requestTokens(account, 1000)
|
// await ocean.market.requestTokens(account, 1000)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -43,21 +50,21 @@ export default class Ocean {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrdersByConsumer(consumerAddress) {
|
async getOrdersByConsumer(consumerAddress: string) {
|
||||||
let accessConsentEvent = this.auth.contract.AccessConsentRequested({ _consumer: consumerAddress }, {
|
let accessConsentEvent = this.auth.contract.AccessConsentRequested({_consumer: consumerAddress}, {
|
||||||
fromBlock: 0,
|
fromBlock: 0,
|
||||||
toBlock: 'latest'
|
toBlock: 'latest'
|
||||||
})
|
})
|
||||||
|
|
||||||
let _resolve = null
|
let _resolve: Function = null
|
||||||
let _reject = null
|
let _reject: Function = null
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise<any[]>((resolve, reject) => {
|
||||||
_resolve = resolve
|
_resolve = resolve
|
||||||
_reject = reject
|
_reject = reject
|
||||||
})
|
})
|
||||||
|
|
||||||
const getEvents = () => {
|
const getEvents = (): Promise<any[]> => {
|
||||||
accessConsentEvent.get((error, logs) => {
|
accessConsentEvent.get((error: any, logs: any[]) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
_reject(error)
|
_reject(error)
|
||||||
throw new Error(error)
|
throw new Error(error)
|
||||||
@ -70,12 +77,13 @@ export default class Ocean {
|
|||||||
const events = await getEvents().then((events) => events)
|
const events = await getEvents().then((events) => events)
|
||||||
// let orders = await this.buildOrdersFromEvents(events, consumerAddress).then((result) => result)
|
// let orders = await this.buildOrdersFromEvents(events, consumerAddress).then((result) => result)
|
||||||
let orders = events
|
let orders = events
|
||||||
.filter(obj => (obj.args._consumer === consumerAddress))
|
.filter((obj: any) => (obj.args._consumer === consumerAddress))
|
||||||
.map(async (event) => ({
|
.map(async (event: any) => ({
|
||||||
...event.args,
|
...event.args,
|
||||||
timeout: event.args._timeout.toNumber(),
|
timeout: event.args._timeout.toNumber(),
|
||||||
status: await this.auth.getOrderStatus(event.args._id).then((status) => status.toNumber()),
|
status: await this.auth.getOrderStatus(event.args._id)
|
||||||
paid: await this.market.verifyOrderPayment(event.args._id).then((received) => received),
|
.then((status: BigNumber) => status.toNumber()),
|
||||||
|
paid: this.market.verifyOrderPayment(event.args._id),
|
||||||
key: null
|
key: null
|
||||||
}))
|
}))
|
||||||
Logger.debug('got orders: ', orders)
|
Logger.debug('got orders: ', orders)
|
||||||
@ -83,12 +91,12 @@ export default class Ocean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async purchaseAsset(
|
async purchaseAsset(
|
||||||
assetId, publisherId, price, privateKey, publicKey, timeout, senderAddress,
|
assetId: string, publisherId: string, price: number, privateKey: string, publicKey: string, timeout: number, senderAddress: string,
|
||||||
initialRequestEventHandler, accessCommittedEventHandler, tokenPublishedEventHandler) {
|
initialRequestEventHandler: Function, accessCommittedEventHandler: Function, tokenPublishedEventHandler: Function) {
|
||||||
const { token, market, auth } = this
|
const {token: OceanToken, market: OceanMarket, auth} = this
|
||||||
try {
|
try {
|
||||||
// Allow market contract to transfer funds on the consumer's behalf
|
// Allow market contract to transfer funds on the consumer's behalf
|
||||||
await token.contract.approve(market.contract.address, price, { from: senderAddress, gas: 2000000 })
|
await this.token.contract.approve(this.market.contract.address, price, {from: senderAddress, gas: 2000000})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.log('token approve', err)
|
Logger.log('token approve', err)
|
||||||
}
|
}
|
||||||
@ -96,33 +104,33 @@ export default class Ocean {
|
|||||||
// Submit the access request
|
// Submit the access request
|
||||||
await auth.contract.initiateAccessRequest(
|
await auth.contract.initiateAccessRequest(
|
||||||
assetId, publisherId, publicKey,
|
assetId, publisherId, publicKey,
|
||||||
timeout, { from: senderAddress, gas: 1000000 }
|
timeout, {from: senderAddress, gas: 1000000}
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.log('initiateAccessRequest', err)
|
Logger.log('initiateAccessRequest', err)
|
||||||
}
|
}
|
||||||
const resourceFilter = { _resourceId: assetId, _consumer: senderAddress }
|
const resourceFilter = {_resourceId: assetId, _consumer: senderAddress}
|
||||||
const initRequestEvent = auth.contract.AccessConsentRequested(resourceFilter)
|
const initRequestEvent = auth.contract.AccessConsentRequested(resourceFilter)
|
||||||
let order = {}
|
let order: any = {}
|
||||||
this._listenOnce(
|
this._listenOnce(
|
||||||
initRequestEvent,
|
initRequestEvent,
|
||||||
'AccessConsentRequested',
|
'AccessConsentRequested',
|
||||||
(result, error) => {
|
(result: any, error: any) => {
|
||||||
order = initialRequestEventHandler(result, error)
|
order = initialRequestEventHandler(result, error)
|
||||||
const requestIdFilter = { _id: order.id }
|
const requestIdFilter = {_id: order.id}
|
||||||
const accessCommittedEvent = auth.contract.AccessRequestCommitted(requestIdFilter)
|
const accessCommittedEvent = auth.contract.AccessRequestCommitted(requestIdFilter)
|
||||||
const tokenPublishedEvent = auth.contract.EncryptedTokenPublished(requestIdFilter)
|
const tokenPublishedEvent = auth.contract.EncryptedTokenPublished(requestIdFilter)
|
||||||
this._listenOnce(
|
this._listenOnce(
|
||||||
accessCommittedEvent,
|
accessCommittedEvent,
|
||||||
'AccessRequestCommitted',
|
'AccessRequestCommitted',
|
||||||
(result, error) => {
|
(result: any, error: any) => {
|
||||||
accessCommittedEventHandler(result, order, error)
|
accessCommittedEventHandler(result, order, error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
this._listenOnce(
|
this._listenOnce(
|
||||||
tokenPublishedEvent,
|
tokenPublishedEvent,
|
||||||
'EncryptedTokenPublished',
|
'EncryptedTokenPublished',
|
||||||
(result, error) => {
|
(result: any, error: any) => {
|
||||||
tokenPublishedEventHandler(result, order, error)
|
tokenPublishedEventHandler(result, order, error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -131,9 +139,9 @@ export default class Ocean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions (private)
|
// Helper functions (private)
|
||||||
_listenOnce(event, eventName, callback) {
|
_listenOnce(event: any, eventName: string, callback: Function) {
|
||||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||||
event.watch((error, result) => {
|
event.watch((error: any, result: any) => {
|
||||||
event.stopWatching()
|
event.stopWatching()
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.log(`Error in keeper ${eventName} event: `, error)
|
Logger.log(`Error in keeper ${eventName} event: `, error)
|
11
src/squid.js
11
src/squid.js
@ -1,11 +0,0 @@
|
|||||||
import OceanAgent from './deprecated/ocean-agent'
|
|
||||||
import OceanKeeper from './deprecated/ocean-keeper'
|
|
||||||
import Ocean from './ocean'
|
|
||||||
import Logger from './utils/logger'
|
|
||||||
|
|
||||||
export {
|
|
||||||
Ocean,
|
|
||||||
OceanAgent, // deprecated
|
|
||||||
OceanKeeper, // deprecated
|
|
||||||
Logger
|
|
||||||
}
|
|
7
src/squid.ts
Normal file
7
src/squid.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Ocean from './ocean'
|
||||||
|
import Logger from './utils/logger'
|
||||||
|
|
||||||
|
export {
|
||||||
|
Ocean,
|
||||||
|
Logger
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
|
import Web3 = require("web3");
|
||||||
|
|
||||||
export default class Web3Helper {
|
export default class Web3Helper {
|
||||||
constructor(web3) {
|
public web3: Web3;
|
||||||
this.web3 = web3
|
|
||||||
|
constructor(config: any) {
|
||||||
|
const web3Provider = config.web3Provider || new Web3.providers.HttpProvider(config.nodeUri)
|
||||||
|
this.web3 = new Web3(web3Provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccounts() {
|
async getAccounts(): Promise<any[]> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise<any[]>((resolve: Function, reject: Function) => {
|
||||||
this.web3.eth.getAccounts((err, accounts) => {
|
this.web3.eth.getAccounts((err: any, accounts: string[]) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
@ -14,9 +19,10 @@ export default class Web3Helper {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNetworkName() {
|
async getNetworkName(): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise<string>((resolve: Function, reject: Function) => {
|
||||||
let network = 'unknown'
|
let network: string = 'unknown'
|
||||||
|
// @ts-ignore old version of web3, lets get to 1.0
|
||||||
this.web3.version.getNetwork((err, networkId) => {
|
this.web3.version.getNetwork((err, networkId) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err
|
throw err
|
||||||
@ -46,7 +52,7 @@ export default class Web3Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// web3 wrappers
|
// web3 wrappers
|
||||||
sign(accountAddress, message) {
|
sign(accountAddress: string, message: string) {
|
||||||
return this.web3.eth.sign(accountAddress, message)
|
return this.web3.eth.sign(accountAddress, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
5
src/utils/config.ts
Normal file
5
src/utils/config.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export default class Config {
|
||||||
|
|
||||||
|
public defaultGas: number = 300000;
|
||||||
|
public providerUri: string;
|
||||||
|
}
|
@ -1,22 +1,23 @@
|
|||||||
export default class Logger {
|
export default class Logger {
|
||||||
static dispatch(verb, ...args) {
|
static dispatch(verb: string, ...args: any[]) {
|
||||||
/* eslint-disable-next-line no-console */
|
/* eslint-disable-next-line no-console */
|
||||||
|
// @ts-ignore
|
||||||
console[verb](...args)
|
console[verb](...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static log(...args) {
|
static log(...args: any[]) {
|
||||||
Logger.dispatch('log', ...args)
|
Logger.dispatch('log', ...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static debug(...args) {
|
static debug(...args: any[]) {
|
||||||
Logger.dispatch('debug', ...args)
|
Logger.dispatch('debug', ...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static warn(...args) {
|
static warn(...args: any[]) {
|
||||||
Logger.dispatch('warn', ...args)
|
Logger.dispatch('warn', ...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static error(...args) {
|
static error(...args: any[]) {
|
||||||
Logger.dispatch('error', ...args)
|
Logger.dispatch('error', ...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
22
tsconfig.json
Normal file
22
tsconfig.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": [
|
||||||
|
"es6",
|
||||||
|
"es7"
|
||||||
|
],
|
||||||
|
"module": "commonjs",
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"removeComments": true,
|
||||||
|
"preserveConstEnums": true,
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"rootDir": "./src/",
|
||||||
|
"sourceMap": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user