@d8x/perpetuals-sdk 0.0.21 → 0.0.22

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.
@@ -0,0 +1,181 @@
1
+ import { BigNumber } from "ethers";
2
+ import { PerpetualState, ExchangeInfo, SmartContractOrder, MarginAccount, OrderStruct, TradeEvent } from "./nodeSDKTypes";
3
+ import MarketData from "./marketData";
4
+ /**
5
+ * This class handles events and stores relevant variables
6
+ * as member variables. The events change the state of the member variables:
7
+ * mktData : MarketData relevant market data with current state (e.g. index price)
8
+ * ordersInPerpetual: Map<number, OrderStruct> all open orders for the given trader
9
+ * positionInPerpetual: Map<number, MarginAccount> all open positions for the given trader
10
+ *
11
+ * TODO:
12
+ * - update functions for midprice & index & collateral prices without event
13
+ * - testing
14
+ *
15
+ * Get data:
16
+ * - getPerpetualData(perp id (string) or symbol) : PerpetualState. This is a reference!
17
+ * - getExchangeInfo() : ExchangeInfo. This is a reference!
18
+ * - getCurrentPositionRisk(perp id (string) or symbol) : MarginAccount. This is a reference!
19
+ * - getOrdersInPerpetualMap : Map<number, OrderStruct>. This is a reference!
20
+ * - getpositionInPerpetualMap : Map<number, MarginAccount>. This is a reference!
21
+ *
22
+ * Construct with a trader address and a marketData object
23
+ * Initialize to gather all the relevant data.
24
+ * Send event variables to event handler "on<EventName>" - this updates members
25
+ * - [x] onUpdateMarkPrice : emitted on proxy; updates markprice and index price data
26
+ * - [x] onUpdateUpdateFundingRate : emitted on proxy; sets funding rate
27
+ * - [x] onExecutionFailed : emitted on order book; removes an open order
28
+ * - [x] onPerpetualLimitOrderCancelled : emitted on order book; removes an open order
29
+ * - [x] onPerpetualLimitOrderCreated : emitted on order book; adds an open order to the data
30
+ * - [x] async onUpdateMarginAccount : emitted on proxy; updates position data and open interest
31
+ * - [x] onTrade : emitted on proxy; returns TradeEvent to be displayed
32
+ */
33
+ export default class PerpetualEventHandler {
34
+ private mktData;
35
+ private traderAddr;
36
+ private ordersInPerpetual;
37
+ private positionInPerpetual;
38
+ private exchangeInfo;
39
+ constructor(mktData: MarketData, traderAddr: string);
40
+ /**
41
+ * Call this async function to initialize the
42
+ * market data
43
+ */
44
+ initialize(): Promise<void>;
45
+ /**
46
+ * Get the current exchange info
47
+ * @returns exchange info
48
+ */
49
+ getExchangeInfo(): ExchangeInfo | undefined;
50
+ /**
51
+ * getOrdersInPerpetualMap
52
+ * @returns this.ordersInPerpetual
53
+ */
54
+ getOrdersInPerpetualMap(): Map<number, OrderStruct>;
55
+ /**
56
+ * getpositionInPerpetualMap
57
+ * @returns this.positionInPerpetual
58
+ */
59
+ getpositionInPerpetualMap(): Map<number, MarginAccount>;
60
+ /**
61
+ * Get the data for a perpetual with a given index
62
+ * @param perpetualIdOrSymbol perpetual idx as string or symbol for which we want the data
63
+ * @returns perpetual data for this idx
64
+ */
65
+ getPerpetualData(perpetualIdOrSymbol: string): PerpetualState | undefined;
66
+ /**
67
+ * Get the trader's current position risk (margin account data)
68
+ * @param perpetualIdOrSymbol perpetual id as string ('100003') or symbol ('BTC-USD-MATIC')
69
+ * @returns undefined if no position or margin account (='position risk')
70
+ */
71
+ getCurrentPositionRisk(perpetualIdOrSymbol: string): MarginAccount | undefined;
72
+ /**
73
+ * Update the following prices:
74
+ * - index price
75
+ * - collateral price
76
+ * - mid-price
77
+ * @param perpetualIdOrSymbol perpetual id as string ('100003') or symbol ('BTC-USD-MATIC')
78
+ */
79
+ updatePrices(perpetualIdOrSymbol: string): Promise<void>;
80
+ /**
81
+ * Handle the event UpdateMarkPrice and update relevant
82
+ * data
83
+ * @param perpetualId perpetual Id
84
+ * @param fMarkPricePremium premium rate in ABDK format
85
+ * @param fSpotIndexPrice spot index price in ABDK format
86
+ * @returns void
87
+ */
88
+ onUpdateMarkPrice(perpetualId: number, fMarkPricePremium: BigNumber, fSpotIndexPrice: BigNumber): void;
89
+ /**
90
+ * Handle the event UpdateFundingRate and update relevant
91
+ * data
92
+ * UpdateFundingRate(uint24 indexed perpetualId, int128 fFundingRate)
93
+ * @param fFundingRate funding rate in ABDK format
94
+ */
95
+ onUpdateUpdateFundingRate(perpetualId: number, fFundingRate: BigNumber): void;
96
+ /**
97
+ * event ExecutionFailed(
98
+ uint24 indexed perpetualId,
99
+ address indexed trader,
100
+ bytes32 digest,
101
+ string reason
102
+ );
103
+ * @param perpetualId id of the perpetual
104
+ * @param trader address of the trader
105
+ * @param digest digest of the order/cancel order
106
+ * @param reason reason why the execution failed
107
+ */
108
+ onExecutionFailed(perpetualId: number, trader: string, digest: string, reason: string): void;
109
+ /**
110
+ * Event emitted by perpetual proxy
111
+ * event PerpetualLimitOrderCancelled(bytes32 indexed orderHash);
112
+ * @param orderId string order id/digest
113
+ */
114
+ onPerpetualLimitOrderCancelled(orderId: string): void;
115
+ /**
116
+ * event PerpetualLimitOrderCreated(
117
+ * uint24 indexed perpetualId,
118
+ * address indexed trader,
119
+ * address referrerAddr,
120
+ * address brokerAddr,
121
+ * Order order,
122
+ * bytes32 digest
123
+ *)
124
+ * @param perpetualId id of the perpetual
125
+ * @param trader address of the trader
126
+ * @param referrerAddr address of the referrer
127
+ * @param brokerAddr address of the broker
128
+ * @param Order order struct
129
+ * @param digest order id
130
+ */
131
+ onPerpetualLimitOrderCreated(perpetualId: number, trader: string, referrerAddr: string, brokerAddr: string, Order: SmartContractOrder, digest: string): void;
132
+ /**
133
+ * This function is async -> queries the margin account
134
+ * @param perpetualId id of the perpetual
135
+ * @param trader trader address
136
+ * @param positionId position id
137
+ * @param fPositionBC position size in base currency
138
+ * @param fCashCC margin collateral in margin account
139
+ * @param fLockedInValueQC pos*average opening price
140
+ * @param fFundingPaymentCC funding payment made
141
+ * @param fOpenInterestBC open interest
142
+ */
143
+ onUpdateMarginAccount(perpetualId: number, trader: string, positionId: string, fPositionBC: BigNumber, fCashCC: BigNumber, fLockedInValueQC: BigNumber, fFundingPaymentCC: BigNumber, fOpenInterestBC: BigNumber): Promise<void>;
144
+ /**
145
+ *
146
+ * @param perpetualId perpetual id
147
+ * @param trader trader address
148
+ * @param positionId position id
149
+ * @param order order struct
150
+ * @param orderDigest order id
151
+ * @param newPositionSizeBC new pos size in base currency ABDK
152
+ * @param price price in ABDK format
153
+ * @returns trade event data in regular number format
154
+ */
155
+ onTrade(perpetualId: number, trader: string, positionId: string, order: SmartContractOrder, orderDigest: string, newPositionSizeBC: BigNumber, price: BigNumber): TradeEvent;
156
+ /**
157
+ * static function to find the number of the OrderStruct with given orderId
158
+ * @param orderId id/digest of order
159
+ * @param orderMap mapping for perpetualId->OrderStruct
160
+ * @returns id of perpetual that contains order with id = orderId or undefined
161
+ */
162
+ private static findOrderForId;
163
+ /**
164
+ * Delete the order with given id from the class member data
165
+ * @param orderStructs array of order struct as stored for the trader and a given perpetual
166
+ * @param orderId digest/order id
167
+ * @returns void
168
+ */
169
+ private static deleteOrder;
170
+ /**
171
+ * UpdateMarkPrice(
172
+ * uint24 indexed perpetualId,
173
+ * int128 fMarkPricePremium,
174
+ * int128 fSpotIndexPrice
175
+ * )
176
+ * @param fMarkPricePremium premium rate in ABDK format
177
+ * @param fSpotIndexPrice spot index price in ABDK format
178
+ * @returns mark price and spot index in float
179
+ */
180
+ private static ConvertUpdateMarkPrice;
181
+ }
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const d8XMath_1 = require("./d8XMath");
13
+ const nodeSDKTypes_1 = require("./nodeSDKTypes");
14
+ const process_1 = require("process");
15
+ /**
16
+ * This class handles events and stores relevant variables
17
+ * as member variables. The events change the state of the member variables:
18
+ * mktData : MarketData relevant market data with current state (e.g. index price)
19
+ * ordersInPerpetual: Map<number, OrderStruct> all open orders for the given trader
20
+ * positionInPerpetual: Map<number, MarginAccount> all open positions for the given trader
21
+ *
22
+ * TODO:
23
+ * - update functions for midprice & index & collateral prices without event
24
+ * - testing
25
+ *
26
+ * Get data:
27
+ * - getPerpetualData(perp id (string) or symbol) : PerpetualState. This is a reference!
28
+ * - getExchangeInfo() : ExchangeInfo. This is a reference!
29
+ * - getCurrentPositionRisk(perp id (string) or symbol) : MarginAccount. This is a reference!
30
+ * - getOrdersInPerpetualMap : Map<number, OrderStruct>. This is a reference!
31
+ * - getpositionInPerpetualMap : Map<number, MarginAccount>. This is a reference!
32
+ *
33
+ * Construct with a trader address and a marketData object
34
+ * Initialize to gather all the relevant data.
35
+ * Send event variables to event handler "on<EventName>" - this updates members
36
+ * - [x] onUpdateMarkPrice : emitted on proxy; updates markprice and index price data
37
+ * - [x] onUpdateUpdateFundingRate : emitted on proxy; sets funding rate
38
+ * - [x] onExecutionFailed : emitted on order book; removes an open order
39
+ * - [x] onPerpetualLimitOrderCancelled : emitted on order book; removes an open order
40
+ * - [x] onPerpetualLimitOrderCreated : emitted on order book; adds an open order to the data
41
+ * - [x] async onUpdateMarginAccount : emitted on proxy; updates position data and open interest
42
+ * - [x] onTrade : emitted on proxy; returns TradeEvent to be displayed
43
+ */
44
+ class PerpetualEventHandler {
45
+ constructor(mktData, traderAddr) {
46
+ this.mktData = mktData;
47
+ this.traderAddr = traderAddr;
48
+ this.ordersInPerpetual = new Map();
49
+ this.positionInPerpetual = new Map();
50
+ }
51
+ /**
52
+ * Call this async function to initialize the
53
+ * market data
54
+ */
55
+ initialize() {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ this.exchangeInfo = yield this.mktData.exchangeInfo();
58
+ // loop through all pools and perpetuals and get
59
+ // open positions and open orders
60
+ for (let k = 0; k < this.exchangeInfo.pools.length; k++) {
61
+ let poolState = this.exchangeInfo.pools[k];
62
+ let poolSymbol = poolState.poolSymbol;
63
+ for (let j = 0; j < poolState.perpetuals.length; j++) {
64
+ let perpState = poolState.perpetuals[j];
65
+ let perpSymbol = perpState.baseCurrency + "-" + perpState.quoteCurrency + "-" + poolSymbol;
66
+ let orders = yield this.mktData.openOrders(this.traderAddr, perpSymbol);
67
+ let perpId = perpState.id;
68
+ this.ordersInPerpetual.set(perpId, orders);
69
+ let position = yield this.mktData.positionRisk(this.traderAddr, perpSymbol);
70
+ this.positionInPerpetual.set(perpId, position);
71
+ }
72
+ }
73
+ });
74
+ }
75
+ /**
76
+ * Get the current exchange info
77
+ * @returns exchange info
78
+ */
79
+ getExchangeInfo() {
80
+ return this.exchangeInfo;
81
+ }
82
+ /**
83
+ * getOrdersInPerpetualMap
84
+ * @returns this.ordersInPerpetual
85
+ */
86
+ getOrdersInPerpetualMap() {
87
+ return this.ordersInPerpetual;
88
+ }
89
+ /**
90
+ * getpositionInPerpetualMap
91
+ * @returns this.positionInPerpetual
92
+ */
93
+ getpositionInPerpetualMap() {
94
+ return this.positionInPerpetual;
95
+ }
96
+ /**
97
+ * Get the data for a perpetual with a given index
98
+ * @param perpetualIdOrSymbol perpetual idx as string or symbol for which we want the data
99
+ * @returns perpetual data for this idx
100
+ */
101
+ getPerpetualData(perpetualIdOrSymbol) {
102
+ var _a;
103
+ let perpId = Number(perpetualIdOrSymbol);
104
+ if (isNaN(perpId)) {
105
+ perpId = this.mktData.getPerpIdFromSymbol(perpetualIdOrSymbol);
106
+ }
107
+ //uint24 perpetualId = uint24(_iPoolId) * 100_000 + iPerpetualIndex;
108
+ let poolIdx = Math.floor(perpId / 100000);
109
+ let perpetuals = (_a = this.exchangeInfo) === null || _a === void 0 ? void 0 : _a.pools[poolIdx].perpetuals;
110
+ if (perpetuals == undefined) {
111
+ (0, process_1.emitWarning)(`exchangeInfo not found, initialize perpetualEventHandler`);
112
+ return undefined;
113
+ }
114
+ // find perpetual
115
+ let k;
116
+ for (k = 0; k < (perpetuals === null || perpetuals === void 0 ? void 0 : perpetuals.length) && perpetuals[k].id != perpId; k++)
117
+ ;
118
+ if (perpetuals[k].id != perpId) {
119
+ (0, process_1.emitWarning)(`getPerpetualData: perpetual id ${perpId} not found`);
120
+ return undefined;
121
+ }
122
+ return perpetuals[k];
123
+ }
124
+ /**
125
+ * Get the trader's current position risk (margin account data)
126
+ * @param perpetualIdOrSymbol perpetual id as string ('100003') or symbol ('BTC-USD-MATIC')
127
+ * @returns undefined if no position or margin account (='position risk')
128
+ */
129
+ getCurrentPositionRisk(perpetualIdOrSymbol) {
130
+ let perpId = Number(perpetualIdOrSymbol);
131
+ if (isNaN(perpId)) {
132
+ perpId = this.mktData.getPerpIdFromSymbol(perpetualIdOrSymbol);
133
+ }
134
+ return this.positionInPerpetual.get(perpId);
135
+ }
136
+ /**
137
+ * Update the following prices:
138
+ * - index price
139
+ * - collateral price
140
+ * - mid-price
141
+ * @param perpetualIdOrSymbol perpetual id as string ('100003') or symbol ('BTC-USD-MATIC')
142
+ */
143
+ updatePrices(perpetualIdOrSymbol) {
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ let perpId = Number(perpetualIdOrSymbol);
146
+ let symbol = perpetualIdOrSymbol;
147
+ if (!isNaN(perpId)) {
148
+ let sym = this.mktData.getSymbolFromPerpId(perpId);
149
+ if (sym == undefined) {
150
+ throw new Error(`Symbol not found for perpetual ${perpId}`);
151
+ }
152
+ symbol = sym;
153
+ }
154
+ let perpState = yield this.mktData.getPerpetualState(symbol);
155
+ let perp = this.getPerpetualData(symbol);
156
+ if (perp == undefined) {
157
+ throw new Error(`Perpetual not found: ${symbol}`);
158
+ }
159
+ perp.state = perpState.state;
160
+ perp.indexPrice = perpState.indexPrice;
161
+ perp.collToQuoteIndexPrice = perpState.collToQuoteIndexPrice;
162
+ perp.markPrice = perpState.markPrice;
163
+ perp.midPrice = perpState.midPrice;
164
+ perp.currentFundingRateBps = perpState.currentFundingRateBps;
165
+ perp.openInterestBC = perpState.openInterestBC;
166
+ perp.maxPositionBC = perpState.maxPositionBC;
167
+ perp.indexPrice = perpState.indexPrice;
168
+ perp.collToQuoteIndexPrice = perpState.collToQuoteIndexPrice;
169
+ });
170
+ }
171
+ /**
172
+ * Handle the event UpdateMarkPrice and update relevant
173
+ * data
174
+ * @param perpetualId perpetual Id
175
+ * @param fMarkPricePremium premium rate in ABDK format
176
+ * @param fSpotIndexPrice spot index price in ABDK format
177
+ * @returns void
178
+ */
179
+ onUpdateMarkPrice(perpetualId, fMarkPricePremium, fSpotIndexPrice) {
180
+ let [newMarkPrice, newIndexPrice] = PerpetualEventHandler.ConvertUpdateMarkPrice(fMarkPricePremium, fSpotIndexPrice);
181
+ let perpetual = this.getPerpetualData(perpetualId.toString());
182
+ if (perpetual == undefined) {
183
+ return;
184
+ }
185
+ perpetual.markPrice = newMarkPrice;
186
+ perpetual.indexPrice = newIndexPrice;
187
+ }
188
+ /**
189
+ * Handle the event UpdateFundingRate and update relevant
190
+ * data
191
+ * UpdateFundingRate(uint24 indexed perpetualId, int128 fFundingRate)
192
+ * @param fFundingRate funding rate in ABDK format
193
+ */
194
+ onUpdateUpdateFundingRate(perpetualId, fFundingRate) {
195
+ let newRate = (0, d8XMath_1.ABK64x64ToFloat)(fFundingRate);
196
+ let perpetual = this.getPerpetualData(perpetualId.toString());
197
+ if (perpetual == undefined) {
198
+ return;
199
+ }
200
+ perpetual.currentFundingRateBps = newRate * 1e4;
201
+ }
202
+ /**
203
+ * event ExecutionFailed(
204
+ uint24 indexed perpetualId,
205
+ address indexed trader,
206
+ bytes32 digest,
207
+ string reason
208
+ );
209
+ * @param perpetualId id of the perpetual
210
+ * @param trader address of the trader
211
+ * @param digest digest of the order/cancel order
212
+ * @param reason reason why the execution failed
213
+ */
214
+ onExecutionFailed(perpetualId, trader, digest, reason) {
215
+ if (trader != this.traderAddr) {
216
+ (0, process_1.emitWarning)(`onExecutionFailed: trader ${trader} not relevant`);
217
+ return;
218
+ }
219
+ // remove order from open orders
220
+ let orderStructs = this.ordersInPerpetual.get(perpetualId);
221
+ if (orderStructs == undefined) {
222
+ (0, process_1.emitWarning)(`onExecutionFailed: no order found for perpetual ${perpetualId}`);
223
+ return;
224
+ }
225
+ if (reason == "cancel delay required") {
226
+ // canceling failed. We don't remove the order
227
+ return;
228
+ }
229
+ PerpetualEventHandler.deleteOrder(orderStructs, digest);
230
+ }
231
+ /**
232
+ * Event emitted by perpetual proxy
233
+ * event PerpetualLimitOrderCancelled(bytes32 indexed orderHash);
234
+ * @param orderId string order id/digest
235
+ */
236
+ onPerpetualLimitOrderCancelled(orderId) {
237
+ // remove order from open orders
238
+ let perpId = PerpetualEventHandler.findOrderForId(orderId, this.ordersInPerpetual);
239
+ if (perpId == undefined) {
240
+ (0, process_1.emitWarning)(`onPerpetualLimitOrderCancelled: no order found with id ${orderId}`);
241
+ return;
242
+ }
243
+ let orderStruct = this.ordersInPerpetual.get(perpId);
244
+ PerpetualEventHandler.deleteOrder(orderStruct, orderId);
245
+ }
246
+ /**
247
+ * event PerpetualLimitOrderCreated(
248
+ * uint24 indexed perpetualId,
249
+ * address indexed trader,
250
+ * address referrerAddr,
251
+ * address brokerAddr,
252
+ * Order order,
253
+ * bytes32 digest
254
+ *)
255
+ * @param perpetualId id of the perpetual
256
+ * @param trader address of the trader
257
+ * @param referrerAddr address of the referrer
258
+ * @param brokerAddr address of the broker
259
+ * @param Order order struct
260
+ * @param digest order id
261
+ */
262
+ onPerpetualLimitOrderCreated(perpetualId, trader, referrerAddr, brokerAddr, Order, digest) {
263
+ if (trader != this.traderAddr) {
264
+ (0, process_1.emitWarning)(`onPerpetualLimitOrderCreated: trader ${trader} not relevant`);
265
+ return;
266
+ }
267
+ let order = this.mktData.smartContractOrderToOrder(Order);
268
+ let orderStruct = this.ordersInPerpetual.get(perpetualId);
269
+ if (orderStruct == undefined) {
270
+ // no order for this perpetual so far
271
+ this.ordersInPerpetual.set(perpetualId, { orders: [order], orderIds: [digest] });
272
+ }
273
+ else {
274
+ orderStruct.orderIds.push(digest);
275
+ orderStruct.orders.push(order);
276
+ }
277
+ }
278
+ /**
279
+ * This function is async -> queries the margin account
280
+ * @param perpetualId id of the perpetual
281
+ * @param trader trader address
282
+ * @param positionId position id
283
+ * @param fPositionBC position size in base currency
284
+ * @param fCashCC margin collateral in margin account
285
+ * @param fLockedInValueQC pos*average opening price
286
+ * @param fFundingPaymentCC funding payment made
287
+ * @param fOpenInterestBC open interest
288
+ */
289
+ onUpdateMarginAccount(perpetualId, trader, positionId, fPositionBC, fCashCC, fLockedInValueQC, fFundingPaymentCC, fOpenInterestBC) {
290
+ return __awaiter(this, void 0, void 0, function* () {
291
+ let perpetual = this.getPerpetualData(perpetualId.toString());
292
+ if (perpetual == undefined) {
293
+ (0, process_1.emitWarning)(`onUpdateMarginAccount: perpetual ${perpetualId} not found`);
294
+ return;
295
+ }
296
+ perpetual.openInterestBC = (0, d8XMath_1.ABK64x64ToFloat)(fOpenInterestBC);
297
+ if (trader != this.traderAddr) {
298
+ return;
299
+ }
300
+ let perpetualIdStr = perpetualId.toString();
301
+ let margin = yield this.mktData.positionRisk(this.traderAddr, perpetualIdStr);
302
+ this.positionInPerpetual.set(perpetualId, margin);
303
+ });
304
+ }
305
+ /**
306
+ *
307
+ * @param perpetualId perpetual id
308
+ * @param trader trader address
309
+ * @param positionId position id
310
+ * @param order order struct
311
+ * @param orderDigest order id
312
+ * @param newPositionSizeBC new pos size in base currency ABDK
313
+ * @param price price in ABDK format
314
+ * @returns trade event data in regular number format
315
+ */
316
+ onTrade(perpetualId, trader, positionId, order, orderDigest, newPositionSizeBC, price) {
317
+ // remove order digest from open orders
318
+ let orderStructs = this.ordersInPerpetual.get(perpetualId);
319
+ if (orderStructs == undefined) {
320
+ (0, process_1.emitWarning)(`onTrade: executed order not found ${orderDigest}`);
321
+ }
322
+ else {
323
+ PerpetualEventHandler.deleteOrder(orderStructs, orderDigest);
324
+ }
325
+ // return transformed trade info
326
+ return {
327
+ perpetualId: perpetualId,
328
+ positionId: positionId,
329
+ orderId: orderDigest,
330
+ newPositionSizeBC: (0, d8XMath_1.ABK64x64ToFloat)(newPositionSizeBC),
331
+ executionPrice: (0, d8XMath_1.ABK64x64ToFloat)(newPositionSizeBC),
332
+ };
333
+ }
334
+ /**
335
+ * static function to find the number of the OrderStruct with given orderId
336
+ * @param orderId id/digest of order
337
+ * @param orderMap mapping for perpetualId->OrderStruct
338
+ * @returns id of perpetual that contains order with id = orderId or undefined
339
+ */
340
+ static findOrderForId(orderId, orderMap) {
341
+ /*orderMapMap<number, {
342
+ orders: Order[];
343
+ orderIds: string[];*/
344
+ for (const perpId of orderMap.keys()) {
345
+ let orderStructs = orderMap.get(perpId);
346
+ if (orderStructs === null || orderStructs === void 0 ? void 0 : orderStructs.orderIds.includes(orderId)) {
347
+ return perpId;
348
+ }
349
+ }
350
+ return undefined;
351
+ }
352
+ /**
353
+ * Delete the order with given id from the class member data
354
+ * @param orderStructs array of order struct as stored for the trader and a given perpetual
355
+ * @param orderId digest/order id
356
+ * @returns void
357
+ */
358
+ static deleteOrder(orderStructs, orderId) {
359
+ // find order
360
+ let k;
361
+ for (k = 0; k < orderStructs.orderIds.length && orderStructs.orderIds[k] != orderId; k++)
362
+ ;
363
+ if (orderStructs.orderIds[k] != orderId) {
364
+ (0, process_1.emitWarning)(`deleteOrder: no order found with digest ${orderId}`);
365
+ return;
366
+ }
367
+ // delete element k on reference of orders
368
+ orderStructs.orders[k] = orderStructs.orders[orderStructs.orders.length - 1];
369
+ orderStructs.orders.pop();
370
+ orderStructs.orderIds[k] = orderStructs.orderIds[orderStructs.orderIds.length - 1];
371
+ orderStructs.orderIds.pop();
372
+ }
373
+ /**
374
+ * UpdateMarkPrice(
375
+ * uint24 indexed perpetualId,
376
+ * int128 fMarkPricePremium,
377
+ * int128 fSpotIndexPrice
378
+ * )
379
+ * @param fMarkPricePremium premium rate in ABDK format
380
+ * @param fSpotIndexPrice spot index price in ABDK format
381
+ * @returns mark price and spot index in float
382
+ */
383
+ static ConvertUpdateMarkPrice(fMarkPricePremium, fSpotIndexPrice) {
384
+ let fMarkPrice = (0, d8XMath_1.mul64x64)(fSpotIndexPrice, nodeSDKTypes_1.ONE_64x64.add(fMarkPricePremium));
385
+ let markPrice = (0, d8XMath_1.ABK64x64ToFloat)(fMarkPrice);
386
+ let indexPrice = (0, d8XMath_1.ABK64x64ToFloat)(fSpotIndexPrice);
387
+ return [markPrice, indexPrice];
388
+ }
389
+ }
390
+ exports.default = PerpetualEventHandler;
package/dist/utils.d.ts CHANGED
@@ -33,5 +33,23 @@ export declare function fromBytes4(b: Buffer): string;
33
33
  * returned by the smart contract as bytes4
34
34
  */
35
35
  export declare function fromBytes4HexString(s: string): string;
36
+ /**
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"
41
+ */
42
+ export declare function contractSymbolToSymbol(s: string, mapping: Array<{
43
+ [key: string]: string;
44
+ }>): string | undefined;
45
+ /**
46
+ * Converts symbol or symbol combination into long format
47
+ * @param {string} s symbol, e.g., USDC-MATC-USDC, MATC, USDC, ...
48
+ * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
49
+ * @returns {string} long format e.g. MATIC. if not found the element is ""
50
+ */
51
+ export declare function symbol4BToLongSymbol(s: string, mapping: Array<{
52
+ [key: string]: string;
53
+ }>): string;
36
54
  export declare function combineFlags(f1: BigNumber, f2: BigNumber): BigNumber;
37
55
  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.fromBytes4HexString = exports.fromBytes4 = exports.toBytes4 = exports.to4Chars = void 0;
3
+ exports.containsFlag = exports.combineFlags = exports.symbol4BToLongSymbol = 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
@@ -76,6 +76,42 @@ function fromBytes4HexString(s) {
76
76
  return res;
77
77
  }
78
78
  exports.fromBytes4HexString = fromBytes4HexString;
79
+ /**
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"
84
+ */
85
+ function contractSymbolToSymbol(s, mapping) {
86
+ s = fromBytes4HexString(s);
87
+ for (let pair of mapping) {
88
+ if (pair.cleanSymbol == s) {
89
+ return pair.symbol;
90
+ }
91
+ }
92
+ }
93
+ exports.contractSymbolToSymbol = contractSymbolToSymbol;
94
+ /**
95
+ * Converts symbol or symbol combination into long format
96
+ * @param {string} s symbol, e.g., USDC-MATC-USDC, MATC, USDC, ...
97
+ * @param {Object} mapping list of symbol and clean symbol pairs, e.g. [{symbol: "MATIC", cleanSymbol: "MATC"}, ...]
98
+ * @returns {string} long format e.g. MATIC. if not found the element is ""
99
+ */
100
+ function symbol4BToLongSymbol(s, mapping) {
101
+ let ccy = s.split("-");
102
+ let longCCY = "";
103
+ 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
+ }
111
+ }
112
+ return longCCY.substring(1);
113
+ }
114
+ exports.symbol4BToLongSymbol = symbol4BToLongSymbol;
79
115
  function combineFlags(f1, f2) {
80
116
  return ethers_1.BigNumber.from(parseInt(f1.toString()) | parseInt(f2.toString()));
81
117
  }
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.21",
30
+ "version": "0.0.22",
31
31
  "main": "./dist/index.js",
32
32
  "types": "./dist/index.d.ts",
33
33
  "directories": {
@@ -190,13 +190,13 @@ export default class AccountTrade extends WriteAccessHandler {
190
190
  * @returns Exchange fee, in decimals (i.e. 0.1% is 0.001).
191
191
  */
192
192
  public async queryExchangeFee(poolSymbolName: string, brokerAddr?: string): Promise<number> {
193
- if (this.proxyContract == null || this.signer == null) {
193
+ if (this.proxyContract == null) {
194
194
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
195
195
  }
196
196
  if (typeof brokerAddr == "undefined") {
197
197
  brokerAddr = ZERO_ADDRESS;
198
198
  }
199
- let poolId = WriteAccessHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
199
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
200
200
  let feeTbps = await this.proxyContract.queryExchangeFee(poolId, this.traderAddr, brokerAddr);
201
201
  return feeTbps / 100_000;
202
202
  }