Writing

5 min read

Merkl Rewards Integration for Web3 Apps

A deep dive into integrating the Merkl protocol into a modern Web3 application using Next.js. Explore API architecture, reward parsing, wallet interactions, Merkle proof claims, and scalable frontend engineering practices.

Merkl integrationMerkl APIMerkl rewardsNext.js Web3wagmi tutorialviem smart contract

Blockchain incentive programs have become a core part of the DeFi ecosystem, but integrating reward distribution into an existing application isn't always straightforward.

A production-ready implementation needs to display rewards accurately, provide a smooth claiming experience, and fit naturally into the application's existing architecture without introducing unnecessary complexity.

In one of my recent Web3 frontend projects, I implemented a complete integration with the Merkl rewards protocol.

The goal was to allow users to view and claim their on-chain rewards while keeping the implementation modular, scalable, and easy to maintain.

Rather than replacing an existing rewards system, the integration was designed as an independent module that could coexist with other claim mechanisms and be extended in the future.

What Is Merkl?

Merkl is a decentralized rewards distribution protocol used by DeFi protocols to incentivize on-chain activity.

Instead of storing claimable balances directly inside smart contracts, Merkl periodically computes user rewards and publishes them as a Merkle Tree.

Users then submit a Merkle proof to the Distributor contract to claim their rewards.

Understanding Merkl Reward Data

Each reward contains several important values:

  • amount: Total cumulative rewards in the current Merkle tree

  • claimed: Rewards already claimed on-chain

  • pending: Rewards earned but not yet included in a Merkle root

  • proofs: Merkle proofs required for claiming

How Claimable Rewards Are Calculated

One of the most important implementation details is understanding the reward calculation.

claimable = amount - claimed

The pending value represents rewards that have not yet been committed into a Merkle root and therefore cannot be claimed.

This distinction is essential for displaying accurate balances and preventing incorrect claim attempts.

Technology Stack

The integration was built using technologies already present in the application.

Frontend Technologies

  • Next.js with App Router

  • TypeScript

  • React

  • Tailwind CSS

Web3 Technologies

  • wagmi

  • viem

  • RainbowKit

One design goal was to avoid introducing additional dependencies. Everything was implemented using the existing frontend architecture.

High-Level Merkl Integration Architecture

The overall integration flow looks like this:

User Wallet
    │
    ▼
React UI
    │
    ▼
Custom React Hook
    │
    ▼
Next.js API Route
    │
    ▼
Merkl REST API
    │
    ▼
Reward Parsing
    │
    ▼
Claim Transaction
    │
    ▼
Distributor Smart Contract

Separating Responsibilities

The architecture intentionally separates responsibilities:

  • UI components display data

  • Custom hooks manage state and wallet interactions

  • Service functions communicate with external APIs

  • Server routes handle communication with external services

  • Smart-contract interactions remain isolated from presentation logic

This separation keeps the codebase easier to maintain as the application grows.

Why Use a Server Proxy?

One interesting challenge was that the browser could not directly communicate with the Merkl API because of the application's Content Security Policy (CSP).

Instead of relaxing browser security policies, I implemented a lightweight Next.js API route that acts as a proxy.

The browser communicates only with the application's backend, while the backend securely fetches data from the Merkl API.

Benefits of the API Proxy

This approach provides several advantages:

  • Maintains a strict Content Security Policy

  • Allows future authentication if required

  • Centralizes API handling

  • Simplifies frontend logic

  • Makes rate limiting easier to implement later

Building a Modular Rewards System

One of the primary goals was modularity.

Instead of scattering Merkl-related logic throughout the application, everything was isolated into its own feature module.

Example Feature Structure

merkl/
├── constants
├── types
├── service
├── utilities
├── hooks
└── components

This organization makes the integration easy to locate, test, extend, or remove without affecting unrelated reward systems.

Fetching and Processing Rewards

The frontend requests rewards through an internal API route.

The server then retrieves reward information from Merkl's public API and filters the response for the appropriate blockchain network and supported reward token.

Reward Information Used by the UI

After parsing the response, the frontend calculates:

  • Total rewards

  • Already claimed rewards

  • Currently claimable rewards

  • Pending rewards

  • Available Merkle proofs

When Should the Claim Button Be Enabled?

The UI only enables claiming when:

  • The claimable balance is greater than zero

  • Valid Merkle proofs are available

This prevents unnecessary failed transactions and improves the overall user experience.

The On-Chain Claim Flow

The claiming process follows a straightforward sequence.

Step-by-Step Claim Process

  1. The user connects their wallet.

  2. Reward data is loaded.

  3. The user initiates a claim.

  4. The application switches to the correct blockchain network if necessary.

  5. Merkle proof data is prepared.

  6. The Distributor contract is called.

  7. The transaction is confirmed.

  8. Reward data is refreshed.

Understanding the Cumulative Reward Amount

An important implementation detail is that the smart contract expects the cumulative reward amount, not only the currently claimable difference.

The contract itself calculates how much has already been claimed and transfers only the remaining rewards.

Using the cumulative amount ensures compatibility with the Distributor contract's accounting model.

User Experience Considerations

Good blockchain UX is often as important as the transaction itself.

The interface was designed to clearly communicate every possible reward state.

Reward States

The UI handles states such as:

  • Wallet not connected

  • No rewards available

  • Rewards fully claimed

  • Pending rewards awaiting the next Merkle root

  • Rewards available but missing proofs

  • Transaction pending

  • Successful claim

  • User-rejected transaction

  • Contract execution failure

Clear Error and Status Messages

Rather than displaying generic errors, each state provides context so users understand exactly what is happening.

This is particularly important in DeFi because users are interacting with financial assets and irreversible blockchain transactions.

Challenges During Development

Challenge 1: Browser Security Restrictions

The browser could not communicate directly with the external rewards API because of Content Security Policy restrictions.

Solution

A Next.js API proxy handled all external communication while keeping browser security intact.

Challenge 2: Correct Reward Calculations

Initially, it was tempting to treat all reported rewards as immediately claimable.

However, Merkl distinguishes between cumulative rewards, claimed rewards, and pending rewards.

Solution

The application explicitly computes:

claimable = amount - claimed

Pending rewards are displayed separately and are never treated as immediately claimable.

Challenge 3: Cache Refresh After Claim

Immediately after claiming, cached API responses may still show the previous reward state because indexing can take a short time.

Solution

After a successful transaction, the application performs a fresh reward fetch using cache-bypass logic so users receive updated information as soon as possible.

Challenge 4: Defensive Error Handling

Blockchain applications encounter many edge cases that traditional web applications do not.

Examples include:

  • Wallet disconnected

  • Wrong network

  • User rejects signature

  • Missing Merkle proofs

  • API unavailable

  • Smart contract reverts

Handling each scenario individually creates a much smoother user experience than relying on generic error messages.

Key Engineering Decisions

Several architectural decisions made the integration easier to maintain.

Modular Feature Structure

All Merkl-related functionality was isolated into a dedicated feature module rather than being distributed throughout the application.

Custom React Hooks

Custom hooks were used to manage reward state and wallet interactions without introducing unnecessary global state.

Server-Side API Proxy

The API proxy keeps external communication centralized and helps maintain the application's security policies.

Minimal Smart Contract Abstraction

Smart-contract interactions were kept focused and isolated instead of introducing a large abstraction layer for a relatively small integration.

Reusing Existing Web3 Libraries

Existing wagmi, viem, and RainbowKit dependencies were reused instead of adding unnecessary packages.

Strong TypeScript Typing

TypeScript types were applied across API responses, reward data, and contract interactions to reduce unexpected runtime issues.

Clear Separation of Responsibilities

Fetching, parsing, UI rendering, and contract execution were kept separate.

These decisions reduce long-term maintenance costs and make future enhancements easier.

Future Improvements

The current architecture provides a solid foundation while leaving room for additional features.

Multi-Token Reward Support

The system could be extended to support multiple reward tokens and display them independently.

Campaign-Level Reward Breakdown

Users could see which campaigns or activities generated their rewards.

Historical Reward Analytics

Historical data could provide users with insights into their reward earnings over time.

Additional Blockchain Networks

The modular structure makes it easier to support additional chains as required.

Enhanced Caching and Rate Limiting

Production environments could introduce more advanced caching and rate-limiting strategies to reduce unnecessary API requests.

Expanded Reward Dashboards

The rewards module could eventually include additional filtering, analytics, and portfolio-level reward views.

Final Thoughts

Integrating a Web3 rewards protocol involves much more than simply calling a smart contract.

A production-ready solution requires careful handling of API responses, blockchain transactions, caching, wallet interactions, security policies, and user experience.

This project reinforced the importance of building integrations that are modular, maintainable, and resilient to real-world edge cases.

By keeping responsibilities clearly separated and designing for future extensibility, the resulting implementation is easier to maintain and ready to evolve alongside the broader Web3 ecosystem.

References

Get practical Web3 & frontend tips

Short articles on Next.js, Web3 dashboards, and DeFi interfaces. No spam, unsubscribe anytime.

Want help implementing this on your product?

I work with crypto startups and product teams on Web3 dashboards, DeFi interfaces, and Next.js frontends — from architecture through launch. Hire me for web3 dashboard development.