From 3d4b30c00f4d113a2657712bdd8395e526eaccf9 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Thu, 11 Nov 2021 07:51:13 +0000 Subject: [PATCH] new DDO (#941) * type out new DDO * remove all DDO ocean.js imports * move over as much as possible to new DDO structure * DDO/Asset split-up * use Asset typing instead of DDO almost everywhere * more typings * more DDO refactor * ddo typings updates * more DDO updates * updates * ddo updates --- content/publish/form.json | 4 +- src/@context/Asset.tsx | 82 ++--- src/@context/Profile.tsx | 6 +- src/@hooks/usePricing.ts | 50 +-- src/@hooks/usePublish.ts | 51 ++- src/@types/Asset.d.ts | 33 ++ src/@types/DDO/Credentials.d.ts | 9 + src/@types/DDO/File.d.ts | 18 + src/@types/DDO/Metadata.d.ts | 24 ++ src/@types/DDO/Services.d.ts | 23 ++ src/@types/DDO/index.d.ts | 12 + src/@types/aquarius/DownloadedAsset.d.ts | 16 +- src/@types/aquarius/MetaData.d.ts | 34 -- src/@types/aquarius/PagedAssets.d.ts | 16 +- src/@types/aquarius/SearchResponse.d.ts | 79 ++-- src/@utils/aquarius.ts | 35 +- src/@utils/checkPreviousOrder.ts | 26 +- src/@utils/compute.ts | 60 ++- src/@utils/ddo.ts | 15 +- src/@utils/provider.ts | 2 +- src/@utils/subgraph.ts | 34 +- .../@shared/AssetList/AssetList.tsx | 3 +- .../@shared/AssetList/AssetListTitle.tsx | 6 +- .../@shared/AssetTeaser/AssetTeaser.tsx | 18 +- src/components/@shared/FileIcon/index.tsx | 1 - .../Form/FormFields/FilesInput/Info.tsx | 1 - .../@shared/Form/Input/InputElement.tsx | 2 +- .../@shared/PoolTransactions/index.tsx | 4 +- .../@shared/TokenApproval/index.tsx | 4 +- .../AlgorithmDatasetsListForCompute.tsx | 15 +- .../Compute/FormComputeDataset.tsx | 11 +- .../Asset/AssetActions/Compute/index.tsx | 342 +++++++++--------- src/components/Asset/AssetActions/Consume.tsx | 17 +- .../AssetActions/Edit/DebugEditCompute.tsx | 4 +- .../AssetActions/Edit/EditComputeDataset.tsx | 105 +++--- .../Edit/FormEditComputeDataset.tsx | 9 +- .../Asset/AssetActions/Edit/_constants.ts | 13 +- .../Asset/AssetActions/Edit/_types.ts | 10 + .../Asset/AssetActions/Edit/index.tsx | 151 ++++---- .../Asset/AssetActions/Pool/index.tsx | 13 +- .../Asset/AssetActions/Trade/FormTrade.tsx | 4 +- .../Asset/AssetActions/Trade/Swap.tsx | 11 +- .../Asset/AssetActions/Trade/index.tsx | 9 +- src/components/Asset/AssetActions/index.tsx | 39 +- .../Asset/AssetContent/EditHistory.tsx | 2 +- .../Asset/AssetContent/MetaFull.tsx | 12 +- .../Asset/AssetContent/MetaMain.tsx | 13 +- .../Asset/AssetContent/MetaSecondary.tsx | 15 +- src/components/Asset/AssetContent/index.tsx | 24 +- src/components/Home/Bookmarks.tsx | 4 +- src/components/Home/index.tsx | 8 +- .../Profile/History/ComputeJobs/Details.tsx | 4 +- src/components/Profile/History/PoolShares.tsx | 21 +- src/components/Publish/Preview/index.tsx | 1 - src/components/Publish/Pricing/index.tsx | 1 - src/components/Publish/Services/index.tsx | 4 +- src/components/Publish/_constants.tsx | 7 +- src/components/Publish/_types.ts | 10 +- src/components/Publish/_utils.ts | 62 ++-- src/components/Publish/index.tsx | 6 +- 60 files changed, 838 insertions(+), 777 deletions(-) create mode 100644 src/@types/Asset.d.ts create mode 100644 src/@types/DDO/Credentials.d.ts create mode 100644 src/@types/DDO/File.d.ts create mode 100644 src/@types/DDO/Metadata.d.ts create mode 100644 src/@types/DDO/Services.d.ts create mode 100644 src/@types/DDO/index.d.ts delete mode 100644 src/@types/aquarius/MetaData.d.ts create mode 100644 src/components/Asset/AssetActions/Edit/_types.ts diff --git a/content/publish/form.json b/content/publish/form.json index dc14d284b..1aaa11fbb 100644 --- a/content/publish/form.json +++ b/content/publish/form.json @@ -97,9 +97,9 @@ }, { - "name": "providerUri", + "name": "providerUrl", "label": "Custom Provider URL", - "type": "providerUri", + "type": "providerUrl", "help": "Enter the URL for your custom provider or leave blank to use the default provider. [Learn more](https://github.com/oceanprotocol/provider/).", "placeholder": "e.g. https://provider.polygon.oceanprotocol.com/" } diff --git a/src/@context/Asset.tsx b/src/@context/Asset.tsx index f99780522..489959e2e 100644 --- a/src/@context/Asset.tsx +++ b/src/@context/Asset.tsx @@ -7,7 +7,7 @@ import React, { useCallback, ReactNode } from 'react' -import { Logger, DDO, MetadataMain } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData' import getAssetPurgatoryData from '@utils/purgatory' import { CancelToken } from 'axios' @@ -20,13 +20,10 @@ import { useCancelToken } from '@hooks/useCancelToken' interface AssetProviderValue { isInPurgatory: boolean purgatoryData: PurgatoryData - ddo: DDO - did: string - metadata: MetadataMarket + ddo: Asset title: string owner: string price: BestPrice - type: MetadataMain['type'] error?: string refreshInterval: number isAssetNetwork: boolean @@ -42,7 +39,7 @@ function AssetProvider({ asset, children }: { - asset: string | DDO + asset: string | Asset children: ReactNode }): ReactElement { const { appConfig } = useSiteMetadata() @@ -50,17 +47,17 @@ function AssetProvider({ const { networkId } = useWeb3() const [isInPurgatory, setIsInPurgatory] = useState(false) const [purgatoryData, setPurgatoryData] = useState() - const [ddo, setDDO] = useState() + const [ddo, setDDO] = useState() const [did, setDID] = useState() - const [metadata, setMetadata] = useState() const [title, setTitle] = useState() const [price, setPrice] = useState() const [owner, setOwner] = useState() const [error, setError] = useState() - const [type, setType] = useState() const [loading, setLoading] = useState(false) const [isAssetNetwork, setIsAssetNetwork] = useState() + const newCancelToken = useCancelToken() + const fetchDdo = async (token?: CancelToken) => { Logger.log('[asset] Init asset, get DDO') setLoading(true) @@ -85,27 +82,6 @@ function AssetProvider({ setLoading(false) } - // - // Get and set DDO based on passed DDO or DID - // - useEffect(() => { - if (!asset || !appConfig.metadataCacheUri) return - - let isMounted = true - - async function init() { - const ddo = await fetchDdo(newCancelToken()) - if (!isMounted) return - Logger.debug('[asset] Got DDO', ddo) - setDDO(ddo) - setDID(asset as string) - } - init() - return () => { - isMounted = false - } - }, [asset, appConfig.metadataCacheUri]) - const setPurgatory = useCallback(async (did: string): Promise => { if (!did) return @@ -119,29 +95,41 @@ function AssetProvider({ } }, []) - const initMetadata = useCallback(async (ddo: DDO): Promise => { + // + // Get and set DDO based on passed DDO or DID + // + useEffect(() => { + if (!asset || !appConfig.metadataCacheUri) return + + let isMounted = true + + async function init() { + const ddo = await fetchDdo(newCancelToken()) + if (!isMounted || !ddo) return + Logger.debug('[asset] Got DDO', ddo) + setDDO(ddo) + setDID(asset as string) + setTitle(ddo.metadata.name) + setOwner(ddo.nft.owner) + setIsInPurgatory(ddo.isInPurgatory === 'true') + await setPurgatory(ddo.id) + } + init() + return () => { + isMounted = false + } + }, [asset, appConfig.metadataCacheUri]) + + const initPrice = useCallback(async (ddo: Asset): Promise => { if (!ddo) return - setLoading(true) const returnedPrice = await getPrice(ddo) setPrice({ ...returnedPrice }) - - // Get metadata from DDO - const { attributes } = ddo.findServiceByType('metadata') - setMetadata(attributes as unknown as MetadataMarket) - setTitle(attributes?.main.name) - setType(attributes.main.type) - setOwner(ddo.publicKey[0].owner) - Logger.log('[asset] Got Metadata from DDO', attributes) - - setIsInPurgatory(ddo.isInPurgatory === 'true') - await setPurgatory(ddo.id) - setLoading(false) }, []) useEffect(() => { if (!ddo) return - initMetadata(ddo) - }, [ddo, initMetadata]) + initPrice(ddo) + }, [ddo, initPrice]) // Check user network against asset network useEffect(() => { @@ -157,11 +145,9 @@ function AssetProvider({ { ddo, did, - metadata, title, owner, price, - type, error, isInPurgatory, purgatoryData, diff --git a/src/@context/Profile.tsx b/src/@context/Profile.tsx index 3210c8a7a..a0f5f3115 100644 --- a/src/@context/Profile.tsx +++ b/src/@context/Profile.tsx @@ -14,7 +14,7 @@ import { } from '@utils/subgraph' import { useUserPreferences } from './UserPreferences' import { PoolShares_poolShares as PoolShare } from '../@types/apollo/PoolShares' -import { DDO, Logger } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { getDownloadAssets, getPublishedAssets } from '@utils/aquarius' import { useSiteMetadata } from '@hooks/useSiteMetadata' import { accountTruncate } from '@utils/web3' @@ -27,7 +27,7 @@ interface ProfileProviderValue { profile: Profile poolShares: PoolShare[] isPoolSharesLoading: boolean - assets: DDO[] + assets: Asset[] assetsTotal: number isEthAddress: boolean downloads: DownloadedAsset[] @@ -170,7 +170,7 @@ function ProfileProvider({ // // PUBLISHED ASSETS // - const [assets, setAssets] = useState() + const [assets, setAssets] = useState() const [assetsTotal, setAssetsTotal] = useState(0) // const [assetsWithPrices, setAssetsWithPrices] = useState() diff --git a/src/@hooks/usePricing.ts b/src/@hooks/usePricing.ts index 06a0a6ab6..452c854f6 100644 --- a/src/@hooks/usePricing.ts +++ b/src/@hooks/usePricing.ts @@ -1,4 +1,4 @@ -import { DDO, Logger } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { useState } from 'react' import { TransactionReceipt } from 'web3-core' import { Decimal } from 'decimal.js' @@ -14,17 +14,17 @@ import { useOcean } from '@context/Ocean' import { useWeb3 } from '@context/Web3' interface UsePricing { - getDTSymbol: (ddo: DDO) => Promise - getDTName: (ddo: DDO) => Promise + getDTSymbol: (ddo: Asset) => Promise + getDTName: (ddo: Asset) => Promise createPricing: ( priceOptions: PriceOptions, - ddo: DDO + ddo: Asset ) => Promise - mint: (tokensToMint: string, ddo: DDO) => Promise + mint: (tokensToMint: string, ddo: Asset) => Promise buyDT: ( amountDataToken: number | string, price: BestPrice, - ddo: DDO + ddo: Asset ) => Promise pricingStep?: number pricingStepText?: string @@ -40,28 +40,28 @@ function usePricing(): UsePricing { const [pricingStepText, setPricingStepText] = useState() const [pricingError, setPricingError] = useState() - async function getDTSymbol(ddo: DDO): Promise { + async function getDTSymbol(ddo: Asset): Promise { if (!ocean || !accountId) return - const { dataToken, dataTokenInfo } = ddo + const { dataTokenInfo } = ddo return dataTokenInfo ? dataTokenInfo.symbol - : await ocean?.datatokens.getSymbol(dataToken) + : await ocean?.datatokens.getSymbol(dataTokenInfo.address) } - async function getDTName(ddo: DDO): Promise { + async function getDTName(ddo: Asset): Promise { if (!ocean || !accountId) return - const { dataToken, dataTokenInfo } = ddo + const { dataTokenInfo } = ddo return dataTokenInfo ? dataTokenInfo.name - : await ocean?.datatokens.getName(dataToken) + : await ocean?.datatokens.getName(dataTokenInfo.address) } // Helper for setting steps & feedback for all flows async function setStep( index: number, type: 'pool' | 'exchange' | 'free' | 'buy' | 'dispense', - ddo: DDO + ddo: Asset ) { const dtSymbol = await getDTSymbol(ddo) setPricingStep(index) @@ -92,18 +92,18 @@ function usePricing(): UsePricing { async function mint( tokensToMint: string, - ddo: DDO + ddo: Asset ): Promise { - const { dataToken } = ddo - Logger.log('mint function', dataToken, accountId) + const { dataTokenInfo } = ddo + Logger.log('mint function', dataTokenInfo.address, accountId) const balance = new Decimal( - await ocean.datatokens.balance(dataToken, accountId) + await ocean.datatokens.balance(dataTokenInfo.address, accountId) ) const tokens = new Decimal(tokensToMint) if (tokens.greaterThan(balance)) { const mintAmount = tokens.minus(balance) const tx = await ocean.datatokens.mint( - dataToken, + dataTokenInfo.address, accountId, mintAmount.toString() ) @@ -114,7 +114,7 @@ function usePricing(): UsePricing { async function buyDT( amountDataToken: number | string, price: BestPrice, - ddo: DDO + ddo: Asset ): Promise { if (!ocean || !accountId) return @@ -181,18 +181,20 @@ function usePricing(): UsePricing { case 'free': { setStep(1, 'dispense', ddo) const isDispensable = await ocean.OceanDispenser.isDispensable( - ddo.dataToken, + ddo?.services[0].datatokenAddress, accountId, '1' ) if (!isDispensable) { - Logger.error(`Dispenser for ${ddo.dataToken} failed to dispense`) + Logger.error( + `Dispenser for ${ddo?.services[0].datatokenAddress} failed to dispense` + ) return } tx = await ocean.OceanDispenser.dispense( - ddo.dataToken, + ddo?.services[0].datatokenAddress, accountId, '1' ) @@ -215,9 +217,9 @@ function usePricing(): UsePricing { async function createPricing( priceOptions: PriceOptions, - ddo: DDO + ddo: Asset ): Promise { - const { dataToken } = ddo + const dataToken = ddo?.services[0].datatokenAddress const dtSymbol = await getDTSymbol(ddo) if (!ocean || !accountId || !dtSymbol) return diff --git a/src/@hooks/usePublish.ts b/src/@hooks/usePublish.ts index b4327d2fc..51ad05270 100644 --- a/src/@hooks/usePublish.ts +++ b/src/@hooks/usePublish.ts @@ -1,11 +1,10 @@ -import { DDO, Logger, Metadata } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { Service, ServiceComputePrivacy, ServiceType } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service' import { useEffect, useState } from 'react' -import { sleep } from '@utils/index' import { publishFeedback } from '@utils/feedback' import { useOcean } from '@context/Ocean' import { useWeb3 } from '@context/Web3' @@ -19,12 +18,12 @@ export interface DataTokenOptions { interface UsePublish { publish: ( - asset: Metadata, + asset: DDO, serviceType: ServiceType, dataTokenOptions?: DataTokenOptions, timeout?: number, providerUri?: string - ) => Promise + ) => Promise publishStep?: number publishStepText?: string publishError?: string @@ -63,15 +62,15 @@ function usePublish(): UsePublish { * @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 {DataTokenOptions} dataTokenOptions custom name, symbol and cap for datatoken - * @return {Promise} Returns the newly published ddo + * @return {Promise} Returns the newly published ddo */ async function publish( - asset: Metadata, + asset: Asset, serviceType: ServiceType, dataTokenOptions?: DataTokenOptions, timeout?: number, providerUri?: string - ): Promise { + ): Promise { if (!ocean || !account) return null setIsLoading(true) setPublishError(undefined) @@ -82,7 +81,7 @@ function usePublish(): UsePublish { new Date(Date.now()).toISOString().split('.')[0] + 'Z' const services: Service[] = [] const price = '1' - asset.main.dateCreated = asset.main.datePublished = publishedDate + asset.created = publishedDate switch (serviceType) { case 'access': { @@ -125,24 +124,24 @@ function usePublish(): UsePublish { Logger.log('services created', services) - const ddo = await ocean.assets - .create( - asset, - account, - services, - undefined, - dataTokenOptions?.cap, - dataTokenOptions?.name, - dataTokenOptions?.symbol, - providerUri - ) - .next(setStep) - Logger.log('ddo created', ddo) - await ocean.assets.publishDdo(ddo, account.getId()) - Logger.log('ddo published') - await sleep(20000) - setStep(7) - return ddo + // const ddo = await ocean.assets + // .create( + // asset, + // account, + // services, + // undefined, + // dataTokenOptions?.cap, + // dataTokenOptions?.name, + // dataTokenOptions?.symbol, + // providerUri + // ) + // .next(setStep) + // Logger.log('ddo created', ddo) + // await ocean.assets.publishDdo(ddo, account.getId()) + // Logger.log('ddo published') + // await sleep(20000) + // setStep(7) + // return ddo } catch (error) { setPublishError(error.message) Logger.error(error) diff --git a/src/@types/Asset.d.ts b/src/@types/Asset.d.ts new file mode 100644 index 000000000..4111fc97b --- /dev/null +++ b/src/@types/Asset.d.ts @@ -0,0 +1,33 @@ +interface AssetNft { + address: string + name: string + symbol: string + owner: string + state: 0 | 1 | 2 | 3 | 4 +} + +interface AssetDatatoken { + name: string + symbol: string + address: string + serviceId: string +} + +interface AssetLastEvent { + tx: string + block: number + from: string + contract: string +} + +interface Asset extends DDO { + nft: AssetNft + datatokens: AssetDatatoken[] + event: AssetLastEvent + stats: { consume: number } + isInPurgatory: string + + // This is fake and most likely won't be used like this. + // Just here so we can continue to have successful builds. + dataTokenInfo: AssetDatatoken +} diff --git a/src/@types/DDO/Credentials.d.ts b/src/@types/DDO/Credentials.d.ts new file mode 100644 index 000000000..bebe34a9d --- /dev/null +++ b/src/@types/DDO/Credentials.d.ts @@ -0,0 +1,9 @@ +interface Credential { + type: string + values: string[] +} + +interface Credentials { + allow: Credential[] + deny: Credential[] +} diff --git a/src/@types/DDO/File.d.ts b/src/@types/DDO/File.d.ts new file mode 100644 index 000000000..79ba55e53 --- /dev/null +++ b/src/@types/DDO/File.d.ts @@ -0,0 +1,18 @@ +// This is all super questionable, +// but we most likely need something to represent what we get +// back from fileinfo endpoint in Provider. But then should be moved out of DDO typings. + +interface FileMetadata { + url: string + contentType: string + name?: string + checksum?: string + checksumType?: string + contentLength?: string + encoding?: string + compression?: string + encrypted?: boolean + encryptionMode?: string + resourceId?: string + attributes?: { [key: string]: any } +} diff --git a/src/@types/DDO/Metadata.d.ts b/src/@types/DDO/Metadata.d.ts new file mode 100644 index 000000000..7b9a17162 --- /dev/null +++ b/src/@types/DDO/Metadata.d.ts @@ -0,0 +1,24 @@ +interface MetadataAlgorithm { + language?: string + version?: string + container: { + entrypoint: string + image: string + tag: string + checksum: string + } +} + +interface Metadata { + name: string + description: string + type: 'dataset' | 'algorithm' + author: string + license: string + links?: string[] + tags?: string[] + copyrightHolder?: string + contentLanguage?: string + algorithm?: MetadataAlgorithm + additionalInformation?: any +} diff --git a/src/@types/DDO/Services.d.ts b/src/@types/DDO/Services.d.ts new file mode 100644 index 000000000..21e956879 --- /dev/null +++ b/src/@types/DDO/Services.d.ts @@ -0,0 +1,23 @@ +interface PublisherTrustedAlgorithm { + did: string + filesChecksum: string + containerSectionChecksum: string +} + +interface ServiceComputePrivacy { + allowRawAlgorithm: boolean + allowNetworkAccess: boolean + publisherTrustedAlgorithmPublishers: string[] + publisherTrustedAlgorithms: PublisherTrustedAlgorithm[] +} + +interface Service { + type: 'access' | 'compute' | string + files: string + datatokenAddress: string + serviceEndpoint: string + timeout: string + name?: string + description?: string + privacy?: ServiceComputePrivacy +} diff --git a/src/@types/DDO/index.d.ts b/src/@types/DDO/index.d.ts new file mode 100644 index 000000000..843f34888 --- /dev/null +++ b/src/@types/DDO/index.d.ts @@ -0,0 +1,12 @@ +// DDO spec +interface DDO { + '@context': string[] + id: string + version: string + chainId: number + created: string + updated?: string + metadata: Metadata + services: Service[] + credentials?: Credentials +} diff --git a/src/@types/aquarius/DownloadedAsset.d.ts b/src/@types/aquarius/DownloadedAsset.d.ts index 97a2052bf..b0e55db2a 100644 --- a/src/@types/aquarius/DownloadedAsset.d.ts +++ b/src/@types/aquarius/DownloadedAsset.d.ts @@ -1,12 +1,6 @@ -import { DDO } from '@oceanprotocol/lib' - -// declaring into global scope to be able to use this as -// ambiant types despite the above imports -declare global { - interface DownloadedAsset { - dtSymbol: string - timestamp: number - networkId: number - ddo: DDO - } +interface DownloadedAsset { + dtSymbol: string + timestamp: number + networkId: number + ddo: Asset } diff --git a/src/@types/aquarius/MetaData.d.ts b/src/@types/aquarius/MetaData.d.ts deleted file mode 100644 index af6ec5022..000000000 --- a/src/@types/aquarius/MetaData.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - Metadata, - AdditionalInformation, - EditableMetadataLinks -} from '@oceanprotocol/lib' - -// declaring into global scope to be able to use this as -// ambiant types despite the above imports -declare global { - interface DdoMarket { - metadata: any - services: any[] - } - - interface AdditionalInformationMarket extends AdditionalInformation { - termsAndConditions: boolean - } - - interface MetadataMarket extends Metadata { - // While required for this market, Aquarius/Plecos will keep this as optional - // allowing external pushes of assets without `additionalInformation`. - // Making it optional here helps safeguarding against those assets. - additionalInformation?: AdditionalInformationMarket - } - - interface MetadataEditForm { - name: string - description: string - timeout: string - price?: number - links?: string | EditableMetadataLinks[] - author?: string - } -} diff --git a/src/@types/aquarius/PagedAssets.d.ts b/src/@types/aquarius/PagedAssets.d.ts index 008d940a9..2e30d7070 100644 --- a/src/@types/aquarius/PagedAssets.d.ts +++ b/src/@types/aquarius/PagedAssets.d.ts @@ -1,12 +1,6 @@ -import { DDO } from '@oceanprotocol/lib' - -// declaring into global scope to be able to use this as -// ambiant types despite the above imports -declare global { - interface PagedAssets { - results: DDO[] - page: number - totalPages: number - totalResults: number - } +interface PagedAssets { + results: Asset[] + page: number + totalPages: number + totalResults: number } diff --git a/src/@types/aquarius/SearchResponse.d.ts b/src/@types/aquarius/SearchResponse.d.ts index 2d2a02f97..a90df2095 100644 --- a/src/@types/aquarius/SearchResponse.d.ts +++ b/src/@types/aquarius/SearchResponse.d.ts @@ -1,46 +1,41 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable camelcase */ -import { DDO } from '@oceanprotocol/lib' -// declaring into global scope to be able to use this as -// ambiant types despite the above imports -declare global { - interface Explanation { - value: number - description: string - details: Explanation[] - } - - interface ShardsResponse { - total: number - successful: number - failed: number - skipped: number - } - - interface SearchResponse { - took: number - timed_out: boolean - _scroll_id?: string | undefined - _shards: ShardsResponse - hits: { - total: number - max_score: number - hits: Array<{ - _index: string - _type: string - _id: string - _score: number - _source: DDO - _version?: number | undefined - _explanation?: Explanation | undefined - fields?: any - highlight?: any - inner_hits?: any - matched_queries?: string[] | undefined - sort?: string[] | undefined - }> - } - aggregations?: any - } +interface Explanation { + value: number + description: string + details: Explanation[] +} + +interface ShardsResponse { + total: number + successful: number + failed: number + skipped: number +} + +interface SearchResponse { + took: number + timed_out: boolean + _scroll_id?: string | undefined + _shards: ShardsResponse + hits: { + total: number + max_score: number + hits: Array<{ + _index: string + _type: string + _id: string + _score: number + _source: Asset + _version?: number | undefined + _explanation?: Explanation | undefined + fields?: any + highlight?: any + inner_hits?: any + matched_queries?: string[] | undefined + sort?: string[] | undefined + }> + } + aggregations?: any } diff --git a/src/@utils/aquarius.ts b/src/@utils/aquarius.ts index 45e8b2297..e115f0426 100644 --- a/src/@utils/aquarius.ts +++ b/src/@utils/aquarius.ts @@ -1,9 +1,4 @@ -import { - DDO, - DID, - Logger, - publisherTrustedAlgorithm as PublisherTrustedAlgorithm -} from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection' import { PriceList, getAssetsPriceList } from './subgraph' import axios, { CancelToken, AxiosResponse } from 'axios' @@ -13,6 +8,7 @@ import { SortDirectionOptions, SortTermOptions } from '../@types/aquarius/SearchQuery' +import { getServiceByName } from './ddo' export const MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS = 476 @@ -77,7 +73,7 @@ export function transformQueryResult( } result.results = (queryResult.hits.hits || []).map( - (hit) => new DDO(hit._source as DDO) + (hit) => hit._source as Asset ) result.totalResults = queryResult.hits.total result.totalPages = @@ -111,18 +107,18 @@ export async function queryMetadata( } export async function retrieveDDO( - did: string | DID, + did: string, cancelToken: CancelToken -): Promise { +): Promise { try { - const response: AxiosResponse = await axios.get( + const response: AxiosResponse = await axios.get( `${metadataCacheUri}/api/v1/aquarius/assets/ddo/${did}`, { cancelToken } ) if (!response || response.status !== 200 || !response.data) return const data = { ...response.data } - return new DDO(data) + return data } catch (error) { if (axios.isCancel(error)) { Logger.log(error.message) @@ -133,7 +129,7 @@ export async function retrieveDDO( } export async function getAssetsNames( - didList: string[] | DID[], + didList: string[], cancelToken: CancelToken ): Promise> { try { @@ -179,10 +175,10 @@ export async function retrieveDDOListByDIDs( didList: string[], chainIds: number[], cancelToken: CancelToken -): Promise { +): Promise { try { if (didList?.length === 0 || chainIds?.length === 0) return [] - const orderedDDOListByDIDList: DDO[] = [] + const orderedDDOListByDIDList: Asset[] = [] const baseQueryparams = { chainIds, filters: [getFilterTerm('id', didList)], @@ -190,8 +186,8 @@ export async function retrieveDDOListByDIDs( } as BaseQueryParams const query = generateBaseQuery(baseQueryparams) const result = await queryMetadata(query, cancelToken) - didList.forEach((did: string | DID) => { - const ddo: DDO = result.results.find((ddo: DDO) => ddo.id === did) + didList.forEach((did: string) => { + const ddo = result.results.find((ddo: Asset) => ddo.id === did) orderedDDOListByDIDList.push(ddo) }) return orderedDDOListByDIDList @@ -202,7 +198,7 @@ export async function retrieveDDOListByDIDs( export async function transformDDOToAssetSelection( datasetProviderEndpoint: string, - ddoList: DDO[], + ddoList: Asset[], selectedAlgorithms?: PublisherTrustedAlgorithm[], cancelToken?: CancelToken ): Promise { @@ -213,7 +209,7 @@ export async function transformDDOToAssetSelection( for (const ddo of ddoList) { didList.push(ddo.id) symbolList[ddo.id] = ddo.dataTokenInfo.symbol - const algoComputeService = ddo.findServiceByType('compute') + const algoComputeService = getServiceByName(ddo, 'compute') algoComputeService?.serviceEndpoint && (didProviderEndpointMap[ddo.id] = algoComputeService?.serviceEndpoint) } @@ -350,7 +346,8 @@ export async function getDownloadAssets( .map((ddo) => { const order = tokenOrders.find( ({ datatokenId }) => - datatokenId?.address.toLowerCase() === ddo.dataToken.toLowerCase() + datatokenId?.address.toLowerCase() === + ddo.services[0].datatokenAddress.toLowerCase() ) return { diff --git a/src/@utils/checkPreviousOrder.ts b/src/@utils/checkPreviousOrder.ts index 066dfdf90..cf07b0622 100644 --- a/src/@utils/checkPreviousOrder.ts +++ b/src/@utils/checkPreviousOrder.ts @@ -1,21 +1,23 @@ -import { DDO, Ocean, ServiceType } from '@oceanprotocol/lib' +import { Ocean } from '@oceanprotocol/lib' +import { getServiceByName } from './ddo' export default async function checkPreviousOrder( ocean: Ocean, accountId: string, - ddo: DDO, - serviceType: ServiceType + ddo: Asset, + serviceType: 'access' | 'compute' ): Promise { if (!ocean) return - const service = ddo.findServiceByType(serviceType) + const service = getServiceByName(ddo, serviceType) // apparenlty cost and timeout are not found, even though they are there... - const previousOrder = await ocean.datatokens.getPreviousValidOrders( - ddo.dataToken, - (service.attributes.main as any).cost, - service.index, - (service.attributes.main as any).timeout, - accountId - ) - return previousOrder + // const previousOrder = await ocean.datatokens.getPreviousValidOrders( + // ddo?.services[0].datatokenAddress, + // service.cost, + // service.index, + // service.timeout, + // accountId + // ) + // return previousOrder + return 'dummy' } diff --git a/src/@utils/compute.ts b/src/@utils/compute.ts index 398a521bc..efbaca79e 100644 --- a/src/@utils/compute.ts +++ b/src/@utils/compute.ts @@ -1,7 +1,6 @@ import { ServiceComputePrivacy, publisherTrustedAlgorithm as PublisherTrustedAlgorithm, - DDO, Service, Logger, Provider, @@ -59,7 +58,7 @@ async function getAssetMetadata( queryDtList: string[], cancelToken: CancelToken, chainIds: number[] -): Promise { +): Promise { const baseQueryparams = { chainIds, filters: [ @@ -75,35 +74,37 @@ async function getAssetMetadata( return result.results } -function getServiceEndpoints(data: TokenOrder[], assets: DDO[]): string[] { - const serviceEndpoints: string[] = [] +function getServiceEndpoints(data: TokenOrder[], assets: Asset[]): string[] { + // const serviceEndpoints: string[] = [] - for (let i = 0; i < data.length; i++) { - try { - const did = web3.utils - .toChecksumAddress(data[i].datatokenId.address) - .replace('0x', 'did:op:') - const ddo = assets.filter((x) => x.id === did)[0] - if (ddo === undefined) continue + // for (let i = 0; i < data.length; i++) { + // try { + // const did = web3.utils + // .toChecksumAddress(data[i].datatokenId.address) + // .replace('0x', 'did:op:') + // const ddo = assets.filter((x) => x.id === did)[0] + // if (ddo === undefined) continue - const service = ddo.service.filter( - (x: Service) => x.index === data[i].serviceId - )[0] + // const service = ddo.services.filter( + // (x: Service) => x.index === data[i].serviceId + // )[0] - if (!service || service.type !== 'compute') continue - const { serviceEndpoint } = service + // if (!service || service.type !== 'compute') continue + // const { providerEndpoint } = service - const wasProviderQueried = - serviceEndpoints?.filter((x) => x === serviceEndpoint).length > 0 + // const wasProviderQueried = + // serviceEndpoints?.filter((x) => x === providerEndpoint).length > 0 - if (wasProviderQueried) continue - serviceEndpoints.push(serviceEndpoint) - } catch (err) { - Logger.error(err.message) - } - } + // if (wasProviderQueried) continue + // serviceEndpoints.push(providerEndpoint) + // } catch (err) { + // Logger.error(err.message) + // } + // } - return serviceEndpoints + // return serviceEndpoints + + return ['dummy'] } async function getProviders( @@ -138,7 +139,7 @@ async function getProviders( async function getJobs( providers: Provider[], account: Account, - assets: DDO[] + assets: Asset[] ): Promise { const computeJobs: ComputeJobMetaData[] = [] @@ -170,13 +171,10 @@ async function getJobs( const ddo = assets.filter((x) => x.id === did)[0] if (!ddo) continue - const serviceMetadata = ddo.service.filter( - (x: Service) => x.type === 'metadata' - )[0] const compJob: ComputeJobMetaData = { ...job, - assetName: serviceMetadata.attributes.main.name, + assetName: ddo.metadata.name, assetDtSymbol: ddo.dataTokenInfo.symbol, networkId: ddo.chainId } @@ -205,7 +203,7 @@ export async function getComputeJobs( config: Config, ocean: Ocean, account: Account, - ddo?: DDO, + ddo?: Asset, token?: CancelToken ): Promise { const assetDTAddress = ddo?.dataTokenInfo?.address diff --git a/src/@utils/ddo.ts b/src/@utils/ddo.ts index ac03cecfa..bf7002efe 100644 --- a/src/@utils/ddo.ts +++ b/src/@utils/ddo.ts @@ -1,8 +1,15 @@ -import axios from 'axios' -import { toast } from 'react-toastify' -import isUrl from 'is-url-superb' import slugify from 'slugify' -import { MetadataAlgorithm, Logger } from '@oceanprotocol/lib' +import { MetadataAlgorithm } from '@oceanprotocol/lib' + +export function getServiceByName( + ddo: Asset | DDO, + name: 'access' | 'compute' +): Service { + if (!ddo) return + + const service = ddo.services.filter((service) => service.type === name)[0] + return service +} export function dateToStringNoMS(date: Date): string { return date.toISOString().replace(/\.[0-9]{3}Z/, 'Z') diff --git a/src/@utils/provider.ts b/src/@utils/provider.ts index deae9236e..f5812f0ed 100644 --- a/src/@utils/provider.ts +++ b/src/@utils/provider.ts @@ -1,6 +1,6 @@ import axios, { CancelToken, AxiosResponse } from 'axios' import { toast } from 'react-toastify' -import { DID, File as FileMetadata, Logger } from '@oceanprotocol/lib' +import { DID, Logger } from '@oceanprotocol/lib' export async function fileinfo( url: string, diff --git a/src/@utils/subgraph.ts b/src/@utils/subgraph.ts index 6b08c3f1e..38819d064 100644 --- a/src/@utils/subgraph.ts +++ b/src/@utils/subgraph.ts @@ -1,5 +1,5 @@ import { gql, OperationResult, TypedDocumentNode, OperationContext } from 'urql' -import { DDO, Logger } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { getUrqlClientInstance } from '@context/UrqlProvider' import { getOceanConfig } from './ocean' import { @@ -35,7 +35,7 @@ export interface PriceList { } export interface AssetListPrices { - ddo: DDO + ddo: Asset price: BestPrice } @@ -402,7 +402,7 @@ function transformPriceToBestPrice( } async function getAssetsPoolsExchangesAndDatatokenMap( - assets: DDO[] + assets: Asset[] ): Promise< [ AssetsPoolPricePool[], @@ -415,13 +415,17 @@ async function getAssetsPoolsExchangesAndDatatokenMap( const chainAssetLists: any = {} for (const ddo of assets) { - didDTMap[ddo?.dataToken.toLowerCase()] = ddo.id + didDTMap[ddo?.services[0].datatokenAddress.toLowerCase()] = ddo.id // harcoded until we have chainId on assets if (chainAssetLists[ddo.chainId]) { - chainAssetLists[ddo.chainId].push(ddo?.dataToken.toLowerCase()) + chainAssetLists[ddo.chainId].push( + ddo?.services[0].datatokenAddress.toLowerCase() + ) } else { chainAssetLists[ddo.chainId] = [] - chainAssetLists[ddo.chainId].push(ddo?.dataToken.toLowerCase()) + chainAssetLists[ddo.chainId].push( + ddo?.services[0].datatokenAddress.toLowerCase() + ) } } let poolPriceResponse: AssetsPoolPricePool[] = [] @@ -464,7 +468,7 @@ async function getAssetsPoolsExchangesAndDatatokenMap( return [poolPriceResponse, frePriceResponse, freePriceResponse, didDTMap] } -export async function getAssetsPriceList(assets: DDO[]): Promise { +export async function getAssetsPriceList(assets: Asset[]): Promise { const priceList: PriceList = {} const values: [ @@ -493,15 +497,15 @@ export async function getAssetsPriceList(assets: DDO[]): Promise { return priceList } -export async function getPrice(asset: DDO): Promise { +export async function getPrice(asset: Asset): Promise { const freVariables = { - datatoken: asset?.dataToken.toLowerCase() + datatoken: asset?.services[0].datatokenAddress.toLowerCase() } const freeVariables = { - datatoken: asset?.dataToken.toLowerCase() + datatoken: asset?.services[0].datatokenAddress.toLowerCase() } const poolVariables = { - datatokenAddress: asset?.dataToken.toLowerCase() + datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase() } const queryContext = getQueryContext(Number(asset.chainId)) @@ -530,9 +534,9 @@ export async function getPrice(asset: DDO): Promise { return bestPrice } -export async function getSpotPrice(asset: DDO): Promise { +export async function getSpotPrice(asset: Asset): Promise { const poolVariables = { - datatokenAddress: asset?.dataToken.toLowerCase() + datatokenAddress: asset?.services[0].datatokenAddress.toLowerCase() } const queryContext = getQueryContext(Number(asset.chainId)) @@ -546,7 +550,7 @@ export async function getSpotPrice(asset: DDO): Promise { } export async function getAssetsBestPrices( - assets: DDO[] + assets: Asset[] ): Promise { const assetsWithPrice: AssetListPrices[] = [] @@ -561,7 +565,7 @@ export async function getAssetsBestPrices( const frePriceResponse = values[1] const freePriceResponse = values[2] for (const ddo of assets) { - const dataToken = ddo.dataToken.toLowerCase() + const dataToken = ddo.services[0].datatokenAddress.toLowerCase() const poolPrice: AssetsPoolPricePool[] = [] const frePrice: AssetsFrePriceFixedRateExchange[] = [] const freePrice: AssetFreePriceDispenser[] = [] diff --git a/src/components/@shared/AssetList/AssetList.tsx b/src/components/@shared/AssetList/AssetList.tsx index ac7cd6548..e10401ea6 100644 --- a/src/components/@shared/AssetList/AssetList.tsx +++ b/src/components/@shared/AssetList/AssetList.tsx @@ -2,7 +2,6 @@ import AssetTeaser from '@shared/AssetTeaser/AssetTeaser' import React, { useEffect, useState } from 'react' import Pagination from '@shared/Pagination' import styles from './AssetList.module.css' -import { DDO } from '@oceanprotocol/lib' import classNames from 'classnames/bind' import { getAssetsBestPrices, AssetListPrices } from '@utils/subgraph' import Loader from '@shared/atoms/Loader' @@ -20,7 +19,7 @@ function LoaderArea() { } declare type AssetListProps = { - assets: DDO[] + assets: Asset[] showPagination: boolean page?: number totalPages?: number diff --git a/src/components/@shared/AssetList/AssetListTitle.tsx b/src/components/@shared/AssetList/AssetListTitle.tsx index 2410823a5..e5c1b0d6e 100644 --- a/src/components/@shared/AssetList/AssetListTitle.tsx +++ b/src/components/@shared/AssetList/AssetListTitle.tsx @@ -1,4 +1,3 @@ -import { DDO } from '@oceanprotocol/lib' import Link from 'next/link' import React, { ReactElement, useEffect, useState } from 'react' import { getAssetsNames } from '@utils/aquarius' @@ -11,7 +10,7 @@ export default function AssetListTitle({ did, title }: { - ddo?: DDO + ddo?: Asset did?: string title?: string }): ReactElement { @@ -21,8 +20,7 @@ export default function AssetListTitle({ useEffect(() => { if (title || !appConfig.metadataCacheUri) return if (ddo) { - const { attributes } = ddo.findServiceByType('metadata') - setAssetTitle(attributes.main.name) + setAssetTitle(ddo.metadata.name) return } diff --git a/src/components/@shared/AssetTeaser/AssetTeaser.tsx b/src/components/@shared/AssetTeaser/AssetTeaser.tsx index 5ad724560..516be30a3 100644 --- a/src/components/@shared/AssetTeaser/AssetTeaser.tsx +++ b/src/components/@shared/AssetTeaser/AssetTeaser.tsx @@ -2,15 +2,15 @@ import React from 'react' import Link from 'next/link' import Dotdotdot from 'react-dotdotdot' import Price from '@shared/Price' -import { DDO } from '@oceanprotocol/lib' import removeMarkdown from 'remove-markdown' import Publisher from '@shared/Publisher' import AssetType from '@shared/AssetType' import NetworkName from '@shared/NetworkName' import styles from './AssetTeaser.module.css' +import { getServiceByName } from '@utils/ddo' declare type AssetTeaserProps = { - ddo: DDO + ddo: Asset price: BestPrice noPublisher?: boolean } @@ -20,12 +20,11 @@ const AssetTeaser: React.FC = ({ price, noPublisher }: AssetTeaserProps) => { - const { attributes } = ddo.findServiceByType('metadata') - const { name, type } = attributes.main + const { name, type, description } = ddo.metadata const { dataTokenInfo } = ddo - const isCompute = Boolean(ddo?.findServiceByType('compute')) + const isCompute = Boolean(getServiceByName(ddo, 'compute')) const accessType = isCompute ? 'compute' : 'access' - const { owner } = ddo.publicKey[0] + const { owner } = ddo.nft return (
@@ -49,12 +48,7 @@ const AssetTeaser: React.FC = ({
- {removeMarkdown( - attributes?.additionalInformation?.description?.substring( - 0, - 300 - ) || '' - )} + {removeMarkdown(description?.substring(0, 300) || '')}
diff --git a/src/components/@shared/FileIcon/index.tsx b/src/components/@shared/FileIcon/index.tsx index 6e3588e17..b0afc17b0 100644 --- a/src/components/@shared/FileIcon/index.tsx +++ b/src/components/@shared/FileIcon/index.tsx @@ -1,5 +1,4 @@ import React, { ReactElement } from 'react' -import { File as FileMetadata } from '@oceanprotocol/lib' import filesize from 'filesize' import classNames from 'classnames/bind' import cleanupContentType from '@utils/cleanupContentType' diff --git a/src/components/@shared/Form/FormFields/FilesInput/Info.tsx b/src/components/@shared/Form/FormFields/FilesInput/Info.tsx index 772f154a2..356041681 100644 --- a/src/components/@shared/Form/FormFields/FilesInput/Info.tsx +++ b/src/components/@shared/Form/FormFields/FilesInput/Info.tsx @@ -1,5 +1,4 @@ import React, { ReactElement, useEffect } from 'react' -import { File as FileMetadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/File' import { prettySize } from './utils' import cleanupContentType from '@utils/cleanupContentType' import styles from './Info.module.css' diff --git a/src/components/@shared/Form/Input/InputElement.tsx b/src/components/@shared/Form/Input/InputElement.tsx index 02faceab6..a07744deb 100644 --- a/src/components/@shared/Form/Input/InputElement.tsx +++ b/src/components/@shared/Form/Input/InputElement.tsx @@ -130,7 +130,7 @@ export default function InputElement({ ) case 'files': return - case 'providerUri': + case 'providerUrl': return case 'datatoken': return diff --git a/src/components/@shared/PoolTransactions/index.tsx b/src/components/@shared/PoolTransactions/index.tsx index 3094ef70b..a1f2fe486 100644 --- a/src/components/@shared/PoolTransactions/index.tsx +++ b/src/components/@shared/PoolTransactions/index.tsx @@ -13,7 +13,7 @@ import { retrieveDDOListByDIDs } from '@utils/aquarius' import { CancelToken } from 'axios' import Title from './Title' import styles from './index.module.css' -import { DDO, Logger } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { useCancelToken } from '@hooks/useCancelToken' const REFETCH_INTERVAL = 20000 @@ -77,7 +77,7 @@ export interface Datatoken { export interface PoolTransaction extends TransactionHistoryPoolTransactions { networkId: number - ddo: DDO + ddo: Asset } const columns = [ diff --git a/src/components/@shared/TokenApproval/index.tsx b/src/components/@shared/TokenApproval/index.tsx index 590da0660..aceedfb12 100644 --- a/src/components/@shared/TokenApproval/index.tsx +++ b/src/components/@shared/TokenApproval/index.tsx @@ -26,7 +26,9 @@ export default function TokenApproval({ const config = getOceanConfig(ddo.chainId) const tokenAddress = - coin === 'OCEAN' ? config.oceanTokenAddress : ddo.dataTokenInfo.address + coin === 'OCEAN' + ? config.oceanTokenAddress + : ddo.services[0].datatokenAddress const spender = price.address const checkTokenApproval = useCallback(async () => { diff --git a/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx b/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx index be89aaaf1..33c9a0b8d 100644 --- a/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx +++ b/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx @@ -4,24 +4,25 @@ import { getAlgorithmDatasetsForCompute } from '@utils/aquarius' import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection' import AssetComputeList from '@shared/AssetList/AssetComputeList' import { useAsset } from '@context/Asset' -import { DDO } from '@oceanprotocol/lib' import { useCancelToken } from '@hooks/useCancelToken' +import { getServiceByName } from '@utils/ddo' export default function AlgorithmDatasetsListForCompute({ algorithmDid, dataset }: { algorithmDid: string - dataset: DDO + dataset: Asset }): ReactElement { - const { type } = useAsset() + const { ddo } = useAsset() const [datasetsForCompute, setDatasetsForCompute] = useState() const newCancelToken = useCancelToken() useEffect(() => { async function getDatasetsAllowedForCompute() { - const isCompute = Boolean(dataset?.findServiceByType('compute')) - const datasetComputeService = dataset.findServiceByType( + const isCompute = Boolean(getServiceByName(dataset, 'compute')) + const datasetComputeService = getServiceByName( + dataset, isCompute ? 'compute' : 'access' ) const datasets = await getAlgorithmDatasetsForCompute( @@ -32,8 +33,8 @@ export default function AlgorithmDatasetsListForCompute({ ) setDatasetsForCompute(datasets) } - type === 'algorithm' && getDatasetsAllowedForCompute() - }, [type]) + ddo.metadata.type === 'algorithm' && getDatasetsAllowedForCompute() + }, [ddo.metadata.type]) return (
diff --git a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx index e7ca97d70..4267e93f8 100644 --- a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx +++ b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx @@ -2,7 +2,6 @@ import React, { ReactElement, useEffect, useState } from 'react' import styles from './FormComputeDataset.module.css' import { Field, Form, FormikContextType, useFormikContext } from 'formik' import Input from '@shared/Form/Input' -import { DDO } from '@oceanprotocol/lib' import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection' import { compareAsBN } from '@utils/numbers' import ButtonBuy from '@shared/ButtonBuy' @@ -38,8 +37,8 @@ export default function FormStartCompute({ consumableFeedback }: { algorithms: AssetSelectionAsset[] - ddoListAlgorithms: DDO[] - setSelectedAlgorithm: React.Dispatch> + ddoListAlgorithms: Asset[] + setSelectedAlgorithm: React.Dispatch> isLoading: boolean isComputeButtonDisabled: boolean hasPreviousOrder: boolean @@ -71,9 +70,9 @@ export default function FormStartCompute({ const [algorithmConsumableStatus, setAlgorithmConsumableStatus] = useState() - function getAlgorithmAsset(algorithmId: string): DDO { + function getAlgorithmAsset(algorithmId: string): Asset { let assetDdo = null - ddoListAlgorithms.forEach((ddo: DDO) => { + ddoListAlgorithms.forEach((ddo: Asset) => { if (ddo.id === algorithmId) assetDdo = ddo }) return assetDdo @@ -87,7 +86,7 @@ export default function FormStartCompute({ if (!accountId || !isConsumable) return async function checkIsConsumable() { const consumable = await ocean.assets.isConsumable( - algorithmDDO, + algorithmDDO as any, accountId.toLowerCase() ) if (consumable) setAlgorithmConsumableStatus(consumable.status) diff --git a/src/components/Asset/AssetActions/Compute/index.tsx b/src/components/Asset/AssetActions/Compute/index.tsx index dd1aded0d..b8b2afddc 100644 --- a/src/components/Asset/AssetActions/Compute/index.tsx +++ b/src/components/Asset/AssetActions/Compute/index.tsx @@ -1,10 +1,5 @@ import React, { useState, ReactElement, useEffect, useCallback } from 'react' -import { - DDO, - File as FileMetadata, - Logger, - publisherTrustedAlgorithm -} from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import { toast } from 'react-toastify' import Price from '@shared/Price' import FileIcon from '@shared/FileIcon' @@ -30,7 +25,7 @@ import axios from 'axios' import FormStartComputeDataset from './FormComputeDataset' import styles from './index.module.css' import SuccessConfetti from '@shared/SuccessConfetti' -import { secondsToString } from '@utils/ddo' +import { getServiceByName, secondsToString } from '@utils/ddo' import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection' import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute' import { getPreviousOrders, getPrice } from '@utils/subgraph' @@ -56,14 +51,14 @@ export default function Compute({ const { appConfig } = useSiteMetadata() const { accountId } = useWeb3() const { ocean, account } = useOcean() - const { price, type, ddo } = useAsset() + const { price, ddo } = useAsset() const { buyDT, pricingError, pricingStepText } = usePricing() const [isJobStarting, setIsJobStarting] = useState(false) const [error, setError] = useState() const [algorithmList, setAlgorithmList] = useState() - const [ddoAlgorithmList, setDdoAlgorithmList] = useState() - const [selectedAlgorithmAsset, setSelectedAlgorithmAsset] = useState() + const [ddoAlgorithmList, setDdoAlgorithmList] = useState() + const [selectedAlgorithmAsset, setSelectedAlgorithmAsset] = useState() const [hasAlgoAssetDatatoken, setHasAlgoAssetDatatoken] = useState() const [isPublished, setIsPublished] = useState(false) const [hasPreviousDatasetOrder, setHasPreviousDatasetOrder] = useState(false) @@ -90,19 +85,19 @@ export default function Compute({ !hasAlgoAssetDatatoken && !isAlgoConsumablePrice) + const { timeout } = ddo?.services[0] + async function checkPreviousOrders(ddo: DDO) { - const { timeout } = ( - ddo.findServiceByType('access') || ddo.findServiceByType('compute') - ).attributes.main + const { type } = ddo.metadata + const orderId = await getPreviousOrders( - ddo.dataToken?.toLowerCase(), + ddo.services[0].datatokenAddress?.toLowerCase(), accountId?.toLowerCase(), timeout.toString() ) - const assetType = ddo.findServiceByType('metadata').attributes.main.type if (!isMounted()) return - if (assetType === 'algorithm') { + if (type === 'algorithm') { setPreviousAlgorithmOrderId(orderId) setHasPreviousAlgorithmOrder(!!orderId) } else { @@ -113,7 +108,7 @@ export default function Compute({ async function checkAssetDTBalance(asset: DDO) { const AssetDtBalance = await ocean.datatokens.balance( - asset.dataToken, + asset.services[0].datatokenAddress, accountId ) setalgorithmDTBalance(AssetDtBalance) @@ -121,7 +116,7 @@ export default function Compute({ } function getQuerryString( - trustedAlgorithmList: publisherTrustedAlgorithm[], + trustedAlgorithmList: PublisherTrustedAlgorithm[], chainId?: number ): SearchQuery { const algorithmDidList = trustedAlgorithmList.map((x) => x.did) @@ -141,28 +136,26 @@ export default function Compute({ async function getAlgorithmList(): Promise { const source = axios.CancelToken.source() - const computeService = ddo.findServiceByType('compute') + const computeService = ddo.services[0] let algorithmSelectionList: AssetSelectionAsset[] if ( - !computeService.attributes.main.privacy || - !computeService.attributes.main.privacy.publisherTrustedAlgorithms || - (computeService.attributes.main.privacy.publisherTrustedAlgorithms - .length === 0 && - !computeService.attributes.main.privacy.allowAllPublishedAlgorithms) + !computeService.privacy || + !computeService.privacy.publisherTrustedAlgorithms || + computeService.privacy.publisherTrustedAlgorithms.length === 0 ) { algorithmSelectionList = [] } else { const gueryResults = await queryMetadata( getQuerryString( - computeService.attributes.main.privacy.publisherTrustedAlgorithms, + computeService.privacy.publisherTrustedAlgorithms, ddo.chainId ), source.token ) setDdoAlgorithmList(gueryResults.results) - const datasetComputeService = ddo.findServiceByType('compute') + algorithmSelectionList = await transformDDOToAssetSelection( - datasetComputeService?.serviceEndpoint, + computeService?.serviceEndpoint, gueryResults.results, [], newCancelToken() @@ -171,7 +164,7 @@ export default function Compute({ return algorithmSelectionList } - const initMetadata = useCallback(async (ddo: DDO): Promise => { + const initMetadata = useCallback(async (ddo: Asset): Promise => { if (!ddo) return const price = await getPrice(ddo) setAlgorithmPrice(price) @@ -186,6 +179,7 @@ export default function Compute({ : true ) }, [algorithmPrice]) + useEffect(() => { if (!price) return @@ -194,12 +188,9 @@ export default function Compute({ ) }, [price]) - useEffect(() => { - const { timeout } = ( - ddo.findServiceByType('access') || ddo.findServiceByType('compute') - ).attributes.main - setDatasetTimeout(secondsToString(timeout)) - }, [ddo]) + // useEffect(() => { + // setDatasetTimeout(secondsToString(timeout)) + // }, [ddo]) useEffect(() => { if (!ddo) return @@ -218,27 +209,26 @@ export default function Compute({ initMetadata(selectedAlgorithmAsset) - const { timeout } = ( - ddo.findServiceByType('access') || ddo.findServiceByType('compute') - ).attributes.main - setAlgorithmTimeout(secondsToString(timeout)) + const { timeout } = ddo.services[0] + + // setAlgorithmTimeout(secondsToString(timeout)) if (accountId) { - if (selectedAlgorithmAsset.findServiceByType('access')) { + if (getServiceByName(selectedAlgorithmAsset, 'access')) { checkPreviousOrders(selectedAlgorithmAsset).then(() => { if ( !hasPreviousAlgorithmOrder && - selectedAlgorithmAsset.findServiceByType('compute') + getServiceByName(selectedAlgorithmAsset, 'compute') ) { checkPreviousOrders(selectedAlgorithmAsset) } }) - } else if (selectedAlgorithmAsset.findServiceByType('compute')) { + } else if (getServiceByName(selectedAlgorithmAsset, 'compute')) { checkPreviousOrders(selectedAlgorithmAsset) } } ocean && checkAssetDTBalance(selectedAlgorithmAsset) - }, [selectedAlgorithmAsset, ocean, accountId, hasPreviousAlgorithmOrder]) + }, [ddo, selectedAlgorithmAsset, ocean, accountId, hasPreviousAlgorithmOrder]) // Output errors in toast UI useEffect(() => { @@ -247,153 +237,153 @@ export default function Compute({ toast.error(newError) }, [error, pricingError]) - async function startJob(algorithmId: string) { - try { - if (!ocean) return + // async function startJob(algorithmId: string) { + // try { + // if (!ocean) return - setIsJobStarting(true) - setIsPublished(false) - setError(undefined) + // setIsJobStarting(true) + // setIsPublished(false) + // setError(undefined) - const computeService = ddo.findServiceByType('compute') - const serviceAlgo = selectedAlgorithmAsset.findServiceByType('access') - ? selectedAlgorithmAsset.findServiceByType('access') - : selectedAlgorithmAsset.findServiceByType('compute') + // const computeService = getServiceByName(ddo, 'compute') + // const serviceAlgo = getServiceByName(selectedAlgorithmAsset, 'access') + // ? getServiceByName(selectedAlgorithmAsset, 'access') + // : getServiceByName(selectedAlgorithmAsset, 'compute') - const computeAlgorithm: ComputeAlgorithm = { - did: selectedAlgorithmAsset.id, - serviceIndex: serviceAlgo.index, - dataToken: selectedAlgorithmAsset.dataToken - } - const allowed = await ocean.compute.isOrderable( - ddo.id, - computeService.index, - computeAlgorithm - ) - Logger.log('[compute] Is data set orderable?', allowed) + // const computeAlgorithm: ComputeAlgorithm = { + // did: selectedAlgorithmAsset.id, + // serviceIndex: serviceAlgo.index, + // dataToken: selectedAlgorithmAsset.services[0].datatokenAddress + // } + // const allowed = await ocean.compute.isOrderable( + // ddo.id, + // computeService.index, + // computeAlgorithm + // ) + // Logger.log('[compute] Is data set orderable?', allowed) - if (!allowed) { - setError( - 'Data set is not orderable in combination with selected algorithm.' - ) - Logger.error( - '[compute] Error starting compute job. Dataset is not orderable in combination with selected algorithm.' - ) - return - } + // if (!allowed) { + // setError( + // 'Data set is not orderable in combination with selected algorithm.' + // ) + // Logger.error( + // '[compute] Error starting compute job. Dataset is not orderable in combination with selected algorithm.' + // ) + // return + // } - if (!hasPreviousDatasetOrder && !hasDatatoken) { - const tx = await buyDT('1', price, ddo) - if (!tx) { - setError('Error buying datatoken.') - Logger.error('[compute] Error buying datatoken for data set ', ddo.id) - return - } - } + // if (!hasPreviousDatasetOrder && !hasDatatoken) { + // const tx = await buyDT('1', price, ddo) + // if (!tx) { + // setError('Error buying datatoken.') + // Logger.error('[compute] Error buying datatoken for data set ', ddo.id) + // return + // } + // } - if (!hasPreviousAlgorithmOrder && !hasAlgoAssetDatatoken) { - const tx = await buyDT('1', algorithmPrice, selectedAlgorithmAsset) - if (!tx) { - setError('Error buying datatoken.') - Logger.error( - '[compute] Error buying datatoken for algorithm ', - selectedAlgorithmAsset.id - ) - return - } - } + // if (!hasPreviousAlgorithmOrder && !hasAlgoAssetDatatoken) { + // const tx = await buyDT('1', algorithmPrice, selectedAlgorithmAsset) + // if (!tx) { + // setError('Error buying datatoken.') + // Logger.error( + // '[compute] Error buying datatoken for algorithm ', + // selectedAlgorithmAsset.id + // ) + // return + // } + // } - // TODO: pricingError is always undefined even upon errors during buyDT for whatever reason. - // So manually drop out above, but ideally could be replaced with this alone. - if (pricingError) { - setError(pricingError) - return - } + // // TODO: pricingError is always undefined even upon errors during buyDT for whatever reason. + // // So manually drop out above, but ideally could be replaced with this alone. + // if (pricingError) { + // setError(pricingError) + // return + // } - const assetOrderId = hasPreviousDatasetOrder - ? previousDatasetOrderId - : await ocean.compute.orderAsset( - accountId, - ddo.id, - computeService.index, - computeAlgorithm, - appConfig.marketFeeAddress, - undefined, - null, - false - ) + // const assetOrderId = hasPreviousDatasetOrder + // ? previousDatasetOrderId + // : await ocean.compute.orderAsset( + // accountId, + // ddo.id, + // computeService.index, + // computeAlgorithm, + // appConfig.marketFeeAddress, + // undefined, + // null, + // false + // ) - assetOrderId && - Logger.log( - `[compute] Got ${ - hasPreviousDatasetOrder ? 'existing' : 'new' - } order ID for dataset: `, - assetOrderId - ) + // assetOrderId && + // Logger.log( + // `[compute] Got ${ + // hasPreviousDatasetOrder ? 'existing' : 'new' + // } order ID for dataset: `, + // assetOrderId + // ) - const algorithmAssetOrderId = hasPreviousAlgorithmOrder - ? previousAlgorithmOrderId - : await ocean.compute.orderAlgorithm( - algorithmId, - serviceAlgo.type, - accountId, - serviceAlgo.index, - appConfig.marketFeeAddress, - undefined, - null, - false - ) + // const algorithmAssetOrderId = hasPreviousAlgorithmOrder + // ? previousAlgorithmOrderId + // : await ocean.compute.orderAlgorithm( + // algorithmId, + // serviceAlgo.type, + // accountId, + // serviceAlgo.index, + // appConfig.marketFeeAddress, + // undefined, + // null, + // false + // ) - algorithmAssetOrderId && - Logger.log( - `[compute] Got ${ - hasPreviousAlgorithmOrder ? 'existing' : 'new' - } order ID for algorithm: `, - algorithmAssetOrderId - ) + // algorithmAssetOrderId && + // Logger.log( + // `[compute] Got ${ + // hasPreviousAlgorithmOrder ? 'existing' : 'new' + // } order ID for algorithm: `, + // algorithmAssetOrderId + // ) - if (!assetOrderId || !algorithmAssetOrderId) { - setError('Error ordering assets.') - return - } + // if (!assetOrderId || !algorithmAssetOrderId) { + // setError('Error ordering assets.') + // return + // } - computeAlgorithm.transferTxId = algorithmAssetOrderId - Logger.log('[compute] Starting compute job.') + // computeAlgorithm.transferTxId = algorithmAssetOrderId + // Logger.log('[compute] Starting compute job.') - const output: ComputeOutput = { - publishAlgorithmLog: true, - publishOutput: true - } - const response = await ocean.compute.start( - ddo.id, - assetOrderId, - ddo.dataToken, - account, - computeAlgorithm, - output, - `${computeService.index}`, - computeService.type - ) + // const output: ComputeOutput = { + // publishAlgorithmLog: true, + // publishOutput: true + // } + // const response = await ocean.compute.start( + // ddo.id, + // assetOrderId, + // ddo.services[0].datatokenAddress, + // account, + // computeAlgorithm, + // output, + // `${computeService.index}`, + // computeService.type + // ) - if (!response) { - setError('Error starting compute job.') - return - } + // if (!response) { + // setError('Error starting compute job.') + // return + // } - Logger.log('[compute] Starting compute job response: ', response) + // Logger.log('[compute] Starting compute job response: ', response) - await checkPreviousOrders(selectedAlgorithmAsset) - await checkPreviousOrders(ddo) - setIsPublished(true) - } catch (error) { - await checkPreviousOrders(selectedAlgorithmAsset) - await checkPreviousOrders(ddo) - setError('Failed to start job!') - Logger.error('[compute] Failed to start job: ', error.message) - } finally { - setIsJobStarting(false) - } - } + // await checkPreviousOrders(selectedAlgorithmAsset) + // await checkPreviousOrders(ddo) + // setIsPublished(true) + // } catch (error) { + // await checkPreviousOrders(selectedAlgorithmAsset) + // await checkPreviousOrders(ddo) + // setError('Failed to start job!') + // Logger.error('[compute] Failed to start job: ', error.message) + // } finally { + // setIsJobStarting(false) + // } + // } return ( <> @@ -402,7 +392,7 @@ export default function Compute({
- {type === 'algorithm' ? ( + {ddo.metadata.type === 'algorithm' ? ( <> await startJob(values.algorithm)} + onSubmit={async (values) => { + // await startJob(values.algorithm) + }} > () - const { isInPurgatory, price, type, isAssetNetwork } = useAsset() + const { isInPurgatory, price, isAssetNetwork } = useAsset() const { buyDT, pricingStepText, pricingError, pricingIsLoading } = usePricing() const { consumeStepText, consume, consumeError, isLoading } = useConsume() @@ -70,7 +69,7 @@ export default function Consume({ if (!ddo || !accountId) return const context = getQueryContext(ddo.chainId) const variables = { - id: ddo.dataToken?.toLowerCase(), + id: ddo.services[0].datatokenAddress?.toLowerCase(), account: accountId?.toLowerCase() } fetchData(previousOrderQuery, variables, context).then((result: any) => { @@ -105,7 +104,7 @@ export default function Consume({ }, [data, assetTimeout, accountId, isAssetNetwork]) useEffect(() => { - const { timeout } = ddo.findServiceByType('access').attributes.main + const { timeout } = ddo.services[0] setAssetTimeout(`${timeout}`) }, [ddo]) @@ -154,7 +153,7 @@ export default function Consume({ } const error = await consume( ddo.id, - ddo.dataToken, + ddo.services[0].datatokenAddress, 'access', appConfig.marketFeeAddress, previousOrderId @@ -177,12 +176,12 @@ export default function Consume({ disabled={isDisabled} hasPreviousOrder={hasPreviousOrder} hasDatatoken={hasDatatoken} - dtSymbol={ddo.dataTokenInfo?.symbol} + dtSymbol={ddo?.dataTokenInfo?.symbol} dtBalance={dtBalance} datasetLowPoolLiquidity={!isConsumablePrice} onClick={handleConsume} assetTimeout={secondsToString(parseInt(assetTimeout))} - assetType={type} + assetType={ddo?.metadata.type} stepText={consumeStepText || pricingStepText} isLoading={pricingIsLoading || isLoading} priceType={price?.type} @@ -203,7 +202,7 @@ export default function Consume({ {!isInPurgatory && } - {type === 'algorithm' && ( + {ddo.metadata.type === 'algorithm' && ( )} diff --git a/src/components/Asset/AssetActions/Edit/DebugEditCompute.tsx b/src/components/Asset/AssetActions/Edit/DebugEditCompute.tsx index ac6e68cfc..ac3202066 100644 --- a/src/components/Asset/AssetActions/Edit/DebugEditCompute.tsx +++ b/src/components/Asset/AssetActions/Edit/DebugEditCompute.tsx @@ -1,4 +1,4 @@ -import { DDO, ServiceComputePrivacy } from '@oceanprotocol/lib' +import { ServiceComputePrivacy } from '@oceanprotocol/lib' import React, { ReactElement, useEffect, useState } from 'react' import { useOcean } from '@context/Ocean' import { transformComputeFormToServiceComputePrivacy } from '@utils/compute' @@ -9,7 +9,7 @@ export default function DebugEditCompute({ ddo }: { values: ComputePrivacyForm - ddo: DDO + ddo: Asset }): ReactElement { const { ocean } = useOcean() const [formTransformed, setFormTransformed] = diff --git a/src/components/Asset/AssetActions/Edit/EditComputeDataset.tsx b/src/components/Asset/AssetActions/Edit/EditComputeDataset.tsx index 62345f966..0225ee95d 100644 --- a/src/components/Asset/AssetActions/Edit/EditComputeDataset.tsx +++ b/src/components/Asset/AssetActions/Edit/EditComputeDataset.tsx @@ -32,59 +32,56 @@ export default function EditComputeDataset({ values: ComputePrivacyForm, resetForm: () => void ) { - try { - if (price.type === 'free') { - const tx = await setMinterToPublisher( - ocean, - ddo.dataToken, - accountId, - setError - ) - if (!tx) return - } - const privacy = await transformComputeFormToServiceComputePrivacy( - values, - ocean - ) - - const ddoEditedComputePrivacy = await ocean.compute.editComputePrivacy( - ddo, - 1, - privacy as ServiceComputePrivacy - ) - - if (!ddoEditedComputePrivacy) { - setError(content.form.error) - Logger.error(content.form.error) - return - } - - const storedddo = await ocean.assets.updateMetadata( - ddoEditedComputePrivacy, - accountId - ) - if (!storedddo) { - setError(content.form.error) - Logger.error(content.form.error) - return - } else { - if (price.type === 'free') { - const tx = await setMinterToDispenser( - ocean, - ddo.dataToken, - accountId, - setError - ) - if (!tx) return - } - // Edit succeeded - setSuccess(content.form.success) - resetForm() - } - } catch (error) { - Logger.error(error.message) - setError(error.message) - } + // try { + // if (price.type === 'free') { + // const tx = await setMinterToPublisher( + // ocean, + // ddo.services[0].datatokenAddress, + // accountId, + // setError + // ) + // if (!tx) return + // } + // const privacy = await transformComputeFormToServiceComputePrivacy( + // values, + // ocean + // ) + // const ddoEditedComputePrivacy = await ocean.compute.editComputePrivacy( + // ddo, + // 1, + // privacy as ServiceComputePrivacy + // ) + // if (!ddoEditedComputePrivacy) { + // setError(content.form.error) + // Logger.error(content.form.error) + // return + // } + // const storedddo = await ocean.assets.updateMetadata( + // ddoEditedComputePrivacy, + // accountId + // ) + // if (!storedddo) { + // setError(content.form.error) + // Logger.error(content.form.error) + // return + // } else { + // if (price.type === 'free') { + // const tx = await setMinterToDispenser( + // ocean, + // ddo.services[0].datatokenAddress, + // accountId, + // setError + // ) + // if (!tx) return + // } + // // Edit succeeded + // setSuccess(content.form.success) + // resetForm() + // } + // } catch (error) { + // Logger.error(error.message) + // setError(error.message) + // } } return ( @@ -100,7 +97,7 @@ export default function EditComputeDataset({ // move user's focus to top of screen window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }) // kick off editing - // await handleSubmit(values, resetForm) + await handleSubmit(values as any, resetForm) }} > {({ values, isSubmitting }) => diff --git a/src/components/Asset/AssetActions/Edit/FormEditComputeDataset.tsx b/src/components/Asset/AssetActions/Edit/FormEditComputeDataset.tsx index 61b344d48..e28538d8b 100644 --- a/src/components/Asset/AssetActions/Edit/FormEditComputeDataset.tsx +++ b/src/components/Asset/AssetActions/Edit/FormEditComputeDataset.tsx @@ -16,6 +16,7 @@ import { useSiteMetadata } from '@hooks/useSiteMetadata' import FormActions from './FormActions' import { useCancelToken } from '@hooks/useCancelToken' import { SortTermOptions } from '../../../../@types/aquarius/SearchQuery' +import { getServiceByName } from '@utils/ddo' export default function FormEditComputeDataset({ data, @@ -31,8 +32,10 @@ export default function FormEditComputeDataset({ const { values }: FormikContextType = useFormikContext() const [allAlgorithms, setAllAlgorithms] = useState() const newCancelToken = useCancelToken() - const { publisherTrustedAlgorithms } = - ddo?.findServiceByType('compute').attributes.main.privacy + const { publisherTrustedAlgorithms } = getServiceByName( + ddo, + 'compute' + ).privacy async function getAlgorithmList( publisherTrustedAlgorithms: PublisherTrustedAlgorithm[] @@ -45,7 +48,7 @@ export default function FormEditComputeDataset({ const query = generateBaseQuery(baseParams) const querryResult = await queryMetadata(query, newCancelToken()) - const datasetComputeService = ddo.findServiceByType('compute') + const datasetComputeService = getServiceByName(ddo, 'compute') const algorithmSelectionList = await transformDDOToAssetSelection( datasetComputeService?.serviceEndpoint, querryResult.results, diff --git a/src/components/Asset/AssetActions/Edit/_constants.ts b/src/components/Asset/AssetActions/Edit/_constants.ts index 2d43d2b65..c2dfc35f8 100644 --- a/src/components/Asset/AssetActions/Edit/_constants.ts +++ b/src/components/Asset/AssetActions/Edit/_constants.ts @@ -1,6 +1,7 @@ import { secondsToString } from '@utils/ddo' import { EditableMetadataLinks } from '@oceanprotocol/lib' import * as Yup from 'yup' +import { MetadataEditForm } from './_types' export const validationSchema = Yup.object().shape({ name: Yup.string() @@ -14,16 +15,16 @@ export const validationSchema = Yup.object().shape({ }) export function getInitialValues( - metadata: MetadataMarket, - timeout: number, + metadata: Metadata, + timeout: string, price: number ): Partial { return { - name: metadata.main.name, - description: metadata.additionalInformation.description, + name: metadata.name, + description: metadata.description, price, - timeout: secondsToString(timeout), - author: metadata.main.author + timeout, + author: metadata.author } } diff --git a/src/components/Asset/AssetActions/Edit/_types.ts b/src/components/Asset/AssetActions/Edit/_types.ts new file mode 100644 index 000000000..43bf9b815 --- /dev/null +++ b/src/components/Asset/AssetActions/Edit/_types.ts @@ -0,0 +1,10 @@ +import { EditableMetadataLinks } from '@oceanprotocol/lib' + +export interface MetadataEditForm { + name: string + description: string + timeout: string + price?: number + links?: string | EditableMetadataLinks[] + author?: string +} diff --git a/src/components/Asset/AssetActions/Edit/index.tsx b/src/components/Asset/AssetActions/Edit/index.tsx index 1c75ef026..32a7d9fc4 100644 --- a/src/components/Asset/AssetActions/Edit/index.tsx +++ b/src/components/Asset/AssetActions/Edit/index.tsx @@ -6,13 +6,14 @@ import { useUserPreferences } from '@context/UserPreferences' // import Debug from './DebugEditMetadata' import Web3Feedback from '@shared/Web3Feedback' import FormEditMetadata from './FormEditMetadata' -import { mapTimeoutStringToSeconds } from '@utils/ddo' +import { getServiceByName, mapTimeoutStringToSeconds } from '@utils/ddo' import styles from './index.module.css' import { Logger } from '@oceanprotocol/lib' import { useWeb3 } from '@context/Web3' import { useOcean } from '@context/Ocean' import { setMinterToDispenser, setMinterToPublisher } from '@utils/freePrice' import content from '../../../../../content/pages/edit.json' +import { MetadataEditForm } from './_types' export default function Edit({ setShowEdit, @@ -24,13 +25,11 @@ export default function Edit({ const { debug } = useUserPreferences() const { accountId } = useWeb3() const { ocean } = useOcean() - const { metadata, ddo, refreshDdo, price } = useAsset() + const { ddo, refreshDdo, price } = useAsset() const [success, setSuccess] = useState() const [error, setError] = useState() const [timeoutStringValue, setTimeoutStringValue] = useState() - const timeout = ddo.findServiceByType('access') - ? ddo.findServiceByType('access').attributes.main.timeout - : ddo.findServiceByType('compute').attributes.main.timeout + const { timeout } = ddo.services[0] const hasFeedback = error || success @@ -50,83 +49,79 @@ export default function Edit({ values: Partial, resetForm: () => void ) { - try { - if (price.type === 'free') { - const tx = await setMinterToPublisher( - ocean, - ddo.dataToken, - accountId, - setError - ) - if (!tx) return - } - // Construct new DDO with new values - const ddoEditedMetdata = await ocean.assets.editMetadata(ddo, { - title: values.name, - description: values.description, - links: typeof values.links !== 'string' ? values.links : [], - author: values.author === '' ? ' ' : values.author - }) - - price.type === 'exchange' && - values.price !== price.value && - (await updateFixedPrice(values.price)) - - if (!ddoEditedMetdata) { - setError(content.form.error) - Logger.error(content.form.error) - return - } - let ddoEditedTimeout = ddoEditedMetdata - if (timeoutStringValue !== values.timeout) { - const service = - ddoEditedMetdata.findServiceByType('access') || - ddoEditedMetdata.findServiceByType('compute') - const timeout = mapTimeoutStringToSeconds(values.timeout) - ddoEditedTimeout = await ocean.assets.editServiceTimeout( - ddoEditedMetdata, - service.index, - timeout - ) - } - - if (!ddoEditedTimeout) { - setError(content.form.error) - Logger.error(content.form.error) - return - } - - const storedddo = await ocean.assets.updateMetadata( - ddoEditedTimeout, - accountId - ) - if (!storedddo) { - setError(content.form.error) - Logger.error(content.form.error) - return - } else { - if (price.type === 'free') { - const tx = await setMinterToDispenser( - ocean, - ddo.dataToken, - accountId, - setError - ) - if (!tx) return - } - // Edit succeeded - setSuccess(content.form.success) - resetForm() - } - } catch (error) { - Logger.error(error.message) - setError(error.message) - } + // try { + // if (price.type === 'free') { + // const tx = await setMinterToPublisher( + // ocean, + // ddo.services[0].datatokenAddress, + // accountId, + // setError + // ) + // if (!tx) return + // } + // // Construct new DDO with new values + // const ddoEditedMetdata = await ocean.assets.editMetadata(ddo as any, { + // title: values.name, + // description: values.description, + // links: typeof values.links !== 'string' ? values.links : [], + // author: values.author === '' ? ' ' : values.author + // }) + // price.type === 'exchange' && + // values.price !== price.value && + // (await updateFixedPrice(values.price)) + // if (!ddoEditedMetdata) { + // setError(content.form.error) + // Logger.error(content.form.error) + // return + // } + // let ddoEditedTimeout = ddoEditedMetdata + // if (timeoutStringValue !== values.timeout) { + // const service = + // getServiceByName(ddoEditedMetdata, 'access') || + // getServiceByName(ddoEditedMetdata, 'compute') + // const timeout = mapTimeoutStringToSeconds(values.timeout) + // ddoEditedTimeout = await ocean.assets.editServiceTimeout( + // ddoEditedMetdata, + // service.index, + // timeout + // ) + // } + // if (!ddoEditedTimeout) { + // setError(content.form.error) + // Logger.error(content.form.error) + // return + // } + // const storedddo = await ocean.assets.updateMetadata( + // ddoEditedTimeout, + // accountId + // ) + // if (!storedddo) { + // setError(content.form.error) + // Logger.error(content.form.error) + // return + // } else { + // if (price.type === 'free') { + // const tx = await setMinterToDispenser( + // ocean, + // ddo.services[0].datatokenAddress, + // accountId, + // setError + // ) + // if (!tx) return + // } + // // Edit succeeded + // setSuccess(content.form.success) + // resetForm() + // } + // } catch (error) { + // Logger.error(error.message) + // setError(error.message) + // } } return ( { // move user's focus to top of screen diff --git a/src/components/Asset/AssetActions/Pool/index.tsx b/src/components/Asset/AssetActions/Pool/index.tsx index b31d367dc..69dd10b4f 100644 --- a/src/components/Asset/AssetActions/Pool/index.tsx +++ b/src/components/Asset/AssetActions/Pool/index.tsx @@ -103,7 +103,7 @@ export default function Pool(): ReactElement { const queryContext = getQueryContext(ddo.chainId) const queryVariables = { id: price.address.toLowerCase(), - shareId: `${price.address.toLowerCase()}-${ddo.publicKey[0].owner.toLowerCase()}` + shareId: `${price.address.toLowerCase()}-${ddo.nft.owner.toLowerCase()}` } const queryResult: OperationResult = await fetchData( @@ -172,7 +172,8 @@ export default function Pool(): ReactElement { // Get weights const weightDt = dataLiquidity.pool.tokens.filter( - (token: any) => token.address === ddo.dataToken.toLowerCase() + (token: any) => + token.address === ddo.services[0].datatokenAddress.toLowerCase() )[0].denormWeight const weightDtDecimal = isValidNumber(weightDt) @@ -249,7 +250,7 @@ export default function Pool(): ReactElement { refetchLiquidity() } init() - }, [dataLiquidity, ddo.dataToken, price.datatoken, price.ocean, price?.value]) + }, [dataLiquidity, ddo, price.datatoken, price.ocean, price?.value]) useEffect(() => { setIsRemoveDisabled(isInPurgatory && owner === accountId) @@ -360,7 +361,7 @@ export default function Pool(): ReactElement { }} swapFee={swapFee} dtSymbol={dtSymbol} - dtAddress={ddo.dataToken} + dtAddress={ddo.services[0].datatokenAddress} /> ) : showRemove ? ( Datatoken diff --git a/src/components/Asset/AssetActions/Trade/FormTrade.tsx b/src/components/Asset/AssetActions/Trade/FormTrade.tsx index 068f56bde..12c6c59c5 100644 --- a/src/components/Asset/AssetActions/Trade/FormTrade.tsx +++ b/src/components/Asset/AssetActions/Trade/FormTrade.tsx @@ -1,5 +1,5 @@ import React, { ReactElement, useState } from 'react' -import { DDO, Logger } from '@oceanprotocol/lib' +import { Logger } from '@oceanprotocol/lib' import * as Yup from 'yup' import { Formik } from 'formik' import Actions from '../Pool/Actions' @@ -23,7 +23,7 @@ export default function FormTrade({ maxOcean, price }: { - ddo: DDO + ddo: Asset balance: PoolBalance maxDt: string maxOcean: string diff --git a/src/components/Asset/AssetActions/Trade/Swap.tsx b/src/components/Asset/AssetActions/Trade/Swap.tsx index 2ae41791c..a28f44927 100644 --- a/src/components/Asset/AssetActions/Trade/Swap.tsx +++ b/src/components/Asset/AssetActions/Trade/Swap.tsx @@ -1,5 +1,4 @@ import React, { ReactElement, useEffect, useState } from 'react' -import { DDO } from '@oceanprotocol/lib' import styles from './Swap.module.css' import TradeInput from './TradeInput' import Button from '@shared/atoms/Button' @@ -26,7 +25,7 @@ export default function Swap({ setMaximumOcean, setCoin }: { - ddo: DDO + ddo: Asset maxDt: string maxOcean: string balance: PoolBalance @@ -149,7 +148,7 @@ export default function Swap({ setTotalValue(newValue) setTokenAmount(value.toString()) - tokenIn = ddo.dataToken + tokenIn = ddo.services[0].datatokenAddress tokenOut = ocean.pool.oceanAddress } else { newValue = await ocean.pool.getDTReceived( @@ -160,7 +159,7 @@ export default function Swap({ setTotalValue(value.toString()) setTokenAmount(newValue) tokenIn = ocean.pool.oceanAddress - tokenOut = ddo.dataToken + tokenOut = ddo.services[0].datatokenAddress } } else { if (values.type === 'sell') { @@ -171,7 +170,7 @@ export default function Swap({ setTotalValue(value.toString()) setTokenAmount(newValue) - tokenIn = ddo.dataToken + tokenIn = ddo.services[0].datatokenAddress tokenOut = ocean.pool.oceanAddress } else { newValue = await ocean.pool.getOceanNeeded( @@ -182,7 +181,7 @@ export default function Swap({ setTotalValue(newValue) setTokenAmount(value.toString()) tokenIn = ocean.pool.oceanAddress - tokenOut = ddo.dataToken + tokenOut = ddo.services[0].datatokenAddress } } diff --git a/src/components/Asset/AssetActions/Trade/index.tsx b/src/components/Asset/AssetActions/Trade/index.tsx index 9338af91d..bd7ac32a7 100644 --- a/src/components/Asset/AssetActions/Trade/index.tsx +++ b/src/components/Asset/AssetActions/Trade/index.tsx @@ -25,19 +25,22 @@ export default function Trade(): ReactElement { !isAssetNetwork || !balance?.ocean || !accountId || - !ddo?.dataToken + !ddo?.services[0].datatokenAddress ) return async function getTokenBalance() { - const dtBalance = await ocean.datatokens.balance(ddo.dataToken, accountId) + const dtBalance = await ocean.datatokens.balance( + ddo.services[0].datatokenAddress, + accountId + ) setTokenBalance({ ocean: new Decimal(balance.ocean).toString(), datatoken: new Decimal(dtBalance).toString() }) } getTokenBalance() - }, [balance.ocean, ocean, accountId, ddo.dataToken]) + }, [balance.ocean, ocean, accountId, ddo, isAssetNetwork]) // Get maximum amount for either OCEAN or datatoken useEffect(() => { diff --git a/src/components/Asset/AssetActions/index.tsx b/src/components/Asset/AssetActions/index.tsx index e85903ee4..cd76e83dc 100644 --- a/src/components/Asset/AssetActions/index.tsx +++ b/src/components/Asset/AssetActions/index.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useState, useEffect } from 'react' import Compute from './Compute' import Consume from './Consume' -import { Logger, File as FileMetadata, DID } from '@oceanprotocol/lib' +import { Logger, DID } from '@oceanprotocol/lib' import Tabs from '@shared/atoms/Tabs' import { compareAsBN } from '@utils/numbers' import Pool from './Pool' @@ -25,27 +25,30 @@ export default function AssetActions(): ReactElement { const [dtBalance, setDtBalance] = useState() const [fileMetadata, setFileMetadata] = useState(Object) const [fileIsLoading, setFileIsLoading] = useState(false) - const isCompute = Boolean(ddo?.findServiceByType('compute')) + const isCompute = Boolean( + ddo?.services.filter((service) => service.type === 'compute')[0] + ) const [isConsumable, setIsConsumable] = useState(true) const [consumableFeedback, setConsumableFeedback] = useState('') const newCancelToken = useCancelToken() const isMounted = useIsMounted() - useEffect(() => { - if (!ddo || !accountId || !ocean || !isAssetNetwork) return - async function checkIsConsumable() { - const consumable = await ocean.assets.isConsumable( - ddo, - accountId.toLowerCase() - ) - if (consumable) { - setIsConsumable(consumable.result) - setConsumableFeedback(consumable.message) - } - } - checkIsConsumable() - }, [accountId, isAssetNetwork, ddo, ocean]) + // useEffect(() => { + // if (!ddo || !accountId || !ocean || !isAssetNetwork) return + + // async function checkIsConsumable() { + // const consumable = await ocean.assets.isConsumable( + // ddo, + // accountId.toLowerCase() + // ) + // if (consumable) { + // setIsConsumable(consumable.result) + // setConsumableFeedback(consumable.message) + // } + // } + // checkIsConsumable() + // }, [accountId, isAssetNetwork, ddo, ocean]) useEffect(() => { const oceanConfig = getOceanConfig(ddo.chainId) @@ -74,7 +77,7 @@ export default function AssetActions(): ReactElement { async function init() { try { const dtBalance = await ocean.datatokens.balance( - ddo.dataToken, + ddo.services[0].datatokenAddress, accountId ) setDtBalance(dtBalance) @@ -83,7 +86,7 @@ export default function AssetActions(): ReactElement { } } init() - }, [ocean, accountId, ddo.dataToken, isAssetNetwork]) + }, [ocean, accountId, ddo, isAssetNetwork]) // Check user balance against price useEffect(() => { diff --git a/src/components/Asset/AssetContent/EditHistory.tsx b/src/components/Asset/AssetContent/EditHistory.tsx index ef510d765..871952b67 100644 --- a/src/components/Asset/AssetContent/EditHistory.tsx +++ b/src/components/Asset/AssetContent/EditHistory.tsx @@ -37,7 +37,7 @@ export default function EditHistory(): ReactElement { const [result] = useQuery({ query: getReceipts, - variables: { address: ddo?.dataToken.toLowerCase() }, + variables: { address: ddo?.services[0].datatokenAddress.toLowerCase() }, context: queryContext, pause: !ddo || !queryContext }) diff --git a/src/components/Asset/AssetContent/MetaFull.tsx b/src/components/Asset/AssetContent/MetaFull.tsx index 95f40347f..77983e719 100644 --- a/src/components/Asset/AssetContent/MetaFull.tsx +++ b/src/components/Asset/AssetContent/MetaFull.tsx @@ -5,22 +5,20 @@ import Publisher from '@shared/Publisher' import { useAsset } from '@context/Asset' export default function MetaFull(): ReactElement { - const { ddo, metadata, isInPurgatory, type } = useAsset() - const { algorithm } = ddo.findServiceByType('metadata').attributes.main + const { ddo, isInPurgatory } = useAsset() + const { type, author, algorithm } = ddo?.metadata function DockerImage() { - const { image, tag } = algorithm.container + const { image, tag } = algorithm?.container return {`${image}:${tag}`} } return (
- {!isInPurgatory && ( - - )} + {!isInPurgatory && } } + content={} /> {type === 'algorithm' && algorithm && ( diff --git a/src/components/Asset/AssetContent/MetaMain.tsx b/src/components/Asset/AssetContent/MetaMain.tsx index 54408f4b1..003d55f81 100644 --- a/src/components/Asset/AssetContent/MetaMain.tsx +++ b/src/components/Asset/AssetContent/MetaMain.tsx @@ -7,12 +7,13 @@ import AddToken from '@shared/AddToken' import Time from '@shared/atoms/Time' import AssetType from '@shared/AssetType' import styles from './MetaMain.module.css' +import { getServiceByName } from '@utils/ddo' export default function MetaMain(): ReactElement { - const { ddo, owner, type, isAssetNetwork } = useAsset() + const { ddo, owner, isAssetNetwork } = useAsset() const { web3ProviderInfo } = useWeb3() - const isCompute = Boolean(ddo?.findServiceByType('compute')) + const isCompute = Boolean(getServiceByName(ddo, 'compute')) const accessType = isCompute ? 'compute' : 'access' const blockscoutNetworks = [1287, 2021000, 2021001, 44787, 246, 1285] const isBlockscoutExplorer = blockscoutNetworks.includes(ddo?.chainId) @@ -21,7 +22,7 @@ export default function MetaMain(): ReactElement {