diff --git a/README.md b/README.md index 03af3a048..44d87ec70 100644 --- a/README.md +++ b/README.md @@ -132,15 +132,19 @@ const queryLatest = { } function Component() { - const { metadataCacheUri } = useOcean() + const { appConfig } = useSiteMetadata() const [result, setResult] = useState() useEffect(() => { - if (!metadataCacheUri) return + if (!appConfig.metadataCacheUri) return const source = axios.CancelToken.source() async function init() { - const result = await queryMetadata(query, metadataCacheUri, source.token) + const result = await queryMetadata( + query, + appConfig.metadataCacheUri, + source.token + ) setResult(result) } init() @@ -148,7 +152,7 @@ function Component() { return () => { source.cancel() } - }, [metadataCacheUri, query]) + }, [appConfig.metadataCacheUri, query]) return
{result}
} diff --git a/app.config.js b/app.config.js index 9226d2f28..cdcfe7228 100644 --- a/app.config.js +++ b/app.config.js @@ -1,4 +1,5 @@ module.exports = { + metadataCacheUri: 'https://aquarius.mainnet.oceanprotocol.com', // List of supported chainIds which metadata cache queries // will return by default chainIds: [1, 3, 4, 137, 1287], diff --git a/package-lock.json b/package-lock.json index 744c08cc1..95f89b505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43525,6 +43525,7 @@ "node-abort-controller": "^2.0.0", "save-file": "^2.3.1", "uuid": "^8.3.2", + "web3": "^1.3.5", "web3-eth-contract": "^1.3.6" } }, @@ -43599,6 +43600,7 @@ "integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==", "dev": true, "requires": { + "@oclif/config": "^1.15.1", "@oclif/errors": "^1.3.3", "@oclif/parser": "^3.8.3", "@oclif/plugin-help": "^3", diff --git a/src/components/molecules/AssetListTitle.tsx b/src/components/molecules/AssetListTitle.tsx index 7b93b24fa..815a7f8d2 100644 --- a/src/components/molecules/AssetListTitle.tsx +++ b/src/components/molecules/AssetListTitle.tsx @@ -5,6 +5,7 @@ import React, { ReactElement, useEffect, useState } from 'react' import { getAssetsNames } from '../../utils/aquarius' import styles from './AssetListTitle.module.css' import axios from 'axios' +import { useSiteMetadata } from '../../hooks/useSiteMetadata' export default function AssetListTitle({ ddo, @@ -15,11 +16,11 @@ export default function AssetListTitle({ did?: string title?: string }): ReactElement { - const { metadataCacheUri } = useOcean() + const { appConfig } = useSiteMetadata() const [assetTitle, setAssetTitle] = useState(title) useEffect(() => { - if (title || !metadataCacheUri) return + if (title || !appConfig.metadataCacheUri) return if (ddo) { const { attributes } = ddo.findServiceByType('metadata') setAssetTitle(attributes.main.name) @@ -29,7 +30,11 @@ export default function AssetListTitle({ const source = axios.CancelToken.source() async function getAssetName() { - const title = await getAssetsNames([did], metadataCacheUri, source.token) + const title = await getAssetsNames( + [did], + appConfig.metadataCacheUri, + source.token + ) setAssetTitle(title[did]) } @@ -38,7 +43,7 @@ export default function AssetListTitle({ return () => { source.cancel() } - }, [assetTitle, metadataCacheUri, ddo, did, title]) + }, [assetTitle, appConfig.metadataCacheUri, ddo, did, title]) return (

diff --git a/src/components/molecules/Bookmarks.tsx b/src/components/molecules/Bookmarks.tsx index 9db952e0b..66a0282cb 100644 --- a/src/components/molecules/Bookmarks.tsx +++ b/src/components/molecules/Bookmarks.tsx @@ -8,6 +8,7 @@ import Tooltip from '../atoms/Tooltip' import AssetTitle from './AssetListTitle' import { queryMetadata } from '../../utils/aquarius' import axios, { CancelToken } from 'axios' +import { useSiteMetadata } from '../../hooks/useSiteMetadata' async function getAssetsBookmarked( bookmarks: string[], @@ -78,7 +79,7 @@ const columns = [ ] export default function Bookmarks(): ReactElement { - const { metadataCacheUri } = useOcean() + const { appConfig } = useSiteMetadata() const { bookmarks } = useUserPreferences() const [pinned, setPinned] = useState() @@ -87,7 +88,7 @@ export default function Bookmarks(): ReactElement { const networkName = (config as ConfigHelperConfig)?.network useEffect(() => { - if (!metadataCacheUri || !networkName || bookmarks === {}) return + if (!appConfig.metadataCacheUri || !networkName || bookmarks === {}) return const source = axios.CancelToken.source() @@ -102,7 +103,7 @@ export default function Bookmarks(): ReactElement { try { const resultPinned = await getAssetsBookmarked( bookmarks[networkName], - metadataCacheUri, + appConfig.metadataCacheUri, source.token ) setPinned(resultPinned?.results) @@ -117,7 +118,7 @@ export default function Bookmarks(): ReactElement { return () => { source.cancel() } - }, [bookmarks, metadataCacheUri, networkName]) + }, [bookmarks, appConfig.metadataCacheUri, networkName]) return ( () + const [oceanTokenMetadata, setOceanTokenMetadata] = + useState<{ + address: string + symbol: string + }>() // const [portisNetwork, setPortisNetwork] = useState() useEffect(() => { if (!networkData) return setMainCurrency(networkData.nativeCurrency.symbol) - }, [networkData]) + + oceanConfigs && + setOceanTokenMetadata(getOceanTokenData(networkId || 1, oceanConfigs)) + }, [networkData, networkId, oceanConfigs]) // Handle network change for Portis // async function handlePortisNetworkChange(e: ChangeEvent) { @@ -38,17 +54,17 @@ export default function Details(): ReactElement { return (
    - {/* {Object.entries(balance).map(([key, value]) => ( + {Object.entries(balance).map(([key, value]) => (
  • - {key === 'eth' ? mainCurrency : config.oceanTokenSymbol} + {key === 'eth' ? mainCurrency : oceanTokenMetadata?.symbol} {' '} {formatCurrency(Number(value), '', locale, false, { significantFigures: 4 })} {key === 'ocean' && }
  • - ))} */} + ))}
  • @@ -66,14 +82,14 @@ export default function Details(): ReactElement { onChange={handlePortisNetworkChange} /> )} */} - {/* {web3ProviderInfo?.name === 'MetaMask' && ( + {web3ProviderInfo?.name === 'MetaMask' && ( - )} */} + )}

    {web3ProviderInfo?.name === 'Portis' && ( diff --git a/src/components/organisms/AssetActions/Compute/index.tsx b/src/components/organisms/AssetActions/Compute/index.tsx index 8cc9a4f74..53ef7b592 100644 --- a/src/components/organisms/AssetActions/Compute/index.tsx +++ b/src/components/organisms/AssetActions/Compute/index.tsx @@ -55,7 +55,7 @@ export default function Compute({ }): ReactElement { const { appConfig } = useSiteMetadata() const { accountId } = useWeb3() - const { ocean, account, metadataCacheUri } = useOcean() + const { ocean, account } = useOcean() const { price, type, ddo, isAssetNetwork } = useAsset() const { buyDT, pricingError, pricingStepText } = usePricing() const [isJobStarting, setIsJobStarting] = useState(false) @@ -150,13 +150,13 @@ export default function Compute({ getQuerryString( computeService.attributes.main.privacy.publisherTrustedAlgorithms ), - metadataCacheUri, + appConfig.metadataCacheUri, source.token ) setDdoAlgorithmList(gueryResults.results) algorithmSelectionList = await transformDDOToAssetSelection( gueryResults.results, - metadataCacheUri, + appConfig.metadataCacheUri, [] ) } diff --git a/src/components/organisms/AssetActions/Edit/FormEditComputeDataset.tsx b/src/components/organisms/AssetActions/Edit/FormEditComputeDataset.tsx index 3b769b72a..c806e02b2 100644 --- a/src/components/organisms/AssetActions/Edit/FormEditComputeDataset.tsx +++ b/src/components/organisms/AssetActions/Edit/FormEditComputeDataset.tsx @@ -16,6 +16,7 @@ import { useAsset } from '../../../../providers/Asset' import { ComputePrivacyForm } from '../../../../models/FormEditComputeDataset' import { publisherTrustedAlgorithm as PublisherTrustedAlgorithm } from '@oceanprotocol/lib' import axios from 'axios' +import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' export default function FormEditComputeDataset({ data, @@ -26,8 +27,9 @@ export default function FormEditComputeDataset({ title: string setShowEdit: (show: boolean) => void }): ReactElement { + const { appConfig } = useSiteMetadata() const { accountId } = useWeb3() - const { ocean, metadataCacheUri } = useOcean() + const { ocean } = useOcean() const { ddo } = useAsset() const { isValid, values }: FormikContextType = useFormikContext() @@ -51,12 +53,12 @@ export default function FormEditComputeDataset({ } const querryResult = await queryMetadata( query, - metadataCacheUri, + appConfig.metadataCacheUri, source.token ) const algorithmSelectionList = await transformDDOToAssetSelection( querryResult.results, - metadataCacheUri, + appConfig.metadataCacheUri, publisherTrustedAlgorithms ) return algorithmSelectionList @@ -66,7 +68,7 @@ export default function FormEditComputeDataset({ getAlgorithmList(publisherTrustedAlgorithms).then((algorithms) => { setAllAlgorithms(algorithms) }) - }, [metadataCacheUri, publisherTrustedAlgorithms]) + }, [appConfig.metadataCacheUri, publisherTrustedAlgorithms]) return (
    diff --git a/src/components/pages/History/ComputeJobs/Details.tsx b/src/components/pages/History/ComputeJobs/Details.tsx index 88d1e19fa..9a7e378f0 100644 --- a/src/components/pages/History/ComputeJobs/Details.tsx +++ b/src/components/pages/History/ComputeJobs/Details.tsx @@ -10,6 +10,7 @@ import { retrieveDDO } from '../../../../utils/aquarius' import { useOcean } from '../../../../providers/Ocean' import Results from './Results' import styles from './Details.module.css' +import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' function Asset({ title, @@ -41,7 +42,7 @@ function Asset({ } function DetailsAssets({ job }: { job: ComputeJobMetaData }) { - const { metadataCacheUri } = useOcean() + const { appConfig } = useSiteMetadata() const [algoName, setAlgoName] = useState() const [algoDtSymbol, setAlgoDtSymbol] = useState() @@ -49,14 +50,18 @@ function DetailsAssets({ job }: { job: ComputeJobMetaData }) { async function getAlgoMetadata() { const source = axios.CancelToken.source() - const ddo = await retrieveDDO(job.algoDID, metadataCacheUri, source.token) + const ddo = await retrieveDDO( + job.algoDID, + appConfig.metadataCacheUri, + source.token + ) setAlgoDtSymbol(ddo.dataTokenInfo.symbol) const { attributes } = ddo.findServiceByType('metadata') setAlgoName(attributes?.main.name) } getAlgoMetadata() - }, [metadataCacheUri, job.algoDID]) + }, [appConfig.metadataCacheUri, job.algoDID]) return ( <> diff --git a/src/components/pages/History/ComputeJobs/index.tsx b/src/components/pages/History/ComputeJobs/index.tsx index 49fd6da26..86f428b28 100644 --- a/src/components/pages/History/ComputeJobs/index.tsx +++ b/src/components/pages/History/ComputeJobs/index.tsx @@ -17,6 +17,7 @@ import Details from './Details' import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute' import { ReactComponent as Refresh } from '../../../../images/refresh.svg' import styles from './index.module.css' +import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' const getComputeOrders = gql` query ComputeOrders($user: String!) { @@ -99,7 +100,8 @@ async function getAssetMetadata( } export default function ComputeJobs(): ReactElement { - const { ocean, account, metadataCacheUri, config } = useOcean() + const { appConfig } = useSiteMetadata() + const { ocean, account } = useOcean() const { accountId } = useWeb3() const [isLoading, setIsLoading] = useState(true) const [jobs, setJobs] = useState([]) @@ -128,7 +130,7 @@ export default function ComputeJobs(): ReactElement { const source = axios.CancelToken.source() const assets = await getAssetMetadata( queryDtList, - metadataCacheUri, + appConfig.metadataCacheUri, source.token ) const providers: Provider[] = [] @@ -232,12 +234,12 @@ export default function ComputeJobs(): ReactElement { } useEffect(() => { - if (data === undefined || !metadataCacheUri) { + if (data === undefined || !appConfig.metadataCacheUri) { setIsLoading(false) return } getJobs() - }, [ocean, account, data, metadataCacheUri]) + }, [ocean, account, data, appConfig.metadataCacheUri]) return ( <> diff --git a/src/components/pages/Home.tsx b/src/components/pages/Home.tsx index a7b6458ca..5627bf857 100644 --- a/src/components/pages/Home.tsx +++ b/src/components/pages/Home.tsx @@ -15,16 +15,21 @@ import { queryMetadata } from '../../utils/aquarius' import { getHighestLiquidityDIDs } from '../../utils/subgraph' import { DDO, Logger } from '@oceanprotocol/lib' import { useWeb3 } from '../../providers/Web3' +import { useSiteMetadata } from '../../hooks/useSiteMetadata' +import { getOceanConfig } from '../../utils/ocean' -const queryLatest = { - page: 1, - offset: 9, - query: { - query_string: { - query: `-isInPurgatory:true` - } - }, - sort: { created: -1 } +// TODO: these queries need to adapt to chainIds +function getQueryHighest(chainIds: number[]) { + return { + page: 1, + offset: 9, + query: { + query_string: { + query: `(price.type:pool) -isInPurgatory:true` + } + }, + sort: { 'price.ocean': -1 } + } } function sortElements(items: DDO[], sorted: string[]) { @@ -34,6 +39,20 @@ function sortElements(items: DDO[], sorted: string[]) { return items } +function getQueryLatest(chainIds: number[]) { + return { + page: 1, + offset: 9, + query: { + query_string: { + query: `-isInPurgatory:true` + } + }, + sort: { created: -1 } + } + return items +} + function SectionQueryResult({ title, query, @@ -45,12 +64,12 @@ function SectionQueryResult({ action?: ReactElement queryData?: string }) { - const { metadataCacheUri } = useOcean() + const { appConfig } = useSiteMetadata() const [result, setResult] = useState() const [loading, setLoading] = useState() useEffect(() => { - if (!metadataCacheUri) return + if (!appConfig.metadataCacheUri) return const source = axios.CancelToken.source() async function init() { @@ -58,7 +77,7 @@ function SectionQueryResult({ setLoading(true) const result = await queryMetadata( query, - metadataCacheUri, + appConfig.metadataCacheUri, source.token ) if (result.totalResults <= 15) { @@ -83,7 +102,7 @@ function SectionQueryResult({ return () => { source.cancel() } - }, [metadataCacheUri, query]) + }, [appConfig.metadataCacheUri, query]) return (

    @@ -99,8 +118,9 @@ function SectionQueryResult({ } export default function HomePage(): ReactElement { - const { config, loading } = useOcean() + // TODO: appConfig.chainIds needs to come from UserPreferences instead const [queryAndDids, setQueryAndDids] = useState<[SearchQuery, string]>() + const { appConfig } = useSiteMetadata() const { web3Loading, web3Provider } = useWeb3() useEffect(() => { @@ -135,13 +155,14 @@ export default function HomePage(): ReactElement { )} All data sets and algorithms → diff --git a/src/components/templates/Search/index.tsx b/src/components/templates/Search/index.tsx index 66a1c3437..1e92eb50e 100644 --- a/src/components/templates/Search/index.tsx +++ b/src/components/templates/Search/index.tsx @@ -9,8 +9,7 @@ import Sort from './sort' import { getResults } from './utils' import { navigate } from 'gatsby' import { updateQueryStringParameter } from '../../../utils' -import Loader from '../../atoms/Loader' -import { useOcean } from '../../../providers/Ocean' +import { useSiteMetadata } from '../../../hooks/useSiteMetadata' export default function SearchPage({ location, @@ -19,7 +18,7 @@ export default function SearchPage({ location: Location setTotalResults: (totalResults: number) => void }): ReactElement { - const { metadataCacheUri } = useOcean() + const { appConfig } = useSiteMetadata() const parsed = queryString.parse(location.search) const { text, owner, tags, page, sort, sortOrder, serviceType } = parsed const [queryResult, setQueryResult] = useState() @@ -31,18 +30,27 @@ export default function SearchPage({ ) useEffect(() => { - if (!metadataCacheUri) return + if (!appConfig.metadataCacheUri) return async function initSearch() { setLoading(true) setTotalResults(undefined) - const queryResult = await getResults(parsed, metadataCacheUri) + const queryResult = await getResults(parsed, appConfig.metadataCacheUri) setQueryResult(queryResult) setTotalResults(queryResult.totalResults) setLoading(false) } initSearch() - }, [text, owner, tags, sort, page, serviceType, sortOrder, metadataCacheUri]) + }, [ + text, + owner, + tags, + sort, + page, + serviceType, + sortOrder, + appConfig.metadataCacheUri + ]) function setPage(page: number) { const newUrl = updateQueryStringParameter( diff --git a/src/helpers/wrapRootElement.tsx b/src/helpers/wrapRootElement.tsx index 3ad24560f..0efd88f55 100644 --- a/src/helpers/wrapRootElement.tsx +++ b/src/helpers/wrapRootElement.tsx @@ -12,13 +12,13 @@ export default function wrapRootElement({ }): ReactElement { return ( - - - - {element} - - - + {/* */} + + + {element} + + + {/* */} ) } diff --git a/src/hooks/useSiteMetadata.ts b/src/hooks/useSiteMetadata.ts index 63cef169a..b68e24eb7 100644 --- a/src/hooks/useSiteMetadata.ts +++ b/src/hooks/useSiteMetadata.ts @@ -20,6 +20,7 @@ interface UseSiteMetadata { polygon: string } appConfig: { + metadataCacheUri: string infuraProjectId: string chainIds: number[] marketFeeAddress: string @@ -52,6 +53,7 @@ const query = graphql` polygon } appConfig { + metadataCacheUri infuraProjectId chainIds marketFeeAddress diff --git a/src/pages/asset/index.tsx b/src/pages/asset/index.tsx index 61d335698..fb0ffb184 100644 --- a/src/pages/asset/index.tsx +++ b/src/pages/asset/index.tsx @@ -2,6 +2,7 @@ import React, { ReactElement, useEffect, useState } from 'react' import { PageProps } from 'gatsby' import PageTemplateAssetDetails from '../../components/templates/PageAssetDetails' import AssetProvider from '../../providers/Asset' +import OceanProvider from '../../providers/Ocean' export default function PageGatsbyAssetDetails(props: PageProps): ReactElement { const [did, setDid] = useState() @@ -12,7 +13,9 @@ export default function PageGatsbyAssetDetails(props: PageProps): ReactElement { return ( - + + + ) } diff --git a/src/providers/ApolloClientProvider.tsx b/src/providers/ApolloClientProvider.tsx index ec60215ee..3f34df684 100644 --- a/src/providers/ApolloClientProvider.tsx +++ b/src/providers/ApolloClientProvider.tsx @@ -5,10 +5,11 @@ import { InMemoryCache, NormalizedCacheObject } from '@apollo/client' -import { Logger, ConfigHelperConfig } from '@oceanprotocol/lib' -import { useOcean } from './Ocean' +import { Logger } from '@oceanprotocol/lib' import fetch from 'cross-fetch' import React, { useState, useEffect, ReactNode, ReactElement } from 'react' +import { useWeb3 } from './Web3' +import { getOceanConfig } from '../utils/ocean' let apolloClient: ApolloClient function createClient(subgraphUri: string) { @@ -32,21 +33,23 @@ export default function ApolloClientProvider({ }: { children: ReactNode }): ReactElement { - const { config } = useOcean() + const { networkId } = useWeb3() const [client, setClient] = useState>() useEffect(() => { - if (!(config as ConfigHelperConfig)?.subgraphUri) { + const { subgraphUri } = getOceanConfig(networkId || 1) + + if (!subgraphUri) { Logger.error( 'No subgraphUri defined, preventing ApolloProvider from initialization.' ) return } - const newClient = createClient((config as ConfigHelperConfig).subgraphUri) + const newClient = createClient(subgraphUri) apolloClient = newClient setClient(newClient) - }, [config]) + }, [networkId]) return client ? ( {children} diff --git a/src/providers/Asset.tsx b/src/providers/Asset.tsx index 9df9857c3..8fb5b2a3b 100644 --- a/src/providers/Asset.tsx +++ b/src/providers/Asset.tsx @@ -16,6 +16,8 @@ import { getPrice } from '../utils/subgraph' import { MetadataMarket } from '../@types/MetaData' import { useOcean } from './Ocean' import { useWeb3 } from './Web3' +import { getOceanConfig } from '../utils/ocean' +import { useSiteMetadata } from '../hooks/useSiteMetadata' interface AssetProviderValue { isInPurgatory: boolean @@ -44,8 +46,9 @@ function AssetProvider({ asset: string | DDO children: ReactNode }): ReactElement { + const { appConfig } = useSiteMetadata() + const { networkId } = useWeb3() - const { metadataCacheUri } = useOcean() const [isInPurgatory, setIsInPurgatory] = useState(false) const [purgatoryData, setPurgatoryData] = useState() const [ddo, setDDO] = useState() @@ -60,7 +63,11 @@ function AssetProvider({ const fetchDdo = async (token?: CancelToken) => { Logger.log('[asset] Init asset, get DDO') - const ddo = await retrieveDDO(asset as string, metadataCacheUri, token) + const ddo = await retrieveDDO( + asset as string, + appConfig.metadataCacheUri, + token + ) if (!ddo) { setError( @@ -82,7 +89,7 @@ function AssetProvider({ // Get and set DDO based on passed DDO or DID // useEffect(() => { - if (!asset || !metadataCacheUri) return + if (!asset || !appConfig.metadataCacheUri) return const source = axios.CancelToken.source() let isMounted = true @@ -99,7 +106,7 @@ function AssetProvider({ isMounted = false source.cancel() } - }, [asset, metadataCacheUri]) + }, [asset, appConfig.metadataCacheUri]) const setPurgatory = useCallback(async (did: string): Promise => { if (!did) return diff --git a/src/providers/Ocean.tsx b/src/providers/Ocean.tsx index 93cfdc52c..6add08d0e 100644 --- a/src/providers/Ocean.tsx +++ b/src/providers/Ocean.tsx @@ -16,112 +16,59 @@ import { } from '@oceanprotocol/lib' import { useWeb3 } from './Web3' -import { - getDevelopmentConfig, - getOceanConfig, - getUserInfo -} from '../utils/ocean' -import { UserBalance } from '../@types/TokenBalance' -import { useSiteMetadata } from '../hooks/useSiteMetadata' - -const refreshInterval = 20000 // 20 sec. +import { getDevelopmentConfig, getOceanConfig } from '../utils/ocean' +import { useAsset } from './Asset' interface OceanProviderValue { - oceanConfigs: ConfigHelperConfig[] - metadataCacheUri: string ocean: Ocean - config: ConfigHelperConfig account: Account - balance: UserBalance - loading: boolean - connect: (config?: Config) => Promise - refreshBalance: () => Promise + connect: (config: Config) => Promise } const OceanContext = createContext({} as OceanProviderValue) function OceanProvider({ children }: { children: ReactNode }): ReactElement { - const { appConfig } = useSiteMetadata() - const { web3, accountId, networkId } = useWeb3() + const { web3, accountId } = useWeb3() + const { ddo } = useAsset() - const [oceanConfigs, setOceanConfigs] = useState() - const [metadataCacheUri, setMetadataCacheUri] = useState() const [ocean, setOcean] = useState() const [account, setAccount] = useState() - const [balance, setBalance] = useState({ - eth: undefined, - ocean: undefined - }) - const [config, setConfig] = useState() // ----------------------------------- - // Initially get all supported configs - // from ocean.js ConfigHelper - // ----------------------------------- - useEffect(() => { - const allConfigs = appConfig.chainIds.map((chainId: number) => - getOceanConfig(chainId) - ) - setOceanConfigs(allConfigs) - setMetadataCacheUri(allConfigs[0].metadataCacheUri) - }, []) - - // ----------------------------------- - // Set active config - // ----------------------------------- - // useEffect(() => { - // const config = { - // ...getOceanConfig(networkId || 'mainnet'), - - // // add local dev values - // ...(networkId === 8996 && { - // ...getDevelopmentConfig() - // }) - // } - // setConfig(config) - // // Sync config.metadataCacheUri with metadataCacheUri - // setMetadataCacheUri(config.metadataCacheUri) - // }, [networkId]) - - // ----------------------------------- - // Create Ocean instance + // Helper: Create Ocean instance // ----------------------------------- const connect = useCallback( async (config: ConfigHelperConfig | Config) => { - if (!web3) return + if (!web3 || !ddo) return + + const newConfig: Config = { + ...config, + web3Provider: web3 + } try { - Logger.log('[ocean] Connecting Ocean...', config) - - config.web3Provider = web3 - setConfig(config) - - const newOcean = await Ocean.getInstance(config) + Logger.log('[ocean] Connecting Ocean...', newConfig) + const newOcean = await Ocean.getInstance(newConfig) setOcean(newOcean) Logger.log('[ocean] Ocean instance created.', newOcean) } catch (error) { Logger.error('[ocean] Error: ', error.message) } }, - [web3] + [web3, ddo] ) - // async function refreshBalance() { - // if (!ocean || !account || !web3) return - - // const { balance } = await getUserInfo(ocean) - // setBalance(balance) - // } - // ----------------------------------- // Initial connection // ----------------------------------- useEffect(() => { + if (!ddo?.chainId) return + const config = { - ...getOceanConfig('mainnet'), + ...getOceanConfig(ddo.chainId), // add local dev values - ...(networkId === 8996 && { + ...(ddo.chainId === 8996 && { ...getDevelopmentConfig() }) } @@ -130,39 +77,28 @@ function OceanProvider({ children }: { children: ReactNode }): ReactElement { await connect(config) } init() - - // init periodic refresh of wallet balance - // const balanceInterval = setInterval(() => refreshBalance(), refreshInterval) - - // return () => { - // clearInterval(balanceInterval) - // } - }, [connect, networkId]) + }, [connect, ddo?.chainId]) // ----------------------------------- // Get user info, handle account change from web3 // ----------------------------------- - // useEffect(() => { - // if (!ocean || !accountId || !web3) return + useEffect(() => { + if (!ocean || !accountId || !web3) return - // async function getInfo() { - // const { account, balance } = await getUserInfo(ocean) - // setAccount(account) - // setBalance(balance) - // } - // getInfo() - // }, [ocean, accountId, web3]) + async function getInfo() { + const account = (await ocean.accounts.list())[0] + Logger.log('[ocean] Account: ', account) + setAccount(account) + } + getInfo() + }, [ocean, accountId, web3]) return ( () const [accountId, setAccountId] = useState() const [web3Loading, setWeb3Loading] = useState(true) + const [balance, setBalance] = useState({ + eth: '0', + ocean: '0' + }) + // ----------------------------------- + // Helper: connect to web3 + // ----------------------------------- const connect = useCallback(async () => { if (!web3Modal) { setWeb3Loading(false) @@ -146,6 +158,24 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement { } }, [web3Modal]) + // ----------------------------------- + // Helper: Get user balance + // ----------------------------------- + const getUserBalance = useCallback(async () => { + if (!accountId || !networkId || !web3) return + + try { + const balance = { + eth: web3.utils.fromWei(await web3.eth.getBalance(accountId, 'latest')), + ocean: await getOceanBalance(accountId, networkId, web3) + } + setBalance(balance) + Logger.log('[web3] Balance: ', balance) + } catch (error) { + Logger.error('[web3] Error: ', error.message) + } + }, [accountId, networkId, web3]) + // ----------------------------------- // Create initial Web3Modal instance // ----------------------------------- @@ -180,6 +210,20 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement { connectCached() }, [connect, web3Modal]) + // ----------------------------------- + // Get and set user balance + // ----------------------------------- + useEffect(() => { + getUserBalance() + + // init periodic refresh of wallet balance + const balanceInterval = setInterval(() => getUserBalance(), refreshInterval) + + return () => { + clearInterval(balanceInterval) + } + }, [getUserBalance]) + // ----------------------------------- // Get and set network metadata // ----------------------------------- @@ -274,6 +318,7 @@ function Web3Provider({ children }: { children: ReactNode }): ReactElement { web3Modal, web3ProviderInfo, accountId, + balance, networkId, networkDisplayName, networkData, @@ -294,3 +339,6 @@ const useWeb3 = (): Web3ProviderValue => useContext(Web3Context) export { Web3Provider, useWeb3, Web3ProviderValue, Web3Context } export default Web3Provider +function getTokenBalance() { + throw new Error('Function not implemented.') +} diff --git a/src/utils/ocean.ts b/src/utils/ocean.ts index 652f6e6da..3d10a17c0 100644 --- a/src/utils/ocean.ts +++ b/src/utils/ocean.ts @@ -1,15 +1,13 @@ import { - Account, - Logger, - Ocean, ConfigHelper, ConfigHelperConfig, ConfigHelperNetworkId, - ConfigHelperNetworkName + ConfigHelperNetworkName, + Logger } from '@oceanprotocol/lib' import contractAddresses from '@oceanprotocol/contracts/artifacts/address.json' - -import { UserBalance } from '../@types/TokenBalance' +import { AbiItem } from 'web3-utils/types' +import Web3 from 'web3' export function getOceanConfig( network: ConfigHelperNetworkName | ConfigHelperNetworkId @@ -24,11 +22,7 @@ export function getOceanConfig( : process.env.GATSBY_INFURA_PROJECT_ID ) - return { - ...config, - // TODO: remove faking one Aquarius for all networks - metadataCacheUri: 'https://aquarius.mainnet.oceanprotocol.com' - } as ConfigHelperConfig + return config as ConfigHelperConfig } export function getDevelopmentConfig(): Partial { @@ -43,19 +37,54 @@ export function getDevelopmentConfig(): Partial { } } -export async function getUserInfo( - ocean: Ocean -): Promise<{ account: Account; balance: UserBalance }> { - if (!ocean) return { account: null, balance: { eth: '0', ocean: '0' } } +export async function getOceanBalance( + accountId: string, + networkId: number, + web3: Web3 +): Promise { + const minABI = [ + { + constant: true, + inputs: [ + { + name: '_owner', + type: 'address' + } + ], + name: 'balanceOf', + outputs: [ + { + name: 'balance', + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view', + type: 'function' + } + ] as AbiItem[] - const account = (await ocean.accounts.list())[0] - Logger.log('[ocean] Account: ', account) - - const balance = { - eth: await account.getEtherBalance(), - ocean: await account.getOceanBalance() + try { + const token = new web3.eth.Contract( + minABI, + getOceanConfig(networkId).oceanTokenAddress, + { from: accountId } + ) + const result = web3.utils.fromWei( + await token.methods.balanceOf(accountId).call() + ) + return result + } catch (e) { + Logger.error(`ERROR: Failed to get the balance: ${e.message}`) } - Logger.log('[ocean] Balance: ', JSON.stringify(balance)) - - return { account, balance } +} + +export function getOceanTokenData( + networkId: number, + configs: ConfigHelperConfig[] +): { address: string; symbol: string } { + const { oceanTokenSymbol, oceanTokenAddress } = configs.filter( + (config) => config.networkId === networkId + )[0] + return { address: oceanTokenAddress, symbol: oceanTokenSymbol } }