diff --git a/example/src/App.tsx b/example/src/App.tsx index cfe4efa..ace802b 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -8,6 +8,7 @@ import { AllDdos } from './AllDdos' import { ConsumeDdo } from './ConsumeDdo' import { NetworkMonitor } from './NetworkMonitor' import { LogLevel } from '@oceanprotocol/lib/dist/node/utils' +import { Pricing } from './Pricing' const configRinkeby = new ConfigHelper().getConfig('rinkeby') const providerOptions = {} @@ -39,6 +40,9 @@ function App() {
+
+ +
diff --git a/example/src/Pricing.tsx b/example/src/Pricing.tsx new file mode 100644 index 0000000..c4d63f8 --- /dev/null +++ b/example/src/Pricing.tsx @@ -0,0 +1,57 @@ +import React from 'react' +import { useOcean, usePricing } from '@oceanprotocol/react' +// import { useOcean, usePublish } from '@oceanprotocol/react' +import { DDO } from '@oceanprotocol/lib' +import { useState } from 'react' +import { Metadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Metadata' + +export function Trade() { + const { ocean, accountId } = useOcean() + const { createPricing,buyDT,sellDT,mint,pricingStep,pricingStepText,pricingIsLoading, pricingError} = usePricing() + const [datatoken, setDatatoken] = useState() + const handleBuy = async () => { + const tx = await buyDT(datatoken,'1') + console.log(tx) + } + const handleSell = async () => { + const tx = await buyDT(datatoken,'1') + console.log(tx) + } + const handleChange = (e: any) => { + setDatatoken(e.target.value) + } + const handlePostForSale = async () => { + if(datatoken){ + const priceOptions = { + price: 7, + dtAmount: 10, + type: 'fixed', + weightOnDataToken: '', + swapFee: '' + } + const tx = await createPricing(datatoken,priceOptions) + console.log(tx) + } + } + return ( + <> +
Trade Datatoken
+
+ Datatoken +
+
+ +
+
+ +
+
+ +
+
+ IsLoading: {pricingIsLoading.toString()} || Status: {pricingStepText} +
+ + + ) +} diff --git a/example/src/Publish.tsx b/example/src/Publish.tsx index 326b61f..6e7e46c 100644 --- a/example/src/Publish.tsx +++ b/example/src/Publish.tsx @@ -1,12 +1,12 @@ import React from 'react' import { usePublish } from '@oceanprotocol/react' -// import { useOcean, usePublish } from '@oceanprotocol/react' import { DDO } from '@oceanprotocol/lib' import { useState } from 'react' import { Metadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Metadata' export function Publish() { const { publish, publishStepText, isLoading } = usePublish() + const { createPricing, pricingStep, pricingStepText, pricingIsLoading, pricingError} = usePricing() const [ddo, setDdo] = useState() const asset = { @@ -31,18 +31,16 @@ export function Publish() { } const publishAsset = async () => { - const priceOptions = { - price: 7, - tokensToMint: 10, - type: 'fixed', - weightOnDataToken: '', - swapFee: '' + + const datatokenOptions = { + } - - const ddo = await publish(asset as Metadata, priceOptions, 'access') + const ddo = await publish(asset as Metadata, 'access', datatokenOptions) console.log(ddo) setDdo(ddo) } + + return ( <>
Publish
@@ -53,6 +51,7 @@ export function Publish() { IsLoading: {isLoading.toString()} || Status: {publishStepText}
DID: {ddo && ddo.id}
+ ) } diff --git a/package-lock.json b/package-lock.json index 8b29263..fea95c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1521,9 +1521,9 @@ "integrity": "sha512-LING+GvW37I0L40rZdPCZ1SvcZurDSGGhT0WOVPNO8oyh2C3bXModDBNE4+gCFa8pTbQBOc4ot1/Zoj9PfT/zA==" }, "@oceanprotocol/lib": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.6.5.tgz", - "integrity": "sha512-GH7ZujwmV997kZT4GJy7cZF0TBitM/RVm+xBLtqpr5qmrP/4Pq38WODbOol3dGEHsyT62qzDTvCGoBYSRSCU1g==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.7.0.tgz", + "integrity": "sha512-XRQ58wWbohtz/buug0498EbpBchxrPwYBh8f/Iln1Vwh6h3IfLWvznmg4gNg/H1AE3qdPsuVcBJwYb0Bos/yGQ==", "requires": { "@ethereum-navigator/navigator": "^0.5.0", "@oceanprotocol/contracts": "^0.5.6", diff --git a/package.json b/package.json index 23e07c4..e52a199 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dist/" ], "dependencies": { - "@oceanprotocol/lib": "^0.6.5", + "@oceanprotocol/lib": "^0.7.0", "axios": "^0.20.0", "decimal.js": "^10.2.1", "web3": "^1.3.0", diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 968161c..d4c70a6 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -2,3 +2,4 @@ export * from './useConsume' export * from './useMetadata' export * from './usePublish' export * from './useCompute' +export * from './usePricing' diff --git a/src/hooks/useCompute/useCompute.ts b/src/hooks/useCompute/useCompute.ts index 2cb10d3..36f4fa1 100644 --- a/src/hooks/useCompute/useCompute.ts +++ b/src/hooks/useCompute/useCompute.ts @@ -4,7 +4,6 @@ import { ComputeValue } from './ComputeOptions' import { Logger, ServiceCompute } from '@oceanprotocol/lib' import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm' import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob' -import { checkAndBuyDT } from 'utils/dtUtils' interface UseCompute { compute: ( @@ -13,7 +12,7 @@ interface UseCompute { dataTokenAddress: string, algorithmRawCode: string, computeContainer: ComputeValue, - marketFeeAddress: string + marketFeeAddress?: string ) => Promise computeStep?: number computeStepText?: string @@ -62,7 +61,7 @@ function useCompute(): UseCompute { dataTokenAddress: string, algorithmRawCode: string, computeContainer: ComputeValue, - marketFeeAddress: string + marketFeeAddress?: string ): Promise { if (!ocean || !account) return @@ -72,50 +71,47 @@ function useCompute(): UseCompute { setIsLoading(true) setStep(0) - await checkAndBuyDT(ocean, dataTokenAddress, account, config) - rawAlgorithmMeta.container = computeContainer - rawAlgorithmMeta.rawcode = algorithmRawCode - - const output = {} - Logger.log( - 'compute order', - accountId, - did, - computeService, - rawAlgorithmMeta, - marketFeeAddress - ) - const tokenTransfer = await ocean.compute.order( - accountId, - did, - computeService.index, - undefined, - rawAlgorithmMeta, - marketFeeAddress - ) - - setStep(1) - // const computeOrder = JSON.parse(order) - // Logger.log('compute order', computeOrder) - // const tokenTransfer = await ocean.datatokens.transferWei( - // computeOrder.dataToken, - // computeOrder.to, - // String(computeOrder.numTokens), - // computeOrder.from - // ) - setStep(2) - const response = await ocean.compute.start( - did, - tokenTransfer, + const userOwnedTokens = await ocean.accounts.getTokenBalance( dataTokenAddress, - account, - undefined, - rawAlgorithmMeta, - output, - `${computeService.index}`, - computeService.type + account ) - return response + if (parseFloat(userOwnedTokens) < 1) { + setComputeError('Not enough datatokens') + } else { + rawAlgorithmMeta.container = computeContainer + rawAlgorithmMeta.rawcode = algorithmRawCode + const output = {} + Logger.log( + 'compute order', + accountId, + did, + computeService, + rawAlgorithmMeta, + marketFeeAddress + ) + const tokenTransfer = await ocean.compute.order( + accountId, + did, + computeService.index, + undefined, + rawAlgorithmMeta, + marketFeeAddress + ) + setStep(1) + setStep(2) + const response = await ocean.compute.start( + did, + tokenTransfer, + dataTokenAddress, + account, + undefined, + rawAlgorithmMeta, + output, + `${computeService.index}`, + computeService.type + ) + return response + } } catch (error) { Logger.error(error) setComputeError(error.message) diff --git a/src/hooks/useConsume/README.md b/src/hooks/useConsume/README.md index 516a200..8de4a67 100644 --- a/src/hooks/useConsume/README.md +++ b/src/hooks/useConsume/README.md @@ -9,6 +9,7 @@ import React from 'react' import { useOcean, useConsume } from '@oceanprotocol/react' const did = 'did:op:0x000000000' +const dtBalance = 20 export default function MyComponent() { const { accountId } = useOcean() @@ -16,10 +17,16 @@ export default function MyComponent() { // Get metadata for this asset const { title, price, ddo } = useMetadata(did) + // Pricing helpers + const { buyDT } = usePricing(ddo) + // Consume helpers const { consume, consumeStep } = useConsume() + const hasDatatoken = dtBalance >= 1 + async function handleDownload() { + !hasDatatoken && (await buyDT('1')) await consume(did, ddo.dataToken, 'access') } diff --git a/src/hooks/useConsume/useConsume.ts b/src/hooks/useConsume/useConsume.ts index 1450924..8e2677a 100644 --- a/src/hooks/useConsume/useConsume.ts +++ b/src/hooks/useConsume/useConsume.ts @@ -2,7 +2,6 @@ import { useState } from 'react' import { useOcean } from 'providers' import { feedback } from 'utils' import { DID, Logger, ServiceType } from '@oceanprotocol/lib' -import { checkAndBuyDT } from 'utils/dtUtils' interface UseConsume { consume: ( @@ -26,7 +25,7 @@ export const consumeFeedback: { [key in number]: string } = { } function useConsume(): UseConsume { - const { ocean, account, accountId, config } = useOcean() + const { ocean, account, accountId } = useOcean() const [isLoading, setIsLoading] = useState(false) const [consumeStep, setConsumeStep] = useState() const [consumeStepText, setConsumeStepText] = useState() @@ -44,43 +43,40 @@ function useConsume(): UseConsume { marketFeeAddress: string ): Promise { if (!ocean || !account || !accountId) return + setIsLoading(true) setConsumeError(undefined) try { setStep(0) - await checkAndBuyDT(ocean, dataTokenAddress, account, config) - - setStep(1) - const tokenTransfer = await ocean.assets.order( - did as string, - serviceType, - accountId, - undefined, - marketFeeAddress - ) - Logger.log('order created', tokenTransfer) - setStep(2) - // const res = JSON.parse(order) - // Logger.log('order parsed', res) - // Logger.log('ocean.datatokens before transfer', ocean.datatokens) - // const tokenTransfer = await ocean.datatokens.transferWei( - // res.dataToken, - // res.to, - // String(res.numTokens), - // res.from - // ) - // Logger.log('token transfered', tokenTransfer) - setStep(3) - await ocean.assets.download( - did as string, - tokenTransfer, + const userOwnedTokens = await ocean.accounts.getTokenBalance( dataTokenAddress, - account, - '' + account ) - - setStep(4) + if (parseFloat(userOwnedTokens) < 1) { + setConsumeError('Not enough datatokens') + } else { + setStep(1) + ocean.datatokens.generateDtName() + const tokenTransfer = await ocean.assets.order( + did as string, + serviceType, + accountId, + undefined, + marketFeeAddress + ) + Logger.log('order created', tokenTransfer) + setStep(2) + setStep(3) + await ocean.assets.download( + did as string, + tokenTransfer, + dataTokenAddress, + account, + '' + ) + setStep(4) + } } catch (error) { setConsumeError(error.message) Logger.error(error) diff --git a/src/hooks/usePublish/PriceOptions.ts b/src/hooks/usePricing/PriceOptions.ts similarity index 85% rename from src/hooks/usePublish/PriceOptions.ts rename to src/hooks/usePricing/PriceOptions.ts index c0b6eb8..a30b665 100644 --- a/src/hooks/usePublish/PriceOptions.ts +++ b/src/hooks/usePricing/PriceOptions.ts @@ -1,6 +1,6 @@ export interface PriceOptions { price: number - tokensToMint: number + dtAmount: number type: 'fixed' | 'dynamic' | string weightOnDataToken: string swapFee: string diff --git a/src/hooks/usePricing/README.md b/src/hooks/usePricing/README.md new file mode 100644 index 0000000..4dd0e84 --- /dev/null +++ b/src/hooks/usePricing/README.md @@ -0,0 +1,58 @@ +# `usePricing` + +Hook with helper utilities to create fixed price exchanges or liquidity pools for your data set, mint datatokens, and buy and sell datatokens. + +## Usage + +```tsx +import React from 'react' +import { useOcean, useCreatePricing } from '@oceanprotocol/react' +import { Metadata, DDO } from '@oceanprotocol/lib' + +export default function MyComponent({ ddo }: { ddo: DDO }) { + const { accountId } = useOcean() + + // Pricing helpers + const { + createPricing, + buyDT, + sellDT, + pricingStepText, + pricingError + } = usePricing(ddo) + + const priceOptions = { + price: 10, + dtAmount: 10, + type: 'fixed', + weightOnDataToken: '', + swapFee: '' + } + + async function handleCreatePricing() { + await createPricing(priceOptions) + } + + async function handleMint() { + await mint('1') + } + async function handleBuyDT() { + await buyDT('1') + } + async function handleSellDT() { + await sellDT('1') + } + + return ( +
+

Post for sale

+ +

Your account: {accountId}

+ + + + +
+ ) +} +``` diff --git a/src/hooks/usePricing/index.ts b/src/hooks/usePricing/index.ts new file mode 100644 index 0000000..3b43af5 --- /dev/null +++ b/src/hooks/usePricing/index.ts @@ -0,0 +1,2 @@ +export * from './usePricing' +export * from './PriceOptions' diff --git a/src/hooks/usePricing/usePricing.ts b/src/hooks/usePricing/usePricing.ts new file mode 100644 index 0000000..75cbd57 --- /dev/null +++ b/src/hooks/usePricing/usePricing.ts @@ -0,0 +1,257 @@ +import { DDO, Logger } from '@oceanprotocol/lib' +import { useEffect, useState } from 'react' +import { useOcean } from 'providers' +import { PriceOptions } from './PriceOptions' +import { TransactionReceipt } from 'web3-core' +import { getBestDataTokenPrice, getFirstPool } from 'utils/dtUtils' +import { Decimal } from 'decimal.js' +import { + getCreatePricingPoolFeedback, + getCreatePricingExchangeFeedback, + getBuyDTFeedback, + getSellDTFeedback +} from './utils' + +interface UsePricing { + dtSymbol?: string + dtName?: string + createPricing: ( + priceOptions: PriceOptions + ) => Promise + buyDT: (dtAmount: number | string) => Promise + sellDT: (dtAmount: number | string) => Promise + mint: (tokensToMint: string) => Promise + pricingStep?: number + pricingStepText?: string + pricingError?: string + pricingIsLoading: boolean +} + +function usePricing(ddo: DDO): UsePricing { + const { ocean, accountId, config } = useOcean() + const [pricingIsLoading, setPricingIsLoading] = useState(false) + const [pricingStep, setPricingStep] = useState() + const [pricingStepText, setPricingStepText] = useState() + const [pricingError, setPricingError] = useState() + const [dtSymbol, setDtSymbol] = useState() + const [dtName, setDtName] = useState() + + const { dataToken, dataTokenInfo } = ddo + + // Get Datatoken info, from DDO first, then from chain + useEffect(() => { + if (!dataToken) return + + async function init() { + const dtSymbol = dataTokenInfo + ? dataTokenInfo.symbol + : await ocean?.datatokens.getSymbol(dataToken) + setDtSymbol(dtSymbol) + + const dtName = dataTokenInfo + ? dataTokenInfo.name + : await ocean?.datatokens.getName(dataToken) + setDtName(dtName) + } + init() + }, [ocean, dataToken, dataTokenInfo]) + + // Helper for setting steps & feedback for all flows + function setStep(index: number, type: 'pool' | 'exchange' | 'buy' | 'sell') { + setPricingStep(index) + if (!dtSymbol) return + + let messages + + switch (type) { + case 'pool': + messages = getCreatePricingPoolFeedback(dtSymbol) + break + case 'exchange': + messages = getCreatePricingExchangeFeedback(dtSymbol) + break + case 'buy': + messages = getBuyDTFeedback(dtSymbol) + break + case 'sell': + messages = getSellDTFeedback(dtSymbol) + break + } + + setPricingStepText(messages[index]) + } + + async function mint(tokensToMint: string): Promise { + Logger.log('mint function', dataToken, accountId) + const tx = await ocean.datatokens.mint(dataToken, accountId, tokensToMint) + return tx + } + + async function buyDT( + dtAmount: number | string + ): Promise { + if (!ocean || !accountId) return + + let tx + + try { + setPricingIsLoading(true) + setPricingError(undefined) + setStep(1, 'buy') + const bestPrice = await getBestDataTokenPrice(ocean, dataToken) + + switch (bestPrice?.type) { + case 'pool': { + const price = new Decimal(bestPrice.value).times(1.05).toString() + const maxPrice = new Decimal(bestPrice.value).times(2).toString() + setStep(2, 'buy') + Logger.log('Buying token from pool', bestPrice, accountId, price) + tx = await ocean.pool.buyDT( + accountId, + bestPrice.address, + String(dtAmount), + price, + maxPrice + ) + setStep(3, 'buy') + Logger.log('DT buy response', tx) + break + } + 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, accountId) + await ocean.datatokens.approve( + config.oceanTokenAddress, + config.fixedRateExchangeAddress, + `${bestPrice.value}`, + accountId + ) + setStep(2, 'buy') + tx = await ocean.fixedRateExchange.buyDT( + bestPrice.address, + `${dtAmount}`, + accountId + ) + setStep(3, 'buy') + Logger.log('DT exchange buy response', tx) + break + } + } + } catch (error) { + setPricingError(error.message) + Logger.error(error) + } finally { + setStep(0, 'buy') + setPricingStepText(undefined) + setPricingIsLoading(false) + } + + return tx + } + + async function sellDT( + dtAmount: number | string + ): Promise { + if (!ocean || !accountId) return + + if (!config.oceanTokenAddress) { + Logger.error(`'oceanTokenAddress' not set in config`) + return + } + + try { + setPricingIsLoading(true) + setPricingError(undefined) + setStep(1, 'sell') + const pool = await getFirstPool(ocean, dataToken) + if (!pool || pool.price === 0) return + const price = new Decimal(pool.price).times(0.95).toString() + setStep(2, 'sell') + Logger.log('Selling token to pool', pool, accountId, price) + const tx = await ocean.pool.sellDT( + accountId, + pool.address, + `${dtAmount}`, + price + ) + setStep(3, 'sell') + Logger.log('DT sell response', tx) + return tx + } catch (error) { + setPricingError(error.message) + Logger.error(error) + } finally { + setStep(0, 'sell') + setPricingStepText(undefined) + setPricingIsLoading(false) + } + } + + async function createPricing( + priceOptions: PriceOptions + ): Promise { + if (!ocean || !accountId || !dtSymbol) return + + const { type, dtAmount, price, weightOnDataToken, swapFee } = priceOptions + const isPool = type === 'dynamic' + + if (!isPool && !config.fixedRateExchangeAddress) { + Logger.error(`'fixedRateExchangeAddress' not set in ccnfig.`) + return + } + + setPricingIsLoading(true) + setPricingError(undefined) + + setStep(99, 'pool') + + try { + await mint(`${dtAmount}`) + + const tx = isPool + ? await ocean.pool + .create( + accountId, + dataToken, + `${dtAmount}`, + weightOnDataToken, + swapFee + ) + .next((step: number) => setStep(step, 'pool')) + : await ocean.fixedRateExchange + .create(dataToken, `${price}`, accountId) + .next((step: number) => setStep(step, 'exchange')) + return tx + } catch (error) { + setPricingError(error.message) + Logger.error(error) + } finally { + setPricingStep(0) + setPricingStepText(undefined) + setPricingIsLoading(false) + } + } + + return { + dtSymbol, + dtName, + createPricing, + buyDT, + sellDT, + mint, + pricingStep, + pricingStepText, + pricingIsLoading, + pricingError + } +} + +export { usePricing, UsePricing } +export default usePricing diff --git a/src/hooks/usePricing/utils.ts b/src/hooks/usePricing/utils.ts new file mode 100644 index 0000000..5589665 --- /dev/null +++ b/src/hooks/usePricing/utils.ts @@ -0,0 +1,39 @@ +export function getCreatePricingPoolFeedback( + dtSymbol: string +): { [key: number]: string } { + return { + 99: `Minting ${dtSymbol} ...`, + 0: 'Creating pool ...', + 1: `Approving ${dtSymbol} ...`, + 2: 'Approving OCEAN ...', + 3: 'Setup pool ...', + 4: 'Pool created.' + } +} + +export function getCreatePricingExchangeFeedback( + dtSymbol: string +): { [key: number]: string } { + return { + 99: `Minting ${dtSymbol} ...`, + 0: 'Creating exchange ...', + 1: `Approving ${dtSymbol} ...`, + 2: 'Fixed exchange created.' + } +} + +export function getBuyDTFeedback(dtSymbol: string): { [key: number]: string } { + return { + 1: '1/3 Approving OCEAN ...', + 2: `2/3 Buying ${dtSymbol} ...`, + 3: `3/3 ${dtSymbol} bought.` + } +} + +export function getSellDTFeedback(dtSymbol: string): { [key: number]: string } { + return { + 1: '1/3 Approving OCEAN ...', + 2: `2/3 Selling ${dtSymbol} ...`, + 3: `3/3 ${dtSymbol} sold.` + } +} diff --git a/src/hooks/usePublish/README.md b/src/hooks/usePublish/README.md index 654c2ca..b985aae 100644 --- a/src/hooks/usePublish/README.md +++ b/src/hooks/usePublish/README.md @@ -1,6 +1,6 @@ # `usePublish` -Publish data sets, and create data tokens and liquidity pools for them. +Publish data sets and create datatokens for them. ## Usage @@ -10,7 +10,7 @@ import { useOcean, usePublish } from '@oceanprotocol/react' import { Metadata } from '@oceanprotocol/lib' export default function MyComponent() { - const { accountId } = useOcean() + const { ocean, accountId } = useOcean() // Publish helpers const { publish, publishStep } = usePublish() @@ -24,16 +24,10 @@ export default function MyComponent() { } } - const priceOptions = { - price: 10, - tokensToMint: 10, - type: 'fixed', - weightOnDataToken: '', - swapFee: '' - } - async function handlePublish() { - const ddo = await publish(metadata, priceOptions, 'access') + const ddo = await publish(metadata, 'access') + // Heads Up! You should now create pricing for your data set + // with the `usePricing()` hook in another step. } return ( diff --git a/src/hooks/usePublish/index.ts b/src/hooks/usePublish/index.ts index 582f913..968ef5e 100644 --- a/src/hooks/usePublish/index.ts +++ b/src/hooks/usePublish/index.ts @@ -1,3 +1,2 @@ export * from './usePublish' -export * from './PriceOptions' export * from './DataTokenOptions' diff --git a/src/hooks/usePublish/usePublish.ts b/src/hooks/usePublish/usePublish.ts index e89b090..e87c76a 100644 --- a/src/hooks/usePublish/usePublish.ts +++ b/src/hooks/usePublish/usePublish.ts @@ -5,21 +5,19 @@ import { ServiceType } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' import { useState } from 'react' -import { DataTokenOptions } from '.' +import { DataTokenOptions } from './DataTokenOptions' import { useOcean } from 'providers' import ProviderStatus from 'providers/OceanProvider/ProviderStatus' import { publishFeedback } from 'utils' -import { PriceOptions } from './PriceOptions' interface UsePublish { publish: ( asset: Metadata, - priceOptions: PriceOptions, serviceConfigs: ServiceType, dataTokenOptions?: DataTokenOptions, + timeout?: number, providerUri?: string ) => Promise - mint: (tokenAddress: string, tokensToMint: string) => void publishStep?: number publishStepText?: string publishError?: string @@ -27,7 +25,7 @@ interface UsePublish { } function usePublish(): UsePublish { - const { ocean, status, account, accountId, config } = useOcean() + const { ocean, status, account } = useOcean() const [isLoading, setIsLoading] = useState(false) const [publishStep, setPublishStep] = useState() const [publishStepText, setPublishStepText] = useState() @@ -37,50 +35,6 @@ function usePublish(): UsePublish { setPublishStep(index) index && setPublishStepText(publishFeedback[index]) } - - async function mint(tokenAddress: string, tokensToMint: string) { - Logger.log('mint function', tokenAddress, accountId) - await ocean.datatokens.mint(tokenAddress, accountId, tokensToMint) - } - - async function createPricing( - priceOptions: PriceOptions, - dataTokenAddress: string, - mintedTokens: string - ): Promise { - switch (priceOptions.type) { - case 'dynamic': { - await ocean.pool.createDTPool( - accountId, - dataTokenAddress, - priceOptions.tokensToMint.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, - mintedTokens, - accountId - ) - break - } - } - } - /** * Publish an asset.It also creates the datatoken, mints tokens and gives the market allowance * @param {Metadata} asset The metadata of the asset. @@ -91,38 +45,37 @@ function usePublish(): UsePublish { */ async function publish( asset: Metadata, - priceOptions: PriceOptions, serviceType: ServiceType, dataTokenOptions?: DataTokenOptions, + timeout?: number, providerUri?: string ): Promise { if (status !== ProviderStatus.CONNECTED || !ocean || !account) return null - setIsLoading(true) setPublishError(undefined) try { - const tokensToMint = priceOptions.tokensToMint.toString() - const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z' - const timeout = 0 const services: Service[] = [] - const price = '1' + switch (serviceType) { case 'access': { + if (!timeout) timeout = 0 const accessService = await ocean.assets.createAccessServiceAttributes( account, price, publishedDate, - timeout + timeout, + providerUri ) Logger.log('access service created', accessService) services.push(accessService) break } case 'compute': { + if (!timeout) timeout = 3600 const cluster = ocean.compute.createClusterAttributes( 'Kubernetes', 'http://10.0.0.17/xxx' @@ -163,7 +116,9 @@ function usePublish(): UsePublish { price, publishedDate, provider, - origComputePrivacy as ServiceComputePrivacy + origComputePrivacy as ServiceComputePrivacy, + timeout, + providerUri ) services.push(computeService) break @@ -186,11 +141,6 @@ function usePublish(): UsePublish { .next(setStep) Logger.log('ddo created', ddo) setStep(7) - await mint(ddo.dataToken, tokensToMint) - Logger.log(`minted ${tokensToMint} tokens`) - - await createPricing(priceOptions, ddo.dataToken, tokensToMint) - setStep(8) return ddo } catch (error) { setPublishError(error.message) @@ -203,7 +153,6 @@ function usePublish(): UsePublish { return { publish, - mint, publishStep, publishStepText, isLoading, diff --git a/src/utils/dtUtils.ts b/src/utils/dtUtils.ts index 9c8b638..38ec580 100644 --- a/src/utils/dtUtils.ts +++ b/src/utils/dtUtils.ts @@ -1,5 +1,4 @@ -import { Logger, Ocean, Account, Config, BestPrice } from '@oceanprotocol/lib' -import { TransactionReceipt } from 'web3-core' +import { Logger, Ocean, BestPrice } from '@oceanprotocol/lib' import { Decimal } from 'decimal.js' import Pool from 'hooks/useMetadata/Pool' import Web3 from 'web3' @@ -146,62 +145,3 @@ export async function getBestDataTokenPrice( } as BestPrice } } - -export async function checkAndBuyDT( - ocean: Ocean, - dataTokenAddress: string, - account: Account, - config: Config -): Promise { - const userOwnedTokens = await ocean.accounts.getTokenBalance( - dataTokenAddress, - account - ) - Logger.log(`User has ${userOwnedTokens} tokens`) - if (userOwnedTokens === '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() - Logger.log('Buying token from pool', bestPrice, account.getId(), price) - const buyResponse = await ocean.pool.buyDT( - account.getId(), - bestPrice.address, - '1', - price, - maxPrice - ) - 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() - ) - const exchange = await ocean.fixedRateExchange.buyDT( - bestPrice.address, - '1', - account.getId() - ) - Logger.log('DT exchange buy response', exchange) - return exchange - } - } - } -} diff --git a/src/utils/index.ts b/src/utils/index.ts index ccc4435..d3114b6 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -31,12 +31,11 @@ export const feedback: { [key in number]: string } = { } export const publishFeedback: { [key in number]: string } = { - 0: '1/6 Creating datatoken ...', - 2: '2/6 Encrypting files ...', - 4: '3/6 Generating proof ...', - 6: '4/6 Storing ddo ...', - 7: '5/6 Minting tokens ...', - 8: '6/6 Asset published succesfully' + 0: '1/5 Creating datatoken ...', + 2: '2/5 Encrypting files ...', + 4: '3/5 Storing ddo ...', + 6: '4/5 Minting tokens ...', + 8: '5/5 Asset published succesfully' } export * from './web3' diff --git a/tsconfig.json b/tsconfig.json index f3c9f7c..9ca5a13 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,5 +14,5 @@ "importHelpers": true, "strict": true }, - "include": ["./src/@types", "./src/index.ts"] + "include": ["./src/@types", "./src/hooks", "./src/index.ts"] }