Getting Started¶
Installation¶
Requirements¶
| Dependency | Kind | Version |
|---|---|---|
viem |
direct dependency | ^2.43.3 |
@tanstack/react-query |
direct dependency | ^5.90.12 |
react |
peer dependency (required) | >=18.0.0 |
react-native |
peer dependency (optional — RN apps only) | >=0.70.0 |
The package ships ESM + CJS + .d.ts (dist/index.js, dist/index.cjs, dist/index.d.ts / dist/index.d.cts) with sideEffects: false (tree-shakeable). Named exports only — there is no default export.
Quickstart: React hooks¶
1. Set up the providers¶
A QueryClientProvider (from @tanstack/react-query) must be above VaultProvider. If your app already uses react-query, reuse the existing provider — don't add a second. Wrap only the vault section of your app, not the whole app.
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>
Note
Without walletAdapter, the provider defaults to the injected window.ethereum wallet on web. Most partners already have a wallet stack (wagmi, RainbowKit, Privy) — see Wallet Integration for the recommended adapter setup. React Native apps must pass a custom adapter.
2. Read vault financials from an address alone¶
import { useVaultFinancials, useReturnHistory } from "@arkonix.xyz/arkonix-vault-sdk";
function VaultDashboard({ vaultAddress }: { vaultAddress: `0x${string}` }) {
const { data: fin, isLoading } = useVaultFinancials(vaultAddress);
const { data: history } = useReturnHistory(fin?.shareClassId, { days: 90 });
if (isLoading || !fin) return <div>Loading…</div>;
return (
<div>
<p>NAV (TVL): ${fin.tvlUsd.toLocaleString()}</p>
<p>Share price: {fin.sharePrice ?? "—"}</p>
{/* null ≠ 0: render a placeholder for insufficient history */}
<p>Return (7d): {fin.return7d != null ? `${fin.return7d}%` : "—"}</p>
<p>Return (all-time, annualized): {fin.returnAllTime != null ? `${fin.returnAllTime}%` : "—"}</p>
{history && <SparklineChart points={history.points} />}
</div>
);
}
Return fields are nullable and not APY
null means "not enough history" — never coerce it to 0. return7d/30d/90d are cumulative window returns, not annualized. Read Working with Financial Data before rendering any return figure.
3. Deposit¶
import { useDeposit, useVaultMetadata } from "@arkonix.xyz/arkonix-vault-sdk";
function DepositForm({ vaultAddress }: { vaultAddress: `0x${string}` }) {
const { data: meta } = useVaultMetadata(vaultAddress);
const [amount, setAmount] = useState("");
const { deposit, txState, error, reset } = useDeposit(
vaultAddress, meta?.asset, meta?.assetDecimals, meta?.vaultType,
);
return (
<div>
<input value={amount} onChange={(e) => setAmount(e.target.value)} placeholder="100" />
<button onClick={() => deposit(amount)} disabled={txState !== "idle"}>
{txState === "approving" ? "Approving…" :
txState === "pending" ? "Depositing…" :
txState === "confirming" ? "Confirming…" :
txState === "success" ? "Done!" : "Deposit"}
</button>
{error && <p style={{ color: "red" }}>{error}</p>}
</div>
);
}
useVaultMetadata is step 1 of every integration — it yields the asset, share, assetDecimals, shareDecimals, and vaultType that all other hooks take as parameters. For the full deposit/redeem/cancel lifecycle, see Deposit & Redeem Flows.
Quickstart: Standalone (no React)¶
All three core classes are static-method namespaces — never instantiated. They take a viem PublicClient and (for writes) a SendTransactionFn:
import { createPublicClient, http } from "viem";
import { arbitrum } from "viem/chains";
import { VaultReader, VaultActions } from "@arkonix.xyz/arkonix-vault-sdk";
const client = createPublicClient({ chain: arbitrum, transport: http(rpcUrl) });
// Bridge to any wallet: WalletConnect, Privy, ethers, a relayer…
const sendTransaction = async (tx) =>
myWallet.sendTransaction({ to: tx.to, data: tx.data, value: tx.value });
const meta = await VaultReader.getMetadata(client, vaultAddress);
const state = await VaultReader.getUserState(client, vaultAddress, userAddress, meta.vaultType, meta.assetDecimals);
const { depositHash } = await VaultActions.deposit(
client, sendTransaction, vaultAddress, "100", userAddress,
meta.asset, meta.assetDecimals, meta.vaultType,
);
await VaultActions.requestRedeem(client, sendTransaction, vaultAddress, "10", userAddress, meta.shareDecimals);
if (state.hasClaimableRedeem) {
await VaultActions.claimRedeem(client, sendTransaction, vaultAddress, state.claimableRedeemShares, userAddress);
}
Note
Unlike the hooks (which surface failures in error state), VaultActions methods throw on failure — wrap them in try/catch. See the Core Reference.
For standalone financial data, use ArkonixAPIClient.
Next steps¶
- Core Concepts — the ERC-7540 lifecycle, vault types, decimals
- Configuration — full
VaultSDKConfigand chain support - Wallet Integration — wagmi, React Native, custom adapters