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,275 @@
|
|
|
1
|
+
/* eslint-env mocha */
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
const PORT = 1337
|
|
5
|
+
|
|
6
|
+
const assert = require('assert')
|
|
7
|
+
|
|
8
|
+
const WebSocket = require('ws')
|
|
9
|
+
const WSv1 = require('../../../lib/transports/ws')
|
|
10
|
+
|
|
11
|
+
const orderbookR0 = require('../../fixtures/response-ws-1-orderbook-R0.json')
|
|
12
|
+
|
|
13
|
+
const getWSInstance = () => {
|
|
14
|
+
return new WSv1({
|
|
15
|
+
apiKey: 'dummy',
|
|
16
|
+
apiSecret: 'dummy',
|
|
17
|
+
url: `ws://localhost:${PORT}`
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe('WebSocket v1 integration', () => {
|
|
22
|
+
it('plays ping pong', (done) => {
|
|
23
|
+
const wss = new WebSocket.Server({
|
|
24
|
+
perMessageDeflate: false,
|
|
25
|
+
port: PORT
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const bws = getWSInstance()
|
|
29
|
+
bws.open()
|
|
30
|
+
|
|
31
|
+
wss.on('connection', function connection (ws) {
|
|
32
|
+
ws.on('message', function incoming (msg) {
|
|
33
|
+
ws.send('{"event":"pong"}')
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
bws.on('open', () => {
|
|
38
|
+
bws.send({ event: 'ping' })
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
bws.on('pong', () => {
|
|
42
|
+
bws.close()
|
|
43
|
+
wss.close(done)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('should receive info message', (done) => {
|
|
48
|
+
const wss = new WebSocket.Server({
|
|
49
|
+
perMessageDeflate: false,
|
|
50
|
+
port: PORT
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const bws = getWSInstance()
|
|
54
|
+
bws.open()
|
|
55
|
+
|
|
56
|
+
wss.on('connection', function connection (ws) {
|
|
57
|
+
ws.send('{"event": "info", "version": 1.1 }')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
bws.on('info', (data) => {
|
|
61
|
+
assert.deepEqual(
|
|
62
|
+
data,
|
|
63
|
+
{
|
|
64
|
+
event: 'info',
|
|
65
|
+
version: 1.1
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
bws.close()
|
|
69
|
+
wss.close(done)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('should emit an error when authorization fails', (done) => {
|
|
74
|
+
const wss = new WebSocket.Server({
|
|
75
|
+
perMessageDeflate: false,
|
|
76
|
+
port: PORT
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const bws = getWSInstance()
|
|
80
|
+
bws.open()
|
|
81
|
+
|
|
82
|
+
wss.on('connection', function connection (ws) {
|
|
83
|
+
ws.on('message', function incoming (msg) {
|
|
84
|
+
ws.send('{"event":"auth","status":"FAILED","chanId":0,"code":10100,"msg":"apikey: invalid"}')
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
bws.on('error', (err) => {
|
|
89
|
+
assert.equal(err.event, 'auth')
|
|
90
|
+
bws.close()
|
|
91
|
+
wss.close(done)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
bws.on('open', () => {
|
|
95
|
+
bws.auth()
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should unsubscribe by channelId', function (done) {
|
|
100
|
+
const wss = new WebSocket.Server({
|
|
101
|
+
perMessageDeflate: false,
|
|
102
|
+
port: PORT
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const bws = getWSInstance()
|
|
106
|
+
bws.open()
|
|
107
|
+
|
|
108
|
+
wss.on('connection', function connection (ws) {
|
|
109
|
+
ws.on('message', function incoming (msg) {
|
|
110
|
+
msg = JSON.parse(msg)
|
|
111
|
+
if (msg.event === 'unsubscribe') {
|
|
112
|
+
ws.send('{"event":"unsubscribed","status":"OK","chanId":4}')
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
ws.send('{"event":"subscribed","channel":"ticker","chanId":4,"pair":"BTCUSD"}')
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
bws.once('subscribed', (data) => {
|
|
121
|
+
const channelId = data.chanId
|
|
122
|
+
|
|
123
|
+
bws.once('unsubscribed', (data) => {
|
|
124
|
+
assert.equal(data.status, 'OK')
|
|
125
|
+
assert.equal(data.chanId, channelId)
|
|
126
|
+
bws.close()
|
|
127
|
+
wss.close(done)
|
|
128
|
+
})
|
|
129
|
+
bws.unsubscribe(channelId)
|
|
130
|
+
})
|
|
131
|
+
bws.on('open', () => {
|
|
132
|
+
bws.subscribeTicker('BTCUSD')
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('should receive a subscribed success messages', (done) => {
|
|
137
|
+
const wss = new WebSocket.Server({
|
|
138
|
+
perMessageDeflate: false,
|
|
139
|
+
port: PORT
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const bws = getWSInstance()
|
|
143
|
+
bws.open()
|
|
144
|
+
|
|
145
|
+
wss.on('connection', function connection (ws) {
|
|
146
|
+
ws.on('message', function incoming (msg) {
|
|
147
|
+
ws.send('{"event":"subscribed","channel":"trades","chanId":4,"pair":"BTCUSD"}')
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
bws.on('subscribed', (data) => {
|
|
152
|
+
assert.equal(data.channel, 'trades')
|
|
153
|
+
assert.equal(data.pair, 'BTCUSD')
|
|
154
|
+
bws.close()
|
|
155
|
+
wss.close(done)
|
|
156
|
+
})
|
|
157
|
+
bws.on('open', () => {
|
|
158
|
+
bws.subscribeTrades('BTCUSD')
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it('#orderBook data should have the defined fields', (done) => {
|
|
163
|
+
const wss = new WebSocket.Server({
|
|
164
|
+
perMessageDeflate: false,
|
|
165
|
+
port: PORT
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
wss.on('connection', function connection (ws) {
|
|
169
|
+
ws.on('message', function incoming (msg) {
|
|
170
|
+
ws.send('{"event":"subscribed","channel":"book","chanId":13242,"prec":"R0","freq":"F0","len":"25","pair":"BTCUSD"}')
|
|
171
|
+
ws.send(JSON.stringify(orderbookR0))
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
const bws = getWSInstance()
|
|
176
|
+
bws.open()
|
|
177
|
+
|
|
178
|
+
bws.once('orderbook', (pair, data) => {
|
|
179
|
+
assert.equal(pair, 'BTCUSD')
|
|
180
|
+
assert.equal(typeof data[0].price, 'number')
|
|
181
|
+
assert.equal(typeof data[0].orderId, 'number')
|
|
182
|
+
assert.equal(typeof data[0].amount, 'number')
|
|
183
|
+
assert.equal(data.length, 50)
|
|
184
|
+
bws.close()
|
|
185
|
+
wss.close(done)
|
|
186
|
+
})
|
|
187
|
+
bws.on('open', () => {
|
|
188
|
+
bws.subscribeOrderBook('BTCUSD')
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('#ticker data should have the defined fields', (done) => {
|
|
193
|
+
const wss = new WebSocket.Server({
|
|
194
|
+
perMessageDeflate: false,
|
|
195
|
+
port: PORT
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
wss.on('connection', function connection (ws) {
|
|
199
|
+
ws.send('{"event":"info","version":1.1}')
|
|
200
|
+
ws.on('message', function incoming (msg) {
|
|
201
|
+
ws.send('{"event":"subscribed","channel":"ticker","chanId":4,"pair":"BTCUSD"}')
|
|
202
|
+
ws.send('[4,2169.6,1.93,2169.8,0.0349,100.9,0.0488,2169.6,25479.40978657,2196,2000.1]')
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
const bws = getWSInstance()
|
|
207
|
+
bws.open()
|
|
208
|
+
|
|
209
|
+
bws.once('ticker', (pair, data) => {
|
|
210
|
+
assert.equal(pair, 'BTCUSD')
|
|
211
|
+
assert.equal(typeof data.bid, 'number')
|
|
212
|
+
assert.equal(typeof data.bidSize, 'number')
|
|
213
|
+
assert.equal(typeof data.ask, 'number')
|
|
214
|
+
assert.equal(typeof data.askSize, 'number')
|
|
215
|
+
assert.equal(typeof data.dailyChange, 'number')
|
|
216
|
+
assert.equal(typeof data.dailyChangePerc, 'number')
|
|
217
|
+
assert.equal(typeof data.lastPrice, 'number')
|
|
218
|
+
assert.equal(typeof data.volume, 'number')
|
|
219
|
+
assert.equal(typeof data.high, 'number')
|
|
220
|
+
assert.equal(typeof data.low, 'number')
|
|
221
|
+
bws.close()
|
|
222
|
+
wss.close(done)
|
|
223
|
+
})
|
|
224
|
+
bws.on('open', () => {
|
|
225
|
+
bws.subscribeTicker('BTCUSD')
|
|
226
|
+
})
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
it('#trade data should have the defined fields', (done) => {
|
|
230
|
+
const wss = new WebSocket.Server({
|
|
231
|
+
perMessageDeflate: false,
|
|
232
|
+
port: PORT
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
wss.on('connection', function connection (ws) {
|
|
236
|
+
ws.send('{"event":"info","version":1.1}')
|
|
237
|
+
ws.on('message', function incoming (msg) {
|
|
238
|
+
ws.send('{"event":"subscribed","channel":"trades","chanId":33,"pair":"BTCUSD"}')
|
|
239
|
+
ws.send(`
|
|
240
|
+
[33,[[32970704,1495442718,2169.1,0.03647196],[32970701,1495442718,2169.1,0.01058338],
|
|
241
|
+
[32970697,1495442717,2169,-0.0000791],[32970696,1495442717,2169,-0.01054738],
|
|
242
|
+
[32970692,1495442716,2169,-0.01063712],[32970683,1495442715,2169,-0.00191556],
|
|
243
|
+
[32970682,1495442715,2169,-0.02003456],[32970681,1495442715,2169,-0.02002811],
|
|
244
|
+
[32970680,1495442715,2169,-0.01079782],[32970679,1495442715,2169,-0.02002726],
|
|
245
|
+
[32970678,1495442715,2169,-0.01079782],[32970662,1495442714,2169,-3.68585828],
|
|
246
|
+
[32970654,1495442712,2169,-0.01413205],[32970646,1495442711,2169,-0.01066102],
|
|
247
|
+
[32970643,1495442710,2169,-0.02002146],[32970640,1495442709,2169,-0.01727607],
|
|
248
|
+
[32970631,1495442708,2169,-0.00984518],[32970629,1495442708,2169,-1.07188465],
|
|
249
|
+
[32970618,1495442706,2169,-0.0995877],[32970613,1495442706,2169,-0.015553],
|
|
250
|
+
[32970595,1495442702,2169,-0.00864857],[32970593,1495442702,2169,-0.01999732],
|
|
251
|
+
[32970592,1495442702,2169,-0.01067048],[32970591,1495442702,2169.1,0.92541262],
|
|
252
|
+
[32970590,1495442702,2169.1,0.9787866],[32970589,1495442702,2169,-0.01067048],
|
|
253
|
+
[32970573,1495442702,2169,-0.01067048],[32970572,1495442702,2169,-0.0172659],
|
|
254
|
+
[32970569,1495442701,2169,-0.02000913],[32970567,1495442701,2169,-0.01413205]]]
|
|
255
|
+
`)
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
const bws = getWSInstance()
|
|
260
|
+
bws.open()
|
|
261
|
+
|
|
262
|
+
bws.once('trade', (pair, data) => {
|
|
263
|
+
assert.equal(pair, 'BTCUSD')
|
|
264
|
+
assert.equal(typeof data[0].seq, 'number')
|
|
265
|
+
assert.equal(typeof data[0].timestamp, 'number')
|
|
266
|
+
assert.equal(typeof data[0].price, 'number')
|
|
267
|
+
assert.equal(typeof data[0].amount, 'number')
|
|
268
|
+
bws.close()
|
|
269
|
+
wss.close(done)
|
|
270
|
+
})
|
|
271
|
+
bws.on('open', () => {
|
|
272
|
+
bws.subscribeTrades('BTCUSD')
|
|
273
|
+
})
|
|
274
|
+
})
|
|
275
|
+
})
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/* eslint-env mocha */
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
const assert = require('assert')
|
|
5
|
+
const WSv2 = require('../../../lib/transports/ws2')
|
|
6
|
+
const { Order } = require('../../../lib/models')
|
|
7
|
+
const { MockWSv2Server } = require('bfx-api-mock-srv')
|
|
8
|
+
|
|
9
|
+
const API_KEY = 'dummy'
|
|
10
|
+
const API_SECRET = 'dummy'
|
|
11
|
+
|
|
12
|
+
const createTestWSv2Instance = (params = {}) => {
|
|
13
|
+
return new WSv2(Object.assign({
|
|
14
|
+
apiKey: API_KEY,
|
|
15
|
+
apiSecret: API_SECRET,
|
|
16
|
+
url: 'ws://localhost:9997'
|
|
17
|
+
}, params))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe('WSv2 orders', () => {
|
|
21
|
+
it('creates & confirms orders', (done) => {
|
|
22
|
+
const wss = new MockWSv2Server({ listen: true })
|
|
23
|
+
const ws = createTestWSv2Instance()
|
|
24
|
+
ws.open()
|
|
25
|
+
ws.on('open', ws.auth.bind(ws))
|
|
26
|
+
ws.once('auth', () => {
|
|
27
|
+
const o = new Order({
|
|
28
|
+
gid: null,
|
|
29
|
+
cid: 0,
|
|
30
|
+
type: 'EXCHANGE LIMIT',
|
|
31
|
+
price: 100,
|
|
32
|
+
amount: 1,
|
|
33
|
+
symbol: 'tBTCUSD'
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
ws.submitOrder(o).then(() => {
|
|
37
|
+
wss.close()
|
|
38
|
+
done()
|
|
39
|
+
}).catch(done)
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('keeps orders up to date', (done) => {
|
|
44
|
+
const wss = new MockWSv2Server({ listen: true })
|
|
45
|
+
const ws = createTestWSv2Instance()
|
|
46
|
+
ws.on('open', ws.auth.bind(ws))
|
|
47
|
+
|
|
48
|
+
ws.once('auth', () => {
|
|
49
|
+
const o = new Order({
|
|
50
|
+
gid: null,
|
|
51
|
+
cid: 0,
|
|
52
|
+
type: 'EXCHANGE LIMIT',
|
|
53
|
+
price: 100,
|
|
54
|
+
amount: 1,
|
|
55
|
+
symbol: 'tBTCUSD'
|
|
56
|
+
}, ws)
|
|
57
|
+
|
|
58
|
+
o.registerListeners()
|
|
59
|
+
|
|
60
|
+
o.submit().then(() => {
|
|
61
|
+
const arr = o.serialize()
|
|
62
|
+
arr[16] = 256
|
|
63
|
+
|
|
64
|
+
wss.send([0, 'ou', arr])
|
|
65
|
+
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
assert.equal(o.price, 256)
|
|
68
|
+
arr[16] = 150
|
|
69
|
+
|
|
70
|
+
wss.send([0, 'oc', arr])
|
|
71
|
+
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
assert.equal(o.price, 150)
|
|
74
|
+
o.removeListeners()
|
|
75
|
+
wss.close()
|
|
76
|
+
done()
|
|
77
|
+
}, 100)
|
|
78
|
+
}, 100)
|
|
79
|
+
}).catch(done)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
ws.open()
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('sends individual order packets when not buffering', (done) => {
|
|
86
|
+
const wss = new MockWSv2Server()
|
|
87
|
+
const wsSingle = createTestWSv2Instance()
|
|
88
|
+
wsSingle.open()
|
|
89
|
+
wsSingle.on('open', wsSingle.auth.bind(wsSingle))
|
|
90
|
+
wsSingle.once('auth', () => {
|
|
91
|
+
const oA = new Order({
|
|
92
|
+
gid: null,
|
|
93
|
+
cid: Date.now(),
|
|
94
|
+
type: 'EXCHANGE LIMIT',
|
|
95
|
+
price: 100,
|
|
96
|
+
amount: 1,
|
|
97
|
+
symbol: 'tBTCUSD'
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const oB = new Order({
|
|
101
|
+
gid: null,
|
|
102
|
+
cid: Date.now(),
|
|
103
|
+
type: 'EXCHANGE LIMIT',
|
|
104
|
+
price: 10,
|
|
105
|
+
amount: 1,
|
|
106
|
+
symbol: 'tETHUSD'
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
let sendN = 0
|
|
110
|
+
|
|
111
|
+
wsSingle._ws.send = (msgJSON) => {
|
|
112
|
+
const msg = JSON.parse(msgJSON)
|
|
113
|
+
assert.equal(msg[1], 'on')
|
|
114
|
+
sendN++
|
|
115
|
+
|
|
116
|
+
if (sendN === 2) {
|
|
117
|
+
wss.close()
|
|
118
|
+
done()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
wsSingle.submitOrder(oA)
|
|
123
|
+
wsSingle.submitOrder(oB)
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('buffers order packets', (done) => {
|
|
128
|
+
const wss = new MockWSv2Server()
|
|
129
|
+
const wsMulti = createTestWSv2Instance({
|
|
130
|
+
orderOpBufferDelay: 100
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
wsMulti.open()
|
|
134
|
+
wsMulti.on('open', wsMulti.auth.bind(wsMulti))
|
|
135
|
+
wsMulti.once('auth', () => {
|
|
136
|
+
const oA = new Order({
|
|
137
|
+
gid: null,
|
|
138
|
+
cid: Date.now(),
|
|
139
|
+
type: 'EXCHANGE LIMIT',
|
|
140
|
+
price: 100,
|
|
141
|
+
amount: 1,
|
|
142
|
+
symbol: 'tBTCUSD'
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const oB = new Order({
|
|
146
|
+
gid: null,
|
|
147
|
+
cid: Date.now(),
|
|
148
|
+
type: 'EXCHANGE LIMIT',
|
|
149
|
+
price: 10,
|
|
150
|
+
amount: 1,
|
|
151
|
+
symbol: 'tETHUSD'
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
wsMulti._ws.send = (msgJSON) => {
|
|
155
|
+
const msg = JSON.parse(msgJSON)
|
|
156
|
+
assert.equal(msg[1], 'ox_multi')
|
|
157
|
+
|
|
158
|
+
msg[3].forEach((payload) => {
|
|
159
|
+
assert.equal(payload[0], 'on')
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
wss.close()
|
|
163
|
+
done()
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
wsMulti.submitOrder(oA)
|
|
167
|
+
wsMulti.submitOrder(oB)
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
describe('WSv2 listeners', () => {
|
|
173
|
+
it('manages listeners by cbGID', () => {
|
|
174
|
+
const ws = createTestWSv2Instance()
|
|
175
|
+
ws._channelMap = { 0: { channel: 'auth' } }
|
|
176
|
+
|
|
177
|
+
let updatesSeen = 0
|
|
178
|
+
ws.onTradeUpdate({ pair: 'tBTCUSD', cbGID: 10 }, () => updatesSeen++)
|
|
179
|
+
ws.onOrderUpdate({ symbol: 'tBTCUSD', cbGID: 10 }, () => updatesSeen++)
|
|
180
|
+
|
|
181
|
+
ws._handleChannelMessage([0, 'tu', ['tBTCUSD']])
|
|
182
|
+
ws._handleChannelMessage([0, 'ou', [0, 0, 0, 'tBTCUSD']])
|
|
183
|
+
ws.removeListeners(10)
|
|
184
|
+
ws._handleChannelMessage([0, 'tu', ['tBTCUSD']])
|
|
185
|
+
ws._handleChannelMessage([0, 'ou', [0, 0, 0, 'tBTCUSD']])
|
|
186
|
+
|
|
187
|
+
assert.equal(updatesSeen, 2)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('tracks channel refs to auto sub/unsub', (done) => {
|
|
191
|
+
const ws = createTestWSv2Instance()
|
|
192
|
+
const wss = new MockWSv2Server()
|
|
193
|
+
let subs = 0
|
|
194
|
+
let unsubs = 0
|
|
195
|
+
|
|
196
|
+
wss.on('message', (ws, msg) => {
|
|
197
|
+
if (msg.event === 'subscribe' && msg.channel === 'trades') {
|
|
198
|
+
subs++
|
|
199
|
+
ws.send(JSON.stringify({
|
|
200
|
+
event: 'subscribed',
|
|
201
|
+
chanId: 42,
|
|
202
|
+
channel: 'trades',
|
|
203
|
+
symbol: msg.symbol
|
|
204
|
+
}))
|
|
205
|
+
} else if (msg.event === 'unsubscribe' && msg.chanId === 42) {
|
|
206
|
+
unsubs++
|
|
207
|
+
ws.send(JSON.stringify({
|
|
208
|
+
event: 'unsubscribed',
|
|
209
|
+
chanId: 42
|
|
210
|
+
}))
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
ws.on('open', () => {
|
|
215
|
+
ws.subscribeTrades('tBTCUSD')
|
|
216
|
+
ws.subscribeTrades('tBTCUSD')
|
|
217
|
+
ws.subscribeTrades('tBTCUSD')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
ws.on('subscribed', () => {
|
|
221
|
+
ws.unsubscribeTrades('tBTCUSD')
|
|
222
|
+
ws.unsubscribeTrades('tBTCUSD')
|
|
223
|
+
ws.unsubscribeTrades('tBTCUSD')
|
|
224
|
+
ws.unsubscribeTrades('tBTCUSD')
|
|
225
|
+
ws.unsubscribeTrades('tBTCUSD')
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
ws.on('unsubscribed', () => {
|
|
229
|
+
assert.equal(subs, 1)
|
|
230
|
+
assert.equal(unsubs, 1)
|
|
231
|
+
wss.close()
|
|
232
|
+
done()
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
ws.open()
|
|
236
|
+
})
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
describe('WSv2 info message handling', () => {
|
|
240
|
+
it('notifies listeners on matching code', (done) => {
|
|
241
|
+
const ws = new WSv2()
|
|
242
|
+
|
|
243
|
+
ws.onInfoMessage(WSv2.info.MAINTENANCE_END, () => {
|
|
244
|
+
done()
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
ws._onWSMessage(JSON.stringify({
|
|
248
|
+
event: 'info',
|
|
249
|
+
code: WSv2.info.MAINTENANCE_START,
|
|
250
|
+
msg: ''
|
|
251
|
+
}))
|
|
252
|
+
|
|
253
|
+
ws._onWSMessage(JSON.stringify({
|
|
254
|
+
event: 'info',
|
|
255
|
+
code: WSv2.info.MAINTENANCE_END,
|
|
256
|
+
msg: ''
|
|
257
|
+
}))
|
|
258
|
+
})
|
|
259
|
+
})
|