JSPM

@insumermodel/mppx-token-gate

1.0.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 139
  • Score
    100M100P100Q84353F
  • License MIT

Condition-based access for mppx routes using signed wallet attestations — 33 chains, no RPC management

Package Exports

  • @insumermodel/mppx-token-gate

Readme

@insumermodel/mppx-token-gate

Add wallet auth to mppx routes using signed attestations. One API call checks token/NFT ownership across 30 EVM chains + Solana + XRPL + Bitcoin — no RPC management, no viem transports, no in-house balance checks.

How it works

mppx embeds the payer's identity in every payment credential as a DID string (credential.source: "did:pkh:eip155:8453:0xABC..."). tokenGate reads that address, calls InsumerAPI to check on-chain ownership, and short-circuits the payment flow for holders.

  1. Request arrives with a payment credential
  2. tokenGate extracts the payer address from credential.source
  3. InsumerAPI checks ownership and returns an ECDSA P-256 signed result
  4. Token holder → free receipt returned (reference: "token-gate🆓{attestationId}")
  5. Non-holder → delegates to the original verify (normal payment proceeds)

The attestation signature is verifiable offline via JWKS — downstream services can independently verify the gate decision.

Install

npm install @insumermodel/mppx-token-gate

Usage

import { Mppx, tempo } from 'mppx/server'
import { tokenGate } from '@insumermodel/mppx-token-gate'

const tempoCharge = tempo({
  currency: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  recipient: '0xYourAddress',
})

const gatedCharge = tokenGate(tempoCharge, {
  apiKey: process.env.INSUMER_API_KEY,
  conditions: [{
    type: 'nft_ownership',
    contractAddress: '0xYourNFT',
    chainId: 8453,        // Base
  }],
})

const mppx = Mppx.create({ methods: [gatedCharge] })

Works with any framework (Hono, Express, Elysia, Next.js) and any payment method (tempo, stripe) — it wraps Method.Server, so no middleware changes needed.

API key

Get a free key (instant, no signup):

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

Or set INSUMER_API_KEY as an environment variable.

Options

Option Type Default Description
apiKey string env.INSUMER_API_KEY InsumerAPI key
conditions TokenCondition[] Token/NFT conditions to check
matchMode 'any' | 'all' 'any' Whether holder must satisfy any or all conditions
cacheTtlSeconds number 300 In-memory ownership cache TTL
jwt boolean false Request ES256 JWT alongside raw attestation
apiBaseUrl string https://api.insumermodel.com API base URL override

TokenCondition

Field Type Description
contractAddress string Token/NFT contract address
chainId number | 'solana' | 'xrpl' Chain identifier
type 'token_balance' | 'nft_ownership' Condition type
threshold number Min balance (token_balance only, default 1)
decimals number Token decimals (auto-detected on most EVM chains)
label string Human-readable label
currency string XRPL currency code
taxon number XRPL NFT taxon filter

Supported chains

30 EVM chains (Ethereum, Base, Polygon, Arbitrum, Optimism, BNB, Avalanche, and 23 more) + Solana + XRPL + Bitcoin.

Full chain list

Distinguishing free vs paid access

const receipt = Receipt.fromResponse(response)
if (receipt.reference.startsWith('token-gate🆓')) {
  // Free access — attestation ID is in the reference
  const attestationId = receipt.reference.replace('token-gate🆓', '')
} else {
  // Paid access
}

Fail-open behavior

If the attestation API is unreachable, the wrapper falls through to the original payment method. Token holders pay normally; non-holders are unaffected.

License

MIT