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