diff --git a/example/package.json b/example/package.json index ed2bce7..ec52bb3 100644 --- a/example/package.json +++ b/example/package.json @@ -3,7 +3,6 @@ "version": "0.1.0", "private": true, "dependencies": { - "-": "0.0.1", "@oceanprotocol/react": "file:../", "@toruslabs/torus-embed": "^1.8.2", "@types/jest": "^24.9.1", diff --git a/example/src/App.tsx b/example/src/App.tsx index 52007d6..0bb135d 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -18,12 +18,7 @@ const config = { factoryAddress: '0x2fC1fd21cb222Dc180Ef817dE4c426fd9230b5A5' } as Config -const configRinkeby = { - metadataStoreUri: 'https://aquarius.rinkeby.v3.dev-ocean.com', - providerUri: 'https://provider.rinkeby.v3.dev-ocean.com', - nodeUri: `https://rinkeby.infura.io/a983b53583044593956054de049922fd`, - factoryAddress: '0xB9d406D24B310A7D821D0b782a36909e8c925471' -} as Config +const configRinkeby = new ConfigHelper().getConfig('rinkeby') const providerOptions = { walletconnect: { @@ -57,8 +52,7 @@ function App() { }, []) return ( -
- +
@@ -76,7 +70,6 @@ function App() {
-
) } diff --git a/example/src/Publish.tsx b/example/src/Publish.tsx index d1c99ac..c694a50 100644 --- a/example/src/Publish.tsx +++ b/example/src/Publish.tsx @@ -31,10 +31,7 @@ export function Publish() { } const publishAsset = async () => { - const ddo = await publish(asset as Metadata, '90', [ - { serviceType: 'access', cost: '1' }, - { serviceType: 'compute', cost: '1' } - ]) + const ddo = await publish(asset as Metadata, '90','access','','') console.log(ddo) const pool = ocean.pool.createDTPool(accountId,ddo.dataToken,'90','9','0.03') setDdo(ddo) diff --git a/package-lock.json b/package-lock.json index 053bea8..9edf2f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1298,13 +1298,14 @@ "integrity": "sha512-ZQ5RHQWp6xkmATt7Sl12LhnH4dovewgKPX1gGeZoDSyFcmpjMDngtJpDns8jMsaclU61tPScw7K/EmxS1ydiCg==" }, "@oceanprotocol/lib": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.1.10.tgz", - "integrity": "sha512-wb0SOX0/ulLMho2Ftm1dFFLCz1+vM8mJQYNS5Ay62AUEny6fymsAMpcTLBsDU5CseqU87fHU6A5g5Rvlu7RRwQ==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.1.11.tgz", + "integrity": "sha512-DvsCWOACxNlsNpGWdbHhKsN2Lj+/B0UAp6l2/29fywFZnFp0mjywKFbhVEY25PGaHZIUG+7YZ0Eot615tKpNjw==", "requires": { "@ethereum-navigator/navigator": "^0.5.0", "@oceanprotocol/contracts": "^0.3.1", "bignumber.js": "^9.0.0", + "decimal.js": "^10.2.0", "fs": "0.0.1-security", "node-fetch": "^2.6.0", "save-file": "^2.3.1", @@ -3285,6 +3286,11 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==" + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", diff --git a/package.json b/package.json index 1ea35ab..d7af2ad 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,9 @@ "dist/" ], "dependencies": { - "@oceanprotocol/lib": "^0.1.10", + "@oceanprotocol/lib": "^0.1.11", "axios": "^0.19.2", + "decimal.js": "^10.2.0", "web3": "^1.2.11", "web3modal": "^1.9.0" }, diff --git a/src/hooks/useCompute/useCompute.ts b/src/hooks/useCompute/useCompute.ts index 89f6284..1c7cffa 100644 --- a/src/hooks/useCompute/useCompute.ts +++ b/src/hooks/useCompute/useCompute.ts @@ -5,6 +5,7 @@ import { feedback } from './../../utils' import { DID, Logger } 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: ( @@ -63,6 +64,8 @@ function useCompute(): UseCompute { try { setIsLoading(true) setStep(0) + + await checkAndBuyDT(ocean,dataTokenAddress, account) rawAlgorithmMeta.container = computeContainer rawAlgorithmMeta.rawcode = algorithmRawCode diff --git a/src/hooks/useConsume/useConsume.ts b/src/hooks/useConsume/useConsume.ts index 447cad9..3f40a4d 100644 --- a/src/hooks/useConsume/useConsume.ts +++ b/src/hooks/useConsume/useConsume.ts @@ -2,7 +2,8 @@ import { useState } from 'react' import { useOcean } from '../../providers' import { feedback } from '../../utils' import { DID, Logger, ServiceType } from '@oceanprotocol/lib' - +import { getCheapestPool, checkAndBuyDT } from '../../utils/dtUtils' +const Decimal = require('decimal.js') interface UseConsume { consume: ( did: DID | string, @@ -34,32 +35,7 @@ function useConsume(): UseConsume { setConsumeStep(index) setConsumeStepText(consumeFeedback[index]) } - async function getCheapestPool(dataTokenAddress): Promise<{poolAddress: string,poolPrice: string}> { - const tokenPools = await ocean.pool.searchPoolforDT(accountId, dataTokenAddress) - Logger.log('DT Pool found', tokenPools) - let cheapestPoolAddress - let cheapestPoolPrice = 999999 - if (tokenPools) { - for (let i = 0; i < tokenPools.length; i++) { - const poolPrice = await ocean.pool.getDTPrice(accountId, tokenPools[i]) - Logger.log('Pool price ',tokenPools[i],poolPrice) - if (poolPrice < cheapestPoolPrice) { - cheapestPoolPrice = poolPrice - cheapestPoolAddress = tokenPools[i] - } - } - } - - return { poolAddress:cheapestPoolAddress, poolPrice: cheapestPoolPrice.toString()} - - } - - async function getBestDataTokenPrice(dataTokenAddress:string): Promise{ - const bestPool = await getCheapestPool(dataTokenAddress) - - return bestPool.poolPrice - } async function consume( did: string, dataTokenAddress: string, @@ -71,24 +47,10 @@ function useConsume(): UseConsume { try { - const userOwnedTokens = await ocean.accounts.getTokenBalance(dataTokenAddress, account) - Logger.log(`User has ${userOwnedTokens} tokens`) - let cheapestPool - if (userOwnedTokens === '0') { - cheapestPool = await getCheapestPool(dataTokenAddress) - - let maxPrice: number = +cheapestPool.poolPrice *10 - Logger.log('Buying token', cheapestPool,accountId, maxPrice.toString()) - let buyResponse = await ocean.pool.buyDT(accountId,cheapestPool.poolAddress,'1','100','999999999999999999999999999999999999999999') - Logger.log('DT buy response', buyResponse) - - if(buyResponse === null) { - return - } - } - - setStep(0) + await checkAndBuyDT(ocean,dataTokenAddress, account) + + setStep(1) const order = await ocean.assets.order(did, serviceType, accountId) Logger.log('order created', order) diff --git a/src/hooks/useMetadata/useMetadata.ts b/src/hooks/useMetadata/useMetadata.ts index 896f02c..afd985e 100644 --- a/src/hooks/useMetadata/useMetadata.ts +++ b/src/hooks/useMetadata/useMetadata.ts @@ -5,10 +5,10 @@ import { Metadata, MetadataStore, Logger, - ConfigHelper } from '@oceanprotocol/lib' import { useOcean } from '../../providers' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' +import { getBestDataTokenPrice } from '../../utils/dtUtils' interface UseMetadata { ddo: DDO @@ -17,10 +17,11 @@ interface UseMetadata { getDDO: (did: DID | string) => Promise getMetadata: (did: DID | string) => Promise getTitle: (did: DID | string) => Promise + getBestPrice: (dataTokenAddress: string) => Promise } function useMetadata(did?: DID | string): UseMetadata { - const { ocean, status, config } = useOcean() + const { ocean, status, config, accountId } = useOcean() const [ddo, setDDO] = useState() const [metadata, setMetadata] = useState() const [title, setTitle] = useState() @@ -37,6 +38,10 @@ function useMetadata(did?: DID | string): UseMetadata { return ddo } + async function getBestPrice(dataTokenAddress:string): Promise { + return await getBestDataTokenPrice(ocean, accountId, dataTokenAddress) + } + async function getMetadata(did: DID | string): Promise { const ddo = await getDDO(did) if (!ddo) return @@ -68,7 +73,8 @@ function useMetadata(did?: DID | string): UseMetadata { title, getDDO, getMetadata, - getTitle + getTitle, + getBestPrice } } diff --git a/src/hooks/usePublish/usePublish.ts b/src/hooks/usePublish/usePublish.ts index 6cf6d26..2523373 100644 --- a/src/hooks/usePublish/usePublish.ts +++ b/src/hooks/usePublish/usePublish.ts @@ -4,7 +4,8 @@ import { useOcean } from '../../providers' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' import { Service, - ServiceComputePrivacy + ServiceComputePrivacy, + ServiceType } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' import { ServiceConfig } from './ServiceConfig' import { publishFeedback } from '../../utils' @@ -13,8 +14,9 @@ interface UsePublish { publish: ( asset: Metadata, tokensToMint: string, - serviceConfigs: ServiceConfig[], - dtAddress?: string + serviceConfigs: ServiceType, + mpAddress: string, + mpFee: string ) => Promise mint: (tokenAddress: string, tokensToMint: string) => void publishStep?: number @@ -24,7 +26,7 @@ interface UsePublish { } function usePublish(): UsePublish { - const { web3, ocean, status, account, accountId, config } = useOcean() + const { ocean, status, account, accountId, config } = useOcean() const [isLoading, setIsLoading] = useState(false) const [publishStep, setPublishStep] = useState() const [publishStepText, setPublishStepText] = useState() @@ -40,26 +42,26 @@ function usePublish(): UsePublish { * @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 {string} dtAddress The address of the market + * @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, - serviceConfigs: ServiceConfig[], - dtAddress?: string + serviceType: ServiceType, + mpAddress: string, + mpFee: string ): Promise { if (status !== ProviderStatus.CONNECTED || !ocean || !account) return setIsLoading(true) setPublishError(undefined) try { - if (!dtAddress) { - setStep(0) - const data = { t: 1, url: config.metadataStoreUri } - const blob = JSON.stringify(data) - dtAddress = await ocean.datatokens.create(blob, accountId) - Logger.log('datatoken created', dtAddress) - } + setStep(0) + const data = { t: 1, url: config.metadataStoreUri } + const blob = JSON.stringify(data) + const dtAddress = await ocean.datatokens.create(blob, accountId) + Logger.log('datatoken created', dtAddress) setStep(1) await mint(dtAddress, tokensToMint) @@ -71,68 +73,68 @@ function usePublish(): UsePublish { const timeout = 0 const services: Service[] = [] - serviceConfigs.forEach(async (serviceConfig) => { - const price = ocean.datatokens.toWei(serviceConfig.cost) - switch (serviceConfig.serviceType) { - case 'access': { - const accessService = await ocean.assets.createAccessServiceAttributes( - account, - price, - publishedDate, + + const price = ocean.datatokens.toWei('1') + switch (serviceType) { + case 'access': { + const accessService = await ocean.assets.createAccessServiceAttributes( + account, + price, + publishedDate, + timeout + ) + Logger.log('access service created', accessService) + services.push(accessService) + break + } + case 'compute': { + const cluster = ocean.compute.createClusterAttributes( + 'Kubernetes', + 'http://10.0.0.17/xxx' + ) + const servers = [ + ocean.compute.createServerAttributes( + '1', + 'xlsize', + '50', + '16', + '0', + '128gb', + '160gb', timeout ) - Logger.log('access service created', accessService) - services.push(accessService) - break - } - case 'compute': { - const cluster = ocean.compute.createClusterAttributes( - 'Kubernetes', - 'http://10.0.0.17/xxx' - ) - const servers = [ - ocean.compute.createServerAttributes( - '1', - 'xlsize', - '50', - '16', - '0', - '128gb', - '160gb', - timeout - ) - ] - const containers = [ - ocean.compute.createContainerAttributes( - 'tensorflow/tensorflow', - 'latest', - 'sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc' - ) - ] - const provider = ocean.compute.createProviderAttributes( - 'Azure', - 'Compute service with 16gb ram for each node.', - cluster, - containers, - servers - ) - const origComputePrivacy = { - allowRawAlgorithm: true, - allowNetworkAccess: false, - trustedAlgorithms: [] - } - const computeService = ocean.compute.createComputeService( - account, - price, - publishedDate, - provider, - origComputePrivacy as ServiceComputePrivacy - ) - services.push(computeService) - break + ] + const containers = [ + ocean.compute.createContainerAttributes( + 'tensorflow/tensorflow', + 'latest', + 'sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc' + ) + ] + const provider = ocean.compute.createProviderAttributes( + 'Azure', + 'Compute service with 16gb ram for each node.', + cluster, + containers, + servers + ) + const origComputePrivacy = { + allowRawAlgorithm: true, + allowNetworkAccess: false, + trustedAlgorithms: [] } + const computeService = ocean.compute.createComputeService( + account, + price, + publishedDate, + provider, + origComputePrivacy as ServiceComputePrivacy + ) + services.push(computeService) + break } - }) + } + Logger.log('services created', services) setStep(3) const ddo = await ocean.assets.create(asset, account, services, dtAddress) @@ -154,8 +156,7 @@ function usePublish(): UsePublish { await ocean.datatokens.mint(tokenAddress, accountId, tokensToMint) } - async function createBalancerPool() - { + async function createBalancerPool() { ocean } diff --git a/src/utils/dtUtils.ts b/src/utils/dtUtils.ts new file mode 100644 index 0000000..0df62b4 --- /dev/null +++ b/src/utils/dtUtils.ts @@ -0,0 +1,47 @@ +import { Logger, Ocean, Account } from '@oceanprotocol/lib' +const Decimal = require('decimal.js') +export async function getCheapestPool(ocean: Ocean, accountId: string, dataTokenAddress: string): Promise<{ poolAddress: string, poolPrice: string }> { + const tokenPools = await ocean.pool.searchPoolforDT(accountId, dataTokenAddress) + Logger.log('DT Pool found', tokenPools) + let cheapestPoolAddress + let cheapestPoolPrice = 999999 + + if (tokenPools) { + for (let i = 0; i < tokenPools.length; i++) { + const poolPrice = await ocean.pool.getOceanNeeded(accountId, tokenPools[i], '1') + Logger.log('Pool price ', tokenPools[i], poolPrice) + if (Decimal(poolPrice) < cheapestPoolPrice) { + cheapestPoolPrice = Decimal(poolPrice) + cheapestPoolAddress = tokenPools[i] + } + } + } + + return { poolAddress: cheapestPoolAddress, poolPrice: cheapestPoolPrice.toString() } + +} + +export async function getBestDataTokenPrice(ocean: Ocean, accountId: string, dataTokenAddress: string): Promise { + const bestPool = await getCheapestPool(ocean, accountId, dataTokenAddress) + + return bestPool.poolPrice +} + +export async function checkAndBuyDT(ocean: Ocean, dataTokenAddress: string, account: Account) { + const userOwnedTokens = await ocean.accounts.getTokenBalance(dataTokenAddress, account) + Logger.log(`User has ${userOwnedTokens} tokens`) + let cheapestPool + if (userOwnedTokens === '0') { + cheapestPool = await getCheapestPool(ocean,account.getId(),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) + let buyResponse = await ocean.pool.buyDT(account.getId(), cheapestPool.poolAddress, '1', price, maxPrice) + Logger.log('DT buy response', buyResponse) + + if (buyResponse === null) { + return + } + } +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts index b068c83..247148a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -14,9 +14,9 @@ export function readFileContent(file: File): Promise { export const feedback: { [key in number]: string } = { 99: 'Decrypting file URL...', - 0: '1/3 Ordering asset...', - 1: '1/3 Transfering data token.', - 2: '2/3 Payment confirmed. Requesting access...' + 0: '1/3 Looking for data token. Buying if none found...', + 1: '2/3 Transfering data token.', + 2: '3/3 Payment confirmed. Requesting access...' } export const publishFeedback: { [key in number]: string } = { diff --git a/src/utils/priceUtils.ts b/src/utils/priceUtils.ts deleted file mode 100644 index e69de29..0000000