@lynx-crypto/kraken-api 0.2.0 → 1.0.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.
- package/README.md +214 -177
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1717 -489
- package/dist/index.d.ts +1717 -489
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +35 -3
package/README.md
CHANGED
|
@@ -8,98 +8,247 @@
|
|
|
8
8
|
[](https://github.com/lynx-laboratory/kraken-api/commits/master)
|
|
9
9
|
[](./LICENSE.md)
|
|
10
10
|
|
|
11
|
-
TypeScript client for **Kraken
|
|
12
|
-
|
|
11
|
+
A modern, strongly-typed TypeScript client for the **Kraken Spot API**, providing both **REST** and **WebSocket v2** access in a single package.
|
|
13
12
|
- **REST API** (public + private endpoints)
|
|
14
13
|
- **WebSocket v2** (public market-data + authenticated user-data/trading)
|
|
15
14
|
|
|
16
15
|
See [Kraken Official Documentation](https://docs.kraken.com/api/docs/category/guides)
|
|
17
16
|
|
|
18
17
|
## Important
|
|
19
|
-
|
|
20
18
|
- This package is currently **SPOT only**. It does **not** implement Kraken Futures.
|
|
21
19
|
- Unofficial project. Not affiliated with Kraken.
|
|
22
20
|
|
|
23
21
|
---
|
|
24
22
|
|
|
25
|
-
##
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
### Spot REST API
|
|
26
|
+
- Public market data (time, assets, pairs, ticker, OHLC, order book, trades, spreads)
|
|
27
|
+
- Private account data (balances, orders, trades, ledgers, export reports)
|
|
28
|
+
- Trading endpoints (add/amend/edit/cancel orders, batch operations)
|
|
29
|
+
- Funding endpoints (deposits, withdrawals, transfers)
|
|
30
|
+
- Earn endpoints (strategies, allocations, status)
|
|
31
|
+
- Subaccounts (master account operations)
|
|
32
|
+
- Transparency endpoints (pre-trade / post-trade data)
|
|
33
|
+
|
|
34
|
+
### Spot WebSocket v2 API
|
|
35
|
+
- Public streams (ticker, trades, book, OHLC, instruments)
|
|
36
|
+
- Private user streams (balances, executions)
|
|
37
|
+
- Private trading RPC methods
|
|
38
|
+
- Automatic request/response correlation (`req_id`)
|
|
39
|
+
- Optional auto-reconnect with backoff
|
|
40
|
+
- Works in Node.js (via `ws`) or browser environments
|
|
26
41
|
|
|
27
|
-
|
|
28
|
-
`npm i @lynx-crypto/kraken-api`
|
|
42
|
+
---
|
|
29
43
|
|
|
30
|
-
|
|
31
|
-
`yarn add @lynx-crypto/kraken-api`
|
|
44
|
+
## Installation
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
`pnpm add @lynx-crypto/kraken-api`
|
|
46
|
+
Using Yarn:
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
```sh
|
|
49
|
+
yarn add @lynx-crypto/kraken-api
|
|
50
|
+
```
|
|
37
51
|
|
|
38
|
-
|
|
52
|
+
Using npm:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npm install @lynx-crypto/kraken-api
|
|
56
|
+
```
|
|
39
57
|
|
|
40
58
|
---
|
|
41
59
|
|
|
42
|
-
##
|
|
60
|
+
## Requirements
|
|
43
61
|
|
|
44
|
-
|
|
62
|
+
- Node.js 18+ recommended
|
|
63
|
+
- TypeScript 4.9+ recommended
|
|
64
|
+
- For private endpoints:
|
|
65
|
+
- Kraken API key and secret
|
|
66
|
+
- Appropriate permissions enabled in Kraken
|
|
67
|
+
- “WebSocket interface” enabled for private WS usage
|
|
45
68
|
|
|
46
|
-
|
|
47
|
-
import {
|
|
48
|
-
KrakenSpotRestClient,
|
|
49
|
-
KrakenSpotWebsocketV2Client,
|
|
50
|
-
} from '@lynx-crypto/kraken-api';
|
|
51
|
-
```
|
|
69
|
+
---
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
## Environment Variables (for private usage)
|
|
54
72
|
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
KrakenSpotWebsocketV2Client,
|
|
59
|
-
} = require('@lynx-crypto/kraken-api');
|
|
73
|
+
```bash
|
|
74
|
+
KRAKEN_API_KEY="your_api_key"
|
|
75
|
+
KRAKEN_API_SECRET="your_api_secret"
|
|
60
76
|
```
|
|
61
77
|
|
|
62
78
|
---
|
|
63
79
|
|
|
64
|
-
##
|
|
80
|
+
## Package Exports
|
|
81
|
+
|
|
82
|
+
### REST
|
|
83
|
+
- `KrakenSpotRestClient`
|
|
84
|
+
|
|
85
|
+
Sub-APIs available on the client:
|
|
86
|
+
- `marketData`
|
|
87
|
+
- `accountData`
|
|
88
|
+
- `trading`
|
|
89
|
+
- `funding`
|
|
90
|
+
- `subaccounts`
|
|
91
|
+
- `earn`
|
|
92
|
+
- `transparency`
|
|
65
93
|
|
|
66
|
-
###
|
|
94
|
+
### WebSocket
|
|
95
|
+
- `KrakenSpotWebsocketV2Client`
|
|
96
|
+
- `KrakenWebsocketBase` (advanced / custom integrations)
|
|
97
|
+
|
|
98
|
+
Typed channel namespaces:
|
|
99
|
+
- `admin`
|
|
100
|
+
- `marketData`
|
|
101
|
+
- `userData`
|
|
102
|
+
- `userTrading`
|
|
103
|
+
|
|
104
|
+
All public request/response and stream payloads are exported as TypeScript types.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
## REST Usage
|
|
108
|
+
|
|
109
|
+
### Public REST example (no authentication)
|
|
67
110
|
|
|
68
111
|
```ts
|
|
69
|
-
|
|
70
|
-
// Optional:
|
|
71
|
-
// baseUrl: "https://api.kraken.com",
|
|
72
|
-
// timeoutMs: 10_000,
|
|
73
|
-
// userAgent: "my-app/1.0.0",
|
|
112
|
+
import { KrakenSpotRestClient } from '@lynx-crypto/kraken-api';
|
|
74
113
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
114
|
+
async function main() {
|
|
115
|
+
const kraken = new KrakenSpotRestClient({
|
|
116
|
+
userAgent: 'example-app/1.0.0',
|
|
117
|
+
});
|
|
78
118
|
|
|
79
|
-
|
|
80
|
-
|
|
119
|
+
const time = await kraken.marketData.getServerTime();
|
|
120
|
+
console.log('Kraken time:', time.rfc1123);
|
|
121
|
+
}
|
|
81
122
|
|
|
82
|
-
|
|
83
|
-
|
|
123
|
+
main().catch((err) => {
|
|
124
|
+
console.error(err);
|
|
125
|
+
process.exitCode = 1;
|
|
84
126
|
});
|
|
85
127
|
```
|
|
86
128
|
|
|
87
|
-
###
|
|
129
|
+
### Private REST example (authenticated)
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import 'dotenv/config';
|
|
133
|
+
import { KrakenSpotRestClient } from '@lynx-crypto/kraken-api';
|
|
134
|
+
|
|
135
|
+
function requireEnv(name: string): string {
|
|
136
|
+
const v = process.env[name];
|
|
137
|
+
if (!v) throw new Error(`Missing env var: ${name}`);
|
|
138
|
+
return v;
|
|
139
|
+
}
|
|
88
140
|
|
|
89
|
-
|
|
141
|
+
async function main() {
|
|
142
|
+
const kraken = new KrakenSpotRestClient({
|
|
143
|
+
userAgent: 'example-app/1.0.0',
|
|
144
|
+
apiKey: requireEnv('KRAKEN_API_KEY'),
|
|
145
|
+
apiSecret: requireEnv('KRAKEN_API_SECRET'),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const balances = await kraken.accountData.getAccountBalance();
|
|
149
|
+
console.log('Asset count:', Object.keys(balances).length);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
main().catch((err) => {
|
|
153
|
+
console.error(err);
|
|
154
|
+
process.exitCode = 1;
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## WebSocket v2 Usage
|
|
161
|
+
|
|
162
|
+
### Public WebSocket (market data)
|
|
90
163
|
|
|
91
164
|
```ts
|
|
92
|
-
|
|
93
|
-
|
|
165
|
+
import { KrakenSpotWebsocketV2Client } from '@lynx-crypto/kraken-api';
|
|
166
|
+
|
|
167
|
+
async function main() {
|
|
168
|
+
const wsClient = new KrakenSpotWebsocketV2Client({
|
|
169
|
+
autoReconnect: false,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
await wsClient.publicConnection.connect();
|
|
173
|
+
|
|
174
|
+
const ack = await wsClient.marketData.subscribeTrade(
|
|
175
|
+
{ symbol: ['BTC/USD'], snapshot: true },
|
|
176
|
+
{ reqId: 1 },
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
if (!ack.success) {
|
|
180
|
+
throw new Error(`Subscribe failed: ${ack.error}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const unsubscribe = wsClient.publicConnection.addMessageHandler((msg) => {
|
|
184
|
+
console.log(JSON.stringify(msg));
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
setTimeout(() => {
|
|
188
|
+
unsubscribe();
|
|
189
|
+
wsClient.publicConnection.close(1000, 'example done');
|
|
190
|
+
}, 20_000);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
main().catch((err) => {
|
|
194
|
+
console.error(err);
|
|
195
|
+
process.exitCode = 1;
|
|
196
|
+
});
|
|
94
197
|
```
|
|
95
198
|
|
|
96
|
-
### Private
|
|
199
|
+
### Private WebSocket (balances / executions)
|
|
97
200
|
|
|
98
|
-
|
|
201
|
+
Authenticated WebSocket usage requires a token obtained via REST.
|
|
99
202
|
|
|
100
203
|
```ts
|
|
101
|
-
|
|
102
|
-
|
|
204
|
+
import 'dotenv/config';
|
|
205
|
+
import {
|
|
206
|
+
KrakenSpotRestClient,
|
|
207
|
+
KrakenSpotWebsocketV2Client,
|
|
208
|
+
} from '@lynx-crypto/kraken-api';
|
|
209
|
+
|
|
210
|
+
function requireEnv(name: string): string {
|
|
211
|
+
const v = process.env[name];
|
|
212
|
+
if (!v) throw new Error(`Missing env var: ${name}`);
|
|
213
|
+
return v;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function main() {
|
|
217
|
+
const rest = new KrakenSpotRestClient({
|
|
218
|
+
userAgent: 'example-app/1.0.0',
|
|
219
|
+
apiKey: requireEnv('KRAKEN_API_KEY'),
|
|
220
|
+
apiSecret: requireEnv('KRAKEN_API_SECRET'),
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const { token } = await rest.trading.getWebSocketsToken();
|
|
224
|
+
|
|
225
|
+
const wsClient = new KrakenSpotWebsocketV2Client({
|
|
226
|
+
authToken: token,
|
|
227
|
+
autoReconnect: false,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
await wsClient.privateConnection.connect();
|
|
231
|
+
|
|
232
|
+
const ack = await wsClient.userData.subscribeBalances({}, { reqId: 10 });
|
|
233
|
+
|
|
234
|
+
if (!ack.success) {
|
|
235
|
+
throw new Error(`Subscribe failed: ${ack.error}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const off = wsClient.privateConnection.addMessageHandler((msg) => {
|
|
239
|
+
console.log(JSON.stringify(msg));
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
setTimeout(() => {
|
|
243
|
+
off();
|
|
244
|
+
wsClient.privateConnection.close(1000, 'example done');
|
|
245
|
+
}, 30_000);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
main().catch((err) => {
|
|
249
|
+
console.error(err);
|
|
250
|
+
process.exitCode = 1;
|
|
251
|
+
});
|
|
103
252
|
```
|
|
104
253
|
|
|
105
254
|
---
|
|
@@ -198,142 +347,30 @@ Notes:
|
|
|
198
347
|
|
|
199
348
|
---
|
|
200
349
|
|
|
201
|
-
##
|
|
202
|
-
|
|
203
|
-
This package provides a top-level v2 WS client that creates:
|
|
204
|
-
|
|
205
|
-
- a public connection (market data + admin)
|
|
206
|
-
- a private/auth connection (user-data + user-trading)
|
|
207
|
-
|
|
208
|
-
### Create a WS v2 client
|
|
209
|
-
|
|
210
|
-
```ts
|
|
211
|
-
const ws = new KrakenSpotWebsocketV2Client({
|
|
212
|
-
// publicUrl: "wss://ws.kraken.com/v2",
|
|
213
|
-
// privateUrl: "wss://ws-auth.kraken.com/v2",
|
|
350
|
+
## Examples
|
|
214
351
|
|
|
215
|
-
|
|
352
|
+
The repository includes a comprehensive [examples](./examples) directory:
|
|
216
353
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
354
|
+
- REST (public + safe private endpoints)
|
|
355
|
+
- WebSocket v2 public streams
|
|
356
|
+
- WebSocket v2 private streams (balances, executions)
|
|
357
|
+
- Clean lifecycle examples (connect → subscribe → receive → close)
|
|
220
358
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
Available sub-APIs:
|
|
227
|
-
|
|
228
|
-
- `ws.admin`
|
|
229
|
-
- `ws.marketData`
|
|
230
|
-
- `ws.userData`
|
|
231
|
-
- `ws.userTrading`
|
|
232
|
-
|
|
233
|
-
### Connect
|
|
234
|
-
|
|
235
|
-
```ts
|
|
236
|
-
await ws.publicConnection.connect();
|
|
237
|
-
await ws.privateConnection.connect();
|
|
238
|
-
```
|
|
359
|
+
Examples are designed to be:
|
|
360
|
+
- Runnable
|
|
361
|
+
- Safe by default
|
|
362
|
+
- Self-contained
|
|
363
|
+
- Easy to copy into your own project
|
|
239
364
|
|
|
240
365
|
---
|
|
241
366
|
|
|
242
|
-
##
|
|
243
|
-
|
|
244
|
-
```ts
|
|
245
|
-
const unsubscribe = ws.publicConnection.addMessageHandler((msg) => {
|
|
246
|
-
// route by msg.channel / msg.type
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// later
|
|
250
|
-
unsubscribe();
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## WS v2: Admin
|
|
256
|
-
|
|
257
|
-
```ts
|
|
258
|
-
const pong = await ws.admin.ping({ reqId: 123 });
|
|
259
|
-
if (!pong.success) console.error('ping failed:', pong.error);
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
## WS v2: User Data (authenticated)
|
|
265
|
-
|
|
266
|
-
Implemented channels:
|
|
267
|
-
|
|
268
|
-
- `executions`
|
|
269
|
-
- `balances`
|
|
367
|
+
## Design Philosophy
|
|
270
368
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
snap_orders: true,
|
|
277
|
-
order_status: true,
|
|
278
|
-
});
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
```ts
|
|
282
|
-
ws.privateConnection.addMessageHandler((msg) => {
|
|
283
|
-
if (msg?.channel === 'executions') {
|
|
284
|
-
for (const report of msg.data ?? []) {
|
|
285
|
-
console.log(report.order_id, report.order_status);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Balances example
|
|
292
|
-
|
|
293
|
-
```ts
|
|
294
|
-
const ack2 = await ws.userData.subscribeBalances({ snapshot: true });
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
```ts
|
|
298
|
-
ws.privateConnection.addMessageHandler((msg) => {
|
|
299
|
-
if (msg?.channel === 'balances') {
|
|
300
|
-
console.log(msg.data);
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
## WS v2: User Trading (authenticated RPC)
|
|
308
|
-
|
|
309
|
-
Implemented RPCs:
|
|
310
|
-
|
|
311
|
-
- `add_order`
|
|
312
|
-
- `amend_order`
|
|
313
|
-
- `cancel_order`
|
|
314
|
-
- `cancel_all`
|
|
315
|
-
- `cancel_all_orders_after`
|
|
316
|
-
- `batch_add`
|
|
317
|
-
- `batch_cancel`
|
|
318
|
-
|
|
319
|
-
Add order:
|
|
320
|
-
|
|
321
|
-
```ts
|
|
322
|
-
const res = await ws.userTrading.addOrder({
|
|
323
|
-
order_type: 'limit',
|
|
324
|
-
side: 'buy',
|
|
325
|
-
symbol: 'BTC/USD',
|
|
326
|
-
order_qty: 0.01,
|
|
327
|
-
limit_price: 30000,
|
|
328
|
-
time_in_force: 'gtc',
|
|
329
|
-
});
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
Dead Man’s Switch:
|
|
333
|
-
|
|
334
|
-
```ts
|
|
335
|
-
await ws.userTrading.cancelAllOrdersAfter({ timeout: 60 });
|
|
336
|
-
```
|
|
369
|
+
- Explicit APIs over magic
|
|
370
|
+
- Strong typing without sacrificing usability
|
|
371
|
+
- Clear separation of REST vs WebSocket concerns
|
|
372
|
+
- No hidden background workers
|
|
373
|
+
- Safe defaults, especially for trading operations
|
|
337
374
|
|
|
338
375
|
---
|
|
339
376
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var crypto=require('crypto'),ws=require('ws');var y=class{constructor(e,r){this.maxCounter=e;this.decayPerSec=r;}counter=0;lastTs=Date.now();queue=[];draining=false;schedule(e,r){let n=Math.max(0,r?.cost??1);return new Promise((s,o)=>{this.queue.push({fn:e,resolve:s,reject:o,cost:n}),this.drain();})}decayNow(){let e=Date.now(),r=(e-this.lastTs)/1e3;r>0&&(this.counter=Math.max(0,this.counter-r*this.decayPerSec),this.lastTs=e);}async drain(){if(!this.draining){this.draining=true;try{for(;this.queue.length>0;){this.decayNow();let e=this.queue[0];if(this.counter+e.cost<=this.maxCounter){this.queue.shift(),this.counter+=e.cost;try{let o=await e.fn();e.resolve(o);}catch(o){e.reject(o);}continue}let n=(this.counter+e.cost-this.maxCounter)/this.decayPerSec,s=Math.max(50,Math.ceil(n*1e3));await w(s);}}finally{this.draining=false;}}}};function I(t){switch(t){case "pro":return {maxCounter:20,decayPerSec:1};case "intermediate":return {maxCounter:20,decayPerSec:.5};case "starter":default:return {maxCounter:15,decayPerSec:.33}}}function L(t){return t.includes("TradesHistory")||t.includes("Ledgers")||t.includes("TradeBalance")?2:1}function v(t){return t.includes("/AddOrder")||t.includes("/CancelOrder")||t.includes("/CancelAll")||t.includes("/EditOrder")||t.includes("/AddOrderBatch")||t.includes("/CancelOrderBatch")}function w(t){return new Promise(e=>setTimeout(e,t))}function D(t){let e=t*.2;return Math.max(0,Math.floor(t+(Math.random()*2-1)*e))}function M(t){let e=t.match(/EService:\s*Throttled:\s*(\d+)/i);if(!e)return null;let r=Number(e[1]);return Number.isFinite(r)?r:null}var g=class extends Error{name="KrakenApiError";endpoint;httpStatus;httpStatusText;krakenErrorCodes;rawBody;constructor(e,r={}){super(e),Object.setPrototypeOf(this,new.target.prototype),this.endpoint=r.endpoint,this.httpStatus=r.httpStatus,this.httpStatusText=r.httpStatusText,this.krakenErrorCodes=r.krakenErrorCodes,this.rawBody=r.rawBody;}};var h=class{baseUrl;timeoutMs;userAgent;apiKey;apiSecret;logger;lastNonce;lastMs=0;restLimiter;tradingLimiter;rateLimitOptions;restCostFn;tradingCostFn;constructor(e={}){this.baseUrl=e.baseUrl??"https://api.kraken.com",this.timeoutMs=e.timeoutMs??1e4,this.userAgent=e.userAgent,this.apiKey=e.apiKey,this.apiSecret=e.apiSecret,this.logger=e.logger;let r=e.rateLimit??{},n=r.mode??"auto",s=r.tier??"starter";if(this.rateLimitOptions={retryOnRateLimit:r.retryOnRateLimit??true,maxRetries:r.maxRetries??5},this.restCostFn=r.restCostFn??L,this.tradingCostFn=r.tradingCostFn??(()=>1),e.limiter?.rest&&(this.restLimiter=e.limiter.rest),e.limiter?.trading&&(this.tradingLimiter=e.limiter.trading),n!=="off"){if(!this.restLimiter){let{maxCounter:o,decayPerSec:a}=I(s);this.restLimiter=new y(o,a);}this.tradingLimiter||(this.tradingLimiter=new y(10,1));}}createNonce(){let e=Date.now();return this.lastNonce===void 0?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e,this.lastNonce.toString()):(e>this.lastMs?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e):this.lastNonce=this.lastNonce+1n,this.lastNonce.toString())}async publicGet(e,r){let n=new URL(e,this.baseUrl);if(r)for(let[s,o]of Object.entries(r))n.searchParams.set(s,String(o));return this.logger?.debug?.("Kraken REST public GET request",{endpoint:e,url:n.toString(),query:r}),this.scheduleWithRetry(e,async()=>{let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs);try{let a=await fetch(n,{method:"GET",signal:s.signal,headers:this.userAgent?{"User-Agent":this.userAgent}:void 0});if(!a.ok)throw this.logger?.error?.("Kraken REST HTTP error",{endpoint:e,status:a.status,statusText:a.statusText}),new g(`HTTP error from Kraken: ${a.status} ${a.statusText}`,{endpoint:e,httpStatus:a.status,httpStatusText:a.statusText});let i;try{i=await a.json();}catch(l){throw this.logger?.error?.("Kraken REST JSON parse error",{endpoint:e,error:l}),new g("Failed to parse Kraken response JSON",{endpoint:e,httpStatus:a.status})}if(i.error?.length)throw this.logger?.warn?.("Kraken REST API error",{endpoint:e,krakenErrors:i.error}),new g(`Kraken API error: ${i.error.join(", ")}`,{endpoint:e,httpStatus:a.status,krakenErrorCodes:i.error,rawBody:i});return this.logger?.debug?.("Kraken REST public GET success",{endpoint:e}),i.result}finally{clearTimeout(o);}})}async privatePost(e,r){if(!this.apiKey||!this.apiSecret)throw new g("Missing apiKey or apiSecret for Kraken private API call",{endpoint:e});let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),o=new URLSearchParams;if(o.set("nonce",s),r)for(let[K,p]of Object.entries(r))p!==void 0&&o.set(K,String(p));let a=o.toString(),i=e,l=crypto.createHash("sha256").update(s+a).digest(),d=Buffer.from(this.apiSecret,"base64"),m=crypto.createHmac("sha512",d).update(i+l).digest("base64");this.logger?.debug?.("Kraken REST private POST request",{endpoint:e,url:n.toString(),hasParams:!!r});let k=new AbortController,u=setTimeout(()=>k.abort(),this.timeoutMs);try{let K=await fetch(n,{method:"POST",signal:k.signal,headers:{"Content-Type":"application/x-www-form-urlencoded","API-Key":this.apiKey,"API-Sign":m,...this.userAgent?{"User-Agent":this.userAgent}:{}},body:a});if(!K.ok)throw this.logger?.error?.("Kraken REST private HTTP error",{endpoint:e,status:K.status,statusText:K.statusText}),new g(`HTTP error from Kraken private API: ${K.status} ${K.statusText}`,{endpoint:e,httpStatus:K.status,httpStatusText:K.statusText});let p;try{p=await K.json();}catch(b){throw this.logger?.error?.("Kraken REST private JSON parse error",{endpoint:e,error:b}),new g("Failed to parse Kraken private API response JSON",{endpoint:e,httpStatus:K.status})}if(p.error?.length)throw this.logger?.warn?.("Kraken REST private API error",{endpoint:e,krakenErrors:p.error}),new g(`Kraken private API error: ${p.error.join(", ")}`,{endpoint:e,httpStatus:K.status,krakenErrorCodes:p.error,rawBody:p});return this.logger?.debug?.("Kraken REST private POST success",{endpoint:e}),p.result}finally{clearTimeout(u);}})}async privatePostBinary(e,r){if(!this.apiKey||!this.apiSecret)throw new Error("KrakenRestBase: apiKey and apiSecret are required for private endpoints");let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),a=new URLSearchParams({nonce:s,...r??{}}).toString(),i=this.signPrivateRequest(e,s,a);this.logger?.debug?.("[KrakenRestBase] privatePostBinary request",{url:n.toString(),path:e,body:r});let l={"API-Key":this.apiKey,"API-Sign":i,"User-Agent":this.userAgent??"lynx-crypto-kraken-client/0.1.0","Content-Type":"application/x-www-form-urlencoded"},d=await fetch(n.toString(),{method:"POST",headers:l,body:a});if(!d.ok){let k=await d.text().catch(()=>"");throw this.logger?.error?.("[KrakenRestBase] privatePostBinary HTTP error",{status:d.status,statusText:d.statusText,body:k}),new Error(`Kraken privatePostBinary failed: ${d.status} ${d.statusText} \u2013 ${k}`)}if((d.headers.get("content-type")??"").includes("application/json")){let k=await d.json().catch(()=>null);if(!k)throw new Error("Kraken privatePostBinary: expected JSON body for error response");let u=k.error??[];if(u.length>0){let K=`Kraken API error: ${u.join(", ")}`;this.logger?.error?.("[KrakenRestBase] Kraken API error (binary response)",{errors:u});let p=new Error(K);throw p.krakenErrors=u,p}throw new Error("Kraken privatePostBinary: expected binary data but got JSON without errors")}let m=await d.arrayBuffer();return this.logger?.debug?.("[KrakenRestBase] privatePostBinary success",{bytes:m.byteLength}),m})}signPrivateRequest(e,r,n){if(!this.apiSecret)throw new Error("KrakenRestBase: apiSecret is required for private endpoints");let s=Buffer.from(this.apiSecret,"base64"),o=crypto.createHash("sha256").update(r+n).digest();return crypto.createHmac("sha512",s).update(e+o).digest("base64")}async scheduleWithRetry(e,r){let n=v(e)?this.tradingLimiter:this.restLimiter,s=v(e)?this.tradingCostFn(e):this.restCostFn(e),o=()=>n?n.schedule(r,{cost:s}):r();if(!this.rateLimitOptions.retryOnRateLimit)return o();let a=this.rateLimitOptions.maxRetries,i=0;for(;;)try{return await o()}catch(l){i++;let d=l?.message??(typeof l=="string"?l:"")??"",c=l?.krakenErrorCodes??l?.krakenErrors,m=d.includes("EAPI:Rate limit exceeded")||Array.isArray(c)&&c.some(b=>b.includes("EAPI:Rate limit exceeded")),k=(()=>{let b=M(d);if(b)return b;if(Array.isArray(c))for(let G of c){let C=M(G);if(C)return C}return null})(),u=l?.httpStatus===429;if(!(m||k!==null||u)||i>a)throw l;let p=0;if(k!==null){let b=Math.floor(Date.now()/1e3);p=Math.max(0,k-b)*1e3;}else {let b=250*Math.pow(2,i-1);p=Math.min(b,1e4);}p=D(p),this.logger?.warn?.("Kraken rate limited; retrying",{endpoint:e,attempt:i,waitMs:p,reason:u?"HTTP 429":k?"EService: Throttled":"EAPI: Rate limit exceeded"}),await w(p);}}};function F(t){return t.publicGet("/0/public/Time")}function H(t){return t.publicGet("/0/public/SystemStatus")}function j(t,e){let r={};return e?.asset&&e.asset.length>0&&(r.asset=e.asset.join(",")),e?.aclass&&(r.aclass=e.aclass),t.publicGet("/0/public/Assets",r)}function Q(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.aclass_base&&(r.aclass_base=e.aclass_base),e?.info&&(r.info=e.info),e?.country_code&&(r.country_code=e.country_code),t.publicGet("/0/public/AssetPairs",r)}function N(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Ticker",r)}async function V(t,e){let r={pair:e.pair};e.interval!==void 0&&(r.interval=String(e.interval)),e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/OHLC",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,ohlc:a}}function z(t,e){let r={pair:e.pair};return e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Depth",r)}async function $(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Trades",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,trades:a}}async function J(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Spread",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,spreads:a}}var x=class{constructor(e){this.base=e;}getServerTime(){return F(this.base)}getSystemStatus(){return H(this.base)}getAssetInfo(e){return j(this.base,e)}getTradableAssetPairs(e){return Q(this.base,e)}getTickerInformation(e){return N(this.base,e)}getOhlcData(e){return V(this.base,e)}getOrderBook(e){return z(this.base,e)}getRecentTrades(e){return $(this.base,e)}getRecentSpreads(e){return J(this.base,e)}};function Y(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Balance",r)}function X(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/BalanceEx",r)}function Z(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/CreditLines",r)}function ee(t,e){let r={};return e?.asset&&(r.asset=e.asset),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeBalance",r)}function re(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenOrders",r)}function te(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.closetime&&(r.closetime=e.closetime),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/ClosedOrders",r)}function ne(t,e){let r={};return e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.userref!==void 0&&(r.userref=String(e.userref)),Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryOrders",r)}function se(t,e){let r={order_id:e.order_id};return e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OrderAmends",r)}function ae(t,e){let r={};return e?.type&&(r.type=e.type),e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.ledgers!==void 0&&(r.ledgers=e.ledgers?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradesHistory",r)}function oe(t,e){let r={};return Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryTrades",r)}function ie(t,e){let r={};return e?.txid!==void 0&&(r.txid=Array.isArray(e.txid)?e.txid.join(","):e.txid),e?.docalcs!==void 0&&(r.docalcs=e.docalcs?"true":"false"),e?.consolidation&&(r.consolidation=e.consolidation),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenPositions",r)}function de(t,e){let r={};return e?.asset!==void 0&&(r.asset=Array.isArray(e.asset)?e.asset.join(","):e.asset),e?.aclass&&(r.aclass=e.aclass),e?.type&&(r.type=e.type),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Ledgers",r)}function ce(t,e){let r={};return Array.isArray(e.id)?r.id=e.id.join(","):r.id=e.id,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryLedgers",r)}function le(t,e){let r={};return e?.pair!==void 0&&(r.pair=Array.isArray(e.pair)?e.pair.join(","):e.pair),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeVolume",r)}function pe(t,e){let r={report:e.report,description:e.description};return e.format&&(r.format=e.format),e.fields&&(r.fields=e.fields),e.starttm!==void 0&&(r.starttm=String(e.starttm)),e.endtm!==void 0&&(r.endtm=String(e.endtm)),t.privatePost("/0/private/AddExport",r)}function ue(t,e){let r={report:e.report};return t.privatePost("/0/private/ExportStatus",r)}function ke(t,e){let r={id:e.id};return t.privatePostBinary("/0/private/RetrieveExport",r)}function Ke(t,e){let r={id:e.id,type:e.type};return t.privatePost("/0/private/RemoveExport",r)}var W=class{constructor(e){this.base=e;}getAccountBalance(e){return Y(this.base,e)}getExtendedBalance(e){return X(this.base,e)}getCreditLines(e){return Z(this.base,e)}getTradeBalance(e){return ee(this.base,e)}getOpenOrders(e){return re(this.base,e)}getClosedOrders(e){return te(this.base,e)}queryOrdersInfo(e){return ne(this.base,e)}getOrderAmends(e){return se(this.base,e)}getTradesHistory(e){return ae(this.base,e)}queryTradesInfo(e){return oe(this.base,e)}getOpenPositions(e){return ie(this.base,e)}getLedgersInfo(e){return de(this.base,e)}queryLedgers(e){return ce(this.base,e)}getTradeVolume(e){return le(this.base,e)}requestExportReport(e){return pe(this.base,e)}getExportReportStatus(e){return ue(this.base,e)}retrieveExportReport(e){return ke(this.base,e)}deleteExportReport(e){return Ke(this.base,e)}};function me(t,e){if(e.userref!==void 0&&e.cl_ord_id)throw new Error("KrakenAddOrderParams: userref and cl_ord_id are mutually exclusive");let r={ordertype:e.ordertype,type:e.type,volume:e.volume,pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.displayvol&&(r.displayvol=e.displayvol),e.asset_class&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.trigger&&(r.trigger=e.trigger),e.leverage!==void 0&&(r.leverage=e.leverage),e.reduce_only!==void 0&&(r.reduce_only=e.reduce_only?"true":"false"),e.stptype&&(r.stptype=e.stptype),e.oflags&&(r.oflags=e.oflags),e.timeinforce&&(r.timeinforce=e.timeinforce),e.starttm!==void 0&&(r.starttm=e.starttm),e.expiretm!==void 0&&(r.expiretm=e.expiretm),e.deadline!==void 0&&(r.deadline=e.deadline),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),e.close&&(r["close[ordertype]"]=e.close.ordertype,e.close.price!==void 0&&(r["close[price]"]=e.close.price),e.close.price2!==void 0&&(r["close[price2]"]=e.close.price2)),t.privatePost("/0/private/AddOrder",r)}function be(t,e){if(!e.txid&&!e.cl_ord_id)throw new Error("KrakenAmendOrderParams: either txid or cl_ord_id must be provided");let r={};return e.txid&&(r.txid=e.txid),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.order_qty!==void 0&&(r.order_qty=e.order_qty),e.display_qty!==void 0&&(r.display_qty=e.display_qty),e.limit_price!==void 0&&(r.limit_price=e.limit_price),e.trigger_price!==void 0&&(r.trigger_price=e.trigger_price),e.pair!==void 0&&(r.pair=e.pair),e.post_only!==void 0&&(r.post_only=e.post_only?"true":"false"),e.deadline!==void 0&&(r.deadline=e.deadline),t.privatePost("/0/private/AmendOrder",r)}function ge(t,e){let{txid:r,userref:n,cl_ord_id:s}=e,o=(r!==void 0?1:0)+(n!==void 0?1:0)+(s!==void 0?1:0);if(o===0)throw new Error("KrakenCancelOrderParams: one of txid, userref, or cl_ord_id must be provided");if(o>1)throw new Error("KrakenCancelOrderParams: txid, userref, and cl_ord_id are mutually exclusive; provide exactly one");let a={};return n!==void 0?a.txid=String(n):s!==void 0?a.cl_ord_id=Array.isArray(s)?s.join(","):s:r!==void 0&&(a.txid=Array.isArray(r)?r.join(","):r),t.privatePost("/0/private/CancelOrder",a)}function ye(t){return t.privatePost("/0/private/CancelAll",{})}function fe(t,e){let r={timeout:String(e.timeout)};return t.privatePost("/0/private/CancelAllOrdersAfter",r)}function he(t){return t.privatePost("/0/private/GetWebSocketsToken",{})}function xe(t,e){let{orders:r,pair:n,asset_class:s,deadline:o,validate:a}=e;if(!Array.isArray(r)||r.length<2||r.length>15)throw new Error(`KrakenAddOrderBatchParams: orders must contain between 2 and 15 items (got ${r.length})`);for(let[d,c]of r.entries())if(c.userref!==void 0&&c.cl_ord_id!==void 0)throw new Error(`KrakenAddOrderBatchParams: order[${d}] cannot have both userref and cl_ord_id`);let i={pair:n};s&&(i.asset_class=s),o!==void 0&&(i.deadline=o),a!==void 0&&(i.validate=a?"true":"false");let l=r.map(d=>{let c={ordertype:d.ordertype,type:d.type,volume:d.volume};return d.userref!==void 0&&(c.userref=String(d.userref)),d.cl_ord_id!==void 0&&(c.cl_ord_id=d.cl_ord_id),d.displayvol!==void 0&&(c.displayvol=d.displayvol),d.price!==void 0&&(c.price=d.price),d.price2!==void 0&&(c.price2=d.price2),d.trigger!==void 0&&(c.trigger=d.trigger),d.leverage!==void 0&&(c.leverage=d.leverage),d.reduce_only!==void 0&&(c.reduce_only=d.reduce_only?"true":"false"),d.stptype!==void 0&&(c.stptype=d.stptype),d.oflags!==void 0&&(c.oflags=d.oflags),d.timeinforce!==void 0&&(c.timeinforce=d.timeinforce),d.starttm!==void 0&&(c.starttm=d.starttm),d.expiretm!==void 0&&(c.expiretm=d.expiretm),c});return i.orders=JSON.stringify(l),t.privatePost("/0/private/AddOrderBatch",i)}function We(t,e){let{orders:r,clOrdIds:n}=e,s=r?.length??0,o=n?.length??0,a=s+o;if(a===0)throw new Error("KrakenCancelOrderBatchParams: at least one txid/userref or cl_ord_id is required");if(a>50)throw new Error(`KrakenCancelOrderBatchParams: maximum 50 total ids/references allowed, got ${a}`);let i={};if(r&&r.length>0){let l=r.map(d=>({txid:String(d.txid)}));i.orders=JSON.stringify(l);}if(n&&n.length>0){let l=n.map(d=>({cl_ord_id:d}));i.cl_ord_ids=JSON.stringify(l);}return t.privatePost("/0/private/CancelOrderBatch",i)}function Oe(t,e){let r={txid:String(e.txid),pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.volume!==void 0&&(r.volume=e.volume),e.displayvol!==void 0&&(r.displayvol=e.displayvol),e.asset_class!==void 0&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.oflags!==void 0&&(r.oflags=e.oflags),e.deadline!==void 0&&(r.deadline=e.deadline),e.cancel_response!==void 0&&(r.cancel_response=e.cancel_response?"true":"false"),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),t.privatePost("/0/private/EditOrder",r)}var O=class{constructor(e){this.base=e;}addOrder(e){return me(this.base,e)}amendOrder(e){return be(this.base,e)}cancelOrder(e){return ge(this.base,e)}cancelAllOrders(){return ye(this.base)}cancelAllOrdersAfter(e){return fe(this.base,e)}getWebSocketsToken(){return he(this.base)}addOrderBatch(e){return xe(this.base,e)}cancelOrderBatch(e){return We(this.base,e)}editOrder(e){return Oe(this.base,e)}};function Re(t,e){let r={asset:e.asset};return e.aclass!==void 0&&(r.aclass=e.aclass),e.rebase_multiplier!==void 0&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositMethods",r)}function Ae(t,e){let r={asset:e.asset,method:e.method};return e.aclass!==void 0&&(r.aclass=e.aclass),e.new!==void 0&&(r.new=e.new?"true":"false"),e.amount!==void 0&&(r.amount=String(e.amount)),t.privatePost("/0/private/DepositAddresses",r)}function Te(t,e={}){let r={};return e.asset&&(r.asset=e.asset),e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.start!==void 0&&(r.start=String(e.start)),e.end!==void 0&&(r.end=String(e.end)),e.cursor&&(r.cursor=e.cursor),e.limit!==void 0&&(r.limit=String(e.limit)),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositStatus",r)}function Pe(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.network&&(r.network=e.network),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/WithdrawMethods",r)}function Se(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.key&&(r.key=e.key),e.verified!==void 0&&(r.verified=e.verified?"true":"false"),t.privatePost("/0/private/WithdrawAddresses",r)}function Be(t,e){let r={asset:e.asset,key:e.key,amount:String(e.amount)};return t.privatePost("/0/private/WithdrawInfo",r)}function _e(t,e){let{asset:r,aclass:n,key:s,address:o,amount:a,max_fee:i,rebase_multiplier:l}=e,d={asset:r,key:s,amount:String(a)};return n&&(d.aclass=n),o&&(d.address=o),i!==void 0&&(d.max_fee=String(i)),l&&(d.rebase_multiplier=l),t.privatePost("/0/private/Withdraw",d)}async function Ee(t,e={}){let{asset:r,aclass:n,method:s,start:o,end:a,cursor:i,limit:l,rebase_multiplier:d}=e,c={};return r&&(c.asset=r),n&&(c.aclass=n),s&&(c.method=s),o!==void 0&&(c.start=o),a!==void 0&&(c.end=a),i!==void 0&&(c.cursor=i),l!==void 0&&(c.limit=l),d&&(c.rebase_multiplier=d),t.privatePost("/0/private/WithdrawStatus",c)}function ve(t,e){let{asset:r,refid:n}=e,s={asset:r,refid:n};return t.privatePost("/0/private/WithdrawCancel",s)}function we(t,e){let{asset:r,from:n,to:s,amount:o}=e,a={asset:r,from:n,to:s,amount:String(o)};return t.privatePost("/0/private/WalletTransfer",a)}var R=class{constructor(e){this.base=e;}getDepositMethods(e){return Re(this.base,e)}getDepositAddresses(e){return Ae(this.base,e)}getDepositStatus(e={}){return Te(this.base,e)}getWithdrawMethods(e){return Pe(this.base,e)}getWithdrawAddresses(e){return Se(this.base,e)}getWithdrawInfo(e){return Be(this.base,e)}withdrawFunds(e){return _e(this.base,e)}getWithdrawStatus(e={}){return Ee(this.base,e)}withdrawCancel(e){return ve(this.base,e)}walletTransfer(e){return we(this.base,e)}};async function Me(t,e){let{username:r,email:n}=e,s={username:r,email:n};return t.privatePost("/0/private/CreateSubaccount",s)}async function Ge(t,e){let{asset:r,asset_class:n,amount:s,from:o,to:a}=e,i={asset:r,amount:String(s),from:o,to:a};return n&&(i.asset_class=n),t.privatePost("/0/private/AccountTransfer",i)}var A=class{constructor(e){this.base=e;}createSubaccount(e){return Me(this.base,e)}accountTransfer(e){return Ge(this.base,e)}};async function Ce(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Allocate",s)}async function Ie(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Deallocate",s)}async function Le(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/AllocateStatus",n)}async function De(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/DeallocateStatus",n)}async function qe(t,e={}){let{ascending:r,asset:n,cursor:s,limit:o,lock_type:a}=e,i={};return r!=null&&(i.ascending=r),n!=null&&(i.asset=n),s!=null&&(i.cursor=s),o!=null&&(i.limit=o),a&&a.length>0&&(i.lock_type=JSON.stringify(a)),t.privatePost("/0/private/Earn/Strategies",i)}async function Ue(t,e={}){let{ascending:r,converted_asset:n,hide_zero_allocations:s}=e,o={};return r!=null&&(o.ascending=r),n!=null&&(o.converted_asset=n),s!=null&&(o.hide_zero_allocations=s),t.privatePost("/0/private/Earn/Allocations",o)}var T=class{constructor(e){this.base=e;}allocateFunds(e){return Ce(this.base,e)}deallocateFunds(e){return Ie(this.base,e)}getAllocationStatus(e){return Le(this.base,e)}getDeallocationStatus(e){return De(this.base,e)}listStrategies(e={}){return qe(this.base,e)}listAllocations(e={}){return Ue(this.base,e)}};async function Fe(t,e){let{symbol:r}=e,s={symbol:typeof r=="string"?r:r.join(",")};return t.publicGet("/0/public/PreTrade",s)}async function He(t,e={}){let{symbol:r,from_ts:n,to_ts:s,count:o}=e,a={};return r&&(a.symbol=r),n&&(a.from_ts=n),s&&(a.to_ts=s),o!==void 0&&(a.count=o),t.publicGet("/0/public/PostTrade",a)}var P=class{constructor(e){this.base=e;}getPreTradeData(e){return Fe(this.base,e)}getPostTradeData(e={}){return He(this.base,e)}};var je=class extends h{marketData;accountData;trading;funding;subaccounts;earn;transparency;constructor(e={}){super(e),this.marketData=new x(this),this.accountData=new W(this),this.trading=new O(this),this.funding=new R(this),this.subaccounts=new A(this),this.earn=new T(this),this.transparency=new P(this);}};var f=class{url;authToken;WebSocketImpl;logger;autoReconnect;reconnectDelayMs;requestTimeoutMs;ws=null;connectingPromise=null;manuallyClosed=false;nextReqId=1;pending=new Map;messageHandlers=new Set;reconnectAttempts=0;constructor(e){if(this.url=e.url,this.authToken=e.authToken,this.WebSocketImpl=e.WebSocketImpl??(typeof ws.WebSocket<"u"?ws.WebSocket:void 0),this.logger=e.logger,this.autoReconnect=e.autoReconnect??true,this.reconnectDelayMs=e.reconnectDelayMs??1e3,this.requestTimeoutMs=e.requestTimeoutMs??1e4,!this.WebSocketImpl)throw new Error("No WebSocket implementation available. Pass `WebSocketImpl` in KrakenWebsocketConnectionOptions when using Node.js.")}get readyState(){return this.ws?.readyState??-1}async connect(){if(!(this.ws&&this.ws.readyState===1))return this.connectingPromise?this.connectingPromise:(this.manuallyClosed=false,this.connectingPromise=new Promise((e,r)=>{try{let n=this.WebSocketImpl,s=new n(this.url);this.ws=s,s.onopen=()=>{this.reconnectAttempts=0,this.logger?.info?.("Kraken WS connected",{url:this.url}),this.connectingPromise=null,e();},s.onclose=o=>{this.logger?.info?.("Kraken WS closed",{url:this.url,event:o,manuallyClosed:this.manuallyClosed}),this.ws=null,this.connectingPromise=null;for(let[a,i]of this.pending)clearTimeout(i.timeoutId),i.reject(new Error(`WebSocket closed before response for req_id ${a}`));if(this.pending.clear(),!this.manuallyClosed&&this.autoReconnect){this.reconnectAttempts++;let a=this.reconnectDelayMs,i=Math.min(3e4,a*Math.pow(2,this.reconnectAttempts-1)),l=this.reconnectAttempts>=4?5e3:0,d=Math.max(l,i),c=Math.max(0,Math.floor(d*(.8+Math.random()*.4)));setTimeout(()=>{this.logger?.info?.("Kraken WS reconnecting",{url:this.url,attempt:this.reconnectAttempts,delayMs:c}),this.connect().catch(m=>{this.logger?.error?.("Kraken WS reconnect failed",{url:this.url,error:m});});},c);}},s.onerror=o=>{this.logger?.error?.("Kraken WS error",{url:this.url,event:o});},s.onmessage=o=>{let a=o.data;if(typeof o.data=="string")try{a=JSON.parse(o.data);}catch(i){this.logger?.warn?.("Failed to parse WS JSON message",{data:o.data,error:i});}if(a&&typeof a=="object"&&"req_id"in a&&typeof a.req_id=="number"){let i=a.req_id,l=this.pending.get(i);l&&(this.pending.delete(i),clearTimeout(l.timeoutId),l.resolve(a));}for(let i of this.messageHandlers)try{i(a);}catch(l){this.logger?.error?.("WS message handler threw",{error:l});}};}catch(n){this.connectingPromise=null,r(n);}}),this.connectingPromise)}close(e,r){this.manuallyClosed=true,this.ws&&this.ws.readyState===1&&this.ws.close(e,r);}addMessageHandler(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}async sendRaw(e){(!this.ws||this.ws.readyState!==1)&&await this.connect();let r=this.ws;if(!r||r.readyState!==1)throw new Error("WebSocket is not open");let n=typeof e=="string"?e:JSON.stringify(e);r.send(n);}async request(e,r,n){(!this.ws||this.ws.readyState!==1)&&await this.connect();let s=n?.reqId??this.nextReqId++,o=n?.timeoutMs??this.requestTimeoutMs,a=n?.attachAuthToken??true,i=r?{...r}:{};a&&this.authToken&&(i.token===void 0||i.token===null)&&(i.token=this.authToken);let l={method:e,params:Object.keys(i).length?i:void 0,req_id:s};return this.logger?.debug?.("Kraken WS request",{envelope:l}),await new Promise((d,c)=>{let m=setTimeout(()=>{this.pending.delete(s),c(new Error(`Kraken WS request timed out after ${o}ms (method=${e}, req_id=${s})`));},o),k={resolve:u=>d(u),reject:c,timeoutId:m};this.pending.set(s,k);try{let u=this.ws;if(!u||u.readyState!==1){clearTimeout(m),this.pending.delete(s),c(new Error(`WebSocket is not open (method=${e}, req_id=${s})`));return}u.send(JSON.stringify(l));}catch(u){clearTimeout(m),this.pending.delete(s),c(u);}})}};function Ne(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="status"&&n.type==="update"&&Array.isArray(n.data)&&e(n);})}async function Ve(t,e={},r={}){return t.request("ping",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}function ze(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="heartbeat"&&e(n);})}var S=class{constructor(e){this.ws=e;}ping(e={},r={}){return Ve(this.ws,e,r)}onStatus(e){return Ne(this.ws,e)}onHeartbeat(e){return ze(this.ws,e)}};async function $e(t,e,r={}){let n={channel:"ticker",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Je(t,e,r={}){let n={channel:"ticker",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Ye(t,e,r={}){let n={channel:"book",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Xe(t,e,r={}){let n={channel:"book",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Ze(t,e,r={}){let n={channel:"level3",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function er(t,e,r={}){let n={channel:"level3",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function rr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function tr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function nr(t,e,r={}){let n={channel:"trade",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function sr(t,e,r={}){let n={channel:"trade",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function ar(t,e={},r={}){let n={channel:"instrument",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function or(t,e={},r={}){let n={channel:"instrument",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}var B=class{constructor(e){this.ws=e;}subscribeTicker(e,r={}){return $e(this.ws,e,r)}unsubscribeTicker(e,r={}){return Je(this.ws,e,r)}subscribeBook(e,r={}){return Ye(this.ws,e,r)}unsubscribeBook(e,r={}){return Xe(this.ws,e,r)}subscribeLevel3(e,r={}){return Ze(this.ws,e,r)}unsubscribeLevel3(e,r={}){return er(this.ws,e,r)}subscribeOhlc(e,r={}){return rr(this.ws,e,r)}unsubscribeOhlc(e,r={}){return tr(this.ws,e,r)}subscribeTrade(e,r={}){return nr(this.ws,e,r)}unsubscribeTrade(e,r={}){return sr(this.ws,e,r)}subscribeInstrument(e={},r={}){return ar(this.ws,e,r)}unsubscribeInstrument(e={},r={}){return or(this.ws,e,r)}};async function ir(t,e,r={}){let n={channel:"executions",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function dr(t,e={},r={}){let n={channel:"executions",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function cr(t,e={},r={}){let n={channel:"balances",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function lr(t,e={},r={}){let n={channel:"balances",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}var _=class{constructor(e){this.ws=e;}subscribeExecutions(e,r){return ir(this.ws,e,r)}unsubscribeExecutions(e,r){return dr(this.ws,e??{},r)}subscribeBalances(e={},r){return cr(this.ws,e,r)}unsubscribeBalances(e,r){return lr(this.ws,e??{},r)}};async function pr(t,e,r={}){return t.request("add_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function ur(t,e,r={}){let n=!!e.order_id,s=!!e.cl_ord_id;if(n&&s||!n&&!s)throw new Error("Kraken WS amend_order: exactly one of `order_id` or `cl_ord_id` must be provided");return t.request("amend_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function kr(t,e,r={}){return t.request("edit_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Kr(t,e,r={}){let n=Array.isArray(e.order_id)&&e.order_id.length>0,s=Array.isArray(e.cl_ord_id)&&e.cl_ord_id.length>0,o=Array.isArray(e.order_userref)&&e.order_userref.length>0;if(!n&&!s&&!o)throw new Error("Kraken WS cancel_order: at least one of `order_id`, `cl_ord_id`, or `order_userref` must contain at least one entry");return t.request("cancel_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function mr(t,e={},r={}){return t.request("cancel_all",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function br(t,e,r={}){if(!Number.isFinite(e.timeout))throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be a finite number (seconds)");if(e.timeout<0||e.timeout>=86400)throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be >= 0 and < 86400 seconds");return t.request("cancel_all_orders_after",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function gr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_add: `orders` must contain at least 2 entries");if(e.orders.length>15)throw new Error("Kraken WS batch_add: `orders` must not contain more than 15 entries");for(let[n,s]of e.orders.entries())if(s.cl_ord_id&&typeof s.order_userref=="number")throw new Error(`Kraken WS batch_add: order at index ${n} must not specify both cl_ord_id and order_userref`);return t.request("batch_add",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function yr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_cancel: `orders` must contain at least 2 identifiers");if(e.orders.length>50)throw new Error("Kraken WS batch_cancel: `orders` must not contain more than 50 identifiers");return t.request("batch_cancel",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}var E=class{constructor(e){this.ws=e;}addOrder(e,r){return pr(this.ws,e,r)}amendOrder(e,r){return ur(this.ws,e,r)}editOrder(e,r){return kr(this.ws,e,r)}cancelOrder(e,r){return Kr(this.ws,e,r)}cancelAll(e,r){return mr(this.ws,e??{},r)}cancelAllOrdersAfter(e,r){return br(this.ws,e,r)}batchAdd(e,r){return gr(this.ws,e,r)}batchCancel(e,r){return yr(this.ws,e,r)}};var fr=class{publicConnection;privateConnection;admin;marketData;userData;userTrading;constructor(e={}){let{publicUrl:r="wss://ws.kraken.com/v2",privateUrl:n="wss://ws-auth.kraken.com/v2",authToken:s,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:l,logger:d}=e,c={authToken:void 0,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:l,logger:d};this.publicConnection=new f({...c,url:r}),this.privateConnection=new f({...c,url:n,authToken:s}),this.admin=new S(this.publicConnection),this.marketData=new B(this.publicConnection),this.userData=new _(this.privateConnection),this.userTrading=new E(this.privateConnection);}};
|
|
2
|
-
exports.KrakenSpotRestClient=je;exports.KrakenSpotWebsocketV2Client=fr;//# sourceMappingURL=index.cjs.map
|
|
1
|
+
'use strict';var crypto=require('crypto'),ws=require('ws');var f=class{constructor(e,r){this.maxCounter=e;this.decayPerSec=r;}counter=0;lastTs=Date.now();queue=[];draining=false;schedule(e,r){let n=Math.max(0,r?.cost??1);return new Promise((s,o)=>{this.queue.push({fn:e,resolve:s,reject:o,cost:n}),this.drain();})}decayNow(){let e=Date.now(),r=(e-this.lastTs)/1e3;r>0&&(this.counter=Math.max(0,this.counter-r*this.decayPerSec),this.lastTs=e);}async drain(){if(!this.draining){this.draining=true;try{for(;this.queue.length>0;){this.decayNow();let e=this.queue[0];if(this.counter+e.cost<=this.maxCounter){this.queue.shift(),this.counter+=e.cost;try{let o=await e.fn();e.resolve(o);}catch(o){e.reject(o);}continue}let n=(this.counter+e.cost-this.maxCounter)/this.decayPerSec,s=Math.max(50,Math.ceil(n*1e3));await w(s);}}finally{this.draining=false;}}}};function I(t){switch(t){case "pro":return {maxCounter:20,decayPerSec:1};case "intermediate":return {maxCounter:20,decayPerSec:.5};case "starter":default:return {maxCounter:15,decayPerSec:.33}}}function L(t){return t.includes("TradesHistory")||t.includes("Ledgers")||t.includes("TradeBalance")?2:1}function v(t){return t.includes("/AddOrder")||t.includes("/CancelOrder")||t.includes("/CancelAll")||t.includes("/EditOrder")||t.includes("/AddOrderBatch")||t.includes("/CancelOrderBatch")}function w(t){return new Promise(e=>setTimeout(e,t))}function D(t){let e=t*.2;return Math.max(0,Math.floor(t+(Math.random()*2-1)*e))}function M(t){let e=t.match(/EService:\s*Throttled:\s*(\d+)/i);if(!e)return null;let r=Number(e[1]);return Number.isFinite(r)?r:null}var b=class extends Error{name="KrakenApiError";endpoint;httpStatus;httpStatusText;krakenErrorCodes;rawBody;constructor(e,r={}){super(e),Object.setPrototypeOf(this,new.target.prototype),this.endpoint=r.endpoint,this.httpStatus=r.httpStatus,this.httpStatusText=r.httpStatusText,this.krakenErrorCodes=r.krakenErrorCodes,this.rawBody=r.rawBody;}};var h=class{baseUrl;timeoutMs;userAgent;apiKey;apiSecret;logger;lastNonce;lastMs=0;restLimiter;tradingLimiter;rateLimitOptions;restCostFn;tradingCostFn;constructor(e={}){this.baseUrl=e.baseUrl??"https://api.kraken.com",this.timeoutMs=e.timeoutMs??1e4,this.userAgent=e.userAgent,this.apiKey=e.apiKey,this.apiSecret=e.apiSecret,this.logger=e.logger;let r=e.rateLimit??{},n=r.mode??"auto",s=r.tier??"starter";if(this.rateLimitOptions={retryOnRateLimit:r.retryOnRateLimit??true,maxRetries:r.maxRetries??5},this.restCostFn=r.restCostFn??L,this.tradingCostFn=r.tradingCostFn??(()=>1),e.limiter?.rest&&(this.restLimiter=e.limiter.rest),e.limiter?.trading&&(this.tradingLimiter=e.limiter.trading),n!=="off"){if(!this.restLimiter){let{maxCounter:o,decayPerSec:a}=I(s);this.restLimiter=new f(o,a);}this.tradingLimiter||(this.tradingLimiter=new f(10,1));}}createNonce(){let e=Date.now();return this.lastNonce===void 0?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e,this.lastNonce.toString()):(e>this.lastMs?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e):this.lastNonce=this.lastNonce+1n,this.lastNonce.toString())}async publicGet(e,r){let n=new URL(e,this.baseUrl);if(r)for(let[s,o]of Object.entries(r))n.searchParams.set(s,String(o));return this.logger?.debug?.("Kraken REST public GET request",{endpoint:e,url:n.toString(),query:r}),this.scheduleWithRetry(e,async()=>{let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs);try{let a=await fetch(n,{method:"GET",signal:s.signal,headers:this.userAgent?{"User-Agent":this.userAgent}:void 0});if(!a.ok)throw this.logger?.error?.("Kraken REST HTTP error",{endpoint:e,status:a.status,statusText:a.statusText}),new b(`HTTP error from Kraken: ${a.status} ${a.statusText}`,{endpoint:e,httpStatus:a.status,httpStatusText:a.statusText});let i;try{i=await a.json();}catch(l){throw this.logger?.error?.("Kraken REST JSON parse error",{endpoint:e,error:l}),new b("Failed to parse Kraken response JSON",{endpoint:e,httpStatus:a.status})}if(i.error?.length)throw this.logger?.warn?.("Kraken REST API error",{endpoint:e,krakenErrors:i.error}),new b(`Kraken API error: ${i.error.join(", ")}`,{endpoint:e,httpStatus:a.status,krakenErrorCodes:i.error,rawBody:i});return this.logger?.debug?.("Kraken REST public GET success",{endpoint:e}),i.result}finally{clearTimeout(o);}})}async privatePost(e,r){if(!this.apiKey||!this.apiSecret)throw new b("Missing apiKey or apiSecret for Kraken private API call",{endpoint:e});let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),o=new URLSearchParams;if(o.set("nonce",s),r)for(let[p,K]of Object.entries(r))K!==void 0&&o.set(p,String(K));let a=o.toString(),i=crypto.createHash("sha256").update(s+a).digest(),l=Buffer.from(this.apiSecret,"base64"),d=crypto.createHmac("sha512",l);d.update(e),d.update(i);let c=d.digest("base64");this.logger?.debug?.("Kraken REST private POST request",{endpoint:e,url:n.toString(),hasParams:!!r});let k=new AbortController,u=setTimeout(()=>k.abort(),this.timeoutMs);try{let p=await fetch(n,{method:"POST",signal:k.signal,headers:{"Content-Type":"application/x-www-form-urlencoded","API-Key":this.apiKey,"API-Sign":c,...this.userAgent?{"User-Agent":this.userAgent}:{}},body:a});if(!p.ok)throw this.logger?.error?.("Kraken REST private HTTP error",{endpoint:e,status:p.status,statusText:p.statusText}),new b(`HTTP error from Kraken private API: ${p.status} ${p.statusText}`,{endpoint:e,httpStatus:p.status,httpStatusText:p.statusText});let K;try{K=await p.json();}catch(m){throw this.logger?.error?.("Kraken REST private JSON parse error",{endpoint:e,error:m}),new b("Failed to parse Kraken private API response JSON",{endpoint:e,httpStatus:p.status})}if(K.error?.length)throw this.logger?.warn?.("Kraken REST private API error",{endpoint:e,krakenErrors:K.error}),new b(`Kraken private API error: ${K.error.join(", ")}`,{endpoint:e,httpStatus:p.status,krakenErrorCodes:K.error,rawBody:K});return this.logger?.debug?.("Kraken REST private POST success",{endpoint:e}),K.result}finally{clearTimeout(u);}})}async privatePostBinary(e,r){if(!this.apiKey||!this.apiSecret)throw new Error("KrakenRestBase: apiKey and apiSecret are required for private endpoints");let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),a=new URLSearchParams({nonce:s,...r??{}}).toString(),i=this.signPrivateRequest(e,s,a);this.logger?.debug?.("[KrakenRestBase] privatePostBinary request",{url:n.toString(),path:e,body:r});let l={"API-Key":this.apiKey,"API-Sign":i,"User-Agent":this.userAgent??"lynx-crypto-kraken-client/0.1.0","Content-Type":"application/x-www-form-urlencoded"},d=await fetch(n.toString(),{method:"POST",headers:l,body:a});if(!d.ok){let u=await d.text().catch(()=>"");throw this.logger?.error?.("[KrakenRestBase] privatePostBinary HTTP error",{status:d.status,statusText:d.statusText,body:u}),new Error(`Kraken privatePostBinary failed: ${d.status} ${d.statusText} \u2013 ${u}`)}if((d.headers.get("content-type")??"").includes("application/json")){let u=await d.json().catch(()=>null);if(!u)throw new Error("Kraken privatePostBinary: expected JSON body for error response");let p=u.error??[];if(p.length>0){let K=`Kraken API error: ${p.join(", ")}`;this.logger?.error?.("[KrakenRestBase] Kraken API error (binary response)",{errors:p});let m=new Error(K);throw m.krakenErrors=p,m}throw new Error("Kraken privatePostBinary: expected binary data but got JSON without errors")}let k=await d.arrayBuffer();return this.logger?.debug?.("[KrakenRestBase] privatePostBinary success",{bytes:k.byteLength}),k})}signPrivateRequest(e,r,n){if(!this.apiSecret)throw new Error("KrakenRestBase: apiSecret is required for private endpoints");let s=Buffer.from(this.apiSecret,"base64"),o=crypto.createHash("sha256").update(r+n).digest(),a=crypto.createHmac("sha512",s);return a.update(e),a.update(o),a.digest("base64")}async scheduleWithRetry(e,r){let n=v(e)?this.tradingLimiter:this.restLimiter,s=v(e)?this.tradingCostFn(e):this.restCostFn(e),o=()=>n?n.schedule(r,{cost:s}):r();if(!this.rateLimitOptions.retryOnRateLimit)return o();let a=this.rateLimitOptions.maxRetries,i=0;for(;;)try{return await o()}catch(l){i++;let d=l?.message??(typeof l=="string"?l:"")??"",c=l?.krakenErrorCodes??l?.krakenErrors,k=d.includes("EAPI:Rate limit exceeded")||Array.isArray(c)&&c.some(g=>g.includes("EAPI:Rate limit exceeded")),u=(()=>{let g=M(d);if(g)return g;if(Array.isArray(c))for(let G of c){let C=M(G);if(C)return C}return null})(),p=l?.httpStatus===429;if(!(k||u!==null||p)||i>a)throw l;let m=0;if(u!==null){let g=Math.floor(Date.now()/1e3);m=Math.max(0,u-g)*1e3;}else {let g=250*Math.pow(2,i-1);m=Math.min(g,1e4);}m=D(m),this.logger?.warn?.("Kraken rate limited; retrying",{endpoint:e,attempt:i,waitMs:m,reason:p?"HTTP 429":u?"EService: Throttled":"EAPI: Rate limit exceeded"}),await w(m);}}};function F(t){return t.publicGet("/0/public/Time")}function H(t){return t.publicGet("/0/public/SystemStatus")}function j(t,e){let r={};return e?.asset&&e.asset.length>0&&(r.asset=e.asset.join(",")),e?.aclass&&(r.aclass=e.aclass),t.publicGet("/0/public/Assets",r)}function Q(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.aclass_base&&(r.aclass_base=e.aclass_base),e?.info&&(r.info=e.info),e?.country_code&&(r.country_code=e.country_code),t.publicGet("/0/public/AssetPairs",r)}function N(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Ticker",r)}async function V(t,e){let r={pair:e.pair};e.interval!==void 0&&(r.interval=String(e.interval)),e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/OHLC",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,ohlc:a}}function z(t,e){let r={pair:e.pair};return e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Depth",r)}async function $(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Trades",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,trades:a}}async function J(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Spread",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,spreads:a}}var x=class{constructor(e){this.base=e;}getServerTime(){return F(this.base)}getSystemStatus(){return H(this.base)}getAssetInfo(e){return j(this.base,e)}getTradableAssetPairs(e){return Q(this.base,e)}getTickerInformation(e){return N(this.base,e)}getOhlcData(e){return V(this.base,e)}getOrderBook(e){return z(this.base,e)}getRecentTrades(e){return $(this.base,e)}getRecentSpreads(e){return J(this.base,e)}};function Y(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Balance",r)}function X(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/BalanceEx",r)}function Z(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/CreditLines",r)}function ee(t,e){let r={};return e?.asset&&(r.asset=e.asset),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeBalance",r)}function re(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenOrders",r)}function te(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.closetime&&(r.closetime=e.closetime),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/ClosedOrders",r)}function ne(t,e){let r={};return e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.userref!==void 0&&(r.userref=String(e.userref)),Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryOrders",r)}function se(t,e){let r={order_id:e.order_id};return e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OrderAmends",r)}function ae(t,e){let r={};return e?.type&&(r.type=e.type),e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.ledgers!==void 0&&(r.ledgers=e.ledgers?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradesHistory",r)}function oe(t,e){let r={};return Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryTrades",r)}function ie(t,e){let r={};return e?.txid!==void 0&&(r.txid=Array.isArray(e.txid)?e.txid.join(","):e.txid),e?.docalcs!==void 0&&(r.docalcs=e.docalcs?"true":"false"),e?.consolidation&&(r.consolidation=e.consolidation),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenPositions",r)}function de(t,e){let r={};return e?.asset!==void 0&&(r.asset=Array.isArray(e.asset)?e.asset.join(","):e.asset),e?.aclass&&(r.aclass=e.aclass),e?.type&&(r.type=e.type),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Ledgers",r)}function ce(t,e){let r={};return Array.isArray(e.id)?r.id=e.id.join(","):r.id=e.id,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryLedgers",r)}function le(t,e){let r={};return e?.pair!==void 0&&(r.pair=Array.isArray(e.pair)?e.pair.join(","):e.pair),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeVolume",r)}function pe(t,e){let r={report:e.report,description:e.description};return e.format&&(r.format=e.format),e.fields&&(r.fields=e.fields),e.starttm!==void 0&&(r.starttm=String(e.starttm)),e.endtm!==void 0&&(r.endtm=String(e.endtm)),t.privatePost("/0/private/AddExport",r)}function ue(t,e){let r={report:e.report};return t.privatePost("/0/private/ExportStatus",r)}function ke(t,e){let r={id:e.id};return t.privatePostBinary("/0/private/RetrieveExport",r)}function Ke(t,e){let r={id:e.id,type:e.type};return t.privatePost("/0/private/RemoveExport",r)}var W=class{constructor(e){this.base=e;}getAccountBalance(e){return Y(this.base,e)}getExtendedBalance(e){return X(this.base,e)}getCreditLines(e){return Z(this.base,e)}getTradeBalance(e){return ee(this.base,e)}getOpenOrders(e){return re(this.base,e)}getClosedOrders(e){return te(this.base,e)}queryOrdersInfo(e){return ne(this.base,e)}getOrderAmends(e){return se(this.base,e)}getTradesHistory(e){return ae(this.base,e)}queryTradesInfo(e){return oe(this.base,e)}getOpenPositions(e){return ie(this.base,e)}getLedgersInfo(e){return de(this.base,e)}queryLedgers(e){return ce(this.base,e)}getTradeVolume(e){return le(this.base,e)}requestExportReport(e){return pe(this.base,e)}getExportReportStatus(e){return ue(this.base,e)}retrieveExportReport(e){return ke(this.base,e)}deleteExportReport(e){return Ke(this.base,e)}};function me(t,e){if(e.userref!==void 0&&e.cl_ord_id)throw new Error("KrakenAddOrderParams: userref and cl_ord_id are mutually exclusive");let r={ordertype:e.ordertype,type:e.type,volume:e.volume,pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.displayvol&&(r.displayvol=e.displayvol),e.asset_class&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.trigger&&(r.trigger=e.trigger),e.leverage!==void 0&&(r.leverage=e.leverage),e.reduce_only!==void 0&&(r.reduce_only=e.reduce_only?"true":"false"),e.stptype&&(r.stptype=e.stptype),e.oflags&&(r.oflags=e.oflags),e.timeinforce&&(r.timeinforce=e.timeinforce),e.starttm!==void 0&&(r.starttm=e.starttm),e.expiretm!==void 0&&(r.expiretm=e.expiretm),e.deadline!==void 0&&(r.deadline=e.deadline),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),e.close&&(r["close[ordertype]"]=e.close.ordertype,e.close.price!==void 0&&(r["close[price]"]=e.close.price),e.close.price2!==void 0&&(r["close[price2]"]=e.close.price2)),t.privatePost("/0/private/AddOrder",r)}function be(t,e){if(!e.txid&&!e.cl_ord_id)throw new Error("KrakenAmendOrderParams: either txid or cl_ord_id must be provided");let r={};return e.txid&&(r.txid=e.txid),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.order_qty!==void 0&&(r.order_qty=e.order_qty),e.display_qty!==void 0&&(r.display_qty=e.display_qty),e.limit_price!==void 0&&(r.limit_price=e.limit_price),e.trigger_price!==void 0&&(r.trigger_price=e.trigger_price),e.pair!==void 0&&(r.pair=e.pair),e.post_only!==void 0&&(r.post_only=e.post_only?"true":"false"),e.deadline!==void 0&&(r.deadline=e.deadline),t.privatePost("/0/private/AmendOrder",r)}function ge(t,e){let{txid:r,userref:n,cl_ord_id:s}=e,o=(r!==void 0?1:0)+(n!==void 0?1:0)+(s!==void 0?1:0);if(o===0)throw new Error("KrakenCancelOrderParams: one of txid, userref, or cl_ord_id must be provided");if(o>1)throw new Error("KrakenCancelOrderParams: txid, userref, and cl_ord_id are mutually exclusive; provide exactly one");let a={};return n!==void 0?a.txid=String(n):s!==void 0?a.cl_ord_id=Array.isArray(s)?s.join(","):s:r!==void 0&&(a.txid=Array.isArray(r)?r.join(","):r),t.privatePost("/0/private/CancelOrder",a)}function ye(t){return t.privatePost("/0/private/CancelAll",{})}function fe(t,e){let r={timeout:String(e.timeout)};return t.privatePost("/0/private/CancelAllOrdersAfter",r)}function he(t){return t.privatePost("/0/private/GetWebSocketsToken",{})}function xe(t,e){let{orders:r,pair:n,asset_class:s,deadline:o,validate:a}=e;if(!Array.isArray(r)||r.length<2||r.length>15)throw new Error(`KrakenAddOrderBatchParams: orders must contain between 2 and 15 items (got ${r.length})`);for(let[d,c]of r.entries())if(c.userref!==void 0&&c.cl_ord_id!==void 0)throw new Error(`KrakenAddOrderBatchParams: order[${d}] cannot have both userref and cl_ord_id`);let i={pair:n};s&&(i.asset_class=s),o!==void 0&&(i.deadline=o),a!==void 0&&(i.validate=a?"true":"false");let l=r.map(d=>{let c={ordertype:d.ordertype,type:d.type,volume:d.volume};return d.userref!==void 0&&(c.userref=String(d.userref)),d.cl_ord_id!==void 0&&(c.cl_ord_id=d.cl_ord_id),d.displayvol!==void 0&&(c.displayvol=d.displayvol),d.price!==void 0&&(c.price=d.price),d.price2!==void 0&&(c.price2=d.price2),d.trigger!==void 0&&(c.trigger=d.trigger),d.leverage!==void 0&&(c.leverage=d.leverage),d.reduce_only!==void 0&&(c.reduce_only=d.reduce_only?"true":"false"),d.stptype!==void 0&&(c.stptype=d.stptype),d.oflags!==void 0&&(c.oflags=d.oflags),d.timeinforce!==void 0&&(c.timeinforce=d.timeinforce),d.starttm!==void 0&&(c.starttm=d.starttm),d.expiretm!==void 0&&(c.expiretm=d.expiretm),c});return i.orders=JSON.stringify(l),t.privatePost("/0/private/AddOrderBatch",i)}function We(t,e){let{orders:r,clOrdIds:n}=e,s=r?.length??0,o=n?.length??0,a=s+o;if(a===0)throw new Error("KrakenCancelOrderBatchParams: at least one txid/userref or cl_ord_id is required");if(a>50)throw new Error(`KrakenCancelOrderBatchParams: maximum 50 total ids/references allowed, got ${a}`);let i={};if(r&&r.length>0){let l=r.map(d=>({txid:String(d.txid)}));i.orders=JSON.stringify(l);}if(n&&n.length>0){let l=n.map(d=>({cl_ord_id:d}));i.cl_ord_ids=JSON.stringify(l);}return t.privatePost("/0/private/CancelOrderBatch",i)}function Oe(t,e){let r={txid:String(e.txid),pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.volume!==void 0&&(r.volume=e.volume),e.displayvol!==void 0&&(r.displayvol=e.displayvol),e.asset_class!==void 0&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.oflags!==void 0&&(r.oflags=e.oflags),e.deadline!==void 0&&(r.deadline=e.deadline),e.cancel_response!==void 0&&(r.cancel_response=e.cancel_response?"true":"false"),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),t.privatePost("/0/private/EditOrder",r)}var O=class{constructor(e){this.base=e;}addOrder(e){return me(this.base,e)}amendOrder(e){return be(this.base,e)}cancelOrder(e){return ge(this.base,e)}cancelAllOrders(){return ye(this.base)}cancelAllOrdersAfter(e){return fe(this.base,e)}getWebSocketsToken(){return he(this.base)}addOrderBatch(e){return xe(this.base,e)}cancelOrderBatch(e){return We(this.base,e)}editOrder(e){return Oe(this.base,e)}};function Re(t,e){let r={asset:e.asset};return e.aclass!==void 0&&(r.aclass=e.aclass),e.rebase_multiplier!==void 0&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositMethods",r)}function Ae(t,e){let r={asset:e.asset,method:e.method};return e.aclass!==void 0&&(r.aclass=e.aclass),e.new!==void 0&&(r.new=e.new?"true":"false"),e.amount!==void 0&&(r.amount=String(e.amount)),t.privatePost("/0/private/DepositAddresses",r)}function Te(t,e={}){let r={};return e.asset&&(r.asset=e.asset),e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.start!==void 0&&(r.start=String(e.start)),e.end!==void 0&&(r.end=String(e.end)),e.cursor&&(r.cursor=e.cursor),e.limit!==void 0&&(r.limit=String(e.limit)),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositStatus",r)}function Pe(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.network&&(r.network=e.network),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/WithdrawMethods",r)}function Se(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.key&&(r.key=e.key),e.verified!==void 0&&(r.verified=e.verified?"true":"false"),t.privatePost("/0/private/WithdrawAddresses",r)}function Be(t,e){let r={asset:e.asset,key:e.key,amount:String(e.amount)};return t.privatePost("/0/private/WithdrawInfo",r)}function _e(t,e){let{asset:r,aclass:n,key:s,address:o,amount:a,max_fee:i,rebase_multiplier:l}=e,d={asset:r,key:s,amount:String(a)};return n&&(d.aclass=n),o&&(d.address=o),i!==void 0&&(d.max_fee=String(i)),l&&(d.rebase_multiplier=l),t.privatePost("/0/private/Withdraw",d)}async function Ee(t,e={}){let{asset:r,aclass:n,method:s,start:o,end:a,cursor:i,limit:l,rebase_multiplier:d}=e,c={};return r&&(c.asset=r),n&&(c.aclass=n),s&&(c.method=s),o!==void 0&&(c.start=o),a!==void 0&&(c.end=a),i!==void 0&&(c.cursor=i),l!==void 0&&(c.limit=l),d&&(c.rebase_multiplier=d),t.privatePost("/0/private/WithdrawStatus",c)}function ve(t,e){let{asset:r,refid:n}=e,s={asset:r,refid:n};return t.privatePost("/0/private/WithdrawCancel",s)}function we(t,e){let{asset:r,from:n,to:s,amount:o}=e,a={asset:r,from:n,to:s,amount:String(o)};return t.privatePost("/0/private/WalletTransfer",a)}var R=class{constructor(e){this.base=e;}getDepositMethods(e){return Re(this.base,e)}getDepositAddresses(e){return Ae(this.base,e)}getDepositStatus(e={}){return Te(this.base,e)}getWithdrawMethods(e){return Pe(this.base,e)}getWithdrawAddresses(e){return Se(this.base,e)}getWithdrawInfo(e){return Be(this.base,e)}withdrawFunds(e){return _e(this.base,e)}getWithdrawStatus(e={}){return Ee(this.base,e)}withdrawCancel(e){return ve(this.base,e)}walletTransfer(e){return we(this.base,e)}};async function Me(t,e){let{username:r,email:n}=e,s={username:r,email:n};return t.privatePost("/0/private/CreateSubaccount",s)}async function Ge(t,e){let{asset:r,asset_class:n,amount:s,from:o,to:a}=e,i={asset:r,amount:String(s),from:o,to:a};return n&&(i.asset_class=n),t.privatePost("/0/private/AccountTransfer",i)}var A=class{constructor(e){this.base=e;}createSubaccount(e){return Me(this.base,e)}accountTransfer(e){return Ge(this.base,e)}};async function Ce(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Allocate",s)}async function Ie(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Deallocate",s)}async function Le(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/AllocateStatus",n)}async function De(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/DeallocateStatus",n)}async function qe(t,e={}){let{ascending:r,asset:n,cursor:s,limit:o,lock_type:a}=e,i={};return r!=null&&(i.ascending=r),n!=null&&(i.asset=n),s!=null&&(i.cursor=s),o!=null&&(i.limit=o),a&&a.length>0&&(i.lock_type=JSON.stringify(a)),t.privatePost("/0/private/Earn/Strategies",i)}async function Ue(t,e={}){let{ascending:r,converted_asset:n,hide_zero_allocations:s}=e,o={};return r!=null&&(o.ascending=r),n!=null&&(o.converted_asset=n),s!=null&&(o.hide_zero_allocations=s),t.privatePost("/0/private/Earn/Allocations",o)}var T=class{constructor(e){this.base=e;}allocateFunds(e){return Ce(this.base,e)}deallocateFunds(e){return Ie(this.base,e)}getAllocationStatus(e){return Le(this.base,e)}getDeallocationStatus(e){return De(this.base,e)}listStrategies(e={}){return qe(this.base,e)}listAllocations(e={}){return Ue(this.base,e)}};async function Fe(t,e){let{symbol:r}=e,s={symbol:typeof r=="string"?r:r.join(",")};return t.publicGet("/0/public/PreTrade",s)}async function He(t,e={}){let{symbol:r,from_ts:n,to_ts:s,count:o}=e,a={};return r&&(a.symbol=r),n&&(a.from_ts=n),s&&(a.to_ts=s),o!==void 0&&(a.count=o),t.publicGet("/0/public/PostTrade",a)}var P=class{constructor(e){this.base=e;}getPreTradeData(e){return Fe(this.base,e)}getPostTradeData(e={}){return He(this.base,e)}};var je=class extends h{marketData;accountData;trading;funding;subaccounts;earn;transparency;constructor(e={}){super(e),this.marketData=new x(this),this.accountData=new W(this),this.trading=new O(this),this.funding=new R(this),this.subaccounts=new A(this),this.earn=new T(this),this.transparency=new P(this);}};var y=class{url;authToken;WebSocketImpl;logger;autoReconnect;reconnectDelayMs;requestTimeoutMs;ws=null;connectingPromise=null;manuallyClosed=false;nextReqId=1;pending=new Map;messageHandlers=new Set;reconnectAttempts=0;constructor(e){if(this.url=e.url,this.authToken=e.authToken,this.WebSocketImpl=e.WebSocketImpl??(typeof ws.WebSocket<"u"?ws.WebSocket:void 0),this.logger=e.logger,this.autoReconnect=e.autoReconnect??true,this.reconnectDelayMs=e.reconnectDelayMs??1e3,this.requestTimeoutMs=e.requestTimeoutMs??1e4,!this.WebSocketImpl)throw new Error("No WebSocket implementation available. Pass `WebSocketImpl` in KrakenWebsocketConnectionOptions when using Node.js.")}get readyState(){return this.ws?.readyState??-1}async connect(){if(!(this.ws&&this.ws.readyState===1))return this.connectingPromise?this.connectingPromise:(this.manuallyClosed=false,this.connectingPromise=new Promise((e,r)=>{try{let n=this.WebSocketImpl,s=new n(this.url);this.ws=s,s.onopen=()=>{this.reconnectAttempts=0,this.logger?.info?.("Kraken WS connected",{url:this.url}),this.connectingPromise=null,e();},s.onclose=o=>{this.logger?.info?.("Kraken WS closed",{url:this.url,event:o,manuallyClosed:this.manuallyClosed}),this.ws=null,this.connectingPromise=null;for(let[a,i]of this.pending)clearTimeout(i.timeoutId),i.reject(new Error(`WebSocket closed before response for req_id ${a}`));if(this.pending.clear(),!this.manuallyClosed&&this.autoReconnect){this.reconnectAttempts++;let a=this.reconnectDelayMs,i=Math.min(3e4,a*Math.pow(2,this.reconnectAttempts-1)),l=this.reconnectAttempts>=4?5e3:0,d=Math.max(l,i),c=Math.max(0,Math.floor(d*(.8+Math.random()*.4)));setTimeout(()=>{this.logger?.info?.("Kraken WS reconnecting",{url:this.url,attempt:this.reconnectAttempts,delayMs:c}),this.connect().catch(k=>{this.logger?.error?.("Kraken WS reconnect failed",{url:this.url,error:k});});},c);}},s.onerror=o=>{this.logger?.error?.("Kraken WS error",{url:this.url,event:o});},s.onmessage=o=>{let a=o.data;if(typeof o.data=="string")try{a=JSON.parse(o.data);}catch(i){this.logger?.warn?.("Failed to parse WS JSON message",{data:o.data,error:i});}if(a&&typeof a=="object"&&"req_id"in a&&typeof a.req_id=="number"){let i=a.req_id,l=this.pending.get(i);l&&(this.pending.delete(i),clearTimeout(l.timeoutId),l.resolve(a));}for(let i of this.messageHandlers)try{i(a);}catch(l){this.logger?.error?.("WS message handler threw",{error:l});}};}catch(n){this.connectingPromise=null,r(n);}}),this.connectingPromise)}close(e,r){this.manuallyClosed=true,this.ws&&this.ws.readyState===1&&this.ws.close(e,r);}addMessageHandler(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}async sendRaw(e){(!this.ws||this.ws.readyState!==1)&&await this.connect();let r=this.ws;if(!r||r.readyState!==1)throw new Error("WebSocket is not open");let n=typeof e=="string"?e:JSON.stringify(e);r.send(n);}async request(e,r,n){(!this.ws||this.ws.readyState!==1)&&await this.connect();let s=n?.reqId??this.nextReqId++,o=n?.timeoutMs??this.requestTimeoutMs,a=n?.attachAuthToken??true,i=r?{...r}:{};a&&this.authToken&&(i.token===void 0||i.token===null)&&(i.token=this.authToken);let l={method:e,params:Object.keys(i).length?i:void 0,req_id:s};return this.logger?.debug?.("Kraken WS request",{envelope:l}),await new Promise((d,c)=>{let k=setTimeout(()=>{this.pending.delete(s),c(new Error(`Kraken WS request timed out after ${o}ms (method=${e}, req_id=${s})`));},o),u={resolve:p=>d(p),reject:c,timeoutId:k};this.pending.set(s,u);try{let p=this.ws;if(!p||p.readyState!==1){clearTimeout(k),this.pending.delete(s),c(new Error(`WebSocket is not open (method=${e}, req_id=${s})`));return}p.send(JSON.stringify(l));}catch(p){clearTimeout(k),this.pending.delete(s),c(p);}})}};function Ne(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="status"&&n.type==="update"&&Array.isArray(n.data)&&e(n);})}async function Ve(t,e={},r={}){return t.request("ping",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}function ze(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="heartbeat"&&e(n);})}var S=class{constructor(e){this.ws=e;}ping(e={},r={}){return Ve(this.ws,e,r)}onStatus(e){return Ne(this.ws,e)}onHeartbeat(e){return ze(this.ws,e)}};async function $e(t,e,r={}){let n={channel:"ticker",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Je(t,e,r={}){let n={channel:"ticker",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Ye(t,e,r={}){let n={channel:"book",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Xe(t,e,r={}){let n={channel:"book",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Ze(t,e,r={}){let n={channel:"level3",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function er(t,e,r={}){let n={channel:"level3",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function rr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function tr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function nr(t,e,r={}){let n={channel:"trade",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function sr(t,e,r={}){let n={channel:"trade",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function ar(t,e={},r={}){let n={channel:"instrument",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function or(t,e={},r={}){let n={channel:"instrument",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}var B=class{constructor(e){this.ws=e;}subscribeTicker(e,r={}){return $e(this.ws,e,r)}unsubscribeTicker(e,r={}){return Je(this.ws,e,r)}subscribeBook(e,r={}){return Ye(this.ws,e,r)}unsubscribeBook(e,r={}){return Xe(this.ws,e,r)}subscribeLevel3(e,r={}){return Ze(this.ws,e,r)}unsubscribeLevel3(e,r={}){return er(this.ws,e,r)}subscribeOhlc(e,r={}){return rr(this.ws,e,r)}unsubscribeOhlc(e,r={}){return tr(this.ws,e,r)}subscribeTrade(e,r={}){return nr(this.ws,e,r)}unsubscribeTrade(e,r={}){return sr(this.ws,e,r)}subscribeInstrument(e={},r={}){return ar(this.ws,e,r)}unsubscribeInstrument(e={},r={}){return or(this.ws,e,r)}};async function ir(t,e,r={}){let n={channel:"executions",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function dr(t,e={},r={}){let n={channel:"executions",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function cr(t,e={},r={}){let n={channel:"balances",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function lr(t,e={},r={}){let n={channel:"balances",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}var _=class{constructor(e){this.ws=e;}subscribeExecutions(e,r){return ir(this.ws,e,r)}unsubscribeExecutions(e,r){return dr(this.ws,e??{},r)}subscribeBalances(e={},r){return cr(this.ws,e,r)}unsubscribeBalances(e,r){return lr(this.ws,e??{},r)}};async function pr(t,e,r={}){return t.request("add_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function ur(t,e,r={}){let n=!!e.order_id,s=!!e.cl_ord_id;if(n&&s||!n&&!s)throw new Error("Kraken WS amend_order: exactly one of `order_id` or `cl_ord_id` must be provided");return t.request("amend_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function kr(t,e,r={}){return t.request("edit_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Kr(t,e,r={}){let n=Array.isArray(e.order_id)&&e.order_id.length>0,s=Array.isArray(e.cl_ord_id)&&e.cl_ord_id.length>0,o=Array.isArray(e.order_userref)&&e.order_userref.length>0;if(!n&&!s&&!o)throw new Error("Kraken WS cancel_order: at least one of `order_id`, `cl_ord_id`, or `order_userref` must contain at least one entry");return t.request("cancel_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function mr(t,e={},r={}){return t.request("cancel_all",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function br(t,e,r={}){if(!Number.isFinite(e.timeout))throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be a finite number (seconds)");if(e.timeout<0||e.timeout>=86400)throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be >= 0 and < 86400 seconds");return t.request("cancel_all_orders_after",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function gr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_add: `orders` must contain at least 2 entries");if(e.orders.length>15)throw new Error("Kraken WS batch_add: `orders` must not contain more than 15 entries");for(let[n,s]of e.orders.entries())if(s.cl_ord_id&&typeof s.order_userref=="number")throw new Error(`Kraken WS batch_add: order at index ${n} must not specify both cl_ord_id and order_userref`);return t.request("batch_add",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function yr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_cancel: `orders` must contain at least 2 identifiers");if(e.orders.length>50)throw new Error("Kraken WS batch_cancel: `orders` must not contain more than 50 identifiers");return t.request("batch_cancel",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}var E=class{constructor(e){this.ws=e;}addOrder(e,r){return pr(this.ws,e,r)}amendOrder(e,r){return ur(this.ws,e,r)}editOrder(e,r){return kr(this.ws,e,r)}cancelOrder(e,r){return Kr(this.ws,e,r)}cancelAll(e,r){return mr(this.ws,e??{},r)}cancelAllOrdersAfter(e,r){return br(this.ws,e,r)}batchAdd(e,r){return gr(this.ws,e,r)}batchCancel(e,r){return yr(this.ws,e,r)}};var fr=class{publicConnection;privateConnection;admin;marketData;userData;userTrading;constructor(e={}){let{publicUrl:r="wss://ws.kraken.com/v2",privateUrl:n="wss://ws-auth.kraken.com/v2",authToken:s,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:l,logger:d}=e,c={authToken:void 0,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:l,logger:d};this.publicConnection=new y({...c,url:r}),this.privateConnection=new y({...c,url:n,authToken:s}),this.admin=new S(this.publicConnection),this.marketData=new B(this.publicConnection),this.userData=new _(this.privateConnection),this.userTrading=new E(this.privateConnection);}};
|
|
2
|
+
exports.KrakenSpotAccountDataApi=W;exports.KrakenSpotEarnApi=T;exports.KrakenSpotFundingApi=R;exports.KrakenSpotMarketDataApi=x;exports.KrakenSpotRestClient=je;exports.KrakenSpotSubaccountsApi=A;exports.KrakenSpotTradingApi=O;exports.KrakenSpotTransparencyApi=P;exports.KrakenSpotWebsocketV2Client=fr;exports.KrakenWebsocketBase=y;//# sourceMappingURL=index.cjs.map
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|