What It Does
- Fetches the proof for the wallet and campaign, treating a 404 as “nothing to claim” rather than an error.
- Switches the wallet to the reward chain if it is somewhere else.
- Simulates the claim before asking for a signature, so a revert becomes a readable message instead of a failed transaction.
- Submits and waits for the receipt.
- Marks the row claimed locally instead of re-fetching, because the API can trail the chain by a few minutes.
The Component
components/claim-button.tsx
Where the Amount Comes From
The button readsclaimable from the proof endpoint, not from the rewards list that renders the row around it. Only the proof is guaranteed to match what the contract will pay. A button driven by accumulatedRewards over-promises and reverts with InvalidProof(). See Show User Rewards.
Why Simulate
tbi.claim.simulate runs an eth_call and needs no signature, so it costs one RPC round trip and no wallet prompt. Every revert the contract can produce has a name, and revertReason carries it. The list is in Contracts.
After the Claim
TheonSuccess handler above writes the settled state into the cache directly. The next natural refresh, a page load or the rewards panel’s 60 second interval, picks up the real value once the API has caught up. If you need the authoritative answer immediately, read it from the chain; see Reading claim state on-chain.
Claim Everything at Once
A wallet with rewards in several campaigns on the same reward chain can settle all of them in one Multicall3 transaction.components/claim-all-button.tsx
claimAll finds every campaign with claimable rewards on that chain, drops the empty ones, and submits one transaction. It is all or nothing: one failing subcall reverts the batch, and it throws TbiClaimError before touching the wallet if nothing is claimable. Render it only when at least one row is claimable, and fall back to per-row buttons if you want partial success. Details in Claim Several Campaigns at Once.
Sponsoring Gas or Skipping viem
The claim pays itsuser argument, not the sender, so your own relayer can submit it. Use tbi.encodeClaim to get { to, data, value } and send it from any signer, account-abstraction stack, or Safe. See Non-viem Stacks.
Keep Exploring
Claim Rewards
The full flow, batching, and gas expectations.
Errors
Which errors to catch and which retry themselves.
Deposit Button
For campaigns that require a Forwarder deposit.