@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.
- package/dist/cjs/abi/testnet/IPerpetualManager.json +5215 -0
- package/dist/cjs/abi/testnet/LimitOrderBook.json +1075 -0
- package/dist/cjs/abi/zkevmTestnet/IPerpetualManager.json +5215 -0
- package/dist/cjs/abi/zkevmTestnet/LimitOrderBook.json +1075 -0
- package/dist/cjs/abi/zkevmTestnet/LimitOrderBookFactory.json +135 -0
- package/dist/cjs/accountTrade.js +441 -0
- package/dist/cjs/accountTrade.js.map +1 -0
- package/dist/{src → cjs}/brokerTool.js +31 -84
- package/dist/cjs/brokerTool.js.map +1 -0
- package/dist/cjs/config/defaultConfig.json +47 -0
- package/dist/cjs/config/mockSwap.json +4 -0
- package/dist/cjs/config/priceFeedConfig.json +104 -0
- package/dist/cjs/config/symbolList.json +13 -0
- package/dist/cjs/d8XMath.js.map +1 -0
- package/dist/cjs/index.js +29 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/liquidatorTool.js +287 -0
- package/dist/cjs/liquidatorTool.js.map +1 -0
- package/dist/{src → cjs}/liquidityProviderTool.js +12 -65
- package/dist/cjs/liquidityProviderTool.js.map +1 -0
- package/dist/{src → cjs}/marketData.js +52 -134
- package/dist/cjs/marketData.js.map +1 -0
- package/dist/{src → cjs}/nodeSDKTypes.d.ts +5 -5
- package/dist/cjs/nodeSDKTypes.js +64 -0
- package/dist/cjs/nodeSDKTypes.js.map +1 -0
- package/dist/{src → cjs}/orderReferrerTool.d.ts +12 -5
- package/dist/{src → cjs}/orderReferrerTool.js +114 -112
- package/dist/cjs/orderReferrerTool.js.map +1 -0
- package/dist/{src → cjs}/perpetualDataHandler.d.ts +1 -1
- package/dist/{src → cjs}/perpetualDataHandler.js +47 -109
- package/dist/cjs/perpetualDataHandler.js.map +1 -0
- package/dist/{src → cjs}/perpetualEventHandler.d.ts +3 -3
- package/dist/{src → cjs}/perpetualEventHandler.js +12 -74
- package/dist/cjs/perpetualEventHandler.js.map +1 -0
- package/dist/cjs/priceFeeds.js +466 -0
- package/dist/cjs/priceFeeds.js.map +1 -0
- package/dist/{src → cjs}/traderDigests.js +7 -43
- package/dist/cjs/traderDigests.js.map +1 -0
- package/dist/{src → cjs}/traderInterface.js +13 -66
- package/dist/cjs/traderInterface.js.map +1 -0
- package/dist/{src → cjs}/triangulator.js +2 -17
- package/dist/cjs/triangulator.js.map +1 -0
- package/dist/{src → cjs}/utils.js +3 -29
- package/dist/cjs/utils.js.map +1 -0
- package/dist/cjs/version.d.ts +1 -0
- package/dist/{src → cjs}/version.js +1 -1
- package/dist/cjs/version.js.map +1 -0
- package/dist/{src → cjs}/writeAccessHandler.js +12 -65
- package/dist/cjs/writeAccessHandler.js.map +1 -0
- package/dist/esm/abi/ERC20.json +288 -0
- package/dist/esm/abi/MockTokenSwap.json +186 -0
- package/dist/{abi/testnet → esm/abi/central-park}/IPerpetualManager.json +404 -214
- package/dist/{abi/testnet → esm/abi/central-park}/LimitOrderBook.json +197 -15
- package/dist/esm/abi/central-park/LimitOrderBookFactory.json +135 -0
- package/dist/esm/abi/testnet/IPerpetualManager.json +5215 -0
- package/dist/esm/abi/testnet/LimitOrderBook.json +1075 -0
- package/dist/esm/abi/testnet/LimitOrderBookFactory.json +135 -0
- package/dist/esm/abi/zkevmTestnet/IPerpetualManager.json +5215 -0
- package/dist/esm/abi/zkevmTestnet/LimitOrderBook.json +1075 -0
- package/dist/esm/abi/zkevmTestnet/LimitOrderBookFactory.json +135 -0
- package/dist/esm/accountTrade.d.ts +221 -0
- package/dist/{src → esm}/accountTrade.js +22 -93
- package/dist/esm/accountTrade.js.map +1 -0
- package/dist/esm/brokerTool.d.ts +318 -0
- package/dist/esm/brokerTool.js +572 -0
- package/dist/esm/brokerTool.js.map +1 -0
- package/dist/esm/config/defaultConfig.json +47 -0
- package/dist/esm/config/mockSwap.json +4 -0
- package/dist/esm/config/priceFeedConfig.json +104 -0
- package/dist/esm/config/symbolList.json +13 -0
- package/dist/esm/d8XMath.d.ts +122 -0
- package/dist/esm/d8XMath.js +247 -0
- package/dist/esm/d8XMath.js.map +1 -0
- package/{src/index.ts → dist/esm/index.d.ts} +1 -15
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/liquidatorTool.d.ts +158 -0
- package/dist/{src → esm}/liquidatorTool.js +10 -65
- package/dist/esm/liquidatorTool.js.map +1 -0
- package/dist/esm/liquidityProviderTool.d.ts +126 -0
- package/dist/esm/liquidityProviderTool.js +218 -0
- package/dist/esm/liquidityProviderTool.js.map +1 -0
- package/dist/esm/marketData.d.ts +309 -0
- package/dist/esm/marketData.js +1007 -0
- package/dist/esm/marketData.js.map +1 -0
- package/dist/esm/nodeSDKTypes.d.ts +266 -0
- package/dist/esm/nodeSDKTypes.js +60 -0
- package/dist/esm/nodeSDKTypes.js.map +1 -0
- package/dist/esm/orderReferrerTool.d.ts +196 -0
- package/dist/esm/orderReferrerTool.js +491 -0
- package/dist/esm/orderReferrerTool.js.map +1 -0
- package/dist/esm/perpetualDataHandler.d.ts +220 -0
- package/dist/esm/perpetualDataHandler.js +1060 -0
- package/dist/esm/perpetualDataHandler.js.map +1 -0
- package/dist/esm/perpetualEventHandler.d.ts +179 -0
- package/dist/esm/perpetualEventHandler.js +435 -0
- package/dist/esm/perpetualEventHandler.js.map +1 -0
- package/dist/esm/priceFeeds.d.ts +115 -0
- package/dist/{src → esm}/priceFeeds.js +16 -83
- package/dist/esm/priceFeeds.js.map +1 -0
- package/dist/esm/traderDigests.d.ts +21 -0
- package/dist/esm/traderDigests.js +80 -0
- package/dist/esm/traderDigests.js.map +1 -0
- package/dist/esm/traderInterface.d.ts +79 -0
- package/dist/esm/traderInterface.js +196 -0
- package/dist/esm/traderInterface.js.map +1 -0
- package/dist/esm/triangulator.d.ts +27 -0
- package/dist/esm/triangulator.js +110 -0
- package/dist/esm/triangulator.js.map +1 -0
- package/dist/esm/utils.d.ts +59 -0
- package/dist/esm/utils.js +138 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/esm/version.d.ts +1 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/esm/writeAccessHandler.d.ts +50 -0
- package/dist/esm/writeAccessHandler.js +157 -0
- package/dist/esm/writeAccessHandler.js.map +1 -0
- package/package.json +16 -26
- package/dist/bundle.js +0 -36793
- package/dist/config/defaultConfig.json +0 -47
- package/dist/config/mockSwap.json +0 -4
- package/dist/config/priceFeedConfig.json +0 -104
- package/dist/config/symbolList.json +0 -13
- package/dist/src/index.js +0 -45
- package/dist/src/nodeSDKTypes.js +0 -115
- package/dist/src/version.d.ts +0 -1
- package/module.d.ts +0 -1
- package/src/accountTrade.ts +0 -392
- package/src/brokerTool.ts +0 -507
- package/src/d8XMath.ts +0 -319
- package/src/liquidatorTool.ts +0 -258
- package/src/liquidityProviderTool.ts +0 -186
- package/src/marketData.ts +0 -946
- package/src/nodeSDKTypes.ts +0 -293
- package/src/orderReferrerTool.ts +0 -389
- package/src/perpetualDataHandler.ts +0 -1061
- package/src/perpetualEventHandler.ts +0 -455
- package/src/priceFeeds.ts +0 -381
- package/src/traderDigests.ts +0 -91
- package/src/traderInterface.ts +0 -159
- package/src/triangulator.ts +0 -105
- package/src/utils.ts +0 -134
- package/src/version.ts +0 -1
- package/src/writeAccessHandler.ts +0 -127
- /package/dist/{abi → cjs/abi}/ERC20.json +0 -0
- /package/dist/{abi → cjs/abi}/MockTokenSwap.json +0 -0
- /package/dist/{abi → cjs/abi}/central-park/IPerpetualManager.json +0 -0
- /package/dist/{abi → cjs/abi}/central-park/LimitOrderBook.json +0 -0
- /package/dist/{abi → cjs/abi}/central-park/LimitOrderBookFactory.json +0 -0
- /package/dist/{abi → cjs/abi}/testnet/LimitOrderBookFactory.json +0 -0
- /package/dist/{src → cjs}/accountTrade.d.ts +0 -0
- /package/dist/{src → cjs}/brokerTool.d.ts +0 -0
- /package/dist/{src → cjs}/d8XMath.d.ts +0 -0
- /package/dist/{src → cjs}/d8XMath.js +0 -0
- /package/dist/{src → cjs}/index.d.ts +0 -0
- /package/dist/{src → cjs}/liquidatorTool.d.ts +0 -0
- /package/dist/{src → cjs}/liquidityProviderTool.d.ts +0 -0
- /package/dist/{src → cjs}/marketData.d.ts +0 -0
- /package/dist/{src → cjs}/priceFeeds.d.ts +0 -0
- /package/dist/{src → cjs}/traderDigests.d.ts +0 -0
- /package/dist/{src → cjs}/traderInterface.d.ts +0 -0
- /package/dist/{src → cjs}/triangulator.d.ts +0 -0
- /package/dist/{src → cjs}/utils.d.ts +0 -0
- /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
|