Hooks Reference¶
All hooks must be used inside VaultProvider (they call useVaultContext(), which throws "useVaultContext must be used within a VaultProvider" otherwise).
Write-hook return shape¶
Every write hook returns the same shape:
{
txState: TxState; // 'idle' | 'approving' | 'pending' | 'confirming' | 'success' | 'error'
txHash: Hash | undefined; // set once the wallet returns a hash
error: string | null; // human-readable; from err.shortMessage ?? err.message
reset: () => void; // back to 'idle', clears txHash and error
// ...plus the action function(s), documented per hook
}
State transitions: idle → (approving →) pending → confirming → success | error. 'approving' occurs only in useDeposit when an ERC-20 approval is needed. 'confirming' is set after the wallet returns a hash, while waitForTransactionReceipt runs.
Actions never throw
Action functions do not throw — failures land in error + txState: 'error'. Precondition failures (wallet not connected, zero amount, wrong vault type) also set error without sending anything.
Read hooks — on-chain¶
useVaultMetadata¶
Returns { data: VaultMetadata | undefined, isLoading: boolean, error: Error | null }. Reads everything on-chain via multicall. Disabled until vaultAddress is set.
| Query key | staleTime |
|---|---|
['vault-metadata', vaultAddress] |
60 s |
This is step 1 of every integration — it yields the asset, share, assetDecimals, shareDecimals, and vaultType that all other hooks take as parameters.
useVaultUserState¶
function useVaultUserState(
vaultAddress: Address | undefined,
shareTokenAddress: Address | undefined,
depositAssetDecimals: number = 6,
vaultType: VaultType = 'ASYNC',
): VaultUserState
Returns the full VaultUserState (never undefined — an all-zeros object with isLoading: true while fetching). Enabled only when vaultAddress, the connected user address, and shareTokenAddress are all present. Auto-refetches every 10 s — this is the mechanism for detecting pending → claimable transitions.
| Query key | Refetch |
|---|---|
['vault-user-state', vaultAddress, userAddress, vaultType] |
every 10 s |
Pass the parameters from metadata: useVaultUserState(vault, meta?.share, meta?.assetDecimals, meta?.vaultType).
Write hooks — deposit / redeem lifecycle¶
useDeposit¶
function useDeposit(
vaultAddress: Address | undefined,
depositAssetAddress: Address | undefined,
depositAssetDecimals: number = 6,
vaultType: VaultType = 'ASYNC',
)
Action: deposit(amount: string) => Promise<void> — amount is human-readable (e.g. "100"), parsed with assetDecimals.
Full orchestration in one call: checks ERC-20 allowance → if insufficient, sends approve (txState: 'approving') and waits for the receipt → sends the deposit tx. For 'ASYNC' vaults the deposit tx is requestDeposit(assets, controller, owner); for 'SYNC_DEPOSIT_ASYNC_REDEEM' it is the ERC-4626 deposit(assets, receiver).
useClaimDeposit¶
Action: claimDeposit(assets: bigint) => Promise<void> — ASYNC vaults only, after the epoch processed a deposit request. Pass state.claimableDepositAssets from useVaultUserState. On-chain this calls ERC-4626 deposit(assets, receiver) to mint the shares.
useRequestRedeem¶
Action: requestRedeem(shares: string, shareDecimals = 18) => Promise<void> — shares are human-readable, parsed with shareDecimals (pass meta.shareDecimals). Sends requestRedeem(shares, controller, owner) with the user as both controller and owner.
useClaimRedeem¶
Action: claimRedeem(shares: bigint) => Promise<void> — after the epoch. Pass state.claimableRedeemShares (raw bigint, not a string). Sends redeem(shares, receiver, controller).
useCancelRedeem¶
Two actions sharing one txState:
cancelRedeem(): Promise<void>— sendscancelRedeemRequest(0, controller).claimCancelRedeem(): Promise<void>— after the epoch, sendsclaimCancelRedeemRequest(0, receiver, controller); the user's shares are returned.
useCancelDeposit¶
function useCancelDeposit(
vaultAddress: Address | undefined,
vaultType: VaultType | undefined, // REQUIRED — pass meta?.vaultType
)
Two actions: cancelDeposit() and claimCancelDeposit(). ASYNC vaults only.
The second argument is required
If vaultType is not exactly 'ASYNC' (including undefined while metadata loads), both actions fail early with:
"Cancel deposit is not supported on this vault: SYNC_DEPOSIT_ASYNC_REDEEM deposits settle immediately."
This guard exists to prevent a confusing on-chain revert.
Financial-data hooks (Arkonix API)¶
All of these require config.arkonixAPI.baseUrl; without it they stay disabled and error clearly if forced. All return standard react-query results ({ data, isLoading, error, … }). See Working with Financial Data for the semantics that matter when rendering.
useVaultFinancials¶
The address-only entry point. NAV/TVL (tvlUsd), sharePrice, all return windows, and — critically — the shareClassId that keys every share-class-scoped hook below.
| Query key | staleTime |
|---|---|
["arkonix-vault-financials", vaultAddress] |
60 s |
useReturnHistory¶
function useReturnHistory(shareClassId: string | undefined, params?: { days?: number }) // → ReturnHistory
Headline returns plus a points[] series (~50 points, oldest → newest, live ~15-min data). days defaults to 30 server-side, range 1–365; it controls only the points window, not the fixed 7/30/90d/all-time headline fields.
| Query key | staleTime |
|---|---|
["arkonix-return-history", shareClassId, params] |
5 min |
useTvlHistory¶
function useTvlHistory(shareClassId: string | undefined, params?: { days?: number }) // → TvlHistory
TVL (NAV) time series.
| Query key | staleTime |
|---|---|
["arkonix-tvl-history", shareClassId, params] |
5 min |
useSharePriceHistory¶
Raw on-chain share-price events (block number, tx hash, price) for a vault.
| Query key | staleTime |
|---|---|
["arkonix-share-price-history", vaultAddress] |
60 s |
useVaultTransactions (new in 2.3.0)¶
function useVaultTransactions(vaultAddress: Address | undefined, params?: VaultTransactionsQueryParams) // → VaultTransactions
A user's deposit/redeem/claim activity plus still-pending requests. Disabled until params.userAddress is set — an all-users feed is rarely what a partner UI wants, and this makes the hook safe to mount before a wallet connects. Supports transactionType ('DEPOSIT' | 'WITHDRAWAL' | 'DEPOSIT_REQUEST' | 'REDEEM_REQUEST' | 'ALL', default 'ALL'), limit, offset.
| Query key | staleTime |
|---|---|
["arkonix-vault-transactions", vaultAddress, params] |
30 s |
useVaultAssetDistribution (new in 2.3.0)¶
Per-asset holdings with backend-computed weights (pctOfTvl). The Arkonix-native replacement for the deprecated Centrifuge holdings hooks.
| Query key | staleTime |
|---|---|
["arkonix-asset-distribution", shareClassId] |
5 min |
useShareClassFees (new in 2.3.0)¶
Management + performance fee rates from the on-chain fee manager. Returns from useVaultFinancials are already net of these fees — display fees as a breakdown label only; never subtract them from returns again.
| Query key | staleTime |
|---|---|
["arkonix-share-class-fees", shareClassId] |
10 min |
Centrifuge hooks¶
Vault discovery (not deprecated):
useCentrifugeVaults(params?: VaultsQueryParams, apiClient?: CentrifugeAPIClient)
usePoolVaults(poolId: string | undefined, apiClient?) // sugar for { poolId }
useActiveVaults(params?, apiClient?) // sugar for { isActive: true }
Deprecated: Centrifuge holdings hooks
The following are deprecated since 2.3.0 (still work, @deprecated-tagged; removal planned v3.0.0). Prefer useVaultAssetDistribution — note this is not a mechanical rename, see Migration.
All Centrifuge hooks: staleTime 30 s, gcTime 5 min. They construct their own CentrifugeAPIClient (default https://api.centrifuge.io) if none is passed — they work even without config.centrifugeAPI.
Utility hooks¶
useUserAddress(): Address | null— the connected wallet address from the wallet adapter (async resolved into state;nullwhile unknown/disconnected).useWriteTransaction()— the low-level primitive behind every write hook: exposesexecute(tx: TransactionRequest): Promise<Hash>(sends via wallet adapter, sets'confirming', waits for the receipt) plus thetxState/txHash/error/resetmachinery. Exported for building custom flows.useVaultContext(): VaultContextValue— escape hatch to{ config, walletAdapter, publicClient, arkonixAPIClient?, centrifugeAPIClient? }.
Hooks summary¶
| Hook | Key params | Purpose |
|---|---|---|
useVaultMetadata(vault) |
address | On-chain metadata: asset, share, decimals, type, TVL |
useVaultUserState(vault, share, assetDecimals, type) |
from metadata | Position + all pending/claimable states; polls every 10 s |
useDeposit(vault, asset, assetDecimals, type) |
from metadata | Allowance check + approve + deposit/requestDeposit |
useClaimDeposit(vault) |
— | Claim shares after async deposit epoch |
useRequestRedeem(vault) |
— | Request async redeem |
useClaimRedeem(vault) |
— | Claim assets after redeem epoch |
useCancelRedeem(vault) |
— | cancelRedeem() + claimCancelRedeem() |
useCancelDeposit(vault, type) |
type required |
cancelDeposit() + claimCancelDeposit(); ASYNC only |
useVaultFinancials(vault) |
address | NAV/TVL, share price, returns, shareClassId |
useReturnHistory(scId, { days }) |
share-class id | Return headlines + points series |
useTvlHistory(scId, { days }) |
share-class id | TVL time series |
useSharePriceHistory(vault) |
address | On-chain share-price events |
useVaultTransactions(vault, { userAddress }) |
needs userAddress |
User activity + pending requests |
useVaultAssetDistribution(scId) |
share-class id | Holdings with pctOfTvl weights |
useShareClassFees(scId) |
share-class id | Mgmt + perf fee rates (returns already net) |
useCentrifugeVaults / usePoolVaults / useActiveVaults |
Centrifuge ids | Vault discovery |
useCentrifugeHoldings / useVaultHoldings / usePoolHoldings |
Centrifuge ids | Deprecated legacy holdings |
useUserAddress() |
— | Connected wallet address |
useWriteTransaction() |
— | Low-level tx primitive |
useVaultContext() |
— | Raw context access |