orionx-sdk-ruby 1.0.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.
@@ -0,0 +1,328 @@
1
+ module OrionX
2
+ module Endpoints
3
+ class Orders
4
+ def initialize(api_client)
5
+ @api = api_client
6
+ @logger = api_client.logger
7
+ end
8
+
9
+ # Get a specific order by ID
10
+ def get_order(order_id)
11
+ raise OrionX::ValidationError, "Order ID cannot be nil or empty" if order_id.nil? || order_id.empty?
12
+
13
+ query = <<~GRAPHQL
14
+ query sdk_getOrder($orderId: ID!) {
15
+ order(orderId: $orderId) {
16
+ _id
17
+ type
18
+ amount
19
+ limitPrice
20
+ stopPriceDown
21
+ stopPriceUp
22
+ status
23
+ createdAt
24
+ activatedAt
25
+ closedAt
26
+ market {
27
+ code
28
+ mainCurrency {
29
+ code
30
+ units
31
+ }
32
+ secondaryCurrency {
33
+ code
34
+ units
35
+ }
36
+ }
37
+ clientId
38
+ }
39
+ }
40
+ GRAPHQL
41
+
42
+ @logger.debug("Fetching order: #{order_id}")
43
+ response = @api.call(query, { orderId: order_id })
44
+
45
+ result = response.dig("order")
46
+ @logger.info("Order #{order_id} retrieved successfully") if result
47
+ result
48
+ end
49
+
50
+ # Get orders with optional filters
51
+ def get_orders(filters = {})
52
+ query = <<~GRAPHQL
53
+ query sdk_getOrders($filter: String, $marketCode: ID, $onlyOpen: Boolean, $onlyClosed: Boolean, $currencyCode: ID, $onlyFilled: Boolean, $page: Int, $limit: Int, $sortBy: String, $sortType: SortType) {
54
+ orders(filter: $filter, marketCode: $marketCode, onlyOpen: $onlyOpen, onlyClosed: $onlyClosed, currencyCode: $currencyCode, onlyFilled: $onlyFilled, page: $page, limit: $limit, sortBy: $sortBy, sortType: $sortType) {
55
+ _id
56
+ items {
57
+ type
58
+ amount
59
+ limitPrice
60
+ stopPriceUp
61
+ stopPriceDown
62
+ status
63
+ createdAt
64
+ activatedAt
65
+ closedAt
66
+ market {
67
+ code
68
+ mainCurrency {
69
+ code
70
+ units
71
+ }
72
+ secondaryCurrency {
73
+ code
74
+ units
75
+ }
76
+ }
77
+ clientId
78
+ }
79
+ }
80
+ }
81
+ GRAPHQL
82
+
83
+ @logger.debug("Fetching orders with filters: #{filters.inspect}")
84
+ response = @api.call(query, filters)
85
+
86
+ result = response.dig("orders")
87
+ @logger.info("Orders retrieved: #{result&.dig('items')&.length || 0} orders") if result
88
+ result
89
+ end
90
+
91
+ # Place a limit order
92
+ def place_limit_order(market_code:, amount:, limit_price:, sell:, client_id: nil)
93
+ validate_order_params(market_code, amount)
94
+ raise OrionX::ValidationError, "Limit price must be positive" if limit_price.nil? || limit_price <= 0
95
+
96
+ query = <<~GRAPHQL
97
+ mutation sdk_placeLimitOrder(
98
+ $marketCode: ID
99
+ $amount: BigInt
100
+ $limitPrice: BigInt
101
+ $sell: Boolean
102
+ $clientId: String
103
+ ) {
104
+ placeLimitOrder(
105
+ marketCode: $marketCode
106
+ amount: $amount
107
+ limitPrice: $limitPrice
108
+ sell: $sell
109
+ clientId: $clientId
110
+ ) {
111
+ _id
112
+ type
113
+ amount
114
+ limitPrice
115
+ status
116
+ createdAt
117
+ market {
118
+ code
119
+ }
120
+ clientId
121
+ }
122
+ }
123
+ GRAPHQL
124
+
125
+ variables = {
126
+ marketCode: market_code,
127
+ amount: amount,
128
+ limitPrice: limit_price,
129
+ sell: sell,
130
+ clientId: client_id
131
+ }
132
+
133
+ @logger.debug("Placing limit order: #{variables.inspect}")
134
+ response = @api.call(query, variables)
135
+
136
+ result = response.dig("placeLimitOrder")
137
+ @logger.info("Limit order placed successfully: #{result&.dig('_id')}") if result
138
+ result
139
+ end
140
+
141
+ # Place a market order
142
+ def place_market_order(market_code:, amount:, sell:, client_id: nil)
143
+ validate_order_params(market_code, amount)
144
+
145
+ query = <<~GRAPHQL
146
+ mutation sdk_placeMarketOrder(
147
+ $marketCode: ID
148
+ $amount: BigInt
149
+ $sell: Boolean
150
+ $clientId: String
151
+ ) {
152
+ placeMarketOrder(
153
+ marketCode: $marketCode
154
+ amount: $amount
155
+ sell: $sell
156
+ clientId: $clientId
157
+ ) {
158
+ _id
159
+ type
160
+ amount
161
+ limitPrice
162
+ status
163
+ createdAt
164
+ market {
165
+ code
166
+ }
167
+ clientId
168
+ }
169
+ }
170
+ GRAPHQL
171
+
172
+ variables = {
173
+ marketCode: market_code,
174
+ amount: amount,
175
+ sell: sell,
176
+ clientId: client_id
177
+ }
178
+
179
+ @logger.debug("Placing market order: #{variables.inspect}")
180
+ response = @api.call(query, variables)
181
+
182
+ result = response.dig("placeMarketOrder")
183
+ @logger.info("Market order placed successfully: #{result&.dig('_id')}") if result
184
+ result
185
+ end
186
+
187
+ # Place a stop limit order
188
+ def place_stop_limit_order(market_code:, stop_price_up:, stop_price_down:, amount:, limit_price:, sell:, client_id: nil)
189
+ validate_order_params(market_code, amount)
190
+ raise OrionX::ValidationError, "Limit price must be positive" if limit_price.nil? || limit_price <= 0
191
+ raise OrionX::ValidationError, "At least one stop price must be provided" if stop_price_up.nil? && stop_price_down.nil?
192
+
193
+ query = <<~GRAPHQL
194
+ mutation sdk_placeStopLimitOrder(
195
+ $marketCode: ID
196
+ $stopPriceUp: BigInt
197
+ $stopPriceDown: BigInt
198
+ $amount: BigInt
199
+ $limitPrice: BigInt
200
+ $sell: Boolean
201
+ $clientId: String
202
+ ) {
203
+ placeStopLimitOrder(
204
+ marketCode: $marketCode
205
+ stopPriceUp: $stopPriceUp
206
+ stopPriceDown: $stopPriceDown
207
+ amount: $amount
208
+ limitPrice: $limitPrice
209
+ sell: $sell
210
+ clientId: $clientId
211
+ ) {
212
+ _id
213
+ type
214
+ amount
215
+ limitPrice
216
+ status
217
+ createdAt
218
+ market {
219
+ code
220
+ }
221
+ clientId
222
+ }
223
+ }
224
+ GRAPHQL
225
+
226
+ variables = {
227
+ marketCode: market_code,
228
+ stopPriceUp: stop_price_up,
229
+ stopPriceDown: stop_price_down,
230
+ amount: amount,
231
+ limitPrice: limit_price,
232
+ sell: sell,
233
+ clientId: client_id
234
+ }
235
+
236
+ @logger.debug("Placing stop limit order: #{variables.inspect}")
237
+ response = @api.call(query, variables)
238
+
239
+ result = response.dig("placeStopLimitOrder")
240
+ @logger.info("Stop limit order placed successfully: #{result&.dig('_id')}") if result
241
+ result
242
+ end
243
+
244
+ # Place a stop market order
245
+ def place_stop_market_order(market_code:, stop_price_up:, stop_price_down:, amount:, sell:, client_id: nil)
246
+ validate_order_params(market_code, amount)
247
+ raise OrionX::ValidationError, "At least one stop price must be provided" if stop_price_up.nil? && stop_price_down.nil?
248
+
249
+ query = <<~GRAPHQL
250
+ mutation sdk_placeStopMarketOrder(
251
+ $marketCode: ID
252
+ $stopPriceUp: BigInt
253
+ $stopPriceDown: BigInt
254
+ $amount: BigInt
255
+ $sell: Boolean
256
+ $clientId: String
257
+ ) {
258
+ placeStopMarketOrder(
259
+ marketCode: $marketCode
260
+ stopPriceUp: $stopPriceUp
261
+ stopPriceDown: $stopPriceDown
262
+ amount: $amount
263
+ sell: $sell
264
+ clientId: $clientId
265
+ ) {
266
+ _id
267
+ type
268
+ amount
269
+ limitPrice
270
+ status
271
+ createdAt
272
+ market {
273
+ code
274
+ }
275
+ clientId
276
+ }
277
+ }
278
+ GRAPHQL
279
+
280
+ variables = {
281
+ marketCode: market_code,
282
+ stopPriceUp: stop_price_up,
283
+ stopPriceDown: stop_price_down,
284
+ amount: amount,
285
+ sell: sell,
286
+ clientId: client_id
287
+ }
288
+
289
+ @logger.debug("Placing stop market order: #{variables.inspect}")
290
+ response = @api.call(query, variables)
291
+
292
+ result = response.dig("placeStopMarketOrder")
293
+ @logger.info("Stop market order placed successfully: #{result&.dig('_id')}") if result
294
+ result
295
+ end
296
+
297
+ # Cancel an order
298
+ def cancel_order(order_id)
299
+ raise OrionX::ValidationError, "Order ID cannot be nil or empty" if order_id.nil? || order_id.empty?
300
+
301
+ query = <<~GRAPHQL
302
+ mutation sdk_cancelOrder($orderId: ID!) {
303
+ cancelOrder(orderId: $orderId) {
304
+ _id
305
+ type
306
+ status
307
+ clientId
308
+ }
309
+ }
310
+ GRAPHQL
311
+
312
+ @logger.debug("Cancelling order: #{order_id}")
313
+ response = @api.call(query, { orderId: order_id })
314
+
315
+ result = response.dig("cancelOrder")
316
+ @logger.info("Order #{order_id} cancelled successfully") if result
317
+ result
318
+ end
319
+
320
+ private
321
+
322
+ def validate_order_params(market_code, amount)
323
+ raise OrionX::ValidationError, "Market code cannot be nil or empty" if market_code.nil? || market_code.empty?
324
+ raise OrionX::ValidationError, "Amount must be positive" if amount.nil? || amount <= 0
325
+ end
326
+ end
327
+ end
328
+ end
@@ -0,0 +1,269 @@
1
+ module OrionX
2
+ module Endpoints
3
+ class Transactions
4
+ def initialize(api_client)
5
+ @api = api_client
6
+ @logger = api_client.logger
7
+ end
8
+
9
+ # Get a specific transaction by ID
10
+ def get_transaction(transaction_id)
11
+ raise OrionX::ValidationError, "Transaction ID cannot be nil or empty" if transaction_id.nil? || transaction_id.empty?
12
+
13
+ query = <<~GRAPHQL
14
+ query sdk_getTransaction($_id: ID!) {
15
+ transaction(_id: $_id) {
16
+ _id
17
+ amount
18
+ balance
19
+ commission
20
+ currency {
21
+ code
22
+ units
23
+ }
24
+ date
25
+ type
26
+ adds
27
+ hash
28
+ description
29
+ market {
30
+ code
31
+ mainCurrency {
32
+ code
33
+ units
34
+ }
35
+ secondaryCurrency {
36
+ code
37
+ units
38
+ }
39
+ }
40
+ price
41
+ cost
42
+ explorerURL
43
+ isInside
44
+ meta {
45
+ status
46
+ }
47
+ }
48
+ }
49
+ GRAPHQL
50
+
51
+ @logger.debug("Fetching transaction: #{transaction_id}")
52
+ response = @api.call(query, { _id: transaction_id })
53
+
54
+ result = response.dig("transaction")
55
+ @logger.info("Transaction #{transaction_id} retrieved successfully") if result
56
+ result
57
+ end
58
+
59
+ # Get transactions with optional filters
60
+ def get_transactions(filters = {})
61
+ query = <<~GRAPHQL
62
+ query sdk_getTransactions($filter: String, $walletId: ID, $types: [String], $initPeriod: Date, $finalPeriod: Date, $page: Int, $limit: Int, $sortBy: String, $sortType: SortType) {
63
+ transactions(filter: $filter, walletId: $walletId, types: $types, initPeriod: $initPeriod, finalPeriod: $finalPeriod, page: $page, limit: $limit, sortBy: $sortBy, sortType: $sortType) {
64
+ _id
65
+ items {
66
+ amount
67
+ balance
68
+ commission
69
+ currency {
70
+ code
71
+ units
72
+ }
73
+ date
74
+ type
75
+ adds
76
+ hash
77
+ description
78
+ market {
79
+ code
80
+ mainCurrency {
81
+ code
82
+ units
83
+ }
84
+ secondaryCurrency {
85
+ code
86
+ units
87
+ }
88
+ }
89
+ price
90
+ cost
91
+ explorerURL
92
+ isInside
93
+ meta {
94
+ status
95
+ }
96
+ }
97
+ }
98
+ }
99
+ GRAPHQL
100
+
101
+ @logger.debug("Fetching transactions with filters: #{filters.inspect}")
102
+ response = @api.call(query, filters)
103
+
104
+ result = response.dig("transactions")
105
+ @logger.info("Transactions retrieved: #{result&.dig('items')&.length || 0} transactions") if result
106
+ result
107
+ end
108
+
109
+ # Send cryptocurrency
110
+ def send_crypto(wallet_id:, network:, amount:, contact_id: nil, description: nil, client_id: nil)
111
+ raise OrionX::ValidationError, "Wallet ID cannot be nil or empty" if wallet_id.nil? || wallet_id.empty?
112
+ raise OrionX::ValidationError, "Network cannot be nil or empty" if network.nil? || network.empty?
113
+ raise OrionX::ValidationError, "Amount must be positive" if amount.nil? || amount <= 0
114
+
115
+ query = <<~GRAPHQL
116
+ mutation sdk_send(
117
+ $fromWalletId: ID!
118
+ $contactId: ID
119
+ $network: String!
120
+ $amount: BigInt!
121
+ $description: String
122
+ $clientId: ID
123
+ ) {
124
+ sendCrypto(
125
+ fromWalletId: $fromWalletId
126
+ contactId: $contactId
127
+ network: $network
128
+ amount: $amount
129
+ description: $description
130
+ clientId: $clientId
131
+ ) {
132
+ _id
133
+ type
134
+ amount
135
+ price
136
+ hash
137
+ date
138
+ market {
139
+ code
140
+ }
141
+ meta {
142
+ status
143
+ }
144
+ }
145
+ }
146
+ GRAPHQL
147
+
148
+ variables = {
149
+ fromWalletId: wallet_id,
150
+ contactId: contact_id,
151
+ network: network,
152
+ amount: amount,
153
+ description: description,
154
+ clientId: client_id
155
+ }
156
+
157
+ @logger.debug("Sending crypto: #{variables.inspect}")
158
+ response = @api.call(query, variables)
159
+
160
+ result = response.dig("sendCrypto")
161
+ @logger.info("Crypto send initiated successfully: #{result&.dig('_id')}") if result
162
+ result
163
+ end
164
+
165
+ # Request withdrawal
166
+ def withdrawal_request(wallet_id:, account_id:, amount:)
167
+ raise OrionX::ValidationError, "Wallet ID cannot be nil or empty" if wallet_id.nil? || wallet_id.empty?
168
+ raise OrionX::ValidationError, "Account ID cannot be nil or empty" if account_id.nil? || account_id.empty?
169
+ raise OrionX::ValidationError, "Amount must be positive" if amount.nil? || amount <= 0
170
+
171
+ query = <<~GRAPHQL
172
+ mutation sdk_withdrawalRequest(
173
+ $walletId: ID
174
+ $accountId: ID
175
+ $amount: BigInt
176
+ ) {
177
+ requestWithdrawal(
178
+ walletId: $walletId
179
+ accountId: $accountId
180
+ amount: $amount
181
+ ) {
182
+ _id
183
+ amount
184
+ commission
185
+ date
186
+ type
187
+ description
188
+ }
189
+ }
190
+ GRAPHQL
191
+
192
+ variables = {
193
+ walletId: wallet_id,
194
+ accountId: account_id,
195
+ amount: amount
196
+ }
197
+
198
+ @logger.debug("Requesting withdrawal: #{variables.inspect}")
199
+ response = @api.call(query, variables)
200
+
201
+ result = response.dig("requestWithdrawal")
202
+ @logger.info("Withdrawal request created successfully: #{result&.dig('_id')}") if result
203
+ result
204
+ end
205
+
206
+ # Convert/Trade instantly
207
+ def convert(quote_option_id:, amount:, market_code:, sell:)
208
+ raise OrionX::ValidationError, "Quote option ID cannot be nil or empty" if quote_option_id.nil? || quote_option_id.empty?
209
+ raise OrionX::ValidationError, "Amount must be positive" if amount.nil? || amount <= 0
210
+ raise OrionX::ValidationError, "Market code cannot be nil or empty" if market_code.nil? || market_code.empty?
211
+
212
+ query = <<~GRAPHQL
213
+ mutation sdk_convert(
214
+ $quoteOptionId: String
215
+ $amount: BigInt!
216
+ $marketCode: String!
217
+ $sell: Boolean!
218
+ ) {
219
+ instantTransaction(
220
+ quoteOptionId: $quoteOptionId
221
+ amount: $amount
222
+ marketCode: $marketCode
223
+ sell: $sell
224
+ )
225
+ }
226
+ GRAPHQL
227
+
228
+ variables = {
229
+ quoteOptionId: quote_option_id,
230
+ amount: amount,
231
+ marketCode: market_code,
232
+ sell: sell
233
+ }
234
+
235
+ @logger.debug("Converting/trading instantly: #{variables.inspect}")
236
+ response = @api.call(query, variables)
237
+
238
+ result = response.dig("instantTransaction")
239
+ @logger.info("Instant conversion completed successfully") if result
240
+ result
241
+ end
242
+
243
+ # Get transaction history for a specific currency
244
+ def get_history(currency_code, limit: 50, page: 1)
245
+ # First get the wallet ID for the currency
246
+ account_query = <<~GRAPHQL
247
+ query sdk_getAccount($assetId: ID!) {
248
+ wallet(code: $assetId) {
249
+ _id
250
+ }
251
+ }
252
+ GRAPHQL
253
+
254
+ account_response = @api.call(account_query, { assetId: currency_code })
255
+ wallet_id = account_response.dig("wallet", "_id")
256
+
257
+ return nil unless wallet_id
258
+
259
+ # Get transactions for this wallet
260
+ get_transactions({
261
+ walletId: wallet_id,
262
+ limit: limit,
263
+ page: page,
264
+ sortType: "DESC"
265
+ })
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,54 @@
1
+ module OrionX
2
+ module Endpoints
3
+ class User
4
+ def initialize(api_client)
5
+ @api = api_client
6
+ @logger = api_client.logger
7
+ end
8
+
9
+ # Get current user information
10
+ def me
11
+ query = <<~GRAPHQL
12
+ query sdk_getMe {
13
+ me {
14
+ _id
15
+ email
16
+ name
17
+ profile {
18
+ fullName
19
+ phone
20
+ kycVerified
21
+ birthdate
22
+ countryCode
23
+ occupation
24
+ address
25
+ }
26
+ }
27
+ }
28
+ GRAPHQL
29
+
30
+ @logger.debug("Fetching user profile")
31
+ response = @api.call(query)
32
+
33
+ result = response.dig("me")
34
+ @logger.info("User profile retrieved successfully") if result
35
+ result
36
+ end
37
+
38
+ # Get user ID only
39
+ def user_id
40
+ query = <<~GRAPHQL
41
+ query sdk_getUserId {
42
+ me {
43
+ _id
44
+ }
45
+ }
46
+ GRAPHQL
47
+
48
+ @logger.debug("Fetching user ID")
49
+ response = @api.call(query)
50
+ response.dig("me", "_id")
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,63 @@
1
+ require "logger"
2
+
3
+ module OrionX
4
+ class Logger
5
+ attr_reader :logger
6
+
7
+ def initialize(level: ::Logger::INFO, output: STDOUT)
8
+ @logger = ::Logger.new(output)
9
+ @logger.level = level
10
+ @logger.formatter = proc do |severity, datetime, progname, msg|
11
+ "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity.ljust(5)} OrionX: #{msg}\n"
12
+ end
13
+ end
14
+
15
+ def debug(message = nil, &block)
16
+ if block_given?
17
+ @logger.debug(&block)
18
+ else
19
+ @logger.debug(message)
20
+ end
21
+ end
22
+
23
+ def info(message = nil, &block)
24
+ if block_given?
25
+ @logger.info(&block)
26
+ else
27
+ @logger.info(message)
28
+ end
29
+ end
30
+
31
+ def warn(message = nil, &block)
32
+ if block_given?
33
+ @logger.warn(&block)
34
+ else
35
+ @logger.warn(message)
36
+ end
37
+ end
38
+
39
+ def error(message = nil, &block)
40
+ if block_given?
41
+ @logger.error(&block)
42
+ else
43
+ @logger.error(message)
44
+ end
45
+ end
46
+
47
+ def fatal(message = nil, &block)
48
+ if block_given?
49
+ @logger.fatal(&block)
50
+ else
51
+ @logger.fatal(message)
52
+ end
53
+ end
54
+
55
+ def level=(level)
56
+ @logger.level = level
57
+ end
58
+
59
+ def level
60
+ @logger.level
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module OrionX
2
+ VERSION = "1.0.0"
3
+ end