@d8x/perpetuals-sdk 0.0.33 → 0.0.35
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/marketData.d.ts +8 -1
- package/dist/marketData.js +24 -0
- package/dist/orderReferrerTool.d.ts +4 -1
- package/dist/orderReferrerTool.js +50 -26
- package/dist/perpetualDataHandler.d.ts +1 -1
- package/dist/perpetualDataHandler.js +2 -5
- package/package.json +1 -1
- package/src/marketData.ts +26 -0
- package/src/orderReferrerTool.ts +70 -14
- package/src/perpetualDataHandler.ts +2 -5
package/dist/marketData.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExchangeInfo, NodeSDKConfig, MarginAccount, PerpetualState, PoolStaticInfo } from "./nodeSDKTypes";
|
|
1
|
+
import { ExchangeInfo, NodeSDKConfig, MarginAccount, PerpetualState, PoolStaticInfo, PerpetualStaticInfo } from "./nodeSDKTypes";
|
|
2
2
|
import { ethers } from "ethers";
|
|
3
3
|
import PerpetualDataHandler from "./perpetualDataHandler";
|
|
4
4
|
import { SmartContractOrder, Order } from "./nodeSDKTypes";
|
|
@@ -198,6 +198,13 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
198
198
|
* @returns PerpetualState reference
|
|
199
199
|
*/
|
|
200
200
|
getPerpetualState(symbol: string): Promise<PerpetualState>;
|
|
201
|
+
/**
|
|
202
|
+
* Query perpetual static info.
|
|
203
|
+
* This information is queried once at createProxyInstance-time and remains static after that.
|
|
204
|
+
* @param symbol symbol of the form ETH-USD-MATIC
|
|
205
|
+
* @returns PerpetualStaticInfo copy.
|
|
206
|
+
*/
|
|
207
|
+
getPerpetualStaticInfo(symbol: string): PerpetualStaticInfo;
|
|
201
208
|
/**
|
|
202
209
|
* get the current mid-price for a perpetual
|
|
203
210
|
* @param symbol symbol of the form ETH-USD-MATIC
|
package/dist/marketData.js
CHANGED
|
@@ -373,6 +373,30 @@ class MarketData extends perpetualDataHandler_1.default {
|
|
|
373
373
|
return state;
|
|
374
374
|
});
|
|
375
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Query perpetual static info.
|
|
378
|
+
* This information is queried once at createProxyInstance-time and remains static after that.
|
|
379
|
+
* @param symbol symbol of the form ETH-USD-MATIC
|
|
380
|
+
* @returns PerpetualStaticInfo copy.
|
|
381
|
+
*/
|
|
382
|
+
getPerpetualStaticInfo(symbol) {
|
|
383
|
+
let perpInfo = this.symbolToPerpStaticInfo.get(symbol);
|
|
384
|
+
if (perpInfo == undefined) {
|
|
385
|
+
throw Error(`Perpetual with symbol ${symbol} not found. Check symbol or use createProxyInstance().`);
|
|
386
|
+
}
|
|
387
|
+
// return new copy, not a reference
|
|
388
|
+
let res = {
|
|
389
|
+
id: perpInfo.id,
|
|
390
|
+
limitOrderBookAddr: perpInfo.limitOrderBookAddr,
|
|
391
|
+
initialMarginRate: perpInfo.initialMarginRate,
|
|
392
|
+
maintenanceMarginRate: perpInfo.maintenanceMarginRate,
|
|
393
|
+
collateralCurrencyType: perpInfo.collateralCurrencyType,
|
|
394
|
+
S2Symbol: perpInfo.S2Symbol,
|
|
395
|
+
S3Symbol: perpInfo.S3Symbol,
|
|
396
|
+
lotSizeBC: perpInfo.lotSizeBC,
|
|
397
|
+
};
|
|
398
|
+
return res;
|
|
399
|
+
}
|
|
376
400
|
/**
|
|
377
401
|
* get the current mid-price for a perpetual
|
|
378
402
|
* @param symbol symbol of the form ETH-USD-MATIC
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import WriteAccessHandler from "./writeAccessHandler";
|
|
2
|
-
import { NodeSDKConfig, Order } from "./nodeSDKTypes";
|
|
2
|
+
import { NodeSDKConfig, Order, PerpetualStaticInfo } from "./nodeSDKTypes";
|
|
3
3
|
import { ethers } from "ethers";
|
|
4
4
|
/**
|
|
5
5
|
* Functions to execute existing conditional orders from the limit order book. This class
|
|
@@ -8,6 +8,7 @@ import { ethers } from "ethers";
|
|
|
8
8
|
* @extends WriteAccessHandler
|
|
9
9
|
*/
|
|
10
10
|
export default class OrderReferrerTool extends WriteAccessHandler {
|
|
11
|
+
static BLOCK_DELAY: number;
|
|
11
12
|
/**
|
|
12
13
|
* Constructor.
|
|
13
14
|
* @param {NodeSDKConfig} config Configuration object, see PerpetualDataHandler.readSDKConfig.
|
|
@@ -172,5 +173,7 @@ export default class OrderReferrerTool extends WriteAccessHandler {
|
|
|
172
173
|
* @returns true if order can be executed for the current state of the perpetuals
|
|
173
174
|
*/
|
|
174
175
|
isTradeable(order: Order): Promise<boolean>;
|
|
176
|
+
isTradeableBatch(orders: Order[]): Promise<boolean[]>;
|
|
177
|
+
static _isTradeable(order: Order, orderPrice: number, markPrice: number, block: number, symbolToPerpInfoMap: Map<string, PerpetualStaticInfo>): boolean;
|
|
175
178
|
getTransactionCount(blockTag?: ethers.providers.BlockTag): Promise<number>;
|
|
176
179
|
}
|
|
@@ -249,38 +249,61 @@ class OrderReferrerTool extends writeAccessHandler_1.default {
|
|
|
249
249
|
if (this.proxyContract == null) {
|
|
250
250
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
251
251
|
}
|
|
252
|
-
// check expiration date
|
|
253
|
-
if (order.deadline != undefined && order.deadline < Date.now() / 1000) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
// check order size
|
|
257
|
-
if (order.quantity < perpetualDataHandler_1.default._getLotSize(order.symbol, this.symbolToPerpStaticInfo)) {
|
|
258
|
-
return false;
|
|
259
|
-
}
|
|
260
|
-
// check limit price, which may be undefined if it's an unrestricted market order
|
|
261
|
-
if (order.limitPrice == undefined) {
|
|
262
|
-
order.limitPrice = order.side == nodeSDKTypes_1.BUY_SIDE ? Infinity : 0;
|
|
263
|
-
}
|
|
264
252
|
let orderPrice = yield perpetualDataHandler_1.default._queryPerpetualPrice(order.symbol, order.quantity, this.symbolToPerpStaticInfo, this.proxyContract);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
253
|
+
let markPrice = yield perpetualDataHandler_1.default._queryPerpetualMarkPrice(order.symbol, this.symbolToPerpStaticInfo, this.proxyContract);
|
|
254
|
+
let block = yield this.provider.getBlockNumber();
|
|
255
|
+
return OrderReferrerTool._isTradeable(order, orderPrice, markPrice, block, this.symbolToPerpStaticInfo);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
isTradeableBatch(orders) {
|
|
259
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
if (orders.length == 0) {
|
|
261
|
+
return [];
|
|
268
262
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
// nothing to check, order is tradeable
|
|
272
|
-
return true;
|
|
263
|
+
if (this.proxyContract == null) {
|
|
264
|
+
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
273
265
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if ((order.side == nodeSDKTypes_1.BUY_SIDE && markPrice < order.stopPrice) ||
|
|
277
|
-
(order.side == nodeSDKTypes_1.SELL_SIDE && markPrice > order.stopPrice)) {
|
|
278
|
-
return false;
|
|
266
|
+
if (orders.filter((o) => o.symbol == orders[0].symbol).length < orders.length) {
|
|
267
|
+
throw Error("all orders in a batch must have the same symbol");
|
|
279
268
|
}
|
|
280
|
-
|
|
281
|
-
|
|
269
|
+
let orderPrice = yield Promise.all(orders.map((o) => perpetualDataHandler_1.default._queryPerpetualPrice(o.symbol, o.quantity, this.symbolToPerpStaticInfo, this.proxyContract)));
|
|
270
|
+
let markPrice = yield perpetualDataHandler_1.default._queryPerpetualMarkPrice(orders[0].symbol, this.symbolToPerpStaticInfo, this.proxyContract);
|
|
271
|
+
let block = yield this.provider.getBlockNumber();
|
|
272
|
+
return orders.map((o, idx) => OrderReferrerTool._isTradeable(o, orderPrice[idx], markPrice, block, this.symbolToPerpStaticInfo));
|
|
282
273
|
});
|
|
283
274
|
}
|
|
275
|
+
static _isTradeable(order, orderPrice, markPrice, block, symbolToPerpInfoMap) {
|
|
276
|
+
// check expiration date
|
|
277
|
+
if (order.deadline != undefined && order.deadline < Date.now() / 1000) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
if (order.submittedBlock == undefined || order.submittedBlock + this.BLOCK_DELAY > block) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
// check order size
|
|
284
|
+
if (order.quantity < perpetualDataHandler_1.default._getLotSize(order.symbol, symbolToPerpInfoMap)) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
// check limit price, which may be undefined if it's an unrestricted market order
|
|
288
|
+
if (order.limitPrice == undefined) {
|
|
289
|
+
order.limitPrice = order.side == nodeSDKTypes_1.BUY_SIDE ? Infinity : 0;
|
|
290
|
+
}
|
|
291
|
+
if ((order.side == nodeSDKTypes_1.BUY_SIDE && orderPrice > order.limitPrice) ||
|
|
292
|
+
(order.side == nodeSDKTypes_1.SELL_SIDE && orderPrice < order.limitPrice)) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
// do we need to check trigger/stop?
|
|
296
|
+
if (order.stopPrice == undefined) {
|
|
297
|
+
// nothing to check, order is tradeable
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
if ((order.side == nodeSDKTypes_1.BUY_SIDE && markPrice < order.stopPrice) ||
|
|
301
|
+
(order.side == nodeSDKTypes_1.SELL_SIDE && markPrice > order.stopPrice)) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
// all checks passed -> order is tradeable
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
284
307
|
getTransactionCount(blockTag) {
|
|
285
308
|
return __awaiter(this, void 0, void 0, function* () {
|
|
286
309
|
if (this.signer == null) {
|
|
@@ -291,3 +314,4 @@ class OrderReferrerTool extends writeAccessHandler_1.default {
|
|
|
291
314
|
}
|
|
292
315
|
}
|
|
293
316
|
exports.default = OrderReferrerTool;
|
|
317
|
+
OrderReferrerTool.BLOCK_DELAY = 2;
|
|
@@ -84,7 +84,7 @@ export default class PerpetualDataHandler {
|
|
|
84
84
|
*/
|
|
85
85
|
protected static symbolToPerpetualId(symbol: string, symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>): number;
|
|
86
86
|
/**
|
|
87
|
-
* Find the symbol ("ETH-USD-
|
|
87
|
+
* Find the long symbol ("ETH-USD-MATIC") of the given perpetual id
|
|
88
88
|
* @param id perpetual id
|
|
89
89
|
* @param symbolToPerpStaticInfo map that contains the bytes4-symbol to PerpetualStaticInfo
|
|
90
90
|
* @returns symbol string or undefined
|
|
@@ -174,10 +174,7 @@ class PerpetualDataHandler {
|
|
|
174
174
|
* @param perpId perpetual id
|
|
175
175
|
*/
|
|
176
176
|
getSymbolFromPerpId(perpId) {
|
|
177
|
-
|
|
178
|
-
if (symbol4Bytes == undefined) {
|
|
179
|
-
return undefined;
|
|
180
|
-
}
|
|
177
|
+
return PerpetualDataHandler.perpetualIdToSymbol(perpId, this.symbolToPerpStaticInfo);
|
|
181
178
|
}
|
|
182
179
|
symbol4BToLongSymbol(sym) {
|
|
183
180
|
return (0, utils_1.symbol4BToLongSymbol)(sym, this.symbolList);
|
|
@@ -354,7 +351,7 @@ class PerpetualDataHandler {
|
|
|
354
351
|
return id;
|
|
355
352
|
}
|
|
356
353
|
/**
|
|
357
|
-
* Find the symbol ("ETH-USD-
|
|
354
|
+
* Find the long symbol ("ETH-USD-MATIC") of the given perpetual id
|
|
358
355
|
* @param id perpetual id
|
|
359
356
|
* @param symbolToPerpStaticInfo map that contains the bytes4-symbol to PerpetualStaticInfo
|
|
360
357
|
* @returns symbol string or undefined
|
package/package.json
CHANGED
package/src/marketData.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
CLOSED_SIDE,
|
|
14
14
|
SELL_SIDE,
|
|
15
15
|
CollaterlCCY,
|
|
16
|
+
PerpetualStaticInfo,
|
|
16
17
|
} from "./nodeSDKTypes";
|
|
17
18
|
import { BigNumber, BytesLike, ethers } from "ethers";
|
|
18
19
|
import {
|
|
@@ -456,6 +457,31 @@ export default class MarketData extends PerpetualDataHandler {
|
|
|
456
457
|
return state;
|
|
457
458
|
}
|
|
458
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Query perpetual static info.
|
|
462
|
+
* This information is queried once at createProxyInstance-time and remains static after that.
|
|
463
|
+
* @param symbol symbol of the form ETH-USD-MATIC
|
|
464
|
+
* @returns PerpetualStaticInfo copy.
|
|
465
|
+
*/
|
|
466
|
+
public getPerpetualStaticInfo(symbol: string): PerpetualStaticInfo {
|
|
467
|
+
let perpInfo = this.symbolToPerpStaticInfo.get(symbol);
|
|
468
|
+
if (perpInfo == undefined) {
|
|
469
|
+
throw Error(`Perpetual with symbol ${symbol} not found. Check symbol or use createProxyInstance().`);
|
|
470
|
+
}
|
|
471
|
+
// return new copy, not a reference
|
|
472
|
+
let res: PerpetualStaticInfo = {
|
|
473
|
+
id: perpInfo.id,
|
|
474
|
+
limitOrderBookAddr: perpInfo.limitOrderBookAddr,
|
|
475
|
+
initialMarginRate: perpInfo.initialMarginRate,
|
|
476
|
+
maintenanceMarginRate: perpInfo.maintenanceMarginRate,
|
|
477
|
+
collateralCurrencyType: perpInfo.collateralCurrencyType,
|
|
478
|
+
S2Symbol: perpInfo.S2Symbol,
|
|
479
|
+
S3Symbol: perpInfo.S3Symbol,
|
|
480
|
+
lotSizeBC: perpInfo.lotSizeBC,
|
|
481
|
+
};
|
|
482
|
+
return res;
|
|
483
|
+
}
|
|
484
|
+
|
|
459
485
|
/**
|
|
460
486
|
* get the current mid-price for a perpetual
|
|
461
487
|
* @param symbol symbol of the form ETH-USD-MATIC
|
package/src/orderReferrerTool.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import WriteAccessHandler from "./writeAccessHandler";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BUY_SIDE,
|
|
4
|
+
NodeSDKConfig,
|
|
5
|
+
Order,
|
|
6
|
+
PerpetualStaticInfo,
|
|
7
|
+
SELL_SIDE,
|
|
8
|
+
ZERO_ADDRESS,
|
|
9
|
+
ZERO_ORDER_ID,
|
|
10
|
+
} from "./nodeSDKTypes";
|
|
3
11
|
import { BigNumber, ethers } from "ethers";
|
|
4
12
|
import PerpetualDataHandler from "./perpetualDataHandler";
|
|
5
13
|
|
|
@@ -10,6 +18,7 @@ import PerpetualDataHandler from "./perpetualDataHandler";
|
|
|
10
18
|
* @extends WriteAccessHandler
|
|
11
19
|
*/
|
|
12
20
|
export default class OrderReferrerTool extends WriteAccessHandler {
|
|
21
|
+
static BLOCK_DELAY = 2;
|
|
13
22
|
/**
|
|
14
23
|
* Constructor.
|
|
15
24
|
* @param {NodeSDKConfig} config Configuration object, see PerpetualDataHandler.readSDKConfig.
|
|
@@ -236,24 +245,77 @@ export default class OrderReferrerTool extends WriteAccessHandler {
|
|
|
236
245
|
if (this.proxyContract == null) {
|
|
237
246
|
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
238
247
|
}
|
|
248
|
+
let orderPrice = await PerpetualDataHandler._queryPerpetualPrice(
|
|
249
|
+
order.symbol,
|
|
250
|
+
order.quantity,
|
|
251
|
+
this.symbolToPerpStaticInfo,
|
|
252
|
+
this.proxyContract
|
|
253
|
+
);
|
|
254
|
+
let markPrice = await PerpetualDataHandler._queryPerpetualMarkPrice(
|
|
255
|
+
order.symbol,
|
|
256
|
+
this.symbolToPerpStaticInfo,
|
|
257
|
+
this.proxyContract
|
|
258
|
+
);
|
|
259
|
+
let block = await this.provider!.getBlockNumber();
|
|
260
|
+
return OrderReferrerTool._isTradeable(order, orderPrice, markPrice, block, this.symbolToPerpStaticInfo);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
public async isTradeableBatch(orders: Order[]): Promise<boolean[]> {
|
|
264
|
+
if (orders.length == 0) {
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
if (this.proxyContract == null) {
|
|
268
|
+
throw Error("no proxy contract initialized. Use createProxyInstance().");
|
|
269
|
+
}
|
|
270
|
+
if (orders.filter((o) => o.symbol == orders[0].symbol).length < orders.length) {
|
|
271
|
+
throw Error("all orders in a batch must have the same symbol");
|
|
272
|
+
}
|
|
273
|
+
let orderPrice = await Promise.all(
|
|
274
|
+
orders.map((o) =>
|
|
275
|
+
PerpetualDataHandler._queryPerpetualPrice(
|
|
276
|
+
o.symbol,
|
|
277
|
+
o.quantity,
|
|
278
|
+
this.symbolToPerpStaticInfo,
|
|
279
|
+
this.proxyContract!
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
);
|
|
283
|
+
let markPrice = await PerpetualDataHandler._queryPerpetualMarkPrice(
|
|
284
|
+
orders[0].symbol,
|
|
285
|
+
this.symbolToPerpStaticInfo,
|
|
286
|
+
this.proxyContract
|
|
287
|
+
);
|
|
288
|
+
let block = await this.provider!.getBlockNumber();
|
|
289
|
+
return orders.map((o, idx) =>
|
|
290
|
+
OrderReferrerTool._isTradeable(o, orderPrice[idx], markPrice, block, this.symbolToPerpStaticInfo)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
public static _isTradeable(
|
|
295
|
+
order: Order,
|
|
296
|
+
orderPrice: number,
|
|
297
|
+
markPrice: number,
|
|
298
|
+
block: number,
|
|
299
|
+
symbolToPerpInfoMap: Map<string, PerpetualStaticInfo>
|
|
300
|
+
): boolean {
|
|
239
301
|
// check expiration date
|
|
240
302
|
if (order.deadline != undefined && order.deadline < Date.now() / 1000) {
|
|
241
303
|
return false;
|
|
242
304
|
}
|
|
305
|
+
|
|
306
|
+
if (order.submittedBlock == undefined || order.submittedBlock + this.BLOCK_DELAY > block) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
|
|
243
310
|
// check order size
|
|
244
|
-
if (order.quantity < PerpetualDataHandler._getLotSize(order.symbol,
|
|
311
|
+
if (order.quantity < PerpetualDataHandler._getLotSize(order.symbol, symbolToPerpInfoMap)) {
|
|
245
312
|
return false;
|
|
246
313
|
}
|
|
247
314
|
// check limit price, which may be undefined if it's an unrestricted market order
|
|
248
315
|
if (order.limitPrice == undefined) {
|
|
249
316
|
order.limitPrice = order.side == BUY_SIDE ? Infinity : 0;
|
|
250
317
|
}
|
|
251
|
-
|
|
252
|
-
order.symbol,
|
|
253
|
-
order.quantity,
|
|
254
|
-
this.symbolToPerpStaticInfo,
|
|
255
|
-
this.proxyContract
|
|
256
|
-
);
|
|
318
|
+
|
|
257
319
|
if (
|
|
258
320
|
(order.side == BUY_SIDE && orderPrice > order.limitPrice) ||
|
|
259
321
|
(order.side == SELL_SIDE && orderPrice < order.limitPrice)
|
|
@@ -265,12 +327,6 @@ export default class OrderReferrerTool extends WriteAccessHandler {
|
|
|
265
327
|
// nothing to check, order is tradeable
|
|
266
328
|
return true;
|
|
267
329
|
}
|
|
268
|
-
// we need the mark price to check
|
|
269
|
-
let markPrice = await PerpetualDataHandler._queryPerpetualMarkPrice(
|
|
270
|
-
order.symbol,
|
|
271
|
-
this.symbolToPerpStaticInfo,
|
|
272
|
-
this.proxyContract
|
|
273
|
-
);
|
|
274
330
|
if (
|
|
275
331
|
(order.side == BUY_SIDE && markPrice < order.stopPrice) ||
|
|
276
332
|
(order.side == SELL_SIDE && markPrice > order.stopPrice)
|
|
@@ -234,10 +234,7 @@ export default class PerpetualDataHandler {
|
|
|
234
234
|
* @param perpId perpetual id
|
|
235
235
|
*/
|
|
236
236
|
public getSymbolFromPerpId(perpId: number): string | undefined {
|
|
237
|
-
|
|
238
|
-
if (symbol4Bytes == undefined) {
|
|
239
|
-
return undefined;
|
|
240
|
-
}
|
|
237
|
+
return PerpetualDataHandler.perpetualIdToSymbol(perpId, this.symbolToPerpStaticInfo);
|
|
241
238
|
}
|
|
242
239
|
|
|
243
240
|
public symbol4BToLongSymbol(sym: string): string {
|
|
@@ -449,7 +446,7 @@ export default class PerpetualDataHandler {
|
|
|
449
446
|
}
|
|
450
447
|
|
|
451
448
|
/**
|
|
452
|
-
* Find the symbol ("ETH-USD-
|
|
449
|
+
* Find the long symbol ("ETH-USD-MATIC") of the given perpetual id
|
|
453
450
|
* @param id perpetual id
|
|
454
451
|
* @param symbolToPerpStaticInfo map that contains the bytes4-symbol to PerpetualStaticInfo
|
|
455
452
|
* @returns symbol string or undefined
|