Project

x402-rack

0.0
The project is in a healthy, maintained state
Rack middleware implementing the x402 stateless settlement-gated HTTP protocol using BSV (Bitcoin SV) payments.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

x402-rack

Rack middleware for payment-gated HTTP using BSV (Bitcoin SV) 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.

Status

Early development (v0.1.0). Architecture is defined; gateway implementation is in progress. See DESIGN.md for architecture notes.

This is pre-release software and should not be used for real-world monetary purposes.

Installation

Add to your Gemfile:

gem "x402-rack", git: "https://github.com/sgbett/x402-rack.git"

Usage

Configuration DSL (recommended)

The DSL handles shared dependencies (ARC client, payee script) and gateway construction automatically. You declare what you want; the middleware builds it at validation time.

# config.ru or Rails initialiser
require "x402"

X402.configure do |config|
  config.domain = "api.example.com"
  config.payee_locking_script_hex = "76a914...88ac"

  # Shared ARC connection — built once, used by all gateways
  config.arc_url = "https://arc.taal.com"
  config.arc_api_key = "..."          # optional — ARC supports anonymous access

  # Enable gateways — constructed automatically from shared deps
  config.enable :pay_gateway
  config.enable :proof_gateway, nonce_provider: my_nonce_provider
  config.enable :brc105_gateway, server_wif: "L3..."

  config.protect method: :GET, path: "/api/expensive", amount_sats: 100
end

use X402::Middleware

Convenience options

Each gateway type supports convenience options that expand into their full form:

  • :brc105_gatewayserver_wif: "L3..." builds a KeyDeriver from a WIF string. server_key: accepts a PrivateKey directly. A default in-memory PrefixStore is used if prefix_store: is not provided.
  • :proof_gatewaynonce_wif: "L3..." builds a PrivateKey for the nonce_key: parameter.
  • :pay_gateway — pass-through options: arc_wait_for:, arc_timeout:, binding_mode:, wallet:, challenge_secret:.

Per-gateway overrides

Any gateway can override shared dependencies:

config.enable :pay_gateway, arc_client: my_custom_arc
config.enable :proof_gateway, nonce_provider: np, payee_locking_script_hex: "deadbeef..."

Order independence

enable records gateway specs; construction is deferred to validate!. This means arc_url can be set after enable calls — order within the configure block does not matter.

Manual gateway construction (power-user escape hatch)

For full control, construct gateways yourself and assign them directly. This bypasses DSL construction entirely and works exactly as before:

X402.configure do |config|
  config.domain = "api.example.com"
  config.payee_locking_script_hex = "76a914...88ac"

  config.gateways = [
    X402::BSV::PayGateway.new(
      arc_client: BSV::Network::ARC.new("https://arc.taal.com", api_key: "..."),
      payee_locking_script_hex: "76a914...88ac"
    ),
    X402::BSV::BRC105Gateway.new(
      key_deriver: BSV::Wallet::KeyDeriver.new(server_private_key),
      prefix_store: X402::BSV::PrefixStore::Memory.new,
      arc_client: arc_client
    )
  ]

  config.protect method: :GET, path: "/api/expensive", amount_sats: 100
end

use X402::Middleware

If config.gateways is set to a non-empty array, any enable calls are ignored.

How It Works

  1. Client requests a protected resource
  2. Middleware returns 402 Payment Required with challenge headers from each configured gateway
  3. Client constructs a BSV payment transaction and retries with proof
  4. Middleware dispatches the proof to the matching gateway for settlement
  5. Gateway verifies and settles — middleware serves or rejects

Three BSV settlement schemes are supported:

  • BSV-pay (Coinbase v2 headers) — server broadcasts via ARC. No nonces, minimal infrastructure.
  • BSV-proof (merkleworks x402) — client broadcasts, server checks mempool. Nonce-bound, request-binding.
  • BRC-105 (BSV Association x-bsv-* headers) — BRC-29 key derivation for unique payment addresses. Works standalone or composes with BRC-103 mutual authentication.

BSV-pay and BSV-proof produce partial transaction templates that clients extend. BRC-105 uses a different model — the client builds the entire transaction using BRC-29 derived addresses. See DESIGN.md for details.

Development

bin/setup              # Install dependencies
bundle exec rake spec  # Run tests
bundle exec rubocop    # Lint
bundle exec rake       # Run all checks (tests + lint)

Contributing

Bug reports and pull requests are welcome on GitHub.

Licence

Available under the terms of the Open BSV Licence.