From 1fa147aadd4c6ee123179d17f02b4c1c2337eb91 Mon Sep 17 00:00:00 2001 From: tom1145 Date: Thu, 16 May 2024 17:53:09 +0300 Subject: [PATCH 01/15] refactor: remove C2D --- src/@types/Compute.d.ts | 12 - src/@types/aquarius/SearchQuery.ts | 6 +- src/@utils/aquarius/index.ts | 37 -- src/@utils/compute.ts | 403 ------------ src/@utils/ddo.ts | 7 +- src/@utils/feedback.ts | 14 - src/@utils/order.ts | 116 ---- src/@utils/provider.ts | 46 -- src/components/@shared/AssetTeaser/index.tsx | 5 +- .../Asset/AssetActions/ButtonBuy/index.tsx | 3 +- ...AlgorithmDatasetsListForCompute.module.css | 29 - .../AlgorithmDatasetsListForCompute.tsx | 46 -- .../Compute/AssetComputeList/index.module.css | 59 -- .../Compute/AssetComputeList/index.tsx | 53 -- .../Compute/FormComputeDataset.module.css | 28 - .../Compute/FormComputeDataset.tsx | 325 ---------- .../AssetActions/Compute/History.module.css | 93 --- .../Asset/AssetActions/Compute/History.tsx | 39 -- .../Compute/PriceOutput.module.css | 60 -- .../AssetActions/Compute/PriceOutput.tsx | 148 ----- .../Asset/AssetActions/Compute/_constants.ts | 45 -- .../AssetActions/Compute/index.module.css | 26 - .../Asset/AssetActions/Compute/index.tsx | 592 ------------------ .../Asset/AssetActions/Download/index.tsx | 8 - src/components/Asset/AssetActions/index.tsx | 27 +- .../Asset/AssetContent/MetaMain/MetaInfo.tsx | 4 +- src/components/Asset/AssetContent/index.tsx | 12 +- .../Asset/Edit/DebugEditCompute.tsx | 41 -- .../Asset/Edit/EditComputeDataset.tsx | 166 ----- src/components/Asset/Edit/EditMetadata.tsx | 2 - .../Asset/Edit/FormEditComputeDataset.tsx | 95 --- .../Asset/Edit/FormEditMetadata.tsx | 2 +- src/components/Asset/Edit/_constants.ts | 20 +- src/components/Asset/Edit/_types.ts | 6 - src/components/Asset/Edit/_validation.ts | 6 - src/components/Asset/Edit/index.tsx | 13 +- .../History/ComputeJobs/Details.module.css | 86 --- .../Profile/History/ComputeJobs/Details.tsx | 107 ---- .../History/ComputeJobs/Results.module.css | 14 - .../Profile/History/ComputeJobs/Results.tsx | 111 ---- .../History/ComputeJobs/index.module.css | 26 - .../Profile/History/ComputeJobs/index.tsx | 89 --- src/components/Profile/History/index.tsx | 93 +-- src/components/Publish/Metadata/index.tsx | 123 +--- src/components/Publish/Services/index.tsx | 55 +- src/components/Publish/_constants.tsx | 17 +- src/components/Publish/_utils.ts | 3 - src/components/Search/Filters.tsx | 11 +- 48 files changed, 39 insertions(+), 3290 deletions(-) delete mode 100644 src/@utils/compute.ts delete mode 100644 src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.module.css delete mode 100644 src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx delete mode 100644 src/components/Asset/AssetActions/Compute/AssetComputeList/index.module.css delete mode 100644 src/components/Asset/AssetActions/Compute/AssetComputeList/index.tsx delete mode 100644 src/components/Asset/AssetActions/Compute/FormComputeDataset.module.css delete mode 100644 src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx delete mode 100644 src/components/Asset/AssetActions/Compute/History.module.css delete mode 100644 src/components/Asset/AssetActions/Compute/History.tsx delete mode 100644 src/components/Asset/AssetActions/Compute/PriceOutput.module.css delete mode 100644 src/components/Asset/AssetActions/Compute/PriceOutput.tsx delete mode 100644 src/components/Asset/AssetActions/Compute/_constants.ts delete mode 100644 src/components/Asset/AssetActions/Compute/index.module.css delete mode 100644 src/components/Asset/AssetActions/Compute/index.tsx delete mode 100644 src/components/Asset/Edit/DebugEditCompute.tsx delete mode 100644 src/components/Asset/Edit/EditComputeDataset.tsx delete mode 100644 src/components/Asset/Edit/FormEditComputeDataset.tsx delete mode 100644 src/components/Profile/History/ComputeJobs/Details.module.css delete mode 100644 src/components/Profile/History/ComputeJobs/Details.tsx delete mode 100644 src/components/Profile/History/ComputeJobs/Results.module.css delete mode 100644 src/components/Profile/History/ComputeJobs/Results.tsx delete mode 100644 src/components/Profile/History/ComputeJobs/index.module.css delete mode 100644 src/components/Profile/History/ComputeJobs/index.tsx diff --git a/src/@types/Compute.d.ts b/src/@types/Compute.d.ts index a34bd93cd1..f9674f13d9 100644 --- a/src/@types/Compute.d.ts +++ b/src/@types/Compute.d.ts @@ -1,15 +1,8 @@ -import { ComputeJob } from '@oceanprotocol/lib' import { OrdersData_orders_datatoken as OrdersDatatoken } from '../@types/subgraph/OrdersData' // declaring into global scope to be able to use this as // ambiant types despite the above imports declare global { - interface ComputeJobMetaData extends ComputeJob { - assetName: string - assetDtSymbol: string - networkId: number - } - interface AlgorithmOption { did: string name: string @@ -23,11 +16,6 @@ declare global { createdTimestamp: number } - interface ComputeResults { - computeJobs: ComputeJobMetaData[] - isLoaded: boolean - } - interface totalPriceMap { value: string symbol: string diff --git a/src/@types/aquarius/SearchQuery.ts b/src/@types/aquarius/SearchQuery.ts index 9dbabc5649..6d2eeca8d7 100644 --- a/src/@types/aquarius/SearchQuery.ts +++ b/src/@types/aquarius/SearchQuery.ts @@ -17,13 +17,11 @@ export enum SortTermOptions { // and gets imported in components. export enum FilterByTypeOptions { - Data = 'dataset', - Algorithm = 'algorithm' + Data = 'dataset' } export enum FilterByAccessOptions { - Download = 'access', - Compute = 'compute' + Download = 'access' } declare global { diff --git a/src/@utils/aquarius/index.ts b/src/@utils/aquarius/index.ts index 452b34ac74..f45cdffe82 100644 --- a/src/@utils/aquarius/index.ts +++ b/src/@utils/aquarius/index.ts @@ -1,5 +1,4 @@ import { Asset, LoggerInstance } from '@oceanprotocol/lib' -import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection' import axios, { CancelToken, AxiosResponse } from 'axios' import { OrdersData_orders as OrdersData } from '../../@types/subgraph/OrdersData' import { metadataCacheUri } from '../../../app.config' @@ -7,7 +6,6 @@ import { SortDirectionOptions, SortTermOptions } from '../../@types/aquarius/SearchQuery' -import { transformAssetToAssetSelection } from '../assetConvertor' export interface UserSales { id: string @@ -206,41 +204,6 @@ export async function getAssetsFromDids( } } -export async function getAlgorithmDatasetsForCompute( - algorithmId: string, - datasetProviderUri: string, - datasetChainId?: number, - cancelToken?: CancelToken -): Promise { - const baseQueryParams = { - chainIds: [datasetChainId], - nestedQuery: { - must: { - match: { - 'services.compute.publisherTrustedAlgorithms.did': { - query: algorithmId - } - } - } - }, - sortOptions: { - sortBy: SortTermOptions.Created, - sortDirection: SortDirectionOptions.Descending - } - } as BaseQueryParams - - const query = generateBaseQuery(baseQueryParams) - const computeDatasets = await queryMetadata(query, cancelToken) - if (computeDatasets?.totalResults === 0) return [] - - const datasets = await transformAssetToAssetSelection( - datasetProviderUri, - computeDatasets.results, - [] - ) - return datasets -} - export async function getPublishedAssets( accountId: string, chainIds: number[], diff --git a/src/@utils/compute.ts b/src/@utils/compute.ts deleted file mode 100644 index efba65ea30..0000000000 --- a/src/@utils/compute.ts +++ /dev/null @@ -1,403 +0,0 @@ -import { - Asset, - ServiceComputeOptions, - PublisherTrustedAlgorithm, - getHash, - LoggerInstance, - ComputeAlgorithm, - DDO, - Service, - ProviderInstance, - ComputeEnvironment, - ComputeJob, - getErrorMessage -} from '@oceanprotocol/lib' -import { CancelToken } from 'axios' -import { gql } from 'urql' -import { - queryMetadata, - getFilterTerm, - generateBaseQuery, - getAssetsFromDids -} from './aquarius' -import { fetchDataForMultipleChains } from './subgraph' -import { getServiceById, getServiceByName } from './ddo' -import { SortTermOptions } from '../@types/aquarius/SearchQuery' -import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection' -import { transformAssetToAssetSelection } from './assetConvertor' -import { ComputeEditForm } from '../components/Asset/Edit/_types' -import { getFileDidInfo } from './provider' -import { toast } from 'react-toastify' - -const getComputeOrders = gql` - query ComputeOrders($user: String!) { - orders( - orderBy: createdTimestamp - orderDirection: desc - where: { payer: $user } - ) { - id - serviceIndex - datatoken { - address - } - tx - createdTimestamp - } - } -` - -const getComputeOrdersByDatatokenAddress = gql` - query ComputeOrdersByDatatokenAddress( - $user: String! - $datatokenAddress: String! - ) { - orders( - orderBy: createdTimestamp - orderDirection: desc - where: { payer: $user, datatoken: $datatokenAddress } - ) { - id - serviceIndex - datatoken { - address - } - tx - createdTimestamp - } - } -` - -async function getAssetMetadata( - queryDtList: string[], - cancelToken: CancelToken, - chainIds: number[] -): Promise { - const baseQueryparams = { - chainIds, - filters: [ - getFilterTerm('services.datatokenAddress', queryDtList), - getFilterTerm('services.type', 'compute'), - getFilterTerm('metadata.type', 'dataset') - ], - ignorePurgatory: true - } as BaseQueryParams - const query = generateBaseQuery(baseQueryparams) - const result = await queryMetadata(query, cancelToken) - return result?.results -} - -export async function isOrderable( - asset: Asset | DDO, - serviceId: string, - algorithm: ComputeAlgorithm, - algorithmDDO: Asset | DDO -): Promise { - const datasetService: Service = getServiceById(asset, serviceId) - if (!datasetService) return false - - if (datasetService.type === 'compute') { - if (algorithm.meta) { - // check if raw algo is allowed - if (datasetService.compute.allowRawAlgorithm) return true - LoggerInstance.error('ERROR: This service does not allow raw algorithm') - return false - } - if (algorithm.documentId) { - const algoService: Service = getServiceById( - algorithmDDO, - algorithm.serviceId - ) - if (algoService && algoService.type === 'compute') { - if (algoService.serviceEndpoint !== datasetService.serviceEndpoint) { - this.logger.error( - 'ERROR: Both assets with compute service are not served by the same provider' - ) - return false - } - } - } - } - return true -} - -export function getValidUntilTime( - computeEnvMaxJobDuration: number, - datasetTimeout?: number, - algorithmTimeout?: number -) { - const inputValues = [] - computeEnvMaxJobDuration && inputValues.push(computeEnvMaxJobDuration) - datasetTimeout && inputValues.push(datasetTimeout) - algorithmTimeout && inputValues.push(algorithmTimeout) - - const minValue = Math.min(...inputValues) - const mytime = new Date() - mytime.setMinutes(mytime.getMinutes() + Math.floor(minValue / 60)) - return Math.floor(mytime.getTime() / 1000) -} - -export async function getComputeEnviroment( - asset: Asset -): Promise { - if (asset?.services[0]?.type !== 'compute') return null - try { - const computeEnvs = await ProviderInstance.getComputeEnvironments( - asset.services[0].serviceEndpoint - ) - if (!computeEnvs[asset.chainId][0]) return null - return computeEnvs[asset.chainId][0] - } catch (e) { - const message = getErrorMessage(e.message) - LoggerInstance.error( - '[Compute to Data] Fetch compute environment:', - message - ) - toast.error(message) - } -} - -export function getQueryString( - trustedAlgorithmList: PublisherTrustedAlgorithm[], - trustedPublishersList: string[], - chainId?: number -): SearchQuery { - const algorithmDidList = trustedAlgorithmList?.map((x) => x.did) - - const baseParams = { - chainIds: [chainId], - sort: { sortBy: SortTermOptions.Created }, - filters: [getFilterTerm('metadata.type', 'algorithm')], - esPaginationOptions: { - size: 3000 - } - } as BaseQueryParams - algorithmDidList?.length > 0 && - baseParams.filters.push(getFilterTerm('_id', algorithmDidList)) - trustedPublishersList?.length > 0 && - baseParams.filters.push(getFilterTerm('nft.owner', trustedPublishersList)) - const query = generateBaseQuery(baseParams) - - return query -} - -export async function getAlgorithmsForAsset( - asset: Asset, - token: CancelToken -): Promise { - const computeService: Service = getServiceByName(asset, 'compute') - - if ( - !computeService.compute || - (computeService.compute.publisherTrustedAlgorithms?.length === 0 && - computeService.compute.publisherTrustedAlgorithmPublishers?.length === 0) - ) { - return [] - } - - const gueryResults = await queryMetadata( - getQueryString( - computeService.compute.publisherTrustedAlgorithms, - computeService.compute.publisherTrustedAlgorithmPublishers, - asset.chainId - ), - token - ) - const algorithms: Asset[] = gueryResults?.results - return algorithms -} - -export async function getAlgorithmAssetSelectionList( - asset: Asset, - algorithms: Asset[] -): Promise { - const computeService: Service = getServiceByName(asset, 'compute') - let algorithmSelectionList: AssetSelectionAsset[] - if (!computeService.compute) { - algorithmSelectionList = [] - } else { - algorithmSelectionList = await transformAssetToAssetSelection( - computeService?.serviceEndpoint, - algorithms, - [] - ) - } - return algorithmSelectionList -} - -async function getJobs( - providerUrls: string[], - accountId: string, - assets: Asset[] -): Promise { - const computeJobs: ComputeJobMetaData[] = [] - try { - const providerComputeJobs = (await ProviderInstance.computeStatus( - providerUrls[0], - accountId - )) as ComputeJob[] - - if (providerComputeJobs) { - providerComputeJobs.sort((a, b) => { - if (a.dateCreated > b.dateCreated) { - return -1 - } - if (a.dateCreated < b.dateCreated) { - return 1 - } - return 0 - }) - - providerComputeJobs.forEach((job) => { - const did = job.inputDID[0] - const asset = assets.filter((x) => x.id === did)[0] - if (asset) { - const compJob: ComputeJobMetaData = { - ...job, - assetName: asset.metadata.name, - assetDtSymbol: asset.datatokens[0].symbol, - networkId: asset.chainId - } - computeJobs.push(compJob) - } - }) - } - } catch (err) { - const message = getErrorMessage(err.message) - LoggerInstance.error('[Compute to Data] Error:', message) - toast.error(message) - } - return computeJobs -} - -export async function getComputeJobs( - chainIds: number[], - accountId: string, - asset?: AssetExtended, - cancelToken?: CancelToken -): Promise { - if (!accountId) return - const assetDTAddress = asset?.datatokens[0]?.address - const computeResult: ComputeResults = { - computeJobs: [], - isLoaded: false - } - const variables = assetDTAddress - ? { - user: accountId.toLowerCase(), - datatokenAddress: assetDTAddress.toLowerCase() - } - : { - user: accountId.toLowerCase() - } - - const results = await fetchDataForMultipleChains( - assetDTAddress ? getComputeOrdersByDatatokenAddress : getComputeOrders, - variables, - assetDTAddress ? [asset?.chainId] : chainIds - ) - - let tokenOrders: TokenOrder[] = [] - results.map((result) => - result.orders.forEach((tokenOrder: TokenOrder) => - tokenOrders.push(tokenOrder) - ) - ) - if (tokenOrders.length === 0) { - computeResult.isLoaded = true - return computeResult - } - - tokenOrders = tokenOrders.sort( - (a, b) => b.createdTimestamp - a.createdTimestamp - ) - - const datatokenAddressList = tokenOrders.map( - (tokenOrder: TokenOrder) => tokenOrder.datatoken.address - ) - if (!datatokenAddressList) return - - const assets = await getAssetMetadata( - datatokenAddressList, - cancelToken, - chainIds - ) - - const providerUrls: string[] = [] - assets.forEach((asset: Asset) => - providerUrls.push(asset.services[0].serviceEndpoint) - ) - - computeResult.computeJobs = await getJobs(providerUrls, accountId, assets) - computeResult.isLoaded = true - - return computeResult -} - -export async function createTrustedAlgorithmList( - selectedAlgorithms: string[], // list of DIDs, - assetChainId: number, - cancelToken: CancelToken -): Promise { - const trustedAlgorithms: PublisherTrustedAlgorithm[] = [] - - // Condition to prevent app from hitting Aquarius with empty DID list - // when nothing is selected in the UI. - if (!selectedAlgorithms || selectedAlgorithms.length === 0) - return trustedAlgorithms - - const selectedAssets = await getAssetsFromDids( - selectedAlgorithms, - [assetChainId], - cancelToken - ) - - if (!selectedAssets || selectedAssets.length === 0) return [] - - for (const selectedAlgorithm of selectedAssets) { - const filesChecksum = await getFileDidInfo( - selectedAlgorithm?.id, - selectedAlgorithm?.services?.[0].id, - selectedAlgorithm?.services?.[0]?.serviceEndpoint, - true - ) - const containerChecksum = - selectedAlgorithm.metadata.algorithm.container.entrypoint + - selectedAlgorithm.metadata.algorithm.container.checksum - const trustedAlgorithm = { - did: selectedAlgorithm.id, - containerSectionChecksum: getHash(containerChecksum), - filesChecksum: filesChecksum?.[0]?.checksum - } - trustedAlgorithms.push(trustedAlgorithm) - } - return trustedAlgorithms -} - -export async function transformComputeFormToServiceComputeOptions( - values: ComputeEditForm, - currentOptions: ServiceComputeOptions, - assetChainId: number, - cancelToken: CancelToken -): Promise { - const publisherTrustedAlgorithms = values.allowAllPublishedAlgorithms - ? null - : await createTrustedAlgorithmList( - values.publisherTrustedAlgorithms, - assetChainId, - cancelToken - ) - - // TODO: add support for selecting trusted publishers and transforming here. - // This only deals with basics so we don't accidentially allow all accounts - // to be trusted. - const publisherTrustedAlgorithmPublishers: string[] = [] - - const privacy: ServiceComputeOptions = { - ...currentOptions, - publisherTrustedAlgorithms, - publisherTrustedAlgorithmPublishers - } - - return privacy -} diff --git a/src/@utils/ddo.ts b/src/@utils/ddo.ts index b087955863..88e3cc6389 100644 --- a/src/@utils/ddo.ts +++ b/src/@utils/ddo.ts @@ -1,7 +1,4 @@ -import { - ComputeEditForm, - MetadataEditForm -} from '@components/Asset/Edit/_types' +import { MetadataEditForm } from '@components/Asset/Edit/_types' import { FormConsumerParameter, FormPublishData @@ -171,7 +168,7 @@ export function normalizeFile( } export function previewDebugPatch( - values: FormPublishData | Partial | ComputeEditForm, + values: FormPublishData | Partial, chainId: number ) { // handle file's object property dynamically diff --git a/src/@utils/feedback.ts b/src/@utils/feedback.ts index e6c047f8e9..a261e2bfb6 100644 --- a/src/@utils/feedback.ts +++ b/src/@utils/feedback.ts @@ -10,17 +10,3 @@ export function getOrderFeedback( 3: 'Generating signature to access download url' } } - -export function getComputeFeedback( - baseTokenSymbol?: string, - datatokenSymbol?: string, - assetType?: string -): { [key in number]: string } { - return { - 0: `Setting price and fees for ${assetType}`, - 1: `Approving ${datatokenSymbol} and ordering ${assetType} `, - 2: `Approving ${baseTokenSymbol} and ordering ${assetType}`, - 3: `Ordering ${assetType}`, - 4: 'Generating signature. Starting compute job ...' - } -} diff --git a/src/@utils/order.ts b/src/@utils/order.ts index 08cd1d7813..83cca1dec7 100644 --- a/src/@utils/order.ts +++ b/src/@utils/order.ts @@ -1,14 +1,11 @@ import { - amountToUnits, approve, - approveWei, Datatoken, Dispenser, FixedRateExchange, FreOrderParams, LoggerInstance, OrderParams, - ProviderComputeInitialize, ProviderFees, ProviderInstance, ProviderInitialize, @@ -218,116 +215,3 @@ export async function reuseOrder( return tx } - -async function approveProviderFee( - asset: AssetExtended, - accountId: string, - signer: Signer, - providerFeeAmount: string -): Promise { - const config = getOceanConfig(asset.chainId) - const baseToken = - asset?.accessDetails?.type === 'free' - ? getOceanConfig(asset.chainId).oceanTokenAddress - : asset?.accessDetails?.baseToken?.address - const txApproveWei = await approveWei( - signer, - config, - accountId, - baseToken, - asset?.accessDetails?.datatoken?.address, - providerFeeAmount - ) - return txApproveWei -} - -/** - * Handles order for compute assets for the following scenarios: - * - have validOrder and no providerFees -> then order is valid, providerFees are valid, it returns the valid order value - * - have validOrder and providerFees -> then order is valid but providerFees are not valid, we need to call reuseOrder and pay only providerFees - * - no validOrder -> we need to call order, to pay 1 DT & providerFees - * @param signer - * @param asset - * @param orderPriceAndFees - * @param accountId - * @param hasDatatoken - * @param initializeData - * @param computeConsumerAddress - * @returns {Promise} tx id - */ -export async function handleComputeOrder( - signer: Signer, - asset: AssetExtended, - orderPriceAndFees: OrderPriceAndFees, - accountId: string, - initializeData: ProviderComputeInitialize, - hasDatatoken, - computeConsumerAddress?: string -): Promise { - LoggerInstance.log( - '[compute] Handle compute order for asset type: ', - asset.metadata.type - ) - LoggerInstance.log('[compute] Using initializeData: ', initializeData) - - try { - // Return early when valid order is found, and no provider fees - // are to be paid - if (initializeData?.validOrder && !initializeData.providerFee) { - LoggerInstance.log( - '[compute] Has valid order: ', - initializeData.validOrder - ) - return asset?.accessDetails?.validOrderTx - } - - // Approve potential Provider fee amount first - if (initializeData?.providerFee?.providerFeeAmount !== '0') { - const txApproveProvider = await approveProviderFee( - asset, - accountId, - signer, - initializeData.providerFee.providerFeeAmount - ) - - if (!txApproveProvider) - throw new Error('Failed to approve provider fees!') - - LoggerInstance.log('[compute] Approved provider fees:', txApproveProvider) - } - - if (initializeData?.validOrder) { - LoggerInstance.log('[compute] Calling reuseOrder ...', initializeData) - const txReuseOrder = await reuseOrder( - signer, - asset, - accountId, - initializeData.validOrder, - initializeData.providerFee - ) - if (!txReuseOrder) throw new Error('Failed to reuse order!') - const tx = await txReuseOrder.wait() - LoggerInstance.log('[compute] Reused order:', tx) - return tx?.transactionHash - } - - LoggerInstance.log('[compute] Calling order ...', initializeData) - - const txStartOrder = await order( - signer, - asset, - orderPriceAndFees, - accountId, - hasDatatoken, - initializeData.providerFee, - computeConsumerAddress - ) - - const tx = await txStartOrder.wait() - LoggerInstance.log('[compute] Order succeeded', tx) - return tx?.transactionHash - } catch (error) { - toast.error(error.message) - LoggerInstance.error(`[compute] ${error.message}`) - } -} diff --git a/src/@utils/provider.ts b/src/@utils/provider.ts index f96212ae65..c624a232ae 100644 --- a/src/@utils/provider.ts +++ b/src/@utils/provider.ts @@ -2,14 +2,10 @@ import { Arweave, GraphqlQuery, Smartcontract, - ComputeAlgorithm, - ComputeAsset, - ComputeEnvironment, downloadFileBrowser, FileInfo, Ipfs, LoggerInstance, - ProviderComputeInitializeResults, ProviderInstance, UrlFile, AbiItem, @@ -20,49 +16,7 @@ import { import { customProviderUrl } from '../../app.config' import { KeyValuePair } from '@shared/FormInput/InputElement/KeyValueInput' import { Signer } from 'ethers' -import { getValidUntilTime } from './compute' import { toast } from 'react-toastify' -import { tr } from 'date-fns/locale' - -export async function initializeProviderForCompute( - dataset: AssetExtended, - algorithm: AssetExtended, - accountId: string, - computeEnv: ComputeEnvironment = null -): Promise { - const computeAsset: ComputeAsset = { - documentId: dataset.id, - serviceId: dataset.services[0].id, - transferTxId: dataset.accessDetails.validOrderTx - } - const computeAlgo: ComputeAlgorithm = { - documentId: algorithm.id, - serviceId: algorithm.services[0].id, - transferTxId: algorithm.accessDetails.validOrderTx - } - - const validUntil = getValidUntilTime( - computeEnv?.maxJobDuration, - dataset.services[0].timeout, - algorithm.services[0].timeout - ) - - try { - return await ProviderInstance.initializeCompute( - [computeAsset], - computeAlgo, - computeEnv?.id, - validUntil, - customProviderUrl || dataset.services[0].serviceEndpoint, - accountId - ) - } catch (error) { - const message = getErrorMessage(error.message) - LoggerInstance.error('[Initialize Provider] Error:', message) - toast.error(message) - return null - } -} // TODO: Why do we have these one line functions ?!?!?! export async function getEncryptedFiles( diff --git a/src/components/@shared/AssetTeaser/index.tsx b/src/components/@shared/AssetTeaser/index.tsx index 2a6fcf15b4..b6b8efbf53 100644 --- a/src/components/@shared/AssetTeaser/index.tsx +++ b/src/components/@shared/AssetTeaser/index.tsx @@ -7,10 +7,8 @@ import Publisher from '@shared/Publisher' import AssetType from '@shared/AssetType' import NetworkName from '@shared/NetworkName' import styles from './index.module.css' -import { getServiceByName } from '@utils/ddo' import { useUserPreferences } from '@context/UserPreferences' import { formatNumber } from '@utils/numbers' -import { AssetPrice } from '@oceanprotocol/lib' export declare type AssetTeaserProps = { asset: AssetExtended @@ -26,8 +24,7 @@ export default function AssetTeaser({ }: AssetTeaserProps): ReactElement { const { name, type, description } = asset.metadata const { datatokens } = asset - const isCompute = Boolean(getServiceByName(asset, 'compute')) - const accessType = isCompute ? 'compute' : 'access' + const accessType = 'access' const { owner } = asset.nft const { orders, allocated, price } = asset.stats const isUnsupportedPricing = diff --git a/src/components/Asset/AssetActions/ButtonBuy/index.tsx b/src/components/Asset/AssetActions/ButtonBuy/index.tsx index 5517de8022..d25eb2ca64 100644 --- a/src/components/Asset/AssetActions/ButtonBuy/index.tsx +++ b/src/components/Asset/AssetActions/ButtonBuy/index.tsx @@ -4,7 +4,7 @@ import styles from './index.module.css' import Loader from '../../../@shared/atoms/Loader' export interface ButtonBuyProps { - action: 'download' | 'compute' + action: 'download' disabled: boolean hasPreviousOrder: boolean hasDatatoken: boolean @@ -261,7 +261,6 @@ export default function ButtonBuy({ type={type} onClick={onClick} disabled={disabled} - className={action === 'compute' ? styles.actionsCenter : ''} > {buttonText} diff --git a/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.module.css b/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.module.css deleted file mode 100644 index 54cd6f2c1c..0000000000 --- a/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.module.css +++ /dev/null @@ -1,29 +0,0 @@ -.datasetsContainer { - display: flex; - flex: 1; - flex-direction: column; - align-items: center; - width: auto; - margin-left: -2rem; - margin-right: -2rem; - border-top: 1px solid var(--border-color); - margin-top: calc(var(--spacer) / 2); -} - -.datasetsContainer div[class*='AssetSelection-module--selection'] { - width: 100%; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-left: 0; - border-right: 0; - padding: 0; -} - -.datasetsContainer .text { - margin-bottom: calc(var(--spacer) / 2); - margin-top: calc(var(--spacer) / 2); - text-align: center; - color: var(--font-color-text); - font-size: var(--font-size-base); - font-family: var(--font-family-heading); -} diff --git a/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx b/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx deleted file mode 100644 index e15137d6c1..0000000000 --- a/src/components/Asset/AssetActions/Compute/AlgorithmDatasetsListForCompute.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { ReactElement, useEffect, useState } from 'react' -import styles from './AlgorithmDatasetsListForCompute.module.css' -import { getAlgorithmDatasetsForCompute } from '@utils/aquarius' -import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection' -import AssetComputeList from './AssetComputeList' -import { useCancelToken } from '@hooks/useCancelToken' -import { getServiceByName } from '@utils/ddo' - -export default function AlgorithmDatasetsListForCompute({ - asset, - algorithmDid -}: { - asset: AssetExtended - algorithmDid: string -}): ReactElement { - const newCancelToken = useCancelToken() - const [datasetsForCompute, setDatasetsForCompute] = - useState() - - useEffect(() => { - if (!asset || !asset?.accessDetails?.type) return - - async function getDatasetsAllowedForCompute() { - const isCompute = Boolean(getServiceByName(asset, 'compute')) - const datasetComputeService = getServiceByName( - asset, - isCompute ? 'compute' : 'access' - ) - const datasets = await getAlgorithmDatasetsForCompute( - algorithmDid, - datasetComputeService?.serviceEndpoint, - asset?.chainId, - newCancelToken() - ) - setDatasetsForCompute(datasets) - } - asset.metadata.type === 'algorithm' && getDatasetsAllowedForCompute() - }, [asset, algorithmDid, newCancelToken]) - - return ( -
-

Datasets algorithm is allowed to run on

- -
- ) -} diff --git a/src/components/Asset/AssetActions/Compute/AssetComputeList/index.module.css b/src/components/Asset/AssetActions/Compute/AssetComputeList/index.module.css deleted file mode 100644 index 8413da135b..0000000000 --- a/src/components/Asset/AssetActions/Compute/AssetComputeList/index.module.css +++ /dev/null @@ -1,59 +0,0 @@ -.display { - composes: selection from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; -} - -.display [class*='loaderWrap'] { - margin: calc(var(--spacer) / 3); -} - -.scroll { - composes: scroll from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; - margin-top: 0; - border-top: none; - width: 100%; -} - -.row { - composes: row from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; -} - -.row:last-child { - border-bottom: none; -} - -.row:first-child { - border-top: none; -} - -.row:hover { - background-color: var(--background-content); -} - -.info { - display: block; - width: 100%; -} - -.title { - composes: title from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; -} - -.hover:hover { - color: var(--color-primary); -} - -.price { - composes: price from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; -} - -.price [class*='symbol'] { - font-size: calc(var(--font-size-small) / 1.2) !important; -} - -.did { - composes: did from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; -} - -.empty { - composes: empty from '@shared/FormInput/InputElement/AssetSelection/index.module.css'; -} diff --git a/src/components/Asset/AssetActions/Compute/AssetComputeList/index.tsx b/src/components/Asset/AssetActions/Compute/AssetComputeList/index.tsx deleted file mode 100644 index f61beb0906..0000000000 --- a/src/components/Asset/AssetActions/Compute/AssetComputeList/index.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react' -import Dotdotdot from 'react-dotdotdot' -import Link from 'next/link' -import PriceUnit from '@shared/Price/PriceUnit' -import Loader from '@shared/atoms/Loader' -import styles from './index.module.css' -import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection' - -function Empty() { - return
No assets found.
-} - -export default function AssetComputeSelection({ - assets -}: { - assets: AssetSelectionAsset[] -}): JSX.Element { - return ( -
-
- {!assets ? ( - - ) : assets && !assets.length ? ( - - ) : ( - assets.map((asset: AssetSelectionAsset) => ( - -
-

- - {asset.name} - -

- - {asset.symbol} | {asset.did} - -
- - - )) - )} -
-
- ) -} diff --git a/src/components/Asset/AssetActions/Compute/FormComputeDataset.module.css b/src/components/Asset/AssetActions/Compute/FormComputeDataset.module.css deleted file mode 100644 index a6d5aeb184..0000000000 --- a/src/components/Asset/AssetActions/Compute/FormComputeDataset.module.css +++ /dev/null @@ -1,28 +0,0 @@ -.form { - padding: 0; - border: none; -} - -.form > div > label, -.form [class*='ButtonBuy-module--actions'] { - text-align: center; -} - -.form > div > label { - margin-bottom: calc(var(--spacer) / 2); - margin-left: -1rem; -} - -.form [class*='AssetSelection-module--selection'] { - margin-left: -2rem; - margin-right: -2rem; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-left: 0; - border-right: 0; - padding: 0; -} - -.warning { - margin-bottom: var(--spacer); -} diff --git a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx deleted file mode 100644 index 5615782acf..0000000000 --- a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx +++ /dev/null @@ -1,325 +0,0 @@ -import React, { ReactElement, useEffect, useState } from 'react' -import styles from './FormComputeDataset.module.css' -import { Field, Form, FormikContextType, useFormikContext } from 'formik' -import Input from '@shared/FormInput' -import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection' -import { compareAsBN } from '@utils/numbers' -import ButtonBuy from '../ButtonBuy' -import PriceOutput from './PriceOutput' -import { useAsset } from '@context/Asset' -import content from '../../../../../content/pages/startComputeDataset.json' -import { Asset, ZERO_ADDRESS } from '@oceanprotocol/lib' -import { getAccessDetails } from '@utils/accessDetailsAndPricing' -import { getTokenBalanceFromSymbol } from '@utils/wallet' -import { MAX_DECIMALS } from '@utils/constants' -import Decimal from 'decimal.js' -import { useAccount } from 'wagmi' -import useBalance from '@hooks/useBalance' -import useNetworkMetadata from '@hooks/useNetworkMetadata' -import ConsumerParameters from '../ConsumerParameters' -import { FormConsumerParameter } from '@components/Publish/_types' - -export default function FormStartCompute({ - algorithms, - ddoListAlgorithms, - selectedAlgorithmAsset, - setSelectedAlgorithm, - isLoading, - isComputeButtonDisabled, - hasPreviousOrder, - hasDatatoken, - dtBalance, - assetType, - assetTimeout, - hasPreviousOrderSelectedComputeAsset, - hasDatatokenSelectedComputeAsset, - datasetSymbol, - algorithmSymbol, - providerFeesSymbol, - dtSymbolSelectedComputeAsset, - dtBalanceSelectedComputeAsset, - selectedComputeAssetType, - selectedComputeAssetTimeout, - stepText, - isConsumable, - consumableFeedback, - datasetOrderPriceAndFees, - algoOrderPriceAndFees, - providerFeeAmount, - validUntil, - retry -}: { - algorithms: AssetSelectionAsset[] - ddoListAlgorithms: Asset[] - selectedAlgorithmAsset: AssetExtended - setSelectedAlgorithm: React.Dispatch> - isLoading: boolean - isComputeButtonDisabled: boolean - hasPreviousOrder: boolean - hasDatatoken: boolean - dtBalance: string - assetType: string - assetTimeout: string - hasPreviousOrderSelectedComputeAsset?: boolean - hasDatatokenSelectedComputeAsset?: boolean - datasetSymbol?: string - algorithmSymbol?: string - providerFeesSymbol?: string - dtSymbolSelectedComputeAsset?: string - dtBalanceSelectedComputeAsset?: string - selectedComputeAssetType?: string - selectedComputeAssetTimeout?: string - stepText: string - isConsumable: boolean - consumableFeedback: string - datasetOrderPriceAndFees?: OrderPriceAndFees - algoOrderPriceAndFees?: OrderPriceAndFees - providerFeeAmount?: string - validUntil?: string - retry: boolean -}): ReactElement { - const { address: accountId, isConnected } = useAccount() - const { balance } = useBalance() - const { isSupportedOceanNetwork } = useNetworkMetadata() - const { - isValid, - values - }: FormikContextType<{ - algorithm: string - dataServiceParams: FormConsumerParameter[] - algoServiceParams: FormConsumerParameter[] - algoParams: FormConsumerParameter[] - }> = useFormikContext() - const { asset, isAssetNetwork } = useAsset() - - const [datasetOrderPrice, setDatasetOrderPrice] = useState( - asset?.accessDetails?.price - ) - const [algoOrderPrice, setAlgoOrderPrice] = useState( - selectedAlgorithmAsset?.accessDetails?.price - ) - const [totalPrices, setTotalPrices] = useState([]) - const [isBalanceSufficient, setIsBalanceSufficient] = useState(true) - - function getAlgorithmAsset(algorithmId: string): Asset { - let assetDdo = null - ddoListAlgorithms.forEach((ddo: Asset) => { - if (ddo.id === algorithmId) assetDdo = ddo - }) - return assetDdo - } - - useEffect(() => { - if (!values.algorithm || !isConsumable) return - - async function fetchAlgorithmAssetExtended() { - const algorithmAsset = getAlgorithmAsset(values.algorithm) - const accessDetails = await getAccessDetails( - algorithmAsset.chainId, - algorithmAsset.services[0].datatokenAddress, - algorithmAsset.services[0].timeout, - accountId || ZERO_ADDRESS // if user is not connected, use ZERO_ADDRESS as accountId - ) - const extendedAlgoAsset: AssetExtended = { - ...algorithmAsset, - accessDetails - } - setSelectedAlgorithm(extendedAlgoAsset) - } - fetchAlgorithmAssetExtended() - }, [values.algorithm, accountId, isConsumable]) - - // - // Set price for calculation output - // - useEffect(() => { - if (!asset?.accessDetails || !selectedAlgorithmAsset?.accessDetails) return - - setDatasetOrderPrice( - datasetOrderPriceAndFees?.price || asset.accessDetails.price - ) - setAlgoOrderPrice( - algoOrderPriceAndFees?.price || - selectedAlgorithmAsset?.accessDetails.price - ) - const totalPrices: totalPriceMap[] = [] - const priceDataset = - !datasetOrderPrice || hasPreviousOrder || hasDatatoken - ? new Decimal(0) - : new Decimal(datasetOrderPrice).toDecimalPlaces(MAX_DECIMALS) - const priceAlgo = - !algoOrderPrice || - hasPreviousOrderSelectedComputeAsset || - hasDatatokenSelectedComputeAsset - ? new Decimal(0) - : new Decimal(algoOrderPrice).toDecimalPlaces(MAX_DECIMALS) - const providerFees = providerFeeAmount - ? new Decimal(providerFeeAmount).toDecimalPlaces(MAX_DECIMALS) - : new Decimal(0) - - if (algorithmSymbol === providerFeesSymbol) { - let sum = providerFees.add(priceAlgo) - totalPrices.push({ - value: sum.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: algorithmSymbol - }) - if (algorithmSymbol === datasetSymbol) { - sum = sum.add(priceDataset) - totalPrices[0].value = sum.toDecimalPlaces(MAX_DECIMALS).toString() - } else { - totalPrices.push({ - value: priceDataset.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: datasetSymbol - }) - } - } else { - if (datasetSymbol === providerFeesSymbol) { - const sum = providerFees.add(priceDataset) - totalPrices.push({ - value: sum.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: datasetSymbol - }) - totalPrices.push({ - value: priceAlgo.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: algorithmSymbol - }) - } else if (datasetSymbol === algorithmSymbol) { - const sum = priceAlgo.add(priceDataset) - totalPrices.push({ - value: sum.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: algorithmSymbol - }) - totalPrices.push({ - value: providerFees.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: providerFeesSymbol - }) - } else { - totalPrices.push({ - value: priceDataset.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: datasetSymbol - }) - totalPrices.push({ - value: providerFees.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: providerFeesSymbol - }) - totalPrices.push({ - value: priceAlgo.toDecimalPlaces(MAX_DECIMALS).toString(), - symbol: algorithmSymbol - }) - } - } - setTotalPrices(totalPrices) - }, [ - asset, - hasPreviousOrder, - hasDatatoken, - hasPreviousOrderSelectedComputeAsset, - hasDatatokenSelectedComputeAsset, - datasetOrderPriceAndFees, - algoOrderPriceAndFees, - providerFeeAmount, - isAssetNetwork, - selectedAlgorithmAsset?.accessDetails, - datasetOrderPrice, - algoOrderPrice, - algorithmSymbol, - datasetSymbol, - providerFeesSymbol - ]) - - useEffect(() => { - totalPrices.forEach((price) => { - const baseTokenBalance = getTokenBalanceFromSymbol(balance, price.symbol) - if (!baseTokenBalance) { - setIsBalanceSufficient(false) - return - } - - // if one comparison of baseTokenBalance and token price comparison is false then the state will be false - setIsBalanceSufficient( - baseTokenBalance && compareAsBN(baseTokenBalance, `${price.value}`) - ) - }) - }, [balance, dtBalance, datasetSymbol, algorithmSymbol, totalPrices]) - - return ( -
- {content.form.data.map((field: FormFieldContent) => { - return ( - - ) - })} - {asset && selectedAlgorithmAsset && ( - - )} - - - - - ) -} diff --git a/src/components/Asset/AssetActions/Compute/History.module.css b/src/components/Asset/AssetActions/Compute/History.module.css deleted file mode 100644 index 1a654d009c..0000000000 --- a/src/components/Asset/AssetActions/Compute/History.module.css +++ /dev/null @@ -1,93 +0,0 @@ -.container { - margin-left: calc(-1 * var(--spacer) / 1.5); - margin-right: calc(-1 * var(--spacer) / 1.5); - padding: calc(var(--spacer) / 1.5) calc(var(--spacer) / 1.5) - calc(var(--spacer) / 2) calc(var(--spacer) / 1.5); -} - -@media (min-width: 40rem) { - .container { - padding-left: var(--spacer); - padding-right: var(--spacer); - margin-left: calc(-1 * var(--spacer)); - margin-right: calc(-1 * var(--spacer)); - } -} - -.section { - composes: container; - - border-top: 1px solid var(--border-color); - position: relative; -} - -.section.highlight { - background: var(--background-highlight); -} - -.section:first-child { - padding-top: 0; - border-top: 0; -} - -.actions { - composes: section; - margin-top: calc(var(--spacer) / 1.5); - padding: calc(var(--spacer) / 1.5); - background: var(--background-highlight); - margin-bottom: -1rem; -} - -.actions [class*='rdt_Pagination'] { - margin-bottom: -1rem; -} - -.title { - font-size: var(--font-size-base); - margin-bottom: calc(var(--spacer) / 3); - color: var(--color-secondary); - margin-bottom: 0; - display: flex; - align-items: center; - justify-content: space-between; - cursor: pointer; -} - -.title:hover .toggle { - color: var(--color-primary); -} - -.title + div { - margin-top: calc(var(--spacer) / 3); -} - -.toggle { - color: var(--color-secondary); -} - -.toggle svg { - display: inline-block; - width: var(--font-size-mini); - height: var(--font-size-mini); - fill: currentColor; - transition: 0.2s ease-out; -} - -.open .toggle svg { - transform: rotate(180deg); -} - -.actions [class*='Table-module--table'] { - /* - react-data-table-component sets a default width: 100% - which often leads to unneccessary overflows. Following lines make - sure table always spans between edges of container, without any overflow - when enough space is available. But it also destroys overflow table on narrow - viewports. - */ - width: 100%; -} - -.actions [class*='TableCell'] { - width: 140px; -} diff --git a/src/components/Asset/AssetActions/Compute/History.tsx b/src/components/Asset/AssetActions/Compute/History.tsx deleted file mode 100644 index 095308d5ae..0000000000 --- a/src/components/Asset/AssetActions/Compute/History.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { ReactElement, ReactNode, useState } from 'react' -import Button from '@shared/atoms/Button' -import styles from './History.module.css' -import Caret from '@images/caret.svg' - -export default function ComputeHistory({ - title, - children, - refetchJobs -}: { - title: string - children: ReactNode - refetchJobs?: React.Dispatch> -}): ReactElement { - const [open, setOpen] = useState(false) - - async function handleClick() { - await refetchJobs(true) - setOpen(!open) - } - - return ( -
- {/* TODO: onClick on h3 is nasty but we're in a hurry */} -

- {`${title} `} - -

- {open === true && children} -
- ) -} diff --git a/src/components/Asset/AssetActions/Compute/PriceOutput.module.css b/src/components/Asset/AssetActions/Compute/PriceOutput.module.css deleted file mode 100644 index a163c2c87c..0000000000 --- a/src/components/Asset/AssetActions/Compute/PriceOutput.module.css +++ /dev/null @@ -1,60 +0,0 @@ -.priceComponent { - margin-left: -2rem; - margin-right: -2rem; - margin-bottom: calc(var(--spacer) / 1.5); - padding-left: calc(var(--spacer) / 2); - padding-right: calc(var(--spacer) / 2); - border-bottom: 1px solid var(--border-color); - padding-bottom: calc(var(--spacer) / 3); - text-align: center; - color: var(--color-secondary); - font-size: var(--font-size-small); -} - -.priceComponent > * { - display: inline-block !important; -} - -.calculation { - min-width: 12rem; -} - -.timeout { - display: block; - text-align: right; - font-size: var(--font-size-mini); - color: var(--color-secondary); -} - -.calculation .price { - font-size: var(--font-size-small) !important; -} - -.priceRow { - width: 100%; - border-bottom: 1px solid var(--border-color); - padding-top: calc(var(--spacer) / 7); - padding-bottom: calc(var(--spacer) / 7); - display: grid; - grid-template-columns: 5% 1fr auto; - column-gap: calc(var(--spacer) / 10); -} - -.priceRow:last-child { - border-bottom: none; - border-top: 1px solid var(--border-color); -} - -.sign { - display: inline-block; - text-align: left; - color: var(--color-secondary); - font-size: var(--font-size-base); -} - -.type { - display: inline-block; - text-align: left; - color: var(--color-secondary); - font-size: var(--font-size-mini); -} diff --git a/src/components/Asset/AssetActions/Compute/PriceOutput.tsx b/src/components/Asset/AssetActions/Compute/PriceOutput.tsx deleted file mode 100644 index 6bc39f2d37..0000000000 --- a/src/components/Asset/AssetActions/Compute/PriceOutput.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { ReactElement } from 'react' -import { useAsset } from '@context/Asset' -import PriceUnit from '@shared/Price/PriceUnit' -import Tooltip from '@shared/atoms/Tooltip' -import styles from './PriceOutput.module.css' -import { MAX_DECIMALS } from '@utils/constants' -import Decimal from 'decimal.js' -import useNetworkMetadata from '@hooks/useNetworkMetadata' - -interface PriceOutputProps { - hasPreviousOrder: boolean - hasDatatoken: boolean - symbol: string - assetTimeout: string - hasPreviousOrderSelectedComputeAsset: boolean - hasDatatokenSelectedComputeAsset: boolean - algorithmConsumeDetails: AccessDetails - algorithmSymbol: string - selectedComputeAssetTimeout: string - datasetOrderPrice?: string - algoOrderPrice?: string - providerFeeAmount?: string - providerFeesSymbol?: string - validUntil?: string - totalPrices?: totalPriceMap[] -} - -function Row({ - price, - hasPreviousOrder, - hasDatatoken, - symbol, - timeout, - sign, - type -}: { - price: string - hasPreviousOrder?: boolean - hasDatatoken?: boolean - symbol?: string - timeout?: string - sign?: string - type?: string -}) { - return ( -
-
{sign}
-
{type}
-
- - - {timeout && - timeout !== 'Forever' && - !hasPreviousOrder && - `for ${timeout}`} - -
-
- ) -} - -export default function PriceOutput({ - hasPreviousOrder, - hasDatatoken, - assetTimeout, - symbol, - hasPreviousOrderSelectedComputeAsset, - hasDatatokenSelectedComputeAsset, - algorithmConsumeDetails, - algorithmSymbol, - selectedComputeAssetTimeout, - datasetOrderPrice, - algoOrderPrice, - providerFeeAmount, - providerFeesSymbol, - validUntil, - totalPrices -}: PriceOutputProps): ReactElement { - const { asset } = useAsset() - - return ( -
- You will pay{' '} - {totalPrices.map((item, index) => ( -
- -
- ))} - - - - - {totalPrices.map((item, index) => ( - - ))} -
- } - /> - - ) -} diff --git a/src/components/Asset/AssetActions/Compute/_constants.ts b/src/components/Asset/AssetActions/Compute/_constants.ts deleted file mode 100644 index 6da694f6f7..0000000000 --- a/src/components/Asset/AssetActions/Compute/_constants.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ConsumerParameter, UserCustomParameters } from '@oceanprotocol/lib' -import * as Yup from 'yup' -import { getDefaultValues } from '../ConsumerParameters/FormConsumerParameters' -import { getUserCustomParameterValidationSchema } from '../ConsumerParameters/_validation' - -export function getComputeValidationSchema( - dataServiceParams: ConsumerParameter[], - algoServiceParams: ConsumerParameter[], - algoParams: ConsumerParameter[] -): Yup.SchemaOf<{ - algorithm: string - dataServiceParams: any - algoServiceParams: any - algoParams: any -}> { - return Yup.object().shape({ - algorithm: Yup.string().required('Required'), - dataServiceParams: - getUserCustomParameterValidationSchema(dataServiceParams), - algoServiceParams: - getUserCustomParameterValidationSchema(algoServiceParams), - algoParams: getUserCustomParameterValidationSchema(algoParams) - }) -} - -export function getInitialValues( - asset?: AssetExtended, - selectedAlgorithmAsset?: AssetExtended -): { - algorithm: string - dataServiceParams?: UserCustomParameters - algoServiceParams?: UserCustomParameters - algoParams?: UserCustomParameters -} { - return { - algorithm: selectedAlgorithmAsset?.id, - dataServiceParams: getDefaultValues(asset?.services[0].consumerParameters), - algoServiceParams: getDefaultValues( - selectedAlgorithmAsset?.services[0].consumerParameters - ), - algoParams: getDefaultValues( - selectedAlgorithmAsset?.metadata?.algorithm.consumerParameters - ) - } -} diff --git a/src/components/Asset/AssetActions/Compute/index.module.css b/src/components/Asset/AssetActions/Compute/index.module.css deleted file mode 100644 index a0c880beb4..0000000000 --- a/src/components/Asset/AssetActions/Compute/index.module.css +++ /dev/null @@ -1,26 +0,0 @@ -.info { - display: flex; - align-items: center; - width: auto; - margin-bottom: calc(var(--spacer) / 2); - border-bottom: 1px solid var(--border-color); - margin-top: -1rem; - margin-left: -2rem; - margin-right: -2rem; - padding: 0 calc(var(--spacer) / 2) calc(var(--spacer) / 2) - calc(var(--spacer) * 1.5); -} - -.warning { - padding-bottom: 0; - border-bottom: 0; -} - -.feedback { - width: 100%; - margin-top: calc(var(--spacer) / 2); -} - -.feedback:empty { - margin-top: 0; -} diff --git a/src/components/Asset/AssetActions/Compute/index.tsx b/src/components/Asset/AssetActions/Compute/index.tsx deleted file mode 100644 index 90d7d04d0e..0000000000 --- a/src/components/Asset/AssetActions/Compute/index.tsx +++ /dev/null @@ -1,592 +0,0 @@ -import React, { useState, ReactElement, useEffect, useCallback } from 'react' -import { - Asset, - DDO, - FileInfo, - Datatoken, - ProviderInstance, - ComputeAsset, - ZERO_ADDRESS, - ComputeEnvironment, - LoggerInstance, - ComputeAlgorithm, - ComputeOutput, - ProviderComputeInitializeResults, - unitsToAmount, - ProviderFees, - AssetPrice, - UserCustomParameters, - getErrorMessage -} from '@oceanprotocol/lib' -import { toast } from 'react-toastify' -import Price from '@shared/Price' -import FileIcon from '@shared/FileIcon' -import Alert from '@shared/atoms/Alert' -import { Formik } from 'formik' -import { getComputeValidationSchema, getInitialValues } from './_constants' -import FormStartComputeDataset from './FormComputeDataset' -import styles from './index.module.css' -import SuccessConfetti from '@shared/SuccessConfetti' -import { getServiceByName, secondsToString } from '@utils/ddo' -import { - isOrderable, - getAlgorithmAssetSelectionList, - getAlgorithmsForAsset, - getComputeEnviroment, - getComputeJobs -} from '@utils/compute' -import { AssetSelectionAsset } from '@shared/FormInput/InputElement/AssetSelection' -import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute' -import ComputeHistory from './History' -import ComputeJobs from '../../../Profile/History/ComputeJobs' -import { useCancelToken } from '@hooks/useCancelToken' -import { Decimal } from 'decimal.js' -import { useAbortController } from '@hooks/useAbortController' -import { - getAvailablePrice, - getOrderPriceAndFees -} from '@utils/accessDetailsAndPricing' -import { handleComputeOrder } from '@utils/order' -import { getComputeFeedback } from '@utils/feedback' -import { initializeProviderForCompute } from '@utils/provider' -import { useUserPreferences } from '@context/UserPreferences' -import { useAccount, useSigner } from 'wagmi' -import { getDummySigner } from '@utils/wallet' -import useNetworkMetadata from '@hooks/useNetworkMetadata' -import { useAsset } from '@context/Asset' -import { parseConsumerParameterValues } from '../ConsumerParameters' - -const refreshInterval = 10000 // 10 sec. - -export default function Compute({ - asset, - dtBalance, - file, - fileIsLoading, - consumableFeedback -}: { - asset: AssetExtended - dtBalance: string - file: FileInfo - fileIsLoading?: boolean - consumableFeedback?: string -}): ReactElement { - const { address: accountId } = useAccount() - const { chainIds } = useUserPreferences() - const { data: signer } = useSigner() - - const newAbortController = useAbortController() - const newCancelToken = useCancelToken() - - const [isOrdering, setIsOrdering] = useState(false) - const [isOrdered, setIsOrdered] = useState(false) - const [error, setError] = useState() - - const [algorithmList, setAlgorithmList] = useState() - const [ddoAlgorithmList, setDdoAlgorithmList] = useState() - const [selectedAlgorithmAsset, setSelectedAlgorithmAsset] = - useState() - const [hasAlgoAssetDatatoken, setHasAlgoAssetDatatoken] = useState() - const [algorithmDTBalance, setAlgorithmDTBalance] = useState() - - const [validOrderTx, setValidOrderTx] = useState('') - const [validAlgorithmOrderTx, setValidAlgorithmOrderTx] = useState('') - - const [isConsumablePrice, setIsConsumablePrice] = useState(true) - const [isConsumableaAlgorithmPrice, setIsConsumableAlgorithmPrice] = - useState(true) - const [computeStatusText, setComputeStatusText] = useState('') - const [computeEnv, setComputeEnv] = useState() - const [initializedProviderResponse, setInitializedProviderResponse] = - useState() - const [providerFeeAmount, setProviderFeeAmount] = useState('0') - const [providerFeesSymbol, setProviderFeesSymbol] = useState('OCEAN') - const [computeValidUntil, setComputeValidUntil] = useState('0') - const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] = - useState() - const [algoOrderPriceAndFees, setAlgoOrderPriceAndFees] = - useState() - const [isRequestingAlgoOrderPrice, setIsRequestingAlgoOrderPrice] = - useState(false) - const [refetchJobs, setRefetchJobs] = useState(false) - const [isLoadingJobs, setIsLoadingJobs] = useState(false) - const [jobs, setJobs] = useState([]) - const [retry, setRetry] = useState(false) - const { isSupportedOceanNetwork } = useNetworkMetadata() - const { isAssetNetwork } = useAsset() - - const price: AssetPrice = getAvailablePrice(asset) - - const hasDatatoken = Number(dtBalance) >= 1 - const isComputeButtonDisabled = - isOrdering === true || - file === null || - (!validOrderTx && !hasDatatoken && !isConsumablePrice) || - (!validAlgorithmOrderTx && - !hasAlgoAssetDatatoken && - !isConsumableaAlgorithmPrice) - - const isUnsupportedPricing = asset?.accessDetails?.type === 'NOT_SUPPORTED' - - async function checkAssetDTBalance(asset: DDO) { - if (!asset?.services[0].datatokenAddress) return - const dummySigner = await getDummySigner(asset?.chainId) - const datatokenInstance = new Datatoken(dummySigner) - const dtBalance = await datatokenInstance.balance( - asset?.services[0].datatokenAddress, - accountId || ZERO_ADDRESS // if the user is not connected, we use ZERO_ADDRESS as accountId - ) - setAlgorithmDTBalance(new Decimal(dtBalance).toString()) - const hasAlgoDt = Number(dtBalance) >= 1 - setHasAlgoAssetDatatoken(hasAlgoDt) - } - - async function setComputeFees( - providerData: ProviderComputeInitializeResults - ): Promise { - if (asset.accessDetails.validProviderFees) { - providerData.datasets[0].providerFee.providerFeeAmount = '0' - } - - const providerFeeToken = - providerData?.datasets?.[0]?.providerFee?.providerFeeToken - const providerFeeAmount = asset.accessDetails.validProviderFees - ? '0' - : providerData?.datasets?.[0]?.providerFee?.providerFeeAmount - const feeValidity = providerData?.datasets?.[0]?.providerFee?.validUntil - - const feeAmount = await unitsToAmount( - !isSupportedOceanNetwork || !isAssetNetwork - ? await getDummySigner(asset?.chainId) - : signer, - providerFeeToken, - providerFeeAmount - ) - setProviderFeeAmount(feeAmount) - - const datatoken = new Datatoken(await getDummySigner(asset?.chainId)) - setProviderFeesSymbol(await datatoken.getSymbol(providerFeeToken)) - - const computeDuration = asset.accessDetails.validProviderFees - ? asset.accessDetails.validProviderFees.validUntil - : (parseInt(feeValidity) - Math.floor(Date.now() / 1000)).toString() - setComputeValidUntil(computeDuration) - - return providerData - } - - async function setAlgoPrice(algoProviderFees: ProviderFees) { - if ( - selectedAlgorithmAsset?.accessDetails?.addressOrId !== ZERO_ADDRESS && - selectedAlgorithmAsset?.accessDetails?.type !== 'free' && - algoProviderFees - ) { - const algorithmOrderPriceAndFees = await getOrderPriceAndFees( - selectedAlgorithmAsset, - ZERO_ADDRESS, - signer, - algoProviderFees - ) - if (!algorithmOrderPriceAndFees) - throw new Error('Error setting algorithm price and fees!') - - setAlgoOrderPriceAndFees(algorithmOrderPriceAndFees) - } - } - - async function setDatasetPrice(datasetProviderFees: ProviderFees) { - if ( - asset?.accessDetails?.addressOrId !== ZERO_ADDRESS && - asset?.accessDetails?.type !== 'free' && - datasetProviderFees - ) { - const datasetPriceAndFees = await getOrderPriceAndFees( - asset, - ZERO_ADDRESS, - signer, - datasetProviderFees - ) - if (!datasetPriceAndFees) - throw new Error('Error setting dataset price and fees!') - - setDatasetOrderPriceAndFees(datasetPriceAndFees) - } - } - - async function initPriceAndFees() { - try { - const computeEnv = await getComputeEnviroment(asset) - if (!computeEnv || !computeEnv.id) - throw new Error(`Error getting compute environments!`) - - setComputeEnv(computeEnv) - const initializedProvider = await initializeProviderForCompute( - asset, - selectedAlgorithmAsset, - accountId || ZERO_ADDRESS, // if the user is not connected, we use ZERO_ADDRESS as accountId - computeEnv - ) - - if ( - !initializedProvider || - !initializedProvider?.datasets || - !initializedProvider?.algorithm - ) - throw new Error(`Error initializing provider for the compute job!`) - - setComputeStatusText( - getComputeFeedback( - asset.accessDetails?.baseToken?.symbol, - asset.accessDetails?.datatoken?.symbol, - asset.metadata.type - )[0] - ) - - await setDatasetPrice(initializedProvider?.datasets?.[0]?.providerFee) - setComputeStatusText( - getComputeFeedback( - selectedAlgorithmAsset?.accessDetails?.baseToken?.symbol, - selectedAlgorithmAsset?.accessDetails?.datatoken?.symbol, - selectedAlgorithmAsset?.metadata?.type - )[0] - ) - - await setAlgoPrice(initializedProvider?.algorithm?.providerFee) - const sanitizedResponse = await setComputeFees(initializedProvider) - setInitializedProviderResponse(sanitizedResponse) - } catch (error) { - setError(error.message) - LoggerInstance.error(`[compute] ${error.message} `) - } - } - - useEffect(() => { - if (!asset?.accessDetails || !accountId || isUnsupportedPricing) return - - setIsConsumablePrice(asset?.accessDetails?.isPurchasable) - setValidOrderTx(asset?.accessDetails?.validOrderTx) - }, [asset?.accessDetails, accountId, isUnsupportedPricing]) - - useEffect(() => { - if (!selectedAlgorithmAsset?.accessDetails) return - - setIsRequestingAlgoOrderPrice(true) - setIsConsumableAlgorithmPrice( - selectedAlgorithmAsset?.accessDetails?.isPurchasable - ) - setValidAlgorithmOrderTx( - selectedAlgorithmAsset?.accessDetails?.validOrderTx - ) - setAlgoOrderPriceAndFees(null) - - async function initSelectedAlgo() { - await checkAssetDTBalance(selectedAlgorithmAsset) - await initPriceAndFees() - setIsRequestingAlgoOrderPrice(false) - } - - initSelectedAlgo() - }, [selectedAlgorithmAsset, accountId]) - - useEffect(() => { - if (!asset?.accessDetails || isUnsupportedPricing) return - - getAlgorithmsForAsset(asset, newCancelToken()).then((algorithmsAssets) => { - setDdoAlgorithmList(algorithmsAssets) - getAlgorithmAssetSelectionList(asset, algorithmsAssets).then( - (algorithmSelectionList) => { - setAlgorithmList(algorithmSelectionList) - } - ) - }) - }, [asset, isUnsupportedPricing]) - - const fetchJobs = useCallback( - async (type: string) => { - if (!chainIds || chainIds.length === 0 || !accountId) { - return - } - - try { - type === 'init' && setIsLoadingJobs(true) - const computeJobs = await getComputeJobs( - [asset?.chainId] || chainIds, - accountId, - asset, - newCancelToken() - ) - setJobs(computeJobs.computeJobs) - setIsLoadingJobs(!computeJobs.isLoaded) - } catch (error) { - LoggerInstance.error(error.message) - setIsLoadingJobs(false) - } - }, - [accountId, asset, chainIds, isLoadingJobs, newCancelToken] - ) - - useEffect(() => { - fetchJobs('init') - - // init periodic refresh for jobs - const balanceInterval = setInterval( - () => fetchJobs('repeat'), - refreshInterval - ) - - return () => { - clearInterval(balanceInterval) - } - }, [refetchJobs]) - - // Output errors in toast UI - useEffect(() => { - const newError = error - if (!newError) return - const errorMsg = newError + '. Please retry.' - toast.error(errorMsg) - }, [error]) - - async function startJob(userCustomParameters: { - dataServiceParams?: UserCustomParameters - algoServiceParams?: UserCustomParameters - algoParams?: UserCustomParameters - }): Promise { - try { - setIsOrdering(true) - setIsOrdered(false) - setError(undefined) - const computeService = getServiceByName(asset, 'compute') - const computeAlgorithm: ComputeAlgorithm = { - documentId: selectedAlgorithmAsset.id, - serviceId: selectedAlgorithmAsset.services[0].id, - algocustomdata: userCustomParameters?.algoParams, - userdata: userCustomParameters?.algoServiceParams - } - - const allowed = await isOrderable( - asset, - computeService.id, - computeAlgorithm, - selectedAlgorithmAsset - ) - LoggerInstance.log('[compute] Is dataset orderable?', allowed) - if (!allowed) - throw new Error( - 'Dataset is not orderable in combination with selected algorithm.' - ) - - await initPriceAndFees() - - setComputeStatusText( - getComputeFeedback( - selectedAlgorithmAsset.accessDetails.baseToken?.symbol, - selectedAlgorithmAsset.accessDetails.datatoken?.symbol, - selectedAlgorithmAsset.metadata.type - )[selectedAlgorithmAsset.accessDetails?.type === 'fixed' ? 2 : 3] - ) - - const algorithmOrderTx = await handleComputeOrder( - signer, - selectedAlgorithmAsset, - algoOrderPriceAndFees, - accountId, - initializedProviderResponse.algorithm, - hasAlgoAssetDatatoken, - computeEnv.consumerAddress - ) - if (!algorithmOrderTx) throw new Error('Failed to order algorithm.') - - setComputeStatusText( - getComputeFeedback( - asset.accessDetails.baseToken?.symbol, - asset.accessDetails.datatoken?.symbol, - asset.metadata.type - )[asset.accessDetails?.type === 'fixed' ? 2 : 3] - ) - - const datasetOrderTx = await handleComputeOrder( - signer, - asset, - datasetOrderPriceAndFees, - accountId, - initializedProviderResponse.datasets[0], - hasDatatoken, - computeEnv.consumerAddress - ) - if (!datasetOrderTx) throw new Error('Failed to order dataset.') - - LoggerInstance.log('[compute] Starting compute job.') - const computeAsset: ComputeAsset = { - documentId: asset.id, - serviceId: asset.services[0].id, - transferTxId: datasetOrderTx, - userdata: userCustomParameters?.dataServiceParams - } - computeAlgorithm.transferTxId = algorithmOrderTx - const output: ComputeOutput = { - publishAlgorithmLog: true, - publishOutput: true - } - setComputeStatusText(getComputeFeedback()[4]) - const response = await ProviderInstance.computeStart( - asset.services[0].serviceEndpoint, - signer, - computeEnv?.id, - computeAsset, - computeAlgorithm, - newAbortController(), - null, - output - ) - if (!response) throw new Error('Error starting compute job.') - - LoggerInstance.log('[compute] Starting compute job response: ', response) - setIsOrdered(true) - setRefetchJobs(!refetchJobs) - initPriceAndFees() - } catch (error) { - const message = getErrorMessage(error.message) - LoggerInstance.error('[Compute] Error:', message) - setError(message) - setRetry(true) - } finally { - setIsOrdering(false) - } - } - - const onSubmit = async (values: { - algorithm: string - dataServiceParams?: UserCustomParameters - algoServiceParams?: UserCustomParameters - algoParams?: UserCustomParameters - }) => { - if (!values.algorithm) return - - const userCustomParameters = { - dataServiceParams: parseConsumerParameterValues( - values?.dataServiceParams, - asset.services[0].consumerParameters - ), - algoServiceParams: parseConsumerParameterValues( - values?.algoServiceParams, - selectedAlgorithmAsset?.services[0].consumerParameters - ), - algoParams: parseConsumerParameterValues( - values?.algoParams, - selectedAlgorithmAsset?.metadata?.algorithm?.consumerParameters - ) - } - - await startJob(userCustomParameters) - } - - return ( - <> -
- - {isUnsupportedPricing ? ( - - ) : ( - - )} -
- - {isUnsupportedPricing ? null : asset.metadata.type === 'algorithm' ? ( - asset.services[0].type === 'compute' && ( - - ) - ) : ( - - - - )} - -
- {isOrdered && ( - - )} -
- {accountId && asset?.accessDetails?.datatoken && ( - setRefetchJobs(!refetchJobs)} - > - setRefetchJobs(!refetchJobs)} - /> - - )} - - ) -} diff --git a/src/components/Asset/AssetActions/Download/index.tsx b/src/components/Asset/AssetActions/Download/index.tsx index d1dfd4702c..72db7c1616 100644 --- a/src/components/Asset/AssetActions/Download/index.tsx +++ b/src/components/Asset/AssetActions/Download/index.tsx @@ -5,7 +5,6 @@ import { useAsset } from '@context/Asset' import ButtonBuy from '../ButtonBuy' import { secondsToString } from '@utils/ddo' import styles from './index.module.css' -import AlgorithmDatasetsListForCompute from '../Compute/AlgorithmDatasetsListForCompute' import { AssetPrice, FileInfo, @@ -299,13 +298,6 @@ export default function Download({ )} - - {asset?.metadata?.type === 'algorithm' && ( - - )} diff --git a/src/components/Asset/AssetActions/index.tsx b/src/components/Asset/AssetActions/index.tsx index 6087c3a642..93ecac6163 100644 --- a/src/components/Asset/AssetActions/index.tsx +++ b/src/components/Asset/AssetActions/index.tsx @@ -1,5 +1,4 @@ import React, { ReactElement, useState, useEffect } from 'react' -import Compute from './Compute' import Download from './Download' import { FileInfo, LoggerInstance, Datatoken } from '@oceanprotocol/lib' import { compareAsBN } from '@utils/numbers' @@ -39,9 +38,6 @@ export default function AssetActions({ const [dtBalance, setDtBalance] = useState() const [fileMetadata, setFileMetadata] = useState() const [fileIsLoading, setFileIsLoading] = useState(false) - const isCompute = Boolean( - asset?.services.filter((service) => service.type === 'compute')[0] - ) // Get and set file info useEffect(() => { @@ -149,22 +145,13 @@ export default function AssetActions({ return (
- {isCompute ? ( - - ) : ( - - )} +
) diff --git a/src/components/Asset/AssetContent/MetaMain/MetaInfo.tsx b/src/components/Asset/AssetContent/MetaMain/MetaInfo.tsx index b2f092a952..64b6bd1af9 100644 --- a/src/components/Asset/AssetContent/MetaMain/MetaInfo.tsx +++ b/src/components/Asset/AssetContent/MetaMain/MetaInfo.tsx @@ -1,7 +1,6 @@ import AssetType from '@shared/AssetType' import Time from '@shared/atoms/Time' import Publisher from '@shared/Publisher' -import { getServiceByName } from '@utils/ddo' import React, { ReactElement } from 'react' import styles from './MetaInfo.module.css' @@ -12,8 +11,7 @@ export default function MetaInfo({ asset: AssetExtended nftPublisher: string }): ReactElement { - const isCompute = Boolean(getServiceByName(asset, 'compute')) - const accessType = isCompute ? 'compute' : 'access' + const accessType = 'access' const nftOwner = asset?.nft?.owner return ( diff --git a/src/components/Asset/AssetContent/index.tsx b/src/components/Asset/AssetContent/index.tsx index e2435cf6ec..ef093ac1b7 100644 --- a/src/components/Asset/AssetContent/index.tsx +++ b/src/components/Asset/AssetContent/index.tsx @@ -30,6 +30,10 @@ export default function AssetContent({ const [receipts, setReceipts] = useState([]) const [nftPublisher, setNftPublisher] = useState() + const hasActions = Boolean( + asset?.services.filter((service) => service.type !== 'compute')[0] + ) + useEffect(() => { if (!receipts.length) return @@ -74,7 +78,7 @@ export default function AssetContent({
- + {hasActions && } {isOwner && isAssetNetwork && (
)} -
- -
+
+ +
diff --git a/src/components/Asset/Edit/DebugEditCompute.tsx b/src/components/Asset/Edit/DebugEditCompute.tsx deleted file mode 100644 index c3952b94b0..0000000000 --- a/src/components/Asset/Edit/DebugEditCompute.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Asset, ServiceComputeOptions } from '@oceanprotocol/lib' -import React, { ReactElement, useEffect, useState } from 'react' -import DebugOutput from '@shared/DebugOutput' -import { useCancelToken } from '@hooks/useCancelToken' -import { transformComputeFormToServiceComputeOptions } from '@utils/compute' -import { ComputeEditForm } from './_types' -import { previewDebugPatch } from '@utils/ddo' - -export default function DebugEditCompute({ - values, - asset -}: { - values: ComputeEditForm - asset: Asset -}): ReactElement { - const [valuePreview, setValuePreview] = useState({}) - const [formTransformed, setFormTransformed] = - useState() - const newCancelToken = useCancelToken() - - useEffect(() => { - async function transformValues() { - const privacy = await transformComputeFormToServiceComputeOptions( - values, - asset.services[0].compute, - asset.chainId, - newCancelToken() - ) - setFormTransformed(privacy) - } - transformValues() - setValuePreview(previewDebugPatch(values, asset.chainId)) - }, [values, asset]) - - return ( - <> - - - - ) -} diff --git a/src/components/Asset/Edit/EditComputeDataset.tsx b/src/components/Asset/Edit/EditComputeDataset.tsx deleted file mode 100644 index c6fcb9421d..0000000000 --- a/src/components/Asset/Edit/EditComputeDataset.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { Formik } from 'formik' -import React, { ReactElement, useState } from 'react' -import FormEditComputeDataset from './FormEditComputeDataset' -import { - LoggerInstance, - ServiceComputeOptions, - Service, - Asset -} from '@oceanprotocol/lib' -import { useUserPreferences } from '@context/UserPreferences' -import styles from './index.module.css' -import Web3Feedback from '@shared/Web3Feedback' -import { useCancelToken } from '@hooks/useCancelToken' -import { getComputeSettingsInitialValues } from './_constants' -import { computeSettingsValidationSchema } from './_validation' -import content from '../../../../content/pages/editComputeDataset.json' -import { getServiceByName } from '@utils/ddo' -import { setMinterToPublisher, setMinterToDispenser } from '@utils/dispenser' -import { transformComputeFormToServiceComputeOptions } from '@utils/compute' -import { useAbortController } from '@hooks/useAbortController' -import DebugEditCompute from './DebugEditCompute' -import { useAsset } from '@context/Asset' -import EditFeedback from './EditFeedback' -import { setNftMetadata } from '@utils/nft' -import { ComputeEditForm } from './_types' -import { useAccount, useSigner } from 'wagmi' - -export default function EditComputeDataset({ - asset -}: { - asset: AssetExtended -}): ReactElement { - const { debug } = useUserPreferences() - const { address: accountId } = useAccount() - const { data: signer } = useSigner() - const { fetchAsset, isAssetNetwork } = useAsset() - - const [success, setSuccess] = useState() - const [error, setError] = useState() - const newAbortController = useAbortController() - const newCancelToken = useCancelToken() - const hasFeedback = error || success - - async function handleSubmit(values: ComputeEditForm, resetForm: () => void) { - try { - if ( - asset?.accessDetails?.type === 'free' && - asset?.accessDetails?.isPurchasable - ) { - const tx = await setMinterToPublisher( - signer, - asset?.accessDetails?.datatoken?.address, - accountId, - setError - ) - if (!tx) return - } - const newComputeSettings: ServiceComputeOptions = - await transformComputeFormToServiceComputeOptions( - values, - asset.services[0].compute, - asset.chainId, - newCancelToken() - ) - - LoggerInstance.log( - '[edit compute settings] newComputeSettings', - newComputeSettings - ) - - const updatedService: Service = { - ...asset.services[0], - compute: newComputeSettings - } - - LoggerInstance.log( - '[edit compute settings] updatedService', - updatedService - ) - - const updatedAsset: Asset = { - ...asset, - services: [updatedService] - } - - const setMetadataTx = await setNftMetadata( - updatedAsset, - accountId, - signer, - newAbortController() - ) - - LoggerInstance.log('[edit] setMetadata result', setMetadataTx) - - if (!setMetadataTx) { - setError(content.form.error) - LoggerInstance.error(content.form.error) - return - } else { - if (asset.accessDetails.type === 'free') { - const tx = await setMinterToDispenser( - signer, - asset?.accessDetails?.datatoken?.address, - accountId, - setError - ) - if (!tx) return - } - } - // Edit succeeded - setSuccess(content.form.success) - resetForm() - } catch (error) { - LoggerInstance.error(error.message) - setError(error.message) - } - } - - return ( - { - // move user's focus to top of screen - window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }) - // kick off editing - await handleSubmit(values, resetForm) - }} - enableReinitialize - > - {({ values, isSubmitting }) => - isSubmitting || hasFeedback ? ( - { - await fetchAsset() - }, - to: `/asset/${asset.id}` - }} - /> - ) : ( - <> - - - {debug === true && ( -
- -
- )} - - ) - } -
- ) -} diff --git a/src/components/Asset/Edit/EditMetadata.tsx b/src/components/Asset/Edit/EditMetadata.tsx index f93fe8cd21..1dcdccfd1c 100644 --- a/src/components/Asset/Edit/EditMetadata.tsx +++ b/src/components/Asset/Edit/EditMetadata.tsx @@ -46,7 +46,6 @@ export default function Edit({ const [success, setSuccess] = useState() const [paymentCollector, setPaymentCollector] = useState() const [error, setError] = useState() - const isComputeType = asset?.services[0]?.type === 'compute' const hasFeedback = error || success useEffect(() => { @@ -235,7 +234,6 @@ export default function Edit({ = useFormikContext() - const newCancelToken = useCancelToken() - - const [allAlgorithms, setAllAlgorithms] = useState() - - const getAlgorithmList = useCallback( - async ( - publisherTrustedAlgorithms: PublisherTrustedAlgorithm[] - ): Promise => { - const baseParams = { - chainIds: [asset.chainId], - sort: { sortBy: SortTermOptions.Created }, - filters: [getFilterTerm('metadata.type', 'algorithm')] - } as BaseQueryParams - - const query = generateBaseQuery(baseParams) - const queryResult = await queryMetadata(query, newCancelToken()) - const datasetComputeService = getServiceByName(asset, 'compute') - const algorithmSelectionList = await transformAssetToAssetSelection( - datasetComputeService?.serviceEndpoint, - queryResult?.results, - publisherTrustedAlgorithms - ) - return algorithmSelectionList - }, - [asset, newCancelToken] - ) - - useEffect(() => { - if (!asset) return - - const { publisherTrustedAlgorithms } = getServiceByName( - asset, - 'compute' - ).compute - - getAlgorithmList(publisherTrustedAlgorithms).then((algorithms) => { - setAllAlgorithms(algorithms) - }) - }, [asset, getAlgorithmList]) - - return ( -
-
-

{content.form.title}

-

- {content.form.description} -

-
- - - - - - - - ) -} diff --git a/src/components/Asset/Edit/FormEditMetadata.tsx b/src/components/Asset/Edit/FormEditMetadata.tsx index 97cc52b51b..29e258787b 100644 --- a/src/components/Asset/Edit/FormEditMetadata.tsx +++ b/src/components/Asset/Edit/FormEditMetadata.tsx @@ -28,7 +28,7 @@ export default function FormEditMetadata({ }: { data: FormFieldContent[] showPrice: boolean - isComputeDataset: boolean + isComputeDataset?: boolean }): ReactElement { const { asset } = useAsset() const { values, setFieldValue } = useFormikContext() diff --git a/src/components/Asset/Edit/_constants.ts b/src/components/Asset/Edit/_constants.ts index 3a8d7b20d0..12f09b95ce 100644 --- a/src/components/Asset/Edit/_constants.ts +++ b/src/components/Asset/Edit/_constants.ts @@ -1,6 +1,6 @@ -import { Metadata, Service, ServiceComputeOptions } from '@oceanprotocol/lib' +import { Metadata, Service } from '@oceanprotocol/lib' import { parseConsumerParameters, secondsToString } from '@utils/ddo' -import { ComputeEditForm, MetadataEditForm } from './_types' +import { MetadataEditForm } from './_types' export function getInitialValues( metadata: Metadata, @@ -30,19 +30,3 @@ export function getInitialValues( } } } - -export function getComputeSettingsInitialValues({ - publisherTrustedAlgorithms, - publisherTrustedAlgorithmPublishers -}: ServiceComputeOptions): ComputeEditForm { - const allowAllPublishedAlgorithms = publisherTrustedAlgorithms === null - const publisherTrustedAlgorithmsForForm = allowAllPublishedAlgorithms - ? null - : publisherTrustedAlgorithms.map((algo) => algo.did) - - return { - allowAllPublishedAlgorithms, - publisherTrustedAlgorithms: publisherTrustedAlgorithmsForForm, - publisherTrustedAlgorithmPublishers - } -} diff --git a/src/components/Asset/Edit/_types.ts b/src/components/Asset/Edit/_types.ts index b8c6171bc2..584d793cec 100644 --- a/src/components/Asset/Edit/_types.ts +++ b/src/components/Asset/Edit/_types.ts @@ -18,9 +18,3 @@ export interface MetadataEditForm { consumerParameters?: FormConsumerParameter[] } } - -export interface ComputeEditForm { - allowAllPublishedAlgorithms: boolean - publisherTrustedAlgorithms: string[] - publisherTrustedAlgorithmPublishers: string[] -} diff --git a/src/components/Asset/Edit/_validation.ts b/src/components/Asset/Edit/_validation.ts index af8093f3cf..98f3483830 100644 --- a/src/components/Asset/Edit/_validation.ts +++ b/src/components/Asset/Edit/_validation.ts @@ -69,9 +69,3 @@ export const validationSchema = Yup.object().shape({ }) }) }) - -export const computeSettingsValidationSchema = Yup.object().shape({ - allowAllPublishedAlgorithms: Yup.boolean().nullable(), - publisherTrustedAlgorithms: Yup.array().nullable(), - publisherTrustedAlgorithmPublishers: Yup.array().nullable() -}) diff --git a/src/components/Asset/Edit/index.tsx b/src/components/Asset/Edit/index.tsx index 2357c03754..2c945ab840 100644 --- a/src/components/Asset/Edit/index.tsx +++ b/src/components/Asset/Edit/index.tsx @@ -3,7 +3,6 @@ import { useAsset } from '@context/Asset' import styles from './index.module.css' import Tabs from '@shared/atoms/Tabs' import EditMetadata from './EditMetadata' -import EditComputeDataset from './EditComputeDataset' import Page from '@shared/Page' import Loader from '@shared/atoms/Loader' import Alert from '@shared/atoms/Alert' @@ -12,7 +11,6 @@ import Container from '@shared/atoms/Container' export default function Edit({ uri }: { uri: string }): ReactElement { const { asset, error, isInPurgatory, title, isOwner } = useAsset() - const [isCompute, setIsCompute] = useState(false) const [pageTitle, setPageTitle] = useState('') useEffect(() => { @@ -25,22 +23,13 @@ export default function Edit({ uri }: { uri: string }): ReactElement { : `Edit ${title}` setPageTitle(pageTitle) - setIsCompute(asset?.services[0]?.type === 'compute') }, [asset, isInPurgatory, title, isOwner]) const tabs = [ { title: 'Edit Metadata', content: - }, - ...[ - isCompute && asset?.metadata.type !== 'algorithm' - ? { - title: 'Edit Compute Settings', - content: - } - : undefined - ] + } ].filter((tab) => tab !== undefined) return ( diff --git a/src/components/Profile/History/ComputeJobs/Details.module.css b/src/components/Profile/History/ComputeJobs/Details.module.css deleted file mode 100644 index f6254c7570..0000000000 --- a/src/components/Profile/History/ComputeJobs/Details.module.css +++ /dev/null @@ -1,86 +0,0 @@ -.main { - margin-bottom: var(--spacer); -} - -.main > div:first-child { - margin-bottom: calc(var(--spacer) / 2); -} - -.asset { - composes: box from '@shared/atoms/Box.module.css'; - box-shadow: none; - padding: calc(var(--spacer) / 2); - margin-bottom: calc(var(--spacer) / 2); -} - -.asset + .asset { - margin-left: var(--spacer); - border-top-left-radius: 0; - border-bottom-left-radius: 0; - position: relative; - overflow: visible; -} - -.asset + .asset:before { - content: ''; - display: block; - position: absolute; - left: -1px; - top: -1.15rem; - bottom: 3px; - width: 1px; - background-color: var(--border-color); -} - -.asset p { - margin: 0; -} - -.asset code { - padding: 0; -} - -.assetTitle { - margin-bottom: 0; - font-size: var(--font-size-base); - color: var(--font-color-text); -} - -.assetLink { - display: inline-block; - margin-left: calc(var(--spacer) / 8); -} - -.assetLink svg { - margin: 0; - fill: var(--color-primary); - width: 0.6em; - height: 0.6em; -} - -.assetMeta, -.assetMeta code { - color: var(--color-secondary); - font-size: var(--font-size-small); - overflow: hidden; - width: 100%; - flex: 6; - text-overflow: ellipsis; - white-space: nowrap; -} - -.assetMeta span { - flex: 1; -} - -.assetMeta { - display: flex; - flex-wrap: wrap; -} - -.meta { - display: grid; - gap: var(--spacer); - grid-template-columns: 1fr 1fr; - margin-top: calc(var(--spacer) * 1.5); -} diff --git a/src/components/Profile/History/ComputeJobs/Details.tsx b/src/components/Profile/History/ComputeJobs/Details.tsx deleted file mode 100644 index d331493022..0000000000 --- a/src/components/Profile/History/ComputeJobs/Details.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import React, { ReactElement, useEffect, useState } from 'react' -import Time from '@shared/atoms/Time' -import Button from '@shared/atoms/Button' -import Modal from '@shared/atoms/Modal' -import External from '@images/external.svg' -import { getAsset } from '@utils/aquarius' -import Results from './Results' -import styles from './Details.module.css' -import { useCancelToken } from '@hooks/useCancelToken' -import MetaItem from '../../../Asset/AssetContent/MetaItem' -import { useMarketMetadata } from '@context/MarketMetadata' - -function Asset({ - title, - symbol, - did -}: { - title: string - symbol: string - did: string -}) { - return ( -
-

- {title}{' '} - - - -

-

- {`${symbol} | `} - {did} -

-
- ) -} - -function DetailsAssets({ job }: { job: ComputeJobMetaData }) { - const { appConfig } = useMarketMetadata() - const newCancelToken = useCancelToken() - - const [algoName, setAlgoName] = useState() - const [algoDtSymbol, setAlgoDtSymbol] = useState() - - useEffect(() => { - async function getAlgoMetadata() { - const ddo = await getAsset(job.algoDID, newCancelToken()) - setAlgoDtSymbol(ddo.datatokens[0].symbol) - setAlgoName(ddo?.metadata.name) - } - getAlgoMetadata() - }, [appConfig.metadataCacheUri, job.algoDID, newCancelToken]) - - return ( - <> - - - - ) -} - -export default function Details({ - job -}: { - job: ComputeJobMetaData -}): ReactElement { - const [isDialogOpen, setIsDialogOpen] = useState(false) - - return ( - <> - - setIsDialogOpen(false)} - > - - - -
- } - /> - {job.dateFinished && ( - } - /> - )} - {job.jobId}} /> -
-
- - ) -} diff --git a/src/components/Profile/History/ComputeJobs/Results.module.css b/src/components/Profile/History/ComputeJobs/Results.module.css deleted file mode 100644 index 563be31b75..0000000000 --- a/src/components/Profile/History/ComputeJobs/Results.module.css +++ /dev/null @@ -1,14 +0,0 @@ -.results { - composes: asset from './Details.module.css'; - border-bottom-left-radius: var(--border-radius) !important; -} - -.title { - font-size: var(--font-size-base); - color: var(--font-color-text); - margin-bottom: calc(var(--spacer) / 3); -} - -.help { - margin-top: calc(var(--spacer) / 3); -} diff --git a/src/components/Profile/History/ComputeJobs/Results.tsx b/src/components/Profile/History/ComputeJobs/Results.tsx deleted file mode 100644 index 750c0e8717..0000000000 --- a/src/components/Profile/History/ComputeJobs/Results.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { - ComputeResultType, - downloadFileBrowser, - getErrorMessage, - LoggerInstance, - Provider -} from '@oceanprotocol/lib' -import React, { ReactElement, useEffect, useState } from 'react' -import { ListItem } from '@shared/atoms/Lists' -import Button from '@shared/atoms/Button' -import styles from './Results.module.css' -import FormHelp from '@shared/FormInput/Help' -import content from '../../../../../content/pages/history.json' -import { useCancelToken } from '@hooks/useCancelToken' -import { getAsset } from '@utils/aquarius' -import { useAccount, useSigner } from 'wagmi' -import { toast } from 'react-toastify' - -export default function Results({ - job -}: { - job: ComputeJobMetaData -}): ReactElement { - const providerInstance = new Provider() - const { address: accountId } = useAccount() - const { data: signer } = useSigner() - - const [datasetProvider, setDatasetProvider] = useState() - const newCancelToken = useCancelToken() - - const isFinished = job.dateFinished !== null - - useEffect(() => { - async function getAssetMetadata() { - const ddo = await getAsset(job.inputDID[0], newCancelToken()) - setDatasetProvider(ddo.services[0].serviceEndpoint) - } - getAssetMetadata() - }, [job.inputDID, newCancelToken]) - - function getDownloadButtonValue(type: ComputeResultType): string { - let buttonName - switch (type) { - case 'output': - buttonName = 'results' - break - case 'algorithmLog': - buttonName = 'algorithm logs' - break - case 'configrationLog': - buttonName = 'configuration logs' - break - case 'publishLog': - buttonName = 'publish logs' - break - default: - buttonName = 'results' - break - } - return buttonName - } - - async function downloadResults(resultIndex: number) { - if (!accountId || !job) return - - try { - const jobResult = await providerInstance.getComputeResultUrl( - datasetProvider, - signer, - job.jobId, - resultIndex - ) - await downloadFileBrowser(jobResult) - } catch (error) { - const message = getErrorMessage(error.message) - LoggerInstance.error('[Provider Get c2d results url] Error:', message) - toast.error(message) - } - } - - return ( -
-

Results

- {isFinished ? ( -
    - {job.results && - Array.isArray(job.results) && - job.results.map((jobResult, i) => - jobResult.filename ? ( - - - - ) : ( - No results found. - ) - )} -
- ) : ( -

Waiting for results...

- )} - {content.compute.storage} -
- ) -} diff --git a/src/components/Profile/History/ComputeJobs/index.module.css b/src/components/Profile/History/ComputeJobs/index.module.css deleted file mode 100644 index 6bd78e0f57..0000000000 --- a/src/components/Profile/History/ComputeJobs/index.module.css +++ /dev/null @@ -1,26 +0,0 @@ -.status { - text-transform: uppercase; - color: var(--color-secondary); -} - -.computeTableContainer { - display: flex; - align-items: center; -} - -.refresh, -.refresh:first-child { - margin-bottom: calc(var(--spacer) / 2); - margin-left: auto; - margin-right: auto; - display: block; -} - -.refresh svg { - display: inline-block; - fill: currentColor; - width: 1em; - height: 1em; - margin-right: calc(var(--spacer) / 6); - margin-bottom: -0.1rem; -} diff --git a/src/components/Profile/History/ComputeJobs/index.tsx b/src/components/Profile/History/ComputeJobs/index.tsx deleted file mode 100644 index e6d760af1b..0000000000 --- a/src/components/Profile/History/ComputeJobs/index.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React, { ReactElement, useState } from 'react' -import Time from '@shared/atoms/Time' -import Table, { TableOceanColumn } from '@shared/atoms/Table' -import Button from '@shared/atoms/Button' -import Details from './Details' -import Refresh from '@images/refresh.svg' -import { useUserPreferences } from '@context/UserPreferences' -import NetworkName from '@shared/NetworkName' -import styles from './index.module.css' -import AssetListTitle from '@shared/AssetListTitle' -import { useAccount } from 'wagmi' - -export function Status({ children }: { children: string }): ReactElement { - return
{children}
-} - -const columns: TableOceanColumn[] = [ - { - name: 'Dataset', - selector: (row) => ( - - ) - }, - { - name: 'Network', - selector: (row) => - }, - { - name: 'Created', - selector: (row) =>