bsv-sdk 0.19.1 → 0.20.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: ffaea2263b4744cda53ec2ad10f1f842fbd19b6baf07ed0268788a2411a5f42a
4
- data.tar.gz: 34ea44a136351a85aa373e6cd8e089dd0cf52d273bf162b3f029f8fd1091448c
3
+ metadata.gz: f7066943d0a9d1aa217f1ed97a3dc0390fd5c1bdbad845183bf7ccbc87f582f3
4
+ data.tar.gz: e4914b71001219c5144433f2481097e141096fcbd82a969f655fe1afae242133
5
5
  SHA512:
6
- metadata.gz: 6eb51aad42cb0ff70bd210c01ac8bada4d32ca38ce574ec9d63ef944d6e75f78902974ffcd35eb290260a81efc375d1bac9b40a82ab083bdbdfa5fb541fc10d4
7
- data.tar.gz: 87a040c985ef1d70b131db723c58367b67ce7b6d3cc68d42d70e37a74b573fabd9354dcffc521214671f49bb75d2635cbee89fcc4c3870b5da4292587f84854e
6
+ metadata.gz: a6497f1705a3e87d5e5cf2e4f7b20150440475463461e3ef15fdb31b33d4a602beb0b2fe30852ea6da3c19c18f44dc4348fbc596008dfd101c3e2ae9de9fccdb
7
+ data.tar.gz: 21cdf72face3b0748442322a8b506f821432dc72d465a126b410e182e7ca4da17f29573f5b3c999c121ff2e5c4e5d284c790974f825bf547ec2ee36ff1417e5f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ 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.20.0 — 2026-05-24
9
+
10
+ ### Changed
11
+ - Raise minimum Ruby version from 2.7 to 3.3; add Ruby 4.0 to CI matrix
12
+ - Remove Ruby 2.7 compatibility workarounds (Point#add fallback, OpenSSL.fixed_length_secure_compare fallback)
13
+ - Apply RuboCop modernisations unlocked by Ruby 3.3 target (anonymous forwarding, redundant `require 'set'`, `Hash#except`)
14
+
8
15
  ## 0.19.1 — 2026-05-13
9
16
 
10
17
  ### Fixed
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/sgbett/bsv-ruby-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/sgbett/bsv-ruby-sdk/actions/workflows/ci.yml)
4
4
  [![codecov](https://codecov.io/gh/sgbett/bsv-ruby-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/sgbett/bsv-ruby-sdk)
5
5
  [![Gem Version](https://img.shields.io/gem/v/bsv-sdk)](https://rubygems.org/gems/bsv-sdk)
6
- [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%202.7-red)](https://rubygems.org/gems/bsv-sdk)
6
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.3-red)](https://rubygems.org/gems/bsv-sdk)
7
7
 
8
8
  Welcome to the BSV Blockchain Libraries Project, the comprehensive Ruby SDK designed to provide an updated and unified layer for developing scalable applications on the BSV Blockchain. This SDK addresses the limitations of previous tools by offering a fresh, peer-to-peer approach, adhering to SPV, and ensuring privacy and scalability.
9
9
 
@@ -44,7 +44,7 @@ Elliptic curve operations (secp256k1) are provided by the [`secp256k1-native`](h
44
44
 
45
45
  ### Requirements
46
46
 
47
- - Ruby >= 2.7
47
+ - Ruby >= 3.3
48
48
  - No external dependencies beyond Ruby's standard library (`openssl` for hashing, HMAC, PBKDF2, and AES)
49
49
 
50
50
  ### Installation
@@ -37,7 +37,7 @@ module BSV
37
37
  #
38
38
  # @yieldparam message [Hash] the incoming auth message
39
39
  # @return [void]
40
- def on_data(&_block)
40
+ def on_data(&)
41
41
  raise NotImplementedError, "#{self.class}#on_data not implemented"
42
42
  end
43
43
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'net/http'
5
4
  require 'json'
6
5
  require 'uri'
@@ -132,11 +131,11 @@ module BSV
132
131
  # Subscriptions are not callable; calling one raises +NotImplementedError+.
133
132
  #
134
133
  # @param command_name [Symbol, String] command to invoke
135
- # @param args [Array] positional arguments forwarded to path interpolation
134
+ # @param * [Array] positional arguments forwarded to path interpolation
136
135
  # @param kwargs [Hash] keyword arguments forwarded to path interpolation
137
136
  # @return [ProtocolResponse]
138
137
  # @raise [ArgumentError] when command_name is not registered
139
- def call(command_name, *args, **kwargs)
138
+ def call(command_name, *, **kwargs)
140
139
  name = command_name.to_sym
141
140
 
142
141
  if self.class.subscriptions.key?(name)
@@ -147,10 +146,10 @@ module BSV
147
146
  escape = :"call_#{name}"
148
147
  if respond_to?(escape, true)
149
148
  BSV.logger&.debug { "[Protocol] #{self.class.name} :#{name} → escape hatch" }
150
- return kwargs.empty? ? send(escape, *args) : send(escape, *args, **kwargs)
149
+ return kwargs.empty? ? send(escape, *) : send(escape, *, **kwargs)
151
150
  end
152
151
 
153
- default_call(name, *args, **kwargs)
152
+ default_call(name, *, **kwargs)
154
153
  end
155
154
 
156
155
  # Dispatches a command directly via HTTP, bypassing any escape hatch.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  module BSV
6
4
  module Network
7
5
  # Provider is a named configuration container that hosts one or more Protocol
@@ -56,10 +54,10 @@ module BSV
56
54
  # execution.
57
55
  #
58
56
  # @param klass [Class] a Protocol subclass
59
- # @param kwargs [Hash] keyword arguments forwarded to +klass.new+
57
+ # @param ** [Hash] keyword arguments forwarded to +klass.new+
60
58
  # @return [Protocol] the newly created protocol instance
61
- def protocol(klass, **kwargs)
62
- instance = klass.new(**kwargs)
59
+ def protocol(klass, **)
60
+ instance = klass.new(**)
63
61
  @protocols << instance
64
62
  klass.commands.each do |cmd|
65
63
  @command_index[cmd] ||= instance
@@ -122,16 +120,16 @@ module BSV
122
120
  # Dispatches a command to the first-registered protocol that serves it.
123
121
  #
124
122
  # @param command_name [Symbol, String] command to invoke
125
- # @param args [Array] positional arguments forwarded to the protocol
126
- # @param kwargs [Hash] keyword arguments forwarded to the protocol
123
+ # @param * [Array] positional arguments forwarded to the protocol
124
+ # @param ** [Hash] keyword arguments forwarded to the protocol
127
125
  # @return [ProtocolResponse]
128
126
  # @raise [ArgumentError] when no registered protocol serves the command
129
- def call(command_name, *args, **kwargs)
127
+ def call(command_name, *, **)
130
128
  sym = command_name.to_sym
131
129
  instance = @command_index[sym]
132
130
  raise ArgumentError, "#{@name} does not provide command :#{sym}" unless instance
133
131
 
134
- instance.call(sym, *args, **kwargs)
132
+ instance.call(sym, *, **)
135
133
  end
136
134
 
137
135
  private
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'uri'
5
4
 
6
5
  module BSV
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'json'
5
4
  require 'uri'
6
5
 
@@ -98,21 +98,11 @@ module BSV
98
98
 
99
99
  # Add two curve points together.
100
100
  #
101
- # Uses +Point#add+ where available (Ruby 3.0+ / OpenSSL 3), falling
102
- # back to multi-scalar multiplication for Ruby 2.7 compatibility.
103
- #
104
101
  # @param point_a [OpenSSL::PKey::EC::Point] first point
105
102
  # @param point_b [OpenSSL::PKey::EC::Point] second point
106
103
  # @return [OpenSSL::PKey::EC::Point] the sum of the two points
107
104
  def add_points(point_a, point_b)
108
- if point_a.respond_to?(:add)
109
- point_a.add(point_b)
110
- else
111
- # Ruby 2.7 / OpenSSL < 3: use multi-scalar mul
112
- # point_a.mul(bns, points) = bns[0]*point_a + bns[1]*points[0] + ...
113
- one = OpenSSL::BN.new('1')
114
- point_a.mul([one, one], [point_b])
115
- end
105
+ point_a.add(point_b)
116
106
  end
117
107
 
118
108
  # Extract the x-coordinate from a curve point as a big number.
@@ -210,14 +210,7 @@ module BSV
210
210
  def secure_compare(mac, expected)
211
211
  return false unless mac.bytesize == expected.bytesize
212
212
 
213
- if OpenSSL.respond_to?(:fixed_length_secure_compare)
214
- OpenSSL.fixed_length_secure_compare(mac, expected)
215
- else
216
- # Constant-time comparison for Ruby < 3.2
217
- result = 0
218
- mac.bytes.zip(expected.bytes) { |x, y| result |= x ^ y }
219
- result.zero?
220
- end
213
+ OpenSSL.fixed_length_secure_compare(mac, expected)
221
214
  end
222
215
 
223
216
  def derive_keys(private_key, public_key)
@@ -22,7 +22,7 @@ module BSV
22
22
  module Hex
23
23
  # Matches an even number of hex characters (case-insensitive).
24
24
  # Empty string is valid (decodes to empty bytes).
25
- HEX_RE = /\A(?:[0-9a-fA-F]{2})*\z/n.freeze
25
+ HEX_RE = /\A(?:[0-9a-fA-F]{2})*\z/n
26
26
  private_constant :HEX_RE
27
27
 
28
28
  # Test whether +str+ is valid hex (even-length, hex-only).
@@ -334,7 +334,7 @@ module BSV
334
334
  }.freeze
335
335
 
336
336
  # Reverse lookup: opcode → hash type symbol (excludes :raw).
337
- RPUZZLE_OP_TO_TYPE = RPUZZLE_HASH_OPS.reject { |k, _| k == :raw }.invert.freeze
337
+ RPUZZLE_OP_TO_TYPE = RPUZZLE_HASH_OPS.except(:raw).invert.freeze
338
338
 
339
339
  # The fixed opcode prefix shared by all RPuzzle locking scripts.
340
340
  # OP_OVER OP_3 OP_SPLIT OP_NIP OP_1 OP_SPLIT OP_SWAP OP_SPLIT OP_DROP
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  module BSV
6
4
  module Transaction
7
5
  # Background Evaluation Extended Format (BEEF) for SPV-ready transaction
@@ -19,10 +19,10 @@ module BSV
19
19
  # Returns a Chaintracks instance using the GorillaPool provider default.
20
20
  #
21
21
  # @param testnet [Boolean] when true, uses the testnet endpoint
22
- # @param opts [Hash] forwarded to the underlying protocol (e.g. +api_key:+, +http_client:+)
22
+ # @param ** [Hash] forwarded to the underlying protocol (e.g. +api_key:+, +http_client:+)
23
23
  # @return [Chaintracks]
24
- def self.default(testnet: false, **opts)
25
- provider = BSV::Network::Providers::GorillaPool.default(testnet: testnet, **opts)
24
+ def self.default(testnet: false, **)
25
+ provider = BSV::Network::Providers::GorillaPool.default(testnet: testnet, **)
26
26
  protocol = provider.protocol_for(:current_height)
27
27
  new(protocol: protocol)
28
28
  end
@@ -20,10 +20,10 @@ module BSV
20
20
  # Returns a WhatsOnChain chain tracker using the provider default.
21
21
  #
22
22
  # @param testnet [Boolean] when true, uses the testnet endpoint
23
- # @param opts [Hash] forwarded to the underlying protocol (e.g. +api_key:+, +http_client:+)
23
+ # @param ** [Hash] forwarded to the underlying protocol (e.g. +api_key:+, +http_client:+)
24
24
  # @return [WhatsOnChain]
25
- def self.default(testnet: false, **opts)
26
- provider = BSV::Network::Providers::WhatsOnChain.default(testnet: testnet, **opts)
25
+ def self.default(testnet: false, **)
26
+ provider = BSV::Network::Providers::WhatsOnChain.default(testnet: testnet, **)
27
27
  new(protocol: provider.protocol_for(:valid_root))
28
28
  end
29
29
 
@@ -10,10 +10,10 @@ module BSV
10
10
  # Return a default chain tracker backed by the Arcade/GorillaPool Chaintracks API.
11
11
  #
12
12
  # @param testnet [Boolean] use the testnet endpoint when true
13
- # @param opts [Hash] forwarded to the underlying tracker (e.g. +api_key:+)
13
+ # @param ** [Hash] forwarded to the underlying tracker (e.g. +api_key:+)
14
14
  # @return [Chaintracks]
15
- def self.default(testnet: false, **opts)
16
- Chaintracks.default(testnet: testnet, **opts)
15
+ def self.default(testnet: false, **)
16
+ Chaintracks.default(testnet: testnet, **)
17
17
  end
18
18
  end
19
19
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  module BSV
6
4
  module Transaction
7
5
  # A BRC-74 merkle path (BUMP — Bitcoin Unified Merkle Path).
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.19.1'
4
+ VERSION = '0.20.0'
5
5
  end
@@ -350,13 +350,7 @@ module BSV
350
350
  def secure_compare(a, b)
351
351
  return false unless a.bytesize == b.bytesize
352
352
 
353
- if OpenSSL.respond_to?(:fixed_length_secure_compare)
354
- OpenSSL.fixed_length_secure_compare(a, b)
355
- else
356
- result = 0
357
- a.bytes.zip(b.bytes) { |x, y| result |= x ^ y }
358
- result.zero?
359
- end
353
+ OpenSSL.fixed_length_secure_compare(a, b)
360
354
  end
361
355
  end
362
356
  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.19.1
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Bettison
@@ -210,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
210
210
  requirements:
211
211
  - - ">="
212
212
  - !ruby/object:Gem::Version
213
- version: '2.7'
213
+ version: '3.3'
214
214
  required_rubygems_version: !ruby/object:Gem::Requirement
215
215
  requirements:
216
216
  - - ">="