Skip to main content

langchain-insumer

LangChain tools for InsumerAPI -- wallet auth across 38 blockchains. Returns ECDSA-signed booleans without exposing wallet balances. Up to 10 conditions per request, each with its own chainId. Optional Merkle storage proofs for trustless verification.

In production: AsterPay — a regulated payments stack — runs live ERC-8183 agentic-commerce trust scoring on InsumerAPI. Case study.

Also available as: MCP server (27 tools, npm) | ElizaOS (10 actions, npm) | OpenAI GPT (GPT Store) | insumer-verify (client-side verification, npm)

Full AI Agent Verification API guide — covers all 38 chains, trust profiles, commerce protocols, and signature verification.

Install

pip install langchain-insumer

Get a key — no signup, no dashboard, no password

Two paths. Both return an insr_live_... key instantly with 10 verification credits and 100 reads/day. One free key per email.

curl -X POST \
  https://api.insumermodel.com/v1/keys/create \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "appName": "my-agent", "tier": "free"}'

Or enter your email on insumermodel.com — the key appears inline.

Already have a key? Manage usage, top up, or upgrade at insumermodel.com/developers/account/.

Quick Start

from langchain_insumer import InsumerAPIWrapper

# Reads the key from the INSUMER_API_KEY environment variable,
# so it never lands in source. Or pass api_key="insr_live_..." directly.
api = InsumerAPIWrapper()

# Verify a wallet holds >= 1 ETH (native balance; a condition the
# example wallet reliably meets, so your first call shows pass: true)
result = api.attest(
    wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    conditions=[
        {
            "type": "token_balance",
            "contractAddress": "native",
            "chainId": 1,
            "threshold": "1",
            "decimals": 18,
            "label": "ETH >= 1 on Ethereum",
        }
    ],
)

attestation = result["data"]["attestation"]
print(f"Pass: {attestation['pass']}")
for r in attestation["results"]:
    print(f"  {r['label']}: {'met' if r['met'] else 'not met'}")
print(f"Signature: {result['data']['sig']}")
print(f"Key ID: {result['data']['kid']}")

token_balance thresholds are decimal strings. Send "threshold": "1000", not 1000. Keys created from 2026-06-10 sign with kid: insumer-attest-v2, which preserves full precision and rejects a JSON number with a 400; older insumer-attest-v1 keys accept either. This wrapper coerces a number to a string for you, but the string form is canonical.

What you get back

{
  "ok": true,
  "data": {
    "attestation": {
      "id": "ATST-A7C3E1B2D4F56789",
      "pass": true,
      "results": [
        {
          "condition": 0,
          "met": true,
          "label": "ETH >= 1 on Ethereum",
          "type": "token_balance",
          "chainId": 1,
          "evaluatedCondition": {
            "chainId": 1,
            "contractAddress": "native",
            "operator": "gte",
            "threshold": "1",
            "type": "token_balance"
          },
          "conditionHash": "0x8a3b...",
          "blockNumber": "0x129e3f7",
          "blockTimestamp": "2026-02-28T12:34:56.000Z"
        }
      ],
      "passCount": 1,
      "failCount": 0,
      "attestedAt": "2026-02-28T12:34:57.000Z",
      "expiresAt": "2026-02-28T13:04:57.000Z"
    },
    "sig": "XUb5ZPUW...(base64 P1363 ECDSA P-256 signature)...",
    "kid": "insumer-attest-v2"
  },
  "meta": { "version": "1.0", "timestamp": "2026-02-28T12:34:57.000Z", "creditsRemaining": 99, "creditsCharged": 1 }
}

No balances. No amounts. Just a signed true/false per condition.

Wallet Auth (JWT)

Add format="jwt" to receive the attestation as a standard JWT bearer token:

result = api.attest(
    wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    conditions=[...],
    format="jwt"
)

print(result["data"]["jwt"])  # ES256-signed JWT

The response includes an additional jwt field. This token is verifiable by any standard JWT library via the JWKS endpoint at GET /v1/jwks — compatible with Kong, Nginx, Cloudflare Access, AWS API Gateway, and other JWT middleware.

XRPL Verification

# Verify native XRP balance
result = api.attest(
    xrpl_wallet="rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
    conditions=[
        {
            "type": "token_balance",
            "contractAddress": "native",
            "chainId": "xrpl",
            "threshold": "100",
            "label": "XRP >= 100",
        }
    ],
)

# Verify RLUSD trust line token
result = api.attest(
    xrpl_wallet="rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
    conditions=[
        {
            "type": "token_balance",
            "contractAddress": "rMxCKbEDwqr76QuheSUMdEGf4B9xJ8m5De",
            "chainId": "xrpl",
            "currency": "RLUSD",
            "threshold": "10",
            "label": "RLUSD >= 10 on XRPL",
        }
    ],
)

# Wallet trust profile with XRPL dimensions
result = api.wallet_trust(
    wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    xrpl_wallet="rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
)

XRPL attestation results include ledgerIndex and ledgerHash (validated ledger hash) instead of blockNumber/blockTimestamp. Trust line token results also include trustLineState: { frozen: bool } — a frozen trust line causes met: false regardless of balance. Native XRP results include ledgerHash but not trustLineState.

Verify the Response

The attestation is ECDSA-signed. Your application should verify it before trusting it. Use insumer-verify in your Node.js backend or browser:

npm install insumer-verify
import { verifyAttestation } from "insumer-verify";

// attestationResponse = the full API envelope {ok, data: {attestation, sig, kid}, meta}
// Do NOT pass attestationResponse.data — the function expects the outer envelope
const result = await verifyAttestation(attestationResponse, {
  jwksUrl: "https://insumermodel.com/.well-known/jwks.json",
  maxAge: 120,
});

if (result.valid) {
  // Signature verified, condition hashes match, not expired
  console.log("Attestation verified");
} else {
  console.log("Verification failed:", result.checks);
}

This verifies the ECDSA P-256 signature, condition hash integrity, block freshness, and attestation expiry. The signing key is fetched from the JWKS endpoint and matched by kid, so it handles key rotation automatically.

With a LangChain Agent

from langchain_insumer import InsumerAPIWrapper, InsumerAttestTool
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

api = InsumerAPIWrapper(api_key="insr_live_your_key_here")
tools = [InsumerAttestTool(api_wrapper=api)]

llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
    ("system", "You verify on-chain token holdings using InsumerAPI."),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)
result = executor.invoke({"input": "Does vitalik.eth hold at least 100 USDC on Ethereum?"})
print(result["output"])

Without an agent (no LLM required)

Every tool can be invoked directly. Note that InsumerAttestTool takes conditions as a JSON string (the schema an LLM fills), so serialize the list first:

import json
from langchain_insumer import InsumerAPIWrapper, InsumerAttestTool, InsumerCreditsTool

api = InsumerAPIWrapper()  # reads INSUMER_API_KEY

print(InsumerCreditsTool(api_wrapper=api).run({}))

attest = InsumerAttestTool(api_wrapper=api)
print(attest.run({
    "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "conditions": json.dumps([
        {"type": "token_balance", "contractAddress": "native",
         "chainId": 1, "threshold": "1", "decimals": 18,
         "label": "ETH >= 1"}
    ]),
}))

Available Tools (26)

Verification

Tool Description Credits
InsumerAttestTool Verify on-chain conditions (token balances, NFT ownership, EAS attestations, Farcaster identity). Optional proof="merkle" for EIP-1186 Merkle proofs. 1/call (2 with merkle)
InsumerComplianceTemplatesTool List available EAS compliance templates (Coinbase Verifications on Base, Gitcoin Passport on Optimism). Free
InsumerWalletTrustTool Generate wallet trust fact profile (36 base checks, 4 dimensions; up to 40 across 7 dimensions with optional Solana, XRPL, and Bitcoin). 3/call (6 with merkle)
InsumerBatchWalletTrustTool Batch trust profiles for up to 10 wallets. 5-8x faster. Each wallet can include optional solanaWallet and xrplWallet. 3/wallet (6 with merkle)
InsumerVerifyTool Create signed discount code (INSR-XXXXX), valid 30 min. 1/call
InsumerConfirmPaymentTool Confirm USDC payment for a discount code. Free
InsumerJwksTool Get ECDSA P-256 public signing key (JWKS). Free

Discovery

Tool Description Credits
InsumerListMerchantsTool Browse merchant directory, filter by token/status. Free
InsumerGetMerchantTool Get full public merchant profile with tier structures. Free
InsumerListTokensTool List registered tokens and NFTs, filter by chain/symbol. Free
InsumerCheckDiscountTool Calculate discount for a wallet at a merchant. Free

Credits

Tool Description Credits
InsumerBuyKeyTool Buy a new API key with USDC, USDT, or BTC (no auth required). Wallet becomes identity. --
InsumerCreditsTool Check API key credit balance and tier. Free
InsumerBuyCreditsTool Buy API key credits with USDC, USDT, or BTC (25 credits/$1). --
InsumerBuyMerchantCreditsTool Buy merchant credits with USDC, USDT, or BTC (25 credits/$1). --

Merchant Onboarding

Tool Description Credits
InsumerCreateMerchantTool Create a new merchant (100 free credits). Free
InsumerMerchantStatusTool Get private merchant details (owner only). Free
InsumerConfigureTokensTool Configure token discount tiers (max 8 tokens). Free
InsumerConfigureNftsTool Configure NFT collection discounts (max 4). Free
InsumerConfigureSettingsTool Update discount mode, cap, USDC payments. Free
InsumerPublishDirectoryTool Publish merchant to public directory. Free

Domain Verification

Tool Description Credits
InsumerRequestDomainVerificationTool Request a verification token for a merchant's domain. Returns token and 3 methods (DNS TXT, meta tag, file upload). Free
InsumerVerifyDomainTool Complete domain verification after placing the token. Verified merchants get a trust badge. Free

Commerce Protocol Integration

Tool Description Credits
InsumerAcpDiscountTool Check discount eligibility in OpenAI/Stripe ACP format. Returns coupon objects and per-item allocations. 1/call
InsumerUcpDiscountTool Check discount eligibility in Google UCP format. Returns title, extension field, and applied array. 1/call
InsumerValidateCodeTool Validate an INSR-XXXXX discount code. Returns validity, discount percent, expiry. Free

Using All Tools

from langchain_insumer import (
    InsumerAPIWrapper,
    InsumerAcpDiscountTool,
    InsumerAttestTool,
    InsumerBatchWalletTrustTool,
    InsumerBuyCreditsTool,
    InsumerBuyKeyTool,
    InsumerBuyMerchantCreditsTool,
    InsumerCheckDiscountTool,
    InsumerComplianceTemplatesTool,
    InsumerConfigureNftsTool,
    InsumerConfigureSettingsTool,
    InsumerConfigureTokensTool,
    InsumerConfirmPaymentTool,
    InsumerCreateMerchantTool,
    InsumerCreditsTool,
    InsumerGetMerchantTool,
    InsumerJwksTool,
    InsumerListMerchantsTool,
    InsumerListTokensTool,
    InsumerMerchantStatusTool,
    InsumerPublishDirectoryTool,
    InsumerRequestDomainVerificationTool,
    InsumerUcpDiscountTool,
    InsumerValidateCodeTool,
    InsumerVerifyDomainTool,
    InsumerVerifyTool,
    InsumerWalletTrustTool,
)

api = InsumerAPIWrapper(api_key="insr_live_your_key_here")

tools = [
    InsumerAttestTool(api_wrapper=api),
    InsumerComplianceTemplatesTool(api_wrapper=api),
    InsumerWalletTrustTool(api_wrapper=api),
    InsumerBatchWalletTrustTool(api_wrapper=api),
    InsumerVerifyTool(api_wrapper=api),
    InsumerConfirmPaymentTool(api_wrapper=api),
    InsumerJwksTool(api_wrapper=api),
    InsumerListMerchantsTool(api_wrapper=api),
    InsumerGetMerchantTool(api_wrapper=api),
    InsumerListTokensTool(api_wrapper=api),
    InsumerCheckDiscountTool(api_wrapper=api),
    InsumerCreditsTool(api_wrapper=api),
    InsumerBuyKeyTool(api_wrapper=api),
    InsumerBuyCreditsTool(api_wrapper=api),
    InsumerBuyMerchantCreditsTool(api_wrapper=api),
    InsumerCreateMerchantTool(api_wrapper=api),
    InsumerMerchantStatusTool(api_wrapper=api),
    InsumerConfigureTokensTool(api_wrapper=api),
    InsumerConfigureNftsTool(api_wrapper=api),
    InsumerConfigureSettingsTool(api_wrapper=api),
    InsumerPublishDirectoryTool(api_wrapper=api),
    InsumerRequestDomainVerificationTool(api_wrapper=api),
    InsumerVerifyDomainTool(api_wrapper=api),
    InsumerAcpDiscountTool(api_wrapper=api),
    InsumerUcpDiscountTool(api_wrapper=api),
    InsumerValidateCodeTool(api_wrapper=api),
]

Merchant Onboarding Example

api = InsumerAPIWrapper(api_key="insr_live_your_key_here")

# 1. Create merchant
merchant = api.create_merchant(
    company_name="My Coffee Shop",
    company_id="my-coffee-shop",
    location="New York",
)

# 2. Configure token tiers
api.configure_tokens(
    merchant_id="my-coffee-shop",
    own_token={
        "symbol": "COFFEE",
        "chainId": 8453,
        "contractAddress": "0x...",
        "decimals": 18,
        "tiers": [
            {"name": "Bronze", "threshold": 100, "discount": 5},
            {"name": "Gold", "threshold": 1000, "discount": 15},
        ],
    },
)

# 3. Publish to directory
api.publish_directory(merchant_id="my-coffee-shop")

Merkle Proof Example

# Request EIP-1186 Merkle storage proofs for trustless verification
result = api.attest(
    wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    proof="merkle",
    conditions=[
        {
            "type": "token_balance",
            "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
            "chainId": 1,
            "threshold": "1000",
            "decimals": 6,
            "label": "USDC >= 1000",
        }
    ],
)

# Each result includes a proof object
for r in result["data"]["attestation"]["results"]:
    proof = r.get("proof", {})
    if proof.get("available"):
        print(f"Block: {proof['blockNumber']}")
        print(f"Mapping slot: {proof['mappingSlot']}")
        print(f"Proof nodes: {len(proof['accountProof'])} account, {len(proof['storageProof'])} storage")
    else:
        print(f"Proof unavailable: {proof.get('reason')}")

Handling rpc_failure Errors

If the API cannot reach one or more blockchain data sources after retries, endpoints that produce signed attestations (create_attestation, wallet_trust, batch_wallet_trust) return ok: false with error code rpc_failure. No signature, no JWT, no credits charged. This is a retryable error — retry after 2-5 seconds.

Important: rpc_failure is NOT a verification failure. Do not treat it as pass: false. It means the data source was temporarily unavailable and the API refused to sign an unverified result.

result = api.attest(wallet="0x...", conditions=[...])
if not result.get("ok") and result.get("error", {}).get("code") == "rpc_failure":
    # Retryable — wait and retry
    print("RPC failure:", result["error"]["failedConditions"])

Supported Chains (38)

32 EVM chains + Solana + XRP Ledger + Bitcoin + Tron + Stellar + Sui. Includes Ethereum, Base, Polygon, Arbitrum, Optimism, BNB Chain, Avalanche, XDC, Robinhood Chain, and 23 more EVM. NFT ownership on 34 of the 38 (EVM + Solana + XRPL); Bitcoin, Tron, Stellar and Sui are token-balance only. Full list →

Get a key — no signup, no dashboard, no password

Generate one from your terminal:

curl -s -X POST https://api.insumermodel.com/v1/keys/create \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "appName": "LangChain Agent", "tier": "free"}' | jq .

Returns an insr_live_... key with 100 reads/day and 10 verification credits. One free key per email.

Or enter your email on insumermodel.com. Already have a key? Manage it at insumermodel.com/developers/account/.

Tiers: Free (100 reads/day, 10 credits) | Pro $9/mo (10,000/day) | Enterprise $29/mo (100,000/day)

Links

License

MIT

Release files for langchain-insumer 0.13.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchain-insumer 0.13.2
File Size Uploaded
langchain_insumer-0.13.2.tar.gz 35.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langchain-insumer 0.13.2
File Interpreter ABI Platform
langchain_insumer-0.13.2-py3-none-any.whl Python 3 none any Details

Total release size: 81.9 kB

Release files / langchain_insumer-0.13.2.tar.gz

Download URL langchain_insumer-0.13.2.tar.gz
Size 35.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4a5c1dcef11f94a8c77838e022074ed9942b9bac9f3cf7e7320fefa42402c33e
BLAKE2b-256 checksum
How to use checksums
bfd7cf39eb5ac5b92a112ccd227cd6db4a944c868835891c67faff0cf2cfebcd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / langchain_insumer-0.13.2-py3-none-any.whl

Download URL langchain_insumer-0.13.2-py3-none-any.whl
Size 46.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1cf6754453d0fda8e2a035b15f3730024bd1f1fc65f6de90a77e21bf91fcacac
BLAKE2b-256 checksum
How to use checksums
8c47a681f0ac707a7aa2a5256b4e1ecfeb1c333efeeb673f8a941cbddfaf4b44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.13.7

2 release files

0.13.6

2 release files

0.13.3

2 release files

This release

0.13.2 This release

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.8

2 release files

0.10.6

2 release files

0.10.5

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.22

2 release files

0.9.21

2 release files

0.9.20

2 release files

0.9.19

2 release files

0.9.18

2 release files

0.9.17

2 release files

0.9.16

2 release files

0.9.9

2 release files

0.9.8

2 release files

0.9.7

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page