bsv-sdk 0.22.0 → 0.23.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d666b0e5af3155dbe92f4298f5448a5792275848f6e3c08fcc1bbfa09d9a20bd
4
- data.tar.gz: c4f3beba29031b049afe90a967b5d982ee473cea57ee077c09ba9c263385c067
3
+ metadata.gz: ce9ccc589a407c6ad98d92e40b9ac05925f3fbf32cc73aa235b9fd9a35b7ad43
4
+ data.tar.gz: 46992e9ea4f2465c4ca80ad2bb84e2591426610b46d1eea72e11171efdc271bf
5
5
  SHA512:
6
- metadata.gz: ce7d22f5b2267f44909e871e15c619af28e0055db71f84a5fc7529c70c7c030d0314f466d328a2154c476530a6485b19588e09a96ce7ae3f406f29cfd6ec8569
7
- data.tar.gz: 46cfee8000801ffd398d659b6174b9ac48cc2e4fc098c93e367634f06cfc9d9c659211ef51c452fd7c83262121e8923c6ab7240588fe01782c3002a6fa4f8075
6
+ metadata.gz: ac7da8fbd4e5cb9e0385bb3035dc34d44460232afe826b095d19cccc04faece15cd090045c49d7d176f68d7ba98b5a16105812c66ae8ac27d657df8682b8c499
7
+ data.tar.gz: 1b6946dd9762ac777aa8d1fff4392c96e30cfabd5c6b14f3eba7a8997e7ef0f8d5eca86383c131dfb479ce7f6ac94b7049bc50490edde5b0ff6b6994d8392629
data/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ All notable changes to the `bsv-sdk` gem are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
6
6
  and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 0.23.1 — 2026-06-06
9
+
10
+ ### Fixed
11
+ - `Protocols::Arcade#parse_broadcast_response`, `Protocols::ARC#parse_single_broadcast_response`,
12
+ and `Protocols::ARC#parse_batch_broadcast_response` now preserve the parsed response body as
13
+ `data:` on non-2xx responses. Previously the body was parsed only to extract an `error_message`,
14
+ then discarded — leaving callers with `data: nil` and no way to read `txStatus` / `extraInfo`
15
+ from synchronous broadcast failures (the terminal-rejection shape). Additive change; the 2xx
16
+ success path and ARC's existing 2xx-REJECTED branch are unchanged. (#793)
17
+
18
+ ## 0.23.0 — 2026-06-03
19
+
20
+ ### Changed (breaking)
21
+ - **Canonical block-header response shape across protocols.** `Protocols::JungleBus`,
22
+ `Protocols::Chaintracks`, and `Protocols::WoCREST` now emit the merkle root as
23
+ `'merkle_root'` (lowercase snake_case) in their `:get_block_header` and
24
+ `:get_block_headers` responses, replacing the upstream-specific names
25
+ (`'merkleroot'` for JungleBus/WoCREST, `'merkleRoot'` for Chaintracks). Consumers
26
+ reading the raw field directly from `provider.call(:get_block_header).data` must
27
+ migrate to the canonical key. Wire protocols stay honest about other fields;
28
+ only the merkle-root key is renamed. No shim. (#791)
29
+ - `WoCREST#:valid_root` now reads the normalised `merkle_root` key internally
30
+ (no behaviour change — same comparison output).
31
+ - `BSV::Transaction::ChainTracker#valid_root_for_height?` reads
32
+ `result.data['merkle_root']` directly; the previous private
33
+ `normalise_merkle_root` helper is removed. Subclass-override pattern unchanged.
34
+
35
+ ### Note
36
+ - This is the "Pattern A" normalisation from #791 — push cosmetic field-name
37
+ divergence down into the wire-protocol classes where the data is semantically
38
+ identical across upstreams. Pattern B (broadcast / get_tx_status with
39
+ structurally divergent shapes) stays at the consumer layer and is not part of
40
+ this release.
41
+
8
42
  ## 0.22.0 — 2026-05-30
9
43
 
10
44
  ### Added
@@ -179,7 +179,8 @@ module BSV
179
179
  return ProtocolResponse.new(
180
180
  response,
181
181
  http_success: false,
182
- error_message: body['detail'] || body['title'] || "HTTP #{code}"
182
+ error_message: body['detail'] || body['title'] || "HTTP #{code}",
183
+ data: body
183
184
  )
184
185
  end
185
186
 
@@ -215,7 +216,8 @@ module BSV
215
216
  return ProtocolResponse.new(
216
217
  response,
217
218
  http_success: false,
218
- error_message: body.is_a?(Hash) ? (body['detail'] || body['title'] || "HTTP #{code}") : "HTTP #{code}"
219
+ error_message: body.is_a?(Hash) ? (body['detail'] || body['title'] || "HTTP #{code}") : "HTTP #{code}",
220
+ data: body.is_a?(Hash) || body.is_a?(Array) ? body : nil
219
221
  )
220
222
  end
221
223
 
@@ -127,7 +127,8 @@ module BSV
127
127
  return ProtocolResponse.new(
128
128
  response,
129
129
  http_success: false,
130
- error_message: body.is_a?(Hash) ? (body['reason'] || body['detail'] || "HTTP #{code}") : "HTTP #{code}"
130
+ error_message: body.is_a?(Hash) ? (body['reason'] || body['detail'] || "HTTP #{code}") : "HTTP #{code}",
131
+ data: body.is_a?(Hash) ? body : nil
131
132
  )
132
133
  end
133
134
 
@@ -21,7 +21,7 @@ module BSV
21
21
  # result.data # => 800000
22
22
  #
23
23
  # result = ct.call(:get_block_header, 800_000)
24
- # result.data # => { 'hash' => '...', 'height' => 800000, 'merkleRoot' => '...' }
24
+ # result.data # => { 'hash' => '...', 'height' => 800000, 'merkle_root' => '...' }
25
25
  #
26
26
  # @note No public Chaintracks instance is hosted by major providers — GorillaPool
27
27
  # serves chain data via JungleBus instead. For general chain-tracking against
@@ -40,6 +40,26 @@ module BSV
40
40
  def initialize(base_url:, api_key: nil, auth: nil, http_client: nil)
41
41
  super
42
42
  end
43
+
44
+ private
45
+
46
+ # Block-header escape hatch: normalises Chaintracks's +merkleRoot+ field
47
+ # to the canonical +merkle_root+ key. See issue #791 for the cross-protocol
48
+ # rationale.
49
+ def call_get_block_header(*, **)
50
+ response = default_call(:get_block_header, *, **)
51
+ return response unless response.http_success?
52
+
53
+ response.with(data: normalize_block_header(response.data))
54
+ end
55
+
56
+ def normalize_block_header(data)
57
+ return data unless data.is_a?(Hash) && data.key?('merkleRoot')
58
+
59
+ data = data.dup
60
+ data['merkle_root'] = data.delete('merkleRoot')
61
+ data
62
+ end
43
63
  end
44
64
  end
45
65
  end
@@ -52,6 +52,34 @@ module BSV
52
52
  def initialize(base_url:, api_key: nil, auth: nil, http_client: nil)
53
53
  super
54
54
  end
55
+
56
+ private
57
+
58
+ # Block-header escape hatch: normalises JungleBus's +merkleroot+ field
59
+ # to the canonical +merkle_root+ key. See issue #791 for the cross-protocol
60
+ # rationale.
61
+ def call_get_block_header(*, **)
62
+ response = default_call(:get_block_header, *, **)
63
+ return response unless response.http_success?
64
+
65
+ response.with(data: normalize_block_header(response.data))
66
+ end
67
+
68
+ def call_get_block_headers(*, **)
69
+ response = default_call(:get_block_headers, *, **)
70
+ return response unless response.http_success?
71
+ return response unless response.data.is_a?(Array)
72
+
73
+ response.with(data: response.data.map { |h| normalize_block_header(h) })
74
+ end
75
+
76
+ def normalize_block_header(data)
77
+ return data unless data.is_a?(Hash) && data.key?('merkleroot')
78
+
79
+ data = data.dup
80
+ data['merkle_root'] = data.delete('merkleroot')
81
+ data
82
+ end
55
83
  end
56
84
  end
57
85
  end
@@ -373,9 +373,36 @@ module BSV
373
373
  result = default_call(:valid_root, height)
374
374
  return result unless result.http_success?
375
375
 
376
- actual = result.data['merkleroot']
376
+ data = normalize_block_header(result.data)
377
+ actual = data['merkle_root']
377
378
  result.with(data: actual.to_s.downcase == root.to_s.downcase)
378
379
  end
380
+
381
+ # Block-header escape hatch: normalises WoCREST's +merkleroot+ field
382
+ # to the canonical +merkle_root+ key. See issue #791 for the cross-protocol
383
+ # rationale.
384
+ def call_get_block_header(*, **)
385
+ response = default_call(:get_block_header, *, **)
386
+ return response unless response.http_success?
387
+
388
+ response.with(data: normalize_block_header(response.data))
389
+ end
390
+
391
+ def call_get_block_headers(*, **)
392
+ response = default_call(:get_block_headers, *, **)
393
+ return response unless response.http_success?
394
+ return response unless response.data.is_a?(Array)
395
+
396
+ response.with(data: response.data.map { |h| normalize_block_header(h) })
397
+ end
398
+
399
+ def normalize_block_header(data)
400
+ return data unless data.is_a?(Hash) && data.key?('merkleroot')
401
+
402
+ data = data.dup
403
+ data['merkle_root'] = data.delete('merkleroot')
404
+ data
405
+ end
379
406
  end
380
407
  end
381
408
  end
@@ -70,8 +70,11 @@ module BSV
70
70
  # Verify that a merkle root is valid for the given block height.
71
71
  #
72
72
  # Dispatches +:get_block_header+ to the configured provider. Returns +false+
73
- # on 404 (block not found). Normalises the merkle root field name from any
74
- # of +merkleroot+, +merkleRoot+, or +merkle_root+.
73
+ # on 404 (block not found). Relies on the wire-protocol classes that expose
74
+ # +:get_block_header+ (+Protocols::JungleBus+, +Protocols::Chaintracks+,
75
+ # +Protocols::WoCREST+) to emit the canonical +merkle_root+ key — see
76
+ # issue #791 for the Pattern A normalisation that absorbed the previous
77
+ # field-name shim.
75
78
  #
76
79
  # @param root [String] merkle root as a hex string
77
80
  # @param height [Integer] block height
@@ -85,7 +88,7 @@ module BSV
85
88
  return false if result.http_not_found?
86
89
  raise result.error_message.to_s unless result.http_success?
87
90
 
88
- actual = normalise_merkle_root(result.data)
91
+ actual = result.data.is_a?(Hash) ? result.data['merkle_root'] : nil
89
92
  return false unless actual
90
93
 
91
94
  actual.casecmp(root).zero?
@@ -106,17 +109,6 @@ module BSV
106
109
 
107
110
  raise result.error_message.to_s
108
111
  end
109
-
110
- private
111
-
112
- # Field-name diversity belongs at the Protocols::* layer; this is a
113
- # transitional shim until the wire protocols return canonical shapes.
114
- # See #791.
115
- def normalise_merkle_root(body)
116
- return nil unless body.is_a?(Hash)
117
-
118
- body['merkleroot'] || body['merkleRoot'] || body['merkle_root']
119
- end
120
112
  end
121
113
  end
122
114
  end
data/lib/bsv/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BSV
4
- VERSION = '0.22.0'
4
+ VERSION = '0.23.1'
5
5
  end
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.22.0
4
+ version: 0.23.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Bettison