Getting started
Quickstart
Install the SDK, point it at a vault, and read its state. Then deposit.
Install
npm install @recurve/sdk viem
viem is a peer dependency. The SDK reuses the client you already have rather than
opening its own transport.
Connect
import {createPublicClient, createWalletClient, http} from "viem";
import {privateKeyToAccount} from "viem/accounts";
import {Recurve} from "@recurve/sdk";
const publicClient = createPublicClient({transport: http(RPC_URL)});
const recurve = new Recurve({
publicClient,
addresses: {
vault: "0x...",
governor: "0x...",
registry: "0x...",
},
});
Leaving out walletClient gives you a read-only instance. Write calls throw
immediately instead of failing partway through, which is what you want in an indexer.
Read a vault
const snap = await recurve.vault.snapshot();
snap.totalAssets // everything the vault owes depositors
snap.float // what can leave right now
snap.deployedAssets // committed to a live strategy
snap.sharePrice // assets per 1e18 shares
float and deployedAssets sum to totalAssets. A position
mid-unwind still belongs to depositors, so it stays counted.
Deposit
const walletClient = createWalletClient({
account: privateKeyToAccount(PRIVATE_KEY),
transport: http(RPC_URL),
});
const recurve = new Recurve({publicClient, walletClient, addresses});
await recurve.depositor.deposit(1_000_000n);
ERC20Votes weight is zero until delegated. A depositor who skips that step holds shares
that cannot veto anything, and only finds out during a live proposal. The SDK delegates for
you; pass {skipDelegate: true} if you delegate elsewhere.
Exit
const {instant, requestId} = await recurve.depositor.redeem(500_000n);
if (!instant) {
await recurve.depositor.claim(requestId);
}
Branch on instant rather than assuming. The float can move between reading it and
the transaction landing.