Skip to main content
If you run a campaign on your own vault, this is usually the first thing to ship. It sits next to the deposit form you already have and answers the questions a depositor asks: is there a reward here, how much, for how long, and what have I earned so far. Deposits keep going through your own frontend; nothing about your deposit flow changes. This page assumes the client and helpers from Project Setup.

What It Shows

The Component

The badge finds the campaign by your vault’s address, on the chain the vault lives on. One request covers both the campaign and the connected wallet’s position: passing userAddress fills in userPosition.
components/reward-badge.tsx
Drop it next to your deposit form:
Style it however your vault page looks. The markup is deliberately bare.

When It Hides

The badge renders nothing rather than a misleading number. That covers four cases:
  • No live campaign on the vault. Before a campaign starts or after it ends, campaigns.active returns nothing for the target.
  • boostApyBps is null. It is null at zero TVL and briefly when the reward-token price feed lags. A live campaign showing 0.00% reads as broken.
  • The budget is spent. An open-ended campaign with budgetExhausted: true pays nothing until it is topped up.
  • The campaign requires Forwarder deposits. Discovery leaves those out by default, which is what you want: your own deposit form would not activate the position. See Forwarder Deposits if you do route through it.

Linking to Claims

The badge says when rewards are ready but does not claim them. Point “ready to claim” at wherever your app claims: a Claim Button under the badge for a single campaign, or a Rewards Panel for everything the wallet has earned. Claims happen on the reward chain, which may not be the chain your vault is on.

Variations

  • You were given a campaign ID. Swap the query for tbi.campaigns.get(id) and drop the select. That call has no userAddress, so read the earnings line from rewards.forUser instead; the Recipes page has that hook.
  • Uniswap v4 pools. Pools have no address to filter on. Fetch active campaigns on the chain and match target.poolId client-side; see Find Your Campaign.
  • A combined number. If your design wants one headline APR, label it as an estimate (“~18% total”) and keep the two lines underneath. The two APRs come from different sources and can each be null on their own.
  • A status line. “Ends in 3 days”, “Rewards paused”, or “Rewards ready to claim” as one string: see Campaign Status Line.

Keep Exploring

Display Campaign Stats

The fields behind the badge and the rules for showing them.

Claim Button

What “ready to claim” should lead to.

Recipes

Smaller pieces: status lines, runway, per-campaign earnings.