grep3/merkletree

Merkle Tree API

Generate cryptographic merkle trees for gasless airdrops and allowlists. Upload raw arrays or CSV files, retrieve verifiable proofs for on-chain claims. Powered by grep3.

On-Chain Verifiable Async Processing CSV & JSON Input

How It Works

1
Submit Data
POST raw JSON or CSV file to /generate
2
Queue Job
Receive job UUID, processing begins async
3
Build Tree
grep3 creates merkle tree from data
4
Get Proofs
Query proofs by root hash & unique ID
Data Format Requirements
  • Each row is an array of string values: [["id1", "val1", "val2"], ["id2", "val3", "val4"]]
  • First element of each row must be a unique identifier
  • All values are treated as strings for maximum flexibility
  • CSV files are parsed with relaxed column counts supported

API Endpoints

POST /generate/raw

Generate a merkle tree from raw JSON array data. Each sub-array becomes a leaf, with the first element as the unique identifier.

{
  "data": [
    ["user_001", "100", "0x1234..."],
    ["user_002", "250", "0x5678..."],
    ["user_003", "75", "0x9abc..."]
  ]
}
Response
{
  "job_uuid": "550e8400-e29b-41d4-a716-446655440000"
}
POST /generate/file

Upload a CSV file to generate a merkle tree. Each row becomes a leaf, with the first column as the unique identifier.

cURL Example
# Upload CSV file
curl -X POST https://merkletree.grep3.com/generate/file \
  -F "file=@airdrop_data.csv"

# Response
{ "job_uuid": "550e8400-e29b-41d4-a716-446655440000" }
GET /status/:uuid

Check the processing status of a merkle tree generation job. Poll this endpoint until status is "complete".

Parameters
uuid string The job UUID returned from /generate endpoints
Created
{ "status": "created" }
Processing
{ "status": "processing" }
Complete
{ "status": "complete",
  "root_hash": "0x..." }
GET /proof/:root_hash/:unique_id

Retrieve the merkle proof for a specific leaf. Use this proof to verify inclusion on-chain in your smart contract.

Parameters
root_hash string The merkle root hash returned after job completion
unique_id string The unique identifier (first element) of the leaf to retrieve
Response
{
  "root_hash": "0x8a3552d60a98e0ade765adddad0a2e420ca9b1eef5f326ba7ab860bb4ea72c94",
  "unique_id": "user_001",
  "values": ["user_001", "100", "0x1234..."],
  "proof": [
    "0x5931b4ed56ace4c46b68524cb5bcbf4195f1bbaacbe5228fbd090546c88dd229",
    "0x1234567890abcdef..."
  ]
}

Quick Start

1 Submit your data
# Using cURL with raw JSON
curl -X POST https://merkletree.grep3.com/generate/raw \
  -H "Content-Type: application/json" \
  -d '{"data":[["addr1","100"],["addr2","200"],["addr3","150"]]}'

# Response: {"job_uuid":"abc123..."}
2 Poll for completion
# Check job status
curl https://merkletree.grep3.com/status/abc123...

# When complete: {"status":"complete","root_hash":"0x8a35..."}
3 Retrieve proofs
# Get proof for a specific address
curl https://merkletree.grep3.com/proof/0x8a35.../addr1

# Response includes the proof array for on-chain verification
{
  "proof": ["0x5931b4ed...", "0x1234..."],
  "values": ["addr1", "100"]
}
4 Verify on-chain in Solidity
Solidity Contract Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract Airdrop {
    bytes32 public immutable root;

    constructor(bytes32 _root) {
        root = _root;  // Set the root_hash from grep3 API
    }

    function claim(
        bytes32[] calldata proof,
        address addr,
        uint256 amount
    ) external {
        // Reconstruct the leaf using double-hash (standard merkle tree format)
        bytes32 leaf = keccak256(bytes.concat(
            keccak256(abi.encode(addr, amount))
        ));

        // Verify the proof from grep3 API
        require(MerkleProof.verify(proof, root, leaf), "Invalid proof");

        // Process the claim (transfer tokens, etc.)
    }
}
Important Notes
  • The proof array from the API response is passed directly to the contract
  • Leaf values must be encoded in the same order as submitted to the API
  • Uses double-hashing (keccak256(bytes.concat(keccak256(...)))) to prevent second preimage attacks
  • Store the root_hash in your contract at deployment or via a setter function

Use Cases

🎁

Token Airdrops

Generate merkle trees for allowlists. Users claim tokens by providing their proof, verified on-chain with minimal gas.

🔒

Allowlist Minting

NFT projects can verify wallet eligibility for presale mints without storing the entire list on-chain.

Data Verification

Prove specific data was part of a larger dataset without revealing the entire dataset. Ideal for audits.

🚀

Rollup Commitments

Batch multiple state transitions into a single merkle root for efficient layer 2 settlement.