bsv-sdk 0.22.0 → 0.23.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d666b0e5af3155dbe92f4298f5448a5792275848f6e3c08fcc1bbfa09d9a20bd
4
- data.tar.gz: c4f3beba29031b049afe90a967b5d982ee473cea57ee077c09ba9c263385c067
3
+ metadata.gz: 5545794c00575e8bb9ce8ad04e6e156c435a9ed984e43a99db86e85d9d9648cb
4
+ data.tar.gz: 197daaa1e748ee650192920494a610d9f5aac6dcc43038eceb73c17991ba67f0
5
5
  SHA512:
6
- metadata.gz: ce7d22f5b2267f44909e871e15c619af28e0055db71f84a5fc7529c70c7c030d0314f466d328a2154c476530a6485b19588e09a96ce7ae3f406f29cfd6ec8569
7
- data.tar.gz: 46cfee8000801ffd398d659b6174b9ac48cc2e4fc098c93e367634f06cfc9d9c659211ef51c452fd7c83262121e8923c6ab7240588fe01782c3002a6fa4f8075
6
+ metadata.gz: 4382cc39a0c07227ba143554943fe66dedb9deaf5b7275ab82731417c4b9150fcfce27dd689b456db374cfdc7d6d4bd7c58238c00219b928332f6b19e0c24041
7
+ data.tar.gz: c6549c97011519d2d0ad8b4856df12fcc72311ff1a9800ec19b9e0d97d10355322f3216fb3c52a4c10b11bad3196b8ec01dd901a10e219d9cce3fd6ecd4a5770
data/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ 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.0 — 2026-06-03
9
+
10
+ ### Changed (breaking)
11
+ - **Canonical block-header response shape across protocols.** `Protocols::JungleBus`,
12
+ `Protocols::Chaintracks`, and `Protocols::WoCREST` now emit the merkle root as
13
+ `'merkle_root'` (lowercase snake_case) in their `:get_block_header` and
14
+ `:get_block_headers` responses, replacing the upstream-specific names
15
+ (`'merkleroot'` for JungleBus/WoCREST, `'merkleRoot'` for Chaintracks). Consumers
16
+ reading the raw field directly from `provider.call(:get_block_header).data` must
17
+ migrate to the canonical key. Wire protocols stay honest about other fields;
18
+ only the merkle-root key is renamed. No shim. (#791)
19
+ - `WoCREST#:valid_root` now reads the normalised `merkle_root` key internally
20
+ (no behaviour change — same comparison output).
21
+ - `BSV::Transaction::ChainTracker#valid_root_for_height?` reads
22
+ `result.data['merkle_root']` directly; the previous private
23
+ `normalise_merkle_root` helper is removed. Subclass-override pattern unchanged.
24
+
25
+ ### Note
26
+ - This is the "Pattern A" normalisation from #791 — push cosmetic field-name
27
+ divergence down into the wire-protocol classes where the data is semantically
28
+ identical across upstreams. Pattern B (broadcast / get_tx_status with
29
+ structurally divergent shapes) stays at the consumer layer and is not part of
30
+ this release.
31
+
8
32
  ## 0.22.0 — 2026-05-30
9
33
 
10
34
  ### Added
@@ -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.0'
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.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Bettison