gmo_coin 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4bae508492f4f4cc52d41571945be4d8230361a4c0fd6c3ad1acbbc4c97975ed
4
+ data.tar.gz: 4723f44498348d7dc2d7a5d73357dd6dae73c56b89c951047639f136038176ca
5
+ SHA512:
6
+ metadata.gz: 4391f23eaa01aa15c39e87a0443e61f34b3feebb486f6d11fcec4d94672e024358dcf05a9c241557290576ecac779fd74efa48f8544893f7e27524af2341876a
7
+ data.tar.gz: 5a58b2a04f86311f9cbf063a79d5f37043e069397d025e0af344cfd0d6729ad60117ec8c5f6029aebae170e813daaf2213dbe0c74d53631b6ebfaf735ed1149e
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in gmo_coin.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 akiraNuma
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # GmoCoin
2
+
3
+ This is API wrapper for trading with GMO Coin.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'gmo_coin'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install gmo_coin
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'gmo_coin'
25
+
26
+ # initialize
27
+ gmo_client = GmoCoin::Client.new(api_key: "YOUR API KEY", api_secret: "YOUR SECRET KEY")
28
+
29
+ # v1/ticker
30
+ gmo_client.read_ticker('MONA')
31
+
32
+ # v1/order_books
33
+ gmo_client.read_order_books('MONA')
34
+
35
+ # Buy limit order by calling /v1/order
36
+ gmo_client.bid_limit_order(symbol: 'MONA', size: '1', price: '40.123')
37
+
38
+ # Sell limit order by calling /v1/order
39
+ gmo_client.ask_limit_order(symbol: 'MONA', size: '1', price: '65.123')
40
+
41
+ # v1/account/assets
42
+ gmo_client.read_assets
43
+
44
+ ```
45
+
46
+ ## Development
47
+
48
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
49
+
50
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
51
+
52
+ ## Contributing
53
+
54
+ Bug reports and pull requests are welcome on GitHub at https://github.com/akiraNuma/gmo_coin.
55
+
56
+ ## License
57
+
58
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "gmo_coin"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/gmo_coin.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "gmo_coin/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gmo_coin"
8
+ spec.version = GmoCoin::VERSION
9
+ spec.authors = ["akiraNuma"]
10
+ spec.email = ["akiran@akiranumakura.com"]
11
+
12
+ spec.summary = %q{API wrapper for GMO Coin.}
13
+ spec.description = %q{API wrapper for trading with GMO Coin.}
14
+ spec.homepage = "https://github.com/akiraNuma/gmo_coin"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.required_ruby_version = '>= 2.4'
34
+ spec.add_dependency "activesupport"
35
+ spec.add_dependency "rest-client"
36
+ spec.add_development_dependency "bundler", "~> 2.1.4"
37
+ spec.add_development_dependency "rake", "~> 10.0"
38
+ spec.add_development_dependency "rspec", "~> 3.0"
39
+ end
@@ -0,0 +1,490 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gmo_coin/config'
4
+
5
+ module GmoCoin
6
+ # GMOCoin cryptocurrency trading API wrapper
7
+ class Client
8
+ def initialize(api_key: nil, api_secret: nil)
9
+ @api_key = api_key
10
+ @api_secret = api_secret
11
+ @public_mode = @api_key&.blank? || @api_secret&.blank?
12
+ end
13
+
14
+ #
15
+ # Public API
16
+ #
17
+
18
+ # /v1/status
19
+ #
20
+ # @return [String] Response body
21
+ def read_status
22
+ path = '/v1/status'
23
+ public_request_for_get(path)
24
+ end
25
+
26
+ # /v1/ticker
27
+ #
28
+ # @param symbol [String] symbol
29
+ # @return [String] Response body
30
+ def read_ticker(symbol = nil)
31
+ path = '/v1/ticker'
32
+ query = {
33
+ symbol: symbol
34
+ }
35
+ query.compact!
36
+ public_request_for_get(path, query)
37
+ end
38
+
39
+ # /v1/orderbooks
40
+ #
41
+ # @param symbol [String] symbol
42
+ # @return [String] Response body
43
+ def read_order_books(symbol)
44
+ path = '/v1/orderbooks'
45
+ query = {
46
+ symbol: symbol
47
+ }
48
+ public_request_for_get(path, query)
49
+ end
50
+
51
+ # /v1/trades
52
+ #
53
+ # @param symbol [String] symbol
54
+ # @param page [Integer] page
55
+ # @param count [Integer] count
56
+ # @return [String] Response body
57
+ def read_trades(symbol, page: nil, count: nil)
58
+ path = '/v1/trades'
59
+ query = {
60
+ symbol: symbol,
61
+ page: page,
62
+ count: count
63
+ }
64
+ query.compact!
65
+ public_request_for_get(path, query)
66
+ end
67
+
68
+ # /v1/klines
69
+ #
70
+ # @param symbol [String] symbol
71
+ # @param interval [String] interval
72
+ # @param date [String] date
73
+ # @return [String] Response body
74
+ def read_klines(symbol, interval, date)
75
+ path = '/v1/klines'
76
+ query = {
77
+ symbol: symbol,
78
+ interval: interval,
79
+ date: date
80
+ }
81
+ public_request_for_get(path, query)
82
+ end
83
+
84
+ # /v1/symbols
85
+ #
86
+ # @return [String] Response body
87
+ def read_symbols
88
+ path = '/v1/symbols'
89
+ public_request_for_get(path)
90
+ end
91
+
92
+ #
93
+ # Private API
94
+ #
95
+
96
+ # /v1/account/margin
97
+ #
98
+ # @return [String] Response body
99
+ def read_margin
100
+ path = '/v1/account/margin'
101
+ private_request_for_get(path)
102
+ end
103
+
104
+ # /v1/account/assets
105
+ #
106
+ # @return [String] Response body
107
+ def read_assets
108
+ path = '/v1/account/assets'
109
+ private_request_for_get(path)
110
+ end
111
+
112
+ # /v1/account/tradingVolume
113
+ #
114
+ # @return [String] Response body
115
+ def read_trading_volume
116
+ path = '/v1/account/tradingVolume'
117
+ private_request_for_get(path)
118
+ end
119
+
120
+ # /v1/orders/
121
+ #
122
+ # @param order_id [String] order_id
123
+ # @return [String] Response body
124
+ def read_orders(order_id)
125
+ path = '/v1/account/orders'
126
+ query = {
127
+ orderId: order_id
128
+ }
129
+ private_request_for_get(path, query)
130
+ end
131
+
132
+ # /v1/activeOrders
133
+ #
134
+ # @param symbol [String] symbol
135
+ # @param page [Integer] page
136
+ # @param count [Integer] count
137
+ # @return [String] Response body
138
+ def read_active_orders(symbol, page: nil, count: nil)
139
+ path = '/v1/activeOrders'
140
+ query = {
141
+ symbol: symbol,
142
+ page: page,
143
+ count: count
144
+ }
145
+ query.compact!
146
+ private_request_for_get(path, query)
147
+ end
148
+
149
+ # /v1/executions
150
+ #
151
+ # @param order_id [Integer] order_id
152
+ # @param execution_id [String] execution_id
153
+ # @return [String] Response body
154
+ def read_executions(order_id: nil, execution_id: nil)
155
+ path = '/v1/executions'
156
+ query = {
157
+ orderId: order_id,
158
+ executionId: execution_id
159
+ }
160
+ query.compact!
161
+ private_request_for_get(path, query)
162
+ end
163
+
164
+ # /v1/latestExecutions
165
+ #
166
+ # @param symbol [String] symbol
167
+ # @param page [Integer] page
168
+ # @param count [Integer] count
169
+ # @return [String] Response body
170
+ def read_latest_executions(symbol, page: nil, count: nil)
171
+ path = '/v1/latestExecutions'
172
+ query = {
173
+ symbol: symbol,
174
+ page: page,
175
+ count: count
176
+ }
177
+ query.compact!
178
+ private_request_for_get(path, query)
179
+ end
180
+
181
+ # /v1/openPositions
182
+ #
183
+ # @param symbol [String] symbol
184
+ # @param page [Integer] page
185
+ # @param count [Integer] count
186
+ # @return [String] Response body
187
+ def read_open_positions(symbol, page: nil, count: nil)
188
+ path = '/v1/openPositions'
189
+ query = {
190
+ symbol: symbol,
191
+ page: page,
192
+ count: count
193
+ }
194
+ query.compact!
195
+ private_request_for_get(path, query)
196
+ end
197
+
198
+ # /v1/positionSummary
199
+ #
200
+ # @param symbol [String] symbol
201
+ # @return [String] Response body
202
+ def read_position_summary(symbol = nil)
203
+ path = '/v1/positionSummary'
204
+ query = {
205
+ symbol: symbol
206
+ }
207
+ query.compact!
208
+ private_request_for_get(path, query)
209
+ end
210
+
211
+ # /v1/account/transfer
212
+ #
213
+ # @param amount [String] amount
214
+ # @param transfer_type [String] transfer_type
215
+ # @return [String] Response body
216
+ def account_transfer(amount, transfer_type)
217
+ path = '/v1/account/transfer'
218
+ request_body = {
219
+ amount: amount,
220
+ transferType: transfer_type
221
+ }
222
+ private_request_for_post(path, request_body)
223
+ end
224
+
225
+ # /v1/order
226
+ #
227
+ # @param [Hash] params he args to order.
228
+ # @option params [String] :symbol Required symbol
229
+ # @option params [String] :side Required BUY SELL
230
+ # @option params [String] :execution_type Required MARKET LIMIT STOP
231
+ # @option params [String] :size Required amounts
232
+ # @option params [String] :price Required if LIMIT STOP. Not required if MARKET.
233
+ # @option params [String] :time_in_force FAK FAS FOK ((SOK is Post-only order) LIMIT can only be specified )
234
+ # *If timeInForce is not specified, FAK for MARKET and STOP, FAS for LIMIT. SOK can be specified for all ticker symbols when order is spot trading, and BTC_JPY when order is margin trading.
235
+ # @option params [String] :losscut_price Available only when order is margin trading and executionType is LIMIT or STOP.
236
+ # @option params [Boolean] :cancel_before true Cancellation of active orders and creating new orders will occur at the same time based on the below rule:
237
+ # *You can only specify cancelBefore as true for orders which are spot trading, executionType: MARKET, timeInforce: FAK and side: SELL.
238
+ # @return [String] Response body
239
+ # @example Sell MONA coins by limit order
240
+ # @gmo_client = GmoCoin::Client.new(api_key: ENV['GMO_KEY'], api_secret: ENV['GMO_SECRET'])
241
+ # @gmo_client.order(symbol: 'MONA', side: 'SELL', execution_type: 'LIMIT', size: '1', price: '100.123')
242
+ def order(**params)
243
+ path = '/v1/order'
244
+ request_body = transform_keys_to_lower_camel_case(params)
245
+ private_request_for_post(path, request_body)
246
+ end
247
+
248
+ # Buy limit order by calling /v1/order
249
+ #
250
+ # @param symbol [String] symbol
251
+ # @param size [String] amount
252
+ # @param price [String] price
253
+ # @return [String] Response body
254
+ # @example Sell coins by limit order
255
+ # @gmo_client = GmoCoin::Client.new(api_key: ENV['GMO_KEY'], api_secret: ENV['GMO_SECRET'])
256
+ # @gmo_client.bid_limit_order(symbol: 'MONA', size: '1', price: '40.123')
257
+ def bid_limit_order(symbol:, size:, price:)
258
+ order(symbol: symbol, side: 'BUY', execution_type: 'LIMIT', size: size, price: price)
259
+ end
260
+
261
+ # Sell limit order by calling /v1/order
262
+ #
263
+ # @param symbol [String] symbol
264
+ # @param size [String] amount
265
+ # @param price [String] price
266
+ # @return [String] Response body
267
+ # @example Sell coins by limit order
268
+ # @gmo_client = GmoCoin::Client.new(api_key: ENV['GMO_KEY'], api_secret: ENV['GMO_SECRET'])
269
+ # @gmo_client.ask_limit_order(symbol: 'MONA', size: '1', price: '65.123')
270
+ def ask_limit_order(symbol:, size:, price:)
271
+ order(symbol: symbol, side: 'SELL', execution_type: 'LIMIT', size: size, price: price)
272
+ end
273
+
274
+ # /v1/changeOrder
275
+ #
276
+ # @param order_id [Integer] order_id
277
+ # @param price [String] price
278
+ # @param losscut_price [String] losscut_price
279
+ # @return [String] Response body
280
+ def change_order(order_id, price, losscut_price: nil)
281
+ path = '/v1/changeOrder'
282
+ request_body = {
283
+ orderId: order_id,
284
+ price: price,
285
+ losscutPrice: losscut_price
286
+ }
287
+ request_body.compact!
288
+ private_request_for_post(path, request_body)
289
+ end
290
+
291
+ # /v1/cancelOrder
292
+ #
293
+ # @param order_id [Integer] order_id
294
+ # @return [String] Response body
295
+ def cancel_order(order_id)
296
+ path = '/v1/cancelOrder'
297
+ request_body = {
298
+ orderId: order_id
299
+ }
300
+ private_request_for_post(path, request_body)
301
+ end
302
+
303
+ # /v1/cancelOrders
304
+ #
305
+ # @param order_ids [Array<Integer>] order_ids
306
+ # @return [String] Response body
307
+ def cancel_orders(order_ids)
308
+ path = '/v1/cancelOrders'
309
+ request_body = {
310
+ orderIds: order_ids
311
+ }
312
+ private_request_for_post(path, request_body)
313
+ end
314
+
315
+ # /v1/cancelBulkOrder
316
+ #
317
+ # @param symbols [Array<String>] symbols
318
+ # @param side [String] side
319
+ # @param settle_type [String] settle_type
320
+ # @param desc [Boolean] desc
321
+ # @return [String] Response body
322
+ def cancel_bulk_order(symbols, side: nil, settle_type: nil, desc: nil)
323
+ path = '/v1/cancelBulkOrder'
324
+ request_body = {
325
+ symbols: symbols,
326
+ side: side,
327
+ settleType: settle_type,
328
+ desc: desc
329
+ }
330
+ request_body.compact!
331
+ private_request_for_post(path, request_body)
332
+ end
333
+
334
+ # /v1/closeOrder
335
+ #
336
+ # @param [Hash] params he args to order.
337
+ # @option params [String] :symbol Required symbol
338
+ # @option params [String] :side Required BUY SELL
339
+ # @option params [String] :execution_type Required MARKET LIMIT STOP
340
+ # @option params [String] :time_in_force FAK FAS FOK ((SOK is Post-only order) LIMIT can only be specified )
341
+ # *If timeInForce is not specified, FAK for MARKET and STOP, FAS for LIMIT. SOK can be specified for BTC_JPY.
342
+ # @option params [String] :price Required if LIMIT STOP. Not required if MARKET.
343
+ # @option params [Array<Hash>] :settle_position
344
+ # @option params [Integer] settle_position.positionId Allowed to set one position.
345
+ # @option params [String] settle_position.size Allowed to set one position.
346
+ # @option params [Boolean] :cancel_before true Cancellation of active orders and creating new orders will occur at the same time based on the below rule:
347
+ # *You can only specify cancelBefore as true for orders which are spot trading, executionType: MARKET, timeInforce: FAK and side: SELL.
348
+ # @return [String] Response body
349
+ # @example Close BTC_JPY by limit order
350
+ # @gmo_client = GmoCoin::Client.new(api_key: ENV['GMO_KEY'], api_secret: ENV['GMO_SECRET'])
351
+ # @gmo_client.close_order(symbol: 'BTC_JPY', side: 'SELL', execution_type: 'LIMIT', price: '6000000' , settle_position: [{positionId: 123, size: '1'}])
352
+ def close_order(**params)
353
+ path = '/v1/closeOrder'
354
+ request_body = transform_keys_to_lower_camel_case(params)
355
+ private_request_for_post(path, request_body)
356
+ end
357
+
358
+ # /v1/closeBulkOrder
359
+ #
360
+ # @param [Hash] params he args to order.
361
+ # @option params [String] :symbol Required symbol
362
+ # @option params [String] :side Required BUY SELL
363
+ # @option params [String] :execution_type Required MARKET LIMIT STOP
364
+ # @option params [String] :time_in_force FAK FAS FOK ((SOK is Post-only order) LIMIT can only be specified )
365
+ # *If timeInForce is not specified, FAK for MARKET and STOP, FAS for LIMIT. SOK can be specified for BTC_JPY.
366
+ # @option params [String] :price Required if LIMIT STOP. Not required if MARKET.
367
+ # @option params [String] :size Required
368
+ # @return [String] Response body
369
+ # @example Close BTC_JPY by limit order
370
+ # @gmo_client = GmoCoin::Client.new(api_key: ENV['GMO_KEY'], api_secret: ENV['GMO_SECRET'])
371
+ # @gmo_client.close_bulk_order(symbol: 'BTC_JPY', side: 'SELL', execution_type: 'LIMIT', price: '6000000' , size: '1')
372
+ def close_bulk_order(**params)
373
+ path = '/v1/closeBulkOrder'
374
+ request_body = transform_keys_to_lower_camel_case(params)
375
+ private_request_for_post(path, request_body)
376
+ end
377
+
378
+ # /v1/changeLosscutPrice
379
+ #
380
+ # @param position_id [Integer] position_id
381
+ # @param losscut_price [String] losscut_price
382
+ # @return [String] Response body
383
+ def change_losscut_price(position_id, losscut_price)
384
+ path = '/v1/changeLosscutPrice'
385
+ request_body = {
386
+ positionId: position_id,
387
+ losscutPrice: losscut_price
388
+ }
389
+ private_request_for_post(path, request_body)
390
+ end
391
+
392
+ private
393
+
394
+ # Call PublicAPI endpoint for Get
395
+ #
396
+ # @param path [String] Path beginning with /v1
397
+ # @param query [String] Query string
398
+ # @return [String] Response body
399
+ def public_request_for_get(path, query = {})
400
+ uri = URI.parse(GmoCoin::Config::PUBLIC_END_POINT + path)
401
+ uri.query = URI.encode_www_form(query) if query.present?
402
+ JSON.parse(RestClient.get(uri.to_s)&.to_s)
403
+ end
404
+
405
+ # Call PrivateAPI endpoint for Get
406
+ #
407
+ # @param path [String] Path beginning with /v1
408
+ # @param query [String] Query string
409
+ # @return [String] Response body
410
+ def private_request_for_get(path, query = {})
411
+ http_method = Net::HTTP::Get::METHOD # GET
412
+ # generate uri http
413
+ uri = URI.parse(GmoCoin::Config::PRIVATE_END_POINT + path)
414
+ uri.query = URI.encode_www_form(query) if query.present?
415
+ http = http_client(uri)
416
+
417
+ headers = private_headers(http_method, path) # Get header
418
+ # http request
419
+ response = http.get(uri.to_s, headers)
420
+ JSON.parse(response.body)
421
+ end
422
+
423
+ # Call PrivateAPI endpoint for Post
424
+ #
425
+ # @param path [String] Path beginning with /v1
426
+ # @param request_body [String] Request body
427
+ # @return [String] Response body
428
+ def private_request_for_post(path, request_body)
429
+ # raise GmoCoinAuthError if public_mode # TODO: FIXME: Behavior when api_secret is missing.
430
+ http_method = Net::HTTP::Post::METHOD # POST
431
+ # generate uri http
432
+ uri = URI.parse(GmoCoin::Config::PRIVATE_END_POINT + path)
433
+ http = http_client(uri)
434
+
435
+ headers = private_headers(http_method, path, request_body) # Post header
436
+ # http request
437
+ response = http.post(uri.path, request_body.to_json, headers)
438
+ JSON.parse(response.body)
439
+ end
440
+
441
+ # Return HTTP client based on Uri
442
+ #
443
+ # @param uri [URI::HTTP] Uri
444
+ # @return [Net::HTTP] HTTP
445
+ def http_client(uri)
446
+ http_client = Net::HTTP.new(
447
+ uri.host,
448
+ uri.port
449
+ )
450
+ http_client.use_ssl = uri.scheme == 'https'
451
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
452
+ http_client.open_timeout = GmoCoin::Config::OPEN_TIME_OUT
453
+ http_client.read_timeout = GmoCoin::Config::READ_TIME_OUT
454
+ http_client
455
+ end
456
+
457
+ # Return headers for authentication
458
+ #
459
+ # @param http_method [String] HTTP method
460
+ # @param path [String] Path beginning with /v1
461
+ # @param request_body [Hash] Request body
462
+ # @return [Hash] Request Headers
463
+ def private_headers(http_method, path, request_body = nil)
464
+ # raise GmoCoinAuthError if public_mode # TODO: FIXME: Behavior when api_secret is missing.
465
+ timestamp = current_unix_millis
466
+ plane_text = timestamp + http_method + path + request_body&.to_json.to_s
467
+ api_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA256'), @api_secret, plane_text)
468
+ {
469
+ 'API-KEY' => @api_key,
470
+ 'API-TIMESTAMP' => timestamp,
471
+ 'API-SIGN' => api_signature
472
+ }
473
+ end
474
+
475
+ # Current unix millis
476
+ #
477
+ # @return [String] Unix millis
478
+ def current_unix_millis
479
+ DateTime.now.strftime('%Q')
480
+ end
481
+
482
+ # lowerCamelize the hash key
483
+ #
484
+ # @param hash [Hash] hash data
485
+ # @return [Hash] Lower camelized hashed beef
486
+ def transform_keys_to_lower_camel_case(hash)
487
+ hash.transform_keys { |k| k.to_s.camelize(:lower).to_sym }
488
+ end
489
+ end
490
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GmoCoin
4
+ module Config
5
+ PUBLIC_END_POINT = 'https://api.coin.z.com/public'
6
+ PRIVATE_END_POINT = 'https://api.coin.z.com/private'
7
+ OPEN_TIME_OUT = 5
8
+ READ_TIME_OUT = 20
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GmoCoin
4
+ VERSION = '0.1.0'
5
+ end
data/lib/gmo_coin.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+ require 'rest_client'
6
+ require 'gmo_coin/version'
7
+ require 'gmo_coin/client'
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gmo_coin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - akiraNuma
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.1.4
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.1.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: API wrapper for trading with GMO Coin.
84
+ email:
85
+ - akiran@akiranumakura.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
97
+ - bin/setup
98
+ - gmo_coin.gemspec
99
+ - lib/gmo_coin.rb
100
+ - lib/gmo_coin/client.rb
101
+ - lib/gmo_coin/config.rb
102
+ - lib/gmo_coin/version.rb
103
+ homepage: https://github.com/akiraNuma/gmo_coin
104
+ licenses:
105
+ - MIT
106
+ metadata:
107
+ allowed_push_host: https://rubygems.org
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '2.4'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubygems_version: 3.1.4
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: API wrapper for GMO Coin.
127
+ test_files: []