1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00
market/src/@context/Asset.tsx
Bogdan Fazakas 165a9b0fb3
Feature/wagmi (#1912)
* wagmi + ethers + web3modal setup

* refactor wallet components

* fallback providers, more config

* kick out useWeb3

* remove all useWeb3 imports

* more web3.js usage removal

* isAddress utils replacement

* restore add token / add network

* less accountId changes

* web3 legacy tinkering, utils/web3 → utils/wallet

* legacy web3 object for ocean.js

* graph sync fix, remove custom network switching code

* package updates, merge fixes

* downgrade to ethers v5

* fix project id

* switch to ConnectKit

* connectkit theming

* add existing chains to wagmi

* rewrite getPaymentCollector()

* kick out getPaymentCollector completely, use wagmi hooks instead

* Revert "kick out getPaymentCollector completely, use wagmi hooks instead"

This reverts commit 54c7d1ef1a2dec0b1575a685125ba78336b30f59.

* switch getPaymentCollector

* calcBaseInGivenDatatokensOut reorg

* wip integrate ocean lib 3.0.0

* update orbis components to use wagmi instead of web hooks

* more oceanjs integration updates

* more refactors

* fix build

* update ocean lib

* fix publish

* fix order fixed rate

* remove logs

* debug and stop infinite cycle orbis connect

* fix orbis dm connection

* mock use network and fix some more tests

* mock wagmi switch network

* mock wagmi  useProvider createClient and connectKit getDefaultClient

* fix jest tests

* try storybook fix

* cleanups and bump ocean lib

* fix order

* bump lib to next.5 and add more modal style

* bump ocean.js lib to 3.0.0

---------

Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2023-05-29 13:28:41 +03:00

233 lines
6.7 KiB
TypeScript

import React, {
useContext,
useState,
useEffect,
createContext,
ReactElement,
useCallback,
ReactNode
} from 'react'
import { Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
import { CancelToken } from 'axios'
import { getAsset } from '@utils/aquarius'
import { useCancelToken } from '@hooks/useCancelToken'
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
import { getAccessDetails } from '@utils/accessDetailsAndPricing'
import { useIsMounted } from '@hooks/useIsMounted'
import { useMarketMetadata } from './MarketMetadata'
import { assetStateToString } from '@utils/assetState'
import { isValidDid } from '@utils/ddo'
import { useAccount, useNetwork } from 'wagmi'
export interface AssetProviderValue {
isInPurgatory: boolean
purgatoryData: Purgatory
asset: AssetExtended
title: string
owner: string
error?: string
isAssetNetwork: boolean
isOwner: boolean
oceanConfig: Config
loading: boolean
assetState: string
fetchAsset: (token?: CancelToken) => Promise<void>
}
const AssetContext = createContext({} as AssetProviderValue)
function AssetProvider({
did,
children
}: {
did: string
children: ReactNode
}): ReactElement {
const { appConfig } = useMarketMetadata()
const { address: accountId } = useAccount()
const { chain } = useNetwork()
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
const [asset, setAsset] = useState<AssetExtended>()
const [title, setTitle] = useState<string>()
const [owner, setOwner] = useState<string>()
const [isOwner, setIsOwner] = useState<boolean>()
const [error, setError] = useState<string>()
const [loading, setLoading] = useState(false)
const [isAssetNetwork, setIsAssetNetwork] = useState<boolean>()
const [oceanConfig, setOceanConfig] = useState<Config>()
const [assetState, setAssetState] = useState<string>()
const newCancelToken = useCancelToken()
const isMounted = useIsMounted()
// -----------------------------------
// Helper: Get and set asset based on passed DID
// -----------------------------------
const fetchAsset = useCallback(
async (token?: CancelToken) => {
if (!did) return
const isDid = isValidDid(did)
if (!isDid) {
setError(`The url is not for a valid DID`)
LoggerInstance.error(`[asset] Not a valid DID`)
return
}
LoggerInstance.log('[asset] Fetching asset...')
setLoading(true)
const asset = await getAsset(did, token)
if (!asset) {
setError(
`\`${did}\`` +
'\n\nWe could not find an asset for this DID in the cache. If you just published a new asset, wait some seconds and refresh this page.'
)
LoggerInstance.error(`[asset] Failed getting asset for ${did}`, asset)
return
}
if (asset.nft.state === (1 | 2 | 3)) {
setTitle(
`This asset has been set as "${assetStateToString(
asset.nft.state
)}" by the publisher`
)
setError(`\`${did}\`` + `\n\nPublisher Address: ${asset.nft.owner}`)
LoggerInstance.error(`[asset] Failed getting asset for ${did}`, asset)
return
}
if (asset) {
setError(undefined)
setAsset((prevState) => ({
...prevState,
...asset
}))
setTitle(asset.metadata?.name)
setOwner(asset.nft?.owner)
setIsInPurgatory(asset.purgatory?.state)
setPurgatoryData(asset.purgatory)
setAssetState(assetStateToString(asset.nft.state))
LoggerInstance.log('[asset] Got asset', asset)
}
setLoading(false)
},
[did, accountId]
)
// -----------------------------------
// Helper: Get and set asset access details
// -----------------------------------
const fetchAccessDetails = useCallback(async (): Promise<void> => {
if (!asset?.chainId || !asset?.services?.length) 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])
// -----------------------------------
// 1. Get and set asset based on passed DID
// -----------------------------------
useEffect(() => {
if (!isMounted || !appConfig?.metadataCacheUri) return
fetchAsset(newCancelToken())
}, [appConfig?.metadataCacheUri, fetchAsset, newCancelToken, isMounted])
// -----------------------------------
// 2. Attach access details to asset
// -----------------------------------
useEffect(() => {
if (!isMounted) return
fetchAccessDetails()
}, [accountId, fetchAccessDetails, isMounted])
// -----------------------------------
// Check user network against asset network
// -----------------------------------
useEffect(() => {
if (!chain?.id || !asset?.chainId) return
const isAssetNetwork = chain?.id === asset?.chainId
setIsAssetNetwork(isAssetNetwork)
}, [chain?.id, asset?.chainId])
// -----------------------------------
// Asset owner check against wallet user
// -----------------------------------
useEffect(() => {
if (!accountId || !owner) return
const isOwner = accountId?.toLowerCase() === owner.toLowerCase()
setIsOwner(isOwner)
}, [accountId, owner])
// -----------------------------------
// Load ocean config based on asset network
// -----------------------------------
useEffect(() => {
if (!asset?.chainId) return
const oceanConfig = {
...getOceanConfig(asset?.chainId),
// add local dev values
...(asset?.chainId === 8996 && {
...getDevelopmentConfig()
})
}
setOceanConfig(oceanConfig)
}, [asset?.chainId])
// -----------------------------------
// Set Asset State as a string
// -----------------------------------
useEffect(() => {
if (!asset?.nft) return
setAssetState(assetStateToString(asset.nft.state))
}, [asset])
return (
<AssetContext.Provider
value={
{
asset,
did,
title,
owner,
error,
isInPurgatory,
purgatoryData,
loading,
fetchAsset,
isAssetNetwork,
isOwner,
oceanConfig,
assetState
} as AssetProviderValue
}
>
{children}
</AssetContext.Provider>
)
}
// Helper hook to access the provider values
const useAsset = (): AssetProviderValue => useContext(AssetContext)
export { AssetProvider, useAsset, AssetContext }
export default AssetProvider