@livo-build/runtime 0.2.6 → 0.2.13
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/dist/aes.d.ts +4 -0
- package/dist/aes.js +38 -0
- package/dist/auth.test.d.ts +1 -0
- package/dist/auth.test.js +57 -0
- package/dist/cache.d.ts +12 -0
- package/dist/cache.js +27 -0
- package/dist/email.d.ts +74 -0
- package/dist/email.js +100 -0
- package/dist/email.test.d.ts +1 -0
- package/dist/email.test.js +68 -0
- package/dist/http.d.ts +48 -0
- package/dist/http.js +133 -0
- package/dist/hyperliquid.d.ts +269 -0
- package/dist/hyperliquid.js +194 -0
- package/dist/hyperliquid.test.js +17 -1
- package/dist/hyperliquidBridge.d.ts +30 -0
- package/dist/hyperliquidBridge.js +61 -0
- package/dist/index.d.ts +24 -1
- package/dist/index.js +17 -0
- package/dist/nft.d.ts +33 -0
- package/dist/nft.js +72 -0
- package/dist/nft.test.d.ts +1 -0
- package/dist/nft.test.js +44 -0
- package/dist/ratelimit.d.ts +19 -0
- package/dist/ratelimit.js +11 -0
- package/dist/reads.d.ts +12 -0
- package/dist/reads.js +36 -0
- package/dist/sessions.d.ts +8 -0
- package/dist/sessions.js +60 -0
- package/dist/signals.d.ts +131 -0
- package/dist/signals.js +146 -0
- package/dist/siwe.d.ts +24 -0
- package/dist/siwe.js +33 -0
- package/dist/sse.test.d.ts +1 -0
- package/dist/sse.test.js +28 -0
- package/dist/webhook.d.ts +18 -0
- package/dist/webhook.js +49 -0
- package/dist/webhook.test.d.ts +1 -0
- package/dist/webhook.test.js +46 -0
- package/package.json +1 -1
package/dist/hyperliquid.d.ts
CHANGED
|
@@ -49,6 +49,51 @@ export interface AccountBalance {
|
|
|
49
49
|
totalMarginUsed: number;
|
|
50
50
|
totalNtlPos: number;
|
|
51
51
|
}
|
|
52
|
+
/** A parsed open perp position. */
|
|
53
|
+
export interface PositionInfo {
|
|
54
|
+
coin: string;
|
|
55
|
+
/** Absolute size (always ≥ 0; see `side`). */
|
|
56
|
+
size: number;
|
|
57
|
+
side: "long" | "short" | "flat";
|
|
58
|
+
entryPx: number;
|
|
59
|
+
positionValue: number;
|
|
60
|
+
unrealizedPnl: number;
|
|
61
|
+
/** Return on equity as a fraction (0.12 = +12%). */
|
|
62
|
+
returnOnEquity: number;
|
|
63
|
+
leverage: number;
|
|
64
|
+
liquidationPx: number | null;
|
|
65
|
+
marginUsed: number;
|
|
66
|
+
}
|
|
67
|
+
/** Best bid / offer snapshot. */
|
|
68
|
+
export interface Bbo {
|
|
69
|
+
bid: number | null;
|
|
70
|
+
ask: number | null;
|
|
71
|
+
mid: number | null;
|
|
72
|
+
spread: number | null;
|
|
73
|
+
}
|
|
74
|
+
interface RawPosition {
|
|
75
|
+
coin: string;
|
|
76
|
+
szi: string;
|
|
77
|
+
entryPx?: string | null;
|
|
78
|
+
positionValue?: string;
|
|
79
|
+
unrealizedPnl?: string;
|
|
80
|
+
returnOnEquity?: string;
|
|
81
|
+
leverage?: {
|
|
82
|
+
value?: number;
|
|
83
|
+
};
|
|
84
|
+
liquidationPx?: string | null;
|
|
85
|
+
marginUsed?: string;
|
|
86
|
+
}
|
|
87
|
+
/** Parse a Hyperliquid clearinghouse position into a clean PositionInfo. */
|
|
88
|
+
export declare function parseHlPosition(p: RawPosition): PositionInfo;
|
|
89
|
+
/** Parse an L2 book into a best bid/offer + mid + spread. */
|
|
90
|
+
export declare function parseBbo(book: {
|
|
91
|
+
levels?: [Array<{
|
|
92
|
+
px: string;
|
|
93
|
+
}>, Array<{
|
|
94
|
+
px: string;
|
|
95
|
+
}>];
|
|
96
|
+
}): Bbo;
|
|
52
97
|
export interface PlaceOrderOptions {
|
|
53
98
|
/** Reduce-only (close, never flip). Default false. */
|
|
54
99
|
reduceOnly?: boolean;
|
|
@@ -133,6 +178,32 @@ export declare class Hyperliquid {
|
|
|
133
178
|
assetCtx(coin: string): Promise<AssetContext>;
|
|
134
179
|
/** OHLCV candles for charting. `interval` default "1h"; window defaults to the last 24h. */
|
|
135
180
|
candles(coin: string, interval?: CandleInterval, opts?: CandlesOptions): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").CandleSnapshotResponse>;
|
|
181
|
+
/** Recent public trades for a coin. */
|
|
182
|
+
recentTrades(coin: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").RecentTradesResponse>;
|
|
183
|
+
/** Best bid/offer + mid + spread for a coin (parsed from the L2 book). */
|
|
184
|
+
bbo(coin: string): Promise<Bbo>;
|
|
185
|
+
/** All open positions as clean PositionInfo[] (default: the signer's account). */
|
|
186
|
+
positionsList(user?: string): Promise<PositionInfo[]>;
|
|
187
|
+
/** A single open position for a coin, or null if flat. */
|
|
188
|
+
position(coin: string, user?: string): Promise<PositionInfo | null>;
|
|
189
|
+
/** Current hourly funding rate for a coin (fraction, e.g. 0.0000125). */
|
|
190
|
+
fundingRate(coin: string): Promise<number>;
|
|
191
|
+
/** Historical funding rates for a coin (default: the last 7 days). */
|
|
192
|
+
fundingHistory(coin: string, opts?: {
|
|
193
|
+
startTime?: number;
|
|
194
|
+
endTime?: number;
|
|
195
|
+
lookbackMs?: number;
|
|
196
|
+
}): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").FundingHistoryResponse>;
|
|
197
|
+
/** Funding payments paid/received by an account (default signer; last 7 days). */
|
|
198
|
+
userFunding(opts?: {
|
|
199
|
+
startTime?: number;
|
|
200
|
+
endTime?: number;
|
|
201
|
+
lookbackMs?: number;
|
|
202
|
+
}, user?: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").UserFundingResponse>;
|
|
203
|
+
/** Predicted next funding rates across venues (no key). */
|
|
204
|
+
predictedFundings(): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").PredictedFundingsResponse>;
|
|
205
|
+
/** Portfolio history (PnL/account-value time series) for an account (default: the signer). */
|
|
206
|
+
portfolio(user?: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").PortfolioResponse>;
|
|
136
207
|
/** Raw order passthrough (the @nktkas `order` shape) for full control. */
|
|
137
208
|
order(params: Parameters<ExchangeClient["order"]>[0]): Promise<{
|
|
138
209
|
status: "ok";
|
|
@@ -333,6 +404,130 @@ export declare class Hyperliquid {
|
|
|
333
404
|
};
|
|
334
405
|
};
|
|
335
406
|
}>;
|
|
407
|
+
/** Cancel a resting order by its client order id (cloid). */
|
|
408
|
+
cancelByCloid(coin: string, cloid: Hex): Promise<{
|
|
409
|
+
status: "ok";
|
|
410
|
+
response: {
|
|
411
|
+
type: "cancel";
|
|
412
|
+
data: {
|
|
413
|
+
statuses: "success"[];
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
}>;
|
|
417
|
+
/** Cancel ALL resting orders (optionally only for one coin). Returns the count cancelled. */
|
|
418
|
+
cancelAll(coin?: string): Promise<{
|
|
419
|
+
cancelled: number;
|
|
420
|
+
}>;
|
|
421
|
+
/** Modify a resting limit order in place (new size/price/side). */
|
|
422
|
+
modifyOrder(oid: number, coin: string, isBuy: boolean, size: number, price: number, opts?: PlaceOrderOptions): Promise<{
|
|
423
|
+
status: "ok";
|
|
424
|
+
response: {
|
|
425
|
+
type: "default";
|
|
426
|
+
};
|
|
427
|
+
}>;
|
|
428
|
+
/**
|
|
429
|
+
* Place a trigger order (stop / take-profit). `triggerPx` is the activation price;
|
|
430
|
+
* `tpsl` is "sl" (stop) or "tp". Market trigger by default (fills at market once
|
|
431
|
+
* armed); reduce-only by default (closing). `isBuy` is the side that executes —
|
|
432
|
+
* to protect a LONG use isBuy=false (sell), for a SHORT use isBuy=true (buy).
|
|
433
|
+
*/
|
|
434
|
+
trigger(coin: string, isBuy: boolean, size: number, triggerPx: number, opts: {
|
|
435
|
+
tpsl: "tp" | "sl";
|
|
436
|
+
isMarket?: boolean;
|
|
437
|
+
reduceOnly?: boolean;
|
|
438
|
+
price?: number;
|
|
439
|
+
}): Promise<{
|
|
440
|
+
status: "ok";
|
|
441
|
+
response: {
|
|
442
|
+
type: "order";
|
|
443
|
+
data: {
|
|
444
|
+
statuses: ({
|
|
445
|
+
resting: {
|
|
446
|
+
oid: number;
|
|
447
|
+
cloid?: `0x${string}`;
|
|
448
|
+
};
|
|
449
|
+
} | {
|
|
450
|
+
filled: {
|
|
451
|
+
totalSz: string;
|
|
452
|
+
avgPx: string;
|
|
453
|
+
oid: number;
|
|
454
|
+
cloid?: `0x${string}`;
|
|
455
|
+
};
|
|
456
|
+
} | "waitingForFill" | "waitingForTrigger")[];
|
|
457
|
+
};
|
|
458
|
+
};
|
|
459
|
+
}>;
|
|
460
|
+
/** Stop-loss trigger (reduce-only market by default). See `trigger` for `isBuy`. */
|
|
461
|
+
stopLoss(coin: string, isBuy: boolean, size: number, triggerPx: number, opts?: {
|
|
462
|
+
isMarket?: boolean;
|
|
463
|
+
price?: number;
|
|
464
|
+
}): Promise<{
|
|
465
|
+
status: "ok";
|
|
466
|
+
response: {
|
|
467
|
+
type: "order";
|
|
468
|
+
data: {
|
|
469
|
+
statuses: ({
|
|
470
|
+
resting: {
|
|
471
|
+
oid: number;
|
|
472
|
+
cloid?: `0x${string}`;
|
|
473
|
+
};
|
|
474
|
+
} | {
|
|
475
|
+
filled: {
|
|
476
|
+
totalSz: string;
|
|
477
|
+
avgPx: string;
|
|
478
|
+
oid: number;
|
|
479
|
+
cloid?: `0x${string}`;
|
|
480
|
+
};
|
|
481
|
+
} | "waitingForFill" | "waitingForTrigger")[];
|
|
482
|
+
};
|
|
483
|
+
};
|
|
484
|
+
}>;
|
|
485
|
+
/** Take-profit trigger (reduce-only market by default). See `trigger` for `isBuy`. */
|
|
486
|
+
takeProfit(coin: string, isBuy: boolean, size: number, triggerPx: number, opts?: {
|
|
487
|
+
isMarket?: boolean;
|
|
488
|
+
price?: number;
|
|
489
|
+
}): Promise<{
|
|
490
|
+
status: "ok";
|
|
491
|
+
response: {
|
|
492
|
+
type: "order";
|
|
493
|
+
data: {
|
|
494
|
+
statuses: ({
|
|
495
|
+
resting: {
|
|
496
|
+
oid: number;
|
|
497
|
+
cloid?: `0x${string}`;
|
|
498
|
+
};
|
|
499
|
+
} | {
|
|
500
|
+
filled: {
|
|
501
|
+
totalSz: string;
|
|
502
|
+
avgPx: string;
|
|
503
|
+
oid: number;
|
|
504
|
+
cloid?: `0x${string}`;
|
|
505
|
+
};
|
|
506
|
+
} | "waitingForFill" | "waitingForTrigger")[];
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
}>;
|
|
510
|
+
/** Dead-man's switch: auto-cancel all orders at `timeMs` (epoch) unless re-armed. Omit to clear. */
|
|
511
|
+
scheduleCancel(timeMs?: number): Promise<{
|
|
512
|
+
status: "ok";
|
|
513
|
+
response: {
|
|
514
|
+
type: "default";
|
|
515
|
+
};
|
|
516
|
+
}>;
|
|
517
|
+
/** Move USDC from spot into the perp wallet (margin top-up; not a withdrawal). */
|
|
518
|
+
transferToPerp(usd: number): Promise<{
|
|
519
|
+
status: "ok";
|
|
520
|
+
response: {
|
|
521
|
+
type: "default";
|
|
522
|
+
};
|
|
523
|
+
}>;
|
|
524
|
+
/** Move USDC from the perp wallet back to spot. */
|
|
525
|
+
transferToSpot(usd: number): Promise<{
|
|
526
|
+
status: "ok";
|
|
527
|
+
response: {
|
|
528
|
+
type: "default";
|
|
529
|
+
};
|
|
530
|
+
}>;
|
|
336
531
|
/** Set leverage for a coin (cross by default). */
|
|
337
532
|
updateLeverage(coin: string, leverage: number, opts?: {
|
|
338
533
|
cross?: boolean;
|
|
@@ -342,6 +537,80 @@ export declare class Hyperliquid {
|
|
|
342
537
|
type: "default";
|
|
343
538
|
};
|
|
344
539
|
}>;
|
|
540
|
+
/**
|
|
541
|
+
* Place a TWAP order — slice `size` evenly over `minutes` (5–1440) to reduce impact.
|
|
542
|
+
* `randomize` jitters slice timing. Returns the @nktkas response (incl. the TWAP id).
|
|
543
|
+
*/
|
|
544
|
+
twap(coin: string, isBuy: boolean, size: number, minutes: number, opts?: {
|
|
545
|
+
reduceOnly?: boolean;
|
|
546
|
+
randomize?: boolean;
|
|
547
|
+
}): Promise<{
|
|
548
|
+
status: "ok";
|
|
549
|
+
response: {
|
|
550
|
+
type: "twapOrder";
|
|
551
|
+
data: {
|
|
552
|
+
status: {
|
|
553
|
+
running: {
|
|
554
|
+
twapId: number;
|
|
555
|
+
};
|
|
556
|
+
};
|
|
557
|
+
};
|
|
558
|
+
};
|
|
559
|
+
}>;
|
|
560
|
+
/** Cancel a running TWAP by its id (from the `twap()` response). */
|
|
561
|
+
cancelTwap(coin: string, twapId: number): Promise<{
|
|
562
|
+
status: "ok";
|
|
563
|
+
response: {
|
|
564
|
+
type: "twapCancel";
|
|
565
|
+
data: {
|
|
566
|
+
status: "success";
|
|
567
|
+
};
|
|
568
|
+
};
|
|
569
|
+
}>;
|
|
570
|
+
/** Create a named sub-account (1–16 chars). Returns its address. */
|
|
571
|
+
createSubAccount(name: string): Promise<{
|
|
572
|
+
status: "ok";
|
|
573
|
+
response: {
|
|
574
|
+
type: "createSubAccount";
|
|
575
|
+
data: `0x${string}`;
|
|
576
|
+
};
|
|
577
|
+
}>;
|
|
578
|
+
/** List sub-accounts for an address (default: the signer). */
|
|
579
|
+
subAccounts(user?: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").SubAccountsResponse>;
|
|
580
|
+
/** Move USDC from the master into a sub-account (`usd` in dollars). */
|
|
581
|
+
transferToSubAccount(subAccount: string, usd: number): Promise<{
|
|
582
|
+
status: "ok";
|
|
583
|
+
response: {
|
|
584
|
+
type: "default";
|
|
585
|
+
};
|
|
586
|
+
}>;
|
|
587
|
+
/** Move USDC from a sub-account back to the master (`usd` in dollars). */
|
|
588
|
+
transferFromSubAccount(subAccount: string, usd: number): Promise<{
|
|
589
|
+
status: "ok";
|
|
590
|
+
response: {
|
|
591
|
+
type: "default";
|
|
592
|
+
};
|
|
593
|
+
}>;
|
|
594
|
+
/** Deposit USDC into a vault (`usd` in dollars). */
|
|
595
|
+
vaultDeposit(vault: string, usd: number): Promise<{
|
|
596
|
+
status: "ok";
|
|
597
|
+
response: {
|
|
598
|
+
type: "default";
|
|
599
|
+
};
|
|
600
|
+
}>;
|
|
601
|
+
/** Withdraw USDC from a vault (`usd` in dollars). */
|
|
602
|
+
vaultWithdraw(vault: string, usd: number): Promise<{
|
|
603
|
+
status: "ok";
|
|
604
|
+
response: {
|
|
605
|
+
type: "default";
|
|
606
|
+
};
|
|
607
|
+
}>;
|
|
608
|
+
/** Vault details + your equity in it (public read; pass a user or use the signer). */
|
|
609
|
+
vaultDetails(vault: string, user?: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").VaultDetailsResponse>;
|
|
610
|
+
/** Your fee schedule + 14-day volume (default: the signer). */
|
|
611
|
+
userFees(user?: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").UserFeesResponse>;
|
|
612
|
+
/** Status of a single order by its oid (resting/filled/canceled). */
|
|
613
|
+
orderStatus(oid: number, user?: string): Promise<import("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts").OrderStatusResponse>;
|
|
345
614
|
private symbols;
|
|
346
615
|
private lookup;
|
|
347
616
|
private requireUser;
|
package/dist/hyperliquid.js
CHANGED
|
@@ -25,6 +25,35 @@ import { keccak_256 } from "@noble/hashes/sha3";
|
|
|
25
25
|
import { localAccount } from "./eip712.js";
|
|
26
26
|
import { privateKeyToAddress } from "./tx.js";
|
|
27
27
|
import { bytesToHex, concatBytes, hexToBytes } from "./hex.js";
|
|
28
|
+
/** Parse a Hyperliquid clearinghouse position into a clean PositionInfo. */
|
|
29
|
+
export function parseHlPosition(p) {
|
|
30
|
+
const szi = Number(p.szi);
|
|
31
|
+
return {
|
|
32
|
+
coin: p.coin,
|
|
33
|
+
size: Math.abs(szi),
|
|
34
|
+
side: szi > 0 ? "long" : szi < 0 ? "short" : "flat",
|
|
35
|
+
entryPx: Number(p.entryPx ?? 0),
|
|
36
|
+
positionValue: Number(p.positionValue ?? 0),
|
|
37
|
+
unrealizedPnl: Number(p.unrealizedPnl ?? 0),
|
|
38
|
+
returnOnEquity: Number(p.returnOnEquity ?? 0),
|
|
39
|
+
leverage: Number(p.leverage?.value ?? 0),
|
|
40
|
+
liquidationPx: p.liquidationPx != null ? Number(p.liquidationPx) : null,
|
|
41
|
+
marginUsed: Number(p.marginUsed ?? 0),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Parse an L2 book into a best bid/offer + mid + spread. */
|
|
45
|
+
export function parseBbo(book) {
|
|
46
|
+
const bidPx = book.levels?.[0]?.[0]?.px;
|
|
47
|
+
const askPx = book.levels?.[1]?.[0]?.px;
|
|
48
|
+
const bid = bidPx != null ? Number(bidPx) : null;
|
|
49
|
+
const ask = askPx != null ? Number(askPx) : null;
|
|
50
|
+
return {
|
|
51
|
+
bid,
|
|
52
|
+
ask,
|
|
53
|
+
mid: bid != null && ask != null ? (bid + ask) / 2 : null,
|
|
54
|
+
spread: bid != null && ask != null ? ask - bid : null,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
28
57
|
function truthy(v) {
|
|
29
58
|
return v === true || v === 1 || v === "1" || v === "true";
|
|
30
59
|
}
|
|
@@ -206,6 +235,47 @@ export class Hyperliquid {
|
|
|
206
235
|
const startTime = opts.startTime ?? endTime - (opts.lookbackMs ?? 24 * 60 * 60 * 1000);
|
|
207
236
|
return this._info.candleSnapshot({ coin, interval, startTime, endTime });
|
|
208
237
|
}
|
|
238
|
+
/** Recent public trades for a coin. */
|
|
239
|
+
async recentTrades(coin) {
|
|
240
|
+
return this._info.recentTrades({ coin });
|
|
241
|
+
}
|
|
242
|
+
/** Best bid/offer + mid + spread for a coin (parsed from the L2 book). */
|
|
243
|
+
async bbo(coin) {
|
|
244
|
+
return parseBbo((await this.book(coin)));
|
|
245
|
+
}
|
|
246
|
+
/** All open positions as clean PositionInfo[] (default: the signer's account). */
|
|
247
|
+
async positionsList(user) {
|
|
248
|
+
const s = (await this.positions(user));
|
|
249
|
+
return (s.assetPositions ?? []).map((ap) => parseHlPosition(ap.position));
|
|
250
|
+
}
|
|
251
|
+
/** A single open position for a coin, or null if flat. */
|
|
252
|
+
async position(coin, user) {
|
|
253
|
+
return (await this.positionsList(user)).find((p) => p.coin === coin) ?? null;
|
|
254
|
+
}
|
|
255
|
+
/** Current hourly funding rate for a coin (fraction, e.g. 0.0000125). */
|
|
256
|
+
async fundingRate(coin) {
|
|
257
|
+
return (await this.assetCtx(coin)).funding;
|
|
258
|
+
}
|
|
259
|
+
/** Historical funding rates for a coin (default: the last 7 days). */
|
|
260
|
+
async fundingHistory(coin, opts = {}) {
|
|
261
|
+
const endTime = opts.endTime ?? Date.now();
|
|
262
|
+
const startTime = opts.startTime ?? endTime - (opts.lookbackMs ?? 7 * 24 * 60 * 60 * 1000);
|
|
263
|
+
return this._info.fundingHistory({ coin, startTime, endTime });
|
|
264
|
+
}
|
|
265
|
+
/** Funding payments paid/received by an account (default signer; last 7 days). */
|
|
266
|
+
async userFunding(opts = {}, user) {
|
|
267
|
+
const endTime = opts.endTime ?? Date.now();
|
|
268
|
+
const startTime = opts.startTime ?? endTime - (opts.lookbackMs ?? 7 * 24 * 60 * 60 * 1000);
|
|
269
|
+
return this._info.userFunding({ user: this.requireUser(user), startTime, endTime });
|
|
270
|
+
}
|
|
271
|
+
/** Predicted next funding rates across venues (no key). */
|
|
272
|
+
async predictedFundings() {
|
|
273
|
+
return this._info.predictedFundings();
|
|
274
|
+
}
|
|
275
|
+
/** Portfolio history (PnL/account-value time series) for an account (default: the signer). */
|
|
276
|
+
async portfolio(user) {
|
|
277
|
+
return this._info.portfolio({ user: this.requireUser(user) });
|
|
278
|
+
}
|
|
209
279
|
// ---- trading (key required) ----
|
|
210
280
|
/** Raw order passthrough (the @nktkas `order` shape) for full control. */
|
|
211
281
|
async order(params) {
|
|
@@ -281,10 +351,134 @@ export class Hyperliquid {
|
|
|
281
351
|
async cancel(coin, oid) {
|
|
282
352
|
return this.exchange.cancel({ cancels: [{ a: await this.assetId(coin), o: oid }] });
|
|
283
353
|
}
|
|
354
|
+
/** Cancel a resting order by its client order id (cloid). */
|
|
355
|
+
async cancelByCloid(coin, cloid) {
|
|
356
|
+
return this.exchange.cancelByCloid({ cancels: [{ asset: await this.assetId(coin), cloid }] });
|
|
357
|
+
}
|
|
358
|
+
/** Cancel ALL resting orders (optionally only for one coin). Returns the count cancelled. */
|
|
359
|
+
async cancelAll(coin) {
|
|
360
|
+
const orders = (await this.openOrders());
|
|
361
|
+
const targets = coin ? orders.filter((o) => o.coin === coin) : orders;
|
|
362
|
+
if (!targets.length)
|
|
363
|
+
return { cancelled: 0 };
|
|
364
|
+
const cancels = await Promise.all(targets.map(async (o) => ({ a: await this.assetId(o.coin), o: o.oid })));
|
|
365
|
+
await this.exchange.cancel({ cancels });
|
|
366
|
+
return { cancelled: targets.length };
|
|
367
|
+
}
|
|
368
|
+
/** Modify a resting limit order in place (new size/price/side). */
|
|
369
|
+
async modifyOrder(oid, coin, isBuy, size, price, opts = {}) {
|
|
370
|
+
const { id, szDecimals } = await this.lookup(coin);
|
|
371
|
+
return this.exchange.modify({
|
|
372
|
+
oid,
|
|
373
|
+
order: {
|
|
374
|
+
a: id,
|
|
375
|
+
b: isBuy,
|
|
376
|
+
p: formatPrice(price),
|
|
377
|
+
s: formatSize(size, szDecimals),
|
|
378
|
+
r: opts.reduceOnly ?? false,
|
|
379
|
+
t: { limit: { tif: opts.tif ?? "Gtc" } },
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Place a trigger order (stop / take-profit). `triggerPx` is the activation price;
|
|
385
|
+
* `tpsl` is "sl" (stop) or "tp". Market trigger by default (fills at market once
|
|
386
|
+
* armed); reduce-only by default (closing). `isBuy` is the side that executes —
|
|
387
|
+
* to protect a LONG use isBuy=false (sell), for a SHORT use isBuy=true (buy).
|
|
388
|
+
*/
|
|
389
|
+
async trigger(coin, isBuy, size, triggerPx, opts) {
|
|
390
|
+
const { id, szDecimals } = await this.lookup(coin);
|
|
391
|
+
return this.exchange.order({
|
|
392
|
+
orders: [
|
|
393
|
+
{
|
|
394
|
+
a: id,
|
|
395
|
+
b: isBuy,
|
|
396
|
+
p: formatPrice(opts.price ?? triggerPx),
|
|
397
|
+
s: formatSize(size, szDecimals),
|
|
398
|
+
r: opts.reduceOnly ?? true,
|
|
399
|
+
t: { trigger: { isMarket: opts.isMarket ?? true, triggerPx: formatPrice(triggerPx), tpsl: opts.tpsl } },
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
grouping: "na",
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
/** Stop-loss trigger (reduce-only market by default). See `trigger` for `isBuy`. */
|
|
406
|
+
stopLoss(coin, isBuy, size, triggerPx, opts = {}) {
|
|
407
|
+
return this.trigger(coin, isBuy, size, triggerPx, { ...opts, tpsl: "sl" });
|
|
408
|
+
}
|
|
409
|
+
/** Take-profit trigger (reduce-only market by default). See `trigger` for `isBuy`. */
|
|
410
|
+
takeProfit(coin, isBuy, size, triggerPx, opts = {}) {
|
|
411
|
+
return this.trigger(coin, isBuy, size, triggerPx, { ...opts, tpsl: "tp" });
|
|
412
|
+
}
|
|
413
|
+
/** Dead-man's switch: auto-cancel all orders at `timeMs` (epoch) unless re-armed. Omit to clear. */
|
|
414
|
+
async scheduleCancel(timeMs) {
|
|
415
|
+
return this.exchange.scheduleCancel(timeMs ? { time: timeMs } : {});
|
|
416
|
+
}
|
|
417
|
+
/** Move USDC from spot into the perp wallet (margin top-up; not a withdrawal). */
|
|
418
|
+
async transferToPerp(usd) {
|
|
419
|
+
return this.exchange.usdClassTransfer({ amount: String(usd), toPerp: true });
|
|
420
|
+
}
|
|
421
|
+
/** Move USDC from the perp wallet back to spot. */
|
|
422
|
+
async transferToSpot(usd) {
|
|
423
|
+
return this.exchange.usdClassTransfer({ amount: String(usd), toPerp: false });
|
|
424
|
+
}
|
|
284
425
|
/** Set leverage for a coin (cross by default). */
|
|
285
426
|
async updateLeverage(coin, leverage, opts = {}) {
|
|
286
427
|
return this.exchange.updateLeverage({ asset: await this.assetId(coin), isCross: opts.cross ?? true, leverage });
|
|
287
428
|
}
|
|
429
|
+
/**
|
|
430
|
+
* Place a TWAP order — slice `size` evenly over `minutes` (5–1440) to reduce impact.
|
|
431
|
+
* `randomize` jitters slice timing. Returns the @nktkas response (incl. the TWAP id).
|
|
432
|
+
*/
|
|
433
|
+
async twap(coin, isBuy, size, minutes, opts = {}) {
|
|
434
|
+
const { id, szDecimals } = await this.lookup(coin);
|
|
435
|
+
return this.exchange.twapOrder({
|
|
436
|
+
twap: { a: id, b: isBuy, s: formatSize(size, szDecimals), r: opts.reduceOnly ?? false, m: minutes, t: opts.randomize ?? false },
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/** Cancel a running TWAP by its id (from the `twap()` response). */
|
|
440
|
+
async cancelTwap(coin, twapId) {
|
|
441
|
+
return this.exchange.twapCancel({ a: await this.assetId(coin), t: twapId });
|
|
442
|
+
}
|
|
443
|
+
// ---- sub-accounts (isolate strategies under one master) ----
|
|
444
|
+
/** Create a named sub-account (1–16 chars). Returns its address. */
|
|
445
|
+
async createSubAccount(name) {
|
|
446
|
+
return this.exchange.createSubAccount({ name });
|
|
447
|
+
}
|
|
448
|
+
/** List sub-accounts for an address (default: the signer). */
|
|
449
|
+
async subAccounts(user) {
|
|
450
|
+
return this._info.subAccounts({ user: this.requireUser(user) });
|
|
451
|
+
}
|
|
452
|
+
/** Move USDC from the master into a sub-account (`usd` in dollars). */
|
|
453
|
+
async transferToSubAccount(subAccount, usd) {
|
|
454
|
+
return this.exchange.subAccountTransfer({ subAccountUser: subAccount, isDeposit: true, usd: Math.round(usd * 1e6) });
|
|
455
|
+
}
|
|
456
|
+
/** Move USDC from a sub-account back to the master (`usd` in dollars). */
|
|
457
|
+
async transferFromSubAccount(subAccount, usd) {
|
|
458
|
+
return this.exchange.subAccountTransfer({ subAccountUser: subAccount, isDeposit: false, usd: Math.round(usd * 1e6) });
|
|
459
|
+
}
|
|
460
|
+
// ---- vaults (deposit into / withdraw from a Hyperliquid vault) ----
|
|
461
|
+
/** Deposit USDC into a vault (`usd` in dollars). */
|
|
462
|
+
async vaultDeposit(vault, usd) {
|
|
463
|
+
return this.exchange.vaultTransfer({ vaultAddress: vault, isDeposit: true, usd: Math.round(usd * 1e6) });
|
|
464
|
+
}
|
|
465
|
+
/** Withdraw USDC from a vault (`usd` in dollars). */
|
|
466
|
+
async vaultWithdraw(vault, usd) {
|
|
467
|
+
return this.exchange.vaultTransfer({ vaultAddress: vault, isDeposit: false, usd: Math.round(usd * 1e6) });
|
|
468
|
+
}
|
|
469
|
+
/** Vault details + your equity in it (public read; pass a user or use the signer). */
|
|
470
|
+
async vaultDetails(vault, user) {
|
|
471
|
+
return this._info.vaultDetails({ vaultAddress: vault, user: (user ?? this.address ?? undefined) });
|
|
472
|
+
}
|
|
473
|
+
// ---- account info ----
|
|
474
|
+
/** Your fee schedule + 14-day volume (default: the signer). */
|
|
475
|
+
async userFees(user) {
|
|
476
|
+
return this._info.userFees({ user: this.requireUser(user) });
|
|
477
|
+
}
|
|
478
|
+
/** Status of a single order by its oid (resting/filled/canceled). */
|
|
479
|
+
async orderStatus(oid, user) {
|
|
480
|
+
return this._info.orderStatus({ user: this.requireUser(user), oid });
|
|
481
|
+
}
|
|
288
482
|
// The @nktkas SymbolConverter resolves asset ids + szDecimals across the main
|
|
289
483
|
// perp dex, spot, AND HIP-3 builder dexes (so "xyz:TSLA" → its global asset id).
|
|
290
484
|
symbols() {
|
package/dist/hyperliquid.test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Hyperliquid agent-wallet delegation: per-user agent keys must be deterministic
|
|
2
2
|
// (recomputable, never stored) and the bound client must sign as the agent.
|
|
3
3
|
import { describe, expect, it } from "vitest";
|
|
4
|
-
import { Hyperliquid } from "./hyperliquid.js";
|
|
4
|
+
import { Hyperliquid, parseHlPosition, parseBbo } from "./hyperliquid.js";
|
|
5
5
|
import { localAccount } from "./eip712.js";
|
|
6
6
|
const SECRET = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
|
|
7
7
|
const MASTER = "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826";
|
|
@@ -29,3 +29,19 @@ describe("Hyperliquid agent-wallet delegation", () => {
|
|
|
29
29
|
expect(() => bare.agentKey("user-1")).toThrow(/agent secret/i);
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
|
+
describe("Hyperliquid parsers", () => {
|
|
33
|
+
it("parseHlPosition normalizes a clearinghouse position (side/size/fields)", () => {
|
|
34
|
+
const long = parseHlPosition({ coin: "BTC", szi: "0.5", entryPx: "60000", positionValue: "31000", unrealizedPnl: "1000", returnOnEquity: "0.12", leverage: { value: 10 }, liquidationPx: "40000", marginUsed: "3100" });
|
|
35
|
+
expect(long).toMatchObject({ coin: "BTC", size: 0.5, side: "long", entryPx: 60000, unrealizedPnl: 1000, leverage: 10, liquidationPx: 40000 });
|
|
36
|
+
const short = parseHlPosition({ coin: "ETH", szi: "-2" });
|
|
37
|
+
expect(short.side).toBe("short");
|
|
38
|
+
expect(short.size).toBe(2);
|
|
39
|
+
expect(short.liquidationPx).toBeNull();
|
|
40
|
+
expect(parseHlPosition({ coin: "X", szi: "0" }).side).toBe("flat");
|
|
41
|
+
});
|
|
42
|
+
it("parseBbo derives bid/ask/mid/spread from the L2 book", () => {
|
|
43
|
+
const bbo = parseBbo({ levels: [[{ px: "99.5" }], [{ px: "100.5" }]] });
|
|
44
|
+
expect(bbo).toEqual({ bid: 99.5, ask: 100.5, mid: 100, spread: 1 });
|
|
45
|
+
expect(parseBbo({ levels: [[], []] })).toEqual({ bid: null, ask: null, mid: null, spread: null });
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Chain } from "./chain.js";
|
|
2
|
+
import type { Hex } from "./hex.js";
|
|
3
|
+
export type HlNetwork = "mainnet" | "testnet";
|
|
4
|
+
export interface HlBridgeConfig {
|
|
5
|
+
/** Arbitrum chainId the deposit transfer goes out on. */
|
|
6
|
+
chainId: number;
|
|
7
|
+
/** Hyperliquid bridge (Bridge2) contract — the USDC transfer recipient. */
|
|
8
|
+
bridge: Hex;
|
|
9
|
+
/** USDC token on that chain. */
|
|
10
|
+
usdc: Hex;
|
|
11
|
+
usdcDecimals: number;
|
|
12
|
+
/** Hyperliquid enforces a minimum deposit; below it funds are lost. */
|
|
13
|
+
minUsdc: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const HL_BRIDGE: Record<HlNetwork, HlBridgeConfig>;
|
|
16
|
+
/**
|
|
17
|
+
* Convert a human USDC amount (e.g. 25 or "25.5") to base units, without float
|
|
18
|
+
* error. Rejects more fractional digits than the token supports.
|
|
19
|
+
*/
|
|
20
|
+
export declare function usdcBaseUnits(amount: number | string, decimals?: number): bigint;
|
|
21
|
+
export interface DepositOptions {
|
|
22
|
+
/** "mainnet" (Arbitrum) or "testnet" (Arbitrum Sepolia). Default "mainnet". */
|
|
23
|
+
network?: HlNetwork;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Deposit USDC into Hyperliquid from Arbitrum. `chain` must be a Chain on the
|
|
27
|
+
* matching Arbitrum network with a funded signer. Returns the deposit tx hash;
|
|
28
|
+
* the credit appears on the signer's Hyperliquid account shortly after.
|
|
29
|
+
*/
|
|
30
|
+
export declare function depositToHyperliquid(chain: Chain, amount: number | string, opts?: DepositOptions): Promise<Hex>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Verify against Hyperliquid docs before relying on the testnet entry; mainnet
|
|
2
|
+
// Bridge2 + native USDC on Arbitrum are the well-known production addresses.
|
|
3
|
+
export const HL_BRIDGE = {
|
|
4
|
+
mainnet: {
|
|
5
|
+
chainId: 42161,
|
|
6
|
+
bridge: "0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7",
|
|
7
|
+
usdc: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
8
|
+
usdcDecimals: 6,
|
|
9
|
+
minUsdc: 5,
|
|
10
|
+
},
|
|
11
|
+
testnet: {
|
|
12
|
+
chainId: 421614,
|
|
13
|
+
bridge: "0x08cfc1B6b2dCF36A1480b99353A354AA8AC56f89",
|
|
14
|
+
usdc: "0x1baAbB04529D43a73232B713C0FE471f7c7334d5",
|
|
15
|
+
usdcDecimals: 6,
|
|
16
|
+
minUsdc: 5,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
const ERC20_TRANSFER = [
|
|
20
|
+
{
|
|
21
|
+
type: "function",
|
|
22
|
+
name: "transfer",
|
|
23
|
+
stateMutability: "nonpayable",
|
|
24
|
+
inputs: [
|
|
25
|
+
{ name: "to", type: "address" },
|
|
26
|
+
{ name: "amount", type: "uint256" },
|
|
27
|
+
],
|
|
28
|
+
outputs: [{ name: "", type: "bool" }],
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Convert a human USDC amount (e.g. 25 or "25.5") to base units, without float
|
|
33
|
+
* error. Rejects more fractional digits than the token supports.
|
|
34
|
+
*/
|
|
35
|
+
export function usdcBaseUnits(amount, decimals = 6) {
|
|
36
|
+
const s = typeof amount === "number" ? amount.toString() : amount.trim();
|
|
37
|
+
if (!/^\d+(\.\d+)?$/.test(s))
|
|
38
|
+
throw new Error(`invalid USDC amount: ${amount}`);
|
|
39
|
+
const [whole, frac = ""] = s.split(".");
|
|
40
|
+
if (frac.length > decimals)
|
|
41
|
+
throw new Error(`USDC supports at most ${decimals} decimals`);
|
|
42
|
+
return BigInt(whole + frac.padEnd(decimals, "0"));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Deposit USDC into Hyperliquid from Arbitrum. `chain` must be a Chain on the
|
|
46
|
+
* matching Arbitrum network with a funded signer. Returns the deposit tx hash;
|
|
47
|
+
* the credit appears on the signer's Hyperliquid account shortly after.
|
|
48
|
+
*/
|
|
49
|
+
export async function depositToHyperliquid(chain, amount, opts = {}) {
|
|
50
|
+
const cfg = HL_BRIDGE[opts.network ?? "mainnet"];
|
|
51
|
+
const units = usdcBaseUnits(amount, cfg.usdcDecimals);
|
|
52
|
+
const min = BigInt(cfg.minUsdc) * 10n ** BigInt(cfg.usdcDecimals);
|
|
53
|
+
if (units < min)
|
|
54
|
+
throw new Error(`Hyperliquid minimum deposit is ${cfg.minUsdc} USDC`);
|
|
55
|
+
return chain.send({
|
|
56
|
+
address: cfg.usdc,
|
|
57
|
+
abi: ERC20_TRANSFER,
|
|
58
|
+
functionName: "transfer",
|
|
59
|
+
args: [cfg.bridge, units],
|
|
60
|
+
});
|
|
61
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export { watchLogs } from "./watch.js";
|
|
|
6
6
|
export type { WatchLogsOptions, WatchLogsResult } from "./watch.js";
|
|
7
7
|
export { defineWatcher } from "./watcher.js";
|
|
8
8
|
export type { WatcherEnv, WatcherMatch, WatcherScope, WatcherContext, WatcherDefinition, WatcherModule, SubscribeOptions, Confidence, MatchStatus, } from "./watcher.js";
|
|
9
|
+
export { Signals, signals, DEFAULT_SIGNALS_URL } from "./signals.js";
|
|
10
|
+
export type { SignalsOptions, Market, SignalMatch, Swap, Launch, EngineSnapshot, MarketFilter, } from "./signals.js";
|
|
9
11
|
export { Relayer } from "./relayer.js";
|
|
10
12
|
export { Queue, queue, queueEnvKey } from "./queue.js";
|
|
11
13
|
export type { RelayerOptions } from "./relayer.js";
|
|
@@ -17,12 +19,33 @@ export { Telegram } from "./telegram.js";
|
|
|
17
19
|
export type { TelegramOptions, BotMessage, SendMessageOptions, ChatJoinRequest } from "./telegram.js";
|
|
18
20
|
export { verifyTelegramInitData, verifyTelegramLoginWidget, parseStartPayload } from "./telegramAuth.js";
|
|
19
21
|
export type { TelegramUser, VerifyOptions } from "./telegramAuth.js";
|
|
22
|
+
export { Email } from "./email.js";
|
|
23
|
+
export type { EmailOptions, EmailMessage, EmailDirection, ListEmailsOptions, SendEmailOptions, SendEmailResult, } from "./email.js";
|
|
20
24
|
export { TelegramLinks, TELEGRAM_LINKS_TABLE } from "./telegramLinks.js";
|
|
21
25
|
export type { TelegramLink } from "./telegramLinks.js";
|
|
22
26
|
export { tokenBalanceOf, meetsGate } from "./gate.js";
|
|
23
27
|
export type { TokenGate } from "./gate.js";
|
|
28
|
+
export { tokenMetadata, ownerOf, tokenURI } from "./reads.js";
|
|
29
|
+
export type { TokenMetadata } from "./reads.js";
|
|
30
|
+
export { resolveUri, fetchTokenMetadata } from "./nft.js";
|
|
31
|
+
export type { NftMetadata, NftAttribute, FetchMetadataOptions } from "./nft.js";
|
|
32
|
+
export { createSiweMessage, verifySiweMessage } from "./siwe.js";
|
|
33
|
+
export type { SiweParams, SiweVerifyResult } from "./siwe.js";
|
|
34
|
+
export { createSession, verifySession } from "./sessions.js";
|
|
35
|
+
export type { SessionOptions } from "./sessions.js";
|
|
36
|
+
export { json, error, withCors, CORS_HEADERS, Router, sse } from "./http.js";
|
|
37
|
+
export type { RouteContext, RouteHandler, SseConnection } from "./http.js";
|
|
38
|
+
export { rateLimit } from "./ratelimit.js";
|
|
39
|
+
export type { KvLike, RateLimitOptions, RateLimitResult } from "./ratelimit.js";
|
|
40
|
+
export { encrypt, decrypt } from "./aes.js";
|
|
41
|
+
export { cached } from "./cache.js";
|
|
42
|
+
export type { CacheOptions } from "./cache.js";
|
|
43
|
+
export { verifyWebhook, signWebhook } from "./webhook.js";
|
|
44
|
+
export type { VerifyWebhookParams, SignatureEncoding } from "./webhook.js";
|
|
24
45
|
export { Hyperliquid } from "./hyperliquid.js";
|
|
25
|
-
export type { HyperliquidOptions, PlaceOrderOptions, MarketOrderOptions, Tif, CandleInterval, CandlesOptions, AssetContext, AccountBalance, } from "./hyperliquid.js";
|
|
46
|
+
export type { HyperliquidOptions, PlaceOrderOptions, MarketOrderOptions, Tif, CandleInterval, CandlesOptions, AssetContext, AccountBalance, PositionInfo, Bbo, } from "./hyperliquid.js";
|
|
47
|
+
export { depositToHyperliquid, usdcBaseUnits, HL_BRIDGE } from "./hyperliquidBridge.js";
|
|
48
|
+
export type { HlNetwork, HlBridgeConfig, DepositOptions } from "./hyperliquidBridge.js";
|
|
26
49
|
export { Polymarket } from "./polymarket.js";
|
|
27
50
|
export type { PolymarketOptions, PolymarketCreds, PlaceOrderParams, Side, OrderType, SignatureType, PriceInterval, PriceHistoryOptions, MarketOutcome, ResolvedMarket, } from "./polymarket.js";
|
|
28
51
|
export { hashTypedData, signTypedData, localAccount } from "./eip712.js";
|