Skip to content

Configuration

VaultSDKConfig

interface VaultSDKConfig {
  chainId: number;
  rpcUrl: string;
  /** Arkonix backend API — source of NAV, returns, share price, history, activity, fees. */
  arkonixAPI?: {
    baseUrl: string;    // e.g. "https://api.arkonix.xyz"
    timeout?: number;   // ms, default 30000
  };
  /** Optional Centrifuge GraphQL API (vault discovery / legacy holdings). */
  centrifugeAPI?: {
    apiUrl?: string;    // default "https://api.centrifuge.io"
    timeout?: number;   // ms, default 30000
  };
}
  • If arkonixAPI is omitted, all financial-data hooks stay disabled and, if invoked, error with: "Arkonix API not configured. Pass config.arkonixAPI.baseUrl to VaultProvider."
  • centrifugeAPI is optional in both senses — the client is only created when configured, and the Centrifuge hooks can also construct their own client with defaults.

VaultProvider

interface VaultProviderProps {
  config: VaultSDKConfig;
  children: React.ReactNode;
  walletAdapter?: WalletAdapter;   // custom wallet bridge (wagmi, Privy, WalletConnect, RN…)
}

Behavior:

  • Creates a viem PublicClient via createPublicClient({ chain, transport: http(config.rpcUrl) }). The chain object is resolved by getChain(config.chainId).
  • If no walletAdapter is passed: uses WebWalletAdapter (injected window.ethereum) on web, or RNWalletAdapter (a stub that throws "pass a custom walletAdapter") on React Native. React Native apps must pass a custom adapter. See Wallet Integration.
  • Creates ArkonixAPIClient / CentrifugeAPIClient only when configured.
  • All of it is memoized on [config, customWalletAdapter] — keep the config object referentially stable (e.g. define it outside the component or useMemo it).

Unsupported chainId silently falls back to Arbitrum

If config.chainId is not one of the supported chains, getChain returns no match and the provider silently falls back to Arbitrum One (DEFAULT_CHAIN, chainId 42161). No error is thrown — reads and writes will target Arbitrum, not the chain you intended. Validate your chainId with isChainSupported(chainId) before passing it.

Provider placement rules

  1. Wrap only the vault section of the app, not the whole app.
  2. A QueryClientProvider (from @tanstack/react-query) must be above VaultProvider. If the app already uses react-query, reuse the existing provider — don't add a second.
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { VaultProvider } from "@arkonix.xyz/arkonix-vault-sdk";

const queryClient = new QueryClient();

<QueryClientProvider client={queryClient}>
  <VaultProvider
    config={{
      chainId: 42161,
      rpcUrl: "https://arb1.arbitrum.io/rpc",
      arkonixAPI: { baseUrl: "https://api.arkonix.xyz" },
    }}
  >
    <VaultWidget />
  </VaultProvider>
</QueryClientProvider>

Supported chains

Chain chainId Notes
Ethereum mainnet 1
Base 8453
Arbitrum One 42161 default chain (DEFAULT_CHAIN_ID = 42161)
BNB Smart Chain 56 native USDC has 18 decimals on BSC — see Concepts
HyperEVM 999 no canonical USDC address registered in the SDK

Chain and contract helpers

All exported from the package root:

getChain(chainId: number): Chain | null            // viem Chain object or null
isChainSupported(chainId: number): boolean
getSupportedChainIds(): number[]                    // [1, 8453, 42161, 56, 999]
getContracts(chainId: number): ChainContracts | null // { USDC?: Address } convenience only
DEFAULT_CHAIN    // viem arbitrum chain object
DEFAULT_CHAIN_ID // 42161

Note

getContracts().USDC is a convenience. The SDK never relies on it for deposit/redeem — the deposit asset is always read on-chain from the vault via VaultReader.getMetadata().asset.