diff --git a/src/@utils/subgraph.ts b/src/@utils/subgraph.ts index c8ac601f9..00f7d16fb 100644 --- a/src/@utils/subgraph.ts +++ b/src/@utils/subgraph.ts @@ -2,23 +2,9 @@ import { gql, OperationResult, TypedDocumentNode, OperationContext } from 'urql' import { LoggerInstance } from '@oceanprotocol/lib' import { getUrqlClientInstance } from '@context/UrqlProvider' import { getOceanConfig } from './ocean' -import { AssetPreviousOrder } from '../@types/subgraph/AssetPreviousOrder' import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData' import { OpcFeesQuery as OpcFeesData } from '../@types/subgraph/OpcFeesQuery' - -const PreviousOrderQuery = gql` - query AssetPreviousOrder($id: String!, $account: String!) { - orders( - first: 1 - where: { datatoken: $id, payer: $account } - orderBy: createdTimestamp - orderDirection: desc - ) { - createdTimestamp - tx - } - } -` +import appConfig from '../../app.config' const UserTokenOrders = gql` query OrdersData($user: String!) { @@ -76,6 +62,11 @@ export function getSubgraphUri(chainId: number): string { export function getQueryContext(chainId: number): OperationContext { try { + if (!appConfig.chainIdsSupported.includes(chainId)) + throw Object.assign( + new Error('network not supported, query context cancelled') + ) + const queryContext: OperationContext = { url: `${getSubgraphUri( Number(chainId) diff --git a/src/components/Asset/AssetActions/ButtonBuy/index.tsx b/src/components/Asset/AssetActions/ButtonBuy/index.tsx index fac87fd64..520da859f 100644 --- a/src/components/Asset/AssetActions/ButtonBuy/index.tsx +++ b/src/components/Asset/AssetActions/ButtonBuy/index.tsx @@ -2,6 +2,8 @@ import React, { FormEvent, ReactElement } from 'react' import Button from '../../../@shared/atoms/Button' import styles from './index.module.css' import Loader from '../../../@shared/atoms/Loader' +import { useWeb3 } from '@context/Web3' +import Web3 from 'web3' export interface ButtonBuyProps { action: 'download' | 'compute' @@ -28,12 +30,11 @@ export interface ButtonBuyProps { priceType?: string algorithmPriceType?: string isAlgorithmConsumable?: boolean + isSupportedOceanNetwork?: boolean hasProviderFee?: boolean retry?: boolean } -// TODO: we need to take a look at these messages - function getConsumeHelpText( btSymbol: string, dtBalance: string, @@ -43,12 +44,14 @@ function getConsumeHelpText( assetType: string, isConsumable: boolean, isBalanceSufficient: boolean, - consumableFeedback: string + consumableFeedback: string, + isSupportedOceanNetwork: boolean, + web3: Web3 ) { const text = isConsumable === false ? consumableFeedback - : hasPreviousOrder + : hasPreviousOrder && web3 && isSupportedOceanNetwork ? `You bought this ${assetType} already allowing you to use it without paying again.` : hasDatatoken ? `You own ${dtBalance} ${dtSymbol} allowing you to use this dataset by spending 1 ${dtSymbol}, but without paying ${btSymbol} again.` @@ -58,6 +61,35 @@ function getConsumeHelpText( return text } +function getAlgoHelpText( + dtSymbolSelectedComputeAsset: string, + dtBalanceSelectedComputeAsset: string, + isConsumable: boolean, + isAlgorithmConsumable: boolean, + hasPreviousOrderSelectedComputeAsset: boolean, + selectedComputeAssetType: string, + hasDatatokenSelectedComputeAsset: boolean, + isBalanceSufficient: boolean, + isSupportedOceanNetwork: boolean, + web3: Web3 +) { + const text = + (!dtSymbolSelectedComputeAsset && !dtBalanceSelectedComputeAsset) || + isConsumable === false || + isAlgorithmConsumable === false + ? '' + : hasPreviousOrderSelectedComputeAsset && web3 && isSupportedOceanNetwork + ? `You already bought the selected ${selectedComputeAssetType}, allowing you to use it without paying again.` + : hasDatatokenSelectedComputeAsset + ? `You own ${dtBalanceSelectedComputeAsset} ${dtSymbolSelectedComputeAsset} allowing you to use the selected ${selectedComputeAssetType} by spending 1 ${dtSymbolSelectedComputeAsset}, but without paying OCEAN again.` + : web3 && !isSupportedOceanNetwork + ? `Connect to the correct network to interact with this asset.` + : isBalanceSufficient === false + ? '' + : `Additionally, you will buy 1 ${dtSymbolSelectedComputeAsset} for the ${selectedComputeAssetType} and spend it back to its publisher and pool.` + return text +} + function getComputeAssetHelpText( hasPreviousOrder: boolean, hasDatatoken: boolean, @@ -74,6 +106,8 @@ function getComputeAssetHelpText( dtBalanceSelectedComputeAsset?: string, selectedComputeAssetType?: string, isAlgorithmConsumable?: boolean, + isSupportedOceanNetwork?: boolean, + web3?: Web3, hasProviderFee?: boolean ) { const computeAssetHelpText = getConsumeHelpText( @@ -85,21 +119,24 @@ function getComputeAssetHelpText( assetType, isConsumable, isBalanceSufficient, - consumableFeedback + consumableFeedback, + isSupportedOceanNetwork, + web3 + ) + + const computeAlgoHelpText = getAlgoHelpText( + dtSymbolSelectedComputeAsset, + dtBalanceSelectedComputeAsset, + isConsumable, + isAlgorithmConsumable, + hasPreviousOrderSelectedComputeAsset, + selectedComputeAssetType, + hasDatatokenSelectedComputeAsset, + isBalanceSufficient, + isSupportedOceanNetwork, + web3 ) - const computeAlgoHelpText = - (!dtSymbolSelectedComputeAsset && !dtBalanceSelectedComputeAsset) || - isConsumable === false || - isAlgorithmConsumable === false - ? '' - : hasPreviousOrderSelectedComputeAsset - ? `You already bought the selected ${selectedComputeAssetType}, allowing you to use it without paying again.` - : hasDatatokenSelectedComputeAsset - ? `You own ${dtBalanceSelectedComputeAsset} ${dtSymbolSelectedComputeAsset} allowing you to use the selected ${selectedComputeAssetType} by spending 1 ${dtSymbolSelectedComputeAsset}, but without paying ${btSymbol} again.` - : isBalanceSufficient === false - ? '' - : `Additionally, you will buy 1 ${dtSymbolSelectedComputeAsset} for the ${selectedComputeAssetType} and spend it back to its publisher.` const providerFeeHelpText = hasProviderFee ? 'In order to start the job you also need to pay the fees for renting the c2d resources.' : 'C2D resources required to start the job are available, no payment required for those fees.' @@ -133,8 +170,10 @@ export default function ButtonBuy({ algorithmPriceType, isAlgorithmConsumable, hasProviderFee, - retry + retry, + isSupportedOceanNetwork }: ButtonBuyProps): ReactElement { + const { web3 } = useWeb3() const buttonText = retry ? 'Retry' : action === 'download' @@ -177,7 +216,9 @@ export default function ButtonBuy({ assetType, isConsumable, isBalanceSufficient, - consumableFeedback + consumableFeedback, + isSupportedOceanNetwork, + web3 ) : getComputeAssetHelpText( hasPreviousOrder, @@ -195,6 +236,8 @@ export default function ButtonBuy({ dtBalanceSelectedComputeAsset, selectedComputeAssetType, isAlgorithmConsumable, + isSupportedOceanNetwork, + web3, hasProviderFee )} diff --git a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx index 18b37b2ba..b6dd83451 100644 --- a/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx +++ b/src/components/Asset/AssetActions/Compute/FormComputeDataset.tsx @@ -9,7 +9,7 @@ import PriceOutput from './PriceOutput' import { useAsset } from '@context/Asset' import { useWeb3 } from '@context/Web3' import content from '../../../../../content/pages/startComputeDataset.json' -import { Asset } from '@oceanprotocol/lib' +import { Asset, ZERO_ADDRESS } from '@oceanprotocol/lib' import { getAccessDetails } from '@utils/accessDetailsAndPricing' import { useMarketMetadata } from '@context/MarketMetadata' import Alert from '@shared/atoms/Alert' @@ -75,7 +75,7 @@ export default function FormStartCompute({ retry: boolean }): ReactElement { const { siteContent } = useMarketMetadata() - const { accountId, balance } = useWeb3() + const { accountId, balance, isSupportedOceanNetwork } = useWeb3() const { isValid, values }: FormikContextType<{ algorithm: string }> = useFormikContext() const { asset, isAssetNetwork } = useAsset() @@ -98,7 +98,7 @@ export default function FormStartCompute({ } useEffect(() => { - if (!values.algorithm || !accountId || !isConsumable) return + if (!values.algorithm || !isConsumable) return async function fetchAlgorithmAssetExtended() { const algorithmAsset = getAlgorithmAsset(values.algorithm) @@ -106,7 +106,7 @@ export default function FormStartCompute({ algorithmAsset.chainId, algorithmAsset.services[0].datatokenAddress, algorithmAsset.services[0].timeout, - accountId + accountId || ZERO_ADDRESS // if user is not connected, use ZERO_ADDRESS as accountId ) const extendedAlgoAsset: AssetExtended = { ...algorithmAsset, @@ -198,15 +198,20 @@ export default function FormStartCompute({ } setTotalPrices(totalPrices) }, [ - asset?.accessDetails, - selectedAlgorithmAsset?.accessDetails, + asset, hasPreviousOrder, hasDatatoken, hasPreviousOrderSelectedComputeAsset, hasDatatokenSelectedComputeAsset, datasetOrderPriceAndFees, algoOrderPriceAndFees, - providerFeeAmount + providerFeeAmount, + isAssetNetwork, + selectedAlgorithmAsset?.accessDetails, + datasetOrderPrice, + algoOrderPrice, + algorithmSymbol, + datasetSymbol ]) useEffect(() => { @@ -216,12 +221,13 @@ export default function FormStartCompute({ setIsBalanceSufficient(false) return } + // if one comparison of baseTokenBalance and token price comparison is false then the state will be false setIsBalanceSufficient( - isBalanceSufficient && compareAsBN(baseTokenBalance, `${price.value}`) + baseTokenBalance && compareAsBN(baseTokenBalance, `${price.value}`) ) }) - }, [balance, dtBalance, datasetSymbol, algorithmSymbol]) + }, [balance, dtBalance, datasetSymbol, algorithmSymbol, totalPrices]) return (
@@ -295,6 +301,7 @@ export default function FormStartCompute({ isAlgorithmConsumable={ selectedAlgorithmAsset?.accessDetails?.isPurchasable } + isSupportedOceanNetwork={isSupportedOceanNetwork} hasProviderFee={providerFeeAmount && providerFeeAmount !== '0'} retry={retry} /> diff --git a/src/components/Asset/AssetActions/Compute/PriceOutput.tsx b/src/components/Asset/AssetActions/Compute/PriceOutput.tsx index d2e31ffc6..39df72837 100644 --- a/src/components/Asset/AssetActions/Compute/PriceOutput.tsx +++ b/src/components/Asset/AssetActions/Compute/PriceOutput.tsx @@ -5,6 +5,7 @@ import Tooltip from '@shared/atoms/Tooltip' import styles from './PriceOutput.module.css' import { MAX_DECIMALS } from '@utils/constants' import Decimal from 'decimal.js' +import { useWeb3 } from '@context/Web3' interface PriceOutputProps { hasPreviousOrder: boolean @@ -40,13 +41,21 @@ function Row({ sign?: string type?: string }) { + const { isSupportedOceanNetwork } = useWeb3() + return (
{sign}
{type}
= 1 @@ -134,9 +137,10 @@ export default function Compute({ const initializedProvider = await initializeProviderForCompute( asset, selectedAlgorithmAsset, - accountId, + accountId || ZERO_ADDRESS, // if the user is not connected, we use ZERO_ADDRESS as accountId computeEnv ) + if ( !initializedProvider || !initializedProvider?.datasets || @@ -145,13 +149,17 @@ export default function Compute({ throw new Error(`Error initializing provider for the compute job!`) setInitializedProviderResponse(initializedProvider) - setProviderFeeAmount( - await unitsToAmount( - web3, - initializedProvider?.datasets?.[0]?.providerFee?.providerFeeToken, - initializedProvider?.datasets?.[0]?.providerFee?.providerFeeAmount - ) + + const feeAmount = await unitsToAmount( + !isSupportedOceanNetwork || !isAssetNetwork + ? await getDummyWeb3(asset?.chainId) + : web3, + initializedProvider?.datasets?.[0]?.providerFee?.providerFeeToken, + initializedProvider?.datasets?.[0]?.providerFee?.providerFeeAmount ) + + setProviderFeeAmount(feeAmount) + const computeDuration = ( parseInt(initializedProvider?.datasets?.[0]?.providerFee?.validUntil) - Math.floor(Date.now() / 1000) @@ -217,7 +225,7 @@ export default function Compute({ }, [asset?.accessDetails, accountId, isUnsupportedPricing]) useEffect(() => { - if (!selectedAlgorithmAsset?.accessDetails || !accountId) return + if (!selectedAlgorithmAsset?.accessDetails) return setIsRequestingAlgoOrderPrice(true) setIsConsumableAlgorithmPrice( @@ -306,6 +314,7 @@ export default function Compute({ documentId: selectedAlgorithmAsset.id, serviceId: selectedAlgorithmAsset.services[0].id } + const allowed = await isOrderable( asset, computeService.id, @@ -450,14 +459,12 @@ export default function Compute({ setSelectedAlgorithm={setSelectedAlgorithmAsset} isLoading={isOrdering || isRequestingAlgoOrderPrice} isComputeButtonDisabled={isComputeButtonDisabled} - hasPreviousOrder={validOrderTx !== undefined} + hasPreviousOrder={!!validOrderTx} hasDatatoken={hasDatatoken} dtBalance={dtBalance} assetType={asset?.metadata.type} assetTimeout={secondsToString(asset?.services[0].timeout)} - hasPreviousOrderSelectedComputeAsset={ - validAlgorithmOrderTx !== undefined - } + hasPreviousOrderSelectedComputeAsset={!!validAlgorithmOrderTx} hasDatatokenSelectedComputeAsset={hasAlgoAssetDatatoken} datasetSymbol={asset?.accessDetails?.baseToken?.symbol || 'OCEAN'} algorithmSymbol={ diff --git a/src/components/Asset/AssetActions/Download.tsx b/src/components/Asset/AssetActions/Download.tsx index 1bcbb360b..abaa35559 100644 --- a/src/components/Asset/AssetActions/Download.tsx +++ b/src/components/Asset/AssetActions/Download.tsx @@ -33,7 +33,7 @@ export default function Download({ fileIsLoading?: boolean consumableFeedback?: string }): ReactElement { - const { accountId, web3 } = useWeb3() + const { accountId, web3, isSupportedOceanNetwork } = useWeb3() const { getOpcFeeForToken } = useMarketMetadata() const { isInPurgatory, isAssetNetwork } = useAsset() const isMounted = useIsMounted() @@ -184,6 +184,7 @@ export default function Download({ isBalanceSufficient={isBalanceSufficient} consumableFeedback={consumableFeedback} retry={retry} + isSupportedOceanNetwork={isSupportedOceanNetwork} /> )