@d8x/perpetuals-sdk 0.7.4 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/accountTrade.js +134 -239
- 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/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/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/ShareToken__factory.js +9 -12
- package/dist/cjs/contracts/factories/ShareToken__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js.map +1 -1
- package/dist/cjs/contracts/factories/zkevmTestnet/ShareToken__factory.js +9 -12
- package/dist/cjs/contracts/factories/zkevmTestnet/ShareToken__factory.js.map +1 -1
- package/dist/cjs/contracts/index.js +1 -1
- package/dist/cjs/d8XMath.d.ts +7 -0
- package/dist/cjs/d8XMath.js +81 -61
- package/dist/cjs/d8XMath.js.map +1 -1
- package/dist/cjs/index.js +11 -11
- 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 -64
- package/dist/cjs/liquidityProviderTool.js.map +1 -1
- package/dist/cjs/marketData.d.ts +8 -1
- package/dist/cjs/marketData.js +641 -949
- package/dist/cjs/marketData.js.map +1 -1
- package/dist/cjs/nodeSDKTypes.d.ts +1 -0
- package/dist/cjs/nodeSDKTypes.js +10 -22
- package/dist/cjs/nodeSDKTypes.js.map +1 -1
- package/dist/cjs/orderReferrerTool.js +200 -321
- package/dist/cjs/orderReferrerTool.js.map +1 -1
- package/dist/cjs/perpetualDataHandler.d.ts +11 -0
- package/dist/cjs/perpetualDataHandler.js +422 -535
- 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/accountTrade.js +126 -233
- 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/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/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/ShareToken__factory.js +8 -12
- package/dist/esm/contracts/factories/ShareToken__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/IPerpetualManager__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBookFactory__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/LimitOrderBook__factory.js.map +1 -1
- package/dist/esm/contracts/factories/zkevmTestnet/ShareToken__factory.js +8 -12
- package/dist/esm/contracts/factories/zkevmTestnet/ShareToken__factory.js.map +1 -1
- package/dist/esm/d8XMath.d.ts +7 -0
- package/dist/esm/d8XMath.js +77 -58
- package/dist/esm/d8XMath.js.map +1 -1
- package/dist/esm/liquidatorTool.js +77 -136
- package/dist/esm/liquidatorTool.js.map +1 -1
- package/dist/esm/liquidityProviderTool.js +30 -63
- package/dist/esm/liquidityProviderTool.js.map +1 -1
- package/dist/esm/marketData.d.ts +8 -1
- package/dist/esm/marketData.js +632 -942
- package/dist/esm/marketData.js.map +1 -1
- package/dist/esm/nodeSDKTypes.d.ts +1 -0
- package/dist/esm/nodeSDKTypes.js +36 -48
- package/dist/esm/nodeSDKTypes.js.map +1 -1
- package/dist/esm/orderReferrerTool.js +194 -317
- package/dist/esm/orderReferrerTool.js.map +1 -1
- package/dist/esm/perpetualDataHandler.d.ts +11 -0
- package/dist/esm/perpetualDataHandler.js +413 -528
- 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 +70 -106
- package/dist/esm/writeAccessHandler.js.map +1 -1
- package/package.json +1 -1
- package/src/d8XMath.ts +21 -0
- package/src/liquidityProviderTool.ts +5 -4
- package/src/marketData.ts +26 -0
- package/src/nodeSDKTypes.ts +1 -0
- package/src/perpetualDataHandler.ts +27 -0
- package/src/version.ts +1 -1
- package/src/writeAccessHandler.ts +3 -3
|
@@ -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,216 +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
|
-
if (poolCCY == "") {
|
|
141
|
-
_a = tslib_1.__read(perp.S2Symbol.split("-"), 2), base = _a[0], quote = _a[1];
|
|
142
|
-
base3 = perp.S3Symbol.split("-")[0];
|
|
143
|
-
// we find out the pool currency by looking at all perpetuals
|
|
144
|
-
// from the perpetual.
|
|
145
|
-
if (perp.collateralCurrencyType == nodeSDKTypes_1.COLLATERAL_CURRENCY_BASE) {
|
|
146
|
-
poolCCY = base;
|
|
147
|
-
}
|
|
148
|
-
else if (perp.collateralCurrencyType == nodeSDKTypes_1.COLLATERAL_CURRENCY_QUOTE) {
|
|
149
|
-
poolCCY = quote;
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
poolCCY = base3;
|
|
153
|
-
}
|
|
154
|
-
// set pool currency
|
|
155
|
-
this.poolStaticInfos[perp.poolId - 1].poolMarginSymbol = poolCCY;
|
|
156
|
-
// push pool margin token address into map
|
|
157
|
-
this.symbolToTokenAddrMap.set(poolCCY, this.poolStaticInfos[perp.poolId - 1].poolMarginTokenAddr);
|
|
158
|
-
}
|
|
159
|
-
currentSymbol3 = perp.S2Symbol + "-" + poolCCY;
|
|
160
|
-
this.symbolToPerpStaticInfo.set(currentSymbol3, perpStaticInfos[j]);
|
|
161
|
-
}
|
|
162
|
-
// pre-calculate all triangulation paths so we can easily get from
|
|
163
|
-
// the prices of price-feeds to the index price required, e.g.
|
|
164
|
-
// BTC-USDC : BTC-USD / USDC-USD
|
|
165
|
-
this.priceFeedGetter.initializeTriangulations(requiredPairs);
|
|
166
|
-
try {
|
|
167
|
-
// fill this.perpetualIdToSymbol
|
|
168
|
-
for (_b = tslib_1.__values(this.symbolToPerpStaticInfo), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
169
|
-
_d = tslib_1.__read(_c.value, 2), key = _d[0], info = _d[1];
|
|
170
|
-
this.perpetualIdToSymbol.set(info.id, key);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
174
|
-
finally {
|
|
175
|
-
try {
|
|
176
|
-
if (_c && !_c.done && (_e = _b.return)) _e.call(_b);
|
|
177
|
-
}
|
|
178
|
-
finally { if (e_1) throw e_1.error; }
|
|
179
|
-
}
|
|
180
|
-
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;
|
|
181
121
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
+
}
|
|
185
145
|
/**
|
|
186
146
|
* Get pool symbol given a pool Id.
|
|
187
147
|
* @param {number} poolId Pool Id.
|
|
188
148
|
* @returns {symbol} Pool symbol, e.g. "USDC".
|
|
189
149
|
*/
|
|
190
|
-
|
|
150
|
+
getSymbolFromPoolId(poolId) {
|
|
191
151
|
return PerpetualDataHandler._getSymbolFromPoolId(poolId, this.poolStaticInfos);
|
|
192
|
-
}
|
|
152
|
+
}
|
|
193
153
|
/**
|
|
194
154
|
* Get pool Id given a pool symbol. Pool IDs start at 1.
|
|
195
155
|
* @param {string} symbol Pool symbol.
|
|
196
156
|
* @returns {number} Pool Id.
|
|
197
157
|
*/
|
|
198
|
-
|
|
158
|
+
getPoolIdFromSymbol(symbol) {
|
|
199
159
|
return PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
|
|
200
|
-
}
|
|
160
|
+
}
|
|
201
161
|
/**
|
|
202
162
|
* Get perpetual Id given a perpetual symbol.
|
|
203
163
|
* @param {string} symbol Perpetual symbol, e.g. "BTC-USD-MATIC".
|
|
204
164
|
* @returns {number} Perpetual Id.
|
|
205
165
|
*/
|
|
206
|
-
|
|
166
|
+
getPerpIdFromSymbol(symbol) {
|
|
207
167
|
return PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
|
|
208
|
-
}
|
|
168
|
+
}
|
|
209
169
|
/**
|
|
210
170
|
* Get the symbol in long format of the perpetual id
|
|
211
171
|
* @param perpId perpetual id
|
|
212
172
|
*/
|
|
213
|
-
|
|
173
|
+
getSymbolFromPerpId(perpId) {
|
|
214
174
|
return this.perpetualIdToSymbol.get(perpId);
|
|
215
|
-
}
|
|
216
|
-
|
|
175
|
+
}
|
|
176
|
+
symbol4BToLongSymbol(sym) {
|
|
217
177
|
return (0, utils_1.symbol4BToLongSymbol)(sym, this.symbolList);
|
|
218
|
-
}
|
|
178
|
+
}
|
|
219
179
|
/**
|
|
220
180
|
* Get PriceFeedSubmission data required for blockchain queries that involve price data, and the corresponding
|
|
221
181
|
* triangulated prices for the indices S2 and S3
|
|
222
182
|
* @param symbol pool symbol of the form "ETH-USD-MATIC"
|
|
223
183
|
* @returns PriceFeedSubmission and prices for S2 and S3. [S2price, 0] if S3 not defined.
|
|
224
184
|
*/
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
case 0: return [4 /*yield*/, this.priceFeedGetter.fetchFeedPriceInfoAndIndicesForPerpetual(symbol)];
|
|
230
|
-
case 1:
|
|
231
|
-
// fetch prices from required price-feeds (REST)
|
|
232
|
-
return [2 /*return*/, _a.sent()];
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
};
|
|
185
|
+
async fetchPriceSubmissionInfoForPerpetual(symbol) {
|
|
186
|
+
// fetch prices from required price-feeds (REST)
|
|
187
|
+
return await this.priceFeedGetter.fetchFeedPriceInfoAndIndicesForPerpetual(symbol);
|
|
188
|
+
}
|
|
237
189
|
/**
|
|
238
190
|
* Get the symbols required as indices for the given perpetual
|
|
239
191
|
* @param symbol of the form ETH-USD-MATIC, specifying the perpetual
|
|
240
192
|
* @returns name of underlying index prices, e.g. ["MATIC-USD", ""]
|
|
241
193
|
*/
|
|
242
|
-
|
|
194
|
+
getIndexSymbols(symbol) {
|
|
243
195
|
// get index
|
|
244
|
-
|
|
196
|
+
let staticInfo = this.symbolToPerpStaticInfo.get(symbol);
|
|
245
197
|
if (staticInfo == undefined) {
|
|
246
|
-
throw new Error(
|
|
198
|
+
throw new Error(`No static info for perpetual with symbol ${symbol}`);
|
|
247
199
|
}
|
|
248
200
|
return [staticInfo.S2Symbol, staticInfo.S3Symbol];
|
|
249
|
-
}
|
|
201
|
+
}
|
|
250
202
|
/**
|
|
251
203
|
* Get the latest prices for a given perpetual from the offchain oracle
|
|
252
204
|
* networks
|
|
@@ -254,68 +206,60 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
254
206
|
* @returns array of price feed updates that can be submitted to the smart contract
|
|
255
207
|
* and corresponding price information
|
|
256
208
|
*/
|
|
257
|
-
|
|
258
|
-
return
|
|
259
|
-
|
|
260
|
-
switch (_a.label) {
|
|
261
|
-
case 0: return [4 /*yield*/, this.priceFeedGetter.fetchLatestFeedPriceInfoForPerpetual(symbol)];
|
|
262
|
-
case 1: return [2 /*return*/, _a.sent()];
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
};
|
|
209
|
+
async fetchLatestFeedPriceInfo(symbol) {
|
|
210
|
+
return await this.priceFeedGetter.fetchLatestFeedPriceInfoForPerpetual(symbol);
|
|
211
|
+
}
|
|
267
212
|
/**
|
|
268
213
|
* Get list of required pyth price source IDs for given perpetual
|
|
269
214
|
* @param symbol perpetual symbol, e.g., BTC-USD-MATIC
|
|
270
215
|
* @returns list of required pyth price sources for this perpetual
|
|
271
216
|
*/
|
|
272
|
-
|
|
273
|
-
|
|
217
|
+
getPriceIds(symbol) {
|
|
218
|
+
let perpInfo = this.symbolToPerpStaticInfo.get(symbol);
|
|
274
219
|
if (perpInfo == undefined) {
|
|
275
|
-
throw Error(
|
|
220
|
+
throw Error(`Perpetual with symbol ${symbol} not found. Check symbol or use createProxyInstance().`);
|
|
276
221
|
}
|
|
277
222
|
return perpInfo.priceIds;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
223
|
+
}
|
|
224
|
+
static _getSymbolFromPoolId(poolId, staticInfos) {
|
|
225
|
+
let idx = poolId - 1;
|
|
281
226
|
return staticInfos[idx].poolMarginSymbol;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
227
|
+
}
|
|
228
|
+
static _getPoolIdFromSymbol(symbol, staticInfos) {
|
|
229
|
+
let symbols = symbol.split("-");
|
|
285
230
|
//in case user provided ETH-USD-MATIC instead of MATIC; or similar
|
|
286
231
|
if (symbols.length == 3) {
|
|
287
232
|
symbol = symbols[2];
|
|
288
233
|
}
|
|
289
|
-
|
|
234
|
+
let j = 0;
|
|
290
235
|
while (j < staticInfos.length && staticInfos[j].poolMarginSymbol != symbol) {
|
|
291
236
|
j++;
|
|
292
237
|
}
|
|
293
238
|
if (j == staticInfos.length) {
|
|
294
|
-
throw new Error(
|
|
239
|
+
throw new Error(`no pool found for symbol ${symbol}`);
|
|
295
240
|
}
|
|
296
241
|
return j + 1;
|
|
297
|
-
}
|
|
242
|
+
}
|
|
298
243
|
/**
|
|
299
244
|
* Get perpetual symbols for a given pool
|
|
300
245
|
* @param poolSymbol pool symbol such as "MATIC"
|
|
301
246
|
* @returns array of perpetual symbols in this pool
|
|
302
247
|
*/
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
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);
|
|
309
253
|
if (s == undefined) {
|
|
310
254
|
return "";
|
|
311
255
|
}
|
|
312
256
|
return s;
|
|
313
257
|
});
|
|
314
258
|
return perpSymbols;
|
|
315
|
-
}
|
|
316
|
-
|
|
259
|
+
}
|
|
260
|
+
getNestedPerpetualIds() {
|
|
317
261
|
return this.nestedPerpetualIDs;
|
|
318
|
-
}
|
|
262
|
+
}
|
|
319
263
|
/**
|
|
320
264
|
* Collect all perpetuals static info
|
|
321
265
|
* @param {ethers.Contract} _proxyContract perpetuals contract with getter
|
|
@@ -323,65 +267,51 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
323
267
|
* @param {Map<string, string>} symbolList mapping of symbols to convert long-format <-> blockchain-format
|
|
324
268
|
* @returns array with PerpetualStaticInfo for each perpetual
|
|
325
269
|
*/
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
referralRebate: (0, d8XMath_1.ABK64x64ToFloat)(perpInfos[j].fReferralRebateCC),
|
|
360
|
-
priceIds: perpInfos[j].priceIds,
|
|
361
|
-
};
|
|
362
|
-
infoArr.push(info);
|
|
363
|
-
}
|
|
364
|
-
_a.label = 3;
|
|
365
|
-
case 3:
|
|
366
|
-
k++;
|
|
367
|
-
return [3 /*break*/, 1];
|
|
368
|
-
case 4: return [2 /*return*/, infoArr];
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
};
|
|
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
|
+
}
|
|
373
303
|
/**
|
|
374
304
|
* Breaks up an array of nested arrays into chunks of a specified size.
|
|
375
305
|
* @param {number} chunkSize The size of each chunk.
|
|
376
306
|
* @param {number[][]} nestedIDs The array of nested arrays to chunk.
|
|
377
307
|
* @returns {number[][]} An array of subarrays, each containing `chunkSize` or fewer elements from `nestedIDs`.
|
|
378
308
|
*/
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
for (
|
|
383
|
-
|
|
384
|
-
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++) {
|
|
385
315
|
currentChunk.push(currentPoolIds[j]);
|
|
386
316
|
if (currentChunk.length === chunkSize) {
|
|
387
317
|
chunkIDs.push(currentChunk);
|
|
@@ -393,61 +323,48 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
393
323
|
chunkIDs.push(currentChunk);
|
|
394
324
|
}
|
|
395
325
|
return chunkIDs;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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
|
-
PerpetualDataHandler.buildMarginAccountFromState = function (symbol, traderState, symbolToPerpStaticInfo, _pxS2S3) {
|
|
434
|
-
var _a;
|
|
435
|
-
var idx_cash = 3;
|
|
436
|
-
var idx_notional = 4;
|
|
437
|
-
var idx_locked_in = 5;
|
|
438
|
-
var idx_mark_price = 8;
|
|
439
|
-
var idx_lvg = 7;
|
|
440
|
-
var idx_s3 = 9;
|
|
441
|
-
var isEmpty = traderState[idx_notional].eq(0);
|
|
442
|
-
var cash = (0, d8XMath_1.ABK64x64ToFloat)(traderState[idx_cash]);
|
|
443
|
-
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;
|
|
444
361
|
if (!isEmpty) {
|
|
445
|
-
|
|
362
|
+
[S2Liq, S3Liq, tau, pnl, unpaidFundingCC] = PerpetualDataHandler._calculateLiquidationPrice(symbol, traderState, _pxS2S3[0], symbolToPerpStaticInfo);
|
|
446
363
|
fLockedIn = traderState[idx_locked_in];
|
|
447
364
|
side = traderState[idx_locked_in].gt(0) ? nodeSDKTypes_1.BUY_SIDE : nodeSDKTypes_1.SELL_SIDE;
|
|
448
365
|
entryPrice = (0, d8XMath_1.ABK64x64ToFloat)((0, d8XMath_1.div64x64)(fLockedIn, traderState[idx_notional]));
|
|
449
366
|
}
|
|
450
|
-
|
|
367
|
+
let mgn = {
|
|
451
368
|
symbol: symbol,
|
|
452
369
|
positionNotionalBaseCCY: isEmpty ? 0 : (0, d8XMath_1.ABK64x64ToFloat)(traderState[idx_notional].abs()),
|
|
453
370
|
side: isEmpty ? nodeSDKTypes_1.CLOSED_SIDE : side,
|
|
@@ -462,96 +379,56 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
462
379
|
collToQuoteConversion: (0, d8XMath_1.ABK64x64ToFloat)(traderState[idx_s3]),
|
|
463
380
|
};
|
|
464
381
|
return mgn;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
return
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
});
|
|
516
|
-
};
|
|
517
|
-
PerpetualDataHandler._queryPerpetualState = function (symbol, symbolToPerpStaticInfo, _proxyContract, indexPrices, overrides) {
|
|
518
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
519
|
-
var perpId, staticInfo, ccy, _a, S2, S3, ammState, markPrice, state;
|
|
520
|
-
return tslib_1.__generator(this, function (_b) {
|
|
521
|
-
switch (_b.label) {
|
|
522
|
-
case 0:
|
|
523
|
-
perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
|
|
524
|
-
staticInfo = symbolToPerpStaticInfo.get(symbol);
|
|
525
|
-
ccy = symbol.split("-");
|
|
526
|
-
_a = tslib_1.__read([indexPrices[0], indexPrices[1]], 2), S2 = _a[0], S3 = _a[1];
|
|
527
|
-
if (staticInfo.collateralCurrencyType == nodeSDKTypes_1.CollaterlCCY.BASE) {
|
|
528
|
-
S3 = S2;
|
|
529
|
-
}
|
|
530
|
-
else if (staticInfo.collateralCurrencyType == nodeSDKTypes_1.CollaterlCCY.QUOTE) {
|
|
531
|
-
S3 = 1;
|
|
532
|
-
}
|
|
533
|
-
return [4 /*yield*/, _proxyContract.getAMMState(perpId, [S2, S3].map(d8XMath_1.floatToABK64x64), overrides || {})];
|
|
534
|
-
case 1:
|
|
535
|
-
ammState = _b.sent();
|
|
536
|
-
markPrice = S2 * (1 + (0, d8XMath_1.ABK64x64ToFloat)(ammState[8]));
|
|
537
|
-
state = {
|
|
538
|
-
id: perpId,
|
|
539
|
-
state: nodeSDKTypes_1.PERP_STATE_STR[ammState[13].toNumber()],
|
|
540
|
-
baseCurrency: ccy[0],
|
|
541
|
-
quoteCurrency: ccy[1],
|
|
542
|
-
indexPrice: S2,
|
|
543
|
-
collToQuoteIndexPrice: S3,
|
|
544
|
-
markPrice: markPrice,
|
|
545
|
-
midPrice: (0, d8XMath_1.ABK64x64ToFloat)(ammState[10]),
|
|
546
|
-
currentFundingRateBps: (0, d8XMath_1.ABK64x64ToFloat)(ammState[14]) * 1e4,
|
|
547
|
-
openInterestBC: (0, d8XMath_1.ABK64x64ToFloat)(ammState[11]),
|
|
548
|
-
isMarketClosed: indexPrices[2] || indexPrices[3],
|
|
549
|
-
};
|
|
550
|
-
return [2 /*return*/, state];
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
});
|
|
554
|
-
};
|
|
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
|
+
}
|
|
555
432
|
/**
|
|
556
433
|
* Liquidation price
|
|
557
434
|
* @param symbol symbol of the form BTC-USD-MATIC
|
|
@@ -560,34 +437,34 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
560
437
|
* @param symbolToPerpStaticInfo mapping symbol->PerpStaticInfo
|
|
561
438
|
* @returns liquidation mark-price, corresponding collateral/quote conversion
|
|
562
439
|
*/
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
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;
|
|
570
447
|
// const idx_s2 = 10;
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
448
|
+
let S2Liq;
|
|
449
|
+
let S3Liq = (0, d8XMath_1.ABK64x64ToFloat)(traderState[idx_s3]);
|
|
450
|
+
let perpInfo = symbolToPerpStaticInfo.get(symbol);
|
|
574
451
|
if (perpInfo == undefined) {
|
|
575
|
-
throw new Error(
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
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;
|
|
584
461
|
if (perpInfo.collateralCurrencyType == nodeSDKTypes_1.CollaterlCCY.BASE) {
|
|
585
462
|
S2Liq = (0, d8XMath_1.calculateLiquidationPriceCollateralBase)(lockedInValueQC, position, cashCC, tau);
|
|
586
463
|
S3Liq = S2Liq;
|
|
587
464
|
unpaidFunding = unpaidFunding / S2;
|
|
588
465
|
}
|
|
589
466
|
else if (perpInfo.collateralCurrencyType == nodeSDKTypes_1.CollaterlCCY.QUANTO) {
|
|
590
|
-
|
|
467
|
+
let S3 = S3Liq;
|
|
591
468
|
S3Liq = S3;
|
|
592
469
|
S2Liq = (0, d8XMath_1.calculateLiquidationPriceCollateralQuanto)(lockedInValueQC, position, cashCC, tau, S3, Sm);
|
|
593
470
|
unpaidFunding = unpaidFunding / S3;
|
|
@@ -599,9 +476,9 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
599
476
|
S2Liq = S2Liq < 0 ? 0 : S2Liq;
|
|
600
477
|
S3Liq = S3Liq && S3Liq < 0 ? 0 : S3Liq;
|
|
601
478
|
// account cash + pnl = avail cash + pos Sm - L = margin balance
|
|
602
|
-
|
|
479
|
+
let pnl = position * Sm - lockedInValueQC + unpaidFunding;
|
|
603
480
|
return [S2Liq, S3Liq, tau, pnl, unpaidFundingCC];
|
|
604
|
-
}
|
|
481
|
+
}
|
|
605
482
|
/**
|
|
606
483
|
* Finds the perpetual id for a symbol of the form
|
|
607
484
|
* <base>-<quote>-<collateral>. The function first converts the
|
|
@@ -611,57 +488,45 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
611
488
|
* including id mapping
|
|
612
489
|
* @returns perpetual id or it fails
|
|
613
490
|
*/
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
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;
|
|
617
493
|
if (id == undefined) {
|
|
618
|
-
throw Error(
|
|
494
|
+
throw Error(`No perpetual found for symbol ${symbol}`);
|
|
619
495
|
}
|
|
620
496
|
return id;
|
|
621
|
-
}
|
|
622
|
-
|
|
497
|
+
}
|
|
498
|
+
static symbolToBytes4Symbol(symbol) {
|
|
623
499
|
//split by dashes BTC-USD-MATIC
|
|
624
|
-
|
|
500
|
+
let symbols = symbol.split("-");
|
|
625
501
|
if (symbols.length != 3) {
|
|
626
|
-
throw Error(
|
|
502
|
+
throw Error(`Symbol ${symbol} not valid. Expecting CCY-CCY-CCY format`);
|
|
627
503
|
}
|
|
628
504
|
//transform into bytes4 currencies (without the space): "BTC", "USD", "MATC"
|
|
629
|
-
symbols = symbols.map(
|
|
630
|
-
|
|
505
|
+
symbols = symbols.map((x) => {
|
|
506
|
+
let v = (0, utils_1.to4Chars)(x);
|
|
631
507
|
v = v.replace(/\0/g, "");
|
|
632
508
|
return v;
|
|
633
509
|
});
|
|
634
510
|
// concatenate and find perpetual Id in map
|
|
635
511
|
return symbols[0] + "-" + symbols[1] + "-" + symbols[2];
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
var _d = tslib_1.__read(_c.value, 2), key = _d[0], value = _d[1];
|
|
642
|
-
if (value[valueField] === searchValue) {
|
|
643
|
-
return key;
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
648
|
-
finally {
|
|
649
|
-
try {
|
|
650
|
-
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;
|
|
651
517
|
}
|
|
652
|
-
finally { if (e_2) throw e_2.error; }
|
|
653
518
|
}
|
|
654
519
|
return undefined;
|
|
655
|
-
}
|
|
656
|
-
|
|
520
|
+
}
|
|
521
|
+
static fromSmartContractOrder(order, symbolToPerpInfoMap) {
|
|
657
522
|
// find symbol of perpetual id
|
|
658
|
-
|
|
523
|
+
let symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, order.iPerpetualId, "id");
|
|
659
524
|
if (symbol == undefined) {
|
|
660
|
-
throw Error(
|
|
525
|
+
throw Error(`Perpetual id ${order.iPerpetualId} not found. Check with marketData.exchangeInfo().`);
|
|
661
526
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
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);
|
|
665
530
|
if (fLimitPrice.eq(0)) {
|
|
666
531
|
limitPrice = side == nodeSDKTypes_1.BUY_SIDE ? undefined : 0;
|
|
667
532
|
}
|
|
@@ -671,14 +536,14 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
671
536
|
else {
|
|
672
537
|
limitPrice = (0, d8XMath_1.ABK64x64ToFloat)(fLimitPrice);
|
|
673
538
|
}
|
|
674
|
-
|
|
539
|
+
let fStopPrice = bignumber_1.BigNumber.from(order.fTriggerPrice);
|
|
675
540
|
if (fStopPrice.eq(0) || fStopPrice.eq(nodeSDKTypes_1.MAX_64x64)) {
|
|
676
541
|
stopPrice = undefined;
|
|
677
542
|
}
|
|
678
543
|
else {
|
|
679
544
|
stopPrice = (0, d8XMath_1.ABK64x64ToFloat)(fStopPrice);
|
|
680
545
|
}
|
|
681
|
-
|
|
546
|
+
let userOrder = {
|
|
682
547
|
symbol: symbol,
|
|
683
548
|
side: side,
|
|
684
549
|
type: PerpetualDataHandler._flagToOrderType(bignumber_1.BigNumber.from(order.flags), bignumber_1.BigNumber.from(order.fLimitPrice)),
|
|
@@ -696,7 +561,7 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
696
561
|
submittedTimestamp: Number(order.submittedTimestamp),
|
|
697
562
|
};
|
|
698
563
|
return userOrder;
|
|
699
|
-
}
|
|
564
|
+
}
|
|
700
565
|
/**
|
|
701
566
|
* Transform the convenient form of the order into a smart-contract accepted type of order
|
|
702
567
|
* @param order order type
|
|
@@ -704,14 +569,14 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
704
569
|
* @param symbolToPerpetualMap mapping of symbol to perpetual Id
|
|
705
570
|
* @returns SmartContractOrder
|
|
706
571
|
*/
|
|
707
|
-
|
|
572
|
+
static toSmartContractOrder(order, traderAddr, perpStaticInfo) {
|
|
708
573
|
// this revers if order is invalid
|
|
709
574
|
PerpetualDataHandler.checkOrder(order, perpStaticInfo);
|
|
710
575
|
// translate order
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
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;
|
|
715
580
|
if (order.side == nodeSDKTypes_1.BUY_SIDE) {
|
|
716
581
|
fAmount = (0, d8XMath_1.floatToABK64x64)(Math.abs(order.quantity));
|
|
717
582
|
}
|
|
@@ -719,9 +584,9 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
719
584
|
fAmount = (0, d8XMath_1.floatToABK64x64)(-Math.abs(order.quantity));
|
|
720
585
|
}
|
|
721
586
|
else {
|
|
722
|
-
throw Error(
|
|
587
|
+
throw Error(`invalid side in order spec, use ${nodeSDKTypes_1.BUY_SIDE} or ${nodeSDKTypes_1.SELL_SIDE}`);
|
|
723
588
|
}
|
|
724
|
-
|
|
589
|
+
let fLimitPrice;
|
|
725
590
|
if (order.limitPrice == undefined) {
|
|
726
591
|
// we need to set the limit price to infinity or zero for
|
|
727
592
|
// the trade to go through
|
|
@@ -732,9 +597,9 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
732
597
|
else {
|
|
733
598
|
fLimitPrice = (0, d8XMath_1.floatToABK64x64)(order.limitPrice);
|
|
734
599
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
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 = {
|
|
738
603
|
flags: flags,
|
|
739
604
|
iPerpetualId: perpetualId,
|
|
740
605
|
brokerFeeTbps: order.brokerFeeTbps == undefined ? 0 : order.brokerFeeTbps,
|
|
@@ -751,14 +616,14 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
751
616
|
submittedTimestamp: 0,
|
|
752
617
|
};
|
|
753
618
|
return smOrder;
|
|
754
|
-
}
|
|
619
|
+
}
|
|
755
620
|
/**
|
|
756
621
|
* Converts a smart contract order to a client order
|
|
757
622
|
* @param scOrder Smart contract order
|
|
758
623
|
* @param parentChildIds Optional parent-child dependency
|
|
759
624
|
* @returns Client order that can be submitted to the corresponding LOB
|
|
760
625
|
*/
|
|
761
|
-
|
|
626
|
+
static fromSmartContratOrderToClientOrder(scOrder, parentChildIds) {
|
|
762
627
|
return {
|
|
763
628
|
flags: scOrder.flags,
|
|
764
629
|
iPerpetualId: scOrder.iPerpetualId,
|
|
@@ -776,24 +641,24 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
776
641
|
parentChildDigest1: parentChildIds ? parentChildIds[0] : nodeSDKTypes_1.ZERO_ORDER_ID,
|
|
777
642
|
parentChildDigest2: parentChildIds ? parentChildIds[1] : nodeSDKTypes_1.ZERO_ORDER_ID,
|
|
778
643
|
};
|
|
779
|
-
}
|
|
644
|
+
}
|
|
780
645
|
/**
|
|
781
646
|
* Converts a user-friendly order to a client order
|
|
782
647
|
* @param order Order
|
|
783
648
|
* @param parentChildIds Optional parent-child dependency
|
|
784
649
|
* @returns Client order that can be submitted to the corresponding LOB
|
|
785
650
|
*/
|
|
786
|
-
|
|
787
|
-
|
|
651
|
+
static toClientOrder(order, traderAddr, perpStaticInfo, parentChildIds) {
|
|
652
|
+
const scOrder = PerpetualDataHandler.toSmartContractOrder(order, traderAddr, perpStaticInfo);
|
|
788
653
|
return PerpetualDataHandler.fromSmartContratOrderToClientOrder(scOrder, parentChildIds);
|
|
789
|
-
}
|
|
654
|
+
}
|
|
790
655
|
/**
|
|
791
656
|
* Converts an order as stored in the LOB smart contract into a user-friendly order type
|
|
792
657
|
* @param obOrder Order-book contract order type
|
|
793
658
|
* @returns User friendly order struct
|
|
794
659
|
*/
|
|
795
|
-
|
|
796
|
-
|
|
660
|
+
static fromClientOrder(obOrder, perpStaticInfo) {
|
|
661
|
+
const scOrder = {
|
|
797
662
|
flags: obOrder.flags,
|
|
798
663
|
iPerpetualId: obOrder.iPerpetualId,
|
|
799
664
|
brokerFeeTbps: obOrder.brokerFeeTbps,
|
|
@@ -807,18 +672,18 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
807
672
|
iDeadline: obOrder.iDeadline,
|
|
808
673
|
executionTimestamp: obOrder.executionTimestamp,
|
|
809
674
|
};
|
|
810
|
-
|
|
675
|
+
const order = PerpetualDataHandler.fromSmartContractOrder(scOrder, perpStaticInfo);
|
|
811
676
|
if (obOrder.parentChildDigest1.toString() != nodeSDKTypes_1.ZERO_ORDER_ID ||
|
|
812
677
|
obOrder.parentChildDigest2.toString() != nodeSDKTypes_1.ZERO_ORDER_ID) {
|
|
813
678
|
order.parentChildOrderIds = [obOrder.parentChildDigest1.toString(), obOrder.parentChildDigest2.toString()];
|
|
814
679
|
}
|
|
815
680
|
return order;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
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);
|
|
822
687
|
if (isStop && hasLimit) {
|
|
823
688
|
return nodeSDKTypes_1.ORDER_TYPE_STOP_LIMIT;
|
|
824
689
|
}
|
|
@@ -831,15 +696,15 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
831
696
|
else {
|
|
832
697
|
return nodeSDKTypes_1.ORDER_TYPE_MARKET;
|
|
833
698
|
}
|
|
834
|
-
}
|
|
699
|
+
}
|
|
835
700
|
/**
|
|
836
701
|
* Determine the correct order flags based on the order-properties.
|
|
837
702
|
* Checks for some misspecifications.
|
|
838
703
|
* @param order order type
|
|
839
704
|
* @returns BigNumber flags
|
|
840
705
|
*/
|
|
841
|
-
|
|
842
|
-
|
|
706
|
+
static _orderTypeToFlag(order) {
|
|
707
|
+
let flag;
|
|
843
708
|
order.type = order.type.toUpperCase();
|
|
844
709
|
switch (order.type) {
|
|
845
710
|
case nodeSDKTypes_1.ORDER_TYPE_LIMIT:
|
|
@@ -855,7 +720,7 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
855
720
|
flag = nodeSDKTypes_1.MASK_STOP_ORDER;
|
|
856
721
|
break;
|
|
857
722
|
default: {
|
|
858
|
-
throw Error(
|
|
723
|
+
throw Error(`Order type ${order.type} not found.`);
|
|
859
724
|
}
|
|
860
725
|
}
|
|
861
726
|
if (order.keepPositionLvg != undefined && order.keepPositionLvg) {
|
|
@@ -865,37 +730,37 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
865
730
|
flag = (0, utils_1.combineFlags)(flag, nodeSDKTypes_1.MASK_CLOSE_ONLY);
|
|
866
731
|
}
|
|
867
732
|
if ((order.type == nodeSDKTypes_1.ORDER_TYPE_LIMIT || order.type == nodeSDKTypes_1.ORDER_TYPE_STOP_LIMIT) && order.limitPrice == undefined) {
|
|
868
|
-
throw Error(
|
|
733
|
+
throw Error(`Order type ${order.type} requires limit price.`);
|
|
869
734
|
}
|
|
870
735
|
if ((order.type == nodeSDKTypes_1.ORDER_TYPE_STOP_MARKET || order.type == nodeSDKTypes_1.ORDER_TYPE_STOP_LIMIT) && order.stopPrice == undefined) {
|
|
871
|
-
throw Error(
|
|
736
|
+
throw Error(`Order type ${order.type} requires trigger price.`);
|
|
872
737
|
}
|
|
873
738
|
if ((order.type == nodeSDKTypes_1.ORDER_TYPE_MARKET || order.type == nodeSDKTypes_1.ORDER_TYPE_LIMIT) && order.stopPrice != undefined) {
|
|
874
|
-
throw Error(
|
|
739
|
+
throw Error(`Order type ${order.type} has no trigger price.`);
|
|
875
740
|
}
|
|
876
741
|
if (order.type != nodeSDKTypes_1.ORDER_TYPE_STOP_LIMIT && order.type != nodeSDKTypes_1.ORDER_TYPE_STOP_MARKET && order.stopPrice != undefined) {
|
|
877
|
-
throw Error(
|
|
742
|
+
throw Error(`Order type ${order.type} has no trigger price.`);
|
|
878
743
|
}
|
|
879
744
|
return flag;
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
|
|
745
|
+
}
|
|
746
|
+
static _getLotSize(symbol, symbolToPerpStaticInfo) {
|
|
747
|
+
let perpInfo = symbolToPerpStaticInfo.get(symbol);
|
|
883
748
|
if (perpInfo == undefined) {
|
|
884
|
-
throw new Error(
|
|
749
|
+
throw new Error(`no info for perpetual ${symbol}`);
|
|
885
750
|
}
|
|
886
751
|
return perpInfo.lotSizeBC;
|
|
887
|
-
}
|
|
888
|
-
|
|
752
|
+
}
|
|
753
|
+
static _getMinimalPositionSize(symbol, symbolToPerpStaticInfo) {
|
|
889
754
|
return 10 * PerpetualDataHandler._getLotSize(symbol, symbolToPerpStaticInfo);
|
|
890
|
-
}
|
|
755
|
+
}
|
|
891
756
|
/**
|
|
892
757
|
* Get NodeSDKConfig from a chain ID, known config name, or custom file location..
|
|
893
758
|
* @param configNameOrfileLocation Name of a known default config, or chain ID, or json-file with required variables for config
|
|
894
759
|
* @param version Config version number. Defaults to highest version if name or chain ID are not unique
|
|
895
760
|
* @returns NodeSDKConfig
|
|
896
761
|
*/
|
|
897
|
-
|
|
898
|
-
|
|
762
|
+
static readSDKConfig(configNameOrChainIdOrFileLocation, version) {
|
|
763
|
+
let config;
|
|
899
764
|
if (typeof configNameOrChainIdOrFileLocation === "number") {
|
|
900
765
|
// user entered a chain ID
|
|
901
766
|
config = this.getConfigByChainId(configNameOrChainIdOrFileLocation, version);
|
|
@@ -912,92 +777,92 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
912
777
|
}
|
|
913
778
|
else {
|
|
914
779
|
// error
|
|
915
|
-
throw Error(
|
|
780
|
+
throw Error(`Please specify a chain ID, config name, or custom file location.`);
|
|
916
781
|
}
|
|
917
782
|
if (config == undefined) {
|
|
918
|
-
throw Error(
|
|
783
|
+
throw Error(`Config ${configNameOrChainIdOrFileLocation} not found.`);
|
|
919
784
|
}
|
|
920
785
|
return config;
|
|
921
|
-
}
|
|
786
|
+
}
|
|
922
787
|
/**
|
|
923
788
|
* Get a NodeSDKConfig from its name
|
|
924
789
|
* @param name Name of the known config
|
|
925
790
|
* @param version Version of the config. Defaults to highest available.
|
|
926
791
|
* @returns NodeSDKConfig
|
|
927
792
|
*/
|
|
928
|
-
|
|
929
|
-
|
|
793
|
+
static getConfigByName(name, version) {
|
|
794
|
+
let configFile = nodeSDKTypes_1.DEFAULT_CONFIG.filter((c) => c.name == name);
|
|
930
795
|
if (configFile.length == 0) {
|
|
931
|
-
throw Error(
|
|
796
|
+
throw Error(`No SDK config found with name ${name}.`);
|
|
932
797
|
}
|
|
933
798
|
if (configFile.length == 1) {
|
|
934
799
|
return configFile[0];
|
|
935
800
|
}
|
|
936
801
|
else {
|
|
937
802
|
if (version === undefined) {
|
|
938
|
-
configFile = configFile.sort(
|
|
803
|
+
configFile = configFile.sort((conf) => -conf.version);
|
|
939
804
|
return configFile[0];
|
|
940
805
|
}
|
|
941
806
|
else {
|
|
942
|
-
return configFile.find(
|
|
807
|
+
return configFile.find((conf) => conf.version === version);
|
|
943
808
|
}
|
|
944
809
|
}
|
|
945
|
-
}
|
|
810
|
+
}
|
|
946
811
|
/**
|
|
947
812
|
* Get a NodeSDKConfig from a json file.
|
|
948
813
|
* @param filename Location of the file
|
|
949
814
|
* @param version Version of the config. Defaults to highest available.
|
|
950
815
|
* @returns NodeSDKConfig
|
|
951
816
|
*/
|
|
952
|
-
|
|
817
|
+
static getConfigByLocation(filename) {
|
|
953
818
|
// file path: this throws a warning during build - that's ok, it just won't work in react apps
|
|
954
819
|
// eslint-disable-next-line
|
|
955
|
-
|
|
820
|
+
let configFile = require(filename);
|
|
956
821
|
(0, nodeSDKTypes_1.loadABIs)(configFile);
|
|
957
822
|
return configFile;
|
|
958
|
-
}
|
|
823
|
+
}
|
|
959
824
|
/**
|
|
960
825
|
* Get a NodeSDKConfig from its chain Id
|
|
961
826
|
* @param chainId Chain Id
|
|
962
827
|
* @param version Version of the config. Defaults to highest available.
|
|
963
828
|
* @returns NodeSDKConfig
|
|
964
829
|
*/
|
|
965
|
-
|
|
966
|
-
|
|
830
|
+
static getConfigByChainId(chainId, version) {
|
|
831
|
+
let configFile = nodeSDKTypes_1.DEFAULT_CONFIG.filter((c) => c.chainId == chainId);
|
|
967
832
|
if (configFile.length == 0) {
|
|
968
|
-
throw Error(
|
|
833
|
+
throw Error(`No SDK config found for chain ID ${chainId}.`);
|
|
969
834
|
}
|
|
970
835
|
if (configFile.length == 1) {
|
|
971
836
|
return configFile[0];
|
|
972
837
|
}
|
|
973
838
|
else {
|
|
974
839
|
if (version === undefined) {
|
|
975
|
-
configFile = configFile.sort(
|
|
840
|
+
configFile = configFile.sort((conf) => -conf.version);
|
|
976
841
|
return configFile[0];
|
|
977
842
|
}
|
|
978
843
|
else {
|
|
979
|
-
return configFile.find(
|
|
844
|
+
return configFile.find((conf) => conf.version === version);
|
|
980
845
|
}
|
|
981
846
|
}
|
|
982
|
-
}
|
|
847
|
+
}
|
|
983
848
|
/**
|
|
984
849
|
* Get the ABI of a function in a given contract
|
|
985
850
|
* @param contract A contract instance, e.g. this.proxyContract
|
|
986
851
|
* @param functionName Name of the function whose ABI we want
|
|
987
852
|
* @returns Function ABI as a single JSON string
|
|
988
853
|
*/
|
|
989
|
-
|
|
854
|
+
static _getABIFromContract(contract, functionName) {
|
|
990
855
|
return contract.interface.getFunction(functionName).format(abi_1.FormatTypes.full);
|
|
991
|
-
}
|
|
856
|
+
}
|
|
992
857
|
/**
|
|
993
858
|
* Gets the pool index (starting at 0 in exchangeInfo, not ID!) corresponding to a given symbol.
|
|
994
859
|
* @param symbol Symbol of the form ETH-USD-MATIC
|
|
995
860
|
* @returns Pool index
|
|
996
861
|
*/
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
862
|
+
getPoolStaticInfoIndexFromSymbol(symbol) {
|
|
863
|
+
let pools = this.poolStaticInfos;
|
|
864
|
+
let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
|
|
865
|
+
let k = 0;
|
|
1001
866
|
while (k < pools.length) {
|
|
1002
867
|
if (pools[k].poolId == poolId) {
|
|
1003
868
|
// pool found
|
|
@@ -1006,11 +871,16 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
1006
871
|
k++;
|
|
1007
872
|
}
|
|
1008
873
|
return -1;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
*
|
|
877
|
+
* @param symbol Symbol of the form USDC
|
|
878
|
+
* @returns Address of the corresponding token
|
|
879
|
+
*/
|
|
880
|
+
getMarginTokenFromSymbol(symbol) {
|
|
881
|
+
let pools = this.poolStaticInfos;
|
|
882
|
+
let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
|
|
883
|
+
let k = 0;
|
|
1014
884
|
while (k < pools.length) {
|
|
1015
885
|
if (pools[k].poolId == poolId) {
|
|
1016
886
|
// pool found
|
|
@@ -1019,13 +889,31 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
1019
889
|
k++;
|
|
1020
890
|
}
|
|
1021
891
|
return undefined;
|
|
1022
|
-
}
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
*
|
|
895
|
+
* @param symbol Symbol of the form USDC
|
|
896
|
+
* @returns Decimals of the corresponding token
|
|
897
|
+
*/
|
|
898
|
+
getMarginTokenDecimalsFromSymbol(symbol) {
|
|
899
|
+
let pools = this.poolStaticInfos;
|
|
900
|
+
let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
|
|
901
|
+
let k = 0;
|
|
902
|
+
while (k < pools.length) {
|
|
903
|
+
if (pools[k].poolId == poolId) {
|
|
904
|
+
// pool found
|
|
905
|
+
return pools[k].poolMarginTokenDecimals;
|
|
906
|
+
}
|
|
907
|
+
k++;
|
|
908
|
+
}
|
|
909
|
+
return undefined;
|
|
910
|
+
}
|
|
1023
911
|
/**
|
|
1024
912
|
* Get ABI for LimitOrderBook, Proxy, or Share Pool Token
|
|
1025
913
|
* @param contract name of contract: proxy|lob|sharetoken
|
|
1026
914
|
* @returns ABI for the requested contract
|
|
1027
915
|
*/
|
|
1028
|
-
|
|
916
|
+
getABI(contract) {
|
|
1029
917
|
switch (contract) {
|
|
1030
918
|
case "proxy":
|
|
1031
919
|
return this.proxyABI;
|
|
@@ -1036,22 +924,22 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
1036
924
|
default:
|
|
1037
925
|
return undefined;
|
|
1038
926
|
}
|
|
1039
|
-
}
|
|
927
|
+
}
|
|
1040
928
|
/**
|
|
1041
929
|
* Performs basic validity checks on a given order
|
|
1042
930
|
* @param order Order struct
|
|
1043
931
|
* @param traderAccount Trader account
|
|
1044
932
|
* @param perpStaticInfo Symbol to perpetual info map
|
|
1045
933
|
*/
|
|
1046
|
-
|
|
934
|
+
static checkOrder(order,
|
|
1047
935
|
// traderAccount: MarginAccount,
|
|
1048
936
|
perpStaticInfo) {
|
|
1049
937
|
// check side
|
|
1050
938
|
if (order.side != nodeSDKTypes_1.BUY_SIDE && order.side != nodeSDKTypes_1.SELL_SIDE) {
|
|
1051
|
-
throw Error(
|
|
939
|
+
throw Error(`order side must be ${nodeSDKTypes_1.BUY_SIDE} or ${nodeSDKTypes_1.SELL_SIDE}`);
|
|
1052
940
|
}
|
|
1053
941
|
// check amount
|
|
1054
|
-
|
|
942
|
+
let lotSize = perpStaticInfo.get(order.symbol).lotSizeBC;
|
|
1055
943
|
// let curPos =
|
|
1056
944
|
// traderAccount.side == CLOSED_SIDE
|
|
1057
945
|
// ? 0
|
|
@@ -1059,22 +947,21 @@ var PerpetualDataHandler = /** @class */ (function () {
|
|
|
1059
947
|
// let newPos = curPos + (order.side == BUY_SIDE ? 1 : -1) * order.quantity;
|
|
1060
948
|
// if (Math.abs(order.quantity) < lotSize || (Math.abs(newPos) >= lotSize && Math.abs(newPos) < 10 * lotSize)) {
|
|
1061
949
|
if (Math.abs(order.quantity) < lotSize) {
|
|
1062
|
-
throw Error(
|
|
950
|
+
throw Error(`trade amount too small: ${order.quantity} ${perpStaticInfo.get(order.symbol).S2Symbol}`);
|
|
1063
951
|
}
|
|
1064
952
|
// check limit price
|
|
1065
953
|
if (order.side == nodeSDKTypes_1.BUY_SIDE && order.limitPrice != undefined && order.limitPrice <= 0) {
|
|
1066
|
-
throw Error(
|
|
954
|
+
throw Error(`invalid limit price for buy order: ${order.limitPrice}`);
|
|
1067
955
|
}
|
|
1068
956
|
// broker fee
|
|
1069
957
|
if (order.brokerFeeTbps != undefined && order.brokerFeeTbps < 0) {
|
|
1070
|
-
throw Error(
|
|
958
|
+
throw Error(`invalid broker fee: ${order.brokerFeeTbps / 10} bps`);
|
|
1071
959
|
}
|
|
1072
960
|
// stop price
|
|
1073
961
|
if (order.stopPrice != undefined && order.stopPrice < 0) {
|
|
1074
|
-
throw Error(
|
|
962
|
+
throw Error(`invalid stop price: ${order.stopPrice}`);
|
|
1075
963
|
}
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
}());
|
|
964
|
+
}
|
|
965
|
+
}
|
|
1079
966
|
exports.default = PerpetualDataHandler;
|
|
1080
967
|
//# sourceMappingURL=perpetualDataHandler.js.map
|