Overview
The AgrospAI Data Space Portal provides a comprehensive set of React hooks built on React Query and wagmi for blockchain interactions.
Asset Hooks
useAssets
Query assets owned by an address with automatic caching and suspense support.
Ethereum address of the asset owner
type
'algorithm' | 'dataset'
required
Type of assets to query
Query result with assets, pagination, and aggregations
Error object if query failed
import { useAssets } from '@hooks/useAssets'
import { Suspense } from 'react'
function MyAssets() {
const { data } = useAssets(
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'dataset',
137
)
return (
<div>
<h2>My Datasets ({data.totalResults})</h2>
{data.results.map(asset => (
<div key={asset.id}>
{asset.metadata.name}
</div>
))}
</div>
)
}
// Wrap with Suspense
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyAssets />
</Suspense>
)
}
User & Account Hooks
useBalance
Track native token and approved ERC20 token balances for the connected wallet.
balance.native
{ symbol: string, balance: string }
Native token (ETH, MATIC, etc.) balance
Object mapping token symbols to balances
getApprovedTokenBalances
(address: string) => Promise<TokenBalances>
Function to manually refresh token balances
import useBalance from '@hooks/useBalance'
function WalletBalance() {
const { balance, getApprovedTokenBalances } = useBalance()
return (
<div>
<p>Native: {balance.native.balance} {balance.native.symbol}</p>
{balance.approved && Object.entries(balance.approved).map(([symbol, amount]) => (
<p key={symbol}>{symbol}: {amount}</p>
))}
</div>
)
}
useAccountPurgatory
Check if an account is flagged in the purgatory moderation system.
Ethereum address to check
Whether the account is flagged
Purgatory details including reason
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
import { useAccount } from 'wagmi'
function AccountStatus() {
const { address } = useAccount()
const { isInPurgatory, purgatoryData, isLoading } = useAccountPurgatory(address)
if (isLoading) return <div>Checking account status...</div>
if (isInPurgatory) {
return (
<Alert state="warning">
Account flagged: {purgatoryData.reason}
</Alert>
)
}
return <div>Account in good standing</div>
}
Network Hooks
Get comprehensive metadata about the current connected network.
Complete list of supported networks
Human-readable network name
Full network metadata object
Whether current network is a testnet
Whether Ocean Protocol is deployed on this network
import useNetworkMetadata from '@hooks/useNetworkMetadata'
function NetworkInfo() {
const {
networkDisplayName,
isTestnet,
isSupportedOceanNetwork,
networkData
} = useNetworkMetadata()
if (!isSupportedOceanNetwork) {
return <Alert state="error">Please switch to a supported network</Alert>
}
return (
<div>
<h3>{networkDisplayName}</h3>
{isTestnet && <Badge>Testnet</Badge>}
<p>Chain ID: {networkData.chainId}</p>
</div>
)
}
useGraphSyncStatus
Monitor the sync status between the blockchain and Ocean Protocol subgraph.
Whether subgraph is synced (within 30 blocks)
Current blockchain head block number
Latest block indexed by subgraph
import { useGraphSyncStatus } from '@hooks/useGraphSyncStatus'
import { useNetwork } from 'wagmi'
function SyncStatus() {
const { chain } = useNetwork()
const { isGraphSynced, blockHead, blockGraph } = useGraphSyncStatus(chain?.id)
if (!isGraphSynced) {
return (
<Alert state="warning">
Subgraph syncing... ({blockGraph}/{blockHead})
</Alert>
)
}
return <div>Data is up to date</div>
}
Utility Hooks
useLocalStorage
Persist state to browser localStorage with type safety.
Default value if key doesn’t exist
[1]
(value: T | ((val: T) => T)) => void
Setter function (same API as useState)
import useLocalStorage from '@hooks/useLocalStorage'
function ThemeToggle() {
const [theme, setTheme] = useLocalStorage<'light' | 'dark'>('theme', 'light')
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current: {theme}
</button>
)
}
usePrevious
Track the previous value of a prop or state.
Value from previous render
import usePrevious from '@hooks/usePrevious'
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
const prevCount = usePrevious(count)
return (
<div>
<p>Current: {count}</p>
<p>Previous: {prevCount}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}
useCancelToken
Generate Axios cancel tokens for abortable requests.
Function that returns a new cancel token
import { useCancelToken } from '@hooks/useCancelToken'
import { getAsset } from '@utils/aquarius'
import { useEffect, useState } from 'react'
function AssetLoader({ did }: { did: string }) {
const newCancelToken = useCancelToken()
const [asset, setAsset] = useState(null)
useEffect(() => {
const loadAsset = async () => {
const result = await getAsset(did, newCancelToken())
setAsset(result)
}
loadAsset()
}, [did])
return <div>{asset?.metadata.name}</div>
}
useAbortController
Generate AbortController signals for fetch API requests.
Function that returns a new abort signal
import { useAbortController } from '@hooks/useAbortController'
import { useEffect, useState } from 'react'
function DataFetcher({ url }: { url: string }) {
const newAbortController = useAbortController()
const [data, setData] = useState(null)
useEffect(() => {
fetch(url, { signal: newAbortController() })
.then(res => res.json())
.then(setData)
.catch(err => {
if (err.name === 'AbortError') {
console.log('Request cancelled')
}
})
}, [url])
return <div>{JSON.stringify(data)}</div>
}
useIsMounted
Check if component is currently mounted (useful for preventing state updates after unmount).
Function that returns current mount status
import { useIsMounted } from '@hooks/useIsMounted'
import { useState, useEffect } from 'react'
function AsyncComponent() {
const isMounted = useIsMounted()
const [data, setData] = useState(null)
useEffect(() => {
fetchData().then(result => {
if (isMounted()) {
setData(result)
}
})
}, [])
return <div>{data}</div>
}
Advanced Hooks
useNftFactory
Interact with the Ocean Protocol NFT Factory contract.
import { useNftFactory } from '@hooks/useNftFactory'
function NftCreator() {
const nftFactory = useNftFactory()
// Access NFT factory methods
}
useUserConsents
Manage user data consents for GDPR compliance.
import { useUserConsents } from '@hooks/useUserConsents'
function ConsentManager() {
const { consents, updateConsent } = useUserConsents()
// Manage user consent preferences
}
useVerifiablePresentations
Handle Gaia-X verifiable presentations and credentials.
import { useVerifiablePresentations } from '@hooks/useVerifiablePresentations'
function CredentialViewer() {
const { presentations } = useVerifiablePresentations()
// Display verifiable credentials
}
Hook Composition
Hooks can be combined for complex functionality:
import useBalance from '@hooks/useBalance'
import useNetworkMetadata from '@hooks/useNetworkMetadata'
import { useAccount } from 'wagmi'
function WalletDashboard() {
const { address } = useAccount()
const { balance } = useBalance()
const { networkDisplayName, isTestnet } = useNetworkMetadata()
if (!address) return <div>Please connect wallet</div>
return (
<div>
<h2>Wallet Dashboard</h2>
<p>Network: {networkDisplayName} {isTestnet && '(Testnet)'}</p>
<p>Balance: {balance.native.balance} {balance.native.symbol}</p>
</div>
)
}
Type Definitions
// Balance types
interface UserBalance {
native: {
symbol: string
balance: string
}
approved?: TokenBalances
}
interface TokenBalances {
[symbol: string]: string
}
// Network types
interface UseNetworkMetadata {
networksList: EthereumListsChain[]
networkDisplayName: string
networkData: EthereumListsChain
isTestnet: boolean
isSupportedOceanNetwork: boolean
}
// Graph sync types
interface UseGraphSyncStatus {
isGraphSynced: boolean
blockHead: number
blockGraph: number
}
// Purgatory types
interface UseAccountPurgatory {
isInPurgatory: boolean
purgatoryData: PurgatoryDataAccount
isLoading: boolean
}