honeymaker 0.12.2 → 0.12.4

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/native-gems.yml +100 -0
  3. data/.github/workflows/release.yml +36 -0
  4. data/.github/workflows/test.yml +19 -4
  5. data/Cargo.lock +1078 -0
  6. data/Cargo.toml +14 -0
  7. data/README.md +39 -0
  8. data/Rakefile +28 -16
  9. data/crates/honeymaker/Cargo.toml +18 -0
  10. data/crates/honeymaker/src/encode.rs +106 -0
  11. data/crates/honeymaker/src/kraken/lookup.rs +140 -0
  12. data/crates/honeymaker/src/kraken/mod.rs +5 -0
  13. data/crates/honeymaker/src/kraken/normalize.rs +536 -0
  14. data/crates/honeymaker/src/kraken/requests.rs +286 -0
  15. data/crates/honeymaker/src/kraken/sign.rs +166 -0
  16. data/crates/honeymaker/src/kraken/trades.rs +201 -0
  17. data/crates/honeymaker/src/lib.rs +10 -0
  18. data/crates/honeymaker/src/num.rs +115 -0
  19. data/crates/honeymaker/src/semantics.rs +100 -0
  20. data/crates/honeymaker/src/types.rs +85 -0
  21. data/crates/honeymaker/tests/kraken_stage2.rs +592 -0
  22. data/crates/honeymaker/tests/kraken_trades_pager.rs +307 -0
  23. data/crates/honeymaker/tests/kraken_vectors.rs +78 -0
  24. data/crates/honeymaker/tests/vectors/decimal.json +146 -0
  25. data/crates/honeymaker/tests/vectors/kraken_add_order_wire.json +74 -0
  26. data/crates/honeymaker/tests/vectors/kraken_signing.json +3314 -0
  27. data/crates/honeymaker/tests/vectors/kraken_trades_pager.json +1583 -0
  28. data/crates/honeymaker-client/Cargo.toml +30 -0
  29. data/crates/honeymaker-client/examples/probe.rs +147 -0
  30. data/crates/honeymaker-client/src/kraken.rs +514 -0
  31. data/crates/honeymaker-client/src/lib.rs +4 -0
  32. data/crates/honeymaker-client/src/transport/connect.rs +583 -0
  33. data/crates/honeymaker-client/src/transport/io_timeout.rs +352 -0
  34. data/crates/honeymaker-client/src/transport/response.rs +169 -0
  35. data/crates/honeymaker-client/src/transport.rs +467 -0
  36. data/crates/honeymaker-client/tests/classification.rs +203 -0
  37. data/crates/honeymaker-client/tests/kraken_client.rs +949 -0
  38. data/crates/honeymaker-client/tests/response.rs +522 -0
  39. data/crates/honeymaker-client/tests/support/mod.rs +550 -0
  40. data/crates/honeymaker-client/tests/transport.rs +828 -0
  41. data/ext/honeymaker_native/Cargo.toml +16 -0
  42. data/ext/honeymaker_native/extconf.rb +6 -0
  43. data/ext/honeymaker_native/src/convert.rs +150 -0
  44. data/ext/honeymaker_native/src/kraken.rs +362 -0
  45. data/ext/honeymaker_native/src/lib.rs +90 -0
  46. data/ext/honeymaker_native/src/ruby_decimal.rs +90 -0
  47. data/lib/honeymaker/clients/bybit.rb +19 -2
  48. data/lib/honeymaker/clients/coinbase.rb +3 -2
  49. data/lib/honeymaker/clients/kraken.rb +17 -1
  50. data/lib/honeymaker/exchanges/coinbase.rb +5 -4
  51. data/lib/honeymaker/native/kraken.rb +263 -0
  52. data/lib/honeymaker/native.rb +42 -0
  53. data/lib/honeymaker/version.rb +1 -1
  54. data/lib/honeymaker.rb +12 -2
  55. data/script/parity/kraken_client_live.rb +191 -0
  56. data/script/parity/kraken_live.rb +70 -0
  57. data/script/parity/kraken_transport.rb +604 -0
  58. data/script/parity/resolve.c +49 -0
  59. data/script/release/push_gems.sh +28 -0
  60. data/script/vectors/kraken.rb +50 -0
  61. data/script/vectors/kraken_stage2.rb +146 -0
  62. data/test/fixtures/coinbase_products.json +1 -1
  63. data/test/honeymaker/clients/bybit_client_test.rb +25 -0
  64. data/test/honeymaker/clients/coinbase_client_test.rb +14 -0
  65. data/test/honeymaker/clients/kraken_client_test.rb +27 -0
  66. data/test/honeymaker/exchanges/coinbase_test.rb +22 -2
  67. data/test/native/backend_switch_test.rb +53 -0
  68. data/test/native/convert_test.rb +137 -0
  69. data/test/native/gem_isolation_test.rb +17 -0
  70. data/test/native/loader_test.rb +29 -0
  71. data/test/native/lockstep_test.rb +23 -0
  72. data/test/native/signing_smoke_test.rb +28 -0
  73. data/test/parity/kraken_client_parity_test.rb +398 -0
  74. data/test/parity/kraken_exchange_parity_test.rb +172 -0
  75. data/test/release/branch_hardening_test.rb +34 -0
  76. data/test/release/push_gems_test.rb +79 -0
  77. data/test/smoke.rb +24 -0
  78. data/test/support/kraken_signing_smoke.rb +21 -0
  79. data/test/support/parity_helper.rb +62 -0
  80. data/test/support/venue_double.rb +100 -0
  81. metadata +84 -4
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+ require "tmpdir"
5
+ require "digest"
6
+ require "rubygems/package"
7
+
8
+ class PushGemsTest < Minitest::Test
9
+ SCRIPT = File.expand_path("../../script/release/push_gems.sh", __dir__)
10
+
11
+ PLATFORMS = %w[x86_64-linux aarch64-linux x86_64-darwin arm64-darwin x64-mingw-ucrt].freeze
12
+
13
+ def build_gem(dir, platform)
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = "honeymaker"
16
+ s.version = "9.9.9"
17
+ s.summary = "t"
18
+ s.authors = ["t"]
19
+ s.files = []
20
+ s.platform = platform
21
+ end
22
+ Dir.chdir(dir) { Gem::Package.build(spec) }
23
+ File.join(dir, spec.file_name)
24
+ end
25
+
26
+ def run_script(gems_dir, published_sha:, push_fails:)
27
+ Dir.mktmpdir do |bin|
28
+ log = File.join(bin, "log")
29
+ File.write(File.join(bin, "gem"), "#!/bin/sh\necho \"push $2\" >> #{log}\n#{push_fails ? 'exit 1' : 'exit 0'}\n")
30
+ File.write(File.join(bin, "curl"), "#!/bin/sh\necho '{\"sha\":\"#{published_sha}\"}'\n")
31
+ File.chmod(0o755, File.join(bin, "gem"), File.join(bin, "curl"))
32
+ out = `PATH=#{bin}:$PATH #{SCRIPT} #{gems_dir} 9.9.9 2>&1`
33
+ [$?.success?, out, File.exist?(log) ? File.read(log).lines.map { |l| File.basename(l.split.last) } : []]
34
+ end
35
+ end
36
+
37
+ def full_set(dir)
38
+ plats = PLATFORMS.map { |pl| build_gem(dir, pl) }
39
+ [plats, build_gem(dir, "ruby")]
40
+ end
41
+
42
+ def test_platform_gems_first_then_source_and_idempotent_on_identical_rerun
43
+ Dir.mktmpdir do |dir|
44
+ plats, source = full_set(dir)
45
+ ok, _out, order = run_script(dir, published_sha: "x", push_fails: false)
46
+ assert ok
47
+ assert_equal plats.map { |g| File.basename(g) } + [File.basename(source)], order
48
+ ok, out, = run_script(dir, published_sha: Digest::SHA256.file(plats.first).hexdigest, push_fails: true)
49
+ refute ok, "only the first gem matches the stubbed sha, so the run must stop at the second"
50
+ assert_includes out, "already published with the same checksum"
51
+ end
52
+ end
53
+
54
+ def test_mismatched_published_gem_fails
55
+ Dir.mktmpdir do |dir|
56
+ full_set(dir)
57
+ ok, out, = run_script(dir, published_sha: "deadbeef", push_fails: true)
58
+ refute ok
59
+ assert_includes out, "differs from the published gem"
60
+ end
61
+ end
62
+
63
+ def test_missing_or_empty_artifacts_push_nothing_and_fail
64
+ Dir.mktmpdir do |dir|
65
+ ok, out, order = run_script(File.join(dir, "nope"), published_sha: "x", push_fails: false)
66
+ refute ok
67
+ assert_empty order
68
+ ok, out, order = run_script(dir, published_sha: "x", push_fails: false)
69
+ refute ok, out
70
+ assert_empty order
71
+ PLATFORMS.first(4).each { |pl| build_gem(dir, pl) }
72
+ build_gem(dir, "ruby")
73
+ ok, out, order = run_script(dir, published_sha: "x", push_fails: false)
74
+ refute ok, "one platform missing must block the whole release"
75
+ assert_includes out, "missing honeymaker-9.9.9-x64-mingw-ucrt.gem"
76
+ assert_empty order
77
+ end
78
+ end
79
+ end
data/test/smoke.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Runs against an INSTALLED gem (no bundler, no -Ilib) on native CI runners.
4
+ # EXPECT_PLATFORM=x86_64-linux (platform gem) or EXPECT_PLATFORM=ruby (source gem, compiled on install).
5
+ require "honeymaker"
6
+
7
+ Honeymaker::Native.load!
8
+ abort "native #{Honeymaker::Native::Ext.version} != gem #{Honeymaker::VERSION}" unless Honeymaker::Native::Ext.version == Honeymaker::VERSION
9
+ spec = Gem.loaded_specs.fetch("honeymaker")
10
+ expected = ENV.fetch("EXPECT_PLATFORM")
11
+ abort "installed platform #{spec.platform} != #{expected}" unless spec.platform.to_s == expected
12
+ puts "smoke ok #{RUBY_VERSION} #{RUBY_PLATFORM} #{spec.full_name}"
13
+
14
+ require "uri"
15
+ ext = Honeymaker::Native::Ext::Kraken.new("k", "c2VjcmV0")
16
+ path, pairs = ext.build_post("get_extended_balance", {})
17
+ body = URI.encode_www_form(pairs)
18
+ headers = ext.sign(path, body)
19
+ abort "bad build #{path} #{body} #{headers.keys}" unless path == "/0/private/BalanceEx" && body.start_with?("nonce=") && headers["API-Sign"]
20
+ puts "smoke kraken ok"
21
+
22
+ require_relative "support/kraken_signing_smoke"
23
+ KrakenSigningSmoke.verify!
24
+ puts "smoke kraken signing vector ok"
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module KrakenSigningSmoke
6
+ VECTORS = File.expand_path("../../crates/honeymaker/tests/vectors/kraken_signing.json", __dir__)
7
+
8
+ def self.verify!
9
+ vector = JSON.parse(File.read(VECTORS)).find do |entry|
10
+ !entry.fetch("api_key").empty? && !entry.fetch("api_secret").empty?
11
+ end
12
+ abort "no authenticated Kraken signing vector" unless vector
13
+
14
+ signer = Honeymaker::Native::Ext::Kraken.new(vector.fetch("api_key"), vector.fetch("api_secret"))
15
+ headers = signer.sign(vector.fetch("path"), vector.fetch("body"))
16
+ %w[API-Key API-Sign].each do |field|
17
+ abort "Kraken signing vector mismatch: #{field}" unless headers[field] == vector.fetch("headers").fetch(field)
18
+ end
19
+ true
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bigdecimal"
4
+ require_relative "venue_double"
5
+
6
+ # Same-process parity; the legacy client is the oracle. Exact comparison: class, value, String
7
+ # encoding, Float#eql?, BigDecimal sign, Hash key order.
8
+ module ParityHelper
9
+ def self.included(base)
10
+ base.class_eval do
11
+ def setup
12
+ Honeymaker::Native.load!
13
+ require "honeymaker/native/kraken"
14
+ rescue LoadError
15
+ raise if ENV["HONEYMAKER_REQUIRE_NATIVE"]
16
+
17
+ skip "native extension not compiled"
18
+ end
19
+ end
20
+ end
21
+
22
+ def assert_same_ruby(expected, actual, path = "result")
23
+ return assert_same_exception(expected, actual, path) if expected.is_a?(Exception)
24
+
25
+ assert_equal expected.class, actual.class, "#{path}: class"
26
+ case expected
27
+ when Honeymaker::Result
28
+ assert_same_ruby(expected.errors, actual.errors, "#{path}.errors")
29
+ assert_same_ruby(expected.data, actual.data, "#{path}.data")
30
+ when Hash
31
+ assert_equal expected.keys, actual.keys, "#{path}: keys/order"
32
+ expected.each { |k, v| assert_same_ruby(v, actual[k], "#{path}[#{k.inspect}]") }
33
+ when Array
34
+ assert_equal expected.length, actual.length, "#{path}: length"
35
+ expected.each_with_index { |v, i| assert_same_ruby(v, actual[i], "#{path}[#{i}]") }
36
+ when String
37
+ assert_equal expected.encoding, actual.encoding, "#{path}: encoding"
38
+ assert_equal expected.b, actual.b, "#{path}: bytes"
39
+ when Float
40
+ assert expected.eql?(actual) || (expected.nan? && actual.nan?), "#{path}: #{expected} vs #{actual}"
41
+ when BigDecimal
42
+ assert_equal [expected.to_s, expected.sign], [actual.to_s, actual.sign], "#{path}: BigDecimal"
43
+ else
44
+ if expected.nil?
45
+ assert_nil actual, "#{path}: value"
46
+ else
47
+ assert_equal expected, actual, "#{path}: value"
48
+ end
49
+ end
50
+ end
51
+
52
+ # The one documented divergence (spec §5.1): legacy's incidental NoMethodError/TypeError on a
53
+ # nonsensical shape vs ShapeError. Never excuses decimal errors (ArgumentError must match exactly).
54
+ def assert_same_exception(expected, actual, path)
55
+ assert_kind_of Exception, actual, "#{path}: native returned instead of raising"
56
+ if actual.is_a?(Honeymaker::Native::ShapeError)
57
+ assert_includes [NoMethodError, TypeError], expected.class, "#{path}: ShapeError only replaces shape crashes"
58
+ else
59
+ assert_equal [expected.class, expected.message], [actual.class, actual.message], path
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ # Plain-HTTP local venue: scripted replies, recorded requests. Both backends talk to it through
6
+ # the same legacy Faraday connection, one after the other, so URLs in messages are equal.
7
+ class VenueDouble
8
+ Request = Struct.new(:method, :target, :headers, :body, keyword_init: true)
9
+
10
+ attr_reader :port, :requests
11
+
12
+ def initialize(replies)
13
+ reset!(replies)
14
+ @tcp = TCPServer.new("127.0.0.1", 0)
15
+ @port = @tcp.addr[1]
16
+ @thread = Thread.new { loop { serve(@tcp.accept) } }
17
+ end
18
+
19
+ def reset!(replies)
20
+ @replies = replies.dup
21
+ @requests = []
22
+ end
23
+
24
+ def url = "http://127.0.0.1:#{port}"
25
+
26
+ def close
27
+ @thread.kill
28
+ @tcp.close
29
+ end
30
+
31
+ private
32
+
33
+ def serve(sock)
34
+ Thread.new do
35
+ loop do
36
+ req = read_request(sock) or break
37
+ @requests << req
38
+ status, headers, body = @replies.length > 1 ? @replies.shift : @replies.first
39
+ body = body.to_s.b
40
+ h = { "content-length" => body.bytesize.to_s }.merge(headers)
41
+ sock.write "HTTP/1.1 #{status} X\r\n#{h.map { |k, v| "#{k}: #{v}\r\n" }.join}\r\n#{body}"
42
+ end
43
+ rescue StandardError
44
+ nil
45
+ ensure
46
+ sock.close rescue nil
47
+ end
48
+ end
49
+
50
+ def read_request(io)
51
+ head = +""
52
+ head << io.readpartial(4096) until head.include?("\r\n\r\n")
53
+ line, *hdrs = head.split("\r\n\r\n", 2).first.split("\r\n")
54
+ headers = hdrs.to_h { |h| k, v = h.split(": ", 2); [k.downcase, v] }
55
+ body = head.split("\r\n\r\n", 2)[1].to_s.b
56
+ body << io.readpartial(4096) while body.bytesize < headers["content-length"].to_i
57
+ method, target, = line.split(" ")
58
+ Request.new(method: method, target: target, headers: headers, body: body)
59
+ rescue EOFError, IOError
60
+ nil
61
+ end
62
+ end
63
+
64
+ # HTTP proxy double: records the first request line of each proxied connection and forwards the
65
+ # bytes to 127.0.0.1:<upstream_port> (absolute-form for http targets, as Net::HTTP sends them).
66
+ class ProxyDouble
67
+ attr_reader :port, :lines
68
+
69
+ def initialize(upstream_port)
70
+ @lines = []
71
+ @tcp = TCPServer.new("127.0.0.1", 0)
72
+ @port = @tcp.addr[1]
73
+ @thread = Thread.new do
74
+ loop do
75
+ s = @tcp.accept
76
+ Thread.new do
77
+ head = +""
78
+ head << s.readpartial(4096) until head.include?("\r\n\r\n")
79
+ @lines << head.lines.first
80
+ up = TCPSocket.new("127.0.0.1", upstream_port)
81
+ up.write(head)
82
+ t = Thread.new { IO.copy_stream(s, up) rescue nil }
83
+ IO.copy_stream(up, s) rescue nil
84
+ t.join(1)
85
+ rescue StandardError
86
+ nil
87
+ ensure
88
+ s.close rescue nil
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def url = "http://127.0.0.1:#{port}"
95
+
96
+ def close
97
+ @thread.kill
98
+ @tcp.close
99
+ end
100
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeymaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.12.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deltabadger
@@ -79,19 +79,76 @@ dependencies:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rb_sys
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.9.130
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.9.130
82
96
  description: Unified interface for cryptocurrency exchange APIs — market data, trading,
83
97
  balances, and orders. Supports Binance, Kraken, Coinbase, Bybit, KuCoin, Bitget,
84
98
  MEXC, and more.
85
99
  email:
86
100
  - hello@deltabadger.com
87
101
  executables: []
88
- extensions: []
102
+ extensions:
103
+ - ext/honeymaker_native/extconf.rb
89
104
  extra_rdoc_files: []
90
105
  files:
106
+ - ".github/workflows/native-gems.yml"
107
+ - ".github/workflows/release.yml"
91
108
  - ".github/workflows/test.yml"
109
+ - Cargo.lock
110
+ - Cargo.toml
92
111
  - LICENSE
93
112
  - README.md
94
113
  - Rakefile
114
+ - crates/honeymaker-client/Cargo.toml
115
+ - crates/honeymaker-client/examples/probe.rs
116
+ - crates/honeymaker-client/src/kraken.rs
117
+ - crates/honeymaker-client/src/lib.rs
118
+ - crates/honeymaker-client/src/transport.rs
119
+ - crates/honeymaker-client/src/transport/connect.rs
120
+ - crates/honeymaker-client/src/transport/io_timeout.rs
121
+ - crates/honeymaker-client/src/transport/response.rs
122
+ - crates/honeymaker-client/tests/classification.rs
123
+ - crates/honeymaker-client/tests/kraken_client.rs
124
+ - crates/honeymaker-client/tests/response.rs
125
+ - crates/honeymaker-client/tests/support/mod.rs
126
+ - crates/honeymaker-client/tests/transport.rs
127
+ - crates/honeymaker/Cargo.toml
128
+ - crates/honeymaker/src/encode.rs
129
+ - crates/honeymaker/src/kraken/lookup.rs
130
+ - crates/honeymaker/src/kraken/mod.rs
131
+ - crates/honeymaker/src/kraken/normalize.rs
132
+ - crates/honeymaker/src/kraken/requests.rs
133
+ - crates/honeymaker/src/kraken/sign.rs
134
+ - crates/honeymaker/src/kraken/trades.rs
135
+ - crates/honeymaker/src/lib.rs
136
+ - crates/honeymaker/src/num.rs
137
+ - crates/honeymaker/src/semantics.rs
138
+ - crates/honeymaker/src/types.rs
139
+ - crates/honeymaker/tests/kraken_stage2.rs
140
+ - crates/honeymaker/tests/kraken_trades_pager.rs
141
+ - crates/honeymaker/tests/kraken_vectors.rs
142
+ - crates/honeymaker/tests/vectors/decimal.json
143
+ - crates/honeymaker/tests/vectors/kraken_add_order_wire.json
144
+ - crates/honeymaker/tests/vectors/kraken_signing.json
145
+ - crates/honeymaker/tests/vectors/kraken_trades_pager.json
146
+ - ext/honeymaker_native/Cargo.toml
147
+ - ext/honeymaker_native/extconf.rb
148
+ - ext/honeymaker_native/src/convert.rs
149
+ - ext/honeymaker_native/src/kraken.rs
150
+ - ext/honeymaker_native/src/lib.rs
151
+ - ext/honeymaker_native/src/ruby_decimal.rs
95
152
  - lib/honeymaker.rb
96
153
  - lib/honeymaker/client.rb
97
154
  - lib/honeymaker/clients/binance.rb
@@ -122,9 +179,18 @@ files:
122
179
  - lib/honeymaker/exchanges/kraken.rb
123
180
  - lib/honeymaker/exchanges/kucoin.rb
124
181
  - lib/honeymaker/exchanges/mexc.rb
182
+ - lib/honeymaker/native.rb
183
+ - lib/honeymaker/native/kraken.rb
125
184
  - lib/honeymaker/result.rb
126
185
  - lib/honeymaker/utils.rb
127
186
  - lib/honeymaker/version.rb
187
+ - script/parity/kraken_client_live.rb
188
+ - script/parity/kraken_live.rb
189
+ - script/parity/kraken_transport.rb
190
+ - script/parity/resolve.c
191
+ - script/release/push_gems.sh
192
+ - script/vectors/kraken.rb
193
+ - script/vectors/kraken_stage2.rb
128
194
  - sig/honeymaker.rbs
129
195
  - test/fixtures/binance_book_ticker.json
130
196
  - test/fixtures/binance_exchange_info.json
@@ -189,7 +255,21 @@ files:
189
255
  - test/honeymaker/honeymaker_test.rb
190
256
  - test/honeymaker/result_test.rb
191
257
  - test/honeymaker/utils_test.rb
258
+ - test/native/backend_switch_test.rb
259
+ - test/native/convert_test.rb
260
+ - test/native/gem_isolation_test.rb
261
+ - test/native/loader_test.rb
262
+ - test/native/lockstep_test.rb
263
+ - test/native/signing_smoke_test.rb
264
+ - test/parity/kraken_client_parity_test.rb
265
+ - test/parity/kraken_exchange_parity_test.rb
266
+ - test/release/branch_hardening_test.rb
267
+ - test/release/push_gems_test.rb
268
+ - test/smoke.rb
192
269
  - test/support/fixture_helper.rb
270
+ - test/support/kraken_signing_smoke.rb
271
+ - test/support/parity_helper.rb
272
+ - test/support/venue_double.rb
193
273
  - test/test_helper.rb
194
274
  homepage: https://github.com/deltabadger/honeymaker
195
275
  licenses:
@@ -204,14 +284,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
284
  requirements:
205
285
  - - ">="
206
286
  - !ruby/object:Gem::Version
207
- version: 3.2.0
287
+ version: 3.4.0
208
288
  required_rubygems_version: !ruby/object:Gem::Requirement
209
289
  requirements:
210
290
  - - ">="
211
291
  - !ruby/object:Gem::Version
212
292
  version: '0'
213
293
  requirements: []
214
- rubygems_version: 4.0.3
294
+ rubygems_version: 3.6.9
215
295
  specification_version: 4
216
296
  summary: Ruby clients for cryptocurrency exchange APIs
217
297
  test_files: []