@lifi/perps-sdk 1.5.2 → 1.5.4

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":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,mBAAmB,CAAA;AACnE,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAUvD,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAoBpC,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAgErB"}
1
+ {"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAGR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAUvD,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAqBpC,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAuFrB"}
@@ -7,7 +7,7 @@ const resolveQuote_js_1 = require("./resolveQuote.js");
7
7
  exports.QUOTE_THROTTLE_MS = 100;
8
8
  async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQuote) {
9
9
  const market = await (0, resolveQuote_js_1.resolveQuoteMarket)(client, provider, params);
10
- const price = await (0, resolveQuote_js_1.resolveQuotePrice)(client, provider, market.id);
10
+ let latestContext = await (0, resolveQuote_js_1.resolveQuotePrice)(client, provider, market.id);
11
11
  let latestBook;
12
12
  let lastEmitAt = Number.NEGATIVE_INFINITY;
13
13
  let trailing;
@@ -23,32 +23,45 @@ async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQu
23
23
  side: params.side,
24
24
  sizeUsd: params.size,
25
25
  market,
26
- price,
26
+ price: latestContext,
27
27
  bids: latestBook.bids,
28
28
  asks: latestBook.asks,
29
29
  feeTier,
30
30
  timestamp: Date.now(),
31
31
  }));
32
32
  };
33
- const unsubscribe = await ws.subscribe({ channel: 'orderbook', dex: provider, marketId: market.id }, (event) => {
34
- if (event.channel !== 'orderbook') {
33
+ const unsubscribeContext = await ws.subscribe({ channel: 'marketContext', dex: provider, marketId: market.id }, (event) => {
34
+ if (event.channel !== 'marketContext') {
35
35
  return;
36
36
  }
37
- latestBook = event.data;
38
- if (trailing !== undefined) {
39
- return;
40
- }
41
- const wait = exports.QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
42
- if (wait <= 0) {
43
- emit();
44
- }
45
- else {
46
- trailing = setTimeout(() => {
47
- trailing = undefined;
48
- emit();
49
- }, wait);
50
- }
37
+ latestContext = event.data;
51
38
  });
39
+ let unsubscribeBook;
40
+ try {
41
+ unsubscribeBook = await ws.subscribe({ channel: 'orderbook', dex: provider, marketId: market.id }, (event) => {
42
+ if (event.channel !== 'orderbook') {
43
+ return;
44
+ }
45
+ latestBook = event.data;
46
+ if (trailing !== undefined) {
47
+ return;
48
+ }
49
+ const wait = exports.QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
50
+ if (wait <= 0) {
51
+ emit();
52
+ }
53
+ else {
54
+ trailing = setTimeout(() => {
55
+ trailing = undefined;
56
+ emit();
57
+ }, wait);
58
+ }
59
+ });
60
+ }
61
+ catch (error) {
62
+ unsubscribeContext();
63
+ throw error;
64
+ }
52
65
  let released = false;
53
66
  return () => {
54
67
  if (released) {
@@ -59,7 +72,8 @@ async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQu
59
72
  clearTimeout(trailing);
60
73
  trailing = undefined;
61
74
  }
62
- unsubscribe();
75
+ unsubscribeContext();
76
+ unsubscribeBook();
63
77
  };
64
78
  }
65
79
  //# sourceMappingURL=resolveSubscribeQuote.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":";;;AAqCA,sDAuEC;AAtGD,8DAAqD;AAErD,uDAAyE;AAS5D,QAAA,iBAAiB,GAAG,GAAG,CAAA;AAoB7B,KAAK,UAAU,qBAAqB,CACzC,MAAsB,EACtB,QAAgB,EAChB,EAAiC,EACjC,MAA8B,EAC9B,OAAgB,EAChB,OAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAkB,EAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,MAAM,IAAA,mCAAiB,EAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;IAElE,IAAI,UAAyC,CAAA;IAC7C,IAAI,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAA;IACzC,IAAI,QAAmD,CAAA;IAEvD,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAM;QACR,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACvB,OAAO,CACL,IAAA,4BAAU,EAAC;YACT,QAAQ;YACR,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,MAAM;YACN,KAAK;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CACH,CAAA;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,SAAS,CACpC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,EAC5D,CAAC,KAAK,EAAE,EAAE;QACR,IAAI,KAAK,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,UAAU,GAAG,KAAK,CAAC,IAAI,CAAA;QACvB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,yBAAiB,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAA;QAC1D,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,IAAI,EAAE,CAAA;QACR,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;gBACzB,QAAQ,GAAG,SAAS,CAAA;gBACpB,IAAI,EAAE,CAAA;YACR,CAAC,EAAE,IAAI,CAAC,CAAA;QACV,CAAC;IACH,CAAC,CACF,CAAA;IAED,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,OAAO,GAAG,EAAE;QACV,IAAI,QAAQ,EAAE,CAAC;YACb,OAAM;QACR,CAAC;QACD,QAAQ,GAAG,IAAI,CAAA;QACf,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,YAAY,CAAC,QAAQ,CAAC,CAAA;YACtB,QAAQ,GAAG,SAAS,CAAA;QACtB,CAAC;QACD,WAAW,EAAE,CAAA;IACf,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  export declare const name = "@lifi/perps-sdk";
2
- export declare const version = "1.5.2";
2
+ export declare const version = "1.5.4";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = exports.name = void 0;
4
4
  exports.name = '@lifi/perps-sdk';
5
- exports.version = '1.5.2';
5
+ exports.version = '1.5.4';
6
6
  //# sourceMappingURL=version.js.map
@@ -16,11 +16,13 @@ export declare class PerpsWsClient {
16
16
  private readonly options;
17
17
  private providers;
18
18
  private initPromises;
19
+ private closed;
19
20
  constructor(client: PerpsSDKClient, options?: PerpsWsClientOptions);
20
21
  subscribe<S extends Subscription>(sub: S, listener: (event: EventForSubscription<S>) => void, onStatus?: WsStatusListener): Promise<() => void>;
21
22
  subscribeQuote(params: GetQuoteParams, onQuote: QuoteListener): Promise<() => void>;
22
23
  close(): void;
23
24
  reconnect(provider: string): void;
25
+ private assertOpen;
24
26
  private getOrCreateProvider;
25
27
  private initProvider;
26
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PerpsWsClient.d.ts","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,KAAK,EACV,oBAAoB,EAEpB,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAQnB,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IAEvC,QAAQ,EAAE,MAAM,CAAA;IAEhB,KAAK,EAAE,MAAM,CAAA;IAOb,OAAO,EAAE,MAAM,EAAE,CAAA;IAMjB,MAAM,EAAE,cAAc,CAAA;CACvB,KAAK,UAAU,CAAA;AAOhB,MAAM,WAAW,oBAAoB;IASnC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAChD;AAQD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAyC;gBAEjD,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB;IAkBhE,SAAS,CAAC,CAAC,SAAS,YAAY,EACpC,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClD,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAkBhB,cAAc,CAClB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;IAkBtB,KAAK;IAcL,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAInB,mBAAmB;YAmBnB,YAAY;CAqC3B"}
1
+ {"version":3,"file":"PerpsWsClient.d.ts","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,KAAK,EACV,oBAAoB,EAEpB,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAQnB,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IAEvC,QAAQ,EAAE,MAAM,CAAA;IAEhB,KAAK,EAAE,MAAM,CAAA;IAOb,OAAO,EAAE,MAAM,EAAE,CAAA;IAMjB,MAAM,EAAE,cAAc,CAAA;CACvB,KAAK,UAAU,CAAA;AAOhB,MAAM,WAAW,oBAAoB;IASnC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAChD;AAQD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,MAAM,CAAQ;gBAEV,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB;IAkBhE,SAAS,CAAC,CAAC,SAAS,YAAY,EACpC,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClD,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAkBhB,cAAc,CAClB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;IAqBtB,KAAK;IAeL,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjC,OAAO,CAAC,UAAU;YASJ,mBAAmB;YAqBnB,YAAY;CAsC3B"}
@@ -10,6 +10,7 @@ class PerpsWsClient {
10
10
  options;
11
11
  providers = new Map();
12
12
  initPromises = new Map();
13
+ closed = false;
13
14
  constructor(client, options = {}) {
14
15
  this.client = client;
15
16
  this.options = options;
@@ -30,6 +31,7 @@ class PerpsWsClient {
30
31
  }, onQuote);
31
32
  }
32
33
  close() {
34
+ this.closed = true;
33
35
  for (const p of this.providers.values()) {
34
36
  p.close();
35
37
  }
@@ -39,7 +41,13 @@ class PerpsWsClient {
39
41
  reconnect(provider) {
40
42
  this.providers.get(provider)?.reconnect();
41
43
  }
44
+ assertOpen() {
45
+ if (this.closed) {
46
+ throw new PerpsError_js_1.PerpsError(perps_types_1.PerpsErrorCode.SDKError, 'PerpsWsClient is closed. Create a new instance to subscribe again.');
47
+ }
48
+ }
42
49
  async getOrCreateProvider(provider) {
50
+ this.assertOpen();
43
51
  const existing = this.providers.get(provider);
44
52
  if (existing) {
45
53
  return existing;
@@ -60,6 +68,7 @@ class PerpsWsClient {
60
68
  'new PerpsWsClient(client, { wsProviders: { [key]: factory } }).');
61
69
  }
62
70
  const { providers } = await (0, getProviders_js_1.getProviders)(this.client);
71
+ this.assertOpen();
63
72
  const providerInfo = providers.find((d) => d.key === provider);
64
73
  if (!providerInfo?.wsUrl) {
65
74
  throw new Error(`No WebSocket URL found for provider: ${provider}`);
@@ -1 +1 @@
1
- {"version":3,"file":"PerpsWsClient.js","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PerpsWsClient.js","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"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"}
@@ -12,17 +12,18 @@ export declare const QUOTE_THROTTLE_MS = 100;
12
12
  /**
13
13
  * Shared provider-side `subscribeQuote` implementation: resolve
14
14
  * `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
15
- * subscribe to that market's orderbook channel on `ws`, and on each book
16
- * update rebuild the {@link Quote} with the provider's public base `feeTier` —
17
- * the same transform the one-shot `resolveQuote` applies to a REST snapshot.
18
- * Emissions are throttled to {@link QUOTE_THROTTLE_MS}: the first book update
19
- * emits immediately, then at most one (trailing, latest-book) emission per
15
+ * subscribe to that market's orderbook and marketContext channels on `ws`,
16
+ * and on each book update rebuild the {@link Quote} against the latest
17
+ * {@link MarketContext} with the provider's public base `feeTier` the same
18
+ * transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
19
+ * are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
20
+ * immediately, then at most one (trailing, latest-book) emission per
20
21
  * interval. Both venue WS plugins delegate here; each only supplies its own
21
22
  * base tier.
22
23
  *
23
- * The returned unsubscribe is idempotent — it releases the underlying
24
- * orderbook listener once and cancels any pending trailing emission, so the
25
- * wire subscription's ref count cannot be double-decremented.
24
+ * The returned unsubscribe is idempotent — it releases both underlying
25
+ * listeners once and cancels any pending trailing emission, so the wire
26
+ * subscriptions' ref counts cannot be double-decremented.
26
27
  *
27
28
  * @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
28
29
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,mBAAmB,CAAA;AACnE,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAgErB"}
1
+ {"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAGR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAuFrB"}
@@ -11,24 +11,27 @@ export const QUOTE_THROTTLE_MS = 100;
11
11
  /**
12
12
  * Shared provider-side `subscribeQuote` implementation: resolve
13
13
  * `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
14
- * subscribe to that market's orderbook channel on `ws`, and on each book
15
- * update rebuild the {@link Quote} with the provider's public base `feeTier` —
16
- * the same transform the one-shot `resolveQuote` applies to a REST snapshot.
17
- * Emissions are throttled to {@link QUOTE_THROTTLE_MS}: the first book update
18
- * emits immediately, then at most one (trailing, latest-book) emission per
14
+ * subscribe to that market's orderbook and marketContext channels on `ws`,
15
+ * and on each book update rebuild the {@link Quote} against the latest
16
+ * {@link MarketContext} with the provider's public base `feeTier` the same
17
+ * transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
18
+ * are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
19
+ * immediately, then at most one (trailing, latest-book) emission per
19
20
  * interval. Both venue WS plugins delegate here; each only supplies its own
20
21
  * base tier.
21
22
  *
22
- * The returned unsubscribe is idempotent — it releases the underlying
23
- * orderbook listener once and cancels any pending trailing emission, so the
24
- * wire subscription's ref count cannot be double-decremented.
23
+ * The returned unsubscribe is idempotent — it releases both underlying
24
+ * listeners once and cancels any pending trailing emission, so the wire
25
+ * subscriptions' ref counts cannot be double-decremented.
25
26
  *
26
27
  * @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
27
28
  * @internal
28
29
  */
29
30
  export async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQuote) {
30
31
  const market = await resolveQuoteMarket(client, provider, params);
31
- const price = await resolveQuotePrice(client, provider, market.id);
32
+ // REST snapshot seeds the context; the marketContext subscription below
33
+ // keeps it live so streamed impact/funding track the moving market.
34
+ let latestContext = await resolveQuotePrice(client, provider, market.id);
32
35
  let latestBook;
33
36
  let lastEmitAt = Number.NEGATIVE_INFINITY;
34
37
  let trailing;
@@ -44,32 +47,45 @@ export async function resolveSubscribeQuote(client, provider, ws, params, feeTie
44
47
  side: params.side,
45
48
  sizeUsd: params.size,
46
49
  market,
47
- price,
50
+ price: latestContext,
48
51
  bids: latestBook.bids,
49
52
  asks: latestBook.asks,
50
53
  feeTier,
51
54
  timestamp: Date.now(),
52
55
  }));
53
56
  };
54
- const unsubscribe = await ws.subscribe({ channel: 'orderbook', dex: provider, marketId: market.id }, (event) => {
55
- if (event.channel !== 'orderbook') {
57
+ const unsubscribeContext = await ws.subscribe({ channel: 'marketContext', dex: provider, marketId: market.id }, (event) => {
58
+ if (event.channel !== 'marketContext') {
56
59
  return;
57
60
  }
58
- latestBook = event.data;
59
- if (trailing !== undefined) {
60
- return;
61
- }
62
- const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
63
- if (wait <= 0) {
64
- emit();
65
- }
66
- else {
67
- trailing = setTimeout(() => {
68
- trailing = undefined;
69
- emit();
70
- }, wait);
71
- }
61
+ latestContext = event.data;
72
62
  });
63
+ let unsubscribeBook;
64
+ try {
65
+ unsubscribeBook = await ws.subscribe({ channel: 'orderbook', dex: provider, marketId: market.id }, (event) => {
66
+ if (event.channel !== 'orderbook') {
67
+ return;
68
+ }
69
+ latestBook = event.data;
70
+ if (trailing !== undefined) {
71
+ return;
72
+ }
73
+ const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
74
+ if (wait <= 0) {
75
+ emit();
76
+ }
77
+ else {
78
+ trailing = setTimeout(() => {
79
+ trailing = undefined;
80
+ emit();
81
+ }, wait);
82
+ }
83
+ });
84
+ }
85
+ catch (error) {
86
+ unsubscribeContext();
87
+ throw error;
88
+ }
73
89
  let released = false;
74
90
  return () => {
75
91
  if (released) {
@@ -80,7 +96,8 @@ export async function resolveSubscribeQuote(client, provider, ws, params, feeTie
80
96
  clearTimeout(trailing);
81
97
  trailing = undefined;
82
98
  }
83
- unsubscribe();
99
+ unsubscribeContext();
100
+ unsubscribeBook();
84
101
  };
85
102
  }
86
103
  //# sourceMappingURL=resolveSubscribeQuote.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAErD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEzE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAEpC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAsB,EACtB,QAAgB,EAChB,EAAiC,EACjC,MAA8B,EAC9B,OAAgB,EAChB,OAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;IAElE,IAAI,UAAyC,CAAA;IAC7C,IAAI,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAA;IACzC,IAAI,QAAmD,CAAA;IAEvD,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAM;QACR,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACvB,OAAO,CACL,UAAU,CAAC;YACT,QAAQ;YACR,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,MAAM;YACN,KAAK;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CACH,CAAA;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,SAAS,CACpC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,EAC5D,CAAC,KAAK,EAAE,EAAE;QACR,IAAI,KAAK,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,UAAU,GAAG,KAAK,CAAC,IAAI,CAAA;QACvB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,iBAAiB,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAA;QAC1D,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,IAAI,EAAE,CAAA;QACR,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;gBACzB,QAAQ,GAAG,SAAS,CAAA;gBACpB,IAAI,EAAE,CAAA;YACR,CAAC,EAAE,IAAI,CAAC,CAAA;QACV,CAAC;IACH,CAAC,CACF,CAAA;IAED,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,OAAO,GAAG,EAAE;QACV,IAAI,QAAQ,EAAE,CAAC;YACb,OAAM;QACR,CAAC;QACD,QAAQ,GAAG,IAAI,CAAA;QACf,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,YAAY,CAAC,QAAQ,CAAC,CAAA;YACtB,QAAQ,GAAG,SAAS,CAAA;QACtB,CAAC;QACD,WAAW,EAAE,CAAA;IACf,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  export declare const name = "@lifi/perps-sdk";
2
- export declare const version = "1.5.2";
2
+ export declare const version = "1.5.4";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  export const name = '@lifi/perps-sdk';
2
- export const version = '1.5.2';
2
+ export const version = '1.5.4';
3
3
  //# sourceMappingURL=version.js.map
@@ -54,6 +54,7 @@ export declare class PerpsWsClient {
54
54
  private readonly options;
55
55
  private providers;
56
56
  private initPromises;
57
+ private closed;
57
58
  constructor(client: PerpsSDKClient, options?: PerpsWsClientOptions);
58
59
  /**
59
60
  * Subscribe to a realtime channel, lazily creating the provider's WS
@@ -83,6 +84,9 @@ export declare class PerpsWsClient {
83
84
  subscribeQuote(params: GetQuoteParams, onQuote: QuoteListener): Promise<() => void>;
84
85
  /**
85
86
  * Close every open provider WS connection and drop all cached providers.
87
+ * Terminal: after `close()` the client is dead — `subscribe` and
88
+ * `subscribeQuote` reject, and any provider init still suspended mid-flight
89
+ * aborts without opening a socket. Create a new instance to subscribe again.
86
90
  *
87
91
  * @public
88
92
  */
@@ -94,6 +98,7 @@ export declare class PerpsWsClient {
94
98
  * @public
95
99
  */
96
100
  reconnect(provider: string): void;
101
+ private assertOpen;
97
102
  private getOrCreateProvider;
98
103
  private initProvider;
99
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PerpsWsClient.d.ts","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,KAAK,EACV,oBAAoB,EAEpB,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IACvC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;;;OAIG;IACH,MAAM,EAAE,cAAc,CAAA;CACvB,KAAK,UAAU,CAAA;AAEhB;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAChD;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAyC;gBAEjD,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB;IAKtE;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,CAAC,SAAS,YAAY,EACpC,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClD,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAOtB;;;;;;;;;;OAUG;IACG,cAAc,CAClB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;IAatB;;;;OAIG;IACH,KAAK;IAQL;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAInB,mBAAmB;YAmBnB,YAAY;CAqC3B"}
1
+ {"version":3,"file":"PerpsWsClient.d.ts","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,KAAK,EACV,oBAAoB,EAEpB,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IACvC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;;;OAIG;IACH,MAAM,EAAE,cAAc,CAAA;CACvB,KAAK,UAAU,CAAA;AAEhB;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAChD;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,MAAM,CAAQ;gBAEV,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB;IAKtE;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,CAAC,SAAS,YAAY,EACpC,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClD,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAOtB;;;;;;;;;;OAUG;IACG,cAAc,CAClB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;IAatB;;;;;;;OAOG;IACH,KAAK;IASL;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjC,OAAO,CAAC,UAAU;YASJ,mBAAmB;YAqBnB,YAAY;CAsC3B"}
@@ -13,6 +13,7 @@ export class PerpsWsClient {
13
13
  options;
14
14
  providers = new Map();
15
15
  initPromises = new Map();
16
+ closed = false;
16
17
  constructor(client, options = {}) {
17
18
  this.client = client;
18
19
  this.options = options;
@@ -58,10 +59,14 @@ export class PerpsWsClient {
58
59
  }
59
60
  /**
60
61
  * Close every open provider WS connection and drop all cached providers.
62
+ * Terminal: after `close()` the client is dead — `subscribe` and
63
+ * `subscribeQuote` reject, and any provider init still suspended mid-flight
64
+ * aborts without opening a socket. Create a new instance to subscribe again.
61
65
  *
62
66
  * @public
63
67
  */
64
68
  close() {
69
+ this.closed = true;
65
70
  for (const p of this.providers.values()) {
66
71
  p.close();
67
72
  }
@@ -77,7 +82,13 @@ export class PerpsWsClient {
77
82
  reconnect(provider) {
78
83
  this.providers.get(provider)?.reconnect();
79
84
  }
85
+ assertOpen() {
86
+ if (this.closed) {
87
+ throw new PerpsError(PerpsErrorCode.SDKError, 'PerpsWsClient is closed. Create a new instance to subscribe again.');
88
+ }
89
+ }
80
90
  async getOrCreateProvider(provider) {
91
+ this.assertOpen();
81
92
  const existing = this.providers.get(provider);
82
93
  if (existing) {
83
94
  return existing;
@@ -98,6 +109,7 @@ export class PerpsWsClient {
98
109
  'new PerpsWsClient(client, { wsProviders: { [key]: factory } }).');
99
110
  }
100
111
  const { providers } = await getProviders(this.client);
112
+ this.assertOpen();
101
113
  const providerInfo = providers.find((d) => d.key === provider);
102
114
  if (!providerInfo?.wsUrl) {
103
115
  throw new Error(`No WebSocket URL found for provider: ${provider}`);
@@ -1 +1 @@
1
- {"version":3,"file":"PerpsWsClient.js","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PerpsWsClient.js","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAA;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAmDhD;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACP,MAAM,CAAgB;IACtB,OAAO,CAAsB;IACtC,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAA;IACzC,YAAY,GAAG,IAAI,GAAG,EAA+B,CAAA;IACrD,MAAM,GAAG,KAAK,CAAA;IAEtB,YAAY,MAAsB,EAAE,UAAgC,EAAE;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,SAAS,CACb,GAAM,EACN,QAAkD,EAClD,QAA2B;QAE3B,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAA;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAA;QAC5D,QAAQ,CAAC,SAAS,EAAE,CAAA;QACpB,OAAO,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,QAAgC,EAAE,QAAQ,CAAC,CAAA;IAC5E,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,cAAc,CAClB,MAAsB,EACtB,OAAsB;QAEtB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAChE,OAAO,QAAQ,CAAC,cAAc,CAC5B;YACE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,EACD,OAAO,CACR,CAAA;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,CAAC,CAAC,KAAK,EAAE,CAAA;QACX,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;QACtB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;IAC3B,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAgB;QACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAA;IAC3C,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,UAAU,CAClB,cAAc,CAAC,QAAQ,EACvB,oEAAoE,CACrE,CAAA;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,QAAgB;QAChD,IAAI,CAAC,UAAU,EAAE,CAAA;QAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,OAAO,YAAY,CACjB,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EACrC,CAAC,CAAC,EAAE,EAAE;YACJ,IAAI,CAAC,EAAE,CAAC;gBACN,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;YACpC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YACpC,CAAC;QACH,CAAC,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAClC,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,QAAgB;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAA;QACpD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,UAAU,CAClB,cAAc,CAAC,QAAQ,EACvB,0CAA0C,QAAQ,kBAAkB;gBAClE,iEAAiE,CACpE,CAAA;QACH,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACrD,IAAI,CAAC,UAAU,EAAE,CAAA;QAEjB,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAA;QAC9D,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,QAAQ,EAAE,CAAC,CAAA;QACrE,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,YAAY,CAAC,UAAU,IAAI,EAAE,CAE/C,CAAA;QACF,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,CAAA;QAC/D,MAAM,iBAAiB,GAAG,cAAc,EAAE,OAAO,CAAA;QACjD,MAAM,OAAO,GAAG,CACd,iBAAiB;YACf,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC,CAAC,UAAU,CACf,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QAElB,MAAM,UAAU,GAAG,OAAO,CAAC;YACzB,QAAQ;YACR,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAA;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACxC,OAAO,UAAU,CAAA;IACnB,CAAC;CACF"}
@@ -12,17 +12,18 @@ export declare const QUOTE_THROTTLE_MS = 100;
12
12
  /**
13
13
  * Shared provider-side `subscribeQuote` implementation: resolve
14
14
  * `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
15
- * subscribe to that market's orderbook channel on `ws`, and on each book
16
- * update rebuild the {@link Quote} with the provider's public base `feeTier` —
17
- * the same transform the one-shot `resolveQuote` applies to a REST snapshot.
18
- * Emissions are throttled to {@link QUOTE_THROTTLE_MS}: the first book update
19
- * emits immediately, then at most one (trailing, latest-book) emission per
15
+ * subscribe to that market's orderbook and marketContext channels on `ws`,
16
+ * and on each book update rebuild the {@link Quote} against the latest
17
+ * {@link MarketContext} with the provider's public base `feeTier` the same
18
+ * transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
19
+ * are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
20
+ * immediately, then at most one (trailing, latest-book) emission per
20
21
  * interval. Both venue WS plugins delegate here; each only supplies its own
21
22
  * base tier.
22
23
  *
23
- * The returned unsubscribe is idempotent — it releases the underlying
24
- * orderbook listener once and cancels any pending trailing emission, so the
25
- * wire subscription's ref count cannot be double-decremented.
24
+ * The returned unsubscribe is idempotent — it releases both underlying
25
+ * listeners once and cancels any pending trailing emission, so the wire
26
+ * subscriptions' ref counts cannot be double-decremented.
26
27
  *
27
28
  * @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
28
29
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,mBAAmB,CAAA;AACnE,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAgErB"}
1
+ {"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAGR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAuFrB"}
@@ -1,3 +1,3 @@
1
1
  export declare const name = "@lifi/perps-sdk";
2
- export declare const version = "1.5.2";
2
+ export declare const version = "1.5.4";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -54,6 +54,7 @@ export declare class PerpsWsClient {
54
54
  private readonly options;
55
55
  private providers;
56
56
  private initPromises;
57
+ private closed;
57
58
  constructor(client: PerpsSDKClient, options?: PerpsWsClientOptions);
58
59
  /**
59
60
  * Subscribe to a realtime channel, lazily creating the provider's WS
@@ -83,6 +84,9 @@ export declare class PerpsWsClient {
83
84
  subscribeQuote(params: GetQuoteParams, onQuote: QuoteListener): Promise<() => void>;
84
85
  /**
85
86
  * Close every open provider WS connection and drop all cached providers.
87
+ * Terminal: after `close()` the client is dead — `subscribe` and
88
+ * `subscribeQuote` reject, and any provider init still suspended mid-flight
89
+ * aborts without opening a socket. Create a new instance to subscribe again.
86
90
  *
87
91
  * @public
88
92
  */
@@ -94,6 +98,7 @@ export declare class PerpsWsClient {
94
98
  * @public
95
99
  */
96
100
  reconnect(provider: string): void;
101
+ private assertOpen;
97
102
  private getOrCreateProvider;
98
103
  private initProvider;
99
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PerpsWsClient.d.ts","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,KAAK,EACV,oBAAoB,EAEpB,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IACvC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;;;OAIG;IACH,MAAM,EAAE,cAAc,CAAA;CACvB,KAAK,UAAU,CAAA;AAEhB;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAChD;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAyC;gBAEjD,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB;IAKtE;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,CAAC,SAAS,YAAY,EACpC,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClD,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAOtB;;;;;;;;;;OAUG;IACG,cAAc,CAClB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;IAatB;;;;OAIG;IACH,KAAK;IAQL;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAInB,mBAAmB;YAmBnB,YAAY;CAqC3B"}
1
+ {"version":3,"file":"PerpsWsClient.d.ts","sourceRoot":"","sources":["../../../src/websocket/PerpsWsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,KAAK,EACV,oBAAoB,EAEpB,UAAU,EACV,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IACvC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;;;OAIG;IACH,MAAM,EAAE,cAAc,CAAA;CACvB,KAAK,UAAU,CAAA;AAEhB;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAChD;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,MAAM,CAAQ;gBAEV,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB;IAKtE;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,CAAC,SAAS,YAAY,EACpC,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClD,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,IAAI,CAAC;IAOtB;;;;;;;;;;OAUG;IACG,cAAc,CAClB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC;IAatB;;;;;;;OAOG;IACH,KAAK;IASL;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjC,OAAO,CAAC,UAAU;YASJ,mBAAmB;YAqBnB,YAAY;CAsC3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/perps-sdk",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "LI.FI Perps SDK for perpetuals trading",
5
5
  "homepage": "https://github.com/lifinance/perps-sdk",
6
6
  "bugs": {
@@ -44,7 +44,7 @@
44
44
  "@lifi/types": "17.82.1",
45
45
  "partysocket": "^1.1.19",
46
46
  "viem": "^2.48.8",
47
- "@lifi/perps-types": "^1.5.1"
47
+ "@lifi/perps-types": "^1.6.0"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"
@@ -1,4 +1,8 @@
1
- import type { FeeTier, OrderbookResponse } from '@lifi/perps-types'
1
+ import type {
2
+ FeeTier,
3
+ MarketContext,
4
+ OrderbookResponse,
5
+ } from '@lifi/perps-types'
2
6
  import type {
3
7
  PerpsSDKClient,
4
8
  ProviderGetQuoteParams,
@@ -20,17 +24,18 @@ export const QUOTE_THROTTLE_MS = 100
20
24
  /**
21
25
  * Shared provider-side `subscribeQuote` implementation: resolve
22
26
  * `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
23
- * subscribe to that market's orderbook channel on `ws`, and on each book
24
- * update rebuild the {@link Quote} with the provider's public base `feeTier` —
25
- * the same transform the one-shot `resolveQuote` applies to a REST snapshot.
26
- * Emissions are throttled to {@link QUOTE_THROTTLE_MS}: the first book update
27
- * emits immediately, then at most one (trailing, latest-book) emission per
27
+ * subscribe to that market's orderbook and marketContext channels on `ws`,
28
+ * and on each book update rebuild the {@link Quote} against the latest
29
+ * {@link MarketContext} with the provider's public base `feeTier` the same
30
+ * transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
31
+ * are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
32
+ * immediately, then at most one (trailing, latest-book) emission per
28
33
  * interval. Both venue WS plugins delegate here; each only supplies its own
29
34
  * base tier.
30
35
  *
31
- * The returned unsubscribe is idempotent — it releases the underlying
32
- * orderbook listener once and cancels any pending trailing emission, so the
33
- * wire subscription's ref count cannot be double-decremented.
36
+ * The returned unsubscribe is idempotent — it releases both underlying
37
+ * listeners once and cancels any pending trailing emission, so the wire
38
+ * subscriptions' ref counts cannot be double-decremented.
34
39
  *
35
40
  * @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
36
41
  * @internal
@@ -44,7 +49,13 @@ export async function resolveSubscribeQuote(
44
49
  onQuote: QuoteListener
45
50
  ): Promise<() => void> {
46
51
  const market = await resolveQuoteMarket(client, provider, params)
47
- const price = await resolveQuotePrice(client, provider, market.id)
52
+ // REST snapshot seeds the context; the marketContext subscription below
53
+ // keeps it live so streamed impact/funding track the moving market.
54
+ let latestContext: MarketContext = await resolveQuotePrice(
55
+ client,
56
+ provider,
57
+ market.id
58
+ )
48
59
 
49
60
  let latestBook: OrderbookResponse | undefined
50
61
  let lastEmitAt = Number.NEGATIVE_INFINITY
@@ -63,7 +74,7 @@ export async function resolveSubscribeQuote(
63
74
  side: params.side,
64
75
  sizeUsd: params.size,
65
76
  market,
66
- price,
77
+ price: latestContext,
67
78
  bids: latestBook.bids,
68
79
  asks: latestBook.asks,
69
80
  feeTier,
@@ -72,28 +83,44 @@ export async function resolveSubscribeQuote(
72
83
  )
73
84
  }
74
85
 
75
- const unsubscribe = await ws.subscribe(
76
- { channel: 'orderbook', dex: provider, marketId: market.id },
86
+ const unsubscribeContext = await ws.subscribe(
87
+ { channel: 'marketContext', dex: provider, marketId: market.id },
77
88
  (event) => {
78
- if (event.channel !== 'orderbook') {
79
- return
80
- }
81
- latestBook = event.data
82
- if (trailing !== undefined) {
89
+ if (event.channel !== 'marketContext') {
83
90
  return
84
91
  }
85
- const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt)
86
- if (wait <= 0) {
87
- emit()
88
- } else {
89
- trailing = setTimeout(() => {
90
- trailing = undefined
91
- emit()
92
- }, wait)
93
- }
92
+ latestContext = event.data
94
93
  }
95
94
  )
96
95
 
96
+ let unsubscribeBook: () => void
97
+ try {
98
+ unsubscribeBook = await ws.subscribe(
99
+ { channel: 'orderbook', dex: provider, marketId: market.id },
100
+ (event) => {
101
+ if (event.channel !== 'orderbook') {
102
+ return
103
+ }
104
+ latestBook = event.data
105
+ if (trailing !== undefined) {
106
+ return
107
+ }
108
+ const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt)
109
+ if (wait <= 0) {
110
+ emit()
111
+ } else {
112
+ trailing = setTimeout(() => {
113
+ trailing = undefined
114
+ emit()
115
+ }, wait)
116
+ }
117
+ }
118
+ )
119
+ } catch (error) {
120
+ unsubscribeContext()
121
+ throw error
122
+ }
123
+
97
124
  let released = false
98
125
  return () => {
99
126
  if (released) {
@@ -104,6 +131,7 @@ export async function resolveSubscribeQuote(
104
131
  clearTimeout(trailing)
105
132
  trailing = undefined
106
133
  }
107
- unsubscribe()
134
+ unsubscribeContext()
135
+ unsubscribeBook()
108
136
  }
109
137
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/perps-sdk'
2
- export const version = '1.5.2'
2
+ export const version = '1.5.4'
@@ -65,6 +65,7 @@ export class PerpsWsClient {
65
65
  private readonly options: PerpsWsClientOptions
66
66
  private providers = new Map<string, WsProvider>()
67
67
  private initPromises = new Map<string, Promise<WsProvider>>()
68
+ private closed = false
68
69
 
69
70
  constructor(client: PerpsSDKClient, options: PerpsWsClientOptions = {}) {
70
71
  this.client = client
@@ -124,10 +125,14 @@ export class PerpsWsClient {
124
125
 
125
126
  /**
126
127
  * Close every open provider WS connection and drop all cached providers.
128
+ * Terminal: after `close()` the client is dead — `subscribe` and
129
+ * `subscribeQuote` reject, and any provider init still suspended mid-flight
130
+ * aborts without opening a socket. Create a new instance to subscribe again.
127
131
  *
128
132
  * @public
129
133
  */
130
134
  close() {
135
+ this.closed = true
131
136
  for (const p of this.providers.values()) {
132
137
  p.close()
133
138
  }
@@ -145,7 +150,18 @@ export class PerpsWsClient {
145
150
  this.providers.get(provider)?.reconnect()
146
151
  }
147
152
 
153
+ private assertOpen(): void {
154
+ if (this.closed) {
155
+ throw new PerpsError(
156
+ PerpsErrorCode.SDKError,
157
+ 'PerpsWsClient is closed. Create a new instance to subscribe again.'
158
+ )
159
+ }
160
+ }
161
+
148
162
  private async getOrCreateProvider(provider: string): Promise<WsProvider> {
163
+ this.assertOpen()
164
+
149
165
  const existing = this.providers.get(provider)
150
166
  if (existing) {
151
167
  return existing
@@ -175,6 +191,7 @@ export class PerpsWsClient {
175
191
  }
176
192
 
177
193
  const { providers } = await getProviders(this.client)
194
+ this.assertOpen()
178
195
 
179
196
  const providerInfo = providers.find((d) => d.key === provider)
180
197
  if (!providerInfo?.wsUrl) {