Module: BSV::Wallet::Wire::Validation
- Defined in:
- lib/bsv/wallet/wire/validation.rb
Overview
Branded-type validators for BRC-100 parameters.
Each method raises InvalidParameterError on failure and returns nil on success. Port of ts-sdk/src/wallet/validationHelpers.ts.
The existing ProtoWallet::Validators module delegates here so there is a single source of truth for all parameter validation logic.
Constant Summary collapse
- MAX_SATOSHIS =
21_000_000 * (10**8)
Class Method Summary collapse
-
.acquisition_protocol!(name, value) ⇒ Object
Validates a certificate acquisition protocol: ‘direct’ or ‘issuance’.
-
.base64_string!(name, value) ⇒ Object
Validates that
valueis a Base64-encoded string. -
.basket_string!(name, value) ⇒ Object
Validates a basket name (1..300 characters).
-
.description_5_to_50!(name, value) ⇒ Object
Validates a description string (5..50 printable characters).
-
.hex_string!(name, value, length: nil) ⇒ Object
Validates that
valueis a hex string (even length, hex chars only). -
.key_id_string_1_to_800!(name, value) ⇒ Object
Validates a BRC-43 key ID string (1..800 bytes).
-
.label_string!(name, value) ⇒ Object
Validates a label string (1..150 characters, no spaces).
-
.originator_domain!(name, value) ⇒ Object
Validates an originator domain (1..250 bytes UTF-8).
-
.outpoint_string!(name, value) ⇒ Object
Validates an outpoint string in the form “<64-hex-txid>.<vout>”.
-
.positive_integer_or_zero!(name, value) ⇒ Object
Validates a non-negative integer.
-
.protocol_string_5_to_400!(name, value) ⇒ Object
Validates a BRC-43 protocol name string (5..400 chars, lowercase).
-
.pub_key_hex!(name, value) ⇒ Object
Validates a compressed public key in hex form (66 chars, 02/03 prefix).
-
.satoshi_value!(name, value) ⇒ Object
Validates a satoshi amount (0..21_000_000 * 10^8).
-
.wallet_counterparty!(name, value) ⇒ Object
Validates a wallet counterparty: ‘self’, ‘anyone’, or a 66-char hex pubkey.
-
.wallet_protocol!(name, value) ⇒ Object
Validates a BRC-43 protocol ID: [security_level (0-2), protocol_name (5-400 chars)].
Class Method Details
.acquisition_protocol!(name, value) ⇒ Object
Validates a certificate acquisition protocol: ‘direct’ or ‘issuance’.
205 206 207 208 209 |
# File 'lib/bsv/wallet/wire/validation.rb', line 205 def acquisition_protocol!(name, value) return if %w[direct issuance].include?(value) raise InvalidParameterError.new(name, "'direct' or 'issuance'") end |
.base64_string!(name, value) ⇒ Object
Validates that value is a Base64-encoded string.
39 40 41 42 43 44 45 |
# File 'lib/bsv/wallet/wire/validation.rb', line 39 def base64_string!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) return if value.match?(%r{\A[A-Za-z0-9+/]*={0,2}\z}) raise InvalidParameterError.new(name, 'a valid Base64 string') end |
.basket_string!(name, value) ⇒ Object
Validates a basket name (1..300 characters).
107 108 109 110 111 112 |
# File 'lib/bsv/wallet/wire/validation.rb', line 107 def basket_string!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) len = value.length raise InvalidParameterError.new(name, 'between 1 and 300 characters') if len < 1 || len > 300 end |
.description_5_to_50!(name, value) ⇒ Object
Validates a description string (5..50 printable characters).
85 86 87 88 89 90 |
# File 'lib/bsv/wallet/wire/validation.rb', line 85 def description_5_to_50!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) len = value.length raise InvalidParameterError.new(name, 'between 5 and 50 characters') if len < 5 || len > 50 end |
.hex_string!(name, value, length: nil) ⇒ Object
Validates that value is a hex string (even length, hex chars only).
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/bsv/wallet/wire/validation.rb', line 23 def hex_string!(name, value, length: nil) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) raise InvalidParameterError.new(name, 'a hex string (characters 0-9, a-f, A-F only)') unless value.match?(/\A[0-9a-fA-F]*\z/) raise InvalidParameterError.new(name, 'a hex string with even number of characters') if value.length.odd? return unless length && value.length != length raise InvalidParameterError.new(name, "a #{length}-character hex string, got #{value.length}") end |
.key_id_string_1_to_800!(name, value) ⇒ Object
Validates a BRC-43 key ID string (1..800 bytes).
171 172 173 174 175 176 |
# File 'lib/bsv/wallet/wire/validation.rb', line 171 def key_id_string_1_to_800!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) byte_length = value.bytesize raise InvalidParameterError.new(name, 'between 1 and 800 bytes') if byte_length < 1 || byte_length > 800 end |
.label_string!(name, value) ⇒ Object
Validates a label string (1..150 characters, no spaces).
96 97 98 99 100 101 |
# File 'lib/bsv/wallet/wire/validation.rb', line 96 def label_string!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) len = value.length raise InvalidParameterError.new(name, 'between 1 and 150 characters') if len < 1 || len > 150 end |
.originator_domain!(name, value) ⇒ Object
Validates an originator domain (1..250 bytes UTF-8). The originator must fit in a single-byte length field in the wire frame.
119 120 121 122 123 124 |
# File 'lib/bsv/wallet/wire/validation.rb', line 119 def originator_domain!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) byte_len = value.bytesize raise InvalidParameterError.new(name, 'at most 250 bytes') if byte_len > 250 end |
.outpoint_string!(name, value) ⇒ Object
Validates an outpoint string in the form “<64-hex-txid>.<vout>”.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/bsv/wallet/wire/validation.rb', line 51 def outpoint_string!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) parts = value.split('.', 2) raise InvalidParameterError.new(name, 'an outpoint string in the format <64-hex-txid>.<vout>') unless parts.length == 2 txid_hex, vout_str = parts raise InvalidParameterError.new(name, 'an outpoint with a 64-character hex transaction ID') unless txid_hex.match?(/\A[0-9a-fA-F]{64}\z/) raise InvalidParameterError.new(name, 'an outpoint with a non-negative integer output index') unless vout_str.match?(/\A\d+\z/) vout = vout_str.to_i return unless vout > 0xFFFFFFFF raise InvalidParameterError.new(name, 'an outpoint with a vout that fits in a uint32 (0..4294967295)') end |
.positive_integer_or_zero!(name, value) ⇒ Object
Validates a non-negative integer.
142 143 144 145 146 |
# File 'lib/bsv/wallet/wire/validation.rb', line 142 def positive_integer_or_zero!(name, value) return if value.is_a?(Integer) && !value.negative? raise InvalidParameterError.new(name, 'a non-negative integer') end |
.protocol_string_5_to_400!(name, value) ⇒ Object
Validates a BRC-43 protocol name string (5..400 chars, lowercase).
152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/bsv/wallet/wire/validation.rb', line 152 def protocol_string_5_to_400!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) normalized = value.strip.downcase max_length = normalized.start_with?('specific linkage revelation') ? 430 : 400 raise InvalidParameterError.new(name, "between 5 and #{max_length} characters") if normalized.length < 5 || normalized.length > max_length raise InvalidParameterError.new(name, 'lowercase letters, numbers, and spaces only') unless normalized.match?(/\A[a-z0-9 ]+\z/) return unless normalized.include?(' ') raise InvalidParameterError.new(name, 'free of consecutive spaces') end |
.pub_key_hex!(name, value) ⇒ Object
Validates a compressed public key in hex form (66 chars, 02/03 prefix).
73 74 75 76 77 78 79 |
# File 'lib/bsv/wallet/wire/validation.rb', line 73 def pub_key_hex!(name, value) raise InvalidParameterError.new(name, 'a String') unless value.is_a?(String) return if value.match?(/\A0[23][0-9a-fA-F]{64}\z/) raise InvalidParameterError.new(name, 'a 66-character compressed public key hex string (02 or 03 prefix)') end |
.satoshi_value!(name, value) ⇒ Object
Validates a satoshi amount (0..21_000_000 * 10^8).
130 131 132 133 134 135 136 |
# File 'lib/bsv/wallet/wire/validation.rb', line 130 def satoshi_value!(name, value) raise InvalidParameterError.new(name, 'a non-negative integer') unless value.is_a?(Integer) return unless value.negative? || value > MAX_SATOSHIS raise InvalidParameterError.new(name, "between 0 and #{MAX_SATOSHIS} satoshis") end |
.wallet_counterparty!(name, value) ⇒ Object
Validates a wallet counterparty: ‘self’, ‘anyone’, or a 66-char hex pubkey.
182 183 184 185 186 |
# File 'lib/bsv/wallet/wire/validation.rb', line 182 def wallet_counterparty!(name, value) return if %w[self anyone].include?(value) pub_key_hex!(name, value) end |
.wallet_protocol!(name, value) ⇒ Object
Validates a BRC-43 protocol ID: [security_level (0-2), protocol_name (5-400 chars)].
192 193 194 195 196 197 198 199 |
# File 'lib/bsv/wallet/wire/validation.rb', line 192 def wallet_protocol!(name, value) raise InvalidParameterError.new(name, 'an Array of [security_level, protocol_name]') unless value.is_a?(Array) && value.length == 2 level, proto_name = value raise InvalidParameterError.new(name, 'a security level of 0, 1, or 2') unless [0, 1, 2].include?(level) protocol_string_5_to_400!("#{name} protocol name", proto_name) end |