bsv-sdk 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/lib/bsv/auth/certificate.rb +6 -2
  4. data/lib/bsv/auth/get_verifiable_certificates.rb +6 -6
  5. data/lib/bsv/auth/peer.rb +10 -4
  6. data/lib/bsv/auth/session_manager.rb +81 -5
  7. data/lib/bsv/identity/client.rb +5 -2
  8. data/lib/bsv/mcp/tools/broadcast_p2pkh.rb +4 -4
  9. data/lib/bsv/mcp/tools/check_balance.rb +2 -2
  10. data/lib/bsv/mcp/tools/fetch_utxos.rb +2 -2
  11. data/lib/bsv/mcp/tools/helpers.rb +2 -2
  12. data/lib/bsv/network/broadcast_error.rb +2 -0
  13. data/lib/bsv/network/broadcast_response.rb +4 -1
  14. data/lib/bsv/network/protocol.rb +56 -4
  15. data/lib/bsv/network/protocols/arc.rb +10 -6
  16. data/lib/bsv/network/protocols/chaintracks.rb +6 -2
  17. data/lib/bsv/network/protocols/jungle_bus.rb +52 -0
  18. data/lib/bsv/network/protocols/ordinals.rb +110 -8
  19. data/lib/bsv/network/protocols/taal_binary.rb +18 -4
  20. data/lib/bsv/network/protocols/woc_rest.rb +166 -85
  21. data/lib/bsv/network/protocols.rb +1 -0
  22. data/lib/bsv/network/provider.rb +36 -5
  23. data/lib/bsv/network/providers/gorilla_pool.rb +42 -20
  24. data/lib/bsv/network/providers/taal.rb +38 -15
  25. data/lib/bsv/network/providers/whats_on_chain.rb +42 -21
  26. data/lib/bsv/network/utxo.rb +8 -2
  27. data/lib/bsv/overlay/lookup_resolver.rb +5 -4
  28. data/lib/bsv/overlay/topic_broadcaster.rb +2 -2
  29. data/lib/bsv/overlay/types.rb +2 -0
  30. data/lib/bsv/primitives/hex.rb +64 -0
  31. data/lib/bsv/registry/client.rb +10 -8
  32. data/lib/bsv/registry/types.rb +2 -0
  33. data/lib/bsv/script/interpreter/interpreter.rb +7 -0
  34. data/lib/bsv/script/interpreter/operations/crypto.rb +7 -1
  35. data/lib/bsv/transaction/beef.rb +223 -147
  36. data/lib/bsv/transaction/merkle_path.rb +54 -38
  37. data/lib/bsv/transaction/transaction.rb +103 -40
  38. data/lib/bsv/transaction/transaction_input.rb +23 -18
  39. data/lib/bsv/version.rb +1 -1
  40. data/lib/bsv/wallet/interface/brc100.rb +5 -2
  41. data/lib/bsv/wallet/proto_wallet/key_deriver.rb +2 -0
  42. data/lib/bsv/wallet/proto_wallet.rb +6 -0
  43. data/lib/bsv/wire_format.rb +40 -14
  44. data/lib/bsv-sdk.rb +14 -0
  45. metadata +4 -3
@@ -18,6 +18,10 @@ module BSV
18
18
  # BSV::WireFormat.to_wire({ outputs: [{ locking_script: 'abc' }] })
19
19
  # # => { 'outputs' => [{ 'lockingScript' => 'abc' }] }
20
20
  module WireFormat
21
+ # Maximum nesting depth for deep conversions. Prevents stack overflow on
22
+ # pathologically deep hashes or arrays.
23
+ MAX_DEPTH = 20
24
+
21
25
  # Well-known snake_case -> camelCase pairs for BRC-100/BRC-103 protocol keys.
22
26
  #
23
27
  # Acronyms like protocolID, keyID are canonical per the TS SDK (Wallet.interfaces.ts).
@@ -90,10 +94,7 @@ module BSV
90
94
  def to_wire(hash)
91
95
  raise ArgumentError, 'argument must not be nil' if hash.nil?
92
96
 
93
- hash.each_with_object({}) do |(k, v), out|
94
- camel_key = snake_to_camel(k.to_s)
95
- out[camel_key] = deep_convert_value_to_wire(v)
96
- end
97
+ to_wire_at_depth(hash, 0)
97
98
  end
98
99
 
99
100
  # Deeply converts all Hash keys from camelCase strings to snake_case symbols.
@@ -107,10 +108,7 @@ module BSV
107
108
  def from_wire(hash)
108
109
  raise ArgumentError, 'argument must not be nil' if hash.nil?
109
110
 
110
- hash.each_with_object({}) do |(k, v), out|
111
- snake_key = camel_to_snake(k.to_s).to_sym
112
- out[snake_key] = deep_convert_value_from_wire(v)
113
- end
111
+ from_wire_at_depth(hash, 0)
114
112
  end
115
113
 
116
114
  # Converts top-level Hash keys only from snake_case to camelCase strings.
@@ -182,12 +180,35 @@ module BSV
182
180
  end
183
181
  private_class_method :generic_camel_to_snake
184
182
 
183
+ # Depth-aware inner implementation of to_wire.
184
+ def to_wire_at_depth(hash, depth)
185
+ hash.each_with_object({}) do |(k, v), out|
186
+ camel_key = snake_to_camel(k.to_s)
187
+ out[camel_key] = deep_convert_value_to_wire(v, depth + 1)
188
+ end
189
+ end
190
+ private_class_method :to_wire_at_depth
191
+
192
+ # Depth-aware inner implementation of from_wire.
193
+ def from_wire_at_depth(hash, depth)
194
+ hash.each_with_object({}) do |(k, v), out|
195
+ snake_key = camel_to_snake(k.to_s).to_sym
196
+ out[snake_key] = deep_convert_value_from_wire(v, depth + 1)
197
+ end
198
+ end
199
+ private_class_method :from_wire_at_depth
200
+
185
201
  # Recursively converts a value destined for the wire (to_wire direction).
186
- def deep_convert_value_to_wire(value)
202
+ # depth is the nesting level of this value (1 = directly inside the root hash).
203
+ def deep_convert_value_to_wire(value, depth = 0)
187
204
  if value.is_a?(Hash)
188
- to_wire(value)
205
+ raise ArgumentError, "WireFormat nesting exceeds maximum depth (#{MAX_DEPTH})" if depth >= MAX_DEPTH
206
+
207
+ to_wire_at_depth(value, depth)
189
208
  elsif value.is_a?(Array)
190
- value.map { |elem| deep_convert_value_to_wire(elem) }
209
+ raise ArgumentError, "WireFormat nesting exceeds maximum depth (#{MAX_DEPTH})" if depth >= MAX_DEPTH
210
+
211
+ value.map { |elem| deep_convert_value_to_wire(elem, depth + 1) }
191
212
  else
192
213
  value
193
214
  end
@@ -195,11 +216,16 @@ module BSV
195
216
  private_class_method :deep_convert_value_to_wire
196
217
 
197
218
  # Recursively converts a value coming from the wire (from_wire direction).
198
- def deep_convert_value_from_wire(value)
219
+ # depth is the nesting level of this value (1 = directly inside the root hash).
220
+ def deep_convert_value_from_wire(value, depth = 0)
199
221
  if value.is_a?(Hash)
200
- from_wire(value)
222
+ raise ArgumentError, "WireFormat nesting exceeds maximum depth (#{MAX_DEPTH})" if depth >= MAX_DEPTH
223
+
224
+ from_wire_at_depth(value, depth)
201
225
  elsif value.is_a?(Array)
202
- value.map { |elem| deep_convert_value_from_wire(elem) }
226
+ raise ArgumentError, "WireFormat nesting exceeds maximum depth (#{MAX_DEPTH})" if depth >= MAX_DEPTH
227
+
228
+ value.map { |elem| deep_convert_value_from_wire(elem, depth + 1) }
203
229
  else
204
230
  value
205
231
  end
data/lib/bsv-sdk.rb CHANGED
@@ -3,6 +3,20 @@
3
3
  require_relative 'bsv/version'
4
4
 
5
5
  module BSV
6
+ class << self
7
+ # Optional logger for debug-level instrumentation of txid conversions,
8
+ # BEEF wiring, and merkle path operations.
9
+ #
10
+ # No logger is configured by default — zero overhead when unused.
11
+ # Consumers opt in via:
12
+ #
13
+ # require 'logger'
14
+ # BSV.logger = Logger.new($stdout).tap { |l| l.level = Logger::DEBUG }
15
+ #
16
+ # @return [Logger, nil]
17
+ attr_accessor :logger
18
+ end
19
+
6
20
  autoload :Primitives, 'bsv/primitives'
7
21
  autoload :Script, 'bsv/script'
8
22
  autoload :Transaction, 'bsv/transaction'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bsv-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Bettison
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '0.12'
32
+ version: '0.15'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0.12'
39
+ version: '0.15'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: secp256k1-native
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -104,6 +104,7 @@ files:
104
104
  - lib/bsv/network/protocols.rb
105
105
  - lib/bsv/network/protocols/arc.rb
106
106
  - lib/bsv/network/protocols/chaintracks.rb
107
+ - lib/bsv/network/protocols/jungle_bus.rb
107
108
  - lib/bsv/network/protocols/ordinals.rb
108
109
  - lib/bsv/network/protocols/taal_binary.rb
109
110
  - lib/bsv/network/protocols/woc_rest.rb