Claim Rewards
This tutorial shows you how to implement reward claiming for Merkl programs in your application.
Overview
Claiming rewards involves:
- Fetching claim data (proof + transaction data) from the appropriate API
- Constructing or using pre-formatted transaction calldata
- Submitting the claim transaction onchain
- Handling the response and updating your UI
Prerequisites
- Understanding of Distribution Systems
- Familiarity with Fetching Rewards Data
- A web3 library (viem, ethers, web3.js)
- User's wallet connected to your app
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}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();
}{
"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
- Merkl Claim Docs: docs.merkl.xyz/integrate-merkl/app#claiming-user-rewards
- Legacy Rewards Lookup: rewards-legacy.morpho.org
- Example Code: morpho-org/merkl-morpho-recipe
