1
0
mirror of https://github.com/oceanprotocol/ocean.js.git synced 2024-11-26 20:39:05 +01:00

Merge pull request #389 from oceanprotocol/feature/subscribe_features

make create methods subscribable
This commit is contained in:
Matthias Kretschmann 2020-10-21 13:53:07 +02:00 committed by GitHub
commit 616e67d372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 92 deletions

View File

@ -4,7 +4,7 @@ import { TransactionReceipt } from 'web3-core'
import { Pool } from './Pool'
import { EventData, Filter } from 'web3-eth-contract'
import BigNumber from 'bignumber.js'
import { SubscribablePromise } from '../utils'
declare type PoolTransactionType = 'swap' | 'join' | 'exit'
const POOL_MAX_AMOUNT_IN_LIMIT = 0.25 // maximum 1/4 of the pool reserve
@ -34,6 +34,13 @@ export interface PoolTransaction {
type: PoolTransactionType
}
export enum PoolCreateProgressStep {
CreatingPool,
ApprovingDatatoken,
ApprovingOcean,
SetupPool
}
/**
* Ocean Pools submodule exposed under ocean.pool
*/
@ -64,13 +71,13 @@ export class OceanPool extends Pool {
* @param {String} fee Swap fee. E.g. to get a 0.1% swapFee use `0.001`. The maximum allowed swapFee is `0.1` (10%).
* @return {String}
*/
public async createDTPool(
public create(
account: string,
token: string,
amount: string,
weight: string,
fee: string
): Promise<string> {
): SubscribablePromise<PoolCreateProgressStep, TransactionReceipt> {
if (this.oceanAddress == null) {
console.error('ERROR: oceanAddress is not defined')
return null
@ -83,47 +90,58 @@ export class OceanPool extends Pool {
console.error('ERROR: Weight out of bounds (min 1, max9)')
return null
}
const address = await super.createPool(account)
const oceanWeight = 10 - parseFloat(weight)
const oceanAmount = (parseFloat(amount) * oceanWeight) / parseFloat(weight)
this.dtAddress = token
let txid
txid = await this.approve(
account,
token,
address,
this.web3.utils.toWei(String(amount))
)
if (!txid) {
console.error('ERROR: Failed to call approve DT token')
return null
}
txid = await this.approve(
account,
this.oceanAddress,
address,
this.web3.utils.toWei(String(oceanAmount))
)
if (!txid) {
console.error('ERROR: Failed to call approve OCEAN token')
return null
}
txid = await super.setup(
account,
address,
token,
this.web3.utils.toWei(String(amount)),
this.web3.utils.toWei(String(weight)),
this.oceanAddress,
this.web3.utils.toWei(String(oceanAmount)),
this.web3.utils.toWei(String(oceanWeight)),
this.web3.utils.toWei(fee)
)
if (!txid) {
console.error('ERROR: Failed to create a new pool')
return null
}
return address
return new SubscribablePromise(async (observer) => {
observer.next(PoolCreateProgressStep.CreatingPool)
const createTxid = await super.createPool(account)
if (!createTxid) {
console.error('ERROR: Failed to call approve DT token')
return null
}
const address = createTxid.events.BPoolRegistered.returnValues[0]
const oceanWeight = 10 - parseFloat(weight)
const oceanAmount = (parseFloat(amount) * oceanWeight) / parseFloat(weight)
this.dtAddress = token
observer.next(PoolCreateProgressStep.ApprovingDatatoken)
let txid
txid = await this.approve(
account,
token,
address,
this.web3.utils.toWei(String(amount))
)
if (!txid) {
console.error('ERROR: Failed to call approve DT token')
return null
}
observer.next(PoolCreateProgressStep.ApprovingOcean)
txid = await this.approve(
account,
this.oceanAddress,
address,
this.web3.utils.toWei(String(oceanAmount))
)
if (!txid) {
console.error('ERROR: Failed to call approve OCEAN token')
return null
}
observer.next(PoolCreateProgressStep.SetupPool)
txid = await super.setup(
account,
address,
token,
this.web3.utils.toWei(String(amount)),
this.web3.utils.toWei(String(weight)),
this.oceanAddress,
this.web3.utils.toWei(String(oceanAmount)),
this.web3.utils.toWei(String(oceanWeight)),
this.web3.utils.toWei(fee)
)
if (!txid) {
console.error('ERROR: Failed to create a new pool')
return null
}
return createTxid
})
}
/**

View File

@ -36,7 +36,7 @@ export class Pool extends PoolFactory {
/**
* Creates a new pool
*/
async createPool(account: string): Promise<string> {
async createPool(account: string): Promise<TransactionReceipt> {
return await super.createPool(account)
}

View File

@ -1,6 +1,7 @@
import Web3 from 'web3'
import { AbiItem } from 'web3-utils/types'
import jsonFactoryABI from '@oceanprotocol/contracts/artifacts/BFactory.json'
import { TransactionReceipt } from 'web3-core'
export class PoolFactory {
public GASLIMIT_DEFAULT = 5000000
@ -27,7 +28,7 @@ export class PoolFactory {
/**
* Creates a new pool
*/
async createPool(account: string): Promise<string> {
async createPool(account: string): Promise<TransactionReceipt> {
if (this.web3 === null) {
console.error('ERROR: Web3 object is null')
return null
@ -41,18 +42,15 @@ export class PoolFactory {
const factory = new this.web3.eth.Contract(this.factoryABI, this.factoryAddress, {
from: account
})
const transactiondata = await factory.methods
.newBPool()
.send({ from: account, gas: this.GASLIMIT_DEFAULT })
let pooladdress: string
let txid = null
try {
pooladdress = transactiondata.events.BPoolRegistered.returnValues[0]
txid = await factory.methods
.newBPool()
.send({ from: account, gas: this.GASLIMIT_DEFAULT })
// pooladdress = transactiondata.events.BPoolRegistered.returnValues[0]
} catch (e) {
console.error(`ERROR: Failed to create new pool: ${e.message}`)
}
return pooladdress
return txid
}
}

View File

@ -4,6 +4,8 @@ import { TransactionReceipt } from 'web3-core'
import { Contract, EventData } from 'web3-eth-contract'
import { AbiItem } from 'web3-utils/types'
import Web3 from 'web3'
import { SubscribablePromise } from '../utils'
import { DataTokens } from '../datatokens/Datatokens'
export interface FixedPriceExchange {
exchangeID?: string
@ -21,6 +23,12 @@ export interface FixedPriceSwap {
baseTokenAmount: string
dataTokenAmount: string
}
export enum FixedRateCreateProgressStep {
CreatingExchange,
ApprovingDatatoken
}
const DEFAULT_GAS_LIMIT = 300000
export class OceanFixedRateExchange {
@ -30,6 +38,7 @@ export class OceanFixedRateExchange {
public fixedRateExchangeABI: AbiItem | AbiItem[]
public web3: Web3
public contract: Contract = null
public datatokens: DataTokens
/**
* Instantiate FixedRateExchange
@ -42,13 +51,15 @@ export class OceanFixedRateExchange {
web3: Web3,
fixedRateExchangeAddress: string = null,
fixedRateExchangeABI: AbiItem | AbiItem[] = null,
oceanAddress: string = null
oceanAddress: string = null,
datatokens: DataTokens
) {
this.web3 = web3
this.fixedRateExchangeAddress = fixedRateExchangeAddress
this.fixedRateExchangeABI =
fixedRateExchangeABI || (defaultFixedRateExchangeABI.abi as AbiItem[])
this.oceanAddress = oceanAddress
this.datatokens = datatokens
if (web3)
this.contract = new this.web3.eth.Contract(
this.fixedRateExchangeABI,
@ -61,39 +72,52 @@ export class OceanFixedRateExchange {
* @param {String} dataToken Data Token Contract Address
* @param {Number} rate exchange rate
* @param {String} address User address
* @return {Promise<string>} exchangeId
* @param {String} amount Optional, amount of datatokens to be approved for the exchange
* @return {Promise<TransactionReceipt>} TransactionReceipt
*/
public async create(dataToken: string, rate: string, address: string): Promise<string> {
let estGas
try {
/* estGas = await this.contract.methods
.create(this.oceanAddress, dataToken, this.web3.utils.toWei(rate))
.estimateGas(function (err, g) {
if (err) {
return DEFAULT_GAS_LIMIT
} else {
return g
}
})
*/
estGas = DEFAULT_GAS_LIMIT
} catch (e) {
estGas = DEFAULT_GAS_LIMIT
}
let exchangeId = null
try {
const trxReceipt = await this.contract.methods
.create(this.oceanAddress, dataToken, this.web3.utils.toWei(rate))
.send({
from: address,
gas: estGas + 1
})
exchangeId = trxReceipt.events.ExchangeCreated.returnValues[0]
} catch (e) {
console.error(`ERROR: Failed to create new exchange: ${e.message}`)
}
return exchangeId
public create(
dataToken: string,
rate: string,
address: string,
amount?: string
): SubscribablePromise<FixedRateCreateProgressStep, TransactionReceipt> {
return new SubscribablePromise(async (observer) => {
observer.next(FixedRateCreateProgressStep.CreatingExchange)
let estGas
try {
/* estGas = await this.contract.methods
.create(this.oceanAddress, dataToken, this.web3.utils.toWei(rate))
.estimateGas(function (err, g) {
if (err) {
return DEFAULT_GAS_LIMIT
} else {
return g
}
})
*/
estGas = DEFAULT_GAS_LIMIT
} catch (e) {
estGas = DEFAULT_GAS_LIMIT
}
let exchangeId = null
let trxReceipt = null
try {
trxReceipt = await this.contract.methods
.create(this.oceanAddress, dataToken, this.web3.utils.toWei(rate))
.send({
from: address,
gas: estGas + 1
})
exchangeId = trxReceipt.events.ExchangeCreated.returnValues[0]
} catch (e) {
console.error(`ERROR: Failed to create new exchange: ${e.message}`)
}
if (amount && exchangeId) {
observer.next(FixedRateCreateProgressStep.ApprovingDatatoken)
this.datatokens.approve(dataToken, this.fixedRateExchangeAddress, amount, address)
}
return trxReceipt
})
}
/**

View File

@ -63,7 +63,8 @@ export class Ocean extends Instantiable {
instanceConfig.config.web3Provider,
instanceConfig.config.fixedRateExchangeAddress,
instanceConfig.config.fixedRateExchangeAddressABI,
instanceConfig.config.oceanTokenAddress
instanceConfig.config.oceanTokenAddress,
instance.datatokens
)
instance.OnChainMetadataCache = new OnChainMetadataCache(
instanceConfig.config.web3Provider,

View File

@ -121,7 +121,8 @@ describe('Balancer flow', () => {
})
it('Alice creates a new OceanPool pool', async () => {
/// new pool with total DT = 45 , dt weight=90% with swap fee 2%
alicePoolAddress = await Pool.createDTPool(alice, tokenAddress, '45', '9', '0.02')
const createTx = await Pool.create(alice, tokenAddress, '45', '9', '0.02')
alicePoolAddress = createTx.events.BPoolRegistered.returnValues[0]
const s = await Pool.getPoolSharesTotalSupply(alicePoolAddress)
assert(String(s) === '100', 'totalSupply does not match: ' + s)
const n = await Pool.getNumTokens(alicePoolAddress)

View File

@ -107,7 +107,8 @@ describe('FixedRateExchange flow', () => {
web3,
FixedRateExchangeAddress,
FixedRateExchangeContract.abi as AbiItem[],
oceanTokenAddress
oceanTokenAddress,
datatoken
)
assert(FixedRateClass !== null)
})
@ -167,7 +168,8 @@ describe('FixedRateExchange flow', () => {
if (consoleDebug) console.log('Bob ocean allowance:' + balance)
})
it('Alice creates a new FixedRate Exchange with a rate of 0.5', async () => {
aliceExchangeId = await FixedRateClass.create(tokenAddress, fixedPriceRate, alice)
const trxReceipt = await FixedRateClass.create(tokenAddress, fixedPriceRate, alice)
aliceExchangeId = trxReceipt.events.ExchangeCreated.returnValues[0]
if (consoleDebug) console.log('aliceExchangeId:' + aliceExchangeId)
})
it('Bob should find the exchange', async () => {