diff --git a/example/src/App.tsx b/example/src/App.tsx index d573c29..a4550d4 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -7,8 +7,7 @@ import { Config, ConfigHelper } from '@oceanprotocol/lib' import { AllDdos } from './AllDdos' import { ConsumeDdo } from './ConsumeDdo' -import WalletConnectProvider from '@walletconnect/web3-provider' -import Torus from '@toruslabs/torus-embed' + import { NetworkMonitor } from './NetworkMonitor' import { MetadataExample } from './MetadataExample' @@ -23,22 +22,7 @@ const config = { const configRinkeby = new ConfigHelper().getConfig('rinkeby') const providerOptions = { - walletconnect: { - package: WalletConnectProvider, - options: { - infuraId: '' - } - }, - torus: { - package: Torus, - options: { - networkParams: { - host: config.nodeUri // optional - // chainId: 1337, // optional - // networkId: 1337 // optional - } - } - } + } export const web3ModalOpts = { diff --git a/example/src/Publish.tsx b/example/src/Publish.tsx index 2c4319d..4aad118 100644 --- a/example/src/Publish.tsx +++ b/example/src/Publish.tsx @@ -32,7 +32,16 @@ export function Publish() { const publishAsset = async () => { console.log(isLoading) - const ddo = await publish(asset as Metadata, '90', 'access', '', '') + + const priceOptions = { + price:10, + tokensToMint:10, + type: 'simple', + weightOnDataToken: '', + liquidityProviderFee: '' + } + + const ddo = await publish(asset as Metadata, priceOptions, 'access', '', '') console.log(ddo) console.log(isLoading) const pool = ocean.pool.createDTPool( diff --git a/src/hooks/usePublish/PriceOptions.ts b/src/hooks/usePublish/PriceOptions.ts new file mode 100644 index 0000000..6ee84fe --- /dev/null +++ b/src/hooks/usePublish/PriceOptions.ts @@ -0,0 +1,8 @@ +export interface PriceOptions { + price?: number + tokensToMint: number + type: 'simple' | 'advanced' | string + weightOnDataToken: string + liquidityProviderFee: string + } + \ No newline at end of file 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 aaefc8e..4168f8b 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,33 +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 : simple, advanced + * @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 { - setStep(0) - - const dtAddress = await ocean.datatokens.create(config.metadataStoreUri,"name",'DT',"1000", accountId) - Logger.log('datatoken created', dtAddress) + const tokensToMint = priceOptions.tokensToMint.toString() - setStep(1) - await mint(dtAddress, tokensToMint) - Logger.log(`minted ${tokensToMint} tokens`) - - setStep(2) const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z' const timeout = 0 @@ -134,11 +124,17 @@ function usePublish(): UsePublish { } Logger.log('services created', services) - setStep(3) - const ddo = await ocean.assets.create(asset, account, services, dtAddress) - Logger.log('ddo created', ddo) - setStep(4) + const ddo = await ocean.assets + .create(asset, account, services) + .next(setStep) + Logger.log('ddo created', ddo) + setStep(7) + await mint(ddo.dataToken, tokensToMint) + Logger.log(`minted ${tokensToMint} tokens`) + + await createPricing(priceOptions, ddo.dataToken) + setStep(8) return ddo } catch (error) { setPublishError(error.message) @@ -149,6 +145,34 @@ function usePublish(): UsePublish { } } + async function createPricing( + priceOptions: PriceOptions, + dataTokenAddress: string + ) { + switch (priceOptions.type) { + case 'advanced': { + // 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 'simple': { + 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 12fb126..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.poolPrice).times(1.05).toString() - const maxPrice = new Decimal(cheapestPool.poolPrice).times(2).toString() - Logger.log('Buying token', cheapestPool, account.getId(), price) - const buyResponse = await ocean.pool.buyDT( - account.getId(), - cheapestPool.poolAddress, - '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 + } } } diff --git a/src/utils/index.ts b/src/utils/index.ts index 0e7fac7..5d44cdb 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -29,10 +29,12 @@ export const feedback: { [key in number]: string } = { } export const publishFeedback: { [key in number]: string } = { - 0: '1/4 Creating datatoken ...', - 1: '2/4 Minting tokens ...', - 3: '3/4 Publishing asset ...', - 4: '4/4 Asset published succesfully' + 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' } export * from './web3'