You have a storefront. Your most loyal customers hold your project's token. You want to give them a discount automatically. No coupon codes, no manual lists, no spreadsheet of wallet addresses.
Here is how to wire that up with a single API and about 20 lines of Express.js.
What we are building
A lightweight Express server that:
- Takes a customer's wallet address
- Checks whether they hold a specific token on any of 31 supported chains
- Returns the discount they qualify for
The API doing the heavy lifting is InsumerAPI. It handles the multi-chain lookup and returns a simple boolean: does this wallet meet the condition, yes or no? It never exposes raw balances to your server. Every response is signed with ECDSA P-256, so you can verify the result cryptographically.
Step 0: Grab a free API key
No credit card, no OAuth. One POST request:
curl -X POST \
https://us-central1-insumer-merchant.cloudfunctions.net/createDeveloperApiKey \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "appName": "my-discount-app", "tier": "free"}'
Response:
{
"success": true,
"key": "insr_live_6cc334d80d...",
"tier": "free",
"dailyLimit": 100,
"apiKeyCredits": 10
}
Save the key. The free tier gives you 100 daily reads and 10 verification credits to start.
Step 1: Scaffold
mkdir token-discounts && cd token-discounts
npm init -y
npm install express
Step 2: Build the server
Create server.js:
const express = require("express");
const app = express();
app.use(express.json());
const API = "https://us-central1-insumer-merchant.cloudfunctions.net/insumerApi";
const KEY = process.env.INSUMER_API_KEY;
const headers = { "Content-Type": "application/json", "X-API-Key": KEY };
app.post("/check-discount", async (req, res) => {
const { wallet, merchantId } = req.body;
// Check what discount this wallet qualifies for
const discountRes = await fetch(
`${API}/v1/discount/check?wallet=${wallet}&merchant=${merchantId}`,
{ headers }
);
const { data } = await discountRes.json();
if (!data.eligible) {
return res.json({ eligible: false, message: "No qualifying tokens found" });
}
res.json({
eligible: true,
totalDiscount: data.totalDiscount,
merchant: data.merchantName,
breakdown: data.breakdown.map((t) => ({
token: t.symbol,
tier: t.tier,
discount: t.discount,
})),
});
});
app.listen(3000, () => console.log("Discount server running on :3000"));
That is the whole thing. One API call, one response.
Step 3: Run it
INSUMER_API_KEY=insr_live_your_key_here node server.js
Test with curl:
curl -X POST http://localhost:3000/check-discount \
-H "Content-Type: application/json" \
-d '{"wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "merchantId": "BLUEMTN"}'
If the wallet holds qualifying tokens:
{
"eligible": true,
"totalDiscount": 12,
"merchant": "Blue Mountain Coffee",
"breakdown": [
{ "token": "SHIB", "tier": "Gold", "discount": 8 },
{ "token": "NOTE", "tier": "Holder", "discount": 4 }
]
}
If not:
{
"eligible": false,
"message": "No qualifying tokens found"
}
Going deeper: verify specific conditions with /v1/attest
The discount check is merchant-specific. If you need custom verification logic (like "does this wallet hold at least 10,000 of token X on Arbitrum?"), use the /v1/attest endpoint directly:
const attestRes = await fetch(`${API}/v1/attest`, {
method: "POST",
headers,
body: JSON.stringify({
wallet: "0xABC...123",
conditions: [
{
type: "token_balance",
contractAddress: "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE",
chainId: 1,
threshold: 10000,
label: "SHIB Gold",
},
{
type: "nft_ownership",
contractAddress: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D",
chainId: 1,
label: "BAYC holder",
},
],
}),
});
const { data } = await attestRes.json();
// data.attestation.pass -> true if ALL conditions met
// data.attestation.results -> [{ label: "SHIB Gold", met: true }, { label: "BAYC holder", met: false }]
// data.sig -> ECDSA P-256 signature (base64, 88 chars)
Up to 10 conditions per call, across any mix of the 31 supported chains. Each verification costs 1 credit ($0.04).
What is happening under the hood
The /v1/discount/check endpoint scans the customer's wallet across all chains where the merchant has configured tokens. It returns the tier and discount per token, but never raw balances. Your backend sees "SHIB, Gold tier, 8% off." It does not see "this wallet holds 847,293,019 SHIB." The financial data stays on-chain.
The /v1/attest endpoint is the lower-level primitive. It takes arbitrary conditions and returns booleans with an ECDSA signature. You can pass this signature to downstream systems (other APIs, smart contracts, audit logs) as cryptographic proof that the verification happened.
Both endpoints work across 31 blockchains: Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, BNB Chain, Solana, and 23 more. You do not pass a chain preference for discount checks. The API checks everywhere the merchant has tokens configured.
If you prefer AI agent tooling
InsumerAPI also ships as:
-
MCP Server:
npx -y mcp-server-insumerfor Claude, Cursor, and any MCP-compatible client. 16 tools covering all endpoints. npm -
LangChain toolkit:
pip install langchain-insumerfor Python agent frameworks. 6 tools plus HTTP wrapper. PyPI - GPT Actions: Import the OpenAPI spec into a Custom GPT. Already live in the GPT Store as InsumerAPI Verify.
These let AI agents autonomously discover merchants, verify tokens, and generate discount codes without writing integration code.
Links
- Developer docs
- OpenAPI 3.1 spec (16 endpoints)
- MCP Server (npm)
- LangChain SDK (PyPI)
- llms.txt (AI agent discovery)
Free to start. 10 verification credits included. Grab a key.
Top comments (0)