honeymaker 0.9.11 → 0.10.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: 50e3e2d9451d404977937fddc4d265c25da9ca8ed848ba6d6c008f24e8e129c9
4
- data.tar.gz: a949bcc4a042ce6076986ae76c19fdb4a4bea583f0934fd6e1a5548e492d8898
3
+ metadata.gz: bbfab70631b45882e86a1f4af9ea69b9c32c98840a383183b69ebae133b2f3bf
4
+ data.tar.gz: 3d65a28ae18b85f5de60959aac90e327471ff617488956538442b6841ddc4bd9
5
5
  SHA512:
6
- metadata.gz: 9489aa1616d24f9d17b37c603b468426b0354d87aa27a16970165919859565a35195aef1a665348e6e1d24e3ca636eb23901d34c002a2a85f932a99d6a7335b1
7
- data.tar.gz: 70f1ebd03b468460c76c28bd5fcc69b975d64562790cef14075e13236e647d2132294a13e2bf3267b822526c6ae7d9905e7c5d18bfe28a0ea4e5548a169e4daa
6
+ metadata.gz: 00f3d5d33b5c1d231be4f1bafb5815083bc26cafae31a8cfe2c4403be217ece9120f7195bc6f5fa15d14286950c9f8817762767a4824f0c29396a6b679ca483e
7
+ data.tar.gz: 3209e5756f1aab9c2af0537c533b3b2dbadf468c635c5f882d4f85362679597495d78f9ec77a2f7ca1b10a8c1c534687d19b95be73989ce88fe23fbf5f03120a
data/README.md CHANGED
@@ -8,7 +8,7 @@ Ruby clients for cryptocurrency exchange APIs used by [Deltabadger](https://gith
8
8
 
9
9
  ## Supported Exchanges
10
10
 
11
- Binance, Binance US, Kraken, Kraken Futures, Coinbase, Bybit, KuCoin, Bitget, MEXC, Bitvavo, Gemini, Hyperliquid, BingX, Bitrue, BitMart.
11
+ Binance, Binance US, Kraken, Kraken Futures, Coinbase, Bybit, KuCoin, Bitget, MEXC, Bitvavo, Gemini, Hyperliquid, BingX, Bitrue.
12
12
 
13
13
  ## Installation
14
14
 
@@ -5,6 +5,11 @@ module Honeymaker
5
5
  class Hyperliquid < Exchange
6
6
  BASE_URL = "https://api.hyperliquid.xyz"
7
7
 
8
+ # Hyperliquid enforces a hard 10-USDC minimum order value on every spot pair (spotMeta exposes
9
+ # no per-token base floor). Surfaced as minimum_quote_size so consumers skip/reject sub-10
10
+ # orders up front instead of having the exchange reject them.
11
+ MINIMUM_QUOTE_SIZE = 10
12
+
8
13
  def get_tickers_info
9
14
  with_rescue do
10
15
  response = connection.post("/info") do |req|
@@ -25,7 +30,7 @@ module Honeymaker
25
30
  base: base_token["name"],
26
31
  quote: quote_token["name"],
27
32
  minimum_base_size: nil,
28
- minimum_quote_size: nil,
33
+ minimum_quote_size: MINIMUM_QUOTE_SIZE,
29
34
  maximum_base_size: nil,
30
35
  maximum_quote_size: nil,
31
36
  base_decimals: base_token["szDecimals"] || 0,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Honeymaker
4
- VERSION = "0.9.11"
4
+ VERSION = "0.10.0"
5
5
  end
data/lib/honeymaker.rb CHANGED
@@ -21,7 +21,6 @@ require_relative "honeymaker/clients/bitvavo"
21
21
  require_relative "honeymaker/clients/gemini"
22
22
  require_relative "honeymaker/clients/bingx"
23
23
  require_relative "honeymaker/clients/bitrue"
24
- require_relative "honeymaker/clients/bitmart"
25
24
  require_relative "honeymaker/clients/hyperliquid"
26
25
  require_relative "honeymaker/clients/kraken_futures"
27
26
  require_relative "honeymaker/exchanges/binance"
@@ -37,7 +36,6 @@ require_relative "honeymaker/exchanges/kucoin"
37
36
  require_relative "honeymaker/exchanges/hyperliquid"
38
37
  require_relative "honeymaker/exchanges/bingx"
39
38
  require_relative "honeymaker/exchanges/bitrue"
40
- require_relative "honeymaker/exchanges/bitmart"
41
39
 
42
40
  module Honeymaker
43
41
  class Error < StandardError; end
@@ -55,8 +53,7 @@ module Honeymaker
55
53
  "kucoin" => Exchanges::Kucoin,
56
54
  "hyperliquid" => Exchanges::Hyperliquid,
57
55
  "bingx" => Exchanges::BingX,
58
- "bitrue" => Exchanges::Bitrue,
59
- "bitmart" => Exchanges::BitMart
56
+ "bitrue" => Exchanges::Bitrue
60
57
  }.freeze
61
58
 
62
59
  CLIENTS = {
@@ -72,7 +69,6 @@ module Honeymaker
72
69
  "gemini" => Clients::Gemini,
73
70
  "bingx" => Clients::BingX,
74
71
  "bitrue" => Clients::Bitrue,
75
- "bitmart" => Clients::BitMart,
76
72
  "hyperliquid" => Clients::Hyperliquid,
77
73
  "kraken_futures" => Clients::KrakenFutures
78
74
  }.freeze
@@ -18,7 +18,7 @@ class HoneymakerClientRegistryTest < Minitest::Test
18
18
  end
19
19
 
20
20
  def test_all_clients_registered
21
- assert_equal 15, Honeymaker::CLIENTS.size
21
+ assert_equal 14, Honeymaker::CLIENTS.size
22
22
  end
23
23
 
24
24
  def test_client_passes_credentials
@@ -36,9 +36,4 @@ class HoneymakerClientRegistryTest < Minitest::Test
36
36
  client = Honeymaker.client("kucoin", api_key: "k", api_secret: "s", passphrase: "p")
37
37
  assert_equal "p", client.passphrase
38
38
  end
39
-
40
- def test_bitmart_accepts_memo
41
- client = Honeymaker.client("bitmart", api_key: "k", api_secret: "s", memo: "m")
42
- assert_equal "m", client.memo
43
- end
44
39
  end
@@ -148,21 +148,6 @@ class ValidationTest < Minitest::Test
148
148
  assert result.success?
149
149
  end
150
150
 
151
- # BitMart
152
- def test_bitmart_validate_trading_success
153
- client = Honeymaker::Clients::BitMart.new(api_key: "k", api_secret: "s", memo: "m")
154
- stub_connection(client, :get, { "code" => 1000, "data" => {} })
155
- result = client.validate(:trading)
156
- assert result.success?
157
- end
158
-
159
- def test_bitmart_validate_trading_failure
160
- client = Honeymaker::Clients::BitMart.new(api_key: "k", api_secret: "s", memo: "m")
161
- stub_connection(client, :get, { "code" => 30004, "message" => "Unauthorized" })
162
- result = client.validate(:trading)
163
- assert result.failure?
164
- end
165
-
166
151
  # Hyperliquid
167
152
  def test_hyperliquid_validate_trading_success
168
153
  client = Honeymaker::Clients::Hyperliquid.new(api_key: "0xabc", api_secret: "s")
@@ -22,8 +22,8 @@ class Honeymaker::Exchanges::HyperliquidTest < Minitest::Test
22
22
  assert_equal "PURR/USDC", ticker[:ticker]
23
23
  assert_equal "PURR", ticker[:base]
24
24
  assert_equal "USDC", ticker[:quote]
25
- assert_nil ticker[:minimum_base_size]
26
- assert_nil ticker[:minimum_quote_size]
25
+ assert_nil ticker[:minimum_base_size] # no per-token base floor in spotMeta
26
+ assert_equal 10, ticker[:minimum_quote_size] # Hyperliquid's hard 10-USDC spot order floor
27
27
  assert_equal 2, ticker[:base_decimals]
28
28
  assert_equal 2, ticker[:quote_decimals]
29
29
  assert_equal 5, ticker[:price_decimals]
@@ -22,6 +22,6 @@ class HoneymakerTest < Minitest::Test
22
22
  end
23
23
 
24
24
  def test_all_exchanges_registered
25
- assert_equal 14, Honeymaker::EXCHANGES.size
25
+ assert_equal 13, Honeymaker::EXCHANGES.size
26
26
  end
27
27
  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.9.11
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deltabadger
@@ -98,7 +98,6 @@ files:
98
98
  - lib/honeymaker/clients/binance_us.rb
99
99
  - lib/honeymaker/clients/bingx.rb
100
100
  - lib/honeymaker/clients/bitget.rb
101
- - lib/honeymaker/clients/bitmart.rb
102
101
  - lib/honeymaker/clients/bitrue.rb
103
102
  - lib/honeymaker/clients/bitvavo.rb
104
103
  - lib/honeymaker/clients/bybit.rb
@@ -114,7 +113,6 @@ files:
114
113
  - lib/honeymaker/exchanges/binance_us.rb
115
114
  - lib/honeymaker/exchanges/bingx.rb
116
115
  - lib/honeymaker/exchanges/bitget.rb
117
- - lib/honeymaker/exchanges/bitmart.rb
118
116
  - lib/honeymaker/exchanges/bitrue.rb
119
117
  - lib/honeymaker/exchanges/bitvavo.rb
120
118
  - lib/honeymaker/exchanges/bybit.rb
@@ -160,7 +158,6 @@ files:
160
158
  - test/honeymaker/clients/binance_us_client_test.rb
161
159
  - test/honeymaker/clients/bingx_client_test.rb
162
160
  - test/honeymaker/clients/bitget_client_test.rb
163
- - test/honeymaker/clients/bitmart_client_test.rb
164
161
  - test/honeymaker/clients/bitrue_client_test.rb
165
162
  - test/honeymaker/clients/bitvavo_client_test.rb
166
163
  - test/honeymaker/clients/bybit_client_test.rb
@@ -178,7 +175,6 @@ files:
178
175
  - test/honeymaker/exchanges/binance_us_test.rb
179
176
  - test/honeymaker/exchanges/bingx_test.rb
180
177
  - test/honeymaker/exchanges/bitget_test.rb
181
- - test/honeymaker/exchanges/bitmart_test.rb
182
178
  - test/honeymaker/exchanges/bitrue_test.rb
183
179
  - test/honeymaker/exchanges/bitvavo_test.rb
184
180
  - test/honeymaker/exchanges/bybit_test.rb
@@ -1,260 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Honeymaker
4
- module Clients
5
- class BitMart < Client
6
- URL = "https://api-cloud.bitmart.com"
7
- RATE_LIMITS = { default: 100, orders: 200 }.freeze
8
-
9
- attr_reader :memo
10
-
11
- def initialize(api_key: nil, api_secret: nil, memo: nil, proxy: nil, logger: nil)
12
- super(api_key: api_key, api_secret: api_secret, proxy: proxy, logger: logger)
13
- @memo = memo
14
- end
15
-
16
- def get_symbols_details
17
- get_public("/spot/v1/symbols/details")
18
- end
19
-
20
- def get_currencies
21
- get_public("/account/v1/currencies")
22
- end
23
-
24
- def get_ticker(symbol: nil)
25
- get_public("/spot/quotation/v3/ticker", { symbol: symbol })
26
- end
27
-
28
- def get_depth(symbol:, limit: nil)
29
- get_public("/spot/quotation/v3/books", { symbol: symbol, limit: limit })
30
- end
31
-
32
- def get_klines(symbol:, step:, before: nil, after_time: nil, limit: nil)
33
- get_public("/spot/quotation/v3/lite-klines", {
34
- symbol: symbol, step: step, before: before, after: after_time, limit: limit
35
- })
36
- end
37
-
38
- def get_wallet
39
- get_signed("/spot/v1/wallet")
40
- end
41
-
42
- def get_balances
43
- result = get_wallet
44
- return result if result.failure?
45
-
46
- return Result::Failure.new("BitMart API error") unless result.data["code"] == 1000
47
-
48
- balances = {}
49
- (result.data.dig("data", "wallet") || []).each do |wallet|
50
- symbol = wallet["id"]
51
- free = BigDecimal((wallet["available"] || "0").to_s)
52
- locked = BigDecimal((wallet["frozen"] || "0").to_s)
53
- next if free.zero? && locked.zero?
54
- balances[symbol] = { free: free, locked: locked }
55
- end
56
-
57
- Result::Success.new(balances)
58
- end
59
-
60
- def submit_order(symbol:, side:, type:, size: nil, notional: nil, price: nil, client_order_id: nil)
61
- result = post_signed("/spot/v2/submit_order", {
62
- symbol: symbol, side: side, type: type,
63
- size: size, notional: notional, price: price,
64
- client_order_id: client_order_id
65
- })
66
- return result if result.failure?
67
- return Result::Failure.new("BitMart API error") unless result.data["code"] == 1000
68
-
69
- order_id = result.data.dig("data", "order_id")
70
- Result::Success.new({ order_id: order_id.to_s, raw: result.data })
71
- end
72
-
73
- def get_order(order_id:)
74
- result = post_signed("/spot/v2/order_detail", { orderId: order_id })
75
- return result if result.failure?
76
- return Result::Failure.new("BitMart API error") unless result.data["code"] == 1000
77
-
78
- raw = result.data["data"]
79
- return Result::Failure.new("Order not found") unless raw
80
-
81
- Result::Success.new(normalize_order(order_id.to_s, raw))
82
- end
83
-
84
- def cancel_order(symbol:, order_id: nil, client_order_id: nil)
85
- post_signed("/spot/v3/cancel_order", {
86
- symbol: symbol, order_id: order_id, client_order_id: client_order_id
87
- })
88
- end
89
-
90
- def get_trades(symbol:, order_mode: nil, start_time: nil, end_time: nil, limit: nil, recv_window: nil)
91
- get_signed("/spot/v2/trades", {
92
- symbol: symbol, orderMode: order_mode,
93
- startTime: start_time, endTime: end_time, N: limit, recvWindow: recv_window
94
- })
95
- end
96
-
97
- def deposit_list(currency: nil, n: nil, status: nil)
98
- get_signed("/account/v1/deposit-withdraw/detail", {
99
- currency: currency, N: n, type: "deposit", operation_type: "deposit", status: status
100
- })
101
- end
102
-
103
- def withdraw_list(currency: nil, n: nil, status: nil)
104
- get_signed("/account/v1/deposit-withdraw/detail", {
105
- currency: currency, N: n, type: "withdraw", operation_type: "withdraw", status: status
106
- })
107
- end
108
-
109
- def get_withdraw_addresses
110
- get_signed("/account/v1/withdraw/address/list")
111
- end
112
-
113
- def withdraw(currency:, amount:, address:, address_memo: nil, destination: nil)
114
- post_signed("/account/v1/withdraw/apply", {
115
- currency: currency, amount: amount,
116
- destination: destination || "To Digital Address",
117
- address: address, address_memo: address_memo
118
- })
119
- end
120
-
121
- # --- Margin ---
122
-
123
- def margin_borrow_records(symbol: nil, borrow_id: nil, start_time: nil, end_time: nil, n: nil)
124
- get_signed("/spot/v1/margin/isolated/borrow_record", {
125
- symbol: symbol, borrow_id: borrow_id, start_time: start_time, end_time: end_time, N: n
126
- })
127
- end
128
-
129
- def margin_repay_records(symbol: nil, repay_id: nil, currency: nil, start_time: nil, end_time: nil, n: nil)
130
- get_signed("/spot/v1/margin/isolated/repay_record", {
131
- symbol: symbol, repay_id: repay_id, currency: currency, start_time: start_time, end_time: end_time, N: n
132
- })
133
- end
134
-
135
- # --- Futures ---
136
-
137
- def futures_transaction_history(start_time: nil, end_time: nil, page_num: nil, page_size: nil, flow_type: nil)
138
- get_signed("/contract/private/transaction-history", {
139
- start_time: start_time, end_time: end_time,
140
- page_num: page_num, page_size: page_size, flow_type: flow_type
141
- })
142
- end
143
-
144
- def futures_trades(symbol:, start_time: nil, end_time: nil, page_num: nil, page_size: nil)
145
- get_signed("/contract/private/trades", {
146
- symbol: symbol, start_time: start_time, end_time: end_time,
147
- page_num: page_num, page_size: page_size
148
- })
149
- end
150
-
151
- private
152
-
153
- def normalize_order(order_id, raw)
154
- order_type = parse_order_type(raw["type"])
155
- side = raw["side"]&.downcase&.to_sym
156
- status = parse_order_status(raw["status"])
157
-
158
- amount = BigDecimal((raw["size"] || "0").to_s)
159
- amount = nil if amount.zero?
160
- quote_amount = raw["notional"] ? BigDecimal(raw["notional"].to_s) : nil
161
- quote_amount = nil if quote_amount&.zero?
162
-
163
- amount_exec = BigDecimal((raw["filled_size"] || "0").to_s)
164
- quote_amount_exec = BigDecimal((raw["filled_notional"] || "0").to_s)
165
- quote_amount_exec = nil if quote_amount_exec.negative?
166
-
167
- price = BigDecimal((raw["price"] || "0").to_s)
168
- if price.zero? && quote_amount_exec&.positive? && amount_exec.positive?
169
- price = quote_amount_exec / amount_exec
170
- end
171
- price = nil if price.zero?
172
-
173
- {
174
- order_id: order_id, status: status, side: side, order_type: order_type,
175
- price: price, amount: amount, quote_amount: quote_amount,
176
- amount_exec: amount_exec, quote_amount_exec: quote_amount_exec, raw: raw
177
- }
178
- end
179
-
180
- def parse_order_type(type)
181
- case type
182
- when "market" then :market
183
- when "limit" then :limit
184
- else :unknown
185
- end
186
- end
187
-
188
- def parse_order_status(status)
189
- case status
190
- when "new", "partially_filled" then :open
191
- when "filled" then :closed
192
- when "canceled", "expired", "partially_canceled" then :cancelled
193
- when "rejected", "failed" then :failed
194
- else :unknown
195
- end
196
- end
197
-
198
- def validate_trading_credentials
199
- result = get_wallet
200
- return Result::Failure.new("Invalid trading credentials") if result.failure?
201
- result.data["code"] == 1000 ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
202
- end
203
-
204
- def validate_read_credentials
205
- validate_trading_credentials
206
- end
207
-
208
- def get_public(path, params = {})
209
- with_rescue do
210
- response = connection.get do |req|
211
- req.url path
212
- req.params = params.compact
213
- end
214
- response.body
215
- end
216
- end
217
-
218
- def get_signed(path, params = {})
219
- with_rescue do
220
- ts = timestamp_ms.to_s
221
- query_string = params.compact.empty? ? "" : "?#{Faraday::Utils.build_query(params.compact)}"
222
- pre_sign = "#{ts}##{@memo}##{query_string}"
223
-
224
- response = connection.get do |req|
225
- req.url path
226
- req.headers = signed_headers(ts, pre_sign)
227
- req.params = params.compact
228
- end
229
- response.body
230
- end
231
- end
232
-
233
- def post_signed(path, body = {})
234
- with_rescue do
235
- ts = timestamp_ms.to_s
236
- body_json = body.compact.to_json
237
- pre_sign = "#{ts}##{@memo}##{body_json}"
238
-
239
- response = connection.post do |req|
240
- req.url path
241
- req.headers = signed_headers(ts, pre_sign)
242
- req.body = body.compact
243
- end
244
- response.body
245
- end
246
- end
247
-
248
- def signed_headers(timestamp, pre_sign)
249
- signature = hmac_sha256(@api_secret, pre_sign)
250
- {
251
- "X-BM-KEY": @api_key,
252
- "X-BM-SIGN": signature,
253
- "X-BM-TIMESTAMP": timestamp,
254
- Accept: "application/json",
255
- "Content-Type": "application/json"
256
- }
257
- end
258
- end
259
- end
260
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Honeymaker
4
- module Exchanges
5
- class BitMart < Exchange
6
- BASE_URL = "https://api-cloud.bitmart.com"
7
-
8
- def get_tickers_info
9
- with_rescue do
10
- response = connection.get("/spot/v1/symbols/details")
11
-
12
- response.body["data"]["symbols"].filter_map do |product|
13
- {
14
- ticker: product["symbol"],
15
- base: product["base_currency"],
16
- quote: product["quote_currency"],
17
- minimum_base_size: product["base_min_size"],
18
- minimum_quote_size: product["min_buy_amount"],
19
- maximum_base_size: nil,
20
- maximum_quote_size: nil,
21
- base_decimals: Utils.decimals(product["base_min_size"]),
22
- quote_decimals: Utils.decimals(product["quote_increment"]),
23
- price_decimals: product["price_max_precision"].to_i,
24
- available: true,
25
- trading_enabled: product["trade_status"] == "trading"
26
- }
27
- end
28
- end
29
- end
30
-
31
- def get_bid_ask(symbol)
32
- with_rescue do
33
- response = connection.get("/spot/quotation/v3/ticker") do |req|
34
- req.params = { symbol: symbol }
35
- end
36
-
37
- data = response.body["data"]
38
- {
39
- bid: BigDecimal(data["best_bid"]),
40
- ask: BigDecimal(data["best_ask"])
41
- }
42
- end
43
- end
44
-
45
- private
46
-
47
- def connection
48
- @connection ||= build_connection(BASE_URL)
49
- end
50
- end
51
- end
52
- end
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "test_helper"
4
-
5
- class Honeymaker::Clients::BitMartTest < Minitest::Test
6
- def setup
7
- @client = Honeymaker::Clients::BitMart.new(
8
- api_key: "test_key", api_secret: "test_secret", memo: "test_memo"
9
- )
10
- end
11
-
12
- def test_url
13
- assert_equal "https://api-cloud.bitmart.com", Honeymaker::Clients::BitMart::URL
14
- end
15
-
16
- def test_accepts_memo
17
- assert_equal "test_memo", @client.memo
18
- end
19
-
20
- def test_get_symbols_details
21
- stub_connection(:get, { "data" => { "symbols" => [{ "symbol" => "BTC_USDT" }] } })
22
- result = @client.get_symbols_details
23
- assert result.success?
24
- end
25
-
26
- def test_get_ticker
27
- stub_connection(:get, { "data" => [{ "symbol" => "BTC_USDT" }] })
28
- result = @client.get_ticker(symbol: "BTC_USDT")
29
- assert result.success?
30
- end
31
-
32
- def test_get_wallet
33
- stub_connection(:get, { "data" => { "wallet" => [{ "id" => "BTC" }] } })
34
- result = @client.get_wallet
35
- assert result.success?
36
- end
37
-
38
- def test_submit_order
39
- stub_connection(:post, { "code" => 1000, "data" => { "order_id" => 123 } })
40
- result = @client.submit_order(symbol: "BTC_USDT", side: "buy", type: "market", notional: "100")
41
- assert result.success?
42
- assert_equal "123", result.data[:order_id]
43
- end
44
-
45
- def test_get_order
46
- stub_connection(:post, { "code" => 1000, "data" => {
47
- "symbol" => "BTC_USDT", "type" => "market", "side" => "buy", "status" => "filled",
48
- "size" => "0.001", "filled_size" => "0.001", "filled_notional" => "50", "price" => "50000"
49
- } })
50
- result = @client.get_order(order_id: "123")
51
- assert result.success?
52
- assert_equal :closed, result.data[:status]
53
- end
54
-
55
- def test_cancel_order
56
- stub_connection(:post, { "data" => true })
57
- result = @client.cancel_order(symbol: "BTC_USDT", order_id: "123")
58
- assert result.success?
59
- end
60
-
61
- def test_withdraw
62
- stub_connection(:post, { "data" => { "withdraw_id" => "w1" } })
63
- result = @client.withdraw(currency: "BTC", amount: "0.1", address: "addr")
64
- assert result.success?
65
- end
66
-
67
- def test_get_trades
68
- stub_connection(:get, { "data" => [{ "tradeId" => "t1" }] })
69
- result = @client.get_trades(symbol: "BTC_USDT")
70
- assert result.success?
71
- end
72
-
73
- def test_deposit_list
74
- stub_connection(:get, { "data" => { "records" => [{ "currency" => "BTC" }] } })
75
- result = @client.deposit_list
76
- assert result.success?
77
- end
78
-
79
- def test_withdraw_list
80
- stub_connection(:get, { "data" => { "records" => [{ "currency" => "ETH" }] } })
81
- result = @client.withdraw_list
82
- assert result.success?
83
- end
84
-
85
- def test_signed_headers_include_memo_in_signature
86
- ts = "1234567890"
87
- pre_sign = "#{ts}#test_memo#body"
88
- headers = @client.send(:signed_headers, ts, pre_sign)
89
- assert_equal "test_key", headers[:"X-BM-KEY"]
90
- assert headers.key?(:"X-BM-SIGN")
91
- end
92
-
93
- private
94
-
95
- def stub_connection(method, body)
96
- response = stub(body: body)
97
- connection = stub
98
- connection.stubs(method).returns(response)
99
- @client.instance_variable_set(:@connection, connection)
100
- end
101
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "test_helper"
4
-
5
- class Honeymaker::Exchanges::BitMartTest < Minitest::Test
6
- include FixtureHelper
7
-
8
- def setup
9
- @exchange = Honeymaker::Exchanges::BitMart.new
10
- end
11
-
12
- def test_get_tickers_info_parses_response
13
- body = load_fixture("bitmart_symbols.json")
14
- stub_connection(body)
15
-
16
- result = @exchange.get_tickers_info
17
-
18
- assert result.success?
19
- assert_equal 2, result.data.size
20
-
21
- ticker = result.data.first
22
- assert_equal "BTC_USDT", ticker[:ticker]
23
- assert_equal "BTC", ticker[:base]
24
- assert_equal "USDT", ticker[:quote]
25
- assert_equal "0.00001", ticker[:minimum_base_size]
26
- assert_equal "5", ticker[:minimum_quote_size]
27
- assert_nil ticker[:maximum_base_size]
28
- assert_equal 5, ticker[:base_decimals]
29
- assert_equal 2, ticker[:quote_decimals]
30
- assert_equal 2, ticker[:price_decimals]
31
- assert ticker[:available]
32
- assert ticker[:trading_enabled]
33
- end
34
-
35
- def test_pre_trade_listed_but_not_trading_enabled
36
- body = load_fixture("bitmart_symbols.json")
37
- stub_connection(body)
38
-
39
- result = @exchange.get_tickers_info
40
-
41
- eth = result.data.find { |t| t[:ticker] == "ETH_USDT" }
42
- assert eth[:available] # still listed
43
- refute eth[:trading_enabled] # but not trading
44
- end
45
-
46
- def test_get_bid_ask_parses_response
47
- body = load_fixture("bitmart_ticker.json")
48
- stub_connection(body)
49
-
50
- result = @exchange.get_bid_ask("BTC_USDT")
51
-
52
- assert result.success?
53
- assert_equal BigDecimal("67123.45"), result.data[:bid]
54
- assert_equal BigDecimal("67125.67"), result.data[:ask]
55
- end
56
-
57
- private
58
-
59
- def stub_connection(body)
60
- response = stub(body: body)
61
- connection = stub
62
- connection.stubs(:get).returns(response)
63
- @exchange.instance_variable_set(:@connection, connection)
64
- end
65
- end