@d8x/perpetuals-sdk 2.6.4 → 2.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/marketData.ts CHANGED
@@ -256,6 +256,7 @@ export default class MarketData extends PerpetualDataHandler {
256
256
  // open orders requested only for given symbol
257
257
  let resArray: Array<{ orders: Order[]; orderIds: string[] }> = [];
258
258
  let symbols: Array<string>;
259
+ await this.refreshSymbols();
259
260
  if (symbol) {
260
261
  symbols = symbol.split("-").length == 1 ? this.getPerpetualSymbolsInPool(symbol) : [symbol];
261
262
  } else {
@@ -365,6 +366,7 @@ export default class MarketData extends PerpetualDataHandler {
365
366
  if (this.proxyContract == null) {
366
367
  throw Error("no proxy contract initialized. Use createProxyInstance().");
367
368
  }
369
+ await this.refreshSymbols();
368
370
  let resArray: Array<MarginAccount> = [];
369
371
  let symbols: Array<string>;
370
372
  if (symbol) {
@@ -622,6 +624,7 @@ export default class MarketData extends PerpetualDataHandler {
622
624
  if (this.proxyContract == null || this.multicall == null) {
623
625
  throw Error("no proxy contract initialized. Use createProxyInstance().");
624
626
  }
627
+ await this.refreshSymbols();
625
628
  const isPredMkt = this.isPredictionMarket(order.symbol);
626
629
  // fetch prices
627
630
  if (indexPriceInfo == undefined) {
@@ -873,6 +876,7 @@ export default class MarketData extends PerpetualDataHandler {
873
876
  if (deltaCollateral + account.collateralCC + account.unrealizedFundingCollateralCCY < 0) {
874
877
  throw new Error("not enough margin to remove");
875
878
  }
879
+ await this.refreshSymbols();
876
880
  if (indexPriceInfo == undefined) {
877
881
  indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
878
882
  }
@@ -1032,6 +1036,7 @@ export default class MarketData extends PerpetualDataHandler {
1032
1036
  * main();
1033
1037
  */
1034
1038
  public async getWalletBalance(address: string, symbol: string, overrides?: Overrides): Promise<number> {
1039
+ await this.refreshSymbols();
1035
1040
  let poolIdx = this.getPoolStaticInfoIndexFromSymbol(symbol);
1036
1041
  let settleTokenAddr = this.poolStaticInfos[poolIdx].poolSettleTokenAddr;
1037
1042
  let token = ERC20__factory.connect(settleTokenAddr, this.provider!);
@@ -1198,6 +1203,7 @@ export default class MarketData extends PerpetualDataHandler {
1198
1203
  throw new Error("proxy contract not initialized");
1199
1204
  }
1200
1205
  if (this.isPredictionMarket(symbol)) {
1206
+ await this.refreshSymbols();
1201
1207
  // prediction markets: also works for closing positions
1202
1208
  return this.pmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
1203
1209
  }
@@ -1462,6 +1468,7 @@ export default class MarketData extends PerpetualDataHandler {
1462
1468
  * main();
1463
1469
  */
1464
1470
  public async maxSignedPosition(side: string, symbol: string, overrides?: Overrides): Promise<number> {
1471
+ await this.refreshSymbols();
1465
1472
  let perpId = this.getPerpIdFromSymbol(symbol);
1466
1473
  let isBuy = side == BUY_SIDE;
1467
1474
  let maxSignedPos = await this.proxyContract!.getMaxSignedOpenTradeSizeForPos(perpId, 0n, isBuy, overrides || {});
@@ -1522,6 +1529,7 @@ export default class MarketData extends PerpetualDataHandler {
1522
1529
  if (!this.proxyContract) {
1523
1530
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1524
1531
  }
1532
+ await this.refreshSymbols();
1525
1533
  const orderBookContract = this.getOrderBookContract(symbol);
1526
1534
  const status = Number(await orderBookContract.getOrderStatus(orderId, overrides || {})) as OrderStatus;
1527
1535
  return status;
@@ -1551,6 +1559,7 @@ export default class MarketData extends PerpetualDataHandler {
1551
1559
  if (!this.proxyContract || !this.multicall) {
1552
1560
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1553
1561
  }
1562
+ await this.refreshSymbols();
1554
1563
  const orderBookContract = this.getOrderBookContract(symbol);
1555
1564
 
1556
1565
  const statusCalls: Multicall3.Call3Struct[] = orderId.map((id) => ({
@@ -1591,6 +1600,7 @@ export default class MarketData extends PerpetualDataHandler {
1591
1600
  if (this.proxyContract == null) {
1592
1601
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1593
1602
  }
1603
+ await this.refreshSymbols();
1594
1604
  if (indexPrices == undefined) {
1595
1605
  indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1596
1606
  }
@@ -1633,6 +1643,7 @@ export default class MarketData extends PerpetualDataHandler {
1633
1643
  if (this.proxyContract == null) {
1634
1644
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1635
1645
  }
1646
+ await this.refreshSymbols();
1636
1647
  if (priceInfo == undefined) {
1637
1648
  // fetch from API
1638
1649
  priceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
@@ -1662,6 +1673,7 @@ export default class MarketData extends PerpetualDataHandler {
1662
1673
  if (this.proxyContract == null || this.multicall == null) {
1663
1674
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1664
1675
  }
1676
+ await this.refreshSymbols();
1665
1677
  if (indexPriceInfo == undefined) {
1666
1678
  indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1667
1679
  }
@@ -1759,6 +1771,7 @@ export default class MarketData extends PerpetualDataHandler {
1759
1771
  if (this.proxyContract == null) {
1760
1772
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1761
1773
  }
1774
+ await this.refreshSymbols();
1762
1775
  return await this.getPerpetualPrice(symbol, 0);
1763
1776
  }
1764
1777
 
@@ -1922,7 +1935,7 @@ export default class MarketData extends PerpetualDataHandler {
1922
1935
  if (!this.proxyContract) {
1923
1936
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1924
1937
  }
1925
-
1938
+ await this.refreshSymbols();
1926
1939
  if (indexPrices == undefined) {
1927
1940
  // fetch from API
1928
1941
  indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
@@ -1998,16 +2011,19 @@ export default class MarketData extends PerpetualDataHandler {
1998
2011
  */
1999
2012
  private static async _getAllActivePerpIndexPrices(
2000
2013
  _symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>,
2001
- _priceFeedGetter: PriceFeeds
2014
+ _priceFeedGetter: PriceFeeds,
2015
+ _symbolList: Map<string, string>
2002
2016
  ): Promise<Map<string, [number, boolean]>> {
2003
2017
  // get all prices from off-chain price-sources
2004
2018
  let allSym = new Set<string>();
2005
2019
  for (let perpSymbol of _symbolToPerpStaticInfo.keys()) {
2006
2020
  let sInfo: PerpetualStaticInfo | undefined = _symbolToPerpStaticInfo.get(perpSymbol);
2007
- if (sInfo?.state == "INVALID" || sInfo?.state == "INITIALIZING") {
2021
+ if (!sInfo || sInfo?.state == "INVALID" || sInfo?.state == "INITIALIZING") {
2008
2022
  continue;
2009
2023
  }
2010
- allSym.add(sInfo!.S2Symbol);
2024
+
2025
+ allSym.add(MarketData.getIndexSymbol(_symbolList, sInfo));
2026
+
2011
2027
  if (sInfo!.S3Symbol != "") {
2012
2028
  allSym.add(sInfo!.S3Symbol);
2013
2029
  }
@@ -2039,6 +2055,7 @@ export default class MarketData extends PerpetualDataHandler {
2039
2055
  if (this.proxyContract == null) {
2040
2056
  throw Error("no proxy contract initialized. Use createProxyInstance().");
2041
2057
  }
2058
+ await this.refreshSymbols();
2042
2059
  return await MarketData._isMarketClosed(symbol, this.symbolToPerpStaticInfo, this.priceFeedGetter);
2043
2060
  }
2044
2061
 
@@ -2088,6 +2105,7 @@ export default class MarketData extends PerpetualDataHandler {
2088
2105
  _symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>,
2089
2106
  _perpetualIdToSymbol: Map<number, string>,
2090
2107
  _idxPriceMap: Map<string, [number, boolean]>,
2108
+ _symbolList: Map<string, string>,
2091
2109
  overrides?: Overrides
2092
2110
  ): Promise<Map<string, number>> {
2093
2111
  // what is the maximal number of queries at once?
@@ -2112,11 +2130,11 @@ export default class MarketData extends PerpetualDataHandler {
2112
2130
  }
2113
2131
  let symbol3s = _perpetualIdToSymbol.get(id);
2114
2132
  let info = _symbolToPerpStaticInfo.get(symbol3s!);
2115
- if (info?.state == "INVALID" || info?.state == "INITIALIZING") {
2133
+ if (!info || info?.state == "INVALID" || info?.state == "INITIALIZING") {
2116
2134
  continue;
2117
2135
  }
2118
2136
  collectedIds.push(id);
2119
- let S2 = floatToABK64x64(_idxPriceMap.get(info!.S2Symbol)![0]);
2137
+ let S2 = floatToABK64x64(_idxPriceMap.get(MarketData.getIndexSymbol(_symbolList, info))![0]);
2120
2138
  let S3 = 0n;
2121
2139
  if (info!.S3Symbol != "") {
2122
2140
  S3 = floatToABK64x64(_idxPriceMap.get(info!.S3Symbol)![0]);
@@ -2136,10 +2154,8 @@ export default class MarketData extends PerpetualDataHandler {
2136
2154
  const encodedResults = await _multicall.aggregate3.staticCall(proxyCalls, overrides || {});
2137
2155
  // apply results
2138
2156
  for (let k = 0; k < collectedPerpIds.length; k++) {
2139
- let fMidPrice = _proxyContract.interface.decodeFunctionResult(
2140
- "queryMidPrices",
2141
- encodedResults[k].returnData
2142
- )[0] as bigint[];
2157
+ const result = _proxyContract.interface.decodeFunctionResult("queryMidPrices", encodedResults[k].returnData);
2158
+ let fMidPrice = result[0] as bigint[];
2143
2159
  for (let j = 0; j < fMidPrice.length; j++) {
2144
2160
  let id = collectedPerpIds[k][j];
2145
2161
  let symbol3s = _perpetualIdToSymbol.get(id);
@@ -2298,7 +2314,6 @@ export default class MarketData extends PerpetualDataHandler {
2298
2314
  }
2299
2315
  return perpStates;
2300
2316
  }
2301
-
2302
2317
  /**
2303
2318
  * Fetch on-chain exchange info
2304
2319
  * @param _proxyContract
@@ -2333,9 +2348,11 @@ export default class MarketData extends PerpetualDataHandler {
2333
2348
  };
2334
2349
 
2335
2350
  // get all prices from off-chain price-sources: no RPC calls
2336
- console.log("1");
2337
- let idxPriceMap = await MarketData._getAllActivePerpIndexPrices(_symbolToPerpStaticInfo, _priceFeedGetter);
2338
- console.log({ idxPriceMap });
2351
+ let idxPriceMap = await MarketData._getAllActivePerpIndexPrices(
2352
+ _symbolToPerpStaticInfo,
2353
+ _priceFeedGetter,
2354
+ _symbolList
2355
+ );
2339
2356
 
2340
2357
  // query mid-prices from on-chain conditional on the off-chain prices
2341
2358
  let midPriceMap: Map<string, number> = await MarketData._queryMidPrices(
@@ -2346,9 +2363,9 @@ export default class MarketData extends PerpetualDataHandler {
2346
2363
  _symbolToPerpStaticInfo,
2347
2364
  _perpetualIdToSymbol,
2348
2365
  idxPriceMap,
2366
+ _symbolList,
2349
2367
  overrides
2350
2368
  );
2351
- console.log({ midPriceMap });
2352
2369
  const { pools: poolStateInfos, perpetuals: perpStateInfos } = await MarketData._queryPoolAndPerpetualStates(
2353
2370
  _proxyContract,
2354
2371
  _multicall,
@@ -2361,10 +2378,10 @@ export default class MarketData extends PerpetualDataHandler {
2361
2378
  for (const perp of perpStateInfos) {
2362
2379
  let symbol3s = _perpetualIdToSymbol.get(perp.id);
2363
2380
  let info = _symbolToPerpStaticInfo.get(symbol3s!);
2364
- if (info?.state == "INVALID" || info?.state == "INITIALIZING") {
2381
+ if (!info || info?.state == "INVALID" || info?.state == "INITIALIZING") {
2365
2382
  perp.isMarketClosed = true;
2366
2383
  } else {
2367
- const idxPriceS2Pair = idxPriceMap.get(info!.S2Symbol);
2384
+ const idxPriceS2Pair = idxPriceMap.get(MarketData.getIndexSymbol(_symbolList, info));
2368
2385
  let idxPriceS3Pair: [number, boolean] = [0, false];
2369
2386
  perp.isMarketClosed = idxPriceS2Pair![1];
2370
2387
  if (info!.S3Symbol != "") {
@@ -2394,7 +2411,7 @@ export default class MarketData extends PerpetualDataHandler {
2394
2411
  perp.midPrice = midPriceMap.get(symbol3s!)!;
2395
2412
  }
2396
2413
  // which pool?
2397
- const poolId = info!.poolId;
2414
+ const poolId = info?.poolId ?? 1;
2398
2415
  poolStateInfos[poolId - 1].perpetuals.push(perp);
2399
2416
  }
2400
2417
  info.pools = poolStateInfos;
@@ -1,4 +1,4 @@
1
- import { BigNumberish, BytesLike, ContractTransaction, ContractTransactionResponse, Interface } from "ethers";
1
+ import { BigNumberish, BytesLike, ContractTransactionResponse, Interface } from "ethers";
2
2
  import { CollaterlCCY } from "./constants";
3
3
 
4
4
  export interface NodeSDKConfig {
@@ -584,3 +584,12 @@ export interface PythMetadata {
584
584
  schedule?: string; // "America/New_York;0930-1600,0930-1600,0930-1600,0930-1600,0930-1600,C,C;0418/C,0526/C,0619/C,0703/0930-1300,0704/C"
585
585
  };
586
586
  }
587
+
588
+ export interface SlotInfo {
589
+ contract_id: string; // "NHL_EDM_NYI_251016",
590
+ yymmdd: string; //"251016",
591
+ expiry: string; // "2025-10-17T06:59:59Z",
592
+ chain_id: number; //84532,
593
+ pool_sym: string; // "PUSD",
594
+ slot: string; //"NHL0"
595
+ }
@@ -70,6 +70,7 @@ import {
70
70
  LiquidityPoolData,
71
71
  SettlementCcyItem,
72
72
  SettlementConfig,
73
+ SlotInfo,
73
74
  TokenOverride,
74
75
  TypeSafeOrder,
75
76
  type ClientOrder,
@@ -107,6 +108,7 @@ export default class PerpetualDataHandler {
107
108
  protected perpetualIdToSymbol: Map<number, string>; // maps unique perpetual id to symbol of the form BTC-USD-MATIC
108
109
  protected poolStaticInfos: Array<PoolStaticInfo>;
109
110
  protected symbolList: Map<string, string>; //mapping 4-digit symbol <-> long format
111
+ protected indexSymbol: Map<string, { indexSymbol: string; expiry: number }> = new Map(); //mapping perpetual symbol to index symbol (NFL_TOR_...-USD-PUSD => NFL0-USD:84532)
110
112
  protected settlementConfig: SettlementConfig;
111
113
  public requiredSymbols: string[] = []; // array of symbols in the current perpetual deployment
112
114
  // config
@@ -225,6 +227,7 @@ export default class PerpetualDataHandler {
225
227
  if (this.proxyContract == null) {
226
228
  throw new Error("proxy not defined");
227
229
  }
230
+ await this.refreshSymbols();
228
231
  return await PerpetualDataHandler._getPerpetuals(ids, this.proxyContract, this.symbolList, overrides);
229
232
  }
230
233
 
@@ -239,6 +242,7 @@ export default class PerpetualDataHandler {
239
242
  if (this.proxyContract == null) {
240
243
  throw new Error("proxy not defined");
241
244
  }
245
+ await this.refreshSymbols();
242
246
  return await PerpetualDataHandler._getLiquidityPools(
243
247
  fromIdx,
244
248
  toIdx,
@@ -262,6 +266,11 @@ export default class PerpetualDataHandler {
262
266
  throw new Error("proxy or multicall not defined");
263
267
  }
264
268
  const tokenOverrides = require("./config/tokenOverrides.json") as TokenOverride[];
269
+
270
+ //reset
271
+ this.poolStaticInfos = [];
272
+ this.symbolToPerpStaticInfo = new Map();
273
+
265
274
  let poolInfo = await PerpetualDataHandler.getPoolStaticInfo(this.proxyContract, overrides);
266
275
  this.nestedPerpetualIDs = poolInfo.nestedPerpetualIDs;
267
276
 
@@ -322,10 +331,12 @@ export default class PerpetualDataHandler {
322
331
  encodedResults[encodedResults.length - 1].returnData
323
332
  )[0] as string;
324
333
 
334
+ // this one updates symbollist and indexsymbol maps inplace if needed
325
335
  let perpStaticInfos = await PerpetualDataHandler.getPerpetualStaticInfo(
326
336
  this.proxyContract,
327
337
  this.nestedPerpetualIDs,
328
338
  this.symbolList,
339
+ this.indexSymbol,
329
340
  overrides
330
341
  );
331
342
 
@@ -338,10 +349,13 @@ export default class PerpetualDataHandler {
338
349
  if (perp.state != "INVALID" && perp.state != "INITIALIZING") {
339
350
  // we only require price feeds to be available if the perpetual
340
351
  // is in normal state
341
- requiredPairs.add(perp.S2Symbol);
352
+ requiredPairs.add(PerpetualDataHandler.getIndexSymbol(this.symbolList, perp));
353
+
342
354
  if (perp.S3Symbol != "") {
343
355
  requiredPairs.add(perp.S3Symbol);
344
356
  }
357
+ } else {
358
+ continue;
345
359
  }
346
360
  let poolCCY = this.poolStaticInfos[perp.poolId - 1].poolMarginSymbol;
347
361
  if (poolCCY == "") {
@@ -522,6 +536,7 @@ export default class PerpetualDataHandler {
522
536
  symbol: string
523
537
  ): Promise<{ submission: PriceFeedSubmission; pxS2S3: [number, number] }> {
524
538
  // fetch prices from required price-feeds (REST)
539
+ await this.refreshSymbols();
525
540
  return await this.priceFeedGetter.fetchFeedPriceInfoAndIndicesForPerpetual(symbol);
526
541
  }
527
542
 
@@ -532,21 +547,12 @@ export default class PerpetualDataHandler {
532
547
  */
533
548
  public getIndexSymbols(symbol: string): [string, string] {
534
549
  // get index
535
- console.log(symbol, this.symbolToPerpStaticInfo);
536
550
  let staticInfo = this.symbolToPerpStaticInfo.get(symbol);
537
551
  if (staticInfo == undefined) {
538
552
  throw new Error(`No static info for perpetual with symbol ${symbol}`);
539
553
  }
540
- const quoteCcy = staticInfo.S2Symbol.split("-")[1];
541
554
  return this.isPredictionMarket(symbol)
542
- ? [
543
- PerpetualDataHandler._getBySingleValue(this.symbolList, staticInfo.S2Symbol) +
544
- "-" +
545
- quoteCcy +
546
- ":" +
547
- Number(this.chainId),
548
- staticInfo.S3Symbol,
549
- ]
555
+ ? [PerpetualDataHandler.getIndexSymbol(this.symbolList, staticInfo), staticInfo.S3Symbol]
550
556
  : [staticInfo.S2Symbol, staticInfo.S3Symbol];
551
557
  }
552
558
 
@@ -558,6 +564,7 @@ export default class PerpetualDataHandler {
558
564
  * and corresponding price information
559
565
  */
560
566
  public async fetchLatestFeedPriceInfo(symbol: string): Promise<PriceFeedSubmission> {
567
+ await this.refreshSymbols();
561
568
  return await this.priceFeedGetter.fetchLatestFeedPriceInfoForPerpetual(symbol);
562
569
  }
563
570
 
@@ -570,6 +577,7 @@ export default class PerpetualDataHandler {
570
577
  * @param symbol either perpetual symbol of the form BTC-USD-MATIC or just collateral token
571
578
  */
572
579
  public async fetchCollateralToSettlementConversion(symbol: string): Promise<number> {
580
+ await this.refreshSymbols();
573
581
  let j = this.getPoolStaticInfoIndexFromSymbol(symbol);
574
582
  if (this.poolStaticInfos[j].poolMarginSymbol == this.poolStaticInfos[j].poolSettleSymbol) {
575
583
  // settlement currency = collateral currency
@@ -657,9 +665,8 @@ export default class PerpetualDataHandler {
657
665
  * @param short List of short perp symbols (<=4 chars)
658
666
  * @returns List of long perp symbols
659
667
  */
660
- protected static async fetchSymbolList(chainId: bigint | number | string, short: string[]) {
661
- const endpoint = `https://sports.quantena.org/long-symbol/${Number(chainId)}?short[]=`; //BTC&short[]=GBP
662
- const query = endpoint + short.join("&short[]=");
668
+ protected static async fetchSymbolList(chainId: bigint | number | string) {
669
+ const query = `https://sports.quantena.org/slots-info/${Number(chainId)}`;
663
670
  const res = await fetch(query);
664
671
  if (res.status !== 200) {
665
672
  throw new Error(`failed to fetch symbolList status code: ${res.status}, ${query}`);
@@ -667,10 +674,10 @@ export default class PerpetualDataHandler {
667
674
  if (!res.ok) {
668
675
  throw new Error(`failed to fetch config (${res.status}): ${res.statusText} ${query}`);
669
676
  }
670
- let t = (await res.json()) as Record<string, string>;
671
- let symbolList = new Map<string, string>();
672
- for (const s of short) {
673
- symbolList.set(s, t[s] && t[s] !== "UNKNOWN" ? t[s] : s);
677
+ let infos = (await res.json()) as SlotInfo[];
678
+ let symbolList = new Map<string, { symbol: string; expiry: number }>();
679
+ for (const s of infos) {
680
+ symbolList.set(s.slot, { symbol: s.contract_id, expiry: new Date(s.expiry).getTime() });
674
681
  }
675
682
  return symbolList;
676
683
  }
@@ -685,6 +692,7 @@ export default class PerpetualDataHandler {
685
692
  _proxyContract: IPerpetualManager,
686
693
  nestedPerpetualIDs: Array<Array<number>>,
687
694
  symbolList: Map<string, string>,
695
+ indexSymbol: Map<string, { indexSymbol: string; expiry: number }>,
688
696
  overrides?: Overrides
689
697
  ): Promise<Array<PerpetualStaticInfo>> {
690
698
  // flatten perpetual ids into chunks
@@ -699,11 +707,16 @@ export default class PerpetualDataHandler {
699
707
  // get normalized symbols
700
708
  if (overrides?.chainId !== undefined) {
701
709
  const shorts = [...new Set(perpInfos.map((p) => fromBytes4HexString(p.S2BaseCCY)))];
702
- const sList = await this.fetchSymbolList(BigInt(overrides.chainId!), shorts);
710
+ const sList = await this.fetchSymbolList(BigInt(overrides.chainId!));
703
711
  // modify inplace
704
712
  for (const s of shorts) {
705
713
  if (sList.has(s)) {
706
- symbolList.set(s, sList.get(s)!);
714
+ const slotInfo = sList.get(s)!;
715
+ symbolList.set(s, slotInfo.symbol);
716
+ indexSymbol.set(slotInfo.symbol, {
717
+ indexSymbol: s + ":" + BigInt(overrides.chainId!),
718
+ expiry: slotInfo.expiry,
719
+ });
707
720
  }
708
721
  }
709
722
  }
@@ -997,6 +1010,7 @@ export default class PerpetualDataHandler {
997
1010
  if (this.proxyContract == null) {
998
1011
  throw Error("no proxy contract initialized. Use createProxyInstance().");
999
1012
  }
1013
+ await this.refreshSymbols();
1000
1014
  const isPred = this.isPredictionMarket(symbol);
1001
1015
  return PerpetualDataHandler.getMarginAccount(
1002
1016
  traderAddr,
@@ -1069,6 +1083,7 @@ export default class PerpetualDataHandler {
1069
1083
  */
1070
1084
  public async getAllOpenOrders(symbol: string, overrides?: Overrides): Promise<[Order[], string[], string[]]> {
1071
1085
  const MAX_ORDERS_POLLED = 500;
1086
+ await this.refreshSymbols();
1072
1087
  let totalOrders = await this.numberOfOpenOrders(symbol, overrides);
1073
1088
  let orderBundles: [Order[], string[], string[]] = [[], [], []];
1074
1089
  let moreOrders = orderBundles[1].length < totalOrders;
@@ -1120,6 +1135,7 @@ export default class PerpetualDataHandler {
1120
1135
  if (overrides) {
1121
1136
  ({ rpcURL, ...overrides } = overrides);
1122
1137
  }
1138
+ await this.refreshSymbols();
1123
1139
  const provider = new JsonRpcProvider(rpcURL ?? this.nodeURL, this.network, {});
1124
1140
  const orderBookSC = this.getOrderBookContract(symbol).connect(provider);
1125
1141
  let numOrders = await orderBookSC.orderCount(overrides || {});
@@ -1162,6 +1178,7 @@ export default class PerpetualDataHandler {
1162
1178
  if (overrides) {
1163
1179
  ({ rpcURL, ...overrides } = overrides);
1164
1180
  }
1181
+ await this.refreshSymbols();
1165
1182
  const provider = new JsonRpcProvider(rpcURL ?? this.nodeURL, this.network, { staticNetwork: true });
1166
1183
  const orderBookSC = this.getOrderBookContract(symbol).connect(provider) as LimitOrderBook;
1167
1184
  const multicall = Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, provider);
@@ -1522,7 +1539,7 @@ export default class PerpetualDataHandler {
1522
1539
  return undefined;
1523
1540
  }
1524
1541
 
1525
- private static _getBySingleValue(map: Map<string, string>, searchValue: string) {
1542
+ protected static _getBySingleValue(map: Map<string, string>, searchValue: string) {
1526
1543
  for (let [key, value] of map.entries()) {
1527
1544
  if (searchValue.startsWith(value)) {
1528
1545
  return key;
@@ -2303,4 +2320,44 @@ export default class PerpetualDataHandler {
2303
2320
  return 1;
2304
2321
  }
2305
2322
  }
2323
+
2324
+ /**
2325
+ * Static function to get index symbol from perp static info
2326
+ * @param _symbolList Mapping from long symbol (e.g. NHL_TOR_DAL_251015) to price-feed API symbol (NHL0-USD:84532)
2327
+ * @param info Perpetual static info
2328
+ * @returns Index symbol
2329
+ */
2330
+ public static getIndexSymbol(_symbolList: Map<string, string>, info: PerpetualStaticInfo) {
2331
+ return PerpetualDataHandler.isPredictionMarketStatic(info!)
2332
+ ? PerpetualDataHandler._getBySingleValue(_symbolList, info.S2Symbol)! +
2333
+ "-" +
2334
+ info!.S2Symbol.split("-")[1] +
2335
+ ":84532"
2336
+ : info!.S2Symbol;
2337
+ }
2338
+
2339
+ /**
2340
+ * Short symbol corresponding to a given long symbol.
2341
+ * @param symbol Long symbol (e.g. NHL_TOR_DAL_251015)
2342
+ * @returns Short symbol (e.g. NHL0)
2343
+ */
2344
+ public async getShortSymbol(symbol: string): Promise<string> {
2345
+ await this.refreshSymbols();
2346
+ if (!this.symbolToPerpStaticInfo.has(symbol)) {
2347
+ throw Error(`Symbol ${symbol} not found`);
2348
+ }
2349
+ const indexSymbol = PerpetualDataHandler.getIndexSymbol(this.symbolList, this.symbolToPerpStaticInfo.get(symbol)!);
2350
+ return indexSymbol.split("-")[0];
2351
+ }
2352
+
2353
+ /**
2354
+ * Refreshes symbol mappings if at least one prediction market is expired
2355
+ */
2356
+ public async refreshSymbols(): Promise<void> {
2357
+ const infos = [...this.indexSymbol.values()];
2358
+ if (!infos || infos.some(({ expiry }) => expiry < Date.now())) {
2359
+ // refresh
2360
+ await this._fillSymbolMaps({ chainId: this.chainId });
2361
+ }
2362
+ }
2306
2363
  }
@@ -1,11 +1,10 @@
1
1
  import { Contract, ContractTransactionResponse, Overrides, Signer } from "ethers";
2
- import { MASK_PREDICTION_MARKET, ZERO_ORDER_ID } from "./constants";
3
- import { ABK64x64ToFloat, floatToDec18, floatToDecN, priceToProb, probToPrice } from "./d8XMath";
2
+ import { ZERO_ORDER_ID } from "./constants";
3
+ import { ABK64x64ToFloat, floatToDec18, floatToDecN } from "./d8XMath";
4
4
  import MarketData from "./marketData";
5
5
  import type { ClientOrder, NodeSDKConfig, Order, SmartContractOrder } from "./nodeSDKTypes";
6
6
  import PerpetualDataHandler from "./perpetualDataHandler";
7
7
  import TraderDigests from "./traderDigests";
8
- import { containsFlag } from "./utils";
9
8
  /**
10
9
  * Interface that can be used by front-end that wraps all private functions
11
10
  * so that signatures can be handled in frontend via wallet
@@ -127,6 +126,7 @@ export default class TraderInterface extends MarketData {
127
126
  if (this.proxyContract == null) {
128
127
  throw Error("no proxy contract initialized. Use createProxyInstance().");
129
128
  }
129
+ await this.refreshSymbols();
130
130
  let orderBookContract = this.getOrderBookContract(symbol);
131
131
  let scOrder: SmartContractOrder = await orderBookContract.orderOfDigest(orderId, overrides || {});
132
132
  let digest = this.digestTool.createDigest(scOrder, this.chainId, false, this.proxyAddr);
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const D8X_SDK_VERSION = "2.6.4";
1
+ export const D8X_SDK_VERSION = "2.6.6";