Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Claim Rewards

This tutorial shows you how to implement reward claiming for Merkl programs in your application.

Overview

Claiming rewards involves:

  1. Fetching claim data (proof + transaction data) from the appropriate API
  2. Constructing or using pre-formatted transaction calldata
  3. Submitting the claim transaction onchain
  4. Handling the response and updating your UI

Prerequisites

Claiming via Merkl

Merkl is the primary distribution system for current reward programs.

Step 1: Fetch Claim Data

Endpoint:
GET https://api.merkl.xyz/v4/claim?user={address}&chainId={chainId}
Example:
async function fetchMerklClaimData(
  userAddress: string,
  chainId: number
): Promise<MerklClaimData> {
  const response = await fetch(
    `https://api.merkl.xyz/v4/claim?user=${userAddress}&chainId=${chainId}`
  );
 
  if (!response.ok) {
    throw new Error(`Merkl API error: ${response.status}`);
  }
 
  return response.json();
}
Response Structure:
{
  "claim": {
    "user": "0x...",
    "tokens": ["0xTOKEN1", "0xTOKEN2"],
    "amounts": ["1000000000000000000", "2000000000000000000"],
    "proofs": [
      ["0xproof1a", "0xproof1b"],
      ["0xproof2a", "0xproof2b"]
    ]
  }
}

Step 2: Execute the Claim

Using viem:

import { createWalletClient, custom } from "viem";
import { mainnet } from "viem/chains";
 
const MERKL_DISTRIBUTOR = "0x3Ef3D8bA38EBe18DB133cEc108f4D14CE00Dd9Ae"; // Mainnet
 
async function claimMerklRewards(
  userAddress: string,
  chainId: number
) {
  // 1. Fetch claim data
  const claimData = await fetchMerklClaimData(userAddress, chainId);
 
  // 2. Setup wallet client
  const walletClient = createWalletClient({
    account: userAddress,
    chain: mainnet,
    transport: custom(window.ethereum),
  });
 
  // 3. Send claim transaction
  const hash = await walletClient.writeContract({
    address: MERKL_DISTRIBUTOR,
    abi: MERKL_ABI,
    functionName: "claim",
    args: [
      claimData.claim.user,
      claimData.claim.tokens,
      claimData.claim.amounts,
      claimData.claim.proofs,
    ],
  });
 
  // 4. Wait for confirmation
  const receipt = await walletClient.waitForTransactionReceipt({ hash });
 
  return receipt;
}
 
// Merkl Distributor ABI (claim function)
const MERKL_ABI = [
  {
    inputs: [
      { name: "user", type: "address" },
      { name: "tokens", type: "address[]" },
      { name: "amounts", type: "uint256[]" },
      { name: "proofs", type: "bytes32[][]" },
    ],
    name: "claim",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
] as const;

Step 3: Handle the Result

try {
  const receipt = await claimMerklRewards(userAddress, 1);
 
  if (receipt.status === "success") {
    console.log("✅ Merkl rewards claimed successfully!");
    // Update your UI to reflect claimed rewards
  } else {
    console.error("❌ Claim transaction failed");
  }
} catch (error) {
  console.error("Error claiming Merkl rewards:", error);
  // Show error message to user
}

For more details on Merkl claiming, see the official Merkl documentation.

Legacy Rewards (Pre-Merkl)

Resources