npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@selat-ai/selat-pay

v0.12.0

Published

Standalone CLI that pays SELAT Router endpoints over x402 Gateway-batched. Keeps the open-source discovery skill free of heavy deps.

Readme

selat-pay

selat-pay is the payment engine for SELAT Agent Payments: a standalone CLI that turns an HTTP 402 into a settled USDC payment — probe, sign, retry — from the user's own self-custodied agent wallet. No API keys, no seed phrase, no gas token.

selat-pay auto-detects the upstream's payment scheme (Circle Gateway-batched x402, erc-3009, MPP) and settles the call through the SELAT Router. It is the engine underneath @selat-ai/selat-cli (selat run / selat skill run), and it works standalone exactly as shown below.

Install

npm install -g @selat-ai/selat-pay

Or one-off, no install:

npx @selat-ai/selat-pay GET https://upstream/api --chain base --max-amount 0.05

How does self-custody work?

Your wallet is yours. selat-pay never holds your keys, your funds, or your credentials.

selat-pay constructs the payment payload (@circle-fin/x402-batching's BatchEvmScheme, protocol-spec EIP-712), then requests the signature through the Circle CLI (circle wallet sign typed-data). The wallet is a Circle Agent Wallet with 2-of-2 MPC key management: the private key exists only as two key shares, both required to sign, and neither share is ever exposed to the agent — or to SELAT. This package is open source precisely so that claim is auditable: every byte that touches the payment path is in bin/selat-pay.mjs.

There is no local-key signing path: every signature — payments and refund claims alike — is produced by the Circle CLI.

Why not circle services pay?

circle services pay cannot complete the SELAT Router round-trip: it runs its own internal probe and does not forward the router's x-selat-quote-id response header on the signed retry. selat-pay performs the probe + retry itself, pinning the quote it pays to the quote it was shown. It also carries the heavier Gateway-batching SDK + viem so that @selat-ai/selat-discovery (the discovery skill) can stay lean — discovery is free and dependency-light; payment is this package's whole job.

Setup

Shell environment or ~/.config/selat-pay/.env (typical on macOS/Linux):

SELAT_ROUTER_URL=https://router.selat.ai
SELAT_AGENT_WALLET_ADDRESS=0xYourAgentWalletAddress

A .env in the working directory may still set unrelated keys, but it cannot set payment routing, freeze/budget/history/session paths, CIRCLE_BIN, or XDG_STATE_HOME. Those are taken from the shell and the home config only, so an untrusted repo cannot retarget settlement, disable or inflate freeze/budget, or swap the signing binary.

Paid calls require an armed session budget from selat budget start (the session.json it writes). SELAT_SESSION_BUDGET in the process environment or home config cannot invent a budget — an agent that can set env must not self-arm. --max-amount is required on the paid path and is hard-capped at $1.10; no flag or env raises that ceiling. --probe-only does not need a budget or --max-amount.

Plus the Circle CLI authenticated:

circle wallet login <your-email> --type agent

Usage

# Probe only — see the 402 terms without paying
selat-pay GET "https://pro-api.coinmarketcap.com/x402/v3/cryptocurrency/quotes/latest?symbol=eth" \
  --chain base --probe-only

# Paid call (GET). --max-amount is required and hard-capped at $1.10.
selat-pay GET "https://upstream/api" \
  --chain base --max-amount 0.05

# Paid call (POST with JSON body)
selat-pay POST "https://upstream/api" \
  --body '{"foo":"bar"}' \
  --chain base --max-amount 0.05

The HTTP method must match the provider's published request schema. If that
schema requires a JSON body and the method cannot carry one (GET / HEAD /
DELETE), selat-pay refuses **before signing** — nothing is charged. Retry as
`POST --body '{...}'` (or PUT/PATCH). GET is never rewritten to POST.
`--skip-schema-check` warns and pays anyway, same as other schema gates.

# Refund claim (SIWx auth via Circle CLI, no payment)
selat-pay refund claim selatx123 --chain base

# Refund query (SIWx auth via Circle CLI, no payment)
selat-pay refund query selatx123 --chain base

# List chains the SDK knows about
selat-pay --list-chains

Refunds

selat-pay supports refund claim and status query against the SELAT Router:

selat-pay refund claim <quote-id> --chain base
selat-pay refund query <quote-id> --chain base

Notes:

  • <quote-id> must be a selatx... id returned by a prior paid call.
  • Refund commands are authenticated requests (SIWx + dummy Gateway owner probe), not payments.
  • Refund commands do not consume session budget and do not require --max-amount. The $1.10 hard per-call ceiling does not apply to refunds.
  • --router-url, --chain, and the Circle Agent Wallet address (--address / SELAT_AGENT_WALLET_ADDRESS) still apply.

What does it cost?

Two prices, both disclosed in the 402 quote before you pay:

  • Same-rail Gateway passthrough (the upstream itself accepts Gateway-batched x402): quoted at par — 0% fee. Verified live against router.selat.ai: a $0.008 Gateway-batched upstream is quoted at exactly $0.008.
  • Cross-protocol (Gateway in → MPP / erc-3009 out): SELAT's flat 5% fee. A $0.01 erc-3009 upstream is quoted at $0.0105.

The per-call 402 quote is authoritative — par pricing is the operator's current live behavior, not a protocol guarantee. Run --probe-only to see the quote before paying, and cross-check it against the upstream's own accept and the discovery catalog's payments[].amountUsd.

--probe-only also surfaces every extension the router attaches to its 402, under quote.extensions in the probe JSON (and a [selat-pay] extensions= stderr line). The one to check before paying is selatTransactabilityIndex — the router's endpoint-health record (last paid status, windowed captured-payment stats), present whenever the router has data for the endpoint. It reports payment-layer observables only — whether payments captured and what HTTP status came back — never the content of the merchant's response. A lastPaid.status of 4xx/5xx or a low successRate across several paidNum is a signal to pick a different endpoint instead of paying to find out; absence of the extension means no data, not bad health.

Flow

selat-pay probes the upstream directly first to detect its payment scheme, then settles every paid call through the SELAT Router — including upstreams that themselves accept Gateway-batched x402. The router settles the upstream leg (same-rail Gateway passthrough, or cross-protocol translation to MPP/erc-3009) and records the call, so SELAT captures per-call settlement data on all rails:

selat-pay      Upstream         SELAT Router            Agent Wallet (MPC)
   │ probe          │                  │                       │
   ├──────────────► │                  │                       │
   │ ◄── 402 (GatewayWalletBatched / erc-3009 / tempo-native)  │
   │                                                            │
   │ probe ${routerUrl}/proxy?target=upstream                   │
   ├─────────────────────────────────► │                       │
   │                                   │ probe upstream         │
   │                                   ├──────────────► …      │
   │ ◄── 402 (Gateway-batched) + x-selat-quote-id              │
   │                                                            │
   │ build EIP-712 + sign ───────────────────────────────────► │
   │ ◄──────── signature ───────────────────────────────────── │
   │                                                            │
   │ retry with x-selat-quote-id + Payment-Signature           │
   ├─────────────────────────────────► │                       │
   │                                   │ settle outbound leg
   │                                   │ (Gateway passthrough or mpp/erc-3009)
   │                                   ├──────────────► upstream
   │ ◄── upstream response ────────────┤                       │

The upstream's detected scheme picks the router's outbound protocol, not whether the router is used, and routing is automatic — there is no manual override. The stderr line after the detection probe reports mode=routed-x402, mode=routed-mpp, or mode=routed-free; a Gateway-capable upstream takes routed-x402 (same-rail passthrough), otherwise MPP wins when present, else x402. routed-mpp never sends x-selat-prefer-protocol: mpp — the router discovers the MPP challenge on its own bare probe, so it can compose Gateway for MPP-only merchants (e.g. Solana-MPP); only routed-x402 advertises x402. SELAT_ROUTER_URL (or --router-url) is always required.

Outputs

  • stdout: upstream response body (parsed JSON if possible, raw text otherwise). Pipe-friendly.
  • stderr: [selat-pay] progress lines (quoteId, price, status). Suppressed from stdout for clean piping.

Example:

selat-pay GET ... 2>/dev/null | jq .

Exit codes

  • 0 — paid call succeeded with 2xx upstream response, or probe-only completed.
  • 1 — runtime error (probe failed, cost cap exceeded, upstream non-2xx, network error).
  • 2 — missing dependency (@circle-fin/x402-batching not installed).

Known limits

  • One inbound signing scheme. This CLI signs against Circle's GatewayWalletBatched scheme only. The router refuses inbound payments in any other scheme today, so the two match; if the router ever accepts erc-3009 inbound, this CLI won't cover that path yet.
  • Router payTo is not allowlisted. A router 402's extra.verifyingContract is pinned to the chain's canonical GatewayWallet (chainConfig.gatewayWallet). This package has no in-tree set of trusted facilitator addresses, so payTo is still taken from the challenge. Prefer a router URL from the shell or home config (a cwd .env cannot set SELAT_ROUTER_URL).
  • No quote attestation yet. The router doesn't attest its 402 quotes with a router key, so this CLI cannot cryptographically pin the operator's claimed upstream base price. Once the router lands EIP-712-attested quotes, this CLI will verify the attestation and surface the quoted-vs-catalog comparison before paying.

Roadmap

  • Verify router-attested quotes once the router supports attestation.
  • Auto-discover available routers from a registry (Phase 2 federation).
  • Surface a fee-vs-catalog-price warning before pay.
  • Per-call telemetry (opt-in).

License

Apache-2.0 — see LICENSE. Free to use, modify, and redistribute.

What's open and why: the client side of SELAT — this payment engine, selat-cli, and selat-discovery — is open source, because a payments client asking for trust must be auditable: you can read every line that touches a payment. The SELAT Router (the settlement service this CLI talks to) is a proprietary hosted service and lives in a separate, private repository.