@deriverse/kit 1.0.0

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/index.js ADDED
@@ -0,0 +1,2361 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.Engine = exports.getPriceStep = exports.ASSOCIATED_TOKEN_PROGRAM_ID = exports.TOKEN_2022_PROGRAM_ID = exports.TOKEN_PROGRAM_ID = exports.LogType = void 0;
27
+ const kit_1 = require("@solana/kit");
28
+ const system_1 = require("@solana-program/system");
29
+ const bs58_1 = require("bs58");
30
+ const types_1 = require("./types");
31
+ const structure_models_1 = require("./structure_models");
32
+ const instruction_models_1 = require("./instruction_models");
33
+ const base64_arraybuffer_1 = require("base64-arraybuffer");
34
+ const logs_models_1 = require("./logs_models");
35
+ __exportStar(require("./types"), exports);
36
+ var logs_models_2 = require("./logs_models");
37
+ Object.defineProperty(exports, "LogType", { enumerable: true, get: function () { return logs_models_2.LogType; } });
38
+ const ADDRESS_LOOKUP_TABLE_PROGRAM_ID = (0, kit_1.address)("AddressLookupTab1e1111111111111111111111111");
39
+ const SYSTEM_PROGRAM_ID = (0, kit_1.address)("11111111111111111111111111111111");
40
+ exports.TOKEN_PROGRAM_ID = (0, kit_1.address)('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
41
+ exports.TOKEN_2022_PROGRAM_ID = (0, kit_1.address)('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
42
+ exports.ASSOCIATED_TOKEN_PROGRAM_ID = (0, kit_1.address)('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
43
+ const dec = 1000000000;
44
+ const nullOrder = 0xFFFF;
45
+ /**
46
+ * Get price step between orderbook lines depending on curent price
47
+ * @param price Current market price
48
+ * @returns Price step
49
+ */
50
+ function getPriceStep(price) {
51
+ if (price <= 0.00001) {
52
+ return 0.000000001;
53
+ }
54
+ else if (price <= 0.00002) {
55
+ return 0.000000002;
56
+ }
57
+ else if (price <= 0.00005) {
58
+ return 0.000000005;
59
+ }
60
+ else if (price <= 0.0001) {
61
+ return 0.00000001;
62
+ }
63
+ else if (price <= 0.0002) {
64
+ return 0.00000002;
65
+ }
66
+ else if (price <= 0.0005) {
67
+ return 0.00000005;
68
+ }
69
+ else if (price <= 0.001) {
70
+ return 0.0000001;
71
+ }
72
+ else if (price <= 0.002) {
73
+ return 0.0000002;
74
+ }
75
+ else if (price <= 0.005) {
76
+ return 0.0000005;
77
+ }
78
+ else if (price <= 0.01) {
79
+ return 0.000001;
80
+ }
81
+ else if (price <= 0.02) {
82
+ return 0.000002;
83
+ }
84
+ else if (price <= 0.05) {
85
+ return 0.000005;
86
+ }
87
+ else if (price <= 0.1) {
88
+ return 0.00001;
89
+ }
90
+ else if (price <= 0.2) {
91
+ return 0.00002;
92
+ }
93
+ else if (price <= 0.5) {
94
+ return 0.00005;
95
+ }
96
+ else if (price <= 1) {
97
+ return 0.0001;
98
+ }
99
+ else if (price <= 2) {
100
+ return 0.0002;
101
+ }
102
+ else if (price <= 5) {
103
+ return 0.0005;
104
+ }
105
+ else if (price <= 10) {
106
+ return 0.001;
107
+ }
108
+ else if (price <= 20) {
109
+ return 0.002;
110
+ }
111
+ else if (price <= 50) {
112
+ return 0.005;
113
+ }
114
+ else if (price <= 100) {
115
+ return 0.01;
116
+ }
117
+ else if (price <= 200) {
118
+ return 0.02;
119
+ }
120
+ else if (price <= 500) {
121
+ return 0.05;
122
+ }
123
+ else if (price <= 1000) {
124
+ return 0.1;
125
+ }
126
+ else if (price <= 2000) {
127
+ return 0.2;
128
+ }
129
+ else if (price <= 5000) {
130
+ return 0.5;
131
+ }
132
+ else if (price <= 10000) {
133
+ return 1;
134
+ }
135
+ else if (price <= 20000) {
136
+ return 2;
137
+ }
138
+ else if (price <= 50000) {
139
+ return 5;
140
+ }
141
+ else if (price <= 100000) {
142
+ return 10;
143
+ }
144
+ else if (price <= 200000) {
145
+ return 20;
146
+ }
147
+ else if (price <= 500000) {
148
+ return 50;
149
+ }
150
+ else if (price <= 1000000) {
151
+ return 100;
152
+ }
153
+ else if (price <= 2000000) {
154
+ return 200;
155
+ }
156
+ else if (price <= 5000000) {
157
+ return 500;
158
+ }
159
+ else {
160
+ return 1000;
161
+ }
162
+ }
163
+ exports.getPriceStep = getPriceStep;
164
+ function findAssociatedTokenAddress(owner, tokenProgramId, mint) {
165
+ return __awaiter(this, void 0, void 0, function* () {
166
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
167
+ programAddress: exports.ASSOCIATED_TOKEN_PROGRAM_ID,
168
+ seeds: [
169
+ (0, kit_1.getAddressEncoder)().encode(owner),
170
+ (0, kit_1.getAddressEncoder)().encode(tokenProgramId),
171
+ (0, kit_1.getAddressEncoder)().encode(mint),
172
+ ]
173
+ }))[0];
174
+ return address;
175
+ });
176
+ }
177
+ function getMultipleSpotOrders(data, firstEntry) {
178
+ let orders = [];
179
+ let entry = firstEntry;
180
+ while (entry != nullOrder) {
181
+ const offset = entry * 64 + structure_models_1.SpotTradeAccountHeaderModel.LENGTH;
182
+ let order = structure_models_1.OrderModel.fromBuffer(data, offset);
183
+ orders.push(order);
184
+ entry = order.clNext;
185
+ }
186
+ return orders;
187
+ }
188
+ function getMultiplePerpOrders(data, firstEntry) {
189
+ let orders = [];
190
+ let entry = firstEntry;
191
+ while (entry != nullOrder) {
192
+ const offset = entry * 64 + structure_models_1.PerpTradeAccountHeaderModel.LENGTH;
193
+ let order = structure_models_1.OrderModel.fromBuffer(data, offset);
194
+ orders.push(order);
195
+ entry = order.clNext;
196
+ }
197
+ return orders;
198
+ }
199
+ function getLookupTableAddress(authority, slot) {
200
+ return __awaiter(this, void 0, void 0, function* () {
201
+ let buf = Buffer.alloc(8);
202
+ buf.writeBigInt64LE(BigInt(slot), 0);
203
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
204
+ programAddress: ADDRESS_LOOKUP_TABLE_PROGRAM_ID,
205
+ seeds: [(0, kit_1.getAddressEncoder)().encode(authority), buf]
206
+ }))[0];
207
+ return address;
208
+ });
209
+ }
210
+ /**
211
+ * Main class to operate with DEXnow.io
212
+ * @property {number} originalClientId DEXnow.io main client ID
213
+ * @property {AddressLookupTableAccount} lut Root address lookup table account
214
+ * @property {AddressLookupTableAccount} clientLut Client address lookup table account
215
+ * @property {Map<number, Token>} tokens Tokens data
216
+ * @property {Map<number, Instrument>} instruments Instruments data
217
+ */
218
+ class Engine {
219
+ /**
220
+ * @param rpc @solana/kit rpc
221
+ */
222
+ constructor(rpc, args) {
223
+ this.rpc = rpc;
224
+ if (args == undefined || args.programId == null || args.programId == undefined) {
225
+ this.programId = types_1.PROGRAM_ID;
226
+ }
227
+ else {
228
+ this.programId = args.programId;
229
+ }
230
+ if (args == undefined || args.version == null || args.version == undefined) {
231
+ this.version = types_1.VERSION;
232
+ }
233
+ else {
234
+ this.version = args.version;
235
+ }
236
+ if (args == undefined || args.commitment == null || args.commitment == undefined) {
237
+ this.commitment = 'confirmed';
238
+ }
239
+ else {
240
+ this.commitment = args.commitment;
241
+ }
242
+ }
243
+ logsDecode(data) {
244
+ let assetTokenDec = null;
245
+ let crncyTokenDec = null;
246
+ let logs = [];
247
+ for (var log of data) {
248
+ if (!log.startsWith("Program data: ")) {
249
+ continue;
250
+ }
251
+ const buffer = Buffer.from((0, base64_arraybuffer_1.decode)(log.substring(14)));
252
+ switch (buffer[0]) {
253
+ case logs_models_1.LogType.deposit: {
254
+ if (buffer.length == logs_models_1.DepositReportModel.LENGTH) {
255
+ let report = logs_models_1.DepositReportModel.fromBuffer(buffer);
256
+ crncyTokenDec = this.tokenDec(report.tokenId);
257
+ report.amount /= crncyTokenDec;
258
+ logs.push(report);
259
+ }
260
+ break;
261
+ }
262
+ case logs_models_1.LogType.withdraw: {
263
+ if (buffer.length == logs_models_1.WithdrawReportModel.LENGTH) {
264
+ let report = logs_models_1.WithdrawReportModel.fromBuffer(buffer);
265
+ crncyTokenDec = this.tokenDec(report.tokenId);
266
+ report.amount /= crncyTokenDec;
267
+ logs.push(report);
268
+ }
269
+ break;
270
+ }
271
+ case logs_models_1.LogType.perpDeposit: {
272
+ if (buffer.length == logs_models_1.PerpDepositReportModel.LENGTH) {
273
+ let report = logs_models_1.PerpDepositReportModel.fromBuffer(buffer);
274
+ const instrInfo = this.instruments.get(report.instrId);
275
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
276
+ report.amount /= crncyTokenDec;
277
+ logs.push(report);
278
+ }
279
+ break;
280
+ }
281
+ case logs_models_1.LogType.perpWithdraw: {
282
+ if (buffer.length == logs_models_1.PerpWithdrawReportModel.LENGTH) {
283
+ let report = logs_models_1.PerpWithdrawReportModel.fromBuffer(buffer);
284
+ const instrInfo = this.instruments.get(report.instrId);
285
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
286
+ report.amount /= crncyTokenDec;
287
+ logs.push(report);
288
+ }
289
+ break;
290
+ }
291
+ case logs_models_1.LogType.feesDeposit: {
292
+ if (buffer.length == logs_models_1.FeesDepositReportModel.LENGTH) {
293
+ let report = logs_models_1.FeesDepositReportModel.fromBuffer(buffer);
294
+ crncyTokenDec = this.tokenDec(report.tokenId);
295
+ report.amount /= crncyTokenDec;
296
+ logs.push(report);
297
+ }
298
+ break;
299
+ }
300
+ case logs_models_1.LogType.feesWithdraw: {
301
+ if (buffer.length == logs_models_1.FeesWithdrawReportModel.LENGTH) {
302
+ let report = logs_models_1.FeesWithdrawReportModel.fromBuffer(buffer);
303
+ crncyTokenDec = this.tokenDec(report.tokenId);
304
+ report.amount /= crncyTokenDec;
305
+ logs.push(report);
306
+ }
307
+ break;
308
+ }
309
+ case logs_models_1.LogType.spotLpTrade: {
310
+ if (buffer.length == logs_models_1.SpotlpTradeReportModel.LENGTH) {
311
+ let report = logs_models_1.SpotlpTradeReportModel.fromBuffer(buffer);
312
+ const instrInfo = this.instruments.get(report.instrId);
313
+ assetTokenDec = this.tokenDec(instrInfo.header.assetTokenId);
314
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
315
+ report.qty /= 10000;
316
+ report.tokens /= assetTokenDec;
317
+ report.crncy /= crncyTokenDec;
318
+ logs.push(report);
319
+ }
320
+ break;
321
+ }
322
+ case logs_models_1.LogType.earnings: {
323
+ if (buffer.length == logs_models_1.EarningsReportModel.LENGTH) {
324
+ let report = logs_models_1.EarningsReportModel.fromBuffer(buffer);
325
+ crncyTokenDec = this.tokenDec(report.tokenId);
326
+ report.amount /= crncyTokenDec;
327
+ logs.push(report);
328
+ }
329
+ break;
330
+ }
331
+ case logs_models_1.LogType.drvsAirdrop: {
332
+ if (buffer.length == logs_models_1.DrvsAirdropReportModel.LENGTH) {
333
+ let report = logs_models_1.DrvsAirdropReportModel.fromBuffer(buffer);
334
+ crncyTokenDec = this.tokenDec(0);
335
+ report.amount /= crncyTokenDec;
336
+ logs.push(report);
337
+ }
338
+ break;
339
+ }
340
+ case logs_models_1.LogType.spotPlaceOrder: {
341
+ if (buffer.length == logs_models_1.SpotPlaceOrderReportModel.LENGTH) {
342
+ let report = logs_models_1.SpotPlaceOrderReportModel.fromBuffer(buffer);
343
+ const instrInfo = this.instruments.get(report.instrId);
344
+ assetTokenDec = this.tokenDec(instrInfo.header.assetTokenId);
345
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
346
+ report.qty /= assetTokenDec;
347
+ report.price /= dec;
348
+ logs.push(report);
349
+ }
350
+ break;
351
+ }
352
+ case logs_models_1.LogType.spotFillOrder: {
353
+ if (buffer.length == logs_models_1.SpotFillOrderReportModel.LENGTH) {
354
+ let report = logs_models_1.SpotFillOrderReportModel.fromBuffer(buffer);
355
+ report.qty /= assetTokenDec;
356
+ report.crncy /= crncyTokenDec;
357
+ report.rebates /= crncyTokenDec;
358
+ report.price /= dec;
359
+ logs.push(report);
360
+ }
361
+ break;
362
+ }
363
+ case logs_models_1.LogType.spotNewOrder: {
364
+ if (buffer.length == logs_models_1.SpotNewOrderReportModel.LENGTH) {
365
+ let report = logs_models_1.SpotNewOrderReportModel.fromBuffer(buffer);
366
+ report.qty /= assetTokenDec;
367
+ report.crncy /= crncyTokenDec;
368
+ logs.push(report);
369
+ }
370
+ break;
371
+ }
372
+ case logs_models_1.LogType.spotOrderCancel: {
373
+ if (buffer.length == logs_models_1.SpotOrderCancelReportModel.LENGTH) {
374
+ let report = logs_models_1.SpotOrderCancelReportModel.fromBuffer(buffer);
375
+ const instrInfo = this.instruments.get(report.instrId);
376
+ assetTokenDec = this.tokenDec(instrInfo.header.assetTokenId);
377
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
378
+ report.qty /= assetTokenDec;
379
+ report.crncy /= crncyTokenDec;
380
+ logs.push(report);
381
+ }
382
+ break;
383
+ }
384
+ case logs_models_1.LogType.spotOrderRevoke: {
385
+ if (buffer.length == logs_models_1.SpotOrderRevokeReportModel.LENGTH) {
386
+ let report = logs_models_1.SpotOrderRevokeReportModel.fromBuffer(buffer);
387
+ report.qty /= assetTokenDec;
388
+ report.crncy /= crncyTokenDec;
389
+ logs.push(report);
390
+ }
391
+ break;
392
+ }
393
+ case logs_models_1.LogType.spotFees: {
394
+ if (buffer.length == logs_models_1.SpotFeesReportModel.LENGTH) {
395
+ let report = logs_models_1.SpotFeesReportModel.fromBuffer(buffer);
396
+ report.fees /= crncyTokenDec;
397
+ report.refPayment /= crncyTokenDec;
398
+ logs.push(report);
399
+ }
400
+ break;
401
+ }
402
+ case logs_models_1.LogType.spotPlaceMassCancel: {
403
+ if (buffer.length == logs_models_1.SpotPlaceMassCancelReportModel.LENGTH) {
404
+ let report = logs_models_1.SpotPlaceMassCancelReportModel.fromBuffer(buffer);
405
+ const instrInfo = this.instruments.get(report.instrId);
406
+ assetTokenDec = this.tokenDec(instrInfo.header.assetTokenId);
407
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
408
+ logs.push(report);
409
+ }
410
+ break;
411
+ }
412
+ case logs_models_1.LogType.spotMassCancel: {
413
+ if (buffer.length == logs_models_1.SpotMassCancelReportModel.LENGTH) {
414
+ let report = logs_models_1.SpotMassCancelReportModel.fromBuffer(buffer);
415
+ report.qty /= assetTokenDec;
416
+ report.crncy /= crncyTokenDec;
417
+ logs.push(report);
418
+ }
419
+ break;
420
+ }
421
+ case logs_models_1.LogType.perpPlaceOrder: {
422
+ if (buffer.length == logs_models_1.PerpPlaceOrderReportModel.LENGTH) {
423
+ let report = logs_models_1.PerpPlaceOrderReportModel.fromBuffer(buffer);
424
+ const instrInfo = this.instruments.get(report.instrId);
425
+ assetTokenDec = this.tokenDec(instrInfo.header.assetTokenId);
426
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
427
+ report.perps /= assetTokenDec;
428
+ report.price /= dec;
429
+ logs.push(report);
430
+ }
431
+ break;
432
+ }
433
+ case logs_models_1.LogType.perpFillOrder: {
434
+ if (buffer.length == logs_models_1.PerpFillOrderReportModel.LENGTH) {
435
+ let report = logs_models_1.PerpFillOrderReportModel.fromBuffer(buffer);
436
+ report.perps /= assetTokenDec;
437
+ report.crncy /= crncyTokenDec;
438
+ report.rebates /= crncyTokenDec;
439
+ report.price /= dec;
440
+ logs.push(report);
441
+ }
442
+ break;
443
+ }
444
+ case logs_models_1.LogType.perpNewOrder: {
445
+ if (buffer.length == logs_models_1.PerpNewOrderReportModel.LENGTH) {
446
+ let report = logs_models_1.PerpNewOrderReportModel.fromBuffer(buffer);
447
+ report.perps /= assetTokenDec;
448
+ report.crncy /= crncyTokenDec;
449
+ logs.push(report);
450
+ }
451
+ break;
452
+ }
453
+ case logs_models_1.LogType.perpOrderCancel: {
454
+ if (buffer.length == logs_models_1.PerpOrderCancelReportModel.LENGTH) {
455
+ let report = logs_models_1.PerpOrderCancelReportModel.fromBuffer(buffer);
456
+ const instrInfo = this.instruments.get(report.instrId);
457
+ assetTokenDec = this.tokenDec(instrInfo.header.assetTokenId);
458
+ crncyTokenDec = this.tokenDec(instrInfo.header.crncyTokenId);
459
+ report.perps /= assetTokenDec;
460
+ report.crncy /= crncyTokenDec;
461
+ logs.push(report);
462
+ }
463
+ break;
464
+ }
465
+ case logs_models_1.LogType.perpOrderRevoke: {
466
+ if (buffer.length == logs_models_1.PerpOrderRevokeReportModel.LENGTH) {
467
+ let report = logs_models_1.PerpOrderRevokeReportModel.fromBuffer(buffer);
468
+ report.perps /= assetTokenDec;
469
+ report.crncy /= crncyTokenDec;
470
+ logs.push(report);
471
+ }
472
+ break;
473
+ }
474
+ case logs_models_1.LogType.perpFees: {
475
+ if (buffer.length == logs_models_1.PerpFeesReportModel.LENGTH) {
476
+ let report = logs_models_1.PerpFeesReportModel.fromBuffer(buffer);
477
+ report.fees /= crncyTokenDec;
478
+ report.refPayment /= crncyTokenDec;
479
+ logs.push(report);
480
+ }
481
+ break;
482
+ }
483
+ case logs_models_1.LogType.perpPlaceMassCancel: {
484
+ if (buffer.length == logs_models_1.PerpPlaceMassCancelReportModel.LENGTH) {
485
+ let report = logs_models_1.PerpPlaceMassCancelReportModel.fromBuffer(buffer);
486
+ logs.push(report);
487
+ }
488
+ break;
489
+ }
490
+ case logs_models_1.LogType.perpMassCancel: {
491
+ if (buffer.length == logs_models_1.PerpMassCancelReportModel.LENGTH) {
492
+ let report = logs_models_1.PerpMassCancelReportModel.fromBuffer(buffer);
493
+ report.perps /= assetTokenDec;
494
+ report.crncy /= crncyTokenDec;
495
+ logs.push(report);
496
+ }
497
+ break;
498
+ }
499
+ case logs_models_1.LogType.perpFunding: {
500
+ if (buffer.length == logs_models_1.PerpFundingReportModel.LENGTH) {
501
+ let report = logs_models_1.PerpFundingReportModel.fromBuffer(buffer);
502
+ report.funding /= crncyTokenDec;
503
+ logs.push(report);
504
+ }
505
+ break;
506
+ }
507
+ case logs_models_1.LogType.perpSocLoss: {
508
+ if (buffer.length == logs_models_1.PerpSocLossReportModel.LENGTH) {
509
+ let report = logs_models_1.PerpSocLossReportModel.fromBuffer(buffer);
510
+ report.socLoss /= crncyTokenDec;
511
+ logs.push(report);
512
+ }
513
+ break;
514
+ }
515
+ case logs_models_1.LogType.perpChangeLeverage: {
516
+ if (buffer.length == logs_models_1.PerpChangeLeverageReportModel.LENGTH) {
517
+ let report = logs_models_1.PerpChangeLeverageReportModel.fromBuffer(buffer);
518
+ logs.push(report);
519
+ }
520
+ break;
521
+ }
522
+ }
523
+ }
524
+ return logs;
525
+ }
526
+ findAccountsByTag(tag, dataSlice) {
527
+ return __awaiter(this, void 0, void 0, function* () {
528
+ let tagBuf = Buffer.alloc(8);
529
+ tagBuf.writeUInt32LE(tag, 0);
530
+ tagBuf.writeUInt32LE(this.version, 4);
531
+ let accounts = yield this.rpc.getProgramAccounts(this.programId, {
532
+ encoding: 'base64',
533
+ dataSlice: dataSlice,
534
+ filters: [
535
+ {
536
+ memcmp: {
537
+ offset: BigInt(0),
538
+ encoding: 'base58',
539
+ bytes: (0, bs58_1.encode)(tagBuf),
540
+ },
541
+ },
542
+ ],
543
+ }).send();
544
+ return accounts;
545
+ });
546
+ }
547
+ /**
548
+ * After creation you have to initialize Engine
549
+ */
550
+ initialize() {
551
+ return __awaiter(this, void 0, void 0, function* () {
552
+ try {
553
+ this.drvsAuthority = (yield (0, kit_1.getProgramDerivedAddress)({ programAddress: this.programId, seeds: ["ndxnt"] }))[0];
554
+ this.rootAccount = yield this.getAccountByTag(types_1.AccountType.ROOT);
555
+ this.communityAccount = yield this.getAccountByTag(types_1.AccountType.COMMUNITY);
556
+ const infos = yield this.rpc.getMultipleAccounts([this.rootAccount, this.communityAccount], {
557
+ commitment: this.commitment,
558
+ encoding: 'base64'
559
+ }).send();
560
+ if (infos == null) {
561
+ throw new Error("Initialization failed: getMultipleAccountsInfo");
562
+ }
563
+ this.rootStateModel = structure_models_1.RootStateModel.fromBuffer(infos.value[0].data);
564
+ this.tokens = new Map();
565
+ this.instruments = new Map();
566
+ const tokenAccounts = yield this.findAccountsByTag(types_1.AccountType.TOKEN);
567
+ tokenAccounts.forEach((t) => {
568
+ let tokenStateModel = structure_models_1.TokenStateModel.fromBuffer(t.account.data);
569
+ this.tokens.set(tokenStateModel.id, tokenStateModel);
570
+ });
571
+ const instrAccounts = yield this.findAccountsByTag(types_1.AccountType.INSTR, { offset: 8, length: 16 });
572
+ instrAccounts.forEach((response) => {
573
+ const buffer = Buffer.from((0, kit_1.getBase64Encoder)().encode(response.account.data[0]));
574
+ let instrAccountHeaderModel = new structure_models_1.InstrAccountHeaderModel();
575
+ instrAccountHeaderModel.id = buffer.readUint32LE(0);
576
+ instrAccountHeaderModel.assetTokenId = buffer.readUint32LE(4);
577
+ instrAccountHeaderModel.crncyTokenId = buffer.readUint32LE(8);
578
+ instrAccountHeaderModel.mask = buffer.readUint32LE(12);
579
+ this.instruments.set(instrAccountHeaderModel.id, {
580
+ address: response.pubkey,
581
+ header: instrAccountHeaderModel,
582
+ spotBids: [],
583
+ spotAsks: [],
584
+ perpBids: [],
585
+ perpAsks: [],
586
+ });
587
+ });
588
+ this.updateCommunityFromBuffer(infos.value[1].data);
589
+ return true;
590
+ }
591
+ catch (err) {
592
+ console.log("Initialization failed:", err);
593
+ return false;
594
+ }
595
+ });
596
+ }
597
+ addToken(tokenAccount) {
598
+ return __awaiter(this, void 0, void 0, function* () {
599
+ const info = yield this.rpc.getAccountInfo(tokenAccount, { commitment: this.commitment, encoding: 'base64' }).send();
600
+ if (info == null) {
601
+ throw new Error("Add Token Failed: getAccountInfo");
602
+ }
603
+ const tokenStateModel = structure_models_1.TokenStateModel.fromBuffer(info.value.data);
604
+ if (tokenStateModel.id > this.rootStateModel.tokensCount ||
605
+ tokenStateModel.tag != types_1.AccountType.TOKEN ||
606
+ tokenStateModel.version != this.version) {
607
+ throw new Error("Invalid Token Account");
608
+ }
609
+ this.tokens.set(tokenStateModel.id, tokenStateModel);
610
+ });
611
+ }
612
+ addInstr(instrAccount) {
613
+ return __awaiter(this, void 0, void 0, function* () {
614
+ const info = yield this.rpc.getAccountInfo(instrAccount, { commitment: this.commitment, encoding: 'base64' }).send();
615
+ if (info == null) {
616
+ throw new Error("Add Instrument Failed: getAccountInfo");
617
+ }
618
+ const instrAccountHeaderModel = structure_models_1.InstrAccountHeaderModel.fromBuffer(info.value.data);
619
+ if (instrAccountHeaderModel.id > this.rootStateModel.instrCount ||
620
+ instrAccountHeaderModel.tag != types_1.AccountType.INSTR ||
621
+ instrAccountHeaderModel.version != this.version) {
622
+ throw new Error("Invalid Instrument Account");
623
+ }
624
+ this.instruments.set(instrAccountHeaderModel.id, {
625
+ address: instrAccount,
626
+ header: instrAccountHeaderModel,
627
+ spotBids: [],
628
+ spotAsks: [],
629
+ perpBids: [],
630
+ perpAsks: [],
631
+ });
632
+ });
633
+ }
634
+ updateCommunityFromBuffer(data) {
635
+ let baseCrncyRecords = new Map();
636
+ let communityAccountHeaderModel = structure_models_1.CommunityAccountHeaderModel.fromBuffer(data);
637
+ const drvsDec = this.tokenDec(0);
638
+ communityAccountHeaderModel.prevVotingSupply /= drvsDec;
639
+ communityAccountHeaderModel.votingSupply /= drvsDec;
640
+ communityAccountHeaderModel.drvsTokens /= drvsDec;
641
+ for (var i = 0; i < communityAccountHeaderModel.count; ++i) {
642
+ let record = structure_models_1.BaseCrncyRecordModel.fromBuffer(data, structure_models_1.CommunityAccountHeaderModel.LENGTH + i * structure_models_1.BaseCrncyRecordModel.LENGTH);
643
+ record.funds /= this.tokenDec(record.crncyTokenId);
644
+ baseCrncyRecords.set(record.crncyTokenId, record);
645
+ }
646
+ this.community = {
647
+ header: communityAccountHeaderModel,
648
+ data: baseCrncyRecords
649
+ };
650
+ }
651
+ updateCommunity() {
652
+ return __awaiter(this, void 0, void 0, function* () {
653
+ const info = yield this.rpc.getAccountInfo(this.communityAccount, { commitment: this.commitment, encoding: 'base64' }).send();
654
+ if (info == null) {
655
+ throw new Error("Community Account: GetAccountInfo Failed");
656
+ }
657
+ this.updateCommunityFromBuffer(info.value.data);
658
+ });
659
+ }
660
+ updateRootFromBuffer(data) {
661
+ this.rootStateModel = structure_models_1.RootStateModel.fromBuffer(data);
662
+ }
663
+ updateRoot() {
664
+ return __awaiter(this, void 0, void 0, function* () {
665
+ const info = yield this.rpc.getAccountInfo(this.rootAccount, { commitment: this.commitment, encoding: 'base64' }).send();
666
+ if (info == null) {
667
+ throw new Error("Root Account: GetAccountInfo Failed");
668
+ }
669
+ this.updateRootFromBuffer(info.value.data);
670
+ });
671
+ }
672
+ getInstrAccountByTag(args) {
673
+ return __awaiter(this, void 0, void 0, function* () {
674
+ let buf = Buffer.alloc(16);
675
+ buf.writeInt32LE(this.version, 0);
676
+ buf.writeInt32LE(args.tag, 4);
677
+ buf.writeInt32LE(args.assetTokenId, 8);
678
+ buf.writeInt32LE(args.crncyTokenId, 12);
679
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
680
+ programAddress: this.programId,
681
+ seeds: [buf, (0, kit_1.getAddressEncoder)().encode(this.drvsAuthority)]
682
+ }))[0];
683
+ return address;
684
+ });
685
+ }
686
+ getAccountByTag(tag) {
687
+ return __awaiter(this, void 0, void 0, function* () {
688
+ let buf = Buffer.alloc(8);
689
+ buf.writeInt32LE(this.version, 0);
690
+ buf.writeInt32LE(tag, 4);
691
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
692
+ programAddress: this.programId,
693
+ seeds: [buf, (0, kit_1.getAddressEncoder)().encode(this.drvsAuthority)]
694
+ }))[0];
695
+ return address;
696
+ });
697
+ }
698
+ getSpotContext(instrAccountHeaderModel) {
699
+ return __awaiter(this, void 0, void 0, function* () {
700
+ return [
701
+ {
702
+ address: yield this.getInstrAccountByTag({
703
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
704
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
705
+ tag: types_1.AccountType.INSTR
706
+ }),
707
+ role: kit_1.AccountRole.WRITABLE
708
+ },
709
+ {
710
+ address: yield this.getInstrAccountByTag({
711
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
712
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
713
+ tag: types_1.AccountType.SPOT_BIDS_TREE
714
+ }),
715
+ role: kit_1.AccountRole.WRITABLE
716
+ },
717
+ {
718
+ address: yield this.getInstrAccountByTag({
719
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
720
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
721
+ tag: types_1.AccountType.SPOT_ASKS_TREE
722
+ }),
723
+ role: kit_1.AccountRole.WRITABLE
724
+ },
725
+ {
726
+ address: yield this.getInstrAccountByTag({
727
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
728
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
729
+ tag: types_1.AccountType.SPOT_BID_ORDERS
730
+ }),
731
+ role: kit_1.AccountRole.WRITABLE
732
+ },
733
+ {
734
+ address: yield this.getInstrAccountByTag({
735
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
736
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
737
+ tag: types_1.AccountType.SPOT_ASK_ORDERS
738
+ }),
739
+ role: kit_1.AccountRole.WRITABLE
740
+ },
741
+ {
742
+ address: yield this.getInstrAccountByTag({
743
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
744
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
745
+ tag: types_1.AccountType.SPOT_LINES
746
+ }),
747
+ role: kit_1.AccountRole.WRITABLE
748
+ },
749
+ {
750
+ address: instrAccountHeaderModel.mapsAddress,
751
+ role: kit_1.AccountRole.WRITABLE
752
+ },
753
+ {
754
+ address: yield this.getInstrAccountByTag({
755
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
756
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
757
+ tag: types_1.AccountType.SPOT_CLIENT_INFOS
758
+ }),
759
+ role: kit_1.AccountRole.WRITABLE
760
+ },
761
+ {
762
+ address: yield this.getInstrAccountByTag({
763
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
764
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
765
+ tag: types_1.AccountType.SPOT_CLIENT_INFOS2
766
+ }),
767
+ role: kit_1.AccountRole.WRITABLE
768
+ },
769
+ {
770
+ address: yield this.getInstrAccountByTag({
771
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
772
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
773
+ tag: types_1.AccountType.SPOT_CLIENT_ACCOUNTS
774
+ }),
775
+ role: kit_1.AccountRole.WRITABLE
776
+ },
777
+ ];
778
+ });
779
+ }
780
+ getPerpContext(instrAccountHeaderModel) {
781
+ return __awaiter(this, void 0, void 0, function* () {
782
+ return [
783
+ {
784
+ address: yield this.getInstrAccountByTag({
785
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
786
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
787
+ tag: types_1.AccountType.INSTR
788
+ }),
789
+ role: kit_1.AccountRole.WRITABLE
790
+ },
791
+ {
792
+ address: yield this.getInstrAccountByTag({
793
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
794
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
795
+ tag: types_1.AccountType.PERP_BIDS_TREE
796
+ }),
797
+ role: kit_1.AccountRole.WRITABLE
798
+ },
799
+ {
800
+ address: yield this.getInstrAccountByTag({
801
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
802
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
803
+ tag: types_1.AccountType.PERP_ASKS_TREE
804
+ }),
805
+ role: kit_1.AccountRole.WRITABLE
806
+ },
807
+ {
808
+ address: yield this.getInstrAccountByTag({
809
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
810
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
811
+ tag: types_1.AccountType.PERP_BID_ORDERS
812
+ }),
813
+ role: kit_1.AccountRole.WRITABLE
814
+ },
815
+ {
816
+ address: yield this.getInstrAccountByTag({
817
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
818
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
819
+ tag: types_1.AccountType.PERP_ASK_ORDERS
820
+ }),
821
+ role: kit_1.AccountRole.WRITABLE
822
+ },
823
+ {
824
+ address: yield this.getInstrAccountByTag({
825
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
826
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
827
+ tag: types_1.AccountType.PERP_LINES
828
+ }),
829
+ role: kit_1.AccountRole.WRITABLE
830
+ },
831
+ {
832
+ address: instrAccountHeaderModel.perpMapsAddress,
833
+ role: kit_1.AccountRole.WRITABLE
834
+ },
835
+ {
836
+ address: yield this.getInstrAccountByTag({
837
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
838
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
839
+ tag: types_1.AccountType.PERP_CLIENT_INFOS
840
+ }),
841
+ role: kit_1.AccountRole.WRITABLE
842
+ },
843
+ {
844
+ address: yield this.getInstrAccountByTag({
845
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
846
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
847
+ tag: types_1.AccountType.PERP_CLIENT_INFOS2
848
+ }),
849
+ role: kit_1.AccountRole.WRITABLE
850
+ },
851
+ {
852
+ address: yield this.getInstrAccountByTag({
853
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
854
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
855
+ tag: types_1.AccountType.PERP_CLIENT_INFOS3
856
+ }),
857
+ role: kit_1.AccountRole.WRITABLE
858
+ },
859
+ {
860
+ address: yield this.getInstrAccountByTag({
861
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
862
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
863
+ tag: types_1.AccountType.PERP_CLIENT_INFOS4
864
+ }),
865
+ role: kit_1.AccountRole.WRITABLE
866
+ },
867
+ {
868
+ address: yield this.getInstrAccountByTag({
869
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
870
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
871
+ tag: types_1.AccountType.PERP_CLIENT_INFOS5
872
+ }),
873
+ role: kit_1.AccountRole.WRITABLE
874
+ },
875
+ {
876
+ address: yield this.getInstrAccountByTag({
877
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
878
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
879
+ tag: types_1.AccountType.PERP_CLIENT_ACCOUNTS
880
+ }),
881
+ role: kit_1.AccountRole.WRITABLE
882
+ },
883
+ {
884
+ address: yield this.getInstrAccountByTag({
885
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
886
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
887
+ tag: types_1.AccountType.PERP_LONG_PX_TREE
888
+ }),
889
+ role: kit_1.AccountRole.WRITABLE
890
+ },
891
+ {
892
+ address: yield this.getInstrAccountByTag({
893
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
894
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
895
+ tag: types_1.AccountType.PERP_SHORT_PX_TREE
896
+ }),
897
+ role: kit_1.AccountRole.WRITABLE
898
+ },
899
+ {
900
+ address: yield this.getInstrAccountByTag({
901
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
902
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
903
+ tag: types_1.AccountType.PERP_REBALANCE_TIME_TREE
904
+ }),
905
+ role: kit_1.AccountRole.WRITABLE
906
+ },
907
+ {
908
+ address: yield this.getInstrAccountByTag({
909
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
910
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
911
+ tag: types_1.AccountType.PERP_PRIORITY_TREE
912
+ }),
913
+ role: kit_1.AccountRole.WRITABLE
914
+ },
915
+ ];
916
+ });
917
+ }
918
+ getSpotCandles(instrAccountHeaderModel) {
919
+ return __awaiter(this, void 0, void 0, function* () {
920
+ return [
921
+ {
922
+ address: yield this.getInstrAccountByTag({
923
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
924
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
925
+ tag: types_1.AccountType.SPOT_1M_CANDLES
926
+ }),
927
+ role: kit_1.AccountRole.WRITABLE
928
+ },
929
+ {
930
+ address: yield this.getInstrAccountByTag({
931
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
932
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
933
+ tag: types_1.AccountType.SPOT_15M_CANDLES
934
+ }),
935
+ role: kit_1.AccountRole.WRITABLE
936
+ },
937
+ {
938
+ address: yield this.getInstrAccountByTag({
939
+ assetTokenId: instrAccountHeaderModel.assetTokenId,
940
+ crncyTokenId: instrAccountHeaderModel.crncyTokenId,
941
+ tag: types_1.AccountType.SPOT_DAY_CANDLES
942
+ }),
943
+ role: kit_1.AccountRole.WRITABLE
944
+ },
945
+ ];
946
+ });
947
+ }
948
+ getTokenAccount(mint) {
949
+ return __awaiter(this, void 0, void 0, function* () {
950
+ let buf = Buffer.from((0, kit_1.getAddressEncoder)().encode(mint).buffer);
951
+ buf.writeInt32LE(this.version, 28);
952
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
953
+ programAddress: this.programId,
954
+ seeds: [buf, (0, kit_1.getAddressEncoder)().encode(this.drvsAuthority)]
955
+ }))[0];
956
+ return address;
957
+ });
958
+ }
959
+ /**
960
+ * Get Token ID from mint public key if this token registered on DEXnow.io
961
+ * @param mint Public key
962
+ * @returns Token ID
963
+ */
964
+ getTokenId(mint) {
965
+ return __awaiter(this, void 0, void 0, function* () {
966
+ const tokenAddress = yield this.getTokenAccount(mint);
967
+ let info = yield this.rpc.getAccountInfo(tokenAddress, { commitment: this.commitment, encoding: 'base64', dataSlice: { offset: structure_models_1.TokenStateModel.OFFSET_ID, length: 4 } }).send();
968
+ if (info == null) {
969
+ return null;
970
+ }
971
+ else {
972
+ const data = Buffer.from((0, kit_1.getBase64Encoder)().encode(info.value.data[0]));
973
+ return data.readUInt32LE(0);
974
+ }
975
+ });
976
+ }
977
+ /**
978
+ * Get intrument ID if this instrument registered on DEXnow.io
979
+ * @param args Base crncy Token ID and asset token ID
980
+ * @returns Instrument ID
981
+ */
982
+ getInstrId(args) {
983
+ return __awaiter(this, void 0, void 0, function* () {
984
+ let buf = Buffer.alloc(16);
985
+ buf.writeInt32LE(this.version, 0);
986
+ buf.writeInt32LE(types_1.AccountType.INSTR, 4);
987
+ buf.writeInt32LE(args.assetTokenId, 8);
988
+ buf.writeInt32LE(args.crncyTokenId, 12);
989
+ const instrAddress = yield this.getInstrAccountByTag({
990
+ assetTokenId: args.assetTokenId,
991
+ crncyTokenId: args.crncyTokenId,
992
+ tag: types_1.AccountType.INSTR
993
+ });
994
+ let info = yield this.rpc.getAccountInfo(instrAddress, { commitment: this.commitment, encoding: 'base64', dataSlice: { offset: structure_models_1.InstrAccountHeaderModel.OFFSET_ID, length: 4 } }).send();
995
+ if (info == null) {
996
+ return null;
997
+ }
998
+ else {
999
+ const data = Buffer.from((0, kit_1.getBase64Encoder)().encode(info.value.data[0]));
1000
+ return data.readUInt32LE(0);
1001
+ }
1002
+ });
1003
+ }
1004
+ /**
1005
+ * Assignes client public key to Engine
1006
+ * @param wallet Client public key
1007
+ */
1008
+ setSigner(signer) {
1009
+ return __awaiter(this, void 0, void 0, function* () {
1010
+ this.signer = signer;
1011
+ let buf = Buffer.alloc(8);
1012
+ buf.writeUint32LE(this.version, 0);
1013
+ buf.writeUint32LE(types_1.AccountType.CLIENT_PRIMARY, 4);
1014
+ const clientPrimaryAccount = yield this.findClientPrimaryAccount(signer);
1015
+ let exists = false;
1016
+ try {
1017
+ const info = yield this.rpc.getAccountInfo(clientPrimaryAccount, {
1018
+ commitment: this.commitment,
1019
+ encoding: 'base64'
1020
+ }).send();
1021
+ if (info != null) {
1022
+ const clientPrimaryAccountHeaderModel = structure_models_1.ClientPrimaryAccountHeaderModel.fromBuffer(info.value.data);
1023
+ if (clientPrimaryAccountHeaderModel.walletAddress == signer) {
1024
+ this.clientPrimaryAccount = clientPrimaryAccount;
1025
+ this.clientCommunityAccount = clientPrimaryAccountHeaderModel.communityAddress;
1026
+ this.originalClientId = clientPrimaryAccountHeaderModel.id;
1027
+ this.clientLutAddress = clientPrimaryAccountHeaderModel.lutAddress;
1028
+ let date = Math.floor((new Date()).valueOf() / 1000);
1029
+ if (date < clientPrimaryAccountHeaderModel.refProgramExpiration) {
1030
+ this.refClientPrimaryAccount = clientPrimaryAccountHeaderModel.refAddress;
1031
+ let refInfo = yield this.rpc.getAccountInfo(this.refClientPrimaryAccount, {
1032
+ commitment: this.commitment,
1033
+ encoding: 'base64'
1034
+ }).send();
1035
+ const refClientPrimaryAccountHeaderModel = structure_models_1.ClientPrimaryAccountHeaderModel.fromBuffer(refInfo.value.data);
1036
+ this.refClientCommunityAccount =
1037
+ yield this.findClientCommunityAccount(refClientPrimaryAccountHeaderModel.walletAddress);
1038
+ }
1039
+ exists = true;
1040
+ }
1041
+ }
1042
+ }
1043
+ catch (err) {
1044
+ console.log(err);
1045
+ throw new Error("Wallet connection failed");
1046
+ }
1047
+ if (!exists) {
1048
+ this.clientPrimaryAccount = null;
1049
+ this.originalClientId = null;
1050
+ }
1051
+ });
1052
+ }
1053
+ findClientPrimaryAccount(wallet) {
1054
+ return __awaiter(this, void 0, void 0, function* () {
1055
+ let tagBuf = Buffer.alloc(8);
1056
+ tagBuf.writeUint32LE(this.version, 0);
1057
+ tagBuf.writeUint32LE(types_1.AccountType.CLIENT_PRIMARY, 4);
1058
+ let source = (wallet == null || wallet == undefined) ? this.signer : wallet;
1059
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
1060
+ programAddress: this.programId,
1061
+ seeds: [tagBuf, (0, kit_1.getAddressEncoder)().encode(source)]
1062
+ }))[0];
1063
+ return address;
1064
+ });
1065
+ }
1066
+ findClientCommunityAccount(wallet) {
1067
+ return __awaiter(this, void 0, void 0, function* () {
1068
+ let tagBuf = Buffer.alloc(8);
1069
+ tagBuf.writeUint32LE(this.version, 0);
1070
+ tagBuf.writeUint32LE(types_1.AccountType.CLIENT_COMMUNITY, 4);
1071
+ let source = (wallet == null || wallet == undefined) ? this.signer : wallet;
1072
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
1073
+ programAddress: this.programId,
1074
+ seeds: [tagBuf, (0, kit_1.getAddressEncoder)().encode(source)]
1075
+ }))[0];
1076
+ return address;
1077
+ });
1078
+ }
1079
+ findClientDrvAccount() {
1080
+ return __awaiter(this, void 0, void 0, function* () {
1081
+ let tagBuf = Buffer.alloc(8);
1082
+ tagBuf.writeUint32LE(this.version, 0);
1083
+ tagBuf.writeUint32LE(types_1.AccountType.CLIENT_DRV, 4);
1084
+ const address = (yield (0, kit_1.getProgramDerivedAddress)({
1085
+ programAddress: this.programId,
1086
+ seeds: [tagBuf, (0, kit_1.getAddressEncoder)().encode(this.signer)]
1087
+ }))[0];
1088
+ return address;
1089
+ });
1090
+ }
1091
+ checkClient() {
1092
+ return __awaiter(this, void 0, void 0, function* () {
1093
+ if (this.signer == null) {
1094
+ throw new Error("Wallet not connected");
1095
+ }
1096
+ if (this.clientPrimaryAccount != null) {
1097
+ return true;
1098
+ }
1099
+ const clientPrimaryAccount = yield this.findClientPrimaryAccount();
1100
+ try {
1101
+ const info = yield this.rpc.getAccountInfo(clientPrimaryAccount, {
1102
+ commitment: this.commitment,
1103
+ encoding: 'base64'
1104
+ }).send();
1105
+ if (info == null) {
1106
+ return false;
1107
+ }
1108
+ const clientPrimaryAccountHeaderModel = structure_models_1.ClientPrimaryAccountHeaderModel.fromBuffer(info.value.data);
1109
+ this.clientPrimaryAccount = clientPrimaryAccount;
1110
+ this.clientCommunityAccount = clientPrimaryAccountHeaderModel.communityAddress;
1111
+ this.originalClientId = clientPrimaryAccountHeaderModel.id;
1112
+ return true;
1113
+ }
1114
+ catch (err) {
1115
+ console.log(err);
1116
+ return false;
1117
+ }
1118
+ });
1119
+ }
1120
+ /**
1121
+ * Unpack client accounts
1122
+ * @returns All client data that are in client accounts
1123
+ */
1124
+ getClientData() {
1125
+ return __awaiter(this, void 0, void 0, function* () {
1126
+ if (!(yield this.checkClient())) {
1127
+ throw new Error("Client account not found");
1128
+ }
1129
+ const infos = yield this.rpc.getMultipleAccounts([this.clientPrimaryAccount, this.clientCommunityAccount], {
1130
+ commitment: this.commitment,
1131
+ encoding: 'base64'
1132
+ }).send();
1133
+ if (infos == null) {
1134
+ throw new Error("GetClientData: GetAccountInfo failed");
1135
+ }
1136
+ const clientPrimaryAccountHeaderModel = structure_models_1.ClientPrimaryAccountHeaderModel.fromBuffer(infos.value[0].data);
1137
+ let clientCommunityAccountHeaderModel = structure_models_1.ClientCommunityAccountHeaderModel.fromBuffer(infos.value[1].data);
1138
+ const primaryData = Buffer.from((0, kit_1.getBase64Encoder)().encode(infos.value[0].data[0]));
1139
+ let tokens = new Map();
1140
+ let lp = new Map();
1141
+ let spot = new Map();
1142
+ let perp = new Map();
1143
+ for (var i = 0; i < clientPrimaryAccountHeaderModel.assetsCount; ++i) {
1144
+ const offset = structure_models_1.ClientPrimaryAccountHeaderModel.LENGTH + i * 16;
1145
+ const assetInfo = primaryData.readUint32LE(offset);
1146
+ const tag = assetInfo >> 24;
1147
+ const id = assetInfo & 0xFFFFFF;
1148
+ if (tag == 1) {
1149
+ tokens.set(id, {
1150
+ tokenId: id,
1151
+ amount: Number(primaryData.readBigInt64LE(offset + 8)) / this.tokenDec(id)
1152
+ });
1153
+ }
1154
+ else if (tag == 2) {
1155
+ lp.set(id, {
1156
+ instrId: id,
1157
+ amount: Number(primaryData.readBigInt64LE(offset + 8)) / 10000
1158
+ });
1159
+ }
1160
+ else if (tag == 3) {
1161
+ const clientId = primaryData.readUint32LE(offset + 4);
1162
+ const slot = primaryData.readUint32LE(offset + 8);
1163
+ spot.set(id, {
1164
+ instrId: id,
1165
+ clientId: clientId,
1166
+ slot: slot
1167
+ });
1168
+ }
1169
+ else if (tag == 4) {
1170
+ const clientId = primaryData.readUint32LE(offset + 4);
1171
+ const slot = primaryData.readUint32LE(offset + 8);
1172
+ perp.set(id, {
1173
+ instrId: id,
1174
+ clientId: clientId,
1175
+ slot: slot
1176
+ });
1177
+ }
1178
+ }
1179
+ let clientCommunityRecords = new Map();
1180
+ for (var i = 0; i < clientCommunityAccountHeaderModel.count; ++i) {
1181
+ const offset = structure_models_1.ClientCommunityAccountHeaderModel.LENGTH + structure_models_1.ClientCommunityRecordModel.LENGTH * i;
1182
+ let clientCommunityRecordModel = structure_models_1.ClientCommunityRecordModel.fromBuffer(infos.value[1].data, offset);
1183
+ const crncyDec = this.tokenDec(clientCommunityRecordModel.crncyTokenId);
1184
+ clientCommunityRecordModel.dividendsValue /= crncyDec;
1185
+ clientCommunityRecordModel.feesPrepayment /= crncyDec;
1186
+ clientCommunityRecordModel.refPayments /= crncyDec;
1187
+ clientCommunityRecords.set(clientCommunityRecordModel.crncyTokenId, clientCommunityRecordModel);
1188
+ }
1189
+ const drvsDec = this.tokenDec(0);
1190
+ clientCommunityAccountHeaderModel.drvsTokens /= drvsDec;
1191
+ clientCommunityAccountHeaderModel.currentVotingTokens /= drvsDec;
1192
+ clientCommunityAccountHeaderModel.lastVotingTokens /= drvsDec;
1193
+ return {
1194
+ clientId: clientPrimaryAccountHeaderModel.id,
1195
+ mask: clientPrimaryAccountHeaderModel.mask,
1196
+ points: clientPrimaryAccountHeaderModel.points,
1197
+ slot: clientPrimaryAccountHeaderModel.slot,
1198
+ spotTrades: clientPrimaryAccountHeaderModel.spotTrades,
1199
+ lpTrades: clientPrimaryAccountHeaderModel.lpTrades,
1200
+ perpTrades: clientPrimaryAccountHeaderModel.perpTrades,
1201
+ tokens: tokens,
1202
+ lp: lp,
1203
+ spot: spot,
1204
+ perp: perp,
1205
+ refProgram: {
1206
+ address: clientPrimaryAccountHeaderModel.refAddress,
1207
+ expiration: clientPrimaryAccountHeaderModel.refProgramExpiration,
1208
+ clientId: clientPrimaryAccountHeaderModel.refClientId,
1209
+ disount: clientPrimaryAccountHeaderModel.refProgramDiscount,
1210
+ ratio: clientPrimaryAccountHeaderModel.refProgramRatio,
1211
+ },
1212
+ community: {
1213
+ header: clientCommunityAccountHeaderModel,
1214
+ data: clientCommunityRecords
1215
+ },
1216
+ refLinks: [
1217
+ {
1218
+ id: clientPrimaryAccountHeaderModel.firstRefLinkId,
1219
+ expiration: clientPrimaryAccountHeaderModel.firstRefLinkExpiration,
1220
+ discount: clientPrimaryAccountHeaderModel.firstRefLinkDiscount,
1221
+ ratio: clientPrimaryAccountHeaderModel.firstRefLinkRatio
1222
+ },
1223
+ {
1224
+ id: clientPrimaryAccountHeaderModel.secondRefLinkId,
1225
+ expiration: clientPrimaryAccountHeaderModel.secondRefLinkExpiration,
1226
+ discount: clientPrimaryAccountHeaderModel.secondRefLinkDiscount,
1227
+ ratio: clientPrimaryAccountHeaderModel.secondRefLinkRatio
1228
+ }
1229
+ ],
1230
+ };
1231
+ });
1232
+ }
1233
+ tokenDec(tokenId) {
1234
+ const token = this.tokens.get(tokenId);
1235
+ return Math.pow(10, token.mask & 0xFF);
1236
+ }
1237
+ /**
1238
+ * Get general information about open orders in particular instrument (spot)
1239
+ * @param args Contains data from getClientData function
1240
+ * @returns General information about open orders (spot)
1241
+ */
1242
+ getClientSpotOrdersInfo(args) {
1243
+ return __awaiter(this, void 0, void 0, function* () {
1244
+ const instr = this.instruments.get(args.instrId);
1245
+ if (instr == undefined) {
1246
+ throw new Error("Invalid Instrument ID");
1247
+ }
1248
+ const clientInfosAccount = yield this.getInstrAccountByTag({
1249
+ assetTokenId: instr.header.assetTokenId,
1250
+ crncyTokenId: instr.header.crncyTokenId,
1251
+ tag: types_1.AccountType.SPOT_CLIENT_INFOS
1252
+ });
1253
+ const clientInfos2Account = yield this.getInstrAccountByTag({
1254
+ assetTokenId: instr.header.assetTokenId,
1255
+ crncyTokenId: instr.header.crncyTokenId,
1256
+ tag: types_1.AccountType.SPOT_CLIENT_INFOS2
1257
+ });
1258
+ const infos = yield this.rpc.getMultipleAccounts([clientInfosAccount, clientInfos2Account], {
1259
+ commitment: this.commitment,
1260
+ encoding: 'base64',
1261
+ dataSlice: {
1262
+ offset: structure_models_1.SpotTradeAccountHeaderModel.LENGTH + 32 * args.clientId,
1263
+ length: 32
1264
+ }
1265
+ }).send();
1266
+ if (infos.value[0] == null || infos.value[1] == null) {
1267
+ throw new Error("Orders Info Not Found");
1268
+ }
1269
+ const data = Buffer.from((0, kit_1.getBase64Encoder)().encode(infos.value[0].data[0]));
1270
+ const data1 = Buffer.from((0, kit_1.getBase64Encoder)().encode(infos.value[1].data[0]));
1271
+ return {
1272
+ contextSlot: Number(infos.context.slot),
1273
+ bidSlot: data1.readUint32LE(structure_models_1.SpotClientInfo2Model.OFFSET_BID_SLOT),
1274
+ askSlot: data1.readUint32LE(structure_models_1.SpotClientInfo2Model.OFFSET_ASK_SLOT),
1275
+ bidsEntry: data.readUint16LE(structure_models_1.SpotClientInfoModel.OFFSET_BIDS_ENTRY),
1276
+ bidsCount: data.readUint16LE(structure_models_1.SpotClientInfoModel.OFFSET_BIDS_ENTRY + 2),
1277
+ asksEntry: data.readUint16LE(structure_models_1.SpotClientInfoModel.OFFSET_ASKS_ENTRY),
1278
+ asksCount: data.readUint16LE(structure_models_1.SpotClientInfoModel.OFFSET_ASKS_ENTRY + 2),
1279
+ tempAssetTokens: Number(data.readBigInt64LE(structure_models_1.SpotClientInfoModel.OFFSET_AVAIL_ASSET_TOKENS)) /
1280
+ this.tokenDec(instr.header.assetTokenId),
1281
+ tempCrncyTokens: Number(data.readBigInt64LE(structure_models_1.SpotClientInfoModel.OFFSET_AVAIL_CRNCY_TOKENS)) /
1282
+ this.tokenDec(instr.header.crncyTokenId),
1283
+ };
1284
+ });
1285
+ }
1286
+ /**
1287
+ * Get general information about open orders in particular instrument (perp)
1288
+ * @param args Contains data from getClientData function
1289
+ * @returns General information about open orders (perp)
1290
+ */
1291
+ getClientPerpOrdersInfo(args) {
1292
+ return __awaiter(this, void 0, void 0, function* () {
1293
+ const instr = this.instruments.get(args.instrId);
1294
+ if (instr == undefined) {
1295
+ throw new Error("Invalid Instrument ID");
1296
+ }
1297
+ const clientInfosAccount = yield this.getInstrAccountByTag({
1298
+ assetTokenId: instr.header.assetTokenId,
1299
+ crncyTokenId: instr.header.crncyTokenId,
1300
+ tag: types_1.AccountType.PERP_CLIENT_INFOS
1301
+ });
1302
+ const clientInfos2Account = yield this.getInstrAccountByTag({
1303
+ assetTokenId: instr.header.assetTokenId,
1304
+ crncyTokenId: instr.header.crncyTokenId,
1305
+ tag: types_1.AccountType.PERP_CLIENT_INFOS2
1306
+ });
1307
+ const clientInfos3Account = yield this.getInstrAccountByTag({
1308
+ assetTokenId: instr.header.assetTokenId,
1309
+ crncyTokenId: instr.header.crncyTokenId,
1310
+ tag: types_1.AccountType.PERP_CLIENT_INFOS3
1311
+ });
1312
+ const clientInfos4Account = yield this.getInstrAccountByTag({
1313
+ assetTokenId: instr.header.assetTokenId,
1314
+ crncyTokenId: instr.header.crncyTokenId,
1315
+ tag: types_1.AccountType.PERP_CLIENT_INFOS4
1316
+ });
1317
+ const clientInfos5Account = yield this.getInstrAccountByTag({
1318
+ assetTokenId: instr.header.assetTokenId,
1319
+ crncyTokenId: instr.header.crncyTokenId,
1320
+ tag: types_1.AccountType.PERP_CLIENT_INFOS5
1321
+ });
1322
+ const infos = yield this.rpc.getMultipleAccounts([clientInfosAccount, clientInfos2Account, clientInfos3Account, clientInfos4Account, clientInfos5Account], {
1323
+ commitment: this.commitment,
1324
+ encoding: 'base64',
1325
+ dataSlice: {
1326
+ offset: structure_models_1.SpotTradeAccountHeaderModel.LENGTH + 32 * args.clientId,
1327
+ length: 32
1328
+ }
1329
+ }).send();
1330
+ if (infos.value[0] == null || infos.value[1] == null || infos.value[2] == null ||
1331
+ infos.value[3] == null || infos.value[4] == null) {
1332
+ throw new Error("Orders Info Not Found");
1333
+ }
1334
+ const clientInfoModel = structure_models_1.PerpClientInfoModel.fromBuffer(infos.value[0].data);
1335
+ const clientInfo2Model = structure_models_1.PerpClientInfo2Model.fromBuffer(infos.value[1].data);
1336
+ const clientInfo3Model = structure_models_1.PerpClientInfo3Model.fromBuffer(infos.value[2].data);
1337
+ const clientInfo4Model = structure_models_1.PerpClientInfo4Model.fromBuffer(infos.value[3].data);
1338
+ const clientInfo5Model = structure_models_1.PerpClientInfo5Model.fromBuffer(infos.value[4].data);
1339
+ return {
1340
+ contextSlot: Number(infos.context.slot),
1341
+ bidSlot: clientInfo2Model.bidSlot,
1342
+ askSlot: clientInfo2Model.askSlot,
1343
+ bidsEntry: clientInfo3Model.bidsEntry & 0xFFFF,
1344
+ bidsCount: clientInfo3Model.bidsEntry >> 16,
1345
+ asksEntry: clientInfo3Model.asksEntry & 0xFFFF,
1346
+ asksCount: clientInfo3Model.asksEntry >> 16,
1347
+ perps: clientInfoModel.perps,
1348
+ funds: clientInfoModel.funds,
1349
+ inOrdersPerps: clientInfoModel.inOrdersPerps,
1350
+ inOrdersFunds: clientInfoModel.inOrdersFunds,
1351
+ fees: clientInfo3Model.fees,
1352
+ rebates: clientInfo3Model.rebates,
1353
+ result: clientInfo2Model.result,
1354
+ cost: clientInfo2Model.cost,
1355
+ mask: clientInfo2Model.mask,
1356
+ socLossFunds: clientInfo4Model.socLossFunds,
1357
+ fundingFunds: clientInfo5Model.fundingFunds,
1358
+ };
1359
+ });
1360
+ }
1361
+ /**
1362
+ * Get list of open orders (spot) in particular instrument
1363
+ * @param args Contains data from getClientSpotOrdersInfo
1364
+ * @returns List of open orders
1365
+ */
1366
+ getClientSpotOrders(args) {
1367
+ return __awaiter(this, void 0, void 0, function* () {
1368
+ const instr = this.instruments.get(args.instrId);
1369
+ const bidOrdersAccount = yield this.getInstrAccountByTag({
1370
+ assetTokenId: instr.header.assetTokenId,
1371
+ crncyTokenId: instr.header.crncyTokenId,
1372
+ tag: types_1.AccountType.SPOT_BID_ORDERS
1373
+ });
1374
+ const askOrdersAccount = yield this.getInstrAccountByTag({
1375
+ assetTokenId: instr.header.assetTokenId,
1376
+ crncyTokenId: instr.header.crncyTokenId,
1377
+ tag: types_1.AccountType.SPOT_ASK_ORDERS
1378
+ });
1379
+ if (args.bidsCount > 1 && args.asksCount > 1) {
1380
+ let infos = yield this.rpc.getMultipleAccounts([bidOrdersAccount, askOrdersAccount], { commitment: this.commitment, encoding: 'base64' }).send();
1381
+ return {
1382
+ bidContextSlot: Number(infos.context.slot),
1383
+ askContextSlot: Number(infos.context.slot),
1384
+ bids: getMultipleSpotOrders(infos.value[0].data, args.bidsEntry),
1385
+ asks: getMultipleSpotOrders(infos.value[1].data, args.asksEntry)
1386
+ };
1387
+ }
1388
+ let bids = [];
1389
+ let asks = [];
1390
+ let bidContextSlot = 0;
1391
+ let askContextSlot = 0;
1392
+ if (args.bidsCount > 1) {
1393
+ let info = yield this.rpc.getAccountInfo(bidOrdersAccount, {
1394
+ commitment: this.commitment,
1395
+ encoding: 'base64'
1396
+ }).send();
1397
+ bidContextSlot = Number(info.context.slot);
1398
+ bids = getMultipleSpotOrders(info.value.data, args.bidsEntry);
1399
+ }
1400
+ else if (args.bidsCount == 1) {
1401
+ let info = yield this.rpc.getAccountInfo(bidOrdersAccount, {
1402
+ commitment: this.commitment,
1403
+ encoding: 'base64',
1404
+ dataSlice: {
1405
+ offset: args.bidsEntry * 64 + structure_models_1.SpotTradeAccountHeaderModel.LENGTH,
1406
+ length: 64
1407
+ }
1408
+ }).send();
1409
+ bids = [structure_models_1.OrderModel.fromBuffer(info.value.data)];
1410
+ bidContextSlot = Number(info.context.slot);
1411
+ }
1412
+ if (args.asksCount > 1) {
1413
+ let info = yield this.rpc.getAccountInfo(askOrdersAccount, {
1414
+ commitment: this.commitment,
1415
+ encoding: 'base64'
1416
+ }).send();
1417
+ askContextSlot = Number(info.context.slot);
1418
+ asks = getMultipleSpotOrders(info.value.data, args.bidsEntry);
1419
+ }
1420
+ else if (args.asksCount == 1) {
1421
+ let info = yield this.rpc.getAccountInfo(askOrdersAccount, {
1422
+ commitment: this.commitment,
1423
+ encoding: 'base64',
1424
+ dataSlice: {
1425
+ offset: args.asksEntry * 64 + structure_models_1.SpotTradeAccountHeaderModel.LENGTH,
1426
+ length: 64
1427
+ }
1428
+ }).send();
1429
+ asks = [structure_models_1.OrderModel.fromBuffer(info.value.data)];
1430
+ askContextSlot = Number(info.context.slot);
1431
+ }
1432
+ return {
1433
+ bidContextSlot: bidContextSlot,
1434
+ askContextSlot: askContextSlot,
1435
+ bids: bids,
1436
+ asks: asks
1437
+ };
1438
+ });
1439
+ }
1440
+ /**
1441
+ * Get list of open orders (perp) in particular instrument
1442
+ * @param args Contains data from getClientSpotOrdersInfo
1443
+ * @returns List of open orders
1444
+ */
1445
+ getClientPerpOrders(args) {
1446
+ return __awaiter(this, void 0, void 0, function* () {
1447
+ const instr = this.instruments.get(args.instrId);
1448
+ const bidOrdersAccount = yield this.getInstrAccountByTag({
1449
+ assetTokenId: instr.header.assetTokenId,
1450
+ crncyTokenId: instr.header.crncyTokenId,
1451
+ tag: types_1.AccountType.PERP_BID_ORDERS
1452
+ });
1453
+ const askOrdersAccount = yield this.getInstrAccountByTag({
1454
+ assetTokenId: instr.header.assetTokenId,
1455
+ crncyTokenId: instr.header.crncyTokenId,
1456
+ tag: types_1.AccountType.PERP_ASK_ORDERS
1457
+ });
1458
+ if (args.bidsCount > 1 && args.asksCount > 1) {
1459
+ let infos = yield this.rpc.getMultipleAccounts([bidOrdersAccount, askOrdersAccount], { commitment: this.commitment, encoding: 'base64' }).send();
1460
+ return {
1461
+ bidContextSlot: Number(infos.context.slot),
1462
+ askContextSlot: Number(infos.context.slot),
1463
+ bids: getMultiplePerpOrders(infos.value[0].data, args.bidsEntry),
1464
+ asks: getMultiplePerpOrders(infos.value[1].data, args.asksEntry)
1465
+ };
1466
+ }
1467
+ let bids = [];
1468
+ let asks = [];
1469
+ let bidContextSlot = 0;
1470
+ let askContextSlot = 0;
1471
+ if (args.bidsCount > 1) {
1472
+ let info = yield this.rpc.getAccountInfo(bidOrdersAccount, { commitment: this.commitment, encoding: 'base64' }).send();
1473
+ bidContextSlot = Number(info.context.slot);
1474
+ bids = getMultiplePerpOrders(info.value.data, args.bidsEntry);
1475
+ }
1476
+ else if (args.bidsCount == 1) {
1477
+ let info = yield this.rpc.getAccountInfo(bidOrdersAccount, {
1478
+ commitment: this.commitment,
1479
+ encoding: 'base64',
1480
+ dataSlice: {
1481
+ offset: args.bidsEntry * 64 + structure_models_1.PerpTradeAccountHeaderModel.LENGTH,
1482
+ length: 64
1483
+ }
1484
+ }).send();
1485
+ bids = [structure_models_1.OrderModel.fromBuffer(info.value.data)];
1486
+ bidContextSlot = Number(info.context.slot);
1487
+ }
1488
+ if (args.asksCount > 1) {
1489
+ let info = yield this.rpc.getAccountInfo(askOrdersAccount, { commitment: this.commitment, encoding: 'base64' }).send();
1490
+ askContextSlot = Number(info.context.slot);
1491
+ asks = getMultiplePerpOrders(info.value.data, args.bidsEntry);
1492
+ }
1493
+ else if (args.asksCount == 1) {
1494
+ let info = yield this.rpc.getAccountInfo(askOrdersAccount, {
1495
+ commitment: this.commitment,
1496
+ encoding: 'base64',
1497
+ dataSlice: {
1498
+ offset: args.asksEntry * 64 + structure_models_1.PerpTradeAccountHeaderModel.LENGTH,
1499
+ length: 64
1500
+ }
1501
+ }).send();
1502
+ asks = [structure_models_1.OrderModel.fromBuffer(info.value.data)];
1503
+ askContextSlot = Number(info.context.slot);
1504
+ }
1505
+ return {
1506
+ bidContextSlot: bidContextSlot,
1507
+ askContextSlot: askContextSlot,
1508
+ bids: bids,
1509
+ asks: asks
1510
+ };
1511
+ });
1512
+ }
1513
+ /**
1514
+ * Unpack market data to Engine fields, you can use this function to subscribe to Solana account
1515
+ * @param buf Engine Instrument Dynamic Account data
1516
+ */
1517
+ updateInstrDataFromBuffer(data) {
1518
+ return __awaiter(this, void 0, void 0, function* () {
1519
+ let header = structure_models_1.InstrAccountHeaderModel.fromBuffer(data);
1520
+ header.ps /= 10000;
1521
+ const assetTokenDec = this.tokenDec(header.assetTokenId);
1522
+ const crncyTokenDec = this.tokenDec(header.crncyTokenId);
1523
+ header.assetTokens /= assetTokenDec;
1524
+ header.crncyTokens /= crncyTokenDec;
1525
+ header.protocolFees /= crncyTokenDec;
1526
+ header.lastAssetTokens /= assetTokenDec;
1527
+ header.lastCrncyTokens /= crncyTokenDec;
1528
+ header.dayAssetTokens /= assetTokenDec;
1529
+ header.dayCrncyTokens /= crncyTokenDec;
1530
+ header.prevDayAssetTokens /= assetTokenDec;
1531
+ header.prevDayCrncyTokens /= crncyTokenDec;
1532
+ header.perpLastAssetTokens /= assetTokenDec;
1533
+ header.perpLastCrncyTokens /= crncyTokenDec;
1534
+ header.perpDayAssetTokens /= assetTokenDec;
1535
+ header.perpDayCrncyTokens /= crncyTokenDec;
1536
+ header.fixingAssetTokens /= assetTokenDec;
1537
+ header.fixingCrncyTokens /= crncyTokenDec;
1538
+ header.perpFundingFunds /= crncyTokenDec;
1539
+ header.perpInsuranceFund /= crncyTokenDec;
1540
+ header.perpOpenInt /= assetTokenDec;
1541
+ header.perpSocLossFunds /= crncyTokenDec;
1542
+ header.perpPrevDayAssetTokens /= assetTokenDec;
1543
+ header.perpPrevDayCrncyTokens /= crncyTokenDec;
1544
+ header.bestBid /= dec;
1545
+ header.bestAsk /= dec;
1546
+ header.dayHigh /= dec;
1547
+ header.dayLow /= dec;
1548
+ header.perpBestBid /= dec;
1549
+ header.perpBestAsk /= dec;
1550
+ header.perpDayHigh /= dec;
1551
+ header.perpDayLow /= dec;
1552
+ header.lastPx /= dec;
1553
+ header.perpUnderlyingPx /= dec;
1554
+ header.lastClose /= dec;
1555
+ header.fixingPx /= dec;
1556
+ header.perpLastClose /= dec;
1557
+ header.perpLastPx /= dec;
1558
+ header.lastHourPx /= dec;
1559
+ header.perpSpotPriceForWithdrowal /= dec;
1560
+ header.poolFees /= crncyTokenDec;
1561
+ let spotBids = [];
1562
+ let spotAsks = [];
1563
+ let perpBids = [];
1564
+ let perpAsks = [];
1565
+ for (var i = 0; i < types_1.MARKET_DEPTH; ++i) {
1566
+ const offset = structure_models_1.InstrAccountHeaderModel.LENGTH + i * 16;
1567
+ let line = structure_models_1.LineQuotesModel.fromBuffer(data, offset);
1568
+ if (line.px == 0) {
1569
+ break;
1570
+ }
1571
+ line.px /= dec;
1572
+ line.qty /= assetTokenDec;
1573
+ spotBids.push(line);
1574
+ }
1575
+ for (var i = 0; i < types_1.MARKET_DEPTH; ++i) {
1576
+ const offset = structure_models_1.InstrAccountHeaderModel.LENGTH + i * 16 + 16 * types_1.MARKET_DEPTH;
1577
+ let line = structure_models_1.LineQuotesModel.fromBuffer(data, offset);
1578
+ if (line.px == 0) {
1579
+ break;
1580
+ }
1581
+ line.px /= dec;
1582
+ line.qty /= assetTokenDec;
1583
+ spotAsks.push(line);
1584
+ }
1585
+ for (var i = 0; i < types_1.MARKET_DEPTH; ++i) {
1586
+ const offset = structure_models_1.InstrAccountHeaderModel.LENGTH + i * 16 + 16 * types_1.MARKET_DEPTH * 2;
1587
+ let line = structure_models_1.LineQuotesModel.fromBuffer(data, offset);
1588
+ if (line.px == 0) {
1589
+ break;
1590
+ }
1591
+ line.px /= dec;
1592
+ line.qty /= assetTokenDec;
1593
+ perpBids.push(line);
1594
+ }
1595
+ for (var i = 0; i < types_1.MARKET_DEPTH; ++i) {
1596
+ const offset = structure_models_1.InstrAccountHeaderModel.LENGTH + i * 16 + 16 * types_1.MARKET_DEPTH * 3;
1597
+ let line = structure_models_1.LineQuotesModel.fromBuffer(data, offset);
1598
+ if (line.px == 0) {
1599
+ break;
1600
+ }
1601
+ line.px /= dec;
1602
+ line.qty /= assetTokenDec;
1603
+ perpAsks.push(line);
1604
+ }
1605
+ let pattern = Buffer.alloc(16);
1606
+ pattern.writeInt32LE(this.version, 0);
1607
+ pattern.writeInt32LE(types_1.AccountType.INSTR, 4);
1608
+ pattern.writeInt32LE(header.assetTokenId, 8);
1609
+ pattern.writeInt32LE(header.crncyTokenId, 12);
1610
+ const instrAddress = (yield (0, kit_1.getProgramDerivedAddress)({
1611
+ programAddress: this.programId,
1612
+ seeds: [pattern, (0, kit_1.getAddressEncoder)().encode(this.drvsAuthority)]
1613
+ }))[0];
1614
+ this.instruments.set(header.id, {
1615
+ address: instrAddress,
1616
+ header: header,
1617
+ spotBids: spotBids,
1618
+ spotAsks: spotAsks,
1619
+ perpBids: perpBids,
1620
+ perpAsks: perpAsks
1621
+ });
1622
+ });
1623
+ }
1624
+ /**
1625
+ * Get AddressLookupTableAccount to compile Versioned Transaction with this instrument (spot + derivatives)
1626
+ * @param args Instrument ID
1627
+ * @returns AddressLookupTableAccount for instrument
1628
+ */
1629
+ instrLut(args) {
1630
+ return this.instruments.get(args.instrId).header.lutAddress;
1631
+ }
1632
+ /**
1633
+ * Update market data on Engine fields
1634
+ * @param args Instrument ID
1635
+ */
1636
+ updateInstrData(args) {
1637
+ return __awaiter(this, void 0, void 0, function* () {
1638
+ let instrAccount = yield this.getInstrAccountByTag({
1639
+ assetTokenId: args.assetTokenId,
1640
+ crncyTokenId: args.crncyTokenId,
1641
+ tag: types_1.AccountType.INSTR
1642
+ });
1643
+ const info = yield this.rpc.getAccountInfo(instrAccount, { commitment: this.commitment, encoding: 'base64' }).send();
1644
+ yield this.updateInstrDataFromBuffer(info.value.data);
1645
+ });
1646
+ }
1647
+ /**
1648
+ * Build instruction to deposit SPL tokens
1649
+ * @param args Order data
1650
+ * @returns Transaction instruction
1651
+ */
1652
+ depositInstruction(args) {
1653
+ return __awaiter(this, void 0, void 0, function* () {
1654
+ const exists = yield this.checkClient();
1655
+ if (this.signer == null) {
1656
+ throw new Error("Wallet is not connected");
1657
+ }
1658
+ const token = this.tokens.get(args.tokenId);
1659
+ const tokenProgramId = (token.mask & 0x80000000) != 0 ? exports.TOKEN_2022_PROGRAM_ID : exports.TOKEN_PROGRAM_ID;
1660
+ const clientTokenAccount = yield findAssociatedTokenAddress(this.signer, tokenProgramId, token.address);
1661
+ let keys = [
1662
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1663
+ { address: clientTokenAccount, role: kit_1.AccountRole.WRITABLE },
1664
+ { address: token.programAddress, role: kit_1.AccountRole.WRITABLE },
1665
+ { address: token.address, role: kit_1.AccountRole.READONLY },
1666
+ { address: this.rootAccount, role: exists ? kit_1.AccountRole.READONLY : kit_1.AccountRole.WRITABLE },
1667
+ { address: yield this.getTokenAccount(token.address), role: kit_1.AccountRole.READONLY },
1668
+ { address: yield this.findClientPrimaryAccount(), role: kit_1.AccountRole.WRITABLE },
1669
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1670
+ { address: tokenProgramId, role: kit_1.AccountRole.READONLY },
1671
+ ];
1672
+ if (exists) {
1673
+ if (args.tokenId == 0) {
1674
+ keys.push({ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.WRITABLE });
1675
+ keys.push({ address: this.clientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
1676
+ }
1677
+ return {
1678
+ accounts: keys,
1679
+ programAddress: this.programId,
1680
+ data: (0, instruction_models_1.depositData)(7, args.tokenId, args.amount * this.tokenDec(args.tokenId), 0, 0)
1681
+ };
1682
+ }
1683
+ else {
1684
+ const slot = Number((yield this.rpc.getSlot().send())) - 1;
1685
+ const lutAddress = yield getLookupTableAddress(this.signer, slot);
1686
+ const clientCommunityAccount = yield this.findClientCommunityAccount();
1687
+ keys.push({ address: yield this.findClientDrvAccount(), role: kit_1.AccountRole.WRITABLE });
1688
+ keys.push({ address: clientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
1689
+ keys.push({ address: lutAddress, role: kit_1.AccountRole.WRITABLE });
1690
+ keys.push({ address: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, role: kit_1.AccountRole.WRITABLE });
1691
+ if (args.tokenId == 0) {
1692
+ keys.push({ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.WRITABLE });
1693
+ keys.push({ address: clientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
1694
+ }
1695
+ let refId;
1696
+ if (args.refId != null && args.refId != undefined) {
1697
+ refId = args.refId;
1698
+ if (args.refWallet == null || args.refWallet == undefined) {
1699
+ throw new Error("Ref Wallet Not Found");
1700
+ }
1701
+ keys.push({ address: yield this.findClientPrimaryAccount(args.refWallet), role: kit_1.AccountRole.WRITABLE });
1702
+ keys.push({ address: yield this.findClientCommunityAccount(args.refWallet), role: kit_1.AccountRole.WRITABLE });
1703
+ }
1704
+ else {
1705
+ refId = 0;
1706
+ }
1707
+ return {
1708
+ accounts: keys,
1709
+ programAddress: this.programId,
1710
+ data: (0, instruction_models_1.depositData)(7, args.tokenId, args.amount * this.tokenDec(args.tokenId), slot, refId)
1711
+ };
1712
+ }
1713
+ });
1714
+ }
1715
+ /**
1716
+ * Build instruction to withdraw SPL tokens
1717
+ * @param args Order data
1718
+ * @returns Transaction instruction
1719
+ */
1720
+ withdrawInstruction(args) {
1721
+ return __awaiter(this, void 0, void 0, function* () {
1722
+ if (!(yield this.checkClient())) {
1723
+ throw new Error("Client account not found");
1724
+ }
1725
+ const token = this.tokens.get(args.tokenId);
1726
+ const tokenProgramId = (token.mask & 0x80000000) != 0 ? exports.TOKEN_2022_PROGRAM_ID : exports.TOKEN_PROGRAM_ID;
1727
+ const clientTokenAccount = yield findAssociatedTokenAddress(this.signer, tokenProgramId, token.address);
1728
+ let keys = [
1729
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1730
+ { address: clientTokenAccount, role: kit_1.AccountRole.WRITABLE },
1731
+ { address: token.programAddress, role: kit_1.AccountRole.WRITABLE },
1732
+ { address: token.address, role: kit_1.AccountRole.READONLY },
1733
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
1734
+ { address: yield this.getTokenAccount(token.address), role: kit_1.AccountRole.READONLY },
1735
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
1736
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1737
+ { address: tokenProgramId, role: kit_1.AccountRole.READONLY },
1738
+ { address: this.drvsAuthority, role: kit_1.AccountRole.READONLY },
1739
+ { address: exports.ASSOCIATED_TOKEN_PROGRAM_ID, role: kit_1.AccountRole.WRITABLE },
1740
+ ];
1741
+ if (args.spot != undefined) {
1742
+ keys.push({ address: yield this.findClientDrvAccount(), role: kit_1.AccountRole.READONLY });
1743
+ for (var i = 0; i < args.spot.length; ++i) {
1744
+ const instr = this.instruments.get(args.spot[i].instrId);
1745
+ if (instr.header.assetTokenId == args.tokenId || instr.header.crncyTokenId == args.tokenId) {
1746
+ keys.push({ address: instr.header.mapsAddress, role: kit_1.AccountRole.READONLY });
1747
+ keys.push({
1748
+ address: yield this.getInstrAccountByTag({
1749
+ assetTokenId: instr.header.assetTokenId,
1750
+ crncyTokenId: instr.header.crncyTokenId,
1751
+ tag: types_1.AccountType.SPOT_CLIENT_INFOS
1752
+ }),
1753
+ role: kit_1.AccountRole.READONLY
1754
+ });
1755
+ }
1756
+ }
1757
+ }
1758
+ if (args.tokenId == 0) {
1759
+ keys.push({ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY });
1760
+ keys.push({ address: yield this.clientCommunityAccount, role: kit_1.AccountRole.READONLY });
1761
+ }
1762
+ return {
1763
+ accounts: keys,
1764
+ programAddress: this.programId,
1765
+ data: (0, instruction_models_1.withdrawData)(8, args.tokenId, args.amount * this.tokenDec(args.tokenId))
1766
+ };
1767
+ });
1768
+ }
1769
+ /**
1770
+ * Build instruction to trade spot LP tokens in particular instrument
1771
+ * @param args Order data
1772
+ * @returns Trabsaction instruction
1773
+ */
1774
+ spotLpInstruction(args) {
1775
+ return __awaiter(this, void 0, void 0, function* () {
1776
+ if (!(yield this.checkClient())) {
1777
+ throw new Error("Client account not found");
1778
+ }
1779
+ const instr = this.instruments.get(args.instrId);
1780
+ let keys = [
1781
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1782
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
1783
+ {
1784
+ address: yield this.getInstrAccountByTag({
1785
+ assetTokenId: instr.header.assetTokenId,
1786
+ crncyTokenId: instr.header.crncyTokenId,
1787
+ tag: types_1.AccountType.INSTR
1788
+ }),
1789
+ role: kit_1.AccountRole.WRITABLE
1790
+ },
1791
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
1792
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1793
+ ];
1794
+ if (instr.header.assetTokenId == 0) {
1795
+ keys.push({ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.WRITABLE });
1796
+ keys.push({ address: this.clientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
1797
+ }
1798
+ return {
1799
+ accounts: keys,
1800
+ programAddress: this.programId,
1801
+ data: (0, instruction_models_1.spotLpData)(14, args.side, args.instrId, Math.round(args.amount * 10000)),
1802
+ };
1803
+ });
1804
+ }
1805
+ /**
1806
+ * Build instruction to add new spot order in particular instrument
1807
+ * @param args Order data
1808
+ * @returns Transaction instruction
1809
+ */
1810
+ newSpotOrderInstruction(args) {
1811
+ return __awaiter(this, void 0, void 0, function* () {
1812
+ if (!(yield this.checkClient())) {
1813
+ throw new Error("Client account not found");
1814
+ }
1815
+ let instr = this.instruments.get(args.instrId);
1816
+ let buf = (0, instruction_models_1.newSpotOrderData)(12, args.ioc == null || args.ioc == undefined ? 0 : args.ioc, args.orderType == null || args.orderType == undefined ? 0 : args.orderType, args.side, args.instrId, Math.round(args.price * dec), Math.round(args.qty * this.tokenDec(instr.header.assetTokenId)));
1817
+ let keys = [
1818
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1819
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
1820
+ { address: yield this.findClientPrimaryAccount(), role: kit_1.AccountRole.WRITABLE },
1821
+ { address: yield this.findClientCommunityAccount(), role: kit_1.AccountRole.WRITABLE },
1822
+ ...yield this.getSpotContext(instr.header),
1823
+ ...yield this.getSpotCandles(instr.header),
1824
+ {
1825
+ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY),
1826
+ role: instr.header.assetTokenId == 0 ? kit_1.AccountRole.WRITABLE : kit_1.AccountRole.READONLY
1827
+ },
1828
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1829
+ ];
1830
+ if (this.refClientPrimaryAccount != null && this.refClientPrimaryAccount != undefined) {
1831
+ keys.push({ address: this.refClientPrimaryAccount, role: kit_1.AccountRole.WRITABLE });
1832
+ keys.push({ address: this.refClientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
1833
+ }
1834
+ return {
1835
+ accounts: keys, programAddress: this.programId, data: buf
1836
+ };
1837
+ });
1838
+ }
1839
+ /**
1840
+ * Build instruction to spot quotes replacement in particular instrument
1841
+ * @param args Order data
1842
+ * @returns Transaction instruction
1843
+ */
1844
+ spotQuotesReplaceInstruction(args) {
1845
+ return __awaiter(this, void 0, void 0, function* () {
1846
+ if (!(yield this.checkClient())) {
1847
+ throw new Error("Client account not found");
1848
+ }
1849
+ let instr = this.instruments.get(args.instrId);
1850
+ let assetTokenDecFactor = this.tokenDec(instr.header.assetTokenId);
1851
+ let buf = (0, instruction_models_1.spotQuotesReplaceData)(34, args.instrId, Math.round(args.newBidPrice * dec), Math.round(args.newBidQty * assetTokenDecFactor), args.bidOrderIdToCancel, Math.round(args.newAskPrice * dec), Math.round(args.newAskQty * assetTokenDecFactor), args.askOrderIdToCancel);
1852
+ let keys = [
1853
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1854
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
1855
+ { address: yield this.findClientPrimaryAccount(), role: kit_1.AccountRole.WRITABLE },
1856
+ { address: yield this.findClientCommunityAccount(), role: kit_1.AccountRole.WRITABLE },
1857
+ ...yield this.getSpotContext(instr.header),
1858
+ ...yield this.getSpotCandles(instr.header),
1859
+ {
1860
+ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY),
1861
+ role: instr.header.assetTokenId == 0 ? kit_1.AccountRole.WRITABLE : kit_1.AccountRole.READONLY
1862
+ },
1863
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1864
+ ];
1865
+ if (this.refClientPrimaryAccount != null && this.refClientPrimaryAccount != undefined) {
1866
+ keys.push({ address: this.refClientPrimaryAccount, role: kit_1.AccountRole.WRITABLE });
1867
+ keys.push({ address: this.refClientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
1868
+ }
1869
+ return {
1870
+ accounts: keys, programAddress: this.programId, data: buf
1871
+ };
1872
+ });
1873
+ }
1874
+ /**
1875
+ * Build instruction to cancel spot order in particular instrument
1876
+ * @param args Order data
1877
+ * @returns Transaction instruction
1878
+ */
1879
+ spotOrderCancelInstruction(args) {
1880
+ return __awaiter(this, void 0, void 0, function* () {
1881
+ if (!(yield this.checkClient())) {
1882
+ throw new Error("Client account not found");
1883
+ }
1884
+ let instr = this.instruments.get(args.instrId);
1885
+ const drvs = instr.header.assetTokenId == 0;
1886
+ let keys = [
1887
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1888
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
1889
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
1890
+ ...yield this.getSpotContext(instr.header),
1891
+ {
1892
+ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY),
1893
+ role: drvs ? kit_1.AccountRole.WRITABLE : kit_1.AccountRole.READONLY
1894
+ },
1895
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1896
+ ];
1897
+ if (drvs) {
1898
+ keys.push({ address: yield this.findClientCommunityAccount(), role: kit_1.AccountRole.WRITABLE });
1899
+ }
1900
+ return {
1901
+ accounts: keys,
1902
+ programAddress: this.programId,
1903
+ data: (0, instruction_models_1.spotOrderCancelData)(13, args.side, args.instrId, args.orderId),
1904
+ };
1905
+ });
1906
+ }
1907
+ /**
1908
+ * Build instruction for spot mass cancel in particular instrument
1909
+ * @param args Order data
1910
+ * @returns Transaction instruction
1911
+ */
1912
+ spotMassCancelInstruction(args) {
1913
+ return __awaiter(this, void 0, void 0, function* () {
1914
+ if (!(yield this.checkClient())) {
1915
+ throw new Error("Client account not found");
1916
+ }
1917
+ const instr = this.instruments.get(args.instrId);
1918
+ const drvs = instr.header.assetTokenId == 0;
1919
+ let keys = [
1920
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1921
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
1922
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
1923
+ ...yield this.getSpotContext(instr.header),
1924
+ {
1925
+ address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY),
1926
+ role: drvs ? kit_1.AccountRole.WRITABLE : kit_1.AccountRole.READONLY
1927
+ },
1928
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1929
+ ];
1930
+ if (drvs) {
1931
+ keys.push({ address: yield this.findClientCommunityAccount(), role: kit_1.AccountRole.WRITABLE });
1932
+ }
1933
+ return {
1934
+ accounts: keys,
1935
+ programAddress: this.programId,
1936
+ data: (0, instruction_models_1.spotMassCancelData)(15, args.instrId),
1937
+ };
1938
+ });
1939
+ }
1940
+ /**
1941
+ * Build upgrade to PERP instructions
1942
+ * @param args Order data
1943
+ * @returns Transaction instruction
1944
+ */
1945
+ upgradeToPerpInstructions(args) {
1946
+ return __awaiter(this, void 0, void 0, function* () {
1947
+ if (this.signer == null) {
1948
+ throw new Error("Wallet is not connected");
1949
+ }
1950
+ let instr = this.instruments.get(args.instrId);
1951
+ if (instr == null) {
1952
+ throw new Error("Invalid Instr ID");
1953
+ }
1954
+ yield this.updateInstrData({
1955
+ assetTokenId: instr.header.assetTokenId,
1956
+ crncyTokenId: instr.header.crncyTokenId
1957
+ });
1958
+ instr = this.instruments.get(args.instrId);
1959
+ if ((instr.header.mask & types_1.InstrMask.READY_TO_PERP_UPGRADE) == 0) {
1960
+ throw new Error("Impossible to upgrade");
1961
+ }
1962
+ if ((instr.header.mask & types_1.InstrMask.PERP) != 0) {
1963
+ throw new Error("Instr already upgraded");
1964
+ }
1965
+ const perpMapsAccountSeed = this.version.toString() + "_" +
1966
+ types_1.AccountType.PERP_MAPS.toString() + "_" +
1967
+ instr.header.assetTokenId.toString() + "_" +
1968
+ instr.header.crncyTokenId.toString();
1969
+ const perpMapsAccount = yield (0, kit_1.createAddressWithSeed)({
1970
+ baseAddress: this.signer,
1971
+ programAddress: this.programId,
1972
+ seed: perpMapsAccountSeed
1973
+ });
1974
+ const perpMapsAccountSize = 175336;
1975
+ const perpMapsAccountLamports = yield this.rpc.getMinimumBalanceForRentExemption(BigInt(perpMapsAccountSize)).send();
1976
+ const signer = (0, kit_1.createNoopSigner)(this.signer);
1977
+ const createMapsAccountIx = (0, system_1.getCreateAccountWithSeedInstruction)({
1978
+ payer: signer,
1979
+ baseAccount: signer,
1980
+ base: this.signer,
1981
+ newAccount: perpMapsAccount,
1982
+ seed: perpMapsAccountSeed,
1983
+ space: perpMapsAccountSize,
1984
+ programAddress: this.programId,
1985
+ amount: perpMapsAccountLamports,
1986
+ });
1987
+ let keys = [
1988
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
1989
+ { address: this.rootAccount, role: kit_1.AccountRole.WRITABLE },
1990
+ {
1991
+ address: yield this.getInstrAccountByTag({
1992
+ assetTokenId: instr.header.assetTokenId,
1993
+ crncyTokenId: instr.header.crncyTokenId,
1994
+ tag: types_1.AccountType.INSTR
1995
+ }), role: kit_1.AccountRole.WRITABLE
1996
+ },
1997
+ { address: instr.header.lutAddress, role: kit_1.AccountRole.WRITABLE },
1998
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
1999
+ { address: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2000
+ { address: this.drvsAuthority, role: kit_1.AccountRole.READONLY },
2001
+ {
2002
+ address: yield this.getInstrAccountByTag({
2003
+ assetTokenId: instr.header.assetTokenId,
2004
+ crncyTokenId: instr.header.crncyTokenId,
2005
+ tag: types_1.AccountType.PERP_BIDS_TREE
2006
+ }), role: kit_1.AccountRole.WRITABLE
2007
+ },
2008
+ {
2009
+ address: yield this.getInstrAccountByTag({
2010
+ assetTokenId: instr.header.assetTokenId,
2011
+ crncyTokenId: instr.header.crncyTokenId,
2012
+ tag: types_1.AccountType.PERP_ASKS_TREE
2013
+ }), role: kit_1.AccountRole.WRITABLE
2014
+ },
2015
+ {
2016
+ address: yield this.getInstrAccountByTag({
2017
+ assetTokenId: instr.header.assetTokenId,
2018
+ crncyTokenId: instr.header.crncyTokenId,
2019
+ tag: types_1.AccountType.PERP_BID_ORDERS
2020
+ }), role: kit_1.AccountRole.WRITABLE
2021
+ },
2022
+ {
2023
+ address: yield this.getInstrAccountByTag({
2024
+ assetTokenId: instr.header.assetTokenId,
2025
+ crncyTokenId: instr.header.crncyTokenId,
2026
+ tag: types_1.AccountType.PERP_ASK_ORDERS
2027
+ }), role: kit_1.AccountRole.WRITABLE
2028
+ },
2029
+ {
2030
+ address: yield this.getInstrAccountByTag({
2031
+ assetTokenId: instr.header.assetTokenId,
2032
+ crncyTokenId: instr.header.crncyTokenId,
2033
+ tag: types_1.AccountType.PERP_LINES
2034
+ }), role: kit_1.AccountRole.WRITABLE
2035
+ },
2036
+ {
2037
+ address: perpMapsAccount, role: kit_1.AccountRole.WRITABLE
2038
+ },
2039
+ {
2040
+ address: yield this.getInstrAccountByTag({
2041
+ assetTokenId: instr.header.assetTokenId,
2042
+ crncyTokenId: instr.header.crncyTokenId,
2043
+ tag: types_1.AccountType.PERP_CLIENT_INFOS
2044
+ }), role: kit_1.AccountRole.WRITABLE
2045
+ },
2046
+ {
2047
+ address: yield this.getInstrAccountByTag({
2048
+ assetTokenId: instr.header.assetTokenId,
2049
+ crncyTokenId: instr.header.crncyTokenId,
2050
+ tag: types_1.AccountType.PERP_CLIENT_INFOS2
2051
+ }), role: kit_1.AccountRole.WRITABLE
2052
+ },
2053
+ {
2054
+ address: yield this.getInstrAccountByTag({
2055
+ assetTokenId: instr.header.assetTokenId,
2056
+ crncyTokenId: instr.header.crncyTokenId,
2057
+ tag: types_1.AccountType.PERP_CLIENT_INFOS3
2058
+ }), role: kit_1.AccountRole.WRITABLE
2059
+ },
2060
+ {
2061
+ address: yield this.getInstrAccountByTag({
2062
+ assetTokenId: instr.header.assetTokenId,
2063
+ crncyTokenId: instr.header.crncyTokenId,
2064
+ tag: types_1.AccountType.PERP_CLIENT_INFOS4
2065
+ }), role: kit_1.AccountRole.WRITABLE
2066
+ },
2067
+ {
2068
+ address: yield this.getInstrAccountByTag({
2069
+ assetTokenId: instr.header.assetTokenId,
2070
+ crncyTokenId: instr.header.crncyTokenId,
2071
+ tag: types_1.AccountType.PERP_CLIENT_INFOS5
2072
+ }), role: kit_1.AccountRole.WRITABLE
2073
+ },
2074
+ {
2075
+ address: yield this.getInstrAccountByTag({
2076
+ assetTokenId: instr.header.assetTokenId,
2077
+ crncyTokenId: instr.header.crncyTokenId,
2078
+ tag: types_1.AccountType.PERP_CLIENT_ACCOUNTS
2079
+ }), role: kit_1.AccountRole.WRITABLE
2080
+ },
2081
+ {
2082
+ address: yield this.getInstrAccountByTag({
2083
+ assetTokenId: instr.header.assetTokenId,
2084
+ crncyTokenId: instr.header.crncyTokenId,
2085
+ tag: types_1.AccountType.PERP_LONG_PX_TREE
2086
+ }), role: kit_1.AccountRole.WRITABLE
2087
+ },
2088
+ {
2089
+ address: yield this.getInstrAccountByTag({
2090
+ assetTokenId: instr.header.assetTokenId,
2091
+ crncyTokenId: instr.header.crncyTokenId,
2092
+ tag: types_1.AccountType.PERP_SHORT_PX_TREE
2093
+ }), role: kit_1.AccountRole.WRITABLE
2094
+ },
2095
+ {
2096
+ address: yield this.getInstrAccountByTag({
2097
+ assetTokenId: instr.header.assetTokenId,
2098
+ crncyTokenId: instr.header.crncyTokenId,
2099
+ tag: types_1.AccountType.PERP_REBALANCE_TIME_TREE
2100
+ }), role: kit_1.AccountRole.WRITABLE
2101
+ },
2102
+ {
2103
+ address: yield this.getInstrAccountByTag({
2104
+ assetTokenId: instr.header.assetTokenId,
2105
+ crncyTokenId: instr.header.crncyTokenId,
2106
+ tag: types_1.AccountType.PERP_PRIORITY_TREE
2107
+ }), role: kit_1.AccountRole.WRITABLE
2108
+ },
2109
+ ];
2110
+ const upgradeIx = {
2111
+ accounts: keys,
2112
+ programAddress: this.programId,
2113
+ data: (0, instruction_models_1.upgradeToPerpData)(10, args.instrId)
2114
+ };
2115
+ return [createMapsAccountIx, upgradeIx];
2116
+ });
2117
+ }
2118
+ /**
2119
+ * Build instruction for perp deposit in particular instrument
2120
+ * @param args Order data
2121
+ * @returns Transaction instruction
2122
+ */
2123
+ perpDepositInstruction(args) {
2124
+ return __awaiter(this, void 0, void 0, function* () {
2125
+ if (!(yield this.checkClient())) {
2126
+ throw new Error("Client account not found");
2127
+ }
2128
+ const instr = this.instruments.get(args.instrId);
2129
+ let keys = [
2130
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2131
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2132
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2133
+ ...yield this.getPerpContext(instr.header),
2134
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2135
+ ];
2136
+ return {
2137
+ accounts: keys,
2138
+ programAddress: this.programId,
2139
+ data: (0, instruction_models_1.perpDepositData)(11, args.instrId, args.amount * this.tokenDec(instr.header.crncyTokenId)),
2140
+ };
2141
+ });
2142
+ }
2143
+ /**
2144
+ * Build instruction for new perp order in particular instrument
2145
+ * @param args Order data
2146
+ * @returns Transaction instruction
2147
+ */
2148
+ newPerpOrderInstruction(args) {
2149
+ return __awaiter(this, void 0, void 0, function* () {
2150
+ if (!(yield this.checkClient())) {
2151
+ throw new Error("Client account not found");
2152
+ }
2153
+ const instr = this.instruments.get(args.instrId);
2154
+ let keys = [
2155
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2156
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2157
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2158
+ { address: this.clientCommunityAccount, role: kit_1.AccountRole.WRITABLE },
2159
+ ...yield this.getPerpContext(instr.header),
2160
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2161
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2162
+ ];
2163
+ if (this.refClientPrimaryAccount != null && this.refClientPrimaryAccount != undefined) {
2164
+ keys.push({ address: this.refClientPrimaryAccount, role: kit_1.AccountRole.WRITABLE });
2165
+ keys.push({ address: this.refClientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
2166
+ }
2167
+ return {
2168
+ accounts: keys,
2169
+ programAddress: this.programId,
2170
+ data: (0, instruction_models_1.newPerpOrderData)(19, args.ioc == null || args.ioc == undefined ? 0 : args.ioc, args.leverage == null || args.leverage == undefined ? 0 : args.leverage, args.orderType == null || args.orderType == undefined ? 0 : args.orderType, args.side, args.instrId, args.price * dec, args.qty * this.tokenDec(instr.header.assetTokenId)),
2171
+ };
2172
+ });
2173
+ }
2174
+ /**
2175
+ * Build instruction for perp quotes replace in particular instrument
2176
+ * @param args Order data
2177
+ * @returns Transaction instruction
2178
+ */
2179
+ perpQuotesReplaceInstruction(args) {
2180
+ return __awaiter(this, void 0, void 0, function* () {
2181
+ if (!(yield this.checkClient())) {
2182
+ throw new Error("Client account not found");
2183
+ }
2184
+ const instr = this.instruments.get(args.instrId);
2185
+ let assetTokenDecFactor = this.tokenDec(instr.header.assetTokenId);
2186
+ let buf = (0, instruction_models_1.perpQuotesReplaceData)(42, args.instrId, Math.round(args.newBidPrice * dec), Math.round(args.newBidQty * assetTokenDecFactor), args.bidOrderIdToCancel, Math.round(args.newAskPrice * dec), Math.round(args.newAskQty * assetTokenDecFactor), args.askOrderIdToCancel);
2187
+ let keys = [
2188
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2189
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2190
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2191
+ { address: this.clientCommunityAccount, role: kit_1.AccountRole.WRITABLE },
2192
+ ...yield this.getPerpContext(instr.header),
2193
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2194
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2195
+ ];
2196
+ if (this.refClientPrimaryAccount != null && this.refClientPrimaryAccount != undefined) {
2197
+ keys.push({ address: this.refClientPrimaryAccount, role: kit_1.AccountRole.WRITABLE });
2198
+ keys.push({ address: this.refClientCommunityAccount, role: kit_1.AccountRole.WRITABLE });
2199
+ }
2200
+ return {
2201
+ accounts: keys,
2202
+ programAddress: this.programId,
2203
+ data: buf,
2204
+ };
2205
+ });
2206
+ }
2207
+ /**
2208
+ * Build instruction for perp order cancel in particular instrument
2209
+ * @param args Order data
2210
+ * @returns Transaction instruction
2211
+ */
2212
+ perpOrderCancelInstruction(args) {
2213
+ return __awaiter(this, void 0, void 0, function* () {
2214
+ if (!(yield this.checkClient())) {
2215
+ throw new Error("Client account not found");
2216
+ }
2217
+ const instr = this.instruments.get(args.instrId);
2218
+ let keys = [
2219
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2220
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2221
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2222
+ ...yield this.getPerpContext(instr.header),
2223
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2224
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2225
+ ];
2226
+ return {
2227
+ accounts: keys,
2228
+ programAddress: this.programId,
2229
+ data: (0, instruction_models_1.perpOrderCancelData)(30, args.side, args.instrId, args.orderId),
2230
+ };
2231
+ });
2232
+ }
2233
+ /**
2234
+ * Build instruction for perp mass cancel in particular instrument
2235
+ * @param args Order data
2236
+ * @returns Transaction instruction
2237
+ */
2238
+ perpMassCancelInstruction(args) {
2239
+ return __awaiter(this, void 0, void 0, function* () {
2240
+ if (!(yield this.checkClient())) {
2241
+ throw new Error("Client account not found");
2242
+ }
2243
+ const instr = this.instruments.get(args.instrId);
2244
+ let keys = [
2245
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2246
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2247
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2248
+ ...yield this.getPerpContext(instr.header),
2249
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2250
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2251
+ ];
2252
+ return {
2253
+ accounts: keys,
2254
+ programAddress: this.programId,
2255
+ data: (0, instruction_models_1.perpMassCancelData)(36, args.instrId),
2256
+ };
2257
+ });
2258
+ }
2259
+ /**
2260
+ * Build instruction for perp forced close in particular instrument
2261
+ * @param args Order data
2262
+ * @returns Transaction instruction
2263
+ */
2264
+ perpForcedCloseInstruction(args) {
2265
+ return __awaiter(this, void 0, void 0, function* () {
2266
+ if (!(yield this.checkClient())) {
2267
+ throw new Error("Client account not found");
2268
+ }
2269
+ const instr = this.instruments.get(args.instrId);
2270
+ let keys = [
2271
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2272
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2273
+ { address: args.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2274
+ ...yield this.getPerpContext(instr.header),
2275
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2276
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2277
+ ];
2278
+ return {
2279
+ accounts: keys,
2280
+ programAddress: this.programId,
2281
+ data: (0, instruction_models_1.perpForcedCloseData)(38, args.instrId),
2282
+ };
2283
+ });
2284
+ }
2285
+ /**
2286
+ * Build instruction for new referral link
2287
+ * @returns Transaction instruction
2288
+ */
2289
+ newRefLinkInstruction() {
2290
+ return __awaiter(this, void 0, void 0, function* () {
2291
+ if (!(yield this.checkClient())) {
2292
+ throw new Error("Client account not found");
2293
+ }
2294
+ let buf = Buffer.alloc(1);
2295
+ buf.writeUInt8(45, 0);
2296
+ let keys = [
2297
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2298
+ { address: this.rootAccount, role: kit_1.AccountRole.WRITABLE },
2299
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2300
+ ];
2301
+ return {
2302
+ accounts: keys,
2303
+ programAddress: this.programId,
2304
+ data: buf,
2305
+ };
2306
+ });
2307
+ }
2308
+ /**
2309
+ * Build instruction for change leverage in particular instrument
2310
+ * @param args Transaction data
2311
+ * @returns Transaction instruction
2312
+ */
2313
+ perpChangeLeverageInstruction(args) {
2314
+ return __awaiter(this, void 0, void 0, function* () {
2315
+ if (!(yield this.checkClient())) {
2316
+ throw new Error("Client account not found");
2317
+ }
2318
+ const instr = this.instruments.get(args.instrId);
2319
+ let keys = [
2320
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2321
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2322
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2323
+ ...yield this.getPerpContext(instr.header),
2324
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2325
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2326
+ ];
2327
+ return {
2328
+ accounts: keys,
2329
+ programAddress: this.programId,
2330
+ data: (0, instruction_models_1.perpChangeLeverageData)(37, args.instrId, args.leverage),
2331
+ };
2332
+ });
2333
+ }
2334
+ /**
2335
+ * Build instruction for statistics reset in particular instrument
2336
+ * @param args Transaction data
2337
+ * @returns Transaction instruction
2338
+ */
2339
+ perpStatisticsResetInstruction(args) {
2340
+ return __awaiter(this, void 0, void 0, function* () {
2341
+ if (!(yield this.checkClient())) {
2342
+ throw new Error("Client account not found");
2343
+ }
2344
+ const instr = this.instruments.get(args.instrId);
2345
+ let keys = [
2346
+ { address: this.signer, role: kit_1.AccountRole.READONLY_SIGNER },
2347
+ { address: this.rootAccount, role: kit_1.AccountRole.READONLY },
2348
+ { address: this.clientPrimaryAccount, role: kit_1.AccountRole.WRITABLE },
2349
+ ...yield this.getPerpContext(instr.header),
2350
+ { address: yield this.getAccountByTag(types_1.AccountType.COMMUNITY), role: kit_1.AccountRole.READONLY },
2351
+ { address: SYSTEM_PROGRAM_ID, role: kit_1.AccountRole.READONLY },
2352
+ ];
2353
+ return {
2354
+ accounts: keys,
2355
+ programAddress: this.programId,
2356
+ data: (0, instruction_models_1.perpStatisticsResetData)(46, args.instrId),
2357
+ };
2358
+ });
2359
+ }
2360
+ }
2361
+ exports.Engine = Engine;