@d8x/perpetuals-sdk 2.6.4 → 2.6.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/marketData.js +28 -15
- package/dist/cjs/marketData.js.map +1 -1
- package/dist/cjs/nodeSDKTypes.d.ts +8 -0
- package/dist/cjs/perpetualDataHandler.d.ts +30 -3
- package/dist/cjs/perpetualDataHandler.js +70 -21
- package/dist/cjs/perpetualDataHandler.js.map +1 -1
- package/dist/cjs/traderInterface.js +1 -0
- package/dist/cjs/traderInterface.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/marketData.js +28 -15
- package/dist/esm/marketData.js.map +1 -1
- package/dist/esm/nodeSDKTypes.d.ts +8 -0
- package/dist/esm/perpetualDataHandler.d.ts +30 -3
- package/dist/esm/perpetualDataHandler.js +70 -21
- package/dist/esm/perpetualDataHandler.js.map +1 -1
- package/dist/esm/traderInterface.js +1 -0
- package/dist/esm/traderInterface.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/marketData.ts +35 -18
- package/src/nodeSDKTypes.ts +10 -1
- package/src/perpetualDataHandler.ts +78 -21
- package/src/traderInterface.ts +3 -3
- package/src/version.ts +1 -1
package/src/marketData.ts
CHANGED
|
@@ -256,6 +256,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
256
256
|
// open orders requested only for given symbol
|
|
257
257
|
let resArray: Array<{ orders: Order[]; orderIds: string[] }> = [];
|
|
258
258
|
let symbols: Array<string>;
|
|
259
|
+
await this.refreshSymbols();
|
|
259
260
|
if (symbol) {
|
|
260
261
|
symbols = symbol.split("-").length == 1 ? this.getPerpetualSymbolsInPool(symbol) : [symbol];
|
|
261
262
|
} else {
|
|
@@ -365,6 +366,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
365
366
|
if (this.proxyContract == null) {
|
|
366
367
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
367
368
|
}
|
|
369
|
+
await this.refreshSymbols();
|
|
368
370
|
let resArray: Array<MarginAccount> = [];
|
|
369
371
|
let symbols: Array<string>;
|
|
370
372
|
if (symbol) {
|
|
@@ -622,6 +624,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
622
624
|
if (this.proxyContract == null || this.multicall == null) {
|
|
623
625
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
624
626
|
}
|
|
627
|
+
await this.refreshSymbols();
|
|
625
628
|
const isPredMkt = this.isPredictionMarket(order.symbol);
|
|
626
629
|
// fetch prices
|
|
627
630
|
if (indexPriceInfo == undefined) {
|
|
@@ -873,6 +876,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
873
876
|
if (deltaCollateral + account.collateralCC + account.unrealizedFundingCollateralCCY < 0) {
|
|
874
877
|
throw new Error("not enough margin to remove");
|
|
875
878
|
}
|
|
879
|
+
await this.refreshSymbols();
|
|
876
880
|
if (indexPriceInfo == undefined) {
|
|
877
881
|
indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
|
|
878
882
|
}
|
|
@@ -1032,6 +1036,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1032
1036
|
* main();
|
|
1033
1037
|
*/
|
|
1034
1038
|
public async getWalletBalance(address: string, symbol: string, overrides?: Overrides): Promise<number> {
|
|
1039
|
+
await this.refreshSymbols();
|
|
1035
1040
|
let poolIdx = this.getPoolStaticInfoIndexFromSymbol(symbol);
|
|
1036
1041
|
let settleTokenAddr = this.poolStaticInfos[poolIdx].poolSettleTokenAddr;
|
|
1037
1042
|
let token = ERC20__factory.connect(settleTokenAddr, this.provider!);
|
|
@@ -1198,6 +1203,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1198
1203
|
throw new Error("proxy contract not initialized");
|
|
1199
1204
|
}
|
|
1200
1205
|
if (this.isPredictionMarket(symbol)) {
|
|
1206
|
+
await this.refreshSymbols();
|
|
1201
1207
|
// prediction markets: also works for closing positions
|
|
1202
1208
|
return this.pmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
|
|
1203
1209
|
}
|
|
@@ -1462,6 +1468,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1462
1468
|
* main();
|
|
1463
1469
|
*/
|
|
1464
1470
|
public async maxSignedPosition(side: string, symbol: string, overrides?: Overrides): Promise<number> {
|
|
1471
|
+
await this.refreshSymbols();
|
|
1465
1472
|
let perpId = this.getPerpIdFromSymbol(symbol);
|
|
1466
1473
|
let isBuy = side == BUY_SIDE;
|
|
1467
1474
|
let maxSignedPos = await this.proxyContract!.getMaxSignedOpenTradeSizeForPos(perpId, 0n, isBuy, overrides || {});
|
|
@@ -1522,6 +1529,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1522
1529
|
if (!this.proxyContract) {
|
|
1523
1530
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1524
1531
|
}
|
|
1532
|
+
await this.refreshSymbols();
|
|
1525
1533
|
const orderBookContract = this.getOrderBookContract(symbol);
|
|
1526
1534
|
const status = Number(await orderBookContract.getOrderStatus(orderId, overrides || {})) as OrderStatus;
|
|
1527
1535
|
return status;
|
|
@@ -1551,6 +1559,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1551
1559
|
if (!this.proxyContract || !this.multicall) {
|
|
1552
1560
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1553
1561
|
}
|
|
1562
|
+
await this.refreshSymbols();
|
|
1554
1563
|
const orderBookContract = this.getOrderBookContract(symbol);
|
|
1555
1564
|
|
|
1556
1565
|
const statusCalls: Multicall3.Call3Struct[] = orderId.map((id) => ({
|
|
@@ -1591,6 +1600,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1591
1600
|
if (this.proxyContract == null) {
|
|
1592
1601
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1593
1602
|
}
|
|
1603
|
+
await this.refreshSymbols();
|
|
1594
1604
|
if (indexPrices == undefined) {
|
|
1595
1605
|
indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1596
1606
|
}
|
|
@@ -1633,6 +1643,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1633
1643
|
if (this.proxyContract == null) {
|
|
1634
1644
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1635
1645
|
}
|
|
1646
|
+
await this.refreshSymbols();
|
|
1636
1647
|
if (priceInfo == undefined) {
|
|
1637
1648
|
// fetch from API
|
|
1638
1649
|
priceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
@@ -1662,6 +1673,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1662
1673
|
if (this.proxyContract == null || this.multicall == null) {
|
|
1663
1674
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1664
1675
|
}
|
|
1676
|
+
await this.refreshSymbols();
|
|
1665
1677
|
if (indexPriceInfo == undefined) {
|
|
1666
1678
|
indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
1667
1679
|
}
|
|
@@ -1759,6 +1771,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1759
1771
|
if (this.proxyContract == null) {
|
|
1760
1772
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1761
1773
|
}
|
|
1774
|
+
await this.refreshSymbols();
|
|
1762
1775
|
return await this.getPerpetualPrice(symbol, 0);
|
|
1763
1776
|
}
|
|
1764
1777
|
|
|
@@ -1922,7 +1935,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1922
1935
|
if (!this.proxyContract) {
|
|
1923
1936
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
1924
1937
|
}
|
|
1925
|
-
|
|
1938
|
+
await this.refreshSymbols();
|
|
1926
1939
|
if (indexPrices == undefined) {
|
|
1927
1940
|
// fetch from API
|
|
1928
1941
|
indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
|
|
@@ -1998,16 +2011,19 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
1998
2011
|
*/
|
|
1999
2012
|
private static async _getAllActivePerpIndexPrices(
|
|
2000
2013
|
_symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>,
|
|
2001
|
-
_priceFeedGetter: PriceFeeds
|
|
2014
|
+
_priceFeedGetter: PriceFeeds,
|
|
2015
|
+
_symbolList: Map<string, string>
|
|
2002
2016
|
): Promise<Map<string, [number, boolean]>> {
|
|
2003
2017
|
// get all prices from off-chain price-sources
|
|
2004
2018
|
let allSym = new Set<string>();
|
|
2005
2019
|
for (let perpSymbol of _symbolToPerpStaticInfo.keys()) {
|
|
2006
2020
|
let sInfo: PerpetualStaticInfo | undefined = _symbolToPerpStaticInfo.get(perpSymbol);
|
|
2007
|
-
if (sInfo?.state == "INVALID" || sInfo?.state == "INITIALIZING") {
|
|
2021
|
+
if (!sInfo || sInfo?.state == "INVALID" || sInfo?.state == "INITIALIZING") {
|
|
2008
2022
|
continue;
|
|
2009
2023
|
}
|
|
2010
|
-
|
|
2024
|
+
|
|
2025
|
+
allSym.add(MarketData.getIndexSymbol(_symbolList, sInfo));
|
|
2026
|
+
|
|
2011
2027
|
if (sInfo!.S3Symbol != "") {
|
|
2012
2028
|
allSym.add(sInfo!.S3Symbol);
|
|
2013
2029
|
}
|
|
@@ -2039,6 +2055,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2039
2055
|
if (this.proxyContract == null) {
|
|
2040
2056
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
2041
2057
|
}
|
|
2058
|
+
await this.refreshSymbols();
|
|
2042
2059
|
return await MarketData._isMarketClosed(symbol, this.symbolToPerpStaticInfo, this.priceFeedGetter);
|
|
2043
2060
|
}
|
|
2044
2061
|
|
|
@@ -2088,6 +2105,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2088
2105
|
_symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>,
|
|
2089
2106
|
_perpetualIdToSymbol: Map<number, string>,
|
|
2090
2107
|
_idxPriceMap: Map<string, [number, boolean]>,
|
|
2108
|
+
_symbolList: Map<string, string>,
|
|
2091
2109
|
overrides?: Overrides
|
|
2092
2110
|
): Promise<Map<string, number>> {
|
|
2093
2111
|
// what is the maximal number of queries at once?
|
|
@@ -2112,11 +2130,11 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2112
2130
|
}
|
|
2113
2131
|
let symbol3s = _perpetualIdToSymbol.get(id);
|
|
2114
2132
|
let info = _symbolToPerpStaticInfo.get(symbol3s!);
|
|
2115
|
-
if (info?.state == "INVALID" || info?.state == "INITIALIZING") {
|
|
2133
|
+
if (!info || info?.state == "INVALID" || info?.state == "INITIALIZING") {
|
|
2116
2134
|
continue;
|
|
2117
2135
|
}
|
|
2118
2136
|
collectedIds.push(id);
|
|
2119
|
-
let S2 = floatToABK64x64(_idxPriceMap.get(info
|
|
2137
|
+
let S2 = floatToABK64x64(_idxPriceMap.get(MarketData.getIndexSymbol(_symbolList, info))![0]);
|
|
2120
2138
|
let S3 = 0n;
|
|
2121
2139
|
if (info!.S3Symbol != "") {
|
|
2122
2140
|
S3 = floatToABK64x64(_idxPriceMap.get(info!.S3Symbol)![0]);
|
|
@@ -2136,10 +2154,8 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2136
2154
|
const encodedResults = await _multicall.aggregate3.staticCall(proxyCalls, overrides || {});
|
|
2137
2155
|
// apply results
|
|
2138
2156
|
for (let k = 0; k < collectedPerpIds.length; k++) {
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
encodedResults[k].returnData
|
|
2142
|
-
)[0] as bigint[];
|
|
2157
|
+
const result = _proxyContract.interface.decodeFunctionResult("queryMidPrices", encodedResults[k].returnData);
|
|
2158
|
+
let fMidPrice = result[0] as bigint[];
|
|
2143
2159
|
for (let j = 0; j < fMidPrice.length; j++) {
|
|
2144
2160
|
let id = collectedPerpIds[k][j];
|
|
2145
2161
|
let symbol3s = _perpetualIdToSymbol.get(id);
|
|
@@ -2298,7 +2314,6 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2298
2314
|
}
|
|
2299
2315
|
return perpStates;
|
|
2300
2316
|
}
|
|
2301
|
-
|
|
2302
2317
|
/**
|
|
2303
2318
|
* Fetch on-chain exchange info
|
|
2304
2319
|
* @param _proxyContract
|
|
@@ -2333,9 +2348,11 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2333
2348
|
};
|
|
2334
2349
|
|
|
2335
2350
|
// get all prices from off-chain price-sources: no RPC calls
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2351
|
+
let idxPriceMap = await MarketData._getAllActivePerpIndexPrices(
|
|
2352
|
+
_symbolToPerpStaticInfo,
|
|
2353
|
+
_priceFeedGetter,
|
|
2354
|
+
_symbolList
|
|
2355
|
+
);
|
|
2339
2356
|
|
|
2340
2357
|
// query mid-prices from on-chain conditional on the off-chain prices
|
|
2341
2358
|
let midPriceMap: Map<string, number> = await MarketData._queryMidPrices(
|
|
@@ -2346,9 +2363,9 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2346
2363
|
_symbolToPerpStaticInfo,
|
|
2347
2364
|
_perpetualIdToSymbol,
|
|
2348
2365
|
idxPriceMap,
|
|
2366
|
+
_symbolList,
|
|
2349
2367
|
overrides
|
|
2350
2368
|
);
|
|
2351
|
-
console.log({ midPriceMap });
|
|
2352
2369
|
const { pools: poolStateInfos, perpetuals: perpStateInfos } = await MarketData._queryPoolAndPerpetualStates(
|
|
2353
2370
|
_proxyContract,
|
|
2354
2371
|
_multicall,
|
|
@@ -2361,10 +2378,10 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2361
2378
|
for (const perp of perpStateInfos) {
|
|
2362
2379
|
let symbol3s = _perpetualIdToSymbol.get(perp.id);
|
|
2363
2380
|
let info = _symbolToPerpStaticInfo.get(symbol3s!);
|
|
2364
|
-
if (info?.state == "INVALID" || info?.state == "INITIALIZING") {
|
|
2381
|
+
if (!info || info?.state == "INVALID" || info?.state == "INITIALIZING") {
|
|
2365
2382
|
perp.isMarketClosed = true;
|
|
2366
2383
|
} else {
|
|
2367
|
-
const idxPriceS2Pair = idxPriceMap.get(info
|
|
2384
|
+
const idxPriceS2Pair = idxPriceMap.get(MarketData.getIndexSymbol(_symbolList, info));
|
|
2368
2385
|
let idxPriceS3Pair: [number, boolean] = [0, false];
|
|
2369
2386
|
perp.isMarketClosed = idxPriceS2Pair![1];
|
|
2370
2387
|
if (info!.S3Symbol != "") {
|
|
@@ -2394,7 +2411,7 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
2394
2411
|
perp.midPrice = midPriceMap.get(symbol3s!)!;
|
|
2395
2412
|
}
|
|
2396
2413
|
// which pool?
|
|
2397
|
-
const poolId = info
|
|
2414
|
+
const poolId = info?.poolId ?? 1;
|
|
2398
2415
|
poolStateInfos[poolId - 1].perpetuals.push(perp);
|
|
2399
2416
|
}
|
|
2400
2417
|
info.pools = poolStateInfos;
|
package/src/nodeSDKTypes.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BigNumberish, BytesLike,
|
|
1
|
+
import { BigNumberish, BytesLike, ContractTransactionResponse, Interface } from "ethers";
|
|
2
2
|
import { CollaterlCCY } from "./constants";
|
|
3
3
|
|
|
4
4
|
export interface NodeSDKConfig {
|
|
@@ -584,3 +584,12 @@ export interface PythMetadata {
|
|
|
584
584
|
schedule?: string; // "America/New_York;0930-1600,0930-1600,0930-1600,0930-1600,0930-1600,C,C;0418/C,0526/C,0619/C,0703/0930-1300,0704/C"
|
|
585
585
|
};
|
|
586
586
|
}
|
|
587
|
+
|
|
588
|
+
export interface SlotInfo {
|
|
589
|
+
contract_id: string; // "NHL_EDM_NYI_251016",
|
|
590
|
+
yymmdd: string; //"251016",
|
|
591
|
+
expiry: string; // "2025-10-17T06:59:59Z",
|
|
592
|
+
chain_id: number; //84532,
|
|
593
|
+
pool_sym: string; // "PUSD",
|
|
594
|
+
slot: string; //"NHL0"
|
|
595
|
+
}
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
LiquidityPoolData,
|
|
71
71
|
SettlementCcyItem,
|
|
72
72
|
SettlementConfig,
|
|
73
|
+
SlotInfo,
|
|
73
74
|
TokenOverride,
|
|
74
75
|
TypeSafeOrder,
|
|
75
76
|
type ClientOrder,
|
|
@@ -107,6 +108,7 @@ export default class PerpetualDataHandler {
|
|
|
107
108
|
protected perpetualIdToSymbol: Map<number, string>; // maps unique perpetual id to symbol of the form BTC-USD-MATIC
|
|
108
109
|
protected poolStaticInfos: Array<PoolStaticInfo>;
|
|
109
110
|
protected symbolList: Map<string, string>; //mapping 4-digit symbol <-> long format
|
|
111
|
+
protected indexSymbol: Map<string, { indexSymbol: string; expiry: number }> = new Map(); //mapping perpetual symbol to index symbol (NFL_TOR_...-USD-PUSD => NFL0-USD:84532)
|
|
110
112
|
protected settlementConfig: SettlementConfig;
|
|
111
113
|
public requiredSymbols: string[] = []; // array of symbols in the current perpetual deployment
|
|
112
114
|
// config
|
|
@@ -225,6 +227,7 @@ export default class PerpetualDataHandler {
|
|
|
225
227
|
if (this.proxyContract == null) {
|
|
226
228
|
throw new Error("proxy not defined");
|
|
227
229
|
}
|
|
230
|
+
await this.refreshSymbols();
|
|
228
231
|
return await PerpetualDataHandler._getPerpetuals(ids, this.proxyContract, this.symbolList, overrides);
|
|
229
232
|
}
|
|
230
233
|
|
|
@@ -239,6 +242,7 @@ export default class PerpetualDataHandler {
|
|
|
239
242
|
if (this.proxyContract == null) {
|
|
240
243
|
throw new Error("proxy not defined");
|
|
241
244
|
}
|
|
245
|
+
await this.refreshSymbols();
|
|
242
246
|
return await PerpetualDataHandler._getLiquidityPools(
|
|
243
247
|
fromIdx,
|
|
244
248
|
toIdx,
|
|
@@ -262,6 +266,11 @@ export default class PerpetualDataHandler {
|
|
|
262
266
|
throw new Error("proxy or multicall not defined");
|
|
263
267
|
}
|
|
264
268
|
const tokenOverrides = require("./config/tokenOverrides.json") as TokenOverride[];
|
|
269
|
+
|
|
270
|
+
//reset
|
|
271
|
+
this.poolStaticInfos = [];
|
|
272
|
+
this.symbolToPerpStaticInfo = new Map();
|
|
273
|
+
|
|
265
274
|
let poolInfo = await PerpetualDataHandler.getPoolStaticInfo(this.proxyContract, overrides);
|
|
266
275
|
this.nestedPerpetualIDs = poolInfo.nestedPerpetualIDs;
|
|
267
276
|
|
|
@@ -322,10 +331,12 @@ export default class PerpetualDataHandler {
|
|
|
322
331
|
encodedResults[encodedResults.length - 1].returnData
|
|
323
332
|
)[0] as string;
|
|
324
333
|
|
|
334
|
+
// this one updates symbollist and indexsymbol maps inplace if needed
|
|
325
335
|
let perpStaticInfos = await PerpetualDataHandler.getPerpetualStaticInfo(
|
|
326
336
|
this.proxyContract,
|
|
327
337
|
this.nestedPerpetualIDs,
|
|
328
338
|
this.symbolList,
|
|
339
|
+
this.indexSymbol,
|
|
329
340
|
overrides
|
|
330
341
|
);
|
|
331
342
|
|
|
@@ -338,10 +349,13 @@ export default class PerpetualDataHandler {
|
|
|
338
349
|
if (perp.state != "INVALID" && perp.state != "INITIALIZING") {
|
|
339
350
|
// we only require price feeds to be available if the perpetual
|
|
340
351
|
// is in normal state
|
|
341
|
-
requiredPairs.add(perp
|
|
352
|
+
requiredPairs.add(PerpetualDataHandler.getIndexSymbol(this.symbolList, perp));
|
|
353
|
+
|
|
342
354
|
if (perp.S3Symbol != "") {
|
|
343
355
|
requiredPairs.add(perp.S3Symbol);
|
|
344
356
|
}
|
|
357
|
+
} else {
|
|
358
|
+
continue;
|
|
345
359
|
}
|
|
346
360
|
let poolCCY = this.poolStaticInfos[perp.poolId - 1].poolMarginSymbol;
|
|
347
361
|
if (poolCCY == "") {
|
|
@@ -522,6 +536,7 @@ export default class PerpetualDataHandler {
|
|
|
522
536
|
symbol: string
|
|
523
537
|
): Promise<{ submission: PriceFeedSubmission; pxS2S3: [number, number] }> {
|
|
524
538
|
// fetch prices from required price-feeds (REST)
|
|
539
|
+
await this.refreshSymbols();
|
|
525
540
|
return await this.priceFeedGetter.fetchFeedPriceInfoAndIndicesForPerpetual(symbol);
|
|
526
541
|
}
|
|
527
542
|
|
|
@@ -532,21 +547,12 @@ export default class PerpetualDataHandler {
|
|
|
532
547
|
*/
|
|
533
548
|
public getIndexSymbols(symbol: string): [string, string] {
|
|
534
549
|
// get index
|
|
535
|
-
console.log(symbol, this.symbolToPerpStaticInfo);
|
|
536
550
|
let staticInfo = this.symbolToPerpStaticInfo.get(symbol);
|
|
537
551
|
if (staticInfo == undefined) {
|
|
538
552
|
throw new Error(`No static info for perpetual with symbol ${symbol}`);
|
|
539
553
|
}
|
|
540
|
-
const quoteCcy = staticInfo.S2Symbol.split("-")[1];
|
|
541
554
|
return this.isPredictionMarket(symbol)
|
|
542
|
-
? [
|
|
543
|
-
PerpetualDataHandler._getBySingleValue(this.symbolList, staticInfo.S2Symbol) +
|
|
544
|
-
"-" +
|
|
545
|
-
quoteCcy +
|
|
546
|
-
":" +
|
|
547
|
-
Number(this.chainId),
|
|
548
|
-
staticInfo.S3Symbol,
|
|
549
|
-
]
|
|
555
|
+
? [PerpetualDataHandler.getIndexSymbol(this.symbolList, staticInfo), staticInfo.S3Symbol]
|
|
550
556
|
: [staticInfo.S2Symbol, staticInfo.S3Symbol];
|
|
551
557
|
}
|
|
552
558
|
|
|
@@ -558,6 +564,7 @@ export default class PerpetualDataHandler {
|
|
|
558
564
|
* and corresponding price information
|
|
559
565
|
*/
|
|
560
566
|
public async fetchLatestFeedPriceInfo(symbol: string): Promise<PriceFeedSubmission> {
|
|
567
|
+
await this.refreshSymbols();
|
|
561
568
|
return await this.priceFeedGetter.fetchLatestFeedPriceInfoForPerpetual(symbol);
|
|
562
569
|
}
|
|
563
570
|
|
|
@@ -570,6 +577,7 @@ export default class PerpetualDataHandler {
|
|
|
570
577
|
* @param symbol either perpetual symbol of the form BTC-USD-MATIC or just collateral token
|
|
571
578
|
*/
|
|
572
579
|
public async fetchCollateralToSettlementConversion(symbol: string): Promise<number> {
|
|
580
|
+
await this.refreshSymbols();
|
|
573
581
|
let j = this.getPoolStaticInfoIndexFromSymbol(symbol);
|
|
574
582
|
if (this.poolStaticInfos[j].poolMarginSymbol == this.poolStaticInfos[j].poolSettleSymbol) {
|
|
575
583
|
// settlement currency = collateral currency
|
|
@@ -657,9 +665,8 @@ export default class PerpetualDataHandler {
|
|
|
657
665
|
* @param short List of short perp symbols (<=4 chars)
|
|
658
666
|
* @returns List of long perp symbols
|
|
659
667
|
*/
|
|
660
|
-
protected static async fetchSymbolList(chainId: bigint | number | string
|
|
661
|
-
const
|
|
662
|
-
const query = endpoint + short.join("&short[]=");
|
|
668
|
+
protected static async fetchSymbolList(chainId: bigint | number | string) {
|
|
669
|
+
const query = `https://sports.quantena.org/slots-info/${Number(chainId)}`;
|
|
663
670
|
const res = await fetch(query);
|
|
664
671
|
if (res.status !== 200) {
|
|
665
672
|
throw new Error(`failed to fetch symbolList status code: ${res.status}, ${query}`);
|
|
@@ -667,10 +674,10 @@ export default class PerpetualDataHandler {
|
|
|
667
674
|
if (!res.ok) {
|
|
668
675
|
throw new Error(`failed to fetch config (${res.status}): ${res.statusText} ${query}`);
|
|
669
676
|
}
|
|
670
|
-
let
|
|
671
|
-
let symbolList = new Map<string, string>();
|
|
672
|
-
for (const s of
|
|
673
|
-
symbolList.set(s,
|
|
677
|
+
let infos = (await res.json()) as SlotInfo[];
|
|
678
|
+
let symbolList = new Map<string, { symbol: string; expiry: number }>();
|
|
679
|
+
for (const s of infos) {
|
|
680
|
+
symbolList.set(s.slot, { symbol: s.contract_id, expiry: new Date(s.expiry).getTime() });
|
|
674
681
|
}
|
|
675
682
|
return symbolList;
|
|
676
683
|
}
|
|
@@ -685,6 +692,7 @@ export default class PerpetualDataHandler {
|
|
|
685
692
|
_proxyContract: IPerpetualManager,
|
|
686
693
|
nestedPerpetualIDs: Array<Array<number>>,
|
|
687
694
|
symbolList: Map<string, string>,
|
|
695
|
+
indexSymbol: Map<string, { indexSymbol: string; expiry: number }>,
|
|
688
696
|
overrides?: Overrides
|
|
689
697
|
): Promise<Array<PerpetualStaticInfo>> {
|
|
690
698
|
// flatten perpetual ids into chunks
|
|
@@ -699,11 +707,16 @@ export default class PerpetualDataHandler {
|
|
|
699
707
|
// get normalized symbols
|
|
700
708
|
if (overrides?.chainId !== undefined) {
|
|
701
709
|
const shorts = [...new Set(perpInfos.map((p) => fromBytes4HexString(p.S2BaseCCY)))];
|
|
702
|
-
const sList = await this.fetchSymbolList(BigInt(overrides.chainId!)
|
|
710
|
+
const sList = await this.fetchSymbolList(BigInt(overrides.chainId!));
|
|
703
711
|
// modify inplace
|
|
704
712
|
for (const s of shorts) {
|
|
705
713
|
if (sList.has(s)) {
|
|
706
|
-
|
|
714
|
+
const slotInfo = sList.get(s)!;
|
|
715
|
+
symbolList.set(s, slotInfo.symbol);
|
|
716
|
+
indexSymbol.set(slotInfo.symbol, {
|
|
717
|
+
indexSymbol: s + ":" + BigInt(overrides.chainId!),
|
|
718
|
+
expiry: slotInfo.expiry,
|
|
719
|
+
});
|
|
707
720
|
}
|
|
708
721
|
}
|
|
709
722
|
}
|
|
@@ -997,6 +1010,7 @@ export default class PerpetualDataHandler {
|
|
|
997
1010
|
if (this.proxyContract == null) {
|
|
998
1011
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
999
1012
|
}
|
|
1013
|
+
await this.refreshSymbols();
|
|
1000
1014
|
const isPred = this.isPredictionMarket(symbol);
|
|
1001
1015
|
return PerpetualDataHandler.getMarginAccount(
|
|
1002
1016
|
traderAddr,
|
|
@@ -1069,6 +1083,7 @@ export default class PerpetualDataHandler {
|
|
|
1069
1083
|
*/
|
|
1070
1084
|
public async getAllOpenOrders(symbol: string, overrides?: Overrides): Promise<[Order[], string[], string[]]> {
|
|
1071
1085
|
const MAX_ORDERS_POLLED = 500;
|
|
1086
|
+
await this.refreshSymbols();
|
|
1072
1087
|
let totalOrders = await this.numberOfOpenOrders(symbol, overrides);
|
|
1073
1088
|
let orderBundles: [Order[], string[], string[]] = [[], [], []];
|
|
1074
1089
|
let moreOrders = orderBundles[1].length < totalOrders;
|
|
@@ -1120,6 +1135,7 @@ export default class PerpetualDataHandler {
|
|
|
1120
1135
|
if (overrides) {
|
|
1121
1136
|
({ rpcURL, ...overrides } = overrides);
|
|
1122
1137
|
}
|
|
1138
|
+
await this.refreshSymbols();
|
|
1123
1139
|
const provider = new JsonRpcProvider(rpcURL ?? this.nodeURL, this.network, {});
|
|
1124
1140
|
const orderBookSC = this.getOrderBookContract(symbol).connect(provider);
|
|
1125
1141
|
let numOrders = await orderBookSC.orderCount(overrides || {});
|
|
@@ -1162,6 +1178,7 @@ export default class PerpetualDataHandler {
|
|
|
1162
1178
|
if (overrides) {
|
|
1163
1179
|
({ rpcURL, ...overrides } = overrides);
|
|
1164
1180
|
}
|
|
1181
|
+
await this.refreshSymbols();
|
|
1165
1182
|
const provider = new JsonRpcProvider(rpcURL ?? this.nodeURL, this.network, { staticNetwork: true });
|
|
1166
1183
|
const orderBookSC = this.getOrderBookContract(symbol).connect(provider) as LimitOrderBook;
|
|
1167
1184
|
const multicall = Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, provider);
|
|
@@ -1522,7 +1539,7 @@ export default class PerpetualDataHandler {
|
|
|
1522
1539
|
return undefined;
|
|
1523
1540
|
}
|
|
1524
1541
|
|
|
1525
|
-
|
|
1542
|
+
protected static _getBySingleValue(map: Map<string, string>, searchValue: string) {
|
|
1526
1543
|
for (let [key, value] of map.entries()) {
|
|
1527
1544
|
if (searchValue.startsWith(value)) {
|
|
1528
1545
|
return key;
|
|
@@ -2303,4 +2320,44 @@ export default class PerpetualDataHandler {
|
|
|
2303
2320
|
return 1;
|
|
2304
2321
|
}
|
|
2305
2322
|
}
|
|
2323
|
+
|
|
2324
|
+
/**
|
|
2325
|
+
* Static function to get index symbol from perp static info
|
|
2326
|
+
* @param _symbolList Mapping from long symbol (e.g. NHL_TOR_DAL_251015) to price-feed API symbol (NHL0-USD:84532)
|
|
2327
|
+
* @param info Perpetual static info
|
|
2328
|
+
* @returns Index symbol
|
|
2329
|
+
*/
|
|
2330
|
+
public static getIndexSymbol(_symbolList: Map<string, string>, info: PerpetualStaticInfo) {
|
|
2331
|
+
return PerpetualDataHandler.isPredictionMarketStatic(info!)
|
|
2332
|
+
? PerpetualDataHandler._getBySingleValue(_symbolList, info.S2Symbol)! +
|
|
2333
|
+
"-" +
|
|
2334
|
+
info!.S2Symbol.split("-")[1] +
|
|
2335
|
+
":84532"
|
|
2336
|
+
: info!.S2Symbol;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
/**
|
|
2340
|
+
* Short symbol corresponding to a given long symbol.
|
|
2341
|
+
* @param symbol Long symbol (e.g. NHL_TOR_DAL_251015)
|
|
2342
|
+
* @returns Short symbol (e.g. NHL0)
|
|
2343
|
+
*/
|
|
2344
|
+
public async getShortSymbol(symbol: string): Promise<string> {
|
|
2345
|
+
await this.refreshSymbols();
|
|
2346
|
+
if (!this.symbolToPerpStaticInfo.has(symbol)) {
|
|
2347
|
+
throw Error(`Symbol ${symbol} not found`);
|
|
2348
|
+
}
|
|
2349
|
+
const indexSymbol = PerpetualDataHandler.getIndexSymbol(this.symbolList, this.symbolToPerpStaticInfo.get(symbol)!);
|
|
2350
|
+
return indexSymbol.split("-")[0];
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
/**
|
|
2354
|
+
* Refreshes symbol mappings if at least one prediction market is expired
|
|
2355
|
+
*/
|
|
2356
|
+
public async refreshSymbols(): Promise<void> {
|
|
2357
|
+
const infos = [...this.indexSymbol.values()];
|
|
2358
|
+
if (!infos || infos.some(({ expiry }) => expiry < Date.now())) {
|
|
2359
|
+
// refresh
|
|
2360
|
+
await this._fillSymbolMaps({ chainId: this.chainId });
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2306
2363
|
}
|
package/src/traderInterface.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Contract, ContractTransactionResponse, Overrides, Signer } from "ethers";
|
|
2
|
-
import {
|
|
3
|
-
import { ABK64x64ToFloat, floatToDec18, floatToDecN
|
|
2
|
+
import { ZERO_ORDER_ID } from "./constants";
|
|
3
|
+
import { ABK64x64ToFloat, floatToDec18, floatToDecN } from "./d8XMath";
|
|
4
4
|
import MarketData from "./marketData";
|
|
5
5
|
import type { ClientOrder, NodeSDKConfig, Order, SmartContractOrder } from "./nodeSDKTypes";
|
|
6
6
|
import PerpetualDataHandler from "./perpetualDataHandler";
|
|
7
7
|
import TraderDigests from "./traderDigests";
|
|
8
|
-
import { containsFlag } from "./utils";
|
|
9
8
|
/**
|
|
10
9
|
* Interface that can be used by front-end that wraps all private functions
|
|
11
10
|
* so that signatures can be handled in frontend via wallet
|
|
@@ -127,6 +126,7 @@ export default class TraderInterface extends MarketData {
|
|
|
127
126
|
if (this.proxyContract == null) {
|
|
128
127
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
129
128
|
}
|
|
129
|
+
await this.refreshSymbols();
|
|
130
130
|
let orderBookContract = this.getOrderBookContract(symbol);
|
|
131
131
|
let scOrder: SmartContractOrder = await orderBookContract.orderOfDigest(orderId, overrides || {});
|
|
132
132
|
let digest = this.digestTool.createDigest(scOrder, this.chainId, false, this.proxyAddr);
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const D8X_SDK_VERSION = "2.6.
|
|
1
|
+
export const D8X_SDK_VERSION = "2.6.6";
|