This commit is contained in:
alexcos20 2020-10-14 04:55:18 -07:00
parent 9d9360230c
commit ad270f8a39
9 changed files with 255 additions and 239 deletions

View File

@ -1,38 +0,0 @@
# `useBuy`
Buy datatoken.
## Usage
```tsx
import React from 'react'
import { useOcean, useConsume } from '@oceanprotocol/react'
const did = 'did:op:0x000000000'
export default function MyComponent() {
const { accountId } = useOcean()
// Get metadata for this asset
const { title, price, ddo } = useMetadata(did)
// Consume helpers
const { consume, consumeStep } = useConsume()
async function handleDownload() {
await consume(did, ddo.dataToken, 'access')
}
return (
<div>
<h1>{title}</h1>
<p>Price: {price}</p>
<p>Your account: {accountId}</p>
<button onClick={handleDownload}>
{consumeStep || 'Download Asset'}
</button>
</div>
)
}
```

View File

@ -1 +0,0 @@
export * from './useBuy'

View File

@ -1,110 +0,0 @@
import { useState } from 'react'
import { useOcean } from 'providers'
import { feedback } from 'utils'
import { DID, Logger, ServiceType } from '@oceanprotocol/lib'
import { getBestDataTokenPrice } from 'utils/dtUtils'
import { TransactionReceipt } from 'web3-core'
import { Decimal } from 'decimal.js'
interface UseBuy {
buyDT: (
dataTokenAddress: string,
dtAmount: number | string,
) => Promise<TransactionReceipt | null>
consumeStep?: number
consumeStepText?: string
consumeError?: string
isLoading: boolean
}
export const buyFeedback: { [key in number]: string } = {
0: '1/2 Approving OCEAN Tokens',
1: '2/3 Buying Datatoken',
2: '3/3 Bought Datatoken'
}
function useBuy(): UseBuy {
const { ocean, account, accountId, config } = useOcean()
const [isLoading, setIsLoading] = useState(false)
const [consumeStep, setConsumeStep] = useState<number | undefined>()
const [consumeStepText, setConsumeStepText] = useState<string | undefined>()
const [consumeError, setConsumeError] = useState<string | undefined>()
function setStep(index: number) {
setConsumeStep(index)
setConsumeStepText(buyFeedback[index])
}
async function buyDT(
dataTokenAddress: string,
dtAmount: number | string,
): Promise<TransactionReceipt | null> {
if (!ocean || !account || !accountId) return
setIsLoading(true)
setConsumeError(undefined)
setStep(0)
try {
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()
Logger.log('Buying token from pool', bestPrice, account.getId(), price)
const buyResponse = await ocean.pool.buyDT(
account.getId(),
bestPrice.address,
String(dtAmount),
price,
maxPrice
)
setStep(2)
Logger.log('DT buy response', buyResponse)
return buyResponse
}
case 'exchange': {
if (!config.oceanTokenAddress) {
Logger.error(`'oceanTokenAddress' not set in config`)
return
}
if (!config.fixedRateExchangeAddress) {
Logger.error(`'fixedRateExchangeAddress' not set in config`)
return
}
Logger.log('Buying token from exchange', bestPrice, account.getId())
await ocean.datatokens.approve(
config.oceanTokenAddress,
config.fixedRateExchangeAddress,
bestPrice.value.toString(),
account.getId()
)
setStep(1)
const exchange = await ocean.fixedRateExchange.buyDT(
bestPrice.address,
String(dtAmount),
account.getId()
)
setStep(2)
Logger.log('DT exchange buy response', exchange)
return exchange
}
}
} catch (error) {
setConsumeError(error.message)
Logger.error(error)
} finally {
setConsumeStep(undefined)
setConsumeStepText(undefined)
setIsLoading(false)
}
}
return { buyDT, consumeStep, consumeStepText, consumeError, isLoading }
}
export { useBuy, UseBuy }
export default useBuy

View File

@ -1,2 +0,0 @@
export * from './usePostforSale'
export * from './PriceOptions'

View File

@ -1,84 +0,0 @@
import { DID, DDO, Logger, Metadata } from '@oceanprotocol/lib'
import {
Service,
ServiceComputePrivacy,
ServiceType
} from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service'
import { useState } from 'react'
import { useOcean } from 'providers'
import ProviderStatus from 'providers/OceanProvider/ProviderStatus'
import { publishFeedback } from 'utils'
import { PriceOptions } from './PriceOptions'
interface UsePostforSale {
createPricing: (
dataTokenAddress: string,
priceOptions: PriceOptions,
) => Promise<void | null>
publishStep?: number
publishStepText?: string
publishError?: string
isLoading: boolean
}
function usePostforSale(): UsePostforSale {
const { ocean, status, account, accountId, config } = useOcean()
const [isLoading, setIsLoading] = useState(false)
const [publishStep, setPublishStep] = useState<number | undefined>()
const [publishStepText, setPublishStepText] = useState<string | undefined>()
const [publishError, setPublishError] = useState<string | undefined>()
function setStep(index?: number) {
setPublishStep(index)
index && setPublishStepText(publishFeedback[index])
}
async function createPricing(
dataTokenAddress: string,
priceOptions: PriceOptions
): Promise<void | null> {
switch (priceOptions.type) {
case 'dynamic': {
await ocean.pool.createDTPool(
accountId,
dataTokenAddress,
priceOptions.dtAmount.toString(),
priceOptions.weightOnDataToken,
priceOptions.swapFee
)
break
}
case 'fixed': {
if (!config.fixedRateExchangeAddress) {
Logger.error(`'fixedRateExchangeAddress' not set in ccnfig.`)
return null
}
await ocean.fixedRateExchange.create(
dataTokenAddress,
priceOptions.price.toString(),
accountId
)
await ocean.datatokens.approve(
dataTokenAddress,
config.fixedRateExchangeAddress,
priceOptions.dtAmount,
accountId
)
break
}
}
}
return {
createPricing,
publishStep,
publishStepText,
isLoading,
publishError
}
}
export { usePostforSale, UsePostforSale }
export default usePostforSale

View File

@ -1,6 +1,8 @@
# `usePublish`
# `usePricing`
Post asset for sale by creating liquidity pools or fixed rate exchange
Buy DT
Sell DT
## Usage
@ -13,7 +15,7 @@ export default function MyComponent() {
const { accountId } = useOcean()
// Publish helpers
const { publish, publishStep } = usePostforSale()
const { createPricing, buyDT, sellDT } = usePricing()
const priceOptions = {
price: 10,
@ -23,16 +25,25 @@ export default function MyComponent() {
swapFee: ''
}
async function handlePostforSale() {
async function handleCreatePricing() {
const ddo = await createPricing(dataTokenAddress, priceOptions)
}
async function handleBuyDT() {
const ddo = await buyDT(dataTokenAddress, 1)
}
async function handleSellDT() {
const ddo = await sellDT(dataTokenAddress, 1)
}
return (
<div>
<h1>Post for sale</h1>
<p>Your account: {accountId}</p>
<button onClick={handlePostforSale}>Post for sale</button>
<button onClick={handleCreatePricing}>Post for sale</button>
<button onClick={handleBuyDT}>Buy DT</button>
<button onClick={handleSellDT}>Sell DT</button>
</div>
)
}

View File

@ -0,0 +1,2 @@
export * from './usePricing'
export * from './PriceOptions'

View File

@ -0,0 +1,238 @@
import { DID, DDO, Logger, Metadata } from '@oceanprotocol/lib'
import {
Service,
ServiceComputePrivacy,
ServiceType
} from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service'
import { useState } from 'react'
import { useOcean } from 'providers'
import ProviderStatus from 'providers/OceanProvider/ProviderStatus'
import { publishFeedback } from 'utils'
import { PriceOptions } from './PriceOptions'
import { TransactionReceipt } from 'web3-core'
import { getBestDataTokenPrice, getFirstPool } from 'utils/dtUtils'
import { Decimal } from 'decimal.js'
interface UsePricing {
createPricing: (
dataTokenAddress: string,
priceOptions: PriceOptions,
) => Promise<TransactionReceipt | null>
buyDT: (
dataTokenAddress: string,
dtAmount: number | string,
) => Promise<TransactionReceipt | null>
sellDT: (
dataTokenAddress: string,
dtAmount: number | string,
) => Promise<TransactionReceipt | null>
pricingStep?: number
pricingStepText?: string
pricingError?: string
isLoading: 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'
}
export const createPricingFeedback:{ [key in number]: string } = {
0: '1/4 Approving DT ...',
1: '2/4 Approving Ocean ...',
2: '3/4 Creating ....',
3: '4/4 Pricing created',
}
function usePricing(): UsePricing {
const { ocean, status, account, accountId, config } = useOcean()
const [isLoading, setIsLoading] = useState(false)
const [pricingStep, setPricingStep] = useState<number | undefined>()
const [pricingStepText, setPricingStepText] = useState<string | undefined>()
const [pricingError, setPricingError] = useState<string | undefined>()
function setStepBuyDT(index?: number) {
setPricingStep(index)
index && setPricingStepText(buyDTFeedback[index])
}
function setStepSellDT(index?: number) {
setPricingStep(index)
index && setPricingStepText(sellDTFeedback[index])
}
function setStepCreatePricing(index?: number) {
setPricingStep(index)
index && setPricingStepText(createPricingFeedback[index])
}
async function createPricing(
dataTokenAddress: string,
priceOptions: PriceOptions
): Promise<TransactionReceipt | null> {
setStepCreatePricing(0)
let response = null
try{
switch (priceOptions.type) {
case 'dynamic': {
setStepCreatePricing(2)
response=await ocean.pool.createDTPool(
accountId,
dataTokenAddress,
priceOptions.dtAmount.toString(),
priceOptions.weightOnDataToken,
priceOptions.swapFee
)
setStepCreatePricing(3)
return response
}
case 'fixed': {
if (!config.fixedRateExchangeAddress) {
Logger.error(`'fixedRateExchangeAddress' not set in ccnfig.`)
return null
}
setStepCreatePricing(2)
response=await ocean.fixedRateExchange.create(
dataTokenAddress,
priceOptions.price.toString(),
accountId
)
setStepCreatePricing(1)
await ocean.datatokens.approve(
dataTokenAddress,
config.fixedRateExchangeAddress,
priceOptions.dtAmount,
accountId
)
setStepCreatePricing(3)
return response
}
}
}
catch (error) {
setPricingError(error.message)
Logger.error(error)
} finally {
setPricingStep(undefined)
setPricingStepText(undefined)
setIsLoading(false)
}
}
async function buyDT(
dataTokenAddress: string,
dtAmount: number | string,
): Promise<TransactionReceipt | null> {
if (!ocean || !account || !accountId) return
setIsLoading(true)
setPricingError(undefined)
setStepBuyDT(0)
try {
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
}
if (!config.fixedRateExchangeAddress) {
Logger.error(`'fixedRateExchangeAddress' not set in config`)
return
}
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) {
setPricingError(error.message)
Logger.error(error)
} finally {
setPricingStep(undefined)
setPricingStepText(undefined)
setIsLoading(false)
}
}
async function sellDT(
dataTokenAddress: string,
dtAmount: number | string,
): Promise<TransactionReceipt | null> {
if (!ocean || !account || !accountId) return
setIsLoading(true)
setPricingError(undefined)
setStepSellDT(0)
try {
const pool=await getFirstPool(ocean, dataTokenAddress)
const price = new Decimal(pool.value).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) {
setPricingError(error.message)
Logger.error(error)
} finally {
setStepSellDT(undefined)
setPricingStepText(undefined)
setIsLoading(false)
}
}
return {
createPricing,
buyDT,
sellDT,
pricingStep,
pricingStepText,
isLoading,
pricingError
}
}
export { usePricing, UsePricing }
export default usePricing