Refactor Asset context provider (#1055)

* refactor Asset context provider

* use useIsMounted hook

* typings and effect tweaks

* use chainId

* effect tweak
This commit is contained in:
Matthias Kretschmann 2022-02-03 14:31:43 +00:00 committed by GitHub
parent 57be62a6b1
commit 8074a6143c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 216 additions and 235 deletions

View File

@ -7,7 +7,7 @@ import React, {
useCallback,
ReactNode
} from 'react'
import { Asset, Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
import { Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
import { CancelToken } from 'axios'
import { retrieveAsset } from '@utils/aquarius'
import { useWeb3 } from './Web3'
@ -16,20 +16,20 @@ import { useCancelToken } from '@hooks/useCancelToken'
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
import { AssetExtended } from 'src/@types/AssetExtended'
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
import { useIsMounted } from '@hooks/useIsMounted'
interface AssetProviderValue {
isInPurgatory: boolean
purgatoryData: Purgatory
assetExtended: AssetExtended
asset: AssetExtended
title: string
owner: string
accessDetails: AccessDetails
error?: string
refreshInterval: number
isAssetNetwork: boolean
oceanConfig: Config
loading: boolean
refreshAsset: (token?: CancelToken) => Promise<void>
fetchAsset: (token?: CancelToken) => Promise<void>
}
const AssetContext = createContext({} as AssetProviderValue)
@ -45,12 +45,11 @@ function AssetProvider({
}): ReactElement {
const { appConfig } = useSiteMetadata()
const { networkId, accountId } = useWeb3()
const { chainId, accountId } = useWeb3()
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
const [assetExtended, setAssetExtended] = useState<Asset>()
const [asset, setAsset] = useState<AssetExtended>()
const [title, setTitle] = useState<string>()
const [accessDetails, setConsumeDetails] = useState<AccessDetails>()
const [owner, setOwner] = useState<string>()
const [error, setError] = useState<string>()
const [loading, setLoading] = useState(false)
@ -58,126 +57,121 @@ function AssetProvider({
const [oceanConfig, setOceanConfig] = useState<Config>()
const newCancelToken = useCancelToken()
const isMounted = useIsMounted()
// -----------------------------------
// Helper: Get and set asset based on passed DID
// -----------------------------------
const fetchAsset = useCallback(
async (token?: CancelToken) => {
LoggerInstance.log('[asset] Init asset, get assetExtended')
setLoading(true)
const assetExtended = await retrieveAsset(did, token)
if (!did) return
if (!assetExtended) {
LoggerInstance.log('[asset] Fetching asset...')
setLoading(true)
const asset = await retrieveAsset(did, token)
if (!asset) {
setError(
`[asset] The assetExtended for ${did} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
`[asset] The asset for ${did} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
)
LoggerInstance.error(`[asset] Failed getting asset for ${did}`, asset)
} else {
setError(undefined)
}
setAsset((prevState) => ({
...prevState,
...asset
}))
setTitle(asset.metadata.name)
setOwner(asset.nft.owner)
setIsInPurgatory((asset.purgatory?.state as unknown as string) === 'true')
setPurgatoryData(asset.purgatory)
LoggerInstance.log('[asset] Got asset', asset)
setLoading(false)
return assetExtended
},
[did]
)
const refreshAsset = async (token?: CancelToken) => {
setLoading(true)
const assetExtended = await fetchAsset(token)
LoggerInstance.debug('[asset] Got assetExtended', assetExtended)
setAssetExtended(assetExtended)
setLoading(false)
}
// -----------------------------------
// Helper: Get and set asset access details
// -----------------------------------
const fetchAccessDetails = useCallback(async (): Promise<void> => {
if (!asset?.chainId || !asset?.services) return
const accessDetails = await getAccessDetails(
asset.chainId,
asset.services[0].datatokenAddress,
asset.services[0].timeout,
accountId
)
setAsset((prevState) => ({
...prevState,
accessDetails
}))
LoggerInstance.log(`[asset] Got access details for ${did}`, accessDetails)
}, [asset?.chainId, asset?.services, accountId, did])
// -----------------------------------
// Get and set assetExtended based on passed DID
// 1. Get and set asset based on passed DID
// -----------------------------------
useEffect(() => {
if (!did || !appConfig.metadataCacheUri) return
if (!isMounted || !appConfig?.metadataCacheUri) return
let isMounted = true
async function init() {
const assetExtended = await fetchAsset(newCancelToken())
if (!isMounted || !assetExtended) return
LoggerInstance.debug('[asset] Got assetExtended', assetExtended)
setAssetExtended(assetExtended)
setTitle(assetExtended.metadata.name)
setOwner(assetExtended.nft.owner)
setIsInPurgatory(
(assetExtended.purgatory?.state as unknown as string) === 'true'
)
setPurgatoryData(assetExtended.purgatory)
}
init()
return () => {
isMounted = false
}
}, [did, appConfig.metadataCacheUri, fetchAsset, newCancelToken])
fetchAsset(newCancelToken())
}, [appConfig?.metadataCacheUri, fetchAsset, newCancelToken, isMounted])
// -----------------------------------
// Attach price to asset
// 2. Attach access details to asset
// -----------------------------------
const initPrice = useCallback(
async (assetExtended: AssetExtended, accountId: string): Promise<void> => {
if (!assetExtended) return
const accessDetails = await getAccessDetails(
assetExtended.chainId,
assetExtended.services[0].datatokenAddress,
assetExtended.services[0].timeout,
accountId
)
assetExtended.accessDetails = accessDetails
setConsumeDetails({ ...accessDetails })
setAssetExtended(assetExtended)
},
[]
)
useEffect(() => {
if (!assetExtended) return
initPrice(assetExtended, accountId)
}, [accountId, assetExtended, initPrice])
if (!isMounted) return
fetchAccessDetails()
}, [accountId, fetchAccessDetails, isMounted])
// -----------------------------------
// Check user network against asset network
// -----------------------------------
useEffect(() => {
if (!networkId || !assetExtended) return
if (!chainId || !asset?.chainId) return
const isAssetNetwork = networkId === assetExtended?.chainId
const isAssetNetwork = chainId === asset?.chainId
setIsAssetNetwork(isAssetNetwork)
}, [networkId, assetExtended])
}, [chainId, asset?.chainId])
// -----------------------------------
// Load ocean config based on asset network
// -----------------------------------
useEffect(() => {
if (!assetExtended?.chainId) return
if (!asset?.chainId) return
const oceanConfig = {
...getOceanConfig(assetExtended?.chainId),
...getOceanConfig(asset?.chainId),
// add local dev values
...(assetExtended?.chainId === 8996 && {
...(asset?.chainId === 8996 && {
...getDevelopmentConfig()
})
}
setOceanConfig(oceanConfig)
}, [assetExtended])
}, [asset?.chainId])
return (
<AssetContext.Provider
value={
{
assetExtended,
asset,
did,
title,
owner,
accessDetails,
error,
isInPurgatory,
purgatoryData,
refreshInterval,
loading,
refreshAsset,
fetchAsset,
isAssetNetwork,
oceanConfig
} as AssetProviderValue

View File

@ -209,9 +209,9 @@ function getAccessDetailsFromTokenPrice(
/**
* returns various consume details for the desired datatoken
* @param chain chain on witch the dt is preset
* @param chain chain on which the datatoken is preset
* @param datatokenAddress address of the datatoken
* @param timeout timeout of the service , only needed if you want order details like owned and validOrderId
* @param timeout timeout of the service, only needed if you want order details like owned and validOrderId
* @param account account that wants to consume, only needed if you want order details like owned and validOrderId
* @returns AccessDetails
*/
@ -221,20 +221,21 @@ export async function getAccessDetails(
timeout?: number,
account = ''
): Promise<AccessDetails> {
let accessDetails = {} as AccessDetails
const queryContext = getQueryContext(Number(chain))
const tokenQueryResult: OperationResult<TokenPriceQuery, any> =
await fetchData(
TokenPriceQuery,
{
datatokenId: datatokenAddress.toLowerCase(),
account: account.toLowerCase()
},
queryContext
)
const tokenQueryResult: OperationResult<
TokenPriceQuery,
{ datatokenId: string; account: string }
> = await fetchData(
TokenPriceQuery,
{
datatokenId: datatokenAddress.toLowerCase(),
account: account.toLowerCase()
},
queryContext
)
const tokenPrice: TokenPrice = tokenQueryResult.data.token
accessDetails = getAccessDetailsFromTokenPrice(tokenPrice, timeout)
const accessDetails = getAccessDetailsFromTokenPrice(tokenPrice, timeout)
return accessDetails
}
@ -243,7 +244,7 @@ export async function getAccessDetailsForAssets(
account = ''
): Promise<AssetExtended[]> {
const assetsExtended: AssetExtended[] = assets
const chainAssetLists: any = {}
const chainAssetLists: { [key: number]: string[] } = {}
for (const asset of assets) {
// harcoded until we have chainId on assets
@ -261,15 +262,17 @@ export async function getAccessDetailsForAssets(
for (const chainKey in chainAssetLists) {
const queryContext = getQueryContext(Number(chainKey))
const tokenQueryResult: OperationResult<TokensPriceQuery, any> =
await fetchData(
TokensPriceQuery,
{
datatokenIds: chainAssetLists[chainKey],
account: account.toLowerCase()
},
queryContext
)
const tokenQueryResult: OperationResult<
TokensPriceQuery,
{ datatokenId: string; account: string }
> = await fetchData(
TokensPriceQuery,
{
datatokenIds: chainAssetLists[chainKey],
account: account.toLowerCase()
},
queryContext
)
tokenQueryResult.data?.tokens.forEach((token) => {
const accessDetails = getAccessDetailsFromTokenPrice(token)
const currentAsset = assetsExtended.find(

View File

@ -80,7 +80,7 @@ export default function AssetList({
{assetsWithPrices.length > 0 ? (
assetsWithPrices.map((assetWithPrice) => (
<AssetTeaser
assetExtended={assetWithPrice}
asset={assetWithPrice}
key={assetWithPrice.id}
noPublisher={noPublisher}
/>

View File

@ -11,22 +11,22 @@ import { getServiceByName } from '@utils/ddo'
import { AssetExtended } from 'src/@types/AssetExtended'
declare type AssetTeaserProps = {
assetExtended: AssetExtended
asset: AssetExtended
noPublisher?: boolean
}
export default function AssetTeaser({
assetExtended,
asset,
noPublisher
}: AssetTeaserProps): ReactElement {
const { name, type, description } = assetExtended.metadata
const { datatokens } = assetExtended
const isCompute = Boolean(getServiceByName(assetExtended, 'compute'))
const { name, type, description } = asset.metadata
const { datatokens } = asset
const isCompute = Boolean(getServiceByName(asset, 'compute'))
const accessType = isCompute ? 'compute' : 'access'
const { owner } = assetExtended.nft
const { owner } = asset.nft
return (
<article className={`${styles.teaser} ${styles[type]}`}>
<Link href={`/asset/${assetExtended.id}`}>
<Link href={`/asset/${asset.id}`}>
<a className={styles.link}>
<header className={styles.header}>
<div className={styles.symbol}>{datatokens[0]?.symbol}</div>
@ -51,11 +51,8 @@ export default function AssetTeaser({
</div>
<footer className={styles.foot}>
<Price accessDetails={assetExtended.accessDetails} small />
<NetworkName
networkId={assetExtended.chainId}
className={styles.network}
/>
<Price accessDetails={asset.accessDetails} small />
<NetworkName networkId={asset.chainId} className={styles.network} />
</footer>
</a>
</Link>

View File

@ -18,12 +18,12 @@ export default function TokenApproval({
tokenAddress: string
tokenSymbol: string
}): ReactElement {
const { accessDetails, isAssetNetwork } = useAsset()
const { asset, isAssetNetwork } = useAsset()
const [tokenApproved, setTokenApproved] = useState(false)
const [loading, setLoading] = useState(false)
const { web3, accountId } = useWeb3()
const spender = accessDetails?.addressOrId
const spender = asset?.accessDetails?.addressOrId
const checkTokenApproval = useCallback(async () => {
if (!web3 || !tokenAddress || !spender || !isAssetNetwork || !amount) return

View File

@ -11,15 +11,13 @@ import { useAsset } from '@context/Asset'
export default function WalletNetworkSwitcher(): ReactElement {
const { networkId, web3Provider } = useWeb3()
const { assetExtended } = useAsset()
const { asset } = useAsset()
const { networksList } = useNetworkMetadata()
const ddoNetworkData = getNetworkDataById(networksList, assetExtended.chainId)
const ddoNetworkData = getNetworkDataById(networksList, asset.chainId)
const walletNetworkData = getNetworkDataById(networksList, networkId)
const ddoNetworkName = (
<strong>
{getNetworkDisplayName(ddoNetworkData, assetExtended.chainId)}
</strong>
<strong>{getNetworkDisplayName(ddoNetworkData, asset.chainId)}</strong>
)
const walletNetworkName = (
<strong>{getNetworkDisplayName(walletNetworkData, networkId)}</strong>
@ -27,7 +25,7 @@ export default function WalletNetworkSwitcher(): ReactElement {
async function switchWalletNetwork() {
const networkNode = await networksList.find(
(data) => data.chainId === assetExtended.chainId
(data) => data.chainId === asset.chainId
)
addCustomNetwork(web3Provider, networkNode)
}

View File

@ -62,8 +62,8 @@ export default function FormStartCompute({
}): ReactElement {
const { isValid, values }: FormikContextType<{ algorithm: string }> =
useFormikContext()
const { accessDetails, assetExtended, isAssetNetwork } = useAsset()
const [totalPrice, setTotalPrice] = useState(accessDetails?.price)
const { asset, isAssetNetwork } = useAsset()
const [totalPrice, setTotalPrice] = useState(asset?.accessDetails?.price)
const [isBalanceSufficient, setIsBalanceSufficient] = useState<boolean>(false)
const { accountId, balance } = useWeb3()
const [algorithmConsumableStatus, setAlgorithmConsumableStatus] =
@ -97,10 +97,10 @@ export default function FormStartCompute({
// Set price for calculation output
//
useEffect(() => {
if (!accessDetails || !algorithmConsumeDetails) return
if (!asset?.accessDetails || !algorithmConsumeDetails) return
const priceDataset =
hasPreviousOrder || hasDatatoken ? 0 : Number(accessDetails.price)
hasPreviousOrder || hasDatatoken ? 0 : Number(asset.accessDetails.price)
const priceAlgo =
hasPreviousOrderSelectedComputeAsset || hasDatatokenSelectedComputeAsset
? 0
@ -108,7 +108,7 @@ export default function FormStartCompute({
setTotalPrice(priceDataset + priceAlgo)
}, [
accessDetails,
asset?.accessDetails,
algorithmConsumeDetails,
hasPreviousOrder,
hasDatatoken,
@ -159,7 +159,7 @@ export default function FormStartCompute({
}
hasPreviousOrder={hasPreviousOrder}
hasDatatoken={hasDatatoken}
dtSymbol={assetExtended?.datatokens[0]?.symbol}
dtSymbol={asset?.datatokens[0]?.symbol}
dtBalance={dtBalance}
datasetLowPoolLiquidity={datasetLowPoolLiquidity}
assetTimeout={assetTimeout}
@ -177,7 +177,7 @@ export default function FormStartCompute({
stepText={stepText}
isLoading={isLoading}
type="submit"
priceType={accessDetails?.type}
priceType={asset?.accessDetails?.type}
algorithmPriceType={algorithmConsumeDetails?.type}
isBalanceSufficient={isBalanceSufficient}
isConsumable={isConsumable}

View File

@ -63,7 +63,7 @@ export default function PriceOutput({
algorithmConsumeDetails,
selectedComputeAssetTimeout
}: PriceOutputProps): ReactElement {
const { accessDetails } = useAsset()
const { asset } = useAsset()
return (
<div className={styles.priceComponent}>
@ -74,7 +74,7 @@ export default function PriceOutput({
<Row
hasPreviousOrder={hasPreviousOrder}
hasDatatoken={hasDatatoken}
price={accessDetails?.price}
price={asset?.accessDetails?.price}
timeout={assetTimeout}
symbol={symbol}
/>

View File

@ -60,14 +60,8 @@ const initialPoolInfoCreator: Partial<PoolInfoUser> = initialPoolInfoUser
export default function Pool(): ReactElement {
const { accountId } = useWeb3()
const {
isInPurgatory,
assetExtended,
owner,
accessDetails,
refreshInterval,
isAssetNetwork
} = useAsset()
const { isInPurgatory, asset, owner, refreshInterval, isAssetNetwork } =
useAsset()
const [poolData, setPoolData] = useState<PoolDataPoolData>()
const [poolInfo, setPoolInfo] = useState<PoolInfo>(
@ -88,11 +82,11 @@ export default function Pool(): ReactElement {
const [fetchInterval, setFetchInterval] = useState<NodeJS.Timeout>()
const fetchAllData = useCallback(async () => {
if (!assetExtended?.chainId || !accessDetails?.addressOrId || !owner) return
if (!asset?.chainId || !asset?.accessDetails?.addressOrId || !owner) return
const response = await getPoolData(
assetExtended.chainId,
accessDetails.addressOrId,
asset.chainId,
asset.accessDetails.addressOrId,
owner,
accountId || ''
)
@ -107,7 +101,7 @@ export default function Pool(): ReactElement {
LoggerInstance.log('[pool] Fetched pool data:', response.poolData)
LoggerInstance.log('[pool] Fetched user data:', response.poolDataUser)
LoggerInstance.log('[pool] Fetched pool snapshots:', response.poolSnapshots)
}, [assetExtended?.chainId, accessDetails?.addressOrId, owner, accountId])
}, [asset?.chainId, asset?.accessDetails?.addressOrId, owner, accountId])
// Helper: start interval fetching
const initFetchInterval = useCallback(() => {
@ -242,7 +236,7 @@ export default function Pool(): ReactElement {
if (
!poolData ||
!poolInfo?.totalPoolTokens ||
!assetExtended?.chainId ||
!asset?.chainId ||
!accountId
)
return
@ -310,7 +304,7 @@ export default function Pool(): ReactElement {
poolData,
poolInfoUser?.poolShares,
accountId,
assetExtended?.chainId,
asset?.chainId,
owner,
poolInfo?.totalPoolTokens
])
@ -328,7 +322,7 @@ export default function Pool(): ReactElement {
{showAdd ? (
<Add
setShowAdd={setShowAdd}
poolAddress={accessDetails?.addressOrId}
poolAddress={asset?.accessDetails?.addressOrId}
totalPoolTokens={poolInfo?.totalPoolTokens}
totalBalance={{
baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(),
@ -343,7 +337,7 @@ export default function Pool(): ReactElement {
) : showRemove ? (
<Remove
setShowRemove={setShowRemove}
poolAddress={accessDetails?.addressOrId}
poolAddress={asset?.accessDetails?.addressOrId}
poolTokens={poolInfoUser?.poolShares}
totalPoolTokens={poolInfo?.totalPoolTokens}
tokenOutAddress={poolInfo?.baseTokenAddress}
@ -361,18 +355,17 @@ export default function Pool(): ReactElement {
<Tooltip content={content.pool.tooltips.price} />
<div className={styles.dataTokenLinks}>
<ExplorerLink
networkId={assetExtended?.chainId}
path={`address/${accessDetails?.addressOrId}`}
networkId={asset?.chainId}
path={`address/${asset?.accessDetails?.addressOrId}`}
>
Pool
</ExplorerLink>
<ExplorerLink
networkId={assetExtended?.chainId}
networkId={asset?.chainId}
path={
assetExtended?.chainId === 2021000 ||
assetExtended?.chainId === 1287
? `tokens/${assetExtended.services[0].datatokenAddress}`
: `token/${assetExtended.services[0].datatokenAddress}`
asset?.chainId === 2021000 || asset?.chainId === 1287
? `tokens/${asset.services[0].datatokenAddress}`
: `token/${asset.services[0].datatokenAddress}`
}
>
Datatoken
@ -478,8 +471,8 @@ export default function Pool(): ReactElement {
<AssetActionHistoryTable title="Your Pool Transactions">
<PoolTransactions
accountId={accountId}
poolAddress={accessDetails?.addressOrId}
poolChainId={[assetExtended?.chainId]}
poolAddress={asset?.accessDetails?.addressOrId}
poolChainId={[asset?.chainId]}
minimal
/>
</AssetActionHistoryTable>

View File

@ -17,12 +17,12 @@ import content from '../../../../../content/price.json'
import { AssetExtended } from 'src/@types/AssetExtended'
export default function FormTrade({
assetExtended,
asset,
balance,
maxDt,
maxOcean
}: {
assetExtended: AssetExtended
asset: AssetExtended
balance: PoolBalance
maxDt: string
maxOcean: string
@ -110,7 +110,7 @@ export default function FormTrade({
<>
{isWarningAccepted ? (
<Swap
assetExtended={assetExtended}
asset={asset}
balance={balance}
maxDt={maxDt}
maxOcean={maxOcean}

View File

@ -17,7 +17,7 @@ import { AssetExtended } from 'src/@types/AssetExtended'
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
export default function Swap({
assetExtended,
asset,
maxDt,
maxOcean,
balance,
@ -25,7 +25,7 @@ export default function Swap({
setMaximumOcean,
setCoin
}: {
assetExtended: AssetExtended
asset: AssetExtended
maxDt: string
maxOcean: string
balance: PoolBalance
@ -36,12 +36,12 @@ export default function Swap({
const { isAssetNetwork } = useAsset()
const [oceanItem, setOceanItem] = useState<TradeItem>({
amount: '0',
token: assetExtended.accessDetails.baseToken?.symbol,
token: asset.accessDetails.baseToken?.symbol,
maxAmount: '0'
})
const [dtItem, setDtItem] = useState<TradeItem>({
amount: '0',
token: assetExtended.accessDetails.datatoken.symbol,
token: asset.accessDetails.datatoken.symbol,
maxAmount: '0'
})
@ -58,7 +58,7 @@ export default function Swap({
const [tokenAmount, setTokenAmount] = useState<string>()
useEffect(() => {
if (!assetExtended || !balance || !values?.type) return
if (!asset || !balance || !values?.type) return
async function calculateMaximum() {
const amountDataToken =
@ -114,7 +114,7 @@ export default function Swap({
}
calculateMaximum()
}, [
assetExtended,
asset,
maxOcean,
maxDt,
balance,
@ -125,9 +125,7 @@ export default function Swap({
const switchTokens = () => {
setFieldValue('type', values.type === 'buy' ? 'sell' : 'buy')
setCoin(
values.type === 'sell' ? 'OCEAN' : assetExtended.datatokens[0].symbol
)
setCoin(values.type === 'sell' ? 'OCEAN' : asset.datatokens[0].symbol)
// don't reset form because we don't want to reset type
setFieldValue('datatoken', 0)
setFieldValue('ocean', 0)
@ -223,7 +221,7 @@ export default function Swap({
<Output
dtSymbol={dtItem.token}
oceanSymbol={oceanItem.token}
poolAddress={assetExtended.accessDetails?.addressOrId}
poolAddress={asset.accessDetails?.addressOrId}
/>
<PriceImpact

View File

@ -11,7 +11,7 @@ export default function Trade(): ReactElement {
const { accountId, balance, web3 } = useWeb3()
const { isAssetNetwork } = useAsset()
const [tokenBalance, setTokenBalance] = useState<PoolBalance>()
const { assetExtended } = useAsset()
const { asset } = useAsset()
const [maxDt, setMaxDt] = useState('0')
const [maxOcean, setMaxOcean] = useState('0')
@ -23,14 +23,14 @@ export default function Trade(): ReactElement {
!isAssetNetwork ||
!balance?.ocean ||
!accountId ||
!assetExtended?.services[0].datatokenAddress
!asset?.services[0].datatokenAddress
)
return
async function getTokenBalance() {
const datatokenInstance = new Datatoken(web3)
const dtBalance = await datatokenInstance.balance(
assetExtended.services[0].datatokenAddress,
asset.services[0].datatokenAddress,
accountId
)
setTokenBalance({
@ -39,14 +39,14 @@ export default function Trade(): ReactElement {
})
}
getTokenBalance()
}, [web3, balance.ocean, accountId, assetExtended, isAssetNetwork])
}, [web3, balance.ocean, accountId, asset, isAssetNetwork])
// Get maximum amount for either OCEAN or datatoken
useEffect(() => {
if (
!isAssetNetwork ||
!assetExtended.accessDetails ||
assetExtended.accessDetails.price === 0
!asset.accessDetails ||
asset.accessDetails.price === 0
)
return
@ -69,11 +69,11 @@ export default function Trade(): ReactElement {
// )
}
getMaximum()
}, [isAssetNetwork, balance.ocean, assetExtended])
}, [isAssetNetwork, balance.ocean, asset])
return (
<FormTrade
assetExtended={assetExtended}
asset={asset}
balance={tokenBalance}
maxDt={maxDt}
maxOcean={maxOcean}

View File

@ -1,12 +1,7 @@
import React, { ReactElement, useState, useEffect } from 'react'
import Compute from './Compute'
import Consume from './Consume'
import {
Asset,
FileMetadata,
LoggerInstance,
Datatoken
} from '@oceanprotocol/lib'
import { FileMetadata, LoggerInstance, Datatoken } from '@oceanprotocol/lib'
import Tabs, { TabsItem } from '@shared/atoms/Tabs'
import { compareAsBN } from '@utils/numbers'
import Pool from './Pool'
@ -21,13 +16,12 @@ import { useIsMounted } from '@hooks/useIsMounted'
import styles from './index.module.css'
import { useFormikContext } from 'formik'
import { FormPublishData } from 'src/components/Publish/_types'
import { AssetExtended } from 'src/@types/AssetExtended'
export default function AssetActions({
ddo,
accessDetails
asset
}: {
ddo: Asset
accessDetails: AccessDetails
asset: AssetExtended
}): ReactElement {
const { accountId, balance, web3 } = useWeb3()
const { isAssetNetwork } = useAsset()
@ -43,7 +37,7 @@ export default function AssetActions({
const [fileMetadata, setFileMetadata] = useState<FileMetadata>()
const [fileIsLoading, setFileIsLoading] = useState<boolean>(false)
const isCompute = Boolean(
ddo?.services.filter((service) => service.type === 'compute')[0]
asset?.services.filter((service) => service.type === 'compute')[0]
)
const [isConsumable, setIsConsumable] = useState<boolean>(true)
@ -68,14 +62,14 @@ export default function AssetActions({
// }, [accountId, isAssetNetwork, ddo, ocean])
useEffect(() => {
const oceanConfig = getOceanConfig(ddo?.chainId)
const oceanConfig = getOceanConfig(asset?.chainId)
if (!oceanConfig) return
async function initFileInfo() {
setFileIsLoading(true)
const fileUrl =
formikState?.values?.services?.[0].files?.[0].url ||
(ddo.metadata?.links ? ddo.metadata?.links[0] : ' ')
(asset.metadata?.links ? asset.metadata?.links[0] : ' ')
const providerUrl =
formikState?.values?.services[0].providerUrl.url ||
oceanConfig.providerUri
@ -89,7 +83,7 @@ export default function AssetActions({
}
}
initFileInfo()
}, [ddo, isMounted, newCancelToken, formikState?.values?.services])
}, [asset, isMounted, newCancelToken, formikState?.values?.services])
// Get and set user DT balance
useEffect(() => {
@ -99,7 +93,7 @@ export default function AssetActions({
try {
const datatokenInstance = new Datatoken(web3)
const dtBalance = await datatokenInstance.balance(
ddo.services[0].datatokenAddress,
asset.services[0].datatokenAddress,
accountId
)
setDtBalance(dtBalance)
@ -108,28 +102,33 @@ export default function AssetActions({
}
}
init()
}, [web3, accountId, ddo, isAssetNetwork])
}, [web3, accountId, asset, isAssetNetwork])
// Check user balance against price
useEffect(() => {
if (accessDetails?.type === 'free') setIsBalanceSufficient(true)
if (!accessDetails?.price || !accountId || !balance?.ocean || !dtBalance)
if (asset?.accessDetails?.type === 'free') setIsBalanceSufficient(true)
if (
!asset?.accessDetails?.price ||
!accountId ||
!balance?.ocean ||
!dtBalance
)
return
setIsBalanceSufficient(
compareAsBN(balance.ocean, `${accessDetails.price}`) ||
compareAsBN(balance.ocean, `${asset?.accessDetails.price}`) ||
Number(dtBalance) >= 1
)
return () => {
setIsBalanceSufficient(false)
}
}, [balance, accountId, accessDetails, dtBalance])
}, [balance, accountId, asset?.accessDetails, dtBalance])
const UseContent = isCompute ? (
<Compute
ddo={ddo}
accessDetails={accessDetails}
ddo={asset}
accessDetails={asset?.accessDetails}
dtBalance={dtBalance}
file={fileMetadata}
fileIsLoading={fileIsLoading}
@ -138,8 +137,8 @@ export default function AssetActions({
/>
) : (
<Consume
ddo={ddo}
accessDetails={accessDetails}
ddo={asset}
accessDetails={asset?.accessDetails}
dtBalance={dtBalance}
isBalanceSufficient={isBalanceSufficient}
file={fileMetadata}
@ -156,24 +155,27 @@ export default function AssetActions({
}
]
accessDetails?.type === 'dynamic' &&
asset?.accessDetails?.type === 'dynamic' &&
tabs.push(
{
title: 'Pool',
content: <Pool />,
disabled: !accessDetails.datatoken
disabled: !asset?.accessDetails.datatoken
},
{
title: 'Trade',
content: <Trade />,
disabled: !accessDetails.datatoken
disabled: !asset?.accessDetails.datatoken
}
)
return (
<>
<Tabs items={tabs} className={styles.actions} />
<Web3Feedback networkId={ddo?.chainId} isAssetNetwork={isAssetNetwork} />
<Web3Feedback
networkId={asset?.chainId}
isAssetNetwork={isAssetNetwork}
/>
</>
)
}

View File

@ -26,7 +26,7 @@ const getReceipts = gql`
`
export default function EditHistory(): ReactElement {
const { assetExtended } = useAsset()
const { asset } = useAsset()
function getUpdateType(type: string): string {
switch (type) {
@ -49,17 +49,17 @@ export default function EditHistory(): ReactElement {
const [queryContext, setQueryContext] = useState<OperationContext>()
useEffect(() => {
if (!assetExtended) return
if (!asset) return
const queryContext = getQueryContext(assetExtended.chainId)
const queryContext = getQueryContext(asset.chainId)
setQueryContext(queryContext)
}, [assetExtended])
}, [asset])
const [result] = useQuery({
query: getReceipts,
variables: { address: assetExtended?.nft.address.toLowerCase() },
variables: { address: asset?.nft.address.toLowerCase() },
context: queryContext,
pause: !assetExtended || !queryContext
pause: !asset || !queryContext
})
const { data } = result
@ -80,10 +80,7 @@ export default function EditHistory(): ReactElement {
<ul className={styles.history}>
{receipts?.map((receipt) => (
<li key={receipt.id} className={styles.item}>
<ExplorerLink
networkId={assetExtended?.chainId}
path={`/tx/${receipt.tx}`}
>
<ExplorerLink networkId={asset?.chainId} path={`/tx/${receipt.tx}`}>
{getUpdateType(receipt.type)}{' '}
<Time date={`${receipt.timestamp}`} relative isUnix />
</ExplorerLink>

View File

@ -13,14 +13,12 @@ import EditHistory from './EditHistory'
import styles from './index.module.css'
import NetworkName from '@shared/NetworkName'
import content from '../../../../content/purgatory.json'
import { Asset } from '@oceanprotocol/lib'
import { AssetExtended } from 'src/@types/AssetExtended'
export default function AssetContent({
asset,
accessDetails
asset
}: {
asset: Asset
accessDetails: AccessDetails
asset: AssetExtended
}): ReactElement {
const { debug } = useUserPreferences()
const { isInPurgatory, purgatoryData } = useAsset()
@ -35,7 +33,9 @@ export default function AssetContent({
<div>
<div className={styles.content}>
<MetaMain ddo={asset} />
{accessDetails?.datatoken !== null && <Bookmark did={asset?.id} />}
{asset?.accessDetails?.datatoken !== null && (
<Bookmark did={asset?.id} />
)}
{isInPurgatory === true ? (
<Alert
@ -61,7 +61,7 @@ export default function AssetContent({
</div>
<div className={styles.actions}>
<AssetActions ddo={asset} accessDetails={accessDetails} />
<AssetActions asset={asset} />
{/*
TODO: restore edit actions, ideally put edit screens on new page

View File

@ -19,7 +19,7 @@ export default function EditComputeDataset({
}): ReactElement {
const { debug } = useUserPreferences()
const { accountId } = useWeb3()
const { assetExtended, isAssetNetwork, refreshAsset } = useAsset()
const { asset, isAssetNetwork, fetchAsset } = useAsset()
const [success, setSuccess] = useState<string>()
const [error, setError] = useState<string>()
@ -111,7 +111,7 @@ export default function EditComputeDataset({
/>
</article>
<Web3Feedback
networkId={assetExtended?.chainId}
networkId={asset?.chainId}
isAssetNetwork={isAssetNetwork}
/>
{debug === true && (

View File

@ -28,12 +28,12 @@ export default function FormEditComputeDataset({
setShowEdit: (show: boolean) => void
}): ReactElement {
const { appConfig } = useSiteMetadata()
const { assetExtended } = useAsset()
const { asset } = useAsset()
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
const newCancelToken = useCancelToken()
const { publisherTrustedAlgorithms } = getServiceByName(
assetExtended,
asset,
'compute'
).compute
@ -41,14 +41,14 @@ export default function FormEditComputeDataset({
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
): Promise<AssetSelectionAsset[]> {
const baseParams = {
chainIds: [assetExtended.chainId],
chainIds: [asset.chainId],
sort: { sortBy: SortTermOptions.Created },
filters: [getFilterTerm('service.attributes.main.type', 'algorithm')]
} as BaseQueryParams
const query = generateBaseQuery(baseParams)
const querryResult = await queryMetadata(query, newCancelToken())
const datasetComputeService = getServiceByName(assetExtended, 'compute')
const datasetComputeService = getServiceByName(asset, 'compute')
const algorithmSelectionList = await transformDDOToAssetSelection(
datasetComputeService?.serviceEndpoint,
querryResult.results,

View File

@ -22,11 +22,11 @@ export default function Edit({
}): ReactElement {
const { debug } = useUserPreferences()
const { accountId } = useWeb3()
const { assetExtended, refreshAsset, accessDetails } = useAsset()
const { asset, fetchAsset } = useAsset()
const [success, setSuccess] = useState<string>()
const [error, setError] = useState<string>()
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
const { timeout } = assetExtended.services[0]
const { timeout } = asset.services[0]
const hasFeedback = error || success
@ -119,9 +119,9 @@ export default function Edit({
return (
<Formik
initialValues={getInitialValues(
assetExtended.metadata,
asset.metadata,
timeout,
accessDetails.price
asset.accessDetails.price
)}
validationSchema={validationSchema}
onSubmit={async (values, { resetForm }) => {
@ -148,7 +148,7 @@ export default function Edit({
/> */}
<aside>
<Web3Feedback networkId={assetExtended?.chainId} />
<Web3Feedback networkId={asset?.chainId} />
</aside>
{/* {debug === true && <Debug values={values} ddo={ddo} />} */}

View File

@ -6,21 +6,20 @@ import { useAsset } from '@context/Asset'
import AssetContent from './AssetContent'
export default function AssetDetails({ uri }: { uri: string }): ReactElement {
const { assetExtended, title, error, isInPurgatory, loading, accessDetails } =
useAsset()
const { asset, title, error, isInPurgatory, loading } = useAsset()
const [pageTitle, setPageTitle] = useState<string>()
useEffect(() => {
if (!assetExtended || error) {
if (!asset || error) {
setPageTitle('Could not retrieve asset')
return
}
setPageTitle(isInPurgatory ? '' : title)
}, [assetExtended, error, isInPurgatory, title])
}, [asset, error, isInPurgatory, title])
return assetExtended && pageTitle !== undefined && !loading ? (
return asset && pageTitle !== undefined && !loading ? (
<Page title={pageTitle} uri={uri}>
<AssetContent asset={assetExtended} accessDetails={accessDetails} />
<AssetContent asset={asset} />
</Page>
) : error ? (
<Page title={pageTitle} noPageHeader uri={uri}>

View File

@ -74,7 +74,7 @@ export default function ComputeJobs({
minimal?: boolean
}): ReactElement {
const { accountId, networkId } = useWeb3()
const { assetExtended } = useAsset()
const { asset } = useAsset()
const { chainIds } = useUserPreferences()
const [isLoading, setIsLoading] = useState(false)
const [jobs, setJobs] = useState<ComputeJobMetaData[]>([])
@ -96,7 +96,7 @@ export default function ComputeJobs({
} catch (error) {
LoggerInstance.error(error.message)
}
}, [chainIds, accountId, assetExtended, isMounted])
}, [chainIds, accountId, asset, isMounted])
useEffect(() => {
fetchJobs()

View File

@ -44,7 +44,7 @@ export default function Preview(): ReactElement {
<h2 className={styles.previewTitle}>Preview</h2>
<h3 className={styles.assetTitle}>{values.metadata.name}</h3>
<AssetContent asset={asset} accessDetails={accessDetails} />
<AssetContent asset={asset} />
</div>
)
}