Class: BSV::Wallet::Wire::Writer
- Inherits:
-
Object
- Object
- BSV::Wallet::Wire::Writer
- Defined in:
- lib/bsv/wallet_interface/wire/writer.rb
Overview
Builds a binary byte string using BRC-100 wire protocol encoding conventions.
All multi-byte integers use little-endian order unless stated otherwise. VarInts follow Bitcoin encoding; -1 is encoded as the 9-byte MaxUint64 sentinel.
Constant Summary collapse
- MAX_PRIVILEGED_REASON =
Maximum byte length for a PrivilegedReason string (Int8 length field).
127
Instance Method Summary collapse
-
#initialize ⇒ Writer
constructor
A new instance of Writer.
-
#to_binary ⇒ String
Returns the accumulated binary data.
-
#write_byte(val) ⇒ Object
Appends a single unsigned byte (0–255).
-
#write_byte_array(data) ⇒ Object
Appends a VarInt-prefixed byte array.
-
#write_bytes(data) ⇒ Object
Appends raw bytes with no length prefix.
-
#write_counterparty(val) ⇒ Object
Appends a counterparty value using the first-byte dispatch scheme.
-
#write_int8(val) ⇒ Object
Appends a signed 8-bit integer (-128–127).
-
#write_map(hash_or_nil) ⇒ Object
Appends an optional string→string map: VarInt count + key/value pairs, or -1 if nil.
-
#write_optional_bool(val_or_nil) ⇒ Object
Appends an optional boolean as a signed Int8: 1=true, 0=false, -1=nil.
-
#write_optional_byte_array(data_or_nil) ⇒ Object
Appends a VarInt-prefixed byte array, or the -1 sentinel if nil.
-
#write_optional_utf8_string(str_or_nil) ⇒ Object
Appends a VarInt-prefixed UTF-8 string, or the -1 sentinel if nil.
-
#write_outpoint(txid_hex, index) ⇒ Object
Appends an outpoint: 32 bytes (txid in display order) + VarInt index.
-
#write_privileged(privileged, privileged_reason) ⇒ Object
Appends privileged parameters: optional bool + Int8-length reason string.
-
#write_protocol_id(protocol_id) ⇒ Object
Appends a protocol ID: UInt8 security level + VarInt-prefixed UTF-8 name.
-
#write_signed_varint(val) ⇒ Object
Appends a signed VarInt where -1 is encoded as MaxUint64 (9 bytes: FF * 9).
-
#write_string_array(arr_or_nil) ⇒ Object
Appends an optional string array: VarInt count + strings, or -1 if nil.
-
#write_utf8_string(str) ⇒ Object
Appends a VarInt-prefixed UTF-8 string.
-
#write_varint(val) ⇒ Object
Appends an unsigned Bitcoin VarInt.
Constructor Details
#initialize ⇒ Writer
Returns a new instance of Writer.
14 15 16 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 14 def initialize @buf = ''.b end |
Instance Method Details
#to_binary ⇒ String
Returns the accumulated binary data.
21 22 23 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 21 def to_binary @buf end |
#write_byte(val) ⇒ Object
Appends a single unsigned byte (0–255).
28 29 30 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 28 def write_byte(val) @buf << [val & 0xFF].pack('C') end |
#write_byte_array(data) ⇒ Object
Appends a VarInt-prefixed byte array.
76 77 78 79 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 76 def write_byte_array(data) write_varint(data.bytesize) write_bytes(data) end |
#write_bytes(data) ⇒ Object
Appends raw bytes with no length prefix.
69 70 71 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 69 def write_bytes(data) @buf << data.b end |
#write_counterparty(val) ⇒ Object
Appends a counterparty value using the first-byte dispatch scheme.
Encoding:
'self' → 0x0B (11)
'anyone' → 0x0C (12)
nil → 0x00 (0)
hex pubkey (33 bytes compressed) → 33 raw bytes
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 143 def write_counterparty(val) case val when 'self' write_byte(11) when 'anyone' write_byte(12) when nil write_byte(0) else write_bytes([val].pack('H*')) end end |
#write_int8(val) ⇒ Object
Appends a signed 8-bit integer (-128–127). Negative values are encoded as their two’s-complement byte.
36 37 38 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 36 def write_int8(val) @buf << [val].pack('c') end |
#write_map(hash_or_nil) ⇒ Object
Appends an optional string→string map: VarInt count + key/value pairs, or -1 if nil.
180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 180 def write_map(hash_or_nil) if hash_or_nil.nil? write_signed_varint(-1) else write_varint(hash_or_nil.length) hash_or_nil.each do |key, value| write_utf8_string(key.to_s) write_utf8_string(value.to_s) end end end |
#write_optional_bool(val_or_nil) ⇒ Object
Appends an optional boolean as a signed Int8: 1=true, 0=false, -1=nil.
115 116 117 118 119 120 121 122 123 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 115 def write_optional_bool(val_or_nil) if val_or_nil.nil? write_int8(-1) elsif val_or_nil write_int8(1) else write_int8(0) end end |
#write_optional_byte_array(data_or_nil) ⇒ Object
Appends a VarInt-prefixed byte array, or the -1 sentinel if nil.
84 85 86 87 88 89 90 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 84 def write_optional_byte_array(data_or_nil) if data_or_nil.nil? write_signed_varint(-1) else write_byte_array(data_or_nil) end end |
#write_optional_utf8_string(str_or_nil) ⇒ Object
Appends a VarInt-prefixed UTF-8 string, or the -1 sentinel if nil.
104 105 106 107 108 109 110 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 104 def write_optional_utf8_string(str_or_nil) if str_or_nil.nil? write_signed_varint(-1) else write_utf8_string(str_or_nil) end end |
#write_outpoint(txid_hex, index) ⇒ Object
Appends an outpoint: 32 bytes (txid in display order) + VarInt index.
129 130 131 132 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 129 def write_outpoint(txid_hex, index) write_bytes([txid_hex].pack('H*')) write_varint(index) end |
#write_privileged(privileged, privileged_reason) ⇒ Object
Appends privileged parameters: optional bool + Int8-length reason string.
PrivilegedReason uses Int8 for its length field (max 127 bytes), not VarInt. -1 (0xFF) means absent.
199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 199 def write_privileged(privileged, privileged_reason) write_optional_bool(privileged) if privileged_reason.nil? write_int8(-1) else reason_bytes = privileged_reason.encode('UTF-8').b raise ArgumentError, 'privileged_reason exceeds 127 bytes' if reason_bytes.bytesize > MAX_PRIVILEGED_REASON write_int8(reason_bytes.bytesize) write_bytes(reason_bytes) end end |
#write_protocol_id(protocol_id) ⇒ Object
Appends a protocol ID: UInt8 security level + VarInt-prefixed UTF-8 name.
159 160 161 162 163 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 159 def write_protocol_id(protocol_id) level, name = protocol_id write_byte(level) write_utf8_string(name) end |
#write_signed_varint(val) ⇒ Object
Appends a signed VarInt where -1 is encoded as MaxUint64 (9 bytes: FF * 9).
58 59 60 61 62 63 64 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 58 def write_signed_varint(val) if val == -1 @buf << "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF".b else write_varint(val) end end |
#write_string_array(arr_or_nil) ⇒ Object
Appends an optional string array: VarInt count + strings, or -1 if nil.
168 169 170 171 172 173 174 175 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 168 def write_string_array(arr_or_nil) if arr_or_nil.nil? write_signed_varint(-1) else write_varint(arr_or_nil.length) arr_or_nil.each { |s| write_utf8_string(s) } end end |
#write_utf8_string(str) ⇒ Object
Appends a VarInt-prefixed UTF-8 string.
95 96 97 98 99 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 95 def write_utf8_string(str) bytes = str.encode('UTF-8').b write_varint(bytes.bytesize) write_bytes(bytes) end |
#write_varint(val) ⇒ Object
Appends an unsigned Bitcoin VarInt.
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/bsv/wallet_interface/wire/writer.rb', line 43 def write_varint(val) @buf << if val < 0xFD [val].pack('C') elsif val <= 0xFFFF [0xFD, val].pack('Cv') elsif val <= 0xFFFF_FFFF [0xFE, val].pack('CV') else [0xFF, val].pack('CQ<') end end |