honeymaker 0.2.0 → 0.4.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 +157 -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 +37 -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 +41 -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 +64 -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 +24 -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 +24 -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: b69b5d2b1995f1def30eaa09cb003cef99a8763ea383c9f71ea8aa0d05e9ecac
4
+ data.tar.gz: 54fb293018729bcfd12c26b596da9fae540bfe6574d9de40cae8b6b0407809bb
5
5
  SHA512:
6
- metadata.gz: 428f23c82dd3d1ae22f5fa05f00cd0036691fd397541b058d541ac7f5ba09936a464959a8c81ff11fa46ccab1c68fbfefe4d8fe7f97f06084fb32aca6e994112
7
- data.tar.gz: a79cbc1061092903465d37be4f1a0627332a05f583bbbd3289b1f46319e76623ad99563f13d2101dcdb9eb07cabc5038d50ec8a9229dc12c1bc32c719f2dd877
6
+ metadata.gz: e1903ef50d96bd65cc630b587a2e4d9f8e7e967bd82768fd2c5d883dd06d8e265364fb853949e0f5308a4ba0dfc65980c91c96d9c89f5d1632966dbf756d9d35
7
+ data.tar.gz: cc74f411106c324c6a12a9b93f02415cc1f14d65d38ee4518b313e487804a87c50c386fb7d9fea0716f21018d46fc42ce82ff9c3496552723c1dfb774318679b
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,149 @@ 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
+
205
+ def convert_trade_flow(start_time:, end_time:, limit: 1000, recv_window: 5000)
206
+ with_rescue do
207
+ response = connection.get do |req|
208
+ req.url "/sapi/v1/convert/tradeFlow"
209
+ req.headers = headers
210
+ req.params = {
211
+ startTime: start_time, endTime: end_time,
212
+ limit: limit, recvWindow: recv_window, timestamp: timestamp_ms
213
+ }.compact
214
+ req.params[:signature] = sign_params(req.params)
215
+ end
216
+ response.body
217
+ end
218
+ end
219
+
220
+ def fiat_payments(transaction_type:, begin_time: nil, end_time: nil, page: nil, rows: nil, recv_window: 5000)
221
+ with_rescue do
222
+ response = connection.get do |req|
223
+ req.url "/sapi/v1/fiat/payments"
224
+ req.headers = headers
225
+ req.params = {
226
+ transactionType: transaction_type,
227
+ beginTime: begin_time, endTime: end_time,
228
+ page: page, rows: rows,
229
+ recvWindow: recv_window, timestamp: timestamp_ms
230
+ }.compact
231
+ req.params[:signature] = sign_params(req.params)
232
+ end
233
+ response.body
234
+ end
235
+ end
236
+
237
+ def fiat_orders(transaction_type:, begin_time: nil, end_time: nil, page: nil, rows: nil, recv_window: 5000)
238
+ with_rescue do
239
+ response = connection.get do |req|
240
+ req.url "/sapi/v1/fiat/orders"
241
+ req.headers = headers
242
+ req.params = {
243
+ transactionType: transaction_type,
244
+ beginTime: begin_time, endTime: end_time,
245
+ page: page, rows: rows,
246
+ recvWindow: recv_window, timestamp: timestamp_ms
247
+ }.compact
248
+ req.params[:signature] = sign_params(req.params)
249
+ end
250
+ response.body
251
+ end
252
+ end
253
+
254
+ def dust_log(start_time: nil, end_time: nil, recv_window: 5000)
255
+ with_rescue do
256
+ response = connection.get do |req|
257
+ req.url "/sapi/v1/asset/dribblet"
258
+ req.headers = headers
259
+ req.params = {
260
+ startTime: start_time, endTime: end_time,
261
+ recvWindow: recv_window, timestamp: timestamp_ms
262
+ }.compact
263
+ req.params[:signature] = sign_params(req.params)
264
+ end
265
+ response.body
266
+ end
267
+ end
268
+
269
+ def asset_dividend(asset: nil, start_time: nil, end_time: nil, limit: 500, recv_window: 5000)
270
+ with_rescue do
271
+ response = connection.get do |req|
272
+ req.url "/sapi/v1/asset/assetDividend"
273
+ req.headers = headers
274
+ req.params = {
275
+ asset: asset, startTime: start_time, endTime: end_time,
276
+ limit: limit, recvWindow: recv_window, timestamp: timestamp_ms
277
+ }.compact
278
+ req.params[:signature] = sign_params(req.params)
279
+ end
280
+ response.body
281
+ end
282
+ end
283
+
284
+ def simple_earn_flexible_rewards(asset: nil, start_time: nil, end_time: nil, current: nil, size: nil)
285
+ with_rescue do
286
+ response = connection.get do |req|
287
+ req.url "/sapi/v1/simple-earn/flexible/history/rewardsRecord"
288
+ req.headers = headers
289
+ req.params = {
290
+ asset: asset, startTime: start_time, endTime: end_time,
291
+ current: current, size: size, timestamp: timestamp_ms
292
+ }.compact
293
+ req.params[:signature] = sign_params(req.params)
294
+ end
295
+ response.body
296
+ end
297
+ end
298
+
299
+ def simple_earn_locked_rewards(asset: nil, start_time: nil, end_time: nil, current: nil, size: nil)
300
+ with_rescue do
301
+ response = connection.get do |req|
302
+ req.url "/sapi/v1/simple-earn/locked/history/rewardsRecord"
303
+ req.headers = headers
304
+ req.params = {
305
+ asset: asset, startTime: start_time, endTime: end_time,
306
+ current: current, size: size, timestamp: timestamp_ms
307
+ }.compact
308
+ req.params[:signature] = sign_params(req.params)
309
+ end
310
+ response.body
311
+ end
312
+ end
313
+
171
314
  def get_all_coins_information(recv_window: 5000)
172
315
  with_rescue do
173
316
  response = connection.get do |req|
@@ -222,6 +365,20 @@ module Honeymaker
222
365
 
223
366
  private
224
367
 
368
+ def validate_trading_credentials
369
+ # Try cancelling a non-existent order — error -2011 (ORDER_DOES_NOT_EXIST) means key is valid with trade permission
370
+ result = cancel_order(symbol: "ETHBTC", order_id: "9999999999")
371
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
372
+
373
+ code = result.data.is_a?(Hash) ? result.data["code"] : nil
374
+ code == -2011 ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
375
+ end
376
+
377
+ def validate_read_credentials
378
+ result = api_description
379
+ Result.new(data: result.success?, errors: result.success? ? [] : ["Invalid read credentials"])
380
+ end
381
+
225
382
  def headers
226
383
  if authenticated?
227
384
  { "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,33 @@ module Honeymaker
61
61
  })
62
62
  end
63
63
 
64
+ def transaction_log(account_type: nil, category: nil, currency: nil, type: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil)
65
+ get_authenticated("/v5/account/transaction-log", {
66
+ accountType: account_type, category: category, currency: currency, type: type,
67
+ startTime: start_time, endTime: end_time, limit: limit, cursor: cursor
68
+ })
69
+ end
70
+
71
+ def execution_list(category:, symbol: nil, order_id: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil)
72
+ get_authenticated("/v5/execution/list", {
73
+ category: category, symbol: symbol, orderId: order_id,
74
+ startTime: start_time, endTime: end_time, limit: limit, cursor: cursor
75
+ })
76
+ end
77
+
78
+ def deposit_records(coin: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil)
79
+ get_authenticated("/v5/asset/deposit/query-record", {
80
+ coin: coin, startTime: start_time, endTime: end_time, limit: limit, cursor: cursor
81
+ })
82
+ end
83
+
84
+ def withdraw_records(coin: nil, start_time: nil, end_time: nil, limit: nil, cursor: nil, withdraw_type: nil)
85
+ get_authenticated("/v5/asset/withdraw/query-record", {
86
+ coin: coin, startTime: start_time, endTime: end_time,
87
+ limit: limit, cursor: cursor, withdrawType: withdraw_type
88
+ })
89
+ end
90
+
64
91
  def withdraw(coin:, chain:, address:, amount:, tag: nil, force_chain: nil)
65
92
  post_authenticated("/v5/asset/withdraw/create", {
66
93
  coin: coin, chain: chain, address: address, amount: amount,
@@ -70,6 +97,16 @@ module Honeymaker
70
97
 
71
98
  private
72
99
 
100
+ def validate_trading_credentials
101
+ result = wallet_balance(account_type: "UNIFIED")
102
+ return Result::Failure.new("Invalid trading credentials") if result.failure?
103
+ result.data["retCode"]&.zero? ? Result::Success.new(true) : Result::Failure.new("Invalid trading credentials")
104
+ end
105
+
106
+ def validate_read_credentials
107
+ validate_trading_credentials
108
+ end
109
+
73
110
  def get_public(path, params = {})
74
111
  with_rescue do
75
112
  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|