coindcx-client 0.1.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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +55 -0
  3. data/.github/workflows/release.yml +138 -0
  4. data/.rubocop.yml +56 -0
  5. data/AGENT.md +352 -0
  6. data/README.md +224 -0
  7. data/bin/console +59 -0
  8. data/docs/README.md +29 -0
  9. data/docs/coindcx_docs_gaps.md +3 -0
  10. data/docs/core.md +179 -0
  11. data/docs/rails_integration.md +151 -0
  12. data/docs/standalone_bot.md +159 -0
  13. data/lib/coindcx/auth/signer.rb +48 -0
  14. data/lib/coindcx/client.rb +44 -0
  15. data/lib/coindcx/configuration.rb +108 -0
  16. data/lib/coindcx/contracts/channel_name.rb +23 -0
  17. data/lib/coindcx/contracts/identifiers.rb +36 -0
  18. data/lib/coindcx/contracts/order_request.rb +120 -0
  19. data/lib/coindcx/contracts/socket_backend.rb +19 -0
  20. data/lib/coindcx/contracts/wallet_transfer_request.rb +46 -0
  21. data/lib/coindcx/errors/base_error.rb +54 -0
  22. data/lib/coindcx/logging/null_logger.rb +12 -0
  23. data/lib/coindcx/logging/structured_logger.rb +17 -0
  24. data/lib/coindcx/models/balance.rb +8 -0
  25. data/lib/coindcx/models/base_model.rb +31 -0
  26. data/lib/coindcx/models/instrument.rb +8 -0
  27. data/lib/coindcx/models/market.rb +8 -0
  28. data/lib/coindcx/models/order.rb +8 -0
  29. data/lib/coindcx/models/trade.rb +8 -0
  30. data/lib/coindcx/rest/base_resource.rb +35 -0
  31. data/lib/coindcx/rest/funding/facade.rb +18 -0
  32. data/lib/coindcx/rest/funding/orders.rb +46 -0
  33. data/lib/coindcx/rest/futures/facade.rb +29 -0
  34. data/lib/coindcx/rest/futures/market_data.rb +71 -0
  35. data/lib/coindcx/rest/futures/orders.rb +47 -0
  36. data/lib/coindcx/rest/futures/positions.rb +93 -0
  37. data/lib/coindcx/rest/futures/wallets.rb +44 -0
  38. data/lib/coindcx/rest/margin/facade.rb +17 -0
  39. data/lib/coindcx/rest/margin/orders.rb +57 -0
  40. data/lib/coindcx/rest/public/facade.rb +17 -0
  41. data/lib/coindcx/rest/public/market_data.rb +52 -0
  42. data/lib/coindcx/rest/spot/facade.rb +17 -0
  43. data/lib/coindcx/rest/spot/orders.rb +67 -0
  44. data/lib/coindcx/rest/transfers/facade.rb +17 -0
  45. data/lib/coindcx/rest/transfers/wallets.rb +40 -0
  46. data/lib/coindcx/rest/user/accounts.rb +17 -0
  47. data/lib/coindcx/rest/user/facade.rb +17 -0
  48. data/lib/coindcx/transport/circuit_breaker.rb +65 -0
  49. data/lib/coindcx/transport/http_client.rb +290 -0
  50. data/lib/coindcx/transport/rate_limit_registry.rb +65 -0
  51. data/lib/coindcx/transport/request_policy.rb +152 -0
  52. data/lib/coindcx/transport/response_normalizer.rb +40 -0
  53. data/lib/coindcx/transport/retry_policy.rb +79 -0
  54. data/lib/coindcx/utils/payload.rb +51 -0
  55. data/lib/coindcx/version.rb +5 -0
  56. data/lib/coindcx/ws/connection_manager.rb +423 -0
  57. data/lib/coindcx/ws/connection_state.rb +75 -0
  58. data/lib/coindcx/ws/parsers/order_book_snapshot.rb +42 -0
  59. data/lib/coindcx/ws/private_channels.rb +38 -0
  60. data/lib/coindcx/ws/public_channels.rb +92 -0
  61. data/lib/coindcx/ws/socket_io_client.rb +89 -0
  62. data/lib/coindcx/ws/socket_io_simple_backend.rb +63 -0
  63. data/lib/coindcx/ws/subscription_registry.rb +80 -0
  64. data/lib/coindcx/ws/uri_ruby3_compat.rb +13 -0
  65. data/lib/coindcx.rb +63 -0
  66. data/spec/auth_signer_spec.rb +22 -0
  67. data/spec/client_spec.rb +19 -0
  68. data/spec/contracts/order_request_spec.rb +136 -0
  69. data/spec/contracts/wallet_transfer_request_spec.rb +45 -0
  70. data/spec/models/base_model_spec.rb +18 -0
  71. data/spec/rest/funding/orders_spec.rb +43 -0
  72. data/spec/rest/futures/market_data_spec.rb +49 -0
  73. data/spec/rest/futures/orders_spec.rb +107 -0
  74. data/spec/rest/futures/positions_spec.rb +57 -0
  75. data/spec/rest/futures/wallets_spec.rb +44 -0
  76. data/spec/rest/margin/orders_spec.rb +87 -0
  77. data/spec/rest/public/market_data_spec.rb +31 -0
  78. data/spec/rest/spot/orders_spec.rb +152 -0
  79. data/spec/rest/transfers/wallets_spec.rb +33 -0
  80. data/spec/rest/user/accounts_spec.rb +21 -0
  81. data/spec/spec_helper.rb +11 -0
  82. data/spec/transport/http_client_spec.rb +232 -0
  83. data/spec/transport/rate_limit_registry_spec.rb +28 -0
  84. data/spec/transport/request_policy_spec.rb +67 -0
  85. data/spec/transport/response_normalizer_spec.rb +63 -0
  86. data/spec/ws/connection_manager_spec.rb +339 -0
  87. data/spec/ws/order_book_snapshot_spec.rb +25 -0
  88. data/spec/ws/private_channels_spec.rb +28 -0
  89. data/spec/ws/public_channels_spec.rb +89 -0
  90. data/spec/ws/socket_io_client_spec.rb +229 -0
  91. data/spec/ws/socket_io_simple_backend_spec.rb +41 -0
  92. data/spec/ws/uri_ruby3_compat_spec.rb +12 -0
  93. metadata +164 -0
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module Models
5
+ class Balance < BaseModel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module Models
5
+ class BaseModel
6
+ def initialize(attributes = {})
7
+ @attributes = Utils::Payload.symbolize_keys(attributes || {})
8
+ end
9
+
10
+ attr_reader :attributes
11
+
12
+ def [](key)
13
+ attributes[key.to_sym]
14
+ end
15
+
16
+ def to_h
17
+ attributes.dup
18
+ end
19
+
20
+ def respond_to_missing?(method_name, include_private = false)
21
+ attributes.key?(method_name.to_sym) || super
22
+ end
23
+
24
+ def method_missing(method_name, *arguments)
25
+ return attributes.fetch(method_name.to_sym) if arguments.empty? && attributes.key?(method_name.to_sym)
26
+
27
+ super
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module Models
5
+ class Instrument < BaseModel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module Models
5
+ class Market < BaseModel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module Models
5
+ class Order < BaseModel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module Models
5
+ class Trade < BaseModel
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ class BaseResource
6
+ def initialize(http_client:)
7
+ @http_client = http_client
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :http_client
13
+
14
+ def get(path, params: {}, body: {}, auth: false, base: :api, bucket: nil)
15
+ http_client.get(path, params: params, body: body, auth: auth, base: base, bucket: bucket)
16
+ end
17
+
18
+ def post(path, body: {}, auth: false, base: :api, bucket: nil)
19
+ http_client.post(path, body: body, auth: auth, base: base, bucket: bucket)
20
+ end
21
+
22
+ def delete(path, body: {}, auth: false, base: :api, bucket: nil)
23
+ http_client.delete(path, body: body, auth: auth, base: base, bucket: bucket)
24
+ end
25
+
26
+ def build_model(model_class, attributes)
27
+ model_class.new(attributes)
28
+ end
29
+
30
+ def build_models(model_class, collection)
31
+ Array(collection).map { |attributes| model_class.new(attributes) }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Funding
6
+ # Funding facade exposing CoinDCX funding-order APIs.
7
+ class Facade
8
+ def initialize(http_client:)
9
+ @http_client = http_client
10
+ end
11
+
12
+ def orders
13
+ @orders ||= Orders.new(http_client: @http_client)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Funding
6
+ # Funding endpoints for lend, settle, and order-history flows.
7
+ class Orders < BaseResource
8
+ # Fetches funding orders for the authenticated account.
9
+ # @param attributes [Hash] request filters accepted by CoinDCX
10
+ # @return [Hash] raw CoinDCX payload
11
+ def list(attributes = {})
12
+ post(
13
+ "/exchange/v1/funding/fetch_orders",
14
+ auth: true,
15
+ bucket: :funding_fetch_orders,
16
+ body: attributes
17
+ )
18
+ end
19
+
20
+ # Places a funding lend order.
21
+ # @param attributes [Hash] lend payload accepted by CoinDCX
22
+ # @return [Hash] raw CoinDCX payload
23
+ def lend(attributes)
24
+ post(
25
+ "/exchange/v1/funding/lend",
26
+ auth: true,
27
+ bucket: :funding_lend,
28
+ body: attributes
29
+ )
30
+ end
31
+
32
+ # Settles a funding order.
33
+ # @param attributes [Hash] settle payload accepted by CoinDCX
34
+ # @return [Hash] raw CoinDCX payload
35
+ def settle(attributes)
36
+ post(
37
+ "/exchange/v1/funding/settle",
38
+ auth: true,
39
+ bucket: :funding_settle,
40
+ body: attributes
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Futures
6
+ class Facade
7
+ def initialize(http_client:)
8
+ @http_client = http_client
9
+ end
10
+
11
+ def market_data
12
+ @market_data ||= MarketData.new(http_client: @http_client)
13
+ end
14
+
15
+ def orders
16
+ @orders ||= Orders.new(http_client: @http_client)
17
+ end
18
+
19
+ def positions
20
+ @positions ||= Positions.new(http_client: @http_client)
21
+ end
22
+
23
+ def wallets
24
+ @wallets ||= Wallets.new(http_client: @http_client)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Futures
6
+ class MarketData < BaseResource
7
+ VALID_ORDER_BOOK_DEPTHS = [10, 20, 50].freeze
8
+
9
+ def list_active_instruments(margin_currency_short_names: ["USDT"])
10
+ get(
11
+ "/exchange/v1/derivatives/futures/data/active_instruments",
12
+ params: { 'margin_currency_short_name[]': margin_currency_short_names }
13
+ )
14
+ end
15
+
16
+ def fetch_instrument(pair:, margin_currency_short_name:)
17
+ build_model(
18
+ Models::Instrument,
19
+ get(
20
+ "/exchange/v1/derivatives/futures/data/instrument",
21
+ params: { pair: pair, margin_currency_short_name: margin_currency_short_name },
22
+ body: {},
23
+ auth: true,
24
+ bucket: :futures_instrument_detail
25
+ )
26
+ )
27
+ end
28
+
29
+ def list_trades(pair:)
30
+ build_models(Models::Trade, get("/exchange/v1/derivatives/futures/data/trades", params: { pair: pair }))
31
+ end
32
+
33
+ def fetch_order_book(instrument:, depth: 50)
34
+ validate_order_book_depth!(depth)
35
+ get("/market_data/v3/orderbook/#{instrument}-futures/#{depth}", base: :public)
36
+ end
37
+
38
+ def list_candlesticks(pair:, from:, to:, resolution:)
39
+ get(
40
+ "/market_data/candlesticks",
41
+ base: :public,
42
+ params: { pair: pair, from: from, to: to, resolution: resolution, pcode: "f" }
43
+ )
44
+ end
45
+
46
+ def current_prices
47
+ get("/market_data/v3/current_prices/futures/rt", base: :public, bucket: :public_market_data)
48
+ end
49
+
50
+ def stats(pair:)
51
+ get(
52
+ "/api/v1/derivatives/futures/data/stats",
53
+ params: { pair: pair }
54
+ )
55
+ end
56
+
57
+ def conversions
58
+ get("/api/v1/derivatives/futures/data/conversions")
59
+ end
60
+
61
+ private
62
+
63
+ def validate_order_book_depth!(depth)
64
+ return depth if VALID_ORDER_BOOK_DEPTHS.include?(depth)
65
+
66
+ raise Errors::ValidationError, "futures order book depth must be one of #{VALID_ORDER_BOOK_DEPTHS.join(', ')}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Futures
6
+ class Orders < BaseResource
7
+ def list(attributes = {})
8
+ build_models(
9
+ Models::Order,
10
+ post("/exchange/v1/derivatives/futures/orders", auth: true, bucket: :futures_list_orders, body: attributes)
11
+ )
12
+ end
13
+
14
+ def list_trades(attributes = {})
15
+ build_models(
16
+ Models::Trade,
17
+ post("/exchange/v1/derivatives/futures/trades", auth: true, bucket: :futures_trades, body: attributes)
18
+ )
19
+ end
20
+
21
+ def create(order:)
22
+ validated_order = Contracts::OrderRequest.validate_futures_create!(order)
23
+ build_model(
24
+ Models::Order,
25
+ post(
26
+ "/exchange/v1/derivatives/futures/orders/create",
27
+ auth: true,
28
+ bucket: :futures_create_order,
29
+ body: { order: validated_order }
30
+ )
31
+ )
32
+ end
33
+
34
+ def cancel(attributes)
35
+ post("/exchange/v1/derivatives/futures/orders/cancel", auth: true, bucket: :futures_cancel_order, body: attributes)
36
+ end
37
+
38
+ def edit(attributes)
39
+ build_model(
40
+ Models::Order,
41
+ post("/exchange/v1/derivatives/futures/orders/edit", auth: true, bucket: :futures_edit_order, body: attributes)
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Futures
6
+ class Positions < BaseResource
7
+ def list(attributes = {})
8
+ post("/exchange/v1/derivatives/futures/positions", auth: true, bucket: :futures_positions_list, body: attributes)
9
+ end
10
+
11
+ def update_leverage(attributes)
12
+ post(
13
+ "/exchange/v1/derivatives/futures/positions/update_leverage",
14
+ auth: true,
15
+ bucket: :futures_positions_update_leverage,
16
+ body: attributes
17
+ )
18
+ end
19
+
20
+ def add_margin(attributes)
21
+ post("/exchange/v1/derivatives/futures/positions/add_margin", auth: true, bucket: :futures_positions_add_margin, body: attributes)
22
+ end
23
+
24
+ def remove_margin(attributes)
25
+ post(
26
+ "/exchange/v1/derivatives/futures/positions/remove_margin",
27
+ auth: true,
28
+ bucket: :futures_positions_remove_margin,
29
+ body: attributes
30
+ )
31
+ end
32
+
33
+ def cancel_all_open_orders(attributes)
34
+ post(
35
+ "/exchange/v1/derivatives/futures/positions/cancel_all_open_orders",
36
+ auth: true,
37
+ bucket: :futures_positions_cancel_all_open_orders,
38
+ body: attributes
39
+ )
40
+ end
41
+
42
+ def cancel_all_open_orders_for_position(attributes)
43
+ post(
44
+ "/exchange/v1/derivatives/futures/positions/cancel_all_open_orders_for_position",
45
+ auth: true,
46
+ bucket: :futures_positions_cancel_all_open_orders_for_position,
47
+ body: attributes
48
+ )
49
+ end
50
+
51
+ def exit_position(attributes)
52
+ post("/exchange/v1/derivatives/futures/positions/exit", auth: true, bucket: :futures_positions_exit, body: attributes)
53
+ end
54
+
55
+ def create_take_profit_stop_loss(attributes)
56
+ post(
57
+ "/exchange/v1/derivatives/futures/positions/create_tpsl",
58
+ auth: true,
59
+ bucket: :futures_positions_create_tpsl,
60
+ body: attributes
61
+ )
62
+ end
63
+
64
+ def list_transactions(attributes = {})
65
+ post(
66
+ "/exchange/v1/derivatives/futures/positions/transactions",
67
+ auth: true,
68
+ bucket: :futures_positions_transactions,
69
+ body: attributes
70
+ )
71
+ end
72
+
73
+ def fetch_cross_margin_details(attributes = {})
74
+ get(
75
+ "/exchange/v1/derivatives/futures/positions/cross_margin_details",
76
+ body: attributes,
77
+ auth: true,
78
+ bucket: :futures_positions_cross_margin_details
79
+ )
80
+ end
81
+
82
+ def update_margin_type(attributes)
83
+ post(
84
+ "/exchange/v1/derivatives/futures/positions/margin_type",
85
+ auth: true,
86
+ bucket: :futures_positions_margin_type,
87
+ body: attributes
88
+ )
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Futures
6
+ class Wallets < BaseResource
7
+ def transfer(transfer_type:, amount:, currency_short_name:, timestamp: nil)
8
+ post(
9
+ "/exchange/v1/derivatives/futures/wallets/transfer",
10
+ auth: true,
11
+ bucket: :futures_wallet_transfer,
12
+ body: {
13
+ transfer_type: transfer_type,
14
+ amount: amount,
15
+ currency_short_name: currency_short_name,
16
+ timestamp: timestamp
17
+ }
18
+ )
19
+ end
20
+
21
+ def fetch_details(attributes = {})
22
+ get(
23
+ "/exchange/v1/derivatives/futures/wallets",
24
+ body: attributes,
25
+ auth: true,
26
+ bucket: :futures_wallet_details
27
+ )
28
+ end
29
+
30
+ def list_transactions(page: 1, size: 1000, timestamp: nil)
31
+ body = {}
32
+ body[:timestamp] = timestamp unless timestamp.nil?
33
+ get(
34
+ "/exchange/v1/derivatives/futures/wallets/transactions",
35
+ params: { page: page, size: size },
36
+ body: body,
37
+ auth: true,
38
+ bucket: :futures_wallet_transactions
39
+ )
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Margin
6
+ class Facade
7
+ def initialize(http_client:)
8
+ @http_client = http_client
9
+ end
10
+
11
+ def orders
12
+ @orders ||= Orders.new(http_client: @http_client)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Margin
6
+ class Orders < BaseResource
7
+ def create(attributes)
8
+ validated_attributes = Contracts::OrderRequest.validate_margin_create!(attributes)
9
+ build_model(
10
+ Models::Order,
11
+ post("/exchange/v1/margin/create", auth: true, bucket: :margin_create_order, body: validated_attributes)
12
+ )
13
+ end
14
+
15
+ def list(attributes = {})
16
+ build_models(Models::Order, post("/exchange/v1/margin/fetch_orders", auth: true, bucket: :margin_list_orders, body: attributes))
17
+ end
18
+
19
+ def fetch(attributes)
20
+ build_model(Models::Order, post("/exchange/v1/margin/order", auth: true, bucket: :margin_fetch_order, body: attributes))
21
+ end
22
+
23
+ def cancel(attributes)
24
+ post("/exchange/v1/margin/cancel", auth: true, bucket: :margin_cancel_order, body: attributes)
25
+ end
26
+
27
+ def exit_order(attributes)
28
+ post("/exchange/v1/margin/exit", auth: true, bucket: :margin_exit_order, body: attributes)
29
+ end
30
+
31
+ def edit_target(attributes)
32
+ post("/exchange/v1/margin/edit_target", auth: true, bucket: :margin_edit_target, body: attributes)
33
+ end
34
+
35
+ def edit_stop_loss(attributes)
36
+ post("/exchange/v1/margin/edit_sl", auth: true, bucket: :margin_edit_stop_loss, body: attributes)
37
+ end
38
+
39
+ def edit_trailing_stop_loss(attributes)
40
+ post("/exchange/v1/margin/edit_trailing_sl", auth: true, bucket: :margin_edit_trailing_stop_loss, body: attributes)
41
+ end
42
+
43
+ def edit_target_order_price(attributes)
44
+ post("/exchange/v1/margin/edit_price_of_target_order", auth: true, bucket: :margin_edit_target_order_price, body: attributes)
45
+ end
46
+
47
+ def add_margin(attributes)
48
+ post("/exchange/v1/margin/add_margin", auth: true, bucket: :margin_add_margin, body: attributes)
49
+ end
50
+
51
+ def remove_margin(attributes)
52
+ post("/exchange/v1/margin/remove_margin", auth: true, bucket: :margin_remove_margin, body: attributes)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Public
6
+ class Facade
7
+ def initialize(http_client:)
8
+ @http_client = http_client
9
+ end
10
+
11
+ def market_data
12
+ @market_data ||= MarketData.new(http_client: @http_client)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Public
6
+ class MarketData < BaseResource
7
+ def list_tickers
8
+ build_models(Models::Market, get("/exchange/ticker", bucket: :public_ticker))
9
+ end
10
+
11
+ def list_markets
12
+ get("/exchange/v1/markets", bucket: :public_market_data)
13
+ end
14
+
15
+ def list_market_details
16
+ build_models(Models::Market, get("/exchange/v1/markets_details", bucket: :public_market_data))
17
+ end
18
+
19
+ def list_trades(pair:, limit: nil)
20
+ build_models(
21
+ Models::Trade,
22
+ get(
23
+ "/market_data/trade_history",
24
+ base: :public,
25
+ bucket: :public_trades,
26
+ params: { pair: pair, limit: limit }
27
+ )
28
+ )
29
+ end
30
+
31
+ def fetch_order_book(pair:)
32
+ get("/market_data/orderbook", base: :public, bucket: :public_order_book, params: { pair: pair })
33
+ end
34
+
35
+ def list_candles(pair:, interval:, start_time: nil, end_time: nil, limit: nil)
36
+ get(
37
+ "/market_data/candles",
38
+ base: :public,
39
+ bucket: :public_candles,
40
+ params: {
41
+ pair: pair,
42
+ interval: interval,
43
+ startTime: start_time,
44
+ endTime: end_time,
45
+ limit: limit
46
+ }
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinDCX
4
+ module REST
5
+ module Spot
6
+ class Facade
7
+ def initialize(http_client:)
8
+ @http_client = http_client
9
+ end
10
+
11
+ def orders
12
+ @orders ||= Orders.new(http_client: @http_client)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end