@tokemak/autopools
v0.2.1
Published
Headless SDK for Tokemak Autopools: read pool/user data and build unsigned transactions with plain [viem](https://viem.sh). No wagmi, no React, no API keys. Works in Node, workers, browsers — and is deliberately friendly to AI agents holding their own wal
Downloads
375
Readme
@tokemak/autopools
Headless SDK for Tokemak Autopools: read pool/user data and build unsigned transactions with plain viem. No wagmi, no React, no API keys. Works in Node, workers, browsers — and is deliberately friendly to AI agents holding their own wallets.
@tokemak/autopools → everything
@tokemak/autopools/queries → reads
@tokemak/autopools/transactions → unsigned transaction buildersConventions
- Every function takes a chain-bound viem
PublicClientfirst; the chain is derived from it. One function = one chain — aggregate across chains yourself withPromise.allSettled. - Functions throw typed errors (
TokemakSdkErrorsubclasses from@tokemak/sdk-core); empty results mean genuinely empty, never a swallowed failure. - Builders return unsigned transactions (
{ chainId, to, data, value, from }) that any wallet can sign. Nothing executes on its own. - Amounts are raw
bigint; slippage is basis points (default 50); USD prices are keyed by token address, never symbol.
Quickstart
import { createTokemakClient, sendTransaction } from "@tokemak/sdk-core";
import { getUserRewards } from "@tokemak/autopools/queries";
import {
prepareDeposit,
prepareClaimRewards
} from "@tokemak/autopools/transactions";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
const client = createTokemakClient({
chainId: 8453,
rpcUrl: process.env.MY_RPC
});
// Read: all claimable rewards for an address (one Lens call)
const rewards = await getUserRewards(client, { user: "0x..." });
// Build: deposit 1000 USDC into baseUSD and stake, in one router multicall
const plan = await prepareDeposit(client, {
autopool: "0x...baseUSD",
owner: account.address, // must be the tx sender — staking credits msg.sender
amount: 1_000_000_000n, // raw base-asset units
slippageBps: 50
});
// Sign & send with any wallet
const wallet = createWalletClient({
account,
chain: base,
transport: http(process.env.MY_RPC)
});
if (plan.approval) await sendTransaction(wallet, plan.approval); // only present when allowance is missing
await sendTransaction(wallet, plan.transaction);Withdrawing
import {
prepareWithdraw,
signPoolPermit
} from "@tokemak/autopools/transactions";
// Two-tx path (works for EOAs and contract wallets):
const plan = await prepareWithdraw(client, {
autopool: "0x...baseUSD",
owner: account.address, // must be the tx sender — the router burns msg.sender's shares
shares: 500_000_000_000_000_000_000n, // or `assets` for an exact base-asset amount
unstake: true // pull staked shares from the rewarder first if the wallet is short
// toAsset: "0x..." // optional zap-out to another token, or NATIVE_TOKEN_ADDRESS for ETH
});
if (plan.approval) await sendTransaction(wallet, plan.approval);
await sendTransaction(wallet, plan.transaction);
// Single-tx path for EOAs: sign a share permit instead of approving
const permit = await signPoolPermit(wallet, {
client,
autopool,
value: shares
});
const single = await prepareWithdraw(client, {
autopool,
owner,
shares,
permit
});
await sendTransaction(wallet, single.transaction);Things agents should know
prepareDepositrefuses pools/chains where deposits are disabled (DepositsDisabledError/PoolShutdownError, including pools with on-chain depositor allowlists) unless you passforce: true. Withdraw/unstake/claim (exits) are never gated.- With
stake: true(the default) you cannot set a customreceiver: the router'sstakeVaultTokencreditsmsg.senderon-chain, soownermust be the account that sends the transaction. Same for withdrawals —redeemburnsmsg.sender's shares. - EOAs can skip the approval transaction by signing an EIP-2612 permit (
signPoolPermitfor pool share tokens) and passing it to the builder. Contract wallets (e.g. Safe) use theapprovaltransaction in the plan instead. - Zap plans embed a swap quote that expires (~60s, see
plan.quote.expiration) — send promptly or rebuild. getUserNavHistory'snavEthis null on chains whose native token is not ETH (the subgraph's native pseudo-address series prices S on Sonic, MON on Monad, XPL on Plasma — not ETH) and when the chain's ETH price series is stale past ~3 days (Arbitrum's price index died 2026-04).navUsdkeeps using the nearest snapshot regardless of age so positions never vanish from the series.getAutopoolAllocationsis one whole-chain lens read (the Lens has no per-pool variant) — callers filter.debtValue*fields are base-asset denominated (the lens field is named...Ethbut is not ETH). Genstrat pools (strategy = dead/zero address) have no on-chain composite returns; theirs come from the genstrat-aprs API, fetched only when the chain has one.exchangeNameis the raw lens string — protocol metadata/branding joins are app-side by design, as is hidden-symbol display policy.- Both
getAutopoolsandgetAutopoolAllocationsacceptincludeUnlisted: trueto also return pools the lens reports but the registry doesn't list (status.lifecycle === "unlisted", deposits gated off). - All built calldata carries Tokemak's ERC-8021 builder-code suffix automatically — except plan
approvallegs: plain ERC-20 approve stays exactly 68 bytes because Ledger's Ethereum app < 1.20.0 rejects longer approve calldata (0x6a80) and older Trezor firmware crashes on it. Attribution rides on the value-moving transaction.
Status
Full v1 surface. This package is the reference implementation of the product-package architecture — the conventions it instantiates live in .claude/rules/product-packages.md.
- Queries:
getAutopools,getAutopool,getAutopoolAllocations(destination-level detail +rollupByExchange/rollupByTokenexposure views),getAutopoolCreationTimes,getUserPositions,getUserPosition,getUserRewards,getUserHistory,getUserNavHistory(daily aggregate NAV series — distinct from the event-loggetUserHistory),getAutopoolHistory,getSwapQuote,getAutopilotRouter,getTokenPrices(re-export). - Transactions:
prepareDeposit(direct + zap + native ETH),prepareWithdraw(shares/assets, unstake, zap-out, native out,redeemWithRoutesdynamic-route upgrade),prepareStake,prepareUnstake,prepareClaimRewards,prepareApprove,signPoolPermit. - Verified against live mainnet + Base (
pnpm smoke).
