mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
DDD refactoring
This commit is contained in:
parent
97fc3d6c1c
commit
1d7597def8
@ -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": "babel ./src/ --watch --out-dir ./dist/",
|
||||||
"build": "babel src --out-dir dist",
|
"build": "babel ./src/ --out-dir ./dist/",
|
||||||
"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",
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import TruffleContract from 'truffle-contract'
|
|
||||||
|
|
||||||
const contracts = []
|
|
||||||
|
|
||||||
export default class ContractLoader {
|
|
||||||
static async _doLoad(what, where, provider) {
|
|
||||||
// console.log("Loading", what, "from", where)
|
|
||||||
/* eslint-disable-next-line */
|
|
||||||
const artifact = require(`@oceanprotocol/keeper-contracts/artifacts/${what}.${where}`)
|
|
||||||
const contract = TruffleContract(artifact)
|
|
||||||
contract.setProvider(provider)
|
|
||||||
contracts[what] = await contract.at(artifact.address)
|
|
||||||
return contracts[what]
|
|
||||||
}
|
|
||||||
|
|
||||||
static load(what, where, provider) {
|
|
||||||
return contracts[what] || ContractLoader._doLoad(what, where, provider)
|
|
||||||
}
|
|
||||||
}
|
|
29
src/keeper/auth.js
Normal file
29
src/keeper/auth.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import ContractLoader from './contractLoader'
|
||||||
|
import KeeperBase from './keeper-base'
|
||||||
|
|
||||||
|
export default class OceanAuth extends KeeperBase {
|
||||||
|
constructor(web3, network) {
|
||||||
|
super(web3, network)
|
||||||
|
|
||||||
|
const instance = this
|
||||||
|
|
||||||
|
return {
|
||||||
|
async getInstance() {
|
||||||
|
instance.contract = ContractLoader.load('OceanAuth', instance._network, instance._web3)
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
}
|
23
src/keeper/contractLoader.js
Normal file
23
src/keeper/contractLoader.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import TruffleContract from 'truffle-contract'
|
||||||
|
import Logger from '../utils/logger'
|
||||||
|
|
||||||
|
const contracts = []
|
||||||
|
|
||||||
|
export default class ContractLoader {
|
||||||
|
static async _doLoad(what, where, web3) {
|
||||||
|
Logger.log('Loading', what, 'from', where)
|
||||||
|
/* eslint-disable-next-line security/detect-non-literal-require */
|
||||||
|
const artifact = require(`@oceanprotocol/keeper-contracts/artifacts/${what}.${where}`)
|
||||||
|
Logger.log('Loaded artifact', artifact)
|
||||||
|
|
||||||
|
const contract = TruffleContract(artifact)
|
||||||
|
Logger.log('Getting instance of', what, 'from', where, 'at', artifact.address)
|
||||||
|
contract.setProvider(web3.currentProvider)
|
||||||
|
contracts[what] = await contract.at(artifact.address)
|
||||||
|
return contracts[what]
|
||||||
|
}
|
||||||
|
|
||||||
|
static async load(what, where, provider) {
|
||||||
|
return contracts[what] || ContractLoader._doLoad(what, where, provider)
|
||||||
|
}
|
||||||
|
}
|
7
src/keeper/keeper-base.js
Normal file
7
src/keeper/keeper-base.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default class KeeperBase {
|
||||||
|
constructor(web3, network) {
|
||||||
|
this._web3 = web3
|
||||||
|
this._network = network
|
||||||
|
this.contract = null
|
||||||
|
}
|
||||||
|
}
|
58
src/keeper/market.js
Normal file
58
src/keeper/market.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import ContractLoader from './contractLoader'
|
||||||
|
import KeeperBase from './keeper-base'
|
||||||
|
|
||||||
|
import Logger from '../utils/logger'
|
||||||
|
|
||||||
|
export default class OceanMarket extends KeeperBase {
|
||||||
|
constructor(web3, network) {
|
||||||
|
super(web3, network)
|
||||||
|
|
||||||
|
const instance = this
|
||||||
|
|
||||||
|
return {
|
||||||
|
async getInstance() {
|
||||||
|
instance.contract = await ContractLoader.load('OceanMarket', instance._network, instance._web3)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(senderAddress, numTokens) {
|
||||||
|
return this.contract.requestTokens(numTokens, { from: senderAddress })
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
34
src/keeper/token.js
Normal file
34
src/keeper/token.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import ContractLoader from './contractLoader'
|
||||||
|
import KeeperBase from './keeper-base'
|
||||||
|
import { Logger } from '../utils/logger'
|
||||||
|
|
||||||
|
export default class OceanToken extends KeeperBase {
|
||||||
|
constructor(web3, network) {
|
||||||
|
super(web3, network)
|
||||||
|
|
||||||
|
const instance = this
|
||||||
|
|
||||||
|
return {
|
||||||
|
async getInstance() {
|
||||||
|
instance.contract = ContractLoader.load('OceanToken', instance._network, instance._web3)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTokenBalance(accountAddress) {
|
||||||
|
return this.contract.balanceOf.call(accountAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
getEthBalance(account) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Logger.log('getting balance for', account)
|
||||||
|
super._web3.eth.getBalance(account, 'latest', (err, balance) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
Logger.log('balance', balance)
|
||||||
|
resolve(balance)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/* global fetch */
|
/* global fetch */
|
||||||
import Logger from 'logger'
|
import Logger from './utils/logger'
|
||||||
|
|
||||||
export default class OceanAgent {
|
export default class OceanAgent {
|
||||||
constructor(connectionUrl) {
|
constructor(connectionUrl) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
import ContractLoader from './contractLoader'
|
import ContractLoader from './keeper/contractLoader'
|
||||||
import Logger from './logger'
|
import Logger from './utils/logger'
|
||||||
|
|
||||||
const DEFAULT_GAS = 300000
|
const DEFAULT_GAS = 300000
|
||||||
|
|
||||||
@ -10,12 +10,14 @@ export default class OceanKeeper {
|
|||||||
this.web3 = new Web3(web3Provider)
|
this.web3 = new Web3(web3Provider)
|
||||||
this.defaultGas = DEFAULT_GAS
|
this.defaultGas = DEFAULT_GAS
|
||||||
this.network = network || 'development'
|
this.network = network || 'development'
|
||||||
|
|
||||||
|
Logger.warn('OceanKeeper is deprecated use the Ocean object from squid instead')
|
||||||
}
|
}
|
||||||
|
|
||||||
async initContracts() {
|
async initContracts() {
|
||||||
this.oceanToken = await ContractLoader.load('OceanToken', this.network, this.web3.currentProvider)
|
this.oceanToken = await ContractLoader.load('OceanToken', this.network, this.web3)
|
||||||
this.oceanMarket = await ContractLoader.load('OceanMarket', this.network, this.web3.currentProvider)
|
this.oceanMarket = await ContractLoader.load('OceanMarket', this.network, this.web3)
|
||||||
this.oceanAuth = await ContractLoader.load('OceanAuth', this.network, this.web3.currentProvider)
|
this.oceanAuth = await ContractLoader.load('OceanAuth', this.network, this.web3)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
oceanToken: this.oceanToken,
|
oceanToken: this.oceanToken,
|
||||||
|
123
src/ocean.js
Normal file
123
src/ocean.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import Web3 from 'web3'
|
||||||
|
import OceanMarket from './keeper/market'
|
||||||
|
import OceanAuth from './keeper/auth'
|
||||||
|
import OceanToken from './keeper/token'
|
||||||
|
import Logger from './utils/logger'
|
||||||
|
import Web3Helper from './utils/Web3Helper'
|
||||||
|
|
||||||
|
const DEFAULT_GAS = 300000
|
||||||
|
|
||||||
|
export default class Ocean {
|
||||||
|
constructor(config) {
|
||||||
|
const web3Provider = config.web3Provider || new Web3.providers.HttpProvider(config.uri)
|
||||||
|
this._web3 = new Web3(web3Provider)
|
||||||
|
this._defaultGas = config.gas || DEFAULT_GAS
|
||||||
|
this._network = config.network || 'development'
|
||||||
|
|
||||||
|
this.helper = new Web3Helper(this._web3)
|
||||||
|
|
||||||
|
const instance = this
|
||||||
|
|
||||||
|
return {
|
||||||
|
async getInstance() {
|
||||||
|
instance.market = await new OceanMarket(instance._web3, instance._network).getInstance()
|
||||||
|
instance.auth = await new OceanAuth(instance._web3, instance._network).getInstance()
|
||||||
|
instance.token = await new OceanToken(instance._web3, instance._network).getInstance()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOrdersByConsumer(consumerAddress) {
|
||||||
|
let accessConsentEvent = this.auth.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
|
||||||
|
}
|
||||||
|
|
||||||
|
purchaseAsset(
|
||||||
|
assetId, publisherId, price, privateKey, publicKey, timeout, senderAddress,
|
||||||
|
initialRequestEventHandler, accessCommittedEventHandler, tokenPublishedEventHandler) {
|
||||||
|
const { token, market, auth } = this
|
||||||
|
// Allow market contract to transfer funds on the consumer's behalf
|
||||||
|
token.approve(market.address, price, { from: senderAddress, gas: 2000000 })
|
||||||
|
// Submit the access request
|
||||||
|
auth.initiateAccessRequest(
|
||||||
|
assetId, publisherId, publicKey,
|
||||||
|
timeout, { from: senderAddress, gas: 1000000 }
|
||||||
|
)
|
||||||
|
|
||||||
|
const resourceFilter = { _resourceId: assetId, _consumer: senderAddress }
|
||||||
|
const initRequestEvent = auth.contract.AccessConsentRequested(resourceFilter)
|
||||||
|
let order = {}
|
||||||
|
this._listenOnce(
|
||||||
|
initRequestEvent,
|
||||||
|
'AccessConsentRequested',
|
||||||
|
(result, error) => {
|
||||||
|
order = initialRequestEventHandler(result, error)
|
||||||
|
const requestIdFilter = { _id: order.id }
|
||||||
|
const accessCommittedEvent = auth.contract.AccessRequestCommitted(requestIdFilter)
|
||||||
|
const tokenPublishedEvent = auth.contract.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) {
|
||||||
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||||
|
event.watch((error, result) => {
|
||||||
|
event.stopWatching()
|
||||||
|
if (error) {
|
||||||
|
Logger.log(`Error in keeper ${eventName} event: `, error)
|
||||||
|
}
|
||||||
|
callback(result, error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,11 @@
|
|||||||
import OceanAgent from './ocean-agent'
|
import OceanAgent from './ocean-agent'
|
||||||
import OceanKeeper from './ocean-keeper'
|
import OceanKeeper from './ocean-keeper'
|
||||||
|
import Ocean from './ocean'
|
||||||
|
import Logger from './utils/logger'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
Ocean,
|
||||||
OceanAgent,
|
OceanAgent,
|
||||||
OceanKeeper
|
OceanKeeper,
|
||||||
|
Logger
|
||||||
}
|
}
|
||||||
|
17
src/utils/Web3Helper.js
Normal file
17
src/utils/Web3Helper.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import Logger from './logger'
|
||||||
|
|
||||||
|
export default class Web3Helper {
|
||||||
|
constructor(web3) {
|
||||||
|
this._web3 = web3
|
||||||
|
}
|
||||||
|
|
||||||
|
getAccounts() {
|
||||||
|
Logger.log(this._web3)
|
||||||
|
return this._web3.eth.accounts
|
||||||
|
}
|
||||||
|
|
||||||
|
// web3 wrappers
|
||||||
|
sign(accountAddress, message) {
|
||||||
|
return this._web3.eth.sign(accountAddress, message)
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,10 @@ export default class Logger {
|
|||||||
Logger.dispatch('debug', ...args)
|
Logger.dispatch('debug', ...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static warn(...args) {
|
||||||
|
Logger.dispatch('warn', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
static error(...args) {
|
static error(...args) {
|
||||||
Logger.dispatch('error', ...args)
|
Logger.dispatch('error', ...args)
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user