@d8x/perpetuals-sdk 0.1.12 → 0.2.0

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 (165) hide show
  1. package/dist/cjs/abi/testnet/IPerpetualManager.json +5215 -0
  2. package/dist/cjs/abi/testnet/LimitOrderBook.json +1075 -0
  3. package/dist/cjs/abi/zkevmTestnet/IPerpetualManager.json +5215 -0
  4. package/dist/cjs/abi/zkevmTestnet/LimitOrderBook.json +1075 -0
  5. package/dist/cjs/abi/zkevmTestnet/LimitOrderBookFactory.json +135 -0
  6. package/dist/cjs/accountTrade.js +441 -0
  7. package/dist/cjs/accountTrade.js.map +1 -0
  8. package/dist/{src → cjs}/brokerTool.js +31 -84
  9. package/dist/cjs/brokerTool.js.map +1 -0
  10. package/dist/cjs/config/defaultConfig.json +47 -0
  11. package/dist/cjs/config/mockSwap.json +4 -0
  12. package/dist/cjs/config/priceFeedConfig.json +104 -0
  13. package/dist/cjs/config/symbolList.json +13 -0
  14. package/dist/cjs/d8XMath.js.map +1 -0
  15. package/dist/cjs/index.js +29 -0
  16. package/dist/cjs/index.js.map +1 -0
  17. package/dist/cjs/liquidatorTool.js +287 -0
  18. package/dist/cjs/liquidatorTool.js.map +1 -0
  19. package/dist/{src → cjs}/liquidityProviderTool.js +12 -65
  20. package/dist/cjs/liquidityProviderTool.js.map +1 -0
  21. package/dist/{src → cjs}/marketData.js +52 -134
  22. package/dist/cjs/marketData.js.map +1 -0
  23. package/dist/{src → cjs}/nodeSDKTypes.d.ts +5 -5
  24. package/dist/cjs/nodeSDKTypes.js +64 -0
  25. package/dist/cjs/nodeSDKTypes.js.map +1 -0
  26. package/dist/{src → cjs}/orderReferrerTool.d.ts +12 -5
  27. package/dist/{src → cjs}/orderReferrerTool.js +114 -112
  28. package/dist/cjs/orderReferrerTool.js.map +1 -0
  29. package/dist/{src → cjs}/perpetualDataHandler.d.ts +1 -1
  30. package/dist/{src → cjs}/perpetualDataHandler.js +47 -109
  31. package/dist/cjs/perpetualDataHandler.js.map +1 -0
  32. package/dist/{src → cjs}/perpetualEventHandler.d.ts +3 -3
  33. package/dist/{src → cjs}/perpetualEventHandler.js +12 -74
  34. package/dist/cjs/perpetualEventHandler.js.map +1 -0
  35. package/dist/cjs/priceFeeds.js +466 -0
  36. package/dist/cjs/priceFeeds.js.map +1 -0
  37. package/dist/{src → cjs}/traderDigests.js +7 -43
  38. package/dist/cjs/traderDigests.js.map +1 -0
  39. package/dist/{src → cjs}/traderInterface.js +13 -66
  40. package/dist/cjs/traderInterface.js.map +1 -0
  41. package/dist/{src → cjs}/triangulator.js +2 -17
  42. package/dist/cjs/triangulator.js.map +1 -0
  43. package/dist/{src → cjs}/utils.js +3 -29
  44. package/dist/cjs/utils.js.map +1 -0
  45. package/dist/cjs/version.d.ts +1 -0
  46. package/dist/{src → cjs}/version.js +1 -1
  47. package/dist/cjs/version.js.map +1 -0
  48. package/dist/{src → cjs}/writeAccessHandler.js +12 -65
  49. package/dist/cjs/writeAccessHandler.js.map +1 -0
  50. package/dist/esm/abi/ERC20.json +288 -0
  51. package/dist/esm/abi/MockTokenSwap.json +186 -0
  52. package/dist/{abi/testnet → esm/abi/central-park}/IPerpetualManager.json +404 -214
  53. package/dist/{abi/testnet → esm/abi/central-park}/LimitOrderBook.json +197 -15
  54. package/dist/esm/abi/central-park/LimitOrderBookFactory.json +135 -0
  55. package/dist/esm/abi/testnet/IPerpetualManager.json +5215 -0
  56. package/dist/esm/abi/testnet/LimitOrderBook.json +1075 -0
  57. package/dist/esm/abi/testnet/LimitOrderBookFactory.json +135 -0
  58. package/dist/esm/abi/zkevmTestnet/IPerpetualManager.json +5215 -0
  59. package/dist/esm/abi/zkevmTestnet/LimitOrderBook.json +1075 -0
  60. package/dist/esm/abi/zkevmTestnet/LimitOrderBookFactory.json +135 -0
  61. package/dist/esm/accountTrade.d.ts +221 -0
  62. package/dist/{src → esm}/accountTrade.js +22 -93
  63. package/dist/esm/accountTrade.js.map +1 -0
  64. package/dist/esm/brokerTool.d.ts +318 -0
  65. package/dist/esm/brokerTool.js +572 -0
  66. package/dist/esm/brokerTool.js.map +1 -0
  67. package/dist/esm/config/defaultConfig.json +47 -0
  68. package/dist/esm/config/mockSwap.json +4 -0
  69. package/dist/esm/config/priceFeedConfig.json +104 -0
  70. package/dist/esm/config/symbolList.json +13 -0
  71. package/dist/esm/d8XMath.d.ts +122 -0
  72. package/dist/esm/d8XMath.js +247 -0
  73. package/dist/esm/d8XMath.js.map +1 -0
  74. package/{src/index.ts → dist/esm/index.d.ts} +1 -15
  75. package/dist/esm/index.js +16 -0
  76. package/dist/esm/index.js.map +1 -0
  77. package/dist/esm/liquidatorTool.d.ts +158 -0
  78. package/dist/{src → esm}/liquidatorTool.js +10 -65
  79. package/dist/esm/liquidatorTool.js.map +1 -0
  80. package/dist/esm/liquidityProviderTool.d.ts +126 -0
  81. package/dist/esm/liquidityProviderTool.js +218 -0
  82. package/dist/esm/liquidityProviderTool.js.map +1 -0
  83. package/dist/esm/marketData.d.ts +309 -0
  84. package/dist/esm/marketData.js +1007 -0
  85. package/dist/esm/marketData.js.map +1 -0
  86. package/dist/esm/nodeSDKTypes.d.ts +266 -0
  87. package/dist/esm/nodeSDKTypes.js +60 -0
  88. package/dist/esm/nodeSDKTypes.js.map +1 -0
  89. package/dist/esm/orderReferrerTool.d.ts +196 -0
  90. package/dist/esm/orderReferrerTool.js +491 -0
  91. package/dist/esm/orderReferrerTool.js.map +1 -0
  92. package/dist/esm/perpetualDataHandler.d.ts +220 -0
  93. package/dist/esm/perpetualDataHandler.js +1060 -0
  94. package/dist/esm/perpetualDataHandler.js.map +1 -0
  95. package/dist/esm/perpetualEventHandler.d.ts +179 -0
  96. package/dist/esm/perpetualEventHandler.js +435 -0
  97. package/dist/esm/perpetualEventHandler.js.map +1 -0
  98. package/dist/esm/priceFeeds.d.ts +115 -0
  99. package/dist/{src → esm}/priceFeeds.js +16 -83
  100. package/dist/esm/priceFeeds.js.map +1 -0
  101. package/dist/esm/traderDigests.d.ts +21 -0
  102. package/dist/esm/traderDigests.js +80 -0
  103. package/dist/esm/traderDigests.js.map +1 -0
  104. package/dist/esm/traderInterface.d.ts +79 -0
  105. package/dist/esm/traderInterface.js +196 -0
  106. package/dist/esm/traderInterface.js.map +1 -0
  107. package/dist/esm/triangulator.d.ts +27 -0
  108. package/dist/esm/triangulator.js +110 -0
  109. package/dist/esm/triangulator.js.map +1 -0
  110. package/dist/esm/utils.d.ts +59 -0
  111. package/dist/esm/utils.js +138 -0
  112. package/dist/esm/utils.js.map +1 -0
  113. package/dist/esm/version.d.ts +1 -0
  114. package/dist/esm/version.js +2 -0
  115. package/dist/esm/version.js.map +1 -0
  116. package/dist/esm/writeAccessHandler.d.ts +50 -0
  117. package/dist/esm/writeAccessHandler.js +157 -0
  118. package/dist/esm/writeAccessHandler.js.map +1 -0
  119. package/package.json +16 -26
  120. package/dist/bundle.js +0 -36793
  121. package/dist/config/defaultConfig.json +0 -47
  122. package/dist/config/mockSwap.json +0 -4
  123. package/dist/config/priceFeedConfig.json +0 -104
  124. package/dist/config/symbolList.json +0 -13
  125. package/dist/src/index.js +0 -45
  126. package/dist/src/nodeSDKTypes.js +0 -115
  127. package/dist/src/version.d.ts +0 -1
  128. package/module.d.ts +0 -1
  129. package/src/accountTrade.ts +0 -392
  130. package/src/brokerTool.ts +0 -507
  131. package/src/d8XMath.ts +0 -319
  132. package/src/liquidatorTool.ts +0 -258
  133. package/src/liquidityProviderTool.ts +0 -186
  134. package/src/marketData.ts +0 -946
  135. package/src/nodeSDKTypes.ts +0 -293
  136. package/src/orderReferrerTool.ts +0 -389
  137. package/src/perpetualDataHandler.ts +0 -1061
  138. package/src/perpetualEventHandler.ts +0 -455
  139. package/src/priceFeeds.ts +0 -381
  140. package/src/traderDigests.ts +0 -91
  141. package/src/traderInterface.ts +0 -159
  142. package/src/triangulator.ts +0 -105
  143. package/src/utils.ts +0 -134
  144. package/src/version.ts +0 -1
  145. package/src/writeAccessHandler.ts +0 -127
  146. /package/dist/{abi → cjs/abi}/ERC20.json +0 -0
  147. /package/dist/{abi → cjs/abi}/MockTokenSwap.json +0 -0
  148. /package/dist/{abi → cjs/abi}/central-park/IPerpetualManager.json +0 -0
  149. /package/dist/{abi → cjs/abi}/central-park/LimitOrderBook.json +0 -0
  150. /package/dist/{abi → cjs/abi}/central-park/LimitOrderBookFactory.json +0 -0
  151. /package/dist/{abi → cjs/abi}/testnet/LimitOrderBookFactory.json +0 -0
  152. /package/dist/{src → cjs}/accountTrade.d.ts +0 -0
  153. /package/dist/{src → cjs}/brokerTool.d.ts +0 -0
  154. /package/dist/{src → cjs}/d8XMath.d.ts +0 -0
  155. /package/dist/{src → cjs}/d8XMath.js +0 -0
  156. /package/dist/{src → cjs}/index.d.ts +0 -0
  157. /package/dist/{src → cjs}/liquidatorTool.d.ts +0 -0
  158. /package/dist/{src → cjs}/liquidityProviderTool.d.ts +0 -0
  159. /package/dist/{src → cjs}/marketData.d.ts +0 -0
  160. /package/dist/{src → cjs}/priceFeeds.d.ts +0 -0
  161. /package/dist/{src → cjs}/traderDigests.d.ts +0 -0
  162. /package/dist/{src → cjs}/traderInterface.d.ts +0 -0
  163. /package/dist/{src → cjs}/triangulator.d.ts +0 -0
  164. /package/dist/{src → cjs}/utils.d.ts +0 -0
  165. /package/dist/{src → cjs}/writeAccessHandler.d.ts +0 -0
@@ -0,0 +1,1060 @@
1
+ import { __awaiter, __generator, __read, __values } from "tslib";
2
+ import { ethers, BigNumber } from "ethers";
3
+ import { MAX_64x64, CollaterlCCY, COLLATERAL_CURRENCY_BASE, COLLATERAL_CURRENCY_QUOTE, BUY_SIDE, SELL_SIDE, CLOSED_SIDE, ORDER_MAX_DURATION_SEC, ZERO_ADDRESS, ORDER_TYPE_LIMIT, ORDER_TYPE_MARKET, ORDER_TYPE_STOP_MARKET, ORDER_TYPE_STOP_LIMIT, MASK_LIMIT_ORDER, MASK_CLOSE_ONLY, MASK_KEEP_POS_LEVERAGE, MASK_MARKET_ORDER, MASK_STOP_ORDER, ONE_64x64, PERP_STATE_STR, DEFAULT_CONFIG, loadABIs, SYMBOL_LIST, ZERO_ORDER_ID, } from "./nodeSDKTypes";
4
+ import { to4Chars, combineFlags, containsFlag, contractSymbolToSymbol, symbol4BToLongSymbol } from "./utils";
5
+ import { ABK64x64ToFloat, floatToABK64x64, div64x64, calculateLiquidationPriceCollateralQuanto, calculateLiquidationPriceCollateralBase, calculateLiquidationPriceCollateralQuote, } from "./d8XMath";
6
+ import PriceFeeds from "./priceFeeds";
7
+ /**
8
+ * Parent class for MarketData and WriteAccessHandler that handles
9
+ * common data and chain operations.
10
+ */
11
+ var PerpetualDataHandler = /** @class */ (function () {
12
+ function PerpetualDataHandler(config) {
13
+ this.PRICE_UPDATE_FEE_GWEI = 1;
14
+ this.proxyContract = null;
15
+ // limit order book
16
+ this.lobFactoryContract = null;
17
+ this.provider = null;
18
+ this.signerOrProvider = null;
19
+ this.symbolToPerpStaticInfo = new Map();
20
+ this.poolStaticInfos = new Array();
21
+ this.symbolToTokenAddrMap = new Map();
22
+ this.nestedPerpetualIDs = new Array();
23
+ this.chainId = config.chainId;
24
+ this.proxyAddr = config.proxyAddr;
25
+ this.nodeURL = config.nodeURL;
26
+ this.proxyABI = config.proxyABI;
27
+ this.lobFactoryABI = config.lobFactoryABI;
28
+ this.lobABI = config.lobABI;
29
+ this.symbolList = SYMBOL_LIST;
30
+ this.priceFeedGetter = new PriceFeeds(this, config.priceFeedConfigNetwork);
31
+ }
32
+ PerpetualDataHandler.prototype.initContractsAndData = function (signerOrProvider) {
33
+ return __awaiter(this, void 0, void 0, function () {
34
+ var network, error_1, _a;
35
+ return __generator(this, function (_b) {
36
+ switch (_b.label) {
37
+ case 0:
38
+ this.signerOrProvider = signerOrProvider;
39
+ _b.label = 1;
40
+ case 1:
41
+ _b.trys.push([1, 6, , 7]);
42
+ if (!(signerOrProvider instanceof ethers.Signer)) return [3 /*break*/, 3];
43
+ return [4 /*yield*/, signerOrProvider.provider.getNetwork()];
44
+ case 2:
45
+ network = _b.sent();
46
+ return [3 /*break*/, 5];
47
+ case 3: return [4 /*yield*/, signerOrProvider.getNetwork()];
48
+ case 4:
49
+ network = _b.sent();
50
+ _b.label = 5;
51
+ case 5: return [3 /*break*/, 7];
52
+ case 6:
53
+ error_1 = _b.sent();
54
+ console.log(error_1);
55
+ throw new Error("Unable to connect to network.");
56
+ case 7:
57
+ if (network.chainId !== this.chainId) {
58
+ throw new Error("Provider: chain id ".concat(network.chainId, " does not match config (").concat(this.chainId, ")"));
59
+ }
60
+ this.proxyContract = new ethers.Contract(this.proxyAddr, this.proxyABI, signerOrProvider);
61
+ _a = this;
62
+ return [4 /*yield*/, this.proxyContract.getOrderBookFactoryAddress()];
63
+ case 8:
64
+ _a.lobFactoryAddr = _b.sent();
65
+ this.lobFactoryContract = new ethers.Contract(this.lobFactoryAddr, this.lobFactoryABI, signerOrProvider);
66
+ return [4 /*yield*/, this._fillSymbolMaps(this.proxyContract)];
67
+ case 9:
68
+ _b.sent();
69
+ return [2 /*return*/];
70
+ }
71
+ });
72
+ });
73
+ };
74
+ /**
75
+ * Returns the order-book contract for the symbol if found or fails
76
+ * @param symbol symbol of the form ETH-USD-MATIC
77
+ * @returns order book contract for the perpetual
78
+ */
79
+ PerpetualDataHandler.prototype.getOrderBookContract = function (symbol) {
80
+ var _a;
81
+ var orderBookAddr = (_a = this.symbolToPerpStaticInfo.get(symbol)) === null || _a === void 0 ? void 0 : _a.limitOrderBookAddr;
82
+ if (orderBookAddr == "" || orderBookAddr == undefined || this.signerOrProvider == null) {
83
+ throw Error("no limit order book found for ".concat(symbol, " or no signer"));
84
+ }
85
+ var lobContract = new ethers.Contract(orderBookAddr, this.lobABI, this.signerOrProvider);
86
+ return lobContract;
87
+ };
88
+ /**
89
+ * Called when initializing. This function fills this.symbolToTokenAddrMap,
90
+ * and this.nestedPerpetualIDs and this.symbolToPerpStaticInfo
91
+ *
92
+ */
93
+ PerpetualDataHandler.prototype._fillSymbolMaps = function (proxyContract) {
94
+ return __awaiter(this, void 0, void 0, function () {
95
+ var oracleFactoryAddr, _a, requiredPairs, _loop_1, this_1, j;
96
+ return __generator(this, function (_b) {
97
+ switch (_b.label) {
98
+ case 0:
99
+ if (proxyContract == null || this.lobFactoryContract == null) {
100
+ throw Error("proxy or limit order book not defined");
101
+ }
102
+ return [4 /*yield*/, proxyContract.getOracleFactory()];
103
+ case 1:
104
+ oracleFactoryAddr = _b.sent();
105
+ _a = this;
106
+ return [4 /*yield*/, PerpetualDataHandler.getNestedPerpetualIds(proxyContract)];
107
+ case 2:
108
+ _a.nestedPerpetualIDs = _b.sent();
109
+ requiredPairs = new Set();
110
+ _loop_1 = function (j) {
111
+ var pool, poolMarginTokenAddr, perpetualIDs, poolCCY, currentSymbols, currentSymbolsS3, currentLimitOrderBookAddr, ccy, initRate, mgnRate, lotSizes, refRebates, k, perp, base, quote, base3, quote3, sym, sym3, lobAddr, info, currentSymbols3, k, _c, idsB32;
112
+ return __generator(this, function (_d) {
113
+ switch (_d.label) {
114
+ case 0: return [4 /*yield*/, proxyContract.getLiquidityPool(j + 1)];
115
+ case 1:
116
+ pool = _d.sent();
117
+ poolMarginTokenAddr = pool.marginTokenAddress;
118
+ perpetualIDs = this_1.nestedPerpetualIDs[j];
119
+ poolCCY = undefined;
120
+ currentSymbols = [];
121
+ currentSymbolsS3 = [];
122
+ currentLimitOrderBookAddr = [];
123
+ ccy = [];
124
+ initRate = [];
125
+ mgnRate = [];
126
+ lotSizes = [];
127
+ refRebates = [];
128
+ k = 0;
129
+ _d.label = 2;
130
+ case 2:
131
+ if (!(k < perpetualIDs.length)) return [3 /*break*/, 6];
132
+ return [4 /*yield*/, proxyContract.getPerpetual(perpetualIDs[k])];
133
+ case 3:
134
+ perp = _d.sent();
135
+ base = contractSymbolToSymbol(perp.S2BaseCCY, this_1.symbolList);
136
+ quote = contractSymbolToSymbol(perp.S2QuoteCCY, this_1.symbolList);
137
+ base3 = contractSymbolToSymbol(perp.S3BaseCCY, this_1.symbolList);
138
+ quote3 = contractSymbolToSymbol(perp.S3QuoteCCY, this_1.symbolList);
139
+ sym = base + "-" + quote;
140
+ sym3 = base3 + "-" + quote3;
141
+ requiredPairs.add(sym);
142
+ if (sym3 != "-") {
143
+ requiredPairs.add(sym3);
144
+ }
145
+ else {
146
+ sym3 = "";
147
+ }
148
+ currentSymbols.push(sym);
149
+ currentSymbolsS3.push(sym3);
150
+ initRate.push(ABK64x64ToFloat(perp.fInitialMarginRate));
151
+ mgnRate.push(ABK64x64ToFloat(perp.fMaintenanceMarginRate));
152
+ lotSizes.push(ABK64x64ToFloat(perp.fLotSizeBC));
153
+ refRebates.push(ABK64x64ToFloat(perp.fReferralRebateCC));
154
+ return [4 /*yield*/, this_1.lobFactoryContract.getOrderBookAddress(perpetualIDs[k])];
155
+ case 4:
156
+ lobAddr = _d.sent();
157
+ currentLimitOrderBookAddr.push(lobAddr);
158
+ // we find out the pool currency by looking at all perpetuals
159
+ // unless for quanto perpetuals, we know the pool currency
160
+ // from the perpetual. This fails if we have a pool with only
161
+ // quanto perpetuals
162
+ if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_BASE) {
163
+ poolCCY = poolCCY !== null && poolCCY !== void 0 ? poolCCY : base;
164
+ ccy.push(CollaterlCCY.BASE);
165
+ }
166
+ else if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_QUOTE) {
167
+ poolCCY = poolCCY !== null && poolCCY !== void 0 ? poolCCY : quote;
168
+ ccy.push(CollaterlCCY.QUOTE);
169
+ }
170
+ else {
171
+ poolCCY = poolCCY !== null && poolCCY !== void 0 ? poolCCY : base3;
172
+ ccy.push(CollaterlCCY.QUANTO);
173
+ }
174
+ _d.label = 5;
175
+ case 5:
176
+ k++;
177
+ return [3 /*break*/, 2];
178
+ case 6:
179
+ if (perpetualIDs.length == 0) {
180
+ return [2 /*return*/, "continue"];
181
+ }
182
+ info = {
183
+ poolId: j + 1,
184
+ poolMarginSymbol: poolCCY,
185
+ poolMarginTokenAddr: poolMarginTokenAddr,
186
+ shareTokenAddr: pool.shareTokenAddress,
187
+ oracleFactoryAddr: oracleFactoryAddr,
188
+ };
189
+ this_1.poolStaticInfos.push(info);
190
+ currentSymbols3 = currentSymbols.map(function (x) { return x + "-" + poolCCY; });
191
+ k = 0;
192
+ _d.label = 7;
193
+ case 7:
194
+ if (!(k < perpetualIDs.length)) return [3 /*break*/, 10];
195
+ return [4 /*yield*/, proxyContract.getPriceInfo(perpetualIDs[k])];
196
+ case 8:
197
+ _c = __read.apply(void 0, [_d.sent(), 1]), idsB32 = _c[0];
198
+ this_1.symbolToPerpStaticInfo.set(currentSymbols3[k], {
199
+ id: perpetualIDs[k],
200
+ limitOrderBookAddr: currentLimitOrderBookAddr[k],
201
+ initialMarginRate: initRate[k],
202
+ maintenanceMarginRate: mgnRate[k],
203
+ collateralCurrencyType: ccy[k],
204
+ S2Symbol: currentSymbols[k],
205
+ S3Symbol: currentSymbolsS3[k],
206
+ lotSizeBC: lotSizes[k],
207
+ referralRebate: refRebates[k],
208
+ priceIds: idsB32,
209
+ });
210
+ _d.label = 9;
211
+ case 9:
212
+ k++;
213
+ return [3 /*break*/, 7];
214
+ case 10:
215
+ // push margin token address into map
216
+ this_1.symbolToTokenAddrMap.set(poolCCY, poolMarginTokenAddr);
217
+ return [2 /*return*/];
218
+ }
219
+ });
220
+ };
221
+ this_1 = this;
222
+ j = 0;
223
+ _b.label = 3;
224
+ case 3:
225
+ if (!(j < this.nestedPerpetualIDs.length)) return [3 /*break*/, 6];
226
+ return [5 /*yield**/, _loop_1(j)];
227
+ case 4:
228
+ _b.sent();
229
+ _b.label = 5;
230
+ case 5:
231
+ j++;
232
+ return [3 /*break*/, 3];
233
+ case 6:
234
+ // pre-calculate all triangulation paths so we can easily get from
235
+ // the prices of price-feeds to the index price required, e.g.
236
+ // BTC-USDC : BTC-USD / USDC-USD
237
+ this.priceFeedGetter.initializeTriangulations(requiredPairs);
238
+ return [2 /*return*/];
239
+ }
240
+ });
241
+ });
242
+ };
243
+ /**
244
+ * Get pool symbol given a pool Id.
245
+ * @param {number} poolId Pool Id.
246
+ * @returns {symbol} Pool symbol, e.g. "USDC".
247
+ */
248
+ PerpetualDataHandler.prototype.getSymbolFromPoolId = function (poolId) {
249
+ return PerpetualDataHandler._getSymbolFromPoolId(poolId, this.poolStaticInfos);
250
+ };
251
+ /**
252
+ * Get pool Id given a pool symbol.
253
+ * @param {string} symbol Pool symbol.
254
+ * @returns {number} Pool Id.
255
+ */
256
+ PerpetualDataHandler.prototype.getPoolIdFromSymbol = function (symbol) {
257
+ return PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
258
+ };
259
+ /**
260
+ * Get perpetual Id given a perpetual symbol.
261
+ * @param {string} symbol Perpetual symbol, e.g. "BTC-USD-MATIC".
262
+ * @returns {number} Perpetual Id.
263
+ */
264
+ PerpetualDataHandler.prototype.getPerpIdFromSymbol = function (symbol) {
265
+ return PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
266
+ };
267
+ /**
268
+ * Get the symbol in long format of the perpetual id
269
+ * @param perpId perpetual id
270
+ */
271
+ PerpetualDataHandler.prototype.getSymbolFromPerpId = function (perpId) {
272
+ return PerpetualDataHandler.perpetualIdToSymbol(perpId, this.symbolToPerpStaticInfo);
273
+ };
274
+ PerpetualDataHandler.prototype.symbol4BToLongSymbol = function (sym) {
275
+ return symbol4BToLongSymbol(sym, this.symbolList);
276
+ };
277
+ /**
278
+ * Get PriceFeedSubmission data required for blockchain queries that involve price data, and the corresponding
279
+ * triangulated prices for the indices S2 and S3
280
+ * @param symbol pool symbol of the form "ETH-USD-MATIC"
281
+ * @returns PriceFeedSubmission and prices for S2 and S3. [S2price, 0] if S3 not defined.
282
+ */
283
+ PerpetualDataHandler.prototype.fetchPriceSubmissionInfoForPerpetual = function (symbol) {
284
+ return __awaiter(this, void 0, void 0, function () {
285
+ return __generator(this, function (_a) {
286
+ switch (_a.label) {
287
+ case 0: return [4 /*yield*/, this.priceFeedGetter.fetchFeedPriceInfoAndIndicesForPerpetual(symbol)];
288
+ case 1:
289
+ // fetch prices from required price-feeds (REST)
290
+ return [2 /*return*/, _a.sent()];
291
+ }
292
+ });
293
+ });
294
+ };
295
+ /**
296
+ * Get the symbols required as indices for the given perpetual
297
+ * @param symbol of the form ETH-USD-MATIC, specifying the perpetual
298
+ * @returns name of underlying index prices, e.g. ["MATIC-USD", ""]
299
+ */
300
+ PerpetualDataHandler.prototype.getIndexSymbols = function (symbol) {
301
+ // get index
302
+ var staticInfo = this.symbolToPerpStaticInfo.get(symbol);
303
+ if (staticInfo == undefined) {
304
+ throw new Error("No static info for perpetual with symbol ".concat(symbol));
305
+ }
306
+ return [staticInfo.S2Symbol, staticInfo.S3Symbol];
307
+ };
308
+ /**
309
+ * Get the latest prices for a given perpetual from the offchain oracle
310
+ * networks
311
+ * @param symbol perpetual symbol of the form BTC-USD-MATIC
312
+ * @returns array of price feed updates that can be submitted to the smart contract
313
+ * and corresponding price information
314
+ */
315
+ PerpetualDataHandler.prototype.fetchLatestFeedPriceInfo = function (symbol) {
316
+ return __awaiter(this, void 0, void 0, function () {
317
+ return __generator(this, function (_a) {
318
+ switch (_a.label) {
319
+ case 0: return [4 /*yield*/, this.priceFeedGetter.fetchLatestFeedPriceInfoForPerpetual(symbol)];
320
+ case 1: return [2 /*return*/, _a.sent()];
321
+ }
322
+ });
323
+ });
324
+ };
325
+ /**
326
+ * Get list of required pyth price source IDs for given perpetual
327
+ * @param symbol perpetual symbol, e.g., BTC-USD-MATIC
328
+ * @returns list of required pyth price sources for this perpetual
329
+ */
330
+ PerpetualDataHandler.prototype.getPriceIds = function (symbol) {
331
+ var perpInfo = this.symbolToPerpStaticInfo.get(symbol);
332
+ if (perpInfo == undefined) {
333
+ throw Error("Perpetual with symbol ".concat(symbol, " not found. Check symbol or use createProxyInstance()."));
334
+ }
335
+ return perpInfo.priceIds;
336
+ };
337
+ PerpetualDataHandler._getSymbolFromPoolId = function (poolId, staticInfos) {
338
+ var idx = poolId - 1;
339
+ return staticInfos[idx].poolMarginSymbol;
340
+ };
341
+ PerpetualDataHandler._getPoolIdFromSymbol = function (symbol, staticInfos) {
342
+ var symbols = symbol.split("-");
343
+ //in case user provided ETH-USD-MATIC instead of MATIC; or similar
344
+ if (symbols.length == 3) {
345
+ symbol = symbols[2];
346
+ }
347
+ var j = 0;
348
+ while (j < staticInfos.length && staticInfos[j].poolMarginSymbol != symbol) {
349
+ j++;
350
+ }
351
+ if (j == staticInfos.length) {
352
+ throw new Error("no pool found for symbol ".concat(symbol));
353
+ }
354
+ return j + 1;
355
+ };
356
+ PerpetualDataHandler.getNestedPerpetualIds = function (_proxyContract) {
357
+ return __awaiter(this, void 0, void 0, function () {
358
+ var poolCount, poolIds, i, perpetualCount, j, id;
359
+ return __generator(this, function (_a) {
360
+ switch (_a.label) {
361
+ case 0: return [4 /*yield*/, _proxyContract.getPoolCount()];
362
+ case 1:
363
+ poolCount = _a.sent();
364
+ poolIds = new Array(poolCount);
365
+ i = 1;
366
+ _a.label = 2;
367
+ case 2:
368
+ if (!(i < poolCount + 1)) return [3 /*break*/, 8];
369
+ return [4 /*yield*/, _proxyContract.getPerpetualCountInPool(i)];
370
+ case 3:
371
+ perpetualCount = _a.sent();
372
+ poolIds[i - 1] = new Array(perpetualCount);
373
+ j = 0;
374
+ _a.label = 4;
375
+ case 4:
376
+ if (!(j < perpetualCount)) return [3 /*break*/, 7];
377
+ return [4 /*yield*/, _proxyContract.getPerpetualId(i, j)];
378
+ case 5:
379
+ id = _a.sent();
380
+ poolIds[i - 1][j] = id;
381
+ _a.label = 6;
382
+ case 6:
383
+ j++;
384
+ return [3 /*break*/, 4];
385
+ case 7:
386
+ i++;
387
+ return [3 /*break*/, 2];
388
+ case 8: return [2 /*return*/, poolIds];
389
+ }
390
+ });
391
+ });
392
+ };
393
+ PerpetualDataHandler.buildMarginAccountFromState = function (symbol, traderState, symbolToPerpStaticInfo, _pxS2S3) {
394
+ var _a;
395
+ var idx_cash = 3;
396
+ var idx_notional = 4;
397
+ var idx_locked_in = 5;
398
+ var idx_mark_price = 8;
399
+ var idx_lvg = 7;
400
+ var idx_s3 = 9;
401
+ var isEmpty = traderState[idx_notional].eq(0);
402
+ var cash = ABK64x64ToFloat(traderState[idx_cash]);
403
+ var S2Liq = 0, S3Liq = 0, tau = Infinity, pnl = 0, unpaidFundingCC = 0, fLockedIn = BigNumber.from(0), side = CLOSED_SIDE, entryPrice = 0;
404
+ if (!isEmpty) {
405
+ _a = __read(PerpetualDataHandler._calculateLiquidationPrice(symbol, traderState, _pxS2S3[0], symbolToPerpStaticInfo), 5), S2Liq = _a[0], S3Liq = _a[1], tau = _a[2], pnl = _a[3], unpaidFundingCC = _a[4];
406
+ fLockedIn = traderState[idx_locked_in];
407
+ side = traderState[idx_locked_in].gt(0) ? BUY_SIDE : SELL_SIDE;
408
+ entryPrice = ABK64x64ToFloat(div64x64(fLockedIn, traderState[idx_notional]));
409
+ }
410
+ var mgn = {
411
+ symbol: symbol,
412
+ positionNotionalBaseCCY: isEmpty ? 0 : ABK64x64ToFloat(traderState[idx_notional].abs()),
413
+ side: isEmpty ? CLOSED_SIDE : side,
414
+ entryPrice: isEmpty ? 0 : entryPrice,
415
+ leverage: isEmpty ? 0 : ABK64x64ToFloat(traderState[idx_lvg]),
416
+ markPrice: ABK64x64ToFloat(traderState[idx_mark_price].abs()),
417
+ unrealizedPnlQuoteCCY: isEmpty ? 0 : pnl,
418
+ unrealizedFundingCollateralCCY: isEmpty ? 0 : unpaidFundingCC,
419
+ collateralCC: cash,
420
+ liquidationLvg: isEmpty ? 0 : 1 / tau,
421
+ liquidationPrice: isEmpty ? [0, 0] : [S2Liq, S3Liq],
422
+ collToQuoteConversion: ABK64x64ToFloat(traderState[idx_s3]),
423
+ };
424
+ return mgn;
425
+ };
426
+ PerpetualDataHandler.getMarginAccount = function (traderAddr, symbol, symbolToPerpStaticInfo, _proxyContract, _pxS2S3) {
427
+ return __awaiter(this, void 0, void 0, function () {
428
+ var perpId, traderState;
429
+ return __generator(this, function (_a) {
430
+ switch (_a.label) {
431
+ case 0:
432
+ perpId = Number(symbol);
433
+ if (isNaN(perpId)) {
434
+ perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
435
+ }
436
+ return [4 /*yield*/, _proxyContract.getTraderState(perpId, traderAddr, _pxS2S3.map(function (x) { return floatToABK64x64(x); }))];
437
+ case 1:
438
+ traderState = _a.sent();
439
+ return [2 /*return*/, PerpetualDataHandler.buildMarginAccountFromState(symbol, traderState, symbolToPerpStaticInfo, _pxS2S3)];
440
+ }
441
+ });
442
+ });
443
+ };
444
+ PerpetualDataHandler._queryPerpetualPrice = function (symbol, tradeAmount, symbolToPerpStaticInfo, _proxyContract, indexPrices) {
445
+ return __awaiter(this, void 0, void 0, function () {
446
+ var perpId, fIndexPrices, fPrice;
447
+ return __generator(this, function (_a) {
448
+ switch (_a.label) {
449
+ case 0:
450
+ perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
451
+ fIndexPrices = indexPrices.map(function (x) { return floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x); });
452
+ return [4 /*yield*/, _proxyContract.queryPerpetualPrice(perpId, floatToABK64x64(tradeAmount), fIndexPrices)];
453
+ case 1:
454
+ fPrice = _a.sent();
455
+ return [2 /*return*/, ABK64x64ToFloat(fPrice)];
456
+ }
457
+ });
458
+ });
459
+ };
460
+ PerpetualDataHandler._queryPerpetualMarkPrice = function (symbol, symbolToPerpStaticInfo, _proxyContract, indexPrices) {
461
+ return __awaiter(this, void 0, void 0, function () {
462
+ var perpId, _a, S2, S3, ammState;
463
+ return __generator(this, function (_b) {
464
+ switch (_b.label) {
465
+ case 0:
466
+ perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
467
+ _a = __read(indexPrices.map(function (x) { return floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x); }), 2), S2 = _a[0], S3 = _a[1];
468
+ return [4 /*yield*/, _proxyContract.getAMMState(perpId, [S2, S3])];
469
+ case 1:
470
+ ammState = _b.sent();
471
+ return [2 /*return*/, ABK64x64ToFloat(ammState[6].mul(ONE_64x64.add(ammState[8])).div(ONE_64x64))];
472
+ }
473
+ });
474
+ });
475
+ };
476
+ PerpetualDataHandler._queryPerpetualState = function (symbol, symbolToPerpStaticInfo, _proxyContract, indexPrices) {
477
+ return __awaiter(this, void 0, void 0, function () {
478
+ var perpId, staticInfo, ccy, _a, S2, S3, ammState, markPrice, state;
479
+ return __generator(this, function (_b) {
480
+ switch (_b.label) {
481
+ case 0:
482
+ perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
483
+ staticInfo = symbolToPerpStaticInfo.get(symbol);
484
+ ccy = symbol.split("-");
485
+ _a = __read([indexPrices[0], indexPrices[1]], 2), S2 = _a[0], S3 = _a[1];
486
+ if (staticInfo.collateralCurrencyType == CollaterlCCY.BASE) {
487
+ S3 = S2;
488
+ }
489
+ else if (staticInfo.collateralCurrencyType == CollaterlCCY.QUOTE) {
490
+ S3 = 1;
491
+ }
492
+ return [4 /*yield*/, _proxyContract.getAMMState(perpId, [S2, S3].map(floatToABK64x64))];
493
+ case 1:
494
+ ammState = _b.sent();
495
+ markPrice = S2 * (1 + ABK64x64ToFloat(ammState[8]));
496
+ state = {
497
+ id: perpId,
498
+ state: PERP_STATE_STR[ammState[13]],
499
+ baseCurrency: ccy[0],
500
+ quoteCurrency: ccy[1],
501
+ indexPrice: S2,
502
+ collToQuoteIndexPrice: S3,
503
+ markPrice: markPrice,
504
+ midPrice: ABK64x64ToFloat(ammState[10]),
505
+ currentFundingRateBps: ABK64x64ToFloat(ammState[14]) * 1e4,
506
+ openInterestBC: ABK64x64ToFloat(ammState[11]),
507
+ isMarketClosed: indexPrices[2] || indexPrices[3],
508
+ };
509
+ return [2 /*return*/, state];
510
+ }
511
+ });
512
+ });
513
+ };
514
+ /**
515
+ * Liquidation price
516
+ * @param symbol symbol of the form BTC-USD-MATIC
517
+ * @param traderState BigInt array according to smart contract
518
+ * @param S2 number, index price S2
519
+ * @param symbolToPerpStaticInfo mapping symbol->PerpStaticInfo
520
+ * @returns liquidation mark-price, corresponding collateral/quote conversion
521
+ */
522
+ PerpetualDataHandler._calculateLiquidationPrice = function (symbol, traderState, S2, symbolToPerpStaticInfo) {
523
+ var idx_availableCashCC = 2;
524
+ var idx_cash = 3;
525
+ var idx_notional = 4;
526
+ var idx_locked_in = 5;
527
+ var idx_mark_price = 8;
528
+ var idx_s3 = 9;
529
+ // const idx_s2 = 10;
530
+ var S2Liq;
531
+ var S3Liq = ABK64x64ToFloat(traderState[idx_s3]);
532
+ var perpInfo = symbolToPerpStaticInfo.get(symbol);
533
+ if (perpInfo == undefined) {
534
+ throw new Error("no info for perpetual ".concat(symbol));
535
+ }
536
+ var tau = perpInfo.maintenanceMarginRate;
537
+ var lockedInValueQC = ABK64x64ToFloat(traderState[idx_locked_in]);
538
+ var position = ABK64x64ToFloat(traderState[idx_notional]);
539
+ var cashCC = ABK64x64ToFloat(traderState[idx_availableCashCC]);
540
+ var Sm = ABK64x64ToFloat(traderState[idx_mark_price]);
541
+ var unpaidFundingCC = ABK64x64ToFloat(traderState[idx_availableCashCC].sub(traderState[idx_cash]));
542
+ var unpaidFunding = unpaidFundingCC;
543
+ if (perpInfo.collateralCurrencyType == CollaterlCCY.BASE) {
544
+ S2Liq = calculateLiquidationPriceCollateralBase(lockedInValueQC, position, cashCC, tau);
545
+ S3Liq = S2Liq;
546
+ unpaidFunding = unpaidFunding / S2;
547
+ }
548
+ else if (perpInfo.collateralCurrencyType == CollaterlCCY.QUANTO) {
549
+ var S3 = S3Liq;
550
+ S3Liq = S3;
551
+ S2Liq = calculateLiquidationPriceCollateralQuanto(lockedInValueQC, position, cashCC, tau, S3, Sm);
552
+ unpaidFunding = unpaidFunding / S3;
553
+ }
554
+ else {
555
+ S2Liq = calculateLiquidationPriceCollateralQuote(lockedInValueQC, position, cashCC, tau);
556
+ }
557
+ // floor at 0
558
+ S2Liq = S2Liq < 0 ? 0 : S2Liq;
559
+ S3Liq = S3Liq && S3Liq < 0 ? 0 : S3Liq;
560
+ // account cash + pnl = avail cash + pos Sm - L = margin balance
561
+ var pnl = position * Sm - lockedInValueQC + unpaidFunding;
562
+ return [S2Liq, S3Liq, tau, pnl, unpaidFundingCC];
563
+ };
564
+ /**
565
+ * Finds the perpetual id for a symbol of the form
566
+ * <base>-<quote>-<collateral>. The function first converts the
567
+ * token names into bytes4 representation
568
+ * @param symbol symbol (e.g., BTC-USD-MATC)
569
+ * @param symbolToPerpStaticInfo map that contains the bytes4-symbol to PerpetualStaticInfo
570
+ * including id mapping
571
+ * @returns perpetual id or it fails
572
+ */
573
+ PerpetualDataHandler.symbolToPerpetualId = function (symbol, symbolToPerpStaticInfo) {
574
+ var _a;
575
+ var id = (_a = symbolToPerpStaticInfo.get(symbol)) === null || _a === void 0 ? void 0 : _a.id;
576
+ if (id == undefined) {
577
+ throw Error("No perpetual found for symbol ".concat(symbol));
578
+ }
579
+ return id;
580
+ };
581
+ /**
582
+ * Find the long symbol ("ETH-USD-MATIC") of the given perpetual id
583
+ * @param id perpetual id
584
+ * @param symbolToPerpStaticInfo map that contains the bytes4-symbol to PerpetualStaticInfo
585
+ * @returns symbol string or undefined
586
+ */
587
+ PerpetualDataHandler.perpetualIdToSymbol = function (id, symbolToPerpStaticInfo) {
588
+ var e_1, _a;
589
+ var _b;
590
+ var symbol;
591
+ try {
592
+ for (var _c = __values(symbolToPerpStaticInfo.keys()), _d = _c.next(); !_d.done; _d = _c.next()) {
593
+ symbol = _d.value;
594
+ if (((_b = symbolToPerpStaticInfo.get(symbol)) === null || _b === void 0 ? void 0 : _b.id) == id) {
595
+ return symbol;
596
+ }
597
+ }
598
+ }
599
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
600
+ finally {
601
+ try {
602
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
603
+ }
604
+ finally { if (e_1) throw e_1.error; }
605
+ }
606
+ return undefined;
607
+ };
608
+ PerpetualDataHandler.symbolToBytes4Symbol = function (symbol) {
609
+ //split by dashes BTC-USD-MATIC
610
+ var symbols = symbol.split("-");
611
+ if (symbols.length != 3) {
612
+ throw Error("Symbol ".concat(symbol, " not valid. Expecting CCY-CCY-CCY format"));
613
+ }
614
+ //transform into bytes4 currencies (without the space): "BTC", "USD", "MATC"
615
+ symbols = symbols.map(function (x) {
616
+ var v = to4Chars(x);
617
+ v = v.replace(/\0/g, "");
618
+ return v;
619
+ });
620
+ // concatenate and find perpetual Id in map
621
+ return symbols[0] + "-" + symbols[1] + "-" + symbols[2];
622
+ };
623
+ PerpetualDataHandler._getByValue = function (map, searchValue, valueField) {
624
+ var e_2, _a;
625
+ try {
626
+ for (var _b = __values(map.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
627
+ var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
628
+ if (value[valueField] === searchValue) {
629
+ return key;
630
+ }
631
+ }
632
+ }
633
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
634
+ finally {
635
+ try {
636
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
637
+ }
638
+ finally { if (e_2) throw e_2.error; }
639
+ }
640
+ return undefined;
641
+ };
642
+ PerpetualDataHandler.fromSmartContractOrder = function (order, symbolToPerpInfoMap) {
643
+ // find symbol of perpetual id
644
+ var symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, order.iPerpetualId, "id");
645
+ if (symbol == undefined) {
646
+ throw Error("Perpetual id ".concat(order.iPerpetualId, " not found. Check with marketData.exchangeInfo()."));
647
+ }
648
+ var side = order.fAmount > 0 ? BUY_SIDE : SELL_SIDE;
649
+ var limitPrice, stopPrice;
650
+ var fLimitPrice = BigNumber.from(order.fLimitPrice);
651
+ if (fLimitPrice.eq(0)) {
652
+ limitPrice = side == BUY_SIDE ? undefined : 0;
653
+ }
654
+ else if (fLimitPrice.eq(MAX_64x64)) {
655
+ limitPrice = side == BUY_SIDE ? Infinity : undefined;
656
+ }
657
+ else {
658
+ limitPrice = ABK64x64ToFloat(fLimitPrice);
659
+ }
660
+ var fStopPrice = BigNumber.from(order.fTriggerPrice);
661
+ if (fStopPrice.eq(0) || fStopPrice.eq(MAX_64x64)) {
662
+ stopPrice = undefined;
663
+ }
664
+ else {
665
+ stopPrice = ABK64x64ToFloat(fStopPrice);
666
+ }
667
+ var userOrder = {
668
+ symbol: symbol,
669
+ side: side,
670
+ type: PerpetualDataHandler._flagToOrderType(order),
671
+ quantity: Math.abs(ABK64x64ToFloat(BigNumber.from(order.fAmount))),
672
+ reduceOnly: containsFlag(BigNumber.from(order.flags), MASK_CLOSE_ONLY),
673
+ limitPrice: limitPrice,
674
+ keepPositionLvg: containsFlag(BigNumber.from(order.flags), MASK_KEEP_POS_LEVERAGE),
675
+ brokerFeeTbps: order.brokerFeeTbps == 0 ? undefined : Number(order.brokerFeeTbps),
676
+ brokerAddr: order.brokerAddr == ZERO_ADDRESS ? undefined : order.brokerAddr,
677
+ brokerSignature: order.brokerSignature == "0x" ? undefined : order.brokerSignature,
678
+ stopPrice: stopPrice,
679
+ leverage: ABK64x64ToFloat(BigNumber.from(order.fLeverage)),
680
+ deadline: Number(order.iDeadline),
681
+ timestamp: Number(order.createdTimestamp),
682
+ submittedTimestamp: Number(order.submittedTimestamp),
683
+ };
684
+ return userOrder;
685
+ };
686
+ /**
687
+ * Transform the convenient form of the order into a smart-contract accepted type of order
688
+ * @param order order type
689
+ * @param traderAddr address of the trader
690
+ * @param symbolToPerpetualMap mapping of symbol to perpetual Id
691
+ * @returns SmartContractOrder
692
+ */
693
+ PerpetualDataHandler.toSmartContractOrder = function (order, traderAddr, perpStaticInfo) {
694
+ // this revers if order is invalid
695
+ PerpetualDataHandler.checkOrder(order, perpStaticInfo);
696
+ // translate order
697
+ var flags = PerpetualDataHandler._orderTypeToFlag(order);
698
+ var brokerSig = order.brokerSignature == undefined ? [] : order.brokerSignature;
699
+ var perpetualId = PerpetualDataHandler.symbolToPerpetualId(order.symbol, perpStaticInfo);
700
+ var fAmount;
701
+ if (order.side == BUY_SIDE) {
702
+ fAmount = floatToABK64x64(Math.abs(order.quantity));
703
+ }
704
+ else if (order.side == SELL_SIDE) {
705
+ fAmount = floatToABK64x64(-Math.abs(order.quantity));
706
+ }
707
+ else {
708
+ throw Error("invalid side in order spec, use ".concat(BUY_SIDE, " or ").concat(SELL_SIDE));
709
+ }
710
+ var fLimitPrice;
711
+ if (order.limitPrice == undefined) {
712
+ // we need to set the limit price to infinity or zero for
713
+ // the trade to go through
714
+ // Also: stop orders always have limits set, so even for this case
715
+ // we set the limit to 0 or infinity
716
+ fLimitPrice = order.side == BUY_SIDE ? MAX_64x64 : BigNumber.from(0);
717
+ }
718
+ else {
719
+ fLimitPrice = floatToABK64x64(order.limitPrice);
720
+ }
721
+ var iDeadline = order.deadline == undefined ? Date.now() / 1000 + ORDER_MAX_DURATION_SEC : order.deadline;
722
+ var fTriggerPrice = order.stopPrice == undefined ? BigNumber.from(0) : floatToABK64x64(order.stopPrice);
723
+ var smOrder = {
724
+ flags: flags,
725
+ iPerpetualId: BigNumber.from(perpetualId),
726
+ brokerFeeTbps: order.brokerFeeTbps == undefined ? BigNumber.from(0) : BigNumber.from(order.brokerFeeTbps),
727
+ traderAddr: traderAddr,
728
+ brokerAddr: order.brokerAddr == undefined ? ZERO_ADDRESS : order.brokerAddr,
729
+ referrerAddr: ZERO_ADDRESS,
730
+ brokerSignature: brokerSig,
731
+ fAmount: fAmount,
732
+ fLimitPrice: fLimitPrice,
733
+ fTriggerPrice: fTriggerPrice,
734
+ fLeverage: order.leverage == undefined ? BigNumber.from(0) : floatToABK64x64(order.leverage),
735
+ iDeadline: BigNumber.from(Math.round(iDeadline)),
736
+ createdTimestamp: BigNumber.from(Math.round(order.timestamp)),
737
+ submittedTimestamp: 0,
738
+ };
739
+ return smOrder;
740
+ };
741
+ /**
742
+ * Converts a smart contract order to a client order
743
+ * @param scOrder Smart contract order
744
+ * @param parentChildIds Optional parent-child dependency
745
+ * @returns Client order that can be submitted to the corresponding LOB
746
+ */
747
+ PerpetualDataHandler.fromSmartContratOrderToClientOrder = function (scOrder, parentChildIds) {
748
+ return {
749
+ flags: scOrder.flags,
750
+ iPerpetualId: scOrder.iPerpetualId,
751
+ brokerFeeTbps: scOrder.brokerFeeTbps,
752
+ traderAddr: scOrder.traderAddr,
753
+ brokerAddr: scOrder.brokerAddr,
754
+ referrerAddr: scOrder.referrerAddr,
755
+ brokerSignature: scOrder.brokerSignature,
756
+ fAmount: scOrder.fAmount,
757
+ fLimitPrice: scOrder.fLimitPrice,
758
+ fTriggerPrice: scOrder.fTriggerPrice,
759
+ fLeverage: scOrder.fLeverage,
760
+ iDeadline: scOrder.iDeadline,
761
+ createdTimestamp: scOrder.createdTimestamp,
762
+ parentChildDigest1: parentChildIds ? parentChildIds[0] : ZERO_ORDER_ID,
763
+ parentChildDigest2: parentChildIds ? parentChildIds[1] : ZERO_ORDER_ID,
764
+ };
765
+ };
766
+ /**
767
+ * Converts a user-friendly order to a client order
768
+ * @param order Order
769
+ * @param parentChildIds Optional parent-child dependency
770
+ * @returns Client order that can be submitted to the corresponding LOB
771
+ */
772
+ PerpetualDataHandler.toClientOrder = function (order, traderAddr, perpStaticInfo, parentChildIds) {
773
+ var scOrder = PerpetualDataHandler.toSmartContractOrder(order, traderAddr, perpStaticInfo);
774
+ return PerpetualDataHandler.fromSmartContratOrderToClientOrder(scOrder, parentChildIds);
775
+ };
776
+ /**
777
+ * Converts an order as stored in the LOB smart contract into a user-friendly order type
778
+ * @param obOrder Order-book contract order type
779
+ * @returns User friendly order struct
780
+ */
781
+ PerpetualDataHandler.fromClientOrder = function (obOrder, perpStaticInfo) {
782
+ var scOrder = {
783
+ flags: obOrder.flags,
784
+ iPerpetualId: obOrder.iPerpetualId,
785
+ brokerFeeTbps: obOrder.brokerFeeTbps,
786
+ traderAddr: obOrder.traderAddr,
787
+ brokerAddr: obOrder.brokerAddr,
788
+ referrerAddr: obOrder.referrerAddr,
789
+ brokerSignature: obOrder.brokerSignature,
790
+ fAmount: obOrder.fAmount,
791
+ fLimitPrice: obOrder.fLimitPrice,
792
+ fTriggerPrice: obOrder.fTriggerPrice,
793
+ fLeverage: obOrder.fLeverage,
794
+ iDeadline: obOrder.iDeadline,
795
+ createdTimestamp: obOrder.createdTimestamp,
796
+ };
797
+ var order = PerpetualDataHandler.fromSmartContractOrder(scOrder, perpStaticInfo);
798
+ if (obOrder.parentChildDigest1 != ZERO_ORDER_ID || obOrder.parentChildDigest2 != ZERO_ORDER_ID) {
799
+ order.parentChildOrderIds = [obOrder.parentChildDigest1, obOrder.parentChildDigest2];
800
+ }
801
+ return order;
802
+ };
803
+ PerpetualDataHandler._flagToOrderType = function (order) {
804
+ var flag = BigNumber.from(order.flags);
805
+ var isLimit = containsFlag(flag, MASK_LIMIT_ORDER);
806
+ var hasLimit = !BigNumber.from(order.fLimitPrice).eq(0) || !BigNumber.from(order.fLimitPrice).eq(MAX_64x64);
807
+ var isStop = containsFlag(flag, MASK_STOP_ORDER);
808
+ if (isStop && hasLimit) {
809
+ return ORDER_TYPE_STOP_LIMIT;
810
+ }
811
+ else if (isStop && !hasLimit) {
812
+ return ORDER_TYPE_STOP_MARKET;
813
+ }
814
+ else if (isLimit && !isStop) {
815
+ return ORDER_TYPE_LIMIT;
816
+ }
817
+ else {
818
+ return ORDER_TYPE_MARKET;
819
+ }
820
+ };
821
+ /**
822
+ * Determine the correct order flags based on the order-properties.
823
+ * Checks for some misspecifications.
824
+ * @param order order type
825
+ * @returns BigNumber flags
826
+ */
827
+ PerpetualDataHandler._orderTypeToFlag = function (order) {
828
+ var flag;
829
+ order.type = order.type.toUpperCase();
830
+ switch (order.type) {
831
+ case ORDER_TYPE_LIMIT:
832
+ flag = MASK_LIMIT_ORDER;
833
+ break;
834
+ case ORDER_TYPE_MARKET:
835
+ flag = MASK_MARKET_ORDER;
836
+ break;
837
+ case ORDER_TYPE_STOP_MARKET:
838
+ flag = MASK_STOP_ORDER;
839
+ break;
840
+ case ORDER_TYPE_STOP_LIMIT:
841
+ flag = MASK_STOP_ORDER;
842
+ break;
843
+ default: {
844
+ throw Error("Order type ".concat(order.type, " not found."));
845
+ }
846
+ }
847
+ if (order.keepPositionLvg != undefined && order.keepPositionLvg) {
848
+ flag = combineFlags(flag, MASK_KEEP_POS_LEVERAGE);
849
+ }
850
+ if (order.reduceOnly != undefined && order.reduceOnly) {
851
+ flag = combineFlags(flag, MASK_CLOSE_ONLY);
852
+ }
853
+ if ((order.type == ORDER_TYPE_LIMIT || order.type == ORDER_TYPE_STOP_LIMIT) && order.limitPrice == undefined) {
854
+ throw Error("Order type ".concat(order.type, " requires limit price."));
855
+ }
856
+ if ((order.type == ORDER_TYPE_STOP_MARKET || order.type == ORDER_TYPE_STOP_LIMIT) && order.stopPrice == undefined) {
857
+ throw Error("Order type ".concat(order.type, " requires trigger price."));
858
+ }
859
+ if ((order.type == ORDER_TYPE_MARKET || order.type == ORDER_TYPE_LIMIT) && order.stopPrice != undefined) {
860
+ throw Error("Order type ".concat(order.type, " has no trigger price."));
861
+ }
862
+ if (order.type != ORDER_TYPE_STOP_LIMIT && order.type != ORDER_TYPE_STOP_MARKET && order.stopPrice != undefined) {
863
+ throw Error("Order type ".concat(order.type, " has no trigger price."));
864
+ }
865
+ return flag;
866
+ };
867
+ PerpetualDataHandler._getLotSize = function (symbol, symbolToPerpStaticInfo) {
868
+ var perpInfo = symbolToPerpStaticInfo.get(symbol);
869
+ if (perpInfo == undefined) {
870
+ throw new Error("no info for perpetual ".concat(symbol));
871
+ }
872
+ return perpInfo.lotSizeBC;
873
+ };
874
+ PerpetualDataHandler._getMinimalPositionSize = function (symbol, symbolToPerpStaticInfo) {
875
+ return 10 * PerpetualDataHandler._getLotSize(symbol, symbolToPerpStaticInfo);
876
+ };
877
+ /**
878
+ * Get NodeSDKConfig from a chain ID, known config name, or custom file location..
879
+ * @param configNameOrfileLocation Name of a known default config, or chain ID, or json-file with required variables for config
880
+ * @param version Config version number. Defaults to highest version if name or chain ID are not unique
881
+ * @returns NodeSDKConfig
882
+ */
883
+ PerpetualDataHandler.readSDKConfig = function (configNameOrChainIdOrFileLocation, version) {
884
+ var config;
885
+ if (typeof configNameOrChainIdOrFileLocation === "number") {
886
+ // user entered a chain ID
887
+ config = this.getConfigByChainId(configNameOrChainIdOrFileLocation, version);
888
+ }
889
+ else if (typeof configNameOrChainIdOrFileLocation === "string") {
890
+ if (/\.json$/.test(configNameOrChainIdOrFileLocation)) {
891
+ // user entered a string that ends in .json
892
+ config = this.getConfigByLocation(configNameOrChainIdOrFileLocation);
893
+ }
894
+ else {
895
+ // user entered a name
896
+ config = this.getConfigByName(configNameOrChainIdOrFileLocation, version);
897
+ }
898
+ }
899
+ else {
900
+ // error
901
+ throw Error("Please specify a chain ID, config name, or custom file location.");
902
+ }
903
+ if (config == undefined) {
904
+ throw Error("Config ".concat(configNameOrChainIdOrFileLocation, " not found."));
905
+ }
906
+ return config;
907
+ };
908
+ /**
909
+ * Get a NodeSDKConfig from its name
910
+ * @param name Name of the known config
911
+ * @param version Version of the config. Defaults to highest available.
912
+ * @returns NodeSDKConfig
913
+ */
914
+ PerpetualDataHandler.getConfigByName = function (name, version) {
915
+ var configFile = DEFAULT_CONFIG.filter(function (c) { return c.name == name; });
916
+ if (configFile.length == 0) {
917
+ throw Error("No SDK config found with name ".concat(name, "."));
918
+ }
919
+ if (configFile.length == 1) {
920
+ return configFile[0];
921
+ }
922
+ else {
923
+ if (version === undefined) {
924
+ configFile = configFile.sort(function (conf) { return conf.version; });
925
+ return configFile[0];
926
+ }
927
+ else {
928
+ return configFile.find(function (conf) { return conf.version === version; });
929
+ }
930
+ }
931
+ };
932
+ /**
933
+ * Get a NodeSDKConfig from a json file.
934
+ * @param filename Location of the file
935
+ * @param version Version of the config. Defaults to highest available.
936
+ * @returns NodeSDKConfig
937
+ */
938
+ PerpetualDataHandler.getConfigByLocation = function (filename) {
939
+ // file path: this throws a warning during build - that's ok, it just won't work in react apps
940
+ // eslint-disable-next-line
941
+ var configFile = require(filename);
942
+ loadABIs(configFile);
943
+ return configFile;
944
+ };
945
+ /**
946
+ * Get a NodeSDKConfig from its chain Id
947
+ * @param chainId Chain Id
948
+ * @param version Version of the config. Defaults to highest available.
949
+ * @returns NodeSDKConfig
950
+ */
951
+ PerpetualDataHandler.getConfigByChainId = function (chainId, version) {
952
+ var configFile = DEFAULT_CONFIG.filter(function (c) { return c.chainId == chainId; });
953
+ if (configFile.length == 0) {
954
+ throw Error("No SDK config found for chain ID ".concat(chainId, "."));
955
+ }
956
+ if (configFile.length == 1) {
957
+ return configFile[0];
958
+ }
959
+ else {
960
+ if (version === undefined) {
961
+ configFile = configFile.sort(function (conf) { return conf.version; });
962
+ return configFile[0];
963
+ }
964
+ else {
965
+ return configFile.find(function (conf) { return conf.version === version; });
966
+ }
967
+ }
968
+ };
969
+ /**
970
+ * Get the ABI of a function in a given contract
971
+ * @param contract A contract instance, e.g. this.proxyContract
972
+ * @param functionName Name of the function whose ABI we want
973
+ * @returns Function ABI as a single JSON string
974
+ */
975
+ PerpetualDataHandler._getABIFromContract = function (contract, functionName) {
976
+ var FormatTypes = ethers.utils.FormatTypes;
977
+ return contract.interface.getFunction(functionName).format(FormatTypes.full);
978
+ };
979
+ /**
980
+ * Gets the pool index (in exchangeInfo) corresponding to a given symbol.
981
+ * @param symbol Symbol of the form ETH-USD-MATIC
982
+ * @returns Pool index
983
+ */
984
+ PerpetualDataHandler.prototype.getPoolIndexFromSymbol = function (symbol) {
985
+ var pools = this.poolStaticInfos;
986
+ var poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
987
+ var k = 0;
988
+ while (k < pools.length) {
989
+ if (pools[k].poolId == poolId) {
990
+ // pool found
991
+ return k;
992
+ }
993
+ k++;
994
+ }
995
+ return -1;
996
+ };
997
+ PerpetualDataHandler.prototype.getMarginTokenFromSymbol = function (symbol) {
998
+ var pools = this.poolStaticInfos;
999
+ var poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
1000
+ var k = 0;
1001
+ while (k < pools.length) {
1002
+ if (pools[k].poolId == poolId) {
1003
+ // pool found
1004
+ return pools[k].poolMarginTokenAddr;
1005
+ }
1006
+ k++;
1007
+ }
1008
+ return undefined;
1009
+ };
1010
+ PerpetualDataHandler.prototype.getABI = function (contract) {
1011
+ switch (contract) {
1012
+ case "proxy":
1013
+ return this.proxyABI;
1014
+ case "lob":
1015
+ return this.lobABI;
1016
+ default:
1017
+ return undefined;
1018
+ }
1019
+ };
1020
+ /**
1021
+ * Performs basic validity checks on a given order
1022
+ * @param order Order struct
1023
+ * @param traderAccount Trader account
1024
+ * @param perpStaticInfo Symbol to perpetual info map
1025
+ */
1026
+ PerpetualDataHandler.checkOrder = function (order,
1027
+ // traderAccount: MarginAccount,
1028
+ perpStaticInfo) {
1029
+ // check side
1030
+ if (order.side != BUY_SIDE && order.side != SELL_SIDE) {
1031
+ throw Error("order side must be ".concat(BUY_SIDE, " or ").concat(SELL_SIDE));
1032
+ }
1033
+ // check amount
1034
+ var lotSize = perpStaticInfo.get(order.symbol).lotSizeBC;
1035
+ // let curPos =
1036
+ // traderAccount.side == CLOSED_SIDE
1037
+ // ? 0
1038
+ // : (traderAccount.side == BUY_SIDE ? 1 : -1) * traderAccount.positionNotionalBaseCCY;
1039
+ // let newPos = curPos + (order.side == BUY_SIDE ? 1 : -1) * order.quantity;
1040
+ // if (Math.abs(order.quantity) < lotSize || (Math.abs(newPos) >= lotSize && Math.abs(newPos) < 10 * lotSize)) {
1041
+ if (Math.abs(order.quantity) < lotSize) {
1042
+ throw Error("trade amount too small: ".concat(order.quantity, " ").concat(perpStaticInfo.get(order.symbol).S2Symbol));
1043
+ }
1044
+ // check limit price
1045
+ if (order.side == BUY_SIDE && order.limitPrice != undefined && order.limitPrice <= 0) {
1046
+ throw Error("invalid limit price for buy order: ".concat(order.limitPrice));
1047
+ }
1048
+ // broker fee
1049
+ if (order.brokerFeeTbps != undefined && order.brokerFeeTbps < 0) {
1050
+ throw Error("invalid broker fee: ".concat(order.brokerFeeTbps / 10, " bps"));
1051
+ }
1052
+ // stop price
1053
+ if (order.stopPrice != undefined && order.stopPrice < 0) {
1054
+ throw Error("invalid stop price: ".concat(order.stopPrice));
1055
+ }
1056
+ };
1057
+ return PerpetualDataHandler;
1058
+ }());
1059
+ export default PerpetualDataHandler;
1060
+ //# sourceMappingURL=perpetualDataHandler.js.map