Class: X402::BSV::Gateway

Inherits:
Object
  • Object
show all
Defined in:
lib/x402/bsv/gateway.rb

Overview

Base gateway class for BSV settlement schemes.

Builds partial transaction templates containing a payment output. The OP_RETURN request binding is NOT included in the template — it must be appended last by the client to preserve SIGHASH_SINGLE index alignment (input N → output N for each signer).

When a wallet is provided, each challenge derives a unique payee address via BRC-29 key derivation, preventing address reuse.

Direct Known Subclasses

PayGateway, ProofGateway

Constant Summary collapse

BRC29_PROTOCOL_ID =

BRC-29 protocol ID — shared with BRC-105 and BRC-121 so all gateways derive keys the wallet can spend via the same scheme.

[2, "3241645161d8"].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(payee_locking_script_hex: nil, wallet: nil, challenge_secret: nil) ⇒ Gateway

Returns a new instance of Gateway.

Parameters:

  • payee_locking_script_hex (String, nil) (defaults to: nil)

    static payee script hex; falls back to X402.configuration.payee_locking_script_hex if nil. Ignored when wallet is provided (derived addresses used instead).

  • wallet (BSV::Wallet::ProtoWallet, nil) (defaults to: nil)

    wallet for key derivation. When provided, each challenge gets a unique derived payee address.

  • challenge_secret (String, nil) (defaults to: nil)

    HMAC secret for signing challenge data. Auto-generated if not provided. Used to verify payTo hasn't been tampered with.



32
33
34
35
36
# File 'lib/x402/bsv/gateway.rb', line 32

def initialize(payee_locking_script_hex: nil, wallet: nil, challenge_secret: nil)
  @payee_locking_script_hex = payee_locking_script_hex
  @wallet = wallet
  @challenge_secret = challenge_secret || SecureRandom.hex(32)
end

Instance Attribute Details

#payee_locking_script_hexObject (readonly)

Returns the value of attribute payee_locking_script_hex.



23
24
25
# File 'lib/x402/bsv/gateway.rb', line 23

def payee_locking_script_hex
  @payee_locking_script_hex
end

Instance Method Details

#build_template(_rack_request, required_sats) ⇒ Array(BSV::Transaction::Transaction, String, String, String)

Build a partial transaction template for the given route.

Output 0: payment (amount_sats to payee locking script)

The OP_RETURN is NOT included — the client appends it last so that SIGHASH_SINGLE index alignment is preserved (each signer's input index matches their change output index).

Parameters:

Returns:

  • (Array(BSV::Transaction::Transaction, String, String, String))

    transaction, payee script hex, derivation prefix, derivation suffix



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/x402/bsv/gateway.rb', line 50

def build_template(_rack_request, required_sats)
  tx = ::BSV::Transaction::Transaction.new

  # Output 0: payment (unique address if wallet configured, static otherwise)
  payee_hex, prefix, suffix = derive_payee_hex
  payee_script = ::BSV::Script::Script.from_hex(payee_hex)
  tx.add_output(::BSV::Transaction::TransactionOutput.new(
                  satoshis: required_sats,
                  locking_script: payee_script
                ))

  [tx, payee_hex, prefix, suffix]
end

#request_binding_hash(rack_request) ⇒ String

Compute the SHA-256 hash used for request binding.

Parameters:

  • rack_request (Rack::Request)

Returns:

  • (String)

    32-byte binary hash



68
69
70
71
72
# File 'lib/x402/bsv/gateway.rb', line 68

def request_binding_hash(rack_request)
  data = "#{rack_request.request_method}#{rack_request.path_info}"
  data += rack_request.query_string unless rack_request.query_string.empty?
  OpenSSL::Digest::SHA256.digest(data)
end