honeymaker 0.2.0 → 0.3.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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/lib/honeymaker/client.rb +22 -0
  4. data/lib/honeymaker/clients/binance.rb +48 -0
  5. data/lib/honeymaker/clients/bingx.rb +31 -0
  6. data/lib/honeymaker/clients/bitget.rb +32 -3
  7. data/lib/honeymaker/clients/bitmart.rb +29 -0
  8. data/lib/honeymaker/clients/bitrue.rb +16 -0
  9. data/lib/honeymaker/clients/bitvavo.rb +24 -0
  10. data/lib/honeymaker/clients/bybit.rb +30 -0
  11. data/lib/honeymaker/clients/coinbase.rb +35 -0
  12. data/lib/honeymaker/clients/gemini.rb +18 -0
  13. data/lib/honeymaker/clients/hyperliquid.rb +23 -0
  14. data/lib/honeymaker/clients/kraken.rb +30 -0
  15. data/lib/honeymaker/clients/kucoin.rb +33 -0
  16. data/lib/honeymaker/clients/mexc.rb +30 -0
  17. data/lib/honeymaker/version.rb +1 -1
  18. data/test/honeymaker/clients/binance_client_test.rb +21 -0
  19. data/test/honeymaker/clients/bingx_client_test.rb +18 -0
  20. data/test/honeymaker/clients/bitget_client_test.rb +25 -1
  21. data/test/honeymaker/clients/bitmart_client_test.rb +18 -0
  22. data/test/honeymaker/clients/bitrue_client_test.rb +6 -0
  23. data/test/honeymaker/clients/bitvavo_client_test.rb +18 -0
  24. data/test/honeymaker/clients/bybit_client_test.rb +18 -0
  25. data/test/honeymaker/clients/coinbase_client_test.rb +14 -0
  26. data/test/honeymaker/clients/gemini_client_test.rb +12 -0
  27. data/test/honeymaker/clients/hyperliquid_client_test.rb +12 -0
  28. data/test/honeymaker/clients/kraken_client_test.rb +14 -0
  29. data/test/honeymaker/clients/kucoin_client_test.rb +18 -0
  30. data/test/honeymaker/clients/mexc_client_test.rb +18 -0
  31. data/test/honeymaker/clients/validation_test.rb +182 -0
  32. metadata +2 -2
  33. data/honeymaker-0.1.0.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e80ebeeb8222d978465b6fca4f757d13eeae098395f99c2ec2223196c55c2b4b
4
- data.tar.gz: 5f00b757a6872a409bdce15b5e77c7370148195397b5827064e49b0f57379ea6
3
+ metadata.gz: ff95afc5916845501bc9cbb7c625979f9f06662608d0e47bfbf9ec4bb7be686b
4
+ data.tar.gz: 978d54c3f108c0a037c627250bd277d6c1e5159d940c10a1579e54d0f96523d3
5
5
  SHA512:
6
- metadata.gz: 428f23c82dd3d1ae22f5fa05f00cd0036691fd397541b058d541ac7f5ba09936a464959a8c81ff11fa46ccab1c68fbfefe4d8fe7f97f06084fb32aca6e994112
7
- data.tar.gz: a79cbc1061092903465d37be4f1a0627332a05f583bbbd3289b1f46319e76623ad99563f13d2101dcdb9eb07cabc5038d50ec8a9229dc12c1bc32c719f2dd877
6
+ metadata.gz: aec9b76d37ca978445002ba6243c73c857b6a3e9bfc4b7fd43f8c73091a7606503df1076da8af93856a4a6a74fb9e72c32af20237b74b3e339339cc5b168d3d3
7
+ data.tar.gz: 630b79116ad0d74be37993f412aa4b81f371cdc58fae756fd5c08fe7496a887c458aee0b9e6439575d89268a6f8f0c8b78bc7734d35ac8debe0c16185d7280a1
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Honeymaker
2
2
 
3
+ [![Gem Version](https://img.shields.io/gem/v/honeymaker)](https://rubygems.org/gems/honeymaker)
4
+ [![CI](https://github.com/deltabadger/honeymaker/actions/workflows/test.yml/badge.svg)](https://github.com/deltabadger/honeymaker/actions)
5
+ [![License](https://img.shields.io/github/license/deltabadger/honeymaker)](LICENSE)
6
+
3
7
  Ruby clients for cryptocurrency exchange APIs. Originally extracted from [Deltabadger](https://github.com/deltabadger/deltabadger).
4
8
 
5
9
  ## Supported Exchanges
@@ -23,8 +23,30 @@ module Honeymaker
23
23
  @logger = logger
24
24
  end
25
25
 
26
+ def validate(type = :trading)
27
+ return Result::Failure.new("No credentials provided") unless authenticated?
28
+
29
+ case type
30
+ when :trading then validate_trading_credentials
31
+ when :read then validate_read_credentials
32
+ else raise Error, "Unknown validation type: #{type}. Use :trading or :read"
33
+ end
34
+ rescue Error
35
+ raise
36
+ rescue StandardError => e
37
+ Result::Failure.new(e.message)
38
+ end
39
+
26
40
  private
27
41
 
42
+ def validate_trading_credentials
43
+ raise NotImplementedError, "#{self.class} must implement #validate_trading_credentials"
44
+ end
45
+
46
+ def validate_read_credentials
47
+ raise NotImplementedError, "#{self.class} must implement #validate_read_credentials"
48
+ end
49
+
28
50
  def with_rescue
29
51
  Result::Success.new(yield)
30
52
  rescue Faraday::Error => e
@@ -168,6 +168,40 @@ module Honeymaker
168
168
  end
169
169
  end
170
170
 
171
+ def deposit_history(coin: nil, status: nil, start_time: nil, end_time: nil, offset: nil, limit: 1000, recv_window: 5000)
172
+ with_rescue do
173
+ response = connection.get do |req|
174
+ req.url "/sapi/v1/capital/deposit/hisrec"
175
+ req.headers = headers
176
+ req.params = {
177
+ coin: coin, status: status,
178
+ startTime: start_time, endTime: end_time,
179
+ offset: offset, limit: limit,
180
+ recvWindow: recv_window, timestamp: timestamp_ms
181
+ }.compact
182
+ req.params[:signature] = sign_params(req.params)
183
+ end
184
+ response.body
185
+ end
186
+ end
187
+
188
+ def withdraw_history(coin: nil, status: nil, start_time: nil, end_time: nil, offset: nil, limit: 1000, recv_window: 5000)
189
+ with_rescue do
190
+ response = connection.get do |req|
191
+ req.url "/sapi/v1/capital/withdraw/history"
192
+ req.headers = headers
193
+ req.params = {
194
+ coin: coin, status: status,
195
+ startTime: start_time, endTime: end_time,
196
+ offset: offset, limit: limit,
197
+ recvWindow: recv_window, timestamp: timestamp_ms
198
+ }.compact
199
+ req.params[:signature] = sign_params(req.params)
200
+ end
201
+ response.body
202
+ end
203
+ end
204
+
171
205
  def get_all_coins_information(recv_window: 5000)
172
206
  with_rescue do
173
207
  response = connection.get do |req|
@@ -222,6 +256,20 @@ module Honeymaker
222
256
 
223
257
  private
224
258
 
259
+ def validate_trading_credentials
260
+ # Try cancelling a non-existent order — error -2011 (ORDER_DOES_NOT_EXIST) means key is valid with trade permission
261
+ result = cancel_order(symbol: "ETHBTC", order_id: "9999999999")
262
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
263
+
264
+ code = result.data.is_a?(Hash) ? result.data["code"] : nil
265
+ code == -2011 ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
266
+ end
267
+
268
+ def validate_read_credentials
269
+ result = api_description
270
+ Result.new(data: result.success?, errors: result.success? ? [] : ["Invalid read credentials"])
271
+ end
272
+
225
273
  def headers
226
274
  if authenticated?
227
275
  { "X-MBX-APIKEY": @api_key, Accept: "application/json", "Content-Type": "application/json" }
@@ -50,6 +50,27 @@ module Honeymaker
50
50
  })
51
51
  end
52
52
 
53
+ def get_trade_fills(symbol: nil, order_id: nil, start_time: nil, end_time: nil, from_id: nil, limit: nil)
54
+ get_signed("/openApi/spot/v1/trade/fills", {
55
+ symbol: symbol, orderId: order_id,
56
+ startTime: start_time, endTime: end_time, fromId: from_id, limit: limit
57
+ })
58
+ end
59
+
60
+ def deposit_history(coin: nil, status: nil, start_time: nil, end_time: nil, offset: nil, limit: nil)
61
+ get_signed("/openApi/wallets/v1/capital/deposit/hisrec", {
62
+ coin: coin, status: status,
63
+ startTime: start_time, endTime: end_time, offset: offset, limit: limit
64
+ })
65
+ end
66
+
67
+ def withdraw_history(coin: nil, status: nil, start_time: nil, end_time: nil, offset: nil, limit: nil, id: nil)
68
+ get_signed("/openApi/wallets/v1/capital/withdraw/history", {
69
+ coin: coin, status: status,
70
+ startTime: start_time, endTime: end_time, offset: offset, limit: limit, id: id
71
+ })
72
+ end
73
+
53
74
  def withdraw(coin:, address:, amount:, network: nil, wallet_type: nil, tag: nil)
54
75
  post_signed("/openApi/wallets/v1/capital/withdraw/apply", {
55
76
  coin: coin, address: address, amount: amount,
@@ -59,6 +80,16 @@ module Honeymaker
59
80
 
60
81
  private
61
82
 
83
+ def validate_trading_credentials
84
+ result = get_balances
85
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
86
+ result.data["code"]&.to_i&.zero? ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
87
+ end
88
+
89
+ def validate_read_credentials
90
+ validate_trading_credentials
91
+ end
92
+
62
93
  def get_public(path, params = {})
63
94
  with_rescue do
64
95
  response = connection.get do |req|
@@ -39,10 +39,10 @@ module Honeymaker
39
39
  get_signed("/api/v2/spot/account/assets", { coin: coin })
40
40
  end
41
41
 
42
- def place_order(symbol:, side:, order_type:, size:, price: nil, force: nil, client_oid: nil)
42
+ def place_order(symbol:, side:, order_type:, size: nil, quote_size: nil, price: nil, force: nil, client_oid: nil)
43
43
  post_signed("/api/v2/spot/trade/place-order", {
44
44
  symbol: symbol, side: side, orderType: order_type,
45
- size: size, price: price, force: force, clientOid: client_oid
45
+ size: size, quoteSize: quote_size, price: price, force: force, clientOid: client_oid
46
46
  })
47
47
  end
48
48
 
@@ -56,7 +56,26 @@ module Honeymaker
56
56
  })
57
57
  end
58
58
 
59
- def withdraw(coin:, transfer_type:, address:, size:, chain: nil, tag: nil, client_oid: nil)
59
+ def get_fills(symbol: nil, order_id: nil, start_time: nil, end_time: nil, limit: nil, id_less_than: nil)
60
+ get_signed("/api/v2/spot/trade/fills", {
61
+ symbol: symbol, orderId: order_id,
62
+ startTime: start_time, endTime: end_time, limit: limit, idLessThan: id_less_than
63
+ })
64
+ end
65
+
66
+ def deposit_list(coin: nil, start_time: nil, end_time: nil, limit: nil, id_less_than: nil)
67
+ get_signed("/api/v2/spot/wallet/deposit-records", {
68
+ coin: coin, startTime: start_time, endTime: end_time, limit: limit, idLessThan: id_less_than
69
+ })
70
+ end
71
+
72
+ def withdrawal_list(coin: nil, start_time: nil, end_time: nil, limit: nil, id_less_than: nil)
73
+ get_signed("/api/v2/spot/wallet/withdrawal-records", {
74
+ coin: coin, startTime: start_time, endTime: end_time, limit: limit, idLessThan: id_less_than
75
+ })
76
+ end
77
+
78
+ def withdraw(coin:, address:, size:, transfer_type: nil, chain: nil, tag: nil, client_oid: nil)
60
79
  post_signed("/api/v2/spot/wallet/withdrawal", {
61
80
  coin: coin, transferType: transfer_type, address: address,
62
81
  size: size, chain: chain, tag: tag, clientOid: client_oid
@@ -65,6 +84,16 @@ module Honeymaker
65
84
 
66
85
  private
67
86
 
87
+ def validate_trading_credentials
88
+ result = get_account_assets
89
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
90
+ result.data["code"] == "00000" ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
91
+ end
92
+
93
+ def validate_read_credentials
94
+ validate_trading_credentials
95
+ end
96
+
68
97
  def get_public(path, params = {})
69
98
  with_rescue do
70
99
  response = connection.get do |req|
@@ -52,6 +52,25 @@ module Honeymaker
52
52
  })
53
53
  end
54
54
 
55
+ def get_trades(symbol:, order_mode: nil, start_time: nil, end_time: nil, limit: nil, recv_window: nil)
56
+ get_signed("/spot/v2/trades", {
57
+ symbol: symbol, orderMode: order_mode,
58
+ startTime: start_time, endTime: end_time, N: limit, recvWindow: recv_window
59
+ })
60
+ end
61
+
62
+ def deposit_list(currency: nil, n: nil, status: nil)
63
+ get_signed("/account/v1/deposit-withdraw/detail", {
64
+ currency: currency, N: n, type: "deposit", operation_type: "deposit", status: status
65
+ })
66
+ end
67
+
68
+ def withdraw_list(currency: nil, n: nil, status: nil)
69
+ get_signed("/account/v1/deposit-withdraw/detail", {
70
+ currency: currency, N: n, type: "withdraw", operation_type: "withdraw", status: status
71
+ })
72
+ end
73
+
55
74
  def withdraw(currency:, amount:, address:, address_memo: nil, destination: nil)
56
75
  post_signed("/account/v1/withdraw/apply", {
57
76
  currency: currency, amount: amount,
@@ -62,6 +81,16 @@ module Honeymaker
62
81
 
63
82
  private
64
83
 
84
+ def validate_trading_credentials
85
+ result = get_wallet
86
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
87
+ result.data["code"] == 1000 ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
88
+ end
89
+
90
+ def validate_read_credentials
91
+ validate_trading_credentials
92
+ end
93
+
65
94
  def get_public(path, params = {})
66
95
  with_rescue do
67
96
  response = connection.get do |req|
@@ -52,8 +52,24 @@ module Honeymaker
52
52
  })
53
53
  end
54
54
 
55
+ def account_trade_list(symbol:, start_time: nil, end_time: nil, from_id: nil, limit: 500, recv_window: 5000)
56
+ get_signed("/api/v1/myTrades", {
57
+ symbol: symbol, startTime: start_time, endTime: end_time,
58
+ fromId: from_id, limit: limit, recvWindow: recv_window
59
+ })
60
+ end
61
+
55
62
  private
56
63
 
64
+ def validate_trading_credentials
65
+ result = account_information
66
+ result.success? ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
67
+ end
68
+
69
+ def validate_read_credentials
70
+ validate_trading_credentials
71
+ end
72
+
57
73
  def get_public(path, params = {})
58
74
  with_rescue do
59
75
  response = connection.get do |req|
@@ -49,6 +49,21 @@ module Honeymaker
49
49
  delete_signed("/v2/order", { market: market, orderId: order_id })
50
50
  end
51
51
 
52
+ def get_trades(market:, limit: nil, start_time: nil, end_time: nil, trade_id_from: nil, trade_id_to: nil)
53
+ get_signed("/v2/trades", {
54
+ market: market, limit: limit, start: start_time, end: end_time,
55
+ tradeIdFrom: trade_id_from, tradeIdTo: trade_id_to
56
+ })
57
+ end
58
+
59
+ def get_deposit_history(symbol: nil, limit: nil, start_time: nil, end_time: nil)
60
+ get_signed("/v2/deposit", { symbol: symbol, limit: limit, start: start_time, end: end_time })
61
+ end
62
+
63
+ def get_withdrawal_history(symbol: nil, limit: nil, start_time: nil, end_time: nil)
64
+ get_signed("/v2/withdrawal", { symbol: symbol, limit: limit, start: start_time, end: end_time })
65
+ end
66
+
52
67
  def withdraw(symbol:, amount:, address:, payment_id: nil)
53
68
  post_signed("/v2/withdrawal", {
54
69
  symbol: symbol, amount: amount, address: address, paymentId: payment_id
@@ -57,6 +72,15 @@ module Honeymaker
57
72
 
58
73
  private
59
74
 
75
+ def validate_trading_credentials
76
+ result = get_balance
77
+ result.success? ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
78
+ end
79
+
80
+ def validate_read_credentials
81
+ validate_trading_credentials
82
+ end
83
+
60
84
  def get_public(path, params = {})
61
85
  with_rescue do
62
86
  response = connection.get do |req|
@@ -61,6 +61,26 @@ module Honeymaker
61
61
  })
62
62
  end
63
63
 
64
+ def execution_list(category:, symbol: nil, order_id: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil)
65
+ get_authenticated("/v5/execution/list", {
66
+ category: category, symbol: symbol, orderId: order_id,
67
+ startTime: start_time, endTime: end_time, limit: limit, cursor: cursor
68
+ })
69
+ end
70
+
71
+ def deposit_records(coin: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil)
72
+ get_authenticated("/v5/asset/deposit/query-record", {
73
+ coin: coin, startTime: start_time, endTime: end_time, limit: limit, cursor: cursor
74
+ })
75
+ end
76
+
77
+ def withdraw_records(coin: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil, withdraw_type: nil)
78
+ get_authenticated("/v5/asset/withdraw/query-record", {
79
+ coin: coin, startTime: start_time, endTime: end_time,
80
+ limit: limit, cursor: cursor, withdrawType: withdraw_type
81
+ })
82
+ end
83
+
64
84
  def withdraw(coin:, chain:, address:, amount:, tag: nil, force_chain: nil)
65
85
  post_authenticated("/v5/asset/withdraw/create", {
66
86
  coin: coin, chain: chain, address: address, amount: amount,
@@ -70,6 +90,16 @@ module Honeymaker
70
90
 
71
91
  private
72
92
 
93
+ def validate_trading_credentials
94
+ result = wallet_balance(account_type: "UNIFIED")
95
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
96
+ result.data["retCode"]&.zero? ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
97
+ end
98
+
99
+ def validate_read_credentials
100
+ validate_trading_credentials
101
+ end
102
+
73
103
  def get_public(path, params = {})
74
104
  with_rescue do
75
105
  response = connection.get do |req|
@@ -108,6 +108,28 @@ module Honeymaker
108
108
  })
109
109
  end
110
110
 
111
+ def list_fills(product_id: nil, order_id: nil, start_sequence_timestamp: nil,
112
+ end_sequence_timestamp: nil, limit: nil, cursor: nil)
113
+ with_rescue do
114
+ response = connection.get do |req|
115
+ req.url "/api/v3/brokerage/orders/historical/fills"
116
+ req.headers = auth_headers(req)
117
+ req.params = {
118
+ product_id: product_id, order_id: order_id,
119
+ start_sequence_timestamp: start_sequence_timestamp,
120
+ end_sequence_timestamp: end_sequence_timestamp,
121
+ limit: limit, cursor: cursor
122
+ }.compact
123
+ req.options.params_encoder = Faraday::FlatParamsEncoder
124
+ end
125
+ response.body
126
+ end
127
+ end
128
+
129
+ def list_transactions(account_id:, limit: nil, starting_after: nil)
130
+ get("/v2/accounts/#{account_id}/transactions", { limit: limit, starting_after: starting_after })
131
+ end
132
+
111
133
  private
112
134
 
113
135
  def get(path, params = {})
@@ -132,6 +154,19 @@ module Honeymaker
132
154
  end
133
155
  end
134
156
 
157
+ def validate_trading_credentials
158
+ # List accounts — if it works, the key has trading access
159
+ result = list_accounts
160
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
161
+ Result::Success.new(true)
162
+ end
163
+
164
+ def validate_read_credentials
165
+ result = get_api_key_permissions
166
+ return Result::Failure.new("Invalid read credentials") if result.failure?
167
+ Result::Success.new(true)
168
+ end
169
+
135
170
  def auth_headers(req)
136
171
  return unauthenticated_headers unless authenticated?
137
172
 
@@ -41,12 +41,30 @@ module Honeymaker
41
41
  post_signed("/v1/order/cancel", { order_id: order_id })
42
42
  end
43
43
 
44
+ def get_my_trades(symbol: nil, limit_trades: nil, timestamp: nil)
45
+ post_signed("/v1/mytrades", { symbol: symbol, limit_trades: limit_trades, timestamp: timestamp })
46
+ end
47
+
48
+ def get_transfers(timestamp: nil, limit_transfers: nil)
49
+ post_signed("/v1/transfers", { timestamp: timestamp, limit_transfers: limit_transfers })
50
+ end
51
+
44
52
  def withdraw(currency:, address:, amount:)
45
53
  post_signed("/v1/withdraw/#{currency}", { address: address, amount: amount })
46
54
  end
47
55
 
48
56
  private
49
57
 
58
+ def validate_trading_credentials
59
+ result = get_balances
60
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
61
+ result.data.is_a?(Array) ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
62
+ end
63
+
64
+ def validate_read_credentials
65
+ validate_trading_credentials
66
+ end
67
+
50
68
  def get_public(path, params = {})
51
69
  with_rescue do
52
70
  response = connection.get do |req|
@@ -25,8 +25,31 @@ module Honeymaker
25
25
  post_info({ type: "openOrders", user: user })
26
26
  end
27
27
 
28
+ def user_fills(user:, start_time: nil, end_time: nil)
29
+ body = { type: "userFills", user: user }
30
+ body[:startTime] = start_time if start_time
31
+ body[:endTime] = end_time if end_time
32
+ post_info(body)
33
+ end
34
+
35
+ def user_fills_by_time(user:, start_time:, end_time: nil)
36
+ body = { type: "userFillsByTime", user: user, startTime: start_time }
37
+ body[:endTime] = end_time if end_time
38
+ post_info(body)
39
+ end
40
+
28
41
  private
29
42
 
43
+ def validate_trading_credentials
44
+ return Result::Failure.new("No wallet address provided") unless @api_key
45
+ result = open_orders(user: @api_key)
46
+ result.success? ? Result::Success.new(true) : Result::Failure.new("Invalid credentials")
47
+ end
48
+
49
+ def validate_read_credentials
50
+ validate_trading_credentials
51
+ end
52
+
30
53
  def post_info(body)
31
54
  with_rescue do
32
55
  response = connection.post do |req|
@@ -61,6 +61,20 @@ module Honeymaker
61
61
  get_public("/0/public/OHLC", { pair: pair, interval: interval, since: since })
62
62
  end
63
63
 
64
+ def get_trades_history(type: nil, trades: nil, start: nil, end_time: nil, ofs: nil)
65
+ post_private("/0/private/TradesHistory", {
66
+ nonce: nonce, type: type, trades: trades,
67
+ start: start, end: end_time, ofs: ofs
68
+ })
69
+ end
70
+
71
+ def get_ledgers(asset: nil, type: nil, start: nil, end_time: nil, ofs: nil)
72
+ post_private("/0/private/Ledgers", {
73
+ nonce: nonce, asset: asset, type: type,
74
+ start: start, end: end_time, ofs: ofs
75
+ })
76
+ end
77
+
64
78
  def get_withdraw_addresses(asset: nil, method: nil)
65
79
  post_private("/0/private/WithdrawAddresses", { nonce: nonce, asset: asset, method: method })
66
80
  end
@@ -75,6 +89,22 @@ module Honeymaker
75
89
 
76
90
  private
77
91
 
92
+ def validate_trading_credentials
93
+ result = get_extended_balance
94
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
95
+
96
+ errors = result.data["error"]
97
+ if errors.is_a?(Array) && errors.none?
98
+ Result::Success.new(true)
99
+ else
100
+ Result::Failure.new("Invalid trading credentials")
101
+ end
102
+ end
103
+
104
+ def validate_read_credentials
105
+ validate_trading_credentials
106
+ end
107
+
78
108
  def get_public(path, params = {})
79
109
  with_rescue do
80
110
  response = connection.get do |req|
@@ -59,6 +59,29 @@ module Honeymaker
59
59
  get_signed("/api/v1/withdrawals/quotas", { currency: currency, chain: chain })
60
60
  end
61
61
 
62
+ def get_fills(order_id: nil, symbol: nil, side: nil, type: nil, start_at: nil, end_at: nil,
63
+ trade_type: nil, limit: nil, current_page: nil)
64
+ get_signed("/api/v1/fills", {
65
+ orderId: order_id, symbol: symbol, side: side, type: type,
66
+ startAt: start_at, endAt: end_at, tradeType: trade_type,
67
+ pageSize: limit, currentPage: current_page
68
+ })
69
+ end
70
+
71
+ def get_deposits(currency: nil, start_at: nil, end_at: nil, status: nil, current_page: nil, page_size: nil)
72
+ get_signed("/api/v1/deposits", {
73
+ currency: currency, startAt: start_at, endAt: end_at,
74
+ status: status, currentPage: current_page, pageSize: page_size
75
+ })
76
+ end
77
+
78
+ def get_withdrawals(currency: nil, start_at: nil, end_at: nil, status: nil, current_page: nil, page_size: nil)
79
+ get_signed("/api/v1/withdrawals", {
80
+ currency: currency, startAt: start_at, endAt: end_at,
81
+ status: status, currentPage: current_page, pageSize: page_size
82
+ })
83
+ end
84
+
62
85
  def withdraw(currency:, address:, amount:, chain: nil, memo: nil)
63
86
  post_signed("/api/v1/withdrawals", {
64
87
  currency: currency, address: address, amount: amount,
@@ -68,6 +91,16 @@ module Honeymaker
68
91
 
69
92
  private
70
93
 
94
+ def validate_trading_credentials
95
+ result = get_accounts(type: "trade")
96
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
97
+ result.data["code"] == "200000" ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
98
+ end
99
+
100
+ def validate_read_credentials
101
+ validate_trading_credentials
102
+ end
103
+
71
104
  def get_public(path, params = {})
72
105
  with_rescue do
73
106
  response = connection.get do |req|
@@ -58,6 +58,27 @@ module Honeymaker
58
58
  })
59
59
  end
60
60
 
61
+ def account_trade_list(symbol:, order_id: nil, start_time: nil, end_time: nil, limit: 500, recv_window: 5000)
62
+ get_signed("/api/v3/myTrades", {
63
+ symbol: symbol, orderId: order_id,
64
+ startTime: start_time, endTime: end_time, limit: limit, recvWindow: recv_window
65
+ })
66
+ end
67
+
68
+ def deposit_history(coin: nil, status: nil, start_time: nil, end_time: nil, limit: 1000, recv_window: 5000)
69
+ get_signed("/api/v3/capital/deposit/hisrec", {
70
+ coin: coin, status: status,
71
+ startTime: start_time, endTime: end_time, limit: limit, recvWindow: recv_window
72
+ })
73
+ end
74
+
75
+ def withdraw_history(coin: nil, status: nil, start_time: nil, end_time: nil, limit: 1000, recv_window: 5000)
76
+ get_signed("/api/v3/capital/withdraw/history", {
77
+ coin: coin, status: status,
78
+ startTime: start_time, endTime: end_time, limit: limit, recvWindow: recv_window
79
+ })
80
+ end
81
+
61
82
  def get_withdraw_addresses(recv_window: 5000)
62
83
  get_signed("/api/v3/capital/withdraw/address", { recvWindow: recv_window })
63
84
  end
@@ -71,6 +92,15 @@ module Honeymaker
71
92
 
72
93
  private
73
94
 
95
+ def validate_trading_credentials
96
+ result = account_information
97
+ result.success? ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
98
+ end
99
+
100
+ def validate_read_credentials
101
+ validate_trading_credentials
102
+ end
103
+
74
104
  def get_public(path, params = {})
75
105
  with_rescue do
76
106
  response = connection.get do |req|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Honeymaker
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -44,6 +44,27 @@ class Honeymaker::Clients::BinanceTest < Minitest::Test
44
44
  assert result.success?
45
45
  end
46
46
 
47
+ def test_account_trade_list
48
+ stub_connection(:get, [{ "symbol" => "BTCUSDT", "id" => 123, "price" => "50000" }])
49
+ result = @client.account_trade_list(symbol: "BTCUSDT")
50
+ assert result.success?
51
+ assert_equal "BTCUSDT", result.data.first["symbol"]
52
+ end
53
+
54
+ def test_deposit_history
55
+ stub_connection(:get, [{ "coin" => "BTC", "amount" => "0.5", "status" => 1 }])
56
+ result = @client.deposit_history
57
+ assert result.success?
58
+ assert_equal "BTC", result.data.first["coin"]
59
+ end
60
+
61
+ def test_withdraw_history
62
+ stub_connection(:get, [{ "coin" => "ETH", "amount" => "1.0", "status" => 6 }])
63
+ result = @client.withdraw_history
64
+ assert result.success?
65
+ assert_equal "ETH", result.data.first["coin"]
66
+ end
67
+
47
68
  def test_handles_api_error
48
69
  connection = stub
49
70
  connection.stubs(:get).raises(Faraday::ServerError.new("500", { status: 500, body: "Server Error" }))
@@ -53,6 +53,24 @@ class Honeymaker::Clients::BingXTest < Minitest::Test
53
53
  assert result.success?
54
54
  end
55
55
 
56
+ def test_get_trade_fills
57
+ stub_connection(:get, { "data" => [{ "tradeId" => "t1" }] })
58
+ result = @client.get_trade_fills(symbol: "BTC-USDT")
59
+ assert result.success?
60
+ end
61
+
62
+ def test_deposit_history
63
+ stub_connection(:get, [{ "coin" => "BTC" }])
64
+ result = @client.deposit_history
65
+ assert result.success?
66
+ end
67
+
68
+ def test_withdraw_history
69
+ stub_connection(:get, [{ "coin" => "ETH" }])
70
+ result = @client.withdraw_history
71
+ assert result.success?
72
+ end
73
+
56
74
  private
57
75
 
58
76
  def stub_connection(method, body)
@@ -41,6 +41,12 @@ class Honeymaker::Clients::BitgetTest < Minitest::Test
41
41
  assert result.success?
42
42
  end
43
43
 
44
+ def test_place_order_with_quote_size
45
+ stub_connection(:post, { "data" => { "orderId" => "456" } })
46
+ result = @client.place_order(symbol: "BTCUSDT", side: "buy", order_type: "market", quote_size: "100")
47
+ assert result.success?
48
+ end
49
+
44
50
  def test_get_order
45
51
  stub_connection(:get, { "data" => [{ "orderId" => "123" }] })
46
52
  result = @client.get_order(order_id: "123")
@@ -61,7 +67,25 @@ class Honeymaker::Clients::BitgetTest < Minitest::Test
61
67
 
62
68
  def test_withdraw
63
69
  stub_connection(:post, { "data" => { "orderId" => "w1" } })
64
- result = @client.withdraw(coin: "BTC", transfer_type: "on_chain", address: "addr", size: "0.1")
70
+ result = @client.withdraw(coin: "BTC", address: "addr", size: "0.1")
71
+ assert result.success?
72
+ end
73
+
74
+ def test_get_fills
75
+ stub_connection(:get, { "data" => [{ "tradeId" => "t1" }] })
76
+ result = @client.get_fills(symbol: "BTCUSDT")
77
+ assert result.success?
78
+ end
79
+
80
+ def test_deposit_list
81
+ stub_connection(:get, { "data" => [{ "coin" => "BTC" }] })
82
+ result = @client.deposit_list
83
+ assert result.success?
84
+ end
85
+
86
+ def test_withdrawal_list
87
+ stub_connection(:get, { "data" => [{ "coin" => "ETH" }] })
88
+ result = @client.withdrawal_list
65
89
  assert result.success?
66
90
  end
67
91
 
@@ -59,6 +59,24 @@ class Honeymaker::Clients::BitMartTest < Minitest::Test
59
59
  assert result.success?
60
60
  end
61
61
 
62
+ def test_get_trades
63
+ stub_connection(:get, { "data" => [{ "tradeId" => "t1" }] })
64
+ result = @client.get_trades(symbol: "BTC_USDT")
65
+ assert result.success?
66
+ end
67
+
68
+ def test_deposit_list
69
+ stub_connection(:get, { "data" => { "records" => [{ "currency" => "BTC" }] } })
70
+ result = @client.deposit_list
71
+ assert result.success?
72
+ end
73
+
74
+ def test_withdraw_list
75
+ stub_connection(:get, { "data" => { "records" => [{ "currency" => "ETH" }] } })
76
+ result = @client.withdraw_list
77
+ assert result.success?
78
+ end
79
+
62
80
  def test_signed_headers_include_memo_in_signature
63
81
  ts = "1234567890"
64
82
  pre_sign = "#{ts}#test_memo#body"
@@ -47,6 +47,12 @@ class Honeymaker::Clients::BitrueTest < Minitest::Test
47
47
  assert result.success?
48
48
  end
49
49
 
50
+ def test_account_trade_list
51
+ stub_connection(:get, [{ "symbol" => "BTCUSDT", "id" => 1 }])
52
+ result = @client.account_trade_list(symbol: "BTCUSDT")
53
+ assert result.success?
54
+ end
55
+
50
56
  def test_headers_include_api_key
51
57
  headers = @client.send(:auth_headers)
52
58
  assert_equal "test_key", headers[:"X-MBX-APIKEY"]
@@ -59,6 +59,24 @@ class Honeymaker::Clients::BitvavoTest < Minitest::Test
59
59
  assert result.success?
60
60
  end
61
61
 
62
+ def test_get_trades
63
+ stub_connection(:get, [{ "id" => "t1", "side" => "buy" }])
64
+ result = @client.get_trades(market: "BTC-EUR")
65
+ assert result.success?
66
+ end
67
+
68
+ def test_get_deposit_history
69
+ stub_connection(:get, [{ "symbol" => "BTC", "amount" => "1.0" }])
70
+ result = @client.get_deposit_history
71
+ assert result.success?
72
+ end
73
+
74
+ def test_get_withdrawal_history
75
+ stub_connection(:get, [{ "symbol" => "ETH", "amount" => "2.0" }])
76
+ result = @client.get_withdrawal_history
77
+ assert result.success?
78
+ end
79
+
62
80
  def test_signed_headers_include_access_window
63
81
  ts = "1234567890"
64
82
  headers = @client.send(:signed_headers, ts, "payload")
@@ -60,6 +60,24 @@ class Honeymaker::Clients::BybitTest < Minitest::Test
60
60
  assert result.success?
61
61
  end
62
62
 
63
+ def test_execution_list
64
+ stub_connection(:get, { "result" => { "list" => [{ "execId" => "e1" }] } })
65
+ result = @client.execution_list(category: "spot")
66
+ assert result.success?
67
+ end
68
+
69
+ def test_deposit_records
70
+ stub_connection(:get, { "result" => { "rows" => [{ "coin" => "BTC" }] } })
71
+ result = @client.deposit_records
72
+ assert result.success?
73
+ end
74
+
75
+ def test_withdraw_records
76
+ stub_connection(:get, { "result" => { "rows" => [{ "coin" => "ETH" }] } })
77
+ result = @client.withdraw_records
78
+ assert result.success?
79
+ end
80
+
63
81
  def test_signed_headers_include_api_key
64
82
  headers = @client.send(:signed_headers, "GET", { foo: "bar" })
65
83
  assert_equal "test_key", headers[:"X-BAPI-API-KEY"]
@@ -68,6 +68,20 @@ class Honeymaker::Clients::CoinbaseTest < Minitest::Test
68
68
  assert result.success?
69
69
  end
70
70
 
71
+ def test_list_fills
72
+ stub_connection(:get, { "fills" => [{ "trade_id" => "f1", "product_id" => "BTC-USD" }] })
73
+ result = @client.list_fills(product_id: "BTC-USD")
74
+ assert result.success?
75
+ assert_equal "f1", result.data["fills"].first["trade_id"]
76
+ end
77
+
78
+ def test_list_transactions
79
+ stub_connection(:get, { "data" => [{ "id" => "tx1", "type" => "send" }] })
80
+ result = @client.list_transactions(account_id: "acc1")
81
+ assert result.success?
82
+ assert_equal "tx1", result.data["data"].first["id"]
83
+ end
84
+
71
85
  def test_handles_api_error
72
86
  connection = stub
73
87
  connection.stubs(:get).raises(Faraday::ClientError.new("401", { status: 401, body: "Unauthorized" }))
@@ -60,6 +60,18 @@ class Honeymaker::Clients::GeminiTest < Minitest::Test
60
60
  assert result.success?
61
61
  end
62
62
 
63
+ def test_get_my_trades
64
+ stub_connection(:post, [{ "tid" => 123, "price" => "50000" }])
65
+ result = @client.get_my_trades(symbol: "btcusd")
66
+ assert result.success?
67
+ end
68
+
69
+ def test_get_transfers
70
+ stub_connection(:post, [{ "type" => "Deposit", "currency" => "BTC" }])
71
+ result = @client.get_transfers
72
+ assert result.success?
73
+ end
74
+
63
75
  private
64
76
 
65
77
  def stub_connection(method, body)
@@ -42,6 +42,18 @@ class Honeymaker::Clients::HyperliquidTest < Minitest::Test
42
42
  assert result.success?
43
43
  end
44
44
 
45
+ def test_user_fills
46
+ stub_connection(:post, [{ "oid" => 1, "side" => "B" }])
47
+ result = @client.user_fills(user: "0xabc")
48
+ assert result.success?
49
+ end
50
+
51
+ def test_user_fills_by_time
52
+ stub_connection(:post, [{ "oid" => 1, "side" => "B" }])
53
+ result = @client.user_fills_by_time(user: "0xabc", start_time: 1710936000000)
54
+ assert result.success?
55
+ end
56
+
45
57
  private
46
58
 
47
59
  def stub_connection(method, body)
@@ -46,6 +46,20 @@ class Honeymaker::Clients::KrakenTest < Minitest::Test
46
46
  assert result.success?
47
47
  end
48
48
 
49
+ def test_get_trades_history
50
+ stub_connection(:post, { "error" => [], "result" => { "trades" => { "T1" => { "pair" => "XBTUSDT" } }, "count" => 1 } })
51
+ result = @client.get_trades_history
52
+ assert result.success?
53
+ assert result.data["result"]["trades"].key?("T1")
54
+ end
55
+
56
+ def test_get_ledgers
57
+ stub_connection(:post, { "error" => [], "result" => { "ledger" => { "L1" => { "type" => "trade" } }, "count" => 1 } })
58
+ result = @client.get_ledgers
59
+ assert result.success?
60
+ assert result.data["result"]["ledger"].key?("L1")
61
+ end
62
+
49
63
  def test_private_headers_produce_signature
50
64
  headers = @client.send(:private_headers, "/0/private/Balance", "nonce=12345")
51
65
  assert headers.key?(:"API-Key")
@@ -59,6 +59,24 @@ class Honeymaker::Clients::KucoinTest < Minitest::Test
59
59
  assert result.success?
60
60
  end
61
61
 
62
+ def test_get_fills
63
+ stub_connection(:get, { "data" => { "items" => [{ "tradeId" => "t1" }] } })
64
+ result = @client.get_fills(symbol: "BTC-USDT")
65
+ assert result.success?
66
+ end
67
+
68
+ def test_get_deposits
69
+ stub_connection(:get, { "data" => { "items" => [{ "currency" => "BTC" }] } })
70
+ result = @client.get_deposits
71
+ assert result.success?
72
+ end
73
+
74
+ def test_get_withdrawals
75
+ stub_connection(:get, { "data" => { "items" => [{ "currency" => "ETH" }] } })
76
+ result = @client.get_withdrawals
77
+ assert result.success?
78
+ end
79
+
62
80
  def test_signed_headers_include_passphrase_and_version
63
81
  ts = "1234567890"
64
82
  headers = @client.send(:signed_headers, ts, "payload")
@@ -53,6 +53,24 @@ class Honeymaker::Clients::MexcTest < Minitest::Test
53
53
  assert result.success?
54
54
  end
55
55
 
56
+ def test_account_trade_list
57
+ stub_connection(:get, [{ "symbol" => "BTCUSDT", "id" => 1 }])
58
+ result = @client.account_trade_list(symbol: "BTCUSDT")
59
+ assert result.success?
60
+ end
61
+
62
+ def test_deposit_history
63
+ stub_connection(:get, [{ "coin" => "BTC" }])
64
+ result = @client.deposit_history
65
+ assert result.success?
66
+ end
67
+
68
+ def test_withdraw_history
69
+ stub_connection(:get, [{ "coin" => "ETH" }])
70
+ result = @client.withdraw_history
71
+ assert result.success?
72
+ end
73
+
56
74
  def test_headers_include_api_key
57
75
  headers = @client.send(:headers)
58
76
  assert_equal "test_key", headers[:"X-MEXC-APIKEY"]
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class ValidationTest < Minitest::Test
6
+ def test_validate_without_credentials
7
+ client = Honeymaker::Client.new
8
+ result = client.validate(:trading)
9
+ assert result.failure?
10
+ assert_includes result.errors, "No credentials provided"
11
+ end
12
+
13
+ def test_validate_unknown_type
14
+ client = Honeymaker::Client.new(api_key: "k", api_secret: "s")
15
+ assert_raises(Honeymaker::Error) { client.validate(:unknown) }
16
+ end
17
+
18
+ def test_validate_rescues_errors
19
+ client = Honeymaker::Client.new(api_key: "k", api_secret: "s")
20
+ client.define_singleton_method(:validate_trading_credentials) { raise "boom" }
21
+ result = client.validate(:trading)
22
+ assert result.failure?
23
+ assert_includes result.errors, "boom"
24
+ end
25
+
26
+ # Binance
27
+ def test_binance_validate_trading_success
28
+ client = Honeymaker::Clients::Binance.new(api_key: "k", api_secret: "s")
29
+ # cancel_order returns error code -2011 = valid key
30
+ stub_connection(client, :delete, { "code" => -2011, "msg" => "Unknown order" })
31
+ result = client.validate(:trading)
32
+ assert result.success?
33
+ end
34
+
35
+ def test_binance_validate_trading_failure
36
+ client = Honeymaker::Clients::Binance.new(api_key: "k", api_secret: "s")
37
+ stub_connection(client, :delete, { "code" => -2015, "msg" => "Invalid API-key" })
38
+ result = client.validate(:trading)
39
+ assert result.failure?
40
+ end
41
+
42
+ def test_binance_validate_read
43
+ client = Honeymaker::Clients::Binance.new(api_key: "k", api_secret: "s")
44
+ stub_connection(client, :get, { "ipRestrict" => true })
45
+ result = client.validate(:read)
46
+ assert result.success?
47
+ end
48
+
49
+ # Kraken
50
+ def test_kraken_validate_trading_success
51
+ client = Honeymaker::Clients::Kraken.new(api_key: "k", api_secret: Base64.strict_encode64("s" * 32))
52
+ stub_connection(client, :post, { "error" => [], "result" => { "XXBT" => "0.5" } })
53
+ result = client.validate(:trading)
54
+ assert result.success?
55
+ end
56
+
57
+ def test_kraken_validate_trading_failure
58
+ client = Honeymaker::Clients::Kraken.new(api_key: "k", api_secret: Base64.strict_encode64("s" * 32))
59
+ stub_connection(client, :post, { "error" => ["EAPI:Invalid key"], "result" => {} })
60
+ result = client.validate(:trading)
61
+ assert result.failure?
62
+ end
63
+
64
+ # Coinbase
65
+ def test_coinbase_validate_trading_success
66
+ key = OpenSSL::PKey::EC.generate("prime256v1")
67
+ client = Honeymaker::Clients::Coinbase.new(api_key: "k", api_secret: key.to_pem)
68
+ stub_connection(client, :get, { "accounts" => [] })
69
+ result = client.validate(:trading)
70
+ assert result.success?
71
+ end
72
+
73
+ # Bybit
74
+ def test_bybit_validate_trading_success
75
+ client = Honeymaker::Clients::Bybit.new(api_key: "k", api_secret: "s")
76
+ stub_connection(client, :get, { "retCode" => 0, "result" => {} })
77
+ result = client.validate(:trading)
78
+ assert result.success?
79
+ end
80
+
81
+ def test_bybit_validate_trading_failure
82
+ client = Honeymaker::Clients::Bybit.new(api_key: "k", api_secret: "s")
83
+ stub_connection(client, :get, { "retCode" => 10003, "retMsg" => "Invalid apikey" })
84
+ result = client.validate(:trading)
85
+ assert result.failure?
86
+ end
87
+
88
+ # MEXC
89
+ def test_mexc_validate_trading_success
90
+ client = Honeymaker::Clients::Mexc.new(api_key: "k", api_secret: "s")
91
+ stub_connection(client, :get, { "balances" => [] })
92
+ result = client.validate(:trading)
93
+ assert result.success?
94
+ end
95
+
96
+ # Bitget
97
+ def test_bitget_validate_trading_success
98
+ client = Honeymaker::Clients::Bitget.new(api_key: "k", api_secret: "s", passphrase: "p")
99
+ stub_connection(client, :get, { "code" => "00000", "data" => [] })
100
+ result = client.validate(:trading)
101
+ assert result.success?
102
+ end
103
+
104
+ def test_bitget_validate_trading_failure
105
+ client = Honeymaker::Clients::Bitget.new(api_key: "k", api_secret: "s", passphrase: "p")
106
+ stub_connection(client, :get, { "code" => "40014", "msg" => "Invalid ApiKey" })
107
+ result = client.validate(:trading)
108
+ assert result.failure?
109
+ end
110
+
111
+ # KuCoin
112
+ def test_kucoin_validate_trading_success
113
+ client = Honeymaker::Clients::Kucoin.new(api_key: "k", api_secret: "s", passphrase: "p")
114
+ stub_connection(client, :get, { "code" => "200000", "data" => [] })
115
+ result = client.validate(:trading)
116
+ assert result.success?
117
+ end
118
+
119
+ # Bitvavo
120
+ def test_bitvavo_validate_trading_success
121
+ client = Honeymaker::Clients::Bitvavo.new(api_key: "k", api_secret: "s")
122
+ stub_connection(client, :get, [{ "symbol" => "BTC", "available" => "0.5" }])
123
+ result = client.validate(:trading)
124
+ assert result.success?
125
+ end
126
+
127
+ # Gemini
128
+ def test_gemini_validate_trading_success
129
+ client = Honeymaker::Clients::Gemini.new(api_key: "k", api_secret: "s")
130
+ stub_connection(client, :post, [{ "currency" => "BTC", "amount" => "0.5" }])
131
+ result = client.validate(:trading)
132
+ assert result.success?
133
+ end
134
+
135
+ # BingX
136
+ def test_bingx_validate_trading_success
137
+ client = Honeymaker::Clients::BingX.new(api_key: "k", api_secret: "s")
138
+ stub_connection(client, :get, { "code" => 0, "data" => {} })
139
+ result = client.validate(:trading)
140
+ assert result.success?
141
+ end
142
+
143
+ # Bitrue
144
+ def test_bitrue_validate_trading_success
145
+ client = Honeymaker::Clients::Bitrue.new(api_key: "k", api_secret: "s")
146
+ stub_connection(client, :get, { "balances" => [] })
147
+ result = client.validate(:trading)
148
+ assert result.success?
149
+ end
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
+ # Hyperliquid
167
+ def test_hyperliquid_validate_trading_success
168
+ client = Honeymaker::Clients::Hyperliquid.new(api_key: "0xabc", api_secret: "s")
169
+ stub_connection(client, :post, [])
170
+ result = client.validate(:trading)
171
+ assert result.success?
172
+ end
173
+
174
+ private
175
+
176
+ def stub_connection(client, method, body)
177
+ response = stub(body: body)
178
+ connection = stub
179
+ connection.stubs(method).returns(response)
180
+ client.instance_variable_set(:@connection, connection)
181
+ end
182
+ 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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deltabadger
@@ -78,7 +78,6 @@ files:
78
78
  - LICENSE
79
79
  - README.md
80
80
  - Rakefile
81
- - honeymaker-0.1.0.gem
82
81
  - lib/honeymaker.rb
83
82
  - lib/honeymaker/client.rb
84
83
  - lib/honeymaker/clients/binance.rb
@@ -144,6 +143,7 @@ files:
144
143
  - test/honeymaker/clients/kraken_client_test.rb
145
144
  - test/honeymaker/clients/kucoin_client_test.rb
146
145
  - test/honeymaker/clients/mexc_client_test.rb
146
+ - test/honeymaker/clients/validation_test.rb
147
147
  - test/honeymaker/exchange_test.rb
148
148
  - test/honeymaker/exchanges/binance_test.rb
149
149
  - test/honeymaker/exchanges/binance_us_test.rb
data/honeymaker-0.1.0.gem DELETED
Binary file