@d8x/perpetuals-sdk 0.0.23 → 0.0.24

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.
@@ -1,9 +1,13 @@
1
- [
2
- { "symbol": "USD", "cleanSymbol": "USD" },
3
- { "symbol": "BTC", "cleanSymbol": "BTC" },
4
- { "symbol": "ETH", "cleanSymbol": "ETH" },
5
- { "symbol": "MATIC", "cleanSymbol": "MATC" },
6
- { "symbol": "CHF", "cleanSymbol": "CHF" },
7
- { "symbol": "GBP", "cleanSymbol": "GBP" },
8
- { "symbol": "XAU", "cleanSymbol": "XAU" }
9
- ]
1
+ {
2
+ "MATC": "MATIC",
3
+ "ETH": "ETH",
4
+ "BTC": "BTC",
5
+ "USDC": "USDC",
6
+ "XAU": "XAU",
7
+ "XAG": "XAG",
8
+ "USD": "USD",
9
+ "GBP": "GBP",
10
+ "CHF": "CHF",
11
+ "EUR": "EUR",
12
+ "JPY": "JPY"
13
+ }
@@ -154,8 +154,6 @@ class AccountTrade extends writeAccessHandler_1.default {
154
154
  throw Error("order size too small");
155
155
  }
156
156
  let orderBookContract = this.getOrderBookContract(order.symbol);
157
- let tx;
158
- let orderId;
159
157
  let res = yield this._order(order, this.traderAddr, this.symbolToPerpStaticInfo, this.proxyContract, orderBookContract, this.chainId, this.signer, this.gasLimit);
160
158
  return res;
161
159
  });
@@ -249,11 +249,8 @@ export default class BrokerTool extends WriteAccessHandler {
249
249
  /**
250
250
  * Adds this broker's signature to an order. An order signed by a broker is considered
251
251
  * to be routed through this broker and benefits from the broker's fee conditions.
252
- * @param {Order} order Order to sign.
252
+ * @param {Order} order Order to sign. It must contain valid broker fee, broker address, and order deadline.
253
253
  * @param {string} traderAddr Address of trader submitting the order.
254
- * @param {number} feeDecimals Fee that this broker imposes on this order.
255
- * The fee is sent to the broker's wallet. Fee should be specified in decimals, e.g., 0.0001 equals 1bps.
256
- * @param {number} deadline Deadline for the order to be executed. Specify deadline as a unix timestamp
257
254
  * @example
258
255
  * import { BrokerTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
259
256
  * async function main() {
@@ -281,7 +278,7 @@ export default class BrokerTool extends WriteAccessHandler {
281
278
  *
282
279
  * @returns {Order} An order signed by this broker, which can be submitted directly with AccountTrade.order.
283
280
  */
284
- signOrder(order: Order, traderAddr: string, brokerFee: number, deadline: number): Promise<Order>;
281
+ signOrder(order: Order, traderAddr: string): Promise<Order>;
285
282
  /**
286
283
  * Creates a signature that a trader can use to place orders with this broker.
287
284
  * This signature can be used to pass on to a trader who wishes to trade via this SDK or directly on the blockchain.
@@ -367,11 +367,8 @@ class BrokerTool extends writeAccessHandler_1.default {
367
367
  /**
368
368
  * Adds this broker's signature to an order. An order signed by a broker is considered
369
369
  * to be routed through this broker and benefits from the broker's fee conditions.
370
- * @param {Order} order Order to sign.
370
+ * @param {Order} order Order to sign. It must contain valid broker fee, broker address, and order deadline.
371
371
  * @param {string} traderAddr Address of trader submitting the order.
372
- * @param {number} feeDecimals Fee that this broker imposes on this order.
373
- * The fee is sent to the broker's wallet. Fee should be specified in decimals, e.g., 0.0001 equals 1bps.
374
- * @param {number} deadline Deadline for the order to be executed. Specify deadline as a unix timestamp
375
372
  * @example
376
373
  * import { BrokerTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
377
374
  * async function main() {
@@ -399,15 +396,12 @@ class BrokerTool extends writeAccessHandler_1.default {
399
396
  *
400
397
  * @returns {Order} An order signed by this broker, which can be submitted directly with AccountTrade.order.
401
398
  */
402
- signOrder(order, traderAddr, brokerFee, deadline) {
399
+ signOrder(order, traderAddr) {
403
400
  return __awaiter(this, void 0, void 0, function* () {
404
401
  if (this.proxyContract == null || this.signer == null) {
405
402
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
406
403
  }
407
- order.brokerAddr = this.traderAddr;
408
- order.brokerFeeTbps = brokerFee * 100000;
409
- order.deadline = Math.round(deadline);
410
- order.brokerSignature = yield BrokerTool._signOrder(order.symbol, order.brokerFeeTbps, traderAddr, ethers_1.BigNumber.from(Math.round(deadline)), this.signer, this.chainId, this.proxyAddr, this.symbolToPerpStaticInfo);
404
+ order.brokerSignature = yield BrokerTool._signOrder(order.symbol, order.brokerFeeTbps, traderAddr, ethers_1.BigNumber.from(order.deadline), this.signer, this.chainId, this.proxyAddr, this.symbolToPerpStaticInfo);
411
405
  return order;
412
406
  });
413
407
  }
package/dist/d8XMath.d.ts CHANGED
@@ -83,7 +83,7 @@ export declare function calculateLiquidationPriceCollateralQuote(LockedInValueQC
83
83
  * @param indexPriceS3 Collateral index price, positive.
84
84
  * @param tradePrice Expected price to trade tradeAmount.
85
85
  * @param feeRate
86
- * @returns
86
+ * @returns Total collateral amount needed for the new position to have he desired leverage.
87
87
  */
88
88
  export declare function getMarginRequiredForLeveragedTrade(targetLeverage: number | undefined, currentPosition: number, currentLockedInValue: number, tradeAmount: number, markPrice: number, indexPriceS2: number, indexPriceS3: number, tradePrice: number, feeRate: number): number;
89
89
  export declare function getMaxSignedPositionSize(marginCollateral: number, currentPosition: number, currentLockedInValue: number, direction: number, limitPrice: number, initialMarginRate: number, feeRate: number, markPrice: number, indexPriceS2: number, indexPriceS3: number): number;
package/dist/d8XMath.js CHANGED
@@ -173,7 +173,7 @@ exports.calculateLiquidationPriceCollateralQuote = calculateLiquidationPriceColl
173
173
  * @param indexPriceS3 Collateral index price, positive.
174
174
  * @param tradePrice Expected price to trade tradeAmount.
175
175
  * @param feeRate
176
- * @returns
176
+ * @returns Total collateral amount needed for the new position to have he desired leverage.
177
177
  */
178
178
  function getMarginRequiredForLeveragedTrade(targetLeverage, currentPosition, currentLockedInValue, tradeAmount, markPrice, indexPriceS2, indexPriceS3, tradePrice, feeRate) {
179
179
  // we solve for margin in:
@@ -0,0 +1,14 @@
1
+ import WriteAccessHandler from "./writeAccessHandler";
2
+ import { NodeSDKConfig } from "./nodeSDKTypes";
3
+ /**
4
+ * LiquidatorTool
5
+ * Methods to liquidate traders
6
+ */
7
+ export default class LiquidatorTool extends WriteAccessHandler {
8
+ /**
9
+ * Constructor
10
+ * @param config configuration
11
+ * @param privateKey private key of account that trades
12
+ */
13
+ constructor(config: NodeSDKConfig, privateKey: string);
14
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const writeAccessHandler_1 = __importDefault(require("./writeAccessHandler"));
7
+ /**
8
+ * LiquidatorTool
9
+ * Methods to liquidate traders
10
+ */
11
+ class LiquidatorTool extends writeAccessHandler_1.default {
12
+ /**
13
+ * Constructor
14
+ * @param config configuration
15
+ * @param privateKey private key of account that trades
16
+ */
17
+ constructor(config, privateKey) {
18
+ super(config, privateKey);
19
+ }
20
+ }
21
+ exports.default = LiquidatorTool;
@@ -150,6 +150,7 @@ export default class MarketData extends PerpetualDataHandler {
150
150
  * @returns {number} Price of index in given currency.
151
151
  */
152
152
  getOraclePrice(base: string, quote: string): Promise<number | undefined>;
153
+ getOrderStatus(symbol: string, orderId: string): Promise<string>;
153
154
  /**
154
155
  * Get the current mark price
155
156
  * @param symbol symbol of the form ETH-USD-MATIC
@@ -233,7 +234,5 @@ export default class MarketData extends PerpetualDataHandler {
233
234
  * @ignore
234
235
  */
235
236
  static orderIdsOfTrader(traderAddr: string, orderBookContract: ethers.Contract): Promise<string[]>;
236
- static _exchangeInfo(_proxyContract: ethers.Contract, _poolStaticInfos: Array<PoolStaticInfo>, _symbolList: Array<{
237
- [key: string]: string;
238
- }>): Promise<ExchangeInfo>;
237
+ static _exchangeInfo(_proxyContract: ethers.Contract, _poolStaticInfos: Array<PoolStaticInfo>, _symbolList: Map<string, string>): Promise<ExchangeInfo>;
239
238
  }
@@ -293,6 +293,17 @@ class MarketData extends perpetualDataHandler_1.default {
293
293
  return px == undefined ? undefined : (0, d8XMath_1.ABK64x64ToFloat)(px);
294
294
  });
295
295
  }
296
+ getOrderStatus(symbol, orderId) {
297
+ return __awaiter(this, void 0, void 0, function* () {
298
+ if (this.proxyContract == null) {
299
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
300
+ }
301
+ let orderBookContract = null;
302
+ orderBookContract = this.getOrderBookContract(symbol);
303
+ let status = yield orderBookContract.getOrderStatus(orderId);
304
+ return status;
305
+ });
306
+ }
296
307
  /**
297
308
  * Get the current mark price
298
309
  * @param symbol symbol of the form ETH-USD-MATIC
@@ -7,9 +7,7 @@ import { NodeSDKConfig, Order, SmartContractOrder, PerpetualStaticInfo, MarginAc
7
7
  export default class PerpetualDataHandler {
8
8
  protected symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>;
9
9
  protected poolStaticInfos: Array<PoolStaticInfo>;
10
- protected symbolList: Array<{
11
- [key: string]: string;
12
- }>;
10
+ protected symbolList: Map<string, string>;
13
11
  protected symbolToTokenAddrMap: Map<string, string>;
14
12
  protected proxyContract: ethers.Contract | null;
15
13
  protected proxyABI: ethers.ContractInterface;
@@ -34,7 +34,7 @@ class PerpetualDataHandler {
34
34
  this.proxyABI = require(config.proxyABILocation);
35
35
  this.lobFactoryABI = require(config.limitOrderBookFactoryABILocation);
36
36
  this.lobABI = require(config.limitOrderBookABILocation);
37
- this.symbolList = require(config.symbolListLocation);
37
+ this.symbolList = new Map(Object.entries(require(config.symbolListLocation)));
38
38
  }
39
39
  initContractsAndData(signerOrProvider) {
40
40
  return __awaiter(this, void 0, void 0, function* () {
@@ -95,21 +95,23 @@ class PerpetualDataHandler {
95
95
  // try to find a limit order book
96
96
  let lobAddr = yield this.lobFactoryContract.getOrderBookAddress(perpetualIDs[k]);
97
97
  currentLimitOrderBookAddr.push(lobAddr);
98
- // we find out the pool currency by looking at all perpetuals
99
- // unless for quanto perpetuals, we know the pool currency
100
- // from the perpetual. This fails if we have a pool with only
101
- // quanto perpetuals
102
- if (perp.eCollateralCurrency == nodeSDKTypes_1.COLLATERAL_CURRENCY_BASE) {
103
- poolCCY = base;
104
- ccy.push(nodeSDKTypes_1.CollaterlCCY.BASE);
105
- }
106
- else if (perp.eCollateralCurrency == nodeSDKTypes_1.COLLATERAL_CURRENCY_QUOTE) {
107
- poolCCY = quote;
108
- ccy.push(nodeSDKTypes_1.CollaterlCCY.QUOTE);
109
- }
110
- else {
111
- poolCCY = base3;
112
- ccy.push(nodeSDKTypes_1.CollaterlCCY.QUANTO);
98
+ if (poolCCY == undefined) {
99
+ // we find out the pool currency by looking at all perpetuals
100
+ // unless for quanto perpetuals, we know the pool currency
101
+ // from the perpetual. This fails if we have a pool with only
102
+ // quanto perpetuals
103
+ if (perp.eCollateralCurrency == nodeSDKTypes_1.COLLATERAL_CURRENCY_BASE) {
104
+ poolCCY = base;
105
+ ccy.push(nodeSDKTypes_1.CollaterlCCY.BASE);
106
+ }
107
+ else if (perp.eCollateralCurrency == nodeSDKTypes_1.COLLATERAL_CURRENCY_QUOTE) {
108
+ poolCCY = quote;
109
+ ccy.push(nodeSDKTypes_1.CollaterlCCY.QUOTE);
110
+ }
111
+ else {
112
+ poolCCY = base3;
113
+ ccy.push(nodeSDKTypes_1.CollaterlCCY.QUANTO);
114
+ }
113
115
  }
114
116
  }
115
117
  if (perpetualIDs.length == 0) {
package/dist/utils.d.ts CHANGED
@@ -35,21 +35,24 @@ export declare function fromBytes4(b: Buffer): string;
35
35
  export declare function fromBytes4HexString(s: string): string;
36
36
  /**
37
37
  *
38
- * @param {string} s string representing a hex-number ("0x...")
39
- * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
40
- * @returns {string} user friendly currency symbol, e.g. "MATIC"
38
+ * @param {string} s String representing a hex-number ("0x...")
39
+ * @param {Object} mapping List of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
40
+ * @returns {string} User friendly currency symbol, e.g. "MATIC"
41
+ */
42
+ export declare function contractSymbolToSymbol(s: string, mapping: Map<string, string>): string;
43
+ /**
44
+ *
45
+ * @param {string} s User friendly currency symbol, e.g. "MATIC"
46
+ * @param {Object} mapping List of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
47
+ * @returns {Buffer} Buffer that can be used with smart contract to identify tokens
41
48
  */
42
- export declare function contractSymbolToSymbol(s: string, mapping: Array<{
43
- [key: string]: string;
44
- }>): string | undefined;
49
+ export declare function symbolToContractSymbol(s: string, mapping: Map<string, string>): Buffer;
45
50
  /**
46
51
  * Converts symbol or symbol combination into long format
47
52
  * @param {string} s symbol, e.g., USDC-MATC-USDC, MATC, USDC, ...
48
53
  * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
49
54
  * @returns {string} long format e.g. MATIC. if not found the element is ""
50
55
  */
51
- export declare function symbol4BToLongSymbol(s: string, mapping: Array<{
52
- [key: string]: string;
53
- }>): string;
56
+ export declare function symbol4BToLongSymbol(s: string, mapping: Map<string, string>): string;
54
57
  export declare function combineFlags(f1: BigNumber, f2: BigNumber): BigNumber;
55
58
  export declare function containsFlag(f1: BigNumber, f2: BigNumber): boolean;
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.containsFlag = exports.combineFlags = exports.symbol4BToLongSymbol = exports.contractSymbolToSymbol = exports.fromBytes4HexString = exports.fromBytes4 = exports.toBytes4 = exports.to4Chars = void 0;
3
+ exports.containsFlag = exports.combineFlags = exports.symbol4BToLongSymbol = exports.symbolToContractSymbol = exports.contractSymbolToSymbol = exports.fromBytes4HexString = exports.fromBytes4 = exports.toBytes4 = exports.to4Chars = void 0;
4
4
  const ethers_1 = require("ethers");
5
5
  /**
6
6
  * @module utils
@@ -78,19 +78,36 @@ function fromBytes4HexString(s) {
78
78
  exports.fromBytes4HexString = fromBytes4HexString;
79
79
  /**
80
80
  *
81
- * @param {string} s string representing a hex-number ("0x...")
82
- * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
83
- * @returns {string} user friendly currency symbol, e.g. "MATIC"
81
+ * @param {string} s String representing a hex-number ("0x...")
82
+ * @param {Object} mapping List of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
83
+ * @returns {string} User friendly currency symbol, e.g. "MATIC"
84
84
  */
85
85
  function contractSymbolToSymbol(s, mapping) {
86
- s = fromBytes4HexString(s);
87
- for (let pair of mapping) {
88
- if (pair.cleanSymbol == s) {
89
- return pair.symbol;
86
+ var _a;
87
+ let shortCCY = fromBytes4HexString(s);
88
+ // assume CCY is already short if not in the mapping file
89
+ let longCCY = (_a = mapping.get(shortCCY)) !== null && _a !== void 0 ? _a : shortCCY;
90
+ return longCCY;
91
+ }
92
+ exports.contractSymbolToSymbol = contractSymbolToSymbol;
93
+ /**
94
+ *
95
+ * @param {string} s User friendly currency symbol, e.g. "MATIC"
96
+ * @param {Object} mapping List of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
97
+ * @returns {Buffer} Buffer that can be used with smart contract to identify tokens
98
+ */
99
+ function symbolToContractSymbol(s, mapping) {
100
+ let shortCCY = undefined;
101
+ for (let [k, v] of mapping) {
102
+ if (v == s) {
103
+ shortCCY = k;
90
104
  }
91
105
  }
106
+ // if not in the mapping file, assume ccy is already valid
107
+ shortCCY = shortCCY !== null && shortCCY !== void 0 ? shortCCY : s;
108
+ return toBytes4(shortCCY);
92
109
  }
93
- exports.contractSymbolToSymbol = contractSymbolToSymbol;
110
+ exports.symbolToContractSymbol = symbolToContractSymbol;
94
111
  /**
95
112
  * Converts symbol or symbol combination into long format
96
113
  * @param {string} s symbol, e.g., USDC-MATC-USDC, MATC, USDC, ...
@@ -98,16 +115,13 @@ exports.contractSymbolToSymbol = contractSymbolToSymbol;
98
115
  * @returns {string} long format e.g. MATIC. if not found the element is ""
99
116
  */
100
117
  function symbol4BToLongSymbol(s, mapping) {
118
+ var _a;
101
119
  let ccy = s.split("-");
102
120
  let longCCY = "";
103
121
  for (let k = 0; k < ccy.length; k++) {
104
- let sym = ccy[k];
105
- for (let pair of mapping) {
106
- if (pair.cleanSymbol == sym) {
107
- longCCY = longCCY + "-" + pair.symbol;
108
- break;
109
- }
110
- }
122
+ let sym = (_a = mapping.get(ccy[k])) !== null && _a !== void 0 ? _a : to4Chars(ccy[k]);
123
+ sym = sym.replace(/\0/g, "");
124
+ longCCY = longCCY + "-" + sym;
111
125
  }
112
126
  return longCCY.substring(1);
113
127
  }
package/package.json CHANGED
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "name": "@d8x/perpetuals-sdk",
29
29
  "description": "Node TypeScript SDK for D8X Perpetual Futures",
30
- "version": "0.0.23",
30
+ "version": "0.0.24",
31
31
  "main": "./dist/index.js",
32
32
  "types": "./dist/index.d.ts",
33
33
  "directories": {
@@ -150,8 +150,6 @@ export default class AccountTrade extends WriteAccessHandler {
150
150
  throw Error("order size too small");
151
151
  }
152
152
  let orderBookContract: ethers.Contract = this.getOrderBookContract(order.symbol);
153
- let tx: ethers.ContractTransaction;
154
- let orderId: string;
155
153
  let res: OrderResponse = await this._order(
156
154
  order,
157
155
  this.traderAddr,
package/src/brokerTool.ts CHANGED
@@ -349,11 +349,8 @@ export default class BrokerTool extends WriteAccessHandler {
349
349
  /**
350
350
  * Adds this broker's signature to an order. An order signed by a broker is considered
351
351
  * to be routed through this broker and benefits from the broker's fee conditions.
352
- * @param {Order} order Order to sign.
352
+ * @param {Order} order Order to sign. It must contain valid broker fee, broker address, and order deadline.
353
353
  * @param {string} traderAddr Address of trader submitting the order.
354
- * @param {number} feeDecimals Fee that this broker imposes on this order.
355
- * The fee is sent to the broker's wallet. Fee should be specified in decimals, e.g., 0.0001 equals 1bps.
356
- * @param {number} deadline Deadline for the order to be executed. Specify deadline as a unix timestamp
357
354
  * @example
358
355
  * import { BrokerTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
359
356
  * async function main() {
@@ -381,18 +378,15 @@ export default class BrokerTool extends WriteAccessHandler {
381
378
  *
382
379
  * @returns {Order} An order signed by this broker, which can be submitted directly with AccountTrade.order.
383
380
  */
384
- public async signOrder(order: Order, traderAddr: string, brokerFee: number, deadline: number): Promise<Order> {
381
+ public async signOrder(order: Order, traderAddr: string): Promise<Order> {
385
382
  if (this.proxyContract == null || this.signer == null) {
386
383
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
387
384
  }
388
- order.brokerAddr = this.traderAddr;
389
- order.brokerFeeTbps = brokerFee * 100_000;
390
- order.deadline = Math.round(deadline);
391
385
  order.brokerSignature = await BrokerTool._signOrder(
392
386
  order.symbol,
393
- order.brokerFeeTbps,
387
+ order.brokerFeeTbps!,
394
388
  traderAddr,
395
- BigNumber.from(Math.round(deadline)),
389
+ BigNumber.from(order.deadline),
396
390
  this.signer,
397
391
  this.chainId,
398
392
  this.proxyAddr,
package/src/d8XMath.ts CHANGED
@@ -190,7 +190,7 @@ export function calculateLiquidationPriceCollateralQuote(
190
190
  * @param indexPriceS3 Collateral index price, positive.
191
191
  * @param tradePrice Expected price to trade tradeAmount.
192
192
  * @param feeRate
193
- * @returns
193
+ * @returns Total collateral amount needed for the new position to have he desired leverage.
194
194
  */
195
195
  export function getMarginRequiredForLeveragedTrade(
196
196
  targetLeverage: number | undefined,
package/src/marketData.ts CHANGED
@@ -371,6 +371,16 @@ export default class MarketData extends PerpetualDataHandler {
371
371
  return px == undefined ? undefined : ABK64x64ToFloat(px);
372
372
  }
373
373
 
374
+ public async getOrderStatus(symbol: string, orderId: string): Promise<string> {
375
+ if (this.proxyContract == null) {
376
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
377
+ }
378
+ let orderBookContract: ethers.Contract | null = null;
379
+ orderBookContract = this.getOrderBookContract(symbol);
380
+ let status = await orderBookContract.getOrderStatus(orderId);
381
+ return status;
382
+ }
383
+
374
384
  /**
375
385
  * Get the current mark price
376
386
  * @param symbol symbol of the form ETH-USD-MATIC
@@ -512,7 +522,7 @@ export default class MarketData extends PerpetualDataHandler {
512
522
  public static async _exchangeInfo(
513
523
  _proxyContract: ethers.Contract,
514
524
  _poolStaticInfos: Array<PoolStaticInfo>,
515
- _symbolList: Array<{ [key: string]: string }>
525
+ _symbolList: Map<string, string>
516
526
  ): Promise<ExchangeInfo> {
517
527
  let nestedPerpetualIDs = await PerpetualDataHandler.getNestedPerpetualIds(_proxyContract);
518
528
  let factory = await _proxyContract.getOracleFactory();
@@ -59,7 +59,7 @@ export default class PerpetualDataHandler {
59
59
  //this is initialized in the createProxyInstance function
60
60
  protected symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>;
61
61
  protected poolStaticInfos: Array<PoolStaticInfo>;
62
- protected symbolList: Array<{ [key: string]: string }>;
62
+ protected symbolList: Map<string, string>;
63
63
 
64
64
  //map margin token of the form MATIC or ETH or USDC into
65
65
  //the address of the margin token
@@ -94,7 +94,7 @@ export default class PerpetualDataHandler {
94
94
  this.proxyABI = require(config.proxyABILocation);
95
95
  this.lobFactoryABI = require(config.limitOrderBookFactoryABILocation);
96
96
  this.lobABI = require(config.limitOrderBookABILocation);
97
- this.symbolList = require(config.symbolListLocation);
97
+ this.symbolList = new Map<string, string>(Object.entries(require(config.symbolListLocation)));
98
98
  }
99
99
 
100
100
  protected async initContractsAndData(signerOrProvider: ethers.Signer | ethers.providers.Provider) {
@@ -155,19 +155,21 @@ export default class PerpetualDataHandler {
155
155
  // try to find a limit order book
156
156
  let lobAddr = await this.lobFactoryContract.getOrderBookAddress(perpetualIDs[k]);
157
157
  currentLimitOrderBookAddr.push(lobAddr);
158
- // we find out the pool currency by looking at all perpetuals
159
- // unless for quanto perpetuals, we know the pool currency
160
- // from the perpetual. This fails if we have a pool with only
161
- // quanto perpetuals
162
- if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_BASE) {
163
- poolCCY = base;
164
- ccy.push(CollaterlCCY.BASE);
165
- } else if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_QUOTE) {
166
- poolCCY = quote;
167
- ccy.push(CollaterlCCY.QUOTE);
168
- } else {
169
- poolCCY = base3;
170
- ccy.push(CollaterlCCY.QUANTO);
158
+ if (poolCCY == undefined) {
159
+ // we find out the pool currency by looking at all perpetuals
160
+ // unless for quanto perpetuals, we know the pool currency
161
+ // from the perpetual. This fails if we have a pool with only
162
+ // quanto perpetuals
163
+ if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_BASE) {
164
+ poolCCY = base;
165
+ ccy.push(CollaterlCCY.BASE);
166
+ } else if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_QUOTE) {
167
+ poolCCY = quote;
168
+ ccy.push(CollaterlCCY.QUOTE);
169
+ } else {
170
+ poolCCY = base3;
171
+ ccy.push(CollaterlCCY.QUANTO);
172
+ }
171
173
  }
172
174
  }
173
175
  if (perpetualIDs.length == 0) {
@@ -52,6 +52,9 @@ export default class PerpetualEventHandler {
52
52
  private ordersInPerpetual: Map<number, OrderStruct>;
53
53
  private positionInPerpetual: Map<number, MarginAccount>;
54
54
 
55
+ // perpetual id to pool index in exchange info
56
+ private poolIndexForPerpetual: Map<number, number>;
57
+
55
58
  // keep current state of the system in exchangeInfo
56
59
  // data is updated when calling "onEvent"-functions
57
60
  private exchangeInfo: ExchangeInfo | undefined;
@@ -61,6 +64,7 @@ export default class PerpetualEventHandler {
61
64
  this.traderAddr = traderAddr;
62
65
  this.ordersInPerpetual = new Map<number, OrderStruct>();
63
66
  this.positionInPerpetual = new Map<number, MarginAccount>();
67
+ this.poolIndexForPerpetual = new Map<number, number>();
64
68
  }
65
69
 
66
70
  /**
@@ -82,6 +86,7 @@ export default class PerpetualEventHandler {
82
86
  this.ordersInPerpetual.set(perpId, orders);
83
87
  let position = await this.mktData.positionRisk(this.traderAddr, perpSymbol);
84
88
  this.positionInPerpetual.set(perpId, position);
89
+ this.poolIndexForPerpetual.set(perpId, k);
85
90
  }
86
91
  }
87
92
  }
@@ -121,7 +126,7 @@ export default class PerpetualEventHandler {
121
126
  perpId = this.mktData.getPerpIdFromSymbol(perpetualIdOrSymbol);
122
127
  }
123
128
  //uint24 perpetualId = uint24(_iPoolId) * 100_000 + iPerpetualIndex;
124
- let poolIdx = Math.floor(perpId / 100_000);
129
+ let poolIdx = this.poolIndexForPerpetual.get(perpId)!; //Math.floor(perpId / 100_000);
125
130
  let perpetuals = this.exchangeInfo?.pools[poolIdx].perpetuals;
126
131
  if (perpetuals == undefined) {
127
132
  emitWarning(`exchangeInfo not found, initialize perpetualEventHandler`);
@@ -192,8 +197,14 @@ export default class PerpetualEventHandler {
192
197
  * @param fSpotIndexPrice spot index price in ABDK format
193
198
  * @returns void
194
199
  */
195
- public onUpdateMarkPrice(perpetualId: number, fMarkPricePremium: BigNumber, fSpotIndexPrice: BigNumber): void {
196
- let [newMarkPrice, newIndexPrice] = PerpetualEventHandler.ConvertUpdateMarkPrice(
200
+ public onUpdateMarkPrice(
201
+ perpetualId: number,
202
+ fMidPricePremium: BigNumber,
203
+ fMarkPricePremium: BigNumber,
204
+ fSpotIndexPrice: BigNumber
205
+ ): void {
206
+ let [newMidPrice, newMarkPrice, newIndexPrice] = PerpetualEventHandler.ConvertUpdateMarkPrice(
207
+ fMidPricePremium,
197
208
  fMarkPricePremium,
198
209
  fSpotIndexPrice
199
210
  );
@@ -201,6 +212,7 @@ export default class PerpetualEventHandler {
201
212
  if (perpetual == undefined) {
202
213
  return;
203
214
  }
215
+ perpetual.midPrice = newMidPrice;
204
216
  perpetual.markPrice = newMarkPrice;
205
217
  perpetual.indexPrice = newIndexPrice;
206
218
  }
@@ -432,10 +444,16 @@ export default class PerpetualEventHandler {
432
444
  * @param fSpotIndexPrice spot index price in ABDK format
433
445
  * @returns mark price and spot index in float
434
446
  */
435
- private static ConvertUpdateMarkPrice(fMarkPricePremium: BigNumber, fSpotIndexPrice: BigNumber): [number, number] {
447
+ private static ConvertUpdateMarkPrice(
448
+ fMidPricePremium: BigNumber,
449
+ fMarkPricePremium: BigNumber,
450
+ fSpotIndexPrice: BigNumber
451
+ ): [number, number, number] {
436
452
  let fMarkPrice = mul64x64(fSpotIndexPrice, ONE_64x64.add(fMarkPricePremium));
453
+ let fMidPrice = mul64x64(fSpotIndexPrice, ONE_64x64.add(fMidPricePremium));
454
+ let midPrice = ABK64x64ToFloat(fMidPrice);
437
455
  let markPrice = ABK64x64ToFloat(fMarkPrice);
438
456
  let indexPrice = ABK64x64ToFloat(fSpotIndexPrice);
439
- return [markPrice, indexPrice];
457
+ return [midPrice, markPrice, indexPrice];
440
458
  }
441
459
  }
package/src/utils.ts CHANGED
@@ -77,17 +77,33 @@ export function fromBytes4HexString(s: string): string {
77
77
 
78
78
  /**
79
79
  *
80
- * @param {string} s string representing a hex-number ("0x...")
81
- * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
82
- * @returns {string} user friendly currency symbol, e.g. "MATIC"
80
+ * @param {string} s String representing a hex-number ("0x...")
81
+ * @param {Object} mapping List of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
82
+ * @returns {string} User friendly currency symbol, e.g. "MATIC"
83
+ */
84
+ export function contractSymbolToSymbol(s: string, mapping: Map<string, string>): string {
85
+ let shortCCY = fromBytes4HexString(s);
86
+ // assume CCY is already short if not in the mapping file
87
+ let longCCY = mapping.get(shortCCY) ?? shortCCY;
88
+ return longCCY;
89
+ }
90
+
91
+ /**
92
+ *
93
+ * @param {string} s User friendly currency symbol, e.g. "MATIC"
94
+ * @param {Object} mapping List of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
95
+ * @returns {Buffer} Buffer that can be used with smart contract to identify tokens
83
96
  */
84
- export function contractSymbolToSymbol(s: string, mapping: Array<{ [key: string]: string }>): string | undefined {
85
- s = fromBytes4HexString(s);
86
- for (let pair of mapping) {
87
- if (pair.cleanSymbol == s) {
88
- return pair.symbol;
97
+ export function symbolToContractSymbol(s: string, mapping: Map<string, string>): Buffer {
98
+ let shortCCY: string | undefined = undefined;
99
+ for (let [k, v] of mapping) {
100
+ if (v == s) {
101
+ shortCCY = k;
89
102
  }
90
103
  }
104
+ // if not in the mapping file, assume ccy is already valid
105
+ shortCCY = shortCCY ?? s;
106
+ return toBytes4(shortCCY);
91
107
  }
92
108
 
93
109
  /**
@@ -96,17 +112,13 @@ export function contractSymbolToSymbol(s: string, mapping: Array<{ [key: string]
96
112
  * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
97
113
  * @returns {string} long format e.g. MATIC. if not found the element is ""
98
114
  */
99
- export function symbol4BToLongSymbol(s: string, mapping: Array<{ [key: string]: string }>): string {
115
+ export function symbol4BToLongSymbol(s: string, mapping: Map<string, string>): string {
100
116
  let ccy = s.split("-");
101
117
  let longCCY = "";
102
118
  for (let k = 0; k < ccy.length; k++) {
103
- let sym = ccy[k];
104
- for (let pair of mapping) {
105
- if (pair.cleanSymbol == sym) {
106
- longCCY = longCCY + "-" + pair.symbol;
107
- break;
108
- }
109
- }
119
+ let sym = mapping.get(ccy[k]) ?? to4Chars(ccy[k]);
120
+ sym = sym.replace(/\0/g, "");
121
+ longCCY = longCCY + "-" + sym;
110
122
  }
111
123
  return longCCY.substring(1);
112
124
  }