binance 0.2.0 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e8027ac747e3eb75ffc8a423995838465231899
4
- data.tar.gz: 7ef223ce562fe69837f2ee6538f00af35a4358cf
3
+ metadata.gz: a44f0ee9e6501f2e0cd830429766dc93e53d24e3
4
+ data.tar.gz: d71bb3d006b04582e8b3bbe0c63ae1b2e178781b
5
5
  SHA512:
6
- metadata.gz: cf06724334d5d49f968c2f9658ea506689f390e89fc175fae7bf074271ada8b09c328d92c8588c0c5cba02e05000bf15d032efa2d94780675f076e2c7bdf27df
7
- data.tar.gz: 6678caae06e9e9ebd40c162c003deacf313a99d52d493db2bf49f5d861f106795a1f56fff2a66fa28c2ce0e9ce3b32ff586fd9e4ac8460321b50989800172327
6
+ metadata.gz: 953a41c328bb44d5af13b0b21bacd246409285e77e2d5da345cc2d786c4abe3bceaa197eecd91e1821944e75bc9023301669e40763869fe5f51ccf58181d429d
7
+ data.tar.gz: 6caf04faa96a0d4b20d12d6ef0135b7ef93c6ad6ba70be0bd88bd3a459e6e0c3193fbf3ae1872af5a0f07193848168abda9edae3f52d8505065584ff446fb9ea
data/bin/console CHANGED
File without changes
data/bin/setup CHANGED
File without changes
data/lib/binance.rb CHANGED
@@ -1,3 +1,4 @@
1
1
 
2
2
  require 'binance/version'
3
3
  require 'binance/client/rest'
4
+ require 'binance/client/websocket'
@@ -1,49 +1,78 @@
1
-
2
- require 'faraday'
3
- require_relative 'rest/api_endpoints'
4
- require_relative 'rest/public_api'
5
- require_relative 'rest/account_api'
6
- require_relative 'rest/withdraw_api'
7
-
8
- module Binance
9
- module Client
10
- # Provides low level methods for Binance APIs via their REST interface
11
- class REST
12
- BASE_URL = 'https://www.binance.com'.freeze
13
-
14
- # Gets populated by the different APIs that get extended by the instances
15
- @api = {}
16
-
17
- class << self
18
- attr_accessor :api
19
- end
20
-
21
- attr_reader :api_key, :secret_key
22
-
23
- def initialize(api_key: '', secret_key: '')
24
- @api_key = api_key
25
- @secret_key = secret_key
26
-
27
- extend Public_API
28
- extend Account_API
29
- extend Withdraw_API
30
- end
31
-
32
- def request(api, method, endpoint, options = {})
33
- conn = REST.api[api].call
34
- response = conn.send(method) do |req|
35
- req.url API_ENDPOINTS[endpoint]
36
- req.params.merge! options
37
- end
38
-
39
- response.body
40
- end
41
-
42
- def self.add_query_param(query, key, value)
43
- query = query.to_s
44
- query << '&' unless query.empty?
45
- query << "#{Faraday::Utils.escape key}=#{Faraday::Utils.escape value}"
46
- end
47
- end
48
- end
49
- end
1
+
2
+ require 'faraday'
3
+ require_relative 'rest/api_endpoints'
4
+ require_relative 'rest/public_api'
5
+ require_relative 'rest/account_api'
6
+ require_relative 'rest/withdraw_api'
7
+
8
+ module Binance
9
+ module Client
10
+ # Public: Client with methods mirroring the Binance REST APIs
11
+ class REST
12
+ # Public: String base url for REST client to use
13
+ BASE_URL = 'https://www.binance.com'.freeze
14
+
15
+ # Gets populated by the different APIs that get extended by the instances
16
+ @api = {}
17
+
18
+ class << self
19
+ attr_accessor :api
20
+ end
21
+
22
+ attr_reader :api_key, :secret_key, :adapter
23
+
24
+ # Public: Initialize a REST Client
25
+ #
26
+ # :api_key - The String API key to authenticate (Default = '')
27
+ #
28
+ # :secret_key - The String secret key to authenticate (Default = '')
29
+ #
30
+ # :adapter - The Faraday::Adapter to be used for the client
31
+ def initialize(api_key: '', secret_key: '',
32
+ adapter: Faraday.default_adapter)
33
+ @api_key = api_key
34
+ @secret_key = secret_key
35
+ @adapter = adapter
36
+
37
+ extend Public_API
38
+ extend Account_API
39
+ extend Withdraw_API
40
+ end
41
+
42
+ private
43
+
44
+ # Internal: Create a request that hits one of the REST APIs
45
+ #
46
+ # qpi - The Symbol that represents which API to use
47
+ #
48
+ # method - The Symbol that represents which HTTP method to use
49
+ #
50
+ # endpoint - The String that represents which API endpoint to request from
51
+ #
52
+ # options - The Hash which hosts various REST query params. (Default = {})
53
+ # Each endpoint will have their own required and optional params.
54
+ def request(api, method, endpoint, options = {})
55
+ conn = REST.api[api].call
56
+ response = conn.send(method) do |req|
57
+ req.url API_ENDPOINTS[endpoint]
58
+ req.params.merge! options
59
+ end
60
+
61
+ response.body
62
+ end
63
+
64
+ # Internal: Append key-value pair to REST query string
65
+ #
66
+ # query - The String of the existing request query url
67
+ #
68
+ # key - The String that represents the param type
69
+ #
70
+ # value - The String that represents the param value
71
+ def self.add_query_param(query, key, value)
72
+ query = query.to_s
73
+ query << '&' unless query.empty?
74
+ query << "#{Faraday::Utils.escape key}=#{Faraday::Utils.escape value}"
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,59 +1,161 @@
1
-
2
- require 'faraday'
3
- require 'faraday_middleware'
4
- require_relative 'sign_request_middleware'
5
- require_relative 'timestamp_request_middleware'
6
-
7
- module Binance
8
- module Client
9
- class REST
10
- # API endpoints that require a timestamp and signature
11
- module Account_API
12
- def self.extended(base)
13
- REST.api[:account] = lambda do
14
- Faraday.new(url: "#{BASE_URL}/api") do |conn|
15
- conn.request :json
16
- conn.response :json, content_type: /\bjson$/
17
- conn.headers['X-MBX-APIKEY'] = base.api_key
18
- conn.use TimestampRequestMiddleware
19
- conn.use SignRequestMiddleware, base.secret_key
20
- conn.adapter Faraday.default_adapter
21
- end
22
- end
23
- end
24
-
25
- def create_order(options)
26
- request :account, :post, 'order', options
27
- end
28
-
29
- def create_test_order(options)
30
- request :account, :post, 'order/test', options
31
- end
32
-
33
- def query_order(options)
34
- request :account, :get, 'order', options
35
- end
36
-
37
- def cancel_order(options)
38
- request :account, :delete, 'order', options
39
- end
40
-
41
- def open_orders(options)
42
- request :account, :get, 'openOrders', options
43
- end
44
-
45
- def all_orders(options)
46
- request :account, :get, 'allOrders', options
47
- end
48
-
49
- def account_info(options = {})
50
- request :account, :get, 'account', options
51
- end
52
-
53
- def account_trade_list(options)
54
- request :account, :get, 'myTrades', options
55
- end
56
- end
57
- end
58
- end
1
+
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+ require_relative 'sign_request_middleware'
5
+ require_relative 'timestamp_request_middleware'
6
+
7
+ module Binance
8
+ module Client
9
+ class REST
10
+ # Public: A module containing all of the Account API endpoints
11
+ module Account_API
12
+ # Internal: Create Lambda that returns a new Faraday client instance
13
+ # and add it to the REST class instance variable @api. This is called
14
+ # while a new instance of the REST class is created.
15
+ #
16
+ # base - The base class that is being extended into
17
+ def self.extended(base)
18
+ REST.api[:account] = lambda do
19
+ Faraday.new(url: "#{BASE_URL}/api") do |conn|
20
+ conn.request :json
21
+ conn.response :json, content_type: /\bjson$/
22
+ conn.headers['X-MBX-APIKEY'] = base.api_key
23
+ conn.use TimestampRequestMiddleware
24
+ conn.use SignRequestMiddleware, base.secret_key
25
+ conn.adapter base.adapter
26
+ end
27
+ end
28
+ end
29
+
30
+ # Public: Create a new order on the specified symbol for the
31
+ # authenticated account
32
+ #
33
+ # options - The Hash which hosts various REST query params
34
+ # :symbol - The String of which trading pair to create the
35
+ # order on.
36
+ # :side - The String determining which side to create the
37
+ # order on.
38
+ # :type - The String determining what type of order it is.
39
+ # :timeInForce - The String determining what the time in force is
40
+ # (optional).
41
+ # :quantity - The String determining the amount of assets to
42
+ # purchase.
43
+ # :price - The String determining what price to purchase at
44
+ # (optional).
45
+ # :newClientOrderId - The String which uniquely identifies this order
46
+ # (optional).
47
+ # :stopPrice - The String determining which price to stop at
48
+ # (optional).
49
+ # :icebergQty - The String determining the amount of assets to
50
+ # show on the order book (optional).
51
+ # :newOrderRespType - The String which sets the type of response to
52
+ # receive (optional).
53
+ # :recvWindow - The Number of how long a request is valid for
54
+ # in milliseconds (optional).
55
+ #
56
+ # Returns a Hash of the request response
57
+ def create_order(options)
58
+ request :account, :post, 'order', options
59
+ end
60
+
61
+ def create_test_order(options)
62
+ request :account, :post, 'order/test', options
63
+ end
64
+
65
+ # Public: Query an orders status on the specified symbol for the
66
+ # authenticated account. One must send either an :orderId or
67
+ # :origOrderId, but not both.
68
+ #
69
+ # options - The Hash which hosts various REST query params
70
+ # :symbol - The String of which trading pair to query from
71
+ # (optional).
72
+ # :orderId - The String determining which order to query
73
+ # (optional).
74
+ # :origClientOrderId - The String determining which order to cancel
75
+ # (optional).
76
+ # :recvWindow - The Number of how long a request is valid for
77
+ # in milliseconds (optional).
78
+ #
79
+ # Returns a Hash of the request response
80
+ def query_order(options)
81
+ request :account, :get, 'order', options
82
+ end
83
+
84
+ # Public: Cancel the order specified for the authenticated account.
85
+ # One must send either an :orderId or :origOrderId, but not both.
86
+ #
87
+ # options - The Hash which hosts various REST query params
88
+ # :symbol - The String of which trading pair to delete from
89
+ # (optional).
90
+ # :orderId - The String determining which order to cancel
91
+ # (optional).
92
+ # :origClientOrderId - The String determining which order to cancel
93
+ # (optional).
94
+ # :newClientOrderId - The String used in uniquely identifying the
95
+ # cancel order (optional).
96
+ # :recvWindow - The Number of how long a request is valid for
97
+ # in milliseconds (optional).
98
+ #
99
+ # Returns a Hash with the request response
100
+ def cancel_order(options)
101
+ request :account, :delete, 'order', options
102
+ end
103
+
104
+ # Public: Retrieve open orders for the authenticated account
105
+ #
106
+ # options - The Hash which hosts various REST query params
107
+ # :symbol - The String of which trading pair to retrieve
108
+ # (optional).
109
+ # :recvWindow - The Number of how long a request is valid for in
110
+ # milliseconds (optional).
111
+ #
112
+ # Returns a Hash with the request response
113
+ def open_orders(options)
114
+ request :account, :get, 'openOrders', options
115
+ end
116
+
117
+ # Public: Retrieve all orders of the specified symbol for the
118
+ # authenticated account
119
+ #
120
+ # options - The Hash which hosts various REST query params
121
+ # :symbol - The String of which trading pair to retrieve.
122
+ # :orderId - The String determining which order to start the data
123
+ # from (optional).
124
+ # :limit - The Number of how many trades to request (optional).
125
+ # :recvWindow - The Number of how long a request is valid for in
126
+ # milliseconds (optional).
127
+ #
128
+ # Returns a Hash with the request response
129
+ def all_orders(options)
130
+ request :account, :get, 'allOrders', options
131
+ end
132
+
133
+ # Public: Retrieve account information for the authenticated account
134
+ #
135
+ # options - The Hash which hosts various REST query params
136
+ # :recvWindow - The Number of how long a request is valid for in
137
+ # milliseconds (optional).
138
+ #
139
+ # Returns a Hash with the request response
140
+ def account_info(options = {})
141
+ request :account, :get, 'account', options
142
+ end
143
+
144
+ # Public: Retrieve trade data of the specified symbol for the
145
+ # authenticated account
146
+ #
147
+ # options - The Hash which hosts various REST query params
148
+ # :symbol - The String of which trading pair to retrieve.
149
+ # :limit - The Number of how many trades to request (optional).
150
+ # :fromId - The String of which trade ID to fetch from (optional).
151
+ # :recvWindow - The Number of how long a request is valid for in
152
+ # milliseconds (optional).
153
+ #
154
+ # Returns a Hash with the request response
155
+ def account_trade_list(options)
156
+ request :account, :get, 'myTrades', options
157
+ end
158
+ end
159
+ end
160
+ end
59
161
  end
@@ -1,36 +1,37 @@
1
-
2
- module Binance
3
- module Client
4
- class REST
5
- API_ENDPOINTS = {
6
- # Public API Endpoints
7
- 'ping' => 'v1/ping',
8
- 'time' => 'v1/time',
9
- 'exchangeInfo' => 'v1/exchangeInfo',
10
- 'products' => '/exchange/public/products',
11
- 'depth' => 'v1/depth',
12
- 'trades' => 'v1/trades',
13
- 'historicalTrades' => 'v1/historicalTrades',
14
- 'aggTrades' => 'v1/aggTrades',
15
- 'klines' => 'v1/klines',
16
- '24hr' => 'v1/ticker/24hr',
17
- 'price' => 'v3/ticker/price',
18
- 'bookTicker' => 'v3/ticker/bookTicker',
19
-
20
- # Account API Endpoints
21
- 'order' => 'v3/order',
22
- 'order/test' => 'v3/order/test',
23
- 'openOrders' => 'v3/openOrders',
24
- 'allOrders' => 'v3/allOrders',
25
- 'account' => 'v3/account',
26
- 'myTrades' => 'v3/myTrades',
27
-
28
- # Withdraw API Endpoints
29
- 'withdraw' => 'v3/withdraw.html',
30
- 'depositHistory' => 'v3/depositHistory.html',
31
- 'withdrawHistory' => 'v3/withdrawHistory.html',
32
- 'depositAddress' => 'v3/depositAddress.html'
33
- }.freeze
34
- end
35
- end
36
- end
1
+
2
+ module Binance
3
+ module Client
4
+ class REST
5
+ API_ENDPOINTS = {
6
+ # Public API Endpoints
7
+ 'ping' => 'v1/ping',
8
+ 'time' => 'v1/time',
9
+ 'exchangeInfo' => 'v1/exchangeInfo',
10
+ 'products' => '/exchange/public/products',
11
+ 'depth' => 'v1/depth',
12
+ 'trades' => 'v1/trades',
13
+ 'historicalTrades' => 'v1/historicalTrades',
14
+ 'aggTrades' => 'v1/aggTrades',
15
+ 'klines' => 'v1/klines',
16
+ '24hr' => 'v1/ticker/24hr',
17
+ 'price' => 'v3/ticker/price',
18
+ 'bookTicker' => 'v3/ticker/bookTicker',
19
+
20
+ # Account API Endpoints
21
+ 'order' => 'v3/order',
22
+ 'order/test' => 'v3/order/test',
23
+ 'openOrders' => 'v3/openOrders',
24
+ 'allOrders' => 'v3/allOrders',
25
+ 'account' => 'v3/account',
26
+ 'myTrades' => 'v3/myTrades',
27
+
28
+ # Withdraw API Endpoints
29
+ 'withdraw' => 'v3/withdraw.html',
30
+ 'depositHistory' => 'v3/depositHistory.html',
31
+ 'withdrawHistory' => 'v3/withdrawHistory.html',
32
+ 'depositAddress' => 'v3/depositAddress.html',
33
+ 'accountStatus' => 'v3/accountStatus.html'
34
+ }.freeze
35
+ end
36
+ end
37
+ end
@@ -1,80 +1,167 @@
1
-
2
- require 'faraday'
3
- require 'faraday_middleware'
4
-
5
- module Binance
6
- module Client
7
- class REST
8
- # API endpoints that don't require any type of authentication
9
- module Public_API
10
- def self.extended(_base)
11
- REST.api[:public] = lambda do
12
- Faraday.new(url: "#{BASE_URL}/api") do |conn|
13
- conn.request :json
14
- conn.response :json, content_type: /\bjson$/
15
- conn.adapter Faraday.default_adapter
16
- end
17
- end
18
- end
19
-
20
- def ping
21
- request :public, :get, 'ping'
22
- end
23
-
24
- def time
25
- request :public, :get, 'time'
26
- end
27
-
28
- def exchange_info
29
- request :public, :get, 'exchangeInfo'
30
- end
31
-
32
- def products
33
- request :public, :get, 'products'
34
- end
35
-
36
- def depth(options)
37
- request :public, :get, 'depth', options
38
- end
39
-
40
- def trades(options)
41
- request :public, :get, 'trades', options
42
- end
43
-
44
- def historical_trades(options)
45
- request :public, :get, 'historicalTrades', options
46
- end
47
-
48
- def agg_trades(options)
49
- request :public, :get, 'aggTrades', options
50
- end
51
-
52
- def klines(options)
53
- request :public, :get, 'klines', options
54
- end
55
-
56
- def twenty_four_hour(options)
57
- request :public, :get, '24hr', options
58
- end
59
-
60
- def price(options)
61
- request :public, :get, 'price', options
62
- end
63
-
64
- # Ensure backwards compatibility
65
- def all_prices
66
- request :public, :get, 'price'
67
- end
68
-
69
- def book_ticker(options)
70
- request :public, :get, 'bookTicker', options
71
- end
72
-
73
- # Ensure backwards compatibility
74
- def all_book_tickers
75
- request :public, :get, 'bookTicker'
76
- end
77
- end
78
- end
79
- end
80
- end
1
+
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+
5
+ module Binance
6
+ module Client
7
+ class REST
8
+ # Public: A Module containing all of the Public API endpoints
9
+ module Public_API
10
+ # Internal: Create Lambda that returns a new Faraday client instance
11
+ # and add it to the REST class instance variable @api. This is called
12
+ # while a new instance of the REST class is created.
13
+ #
14
+ # base - The base class that is being extended into
15
+ def self.extended(base)
16
+ REST.api[:public] = lambda do
17
+ Faraday.new(url: "#{BASE_URL}/api") do |conn|
18
+ conn.request :json
19
+ conn.response :json, content_type: /\bjson$/
20
+ conn.adapter base.adapter
21
+ end
22
+ end
23
+ end
24
+
25
+ # Public: Ping the server to test connectivity
26
+ #
27
+ # Returns a Hash with the request response
28
+ def ping
29
+ request :public, :get, 'ping'
30
+ end
31
+
32
+ # Public: Retrieve the server time in milliseconds
33
+ #
34
+ # Returns a Hash with the request response
35
+ def time
36
+ request :public, :get, 'time'
37
+ end
38
+
39
+ # Public: Retrieve current exchange trading rules and symbol information
40
+ #
41
+ # Returns a Hash with the request response
42
+ def exchange_info
43
+ request :public, :get, 'exchangeInfo'
44
+ end
45
+
46
+ # Public: Retrieve current exchange asset information. This is an
47
+ # undocumented endpoint.
48
+ #
49
+ # Returns a Hash with the request response
50
+ def products
51
+ request :public, :get, 'products'
52
+ end
53
+
54
+ # Public: Retrieve depth information for the specified symbol
55
+ #
56
+ # options - The Hash which hosts various REST query params
57
+ # :symbol - The String of which trading pair to retrieve.
58
+ # :limit - The Number of how many updates to request (optional).
59
+ #
60
+ # Returns a Hash with the request response
61
+ def depth(options)
62
+ request :public, :get, 'depth', options
63
+ end
64
+
65
+ # Public: Retrieve recent trades for the specified symbol
66
+ #
67
+ # options - The Hash which hosts various REST query params
68
+ # :symbol - The String of which trading pair to retrieve.
69
+ # :limit - The Number of how many trades to request (optional).
70
+ #
71
+ # Returns a Hash with the request response
72
+ def trades(options)
73
+ request :public, :get, 'trades', options
74
+ end
75
+
76
+ # Public: Retrieve old trade data for the specified symbol
77
+ #
78
+ # options - The Hash which hosts various REST query params
79
+ # :symbol - The String of which trading pair to retrieve.
80
+ # :limit - The Number of how many trades to request (optional).
81
+ # :fromId - The String of which trade ID to fetch from.
82
+ #
83
+ # Returns a Hash with the request response
84
+ def historical_trades(options)
85
+ request :public, :get, 'historicalTrades', options
86
+ end
87
+
88
+ # Public: Retrieve aggregate trade data for the specified symbol
89
+ #
90
+ # options - The Hash which hosts various REST query params
91
+ # :symbol - The String of which trading pair to retrieve.
92
+ # :fromId - The String of which trade ID to fetch from (optional).
93
+ # :startTime - The Timestamp of when to get trades from in
94
+ # milliseconds (optional).
95
+ # :endTime - The Timestamp of when to get trades until in
96
+ # milliseconds (optional).
97
+ # :limit - The Number of how many trades to request (optional).
98
+ #
99
+ # Returns a Hash with the request response
100
+ def agg_trades(options)
101
+ request :public, :get, 'aggTrades', options
102
+ end
103
+
104
+ # Public: Retrieve kline data for the specified symbol
105
+ #
106
+ # options - The Hash which hosts various REST query params
107
+ # :symbol - The String of which trading pair to retrieve.
108
+ # :interval -
109
+ # :fromId - The String of which trade ID to fetch from (optional).
110
+ # :startTime - The Timestamp of when to get trades from in
111
+ # milliseconds (optional).
112
+ # :endTime - The Timestamp of when to get trades until in
113
+ # milliseconds (optional).
114
+ # :limit - The Number of how many trades to request (optional).
115
+ #
116
+ # Returns a Hash with the request response
117
+ def klines(options)
118
+ request :public, :get, 'klines', options
119
+ end
120
+
121
+ # Public: Retrieve 24 hour ticker price data
122
+ #
123
+ # options - The Hash which hosts various REST query params
124
+ # :symbol - The String of which trading pair to retrieve (optional).
125
+ #
126
+ # Returns a Hash with the request response
127
+ def twenty_four_hour(options)
128
+ request :public, :get, '24hr', options
129
+ end
130
+
131
+ # Public: Retrieve price ticker data for the specified symbol
132
+ #
133
+ # options - The Hash which hosts various REST query params
134
+ # :symbol - The String of which trading pair to retrieve (optional).
135
+ #
136
+ # Returns a Hash with the request response
137
+ def price(options)
138
+ request :public, :get, 'price', options
139
+ end
140
+
141
+ # Public: Retrieve all price ticker data
142
+ #
143
+ # Returns a Hash with the request response
144
+ def all_prices
145
+ request :public, :get, 'price'
146
+ end
147
+
148
+ # Public: Retrieve best price per quantity on the order book
149
+ #
150
+ # options - The Hash which hosts various REST query params
151
+ # :symbol - The String of which trading pair to retrieve (optional).
152
+ #
153
+ # Returns a Hash with the request response
154
+ def book_ticker(options)
155
+ request :public, :get, 'bookTicker', options
156
+ end
157
+
158
+ # Public: Retrieve all book ticker data for all symbols
159
+ #
160
+ # Returns a Hash with the request response
161
+ def all_book_tickers
162
+ request :public, :get, 'bookTicker'
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -1,18 +1,18 @@
1
-
2
- module Binance
3
- module Client
4
- class REST
5
- # Sign the query string using HMAC(sha-256) and appends to query string
6
- SignRequestMiddleware = Struct.new(:app, :secret_key) do
7
- def call(env)
8
- value = OpenSSL::HMAC.hexdigest(
9
- OpenSSL::Digest.new('sha256'), secret_key, env.url.query
10
- )
11
- env.url.query = REST.add_query_param(env.url.query, 'signature', value)
12
-
13
- app.call env
14
- end
15
- end
16
- end
17
- end
18
- end
1
+
2
+ module Binance
3
+ module Client
4
+ class REST
5
+ # Sign the query string using HMAC(sha-256) and appends to query string
6
+ SignRequestMiddleware = Struct.new(:app, :secret_key) do
7
+ def call(env)
8
+ value = OpenSSL::HMAC.hexdigest(
9
+ OpenSSL::Digest.new('sha256'), secret_key, env.url.query
10
+ )
11
+ env.url.query = REST.add_query_param(env.url.query, 'signature', value)
12
+
13
+ app.call env
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,19 +1,19 @@
1
-
2
- require 'date'
3
-
4
- module Binance
5
- module Client
6
- class REST
7
- # Generate a timestamp in milliseconds and append to query string
8
- TimestampRequestMiddleware = Struct.new(:app) do
9
- def call(env)
10
- env.url.query = REST.add_query_param(
11
- env.url.query, 'timestamp', DateTime.now.strftime('%Q')
12
- )
13
-
14
- app.call env
15
- end
16
- end
17
- end
18
- end
19
- end
1
+
2
+ require 'date'
3
+
4
+ module Binance
5
+ module Client
6
+ class REST
7
+ # Generate a timestamp in milliseconds and append to query string
8
+ TimestampRequestMiddleware = Struct.new(:app) do
9
+ def call(env)
10
+ env.url.query = REST.add_query_param(
11
+ env.url.query, 'timestamp', DateTime.now.strftime('%Q')
12
+ )
13
+
14
+ app.call env
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,44 +1,106 @@
1
-
2
- require 'faraday'
3
- require 'faraday_middleware'
4
- require_relative 'sign_request_middleware'
5
- require_relative 'timestamp_request_middleware'
6
-
7
- module Binance
8
- module Client
9
- class REST
10
- # API endpoints with require a timestamp and signature,
11
- # as well as requiring url_encoded parameters
12
- module Withdraw_API
13
- def self.extended(base)
14
- REST.api[:withdraw] = lambda do
15
- Faraday.new(url: "#{BASE_URL}/wapi") do |conn|
16
- conn.request :url_encoded
17
- conn.response :json, content_type: /\bjson$/
18
- conn.headers['X-MBX-APIKEY'] = base.api_key
19
- conn.use TimestampRequestMiddleware
20
- conn.use SignRequestMiddleware, base.secret_key
21
- conn.adapter Faraday.default_adapter
22
- end
23
- end
24
- end
25
-
26
- def withdraw(options)
27
- request :withdraw, :post, 'withdraw', options
28
- end
29
-
30
- def deposit_history(options = {})
31
- request :withdraw, :get, 'depositHistory', options
32
- end
33
-
34
- def withdraw_history(options = {})
35
- request :withdraw, :get, 'withdrawHistory', options
36
- end
37
-
38
- def deposit_address(options)
39
- request :withdraw, :get, 'depositAddress', options
40
- end
41
- end
42
- end
43
- end
1
+
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+ require_relative 'sign_request_middleware'
5
+ require_relative 'timestamp_request_middleware'
6
+
7
+ module Binance
8
+ module Client
9
+ class REST
10
+ # Public: A Module containing all of the Withdraw API endpoints
11
+ module Withdraw_API
12
+ # Internal: Create Lambda that returns a new Faraday client instance
13
+ # and add it to the REST class instance variable @api. This is called
14
+ # while a new instance of the REST class is created.
15
+ #
16
+ # base - The base class that is being extended into
17
+ def self.extended(base)
18
+ REST.api[:withdraw] = lambda do
19
+ Faraday.new(url: "#{BASE_URL}/wapi") do |conn|
20
+ conn.request :url_encoded
21
+ conn.response :json, content_type: /\bjson$/
22
+ conn.headers['X-MBX-APIKEY'] = base.api_key
23
+ conn.use TimestampRequestMiddleware
24
+ conn.use SignRequestMiddleware, base.secret_key
25
+ conn.adapter base.adapter
26
+ end
27
+ end
28
+ end
29
+
30
+ # Public: Withdraw the specified asset to the given address using
31
+ # the authenticated account
32
+ #
33
+ # options - The Hash which hosts various REST query params
34
+ # :asset - The String of which asset to withdraw.
35
+ # :address - The String of where to send the asset to.
36
+ # :addressTag - The String secondary address identifier (optional).
37
+ # :amount - The String decimal value of how much to withdraw.
38
+ # :name - The String description of the address
39
+ # :recvWindow - The Number of how long a request is valid for in
40
+ # milliseconds (optional).
41
+ #
42
+ # Returns a Hash with the request response
43
+ def withdraw(options)
44
+ request :withdraw, :post, 'withdraw', options
45
+ end
46
+
47
+ # Public: Retrieve the deposit history for the authenticated account
48
+ #
49
+ # options - The Hash which hosts various REST query params
50
+ # :asset - The String of which asset to retrieve (optional).
51
+ # :status - The Number of which status to retrieve (optional).
52
+ # :startTime - The Timestamp of when to start the history in
53
+ # milliseconds (optional).
54
+ # :endTime - The Timestamp of when to end the history in
55
+ # milliseconds (optional).
56
+ # :recvWindow - The Number of how long a request is valid for in
57
+ # milliseconds (optional).
58
+ #
59
+ # Returns a Hash with the request response
60
+ def deposit_history(options = {})
61
+ request :withdraw, :get, 'depositHistory', options
62
+ end
63
+
64
+ # Public: Retrieve the withdraw history for the authenticated account
65
+ #
66
+ # options - The Hash which hosts various REST query params
67
+ # :asset - The String of which asset to retrieve (optional).
68
+ # :status - The Number of which status to retrieve (optional).
69
+ # :startTime - The Timestamp of when to start the history in
70
+ # milliseconds (optional).
71
+ # :endTime - The Timestamp of when to end the history in
72
+ # milliseconds (optional).
73
+ # :recvWindow - The Number of how long a request is valid for in
74
+ # milliseconds (optional).
75
+ #
76
+ # Returns a Hash with the request response
77
+ def withdraw_history(options = {})
78
+ request :withdraw, :get, 'withdrawHistory', options
79
+ end
80
+
81
+ # Public: Retrieve the deposit address for a specific asset
82
+ #
83
+ # options - The Hash which hosts various REST query params
84
+ # :asset - The String of which asset to retrieve (optional).
85
+ # :recvWindow - The Number of how long a request is valid for in
86
+ # milliseconds (optional).
87
+ #
88
+ # Returns a Hash with the request response
89
+ def deposit_address(options)
90
+ request :withdraw, :get, 'depositAddress', options
91
+ end
92
+
93
+ # Public: Retrieve current account status
94
+ #
95
+ # options - The Hash which hosts various REST query params
96
+ # :recvWindow - The Number of how long a request is valid for in
97
+ # milliseconds (optional).
98
+ #
99
+ # Returns a Hash with the request response
100
+ def account_status(options)
101
+ request :withdraw, :get, 'accountStatus', options
102
+ end
103
+ end
104
+ end
105
+ end
44
106
  end
@@ -0,0 +1,202 @@
1
+
2
+ require 'faye/websocket'
3
+
4
+ module Binance
5
+ module Client
6
+ # Public: Client with methods mirroring the Binance WebSocket API
7
+ class WebSocket
8
+ # Public: String base url for WebSocket client to use
9
+ BASE_URL = 'wss://stream.binance.com:9443'.freeze
10
+
11
+ # Public: Create a single WebSocket stream
12
+ #
13
+ # :stream - The Hash used to define the stream
14
+ # :symbol - The String symbol to listen to
15
+ # :type - The String type of stream to listen to
16
+ # :level - The String level to use for the depth stream (optional)
17
+ # :interval - The String interval to use for the kline stream (optional)
18
+ #
19
+ # :methods - The Hash which contains the event handler methods to pass to
20
+ # the WebSocket client
21
+ # :open - The Proc called when a stream is opened (optional)
22
+ # :message - The Proc called when a stream receives a message
23
+ # :error - The Proc called when a stream receives an error (optional)
24
+ # :close - The Proc called when a stream is closed (optional)
25
+ def single(stream:, methods:)
26
+ create_stream("#{BASE_URL}/ws/#{stream_url(stream)}",
27
+ methods: methods)
28
+ end
29
+
30
+ # Public: Create multiple WebSocket streams
31
+ #
32
+ # :streams - The Array of Hashes used to define the stream.
33
+ # Each Hash can have the following keys
34
+ # :symbol - The String symbol the stream will listen to
35
+ # :type - The String type of stream to listen to
36
+ # :level - The String level to use for the depth stream (optional)
37
+ # :interval - The String interval to use for the kline stream (optional)
38
+ #
39
+ # :methods - The Hash which contains the event handler methods to pass to
40
+ # the WebSocket client
41
+ # :open - The Proc called when a stream is opened (optional)
42
+ # :message - The Proc called when a stream receives a message
43
+ # :error - The Proc called when a stream receives an error (optional)
44
+ # :close - The Proc called when a stream is closed (optional)
45
+ def multi(streams:, methods:)
46
+ names = streams.map { |stream| stream_url(stream) }
47
+ create_stream("#{BASE_URL}/stream?streams=#{names.join('/')}",
48
+ methods: methods)
49
+ end
50
+
51
+ # Public: Create an Aggregate Trade stream
52
+ #
53
+ # :symbol - The String symbol the stream will listen to
54
+ #
55
+ # :methods - The Hash which contains the event handler methods to pass to
56
+ # the WebSocket client
57
+ # :open - The Proc called when a stream is opened (optional)
58
+ # :message - The Proc called when a stream receives a message
59
+ # :error - The Proc called when a stream receives an error (optional)
60
+ # :close - The Proc called when a stream is closed (optional)
61
+ def agg_trade(symbol:, methods:)
62
+ single stream: { symbol: symbol, type: 'aggTrade' }, methods: methods
63
+ end
64
+
65
+ # Public: Create a Trade stream
66
+ #
67
+ # :symbol - The String symbol the stream will listen to
68
+ #
69
+ # :methods - The Hash which contains the event handler methods to pass to
70
+ # the WebSocket client
71
+ # :open - The Proc called when a stream is opened (optional)
72
+ # :message - The Proc called when a stream receives a message
73
+ # :error - The Proc called when a stream receives an error (optional)
74
+ # :close - The Proc called when a stream is closed (optional)
75
+ def trade(symbol:, methods:)
76
+ single stream: { symbol: symbol, type: 'trade' }, methods: methods
77
+ end
78
+
79
+ # Public: Create an Kline stream
80
+ #
81
+ # :symbol - The String symbol the stream will listen to
82
+ #
83
+ # :interval - The String interval the stream will update with.
84
+ # The intervals that may be used can be found in the Binance API 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.
128
+ # The intervals 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
+ private
156
+
157
+ # Internal: Create a valid URL for a WebSocket to use
158
+ #
159
+ # :symbol - The String symbol to listen to
160
+ # :type - The String type the stream will listen to
161
+ # :level - The String level to use for the depth stream (optional)
162
+ # :interval - The String interval to use for the kline stream (optional)
163
+ def stream_url(symbol:, type:, level: '', interval: '')
164
+ "#{symbol.downcase}@#{type}".tap do |url|
165
+ url << level
166
+ url << "_#{interval}" unless interval.empty?
167
+ end
168
+ end
169
+
170
+ # Internal: Initialize and return a Faye::WebSocket::Client
171
+ #
172
+ # url - The String url that the WebSocket should try to connect to
173
+ #
174
+ # :methods - The Hash which contains the event handler methods to pass to
175
+ # the WebSocket client
176
+ # :open - The Proc called when a stream is opened (optional)
177
+ # :message - The Proc called when a stream receives a message
178
+ # :error - The Proc called when a stream receives an error (optional)
179
+ # :close - The Proc called when a stream is closed (optional)
180
+ def create_stream(url, methods:)
181
+ Faye::WebSocket::Client.new(url)
182
+ .tap { |ws| attach_methods(ws, methods) }
183
+ end
184
+
185
+ # Internal: Iterate through methods passed and add them to the WebSocket
186
+ #
187
+ # websocket - The Faye::WebSocket::Client to apply methods 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 attach_methods(websocket, methods)
196
+ methods.each_pair do |key, method|
197
+ websocket.on(key) { |event| method.call(event) }
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
@@ -1,4 +1,4 @@
1
-
2
- module Binance
3
- VERSION = '0.2.0'.freeze
4
- end
1
+
2
+ module Binance
3
+ VERSION = '0.3.0'.freeze
4
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Ray Shisler III
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-13 00:00:00.000000000 Z
11
+ date: 2017-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.12.2
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.7
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.7
83
97
  description:
84
98
  email:
85
99
  - charles@cray.io
@@ -97,6 +111,7 @@ files:
97
111
  - lib/binance/client/rest/sign_request_middleware.rb
98
112
  - lib/binance/client/rest/timestamp_request_middleware.rb
99
113
  - lib/binance/client/rest/withdraw_api.rb
114
+ - lib/binance/client/websocket.rb
100
115
  - lib/binance/version.rb
101
116
  homepage: https://github.com/craysiii/binance
102
117
  licenses:
@@ -118,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
133
  version: '0'
119
134
  requirements: []
120
135
  rubyforge_project:
121
- rubygems_version: 2.5.2
136
+ rubygems_version: 2.6.11
122
137
  signing_key:
123
138
  specification_version: 4
124
139
  summary: API Wrapper for the Binance cryptocurrency exchange.