marcel-binance 1.3.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 +7 -0
- data/lib/binance/client/rest/clients.rb +106 -0
- data/lib/binance/client/rest/endpoints.rb +87 -0
- data/lib/binance/client/rest/methods.rb +245 -0
- data/lib/binance/client/rest/sign_request_middleware.rb +31 -0
- data/lib/binance/client/rest/timestamp_request_middleware.rb +34 -0
- data/lib/binance/client/rest.rb +77 -0
- data/lib/binance/client/websocket.rb +430 -0
- data/lib/binance/version.rb +3 -0
- data/lib/binance.rb +3 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 681a6d991592ad3bdb5d8c2e16c600c83d724ee1ec17946a0063a3cd1563f293
|
4
|
+
data.tar.gz: 0d50747b17a57e7cb6bf3210febef89337d60416f29a3be83d174b14aad66527
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f00c3b43942185d5ee9ba7c0e1354644b7b62df1e7894128afce666116e9caf90a0f0a4634a0c0622f8455c8b216481ecf8acf54fa8f905d053baa5a0e1b26f7
|
7
|
+
data.tar.gz: dfb7da75487d4fec9a83258c84e7d72d4ea04d374bcc347f32581cf8d2e9efd4544c7b76bab3798714a707fc69f64f91abfa6b995ce0cec3257e290bce9154ef
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'faraday_middleware'
|
2
|
+
|
3
|
+
module Binance
|
4
|
+
module Client
|
5
|
+
class REST
|
6
|
+
BASE_URL = 'https://api.binance.com'.freeze
|
7
|
+
|
8
|
+
def public_client(adapter)
|
9
|
+
Faraday.new(url: "#{BASE_URL}/api") do |conn|
|
10
|
+
conn.request :json
|
11
|
+
conn.response :json, content_type: /\bjson$/
|
12
|
+
conn.adapter adapter
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def verified_client(api_key, adapter)
|
17
|
+
Faraday.new(url: "#{BASE_URL}/api") do |conn|
|
18
|
+
conn.response :json, content_type: /\bjson$/
|
19
|
+
conn.headers['X-MBX-APIKEY'] = api_key
|
20
|
+
conn.adapter adapter
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def signed_client(api_key, secret_key, adapter)
|
25
|
+
Faraday.new(url: "#{BASE_URL}/api") do |conn|
|
26
|
+
conn.request :json
|
27
|
+
conn.response :json, content_type: /\bjson$/
|
28
|
+
conn.headers['X-MBX-APIKEY'] = api_key
|
29
|
+
conn.use TimestampRequestMiddleware
|
30
|
+
conn.use SignRequestMiddleware, secret_key
|
31
|
+
conn.adapter adapter
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def public_withdraw_client(adapter)
|
36
|
+
Faraday.new(url: "#{BASE_URL}/wapi") do |conn|
|
37
|
+
conn.request :json
|
38
|
+
conn.response :json, content_type: /\bjson$/
|
39
|
+
conn.adapter adapter
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def withdraw_client(api_key, secret_key, adapter)
|
44
|
+
Faraday.new(url: "#{BASE_URL}/wapi") do |conn|
|
45
|
+
conn.request :url_encoded
|
46
|
+
conn.response :json, content_type: /\bjson$/
|
47
|
+
conn.headers['X-MBX-APIKEY'] = api_key
|
48
|
+
conn.use TimestampRequestMiddleware
|
49
|
+
conn.use SignRequestMiddleware, secret_key
|
50
|
+
conn.adapter adapter
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class REST_FUTURE
|
56
|
+
BASE_URL = 'https://fapi.binance.com'.freeze
|
57
|
+
TEST_BASE_URL = 'https://testnet.binancefuture.com'.freeze
|
58
|
+
def public_client(adapter, test_api)
|
59
|
+
Faraday.new(url: "#{(test_api)? TEST_BASE_URL : BASE_URL}/fapi") do |conn|
|
60
|
+
conn.request :json
|
61
|
+
conn.response :json, content_type: /\bjson$/
|
62
|
+
conn.adapter adapter
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def verified_client(api_key, adapter, test_api)
|
67
|
+
Faraday.new(url: "#{(test_api)? TEST_BASE_URL : BASE_URL}/fapi") do |conn|
|
68
|
+
conn.response :json, content_type: /\bjson$/
|
69
|
+
conn.headers['X-MBX-APIKEY'] = api_key
|
70
|
+
conn.adapter adapter
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def signed_client(api_key, secret_key, adapter, test_api)
|
75
|
+
Faraday.new(url: "#{(test_api)? TEST_BASE_URL : BASE_URL}/fapi") do |conn|
|
76
|
+
conn.request :json
|
77
|
+
conn.response :json, content_type: /\bjson$/
|
78
|
+
conn.headers['X-MBX-APIKEY'] = api_key
|
79
|
+
conn.use TimestampRequestMiddleware
|
80
|
+
conn.use SignRequestMiddleware, secret_key
|
81
|
+
conn.adapter adapter
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def public_withdraw_client(adapter, test_api)
|
86
|
+
Faraday.new(url: "#{(test_api)? TEST_BASE_URL : BASE_URL}/wapi") do |conn|
|
87
|
+
conn.request :json
|
88
|
+
conn.response :json, content_type: /\bjson$/
|
89
|
+
conn.adapter adapter
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def withdraw_client(api_key, secret_key, adapter, test_api)
|
94
|
+
Faraday.new(url: "#{(test_api)? TEST_BASE_URL : BASE_URL}/wapi") do |conn|
|
95
|
+
conn.request :url_encoded
|
96
|
+
conn.response :json, content_type: /\bjson$/
|
97
|
+
conn.headers['X-MBX-APIKEY'] = api_key
|
98
|
+
conn.use TimestampRequestMiddleware
|
99
|
+
conn.use SignRequestMiddleware, secret_key
|
100
|
+
conn.adapter adapter
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Binance
|
2
|
+
module Client
|
3
|
+
class REST
|
4
|
+
ENDPOINTS = {
|
5
|
+
# Public API Endpoints
|
6
|
+
ping: 'v1/ping',
|
7
|
+
time: 'v1/time',
|
8
|
+
exchange_info: 'v1/exchangeInfo',
|
9
|
+
depth: 'v1/depth',
|
10
|
+
trades: 'v1/trades',
|
11
|
+
historical_trades: 'v1/historicalTrades',
|
12
|
+
agg_trades: 'v1/aggTrades',
|
13
|
+
klines: 'v1/klines',
|
14
|
+
twenty_four_hour: 'v1/ticker/24hr',
|
15
|
+
price: 'v3/ticker/price',
|
16
|
+
book_ticker: 'v3/ticker/bookTicker',
|
17
|
+
|
18
|
+
# Account API Endpoints
|
19
|
+
order: 'v3/order',
|
20
|
+
test_order: 'v3/order/test',
|
21
|
+
open_orders: 'v3/openOrders',
|
22
|
+
all_orders: 'v3/allOrders',
|
23
|
+
account: 'v3/account',
|
24
|
+
my_trades: 'v3/myTrades',
|
25
|
+
user_data_stream: 'v1/userDataStream',
|
26
|
+
|
27
|
+
# Withdraw API Endpoints
|
28
|
+
balance: 'v1/balance',
|
29
|
+
withdraw: 'v3/withdraw.html',
|
30
|
+
deposit_history: 'v3/depositHistory.html',
|
31
|
+
withdraw_history: 'v3/withdrawHistory.html',
|
32
|
+
deposit_address: 'v3/depositAddress.html',
|
33
|
+
account_status: 'v3/accountStatus.html',
|
34
|
+
system_status: 'v3/systemStatus.html',
|
35
|
+
withdraw_fee: 'v3/withdrawFee.html',
|
36
|
+
dust_log: 'v3/userAssetDribbletLog.html'
|
37
|
+
}.freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
class REST_FUTURE
|
41
|
+
ENDPOINTS = {
|
42
|
+
# Public API Endpoints
|
43
|
+
ping: 'v1/ping',
|
44
|
+
time: 'v1/time',
|
45
|
+
exchange_info: 'v1/exchangeInfo',
|
46
|
+
depth: 'v1/depth',
|
47
|
+
trades: 'v1/trades',
|
48
|
+
historical_trades: 'v1/historicalTrades',
|
49
|
+
agg_trades: 'v1/aggTrades',
|
50
|
+
klines: 'v1/klines',
|
51
|
+
twenty_four_hour: 'v1/ticker/24hr',
|
52
|
+
price: 'v1/ticker/price',
|
53
|
+
book_ticker: 'v1/ticker/bookTicker',
|
54
|
+
|
55
|
+
# Account API Endpoints
|
56
|
+
order: 'v1/order',
|
57
|
+
open_orders: 'v1/openOrders',
|
58
|
+
all_orders: 'v1/allOrders',
|
59
|
+
account: 'v1/account',
|
60
|
+
user_trades: 'v1/userTrades',
|
61
|
+
test_order: 'v1/order/test',
|
62
|
+
user_data_stream: 'v1/userDataStream',
|
63
|
+
withdraw: 'v1/withdraw.html',
|
64
|
+
|
65
|
+
# Withdraw API Endpoints
|
66
|
+
balance: 'v1/balance',
|
67
|
+
funding_rate: 'v1/fundingRate',
|
68
|
+
income: 'v1/income',
|
69
|
+
leverage: 'v1/leverage',
|
70
|
+
listenKey: 'v1/listenKey',
|
71
|
+
position_risk: 'v1/positionRisk',
|
72
|
+
premium_index: 'v1/premiumIndex',
|
73
|
+
|
74
|
+
#not found in Future-API yet
|
75
|
+
my_trades: 'v1/myTrades',
|
76
|
+
deposit_history: 'v1/depositHistory.html',
|
77
|
+
withdraw_history: 'v1/withdrawHistory.html',
|
78
|
+
deposit_address: 'v1/depositAddress.html',
|
79
|
+
account_status: 'v1/accountStatus.html',
|
80
|
+
system_status: 'v1/systemStatus.html',
|
81
|
+
withdraw_fee: 'v1/withdrawFee.html',
|
82
|
+
dust_log: 'v1/userAssetDribbletLog.html'
|
83
|
+
}.freeze
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
module Binance
|
2
|
+
module Client
|
3
|
+
|
4
|
+
class REST
|
5
|
+
METHODS = [
|
6
|
+
# Public API Methods
|
7
|
+
# #ping
|
8
|
+
{ name: :ping, client: :public,
|
9
|
+
action: :get, endpoint: :ping },
|
10
|
+
# #time
|
11
|
+
{ name: :time, client: :public,
|
12
|
+
action: :get, endpoint: :time },
|
13
|
+
# #exchange_info
|
14
|
+
{ name: :exchange_info, client: :public,
|
15
|
+
action: :get, endpoint: :exchange_info },
|
16
|
+
# #depth
|
17
|
+
{ name: :depth, client: :public,
|
18
|
+
action: :get, endpoint: :depth },
|
19
|
+
# #trades
|
20
|
+
{ name: :trades, client: :public,
|
21
|
+
action: :get, endpoint: :trades },
|
22
|
+
# #historical_trades
|
23
|
+
{ name: :historical_trades, client: :verified,
|
24
|
+
action: :get, endpoint: :historical_trades },
|
25
|
+
# #agg_trades
|
26
|
+
{ name: :agg_trades, client: :public,
|
27
|
+
action: :get, endpoint: :agg_trades },
|
28
|
+
# #klines
|
29
|
+
{ name: :klines, client: :public,
|
30
|
+
action: :get, endpoint: :klines },
|
31
|
+
# #twenty_four_hour
|
32
|
+
{ name: :twenty_four_hour, client: :public,
|
33
|
+
action: :get, endpoint: :twenty_four_hour },
|
34
|
+
# #price
|
35
|
+
{ name: :price, client: :public,
|
36
|
+
action: :get, endpoint: :price },
|
37
|
+
# #all_prices
|
38
|
+
{ name: :all_prices, client: :public,
|
39
|
+
action: :get, endpoint: :price },
|
40
|
+
# #book_ticker
|
41
|
+
{ name: :book_ticker, client: :public,
|
42
|
+
action: :get, endpoint: :book_ticker },
|
43
|
+
|
44
|
+
# Account API Methods
|
45
|
+
# #create_order!
|
46
|
+
{ name: :create_order!, client: :signed,
|
47
|
+
action: :post, endpoint: :order },
|
48
|
+
# #create_test_order
|
49
|
+
{ name: :create_test_order, client: :signed,
|
50
|
+
action: :post, endpoint: :test_order },
|
51
|
+
# #query_order
|
52
|
+
{ name: :query_order, client: :signed,
|
53
|
+
action: :get, endpoint: :order },
|
54
|
+
# #cancel_order!
|
55
|
+
{ name: :cancel_order!, client: :signed,
|
56
|
+
action: :delete, endpoint: :order },
|
57
|
+
# #open_orders
|
58
|
+
{ name: :open_orders, client: :signed,
|
59
|
+
action: :get, endpoint: :open_orders },
|
60
|
+
# #all_orders
|
61
|
+
{ name: :all_orders, client: :signed,
|
62
|
+
action: :get, endpoint: :all_orders },
|
63
|
+
# #account_info
|
64
|
+
{ name: :account_info, client: :signed,
|
65
|
+
action: :get, endpoint: :account },
|
66
|
+
# #my_trades
|
67
|
+
{ name: :my_trades, client: :signed,
|
68
|
+
action: :get, endpoint: :my_trades },
|
69
|
+
# #listen_key
|
70
|
+
{ name: :listen_key, client: :verified,
|
71
|
+
action: :post, endpoint: :user_data_stream },
|
72
|
+
# #keep_alive_stream!
|
73
|
+
{ name: :keep_alive_stream!, client: :verified,
|
74
|
+
action: :put, endpoint: :user_data_stream },
|
75
|
+
# #close_stream!
|
76
|
+
{ name: :close_stream!, client: :verified,
|
77
|
+
action: :delete, endpoint: :user_data_stream },
|
78
|
+
|
79
|
+
# #withdraw!
|
80
|
+
{ name: :withdraw!, client: :withdraw,
|
81
|
+
action: :post, endpoint: :withdraw },
|
82
|
+
# #deposit_history
|
83
|
+
{ name: :deposit_history, client: :withdraw,
|
84
|
+
action: :get, endpoint: :deposit_history },
|
85
|
+
# #withdraw_history
|
86
|
+
{ name: :withdraw_history, client: :withdraw,
|
87
|
+
action: :get, endpoint: :withdraw_history },
|
88
|
+
# #deposit_address
|
89
|
+
{ name: :deposit_address, client: :withdraw,
|
90
|
+
action: :get, endpoint: :deposit_address },
|
91
|
+
# #account_status
|
92
|
+
{ name: :account_status, client: :withdraw,
|
93
|
+
action: :get, endpoint: :account_status },
|
94
|
+
# #system_status
|
95
|
+
{ name: :system_status, client: :public_withdraw,
|
96
|
+
action: :get, endpoint: :system_status },
|
97
|
+
# #withdraw_fee
|
98
|
+
{ name: :withdraw_fee, client: :withdraw,
|
99
|
+
action: :get, endpoint: :withdraw_fee },
|
100
|
+
# dust_log
|
101
|
+
{ name: :dust_log, client: :withdraw,
|
102
|
+
action: :get, endpoint: :dust_log }
|
103
|
+
].freeze
|
104
|
+
end
|
105
|
+
|
106
|
+
class REST_FUTURE
|
107
|
+
METHODS = [
|
108
|
+
# Public API Methods
|
109
|
+
# #ping
|
110
|
+
{ name: :ping, client: :public,
|
111
|
+
action: :get, endpoint: :ping },
|
112
|
+
# #time
|
113
|
+
{ name: :time, client: :public,
|
114
|
+
action: :get, endpoint: :time },
|
115
|
+
# #exchange_info
|
116
|
+
{ name: :exchange_info, client: :public,
|
117
|
+
action: :get, endpoint: :exchange_info },
|
118
|
+
# #depth
|
119
|
+
{ name: :depth, client: :public,
|
120
|
+
action: :get, endpoint: :depth },
|
121
|
+
# #trades
|
122
|
+
{ name: :trades, client: :public,
|
123
|
+
action: :get, endpoint: :trades },
|
124
|
+
# #historical_trades
|
125
|
+
{ name: :historical_trades, client: :verified,
|
126
|
+
action: :get, endpoint: :historical_trades },
|
127
|
+
# #agg_trades
|
128
|
+
{ name: :agg_trades, client: :public,
|
129
|
+
action: :get, endpoint: :agg_trades },
|
130
|
+
# #klines
|
131
|
+
{ name: :klines, client: :public,
|
132
|
+
action: :get, endpoint: :klines },
|
133
|
+
# #twenty_four_hour
|
134
|
+
{ name: :twenty_four_hour, client: :public,
|
135
|
+
action: :get, endpoint: :twenty_four_hour },
|
136
|
+
# #price
|
137
|
+
{ name: :price, client: :public,
|
138
|
+
action: :get, endpoint: :price },
|
139
|
+
# #all_prices
|
140
|
+
{ name: :all_prices, client: :public,
|
141
|
+
action: :get, endpoint: :price },
|
142
|
+
# #book_ticker
|
143
|
+
{ name: :book_ticker, client: :public,
|
144
|
+
action: :get, endpoint: :book_ticker },
|
145
|
+
|
146
|
+
# Account API Methods
|
147
|
+
# #create_order!
|
148
|
+
{ name: :create_order!, client: :signed,
|
149
|
+
action: :post, endpoint: :order },
|
150
|
+
# #create_test_order
|
151
|
+
{ name: :create_test_order, client: :signed,
|
152
|
+
action: :post, endpoint: :test_order },
|
153
|
+
# #query_order
|
154
|
+
{ name: :query_order, client: :signed,
|
155
|
+
action: :get, endpoint: :order },
|
156
|
+
# #cancel_order!
|
157
|
+
{ name: :cancel_order!, client: :signed,
|
158
|
+
action: :delete, endpoint: :order },
|
159
|
+
# #cancel_all_open_orders
|
160
|
+
{ name: :cancel_all, client: :signed,
|
161
|
+
action: :delete, endpoint: :all_open_orders },
|
162
|
+
# #cancel_batch_orders
|
163
|
+
{ name: :cancel_orders, client: :signed,
|
164
|
+
action: :delete, endpoint: :batch_orders },
|
165
|
+
# #open_orders
|
166
|
+
{ name: :open_orders, client: :signed,
|
167
|
+
action: :get, endpoint: :open_orders },
|
168
|
+
# #all_orders
|
169
|
+
{ name: :all_orders, client: :signed,
|
170
|
+
action: :get, endpoint: :all_orders },
|
171
|
+
# #account_info
|
172
|
+
{ name: :account_info, client: :signed,
|
173
|
+
action: :get, endpoint: :account },
|
174
|
+
# #user_trades
|
175
|
+
{ name: :user_trades, client: :signed,
|
176
|
+
action: :get, endpoint: :user_trades },
|
177
|
+
# #listen_key
|
178
|
+
{ name: :listen_key, client: :verified,
|
179
|
+
action: :post, endpoint: :user_data_stream },
|
180
|
+
# #keep_alive_stream!
|
181
|
+
{ name: :keep_alive_stream!, client: :verified,
|
182
|
+
action: :put, endpoint: :user_data_stream },
|
183
|
+
# #close_stream!
|
184
|
+
{ name: :close_stream!, client: :verified,
|
185
|
+
action: :delete, endpoint: :user_data_stream },
|
186
|
+
|
187
|
+
# Withdraw API Endpoints
|
188
|
+
# # funding_rate
|
189
|
+
{ name: :funding_rate, client: :signed,
|
190
|
+
action: :get, endpoint: :funding_rate },
|
191
|
+
# # income
|
192
|
+
{ name: :income, client: :signed,
|
193
|
+
action: :get, endpoint: :income },
|
194
|
+
# # leverage
|
195
|
+
{ name: :leverage, client: :signed,
|
196
|
+
action: :post, endpoint: :leverage },
|
197
|
+
# listenKey
|
198
|
+
{ name: :listenKey, client: :signed,
|
199
|
+
action: :post, endpoint: :listenKey },
|
200
|
+
# # listenKey
|
201
|
+
{ name: :getlistenKey, client: :signed,
|
202
|
+
action: :get, endpoint: :listenKey },
|
203
|
+
# # position_risk
|
204
|
+
{ name: :position_risk, client: :signed,
|
205
|
+
action: :get, endpoint: :position_risk },
|
206
|
+
# # premium_index
|
207
|
+
{ name: :premium_index, client: :signed,
|
208
|
+
action: :get, endpoint: :premium_index },
|
209
|
+
# #withdraw!
|
210
|
+
{ name: :withdraw!, client: :withdraw,
|
211
|
+
action: :post, endpoint: :withdraw },
|
212
|
+
# #balance
|
213
|
+
{ name: :balance, client: :signed,
|
214
|
+
action: :get, endpoint: :balance },
|
215
|
+
|
216
|
+
# NOT FOUND IN FUTURE API (yet)
|
217
|
+
# #my_trades
|
218
|
+
{ name: :my_trades, client: :signed,
|
219
|
+
action: :get, endpoint: :my_trades },
|
220
|
+
# #deposit_history
|
221
|
+
{ name: :deposit_history, client: :withdraw,
|
222
|
+
action: :get, endpoint: :deposit_history },
|
223
|
+
# #withdraw_history
|
224
|
+
{ name: :withdraw_history, client: :withdraw,
|
225
|
+
action: :get, endpoint: :withdraw_history },
|
226
|
+
# #deposit_address
|
227
|
+
{ name: :deposit_address, client: :withdraw,
|
228
|
+
action: :get, endpoint: :deposit_address },
|
229
|
+
# #account_status
|
230
|
+
{ name: :account_status, client: :withdraw,
|
231
|
+
action: :get, endpoint: :account_status },
|
232
|
+
# #system_status
|
233
|
+
{ name: :system_status, client: :public_withdraw,
|
234
|
+
action: :get, endpoint: :system_status },
|
235
|
+
# #withdraw_fee
|
236
|
+
{ name: :withdraw_fee, client: :withdraw,
|
237
|
+
action: :get, endpoint: :withdraw_fee },
|
238
|
+
# dust_log
|
239
|
+
{ name: :dust_log, client: :withdraw,
|
240
|
+
action: :get, endpoint: :dust_log }
|
241
|
+
].freeze
|
242
|
+
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Binance
|
2
|
+
module Client
|
3
|
+
class REST
|
4
|
+
# Sign the query string using HMAC(sha-256) and appends to query string
|
5
|
+
SignRequestMiddleware = Struct.new(:app, :secret_key) do
|
6
|
+
def call(env)
|
7
|
+
hash = OpenSSL::HMAC.hexdigest(
|
8
|
+
OpenSSL::Digest.new('sha256'), secret_key, env.url.query
|
9
|
+
)
|
10
|
+
env.url.query = REST.add_query_param(env.url.query, 'signature', hash)
|
11
|
+
|
12
|
+
app.call env
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class REST_FUTURE
|
18
|
+
# Sign the query string using HMAC(sha-256) and appends to query string
|
19
|
+
SignRequestMiddleware = Struct.new(:app, :secret_key) do
|
20
|
+
def call(env)
|
21
|
+
hash = OpenSSL::HMAC.hexdigest(
|
22
|
+
OpenSSL::Digest.new('sha256'), secret_key, env.url.query
|
23
|
+
)
|
24
|
+
env.url.query = REST_FUTURE.add_query_param(env.url.query, 'signature', hash)
|
25
|
+
|
26
|
+
app.call env
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Binance
|
4
|
+
module Client
|
5
|
+
class REST
|
6
|
+
# Generate a timestamp in milliseconds and append to query string
|
7
|
+
TimestampRequestMiddleware = Struct.new(:app) do
|
8
|
+
def call(env)
|
9
|
+
date = DateTime.now
|
10
|
+
date = Time.at(date.to_time.to_f-$diff).to_datetime if !$diff.nil?
|
11
|
+
env.url.query = REST.add_query_param(
|
12
|
+
env.url.query, 'timestamp', date.strftime('%Q')
|
13
|
+
)
|
14
|
+
app.call env
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class REST_FUTURE
|
20
|
+
# Generate a timestamp in milliseconds and append to query string
|
21
|
+
TimestampRequestMiddleware = Struct.new(:app) do
|
22
|
+
def call(env)
|
23
|
+
date = DateTime.now
|
24
|
+
date = Time.at(date.to_time.to_f-$diff).to_datetime if !$diff.nil?
|
25
|
+
env.url.query = REST_FUTURE.add_query_param(
|
26
|
+
env.url.query, 'timestamp', date.strftime('%Q')
|
27
|
+
)
|
28
|
+
app.call env
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
require_relative 'rest/sign_request_middleware'
|
4
|
+
require_relative 'rest/timestamp_request_middleware'
|
5
|
+
require_relative 'rest/clients'
|
6
|
+
require_relative 'rest/endpoints'
|
7
|
+
require_relative 'rest/methods'
|
8
|
+
|
9
|
+
module Binance
|
10
|
+
module Client
|
11
|
+
class REST
|
12
|
+
def initialize(api_key: '', secret_key: '',
|
13
|
+
adapter: Faraday.default_adapter)
|
14
|
+
@clients = {}
|
15
|
+
@clients[:public] = public_client adapter
|
16
|
+
@clients[:verified] = verified_client api_key, adapter
|
17
|
+
@clients[:signed] = signed_client api_key, secret_key, adapter
|
18
|
+
@clients[:withdraw] = withdraw_client api_key, secret_key, adapter
|
19
|
+
@clients[:public_withdraw] = public_withdraw_client adapter
|
20
|
+
end
|
21
|
+
|
22
|
+
METHODS.each do |method|
|
23
|
+
define_method(method[:name]) do |options = {}|
|
24
|
+
response = @clients[method[:client]].send(method[:action]) do |req|
|
25
|
+
req.url ENDPOINTS[method[:endpoint]]
|
26
|
+
req.params.merge! options.map { |k, v| [camelize(k.to_s), v] }.to_h
|
27
|
+
end
|
28
|
+
response.body
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.add_query_param(query, key, value)
|
33
|
+
query = query.to_s
|
34
|
+
query << '&' unless query.empty?
|
35
|
+
query << "#{Faraday::Utils.escape key}=#{Faraday::Utils.escape value}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def camelize(str)
|
39
|
+
str.split('_')
|
40
|
+
.map.with_index { |word, i| i.zero? ? word : word.capitalize }.join
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class REST_FUTURE
|
45
|
+
def initialize(api_key: '', secret_key: '',
|
46
|
+
adapter: Faraday.default_adapter, test_api: false)
|
47
|
+
@clients = {}
|
48
|
+
@clients[:public] = public_client adapter, test_api
|
49
|
+
@clients[:verified] = verified_client api_key, adapter, test_api
|
50
|
+
@clients[:signed] = signed_client api_key, secret_key, adapter, test_api
|
51
|
+
@clients[:withdraw] = withdraw_client api_key, secret_key, adapter, test_api
|
52
|
+
@clients[:public_withdraw] = public_withdraw_client adapter, test_api
|
53
|
+
end
|
54
|
+
|
55
|
+
METHODS.each do |method|
|
56
|
+
define_method(method[:name]) do |options = {}|
|
57
|
+
response = @clients[method[:client]].send(method[:action]) do |req|
|
58
|
+
req.url ENDPOINTS[method[:endpoint]]
|
59
|
+
req.params.merge! options.map { |k, v| [camelize(k.to_s), v] }.to_h
|
60
|
+
end
|
61
|
+
response.body
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.add_query_param(query, key, value)
|
66
|
+
query = query.to_s
|
67
|
+
query << '&' unless query.empty?
|
68
|
+
query << "#{Faraday::Utils.escape key}=#{Faraday::Utils.escape value}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def camelize(str)
|
72
|
+
str.split('_')
|
73
|
+
.map.with_index { |word, i| i.zero? ? word : word.capitalize }.join
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,430 @@
|
|
1
|
+
require 'faye/websocket'
|
2
|
+
|
3
|
+
module Binance
|
4
|
+
module Client
|
5
|
+
# Public: Client with methods mirroring the Binance WebSocket API
|
6
|
+
class WebSocket
|
7
|
+
# Public: String base url for WebSocket client to use
|
8
|
+
BASE_URL = 'wss://stream.binance.com:9443'.freeze
|
9
|
+
|
10
|
+
# Public: Create a single WebSocket stream
|
11
|
+
#
|
12
|
+
# :stream - The Hash used to define the stream
|
13
|
+
# :symbol - The String symbol to listen to
|
14
|
+
# :type - The String type of stream to listen to
|
15
|
+
# :level - The String level to use for the depth stream (optional)
|
16
|
+
# :interval - The String interval to use for the kline stream (optional)
|
17
|
+
#
|
18
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
19
|
+
# the WebSocket client
|
20
|
+
# :open - The Proc called when a stream is opened (optional)
|
21
|
+
# :message - The Proc called when a stream receives a message
|
22
|
+
# :error - The Proc called when a stream receives an error (optional)
|
23
|
+
# :close - The Proc called when a stream is closed (optional)
|
24
|
+
def single(stream:, methods:)
|
25
|
+
create_stream("#{BASE_URL}/ws/#{stream_url(stream)}",
|
26
|
+
methods: methods)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Create multiple WebSocket streams
|
30
|
+
#
|
31
|
+
# :streams - The Array of Hashes used to define the stream. Each Hash can
|
32
|
+
# have the following keys:
|
33
|
+
# :symbol - The String symbol the stream will listen to
|
34
|
+
# :type - The String type of stream to listen to
|
35
|
+
# :level - The String level to use for the depth stream (optional)
|
36
|
+
# :interval - The String interval to use for the kline stream (optional)
|
37
|
+
#
|
38
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
39
|
+
# the WebSocket client
|
40
|
+
# :open - The Proc called when a stream is opened (optional)
|
41
|
+
# :message - The Proc called when a stream receives a message
|
42
|
+
# :error - The Proc called when a stream receives an error (optional)
|
43
|
+
# :close - The Proc called when a stream is closed (optional)
|
44
|
+
def multi(streams:, methods:)
|
45
|
+
names = streams.map { |stream| stream_url(stream) }
|
46
|
+
create_stream("#{BASE_URL}/stream?streams=#{names.join('/')}",
|
47
|
+
methods: methods)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Create an Aggregate Trade stream
|
51
|
+
#
|
52
|
+
# :symbol - The String symbol the stream will listen to
|
53
|
+
#
|
54
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
55
|
+
# the WebSocket client
|
56
|
+
# :open - The Proc called when a stream is opened (optional)
|
57
|
+
# :message - The Proc called when a stream receives a message
|
58
|
+
# :error - The Proc called when a stream receives an error (optional)
|
59
|
+
# :close - The Proc called when a stream is closed (optional)
|
60
|
+
def agg_trade(symbol:, methods:)
|
61
|
+
single stream: { symbol: symbol, type: 'aggTrade' }, methods: methods
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Create a Trade stream
|
65
|
+
#
|
66
|
+
# :symbol - The String symbol the stream will listen to
|
67
|
+
#
|
68
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
69
|
+
# the WebSocket client
|
70
|
+
# :open - The Proc called when a stream is opened (optional)
|
71
|
+
# :message - The Proc called when a stream receives a message
|
72
|
+
# :error - The Proc called when a stream receives an error (optional)
|
73
|
+
# :close - The Proc called when a stream is closed (optional)
|
74
|
+
def trade(symbol:, methods:)
|
75
|
+
single stream: { symbol: symbol, type: 'trade' }, methods: methods
|
76
|
+
end
|
77
|
+
|
78
|
+
# Public: Create an Kline stream
|
79
|
+
#
|
80
|
+
# :symbol - The String symbol the stream will listen to
|
81
|
+
#
|
82
|
+
# :interval - The String interval the stream will update with. The
|
83
|
+
# intervals that may be used can be found in the Binance API
|
84
|
+
# docs.
|
85
|
+
#
|
86
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
87
|
+
# the WebSocket client
|
88
|
+
# :open - The Proc called when a stream is opened (optional)
|
89
|
+
# :message - The Proc called when a stream receives a message
|
90
|
+
# :error - The Proc called when a stream receives an error (optional)
|
91
|
+
# :close - The Proc called when a stream is closed (optional)
|
92
|
+
def kline(symbol:, interval:, methods:)
|
93
|
+
single stream: { symbol: symbol, type: 'kline', interval: interval },
|
94
|
+
methods: methods
|
95
|
+
end
|
96
|
+
|
97
|
+
# Public: Create a Ticker stream
|
98
|
+
#
|
99
|
+
# :symbol - The String symbol the stream will listen to
|
100
|
+
#
|
101
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
102
|
+
# the WebSocket client
|
103
|
+
# :open - The Proc called when a stream is opened (optional)
|
104
|
+
# :message - The Proc called when a stream receives a message
|
105
|
+
# :error - The Proc called when a stream receives an error (optional)
|
106
|
+
# :close - The Proc called when a stream is closed (optional)
|
107
|
+
def ticker(symbol:, methods:)
|
108
|
+
single stream: { symbol: symbol, type: 'ticker' }, methods: methods
|
109
|
+
end
|
110
|
+
|
111
|
+
# Public: Create a Ticker stream for all symbols
|
112
|
+
#
|
113
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
114
|
+
# the WebSocket client
|
115
|
+
# :open - The Proc called when a stream is opened (optional)
|
116
|
+
# :message - The Proc called when a stream receives a message
|
117
|
+
# :error - The Proc called when a stream receives an error (optional)
|
118
|
+
# :close - The Proc called when a stream is closed (optional)
|
119
|
+
def all_market_ticker(methods:)
|
120
|
+
single stream: { symbol: '!ticker', type: 'arr' }, methods: methods
|
121
|
+
end
|
122
|
+
|
123
|
+
# Public: Create an Partial Book Depth stream
|
124
|
+
#
|
125
|
+
# :symbol - The String symbol the stream will listen to
|
126
|
+
#
|
127
|
+
# :level - The String interval the stream will update with. The intervals
|
128
|
+
# that may be used can be found in the Binance API docs.
|
129
|
+
#
|
130
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
131
|
+
# the WebSocket client
|
132
|
+
# :open - The Proc called when a stream is opened (optional)
|
133
|
+
# :message - The Proc called when a stream receives a message
|
134
|
+
# :error - The Proc called when a stream receives an error (optional)
|
135
|
+
# :close - The Proc called when a stream is closed (optional)
|
136
|
+
def partial_book_depth(symbol:, level:, methods:)
|
137
|
+
single stream: { symbol: symbol, type: 'depth', level: level },
|
138
|
+
methods: methods
|
139
|
+
end
|
140
|
+
|
141
|
+
# Public: Create a Diff Depth stream
|
142
|
+
#
|
143
|
+
# :symbol - The String symbol the stream will listen to
|
144
|
+
#
|
145
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
146
|
+
# the WebSocket client
|
147
|
+
# :open - The Proc called when a stream is opened (optional)
|
148
|
+
# :message - The Proc called when a stream receives a message
|
149
|
+
# :error - The Proc called when a stream receives an error (optional)
|
150
|
+
# :close - The Proc called when a stream is closed (optional)
|
151
|
+
def diff_depth(symbol:, methods:)
|
152
|
+
single stream: { symbol: symbol, type: 'depth' }, methods: methods
|
153
|
+
end
|
154
|
+
|
155
|
+
# Public: Create a User Data stream
|
156
|
+
#
|
157
|
+
# listen_key - The String key the stream will listen to, attained by
|
158
|
+
# interacting with the REST API userDataStream endpoint
|
159
|
+
#
|
160
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
161
|
+
# the WebSocket client
|
162
|
+
# :open - The Proc called when a stream is opened (optional)
|
163
|
+
# :message - The Proc called when a stream receives a message
|
164
|
+
# :error - The Proc called when a stream receives an error (optional)
|
165
|
+
# :close - The Proc called when a stream is closed (optional)
|
166
|
+
def user_data(listen_key:, methods:)
|
167
|
+
create_stream "#{BASE_URL}/ws/#{listen_key}", methods: methods
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
# Internal: Create a valid URL for a WebSocket to use
|
173
|
+
#
|
174
|
+
# :symbol - The String symbol to listen to
|
175
|
+
# :type - The String type the stream will listen to
|
176
|
+
# :level - The String level to use for the depth stream (optional)
|
177
|
+
# :interval - The String interval to use for the kline stream (optional)
|
178
|
+
def stream_url(symbol:, type:, level: '', interval: '')
|
179
|
+
"#{symbol.downcase}@#{type}".tap do |url|
|
180
|
+
url << level
|
181
|
+
url << "_#{interval}" unless interval.empty?
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Internal: Initialize and return a Faye::WebSocket::Client
|
186
|
+
#
|
187
|
+
# url - The String url that the WebSocket should try to connect to
|
188
|
+
#
|
189
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
190
|
+
# the WebSocket client
|
191
|
+
# :open - The Proc called when a stream is opened (optional)
|
192
|
+
# :message - The Proc called when a stream receives a message
|
193
|
+
# :error - The Proc called when a stream receives an error (optional)
|
194
|
+
# :close - The Proc called when a stream is closed (optional)
|
195
|
+
def create_stream(url, methods:)
|
196
|
+
Faye::WebSocket::Client.new(url)
|
197
|
+
.tap { |ws| attach_methods(ws, methods) }
|
198
|
+
end
|
199
|
+
|
200
|
+
# Internal: Iterate through methods passed and add them to the WebSocket
|
201
|
+
#
|
202
|
+
# websocket - The Faye::WebSocket::Client to apply methods to
|
203
|
+
#
|
204
|
+
# methods - The Hash which contains the event handler methods to pass to
|
205
|
+
# the WebSocket client
|
206
|
+
# :open - The Proc called when a stream is opened (optional)
|
207
|
+
# :message - The Proc called when a stream receives a message
|
208
|
+
# :error - The Proc called when a stream receives an error (optional)
|
209
|
+
# :close - The Proc called when a stream is closed (optional)
|
210
|
+
def attach_methods(websocket, methods)
|
211
|
+
methods.each_pair do |key, method|
|
212
|
+
websocket.on(key) { |event| method.call(event) }
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class WebSocketFuture
|
218
|
+
# Public: String base url for WebSocket client to use
|
219
|
+
BASE_URL = 'wss://fstream.binance.com'.freeze
|
220
|
+
|
221
|
+
# Public: Create a single WebSocket stream
|
222
|
+
#
|
223
|
+
# :stream - The Hash used to define the stream
|
224
|
+
# :symbol - The String symbol to listen to
|
225
|
+
# :type - The String type of stream to listen to
|
226
|
+
# :level - The String level to use for the depth stream (optional)
|
227
|
+
# :interval - The String interval to use for the kline stream (optional)
|
228
|
+
#
|
229
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
230
|
+
# the WebSocket client
|
231
|
+
# :open - The Proc called when a stream is opened (optional)
|
232
|
+
# :message - The Proc called when a stream receives a message
|
233
|
+
# :error - The Proc called when a stream receives an error (optional)
|
234
|
+
# :close - The Proc called when a stream is closed (optional)
|
235
|
+
def single(stream:, methods:)
|
236
|
+
create_stream("#{BASE_URL}/ws/#{stream_url(stream)}",
|
237
|
+
methods: methods)
|
238
|
+
end
|
239
|
+
|
240
|
+
# Public: Create multiple WebSocket streams
|
241
|
+
#
|
242
|
+
# :streams - The Array of Hashes used to define the stream. Each Hash can
|
243
|
+
# have the following keys:
|
244
|
+
# :symbol - The String symbol the stream will listen to
|
245
|
+
# :type - The String type of stream to listen to
|
246
|
+
# :level - The String level to use for the depth stream (optional)
|
247
|
+
# :interval - The String interval to use for the kline stream (optional)
|
248
|
+
#
|
249
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
250
|
+
# the WebSocket client
|
251
|
+
# :open - The Proc called when a stream is opened (optional)
|
252
|
+
# :message - The Proc called when a stream receives a message
|
253
|
+
# :error - The Proc called when a stream receives an error (optional)
|
254
|
+
# :close - The Proc called when a stream is closed (optional)
|
255
|
+
def multi(streams:, methods:)
|
256
|
+
names = streams.map { |stream| stream_url(stream) }
|
257
|
+
create_stream("#{BASE_URL}/stream?streams=#{names.join('/')}",
|
258
|
+
methods: methods)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Public: Create an Aggregate Trade stream
|
262
|
+
#
|
263
|
+
# :symbol - The String symbol the stream will listen to
|
264
|
+
#
|
265
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
266
|
+
# the WebSocket client
|
267
|
+
# :open - The Proc called when a stream is opened (optional)
|
268
|
+
# :message - The Proc called when a stream receives a message
|
269
|
+
# :error - The Proc called when a stream receives an error (optional)
|
270
|
+
# :close - The Proc called when a stream is closed (optional)
|
271
|
+
def agg_trade(symbol:, methods:)
|
272
|
+
single stream: { symbol: symbol, type: 'aggTrade' }, methods: methods
|
273
|
+
end
|
274
|
+
|
275
|
+
# Public: Create a Trade stream
|
276
|
+
#
|
277
|
+
# :symbol - The String symbol the stream will listen to
|
278
|
+
#
|
279
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
280
|
+
# the WebSocket client
|
281
|
+
# :open - The Proc called when a stream is opened (optional)
|
282
|
+
# :message - The Proc called when a stream receives a message
|
283
|
+
# :error - The Proc called when a stream receives an error (optional)
|
284
|
+
# :close - The Proc called when a stream is closed (optional)
|
285
|
+
def trade(symbol:, methods:)
|
286
|
+
single stream: { symbol: symbol, type: 'trade' }, methods: methods
|
287
|
+
end
|
288
|
+
|
289
|
+
# Public: Create an Kline stream
|
290
|
+
#
|
291
|
+
# :symbol - The String symbol the stream will listen to
|
292
|
+
#
|
293
|
+
# :interval - The String interval the stream will update with. The
|
294
|
+
# intervals that may be used can be found in the Binance API
|
295
|
+
# docs.
|
296
|
+
#
|
297
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
298
|
+
# the WebSocket client
|
299
|
+
# :open - The Proc called when a stream is opened (optional)
|
300
|
+
# :message - The Proc called when a stream receives a message
|
301
|
+
# :error - The Proc called when a stream receives an error (optional)
|
302
|
+
# :close - The Proc called when a stream is closed (optional)
|
303
|
+
def kline(symbol:, interval:, methods:)
|
304
|
+
single stream: { symbol: symbol, type: 'kline', interval: interval },
|
305
|
+
methods: methods
|
306
|
+
end
|
307
|
+
|
308
|
+
# Public: Create a Ticker stream
|
309
|
+
#
|
310
|
+
# :symbol - The String symbol the stream will listen to
|
311
|
+
#
|
312
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
313
|
+
# the WebSocket client
|
314
|
+
# :open - The Proc called when a stream is opened (optional)
|
315
|
+
# :message - The Proc called when a stream receives a message
|
316
|
+
# :error - The Proc called when a stream receives an error (optional)
|
317
|
+
# :close - The Proc called when a stream is closed (optional)
|
318
|
+
def ticker(symbol:, methods:)
|
319
|
+
single stream: { symbol: symbol, type: 'ticker' }, methods: methods
|
320
|
+
end
|
321
|
+
|
322
|
+
# Public: Create a Ticker stream for all symbols
|
323
|
+
#
|
324
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
325
|
+
# the WebSocket client
|
326
|
+
# :open - The Proc called when a stream is opened (optional)
|
327
|
+
# :message - The Proc called when a stream receives a message
|
328
|
+
# :error - The Proc called when a stream receives an error (optional)
|
329
|
+
# :close - The Proc called when a stream is closed (optional)
|
330
|
+
def all_market_ticker(methods:)
|
331
|
+
single stream: { symbol: '!ticker', type: 'arr' }, methods: methods
|
332
|
+
end
|
333
|
+
|
334
|
+
# Public: Create an Partial Book Depth stream
|
335
|
+
#
|
336
|
+
# :symbol - The String symbol the stream will listen to
|
337
|
+
#
|
338
|
+
# :level - The String interval the stream will update with. The intervals
|
339
|
+
# that may be used can be found in the Binance API docs.
|
340
|
+
#
|
341
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
342
|
+
# the WebSocket client
|
343
|
+
# :open - The Proc called when a stream is opened (optional)
|
344
|
+
# :message - The Proc called when a stream receives a message
|
345
|
+
# :error - The Proc called when a stream receives an error (optional)
|
346
|
+
# :close - The Proc called when a stream is closed (optional)
|
347
|
+
def partial_book_depth(symbol:, level:, methods:)
|
348
|
+
single stream: { symbol: symbol, type: 'depth', level: level },
|
349
|
+
methods: methods
|
350
|
+
end
|
351
|
+
|
352
|
+
# Public: Create a Diff Depth stream
|
353
|
+
#
|
354
|
+
# :symbol - The String symbol the stream will listen to
|
355
|
+
#
|
356
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
357
|
+
# the WebSocket client
|
358
|
+
# :open - The Proc called when a stream is opened (optional)
|
359
|
+
# :message - The Proc called when a stream receives a message
|
360
|
+
# :error - The Proc called when a stream receives an error (optional)
|
361
|
+
# :close - The Proc called when a stream is closed (optional)
|
362
|
+
def diff_depth(symbol:, methods:)
|
363
|
+
single stream: { symbol: symbol, type: 'depth' }, methods: methods
|
364
|
+
end
|
365
|
+
|
366
|
+
# Public: Create a User Data stream
|
367
|
+
#
|
368
|
+
# listen_key - The String key the stream will listen to, attained by
|
369
|
+
# interacting with the REST API userDataStream endpoint
|
370
|
+
#
|
371
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
372
|
+
# the WebSocket client
|
373
|
+
# :open - The Proc called when a stream is opened (optional)
|
374
|
+
# :message - The Proc called when a stream receives a message
|
375
|
+
# :error - The Proc called when a stream receives an error (optional)
|
376
|
+
# :close - The Proc called when a stream is closed (optional)
|
377
|
+
def user_data(listen_key:, methods:)
|
378
|
+
create_stream "#{BASE_URL}/ws/#{listen_key}", methods: methods
|
379
|
+
end
|
380
|
+
|
381
|
+
private
|
382
|
+
|
383
|
+
# Internal: Create a valid URL for a WebSocket to use
|
384
|
+
#
|
385
|
+
# :symbol - The String symbol to listen to
|
386
|
+
# :type - The String type the stream will listen to
|
387
|
+
# :level - The String level to use for the depth stream (optional)
|
388
|
+
# :interval - The String interval to use for the kline stream (optional)
|
389
|
+
def stream_url(symbol:, type:, level: '', interval: '')
|
390
|
+
"#{symbol.downcase}@#{type}".tap do |url|
|
391
|
+
url << level
|
392
|
+
url << "_#{interval}" unless interval.empty?
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
# Internal: Initialize and return a Faye::WebSocket::Client
|
397
|
+
#
|
398
|
+
# url - The String url that the WebSocket should try to connect to
|
399
|
+
#
|
400
|
+
# :methods - The Hash which contains the event handler methods to pass to
|
401
|
+
# the WebSocket client
|
402
|
+
# :open - The Proc called when a stream is opened (optional)
|
403
|
+
# :message - The Proc called when a stream receives a message
|
404
|
+
# :error - The Proc called when a stream receives an error (optional)
|
405
|
+
# :close - The Proc called when a stream is closed (optional)
|
406
|
+
def create_stream(url, methods:)
|
407
|
+
Faye::WebSocket::Client.new(url)
|
408
|
+
.tap { |ws| attach_methods(ws, methods) }
|
409
|
+
end
|
410
|
+
|
411
|
+
# Internal: Iterate through methods passed and add them to the WebSocket
|
412
|
+
#
|
413
|
+
# websocket - The Faye::WebSocket::Client to apply methods to
|
414
|
+
#
|
415
|
+
# methods - The Hash which contains the event handler methods to pass to
|
416
|
+
# the WebSocket client
|
417
|
+
# :open - The Proc called when a stream is opened (optional)
|
418
|
+
# :message - The Proc called when a stream receives a message
|
419
|
+
# :error - The Proc called when a stream receives an error (optional)
|
420
|
+
# :close - The Proc called when a stream is closed (optional)
|
421
|
+
def attach_methods(websocket, methods)
|
422
|
+
methods.each_pair do |key, method|
|
423
|
+
websocket.on(key) { |event| method.call(event) }
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
data/lib/binance.rb
ADDED
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: marcel-binance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marcel Bonnet
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.12'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday_middleware
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.12'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: faye-websocket
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.10'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.10'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- marcel.social@protonmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- lib/binance.rb
|
105
|
+
- lib/binance/client/rest.rb
|
106
|
+
- lib/binance/client/rest/clients.rb
|
107
|
+
- lib/binance/client/rest/endpoints.rb
|
108
|
+
- lib/binance/client/rest/methods.rb
|
109
|
+
- lib/binance/client/rest/sign_request_middleware.rb
|
110
|
+
- lib/binance/client/rest/timestamp_request_middleware.rb
|
111
|
+
- lib/binance/client/websocket.rb
|
112
|
+
- lib/binance/version.rb
|
113
|
+
homepage: https://github.com/marcelbonnet/binance
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubygems_version: 3.1.2
|
133
|
+
signing_key:
|
134
|
+
specification_version: 4
|
135
|
+
summary: API Wrapper for the Binance cryptocurrency exchange.
|
136
|
+
test_files: []
|