btc-api-node 1.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of btc-api-node might be problematic. Click here for more details.
- package/.istanbul.yml +53 -0
- package/.travis.yml +5 -0
- package/CHANGELOG +33 -0
- package/LICENSE.md +21 -0
- package/README.md +211 -0
- package/doc/order.md +160 -0
- package/doc/rest2.md +573 -0
- package/doc/ws2.md +925 -0
- package/examples/bfx.js +26 -0
- package/examples/rest2/order_history.js +29 -0
- package/examples/rest2/symbols.js +15 -0
- package/examples/rest2/tickers.js +24 -0
- package/examples/rest2/trade_history.js +28 -0
- package/examples/ws2/auth.js +31 -0
- package/examples/ws2/calc.js +33 -0
- package/examples/ws2/cancel_all.js +35 -0
- package/examples/ws2/cancel_all_buf.js +39 -0
- package/examples/ws2/candles.js +36 -0
- package/examples/ws2/info_events.js +40 -0
- package/examples/ws2/oc_multi.js +50 -0
- package/examples/ws2/order_books.js +37 -0
- package/examples/ws2/orders.js +67 -0
- package/examples/ws2/ox_multi.js +61 -0
- package/examples/ws2/sequencing.js +23 -0
- package/examples/ws2/ticker.js +20 -0
- package/examples/ws2/trades.js +27 -0
- package/index.js +24 -0
- package/lib/model.js +25 -0
- package/lib/models/alert.js +25 -0
- package/lib/models/balance_info.js +21 -0
- package/lib/models/candle.js +33 -0
- package/lib/models/funding_credit.js +61 -0
- package/lib/models/funding_info.js +16 -0
- package/lib/models/funding_loan.js +64 -0
- package/lib/models/funding_offer.js +60 -0
- package/lib/models/funding_trade.js +33 -0
- package/lib/models/index.js +23 -0
- package/lib/models/margin_info.js +29 -0
- package/lib/models/notification.js +31 -0
- package/lib/models/order.js +288 -0
- package/lib/models/order_book.js +214 -0
- package/lib/models/position.js +43 -0
- package/lib/models/tick.js +83 -0
- package/lib/models/trade.js +43 -0
- package/lib/models/trade_tick.js +29 -0
- package/lib/models/wallet.js +34 -0
- package/lib/transports/rest.js +391 -0
- package/lib/transports/rest2.js +597 -0
- package/lib/transports/ws.js +323 -0
- package/lib/transports/ws2.js +1729 -0
- package/lib/util/gen_auth_sig.js +23 -0
- package/lib/util/index.js +11 -0
- package/lib/util/is_snapshot.js +5 -0
- package/lib/util/nonce.js +5 -0
- package/package.json +39 -0
- package/test/fixtures/response-ticker-funding.json +1 -0
- package/test/fixtures/response-ticker-pairs.json +1 -0
- package/test/fixtures/response-trades-funding.json +1 -0
- package/test/fixtures/response-trades-pairs.json +1 -0
- package/test/fixtures/response-ws-1-orderbook-R0.json +51 -0
- package/test/fixtures/response-ws2-server-order-book-P0.json +1 -0
- package/test/fixtures/response-ws2-server-order-book-P1.json +1 -0
- package/test/fixtures/response-ws2-server-order-book-R0.json +1 -0
- package/test/fixtures/response-ws2-server-ticker-funding.json +1 -0
- package/test/fixtures/response-ws2-server-trades.json +1 -0
- package/test/helpers/test_model.js +71 -0
- package/test/index.js +131 -0
- package/test/lib/models/alert.js +12 -0
- package/test/lib/models/balance_info.js +12 -0
- package/test/lib/models/candle.js +12 -0
- package/test/lib/models/funding_credit.js +17 -0
- package/test/lib/models/funding_info.js +7 -0
- package/test/lib/models/funding_loan.js +17 -0
- package/test/lib/models/funding_offer.js +17 -0
- package/test/lib/models/funding_trade.js +15 -0
- package/test/lib/models/margin_info.js +15 -0
- package/test/lib/models/notification.js +14 -0
- package/test/lib/models/order.js +395 -0
- package/test/lib/models/order_book.js +188 -0
- package/test/lib/models/position.js +15 -0
- package/test/lib/models/tick.js +34 -0
- package/test/lib/models/trade.js +16 -0
- package/test/lib/models/trade_tick.js +14 -0
- package/test/lib/models/wallet.js +14 -0
- package/test/lib/transports/rest-1-integration.js +131 -0
- package/test/lib/transports/rest-2-integration.js +80 -0
- package/test/lib/transports/rest-2-issue-80-argument-length.js +61 -0
- package/test/lib/transports/rest-2-smoke-test.js +49 -0
- package/test/lib/transports/rest-2-unit.js +26 -0
- package/test/lib/transports/rest1.js +152 -0
- package/test/lib/transports/ws-1-handle-channel.js +83 -0
- package/test/lib/transports/ws-1-parsing.js +40 -0
- package/test/lib/transports/ws-1-test.js +275 -0
- package/test/lib/transports/ws2-integration.js +259 -0
- package/test/lib/transports/ws2-unit.js +1295 -0
- package/test/lib/util/is_snapshot.js +20 -0
- package/test/lib/util/nonce.js +20 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
/* eslint camelcase: "off" */
|
|
3
|
+
|
|
4
|
+
const request = require('request')
|
|
5
|
+
const { genAuthSig, nonce } = require('../util')
|
|
6
|
+
|
|
7
|
+
const API_URL = 'https://api.bitfinex.com'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Communicates with v1 of the Bitfinex HTTP API
|
|
11
|
+
*/
|
|
12
|
+
class RESTv1 {
|
|
13
|
+
constructor (opts = {
|
|
14
|
+
apiKey: '',
|
|
15
|
+
apiSecret: '',
|
|
16
|
+
url: API_URL,
|
|
17
|
+
agent: null
|
|
18
|
+
}) {
|
|
19
|
+
this._url = opts.url || API_URL
|
|
20
|
+
this._apiKey = opts.apiKey || ''
|
|
21
|
+
this._apiSecret = opts.apiSecret || ''
|
|
22
|
+
this._agent = opts.agent
|
|
23
|
+
this._generateNonce = (typeof opts.nonceGenerator === 'function')
|
|
24
|
+
? opts.nonceGenerator
|
|
25
|
+
: nonce
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_parse_req_body (body, cb) {
|
|
29
|
+
let result
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
result = JSON.parse(body)
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return cb(error)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (typeof result.message === 'string') {
|
|
38
|
+
if (result.message.indexOf('Nonce is too small') !== -1) {
|
|
39
|
+
result.message += ' See https://github.com/bitfinexcom/bitfinex-api-node/blob/master/README.md#nonce-too-small for help'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return cb(new Error(result.message))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return cb(null, result)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
make_request (path, params, cb) {
|
|
49
|
+
if (!this._apiKey || !this._apiSecret) {
|
|
50
|
+
return cb(new Error('missing api key or secret'))
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const payload = Object.assign({
|
|
54
|
+
request: `/v1/${path}`,
|
|
55
|
+
nonce: JSON.stringify(this._generateNonce())
|
|
56
|
+
}, params)
|
|
57
|
+
|
|
58
|
+
const payloadBase64 = Buffer.from(JSON.stringify(payload)).toString('base64')
|
|
59
|
+
const { sig } = genAuthSig(this._apiSecret, payloadBase64)
|
|
60
|
+
|
|
61
|
+
return request({
|
|
62
|
+
url: `${this._url}/v1/${path}`,
|
|
63
|
+
method: 'POST',
|
|
64
|
+
timeout: 15000,
|
|
65
|
+
agent: this._agent,
|
|
66
|
+
headers: {
|
|
67
|
+
'X-BFX-APIKEY': this._apiKey,
|
|
68
|
+
'X-BFX-PAYLOAD': payloadBase64,
|
|
69
|
+
'X-BFX-SIGNATURE': sig
|
|
70
|
+
}
|
|
71
|
+
}, (err, res, body) => {
|
|
72
|
+
if (err) return cb(err)
|
|
73
|
+
if (res.statusCode !== 200 && res.statusCode !== 400) {
|
|
74
|
+
return cb(
|
|
75
|
+
new Error(`HTTP code ${res.statusCode} ${res.statusMessage || ''}`)
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this._parse_req_body(body, cb)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
make_public_request (path, cb) {
|
|
84
|
+
return request({
|
|
85
|
+
method: 'GET',
|
|
86
|
+
agent: this._agent,
|
|
87
|
+
timeout: 15000,
|
|
88
|
+
url: `${this._url}/v1/${path}`
|
|
89
|
+
}, (err, res, body) => {
|
|
90
|
+
if (err) return cb(err)
|
|
91
|
+
if (res.statusCode !== 200 && res.statusCode !== 400) {
|
|
92
|
+
return cb(
|
|
93
|
+
new Error(`HTTP code ${res.statusCode} ${res.statusMessage || ''}`)
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this._parse_req_body(body, cb)
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
ticker (symbol = 'BTCUSD', cb) {
|
|
102
|
+
if (!cb) {
|
|
103
|
+
cb = (err, data) => {
|
|
104
|
+
if (err) {
|
|
105
|
+
console.error(err)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log(data)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return this.make_public_request(`pubticker/${symbol}`, cb)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
today (symbol, cb) {
|
|
116
|
+
return this.make_public_request(`today/${symbol}`, cb)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
stats (symbol, cb) {
|
|
120
|
+
return this.make_public_request(`stats/${symbol}`, cb)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
fundingbook (currency, options, cb) {
|
|
124
|
+
let uri = `lendbook/${currency}`
|
|
125
|
+
|
|
126
|
+
if (typeof options === 'function') {
|
|
127
|
+
cb = options
|
|
128
|
+
} else {
|
|
129
|
+
const keys = Object.keys(options)
|
|
130
|
+
|
|
131
|
+
for (let i = 0; i < keys.length; i++) {
|
|
132
|
+
uri += `${i === 0 ? '/?' : '&'}${keys[i]}=${options[keys[i]]}`
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return this.make_public_request(uri, cb)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
orderbook (symbol, options, cb) {
|
|
140
|
+
let uri = `book/${symbol}`
|
|
141
|
+
|
|
142
|
+
if (typeof options === 'function') {
|
|
143
|
+
cb = options
|
|
144
|
+
} else {
|
|
145
|
+
const keys = Object.keys(options)
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < keys.length; i++) {
|
|
148
|
+
uri += `${i === 0 ? '/?' : '&'}${keys[i]}=${options[keys[i]]}`
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return this.make_public_request(uri, cb)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
trades (symbol, cb) {
|
|
156
|
+
return this.make_public_request('trades/' + symbol, cb)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
lends (currency, cb) {
|
|
160
|
+
return this.make_public_request('lends/' + currency, cb)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
get_symbols (cb) {
|
|
164
|
+
return this.make_public_request('symbols', cb)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
symbols_details (cb) {
|
|
168
|
+
return this.make_public_request('symbols_details', cb)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
new_order (symbol, amount, price, exchange, side, type, is_hidden, postOnly, cb) {
|
|
172
|
+
if (typeof is_hidden === 'function') {
|
|
173
|
+
cb = is_hidden
|
|
174
|
+
is_hidden = false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (typeof postOnly === 'function') {
|
|
178
|
+
cb = postOnly
|
|
179
|
+
postOnly = false
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const params = {
|
|
183
|
+
symbol,
|
|
184
|
+
amount,
|
|
185
|
+
price,
|
|
186
|
+
exchange,
|
|
187
|
+
side,
|
|
188
|
+
type
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (postOnly) params['post_only'] = true
|
|
192
|
+
if (is_hidden) params['is_hidden'] = true
|
|
193
|
+
|
|
194
|
+
return this.make_request('order/new', params, cb)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
multiple_new_orders (orders, cb) {
|
|
198
|
+
return this.make_request('order/new/multi', { orders }, cb)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
cancel_order (order_id, cb) {
|
|
202
|
+
return this.make_request('order/cancel', {
|
|
203
|
+
order_id: parseInt(order_id)
|
|
204
|
+
}, cb)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
cancel_all_orders (cb) {
|
|
208
|
+
return this.make_request('order/cancel/all', {}, cb)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
cancel_multiple_orders (order_ids, cb) {
|
|
212
|
+
return this.make_request('order/cancel/multi', {
|
|
213
|
+
order_ids: order_ids.map(id => parseInt(id))
|
|
214
|
+
}, cb)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
replace_order (order_id, symbol, amount, price, exchange, side, type, cb) {
|
|
218
|
+
return this.make_request('order/cancel/replace', {
|
|
219
|
+
order_id: parseInt(order_id),
|
|
220
|
+
symbol,
|
|
221
|
+
amount,
|
|
222
|
+
price,
|
|
223
|
+
exchange,
|
|
224
|
+
side,
|
|
225
|
+
type
|
|
226
|
+
}, cb)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// TODO: Why is order_id not parsed here as above? Also applies to further
|
|
230
|
+
// instances below
|
|
231
|
+
order_status (order_id, cb) {
|
|
232
|
+
return this.make_request('order/status', {
|
|
233
|
+
order_id: parseInt(order_id)
|
|
234
|
+
}, cb)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
active_orders (cb) {
|
|
238
|
+
return this.make_request('orders', {}, cb)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
orders_history (cb) {
|
|
242
|
+
return this.make_request('orders/hist', {}, cb)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
active_positions (cb) {
|
|
246
|
+
return this.make_request('positions', {}, cb)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
claim_position (position_id, amount, cb) {
|
|
250
|
+
return this.make_request('position/claim', {
|
|
251
|
+
position_id: parseInt(position_id),
|
|
252
|
+
amount
|
|
253
|
+
}, cb)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
balance_history (currency, options, cb) {
|
|
257
|
+
const params = { currency }
|
|
258
|
+
|
|
259
|
+
if (typeof options === 'function') {
|
|
260
|
+
cb = options
|
|
261
|
+
} else if (options && options.constructor.name === 'Object') {
|
|
262
|
+
Object.assign(params, options)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return this.make_request('history', params, cb)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
movements (currency, options, cb) {
|
|
269
|
+
const params = { currency }
|
|
270
|
+
|
|
271
|
+
if (typeof options === 'function') {
|
|
272
|
+
cb = options
|
|
273
|
+
} else if (options && options.constructor.name === 'Object') {
|
|
274
|
+
Object.assign(params, options)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return this.make_request('history/movements', params, cb)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
past_trades (symbol, options, cb) {
|
|
281
|
+
const params = { symbol }
|
|
282
|
+
|
|
283
|
+
if (typeof options === 'function') {
|
|
284
|
+
cb = options
|
|
285
|
+
} else if (options && options.constructor.name === 'Object') {
|
|
286
|
+
Object.assign(params, options)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return this.make_request('mytrades', params, cb)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
new_deposit (currency, method, wallet_name, cb) {
|
|
293
|
+
return this.make_request('deposit/new', {
|
|
294
|
+
currency,
|
|
295
|
+
method,
|
|
296
|
+
wallet_name
|
|
297
|
+
}, cb)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
new_offer (currency, amount, rate, period, direction, cb) {
|
|
301
|
+
return this.make_request('offer/new', {
|
|
302
|
+
currency,
|
|
303
|
+
amount,
|
|
304
|
+
rate,
|
|
305
|
+
period,
|
|
306
|
+
direction
|
|
307
|
+
}, cb)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
cancel_offer (offer_id, cb) {
|
|
311
|
+
return this.make_request('offer/cancel', {
|
|
312
|
+
offer_id: parseInt(offer_id)
|
|
313
|
+
}, cb)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
offer_status (offer_id, cb) {
|
|
317
|
+
return this.make_request('offer/status', {
|
|
318
|
+
offer_id: parseInt(offer_id)
|
|
319
|
+
}, cb)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
active_offers (cb) {
|
|
323
|
+
return this.make_request('offers', {}, cb)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
active_credits (cb) {
|
|
327
|
+
return this.make_request('credits', {}, cb)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
wallet_balances (cb) {
|
|
331
|
+
return this.make_request('balances', {}, cb)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
taken_swaps (cb) {
|
|
335
|
+
return this.make_request('taken_funds', {}, cb)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
total_taken_swaps (cb) {
|
|
339
|
+
return this.make_request('total_taken_funds', {}, cb)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
close_swap (swap_id, cb) {
|
|
343
|
+
return this.make_request('swap/close', {
|
|
344
|
+
swap_id: parseInt(swap_id)
|
|
345
|
+
}, cb)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
account_infos (cb) {
|
|
349
|
+
return this.make_request('account_infos', {}, cb)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
margin_infos (cb) {
|
|
353
|
+
return this.make_request('margin_infos', {}, cb)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* POST /v1/withdraw
|
|
358
|
+
*
|
|
359
|
+
* @param {string} withdrawType "bitcoin", "litecoin", "darkcoin" or "mastercoin"
|
|
360
|
+
* @param {string} walletSelected origin of the wallet to withdraw from, can be "trading", "exchange", or "deposit"
|
|
361
|
+
* @param {number} amount amount to withdraw
|
|
362
|
+
* @param {string} address destination address for withdrawal
|
|
363
|
+
*/
|
|
364
|
+
withdraw (withdrawType, walletSelected, amount, address, cb) {
|
|
365
|
+
return this.make_request('withdraw', {
|
|
366
|
+
withdrawType,
|
|
367
|
+
walletSelected,
|
|
368
|
+
amount,
|
|
369
|
+
address
|
|
370
|
+
}, cb)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* POST /v1/transfer
|
|
375
|
+
*
|
|
376
|
+
* @param {number} amount amount to transfer
|
|
377
|
+
* @param {string} currency currency of funds to transfer
|
|
378
|
+
* @param {string} walletFrom wallet to transfer from
|
|
379
|
+
* @param {string} walletTo wallet to transfer to
|
|
380
|
+
*/
|
|
381
|
+
transfer (amount, currency, walletFrom, walletTo, cb) {
|
|
382
|
+
return this.make_request('transfer', {
|
|
383
|
+
amount,
|
|
384
|
+
currency,
|
|
385
|
+
walletFrom,
|
|
386
|
+
walletTo
|
|
387
|
+
}, cb)
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
module.exports = RESTv1
|