1
0
mirror of https://github.com/oceanprotocol/react.git synced 2025-02-14 21:10:38 +01:00
react/src/hooks/useTrade/useTrade.ts
2020-10-16 05:06:34 -07:00

184 lines
5.4 KiB
TypeScript

import { Logger } from '@oceanprotocol/lib'
import { useState } from 'react'
import { useOcean } from 'providers'
import { TransactionReceipt } from 'web3-core'
import { getBestDataTokenPrice, getFirstPool } from 'utils/dtUtils'
import { Decimal } from 'decimal.js'
interface UseTrade {
buyDT: (
dataTokenAddress: string,
dtAmount: number | string
) => Promise<TransactionReceipt | null>
sellDT: (
dataTokenAddress: string,
dtAmount: number | string
) => Promise<TransactionReceipt | null>
tradeStep?: number
tradeStepText?: string
tradeError?: string
tradeIsLoading: boolean
}
export const buyDTFeedback: { [key in number]: string } = {
0: '1/3 Approving OCEAN ...',
1: '2/3 Buying DT ...',
2: '3/3 DT Bought'
}
export const sellDTFeedback: { [key in number]: string } = {
0: '1/3 Approving DT ...',
1: '2/3 Selling DT ...',
2: '3/3 DT sold'
}
function useTrade(): UseTrade {
const { ocean, status, account, accountId, config } = useOcean()
const [tradeIsLoading, setTradeIsLoading] = useState(false)
const [tradeStep, setTradeStep] = useState<number | undefined>()
const [tradeStepText, setTradeStepText] = useState<string | undefined>()
const [tradeError, setTradeError] = useState<string | undefined>()
const [dtSymbol, setDtSymbol] = useState<string>()
function setStepBuyDT(index?: number) {
setTradeStep(index)
let message
if (index) {
if (dtSymbol) message = buyDTFeedback[index].replace(/DT/g, dtSymbol)
else message = buyDTFeedback[index]
setTradeStepText(message)
}
}
function setStepSellDT(index?: number) {
setTradeStep(index)
let message
if (index) {
if (dtSymbol) message = sellDTFeedback[index].replace(/DT/g, dtSymbol)
else message = sellDTFeedback[index]
setTradeStepText(message)
}
}
async function buyDT(
dataTokenAddress: string,
dtAmount: number | string
): Promise<TransactionReceipt | null> {
if (!ocean || !account || !accountId) return null
try {
setDtSymbol(await ocean.datatokens.getSymbol(dataTokenAddress))
setTradeIsLoading(true)
setTradeError(undefined)
setStepBuyDT(0)
const bestPrice = await getBestDataTokenPrice(ocean, dataTokenAddress)
switch (bestPrice?.type) {
case 'pool': {
const price = new Decimal(bestPrice.value).times(1.05).toString()
const maxPrice = new Decimal(bestPrice.value).times(2).toString()
setStepBuyDT(1)
Logger.log(
'Buying token from pool',
bestPrice,
account.getId(),
price
)
const buyResponse = await ocean.pool.buyDT(
account.getId(),
bestPrice.address,
String(dtAmount),
price,
maxPrice
)
setStepBuyDT(2)
Logger.log('DT buy response', buyResponse)
return buyResponse
}
case 'exchange': {
if (!config.oceanTokenAddress) {
Logger.error(`'oceanTokenAddress' not set in config`)
return null
}
if (!config.fixedRateExchangeAddress) {
Logger.error(`'fixedRateExchangeAddress' not set in config`)
return null
}
Logger.log('Buying token from exchange', bestPrice, account.getId())
await ocean.datatokens.approve(
config.oceanTokenAddress,
config.fixedRateExchangeAddress,
bestPrice.value.toString(),
account.getId()
)
setStepBuyDT(1)
const exchange = await ocean.fixedRateExchange.buyDT(
bestPrice.address,
String(dtAmount),
account.getId()
)
setStepBuyDT(2)
Logger.log('DT exchange buy response', exchange)
return exchange
}
}
} catch (error) {
setTradeError(error.message)
Logger.error(error)
} finally {
setTradeStep(undefined)
setTradeStepText(undefined)
setTradeIsLoading(false)
}
return null
}
async function sellDT(
dataTokenAddress: string,
dtAmount: number | string
): Promise<TransactionReceipt | null> {
if (!ocean || !account || !accountId) return null
if (!config.oceanTokenAddress) {
Logger.error(`'oceanTokenAddress' not set in config`)
return null
}
try {
setDtSymbol(await ocean.datatokens.getSymbol(dataTokenAddress))
setTradeIsLoading(true)
setTradeError(undefined)
setStepSellDT(0)
const pool = await getFirstPool(ocean, dataTokenAddress)
if (!pool || pool.price === 0) return null
const price = new Decimal(pool.price).times(0.95).toString()
setStepSellDT(1)
Logger.log('Selling token to pool', pool, account.getId(), price)
const sellResponse = await ocean.pool.sellDT(
account.getId(),
pool.address,
String(dtAmount),
price
)
setStepSellDT(2)
Logger.log('DT sell response', sellResponse)
return sellResponse
} catch (error) {
setTradeError(error.message)
Logger.error(error)
} finally {
setStepSellDT(undefined)
setTradeStepText(undefined)
setTradeIsLoading(false)
}
return null
}
return {
buyDT,
sellDT,
tradeStep,
tradeStepText,
tradeIsLoading,
tradeError
}
}
export { useTrade, UseTrade }
export default useTrade