ccxt 4.2.70 → 4.2.71
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.
- package/README.md +4 -4
- package/build.sh +1 -1
- package/dist/ccxt.browser.js +785 -180
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +3 -1
- package/dist/cjs/src/bitget.js +14 -6
- package/dist/cjs/src/coinbase.js +108 -89
- package/dist/cjs/src/digifinex.js +2 -1
- package/dist/cjs/src/hyperliquid.js +1 -1
- package/dist/cjs/src/kraken.js +1 -0
- package/dist/cjs/src/mexc.js +9 -0
- package/dist/cjs/src/pro/hyperliquid.js +556 -0
- package/js/ccxt.d.ts +4 -1
- package/js/ccxt.js +3 -1
- package/js/src/abstract/coinbase.d.ts +2 -0
- package/js/src/base/types.d.ts +48 -48
- package/js/src/bitget.js +14 -6
- package/js/src/coinbase.d.ts +1 -1
- package/js/src/coinbase.js +108 -89
- package/js/src/digifinex.js +2 -1
- package/js/src/hyperliquid.js +1 -1
- package/js/src/kraken.js +1 -0
- package/js/src/mexc.js +9 -0
- package/js/src/pro/hyperliquid.d.ts +23 -0
- package/js/src/pro/hyperliquid.js +557 -0
- package/package.json +1 -1
- package/skip-tests.json +33 -58
package/dist/cjs/src/kraken.js
CHANGED
|
@@ -1295,6 +1295,7 @@ class kraken extends kraken$1 {
|
|
|
1295
1295
|
const lastTrade = trades[length - 1];
|
|
1296
1296
|
const lastTradeId = this.safeString(result, 'last');
|
|
1297
1297
|
lastTrade.push(lastTradeId);
|
|
1298
|
+
trades[length - 1] = lastTrade;
|
|
1298
1299
|
return this.parseTrades(trades, market, since, limit);
|
|
1299
1300
|
}
|
|
1300
1301
|
parseBalance(response) {
|
package/dist/cjs/src/mexc.js
CHANGED
|
@@ -41,6 +41,7 @@ class mexc extends mexc$1 {
|
|
|
41
41
|
'createMarketSellOrderWithCost': false,
|
|
42
42
|
'createOrder': true,
|
|
43
43
|
'createOrders': true,
|
|
44
|
+
'createPostOnlyOrder': true,
|
|
44
45
|
'createReduceOnlyOrder': true,
|
|
45
46
|
'deposit': undefined,
|
|
46
47
|
'editOrder': undefined,
|
|
@@ -2207,6 +2208,14 @@ class mexc extends mexc$1 {
|
|
|
2207
2208
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2208
2209
|
* @param {string} [params.marginMode] only 'isolated' is supported for spot-margin trading
|
|
2209
2210
|
* @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
|
|
2211
|
+
* @param {bool} [params.postOnly] if true, the order will only be posted if it will be a maker order
|
|
2212
|
+
* @param {bool} [params.reduceOnly] *contract only* indicates if this order is to reduce the size of a position
|
|
2213
|
+
*
|
|
2214
|
+
* EXCHANGE SPECIFIC PARAMETERS
|
|
2215
|
+
* @param {int} [params.leverage] *contract only* leverage is necessary on isolated margin
|
|
2216
|
+
* @param {long} [params.positionId] *contract only* it is recommended to fill in this parameter when closing a position
|
|
2217
|
+
* @param {string} [params.externalOid] *contract only* external order ID
|
|
2218
|
+
* @param {int} [params.positionMode] *contract only* 1:hedge, 2:one-way, default: the user's current config
|
|
2210
2219
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2211
2220
|
*/
|
|
2212
2221
|
await this.loadMarkets();
|
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var hyperliquid$1 = require('../hyperliquid.js');
|
|
4
|
+
var errors = require('../base/errors.js');
|
|
5
|
+
var Cache = require('../base/ws/Cache.js');
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
class hyperliquid extends hyperliquid$1 {
|
|
10
|
+
describe() {
|
|
11
|
+
return this.deepExtend(super.describe(), {
|
|
12
|
+
'has': {
|
|
13
|
+
'ws': true,
|
|
14
|
+
'watchBalance': false,
|
|
15
|
+
'watchMyTrades': true,
|
|
16
|
+
'watchOHLCV': true,
|
|
17
|
+
'watchOrderBook': true,
|
|
18
|
+
'watchOrders': true,
|
|
19
|
+
'watchTicker': false,
|
|
20
|
+
'watchTickers': false,
|
|
21
|
+
'watchTrades': true,
|
|
22
|
+
'watchPosition': false,
|
|
23
|
+
},
|
|
24
|
+
'urls': {
|
|
25
|
+
'api': {
|
|
26
|
+
'ws': {
|
|
27
|
+
'public': 'wss://api.hyperliquid.xyz/ws',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
'test': {
|
|
31
|
+
'ws': {
|
|
32
|
+
'public': 'wss://api.hyperliquid-testnet.xyz/ws',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
'options': {},
|
|
37
|
+
'streaming': {
|
|
38
|
+
'ping': this.ping,
|
|
39
|
+
'keepAlive': 20000,
|
|
40
|
+
},
|
|
41
|
+
'exceptions': {
|
|
42
|
+
'ws': {
|
|
43
|
+
'exact': {},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async watchOrderBook(symbol, limit = undefined, params = {}) {
|
|
49
|
+
/**
|
|
50
|
+
* @method
|
|
51
|
+
* @name hyperliquid#watchOrderBook
|
|
52
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
53
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
54
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
55
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
56
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
57
|
+
*/
|
|
58
|
+
await this.loadMarkets();
|
|
59
|
+
const market = this.market(symbol);
|
|
60
|
+
symbol = market['symbol'];
|
|
61
|
+
const messageHash = 'orderbook:' + symbol;
|
|
62
|
+
const url = this.urls['api']['ws']['public'];
|
|
63
|
+
const request = {
|
|
64
|
+
'method': 'subscribe',
|
|
65
|
+
'subscription': {
|
|
66
|
+
'type': 'l2Book',
|
|
67
|
+
'coin': market['base'],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const message = this.extend(request, params);
|
|
71
|
+
const orderbook = await this.watch(url, messageHash, message, messageHash);
|
|
72
|
+
return orderbook.limit();
|
|
73
|
+
}
|
|
74
|
+
handleOrderBook(client, message) {
|
|
75
|
+
//
|
|
76
|
+
// {
|
|
77
|
+
// "channel": "l2Book",
|
|
78
|
+
// "data": {
|
|
79
|
+
// "coin": "BTC",
|
|
80
|
+
// "time": 1710131872708,
|
|
81
|
+
// "levels": [
|
|
82
|
+
// [
|
|
83
|
+
// {
|
|
84
|
+
// "px": "68674.0",
|
|
85
|
+
// "sz": "0.97139",
|
|
86
|
+
// "n": 4
|
|
87
|
+
// }
|
|
88
|
+
// ],
|
|
89
|
+
// [
|
|
90
|
+
// {
|
|
91
|
+
// "px": "68675.0",
|
|
92
|
+
// "sz": "0.04396",
|
|
93
|
+
// "n": 1
|
|
94
|
+
// }
|
|
95
|
+
// ]
|
|
96
|
+
// ]
|
|
97
|
+
// }
|
|
98
|
+
// }
|
|
99
|
+
//
|
|
100
|
+
const entry = this.safeDict(message, 'data', {});
|
|
101
|
+
const coin = this.safeString(entry, 'coin');
|
|
102
|
+
const marketId = coin + '/USDC:USDC';
|
|
103
|
+
const market = this.market(marketId);
|
|
104
|
+
const symbol = market['symbol'];
|
|
105
|
+
const rawData = this.safeList(entry, 'levels', []);
|
|
106
|
+
const data = {
|
|
107
|
+
'bids': this.safeList(rawData, 0, []),
|
|
108
|
+
'asks': this.safeList(rawData, 1, []),
|
|
109
|
+
};
|
|
110
|
+
const timestamp = this.safeInteger(entry, 'time');
|
|
111
|
+
const snapshot = this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'px', 'sz');
|
|
112
|
+
if (!(symbol in this.orderbooks)) {
|
|
113
|
+
const ob = this.orderBook(snapshot);
|
|
114
|
+
this.orderbooks[symbol] = ob;
|
|
115
|
+
}
|
|
116
|
+
const orderbook = this.orderbooks[symbol];
|
|
117
|
+
orderbook.reset(snapshot);
|
|
118
|
+
const messageHash = 'orderbook:' + symbol;
|
|
119
|
+
client.resolve(orderbook, messageHash);
|
|
120
|
+
}
|
|
121
|
+
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
122
|
+
/**
|
|
123
|
+
* @method
|
|
124
|
+
* @name hyperliquid#watchMyTrades
|
|
125
|
+
* @description watches information on multiple trades made by the user
|
|
126
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
127
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
128
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
129
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
130
|
+
* @param {string} [params.user] user address, will default to this.walletAddress if not provided
|
|
131
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
|
|
132
|
+
*/
|
|
133
|
+
let userAddress = undefined;
|
|
134
|
+
[userAddress, params] = this.handlePublicAddress('watchMyTrades', params);
|
|
135
|
+
await this.loadMarkets();
|
|
136
|
+
let messageHash = 'myTrades';
|
|
137
|
+
if (symbol !== undefined) {
|
|
138
|
+
symbol = this.symbol(symbol);
|
|
139
|
+
messageHash += ':' + symbol;
|
|
140
|
+
}
|
|
141
|
+
const url = this.urls['api']['ws']['public'];
|
|
142
|
+
const request = {
|
|
143
|
+
'method': 'subscribe',
|
|
144
|
+
'subscription': {
|
|
145
|
+
'type': 'userFills',
|
|
146
|
+
'user': userAddress,
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
const message = this.extend(request, params);
|
|
150
|
+
const trades = await this.watch(url, messageHash, message, messageHash);
|
|
151
|
+
if (this.newUpdates) {
|
|
152
|
+
limit = trades.getLimit(symbol, limit);
|
|
153
|
+
}
|
|
154
|
+
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
|
|
155
|
+
}
|
|
156
|
+
handleMyTrades(client, message) {
|
|
157
|
+
//
|
|
158
|
+
// {
|
|
159
|
+
// "channel": "userFills",
|
|
160
|
+
// "data": {
|
|
161
|
+
// "isSnapshot": true,
|
|
162
|
+
// "user": "0x15f43d1f2dee81424afd891943262aa90f22cc2a",
|
|
163
|
+
// "fills": [
|
|
164
|
+
// {
|
|
165
|
+
// "coin": "BTC",
|
|
166
|
+
// "px": "72528.0",
|
|
167
|
+
// "sz": "0.11693",
|
|
168
|
+
// "side": "A",
|
|
169
|
+
// "time": 1710208712815,
|
|
170
|
+
// "startPosition": "0.11693",
|
|
171
|
+
// "dir": "Close Long",
|
|
172
|
+
// "closedPnl": "-0.81851",
|
|
173
|
+
// "hash": "0xc5adaf35f8402750c218040b0a7bc301130051521273b6f398b3caad3e1f3f5f",
|
|
174
|
+
// "oid": 7484888874,
|
|
175
|
+
// "crossed": true,
|
|
176
|
+
// "fee": "2.968244",
|
|
177
|
+
// "liquidationMarkPx": null,
|
|
178
|
+
// "tid": 567547935839686,
|
|
179
|
+
// "cloid": null
|
|
180
|
+
// }
|
|
181
|
+
// ]
|
|
182
|
+
// }
|
|
183
|
+
// }
|
|
184
|
+
//
|
|
185
|
+
const entry = this.safeDict(message, 'data', {});
|
|
186
|
+
if (this.myTrades === undefined) {
|
|
187
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
188
|
+
this.myTrades = new Cache.ArrayCacheBySymbolById(limit);
|
|
189
|
+
}
|
|
190
|
+
const trades = this.myTrades;
|
|
191
|
+
const symbols = {};
|
|
192
|
+
const data = this.safeList(entry, 'fills', []);
|
|
193
|
+
const dataLength = data.length;
|
|
194
|
+
if (dataLength === 0) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
for (let i = 0; i < data.length; i++) {
|
|
198
|
+
const rawTrade = data[i];
|
|
199
|
+
const parsed = this.parseWsTrade(rawTrade);
|
|
200
|
+
const symbol = parsed['symbol'];
|
|
201
|
+
symbols[symbol] = true;
|
|
202
|
+
trades.append(parsed);
|
|
203
|
+
}
|
|
204
|
+
const keys = Object.keys(symbols);
|
|
205
|
+
for (let i = 0; i < keys.length; i++) {
|
|
206
|
+
const currentMessageHash = 'myTrades:' + keys[i];
|
|
207
|
+
client.resolve(trades, currentMessageHash);
|
|
208
|
+
}
|
|
209
|
+
// non-symbol specific
|
|
210
|
+
const messageHash = 'myTrades';
|
|
211
|
+
client.resolve(trades, messageHash);
|
|
212
|
+
}
|
|
213
|
+
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
214
|
+
/**
|
|
215
|
+
* @method
|
|
216
|
+
* @name hyperliquid#watchTrades
|
|
217
|
+
* @description watches information on multiple trades made in a market
|
|
218
|
+
* @param {string} symbol unified market symbol of the market trades were made in
|
|
219
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
220
|
+
* @param {int} [limit] the maximum number of trade structures to retrieve
|
|
221
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
222
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
223
|
+
*/
|
|
224
|
+
await this.loadMarkets();
|
|
225
|
+
const market = this.market(symbol);
|
|
226
|
+
symbol = market['symbol'];
|
|
227
|
+
const messageHash = 'trade:' + symbol;
|
|
228
|
+
const url = this.urls['api']['ws']['public'];
|
|
229
|
+
const request = {
|
|
230
|
+
'method': 'subscribe',
|
|
231
|
+
'subscription': {
|
|
232
|
+
'type': 'trades',
|
|
233
|
+
'coin': market['base'],
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
const message = this.extend(request, params);
|
|
237
|
+
const trades = await this.watch(url, messageHash, message, messageHash);
|
|
238
|
+
if (this.newUpdates) {
|
|
239
|
+
limit = trades.getLimit(symbol, limit);
|
|
240
|
+
}
|
|
241
|
+
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
242
|
+
}
|
|
243
|
+
handleTrades(client, message) {
|
|
244
|
+
//
|
|
245
|
+
// {
|
|
246
|
+
// "channel": "trades",
|
|
247
|
+
// "data": [
|
|
248
|
+
// {
|
|
249
|
+
// "coin": "BTC",
|
|
250
|
+
// "side": "A",
|
|
251
|
+
// "px": "68517.0",
|
|
252
|
+
// "sz": "0.005",
|
|
253
|
+
// "time": 1710125266669,
|
|
254
|
+
// "hash": "0xc872699f116e012186620407fc08a802015e0097c5cce74710697f7272e6e959",
|
|
255
|
+
// "tid": 981894269203506
|
|
256
|
+
// }
|
|
257
|
+
// ]
|
|
258
|
+
// }
|
|
259
|
+
//
|
|
260
|
+
const entry = this.safeList(message, 'data', []);
|
|
261
|
+
const first = this.safeDict(entry, 0, {});
|
|
262
|
+
const coin = this.safeString(first, 'coin');
|
|
263
|
+
const marketId = coin + '/USDC:USDC';
|
|
264
|
+
const market = this.market(marketId);
|
|
265
|
+
const symbol = market['symbol'];
|
|
266
|
+
if (!(symbol in this.trades)) {
|
|
267
|
+
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
268
|
+
const stored = new Cache.ArrayCache(limit);
|
|
269
|
+
this.trades[symbol] = stored;
|
|
270
|
+
}
|
|
271
|
+
const trades = this.trades[symbol];
|
|
272
|
+
for (let i = 0; i < entry.length; i++) {
|
|
273
|
+
const data = this.safeDict(entry, i);
|
|
274
|
+
const trade = this.parseWsTrade(data);
|
|
275
|
+
trades.append(trade);
|
|
276
|
+
}
|
|
277
|
+
const messageHash = 'trade:' + symbol;
|
|
278
|
+
client.resolve(trades, messageHash);
|
|
279
|
+
}
|
|
280
|
+
parseWsTrade(trade, market = undefined) {
|
|
281
|
+
//
|
|
282
|
+
// fetchMyTrades
|
|
283
|
+
//
|
|
284
|
+
// {
|
|
285
|
+
// "coin": "BTC",
|
|
286
|
+
// "px": "72528.0",
|
|
287
|
+
// "sz": "0.11693",
|
|
288
|
+
// "side": "A",
|
|
289
|
+
// "time": 1710208712815,
|
|
290
|
+
// "startPosition": "0.11693",
|
|
291
|
+
// "dir": "Close Long",
|
|
292
|
+
// "closedPnl": "-0.81851",
|
|
293
|
+
// "hash": "0xc5adaf35f8402750c218040b0a7bc301130051521273b6f398b3caad3e1f3f5f",
|
|
294
|
+
// "oid": 7484888874,
|
|
295
|
+
// "crossed": true,
|
|
296
|
+
// "fee": "2.968244",
|
|
297
|
+
// "liquidationMarkPx": null,
|
|
298
|
+
// "tid": 567547935839686,
|
|
299
|
+
// "cloid": null
|
|
300
|
+
// }
|
|
301
|
+
//
|
|
302
|
+
// fetchTrades
|
|
303
|
+
//
|
|
304
|
+
// {
|
|
305
|
+
// "coin": "BTC",
|
|
306
|
+
// "side": "A",
|
|
307
|
+
// "px": "68517.0",
|
|
308
|
+
// "sz": "0.005",
|
|
309
|
+
// "time": 1710125266669,
|
|
310
|
+
// "hash": "0xc872699f116e012186620407fc08a802015e0097c5cce74710697f7272e6e959",
|
|
311
|
+
// "tid": 981894269203506
|
|
312
|
+
// }
|
|
313
|
+
//
|
|
314
|
+
const timestamp = this.safeInteger(trade, 'time');
|
|
315
|
+
const price = this.safeString(trade, 'px');
|
|
316
|
+
const amount = this.safeString(trade, 'sz');
|
|
317
|
+
const coin = this.safeString(trade, 'coin');
|
|
318
|
+
const marketId = coin + '/USDC:USDC';
|
|
319
|
+
market = this.safeMarket(marketId, undefined);
|
|
320
|
+
const symbol = market['symbol'];
|
|
321
|
+
const id = this.safeString(trade, 'tid');
|
|
322
|
+
let side = this.safeString(trade, 'side');
|
|
323
|
+
if (side !== undefined) {
|
|
324
|
+
side = (side === 'A') ? 'sell' : 'buy';
|
|
325
|
+
}
|
|
326
|
+
const fee = this.safeString(trade, 'fee');
|
|
327
|
+
return this.safeTrade({
|
|
328
|
+
'info': trade,
|
|
329
|
+
'timestamp': timestamp,
|
|
330
|
+
'datetime': this.iso8601(timestamp),
|
|
331
|
+
'symbol': symbol,
|
|
332
|
+
'id': id,
|
|
333
|
+
'order': undefined,
|
|
334
|
+
'type': undefined,
|
|
335
|
+
'side': side,
|
|
336
|
+
'takerOrMaker': undefined,
|
|
337
|
+
'price': price,
|
|
338
|
+
'amount': amount,
|
|
339
|
+
'cost': undefined,
|
|
340
|
+
'fee': { 'cost': fee, 'currency': 'USDC' },
|
|
341
|
+
}, market);
|
|
342
|
+
}
|
|
343
|
+
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
344
|
+
/**
|
|
345
|
+
* @method
|
|
346
|
+
* @name hyperliquid#watchOHLCV
|
|
347
|
+
* @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
|
|
348
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
349
|
+
* @param {string} timeframe the length of time each candle represents
|
|
350
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
351
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
352
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
353
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
354
|
+
*/
|
|
355
|
+
await this.loadMarkets();
|
|
356
|
+
const market = this.market(symbol);
|
|
357
|
+
symbol = market['symbol'];
|
|
358
|
+
const url = this.urls['api']['ws']['public'];
|
|
359
|
+
const request = {
|
|
360
|
+
'method': 'subscribe',
|
|
361
|
+
'subscription': {
|
|
362
|
+
'type': 'candle',
|
|
363
|
+
'coin': market['base'],
|
|
364
|
+
'interval': timeframe,
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
const messageHash = 'candles:' + timeframe + ':' + symbol;
|
|
368
|
+
const message = this.extend(request, params);
|
|
369
|
+
const ohlcv = await this.watch(url, messageHash, message, messageHash);
|
|
370
|
+
if (this.newUpdates) {
|
|
371
|
+
limit = ohlcv.getLimit(symbol, limit);
|
|
372
|
+
}
|
|
373
|
+
return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
|
|
374
|
+
}
|
|
375
|
+
handleOHLCV(client, message) {
|
|
376
|
+
//
|
|
377
|
+
// {
|
|
378
|
+
// channel: 'candle',
|
|
379
|
+
// data: {
|
|
380
|
+
// t: 1710146280000,
|
|
381
|
+
// T: 1710146339999,
|
|
382
|
+
// s: 'BTC',
|
|
383
|
+
// i: '1m',
|
|
384
|
+
// o: '71400.0',
|
|
385
|
+
// c: '71411.0',
|
|
386
|
+
// h: '71422.0',
|
|
387
|
+
// l: '71389.0',
|
|
388
|
+
// v: '1.20407',
|
|
389
|
+
// n: 20
|
|
390
|
+
// }
|
|
391
|
+
// }
|
|
392
|
+
//
|
|
393
|
+
const data = this.safeDict(message, 'data', {});
|
|
394
|
+
const base = this.safeString(data, 's');
|
|
395
|
+
const symbol = base + '/USDC:USDC';
|
|
396
|
+
const timeframe = this.safeString(data, 'i');
|
|
397
|
+
if (!(symbol in this.ohlcvs)) {
|
|
398
|
+
this.ohlcvs[symbol] = {};
|
|
399
|
+
}
|
|
400
|
+
if (!(timeframe in this.ohlcvs[symbol])) {
|
|
401
|
+
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
|
|
402
|
+
const stored = new Cache.ArrayCacheByTimestamp(limit);
|
|
403
|
+
this.ohlcvs[symbol][timeframe] = stored;
|
|
404
|
+
}
|
|
405
|
+
const ohlcv = this.ohlcvs[symbol][timeframe];
|
|
406
|
+
const parsed = this.parseOHLCV(data);
|
|
407
|
+
ohlcv.append(parsed);
|
|
408
|
+
const messageHash = 'candles:' + timeframe + ':' + symbol;
|
|
409
|
+
client.resolve(ohlcv, messageHash);
|
|
410
|
+
}
|
|
411
|
+
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
412
|
+
/**
|
|
413
|
+
* @method
|
|
414
|
+
* @name hyperliquid#watchOrders
|
|
415
|
+
* @description watches information on multiple orders made by the user
|
|
416
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
417
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
418
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
419
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
420
|
+
* @param {string} [params.user] user address, will default to this.walletAddress if not provided
|
|
421
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
|
|
422
|
+
*/
|
|
423
|
+
await this.loadMarkets();
|
|
424
|
+
let userAddress = undefined;
|
|
425
|
+
[userAddress, params] = this.handlePublicAddress('watchOrders', params);
|
|
426
|
+
let market = undefined;
|
|
427
|
+
let messageHash = 'order';
|
|
428
|
+
if (symbol !== undefined) {
|
|
429
|
+
market = this.market(symbol);
|
|
430
|
+
symbol = market['symbol'];
|
|
431
|
+
messageHash = messageHash + ':' + symbol;
|
|
432
|
+
}
|
|
433
|
+
const url = this.urls['api']['ws']['public'];
|
|
434
|
+
const request = {
|
|
435
|
+
'method': 'subscribe',
|
|
436
|
+
'subscription': {
|
|
437
|
+
'type': 'orderUpdates',
|
|
438
|
+
'user': userAddress,
|
|
439
|
+
},
|
|
440
|
+
};
|
|
441
|
+
const message = this.extend(request, params);
|
|
442
|
+
const orders = await this.watch(url, messageHash, message, messageHash);
|
|
443
|
+
if (this.newUpdates) {
|
|
444
|
+
limit = orders.getLimit(symbol, limit);
|
|
445
|
+
}
|
|
446
|
+
return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
|
|
447
|
+
}
|
|
448
|
+
handleOrder(client, message) {
|
|
449
|
+
//
|
|
450
|
+
// {
|
|
451
|
+
// channel: 'orderUpdates',
|
|
452
|
+
// data: [
|
|
453
|
+
// {
|
|
454
|
+
// order: {
|
|
455
|
+
// coin: 'BTC',
|
|
456
|
+
// side: 'B',
|
|
457
|
+
// limitPx: '30000.0',
|
|
458
|
+
// sz: '0.001',
|
|
459
|
+
// oid: 7456484275,
|
|
460
|
+
// timestamp: 1710163596492,
|
|
461
|
+
// origSz: '0.001'
|
|
462
|
+
// },
|
|
463
|
+
// status: 'open',
|
|
464
|
+
// statusTimestamp: 1710163596492
|
|
465
|
+
// }
|
|
466
|
+
// ]
|
|
467
|
+
// }
|
|
468
|
+
//
|
|
469
|
+
const data = this.safeList(message, 'data', []);
|
|
470
|
+
if (this.orders === undefined) {
|
|
471
|
+
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
|
|
472
|
+
this.orders = new Cache.ArrayCacheBySymbolById(limit);
|
|
473
|
+
}
|
|
474
|
+
const dataLength = data.length;
|
|
475
|
+
if (dataLength === 0) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const stored = this.orders;
|
|
479
|
+
const messageHash = 'order';
|
|
480
|
+
const marketSymbols = {};
|
|
481
|
+
for (let i = 0; i < data.length; i++) {
|
|
482
|
+
const rawOrder = data[i];
|
|
483
|
+
const order = this.parseOrder(rawOrder);
|
|
484
|
+
stored.append(order);
|
|
485
|
+
const symbol = this.safeString(order, 'symbol');
|
|
486
|
+
marketSymbols[symbol] = true;
|
|
487
|
+
}
|
|
488
|
+
const keys = Object.keys(marketSymbols);
|
|
489
|
+
for (let i = 0; i < keys.length; i++) {
|
|
490
|
+
const symbol = keys[i];
|
|
491
|
+
const innerMessageHash = messageHash + ':' + symbol;
|
|
492
|
+
client.resolve(stored, innerMessageHash);
|
|
493
|
+
}
|
|
494
|
+
client.resolve(stored, messageHash);
|
|
495
|
+
}
|
|
496
|
+
handleErrorMessage(client, message) {
|
|
497
|
+
//
|
|
498
|
+
// {
|
|
499
|
+
// "channel": "error",
|
|
500
|
+
// "data": "Error parsing JSON into valid websocket request: { \"type\": \"allMids\" }"
|
|
501
|
+
// }
|
|
502
|
+
//
|
|
503
|
+
const channel = this.safeString(message, 'channel', '');
|
|
504
|
+
const ret_msg = this.safeString(message, 'data', '');
|
|
505
|
+
if (channel === 'error') {
|
|
506
|
+
throw new errors.ExchangeError(this.id + ' ' + ret_msg);
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
handleMessage(client, message) {
|
|
513
|
+
if (this.handleErrorMessage(client, message)) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const topic = this.safeString(message, 'channel', '');
|
|
517
|
+
const methods = {
|
|
518
|
+
'pong': this.handlePong,
|
|
519
|
+
'trades': this.handleTrades,
|
|
520
|
+
'l2Book': this.handleOrderBook,
|
|
521
|
+
'candle': this.handleOHLCV,
|
|
522
|
+
'orderUpdates': this.handleOrder,
|
|
523
|
+
'userFills': this.handleMyTrades,
|
|
524
|
+
};
|
|
525
|
+
const exacMethod = this.safeValue(methods, topic);
|
|
526
|
+
if (exacMethod !== undefined) {
|
|
527
|
+
exacMethod.call(this, client, message);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const keys = Object.keys(methods);
|
|
531
|
+
for (let i = 0; i < keys.length; i++) {
|
|
532
|
+
const key = keys[i];
|
|
533
|
+
if (topic.indexOf(keys[i]) >= 0) {
|
|
534
|
+
const method = methods[key];
|
|
535
|
+
method.call(this, client, message);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
ping(client) {
|
|
541
|
+
return {
|
|
542
|
+
'method': 'ping',
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
handlePong(client, message) {
|
|
546
|
+
//
|
|
547
|
+
// {
|
|
548
|
+
// "channel": "pong"
|
|
549
|
+
// }
|
|
550
|
+
//
|
|
551
|
+
client.lastPong = this.safeInteger(message, 'pong');
|
|
552
|
+
return message;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
module.exports = hyperliquid;
|
package/js/ccxt.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
|
|
|
4
4
|
import * as errors from './src/base/errors.js';
|
|
5
5
|
import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, Leverage, Leverages } from './src/base/types.js';
|
|
6
6
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
|
|
7
|
-
declare const version = "4.2.
|
|
7
|
+
declare const version = "4.2.70";
|
|
8
8
|
import ace from './src/ace.js';
|
|
9
9
|
import alpaca from './src/alpaca.js';
|
|
10
10
|
import ascendex from './src/ascendex.js';
|
|
@@ -145,6 +145,7 @@ import hollaexPro from './src/pro/hollaex.js';
|
|
|
145
145
|
import htxPro from './src/pro/htx.js';
|
|
146
146
|
import huobiPro from './src/pro/huobi.js';
|
|
147
147
|
import huobijpPro from './src/pro/huobijp.js';
|
|
148
|
+
import hyperliquidPro from './src/pro/hyperliquid.js';
|
|
148
149
|
import idexPro from './src/pro/idex.js';
|
|
149
150
|
import independentreservePro from './src/pro/independentreserve.js';
|
|
150
151
|
import krakenPro from './src/pro/kraken.js';
|
|
@@ -310,6 +311,7 @@ declare const pro: {
|
|
|
310
311
|
htx: typeof htxPro;
|
|
311
312
|
huobi: typeof huobiPro;
|
|
312
313
|
huobijp: typeof huobijpPro;
|
|
314
|
+
hyperliquid: typeof hyperliquidPro;
|
|
313
315
|
idex: typeof idexPro;
|
|
314
316
|
independentreserve: typeof independentreservePro;
|
|
315
317
|
kraken: typeof krakenPro;
|
|
@@ -378,6 +380,7 @@ declare const ccxt: {
|
|
|
378
380
|
htx: typeof htxPro;
|
|
379
381
|
huobi: typeof huobiPro;
|
|
380
382
|
huobijp: typeof huobijpPro;
|
|
383
|
+
hyperliquid: typeof hyperliquidPro;
|
|
381
384
|
idex: typeof idexPro;
|
|
382
385
|
independentreserve: typeof independentreservePro;
|
|
383
386
|
kraken: typeof krakenPro;
|
package/js/ccxt.js
CHANGED
|
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
|
|
|
38
38
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
|
|
39
39
|
//-----------------------------------------------------------------------------
|
|
40
40
|
// this is updated by vss.js when building
|
|
41
|
-
const version = '4.2.
|
|
41
|
+
const version = '4.2.71';
|
|
42
42
|
Exchange.ccxtVersion = version;
|
|
43
43
|
//-----------------------------------------------------------------------------
|
|
44
44
|
import ace from './src/ace.js';
|
|
@@ -182,6 +182,7 @@ import hollaexPro from './src/pro/hollaex.js';
|
|
|
182
182
|
import htxPro from './src/pro/htx.js';
|
|
183
183
|
import huobiPro from './src/pro/huobi.js';
|
|
184
184
|
import huobijpPro from './src/pro/huobijp.js';
|
|
185
|
+
import hyperliquidPro from './src/pro/hyperliquid.js';
|
|
185
186
|
import idexPro from './src/pro/idex.js';
|
|
186
187
|
import independentreservePro from './src/pro/independentreserve.js';
|
|
187
188
|
import krakenPro from './src/pro/kraken.js';
|
|
@@ -347,6 +348,7 @@ const pro = {
|
|
|
347
348
|
'htx': htxPro,
|
|
348
349
|
'huobi': huobiPro,
|
|
349
350
|
'huobijp': huobijpPro,
|
|
351
|
+
'hyperliquid': hyperliquidPro,
|
|
350
352
|
'idex': idexPro,
|
|
351
353
|
'independentreserve': independentreservePro,
|
|
352
354
|
'kraken': krakenPro,
|
|
@@ -69,6 +69,8 @@ interface Exchange {
|
|
|
69
69
|
v3PrivateGetBrokerageIntxPortfolioPortfolioUuid(params?: {}): Promise<implicitReturnType>;
|
|
70
70
|
v3PrivateGetBrokerageIntxPositionsPortfolioUuid(params?: {}): Promise<implicitReturnType>;
|
|
71
71
|
v3PrivateGetBrokerageIntxPositionsPortfolioUuidSymbol(params?: {}): Promise<implicitReturnType>;
|
|
72
|
+
v3PrivateGetBrokeragePaymentMethods(params?: {}): Promise<implicitReturnType>;
|
|
73
|
+
v3PrivateGetBrokeragePaymentMethodsPaymentMethodId(params?: {}): Promise<implicitReturnType>;
|
|
72
74
|
v3PrivatePostBrokerageOrders(params?: {}): Promise<implicitReturnType>;
|
|
73
75
|
v3PrivatePostBrokerageOrdersBatchCancel(params?: {}): Promise<implicitReturnType>;
|
|
74
76
|
v3PrivatePostBrokerageOrdersEdit(params?: {}): Promise<implicitReturnType>;
|