@lifi/perps-sdk 0.0.0-preview-3487136 → 0.0.0-preview-6a6cdfa

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":"getMarket.d.ts","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAA;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAO1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAMhB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAiBD,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAYjB"}
1
+ {"version":3,"file":"getMarket.d.ts","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAA;AAIhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAO1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAMhB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAkBD,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getMarket = getMarket;
4
+ const perps_types_1 = require("@lifi/perps-types");
5
+ const PerpsError_js_1 = require("../errors/PerpsError.js");
4
6
  const request_js_1 = require("../transport/request.js");
5
7
  async function getMarket(client, params, options) {
6
8
  const url = (0, request_js_1.buildUrl)(`${client.config.apiUrl}/markets`, {
@@ -8,6 +10,12 @@ async function getMarket(client, params, options) {
8
10
  marketIds: params.marketId,
9
11
  });
10
12
  const { markets } = await (0, request_js_1.request)(client.config, url, {}, options);
11
- return markets[0];
13
+ const market = markets[0];
14
+ if (market === undefined) {
15
+ const error = new PerpsError_js_1.PerpsError(perps_types_1.PerpsErrorCode.MarketNotFound, `No ${params.provider} market found for marketId '${params.marketId}'`);
16
+ error.tool = params.provider;
17
+ throw error;
18
+ }
19
+ return market;
12
20
  }
13
21
  //# sourceMappingURL=getMarket.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getMarket.js","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":";;AAmCA,8BAgBC;AAlDD,wDAA2D;AAkCpD,KAAK,UAAU,SAAS,CAC7B,MAAsB,EACtB,MAAuB,EACvB,OAA2B;IAE3B,MAAM,GAAG,GAAG,IAAA,qBAAQ,EAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE;QACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,QAAQ;KAC3B,CAAC,CAAA;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,oBAAO,EAC/B,MAAM,CAAC,MAAM,EACb,GAAG,EACH,EAAE,EACF,OAAO,CACR,CAAA;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC"}
1
+ {"version":3,"file":"getMarket.js","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":";;AAsCA,8BAyBC;AA9DD,mDAAkD;AAClD,2DAAoD;AACpD,wDAA2D;AAmCpD,KAAK,UAAU,SAAS,CAC7B,MAAsB,EACtB,MAAuB,EACvB,OAA2B;IAE3B,MAAM,GAAG,GAAG,IAAA,qBAAQ,EAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE;QACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,QAAQ;KAC3B,CAAC,CAAA;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,oBAAO,EAC/B,MAAM,CAAC,MAAM,EACb,GAAG,EACH,EAAE,EACF,OAAO,CACR,CAAA;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACzB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,0BAAU,CAC1B,4BAAc,CAAC,cAAc,EAC7B,MAAM,MAAM,CAAC,QAAQ,+BAA+B,MAAM,CAAC,QAAQ,GAAG,CACvE,CAAA;QACD,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC5B,MAAM,KAAK,CAAA;IACb,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -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 = "0.0.0-preview-3487136";
2
+ export declare const version = "0.0.0-preview-6a6cdfa";
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 = '0.0.0-preview-3487136';
5
+ exports.version = '0.0.0-preview-6a6cdfa';
6
6
  //# sourceMappingURL=version.js.map
@@ -18,10 +18,11 @@ export interface GetMarketParams {
18
18
  /**
19
19
  * Get a specific market by its opaque marketId. Requests the single market
20
20
  * from the backend `/markets` route (filtered by `marketIds`) and returns the
21
- * first match; the backend responds 404 (thrown as a {@link PerpsError}) when
22
- * nothing matches.
21
+ * first match; throws a `MarketNotFound` {@link PerpsError} both when the
22
+ * backend responds 404 and when it responds 200 with an empty list, matching
23
+ * `MarketRegistry.require`'s miss behaviour.
23
24
  *
24
- * @throws {PerpsError} On backend (e.g. 404), network, or parsing errors.
25
+ * @throws {PerpsError} On backend (e.g. 404 or empty match), network, or parsing errors.
25
26
  * @example
26
27
  * ```ts
27
28
  * const client = createPerpsClient({ integrator: 'my-app' })
@@ -1 +1 @@
1
- {"version":3,"file":"getMarket.d.ts","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAA;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAYjB"}
1
+ {"version":3,"file":"getMarket.d.ts","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAA;AAIhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
@@ -1,11 +1,14 @@
1
+ import { PerpsErrorCode } from '@lifi/perps-types';
2
+ import { PerpsError } from '../errors/PerpsError.js';
1
3
  import { buildUrl, request } from '../transport/request.js';
2
4
  /**
3
5
  * Get a specific market by its opaque marketId. Requests the single market
4
6
  * from the backend `/markets` route (filtered by `marketIds`) and returns the
5
- * first match; the backend responds 404 (thrown as a {@link PerpsError}) when
6
- * nothing matches.
7
+ * first match; throws a `MarketNotFound` {@link PerpsError} both when the
8
+ * backend responds 404 and when it responds 200 with an empty list, matching
9
+ * `MarketRegistry.require`'s miss behaviour.
7
10
  *
8
- * @throws {PerpsError} On backend (e.g. 404), network, or parsing errors.
11
+ * @throws {PerpsError} On backend (e.g. 404 or empty match), network, or parsing errors.
9
12
  * @example
10
13
  * ```ts
11
14
  * const client = createPerpsClient({ integrator: 'my-app' })
@@ -20,6 +23,12 @@ export async function getMarket(client, params, options) {
20
23
  marketIds: params.marketId,
21
24
  });
22
25
  const { markets } = await request(client.config, url, {}, options);
23
- return markets[0];
26
+ const market = markets[0];
27
+ if (market === undefined) {
28
+ const error = new PerpsError(PerpsErrorCode.MarketNotFound, `No ${params.provider} market found for marketId '${params.marketId}'`);
29
+ error.tool = params.provider;
30
+ throw error;
31
+ }
32
+ return market;
24
33
  }
25
34
  //# sourceMappingURL=getMarket.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getMarket.js","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAmB3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAsB,EACtB,MAAuB,EACvB,OAA2B;IAE3B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE;QACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,QAAQ;KAC3B,CAAC,CAAA;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAC/B,MAAM,CAAC,MAAM,EACb,GAAG,EACH,EAAE,EACF,OAAO,CACR,CAAA;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC"}
1
+ {"version":3,"file":"getMarket.js","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAmB3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAsB,EACtB,MAAuB,EACvB,OAA2B;IAE3B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE;QACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,QAAQ;KAC3B,CAAC,CAAA;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAC/B,MAAM,CAAC,MAAM,EACb,GAAG,EACH,EAAE,EACF,OAAO,CACR,CAAA;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACzB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,UAAU,CAC1B,cAAc,CAAC,cAAc,EAC7B,MAAM,MAAM,CAAC,QAAQ,+BAA+B,MAAM,CAAC,QAAQ,GAAG,CACvE,CAAA;QACD,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC5B,MAAM,KAAK,CAAA;IACb,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -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 = "0.0.0-preview-3487136";
2
+ export declare const version = "0.0.0-preview-6a6cdfa";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  export const name = '@lifi/perps-sdk';
2
- export const version = '0.0.0-preview-3487136';
2
+ export const version = '0.0.0-preview-6a6cdfa';
3
3
  //# sourceMappingURL=version.js.map
@@ -18,10 +18,11 @@ export interface GetMarketParams {
18
18
  /**
19
19
  * Get a specific market by its opaque marketId. Requests the single market
20
20
  * from the backend `/markets` route (filtered by `marketIds`) and returns the
21
- * first match; the backend responds 404 (thrown as a {@link PerpsError}) when
22
- * nothing matches.
21
+ * first match; throws a `MarketNotFound` {@link PerpsError} both when the
22
+ * backend responds 404 and when it responds 200 with an empty list, matching
23
+ * `MarketRegistry.require`'s miss behaviour.
23
24
  *
24
- * @throws {PerpsError} On backend (e.g. 404), network, or parsing errors.
25
+ * @throws {PerpsError} On backend (e.g. 404 or empty match), network, or parsing errors.
25
26
  * @example
26
27
  * ```ts
27
28
  * const client = createPerpsClient({ integrator: 'my-app' })
@@ -1 +1 @@
1
- {"version":3,"file":"getMarket.d.ts","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAA;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAYjB"}
1
+ {"version":3,"file":"getMarket.d.ts","sourceRoot":"","sources":["../../../src/services/getMarket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAA;AAIhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
@@ -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 = "0.0.0-preview-3487136";
2
+ export declare const version = "0.0.0-preview-6a6cdfa";
3
3
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/perps-sdk",
3
- "version": "0.0.0-preview-3487136",
3
+ "version": "0.0.0-preview-6a6cdfa",
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": "^0.0.0-preview-3487136"
47
+ "@lifi/perps-types": "^1.6.0"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"
@@ -1,4 +1,6 @@
1
1
  import type { Market, MarketsResponse } from '@lifi/perps-types'
2
+ import { PerpsErrorCode } from '@lifi/perps-types'
3
+ import { PerpsError } from '../errors/PerpsError.js'
2
4
  import { buildUrl, request } from '../transport/request.js'
3
5
  import type { SDKRequestOptions } from '../types/config.js'
4
6
  import type { PerpsSDKClient } from '../types/provider.js'
@@ -21,10 +23,11 @@ export interface GetMarketParams {
21
23
  /**
22
24
  * Get a specific market by its opaque marketId. Requests the single market
23
25
  * from the backend `/markets` route (filtered by `marketIds`) and returns the
24
- * first match; the backend responds 404 (thrown as a {@link PerpsError}) when
25
- * nothing matches.
26
+ * first match; throws a `MarketNotFound` {@link PerpsError} both when the
27
+ * backend responds 404 and when it responds 200 with an empty list, matching
28
+ * `MarketRegistry.require`'s miss behaviour.
26
29
  *
27
- * @throws {PerpsError} On backend (e.g. 404), network, or parsing errors.
30
+ * @throws {PerpsError} On backend (e.g. 404 or empty match), network, or parsing errors.
28
31
  * @example
29
32
  * ```ts
30
33
  * const client = createPerpsClient({ integrator: 'my-app' })
@@ -48,5 +51,14 @@ export async function getMarket(
48
51
  {},
49
52
  options
50
53
  )
51
- return markets[0]
54
+ const market = markets[0]
55
+ if (market === undefined) {
56
+ const error = new PerpsError(
57
+ PerpsErrorCode.MarketNotFound,
58
+ `No ${params.provider} market found for marketId '${params.marketId}'`
59
+ )
60
+ error.tool = params.provider
61
+ throw error
62
+ }
63
+ return market
52
64
  }
@@ -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 = '0.0.0-preview-3487136'
2
+ export const version = '0.0.0-preview-6a6cdfa'