@lifi/perps-sdk-provider-hyperliquid 0.0.0-preview-3487136 → 0.0.0-preview-e857187

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.
@@ -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;AAUvD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAeD,eAAO,MAAM,QAAQ,GACnB,oBAAoB,kBAAkB,EACtC,QAAQ,cAAc,EACtB,UAAU,iBAAiB,KAC1B,OAAO,CAAC,aAAa,CAiDvB,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;AAcvD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAiCD,eAAO,MAAM,QAAQ,GACnB,oBAAoB,kBAAkB,EACtC,QAAQ,cAAc,EACtB,UAAU,iBAAiB,KAC1B,OAAO,CAAC,aAAa,CAqDvB,CAAA"}
@@ -5,6 +5,12 @@ const perps_sdk_1 = require("@lifi/perps-sdk");
5
5
  const constants_js_1 = require("../constants.js");
6
6
  const index_js_1 = require("../utils/index.js");
7
7
  const infoClient_js_1 = require("../utils/infoClient.js");
8
+ const compareFillsDesc = (a, b) => b.time - a.time || b.tid - a.tid;
9
+ const encodeCursor = (fill) => `${fill.time}:${fill.tid}`;
10
+ const decodeCursor = (cursor) => {
11
+ const [time, tid] = cursor.split(':').map(Number);
12
+ return { time, tid };
13
+ };
8
14
  const getFills = async ({ client, apiUrl }, params, options) => {
9
15
  const registry = (0, perps_sdk_1.getMarketRegistry)(client, constants_js_1.PROVIDER_KEY);
10
16
  await registry.sync();
@@ -19,20 +25,21 @@ const getFills = async ({ client, apiUrl }, params, options) => {
19
25
  ...(params.endTime !== undefined ? { endTime: params.endTime } : {}),
20
26
  }, infoOpts)
21
27
  : await (0, infoClient_js_1.infoRequest)(apiUrl, { type: 'userFills', user: params.address }, infoOpts);
28
+ const sorted = [...allFills].sort(compareFillsDesc);
22
29
  const filtered = params.cursor === undefined
23
- ? allFills
24
- : allFills.filter((f) => f.tid < Number.parseInt(params.cursor, 10));
30
+ ? sorted
31
+ : sorted.filter((f) => compareFillsDesc(f, decodeCursor(params.cursor)) > 0);
25
32
  const hasMore = filtered.length > limit;
26
- const items = filtered
27
- .slice(0, limit)
28
- .map((f) => (0, index_js_1.mapFill)(f, registry.require(f.coin)));
33
+ const page = filtered.slice(0, limit);
34
+ const items = page.map((f) => (0, index_js_1.mapFill)(f, registry.require(f.coin)));
35
+ const lastPageFill = page[page.length - 1];
29
36
  return {
30
37
  provider: constants_js_1.PROVIDER_KEY,
31
38
  items,
32
39
  pagination: {
33
40
  limit,
34
41
  hasMore,
35
- cursor: items.length > 0 ? items[items.length - 1].id : undefined,
42
+ cursor: lastPageFill ? encodeCursor(lastPageFill) : undefined,
36
43
  },
37
44
  };
38
45
  };
@@ -1 +1 @@
1
- {"version":3,"file":"getFills.js","sourceRoot":"","sources":["../../../src/services/getFills.ts"],"names":[],"mappings":";;;AAAA,+CAA2E;AAG3E,kDAIwB;AAGxB,gDAA2C;AAC3C,0DAAmE;AA+B5D,MAAM,QAAQ,GAAG,KAAK,EAC3B,EAAE,MAAM,EAAE,MAAM,EAAsB,EACtC,MAAsB,EACtB,OAA2B,EACH,EAAE;IAC1B,MAAM,QAAQ,GAAG,IAAA,6BAAiB,EAAC,MAAM,EAAE,2BAAY,CAAC,CAAA;IACxD,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IACrB,MAAM,QAAQ,GAAG,IAAA,6BAAa,EAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,MAAM,CAAC,KAAK,IAAI,oCAAqB,EACrC,gCAAiB,CAClB,CAAA;IAED,MAAM,SAAS,GACb,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,CAAA;IAEhE,MAAM,QAAQ,GAAG,SAAS;QACxB,CAAC,CAAC,MAAM,IAAA,2BAAW,EACf,MAAM,EACN;YACE,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,MAAM,CAAC,OAAO;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,CAAC;YAChC,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,EACD,QAAQ,CACT;QACH,CAAC,CAAC,MAAM,IAAA,2BAAW,EACf,MAAM,EACN,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,EAC3C,QAAQ,CACT,CAAA;IAEL,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,KAAK,SAAS;QACzB,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAEzE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAA;IACvC,MAAM,KAAK,GAAG,QAAQ;SACnB,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,kBAAO,EAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAEnD,OAAO;QACL,QAAQ,EAAE,2BAAY;QACtB,KAAK;QACL,UAAU,EAAE;YACV,KAAK;YACL,OAAO;YACP,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;SAClE;KACF,CAAA;AACH,CAAC,CAAA;AArDY,QAAA,QAAQ,YAqDpB"}
1
+ {"version":3,"file":"getFills.js","sourceRoot":"","sources":["../../../src/services/getFills.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ import type { HyperliquidContext } from '../context.js';
10
10
  export interface GetFillsParams {
11
11
  address: Address;
12
12
  limit?: number;
13
- /** `tid` of the oldest fill to return (returned items have `tid < cursor`). */
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
- * Pagination is cursor-based on the fill's `tid`: results with
28
- * `tid < cursor` are kept and the last-page's tail `id` is returned as the
29
- * next cursor.
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;AAKvD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,GACnB,oBAAoB,kBAAkB,EACtC,QAAQ,cAAc,EACtB,UAAU,iBAAiB,KAC1B,OAAO,CAAC,aAAa,CAiDvB,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"}
@@ -2,6 +2,15 @@ import { getMarketRegistry } from '@lifi/perps-sdk';
2
2
  import { DEFAULT_HISTORY_LIMIT, MAX_HISTORY_LIMIT, PROVIDER_KEY, } from '../constants.js';
3
3
  import { mapFill } from '../utils/index.js';
4
4
  import { hlInfoOptions, infoRequest } from '../utils/infoClient.js';
5
+ // HL's docs specify neither newest-first ordering nor monotonic `tid` for
6
+ // `userFills`/`userFillsByTime`, so pagination can't rely on upstream order —
7
+ // it must impose its own (time desc, tid desc as tiebreaker for same-time fills).
8
+ const compareFillsDesc = (a, b) => b.time - a.time || b.tid - a.tid;
9
+ const encodeCursor = (fill) => `${fill.time}:${fill.tid}`;
10
+ const decodeCursor = (cursor) => {
11
+ const [time, tid] = cursor.split(':').map(Number);
12
+ return { time, tid };
13
+ };
5
14
  /**
6
15
  * Fetch the user's fills history. When `startTime` or `endTime` is provided,
7
16
  * Hyperliquid's `userFillsByTime` endpoint is used; otherwise the unbounded
@@ -9,9 +18,9 @@ import { hlInfoOptions, infoRequest } from '../utils/infoClient.js';
9
18
  * list supplies the display fields; only the fills endpoint is read direct
10
19
  * from HL.
11
20
  *
12
- * Pagination is cursor-based on the fill's `tid`: results with
13
- * `tid < cursor` are kept and the last-page's tail `id` is returned as the
14
- * next cursor.
21
+ * The response is sorted (time desc, `tid` as tiebreaker) before pagination —
22
+ * see {@link compareFillsDesc}. The cursor encodes the last returned fill's
23
+ * `(time, tid)`; the next page keeps fills that sort strictly after it.
15
24
  * @throws {PerpsError} On Hyperliquid REST error, network, or parsing failures.
16
25
  * @public
17
26
  */
@@ -29,20 +38,21 @@ export const getFills = async ({ client, apiUrl }, params, options) => {
29
38
  ...(params.endTime !== undefined ? { endTime: params.endTime } : {}),
30
39
  }, infoOpts)
31
40
  : await infoRequest(apiUrl, { type: 'userFills', user: params.address }, infoOpts);
41
+ const sorted = [...allFills].sort(compareFillsDesc);
32
42
  const filtered = params.cursor === undefined
33
- ? allFills
34
- : allFills.filter((f) => f.tid < Number.parseInt(params.cursor, 10));
43
+ ? sorted
44
+ : sorted.filter((f) => compareFillsDesc(f, decodeCursor(params.cursor)) > 0);
35
45
  const hasMore = filtered.length > limit;
36
- const items = filtered
37
- .slice(0, limit)
38
- .map((f) => mapFill(f, registry.require(f.coin)));
46
+ const page = filtered.slice(0, limit);
47
+ const items = page.map((f) => mapFill(f, registry.require(f.coin)));
48
+ const lastPageFill = page[page.length - 1];
39
49
  return {
40
50
  provider: PROVIDER_KEY,
41
51
  items,
42
52
  pagination: {
43
53
  limit,
44
54
  hasMore,
45
- cursor: items.length > 0 ? items[items.length - 1].id : undefined,
55
+ cursor: lastPageFill ? encodeCursor(lastPageFill) : undefined,
46
56
  },
47
57
  };
48
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"getFills.js","sourceRoot":"","sources":["../../../src/services/getFills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA0B,MAAM,iBAAiB,CAAA;AAG3E,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,YAAY,GACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAkBnE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAC3B,EAAE,MAAM,EAAE,MAAM,EAAsB,EACtC,MAAsB,EACtB,OAA2B,EACH,EAAE;IAC1B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACxD,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IACrB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,MAAM,CAAC,KAAK,IAAI,qBAAqB,EACrC,iBAAiB,CAClB,CAAA;IAED,MAAM,SAAS,GACb,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,CAAA;IAEhE,MAAM,QAAQ,GAAG,SAAS;QACxB,CAAC,CAAC,MAAM,WAAW,CACf,MAAM,EACN;YACE,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,MAAM,CAAC,OAAO;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,CAAC;YAChC,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,EACD,QAAQ,CACT;QACH,CAAC,CAAC,MAAM,WAAW,CACf,MAAM,EACN,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,EAC3C,QAAQ,CACT,CAAA;IAEL,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,KAAK,SAAS;QACzB,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAEzE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAA;IACvC,MAAM,KAAK,GAAG,QAAQ;SACnB,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAEnD,OAAO;QACL,QAAQ,EAAE,YAAY;QACtB,KAAK;QACL,UAAU,EAAE;YACV,KAAK;YACL,OAAO;YACP,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;SAClE;KACF,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"getFills.js","sourceRoot":"","sources":["../../../src/services/getFills.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ import type { HyperliquidContext } from '../context.js';
10
10
  export interface GetFillsParams {
11
11
  address: Address;
12
12
  limit?: number;
13
- /** `tid` of the oldest fill to return (returned items have `tid < cursor`). */
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
- * Pagination is cursor-based on the fill's `tid`: results with
28
- * `tid < cursor` are kept and the last-page's tail `id` is returned as the
29
- * next cursor.
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;AAKvD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,GACnB,oBAAoB,kBAAkB,EACtC,QAAQ,cAAc,EACtB,UAAU,iBAAiB,KAC1B,OAAO,CAAC,aAAa,CAiDvB,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/perps-sdk-provider-hyperliquid",
3
- "version": "0.0.0-preview-3487136",
3
+ "version": "0.0.0-preview-e857187",
4
4
  "description": "Hyperliquid provider plugin for @lifi/perps-sdk",
5
5
  "homepage": "https://github.com/lifinance/perps-sdk",
6
6
  "bugs": {
@@ -48,10 +48,10 @@
48
48
  "dependencies": {
49
49
  "big.js": "^7.0.1",
50
50
  "viem": "^2.48.8",
51
- "@lifi/perps-types": "^0.0.0-preview-3487136"
51
+ "@lifi/perps-types": "^1.6.0"
52
52
  },
53
53
  "peerDependencies": {
54
- "@lifi/perps-sdk": "^0.0.0-preview-3487136"
54
+ "@lifi/perps-sdk": "^1.5.5"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public"
@@ -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 { HlUserFills, HlUserFillsByTime } from '../types/index.js'
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
- /** `tid` of the oldest fill to return (returned items have `tid < cursor`). */
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
- * Pagination is cursor-based on the fill's `tid`: results with
38
- * `tid < cursor` are kept and the last-page's tail `id` is returned as the
39
- * next cursor.
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
- ? allFills
80
- : allFills.filter((f) => f.tid < Number.parseInt(params.cursor!, 10))
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 items = filtered
84
- .slice(0, limit)
85
- .map((f) => mapFill(f, registry.require(f.coin)))
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: items.length > 0 ? items[items.length - 1].id : undefined,
119
+ cursor: lastPageFill ? encodeCursor(lastPageFill) : undefined,
94
120
  },
95
121
  }
96
122
  }