Skip to content

Treasury

The treasury mints and manages 1-satoshi nonce UTXOs for the ProofGateway. It is not needed for PayGateway (which uses ARC as the replay gate).

Nonce UTXO Lifecycle

Minting

The treasury creates 1-sat P2PKH outputs locked to the nonce key. Each output becomes a nonce for one challenge.

Issuance

When the ProofGateway builds a challenge, it requests a nonce from the treasury (via the nonce_provider callable). The nonce UTXO details (txid, vout, satoshis, locking_script_hex) are included in the challenge.

In Profile B, the treasury signs the nonce input with 0xC3 and returns the pre-signed template (as partial_tx binary) to the gateway. The gateway appends the OP_RETURN and includes the template in the challenge.

Spending

The client spends the nonce UTXO as input 0 of the payment transaction. Bitcoin's single-spend guarantee ensures the nonce can only be used once — this is the replay protection mechanism.

Expiry and Reclamation

Unused nonces (challenges that were issued but never answered) need reclamation. The approach:

  • Nonce UTXOs carry a timelocked return path — if not spent within the timelock window, the funds auto-return to the treasury's source address
  • Script structure: OP_IF <spend_path> OP_ELSE <timeout> OP_CSV OP_DROP <treasury_pubkey> OP_CHECKSIG OP_ENDIF
  • After the timelock expires, miners may consolidate these UTXOs for free (they're incentivised to reduce the UTXO set)

The blockchain is the state. No server-side nonce pools, no lease tables, no release callbacks.

Wallet Integration

The treasury is a role the bsv-wallet gem plays, using the x402-nonces basket:

Operation BRC-100 Method
Mint nonces createAction
List available nonces listOutputs (basket: x402-nonces)
Sign templates Uses the nonce key (held by wallet)

Scaling

Nonce provision can be horizontally scaled:

  • Multiple treasury instances can mint UTXOs independently
  • Each instance manages its own nonce pool
  • The nonce key can be shared (or derived) across instances
  • Minting 1-sat UTXOs is fast and cheap (1 sat per nonce + negligible fee)

The treasury is not on the critical path for settlement — it only participates at challenge time. Settlement just checks mempool.

Current Implementation

The nonce_provider is a callable injected into ProofGateway. It receives payee: and amount: kwargs so the treasury can build the template:

# Profile A — bare UTXO metadata
nonce_provider = ->(request, payee:, amount:) {
  { txid: "...", vout: 0, satoshis: 1, locking_script_hex: "76a914...88ac" }
}

# Profile B — treasury builds and signs the template
nonce_provider = ->(request, payee:, amount:) {
  tx = build_and_sign_template(payee: payee, amount: amount)
  { txid: "...", vout: 0, satoshis: 1, locking_script_hex: "76a914...88ac",
    partial_tx: tx.to_binary }
}

Full wallet-backed treasury integration (basket-managed nonce pool, automatic minting, timelock expiry) is tracked in bsv-ruby-sdk#196.