@lifi/perps-sdk-provider-hyperliquid 1.5.3 → 1.5.5
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/cjs/services/getFills.d.ts.map +1 -1
- package/dist/cjs/services/getFills.js +13 -6
- package/dist/cjs/services/getFills.js.map +1 -1
- package/dist/cjs/services/getOrders.js +1 -1
- package/dist/cjs/services/getOrders.js.map +1 -1
- package/dist/cjs/signers/HyperliquidAgentStore.js +1 -1
- package/dist/cjs/signers/HyperliquidAgentStore.js.map +1 -1
- package/dist/cjs/types/order.d.ts +1 -1
- package/dist/cjs/types/order.d.ts.map +1 -1
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
- package/dist/cjs/utils/mapOrder.js +26 -0
- package/dist/cjs/utils/mapOrder.js.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts +2 -0
- package/dist/cjs/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/HyperliquidWsProvider.js +59 -38
- package/dist/cjs/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/esm/services/getFills.d.ts +4 -4
- package/dist/esm/services/getFills.d.ts.map +1 -1
- package/dist/esm/services/getFills.js +19 -9
- package/dist/esm/services/getFills.js.map +1 -1
- package/dist/esm/services/getOrders.js +1 -1
- package/dist/esm/services/getOrders.js.map +1 -1
- package/dist/esm/signers/HyperliquidAgentStore.js +1 -1
- package/dist/esm/signers/HyperliquidAgentStore.js.map +1 -1
- package/dist/esm/types/order.d.ts +1 -1
- package/dist/esm/types/order.d.ts.map +1 -1
- package/dist/esm/utils/mapOrder.d.ts.map +1 -1
- package/dist/esm/utils/mapOrder.js +26 -0
- package/dist/esm/utils/mapOrder.js.map +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts +13 -2
- package/dist/esm/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/HyperliquidWsProvider.js +75 -44
- package/dist/esm/websocket/HyperliquidWsProvider.js.map +1 -1
- package/dist/types/services/getFills.d.ts +4 -4
- package/dist/types/services/getFills.d.ts.map +1 -1
- package/dist/types/types/order.d.ts +1 -1
- package/dist/types/types/order.d.ts.map +1 -1
- package/dist/types/utils/mapOrder.d.ts.map +1 -1
- package/dist/types/websocket/HyperliquidWsProvider.d.ts +13 -2
- package/dist/types/websocket/HyperliquidWsProvider.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/services/getFills.ts +37 -11
- package/src/services/getOrders.ts +1 -1
- package/src/signers/HyperliquidAgentStore.ts +1 -1
- package/src/types/order.ts +1 -1
- package/src/utils/mapOrder.ts +26 -0
- package/src/websocket/HyperliquidWsProvider.ts +79 -47
|
@@ -10,7 +10,7 @@ import type { HyperliquidContext } from '../context.js';
|
|
|
10
10
|
export interface GetFillsParams {
|
|
11
11
|
address: Address;
|
|
12
12
|
limit?: number;
|
|
13
|
-
/**
|
|
13
|
+
/** Opaque pagination cursor from a previous page's `pagination.cursor`. */
|
|
14
14
|
cursor?: string;
|
|
15
15
|
/** Inclusive lower bound in ms-since-epoch — switches to the `userFillsByTime` endpoint. */
|
|
16
16
|
startTime?: number;
|
|
@@ -24,9 +24,9 @@ export interface GetFillsParams {
|
|
|
24
24
|
* list supplies the display fields; only the fills endpoint is read direct
|
|
25
25
|
* from HL.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* next
|
|
27
|
+
* The response is sorted (time desc, `tid` as tiebreaker) before pagination —
|
|
28
|
+
* see {@link compareFillsDesc}. The cursor encodes the last returned fill's
|
|
29
|
+
* `(time, tid)`; the next page keeps fills that sort strictly after it.
|
|
30
30
|
* @throws {PerpsError} On Hyperliquid REST error, network, or parsing failures.
|
|
31
31
|
* @public
|
|
32
32
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFills.d.ts","sourceRoot":"","sources":["../../../src/services/getFills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAMnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"getFills.d.ts","sourceRoot":"","sources":["../../../src/services/getFills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAMnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AASvD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAoBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,GACnB,oBAAoB,kBAAkB,EACtC,QAAQ,cAAc,EACtB,UAAU,iBAAiB,KAC1B,OAAO,CAAC,aAAa,CAqDvB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../../../src/types/order.ts"],"names":[],"mappings":"AAEA,cAAc;AACd,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,EAAE,OAAO,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,mBAAmB,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../../../src/types/order.ts"],"names":[],"mappings":"AAEA,cAAc;AACd,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,EAAE,OAAO,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAA;IAChC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB,CAAA;AAED,cAAc;AACd,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,EAAE,CAAA;AAExD,cAAc;AACd,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,EAAE,OAAO,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;QAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,gBAAgB,EAAE,MAAM,CAAA;QACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KACzB,CAAA;IACD,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,cAAc;AACd,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,aAAa,CAAA;CACrB,CAAA;AAED,cAAc;AACd,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapOrder.d.ts","sourceRoot":"","sources":["../../../src/utils/mapOrder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,KAAK,EACL,YAAY,EACb,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAEL,WAAW,EACX,SAAS,EAEV,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAE3E;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,KAAG,SAehD,CAAA;AAED,cAAc;AACd,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,KAAG,OAIjB,CAAA;AAE/B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,cAAc,GACzB,GAAG,mBAAmB,GAAG,aAAa,CAAC,OAAO,CAAC,KAC9C,OAkBF,CAAA;AAED,cAAc;AACd,eAAO,MAAM,YAAY,GACvB,GAAG,mBAAmB,EACtB,QAAQ,aAAa,KACpB,SAaD,CAAA;AAEF,cAAc;AACd,eAAO,MAAM,eAAe,GAC1B,GAAG,mBAAmB,EACtB,QAAQ,aAAa,KACpB,YAcF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,WAwB/C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"mapOrder.d.ts","sourceRoot":"","sources":["../../../src/utils/mapOrder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,KAAK,EACL,YAAY,EACb,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAEL,WAAW,EACX,SAAS,EAEV,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAE3E;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,KAAG,SAehD,CAAA;AAED,cAAc;AACd,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,KAAG,OAIjB,CAAA;AAE/B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,cAAc,GACzB,GAAG,mBAAmB,GAAG,aAAa,CAAC,OAAO,CAAC,KAC9C,OAkBF,CAAA;AAED,cAAc;AACd,eAAO,MAAM,YAAY,GACvB,GAAG,mBAAmB,EACtB,QAAQ,aAAa,KACpB,SAaD,CAAA;AAEF,cAAc;AACd,eAAO,MAAM,eAAe,GAC1B,GAAG,mBAAmB,EACtB,QAAQ,aAAa,KACpB,YAcF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,WAwB/C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,SAmDzD,CAAA;AAeD,cAAc;AACd,eAAO,MAAM,QAAQ,GACnB,QAAQ,aAAa,EACrB,QAAQ,aAAa,KACpB,KAsBF,CAAA"}
|
|
@@ -30,6 +30,7 @@ export declare class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
30
30
|
private readonly registry;
|
|
31
31
|
private perpCtxBySubDex;
|
|
32
32
|
private spotCtxByMarketId;
|
|
33
|
+
private marketsContextByMarketId;
|
|
33
34
|
private orderbookKeysByMarketId;
|
|
34
35
|
private latestOrderbookByMarketId;
|
|
35
36
|
private fastCtxByMarketId;
|
|
@@ -65,6 +66,7 @@ export declare class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
65
66
|
protected handleMessage(raw: string): void;
|
|
66
67
|
private handleAllDexsAssetCtxs;
|
|
67
68
|
private handlePac;
|
|
69
|
+
/** Merge perp asset contexts in place; returns the marketIds this frame touched. */
|
|
68
70
|
private mergePerpAssetCtxEntries;
|
|
69
71
|
private handleSac;
|
|
70
72
|
private spotMarketIdBySacKey;
|
|
@@ -76,10 +78,19 @@ export declare class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
76
78
|
*/
|
|
77
79
|
private handleFastAssetCtxs;
|
|
78
80
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
+
* Emit the all-markets context map, re-mapping only the markets the incoming
|
|
82
|
+
* frame touched. Each emission is a fresh snapshot object that carries
|
|
83
|
+
* untouched entries over by reference, so a listener holding an earlier
|
|
84
|
+
* snapshot never observes later-frame mutation.
|
|
81
85
|
*/
|
|
82
86
|
private emitMarketsContext;
|
|
87
|
+
/**
|
|
88
|
+
* Context for one market from the cached feeds: spot asset context when it
|
|
89
|
+
* maps, else perp asset context with mid + mark overlaid from
|
|
90
|
+
* `fastAssetCtxs`, else the fast feed alone — each price standing in for the
|
|
91
|
+
* other where it carries only one of mid/mark.
|
|
92
|
+
*/
|
|
93
|
+
private computeMarketContext;
|
|
83
94
|
private handleActiveAssetCtx;
|
|
84
95
|
private handleActiveSpotAssetCtx;
|
|
85
96
|
/** Latest mid per `Market.id` across asset-context and fast feeds. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HyperliquidWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/HyperliquidWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAGlB,cAAc,EACd,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAOL,KAAK,YAAY,EAElB,MAAM,mBAAmB,CAAA;AA6C1B;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,QAC5B,iBAEgD,CAAA;AAEtD;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,SAAQ,cAAc,CAAC,MAAM,CAAC;IAC/D,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,uBAAuB,CAAiC;IAChE,OAAO,CAAC,yBAAyB,CAAuC;IAKxE,OAAO,CAAC,iBAAiB,CAAuC;IAGhE,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,oBAAoB,CAAmC;gBAEnD,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc;IASjE,cAAc,CAClB,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;cAkBN,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"HyperliquidWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/HyperliquidWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAGlB,cAAc,EACd,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAOL,KAAK,YAAY,EAElB,MAAM,mBAAmB,CAAA;AA6C1B;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,QAC5B,iBAEgD,CAAA;AAEtD;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,SAAQ,cAAc,CAAC,MAAM,CAAC;IAC/D,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,wBAAwB,CAAoC;IACpE,OAAO,CAAC,uBAAuB,CAAiC;IAChE,OAAO,CAAC,yBAAyB,CAAuC;IAKxE,OAAO,CAAC,iBAAiB,CAAuC;IAGhE,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,oBAAoB,CAAmC;gBAEnD,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc;IASjE,cAAc,CAClB,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;cAkBN,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAgEnE;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAiB5B,OAAO,CAAC,iBAAiB;IAmBzB;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,gBAAgB;cAcL,OAAO,IAAI,IAAI;IAclC,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM9C,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM;IA0B1C,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,WAAW;IA6CnB,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM;IA8EnC,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,SAAS;IAYjB,oFAAoF;IACpF,OAAO,CAAC,wBAAwB;IAyBhC,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,oBAAoB;IAe5B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA6B5B,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,wBAAwB;IAWhC,sEAAsE;IACtE,OAAO,CAAC,UAAU;IAuBlB,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,QAAQ;IAoBhB,OAAO,CAAC,oBAAoB;IAmC5B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,kBAAkB;IAyD1B,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,+BAA+B;IAkBvC,OAAO,CAAC,eAAe;CAaxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/perps-sdk-provider-hyperliquid",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.5",
|
|
4
4
|
"description": "Hyperliquid provider plugin for @lifi/perps-sdk",
|
|
5
5
|
"homepage": "https://github.com/lifinance/perps-sdk",
|
|
6
6
|
"bugs": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@lifi/perps-types": "^1.6.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@lifi/perps-sdk": "^1.5.
|
|
54
|
+
"@lifi/perps-sdk": "^1.5.6"
|
|
55
55
|
},
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
package/src/services/getFills.ts
CHANGED
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
PROVIDER_KEY,
|
|
8
8
|
} from '../constants.js'
|
|
9
9
|
import type { HyperliquidContext } from '../context.js'
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
HlUserFill,
|
|
12
|
+
HlUserFills,
|
|
13
|
+
HlUserFillsByTime,
|
|
14
|
+
} from '../types/index.js'
|
|
11
15
|
import { mapFill } from '../utils/index.js'
|
|
12
16
|
import { hlInfoOptions, infoRequest } from '../utils/infoClient.js'
|
|
13
17
|
|
|
@@ -19,7 +23,7 @@ import { hlInfoOptions, infoRequest } from '../utils/infoClient.js'
|
|
|
19
23
|
export interface GetFillsParams {
|
|
20
24
|
address: Address
|
|
21
25
|
limit?: number
|
|
22
|
-
/**
|
|
26
|
+
/** Opaque pagination cursor from a previous page's `pagination.cursor`. */
|
|
23
27
|
cursor?: string
|
|
24
28
|
/** Inclusive lower bound in ms-since-epoch — switches to the `userFillsByTime` endpoint. */
|
|
25
29
|
startTime?: number
|
|
@@ -27,6 +31,24 @@ export interface GetFillsParams {
|
|
|
27
31
|
endTime?: number
|
|
28
32
|
}
|
|
29
33
|
|
|
34
|
+
interface FillCursor {
|
|
35
|
+
time: number
|
|
36
|
+
tid: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// HL's docs specify neither newest-first ordering nor monotonic `tid` for
|
|
40
|
+
// `userFills`/`userFillsByTime`, so pagination can't rely on upstream order —
|
|
41
|
+
// it must impose its own (time desc, tid desc as tiebreaker for same-time fills).
|
|
42
|
+
const compareFillsDesc = (a: FillCursor, b: FillCursor): number =>
|
|
43
|
+
b.time - a.time || b.tid - a.tid
|
|
44
|
+
|
|
45
|
+
const encodeCursor = (fill: FillCursor): string => `${fill.time}:${fill.tid}`
|
|
46
|
+
|
|
47
|
+
const decodeCursor = (cursor: string): FillCursor => {
|
|
48
|
+
const [time, tid] = cursor.split(':').map(Number)
|
|
49
|
+
return { time, tid }
|
|
50
|
+
}
|
|
51
|
+
|
|
30
52
|
/**
|
|
31
53
|
* Fetch the user's fills history. When `startTime` or `endTime` is provided,
|
|
32
54
|
* Hyperliquid's `userFillsByTime` endpoint is used; otherwise the unbounded
|
|
@@ -34,9 +56,9 @@ export interface GetFillsParams {
|
|
|
34
56
|
* list supplies the display fields; only the fills endpoint is read direct
|
|
35
57
|
* from HL.
|
|
36
58
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* next
|
|
59
|
+
* The response is sorted (time desc, `tid` as tiebreaker) before pagination —
|
|
60
|
+
* see {@link compareFillsDesc}. The cursor encodes the last returned fill's
|
|
61
|
+
* `(time, tid)`; the next page keeps fills that sort strictly after it.
|
|
40
62
|
* @throws {PerpsError} On Hyperliquid REST error, network, or parsing failures.
|
|
41
63
|
* @public
|
|
42
64
|
*/
|
|
@@ -74,15 +96,19 @@ export const getFills = async (
|
|
|
74
96
|
infoOpts
|
|
75
97
|
)
|
|
76
98
|
|
|
99
|
+
const sorted = [...allFills].sort(compareFillsDesc)
|
|
100
|
+
|
|
77
101
|
const filtered =
|
|
78
102
|
params.cursor === undefined
|
|
79
|
-
?
|
|
80
|
-
:
|
|
103
|
+
? sorted
|
|
104
|
+
: sorted.filter(
|
|
105
|
+
(f) => compareFillsDesc(f, decodeCursor(params.cursor!)) > 0
|
|
106
|
+
)
|
|
81
107
|
|
|
82
108
|
const hasMore = filtered.length > limit
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
109
|
+
const page = filtered.slice(0, limit)
|
|
110
|
+
const items = page.map((f) => mapFill(f, registry.require(f.coin)))
|
|
111
|
+
const lastPageFill: HlUserFill | undefined = page[page.length - 1]
|
|
86
112
|
|
|
87
113
|
return {
|
|
88
114
|
provider: PROVIDER_KEY,
|
|
@@ -90,7 +116,7 @@ export const getFills = async (
|
|
|
90
116
|
pagination: {
|
|
91
117
|
limit,
|
|
92
118
|
hasMore,
|
|
93
|
-
cursor:
|
|
119
|
+
cursor: lastPageFill ? encodeCursor(lastPageFill) : undefined,
|
|
94
120
|
},
|
|
95
121
|
}
|
|
96
122
|
}
|
|
@@ -115,7 +115,7 @@ export class HyperliquidAgentStore {
|
|
|
115
115
|
return await this.get(address)
|
|
116
116
|
} catch (error) {
|
|
117
117
|
if (
|
|
118
|
-
error instanceof PerpsError
|
|
118
|
+
!(error instanceof PerpsError) ||
|
|
119
119
|
error.message !== PerpsErrorMessage.AgentNotFound
|
|
120
120
|
) {
|
|
121
121
|
throw error
|
package/src/types/order.ts
CHANGED
package/src/utils/mapOrder.ts
CHANGED
|
@@ -188,6 +188,32 @@ export const mapStatusReason = (status: string): string | undefined => {
|
|
|
188
188
|
return 'Order rejected: notional value below the minimum trade size.'
|
|
189
189
|
case 'delistedCanceled':
|
|
190
190
|
return 'Order cancelled: market has been delisted.'
|
|
191
|
+
case 'perpMarginRejected':
|
|
192
|
+
return 'Order rejected: insufficient margin.'
|
|
193
|
+
case 'reduceOnlyRejected':
|
|
194
|
+
return 'Order rejected: would not reduce your position.'
|
|
195
|
+
case 'badAloPxRejected':
|
|
196
|
+
return 'Order rejected: post-only order would have matched immediately.'
|
|
197
|
+
case 'badTriggerPxRejected':
|
|
198
|
+
return 'Order rejected: invalid take-profit/stop-loss trigger price.'
|
|
199
|
+
case 'marketOrderNoLiquidityRejected':
|
|
200
|
+
return 'Order rejected: not enough liquidity for the market order.'
|
|
201
|
+
case 'oracleRejected':
|
|
202
|
+
return 'Order rejected: price too far from the oracle price.'
|
|
203
|
+
case 'vaultWithdrawalCanceled':
|
|
204
|
+
return 'Order cancelled: a vault withdrawal occurred.'
|
|
205
|
+
case 'openInterestCapCanceled':
|
|
206
|
+
return 'Order cancelled: too aggressive while open interest was at its cap.'
|
|
207
|
+
case 'positionIncreaseAtOpenInterestCapRejected':
|
|
208
|
+
case 'positionFlipAtOpenInterestCapRejected':
|
|
209
|
+
case 'openInterestIncreaseRejected':
|
|
210
|
+
return 'Order rejected: open interest is at its cap.'
|
|
211
|
+
case 'tooAggressiveAtOpenInterestCapRejected':
|
|
212
|
+
return 'Order rejected: price too aggressive while open interest was at its cap.'
|
|
213
|
+
case 'insufficientSpotBalanceRejected':
|
|
214
|
+
return 'Order rejected: insufficient spot balance.'
|
|
215
|
+
case 'perpMaxPositionRejected':
|
|
216
|
+
return 'Order rejected: exceeds the maximum position size for the current leverage tier.'
|
|
191
217
|
default:
|
|
192
218
|
return undefined
|
|
193
219
|
}
|
|
@@ -99,6 +99,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
99
99
|
private readonly registry: MarketRegistry | undefined
|
|
100
100
|
private perpCtxBySubDex = new Map<string, Record<string, HlWsPerpAssetCtx>>()
|
|
101
101
|
private spotCtxByMarketId: Record<string, HlWsSpotAssetCtx> = {}
|
|
102
|
+
private marketsContextByMarketId: Record<string, MarketContext> = {}
|
|
102
103
|
private orderbookKeysByMarketId = new Map<string, Set<string>>()
|
|
103
104
|
private latestOrderbookByMarketId = new Map<string, OrderbookResponse>()
|
|
104
105
|
// Latest mid/mark per `Market.id` from the high-frequency `fastAssetCtxs`
|
|
@@ -173,6 +174,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
173
174
|
this.perpCtxBySubDex.clear()
|
|
174
175
|
this.spotCtxByMarketId = {}
|
|
175
176
|
this.fastCtxByMarketId = {}
|
|
177
|
+
this.marketsContextByMarketId = {}
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
180
|
|
|
@@ -292,6 +294,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
292
294
|
this.perpCtxBySubDex.clear()
|
|
293
295
|
this.spotCtxByMarketId = {}
|
|
294
296
|
this.fastCtxByMarketId = {}
|
|
297
|
+
this.marketsContextByMarketId = {}
|
|
295
298
|
this.orderbookKeysByMarketId.clear()
|
|
296
299
|
this.latestOrderbookByMarketId.clear()
|
|
297
300
|
this.fastDecodeChain = Promise.resolve()
|
|
@@ -483,41 +486,47 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
483
486
|
}
|
|
484
487
|
|
|
485
488
|
private handleAllDexsAssetCtxs(data: HlWsAllDexsAssetCtxsData) {
|
|
486
|
-
this.
|
|
487
|
-
|
|
489
|
+
this.emitMarketsContext(
|
|
490
|
+
this.mergePerpAssetCtxEntries(allDexsAssetCtxEntries(data))
|
|
491
|
+
)
|
|
488
492
|
}
|
|
489
493
|
|
|
490
494
|
private handlePac(base64: string) {
|
|
491
495
|
this.pacDecodeChain = this.pacDecodeChain
|
|
492
496
|
.then(async () => {
|
|
493
|
-
this.
|
|
494
|
-
|
|
497
|
+
this.emitMarketsContext(
|
|
498
|
+
this.mergePerpAssetCtxEntries(
|
|
499
|
+
await decodeCompressedJson<HlWsPacData>(base64)
|
|
500
|
+
)
|
|
495
501
|
)
|
|
496
|
-
this.emitMarketsContext()
|
|
497
502
|
})
|
|
498
503
|
.catch((error) => wsLog.handlerFailure(this.providerKey, error))
|
|
499
504
|
}
|
|
500
505
|
|
|
506
|
+
/** Merge perp asset contexts in place; returns the marketIds this frame touched. */
|
|
501
507
|
private mergePerpAssetCtxEntries(
|
|
502
508
|
entries: [string, HlWsPerpAssetCtxPayload[]][]
|
|
503
|
-
) {
|
|
509
|
+
): Set<string> {
|
|
510
|
+
const touched = new Set<string>()
|
|
504
511
|
for (const [dex, ctxs] of entries) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
512
|
+
let byMarketId = this.perpCtxBySubDex.get(dex || 'default')
|
|
513
|
+
if (byMarketId === undefined) {
|
|
514
|
+
byMarketId = {}
|
|
515
|
+
this.perpCtxBySubDex.set(dex || 'default', byMarketId)
|
|
508
516
|
}
|
|
509
517
|
for (const ctx of ctxs) {
|
|
510
518
|
const marketId = ctx.coin
|
|
511
519
|
if (marketId === undefined) {
|
|
512
520
|
continue
|
|
513
521
|
}
|
|
514
|
-
const merged = mergePerpAssetCtx(
|
|
522
|
+
const merged = mergePerpAssetCtx(byMarketId[marketId], marketId, ctx)
|
|
515
523
|
if (merged !== undefined) {
|
|
516
524
|
byMarketId[marketId] = merged
|
|
525
|
+
touched.add(marketId)
|
|
517
526
|
}
|
|
518
527
|
}
|
|
519
|
-
this.perpCtxBySubDex.set(dex || 'default', byMarketId)
|
|
520
528
|
}
|
|
529
|
+
return touched
|
|
521
530
|
}
|
|
522
531
|
|
|
523
532
|
private handleSac(base64: string) {
|
|
@@ -525,6 +534,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
525
534
|
.then(async () => {
|
|
526
535
|
const spotMarketIdBySacKey = this.spotMarketIdBySacKey()
|
|
527
536
|
const ctxs = await decodeCompressedJson<HlWsSacData>(base64)
|
|
537
|
+
const touched = new Set<string>()
|
|
528
538
|
for (const [sacKey, ctx] of Object.entries(ctxs)) {
|
|
529
539
|
const marketId = spotMarketIdBySacKey.get(sacKey)
|
|
530
540
|
if (marketId === undefined) {
|
|
@@ -534,8 +544,9 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
534
544
|
...this.spotCtxByMarketId[marketId],
|
|
535
545
|
...ctx,
|
|
536
546
|
}
|
|
547
|
+
touched.add(marketId)
|
|
537
548
|
}
|
|
538
|
-
this.emitMarketsContext()
|
|
549
|
+
this.emitMarketsContext(touched)
|
|
539
550
|
})
|
|
540
551
|
.catch((error) => wsLog.handlerFailure(this.providerKey, error))
|
|
541
552
|
}
|
|
@@ -572,52 +583,66 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
572
583
|
midPx: 'midPx' in ctx ? ctx.midPx : prev?.midPx,
|
|
573
584
|
}
|
|
574
585
|
}
|
|
575
|
-
this.emitMarketsContext()
|
|
586
|
+
this.emitMarketsContext(Object.keys(ctxs))
|
|
576
587
|
})
|
|
577
588
|
.catch((error) => wsLog.handlerFailure(this.providerKey, error))
|
|
578
589
|
}
|
|
579
590
|
|
|
580
591
|
/**
|
|
581
|
-
*
|
|
582
|
-
*
|
|
592
|
+
* Emit the all-markets context map, re-mapping only the markets the incoming
|
|
593
|
+
* frame touched. Each emission is a fresh snapshot object that carries
|
|
594
|
+
* untouched entries over by reference, so a listener holding an earlier
|
|
595
|
+
* snapshot never observes later-frame mutation.
|
|
583
596
|
*/
|
|
584
|
-
private emitMarketsContext() {
|
|
585
|
-
const data: Record<string, MarketContext> = {
|
|
586
|
-
|
|
587
|
-
for (const [marketId, ctx] of Object.entries(byMarketId)) {
|
|
588
|
-
const base = mapMarketContext(marketId, ctx)
|
|
589
|
-
const fast = this.fastCtxByMarketId[marketId]
|
|
590
|
-
data[marketId] = {
|
|
591
|
-
...base,
|
|
592
|
-
midPrice: fast?.midPx != null ? fast.midPx : base.midPrice,
|
|
593
|
-
markPrice: fast?.markPx != null ? fast.markPx : base.markPrice,
|
|
594
|
-
}
|
|
595
|
-
}
|
|
597
|
+
private emitMarketsContext(touchedMarketIds: Iterable<string>) {
|
|
598
|
+
const data: Record<string, MarketContext> = {
|
|
599
|
+
...this.marketsContextByMarketId,
|
|
596
600
|
}
|
|
597
|
-
for (const
|
|
598
|
-
const context =
|
|
599
|
-
marketId,
|
|
600
|
-
ctx,
|
|
601
|
-
this.fastCtxByMarketId[marketId]
|
|
602
|
-
)
|
|
601
|
+
for (const marketId of touchedMarketIds) {
|
|
602
|
+
const context = this.computeMarketContext(marketId)
|
|
603
603
|
if (context === undefined) {
|
|
604
|
-
|
|
604
|
+
delete data[marketId]
|
|
605
|
+
} else {
|
|
606
|
+
data[marketId] = context
|
|
605
607
|
}
|
|
606
|
-
data[marketId] = context
|
|
607
608
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
609
|
+
this.marketsContextByMarketId = data
|
|
610
|
+
this.emit('marketsContext', { channel: 'marketsContext', data })
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Context for one market from the cached feeds: spot asset context when it
|
|
615
|
+
* maps, else perp asset context with mid + mark overlaid from
|
|
616
|
+
* `fastAssetCtxs`, else the fast feed alone — each price standing in for the
|
|
617
|
+
* other where it carries only one of mid/mark.
|
|
618
|
+
*/
|
|
619
|
+
private computeMarketContext(marketId: string): MarketContext | undefined {
|
|
620
|
+
const fast = this.fastCtxByMarketId[marketId]
|
|
621
|
+
const spotCtx = this.spotCtxByMarketId[marketId]
|
|
622
|
+
if (spotCtx !== undefined) {
|
|
623
|
+
const context = mapSpotMarketContext(marketId, spotCtx, fast)
|
|
624
|
+
if (context !== undefined) {
|
|
625
|
+
return context
|
|
611
626
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
627
|
+
}
|
|
628
|
+
let perpCtx: HlWsPerpAssetCtx | undefined
|
|
629
|
+
for (const byMarketId of this.perpCtxBySubDex.values()) {
|
|
630
|
+
perpCtx = byMarketId[marketId] ?? perpCtx
|
|
631
|
+
}
|
|
632
|
+
if (perpCtx !== undefined) {
|
|
633
|
+
const base = mapMarketContext(marketId, perpCtx)
|
|
634
|
+
return {
|
|
635
|
+
...base,
|
|
636
|
+
midPrice: fast?.midPx != null ? fast.midPx : base.midPrice,
|
|
637
|
+
markPrice: fast?.markPx != null ? fast.markPx : base.markPrice,
|
|
618
638
|
}
|
|
619
639
|
}
|
|
620
|
-
|
|
640
|
+
const midPrice = fast?.midPx ?? fast?.markPx
|
|
641
|
+
const markPrice = fast?.markPx ?? fast?.midPx
|
|
642
|
+
if (midPrice != null && markPrice != null) {
|
|
643
|
+
return { marketId, midPrice, markPrice }
|
|
644
|
+
}
|
|
645
|
+
return undefined
|
|
621
646
|
}
|
|
622
647
|
|
|
623
648
|
private handleActiveAssetCtx(data: HlWsActiveAssetCtxData, raw: string) {
|
|
@@ -725,6 +750,14 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
725
750
|
return
|
|
726
751
|
}
|
|
727
752
|
|
|
753
|
+
// Compact deltas decode asynchronously via `orderbookDecodeChain`, so one
|
|
754
|
+
// can resolve after a newer frame (sync snapshot/update, or a later delta)
|
|
755
|
+
// has already been applied. A delta no newer than the maintained book is
|
|
756
|
+
// stale; applying it would overwrite fresher state with older levels.
|
|
757
|
+
if (delta.t <= previous.timestamp) {
|
|
758
|
+
return
|
|
759
|
+
}
|
|
760
|
+
|
|
728
761
|
const book: OrderbookResponse = {
|
|
729
762
|
provider: this.providerKey,
|
|
730
763
|
marketId: delta.c,
|
|
@@ -806,8 +839,7 @@ export class HyperliquidWsProvider extends WsProviderBase<object> {
|
|
|
806
839
|
continue
|
|
807
840
|
}
|
|
808
841
|
const type = mapOrderType(o.orderType)
|
|
809
|
-
//
|
|
810
|
-
// (the id may have listed after the snapshot); skip just this item.
|
|
842
|
+
// Unknown market id (absent from the synced snapshot); skip just this item.
|
|
811
843
|
const market = this.registry?.get(o.coin)
|
|
812
844
|
if (!market) {
|
|
813
845
|
continue
|