Skip to content

Distribute Rewards

Distribute rewards to token holders using TIP-20's built-in reward distribution mechanism. Rewards allow parties to incentivize holders of a token by distributing tokens proportionally based on their balance.

Rewards can be distributed by anyone on any TIP-20 token, and claimed by any holder who has opted in. This guide covers both the reward distributor and token holder use cases. While the demo below uses a token you create, the same principles apply to any token.

Demo

Try out the complete rewards flow: create a token, opt in to receive rewards on it, create a reward for yourself, and claim it.

Distribute Rewards

demo
1
Create an account, or use an existing one.
2
Add testnet funds to your account.
3
Create & deploy a token to testnet.
4
Grant issuer role on token.
5
Mint 100 tokens to yourself.
6
Opt in to receive token rewards.
7
Start a reward of 50 tokens.
8
Claim your rewards.
pnpx gitpick tempoxyz/tempo-ts/tree/main/examples/issuance

Steps

[Optional] Create a Stablecoin

If you would like to distribute rewards on a token you have created, follow the Create a Stablecoin guide to deploy your token.

Tell Your Users to Opt In to Rewards

Token holders must opt in to receive rewards by setting their reward recipient address. This is typically set to their own address.

OptInToRewards.tsx
import React from 'react'
import { Hooks } from 'tempo.ts/wagmi'
import { useConnection } from 'wagmi'
 
export function OptInToRewards() {
  const { address } = useConnection()
  const tokenAddress = '0x...' // Your token address
 
  const setRecipient = Hooks.reward.useSetRecipientSync()
 
  const handleOptIn = () => { 
    if (!address) return
    setRecipient.mutate({ 
      recipient: address, 
      token: tokenAddress, 
    }) 
  } 
 
  return (
    <button 
      disabled={setRecipient.isPending}
      onClick={handleOptIn}
      type="button"
    >
      {setRecipient.isPending ? 'Opting in...' : 'Opt In to Rewards'}
    </button>
  )
}

Make a Reward Distribution

Anyone can make a reward distribution that allocates tokens to all opted-in holders proportionally based on their balance.

StartReward.tsx
import React from 'react'
import { Hooks } from 'tempo.ts/wagmi'
import { parseUnits } from 'viem'
 
export function StartReward() {
  const tokenAddress = '0x...' // Your token address
 
  const { data: metadata } = Hooks.token.useGetMetadata({
    token: tokenAddress,
  })
 
  const start = Hooks.reward.useStartSync()
 
  const handleStart = () => { 
    if (!metadata) return
    start.mutate({ 
      amount: parseUnits('50', metadata.decimals), 
      token: tokenAddress, 
    }) 
  } 
 
  return (
    <button
      disabled={start.isPending || !metadata}
      onClick={handleStart}
      type="button"
    >
      {start.isPending ? 'Starting...' : 'Start Reward'}
    </button>
  )
}

Your Users Can Claim Rewards

Once a reward is distributed, opted-in holders can claim their share.

ClaimReward.tsx
import React from 'react'
import { Hooks } from 'tempo.ts/wagmi'
 
export function ClaimReward() {
  const tokenAddress = '0x...' // Your token address
 
  const claim = Hooks.reward.useClaimSync()
 
  const handleClaim = () => { 
    claim.mutate({ 
      token: tokenAddress, 
    }) 
  } 
 
  return (
    <button
      disabled={claim.isPending}
      onClick={handleClaim}
      type="button"
    >
      {claim.isPending ? 'Claiming...' : 'Claim Rewards'}
    </button>
  )
}

Recipes

Watch for new reward distributions

Use useWatchRewardScheduled to listen for new reward distributions on a token. This is useful for updating your UI when a reward is distributed.

import { Hooks } from 'tempo.ts/wagmi'
 
function WatchRewards() {
  const tokenAddress = '0x...' // Your token address
 
  Hooks.reward.useWatchRewardScheduled({ 
    token: tokenAddress, 
    onRewardScheduled(args) { 
      console.log('New reward scheduled:', args) 
      // Update UI, refetch balances, show notification, etc. 
    }, 
  }) 
 
  return <div>Watching for reward distributions...</div>
}

Watch for reward opt-ins

Use useWatchRewardRecipientSet to listen for when users opt in to rewards by setting their recipient address. This is useful for tracking opt-in activity.

import { Hooks } from 'tempo.ts/wagmi'
 
function WatchOptIns() {
  const tokenAddress = '0x...' // Your token address
 
  Hooks.reward.useWatchRewardRecipientSet({ 
    token: tokenAddress, 
    onRewardRecipientSet(args) { 
      console.log('User opted in:', args) 
      // Update UI, track analytics, etc. 
    }, 
  }) 
 
  return <div>Watching for reward opt-ins...</div>
}

Learning Resources