Class: X402::Challenge

Inherits:
Object
  • Object
show all
Defined in:
lib/x402/protocol/challenge.rb

Constant Summary collapse

CURRENT_VERSION =
1
SUPPORTED_SCHEMES =
["bsv-tx-v1"].freeze
DEFAULT_TTL =

5 minutes

300
KNOWN_ATTRS =
%i[
  version scheme domain method path query
  req_headers_sha256 req_body_sha256
  amount_sats payee_locking_script_hex
  nonce_txid nonce_vout nonce_satoshis nonce_locking_script_hex
  expires_at partial_tx_b64 payee_sig
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ Challenge

Returns a new instance of Challenge.



22
23
24
25
26
27
# File 'lib/x402/protocol/challenge.rb', line 22

def initialize(attrs = {})
  attrs.each do |k, v|
    key = k.to_sym
    instance_variable_set(:"@#{key}", v) if KNOWN_ATTRS.include?(key)
  end
end

Class Method Details

.from_header(header_value) ⇒ Object

Reconstruct a challenge from the echoed X402-Challenge header.



71
72
73
74
75
76
77
# File 'lib/x402/protocol/challenge.rb', line 71

def self.from_header(header_value)
  json = Base64Url.decode(header_value)
  data = JSON.parse(json, symbolize_names: true)
  new(data)
rescue JSON::ParserError
  raise X402::Error, "invalid challenge JSON"
end

Instance Method Details

#sha256_hexObject



53
54
55
# File 'lib/x402/protocol/challenge.rb', line 53

def sha256_hex
  OpenSSL::Digest::SHA256.hexdigest(to_canonical_json)
end

#to_canonical_jsonObject



49
50
51
# File 'lib/x402/protocol/challenge.rb', line 49

def to_canonical_json
  to_h.to_json_c14n
end

#to_hObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/x402/protocol/challenge.rb', line 29

def to_h
  {
    version: @version,
    scheme: @scheme,
    domain: @domain,
    method: @method,
    path: @path,
    query: @query,
    req_headers_sha256: @req_headers_sha256,
    req_body_sha256: @req_body_sha256,
    amount_sats: @amount_sats,
    payee_locking_script_hex: @payee_locking_script_hex,
    nonce_txid: @nonce_txid,
    nonce_vout: @nonce_vout,
    nonce_satoshis: @nonce_satoshis,
    nonce_locking_script_hex: @nonce_locking_script_hex,
    expires_at: @expires_at
  }
end

#to_headerObject



66
67
68
# File 'lib/x402/protocol/challenge.rb', line 66

def to_header
  Base64Url.encode(to_header_h.to_json)
end

#to_header_hObject

Full representation for header encoding — includes optional fields like partial_tx_b64 that are excluded from the canonical hash.



59
60
61
62
63
64
# File 'lib/x402/protocol/challenge.rb', line 59

def to_header_h
  h = to_h
  h[:partial_tx_b64] = @partial_tx_b64 if @partial_tx_b64
  h[:payee_sig] = @payee_sig if @payee_sig
  h
end