@d8x/perpetuals-sdk 0.8.0 → 0.8.2
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/Multicall3.json +452 -0
- package/dist/cjs/contracts/Multicall3.d.ts +292 -0
- package/dist/cjs/contracts/Multicall3.js +3 -0
- package/dist/cjs/contracts/Multicall3.js.map +1 -0
- package/dist/cjs/contracts/factories/Multicall3__factory.d.ts +351 -0
- package/dist/cjs/contracts/factories/Multicall3__factory.js +481 -0
- package/dist/cjs/contracts/factories/Multicall3__factory.js.map +1 -0
- package/dist/cjs/contracts/factories/index.d.ts +1 -0
- package/dist/cjs/contracts/factories/index.js +3 -1
- package/dist/cjs/contracts/factories/index.js.map +1 -1
- package/dist/cjs/contracts/index.d.ts +2 -0
- package/dist/cjs/contracts/index.js +3 -1
- package/dist/cjs/contracts/index.js.map +1 -1
- package/dist/cjs/marketData.d.ts +24 -1
- package/dist/cjs/marketData.js +129 -6
- package/dist/cjs/marketData.js.map +1 -1
- package/dist/cjs/nodeSDKTypes.d.ts +1 -0
- package/dist/cjs/nodeSDKTypes.js +2 -1
- package/dist/cjs/nodeSDKTypes.js.map +1 -1
- package/dist/cjs/perpetualDataHandler.d.ts +25 -1
- package/dist/cjs/perpetualDataHandler.js +63 -1
- package/dist/cjs/perpetualDataHandler.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/abi/Multicall3.json +452 -0
- package/dist/esm/contracts/Multicall3.d.ts +292 -0
- package/dist/esm/contracts/Multicall3.js +2 -0
- package/dist/esm/contracts/Multicall3.js.map +1 -0
- package/dist/esm/contracts/factories/Multicall3__factory.d.ts +351 -0
- package/dist/esm/contracts/factories/Multicall3__factory.js +477 -0
- package/dist/esm/contracts/factories/Multicall3__factory.js.map +1 -0
- package/dist/esm/contracts/factories/index.d.ts +1 -0
- package/dist/esm/contracts/factories/index.js +1 -0
- package/dist/esm/contracts/factories/index.js.map +1 -1
- package/dist/esm/contracts/index.d.ts +2 -0
- package/dist/esm/contracts/index.js +1 -0
- package/dist/esm/contracts/index.js.map +1 -1
- package/dist/esm/marketData.d.ts +24 -1
- package/dist/esm/marketData.js +130 -7
- package/dist/esm/marketData.js.map +1 -1
- package/dist/esm/nodeSDKTypes.d.ts +1 -0
- package/dist/esm/nodeSDKTypes.js +1 -0
- package/dist/esm/nodeSDKTypes.js.map +1 -1
- package/dist/esm/perpetualDataHandler.d.ts +25 -1
- package/dist/esm/perpetualDataHandler.js +65 -3
- package/dist/esm/perpetualDataHandler.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +1 -1
- package/src/abi/Multicall3.json +452 -0
- package/src/contracts/Multicall3.ts +582 -0
- package/src/contracts/factories/Multicall3__factory.ts +497 -0
- package/src/contracts/factories/index.ts +1 -0
- package/src/contracts/index.ts +2 -0
- package/src/marketData.ts +162 -8
- package/src/nodeSDKTypes.ts +1 -1
- package/src/perpetualDataHandler.ts +85 -2
- package/src/version.ts +1 -1
package/src/marketData.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { BigNumber } from "@ethersproject/bignumber";
|
|
|
2
2
|
import { CallOverrides, Contract } from "@ethersproject/contracts";
|
|
3
3
|
import { Provider, StaticJsonRpcProvider } from "@ethersproject/providers";
|
|
4
4
|
import { formatUnits } from "@ethersproject/units";
|
|
5
|
-
import { ERC20__factory, LimitOrderBook } from "./contracts";
|
|
5
|
+
import { ERC20__factory, LimitOrderBook, Multicall3 } from "./contracts";
|
|
6
6
|
import { IClientOrder } from "./contracts/LimitOrderBook";
|
|
7
7
|
import {
|
|
8
8
|
ABK64x64ToFloat,
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
SELL_SIDE,
|
|
34
34
|
SmartContractOrder,
|
|
35
35
|
ZERO_ADDRESS,
|
|
36
|
+
ZERO_ORDER_ID,
|
|
36
37
|
} from "./nodeSDKTypes";
|
|
37
38
|
import PerpetualDataHandler from "./perpetualDataHandler";
|
|
38
39
|
import PriceFeeds from "./priceFeeds";
|
|
@@ -190,9 +191,13 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
190
191
|
// open orders requested only for given symbol
|
|
191
192
|
let resArray: Array<{ orders: Order[]; orderIds: string[] }> = [];
|
|
192
193
|
const symbols = symbol.split("-").length == 1 ? this.getPerpetualSymbolsInPool(symbol) : [symbol];
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
if (symbols.length < 1) {
|
|
195
|
+
throw new Error(`No perpetuals found for symbol ${symbol}`);
|
|
196
|
+
} else if (symbols.length < 2) {
|
|
197
|
+
let res = await this._openOrdersOfPerpetual(traderAddr, symbols[0], overrides);
|
|
195
198
|
resArray.push(res!);
|
|
199
|
+
} else {
|
|
200
|
+
resArray = await this._openOrdersOfPerpetuals(traderAddr, symbols, overrides);
|
|
196
201
|
}
|
|
197
202
|
return resArray;
|
|
198
203
|
}
|
|
@@ -215,6 +220,24 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
215
220
|
return { orders: orders, orderIds: digests };
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
/**
|
|
224
|
+
* All open orders for a trader-address and a given perpetual symbol.
|
|
225
|
+
* @param {string} traderAddr Address of the trader for which we get the open orders.
|
|
226
|
+
* @param {string} symbol perpetual-symbol of the form ETH-USD-MATIC
|
|
227
|
+
* @returns open orders and order ids
|
|
228
|
+
*/
|
|
229
|
+
private async _openOrdersOfPerpetuals(
|
|
230
|
+
traderAddr: string,
|
|
231
|
+
symbols: string[],
|
|
232
|
+
overrides?: CallOverrides
|
|
233
|
+
): Promise<{ orders: Order[]; orderIds: string[] }[]> {
|
|
234
|
+
// open orders requested only for given symbol
|
|
235
|
+
const orderBookContracts = symbols.map((symbol) => this.getOrderBookContract(symbol));
|
|
236
|
+
const orders = await this._openOrdersOnOrderBooks(traderAddr, orderBookContracts, overrides);
|
|
237
|
+
const digests = await this._orderIdsOfTrader(traderAddr, orderBookContracts, overrides);
|
|
238
|
+
return symbols.map((_symbol, i) => ({ orders: orders[i], orderIds: digests[i] }));
|
|
239
|
+
}
|
|
240
|
+
|
|
218
241
|
/**
|
|
219
242
|
* Information about the position open by a given trader in a given perpetual contract, or
|
|
220
243
|
* for all perpetuals in a pool
|
|
@@ -243,9 +266,13 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
243
266
|
}
|
|
244
267
|
let resArray: Array<MarginAccount> = [];
|
|
245
268
|
let symbols = symbol.split("-").length == 1 ? this.getPerpetualSymbolsInPool(symbol) : [symbol];
|
|
246
|
-
|
|
247
|
-
|
|
269
|
+
if (symbols.length < 1) {
|
|
270
|
+
throw new Error(`No perpetuals found for symbol ${symbol}`);
|
|
271
|
+
} else if (symbols.length < 2) {
|
|
272
|
+
let res = await this._positionRiskForTraderInPerpetual(traderAddr, symbols[0], overrides);
|
|
248
273
|
resArray.push(res!);
|
|
274
|
+
} else {
|
|
275
|
+
resArray = await this._positionRiskForTraderInPerpetuals(traderAddr, symbols, overrides);
|
|
249
276
|
}
|
|
250
277
|
return resArray;
|
|
251
278
|
}
|
|
@@ -256,7 +283,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
256
283
|
* @param {string} symbol perpetual symbol of the form ETH-USD-MATIC
|
|
257
284
|
* @returns MarginAccount struct for the trader
|
|
258
285
|
*/
|
|
259
|
-
|
|
286
|
+
protected async _positionRiskForTraderInPerpetual(
|
|
260
287
|
traderAddr: string,
|
|
261
288
|
symbol: string,
|
|
262
289
|
overrides?: CallOverrides
|
|
@@ -273,6 +300,35 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
273
300
|
return mgnAcct;
|
|
274
301
|
}
|
|
275
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Information about the position open by a given trader in a given perpetual contract.
|
|
305
|
+
* @param {string} traderAddr Address of the trader for which we get the position risk.
|
|
306
|
+
* @param {string} symbol perpetual symbol of the form ETH-USD-MATIC
|
|
307
|
+
* @returns MarginAccount struct for the trader
|
|
308
|
+
*/
|
|
309
|
+
protected async _positionRiskForTraderInPerpetuals(
|
|
310
|
+
traderAddr: string,
|
|
311
|
+
symbols: string[],
|
|
312
|
+
overrides?: CallOverrides
|
|
313
|
+
): Promise<MarginAccount[]> {
|
|
314
|
+
let S2S3 = await Promise.all(
|
|
315
|
+
symbols.map(async (symbol) => {
|
|
316
|
+
let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
317
|
+
return [obj.idxPrices[0], obj.idxPrices[1]];
|
|
318
|
+
})
|
|
319
|
+
);
|
|
320
|
+
let mgnAcct = await PerpetualDataHandler.getMarginAccounts(
|
|
321
|
+
Array(symbols.length).fill(traderAddr),
|
|
322
|
+
symbols,
|
|
323
|
+
this.symbolToPerpStaticInfo,
|
|
324
|
+
this.multicall!,
|
|
325
|
+
this.proxyContract!,
|
|
326
|
+
S2S3,
|
|
327
|
+
overrides
|
|
328
|
+
);
|
|
329
|
+
return mgnAcct;
|
|
330
|
+
}
|
|
331
|
+
|
|
276
332
|
/**
|
|
277
333
|
* Estimates what the position risk will be if a given order is executed.
|
|
278
334
|
* @param traderAddr Address of trader
|
|
@@ -971,6 +1027,105 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
971
1027
|
return userFriendlyOrders;
|
|
972
1028
|
}
|
|
973
1029
|
|
|
1030
|
+
/**
|
|
1031
|
+
* Query smart contract to get user orders and convert to user friendly order format.
|
|
1032
|
+
* @param {string} traderAddr Address of trader.
|
|
1033
|
+
* @param {ethers.Contract} orderBookContract Instance of order book.
|
|
1034
|
+
* @returns {Order[]} Array of user friendly order struct.
|
|
1035
|
+
* @ignore
|
|
1036
|
+
*/
|
|
1037
|
+
protected async _openOrdersOnOrderBooks(
|
|
1038
|
+
traderAddr: string,
|
|
1039
|
+
orderBookContracts: LimitOrderBook[],
|
|
1040
|
+
overrides?: CallOverrides
|
|
1041
|
+
): Promise<Order[][]> {
|
|
1042
|
+
// eliminate empty orders and map to user friendly orders
|
|
1043
|
+
const numOBs = orderBookContracts.length;
|
|
1044
|
+
|
|
1045
|
+
let userFriendlyOrders = new Array(numOBs).fill(0).map(() => new Array<Order>());
|
|
1046
|
+
|
|
1047
|
+
let haveMoreOrders = new Array(numOBs).fill(true);
|
|
1048
|
+
let from = new Array(numOBs).fill(0);
|
|
1049
|
+
const bulkSize = 15;
|
|
1050
|
+
|
|
1051
|
+
while (haveMoreOrders.some((x) => x)) {
|
|
1052
|
+
// filter by books with some orders left
|
|
1053
|
+
const contracts = orderBookContracts.filter((_c, i) => haveMoreOrders[i]);
|
|
1054
|
+
// prepare calls
|
|
1055
|
+
const ordersCalls: Multicall3.Call3Struct[] = contracts.map((c, i) => ({
|
|
1056
|
+
target: c.address,
|
|
1057
|
+
allowFailure: true,
|
|
1058
|
+
callData: c.interface.encodeFunctionData("getOrders", [traderAddr, from[i], bulkSize]),
|
|
1059
|
+
}));
|
|
1060
|
+
// call
|
|
1061
|
+
const encodedOrders = await this.multicall!.callStatic.aggregate3(ordersCalls, overrides || {});
|
|
1062
|
+
// parse
|
|
1063
|
+
const allOrders: IClientOrder.ClientOrderStructOutput[][] = encodedOrders.map(({ success, returnData }, i) => {
|
|
1064
|
+
if (!success) throw new Error(`Failed to get orders for order book ${contracts[i].address}`);
|
|
1065
|
+
return contracts[i].interface.decodeFunctionResult("getOrders", returnData)[0];
|
|
1066
|
+
});
|
|
1067
|
+
// arrange
|
|
1068
|
+
for (let j = 0; j < contracts.length; j++) {
|
|
1069
|
+
let orders = allOrders[j].filter((o) => o.traderAddr != ZERO_ADDRESS);
|
|
1070
|
+
let i = orderBookContracts.findIndex((c) => c.address == contracts[j].address);
|
|
1071
|
+
let k = 0;
|
|
1072
|
+
while (k < orders.length && orders[k].traderAddr != ZERO_ADDRESS) {
|
|
1073
|
+
userFriendlyOrders[i].push(PerpetualDataHandler.fromClientOrder(orders[k], this.symbolToPerpStaticInfo));
|
|
1074
|
+
k++;
|
|
1075
|
+
}
|
|
1076
|
+
haveMoreOrders[i] = orders.length > 0 && orders[orders.length - 1].traderAddr != ZERO_ADDRESS;
|
|
1077
|
+
from[i] = from[i] + bulkSize;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
return userFriendlyOrders;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
protected async _orderIdsOfTrader(
|
|
1084
|
+
traderAddr: string,
|
|
1085
|
+
orderBookContracts: LimitOrderBook[],
|
|
1086
|
+
overrides?: CallOverrides
|
|
1087
|
+
): Promise<string[][]> {
|
|
1088
|
+
// eliminate empty orders and map to user friendly orders
|
|
1089
|
+
const numOBs = orderBookContracts.length;
|
|
1090
|
+
|
|
1091
|
+
let orderDigests = new Array(numOBs).fill(0).map(() => new Array<string>());
|
|
1092
|
+
|
|
1093
|
+
let haveMoreOrders = new Array(numOBs).fill(true);
|
|
1094
|
+
let from = new Array(numOBs).fill(0);
|
|
1095
|
+
const bulkSize = 15;
|
|
1096
|
+
|
|
1097
|
+
while (haveMoreOrders.some((x) => x)) {
|
|
1098
|
+
// filter by books with some orders left
|
|
1099
|
+
const contracts = orderBookContracts.filter((_c, i) => haveMoreOrders[i]);
|
|
1100
|
+
// prepare alls
|
|
1101
|
+
const digestsCalls: Multicall3.Call3Struct[] = contracts.map((c, i) => ({
|
|
1102
|
+
target: c.address,
|
|
1103
|
+
allowFailure: true,
|
|
1104
|
+
callData: c.interface.encodeFunctionData("limitDigestsOfTrader", [traderAddr, from[i], bulkSize]),
|
|
1105
|
+
}));
|
|
1106
|
+
// call
|
|
1107
|
+
const encodedDigests = await this.multicall!.callStatic.aggregate3(digestsCalls, overrides || {});
|
|
1108
|
+
// parse
|
|
1109
|
+
const allDigests: string[][] = encodedDigests.map(({ success, returnData }, i) => {
|
|
1110
|
+
if (!success) throw new Error(`Failed to get orders for order book ${contracts[i].address}`);
|
|
1111
|
+
return contracts[i].interface.decodeFunctionResult("limitDigestsOfTrader", returnData)[0];
|
|
1112
|
+
});
|
|
1113
|
+
// arrange
|
|
1114
|
+
for (let j = 0; j < contracts.length; j++) {
|
|
1115
|
+
let digests = allDigests[j].filter((d) => d != ZERO_ORDER_ID);
|
|
1116
|
+
let i = orderBookContracts.findIndex((c) => c.address == contracts[j].address);
|
|
1117
|
+
let k = 0;
|
|
1118
|
+
while (k < digests.length && digests[k] != ZERO_ORDER_ID) {
|
|
1119
|
+
orderDigests[i].push(digests[k]);
|
|
1120
|
+
k++;
|
|
1121
|
+
}
|
|
1122
|
+
haveMoreOrders[i] = digests.length > 0 && digests[digests.length - 1] != ZERO_ORDER_ID;
|
|
1123
|
+
from[i] = from[i] + bulkSize;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
return orderDigests;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
974
1129
|
/**
|
|
975
1130
|
*
|
|
976
1131
|
* @param traderAddr Address of the trader
|
|
@@ -1286,8 +1441,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1286
1441
|
overrides
|
|
1287
1442
|
);
|
|
1288
1443
|
// put together all info
|
|
1289
|
-
for (
|
|
1290
|
-
const perp = perpStateInfos[k];
|
|
1444
|
+
for (const perp of perpStateInfos) {
|
|
1291
1445
|
let symbol3s = _perpetualIdToSymbol.get(perp.id);
|
|
1292
1446
|
let info = _symbolToPerpStaticInfo.get(symbol3s!);
|
|
1293
1447
|
const idxPriceS2Pair = idxPriceMap.get(info!.S2Symbol);
|
package/src/nodeSDKTypes.ts
CHANGED
|
@@ -12,7 +12,7 @@ export const COLLATERAL_CURRENCY_QUANTO = 2;
|
|
|
12
12
|
export const PERP_STATE_STR = ["INVALID", "INITIALIZING", "NORMAL", "EMERGENCY", "CLEARED"];
|
|
13
13
|
export const ZERO_ADDRESS = AddressZero;
|
|
14
14
|
export const ZERO_ORDER_ID = HashZero;
|
|
15
|
-
|
|
15
|
+
export const MULTICALL_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
16
16
|
export const ONE_64x64 = BigNumber.from("0x010000000000000000");
|
|
17
17
|
export const MAX_64x64 = BigNumber.from("0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
|
|
18
18
|
export const MAX_UINT_256 = BigNumber.from(2).pow(256).sub(BigNumber.from(1));
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
LimitOrderBookFactory,
|
|
13
13
|
LimitOrderBookFactory__factory,
|
|
14
14
|
LimitOrderBook__factory,
|
|
15
|
+
Multicall3,
|
|
16
|
+
Multicall3__factory,
|
|
15
17
|
} from "./contracts";
|
|
16
18
|
import { IPerpetualOrder } from "./contracts/IPerpetualManager";
|
|
17
19
|
import { IClientOrder } from "./contracts/LimitOrderBook";
|
|
@@ -40,6 +42,7 @@ import {
|
|
|
40
42
|
MASK_MARKET_ORDER,
|
|
41
43
|
MASK_STOP_ORDER,
|
|
42
44
|
MAX_64x64,
|
|
45
|
+
MULTICALL_ADDRESS,
|
|
43
46
|
NodeSDKConfig,
|
|
44
47
|
Order,
|
|
45
48
|
ORDER_MAX_DURATION_SEC,
|
|
@@ -86,7 +89,11 @@ export default class PerpetualDataHandler {
|
|
|
86
89
|
protected lobFactoryABI: ContractInterface;
|
|
87
90
|
protected lobFactoryAddr: string | undefined;
|
|
88
91
|
protected lobABI: ContractInterface;
|
|
92
|
+
// share token
|
|
89
93
|
protected shareTokenABI: ContractInterface;
|
|
94
|
+
// multicall
|
|
95
|
+
protected multicall: Multicall3 | null = null;
|
|
96
|
+
// provider
|
|
90
97
|
protected nodeURL: string;
|
|
91
98
|
protected provider: Provider | null = null;
|
|
92
99
|
|
|
@@ -133,9 +140,9 @@ export default class PerpetualDataHandler {
|
|
|
133
140
|
throw new Error(`Provider: chain id ${network.chainId} does not match config (${this.chainId})`);
|
|
134
141
|
}
|
|
135
142
|
this.proxyContract = IPerpetualManager__factory.connect(this.proxyAddr, signerOrProvider);
|
|
136
|
-
|
|
137
143
|
this.lobFactoryAddr = await this.proxyContract.getOrderBookFactoryAddress(overrides || {});
|
|
138
144
|
this.lobFactoryContract = LimitOrderBookFactory__factory.connect(this.lobFactoryAddr, signerOrProvider);
|
|
145
|
+
this.multicall = Multicall3__factory.connect(MULTICALL_ADDRESS, this.signerOrProvider);
|
|
139
146
|
await this._fillSymbolMaps(overrides);
|
|
140
147
|
}
|
|
141
148
|
|
|
@@ -516,6 +523,16 @@ export default class PerpetualDataHandler {
|
|
|
516
523
|
return mgn;
|
|
517
524
|
}
|
|
518
525
|
|
|
526
|
+
/**
|
|
527
|
+
* Get trader state from the blockchain and parse into a human-readable margin account
|
|
528
|
+
* @param traderAddr Trader address
|
|
529
|
+
* @param symbol Perpetual symbol
|
|
530
|
+
* @param symbolToPerpStaticInfo Symbol to perp static info mapping
|
|
531
|
+
* @param _proxyContract Proxy contract instance
|
|
532
|
+
* @param _pxS2S3 Prices [S2, S3]
|
|
533
|
+
* @param overrides Optional overrides for eth_call
|
|
534
|
+
* @returns A Margin account
|
|
535
|
+
*/
|
|
519
536
|
public static async getMarginAccount(
|
|
520
537
|
traderAddr: string,
|
|
521
538
|
symbol: string,
|
|
@@ -537,6 +554,55 @@ export default class PerpetualDataHandler {
|
|
|
537
554
|
return PerpetualDataHandler.buildMarginAccountFromState(symbol, traderState, symbolToPerpStaticInfo, _pxS2S3);
|
|
538
555
|
}
|
|
539
556
|
|
|
557
|
+
/**
|
|
558
|
+
* Get trader states from the blockchain and parse into a list of human-readable margin accounts
|
|
559
|
+
* @param traderAddrs List of trader addresses
|
|
560
|
+
* @param symbols List of symbols
|
|
561
|
+
* @param symbolToPerpStaticInfo Symbol to perp static info mapping
|
|
562
|
+
* @param _multicall Multicall3 contract instance
|
|
563
|
+
* @param _proxyContract Proxy contract instance
|
|
564
|
+
* @param _pxS2S3s List of price pairs, [[S2, S3] (1st perp), [S2, S3] (2nd perp), ... ]
|
|
565
|
+
* @param overrides Optional eth_call overrides
|
|
566
|
+
* @returns List of margin accounts
|
|
567
|
+
*/
|
|
568
|
+
public static async getMarginAccounts(
|
|
569
|
+
traderAddrs: string[],
|
|
570
|
+
symbols: string[],
|
|
571
|
+
symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>,
|
|
572
|
+
_multicall: Multicall3,
|
|
573
|
+
_proxyContract: IPerpetualManager,
|
|
574
|
+
_pxS2S3s: number[][],
|
|
575
|
+
overrides?: CallOverrides
|
|
576
|
+
): Promise<MarginAccount[]> {
|
|
577
|
+
if (
|
|
578
|
+
traderAddrs.length != symbols.length ||
|
|
579
|
+
traderAddrs.length != _pxS2S3s.length ||
|
|
580
|
+
symbols.length != _pxS2S3s.length
|
|
581
|
+
) {
|
|
582
|
+
throw new Error("traderAddr, symbol and pxS2S3 should all have the same length");
|
|
583
|
+
}
|
|
584
|
+
const proxyCalls: Multicall3.Call3Struct[] = traderAddrs.map((_addr, i) => ({
|
|
585
|
+
target: _proxyContract.address,
|
|
586
|
+
allowFailure: true,
|
|
587
|
+
callData: _proxyContract.interface.encodeFunctionData("getTraderState", [
|
|
588
|
+
PerpetualDataHandler.symbolToPerpetualId(symbols[i], symbolToPerpStaticInfo),
|
|
589
|
+
_addr,
|
|
590
|
+
_pxS2S3s[i].map((x) => floatToABK64x64(x)) as [BigNumber, BigNumber],
|
|
591
|
+
]),
|
|
592
|
+
}));
|
|
593
|
+
const encodedResults = await _multicall.callStatic.aggregate3(proxyCalls, overrides || {});
|
|
594
|
+
const traderStates: BigNumber[][] = encodedResults.map(({ success, returnData }, i) => {
|
|
595
|
+
if (!success) throw new Error(`Failed to get perp info for ${symbols[i]}`);
|
|
596
|
+
return _proxyContract.interface.decodeFunctionResult("getTraderState", returnData)[0];
|
|
597
|
+
});
|
|
598
|
+
return traderStates.map((traderState, i) =>
|
|
599
|
+
PerpetualDataHandler.buildMarginAccountFromState(symbols[i], traderState, symbolToPerpStaticInfo, [
|
|
600
|
+
_pxS2S3s[i][0],
|
|
601
|
+
_pxS2S3s[i][1],
|
|
602
|
+
])
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
|
|
540
606
|
protected static async _queryPerpetualPrice(
|
|
541
607
|
symbol: string,
|
|
542
608
|
tradeAmount: number,
|
|
@@ -579,7 +645,6 @@ export default class PerpetualDataHandler {
|
|
|
579
645
|
): Promise<PerpetualState> {
|
|
580
646
|
let perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
|
|
581
647
|
let staticInfo = symbolToPerpStaticInfo.get(symbol)!;
|
|
582
|
-
let ccy = symbol.split("-");
|
|
583
648
|
let [S2, S3] = [indexPrices[0], indexPrices[1]];
|
|
584
649
|
if (staticInfo.collateralCurrencyType == CollaterlCCY.BASE) {
|
|
585
650
|
S3 = S2;
|
|
@@ -591,6 +656,24 @@ export default class PerpetualDataHandler {
|
|
|
591
656
|
[S2, S3].map(floatToABK64x64) as [BigNumber, BigNumber],
|
|
592
657
|
overrides || {}
|
|
593
658
|
);
|
|
659
|
+
return PerpetualDataHandler._parseAMMState(symbol, ammState, indexPrices, symbolToPerpStaticInfo);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
protected static _parseAMMState(
|
|
663
|
+
symbol: string,
|
|
664
|
+
ammState: BigNumber[],
|
|
665
|
+
indexPrices: [number, number, boolean, boolean],
|
|
666
|
+
symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>
|
|
667
|
+
) {
|
|
668
|
+
let perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, symbolToPerpStaticInfo);
|
|
669
|
+
let staticInfo = symbolToPerpStaticInfo.get(symbol)!;
|
|
670
|
+
let ccy = symbol.split("-");
|
|
671
|
+
let [S2, S3] = [indexPrices[0], indexPrices[1]];
|
|
672
|
+
if (staticInfo.collateralCurrencyType == CollaterlCCY.BASE) {
|
|
673
|
+
S3 = S2;
|
|
674
|
+
} else if (staticInfo.collateralCurrencyType == CollaterlCCY.QUOTE) {
|
|
675
|
+
S3 = 1;
|
|
676
|
+
}
|
|
594
677
|
let markPrice = S2 * (1 + ABK64x64ToFloat(ammState[8]));
|
|
595
678
|
let state: PerpetualState = {
|
|
596
679
|
id: perpId,
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const D8X_SDK_VERSION = "0.8.
|
|
1
|
+
export const D8X_SDK_VERSION = "0.8.2";
|