Skill instructions
insumer-attest13.2 KB
View saved version →
---
name: insumer-attest
description: >
Wallet auth via InsumerAPI: condition-based access with ES256-signed,
JWKS-verifiable boolean responses (token balances across 37 chains, plus NFT
ownership, EAS attestations, Farcaster IDs and other condition types). Use
when the user wants InsumerAPI to give a "verified yes or no" on whether a
wallet satisfies an on-chain condition, to gate a feature by what a wallet
holds with InsumerAPI, or to compose an InsumerAPI wallet_state signal in a
multi-issuer trust envelope. Read, evaluate, sign, in one call.
metadata:
version: "0.3.2"
author: InsumerAPI
---
# InsumerAPI Wallet Condition Attestation
**Boolean, not balance.** A signed `true`/`false` answering "does this wallet satisfy this condition right now?", never the underlying balance. The response is signed twice (ES256 and a post-quantum ML-DSA-65 signature) and verifiable offline against the public JWKS at `https://insumermodel.com/.well-known/jwks.json`. The signing key never leaves the issuer; anyone holding the JWKS can independently re-run the verification.
You send conditions in. You get cryptographically verifiable results out.
## The primitive
Wallet auth is the OAuth-equivalent for what a wallet holds. The pattern is **read → evaluate → sign**:
1. **Read**: InsumerAPI reads the wallet's on-chain state on the requested chain
2. **Evaluate**: wallet state is checked against the supplied condition
3. **Sign**: a boolean result is returned, ES256-signed, with a `conditionHash` for tamper detection and a block anchor for replay defense
**No secrets. No identity-first. No static credentials.** Token gating is one form of condition-based access; this is the general primitive.
## Capabilities
- Single-call attestation across 37 chains: 31 EVM, Solana, XRPL, Bitcoin, Tron, Stellar, Sui
- Up to 10 conditions per request: overall `pass` is `true` only if every condition is `true`
- Ten condition types: `token_balance`, `nft_ownership` (33 of 37 chains: EVM + Solana + XRPL), `eas_attestation` (Ethereum, Optimism, Polygon, Base, Arbitrum), `farcaster_id`, `evm_view_call` (single-address-argument view function returning bool; `contractAddress`, `chainId` and `selector` required, EVM chains only), `ratio_to_amount` (EVM chains only; `contractAddress`, `chainId`, `multiple` and `amount` required; met when the balance is at least `multiple` times `amount`), `ratio_to_supply` (EVM chains, ERC-20 contracts only; `contractAddress`, `chainId` and `minFraction` required, a fraction above 0 and up to 1; met when the balance is at least that share of total supply). On v2 keys `multiple`, `amount` and `minFraction` are decimal strings, like `threshold`. `erc8004_agent` (Base; `chainId` and `agentId` required), `erc7710_delegation` (Base; `chainId`, `delegationManager`, `expectedDelegator`, `delegation` required; max 3 per call, 5-minute expiry), `account_code` (EVM chains only; `expect` required: `"none"` for a plain key account with no code, `"eip7702"` for an EIP-7702 delegation designator, `"contract"` for any other code; optional `delegate`, only with `"eip7702"`, met only when the designator points at that address; a non-EVM `chainId` or a `delegate` with another `expect` is a `400`)
- Every response is signed twice: ES256 (`sig`, `kid`) and a post-quantum ML-DSA-65 signature (`pqSig`, `pqKid`, optional fields: check them when present). `format: "jwt"` adds an ES256 JWT (`jwt`) for standard JWT-library verification, with the same claims as a post-quantum JWT (`pqJwt`)
- Optional EIP-1186 Merkle proofs (`proof: "merkle"`) for 27 of the 31 EVM chains (not ZKsync Era, Sei, Viction or XDC Network, nor any non-EVM chain): storage proofs on token_balance and ratio_to_amount conditions, account proofs (`subject: "account_code"`) on account_code conditions, plus revocation-slot proofs for erc7710_delegation on the verified v1.3.0 manager
- 30-minute attestation TTL, 5 minutes when the request includes an `erc7710_delegation`
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 3 — file references are metadata, not package contents.
insumer-auth18.4 KB
View saved version →
---
name: insumer-auth
description: >
InsumerAPI wallet auth: get an InsumerAPI key, configure INSUMER_API_KEY,
check or top up InsumerAPI credits, or debug InsumerAPI 401/402/429 errors.
Covers four key paths: free (email), paid (Stripe), an agent's first key
paid on-chain, and an on-chain top-up of an existing key. The on-chain paths
need the user's explicit approval of every payment.
metadata:
version: "0.2.3"
author: InsumerAPI
---
# InsumerAPI Authentication
Wallet auth via InsumerAPI starts with an API key. The key authenticates the *caller*; the signing key that produces the boolean response stays with the issuer and never leaves. **Read → evaluate → sign.**
This skill covers **four** ways to get or extend a key. Pick the one that matches the caller and stop: don't push upsell copy into emitted code.
## Pick the right path
| Who's getting the key? | What they want | Path | Endpoint |
| ----- | ----- | ----- | ----- |
| **Human**, building or testing | Free starter access (10 free verifications plus 100 requests a day) | **Path 1: Free** | `POST /v1/keys/create` |
| **Human**, wants Pro/Enterprise tier | Higher limits, bulk credits, monthly billing | **Path 2: Paid (Stripe)** | <https://insumermodel.com/pricing/> for a new key; <https://insumermodel.com/developers/account/> to upgrade an existing one |
| **Agent** whose operator funds it, **first key** | Bootstrap with no email, sender wallet = identity | **Path 3: Agent onboarding (crypto)** | `POST /v1/keys/buy` |
| **Agent or human**, **already has a key** | Top up credits, keep the key/history/integrations | **Path 4: Top-up (crypto)** | `POST /v1/credits/buy` |
**Decision rule:** default to Path 1 (free). Use Path 3 or Path 4 only when the user, or the operator of an autonomous agent, has explicitly chosen to pay with crypto. Path 4 tops the key up in place: it keeps its history, tier, and integrations.
**Pay per call, with no key at all:** `POST /v1/attest`, `/v1/trust` and `/v1/trust/batch` accept x402. Called with no credential headers they answer `402 Payment Required` with a quote, not an error about credits. Pay the quote in USDC on Base, Polygon, Arbitrum, Arc or Solana and retry with the `PAYMENT-SIGNATURE` header; the quote carries the exact amount. The payer is charged only for a successful answer, and the payer sees the answer only after the payment settled. If a paid call answers `503`, retry the exact same request with the same payment header and do not sign a new authorization: on Arc the payment may still be settling, and the retry resolves to the same payment. Like the on-chain paths, it needs the user's explicit approval of the payment. The skills in this repo call with a key.
**Payments need explicit approval (never violate).** Paths 3 and 4 start with a real, irreversible transfer of funds. Never send, or prepare for signing, any payment unless the user has confirmed the amount, token, chain and recipient address in this session. This skill documents the calls; it does not authorize a payment.
## Reference values (do not hallucinate)
- **API base**: `https://api.insumermodel.com`
- **Auth header**: `X-API-Key: insr_live_...`
- **Purchases are paid in USDC only.** Payments on Bitcoin or Tron, and USDT or any other token, are refused with a `400`
- **Platform wallet, USDC on Ethereum, Base, Polygon, Arbitrum, Optimism or Avalanche**: `0xee432065474D2C852700f74e3fD81e2Bcc16a3D4`
- **Platform wallet, USDC on BNB Chain**: `0xAd982CB19aCCa2923Df8F687C0614a7700255a23`. This previous address also still takes USDC on the other EVM chains during the changeover; it takes no USDT
- **Platform wallet, USDC on Solana**: `8fyEGM5tRjMocKQWaVXyM2XvvnTxR3sWdrYtug2zeLX4`. The previous Solana address `6a1mLjefhvSJX1sEX8PTnionbE9DqoYjU6F6bNkT4Ydr` still takes USDC during the changeover; it takes no USDT
- **Volume discounts** (paths 3 and 4): $5–$99 → 25 credits per $1 ($0.04/credit), $100–$499 → 33 credits per $1 (about $0.03/credit), $500+ →
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 3 — file references are metadata, not package contents.
insumer-discount8.46 KB
View saved version →
---
name: insumer-discount
description: >
Token-holder discounts at InsumerAPI merchants: read a store's terms, check
what a wallet qualifies for (free), optionally prove control of the wallet
by signing an EIP-4361 message, and create a signed single-use discount code
(INSR-XXXXX). Use when the user or agent wants a holder discount at a store
in the InsumerAPI merchant directory, wants to know whether signing with the
wallet gets a bigger discount, or needs a discount in ACP or UCP checkout
format.
metadata:
version: "0.1.1"
author: InsumerAPI
---
# InsumerAPI Token-Holder Discounts
A store lists the tokens and NFTs it recognizes and the discount each earns. InsumerAPI reads the wallet, works out the discount, and issues a signed, single-use code (`INSR-XXXXX`, valid 30 minutes) that the store redeems. The store sees the code and the percentage, never the wallet or its balances.
**Two routes, the store sets the terms.**
- **Proven wallet:** the caller sends `walletProof`, a message signed by the wallet. The wallet gets the full discount its holdings earn (under the store's tiers and cap), without the unproven-wallet daily limit.
- **Unproven wallet:** no proof. The store decides what that gets: the same discount (the default), up to a lower percentage, or nothing, and optionally a daily limit per wallet.
Read the terms first, then decide whether signing is worth it.
## Setup
Get the API key from the `insumer-auth` skill, then:
```bash
export INSUMER_API_KEY='insr_live_...'
```
A code that carries a discount uses one credit from the API key that owns the store. A caller using another key is not charged; when the caller's key owns the store, the caller's key pays. A 0% result is free.
## Reference values (do not hallucinate)
- **API base**: `https://api.insumermodel.com`
- **Store terms**: `GET /v1/merchants/{merchantId}` → `data.walletTerms` (no key needed). The free check returns the same `walletTerms`, and also answers for a store that is not listed in the public directory
- **Free check**: `GET /v1/discount/check?merchant={merchantId}&wallet={0x...}` (no key needed)
- **Create a code**: `POST /v1/verify` with `X-API-Key` (also `POST /v1/acp/discount` and `POST /v1/ucp/discount` for checkout formats)
- **Validate a code**: `GET /v1/codes/{code}` (no key needed)
- **Proof message domain**: `api.insumermodel.com`
- **Proof message URI**: `https://api.insumermodel.com/v1/merchants/{merchantId}` (exactly this merchant)
- **Proof freshness**: signed within the last 5 minutes; every nonce used once
- **Proof wallets**: EVM wallets that sign with `personal_sign` (EIP-191). Smart-contract wallets are not accepted yet. Solana and XRPL wallets can still get the unproven terms.
## Usage
### Step 1: read the store's terms (free)
```bash
curl -s https://api.insumermodel.com/v1/merchants/acme-store
```
```json
"walletTerms": {
"proofAccepted": ["evm"],
"proven": { "maxDiscountsPerWalletPerDay": null },
"unproven": { "maxDiscount": 5, "maxDiscountsPerWalletPerDay": 10 }
}
```
`unproven.maxDiscount`: `null` = the same as proven, `0` = no discount without proof, otherwise at most that percent. `unproven.maxDiscountsPerWalletPerDay`: `null` = no limit.
### Step 2: check what the wallet qualifies for (free)
```bash
curl -s "https://api.insumermodel.com/v1/discount/check?merchant=acme-store&wallet=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
```
`totalDiscount` is what the wallet gets **without** proof. If `discountIfProven` is present, signing gets that instead. If it is absent, signing changes the discount by nothing (it still lifts the daily limit).
### Step 3 (optional): prove the wallet
Sign this exact message with the wallet, using `personal_sign`:
```
api.insumermodel.com wants you to sign in with your Ethereum account:
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Prove wallet for a discount.
URI: https://api.insumermodel.com/v1/merchants/acme-store
Version: 1
Chain ID: 1
Nonce: k3j9x2m8q1
IPreview of the first 4,000 characters. Read full instructions →
Referenced files: 2 — file references are metadata, not package contents.
insumer-hosted-tools5.24 KB
View saved version →
---
name: insumer-hosted-tools
description: >
How to use the InsumerAPI MCP tools this plugin connects to (the hosted
server at api.insumermodel.com/mcp, no key needed). Use when the user asks
to check if a wallet holds a token or an amount, whether a wallet owns an
NFT, whether a wallet is a registered ERC-8004 agent, for a wallet trust
profile, for InsumerAPI's signing keys or how to verify an attestation, for
compliance templates, or for a merchant's discount, and the insumer MCP
tools are available. Do not use for exact balances, prices, or sending
transactions. Explains the shared daily allowance and when to switch to the
REST skills with the user's own key.
metadata:
version: "0.1.1"
author: InsumerAPI
---
# InsumerAPI hosted tools
This plugin connects to InsumerAPI's hosted MCP server. The tools need no account and no key. Prefer them over the REST path in the other skills whenever they are available; the REST skills remain the reference for request shapes, response fields and verification.
**Boolean, not balance.** Every signed result says whether a wallet satisfies a condition right now. It never says how much the wallet holds.
## The ten tools
| Tool | What it does | Spends the allowance? |
| ---- | ------------ | --------------------- |
| `insumer_jwks` | The public signing keys: an ECDSA P-256 key under its kids, then the ML-DSA-65 post-quantum key | No |
| `insumer_attest` | Signed yes or no for 1 to 10 conditions on one wallet, across 37 chains | Yes |
| `insumer_compliance_templates` | Named EAS templates (Coinbase Verifications, Gitcoin Passport) usable as conditions | No |
| `insumer_wallet_trust` | Signed trust profile for one EVM wallet: 155 base checks across 27 chains in ten dimensions, held or not held, no score | Yes |
| `insumer_batch_wallet_trust` | Trust profiles for up to 10 wallets in one call | Yes, per wallet |
| `insumer_list_merchants` | The public merchant directory | No |
| `insumer_get_merchant` | One merchant's public profile: token tiers, NFT collections, discount mode | No |
| `insumer_list_tokens` | Registered tokens and NFT collections | No |
| `insumer_check_discount` | What discount a wallet would get at a merchant | No |
| `insumer_validate_code` | Whether an INSR-XXXXX discount code is valid | No |
## Rules for calling them
- **Quantities are decimal strings in display units.** `threshold: "100"` means 100 tokens, not base units. Never send `decimals`; the token's own decimals are read from the chain.
- **Chains.** EVM chains by numeric chain ID (1 Ethereum, 8453 Base, 137 Polygon, 42161 Arbitrum, 10 Optimism, 56 BNB Chain, and so on). Non-EVM by name: `solana`, `xrpl`, `bitcoin`, `tron`, `stellar`, `sui`. Each non-EVM chain needs its own wallet field (`solanaWallet`, `xrplWallet`, `bitcoinWallet`, `tronWallet`, `stellarWallet`, `suiWallet`).
- **Native coins.** `contractAddress: "native"` on every chain except Sui, where native SUI is the coin type `0x2::sui::SUI`.
- **NFTs** need the NFT contract address; `native` with `nft_ownership` is rejected.
- **Read the result, not the request.** Report `met` per condition and the overall `pass`. Quote the attestation ID, the `kid` and `pqKid`, and the block or ledger it was read at. Do not invent a balance; none is returned.
- **Verification.** Anyone can check a result offline with the `insumer-verify` package (npm and PyPI) against the keys from `insumer_jwks`. Match keys by `kid`, never by position. The `insumer-jwks-verify` skill has the details.
## The shared allowance
The hosted server runs on one shared allowance for the tools that produce signed results (`insumer_attest`, `insumer_wallet_trust`, `insumer_batch_wallet_trust`). When it is used up for the day, those tools return an error that says so; it resets at 00:00 UTC. The free tools keep working.
When that happens, or when the user needs more than occasional calls, key and credit management, or the merchant tools:
1. Tell the user plainly that th
Preview of the first 4,000 characters. Read full instructions →
insumer-jwks-verify14.5 KB
View saved version →
---
name: insumer-jwks-verify
description: >
Offline ES256 verification of InsumerAPI signed responses against the public
JWKS. Use when the user receives a signed attestation from /v1/attest,
/v1/trust, or /v1/trust/batch and needs to verify the signature without
trusting the JSON body. Covers both the JWT path (jose / PyJWT / go-jose) and
the raw sig path (ES256 over the canonical attestation/trust object).
metadata:
version: "0.2.1"
author: InsumerAPI
---
# InsumerAPI Offline JWKS Verification
The signed boolean is the product. The JSON body alone is untrusted: anyone can fabricate a JSON response. **Verify the signature, every time.**
InsumerAPI signs every `/v1/attest`, `/v1/trust`, and `/v1/trust/batch` response twice: with ES256 (ECDSA P-256) and with a post-quantum ML-DSA-65 signature. The public keys are published as a standard JWKS at `https://insumermodel.com/.well-known/jwks.json`. The signing key never leaves the issuer; anyone holding the JWKS can independently re-run the verification, with no callback to InsumerAPI.
## Reference values (do not hallucinate)
- **JWKS URL**: `https://insumermodel.com/.well-known/jwks.json`
- **Algorithm**: ES256 (ECDSA P-256)
- **Key IDs (`kid`)**: five JWKS entries over two keys. Three EC kids on the same P-256 key: `insumer-attest-v2` (attest, every key issued since 2026-06-10), `insumer-trust-v2` (trust), `insumer-attest-v1` (pre-cutover keys, and the commerce discount path). Then two RFC 9964 `AKP` entries for the ML-DSA-65 post-quantum key: `insumer-attest-pq1` and `insumer-trust-pq1`, selected by the response `pqKid`. Resolve by kid, never by position; fail closed on an unknown kid.
- **JWT issuer claim** (when `format: "jwt"` is requested): `https://api.insumermodel.com`
- **Raw signature format**: base64 P1363 (88 chars) on the `sig` field
## Two verification paths
InsumerAPI returns up to **two** verifiable forms in a signed response:
1. **`sig` field** (every response): base64 P1363 ES256 signature over the preimage the `kid` selects (see "What's signed" in `references/jwks-format.md`). Attestations: for `insumer-attest-v2`, the domain tag `insumer.attestation.v2` + newline + canonical JSON (keys sorted recursively, no whitespace) of `{v:2, id, pass, results, attestedAt}`; for `insumer-attest-v1`, `JSON.stringify({id, pass, results, attestedAt})` in that insertion order. Trust profiles: for `insumer-trust-v2`, the domain tag `insumer.trust.v2` + newline + canonical JSON of the whole `trust` object; for `insumer-attest-v1`, `JSON.stringify(trust)` as issued. Verify with any ES256 library + the JWKS key the `kid` names. Responses also carry `pqSig`/`pqKid`, a post-quantum ML-DSA-65 signature over the same preimage under a post-quantum domain tag (spec Check 6). The two fields are optional: a stored artifact without them reads as `absent`, which is not a failed signature.
2. **`jwt` field** *(`/v1/attest` only, and only when `"format": "jwt"` is in the request body; `/v1/trust` and `/v1/trust/batch` have no JWT form)*: standard ES256 JWT carrying the attestation as claims, beside `pqJwt`, the same claims under the post-quantum signature. Verify with any standard JWT library pointed at the JWKS URL.
The `jwt` path is easier when the consumer is already using a JWT library, and it signs the wallet as the `sub` claim. The raw `sig` path is more compact, but for most condition types it does not sign the wallet: it proves that some wallet met the condition, not which one. Use the JWT form (or an `erc8004_agent` / `erc7710_delegation` condition, which carry the wallet in the signed result) whenever the relying party must know which wallet was attested.
## Recipe 1: JWT verification (Node.js, `jose`)
Add `"format": "jwt"` to the `/v1/attest` request body (trust profiles have no JWT form; use Recipe 3), then:
```javascript
import { createRemoteJWKSet, jwtVerify } from 'jose';
const JWKS = createRemoteJWKSet(
new URL('https://insumermodel.com/.well-known/Preview of the first 4,000 characters. Read full instructions →
Referenced files: 2 — file references are metadata, not package contents.
insumer-trust13.3 KB
View saved version →
---
name: insumer-trust
description: >
InsumerAPI wallet trust profile: a curated multi-dimensional condition-based
access bundle for a single wallet. 155 base checks across 27 chains in 10
dimensions (stablecoins, governance, NFTs, staking, institutional
stablecoins, tokenized treasuries, stablecoin deposits, wrapped bitcoin,
names, account), plus optional Solana, XRPL, Bitcoin and Tron dimensions (up
to 176 checks across 29 chains in 14 dimensions). Use when the user wants an InsumerAPI
trust profile, a pre-built signed wallet snapshot rather than conditions
specified one by one (for example an InsumerAPI pre-transaction trust check). The profile is signed once, as a whole. Carry it unchanged:
never re-sign or wrap it.
metadata:
version: "0.3.1"
author: InsumerAPI
---
# InsumerAPI Wallet Trust Profile
A curated condition bundle for a single wallet. Same primitive as `insumer-attest` (read → evaluate → sign), but the conditions are pre-defined: 155 base checks across 27 chains in 10 dimensions, with optional cross-chain extensions. **Boolean, not balance, on every check.** Every row is a presence check.
Pick this skill when the developer wants a snapshot. Pick `insumer-attest` when they want to specify their own conditions.
## What you get
- **155 base checks** across **27 chains** in **10 dimensions** (23 EVM chains plus the Solana, XRPL, Stellar and Sui rows inside the base dimensions):
- **Stablecoins** (52): USDC, USDT, OUSD, PYUSD, USDG, USD1, RLUSD, USDS, DAI and EURC across 23 EVM chains, including USDC on Arc and USDG on Robinhood Chain
- **Governance** (8): UNI, AAVE, ENS, LDO, SKY and COMP on Ethereum, ARB on Arbitrum, OP on Optimism
- **NFTs** (3): BAYC, Pudgy Penguins, Wrapped CryptoPunks
- **Staking** (5): stETH, rETH, cbETH, wstETH, weETH
- **Institutional stablecoins** (8): EURCV, USDCV, USDC, and BENJI across Ethereum, Solana, XRPL, Stellar, and Sui. Always present; the Solana, XRPL, Stellar and Sui entries are evaluated only when the matching wallet is supplied, and are otherwise marked `evaluated: false`
- **Tokenized treasuries** (16): BUIDL, USYC, OUSG, USTB, USDY (the USDY on Sui row needs `suiWallet`, otherwise `evaluated: false`)
- **Stablecoin deposits** (39): Aave v3 aUSDC/aUSDT, sUSDS, sDAI, listed Morpho USDC vaults
- **Wrapped bitcoin** (12): cbBTC, WBTC, tBTC
- **Names** (2): ENS .eth, Basenames
- **Account** (10): two rows per chain on Ethereum, Base, Arbitrum, Optimism and Polygon. "Contract code on X" is met when bytecode other than the EIP-7702 delegation designator is at the wallet address; "EIP-7702 delegation on X" is met when the designator is there. The two are exclusive per chain; a plain key account reads false on both. Which contract is never named; to require a specific delegation target, send `delegate` with an `account_code` condition in `insumer-attest` (the answer is still yes or no). Each row's `evaluatedCondition` is `{type: "account_code", chainId, expect, operator: "code_state"}`, hashed exactly like the equivalent attest condition
- **Optional extensions** (when extra wallet addresses are provided):
- **Solana** (14): pass `solanaWallet` (USDC, EURC, OUSD, PYUSD, USD1, USDG, USDS, BUIDL, USDY, WBTC, cbBTC, tBTC, JitoSOL, mSOL on Solana)
- **XRPL** (3): pass `xrplWallet` (RLUSD, USDC, OUSG)
- **Bitcoin** (1): pass `bitcoinWallet` (native BTC)
- **Tron** (3): pass `tronWallet` (USDT, USD1, WBTC)
- **Stellar / Sui**: pass `stellarWallet` / `suiWallet`. These add no checks and no dimension; they let the Stellar and Sui rows inside the base dimensions be evaluated
- Up to 176 total checks across 29 chains in 14 dimensions when all extensions are included
- Each check returns its own boolean; the response includes per-dimension and overall summaries
- Dimension order is fixed: the base dimensions in the order above (`stablecoins`, `governance`, `nfts`, `staking`, `institutional_stablecoins`, `tokenized_treasuries`, `stablecoiPreview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
insumer-trust-batch11.2 KB
View saved version →
---
name: insumer-trust-batch
description: >
InsumerAPI batch wallet trust profiles: the same curated bundle as
insumer-trust, for up to 10 wallets in a single call. Use when the user wants
InsumerAPI trust profiles for a list of wallets (for example screening an
airdrop or allowlist with InsumerAPI). Each wallet's profile is independently
signed; the response supports partial success.
metadata:
version: "0.4.3"
author: InsumerAPI
---
# InsumerAPI Batch Wallet Trust Profile
Same curated condition-based access bundle as `insumer-trust` (155 base checks across 27 chains in 10 dimensions, up to 176 checks across 29 chains in 14 dimensions with the optional wallets; `conditionSetVersion` `"2026-10-08"`), but accepts up to **10 wallets** in one request. Each wallet's profile is independently signed; the response supports partial success: a failure for one wallet does not fail the rest.
Each wallet's profile is signed once, as a whole, by InsumerAPI, and signed twice: ES256 (`sig`, `kid`) and a post-quantum ML-DSA-65 signature (`pqSig`, `pqKid`). The `kid` is `insumer-trust-v2` on v2 keys and `insumer-attest-v1` on v1 keys: read it from each entry, never assume it. There are no per-dimension signatures and no signature over the batch. **Do not add an orchestrator wrap:** carry each signed profile exactly as issued.
## Setup
```bash
export INSUMER_API_KEY='insr_live_...'
```
## Reference values
- **Endpoint**: `POST https://api.insumermodel.com/v1/trust/batch`
- **Cost**: 3 credits per **successful** wallet (6 with `proof: "merkle"`). Failed wallets in the batch don't cost credits.
- **Max wallets per call**: 10
- **Profile ID format per wallet**: `TRST-XXXXX`
## Request shape
`wallets` is an **array of objects**, each with a required `wallet` field plus optional cross-chain wallet fields. (Not an array of plain strings.)
```json
{
"wallets": [
{
"wallet": "0x1601843c5E9bC251A3272907010AFa41Fa18347E",
"solanaWallet": "DXK4yMpigbTSqv33nJk1tJucXB4E3rDmTXn3yZmiFAXt"
},
{ "wallet": "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb" }
]
}
```
| Field per entry | Required | Notes |
|---|---|---|
| `wallet` | yes | EVM address, `0x` + 40 hex chars |
| `solanaWallet` | optional | Adds the 14-check `solana` dimension to this wallet's profile and evaluates the Solana rows in institutional stablecoins |
| `xrplWallet` | optional | Adds the `xrpl` dimension (RLUSD, USDC, OUSG) and evaluates the XRPL row in institutional stablecoins |
| `bitcoinWallet` | optional | Adds the `bitcoin` dimension (native BTC) |
| `tronWallet` | optional | Adds the `tron` dimension (USDT, USD1, WBTC) |
| `stellarWallet` | optional | Evaluates the Stellar rows in the institutional stablecoins dimension; adds no dimension |
| `suiWallet` | optional | Evaluates the Sui rows (USDC in institutional stablecoins, USDY in tokenized treasuries); adds no dimension |
Top-level `proof: "merkle"` (optional) applies to all wallets in the batch and costs up to 6 credits per successful wallet (3 for a wallet whose profile carried no proof; a failed wallet costs nothing).
## Response shape
Abbreviated; the profile ids and counts are from real profiles of the two wallets above, and the batch totals are those of a two-wallet call (the first with its Solana wallet, so its profile has 11 dimensions and 169 checks; the second has the 10 base dimensions and 155 checks):
```json
{
"ok": true,
"data": {
"results": [
{
"trust": {
"id": "TRST-74167",
"wallet": "0x1601843c5E9bC251A3272907010AFa41Fa18347E",
"conditionSetVersion": "2026-10-08",
"dimensions": { ... },
"summary": { "totalChecks": 169, "totalPassed": 17, "totalFailed": 147, "totalNotEvaluated": 5, "dimensionsWithActivity": 4, "dimensionsChecked": 11 },
"profiledAt": "2026-10-07T21:53:03.720Z",
"expiresAt": "2026-10-07T22:23:03.720Z"
},
"sig": "...",
"kid": "insumer-truPreview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.