mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
new squid design
This commit is contained in:
parent
fe1472208f
commit
19201ef6e7
15
src/ConfigProvider.ts
Normal file
15
src/ConfigProvider.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import Config from "./models/Config"
|
||||
|
||||
export default class ConfigProvider {
|
||||
|
||||
public static getConfig() {
|
||||
return ConfigProvider.config
|
||||
}
|
||||
|
||||
public static configure(config: Config) {
|
||||
|
||||
ConfigProvider.config = config
|
||||
}
|
||||
|
||||
private static config: Config
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
import {Receipt} from "web3-utils"
|
||||
import Asset from "../models/Asset"
|
||||
import Config from "../models/Config"
|
||||
import Asset from "../ocean/Asset"
|
||||
import ContractBaseWrapper from "./ContractWrapperBase"
|
||||
import Web3Helper from "./Web3Helper"
|
||||
|
||||
export default class OceanAuth extends ContractBaseWrapper {
|
||||
|
||||
public static async getInstance(config: Config, web3Helper: Web3Helper): Promise<OceanAuth> {
|
||||
const auth: OceanAuth = new OceanAuth(config, "OceanAuth", web3Helper)
|
||||
public static async getInstance(): Promise<OceanAuth> {
|
||||
const auth: OceanAuth = new OceanAuth("OceanAuth")
|
||||
await auth.init()
|
||||
return auth
|
||||
}
|
||||
@ -35,14 +33,11 @@ export default class OceanAuth extends ContractBaseWrapper {
|
||||
public async initiateAccessRequest(asset: Asset, publicKey: string,
|
||||
timeout: number, buyerAddress: string): Promise<Receipt> {
|
||||
|
||||
const args = [asset.assetId, asset.publisherId, publicKey, timeout]
|
||||
const tx = this.contract.methods.initiateAccessRequest(...args)
|
||||
const gas = await tx.estimateGas(args, {
|
||||
from: buyerAddress,
|
||||
})
|
||||
return tx.send({
|
||||
from: buyerAddress,
|
||||
gas,
|
||||
})
|
||||
const args = [asset.getId(), asset.publisher.getId(), publicKey, timeout]
|
||||
return this.sendTransaction("initiateAccessRequest", buyerAddress, args)
|
||||
}
|
||||
|
||||
public async commitAccessRequest() {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
import Contract from "web3-eth-contract"
|
||||
import Logger from "../utils/Logger"
|
||||
import Web3Helper from "./Web3Helper"
|
||||
import Web3Provider from "./Web3Provider"
|
||||
import Keeper from "./Keeper"
|
||||
|
||||
const contracts: Map<string, Contract> = new Map<string, Contract>()
|
||||
|
||||
export default class ContractHandler {
|
||||
|
||||
public static async get(what: string, web3Helper: Web3Helper): Contract {
|
||||
return contracts.get(what) || await ContractHandler.load(what, web3Helper)
|
||||
public static async get(what: string): Contract {
|
||||
return contracts.get(what) || await ContractHandler.load(what)
|
||||
}
|
||||
|
||||
public static async deployContracts(web3Helper: Web3Helper) {
|
||||
public static async deployContracts() {
|
||||
Logger.log("Trying to deploy contracts")
|
||||
|
||||
const web3 = web3Helper.getWeb3()
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
|
||||
const deployerAddress = (await web3.eth.getAccounts())[0]
|
||||
|
||||
@ -47,14 +48,14 @@ export default class ContractHandler {
|
||||
})
|
||||
}
|
||||
|
||||
private static async load(what: string, web3Helper: Web3Helper): Promise<Contract> {
|
||||
const where = (await web3Helper.getNetworkName()).toLowerCase()
|
||||
private static async load(what: string): Promise<Contract> {
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
const where = (await (await Keeper.getInstance()).getNetworkName()).toLowerCase()
|
||||
Logger.log("Loading", what, "from", where)
|
||||
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)
|
||||
const web3 = web3Helper.getWeb3()
|
||||
const contract = new web3.eth.Contract(artifact.abi, artifact.address)
|
||||
Logger.log("Loaded", what, "from", where)
|
||||
contracts.set(what, contract)
|
||||
|
@ -1,25 +1,16 @@
|
||||
import Event from "web3"
|
||||
import Contract from "web3-eth-contract"
|
||||
import Config from "../models/Config"
|
||||
import ContractHandler from "./ContractHandler"
|
||||
import Web3Helper from "./Web3Helper"
|
||||
|
||||
export default class ContractWrapperBase {
|
||||
export default abstract class ContractWrapperBase {
|
||||
|
||||
public static async getInstance(config: Config, web3Helper: Web3Helper): Promise<any> {
|
||||
// stub
|
||||
}
|
||||
protected static instance = null
|
||||
|
||||
protected contract: Contract = null
|
||||
protected config: Config
|
||||
protected web3Helper: Web3Helper
|
||||
|
||||
private contractName: string
|
||||
|
||||
constructor(config: Config, contractName: string, web3Helper: Web3Helper) {
|
||||
this.config = config
|
||||
constructor(contractName) {
|
||||
this.contractName = contractName
|
||||
this.web3Helper = web3Helper
|
||||
}
|
||||
|
||||
public async listenToEventOnce(eventName: string, options: any): Promise<any> {
|
||||
@ -48,7 +39,21 @@ export default class ContractWrapperBase {
|
||||
}
|
||||
|
||||
protected async init() {
|
||||
this.contract = await ContractHandler.get(this.contractName, this.web3Helper)
|
||||
this.contract = await ContractHandler.get(this.contractName)
|
||||
}
|
||||
|
||||
protected async sendTransaction(name: string, from: string, args: any[]) {
|
||||
if (!this.contract.methods[name]) {
|
||||
throw new Error(`Method ${name} is not part of contract ${this.contractName}`)
|
||||
}
|
||||
const tx = this.contract.methods[name](...args)
|
||||
const gas = await tx.estimateGas(args, {
|
||||
from,
|
||||
})
|
||||
return tx.send({
|
||||
from,
|
||||
gas,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,28 +1,53 @@
|
||||
import Config from "../models/Config"
|
||||
import OceanAuth from "./Auth"
|
||||
import OceanMarket from "./Market"
|
||||
import OceanToken from "./Token"
|
||||
import Web3Helper from "./Web3Helper"
|
||||
import Web3Provider from "./Web3Provider"
|
||||
|
||||
export default class Keeper {
|
||||
|
||||
public static async getInstance(config: Config, helper: Web3Helper) {
|
||||
public static async getInstance() {
|
||||
|
||||
const contracts = new Keeper(helper)
|
||||
if (Keeper.instance === null) {
|
||||
Keeper.instance = new Keeper()
|
||||
|
||||
contracts.market = await OceanMarket.getInstance(config, helper)
|
||||
contracts.auth = await OceanAuth.getInstance(config, helper)
|
||||
contracts.token = await OceanToken.getInstance(config, helper)
|
||||
|
||||
return contracts
|
||||
Keeper.instance.market = await OceanMarket.getInstance()
|
||||
Keeper.instance.auth = await OceanAuth.getInstance()
|
||||
Keeper.instance.token = await OceanToken.getInstance()
|
||||
}
|
||||
return Keeper.instance
|
||||
}
|
||||
|
||||
public web3Helper: Web3Helper
|
||||
private static instance: Keeper = null
|
||||
|
||||
public token: OceanToken
|
||||
public market: OceanMarket
|
||||
public auth: OceanAuth
|
||||
|
||||
private constructor(helper: Web3Helper) {
|
||||
this.web3Helper = helper
|
||||
public async getNetworkName(): Promise<string> {
|
||||
return Web3Provider.getWeb3().eth.net.getId()
|
||||
.then((networkId) => {
|
||||
let network: string = "unknown"
|
||||
|
||||
switch (networkId) {
|
||||
case 1:
|
||||
network = "Main"
|
||||
break
|
||||
case 2:
|
||||
network = "Morden"
|
||||
break
|
||||
case 3:
|
||||
network = "Ropsten"
|
||||
break
|
||||
case 4:
|
||||
network = "Rinkeby"
|
||||
break
|
||||
case 42:
|
||||
network = "Kovan"
|
||||
break
|
||||
default:
|
||||
network = "development"
|
||||
}
|
||||
return network
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
import BigNumber from "bignumber.js"
|
||||
import {Receipt} from "web3-utils"
|
||||
import Asset from "../models/Asset"
|
||||
import Config from "../models/Config"
|
||||
import Order from "../models/Order"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Order from "../ocean/Order"
|
||||
import ContractWrapperBase from "./ContractWrapperBase"
|
||||
import Web3Helper from "./Web3Helper"
|
||||
|
||||
export default class OceanMarket extends ContractWrapperBase {
|
||||
|
||||
public static async getInstance(config: Config, web3Helper: Web3Helper): Promise<OceanMarket> {
|
||||
const market: OceanMarket = new OceanMarket(config, "OceanMarket", web3Helper)
|
||||
public static async getInstance(): Promise<OceanMarket> {
|
||||
const market: OceanMarket = new OceanMarket("OceanMarket")
|
||||
await market.init()
|
||||
return market
|
||||
}
|
||||
@ -44,15 +42,22 @@ export default class OceanMarket extends ContractWrapperBase {
|
||||
return await this.contract.methods.register(assetId, price)
|
||||
.send({
|
||||
from: publisherAddress,
|
||||
gas: this.config.defaultGas,
|
||||
gas: ConfigProvider.getConfig().defaultGas,
|
||||
})
|
||||
}
|
||||
|
||||
public async payAsset(asset: Asset, order: Order, buyerAddress: string): Promise<Receipt> {
|
||||
return this.contract.methods.sendPayment(order.id, asset.publisherId, asset.price, order.timeout)
|
||||
.send({
|
||||
from: buyerAddress,
|
||||
gas: this.config.defaultGas,
|
||||
})
|
||||
public async payOrder(order: Order, payerAddreess: string): Promise<Receipt> {
|
||||
|
||||
const args = [
|
||||
order.getId(), order.getAsset().publisher.getId(),
|
||||
order.getAsset().price, order.getTimeout(),
|
||||
]
|
||||
|
||||
return this.sendTransaction("sendPayment", payerAddreess, args)
|
||||
}
|
||||
|
||||
public getAssetPublisher(assetId: string): Promise<string> {
|
||||
return this.contract.methods.getAssetPublisher(assetId)
|
||||
.call()
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
import BigNumber from "bignumber.js"
|
||||
import {Receipt} from "web3-utils"
|
||||
import Config from "../models/Config"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import ContractBaseWrapper from "./ContractWrapperBase"
|
||||
import Web3Helper from "./Web3Helper"
|
||||
|
||||
export default class OceanToken extends ContractBaseWrapper {
|
||||
|
||||
public static async getInstance(config: Config, web3Helper: Web3Helper): Promise<OceanToken> {
|
||||
const token: OceanToken = new OceanToken(config, "OceanToken", web3Helper)
|
||||
public static async getInstance(): Promise<OceanToken> {
|
||||
const token: OceanToken = new OceanToken("OceanToken")
|
||||
await token.init()
|
||||
return token
|
||||
}
|
||||
@ -16,7 +15,7 @@ export default class OceanToken extends ContractBaseWrapper {
|
||||
return this.contract.methods.approve(marketAddress, price)
|
||||
.send({
|
||||
from: buyerAddress,
|
||||
gas: this.config.defaultGas,
|
||||
gas: ConfigProvider.getConfig().defaultGas,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
import * as Web3 from "web3"
|
||||
import Config from "../models/Config"
|
||||
import Logger from "../utils/Logger"
|
||||
|
||||
Logger.log("using web3", Web3.version)
|
||||
|
||||
export default class Web3Helper {
|
||||
|
||||
private web3: Web3
|
||||
|
||||
public constructor(config: Config) {
|
||||
const web3Provider = config.web3Provider || new Web3.providers.HttpProvider(config.nodeUri)
|
||||
this.web3 = new Web3(Web3.givenProvider || web3Provider)
|
||||
}
|
||||
|
||||
public getWeb3() {
|
||||
return this.web3
|
||||
}
|
||||
|
||||
public getCurrentProvider() {
|
||||
return this.web3.currentProvider
|
||||
}
|
||||
|
||||
public async getAccounts(): Promise<any[]> {
|
||||
return new Promise<any[]>((resolve, reject) => {
|
||||
this.web3.eth.getAccounts((err: any, accounts: string[]) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
throw err
|
||||
}
|
||||
resolve(accounts)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async getNetworkName(): Promise<string> {
|
||||
return this.web3.eth.net.getId()
|
||||
.then((networkId) => {
|
||||
let network: string = "unknown"
|
||||
|
||||
switch (networkId) {
|
||||
case 1:
|
||||
network = "Main"
|
||||
break
|
||||
case 2:
|
||||
network = "Morden"
|
||||
break
|
||||
case 3:
|
||||
network = "Ropsten"
|
||||
break
|
||||
case 4:
|
||||
network = "Rinkeby"
|
||||
break
|
||||
case 42:
|
||||
network = "Kovan"
|
||||
break
|
||||
default:
|
||||
network = "development"
|
||||
}
|
||||
return network
|
||||
})
|
||||
}
|
||||
|
||||
// web3 wrappers
|
||||
public sign(accountAddress: string, message: string) {
|
||||
return this.web3.eth.sign(accountAddress, message)
|
||||
}
|
||||
|
||||
}
|
19
src/keeper/Web3Provider.ts
Normal file
19
src/keeper/Web3Provider.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import * as Web3 from "web3"
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Logger from "../utils/Logger"
|
||||
|
||||
Logger.log("using web3", Web3.version)
|
||||
|
||||
export default class Web3Provider {
|
||||
|
||||
public static getWeb3() {
|
||||
if (Web3Provider.web3 === null) {
|
||||
const config = ConfigProvider.getConfig()
|
||||
const web3Provider = config.web3Provider || new Web3.providers.HttpProvider(config.nodeUri)
|
||||
Web3Provider.web3 = new Web3(Web3.givenProvider || web3Provider)
|
||||
}
|
||||
return Web3Provider.web3
|
||||
}
|
||||
|
||||
private static web3: Web3 = null
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import Balance from "./Balance"
|
||||
|
||||
export default class Account {
|
||||
public name: string
|
||||
public balance: Balance
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export default class Asset {
|
||||
public assetId: string
|
||||
public publisherId: string
|
||||
public price: number
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import Asset from "./Asset"
|
||||
|
||||
export default class Order {
|
||||
public id: string
|
||||
public asset: Asset
|
||||
public assetId: string
|
||||
public timeout: number
|
||||
public pubkey: string
|
||||
public key: any
|
||||
public paid: boolean
|
||||
public status: number
|
||||
}
|
@ -1,42 +1,40 @@
|
||||
import BigNumber from "bignumber.js"
|
||||
import AccountModel from "../models/Account"
|
||||
import Keeper from "../keeper/Keeper"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import Balance from "../models/Balance"
|
||||
import OceanBase from "./OceanBase"
|
||||
|
||||
export default class Account extends OceanBase {
|
||||
private balance: Balance
|
||||
|
||||
public async getTokenBalance(accountAddress: string): Promise<number> {
|
||||
return this.keeper.token.balanceOf(accountAddress)
|
||||
public async getOceanBalance(): Promise<number> {
|
||||
return (await Keeper.getInstance()).token.balanceOf(this.id)
|
||||
}
|
||||
|
||||
public async getEthBalance(account: string): Promise<number> {
|
||||
const {web3Helper} = this.keeper
|
||||
public async getEthBalance(): Promise<number> {
|
||||
// Logger.log("getting balance for", account);
|
||||
return web3Helper.getWeb3().eth.getBalance(account, "latest")
|
||||
.then((balance: string) => {
|
||||
return Web3Provider.getWeb3().eth
|
||||
.getBalance(this.id, "latest")
|
||||
.then((balance: string): number => {
|
||||
// Logger.log("balance", balance);
|
||||
return new BigNumber(balance).toNumber()
|
||||
})
|
||||
}
|
||||
|
||||
public async list() {
|
||||
const {web3Helper} = this.keeper
|
||||
public async getBalance(): Promise<Balance> {
|
||||
|
||||
const ethAccounts = await web3Helper.getAccounts()
|
||||
return Promise.all(ethAccounts
|
||||
.map(async (account: string) => {
|
||||
// await ocean.market.requestTokens(account, 1000)
|
||||
return {
|
||||
name: account,
|
||||
balance: {
|
||||
eth: await this.getEthBalance(account),
|
||||
ocn: await this.getTokenBalance(account),
|
||||
},
|
||||
} as AccountModel
|
||||
}))
|
||||
if (!this.balance) {
|
||||
this.balance = {
|
||||
eth: await this.getEthBalance(),
|
||||
ocn: await this.getOceanBalance(),
|
||||
} as Balance
|
||||
}
|
||||
|
||||
return this.balance
|
||||
}
|
||||
|
||||
// Transactions with gas cost
|
||||
public async requestTokens(amount: number, receiver: string): Promise<boolean> {
|
||||
return this.keeper.market.requestTokens(amount, receiver)
|
||||
public async requestTokens(amount: number): Promise<boolean> {
|
||||
return (await Keeper.getInstance()).market.requestTokens(amount, this.id)
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,163 @@
|
||||
import AssetModel from "../models/Asset"
|
||||
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 Web3Provider from "../keeper/Web3Provider"
|
||||
import Logger from "../utils/Logger"
|
||||
import Account from "./Account"
|
||||
import OceanBase from "./OceanBase"
|
||||
import Order from "./Order"
|
||||
|
||||
declare var fetch
|
||||
|
||||
export default class Asset extends OceanBase {
|
||||
|
||||
public async isAssetActive(assetId: string): Promise<boolean> {
|
||||
const {market} = this.keeper
|
||||
return market.isAssetActive(assetId)
|
||||
public static async load(assetId): Promise<Asset> {
|
||||
const {market} = await Keeper.getInstance()
|
||||
|
||||
const asset = new Asset("unknown", "unknown",
|
||||
await market.getAssetPrice(assetId),
|
||||
new Account(await market.getAssetPublisher(assetId)))
|
||||
|
||||
asset.setId(assetId)
|
||||
|
||||
return asset
|
||||
}
|
||||
|
||||
public async registerAsset(name: string, description: string,
|
||||
price: number, publisherAddress: string): Promise<AssetModel> {
|
||||
const {market} = this.keeper
|
||||
|
||||
// generate an id
|
||||
const assetId = await market.generateId(name + description)
|
||||
Logger.log(`Registering: ${assetId} with price ${price}`)
|
||||
|
||||
// register asset in the market
|
||||
const result = await market.register(assetId, price, publisherAddress)
|
||||
Logger.log("Registered:", assetId, "in block", result.blockNumber)
|
||||
|
||||
return {
|
||||
assetId,
|
||||
publisherId: publisherAddress,
|
||||
price,
|
||||
} as AssetModel
|
||||
constructor(public name: string,
|
||||
public description: string,
|
||||
public price: number,
|
||||
public publisher: Account) {
|
||||
super()
|
||||
}
|
||||
|
||||
public async isActive(): Promise<boolean> {
|
||||
const {market} = await Keeper.getInstance()
|
||||
return market.isAssetActive(this.getId())
|
||||
}
|
||||
|
||||
public async purchase(account: Account, timeout: number): Promise<Order> {
|
||||
const {token, market, auth} = await Keeper.getInstance()
|
||||
|
||||
const key = EthCrypto.createIdentity()
|
||||
const publicKey = EthjsUtil.privateToPublic(key.privateKey).toString("hex")
|
||||
const price = await market.getAssetPrice(this.getId())
|
||||
const isValid = await market.isAssetActive(this.getId())
|
||||
|
||||
Logger.log("The asset:", this.getId(), "is it valid?", isValid, "it's price is:", price)
|
||||
|
||||
if (!isValid) {
|
||||
throw new Error("The Asset is not valid!")
|
||||
}
|
||||
try {
|
||||
const marketAddr = market.getAddress()
|
||||
// Allow market contract to transfer funds on the consumer"s behalf
|
||||
await token.approve(marketAddr, price, account.getId())
|
||||
Logger.log(`${price} tokens approved on market with id: ${marketAddr}`)
|
||||
} catch (err) {
|
||||
Logger.error("token.approve failed", err)
|
||||
}
|
||||
let order: Order
|
||||
try {
|
||||
// Submit the access request
|
||||
const initiateAccessRequestReceipt = await auth.initiateAccessRequest(this,
|
||||
publicKey, timeout, account.getId())
|
||||
|
||||
const {returnValues} = initiateAccessRequestReceipt.events.AccessConsentRequested
|
||||
Logger.log(`Keeper AccessConsentRequested event received on asset: ${this.getId()}`, returnValues)
|
||||
order = new Order(this, returnValues._timeout, returnValues._pubKey, key)
|
||||
order.setId(returnValues._id)
|
||||
} catch (err) {
|
||||
Logger.error("auth.initiateAccessRequest failed", err)
|
||||
}
|
||||
|
||||
return order
|
||||
if (false) {
|
||||
// todo: AccessRequestCommitted event is not emitted in this flow
|
||||
await auth.listenToEventOnce(
|
||||
"AccessRequestCommitted", {
|
||||
filter: {
|
||||
_id: order.getId(),
|
||||
},
|
||||
})
|
||||
.then((accessRequestCommittedResult) => {
|
||||
Logger.log("Got AccessRequestCommitted Event")
|
||||
|
||||
return order.pay(account)
|
||||
})
|
||||
.then((payAssetReceipt) => {
|
||||
return auth.listenToEventOnce(
|
||||
"EncryptedTokenPublished", {
|
||||
filter: {
|
||||
_id: order.getId(),
|
||||
},
|
||||
})
|
||||
})
|
||||
.then((encryptedTokenPublishedResult) => {
|
||||
Logger.log("Got EncryptedTokenPublished Event")
|
||||
|
||||
const {returnValues} = encryptedTokenPublishedResult
|
||||
|
||||
return this.finalizePurchaseAsset(
|
||||
returnValues._id, order, key, account,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public async finalizePurchaseAsset(accessId: string, order: Order, key: any, account: Account): Promise<Order> {
|
||||
const {auth} = await Keeper.getInstance()
|
||||
|
||||
const encryptedAccessToken = await auth.getEncryptedAccessToken(accessId, this.getId())
|
||||
|
||||
// grab the access token from acl contract
|
||||
const tokenNo0x = encryptedAccessToken.slice(2)
|
||||
const encryptedTokenBuffer = Buffer.from(tokenNo0x, "hex")
|
||||
|
||||
const privateKey = key.privateKey.slice(2)
|
||||
const accessTokenEncoded = EthEcies.Decrypt(Buffer.from(privateKey, "hex"), encryptedTokenBuffer)
|
||||
const accessToken = JWT.decode(accessTokenEncoded) // Returns a json object
|
||||
|
||||
// sign it
|
||||
const hexEncrToken = `0x${encryptedTokenBuffer.toString("hex")}`
|
||||
|
||||
const signature = Web3Provider.getWeb3().eth.sign(account.getId(), hexEncrToken)
|
||||
const fixedMsgSha = Web3Provider.getWeb3().utils.sha3(encryptedAccessToken)
|
||||
|
||||
// Download the data set from the provider using the url in the access token
|
||||
// decode the access token, grab the service_endpoint, request_id,
|
||||
|
||||
// payload keys: ['consumerId', 'fixed_msg', 'sigEncJWT', 'jwt']
|
||||
const payload = JSON.stringify({
|
||||
consumerId: account.getId(),
|
||||
fixed_msg: fixedMsgSha,
|
||||
sigEncJWT: signature,
|
||||
jwt: accessTokenEncoded,
|
||||
})
|
||||
const accessUrl = await fetch(`${accessToken.service_endpoint}/${accessToken.resource_id}`, {
|
||||
method: "POST",
|
||||
body: payload,
|
||||
headers: {
|
||||
"Content-type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.text()
|
||||
}
|
||||
Logger.log("Failed: ", response.status, response.statusText)
|
||||
})
|
||||
.then((consumptionUrl: string) => {
|
||||
Logger.log("Success accessing consume endpoint: ", consumptionUrl)
|
||||
return consumptionUrl
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching the data asset consumption url: ", error)
|
||||
})
|
||||
Logger.log("consume url: ", accessUrl)
|
||||
order.setAccessUrl(accessUrl)
|
||||
|
||||
return order
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
import Config from "../models/Config"
|
||||
import Logger from "../utils/Logger"
|
||||
|
||||
declare var fetch
|
||||
|
||||
export default class MetaData {
|
||||
|
||||
private assetsUrl: string
|
||||
|
||||
constructor(config: Config) {
|
||||
const providerUri = config.providerUri || null
|
||||
|
||||
this.assetsUrl = providerUri + "/assets"
|
||||
}
|
||||
|
||||
public getAssetsMetadata() {
|
||||
return fetch(this.assetsUrl + "/metadata", {method: "GET"})
|
||||
.then((res) => res.json())
|
||||
.then((data) => JSON.parse(data))
|
||||
}
|
||||
|
||||
public publishDataAsset(asset: object) {
|
||||
return fetch(this.assetsUrl + "/metadata",
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(asset),
|
||||
headers: {"Content-type": "application/json"},
|
||||
})
|
||||
.then((response: any) => {
|
||||
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: Error) => {
|
||||
Logger.log(`Publish asset to ocean database could not be completed: ${error.message}`)
|
||||
return false
|
||||
})
|
||||
}
|
||||
}
|
@ -1,36 +1,86 @@
|
||||
import ConfigProvider from "../ConfigProvider"
|
||||
import Keeper from "../keeper/Keeper"
|
||||
import Web3Helper from "../keeper/Web3Helper"
|
||||
import Config from "../models/Config"
|
||||
import Web3Provider from "../keeper/Web3Provider"
|
||||
import Logger from "../utils/Logger"
|
||||
import Account from "./Account"
|
||||
import Asset from "./Asset"
|
||||
import MetaData from "./MetaData"
|
||||
import Order from "./Order"
|
||||
import Tribe from "./Tribe"
|
||||
|
||||
export default class Ocean {
|
||||
|
||||
public static async getInstance(config) {
|
||||
const ocean = new Ocean(config)
|
||||
ocean.keeper = await Keeper.getInstance(config, ocean.helper)
|
||||
ocean.tribe = await Tribe.getInstance(ocean.helper)
|
||||
ocean.order = new Order(ocean.keeper)
|
||||
ocean.account = new Account(ocean.keeper)
|
||||
ocean.asset = new Asset(ocean.keeper)
|
||||
return ocean
|
||||
|
||||
if (!Ocean.instance) {
|
||||
ConfigProvider.configure(config)
|
||||
Ocean.instance = new Ocean()
|
||||
}
|
||||
|
||||
return Ocean.instance
|
||||
}
|
||||
|
||||
public account: Account
|
||||
public order: Order
|
||||
public tribe: Tribe
|
||||
public asset: Asset
|
||||
public helper: Web3Helper
|
||||
public metadata: MetaData
|
||||
private static instance = null
|
||||
|
||||
private keeper: Keeper
|
||||
public async getAccounts(): Promise<Account[]> {
|
||||
|
||||
private constructor(config: Config) {
|
||||
// retrieve eth accounts
|
||||
const ethAccounts = await Web3Provider.getWeb3().eth.getAccounts()
|
||||
|
||||
this.helper = new Web3Helper(config)
|
||||
this.metadata = new MetaData(config)
|
||||
return ethAccounts
|
||||
.map((address: string) => {
|
||||
return new Account(address)
|
||||
})
|
||||
}
|
||||
|
||||
public async register(asset: Asset): Promise<Asset> {
|
||||
const {market} = await Keeper.getInstance()
|
||||
|
||||
// generate an id
|
||||
const assetId = await market.generateId(asset.name + asset.description)
|
||||
Logger.log(`Registering: ${assetId} with price ${asset.price}`)
|
||||
asset.setId(assetId)
|
||||
// register asset in the market
|
||||
const result = await market.register(asset.getId(), asset.price, asset.publisher.getId())
|
||||
Logger.log("Registered:", assetId, "in block", result.blockNumber)
|
||||
|
||||
return asset
|
||||
}
|
||||
|
||||
public async getOrdersByConsumer(consumer: Account): Promise<Order[]> {
|
||||
const {auth, market} = await Keeper.getInstance()
|
||||
|
||||
Logger.log("Getting orders")
|
||||
|
||||
const accessConsentRequestedData = await auth.getEventData(
|
||||
"AccessConsentRequested", {
|
||||
filter: {
|
||||
_consumer: consumer.getId(),
|
||||
},
|
||||
fromBlock: 0,
|
||||
toBlock: "latest",
|
||||
})
|
||||
|
||||
const orders = await Promise.all(
|
||||
accessConsentRequestedData
|
||||
.map(async (event: any) => {
|
||||
|
||||
const {returnValues} = event
|
||||
|
||||
const order: Order = new Order(
|
||||
await Asset.load(returnValues._resourceId),
|
||||
parseInt(returnValues._timeout, 10),
|
||||
null, null)
|
||||
|
||||
order.setId(returnValues._id)
|
||||
order.setStatus(await auth.getOrderStatus(returnValues._id))
|
||||
order.setPaid(await market.verifyOrderPayment(returnValues._id))
|
||||
|
||||
return order
|
||||
}),
|
||||
)
|
||||
|
||||
// Logger.log("Got orders:", JSON.stringify(orders, null, 2))
|
||||
Logger.log(`Got ${Object.keys(orders).length} orders`)
|
||||
|
||||
return orders
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,18 @@
|
||||
import Keeper from "../keeper/Keeper"
|
||||
export default abstract class OceanBase {
|
||||
|
||||
export default class OceanBase {
|
||||
protected id = "0x00"
|
||||
|
||||
protected keeper: Keeper
|
||||
constructor(id?) {
|
||||
if (id) {
|
||||
this.id = id
|
||||
}
|
||||
}
|
||||
|
||||
constructor(keeper: Keeper) {
|
||||
this.keeper = keeper
|
||||
public getId() {
|
||||
return this.id
|
||||
}
|
||||
|
||||
public setId(id) {
|
||||
this.id = id
|
||||
}
|
||||
}
|
||||
|
@ -1,198 +1,71 @@
|
||||
import * as EthCrypto from "eth-crypto"
|
||||
import EthEcies from "eth-ecies"
|
||||
import * as EthjsUtil from "ethereumjs-util"
|
||||
import JWT from "jsonwebtoken"
|
||||
import Asset from "../models/Asset"
|
||||
import OrderModel from "../models/Order"
|
||||
import Keeper from "../keeper/Keeper"
|
||||
import Logger from "../utils/Logger"
|
||||
import Asset from "./Asset"
|
||||
import OceanBase from "./OceanBase"
|
||||
|
||||
declare var fetch
|
||||
import Account from "./Account"
|
||||
|
||||
export default class Order extends OceanBase {
|
||||
|
||||
private static create(asset: Asset, args, key): OrderModel {
|
||||
const accessId = args._id
|
||||
Logger.log(`got new access request id: ${accessId}`)
|
||||
const order: OrderModel = {
|
||||
id: accessId,
|
||||
assetId: asset.assetId,
|
||||
asset,
|
||||
timeout: parseInt(args._timeout, 10),
|
||||
pubkey: args._pubKey,
|
||||
key,
|
||||
} as OrderModel
|
||||
// Logger.log("Created order", order)
|
||||
private paid: boolean
|
||||
private status: number
|
||||
private accessUrl: string
|
||||
private accessId: string
|
||||
|
||||
return order
|
||||
constructor(private asset: Asset, private timeout: number,
|
||||
private pubkey: string, private key: any) {
|
||||
super()
|
||||
}
|
||||
|
||||
public async getOrdersByConsumer(consumerAddress: string): Promise<OrderModel[]> {
|
||||
const {auth, market} = this.keeper
|
||||
|
||||
Logger.log("Getting orders")
|
||||
|
||||
const accessConsentRequestedData = await auth.getEventData(
|
||||
"AccessConsentRequested", {
|
||||
filter: {
|
||||
_consumer: consumerAddress,
|
||||
},
|
||||
fromBlock: 0,
|
||||
toBlock: "latest",
|
||||
})
|
||||
|
||||
const orders = await Promise.all(
|
||||
accessConsentRequestedData
|
||||
.filter((event: any) => {
|
||||
return event.returnValues._consumer === consumerAddress
|
||||
})
|
||||
// todo: this is not orders model maybe? lacking proper typing here
|
||||
.map(async (event: any) => ({
|
||||
id: event.returnValues._id,
|
||||
asset: null,
|
||||
assetId: event.returnValues._resourceId,
|
||||
timeout: parseInt(event.returnValues._timeout, 10),
|
||||
pubkey: null,
|
||||
key: null,
|
||||
status: await auth.getOrderStatus(event.returnValues._id),
|
||||
paid: await market.verifyOrderPayment(event.returnValues._id),
|
||||
} as OrderModel
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// Logger.log("Got orders:", JSON.stringify(orders, null, 2))
|
||||
Logger.log(`Got ${Object.keys(orders).length} orders`)
|
||||
|
||||
return orders
|
||||
public setAccessUrl(url: string) {
|
||||
this.accessUrl = url
|
||||
}
|
||||
|
||||
public async purchaseAsset(asset: Asset, timeout: number, buyerAddress: string): Promise<OrderModel> {
|
||||
const {token, market, auth} = this.keeper
|
||||
|
||||
const key = EthCrypto.createIdentity()
|
||||
const publicKey = EthjsUtil.privateToPublic(key.privateKey).toString("hex")
|
||||
const price = await market.getAssetPrice(asset.assetId)
|
||||
const isValid = await market.isAssetActive(asset.assetId)
|
||||
|
||||
Logger.log("The asset:", asset.assetId, "is it valid?", isValid, "it's price is:", price)
|
||||
|
||||
if (!isValid) {
|
||||
throw new Error("The Asset is not valid!")
|
||||
}
|
||||
try {
|
||||
const marketAddr = market.getAddress()
|
||||
// Allow market contract to transfer funds on the consumer"s behalf
|
||||
await token.approve(marketAddr, price, buyerAddress)
|
||||
Logger.log(`${price} tokens approved on market with id: ${marketAddr}`)
|
||||
} catch (err) {
|
||||
Logger.error("token.approve failed", err)
|
||||
}
|
||||
let order: OrderModel
|
||||
try {
|
||||
// Submit the access request
|
||||
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}`)
|
||||
order = Order.create(asset, args, key)
|
||||
} catch (err) {
|
||||
Logger.error("auth.initiateAccessRequest failed", err)
|
||||
}
|
||||
|
||||
return order
|
||||
if (false) {
|
||||
// todo: AccessRequestCommitted event is not emitted in this flow
|
||||
await auth.listenToEventOnce(
|
||||
"AccessRequestCommitted", {
|
||||
filter: {
|
||||
_id: order.id,
|
||||
},
|
||||
})
|
||||
.then((accessRequestCommittedResult) => {
|
||||
Logger.log("Got AccessRequestCommitted Event")
|
||||
|
||||
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,
|
||||
)
|
||||
})
|
||||
}
|
||||
public getAccessUrl() {
|
||||
return this.accessUrl
|
||||
}
|
||||
|
||||
private async payAsset(asset: Asset, args, order, buyerAddress) {
|
||||
const {market} = this.keeper
|
||||
public setStatus(status: number) {
|
||||
this.status = status
|
||||
}
|
||||
|
||||
public setAccessId(accessId: string) {
|
||||
Logger.log("accessId", accessId)
|
||||
this.accessId = accessId
|
||||
}
|
||||
|
||||
public getStatus() {
|
||||
return this.status
|
||||
}
|
||||
|
||||
public setPaid(paid: boolean) {
|
||||
this.paid = paid
|
||||
}
|
||||
|
||||
public getPaid() {
|
||||
return this.paid
|
||||
}
|
||||
|
||||
public getAsset() {
|
||||
return this.asset
|
||||
}
|
||||
|
||||
public getPubkey() {
|
||||
return this.pubkey
|
||||
}
|
||||
|
||||
public getTimeout() {
|
||||
return this.timeout
|
||||
}
|
||||
|
||||
public getKey() {
|
||||
return this.key
|
||||
}
|
||||
|
||||
public async pay(account: Account) {
|
||||
const {market} = await Keeper.getInstance()
|
||||
// send payment
|
||||
Logger.log("Sending payment: ", order.id, args._id, asset.publisherId, asset.price, order.timeout)
|
||||
return market.payAsset(asset, order, buyerAddress)
|
||||
}
|
||||
|
||||
private async finalizePurchaseAsset(args, order, key, buyerAddress): Promise<OrderModel> {
|
||||
const {auth, web3Helper} = this.keeper
|
||||
|
||||
const encryptedAccessToken = await auth.getEncryptedAccessToken(args._id, buyerAddress)
|
||||
|
||||
// grab the access token from acl contract
|
||||
const tokenNo0x = encryptedAccessToken.slice(2)
|
||||
const encryptedTokenBuffer = Buffer.from(tokenNo0x, "hex")
|
||||
|
||||
const privateKey = key.privateKey.slice(2)
|
||||
const accessTokenEncoded = EthEcies.Decrypt(Buffer.from(privateKey, "hex"), encryptedTokenBuffer)
|
||||
const accessToken = JWT.decode(accessTokenEncoded) // Returns a json object
|
||||
|
||||
// sign it
|
||||
const hexEncrToken = `0x${encryptedTokenBuffer.toString("hex")}`
|
||||
|
||||
const signature = web3Helper.sign(buyerAddress, hexEncrToken)
|
||||
const fixedMsgSha = web3Helper.getWeb3().utils.sha3(encryptedAccessToken)
|
||||
|
||||
// Download the data set from the provider using the url in the access token
|
||||
// decode the access token, grab the service_endpoint, request_id,
|
||||
|
||||
// payload keys: ['consumerId', 'fixed_msg', 'sigEncJWT', 'jwt']
|
||||
const payload = JSON.stringify({
|
||||
consumerId: buyerAddress,
|
||||
fixed_msg: fixedMsgSha,
|
||||
sigEncJWT: signature,
|
||||
jwt: accessTokenEncoded,
|
||||
})
|
||||
const accessUrl = await fetch(`${accessToken.service_endpoint}/${accessToken.resource_id}`, {
|
||||
method: "POST",
|
||||
body: payload,
|
||||
headers: {
|
||||
"Content-type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.text()
|
||||
}
|
||||
Logger.log("Failed: ", response.status, response.statusText)
|
||||
})
|
||||
.then((consumptionUrl: string) => {
|
||||
Logger.log("Success accessing consume endpoint: ", consumptionUrl)
|
||||
return consumptionUrl
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("Error fetching the data asset consumption url: ", error)
|
||||
})
|
||||
Logger.log("consume url: ", accessUrl)
|
||||
order.accessUrl = accessUrl
|
||||
|
||||
return order
|
||||
Logger.log("Sending payment: ", this.getId(), this.accessId,
|
||||
this.asset.publisher.getId(), this.asset.price, this.timeout)
|
||||
return market.payOrder(this, account.getId())
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
import Web3Helper from "../keeper/Web3Helper"
|
||||
|
||||
export default class Tribe {
|
||||
|
||||
public static getInstance(web3Helper: Web3Helper) {
|
||||
|
||||
return new Tribe(web3Helper)
|
||||
}
|
||||
|
||||
private constructor(web3Helper: Web3Helper) {
|
||||
|
||||
}
|
||||
|
||||
// did ddo for tribes/marketplaces
|
||||
public registerTribe() {
|
||||
return ""
|
||||
}
|
||||
|
||||
public tribessList() {
|
||||
return ""
|
||||
}
|
||||
|
||||
public resolveTribeDID() {
|
||||
// verify DDO
|
||||
return "DDO"
|
||||
}
|
||||
}
|
5
test/config.ts
Normal file
5
test/config.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import Config from "../src/models/Config"
|
||||
|
||||
export default {
|
||||
nodeUri: "http://localhost:8545",
|
||||
} as Config
|
20
test/keeper/ContractHandler.test.ts
Normal file
20
test/keeper/ContractHandler.test.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import * as assert from "assert"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import config from "../config"
|
||||
|
||||
before(async () => {
|
||||
ConfigProvider.configure(config)
|
||||
await ContractHandler.deployContracts()
|
||||
})
|
||||
|
||||
describe("ContractHandler", () => {
|
||||
|
||||
describe("#get()", () => {
|
||||
|
||||
it("should load and get OceanToken correctly", async () => {
|
||||
assert(await ContractHandler.get("OceanTokewn") !== null)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
@ -1,18 +1,15 @@
|
||||
import * as assert from "assert"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Keeper from "../../src/keeper/Keeper"
|
||||
import Web3Helper from "../../src/keeper/Web3Helper"
|
||||
import Config from "../../src/models/Config"
|
||||
import config from "../config"
|
||||
|
||||
let keeper: Keeper
|
||||
|
||||
before(async () => {
|
||||
const config: Config = {
|
||||
nodeUri: "http://localhost:8545",
|
||||
} as Config
|
||||
const web3Helper = new Web3Helper(config)
|
||||
await ContractHandler.deployContracts(web3Helper)
|
||||
keeper = await Keeper.getInstance(config, web3Helper)
|
||||
ConfigProvider.configure(config)
|
||||
await ContractHandler.deployContracts()
|
||||
keeper = await Keeper.getInstance()
|
||||
})
|
||||
|
||||
describe("Keeper", () => {
|
||||
@ -30,9 +27,14 @@ describe("Keeper", () => {
|
||||
it("should have token", () => {
|
||||
assert(keeper.token !== null)
|
||||
})
|
||||
})
|
||||
|
||||
it("should have web3Helper", () => {
|
||||
assert(keeper.web3Helper !== null)
|
||||
describe("#getNetworkName()", () => {
|
||||
|
||||
it("should get development as default", async () => {
|
||||
const networkName: string = await keeper.getNetworkName()
|
||||
assert(networkName === "development")
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
@ -1,44 +1,39 @@
|
||||
import * as assert from "assert"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Keeper from "../../src/keeper/Keeper"
|
||||
import Web3Helper from "../../src/keeper/Web3Helper"
|
||||
import Config from "../../src/models/Config"
|
||||
import Web3Provider from "../../src/keeper/Web3Provider"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import config from "../config"
|
||||
|
||||
let keeper: Keeper
|
||||
|
||||
const config: Config = {
|
||||
nodeUri: "http://localhost:8545",
|
||||
} as Config
|
||||
const web3Helper = new Web3Helper(config)
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
|
||||
before(async () => {
|
||||
await ContractHandler.deployContracts(web3Helper)
|
||||
keeper = await Keeper.getInstance(config, web3Helper)
|
||||
ConfigProvider.configure(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
|
||||
accounts = await ocean.getAccounts()
|
||||
})
|
||||
|
||||
describe("Account", () => {
|
||||
|
||||
describe("#getTokenBalance()", () => {
|
||||
describe("#getOceanBalance()", () => {
|
||||
|
||||
it("should get initial balance", async () => {
|
||||
it("should get initial ocean balance", async () => {
|
||||
|
||||
const account = new Account(keeper)
|
||||
const accounts = await account.list()
|
||||
const addr = accounts[1].name
|
||||
const balance = await account.getTokenBalance(addr)
|
||||
const balance = await accounts[0].getOceanBalance()
|
||||
|
||||
assert(0 === balance)
|
||||
})
|
||||
|
||||
it("should get balance the correct balance", async () => {
|
||||
it("should get the correct balance", async () => {
|
||||
|
||||
const account = new Account(keeper)
|
||||
const amount: number = 100
|
||||
const accounts = await account.list()
|
||||
const addr = accounts[0].name
|
||||
await account.requestTokens(amount, addr)
|
||||
const balance = await account.getTokenBalance(addr)
|
||||
const account: Account = accounts[0]
|
||||
await account.requestTokens(amount)
|
||||
const balance = await account.getOceanBalance()
|
||||
|
||||
assert(amount === balance)
|
||||
})
|
||||
@ -48,27 +43,24 @@ describe("Account", () => {
|
||||
|
||||
it("should get initial balance", async () => {
|
||||
|
||||
const account = new Account(keeper)
|
||||
const accounts = await account.list()
|
||||
const addr = accounts[5].name
|
||||
const balance = await account.getEthBalance(addr)
|
||||
const web3 = web3Helper.getWeb3()
|
||||
const account: Account = accounts[1]
|
||||
const balance = await account.getEthBalance()
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
|
||||
assert(Number(web3.utils.toWei("100", "ether")) === balance)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#list()", () => {
|
||||
describe("#getBalance()", () => {
|
||||
|
||||
it("should list accounts", async () => {
|
||||
it("should get initial balance", async () => {
|
||||
|
||||
const account = new Account(keeper)
|
||||
const accounts = await account.list()
|
||||
const account: Account = accounts[1]
|
||||
const balance = await account.getBalance()
|
||||
const web3 = Web3Provider.getWeb3()
|
||||
|
||||
assert(10 === accounts.length)
|
||||
assert(0 === accounts[5].balance.ocn)
|
||||
assert("string" === typeof accounts[0].name)
|
||||
assert(Number(web3.utils.toWei("100", "ether")) === balance.eth)
|
||||
assert(0 === balance.ocn)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -1,73 +1,63 @@
|
||||
import * as assert from "assert"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Keeper from "../../src/keeper/Keeper"
|
||||
import Web3Helper from "../../src/keeper/Web3Helper"
|
||||
import AssetModel from "../../src/models/Asset"
|
||||
import Config from "../../src/models/Config"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Asset from "../../src/ocean/Asset"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import config from "../config"
|
||||
|
||||
let keeper: Keeper
|
||||
const testName = "Test Asset 2"
|
||||
const testDescription = "This asset is pure owange"
|
||||
const testPrice = 100
|
||||
|
||||
const config: Config = {
|
||||
nodeUri: "http://localhost:8545",
|
||||
} as Config
|
||||
const web3Helper = new Web3Helper(config)
|
||||
let ocean: Ocean
|
||||
let testAsset: Asset
|
||||
let accounts: Account[]
|
||||
let testPublisher: Account
|
||||
|
||||
before(async () => {
|
||||
await ContractHandler.deployContracts(web3Helper)
|
||||
keeper = await Keeper.getInstance(config, web3Helper)
|
||||
ConfigProvider.configure(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
testPublisher = accounts[0]
|
||||
testAsset = new Asset(testName, testDescription, testPrice, testPublisher)
|
||||
|
||||
await ocean.register(testAsset)
|
||||
})
|
||||
|
||||
describe("Asset", () => {
|
||||
|
||||
describe("#register()", () => {
|
||||
|
||||
it("should register asset", async () => {
|
||||
|
||||
const account = new Account(keeper)
|
||||
const accounts = await account.list()
|
||||
const addr = accounts[0].name
|
||||
|
||||
const name = "Test Asset"
|
||||
const description = "This asset is pure owange"
|
||||
const price = 100
|
||||
|
||||
const asset = new Asset(keeper)
|
||||
const finalAsset: AssetModel = await asset.registerAsset(name, description, price, addr)
|
||||
|
||||
assert(finalAsset.assetId.length === 66)
|
||||
assert(finalAsset.assetId.startsWith("0x"))
|
||||
assert(finalAsset.publisherId === addr)
|
||||
assert(finalAsset.price === price)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#isAssetActive()", () => {
|
||||
describe("#isActive()", () => {
|
||||
|
||||
it("should return true on new asset", async () => {
|
||||
|
||||
const account = new Account(keeper)
|
||||
const accounts = await account.list()
|
||||
const addr = accounts[0].name
|
||||
|
||||
const name = "Test Asset 2"
|
||||
const description = "This asset is pure owange"
|
||||
const price = 100
|
||||
|
||||
const asset = new Asset(keeper)
|
||||
const finalAsset = await asset.registerAsset(name, description, price, addr)
|
||||
|
||||
const isAssetActive = await asset.isAssetActive(finalAsset.assetId)
|
||||
const isAssetActive = await testAsset.isActive()
|
||||
assert(true === isAssetActive)
|
||||
})
|
||||
|
||||
it("should return false on unknown asset", async () => {
|
||||
|
||||
const asset = new Asset(keeper)
|
||||
|
||||
const isAssetActive = await asset.isAssetActive("0x0000")
|
||||
const isAssetActive = await new Asset(testName, testDescription, testPrice, testPublisher)
|
||||
.isActive()
|
||||
assert(false === isAssetActive)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#purchase()", () => {
|
||||
|
||||
it("should purchase an asset", async () => {
|
||||
|
||||
// todo
|
||||
await testAsset.purchase(accounts[5], 10000)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#purchase()", () => {
|
||||
|
||||
it("should purchase an asset", async () => {
|
||||
// todo
|
||||
// await testAsset.finalizePurchaseAsset()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,43 +1,67 @@
|
||||
import * as assert from "assert"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Web3Helper from "../../src/keeper/Web3Helper"
|
||||
import Config from "../../src/models/Config"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Asset from "../../src/ocean/Asset"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import Logger from "../../src/utils/Logger"
|
||||
import config from "../config"
|
||||
|
||||
let ocean: Ocean
|
||||
let accounts: Account[]
|
||||
|
||||
before(async () => {
|
||||
const config: Config = {
|
||||
nodeUri: "http://localhost:8545",
|
||||
} as Config
|
||||
const web3Helper = new Web3Helper(config)
|
||||
await ContractHandler.deployContracts(web3Helper)
|
||||
ConfigProvider.configure(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
})
|
||||
|
||||
describe("Ocean", () => {
|
||||
|
||||
describe("public interface", () => {
|
||||
describe("#getAccounts()", () => {
|
||||
|
||||
it("should have tribe", async () => {
|
||||
it("should list accounts", async () => {
|
||||
|
||||
assert(ocean.tribe !== null)
|
||||
const accs: Account[] = await ocean.getAccounts()
|
||||
|
||||
assert(10 === accs.length)
|
||||
assert(0 === (await accs[5].getBalance()).ocn)
|
||||
assert("string" === typeof accs[0].getId())
|
||||
})
|
||||
|
||||
it("should have account", async () => {
|
||||
})
|
||||
|
||||
assert(ocean.account !== null)
|
||||
})
|
||||
describe("#register()", () => {
|
||||
|
||||
it("should have order", async () => {
|
||||
it("should register an asset", async () => {
|
||||
|
||||
assert(ocean.order !== null)
|
||||
})
|
||||
const publisher: Account = accounts[0]
|
||||
|
||||
it("should have asset", async () => {
|
||||
const name = "Test Asset 3"
|
||||
const description = "This asset is pure owange"
|
||||
const price = 100
|
||||
|
||||
assert(ocean.asset !== null)
|
||||
const asset = new Asset(name, description, price, publisher)
|
||||
|
||||
const finalAsset: Asset = await ocean.register(asset)
|
||||
|
||||
assert(finalAsset.getId().length === 66)
|
||||
assert(finalAsset.getId().startsWith("0x"))
|
||||
assert(finalAsset.publisher === publisher)
|
||||
assert(finalAsset.price === price)
|
||||
})
|
||||
})
|
||||
|
||||
describe("#getOrdersByConsumer()", () => {
|
||||
|
||||
it("should list orders", async () => {
|
||||
|
||||
// todo
|
||||
const orders = await ocean.getOrdersByConsumer(accounts[1])
|
||||
Logger.log(orders)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
30
test/ocean/OceanBase.test.ts
Normal file
30
test/ocean/OceanBase.test.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import * as assert from "assert"
|
||||
import OceanBase from "./OceanBaseMock"
|
||||
|
||||
describe("OceanBase", () => {
|
||||
|
||||
describe("#getId()", () => {
|
||||
|
||||
it("should get the id", async () => {
|
||||
|
||||
const id = "test"
|
||||
const oceanBase = new OceanBase(id)
|
||||
|
||||
assert(oceanBase.getId() === id)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#setId()", () => {
|
||||
|
||||
it("should get the id", async () => {
|
||||
|
||||
const id = "test"
|
||||
const oceanBase = new OceanBase()
|
||||
oceanBase.setId(id)
|
||||
|
||||
assert(oceanBase.getId() === id)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
5
test/ocean/OceanBaseMock.ts
Normal file
5
test/ocean/OceanBaseMock.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import OceanBase from "../../src/ocean/OceanBase"
|
||||
|
||||
export default class OceanBaseMock extends OceanBase {
|
||||
|
||||
}
|
@ -1,86 +1,44 @@
|
||||
import * as assert from "assert"
|
||||
import ConfigProvider from "../../src/ConfigProvider"
|
||||
import ContractHandler from "../../src/keeper/ContractHandler"
|
||||
import Keeper from "../../src/keeper/Keeper"
|
||||
import Web3Helper from "../../src/keeper/Web3Helper"
|
||||
import AssetModel from "../../src/models/Asset"
|
||||
import Config from "../../src/models/Config"
|
||||
import OrderModel from "../../src/models/Order"
|
||||
import Account from "../../src/ocean/Account"
|
||||
import Asset from "../../src/ocean/Asset"
|
||||
import Ocean from "../../src/ocean/Ocean"
|
||||
import Order from "../../src/ocean/Order"
|
||||
import config from "../config"
|
||||
|
||||
let keeper: Keeper
|
||||
let testAsset: AssetModel
|
||||
let accounts
|
||||
let buyerAddr
|
||||
const testName = "Test Asset 333"
|
||||
const testDescription = "This asset is pure owange"
|
||||
const testPrice = 100
|
||||
|
||||
const config: Config = {
|
||||
nodeUri: "http://localhost:8545",
|
||||
} as Config
|
||||
const web3Helper = new Web3Helper(config)
|
||||
let ocean: Ocean
|
||||
let testAsset: Asset
|
||||
let accounts: Account[]
|
||||
let testPublisher: Account
|
||||
|
||||
before(async () => {
|
||||
await ContractHandler.deployContracts(web3Helper)
|
||||
keeper = await Keeper.getInstance(config, web3Helper)
|
||||
|
||||
const account = new Account(keeper)
|
||||
accounts = await account.list()
|
||||
|
||||
const sellerAddr = accounts[0].name
|
||||
buyerAddr = accounts[2].name
|
||||
|
||||
const name = "Order Test Asset"
|
||||
const description = "This asset is pure owange"
|
||||
const price = 100
|
||||
|
||||
const asset = new Asset(keeper)
|
||||
testAsset = await asset.registerAsset(name, description, price, sellerAddr)
|
||||
|
||||
// get tokens
|
||||
await account.requestTokens(1000000000000000, buyerAddr)
|
||||
ConfigProvider.configure(config)
|
||||
await ContractHandler.deployContracts()
|
||||
ocean = await Ocean.getInstance(config)
|
||||
accounts = await ocean.getAccounts()
|
||||
testPublisher = accounts[0]
|
||||
// register an asset to play around with
|
||||
testAsset = new Asset(testName, testDescription, testPrice, testPublisher)
|
||||
await ocean.register(testAsset)
|
||||
})
|
||||
|
||||
const timeout = 100000000000
|
||||
|
||||
describe("Order", () => {
|
||||
|
||||
describe("#purchaseAsset()", () => {
|
||||
describe("#pay()", () => {
|
||||
|
||||
it("should purchase an asset", async () => {
|
||||
it("should pay for the order", async () => {
|
||||
|
||||
const order = new Order(keeper)
|
||||
const finalOrder: OrderModel = await order.purchaseAsset(testAsset, timeout, buyerAddr)
|
||||
const order: Order = await testAsset.purchase(accounts[0], 10000)
|
||||
assert(order)
|
||||
|
||||
assert(finalOrder.assetId === testAsset.assetId)
|
||||
assert(finalOrder.asset.assetId === testAsset.assetId)
|
||||
assert(finalOrder.timeout === timeout)
|
||||
await order.pay(accounts[0])
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe("#getOrdersByConsumer()", () => {
|
||||
|
||||
it("should get orders by consumer if there is one", async () => {
|
||||
|
||||
const order = new Order(keeper)
|
||||
const finalOrder: OrderModel = await order.purchaseAsset(testAsset, timeout, buyerAddr)
|
||||
|
||||
const orders: OrderModel[] = await order.getOrdersByConsumer(buyerAddr)
|
||||
const datOrder = (await orders.filter((o) => o.id === finalOrder.id))[0]
|
||||
|
||||
assert(datOrder !== null)
|
||||
assert(datOrder.assetId === testAsset.assetId)
|
||||
assert(datOrder.timeout === timeout)
|
||||
assert(datOrder.paid === true)
|
||||
assert(datOrder.status === 0)
|
||||
})
|
||||
|
||||
it("should return empty array if no orders found", async () => {
|
||||
|
||||
const order = new Order(keeper)
|
||||
|
||||
const orders: OrderModel[] = await order.getOrdersByConsumer(accounts[4].name)
|
||||
|
||||
assert(orders.length === 0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user