binance-ruby 1.1.2 → 1.2.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0b8a2d2b8699dd1ab11f5c4927f492f1083178f6c490b2f128bec3e17519142
4
- data.tar.gz: d0f3a90df602d2218abb7a479ee239b25c45a3c556350cd1a044d0fff2e1d123
3
+ metadata.gz: ed932ba3687136b21bbf45ab2a104ebb89c8ad2073852c166c49bae172ee2693
4
+ data.tar.gz: f62479b21ed010c103f47f7cda6b1c64961389ce55667775e3099524fbca1490
5
5
  SHA512:
6
- metadata.gz: 7e79efbfe09d9046dbec1de668d00e34811170eb5fa323f4b1999bc5586f960d9f7790093e753b861f6c2b7cf0af687cb3b12f3afa020a99d67426930dbec331
7
- data.tar.gz: 16cfb386ab4ea3bfd87067b3cffbeca50145b7108453bff5edf95b84a1fe90a0f2a7caf21e8927b233624c86263f7fe8c6df3f691d10b4fffa628f20445d5089
6
+ metadata.gz: 6f2748f9c2124ff7615a23b8b73b3edbe3f88606395e9bc99ce864f6891803cbabe1fad881496a07441e1d518dd30dc1922b1e535752446513a91debb3f5001a
7
+ data.tar.gz: 6753fa662464ea79db5eb58f132c4f24ee94190279ce8de845389d40d4ae78e9232584caf71c330abd0d8e12e895d2a73afa94464a30c2d6ee6ec981bbbeffb7
data/lib/binance-ruby.rb CHANGED
@@ -1,15 +1,18 @@
1
1
  require "active_support/core_ext/string"
2
2
  require "awrence"
3
3
  require "httparty"
4
+ require "faye/websocket"
4
5
 
5
6
  require "binance/api"
6
7
  require "binance/api/account"
7
8
  require "binance/api/configuration"
8
- require "binance/api/data_stream"
9
9
  require "binance/api/error"
10
10
  require "binance/api/margin"
11
11
  require "binance/api/margin/account"
12
12
  require "binance/api/margin/order"
13
13
  require "binance/api/order"
14
14
  require "binance/api/request"
15
+ require "binance/api/trade"
16
+ require "binance/api/user_data_stream"
15
17
  require "binance/api/version"
18
+ require "binance/websocket"
@@ -27,6 +27,23 @@ module Binance
27
27
  params: params.delete_if { |key, value| value.nil? },
28
28
  security_type: :user_data, api_key: api_key, api_secret_key: api_secret_key)
29
29
  end
30
+
31
+ # @note have not tested this for binance.us yet.
32
+ def withdraw!(coin: nil, withdrawOrderId: nil, network: nil, address: nil, addressTag: nil, amount: nil,
33
+ transactionFeeFlag: false, name: nil, recvWindow: nil, api_key: nil, api_secret_key: nil)
34
+ raise Error.new(message: "amount is required") if amount.nil?
35
+ raise Error.new(message: "coin is required") if coin.nil?
36
+ raise Error.new(message: "address is required") if address.nil?
37
+ timestamp = Configuration.timestamp
38
+ params = {
39
+ coin: coin, withdrawOrderId: withdrawOrderId, network: network, address: address, timestamp: timestamp,
40
+ addressTag: addressTag, amount: amount, transactionFeeFlag: transactionFeeFlag,
41
+ name: name, recvWindow: recvWindow,
42
+ }
43
+ Request.send!(api_key_type: :read_info, path: "/sapi/v1/capital/withdraw/apply",
44
+ params: params.delete_if { |key, value| value.nil? }, method: :post,
45
+ security_type: :user_data, api_key: api_key, api_secret_key: api_secret_key)
46
+ end
30
47
  end
31
48
  end
32
49
  end
@@ -0,0 +1,46 @@
1
+ module Binance
2
+ module Api
3
+ class MarketStream
4
+ class << self
5
+ def connect(api_key: nil, api_secret_key: nil)
6
+ EM.run {
7
+ ws = Faye::WebSocket::Client.new("wss://stream.binance.com:9443/stream?streams=<streamName1>/<streamName2>/<streamName3>")
8
+
9
+ ws.on :open do |event|
10
+ p [:open]
11
+ ws.send("Hello, world!")
12
+ end
13
+
14
+ ws.on :message do |event|
15
+ p [:message, event.data]
16
+ end
17
+
18
+ ws.on :close do |event|
19
+ p [:close, event.code, event.reason]
20
+ ws = nil
21
+ end
22
+ }
23
+ end
24
+
25
+ # It's recommended to send a ping about every 30 minutes.
26
+ def keepalive!(listen_key: nil, api_key: nil, api_secret_key: nil)
27
+ raise Error.new(message: "listen_key is required") if listen_key.nil?
28
+ Request.send!(api_key_type: :none, method: :put, path: "/api/v1/userDataStream",
29
+ params: { listenKey: listen_key }, security_type: :user_stream)
30
+ end
31
+
32
+ def start!(api_key: nil, api_secret_key: nil)
33
+ Request.send!(api_key_type: :none, method: :post, path: "/api/v1/userDataStream",
34
+ security_type: :user_stream, api_key: api_key, api_secret_key: api_secret_key)
35
+ end
36
+
37
+ def stop!(listen_key: nil, api_key: nil, api_secret_key: nil)
38
+ raise Error.new(message: "listen_key is required") if listen_key.nil?
39
+ Request.send!(api_key_type: :none, method: :delete, path: "/api/v1/userDataStream",
40
+ params: { listenKey: listen_key }, security_type: :user_stream,
41
+ api_key: api_key, api_secret_key: api_secret_key)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -10,13 +10,16 @@ module Binance
10
10
  raise Error.new(message: "invalid security type #{security_type}") unless security_types.include?(security_type)
11
11
  all_headers = default_headers(api_key_type: api_key_type, security_type: security_type, api_key: api_key)
12
12
  params.delete_if { |k, v| v.nil? }
13
- signature = signed_request_signature(params: params, api_secret_key: api_secret_key)
14
- params.merge!(signature: signature) if [:trade, :user_data].include?(security_type)
13
+ if %w(trade user_data).include?(security_type&.to_s)
14
+ signature = signed_request_signature(params: params, api_secret_key: api_secret_key)
15
+ params.merge!(signature: signature)
16
+ end
15
17
  # send() is insecure so don't use it.
16
18
  case method
17
19
  when :get
18
20
  response = get(path, headers: all_headers, query: params)
19
21
  when :post
22
+ byebug
20
23
  response = post(path, body: params, headers: all_headers)
21
24
  when :put
22
25
  response = put(path, body: params, headers: all_headers)
@@ -0,0 +1,27 @@
1
+ module Binance
2
+ module Api
3
+ class Trade
4
+ class << self
5
+ def get_bnb_burn_status!(recvWindow: nil, api_key: nil, api_secret_key: nil)
6
+ timestamp = Configuration.timestamp
7
+ params = { recvWindow: recvWindow, timestamp: timestamp }
8
+ Request.send!(api_key_type: :read_info, path: "/sapi/v1/bnbBurn",
9
+ params: params.delete_if { |key, value| value.nil? },
10
+ security_type: :user_data, tld: Configuration.tld, api_key: api_key,
11
+ api_secret_key: api_secret_key)
12
+ end
13
+
14
+ def toggle_bnb_burn!(spot_bnb_burn: true, interest_bnb_burn: false, recvWindow: nil, api_key: nil,
15
+ api_secret_key: nil)
16
+ timestamp = Configuration.timestamp
17
+ params = { spotBNBBurn: spot_bnb_burn, interestBNBBurn: interest_bnb_burn,
18
+ recvWindow: recvWindow, timestamp: timestamp }
19
+ Request.send!(api_key_type: :read_info, path: "/sapi/v1/bnbBurn", method: :post,
20
+ params: params.delete_if { |key, value| value.nil? },
21
+ security_type: :user_data, tld: Configuration.tld, api_key: api_key,
22
+ api_secret_key: api_secret_key)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,17 +1,18 @@
1
1
  module Binance
2
2
  module Api
3
- class DataStream
3
+ class UserDataStream
4
4
  class << self
5
5
  # It's recommended to send a ping about every 30 minutes.
6
6
  def keepalive!(listen_key: nil, api_key: nil, api_secret_key: nil)
7
7
  raise Error.new(message: "listen_key is required") if listen_key.nil?
8
8
  Request.send!(api_key_type: :none, method: :put, path: "/api/v1/userDataStream",
9
- params: { listenKey: listen_key }, security_type: :user_stream)
9
+ params: { listenKey: listen_key }, security_type: :user_stream,
10
+ api_key: api_key, api_secret_key: api_secret_key)
10
11
  end
11
12
 
12
13
  def start!(api_key: nil, api_secret_key: nil)
13
14
  Request.send!(api_key_type: :none, method: :post, path: "/api/v1/userDataStream",
14
- security_type: :user_stream, api_key: api_key, api_secret_key: api_secret_key)
15
+ security_type: :user_stream, api_key: api_key, api_secret_key: api_secret_key)[:listenKey]
15
16
  end
16
17
 
17
18
  def stop!(listen_key: nil, api_key: nil, api_secret_key: nil)
@@ -1,5 +1,5 @@
1
1
  module Binance
2
2
  module Api
3
- VERSION = "1.1.2"
3
+ VERSION = "1.2.7"
4
4
  end
5
5
  end
@@ -0,0 +1,105 @@
1
+ module Binance
2
+ class WebSocket < Faye::WebSocket::Client
3
+ class Error < StandardError; end
4
+
5
+ def initialize(on_open: nil, on_close: nil)
6
+ super "wss://stream.binance.com:9443/stream", nil, ping: 180
7
+
8
+ @request_id_inc = 0
9
+ @user_stream_handlers = {}
10
+
11
+ on :open do |event|
12
+ on_open&.call(event)
13
+ end
14
+
15
+ on :message do |event|
16
+ process_data(event.data)
17
+ end
18
+
19
+ on :close do |event|
20
+ on_close&.call(event)
21
+ end
22
+ end
23
+
24
+ # stream name: <symbol>@kline_<interval>
25
+ #
26
+ # {
27
+ # "e": "kline", // Event type
28
+ # "E": 123456789, // Event time
29
+ # "s": "BNBBTC", // Symbol
30
+ # "k": {
31
+ # "t": 123400000, // Kline start time
32
+ # "T": 123460000, // Kline close time
33
+ # "s": "BNBBTC", // Symbol
34
+ # "i": "1m", // Interval
35
+ # "f": 100, // First trade ID
36
+ # "L": 200, // Last trade ID
37
+ # "o": "0.0010", // Open price
38
+ # "c": "0.0020", // Close price
39
+ # "h": "0.0025", // High price
40
+ # "l": "0.0015", // Low price
41
+ # "v": "1000", // Base asset volume
42
+ # "n": 100, // Number of trades
43
+ # "x": false, // Is this kline closed?
44
+ # "q": "1.0000", // Quote asset volume
45
+ # "V": "500", // Taker buy base asset volume
46
+ # "Q": "0.500", // Taker buy quote asset volume
47
+ # "B": "123456" // Ignore
48
+ # }
49
+ # }
50
+ def candlesticks!(symbols, interval, &on_receive)
51
+ symbols_fmt = symbols.is_a?(String) ? [symbols] : symbols
52
+ @candlesticks_handler = on_receive
53
+ subscribe(symbols_fmt.map { |s| "#{s.downcase}@kline_#{interval}" })
54
+ end
55
+
56
+ def user_data_stream!(listen_key, &on_receive)
57
+ @user_stream_handlers[listen_key] = on_receive
58
+ subscribe([listen_key])
59
+ end
60
+
61
+ private
62
+
63
+ def process_data(data)
64
+ json = JSON.parse(data, symbolize_names: true)
65
+ if json[:error]
66
+ raise Error.new("(#{json[:code]}) #{json[:msg]}")
67
+ elsif json.key?(:result)
68
+ # Binance stream connected successfully
69
+ else
70
+ case json[:data][:e]&.to_sym
71
+ when :kline
72
+ @candlesticks_handler&.call(json[:stream], json[:data])
73
+ when :outboundAccountPosition
74
+ when :balanceUpdate
75
+ when :executionReport # order update
76
+ listen_key = json[:stream]
77
+ @user_stream_handlers[listen_key]&.call(listen_key, json[:data])
78
+ end
79
+ end
80
+ end
81
+
82
+ def request_id
83
+ @request_id_inc += 1
84
+ end
85
+
86
+ def subscribe(streams)
87
+ send({
88
+ method: "SUBSCRIBE",
89
+ params: streams,
90
+ id: request_id,
91
+ }.to_json)
92
+ end
93
+
94
+ # Terminating socket connection achieves the same result.
95
+ # If you have a use-case for this, please create a GitHub issue.
96
+ #
97
+ # def unsubscribe(streams)
98
+ # send({
99
+ # method: "UNSUBSCRIBE",
100
+ # params: streams,
101
+ # id: request_id,
102
+ # }.to_json)
103
+ # end
104
+ end
105
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binance-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Peterson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-28 00:00:00.000000000 Z
11
+ date: 2021-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codecov
@@ -95,19 +95,19 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '12.0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: pry
98
+ name: byebug
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.11.3
103
+ version: 11.1.3
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.11.3
110
+ version: 11.1.3
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -123,47 +123,75 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.20.0
125
125
  - !ruby/object:Gem::Dependency
126
- name: activesupport
126
+ name: awrence
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 5.1.0
131
+ version: '1.0'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 5.1.0
138
+ version: '1.0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: awrence
140
+ name: httparty
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '1.0'
145
+ version: '0.15'
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '1.0'
152
+ version: '0.15'
153
153
  - !ruby/object:Gem::Dependency
154
- name: httparty
154
+ name: faye-websocket
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '0.15'
159
+ version: '0.11'
160
160
  type: :runtime
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '0.15'
166
+ version: '0.11'
167
+ - !ruby/object:Gem::Dependency
168
+ name: eventmachine
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.2'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.2'
181
+ - !ruby/object:Gem::Dependency
182
+ name: activesupport
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: 5.1.0
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: 5.1.0
167
195
  description: Ruby wrapper for the Binance API.
168
196
  email:
169
197
  - hello@jakenberg.io
@@ -175,14 +203,17 @@ files:
175
203
  - lib/binance/api.rb
176
204
  - lib/binance/api/account.rb
177
205
  - lib/binance/api/configuration.rb
178
- - lib/binance/api/data_stream.rb
179
206
  - lib/binance/api/error.rb
180
207
  - lib/binance/api/margin.rb
181
208
  - lib/binance/api/margin/account.rb
182
209
  - lib/binance/api/margin/order.rb
210
+ - lib/binance/api/market_stream.rb
183
211
  - lib/binance/api/order.rb
184
212
  - lib/binance/api/request.rb
213
+ - lib/binance/api/trade.rb
214
+ - lib/binance/api/user_data_stream.rb
185
215
  - lib/binance/api/version.rb
216
+ - lib/binance/websocket.rb
186
217
  homepage: https://github.com/jakenberg/binance-ruby
187
218
  licenses:
188
219
  - MIT
@@ -206,5 +237,5 @@ requirements: []
206
237
  rubygems_version: 3.1.6
207
238
  signing_key:
208
239
  specification_version: 4
209
- summary: binance-ruby-1.1.2
240
+ summary: binance-ruby-1.2.7
210
241
  test_files: []