1 |
|
2 |
|
3 | process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
|
4 |
|
5 | request = require 'request'
|
6 | crypto = require 'crypto'
|
7 | qs = require 'querystring'
|
8 |
|
9 | module.exports = class Bitfinex
|
10 |
|
11 | constructor: (key, secret) ->
|
12 |
|
13 | @url = "https://api.bitfinex.com"
|
14 | @key = key
|
15 | @secret = secret
|
16 | @nonce = Math.round((new Date()).getTime() / 1000)
|
17 |
|
18 | _nonce: () ->
|
19 |
|
20 | return @nonce++
|
21 |
|
22 | make_request: (sub_path, params, cb) ->
|
23 |
|
24 | if !@key or !@secret
|
25 | return cb(new Error("missing api key or secret"))
|
26 |
|
27 | path = '/v1/' + sub_path
|
28 | url = @url + path
|
29 | nonce = JSON.stringify(@_nonce())
|
30 |
|
31 | payload =
|
32 | request: path
|
33 | nonce: nonce
|
34 |
|
35 | for key, value of params
|
36 | payload[key] = value
|
37 |
|
38 | payload = new Buffer(JSON.stringify(payload)).toString('base64')
|
39 | signature = crypto.createHmac("sha384", @secret).update(payload).digest('hex')
|
40 |
|
41 | headers =
|
42 | 'X-BFX-APIKEY': @key
|
43 | 'X-BFX-PAYLOAD': payload
|
44 | 'X-BFX-SIGNATURE': signature
|
45 |
|
46 | request { url: url, method: "POST", headers: headers, timeout: 15000 }, (err,response,body)->
|
47 |
|
48 | if err || (response.statusCode != 200 && response.statusCode != 400)
|
49 | return cb new Error(err ? response.statusCode)
|
50 |
|
51 | try
|
52 | result = JSON.parse(body)
|
53 | catch error
|
54 | return cb(null, { messsage : body.toString() } )
|
55 |
|
56 | if result.message?
|
57 | return cb new Error(result.message)
|
58 |
|
59 | cb null, result
|
60 |
|
61 | make_public_request: (path, cb) ->
|
62 |
|
63 | url = @url + '/v1/' + path
|
64 |
|
65 | request { url: url, method: "GET", timeout: 15000}, (err,response,body)->
|
66 |
|
67 | if err || (response.statusCode != 200 && response.statusCode != 400)
|
68 | return cb new Error(err ? response.statusCode)
|
69 |
|
70 | try
|
71 | result = JSON.parse(body)
|
72 | catch error
|
73 | return cb(null, { messsage : body.toString() } )
|
74 |
|
75 | if result.message?
|
76 | return cb new Error(result.message)
|
77 |
|
78 | cb null, result
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | ticker: (symbol, cb) ->
|
85 |
|
86 | @make_public_request('ticker/' + symbol, cb)
|
87 |
|
88 | today: (symbol, cb) ->
|
89 |
|
90 | @make_public_request('today/' + symbol, cb)
|
91 |
|
92 | candles: (symbol, cb) ->
|
93 |
|
94 | @make_public_request('candles/' + symbol, cb)
|
95 |
|
96 | lendbook: (currency, cb) ->
|
97 |
|
98 | @make_public_request('lendbook/' + currency, cb)
|
99 |
|
100 | orderbook: (symbol, cb) ->
|
101 |
|
102 | maxOrders = 50
|
103 | uri = 'book/' + symbol + '/?limit_bids=' + maxOrders + '&limit_asks=' + maxOrders
|
104 | @make_public_request(uri, cb)
|
105 |
|
106 | trades: (symbol, cb) ->
|
107 |
|
108 | @make_public_request('trades/' + symbol, cb)
|
109 |
|
110 | lends: (currency, cb) ->
|
111 |
|
112 | @make_public_request('lends/' + currency, cb)
|
113 |
|
114 | get_symbols: (cb) ->
|
115 |
|
116 | @make_public_request('symbols/', cb)
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | new_order: (symbol, amount, price, exchange, side, type, cb) ->
|
123 |
|
124 | params =
|
125 | symbol: symbol
|
126 | amount: amount
|
127 | price: price
|
128 | exchange: exchange
|
129 | side: side
|
130 | type: type
|
131 |
|
132 |
|
133 | @make_request('order/new', params, cb)
|
134 |
|
135 | multiple_new_orders: (symbol, amount, price, exchange, side, type, cb) ->
|
136 |
|
137 | params =
|
138 | symbol: symbol
|
139 | amount: amount
|
140 | price: price
|
141 | exchange: exchange
|
142 | side: side
|
143 | type: type
|
144 |
|
145 | @make_request('order/new/multi', params, cb)
|
146 |
|
147 | cancel_order: (order_id, cb) ->
|
148 |
|
149 | params =
|
150 | order_id: parseInt(order_id)
|
151 |
|
152 | @make_request('order/cancel', params, cb)
|
153 |
|
154 | cancel_all_orders: (cb) ->
|
155 |
|
156 | @make_request('order/cancel/all', {}, cb)
|
157 |
|
158 | cancel_multiple_orders: (order_ids, cb) ->
|
159 |
|
160 | params =
|
161 | order_ids: order_ids.map( (id) ->
|
162 | return parseInt(id) )
|
163 |
|
164 | @make_request('order/cancel/multi', params, cb)
|
165 |
|
166 | replace_order: (order_id, symbol, amount, price, exchange, side, type, cb) ->
|
167 |
|
168 | params =
|
169 | order_id: parseInt(order_id)
|
170 | symbol: symbol
|
171 | amount: amount
|
172 | price: price
|
173 | exchange: exchange
|
174 | side: side
|
175 | type: type
|
176 |
|
177 | @make_request('order/cancel/replace', params, cb)
|
178 |
|
179 | order_status: (order_id, cb) ->
|
180 |
|
181 | params =
|
182 | order_id: order_id
|
183 |
|
184 | @make_request('order/status', params, cb)
|
185 |
|
186 | active_orders: (cb) ->
|
187 |
|
188 | @make_request('orders', {}, cb)
|
189 |
|
190 | active_positions: (cb) ->
|
191 |
|
192 | @make_request('positions', {}, cb)
|
193 |
|
194 | past_trades: (symbol, timestamp, limit_trades, cb) ->
|
195 |
|
196 | params =
|
197 | symbol: symbol
|
198 | timestamp: timestamp
|
199 | limit_trades: limit_trades
|
200 |
|
201 | @make_request('mytrades', params, cb)
|
202 |
|
203 | new_offer: (currency, amount, rate, period, direction, insurance_option, cb) ->
|
204 |
|
205 | params =
|
206 | currency: currency
|
207 | amount: amount
|
208 | rate: rate
|
209 | period: period
|
210 | direction: direction
|
211 | insurance_option: insurance_option
|
212 |
|
213 | @make_request('offer/new', params, cb)
|
214 |
|
215 | cancel_offer: (offer_id, cb) ->
|
216 |
|
217 | params =
|
218 | order_id: offer_id
|
219 |
|
220 | @make_request('offer/cancel', params, cb)
|
221 |
|
222 | offer_status: (order_id, cb) ->
|
223 |
|
224 | params =
|
225 | order_id: order_id
|
226 |
|
227 | @make_request('offer/status', params, cb)
|
228 |
|
229 | active_offers: (cb) ->
|
230 |
|
231 | @make_request('offers', {}, cb)
|
232 |
|
233 | active_credits: (cb) ->
|
234 |
|
235 | @make_request('credits', {}, cb)
|
236 |
|
237 | wallet_balances: (cb) ->
|
238 |
|
239 | @make_request('balances', {}, cb)
|