diff --git a/example/src/AllDdos.tsx b/example/src/AllDdos.tsx index 0112290..67c25ae 100644 --- a/example/src/AllDdos.tsx +++ b/example/src/AllDdos.tsx @@ -13,7 +13,7 @@ export function AllDdos() { useEffect(() => { async function init() { - if (ocean === undefined || account === undefined) return + if (!ocean || !account) return const assets = await ocean.assets.query({ page: 1, diff --git a/example/src/App.tsx b/example/src/App.tsx index 4abd2e3..1ddb721 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -3,20 +3,11 @@ import './App.css' import { OceanProvider } from '@oceanprotocol/react' import { Wallet } from './Wallet' import { Publish } from './Publish' -// import { Config } from '@oceanprotocol/lib' import { ConfigHelper } from '@oceanprotocol/lib' import { AllDdos } from './AllDdos' import { ConsumeDdo } from './ConsumeDdo' import { NetworkMonitor } from './NetworkMonitor' -// factory Address needs to be updated each time you deploy the contract on local network -// const config: Config = { -// metadataStoreUri: 'http://aquarius:5000', -// providerUri: 'http://localhost:8030', -// nodeUri: `http://localhost:8545`, -// factoryAddress: '0x2fC1fd21cb222Dc180Ef817dE4c426fd9230b5A5' -// } - const configRinkeby = new ConfigHelper().getConfig('rinkeby') const providerOptions = {} @@ -43,11 +34,9 @@ function App() {
-
-
diff --git a/example/src/ConsumeDdo.tsx b/example/src/ConsumeDdo.tsx index 9ab237a..5adb1ab 100644 --- a/example/src/ConsumeDdo.tsx +++ b/example/src/ConsumeDdo.tsx @@ -19,14 +19,14 @@ export function ConsumeDdo() { }, [ocean]) const consumeDid = async () => { - if (did === undefined) return + if (!did) return const ddo = await ocean.assets.resolve(did) await consume(did, ddo.dataToken, 'access') } const computeDid = async () => { - if (did === undefined) return + if (!did) return const ddo = await ocean.assets.resolve(did) console.log(ddo) console.log('ocean dt', ocean.datatokens) diff --git a/example/src/NetworkMonitor.tsx b/example/src/NetworkMonitor.tsx index d643af0..8ba4f28 100644 --- a/example/src/NetworkMonitor.tsx +++ b/example/src/NetworkMonitor.tsx @@ -8,20 +8,7 @@ export const NetworkMonitor = () => { const handleNetworkChanged = useCallback( (chainId: number) => { - // const config = getOceanConfig(chainId) - // temp hack - let network = '' - switch (chainId) { - case 1: { - network = 'mainnet' - break - } - case 4: { - network = 'rinkeby' - break - } - } - const config = new ConfigHelper().getConfig(network) + const config = new ConfigHelper().getConfigById(chainId) connect(config) }, [connect] diff --git a/example/src/Publish.tsx b/example/src/Publish.tsx index 5d020f3..2efcd16 100644 --- a/example/src/Publish.tsx +++ b/example/src/Publish.tsx @@ -6,7 +6,6 @@ import { useState } from 'react' import { Metadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Metadata' export function Publish() { - // const { accountId, ocean } = useOcean() const { publish, publishStepText, isLoading } = usePublish() const [ddo, setDdo] = useState() @@ -32,14 +31,16 @@ export function Publish() { } const publishAsset = async () => { - const ddo = await publish(asset as Metadata, '90', 'access', '', '') - // const pool = ocean.pool.createDTPool( - // accountId, - // ddo.dataToken, - // '90', - // '9', - // '0.03' - // ) + const priceOptions = { + price: 10, + tokensToMint: 10, + type: 'fixed', + weightOnDataToken: '', + liquidityProviderFee: '' + } + + const ddo = await publish(asset as Metadata, priceOptions, 'access', '', '') + console.log(ddo) setDdo(ddo) } return ( @@ -51,7 +52,6 @@ export function Publish() {
IsLoading: {isLoading.toString()} || Status: {publishStepText}
-
DID: {ddo && ddo.id}
) diff --git a/example/src/Wallet.tsx b/example/src/Wallet.tsx index 7b375e1..b260a56 100644 --- a/example/src/Wallet.tsx +++ b/example/src/Wallet.tsx @@ -29,11 +29,9 @@ export function Wallet() {
-
-
{accountId}
) diff --git a/package.json b/package.json index 46eb494..37885a5 100644 --- a/package.json +++ b/package.json @@ -85,5 +85,8 @@ }, "publishConfig": { "access": "public" + }, + "directories": { + "example": "example" } } diff --git a/src/hooks/usePublish/PriceOptions.ts b/src/hooks/usePublish/PriceOptions.ts new file mode 100644 index 0000000..47340e8 --- /dev/null +++ b/src/hooks/usePublish/PriceOptions.ts @@ -0,0 +1,7 @@ +export interface PriceOptions { + price?: number + tokensToMint: number + type: 'fixed' | 'dynamic' | string + weightOnDataToken: string + liquidityProviderFee: string +} diff --git a/src/hooks/usePublish/ServiceConfig.ts b/src/hooks/usePublish/ServiceConfig.ts deleted file mode 100644 index 963eca0..0000000 --- a/src/hooks/usePublish/ServiceConfig.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ServiceType } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' -export interface ServiceConfig { - serviceType: ServiceType - cost: string -} diff --git a/src/hooks/usePublish/index.ts b/src/hooks/usePublish/index.ts index 98b1d00..b550b5c 100644 --- a/src/hooks/usePublish/index.ts +++ b/src/hooks/usePublish/index.ts @@ -1,2 +1,2 @@ export * from './usePublish' -export * from './ServiceConfig' +export * from './PriceOptions' diff --git a/src/hooks/usePublish/usePublish.ts b/src/hooks/usePublish/usePublish.ts index 6c520c4..d50dcb0 100644 --- a/src/hooks/usePublish/usePublish.ts +++ b/src/hooks/usePublish/usePublish.ts @@ -1,5 +1,5 @@ -import { useEffect, useState } from 'react' -import { DDO, Metadata, DataTokens, Logger } from '@oceanprotocol/lib' +import { useState } from 'react' +import { DDO, Metadata, Logger } from '@oceanprotocol/lib' import { useOcean } from '../../providers' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' import { @@ -7,13 +7,13 @@ import { ServiceComputePrivacy, ServiceType } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' -import { ServiceConfig } from './ServiceConfig' +import { PriceOptions } from './PriceOptions' import { publishFeedback } from '../../utils' interface UsePublish { publish: ( asset: Metadata, - tokensToMint: string, + priceOptions: PriceOptions, serviceConfigs: ServiceType, mpAddress: string, mpFee: string @@ -26,7 +26,7 @@ interface UsePublish { } function usePublish(): UsePublish { - const { ocean, status, account, accountId, config } = useOcean() + const { ocean, status, account, accountId } = useOcean() const [isLoading, setIsLoading] = useState(false) const [publishStep, setPublishStep] = useState() const [publishStepText, setPublishStepText] = useState() @@ -40,23 +40,23 @@ function usePublish(): UsePublish { /** * Publish an asset.It also creates the datatoken, mints tokens and gives the market allowance * @param {Metadata} asset The metadata of the asset. - * @param {string} tokensToMint Numer of tokens to mint and give allowance to market - * @param {ServiceConfig[]} serviceConfigs Desired services of the asset, ex: [{serviceType: 'access', cost:'1'}] + * @param {PriceOptions} priceOptions : number of tokens to mint, datatoken weight , liquidity fee, type : fixed, dynamic + * @param {ServiceType} serviceType Desired service type of the asset access or compute * @param {string} mpAddress The address of the market * @param {string} mpFee The fee of the market * @return {Promise} Returns the newly published ddo */ async function publish( asset: Metadata, - tokensToMint: string, - serviceType: ServiceType, - mpAddress: string, - mpFee: string + priceOptions: PriceOptions, + serviceType: ServiceType ): Promise { if (status !== ProviderStatus.CONNECTED || !ocean || !account) return setIsLoading(true) setPublishError(undefined) try { + const tokensToMint = priceOptions.tokensToMint.toString() + const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z' const timeout = 0 @@ -132,8 +132,9 @@ function usePublish(): UsePublish { setStep(7) await mint(ddo.dataToken, tokensToMint) Logger.log(`minted ${tokensToMint} tokens`) - setStep(8) + await createPricing(priceOptions, ddo.dataToken) + setStep(8) return ddo } catch (error) { setPublishError(error.message) @@ -144,6 +145,34 @@ function usePublish(): UsePublish { } } + async function createPricing( + priceOptions: PriceOptions, + dataTokenAddress: string + ) { + switch (priceOptions.type) { + case 'dynamic': { + // weight is hardcoded at 9 (90%) and publisher fee at 0.03(this was a random value set by me) + const pool = await ocean.pool.createDTPool( + accountId, + dataTokenAddress, + priceOptions.tokensToMint.toString(), + priceOptions.weightOnDataToken, + priceOptions.liquidityProviderFee + ) + break + } + case 'fixed': { + const fixedPriceExchange = await ocean.fixedRateExchange.create( + dataTokenAddress, + priceOptions.price.toString(), + accountId + ) + await ocean.fixedRateExchange.activate(fixedPriceExchange, accountId) + break + } + } + } + async function mint(tokenAddress: string, tokensToMint: string) { Logger.log('mint function', tokenAddress, accountId) await ocean.datatokens.mint(tokenAddress, accountId, tokensToMint) diff --git a/src/utils/dtUtils.ts b/src/utils/dtUtils.ts index 317b730..d4e2eca 100644 --- a/src/utils/dtUtils.ts +++ b/src/utils/dtUtils.ts @@ -54,6 +54,48 @@ export async function getBestDataTokenPrice( return bestPool.price } +export async function getCheapestExchange( + ocean: Ocean, + dataTokenAddress: string +) { + if (!ocean || !dataTokenAddress) return + + const tokenExchanges = await ocean.fixedRateExchange.searchforDT( + dataTokenAddress, + '1' + ) + Logger.log('Exchanges found', tokenExchanges) + if (tokenExchanges === undefined || tokenExchanges.length === 0) { + return { + address: '', + price: '' + } + } + let cheapestExchangeAddress + let cheapestExchangePrice = new Decimal(999999999999) + + if (tokenExchanges) { + for (let i = 0; i < tokenExchanges.length; i++) { + const exchangePrice = tokenExchanges[i].fixedRate + + const decimalExchangePrice = new Decimal(exchangePrice) + Logger.log( + 'Pool price ', + tokenExchanges[i], + decimalExchangePrice.toString() + ) + if (decimalExchangePrice < cheapestExchangePrice) { + cheapestExchangePrice = decimalExchangePrice + cheapestExchangeAddress = tokenExchanges[i] + } + } + } + + return { + address: cheapestExchangeAddress, + price: cheapestExchangePrice.toString() + } +} export async function checkAndBuyDT( ocean: Ocean, @@ -65,25 +107,37 @@ export async function checkAndBuyDT( account ) Logger.log(`User has ${userOwnedTokens} tokens`) - let cheapestPool if (userOwnedTokens === '0') { - cheapestPool = await getCheapestPool( + const cheapestPool = await getCheapestPool( ocean, account.getId(), dataTokenAddress ) + const cheapestExchange = await getCheapestExchange(ocean, dataTokenAddress) Decimal.set({ precision: 5 }) - const price = new Decimal(cheapestPool.price).times(1.05).toString() - const maxPrice = new Decimal(cheapestPool.price).times(2).toString() - Logger.log('Buying token', cheapestPool, account.getId(), price) - const buyResponse = await ocean.pool.buyDT( - account.getId(), - cheapestPool.address, - '1', - price, - maxPrice - ) - Logger.log('DT buy response', buyResponse) - return buyResponse + const cheapestPoolPrice = new Decimal(cheapestPool.price) + const cheapestExchangePrice = new Decimal(cheapestExchange.price) + + if (cheapestExchangePrice > cheapestPoolPrice) { + const price = new Decimal(cheapestPool.price).times(1.05).toString() + const maxPrice = new Decimal(cheapestPool.price).times(2).toString() + Logger.log('Buying token', cheapestPool, account.getId(), price) + const buyResponse = await ocean.pool.buyDT( + account.getId(), + cheapestPool.address, + '1', + price, + maxPrice + ) + Logger.log('DT buy response', buyResponse) + return buyResponse + } else { + const exchange = await ocean.fixedRateExchange.buyDT( + cheapestExchange.address, + '1', + account.getId() + ) + return exchange + } } }