@d8x/perpetuals-sdk 0.0.44 → 0.0.46

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.
Files changed (41) hide show
  1. package/README.md +12 -0
  2. package/abi/MockTokenSwap.json +186 -0
  3. package/config/defaultConfig.json +36 -10
  4. package/config/mockSwap.json +4 -0
  5. package/config/oldConfig.json +2 -1
  6. package/config/priceFeedConfig.json +18 -0
  7. package/dist/accountTrade.d.ts +1 -0
  8. package/dist/accountTrade.js +31 -7
  9. package/dist/d8XMath.d.ts +6 -0
  10. package/dist/d8XMath.js +19 -1
  11. package/dist/liquidatorTool.d.ts +6 -4
  12. package/dist/liquidatorTool.js +13 -7
  13. package/dist/marketData.d.ts +6 -11
  14. package/dist/marketData.js +59 -41
  15. package/dist/nodeSDKTypes.d.ts +33 -2
  16. package/dist/nodeSDKTypes.js +3 -18
  17. package/dist/orderReferrerTool.d.ts +17 -7
  18. package/dist/orderReferrerTool.js +43 -13
  19. package/dist/perpetualDataHandler.d.ts +46 -6
  20. package/dist/perpetualDataHandler.js +143 -16
  21. package/dist/perpetualEventHandler.d.ts +0 -3
  22. package/dist/perpetualEventHandler.js +0 -3
  23. package/dist/priceFeeds.d.ts +115 -0
  24. package/dist/priceFeeds.js +373 -0
  25. package/dist/triangulator.d.ts +27 -0
  26. package/dist/triangulator.js +107 -0
  27. package/dist/version.d.ts +1 -1
  28. package/dist/version.js +1 -1
  29. package/package.json +3 -2
  30. package/src/accountTrade.ts +31 -8
  31. package/src/d8XMath.ts +47 -22
  32. package/src/index.ts +2 -0
  33. package/src/liquidatorTool.ts +28 -8
  34. package/src/marketData.ts +99 -61
  35. package/src/nodeSDKTypes.ts +30 -3
  36. package/src/orderReferrerTool.ts +56 -13
  37. package/src/perpetualDataHandler.ts +149 -21
  38. package/src/perpetualEventHandler.ts +0 -3
  39. package/src/priceFeeds.ts +371 -0
  40. package/src/triangulator.ts +105 -0
  41. package/src/version.ts +1 -1
package/src/d8XMath.ts CHANGED
@@ -28,6 +28,24 @@ export function ABK64x64ToFloat(x: BigNumber | number): number {
28
28
  return parseFloat(NumberStr) * s;
29
29
  }
30
30
 
31
+ /**
32
+ *
33
+ * @param {BigNumber} x BigNumber in Dec-N format
34
+ * @returns {number} x as a float (number)
35
+ */
36
+ export function decNToFloat(x: BigNumber, numDec: number) {
37
+ //x: BigNumber in DecN format to float
38
+ const DECIMALS = BigNumber.from(10).pow(BigNumber.from(numDec));
39
+ let s = x.lt(0) ? -1 : 1;
40
+ x = x.mul(s);
41
+ let xInt = x.div(DECIMALS);
42
+ let xDec = x.sub(xInt.mul(DECIMALS));
43
+ let k = numDec - xDec.toString().length;
44
+ let sPad = "0".repeat(k);
45
+ let NumberStr = xInt.toString() + "." + sPad + xDec.toString();
46
+ return parseFloat(NumberStr) * s;
47
+ }
48
+
31
49
  /**
32
50
  *
33
51
  * @param {BigNumber} x BigNumber in Dec18 format
@@ -275,26 +293,33 @@ export function getNewPositionLeverage(
275
293
  );
276
294
  }
277
295
 
278
- export function getMaxCollateralToRemove(
279
- currentPosition: number,
280
- currentLockedInValue: number,
281
- currentAvailableCash: number,
282
- markPrice: number,
283
- indexPriceS2: number,
284
- indexPriceS3: number,
285
- initialMarginRate: number
286
- ): number {
287
- return (
288
- getMarginRequiredForLeveragedTrade(
289
- 1 / initialMarginRate,
290
- currentPosition,
291
- currentLockedInValue,
292
- 0,
293
- markPrice,
294
- indexPriceS2,
295
- indexPriceS3,
296
- indexPriceS2,
297
- 0
298
- ) - currentAvailableCash
299
- );
296
+ /**
297
+ * Determine amount to be deposited into margin account so that the given leverage
298
+ * is obtained when trading a position pos (trade amount = position)
299
+ * Does NOT include fees
300
+ * Smart contract equivalent: calcMarginForTargetLeverage(..., _ignorePosBalance = false & balance = b0)
301
+ * @param {number} pos0 - current position
302
+ * @param {number} b0 - current balance
303
+ * @param {number} tradeAmnt - amount to trade
304
+ * @param {number} targetLvg - target leverage
305
+ * @param {number} price - price to trade amount 'tradeAmnt'
306
+ * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quote collateral, = index S3 if quanto)
307
+ * @param {number} S2Mark - mark price
308
+ * @returns {number} Amount to be deposited to have the given leverage when trading into position pos before fees
309
+ */
310
+ export function getDepositAmountForLvgTrade(
311
+ pos0: number,
312
+ b0: number,
313
+ tradeAmnt: number,
314
+ targetLvg: number,
315
+ price: number,
316
+ S3: number,
317
+ S2Mark: number
318
+ ) {
319
+ let pnl = (tradeAmnt * (S2Mark - price)) / S3;
320
+ if (targetLvg == 0) {
321
+ targetLvg = (Math.abs(pos0) * S2Mark) / S3 / b0;
322
+ }
323
+ let b = (Math.abs(pos0 + tradeAmnt) * S2Mark) / S3 / targetLvg;
324
+ return -(b0 + pnl - b);
300
325
  }
package/src/index.ts CHANGED
@@ -25,3 +25,5 @@ export {
25
25
  TraderInterface,
26
26
  PerpetualEventHandler,
27
27
  };
28
+
29
+ export * from "./version";
@@ -1,5 +1,5 @@
1
1
  import WriteAccessHandler from "./writeAccessHandler";
2
- import { NodeSDKConfig } from "./nodeSDKTypes";
2
+ import { NodeSDKConfig, PriceFeedSubmission } from "./nodeSDKTypes";
3
3
  import { ethers } from "ethers";
4
4
 
5
5
  /**
@@ -37,6 +37,7 @@ export default class LiquidatorTool extends WriteAccessHandler {
37
37
  * @param {string} symbol Symbol of the form ETH-USD-MATIC.
38
38
  * @param {string} traderAddr Address of the trader to be liquidated.
39
39
  * @param {string=} liquidatorAddr Address to be credited if the liquidation succeeds.
40
+ * @param {PriceFeedSubmission} priceFeedData optional. VAA and timestamps for oracle. If not provided will query from REST API.
40
41
  * Defaults to the wallet used to execute the liquidation.
41
42
  * @example
42
43
  * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
@@ -59,7 +60,8 @@ export default class LiquidatorTool extends WriteAccessHandler {
59
60
  public async liquidateTrader(
60
61
  symbol: string,
61
62
  traderAddr: string,
62
- liquidatorAddr: string = ""
63
+ liquidatorAddr: string = "",
64
+ priceFeedData?: PriceFeedSubmission
63
65
  ): Promise<ethers.ContractTransaction> {
64
66
  // this operation spends gas, so signer is required
65
67
  if (this.proxyContract == null || this.signer == null) {
@@ -70,7 +72,13 @@ export default class LiquidatorTool extends WriteAccessHandler {
70
72
  liquidatorAddr = this.traderAddr;
71
73
  }
72
74
  let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
73
- return await this._liquidateByAMM(perpID, liquidatorAddr, traderAddr, this.gasLimit);
75
+ if (priceFeedData == undefined) {
76
+ priceFeedData = await this.fetchLatestFeedPriceInfo(symbol);
77
+ }
78
+ return await this._liquidateByAMM(perpID, liquidatorAddr, traderAddr, priceFeedData, {
79
+ gasLimit: this.gasLimit,
80
+ value: this.PRICE_UPDATE_FEE_GWEI * priceFeedData.priceFeedVaas.length,
81
+ });
74
82
  }
75
83
 
76
84
  /**
@@ -116,13 +124,25 @@ export default class LiquidatorTool extends WriteAccessHandler {
116
124
  * @param perpetualId Perpetual id.
117
125
  * @param liquidatorAddr Address to be credited for the liquidation.
118
126
  * @param traderAddr Address of the trader to be liquidated.
119
- * @param gasLimit Gas limit.
127
+ * @param priceFeedData contains VAA and timestamps required
128
+ * @param options E.g., Gas limit, fee.
120
129
  * @ignore
121
130
  */
122
- public async _liquidateByAMM(perpetualId: number, liquidatorAddr: string, traderAddr: string, gasLimit: number) {
123
- return await this.proxyContract!.liquidateByAMM(perpetualId, liquidatorAddr, traderAddr, {
124
- gasLimit: gasLimit,
125
- });
131
+ public async _liquidateByAMM(
132
+ perpetualId: number,
133
+ liquidatorAddr: string,
134
+ traderAddr: string,
135
+ priceFeedData: PriceFeedSubmission,
136
+ options: object
137
+ ) {
138
+ return await this.proxyContract!.liquidateByAMM(
139
+ perpetualId,
140
+ liquidatorAddr,
141
+ traderAddr,
142
+ priceFeedData.priceFeedVaas,
143
+ priceFeedData.timestamps,
144
+ options
145
+ );
126
146
  }
127
147
 
128
148
  /**
package/src/marketData.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  calculateLiquidationPriceCollateralQuanto,
6
6
  calculateLiquidationPriceCollateralQuote,
7
7
  floatToABK64x64,
8
+ getDepositAmountForLvgTrade,
8
9
  getMarginRequiredForLeveragedTrade,
9
10
  getMaxSignedPositionSize,
10
11
  getNewPositionLeverage,
@@ -31,6 +32,7 @@ import {
31
32
  ZERO_ADDRESS,
32
33
  } from "./nodeSDKTypes";
33
34
  import PerpetualDataHandler from "./perpetualDataHandler";
35
+ import PriceFeeds from "./priceFeeds";
34
36
  import { contractSymbolToSymbol, toBytes4 } from "./utils";
35
37
 
36
38
  /**
@@ -144,7 +146,7 @@ export default class MarketData extends PerpetualDataHandler {
144
146
  if (this.proxyContract == null) {
145
147
  throw Error("no proxy contract initialized. Use createProxyInstance().");
146
148
  }
147
- return await MarketData._exchangeInfo(this.proxyContract, this.poolStaticInfos, this.symbolList);
149
+ return await MarketData._exchangeInfo(this.proxyContract, this.poolStaticInfos, this.symbolToPerpStaticInfo, this.symbolList, this.priceFeedGetter);
148
150
  }
149
151
 
150
152
  /**
@@ -297,13 +299,17 @@ export default class MarketData extends PerpetualDataHandler {
297
299
  currentPositionRisk: MarginAccount,
298
300
  symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>
299
301
  ): MarginAccount {
300
- let currentPosition = currentPositionRisk.positionNotionalBaseCCY;
301
- let newPosition = currentPositionRisk.positionNotionalBaseCCY + tradeAmount;
302
- let side = newPosition > 0 ? BUY_SIDE : newPosition < 0 ? SELL_SIDE : CLOSED_SIDE;
302
+ let currentSide = currentPositionRisk.side;
303
+ let currentPosition = (currentSide == BUY_SIDE ? 1 : -1) * currentPositionRisk.positionNotionalBaseCCY;
304
+ let newPosition = currentPosition + tradeAmount;
305
+ let newSide = newPosition > 0 ? BUY_SIDE : newPosition < 0 ? SELL_SIDE : CLOSED_SIDE;
303
306
  let lockedInValue = currentPositionRisk.entryPrice * currentPosition;
304
307
  if (tradeAmount == 0) {
305
308
  keepPositionLvg = false;
306
309
  }
310
+ let isOpen = newPosition != 0 && (tradeAmount == 0 || currentPosition == 0 || tradeAmount * currentPosition > 0);
311
+ let isFlip = Math.abs(tradeAmount) > Math.abs(currentPosition) && !isOpen;
312
+ let keepPositionLvgOnClose = keepPositionLvg && !isOpen;
307
313
  // need these for leverage/margin calculations
308
314
  let [markPrice, indexPriceS2, indexPriceS3] = [
309
315
  perpetualState.markPrice,
@@ -339,19 +345,26 @@ export default class MarketData extends PerpetualDataHandler {
339
345
  feeRate
340
346
  );
341
347
  } else if (tradeAmount != 0) {
342
- // the order has its own leverage and margin requirements
343
- let tradeCollateral = getMarginRequiredForLeveragedTrade(
344
- tradeLeverage,
345
- 0,
346
- 0,
347
- tradeAmount,
348
- markPrice,
349
- indexPriceS2,
350
- indexPriceS3,
351
- tradePrice,
352
- feeRate
353
- );
354
- newCollateral = currentPositionRisk.collateralCC + tradeCollateral;
348
+ let depositAtTradeTime: number;
349
+ if (!isOpen && !isFlip && !keepPositionLvgOnClose) {
350
+ // no deposit from trader's wallet, but there is realized pnl
351
+ depositAtTradeTime = tradeAmount * (tradePrice - currentPositionRisk.entryPrice);
352
+ } else {
353
+ // target lvg will default current lvg if not specified
354
+ let targetLvg = isFlip || isOpen ? tradeLeverage ?? 0 : 0;
355
+ let b0, pos0;
356
+ [b0, pos0] = isOpen ? [0, 0] : [currentPositionRisk.collateralCC, currentPosition];
357
+ depositAtTradeTime = getDepositAmountForLvgTrade(
358
+ b0,
359
+ pos0,
360
+ tradeAmount,
361
+ targetLvg,
362
+ tradePrice,
363
+ indexPriceS2,
364
+ markPrice
365
+ );
366
+ }
367
+ newCollateral = currentPositionRisk.collateralCC + depositAtTradeTime;
355
368
  // the new leverage corresponds to increasing the position and collateral according to the order
356
369
  newLeverage = getNewPositionLeverage(
357
370
  tradeAmount,
@@ -380,7 +393,7 @@ export default class MarketData extends PerpetualDataHandler {
380
393
  );
381
394
  }
382
395
  let newLockedInValue = lockedInValue + tradeAmount * tradePrice;
383
-
396
+ let entryPrice = newPosition == 0 ? 0 : Math.abs(newLockedInValue / newPosition);
384
397
  // liquidation vars
385
398
  let S2Liq: number, S3Liq: number | undefined;
386
399
  let tau = symbolToPerpStaticInfo.get(symbol)!.maintenanceMarginRate;
@@ -401,14 +414,15 @@ export default class MarketData extends PerpetualDataHandler {
401
414
  } else {
402
415
  S2Liq = calculateLiquidationPriceCollateralQuote(newLockedInValue, newPosition, newCollateral, tau);
403
416
  }
417
+
404
418
  let newPositionRisk: MarginAccount = {
405
419
  symbol: currentPositionRisk.symbol,
406
420
  positionNotionalBaseCCY: Math.abs(newPosition),
407
- side: side,
408
- entryPrice: newPosition == 0 ? 0 : Math.abs(newLockedInValue / newPosition),
421
+ side: newSide,
422
+ entryPrice: entryPrice,
409
423
  leverage: newLeverage,
410
424
  markPrice: markPrice,
411
- unrealizedPnlQuoteCCY: currentPositionRisk.unrealizedPnlQuoteCCY + tradeAmount * (markPrice - tradePrice),
425
+ unrealizedPnlQuoteCCY: newPosition * markPrice - newLockedInValue,
412
426
  unrealizedFundingCollateralCCY: currentPositionRisk.unrealizedFundingCollateralCCY,
413
427
  collateralCC: newCollateral,
414
428
  collToQuoteConversion: indexPriceS3,
@@ -418,25 +432,6 @@ export default class MarketData extends PerpetualDataHandler {
418
432
  return newPositionRisk;
419
433
  }
420
434
 
421
- /**
422
- * Gets the pool index (in exchangeInfo) corresponding to a given symbol.
423
- * @param symbol Symbol of the form ETH-USD-MATIC
424
- * @returns Pool index
425
- */
426
- public getPoolIndexFromSymbol(symbol: string): number {
427
- let pools = this.poolStaticInfos!;
428
- let poolId = this.getPoolIdFromSymbol(symbol);
429
- let k = 0;
430
- while (k < pools.length) {
431
- if (pools[k].poolId == poolId) {
432
- // pool found
433
- return k;
434
- }
435
- k++;
436
- }
437
- return -1;
438
- }
439
-
440
435
  /**
441
436
  * Gets the wallet balance in the collateral currency corresponding to a given perpetual symbol.
442
437
  * @param address Address to check
@@ -550,11 +545,15 @@ export default class MarketData extends PerpetualDataHandler {
550
545
  *
551
546
  * @returns mark price
552
547
  */
553
- public async getMarkPrice(symbol: string): Promise<number> {
548
+ public async getMarkPrice(symbol: string, indexPrices?: [number, number]): Promise<number> {
554
549
  if (this.proxyContract == null) {
555
550
  throw Error("no proxy contract initialized. Use createProxyInstance().");
556
551
  }
557
- return await PerpetualDataHandler._queryPerpetualMarkPrice(symbol, this.symbolToPerpStaticInfo, this.proxyContract);
552
+ if(indexPrices==undefined) {
553
+ let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
554
+ indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
555
+ }
556
+ return await PerpetualDataHandler._queryPerpetualMarkPrice(symbol, this.symbolToPerpStaticInfo, this.proxyContract, indexPrices);
558
557
  }
559
558
 
560
559
  /**
@@ -577,31 +576,43 @@ export default class MarketData extends PerpetualDataHandler {
577
576
  *
578
577
  * @returns price (number)
579
578
  */
580
- public async getPerpetualPrice(symbol: string, quantity: number): Promise<number> {
579
+ public async getPerpetualPrice(symbol: string, quantity: number, indexPrices?:[number, number]): Promise<number> {
581
580
  if (this.proxyContract == null) {
582
581
  throw Error("no proxy contract initialized. Use createProxyInstance().");
583
582
  }
583
+ if (indexPrices==undefined) {
584
+ // fetch from API
585
+ let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
586
+ indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
587
+ }
584
588
  return await PerpetualDataHandler._queryPerpetualPrice(
585
589
  symbol,
586
590
  quantity,
587
591
  this.symbolToPerpStaticInfo,
588
- this.proxyContract
592
+ this.proxyContract,
593
+ indexPrices
589
594
  );
590
595
  }
591
596
 
592
597
  /**
593
598
  * Query recent perpetual state from blockchain
594
599
  * @param symbol symbol of the form ETH-USD-MATIC
600
+ * @param indexPrices S2 and S3 prices/isMarketOpen if not provided fetch via REST API
595
601
  * @returns PerpetualState reference
596
602
  */
597
- public async getPerpetualState(symbol: string): Promise<PerpetualState> {
603
+ public async getPerpetualState(symbol: string, indexPriceInfo?: [number, number, boolean, boolean]): Promise<PerpetualState> {
598
604
  if (this.proxyContract == null) {
599
605
  throw Error("no proxy contract initialized. Use createProxyInstance().");
600
606
  }
607
+ if (indexPriceInfo==undefined) {
608
+ let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
609
+ indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
610
+ }
601
611
  let state: PerpetualState = await PerpetualDataHandler._queryPerpetualState(
602
612
  symbol,
603
613
  this.symbolToPerpStaticInfo,
604
- this.proxyContract
614
+ this.proxyContract,
615
+ indexPriceInfo
605
616
  );
606
617
  return state;
607
618
  }
@@ -627,6 +638,7 @@ export default class MarketData extends PerpetualDataHandler {
627
638
  S2Symbol: perpInfo.S2Symbol,
628
639
  S3Symbol: perpInfo.S3Symbol,
629
640
  lotSizeBC: perpInfo.lotSizeBC,
641
+ priceIds: perpInfo.priceIds,
630
642
  };
631
643
  return res;
632
644
  }
@@ -713,24 +725,30 @@ export default class MarketData extends PerpetualDataHandler {
713
725
  return balanceCC - initalMarginCC;
714
726
  }
715
727
 
716
- public async getPythIds(symbol: string): Promise<string[]> {
717
- if (this.proxyContract == null) {
718
- throw Error("no proxy contract initialized. Use createProxyInstance().");
719
- }
720
- let perpId = this.getPerpIdFromSymbol(symbol);
721
- let idsB32 = await this.proxyContract.getPythIds(perpId);
722
- return idsB32.apply((id: string) => ethers.utils.parseBytes32String(id));
723
- }
724
-
725
728
  public static async _exchangeInfo(
726
729
  _proxyContract: ethers.Contract,
727
730
  _poolStaticInfos: Array<PoolStaticInfo>,
728
- _symbolList: Map<string, string>
731
+ _symbolToPerpStaticInfo : Map<string, PerpetualStaticInfo>,
732
+ _symbolList: Map<string, string>,
733
+ _priceFeedGetter: PriceFeeds
729
734
  ): Promise<ExchangeInfo> {
730
735
  let nestedPerpetualIDs = await PerpetualDataHandler.getNestedPerpetualIds(_proxyContract);
731
736
  let factory = await _proxyContract.getOracleFactory();
732
737
  let info: ExchangeInfo = { pools: [], oracleFactoryAddr: factory, proxyAddr: _proxyContract.address };
733
738
  const numPools = nestedPerpetualIDs.length;
739
+
740
+ // get all prices
741
+ let allSym = new Set<string>();
742
+ for(let perpSymbol of _symbolToPerpStaticInfo.keys()) {
743
+ let sInfo : PerpetualStaticInfo | undefined = _symbolToPerpStaticInfo.get(perpSymbol);
744
+ allSym.add(sInfo!.S2Symbol);
745
+ if(sInfo!.S3Symbol!='') {
746
+ allSym.add(sInfo!.S3Symbol);
747
+ }
748
+ }
749
+ let allSymArr = Array.from(allSym.values());
750
+ let idxPriceMap : Map<string, [number,boolean]> = await _priceFeedGetter.fetchPrices(allSymArr);
751
+
734
752
  for (var j = 0; j < numPools; j++) {
735
753
  let perpetualIDs = nestedPerpetualIDs[j];
736
754
  let pool = await _proxyContract.getLiquidityPool(j + 1);
@@ -746,17 +764,36 @@ export default class MarketData extends PerpetualDataHandler {
746
764
  brokerCollateralLotSize: ABK64x64ToFloat(pool.fBrokerCollateralLotSize),
747
765
  perpetuals: [],
748
766
  };
767
+ let poolSymbol = PoolState.poolSymbol;
749
768
  for (var k = 0; k < perpetualIDs.length; k++) {
750
769
  let perp = await _proxyContract.getPerpetual(perpetualIDs[k]);
751
- let fIndexS2 = await _proxyContract.getOraclePrice([perp.S2BaseCCY, perp.S2QuoteCCY]);
752
- let fMidPrice = await _proxyContract.queryPerpetualPrice(perpetualIDs[k], BigNumber.from(0));
753
- let indexS2 = ABK64x64ToFloat(fIndexS2);
770
+ let symS2 = contractSymbolToSymbol(perp.S2BaseCCY, _symbolList)+"-"+contractSymbolToSymbol(perp.S2QuoteCCY, _symbolList);
771
+ let symS3 = contractSymbolToSymbol(perp.S3BaseCCY, _symbolList)+"-"+contractSymbolToSymbol(perp.S3QuoteCCY, _symbolList);
772
+ let perpSymbol = symS2+"-"+poolSymbol;
773
+ //console.log("perpsymbol=",perpSymbol);
774
+ let res = idxPriceMap.get(symS2)
775
+ if (res==undefined) {
776
+ throw new Error(`Price for index ${symS2} could not be fetched - config issue`);
777
+ }
778
+ let [indexS2, isS2MktClosed] : [number, boolean] = [res[0], res[1]];
754
779
  let indexS3 = 1;
780
+ let isS3MktClosed = false;
755
781
  if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_BASE) {
756
782
  indexS3 = indexS2;
757
783
  } else if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_QUANTO) {
758
- indexS3 = ABK64x64ToFloat(await _proxyContract.getOraclePrice([perp.S3BaseCCY, perp.S3QuoteCCY]));
784
+ res = idxPriceMap.get(symS3);
785
+ if (res==undefined) {
786
+ throw new Error(`Price for index ${symS3} could not be fetched - config issue`);
787
+ } else {
788
+ indexS3 = res[0];
789
+ isS3MktClosed = res[1];
790
+ }
759
791
  }
792
+ let fMidPrice = await _proxyContract.queryPerpetualPrice(perpetualIDs[k], BigNumber.from(0), [
793
+ floatToABK64x64(indexS2),
794
+ floatToABK64x64(indexS3)
795
+ ]);
796
+
760
797
  let markPremiumRate = ABK64x64ToFloat(perp.currentMarkPremiumRate.fPrice);
761
798
  let currentFundingRateBps = 1e4 * ABK64x64ToFloat(perp.fCurrentFundingRate);
762
799
  let state = PERP_STATE_STR[perp.state];
@@ -771,7 +808,8 @@ export default class MarketData extends PerpetualDataHandler {
771
808
  midPrice: ABK64x64ToFloat(fMidPrice),
772
809
  currentFundingRateBps: currentFundingRateBps,
773
810
  openInterestBC: ABK64x64ToFloat(perp.fOpenInterest),
774
- maxPositionBC: ABK64x64ToFloat(perp.fMaxPositionBC),
811
+ maxPositionBC: Infinity,
812
+ isMarketClosed: isS2MktClosed || isS3MktClosed
775
813
  };
776
814
  PoolState.perpetuals.push(PerpetualState);
777
815
  }
@@ -1,10 +1,11 @@
1
1
  import { BigNumber, BigNumberish, BytesLike, constants, ContractTransaction } from "ethers";
2
- export const DEFAULT_CONFIG_TESTNET = "../config/defaultConfig.json";
3
- export const DEFAULT_CONFIG_MAINNET = "notthereyet";
2
+ import { NumberLiteralType } from "typescript";
3
+ export const DEFAULT_CONFIG = "../config/defaultConfig.json";
4
4
  export const DEFAULT_CONFIG_TESTNET_NAME = "testnet";
5
5
  export const DEFAULT_CONFIG_MAINNET_NAME = "mainnet";
6
6
 
7
7
  export const ERC20_ABI = require("../abi/ERC20.json");
8
+ export const MOCK_TOKEN_SWAP_ABI = require("../abi/MockTokenSwap.json");
8
9
  export const COLLATERAL_CURRENCY_QUOTE = 0;
9
10
  export const COLLATERAL_CURRENCY_BASE = 1;
10
11
  export const COLLATERAL_CURRENCY_QUANTO = 2;
@@ -33,6 +34,8 @@ export const BUY_SIDE = "BUY";
33
34
  export const SELL_SIDE = "SELL";
34
35
  export const CLOSED_SIDE = "CLOSED";
35
36
  export interface NodeSDKConfig {
37
+ name: string | undefined;
38
+ version: number;
36
39
  nodeURL: string;
37
40
  proxyAddr: string;
38
41
  proxyABILocation: string;
@@ -40,6 +43,7 @@ export interface NodeSDKConfig {
40
43
  limitOrderBookABILocation: string;
41
44
  limitOrderBookFactoryABILocation: string;
42
45
  symbolListLocation: string;
46
+ priceFeedConfigNetwork: string;
43
47
  gasLimit?: number | undefined;
44
48
  }
45
49
 
@@ -81,6 +85,7 @@ export interface PerpetualStaticInfo {
81
85
  S2Symbol: string;
82
86
  S3Symbol: string;
83
87
  lotSizeBC: number;
88
+ priceIds: string[];
84
89
  }
85
90
 
86
91
  /**
@@ -135,6 +140,7 @@ export interface PerpetualState {
135
140
  currentFundingRateBps: number;
136
141
  openInterestBC: number;
137
142
  maxPositionBC: number;
143
+ isMarketClosed: boolean;
138
144
  }
139
145
 
140
146
  export interface OrderResponse {
@@ -148,7 +154,7 @@ export interface OrderStruct {
148
154
  }
149
155
 
150
156
  export interface Order {
151
- symbol: string;
157
+ symbol: string;//symbol of the form ETH-USD-MATIC
152
158
  side: string;
153
159
  type: string;
154
160
  quantity: number;
@@ -204,3 +210,24 @@ export interface SmartContractOrder {
204
210
  uint256 iDeadline;
205
211
  uint256 createdTimestamp;
206
212
  */
213
+
214
+ export interface PriceFeedConfig {
215
+ network: string;
216
+ ids: Array<{ symbol: string; id: string; type: string; origin: string }>;
217
+ endpoints: Array<{ type: string; endpoint: string }>;
218
+ }
219
+
220
+ export interface PriceFeedSubmission {
221
+ symbols: string[];
222
+ priceFeedVaas: string[];
223
+ prices: number[];
224
+ isMarketClosed: boolean[];
225
+ timestamps: number[];
226
+ }
227
+
228
+ export interface PriceFeedFormat {
229
+ conf: BigNumber;
230
+ expo: number;
231
+ price: BigNumber;
232
+ publish_time: number;
233
+ }