x402-rack¶
Rack middleware for payment-gated HTTP using BSV and the x402 protocol.
The middleware is a pure dispatcher — it matches routes, issues payment challenges, and routes proofs to pluggable gateway backends for settlement. It has no blockchain knowledge and holds no keys.
Four BSV settlement schemes¶
Zero-config gateways — enabled automatically when you set wallet::
- BSV-pay (Coinbase v2 headers) — server broadcasts via ARC. Partial transaction template, unique derived addresses per payment.
- BRC-121 (BSV Association
x-bsv-*simple) — stateless server, BRC-100 wallet handles validation and replay detection viainternalize_action. No PrefixStore, no challenge_secret, no nonce store.
Specialist gateways — explicit opt-in required:
- BRC-105 (BSV Association
x-bsv-payment-*) — transitional; requires BRC-103 mutual authentication per spec. x402-rack accepts the client identity key via HTTP header as a stopgap until Ruby BRC-103 middleware lands. - BSV-proof (merkleworks x402) — experimental; client broadcasts, server checks mempool.
Getting started¶
Add to your Gemfile:
Minimal: relay to an existing wallet¶
The simplest path — no keys, no local wallet. Point operator_wallet_url at an existing @bsv/simple server wallet:
X402.configure do |c|
c.domain = "api.example.com"
c.operator_wallet_url = "https://my-wallet.example.com/api/server-wallet"
c.protect method: :GET, path: "/api/data", amount_sats: 100
end
use X402::Middleware
PayGateway is auto-enabled. ARC defaults to ARCADE. The server holds no private keys.
With a local wallet (enables BRC-121)¶
X402.configure do |c|
c.domain = "api.example.com"
c.wallet = X402::Wallet.load
c.protect method: :GET, path: "/api/data", amount_sats: 100
end
use X402::Middleware
Both PayGateway and BRC121Gateway are auto-enabled. ARC defaults to ARCADE.
With a remote wallet for all gateways¶
X402.configure do |c|
c.domain = "api.example.com"
c.wallet = X402::RemoteWallet.new(url: "https://my-wallet.example.com/api/server-wallet")
c.protect method: :GET, path: "/api/data", amount_sats: 100
end
use X402::Middleware
RemoteWallet implements the same duck-typed interface as the local wallet, so all gateways (PayGateway, BRC-121, BRC-105) work with it.
See the Architecture guide for how the pieces fit together, or jump to the API Reference for class and method documentation.