Skip to main content
This tutorial walks through claiming yield from the Yield Distributor. Yield is distributed in weekly periods; each period has its own merkle root on-chain and a matching leaf + proof per holder. By the end of this tutorial you’ll have claimed every unclaimed period for an address in a single loop.

View claim.ts on GitHub

Runnable script in the SDK repo.

1. Set up the config

Build a wagmi config with a private key account. (For browser/dApp usage, swap the private key for a connector like injected() from @wagmi/core.)
import { createConfig, http } from "@wagmi/core";
import { mainnet } from "@wagmi/core/chains";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const config = createConfig({
  chains: [mainnet],
  transports: { [mainnet.id]: http(process.env.ETH_RPC_URL) },
});

2. Fetch your periods

getPeriods resolves your leaves and proofs entirely client-side — it reads the YieldDistributor over your wagmi Config and pulls per-period merkle proofs from the public artifact endpoint. No API key needed. Periods still in the operator’s replace window (~24h post-publish) and expired periods are filtered out automatically; everything returned with status: "unclaimed" is safe to submit immediately.
import { getPeriods } from "@camino-treasury/sdk";

const { data: periods } = await getPeriods({
  config,
  chainId: mainnet.id,
  holder: account.address,
});

const unclaimed = periods.filter((p) => p.status === "unclaimed");

if (unclaimed.length === 0) {
  console.log("nothing to claim");
  process.exit(0);
}
Each entry carries { chainId, distributor, periodId, status, root, index, account, amount, proof } — everything the on-chain claim() needs. amount is raw 6-decimal C0 (use viem’s formatUnits for display).
The default artifact host is https://api.caminotreasury.com. Override per-call with apiUrl to point at a self-hosted mirror or, once artifacts are mirrored to a static CDN, a fully decentralized source:
await getPeriods({ config, chainId, holder, apiUrl: "https://my-host" });

3. Submit one claim per period

There’s no on-chain batch entrypoint, so a loop is the right shape. claim() returns the tx hash immediately; waitForTransactionReceipt blocks until the claim is mined.
import { waitForTransactionReceipt } from "@wagmi/core";
import { formatUnits } from "viem";
import { claim } from "@camino-treasury/sdk";

for (const p of unclaimed) {
  const hash = await claim({ config, account, period: p });
  await waitForTransactionReceipt(config, { hash });
  console.log(
    `claimed period ${p.periodId}: ${formatUnits(p.amount, 6)} C0  tx ${hash}`,
  );
}
msg.sender is unconstrained on the contract — the C0 is transferred to the account embedded in the leaf, not to whoever signs the transaction. This is what lets a relayer or sponsor pay gas while the holder still receives the funds.

What’s next