Core Concepts¶
Domain model: Pool → ShareClass → Vault¶
Vaults follow the Centrifuge model: Pool → ShareClass → Vault. A vault is identified by its on-chain address; it has a poolId and a vaultKind. A share class can have multiple vault deployments (possibly on multiple chains) — VaultFinancials.vaults lists the sibling deployments.
Two identifier types appear throughout the API:
- Vault address (
0x…, on-chain contract address) — keys everything on-chain and the address-only API endpoints (getVaultFinancials,getSharePriceHistory,getVaultTransactions). - Share-class id (hex string, e.g.
"0x0001…") — keys the share-class-scoped API endpoints (return history, TVL history, asset distribution, fees). You never need to know it in advance:useVaultFinancials(vaultAddress)/getVaultFinancials()returns it asshareClassId.
Vault types¶
Mapped from the on-chain vaultKind: 0 → 'ASYNC', any other value → 'SYNC_DEPOSIT_ASYNC_REDEEM'.
'ASYNC'— both deposit and redeem are asynchronous (ERC-7540 request → epoch → claim).'SYNC_DEPOSIT_ASYNC_REDEEM'— deposit is synchronous (plain ERC-4626deposit(), shares mint immediately); redeem is still asynchronous.
The ERC-7540 request → epoch → claim lifecycle¶
DEPOSIT (ASYNC): requestDeposit(assets) → [epoch] → deposit(assets) mints shares
DEPOSIT (SYNC_DEPOSIT...): deposit(assets) mints shares immediately (ERC-4626)
REDEEM (both types): requestRedeem(shares) → [epoch] → redeem(shares) returns assets
CANCEL DEPOSIT (ASYNC only): cancelDepositRequest() → [epoch] → claimCancelDepositRequest() returns assets
CANCEL REDEEM (both types): cancelRedeemRequest() → [epoch] → claimCancelRedeemRequest() returns shares
Key rules:
requestIdis always0— one request per user (controller) per vault.- Epoch execution is performed off-chain by the Arkonix operator. The SDK cannot trigger it; UIs must wait for the pending → claimable transition.
- Detecting transitions: poll
useVaultUserState— it auto-refetches every 10 s and exposeshasPending*/hasClaimable*booleans for every flow. - The "claim" of an async deposit is the ERC-4626
deposit(assets, receiver)call (this is intentional and standard-conformant — after the epoch,depositfulfills the request). - Cancel-deposit is ASYNC vaults only (sync deposits settle immediately; there is nothing to cancel). The SDK fails early with a clear error rather than reverting on-chain.
See Deposit & Redeem Flows for working examples of each stage.
Decimals — the most common integration mistake¶
Asset and share tokens have different decimals (e.g. USDC = 6, shares = 18).
- Asset amounts are parsed/formatted with
assetDecimals. - Share amounts are parsed/formatted with
shareDecimals. - Both come from
useVaultMetadata/VaultReader.getMetadata— always read them from there rather than hard-coding.
USDC is 18 decimals on BSC
Do not assume USDC is 6 decimals everywhere: native USDC on BNB Smart Chain (chainId 56) has 18 decimals. Hard-coding 6 will mis-parse amounts by 12 orders of magnitude. Always take assetDecimals from vault metadata.
The three data sources¶
| Source | What it provides | Config needed |
|---|---|---|
On-chain (viem PublicClient) |
Metadata, balances, pending/claimable request state, conversions, transactions | chainId + rpcUrl |
| Arkonix backend API (public, no auth) | NAV/TVL, share price, returns, history series, user activity, asset distribution, fees | arkonixAPI.baseUrl |
| Centrifuge GraphQL API | Vault discovery across the ecosystem; legacy holdings (deprecated) | optional centrifugeAPI (has default URL) |
NAV, returns, and share price are not on the vault contract — they come from the Arkonix backend, keyed by vault address or share-class id. See Configuration for how each source is enabled.