@drift-labs/sdk 0.2.0-master.1 → 0.2.0-master.12

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.
Files changed (142) hide show
  1. package/lib/accounts/types.d.ts +1 -0
  2. package/lib/admin.d.ts +8 -5
  3. package/lib/admin.js +43 -11
  4. package/lib/clearingHouse.d.ts +35 -20
  5. package/lib/clearingHouse.js +497 -154
  6. package/lib/clearingHouseUser.d.ts +12 -17
  7. package/lib/clearingHouseUser.js +97 -88
  8. package/lib/config.js +1 -1
  9. package/lib/constants/banks.d.ts +2 -2
  10. package/lib/constants/banks.js +12 -4
  11. package/lib/constants/numericConstants.d.ts +4 -0
  12. package/lib/constants/numericConstants.js +5 -1
  13. package/lib/events/eventList.js +3 -0
  14. package/lib/events/types.d.ts +2 -1
  15. package/lib/factory/bigNum.d.ts +9 -2
  16. package/lib/factory/bigNum.js +50 -16
  17. package/lib/idl/clearing_house.json +858 -177
  18. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  19. package/lib/index.d.ts +4 -2
  20. package/lib/index.js +8 -2
  21. package/lib/math/amm.d.ts +6 -1
  22. package/lib/math/amm.js +124 -41
  23. package/lib/math/auction.js +4 -1
  24. package/lib/math/bankBalance.d.ts +3 -1
  25. package/lib/math/bankBalance.js +54 -1
  26. package/lib/math/margin.d.ts +11 -0
  27. package/lib/math/margin.js +72 -0
  28. package/lib/math/market.d.ts +4 -1
  29. package/lib/math/market.js +35 -1
  30. package/lib/math/orders.d.ts +2 -2
  31. package/lib/math/orders.js +18 -11
  32. package/lib/math/position.d.ts +8 -0
  33. package/lib/math/position.js +44 -12
  34. package/lib/math/repeg.js +1 -1
  35. package/lib/math/trade.d.ts +1 -1
  36. package/lib/math/trade.js +7 -10
  37. package/lib/orderParams.d.ts +14 -5
  38. package/lib/orderParams.js +8 -96
  39. package/lib/orders.d.ts +2 -4
  40. package/lib/orders.js +7 -161
  41. package/lib/slot/SlotSubscriber.d.ts +7 -0
  42. package/lib/slot/SlotSubscriber.js +3 -0
  43. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  44. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  45. package/lib/tx/retryTxSender.js +9 -2
  46. package/lib/tx/utils.js +1 -1
  47. package/lib/types.d.ts +159 -15
  48. package/lib/types.js +59 -1
  49. package/lib/util/computeUnits.js +1 -1
  50. package/lib/util/getTokenAddress.d.ts +2 -0
  51. package/lib/util/getTokenAddress.js +9 -0
  52. package/package.json +3 -3
  53. package/src/accounts/bulkAccountLoader.js +197 -0
  54. package/src/accounts/bulkUserSubscription.js +33 -0
  55. package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
  56. package/src/accounts/pollingOracleSubscriber.js +93 -0
  57. package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
  58. package/src/accounts/pollingUserAccountSubscriber.js +132 -0
  59. package/src/accounts/types.js +10 -0
  60. package/src/accounts/utils.js +7 -0
  61. package/src/accounts/webSocketAccountSubscriber.js +93 -0
  62. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
  63. package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
  64. package/src/addresses/marketAddresses.js +26 -0
  65. package/src/admin.ts +66 -14
  66. package/src/assert/assert.js +9 -0
  67. package/src/clearingHouse.ts +836 -254
  68. package/src/clearingHouseConfig.js +2 -0
  69. package/src/clearingHouseUser.ts +219 -121
  70. package/src/clearingHouseUserConfig.js +2 -0
  71. package/src/config.ts +1 -1
  72. package/src/constants/banks.js +42 -0
  73. package/src/constants/banks.ts +14 -4
  74. package/src/constants/markets.js +42 -0
  75. package/src/constants/numericConstants.js +41 -0
  76. package/src/constants/numericConstants.ts +5 -0
  77. package/src/events/eventList.js +77 -0
  78. package/src/events/eventList.ts +3 -0
  79. package/src/events/eventSubscriber.js +139 -0
  80. package/src/events/fetchLogs.js +50 -0
  81. package/src/events/pollingLogProvider.js +64 -0
  82. package/src/events/sort.js +44 -0
  83. package/src/events/txEventCache.js +71 -0
  84. package/src/events/types.js +20 -0
  85. package/src/events/types.ts +2 -0
  86. package/src/events/webSocketLogProvider.js +41 -0
  87. package/src/examples/makeTradeExample.js +80 -0
  88. package/src/factory/bigNum.js +390 -0
  89. package/src/factory/bigNum.ts +65 -18
  90. package/src/factory/oracleClient.js +20 -0
  91. package/src/idl/clearing_house.json +858 -177
  92. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  93. package/src/index.js +69 -0
  94. package/src/index.ts +4 -2
  95. package/src/math/amm.js +369 -0
  96. package/src/math/amm.ts +207 -52
  97. package/src/math/auction.js +42 -0
  98. package/src/math/auction.ts +5 -1
  99. package/src/math/bankBalance.ts +98 -1
  100. package/src/math/conversion.js +11 -0
  101. package/src/math/funding.js +248 -0
  102. package/src/math/margin.ts +124 -0
  103. package/src/math/market.ts +66 -1
  104. package/src/math/oracles.js +26 -0
  105. package/src/math/orders.ts +17 -13
  106. package/src/math/position.ts +63 -9
  107. package/src/math/repeg.js +128 -0
  108. package/src/math/repeg.ts +2 -1
  109. package/src/math/state.js +15 -0
  110. package/src/math/trade.js +253 -0
  111. package/src/math/trade.ts +23 -25
  112. package/src/math/utils.js +0 -1
  113. package/src/mockUSDCFaucet.js +280 -0
  114. package/src/oracles/oracleClientCache.js +19 -0
  115. package/src/oracles/pythClient.js +46 -0
  116. package/src/oracles/quoteAssetOracleClient.js +32 -0
  117. package/src/oracles/switchboardClient.js +69 -0
  118. package/src/oracles/types.js +2 -0
  119. package/src/orderParams.js +20 -0
  120. package/src/orderParams.ts +20 -141
  121. package/src/orders.ts +10 -287
  122. package/src/slot/SlotSubscriber.js +39 -0
  123. package/src/slot/SlotSubscriber.ts +11 -1
  124. package/src/token/index.js +38 -0
  125. package/src/tokenFaucet.js +189 -0
  126. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  127. package/src/tx/retryTxSender.ts +11 -3
  128. package/src/tx/types.js +2 -0
  129. package/src/tx/utils.js +17 -0
  130. package/src/tx/utils.ts +1 -1
  131. package/src/types.js +125 -0
  132. package/src/types.ts +155 -17
  133. package/src/userName.js +20 -0
  134. package/src/util/computeUnits.js +21 -11
  135. package/src/util/computeUnits.ts +1 -1
  136. package/src/util/getTokenAddress.js +9 -0
  137. package/src/util/getTokenAddress.ts +18 -0
  138. package/src/util/promiseTimeout.js +14 -0
  139. package/src/util/tps.js +27 -0
  140. package/src/wallet.js +35 -0
  141. package/tests/bn/test.ts +2 -0
  142. package/src/util/computeUnits.js.map +0 -1
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.ClearingHouse = void 0;
30
30
  const anchor_1 = require("@project-serum/anchor");
31
31
  const spl_token_1 = require("@solana/spl-token");
32
+ const types_1 = require("./types");
32
33
  const anchor = __importStar(require("@project-serum/anchor"));
33
34
  const clearing_house_json_1 = __importDefault(require("./idl/clearing_house.json"));
34
35
  const web3_js_1 = require("@solana/web3.js");
@@ -42,8 +43,8 @@ const pollingClearingHouseAccountSubscriber_1 = require("./accounts/pollingClear
42
43
  const webSocketClearingHouseAccountSubscriber_1 = require("./accounts/webSocketClearingHouseAccountSubscriber");
43
44
  const retryTxSender_1 = require("./tx/retryTxSender");
44
45
  const clearingHouseUser_1 = require("./clearingHouseUser");
45
- const orderParams_1 = require("./orderParams");
46
46
  const config_1 = require("./config");
47
+ const banks_1 = require("./constants/banks");
47
48
  /**
48
49
  * # ClearingHouse
49
50
  * This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
@@ -284,8 +285,7 @@ class ClearingHouse {
284
285
  marketAccountMap.set(marketIndexNum, {
285
286
  pubkey: marketAccount.pubkey,
286
287
  isSigner: false,
287
- // isWritable: false, // TODO
288
- isWritable: true,
288
+ isWritable: false,
289
289
  });
290
290
  oracleAccountMap.set(marketAccount.pubkey.toString(), {
291
291
  pubkey: marketAccount.amm.oracle,
@@ -294,6 +294,19 @@ class ClearingHouse {
294
294
  });
295
295
  }
296
296
  }
297
+ if (params.readableMarketIndex) {
298
+ const marketAccount = this.getMarketAccount(params.readableMarketIndex.toNumber());
299
+ marketAccountMap.set(params.readableMarketIndex.toNumber(), {
300
+ pubkey: marketAccount.pubkey,
301
+ isSigner: false,
302
+ isWritable: true,
303
+ });
304
+ oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
305
+ pubkey: marketAccount.amm.oracle,
306
+ isSigner: false,
307
+ isWritable: false,
308
+ });
309
+ }
297
310
  if (params.writableMarketIndex) {
298
311
  const marketAccount = this.getMarketAccount(params.writableMarketIndex.toNumber());
299
312
  marketAccountMap.set(params.writableMarketIndex.toNumber(), {
@@ -355,9 +368,27 @@ class ClearingHouse {
355
368
  return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.find((order) => order.userOrderId === userOrderId);
356
369
  }
357
370
  async deposit(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly = false) {
371
+ const tx = new web3_js_1.Transaction();
372
+ const additionalSigners = [];
373
+ const bank = this.getBankAccount(bankIndex);
374
+ const isSolBank = bank.mint.equals(banks_1.WRAPPED_SOL_MINT);
375
+ const authority = this.wallet.publicKey;
376
+ const createWSOLTokenAccount = isSolBank && collateralAccountPublicKey.equals(authority);
377
+ if (createWSOLTokenAccount) {
378
+ const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount);
379
+ collateralAccountPublicKey = pubkey;
380
+ ixs.forEach((ix) => {
381
+ tx.add(ix);
382
+ });
383
+ signers.forEach((signer) => additionalSigners.push(signer));
384
+ }
358
385
  const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly, true);
359
- const tx = new web3_js_1.Transaction().add(depositCollateralIx);
360
- const { txSig } = await this.txSender.send(tx);
386
+ tx.add(depositCollateralIx);
387
+ // Close the wrapped sol account at the end of the transaction
388
+ if (createWSOLTokenAccount) {
389
+ tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, collateralAccountPublicKey, authority, authority, []));
390
+ }
391
+ const { txSig } = await this.txSender.send(tx, additionalSigners, this.opts);
361
392
  return txSig;
362
393
  }
363
394
  async getDepositInstruction(amount, bankIndex, userTokenAccount, userId, reduceOnly = false, userInitialized = true) {
@@ -371,13 +402,19 @@ class ClearingHouse {
371
402
  });
372
403
  }
373
404
  else {
374
- remainingAccounts = [
375
- {
376
- pubkey: this.getBankAccount(bankIndex).pubkey,
405
+ const bankAccount = this.getBankAccount(bankIndex);
406
+ if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
407
+ remainingAccounts.push({
408
+ pubkey: bankAccount.oracle,
377
409
  isSigner: false,
378
- isWritable: true,
379
- },
380
- ];
410
+ isWritable: false,
411
+ });
412
+ }
413
+ remainingAccounts.push({
414
+ pubkey: bankAccount.pubkey,
415
+ isSigner: false,
416
+ isWritable: true,
417
+ });
381
418
  }
382
419
  const bank = this.getBankAccount(bankIndex);
383
420
  return await this.program.instruction.deposit(bankIndex, amount, reduceOnly, {
@@ -393,30 +430,99 @@ class ClearingHouse {
393
430
  remainingAccounts,
394
431
  });
395
432
  }
433
+ async checkIfAccountExists(account) {
434
+ try {
435
+ const accountInfo = await this.connection.getAccountInfo(account);
436
+ return accountInfo && true;
437
+ }
438
+ catch (e) {
439
+ // Doesn't already exist
440
+ return false;
441
+ }
442
+ }
443
+ async getSolWithdrawalIxs(bankIndex, amount) {
444
+ const result = {
445
+ ixs: [],
446
+ signers: [],
447
+ pubkey: web3_js_1.PublicKey.default,
448
+ };
449
+ // Create a temporary wrapped SOL account to store the SOL that we're withdrawing
450
+ const authority = this.wallet.publicKey;
451
+ const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount);
452
+ result.pubkey = pubkey;
453
+ ixs.forEach((ix) => {
454
+ result.ixs.push(ix);
455
+ });
456
+ signers.forEach((ix) => {
457
+ result.signers.push(ix);
458
+ });
459
+ const withdrawIx = await this.getWithdrawIx(amount, bankIndex, pubkey, true);
460
+ result.ixs.push(withdrawIx);
461
+ result.ixs.push(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, pubkey, authority, authority, []));
462
+ return result;
463
+ }
464
+ async getWrappedSolAccountCreationIxs(amount) {
465
+ const wrappedSolAccount = new web3_js_1.Keypair();
466
+ const result = {
467
+ ixs: [],
468
+ signers: [],
469
+ pubkey: wrappedSolAccount.publicKey,
470
+ };
471
+ const rentSpaceLamports = new anchor_1.BN(web3_js_1.LAMPORTS_PER_SOL / 100);
472
+ const depositAmountLamports = amount.add(rentSpaceLamports);
473
+ const authority = this.wallet.publicKey;
474
+ result.ixs.push(web3_js_1.SystemProgram.createAccount({
475
+ fromPubkey: authority,
476
+ newAccountPubkey: wrappedSolAccount.publicKey,
477
+ lamports: depositAmountLamports.toNumber(),
478
+ space: 165,
479
+ programId: spl_token_1.TOKEN_PROGRAM_ID,
480
+ }));
481
+ result.ixs.push(spl_token_1.Token.createInitAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, banks_1.WRAPPED_SOL_MINT, wrappedSolAccount.publicKey, authority));
482
+ result.signers.push(wrappedSolAccount);
483
+ return result;
484
+ }
396
485
  /**
397
486
  * Creates the Clearing House User account for a user, and deposits some initial collateral
398
- * @param userId
399
- * @param name
400
487
  * @param amount
401
488
  * @param userTokenAccount
489
+ * @param bankIndex
490
+ * @param userId
491
+ * @param name
402
492
  * @param fromUserId
403
493
  * @returns
404
494
  */
405
495
  async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, bankIndex = new anchor_1.BN(0), userId = 0, name = userName_1.DEFAULT_USER_NAME, fromUserId) {
406
496
  const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
497
+ const additionalSigners = [];
498
+ const bank = this.getBankAccount(bankIndex);
499
+ const isSolBank = bank.mint.equals(banks_1.WRAPPED_SOL_MINT);
500
+ const tx = new web3_js_1.Transaction();
501
+ const authority = this.wallet.publicKey;
502
+ const createWSOLTokenAccount = isSolBank && userTokenAccount.equals(authority);
503
+ if (createWSOLTokenAccount) {
504
+ const { ixs: startIxs, signers, pubkey, } = await this.getWrappedSolAccountCreationIxs(amount);
505
+ userTokenAccount = pubkey;
506
+ startIxs.forEach((ix) => {
507
+ tx.add(ix);
508
+ });
509
+ signers.forEach((signer) => additionalSigners.push(signer));
510
+ }
407
511
  const depositCollateralIx = fromUserId != null
408
512
  ? await this.getTransferDepositIx(amount, bankIndex, fromUserId, userId)
409
513
  : await this.getDepositInstruction(amount, bankIndex, userTokenAccount, userId, false, false);
410
- const tx = new web3_js_1.Transaction()
411
- .add(initializeUserAccountIx)
412
- .add(depositCollateralIx);
413
- const { txSig } = await this.txSender.send(tx, []);
514
+ tx.add(initializeUserAccountIx).add(depositCollateralIx);
515
+ // Close the wrapped sol account at the end of the transaction
516
+ if (createWSOLTokenAccount) {
517
+ tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, userTokenAccount, authority, authority, []));
518
+ }
519
+ const { txSig } = await this.txSender.send(tx, additionalSigners, this.opts);
414
520
  return [txSig, userAccountPublicKey];
415
521
  }
416
- async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME, mockUSDCFaucet, amount) {
417
- const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await mockUSDCFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
522
+ async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME, bankIndex, tokenFaucet, amount) {
523
+ const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
418
524
  const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
419
- const depositCollateralIx = await this.getDepositInstruction(amount, new anchor_1.BN(0), associateTokenPublicKey, userId, false, false);
525
+ const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, associateTokenPublicKey, userId, false, false);
420
526
  const tx = new web3_js_1.Transaction()
421
527
  .add(createAssociatedAccountIx)
422
528
  .add(mintToIx)
@@ -426,7 +532,27 @@ class ClearingHouse {
426
532
  return [txSig, userAccountPublicKey];
427
533
  }
428
534
  async withdraw(amount, bankIndex, userTokenAccount, reduceOnly = false) {
429
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly)), [], this.opts);
535
+ const tx = new web3_js_1.Transaction();
536
+ const additionalSigners = [];
537
+ const bank = this.getBankAccount(bankIndex);
538
+ const isSolBank = bank.mint.equals(banks_1.WRAPPED_SOL_MINT);
539
+ const authority = this.wallet.publicKey;
540
+ const createWSOLTokenAccount = isSolBank && userTokenAccount.equals(authority);
541
+ if (createWSOLTokenAccount) {
542
+ const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount);
543
+ userTokenAccount = pubkey;
544
+ ixs.forEach((ix) => {
545
+ tx.add(ix);
546
+ });
547
+ signers.forEach((signer) => additionalSigners.push(signer));
548
+ }
549
+ const withdrawCollateral = await this.getWithdrawIx(amount, bank.bankIndex, userTokenAccount, reduceOnly);
550
+ tx.add(withdrawCollateral);
551
+ // Close the wrapped sol account at the end of the transaction
552
+ if (createWSOLTokenAccount) {
553
+ tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, userTokenAccount, authority, authority, []));
554
+ }
555
+ const { txSig } = await this.txSender.send(tx, additionalSigners, this.opts);
430
556
  return txSig;
431
557
  }
432
558
  async getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly = false) {
@@ -482,45 +608,37 @@ class ClearingHouse {
482
608
  });
483
609
  }
484
610
  async openPosition(direction, amount, marketIndex, limitPrice) {
485
- return await this.placeAndTake((0, orderParams_1.getMarketOrderParams)(marketIndex, direction, numericConstants_1.ZERO, amount, false, limitPrice));
611
+ return await this.placeAndTake({
612
+ orderType: types_1.OrderType.MARKET,
613
+ marketIndex,
614
+ direction,
615
+ baseAssetAmount: amount,
616
+ price: limitPrice,
617
+ });
486
618
  }
487
619
  async placeOrder(orderParams) {
488
620
  const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceOrderIx(orderParams)), [], this.opts);
489
621
  this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
490
622
  return txSig;
491
623
  }
624
+ getOrderParams(optionalOrderParams) {
625
+ return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams);
626
+ }
492
627
  async getPlaceOrderIx(orderParams) {
628
+ orderParams = this.getOrderParams(orderParams);
493
629
  const userAccountPublicKey = await this.getUserAccountPublicKey();
494
- const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
495
- .oracle;
496
630
  const remainingAccounts = this.getRemainingAccounts({
497
- writableMarketIndex: orderParams.marketIndex,
631
+ readableMarketIndex: orderParams.marketIndex,
498
632
  });
499
633
  return await this.program.instruction.placeOrder(orderParams, {
500
634
  accounts: {
501
635
  state: await this.getStatePublicKey(),
502
636
  user: userAccountPublicKey,
503
637
  authority: this.wallet.publicKey,
504
- oracle: priceOracle,
505
638
  },
506
639
  remainingAccounts,
507
640
  });
508
641
  }
509
- async expireOrders(userAccountPublicKey) {
510
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getExpireOrdersIx(userAccountPublicKey)), [], this.opts);
511
- return txSig;
512
- }
513
- async getExpireOrdersIx(userAccountPublicKey) {
514
- const fillerPublicKey = await this.getUserAccountPublicKey();
515
- return await this.program.instruction.expireOrders({
516
- accounts: {
517
- state: await this.getStatePublicKey(),
518
- filler: fillerPublicKey,
519
- user: userAccountPublicKey,
520
- authority: this.wallet.publicKey,
521
- },
522
- });
523
- }
524
642
  async updateAMMs(marketIndexes) {
525
643
  const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateAMMsIx(marketIndexes)), [], this.opts);
526
644
  return txSig;
@@ -561,15 +679,12 @@ class ClearingHouse {
561
679
  }
562
680
  async getCancelOrderIx(orderId) {
563
681
  const userAccountPublicKey = await this.getUserAccountPublicKey();
564
- const order = this.getOrder(orderId);
565
- const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
566
682
  const remainingAccounts = this.getRemainingAccounts({});
567
- return await this.program.instruction.cancelOrder(orderId, {
683
+ return await this.program.instruction.cancelOrder(orderId !== null && orderId !== void 0 ? orderId : null, {
568
684
  accounts: {
569
685
  state: await this.getStatePublicKey(),
570
686
  user: userAccountPublicKey,
571
687
  authority: this.wallet.publicKey,
572
- oracle,
573
688
  },
574
689
  remainingAccounts,
575
690
  });
@@ -593,117 +708,150 @@ class ClearingHouse {
593
708
  remainingAccounts,
594
709
  });
595
710
  }
596
- async cancelAllOrders(bestEffort) {
597
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelAllOrdersIx(bestEffort)), [], this.opts);
711
+ async fillOrder(userAccountPublicKey, user, order, makerInfo) {
712
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getFillOrderIx(userAccountPublicKey, user, order, makerInfo)), [], this.opts);
598
713
  return txSig;
599
714
  }
600
- async getCancelAllOrdersIx(bestEffort) {
601
- const userAccountPublicKey = await this.getUserAccountPublicKey();
602
- const remainingAccounts = this.getRemainingAccounts({});
603
- for (const order of this.getUserAccount().orders) {
604
- const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
605
- remainingAccounts.push({
606
- pubkey: oracle,
607
- isWritable: false,
608
- isSigner: false,
609
- });
715
+ async getFillOrderIx(userAccountPublicKey, userAccount, order, makerInfo) {
716
+ const fillerPublicKey = await this.getUserAccountPublicKey();
717
+ const marketIndex = order.marketIndex;
718
+ const marketAccount = this.getMarketAccount(marketIndex);
719
+ const oracleAccountMap = new Map();
720
+ const bankAccountMap = new Map();
721
+ const marketAccountMap = new Map();
722
+ for (const bankBalance of userAccount.bankBalances) {
723
+ if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
724
+ const bankAccount = this.getBankAccount(bankBalance.bankIndex);
725
+ bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
726
+ pubkey: bankAccount.pubkey,
727
+ isSigner: false,
728
+ isWritable: false,
729
+ });
730
+ if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
731
+ oracleAccountMap.set(bankAccount.oracle.toString(), {
732
+ pubkey: bankAccount.oracle,
733
+ isSigner: false,
734
+ isWritable: false,
735
+ });
736
+ }
737
+ }
610
738
  }
611
- return await this.program.instruction.cancelAllOrders(bestEffort, {
612
- accounts: {
613
- state: await this.getStatePublicKey(),
614
- user: userAccountPublicKey,
615
- authority: this.wallet.publicKey,
616
- },
617
- remainingAccounts,
739
+ for (const position of userAccount.positions) {
740
+ if (!(0, position_1.positionIsAvailable)(position) &&
741
+ !position.marketIndex.eq(order.marketIndex)) {
742
+ const market = this.getMarketAccount(position.marketIndex);
743
+ marketAccountMap.set(position.marketIndex.toNumber(), {
744
+ pubkey: market.pubkey,
745
+ isWritable: false,
746
+ isSigner: false,
747
+ });
748
+ oracleAccountMap.set(market.amm.oracle.toString(), {
749
+ pubkey: market.amm.oracle,
750
+ isWritable: false,
751
+ isSigner: false,
752
+ });
753
+ }
754
+ }
755
+ marketAccountMap.set(marketIndex.toNumber(), {
756
+ pubkey: marketAccount.pubkey,
757
+ isWritable: true,
758
+ isSigner: false,
618
759
  });
619
- }
620
- async cancelOrdersByMarketAndSide(bestEffort, marketIndexOnly, directionOnly) {
621
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelOrdersByMarketAndSideIx(bestEffort, marketIndexOnly, directionOnly)), [], this.opts);
622
- return txSig;
623
- }
624
- async getCancelOrdersByMarketAndSideIx(bestEffort, marketIndexOnly, directionOnly) {
625
- const userAccountPublicKey = await this.getUserAccountPublicKey();
626
- const remainingAccounts = this.getRemainingAccounts({});
627
- for (const order of this.getUserAccount().orders) {
628
- const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
760
+ oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
761
+ pubkey: marketAccount.amm.oracle,
762
+ isWritable: false,
763
+ isSigner: false,
764
+ });
765
+ const remainingAccounts = [
766
+ ...oracleAccountMap.values(),
767
+ ...bankAccountMap.values(),
768
+ ...marketAccountMap.values(),
769
+ ];
770
+ if (makerInfo) {
629
771
  remainingAccounts.push({
630
- pubkey: oracle,
631
- isWritable: false,
772
+ pubkey: makerInfo.maker,
773
+ isWritable: true,
632
774
  isSigner: false,
633
775
  });
634
776
  }
635
- return await this.program.instruction.cancelOrdersByMarketAndSide(bestEffort, marketIndexOnly, directionOnly, {
777
+ const orderId = order.orderId;
778
+ const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
779
+ return await this.program.instruction.fillOrder(orderId, makerOrderId, {
636
780
  accounts: {
637
781
  state: await this.getStatePublicKey(),
782
+ filler: fillerPublicKey,
638
783
  user: userAccountPublicKey,
639
784
  authority: this.wallet.publicKey,
640
785
  },
641
786
  remainingAccounts,
642
787
  });
643
788
  }
644
- async fillOrder(userAccountPublicKey, user, order, makerInfo) {
645
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getFillOrderIx(userAccountPublicKey, user, order, makerInfo)), [], this.opts);
789
+ async triggerOrder(userAccountPublicKey, user, order) {
790
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getTriggerOrderIx(userAccountPublicKey, user, order)), [], this.opts);
646
791
  return txSig;
647
792
  }
648
- async getFillOrderIx(userAccountPublicKey, userAccount, order, makerInfo) {
793
+ async getTriggerOrderIx(userAccountPublicKey, userAccount, order) {
649
794
  const fillerPublicKey = await this.getUserAccountPublicKey();
650
795
  const marketIndex = order.marketIndex;
651
796
  const marketAccount = this.getMarketAccount(marketIndex);
652
- const oracle = marketAccount.amm.oracle;
653
- const bankAccountInfos = [
654
- {
655
- pubkey: this.getQuoteAssetBankAccount().pubkey,
656
- isSigner: false,
657
- isWritable: true,
658
- },
659
- ];
660
- const marketAccountInfos = [
661
- {
662
- pubkey: marketAccount.pubkey,
663
- isWritable: true,
664
- isSigner: false,
665
- },
666
- ];
667
- const oracleAccountInfos = [
668
- {
669
- pubkey: marketAccount.amm.oracle,
670
- isWritable: false,
671
- isSigner: false,
672
- },
673
- ];
797
+ const oracleAccountMap = new Map();
798
+ const bankAccountMap = new Map();
799
+ const marketAccountMap = new Map();
800
+ for (const bankBalance of userAccount.bankBalances) {
801
+ if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
802
+ const bankAccount = this.getBankAccount(bankBalance.bankIndex);
803
+ bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
804
+ pubkey: bankAccount.pubkey,
805
+ isSigner: false,
806
+ isWritable: false,
807
+ });
808
+ if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
809
+ oracleAccountMap.set(bankAccount.oracle.toString(), {
810
+ pubkey: bankAccount.oracle,
811
+ isSigner: false,
812
+ isWritable: false,
813
+ });
814
+ }
815
+ }
816
+ }
674
817
  for (const position of userAccount.positions) {
675
818
  if (!(0, position_1.positionIsAvailable)(position) &&
676
819
  !position.marketIndex.eq(order.marketIndex)) {
677
820
  const market = this.getMarketAccount(position.marketIndex);
678
- marketAccountInfos.push({
821
+ marketAccountMap.set(position.marketIndex.toNumber(), {
679
822
  pubkey: market.pubkey,
680
823
  isWritable: false,
681
824
  isSigner: false,
682
825
  });
683
- oracleAccountInfos.push({
826
+ oracleAccountMap.set(market.amm.oracle.toString(), {
684
827
  pubkey: market.amm.oracle,
685
828
  isWritable: false,
686
829
  isSigner: false,
687
830
  });
688
831
  }
689
832
  }
690
- const remainingAccounts = oracleAccountInfos.concat(bankAccountInfos.concat(marketAccountInfos));
691
- if (makerInfo) {
692
- remainingAccounts.push({
693
- pubkey: makerInfo.maker,
694
- isWritable: true,
695
- isSigner: false,
696
- });
697
- }
833
+ marketAccountMap.set(marketIndex.toNumber(), {
834
+ pubkey: marketAccount.pubkey,
835
+ isWritable: true,
836
+ isSigner: false,
837
+ });
838
+ oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
839
+ pubkey: marketAccount.amm.oracle,
840
+ isWritable: false,
841
+ isSigner: false,
842
+ });
843
+ const remainingAccounts = [
844
+ ...oracleAccountMap.values(),
845
+ ...bankAccountMap.values(),
846
+ ...marketAccountMap.values(),
847
+ ];
698
848
  const orderId = order.orderId;
699
- const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
700
- return await this.program.instruction.fillOrder(orderId, makerOrderId, {
849
+ return await this.program.instruction.triggerOrder(orderId, {
701
850
  accounts: {
702
851
  state: await this.getStatePublicKey(),
703
852
  filler: fillerPublicKey,
704
853
  user: userAccountPublicKey,
705
854
  authority: this.wallet.publicKey,
706
- oracle: oracle,
707
855
  },
708
856
  remainingAccounts,
709
857
  });
@@ -714,9 +862,8 @@ class ClearingHouse {
714
862
  return txSig;
715
863
  }
716
864
  async getPlaceAndTakeIx(orderParams, makerInfo) {
865
+ orderParams = this.getOrderParams(orderParams);
717
866
  const userAccountPublicKey = await this.getUserAccountPublicKey();
718
- const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
719
- .oracle;
720
867
  const remainingAccounts = this.getRemainingAccounts({
721
868
  writableMarketIndex: orderParams.marketIndex,
722
869
  writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
@@ -735,7 +882,34 @@ class ClearingHouse {
735
882
  state: await this.getStatePublicKey(),
736
883
  user: userAccountPublicKey,
737
884
  authority: this.wallet.publicKey,
738
- oracle: priceOracle,
885
+ },
886
+ remainingAccounts,
887
+ });
888
+ }
889
+ async placeAndMake(orderParams, takerInfo) {
890
+ const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceAndMakeIx(orderParams, takerInfo)), [], this.opts);
891
+ this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
892
+ return txSig;
893
+ }
894
+ async getPlaceAndMakeIx(orderParams, takerInfo) {
895
+ orderParams = this.getOrderParams(orderParams);
896
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
897
+ const remainingAccounts = this.getRemainingAccounts({
898
+ writableMarketIndex: orderParams.marketIndex,
899
+ writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
900
+ });
901
+ const takerOrderId = takerInfo.order.orderId;
902
+ remainingAccounts.push({
903
+ pubkey: takerInfo.taker,
904
+ isSigner: false,
905
+ isWritable: true,
906
+ });
907
+ return await this.program.instruction.placeAndMake(orderParams, takerOrderId, {
908
+ accounts: {
909
+ state: await this.getStatePublicKey(),
910
+ user: userAccountPublicKey,
911
+ taker: takerInfo.taker,
912
+ authority: this.wallet.publicKey,
739
913
  },
740
914
  remainingAccounts,
741
915
  });
@@ -750,7 +924,13 @@ class ClearingHouse {
750
924
  if (!userPosition) {
751
925
  throw Error(`No position in market ${marketIndex.toString()}`);
752
926
  }
753
- return await this.placeAndTake((0, orderParams_1.getMarketOrderParams)(marketIndex, (0, position_1.findDirectionToClose)(userPosition), numericConstants_1.ZERO, userPosition.baseAssetAmount, true, undefined));
927
+ return await this.placeAndTake({
928
+ orderType: types_1.OrderType.MARKET,
929
+ marketIndex,
930
+ direction: (0, position_1.findDirectionToClose)(userPosition),
931
+ baseAssetAmount: userPosition.baseAssetAmount,
932
+ reduceOnly: true,
933
+ });
754
934
  }
755
935
  async settlePNLs(users, marketIndex) {
756
936
  const ixs = [];
@@ -774,7 +954,7 @@ class ClearingHouse {
774
954
  const market = this.getMarketAccount(position.marketIndex);
775
955
  marketAccountMap.set(position.marketIndex.toNumber(), {
776
956
  pubkey: market.pubkey,
777
- isWritable: true,
957
+ isWritable: false,
778
958
  isSigner: false,
779
959
  });
780
960
  oracleAccountMap.set(market.amm.oracle.toString(), {
@@ -831,54 +1011,217 @@ class ClearingHouse {
831
1011
  remainingAccounts: remainingAccounts,
832
1012
  });
833
1013
  }
834
- async liquidate(liquidateeUserAccountPublicKey) {
835
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateIx(liquidateeUserAccountPublicKey)), [], this.opts);
1014
+ async liquidatePerp(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
1015
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount)), [], this.opts);
836
1016
  return txSig;
837
1017
  }
838
- async getLiquidateIx(liquidateeUserAccountPublicKey) {
839
- const userAccountPublicKey = await this.getUserAccountPublicKey();
840
- const liquidateeUserAccount = (await this.program.account.user.fetch(liquidateeUserAccountPublicKey));
841
- const bankAccountInfos = [
842
- {
843
- pubkey: this.getQuoteAssetBankAccount().pubkey,
844
- isSigner: false,
845
- isWritable: true,
1018
+ async getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
1019
+ const liquidatorPublicKey = await this.getUserAccountPublicKey();
1020
+ const remainingAccounts = this.getRemainingAccountsForLiquidation({
1021
+ writableMarketIndex: marketIndex,
1022
+ userAccount,
1023
+ });
1024
+ return await this.program.instruction.liquidatePerp(marketIndex, maxBaseAssetAmount, {
1025
+ accounts: {
1026
+ state: await this.getStatePublicKey(),
1027
+ authority: this.wallet.publicKey,
1028
+ user: userAccountPublicKey,
1029
+ liquidator: liquidatorPublicKey,
846
1030
  },
847
- ];
848
- const marketAccountInfos = [];
849
- const oracleAccountInfos = [];
1031
+ remainingAccounts: remainingAccounts,
1032
+ });
1033
+ }
1034
+ async liquidateBorrow(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
1035
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
1036
+ return txSig;
1037
+ }
1038
+ async getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
1039
+ const liquidatorPublicKey = await this.getUserAccountPublicKey();
1040
+ const remainingAccounts = this.getRemainingAccountsForLiquidation({
1041
+ userAccount,
1042
+ writableBankIndexes: [liabilityBankIndex, assetBankIndex],
1043
+ });
1044
+ return await this.program.instruction.liquidateBorrow(assetBankIndex, liabilityBankIndex, maxLiabilityTransfer, {
1045
+ accounts: {
1046
+ state: await this.getStatePublicKey(),
1047
+ authority: this.wallet.publicKey,
1048
+ user: userAccountPublicKey,
1049
+ liquidator: liquidatorPublicKey,
1050
+ },
1051
+ remainingAccounts: remainingAccounts,
1052
+ });
1053
+ }
1054
+ async liquidateBorrowForPerpPnl(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
1055
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
1056
+ return txSig;
1057
+ }
1058
+ async getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
1059
+ const liquidatorPublicKey = await this.getUserAccountPublicKey();
1060
+ const remainingAccounts = this.getRemainingAccountsForLiquidation({
1061
+ userAccount,
1062
+ writableMarketIndex: perpMarketIndex,
1063
+ writableBankIndexes: [liabilityBankIndex],
1064
+ });
1065
+ return await this.program.instruction.liquidateBorrowForPerpPnl(perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer, {
1066
+ accounts: {
1067
+ state: await this.getStatePublicKey(),
1068
+ authority: this.wallet.publicKey,
1069
+ user: userAccountPublicKey,
1070
+ liquidator: liquidatorPublicKey,
1071
+ },
1072
+ remainingAccounts: remainingAccounts,
1073
+ });
1074
+ }
1075
+ async liquidatePerpPnlForDeposit(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
1076
+ const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer)), [], this.opts);
1077
+ return txSig;
1078
+ }
1079
+ async getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
1080
+ const liquidatorPublicKey = await this.getUserAccountPublicKey();
1081
+ const remainingAccounts = this.getRemainingAccountsForLiquidation({
1082
+ userAccount,
1083
+ writableMarketIndex: perpMarketIndex,
1084
+ writableBankIndexes: [assetBankIndex],
1085
+ });
1086
+ return await this.program.instruction.liquidatePerpPnlForDeposit(perpMarketIndex, assetBankIndex, maxPnlTransfer, {
1087
+ accounts: {
1088
+ state: await this.getStatePublicKey(),
1089
+ authority: this.wallet.publicKey,
1090
+ user: userAccountPublicKey,
1091
+ liquidator: liquidatorPublicKey,
1092
+ },
1093
+ remainingAccounts: remainingAccounts,
1094
+ });
1095
+ }
1096
+ getRemainingAccountsForLiquidation(params) {
1097
+ const liquidateeUserAccount = params.userAccount;
1098
+ const oracleAccountMap = new Map();
1099
+ const bankAccountMap = new Map();
1100
+ const marketAccountMap = new Map();
1101
+ for (const bankBalance of liquidateeUserAccount.bankBalances) {
1102
+ if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
1103
+ const bankAccount = this.getBankAccount(bankBalance.bankIndex);
1104
+ bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
1105
+ pubkey: bankAccount.pubkey,
1106
+ isSigner: false,
1107
+ isWritable: false,
1108
+ });
1109
+ if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
1110
+ oracleAccountMap.set(bankAccount.oracle.toString(), {
1111
+ pubkey: bankAccount.oracle,
1112
+ isSigner: false,
1113
+ isWritable: false,
1114
+ });
1115
+ }
1116
+ }
1117
+ }
850
1118
  for (const position of liquidateeUserAccount.positions) {
851
1119
  if (!(0, position_1.positionIsAvailable)(position)) {
852
1120
  const market = this.getMarketAccount(position.marketIndex);
853
- const marketPublicKey = await (0, pda_1.getMarketPublicKey)(this.program.programId, position.marketIndex);
854
- marketAccountInfos.push({
855
- pubkey: marketPublicKey,
856
- isWritable: true,
1121
+ marketAccountMap.set(position.marketIndex.toNumber(), {
1122
+ pubkey: market.pubkey,
1123
+ isWritable: false,
857
1124
  isSigner: false,
858
1125
  });
859
- oracleAccountInfos.push({
1126
+ oracleAccountMap.set(market.amm.oracle.toString(), {
860
1127
  pubkey: market.amm.oracle,
861
1128
  isWritable: false,
862
1129
  isSigner: false,
863
1130
  });
864
1131
  }
865
1132
  }
866
- const remainingAccounts = oracleAccountInfos.concat(bankAccountInfos.concat(marketAccountInfos));
867
- const state = this.getStateAccount();
868
- const quoteAssetBankAccount = this.getQuoteAssetBankAccount();
869
- return await this.program.instruction.liquidate({
870
- accounts: {
871
- state: await this.getStatePublicKey(),
872
- authority: this.wallet.publicKey,
873
- user: liquidateeUserAccountPublicKey,
874
- liquidator: userAccountPublicKey,
875
- bankVault: quoteAssetBankAccount.vault,
876
- bankVaultAuthority: quoteAssetBankAccount.vaultAuthority,
877
- insuranceVault: state.insuranceVault,
878
- tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
879
- },
880
- remainingAccounts: remainingAccounts,
881
- });
1133
+ const userAccountAndSlot = this.getUserAccountAndSlot();
1134
+ if (!userAccountAndSlot) {
1135
+ throw Error('No user account found. Most likely user account does not exist or failed to fetch account');
1136
+ }
1137
+ const { data: userAccount, slot: lastUserPositionsSlot } = userAccountAndSlot;
1138
+ for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
1139
+ // if cache has more recent slot than user positions account slot, add market to remaining accounts
1140
+ // otherwise remove from slot
1141
+ if (slot > lastUserPositionsSlot) {
1142
+ const marketAccount = this.getMarketAccount(marketIndexNum);
1143
+ marketAccountMap.set(marketIndexNum, {
1144
+ pubkey: marketAccount.pubkey,
1145
+ isSigner: false,
1146
+ isWritable: false,
1147
+ });
1148
+ oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
1149
+ pubkey: marketAccount.amm.oracle,
1150
+ isSigner: false,
1151
+ isWritable: false,
1152
+ });
1153
+ }
1154
+ else {
1155
+ this.marketLastSlotCache.delete(marketIndexNum);
1156
+ }
1157
+ }
1158
+ for (const bankBalance of userAccount.bankBalances) {
1159
+ if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
1160
+ const bankAccount = this.getBankAccount(bankBalance.bankIndex);
1161
+ bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
1162
+ pubkey: bankAccount.pubkey,
1163
+ isSigner: false,
1164
+ isWritable: false,
1165
+ });
1166
+ if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
1167
+ oracleAccountMap.set(bankAccount.oracle.toString(), {
1168
+ pubkey: bankAccount.oracle,
1169
+ isSigner: false,
1170
+ isWritable: false,
1171
+ });
1172
+ }
1173
+ }
1174
+ }
1175
+ for (const position of userAccount.positions) {
1176
+ if (!(0, position_1.positionIsAvailable)(position)) {
1177
+ const market = this.getMarketAccount(position.marketIndex);
1178
+ marketAccountMap.set(position.marketIndex.toNumber(), {
1179
+ pubkey: market.pubkey,
1180
+ isWritable: false,
1181
+ isSigner: false,
1182
+ });
1183
+ oracleAccountMap.set(market.amm.oracle.toString(), {
1184
+ pubkey: market.amm.oracle,
1185
+ isWritable: false,
1186
+ isSigner: false,
1187
+ });
1188
+ }
1189
+ }
1190
+ if (params.writableMarketIndex) {
1191
+ const market = this.getMarketAccount(params.writableMarketIndex);
1192
+ marketAccountMap.set(market.marketIndex.toNumber(), {
1193
+ pubkey: market.pubkey,
1194
+ isSigner: false,
1195
+ isWritable: true,
1196
+ });
1197
+ oracleAccountMap.set(market.amm.oracle.toString(), {
1198
+ pubkey: market.amm.oracle,
1199
+ isSigner: false,
1200
+ isWritable: false,
1201
+ });
1202
+ }
1203
+ if (params.writableBankIndexes) {
1204
+ for (const writableBankIndex of params.writableBankIndexes) {
1205
+ const bank = this.getBankAccount(writableBankIndex);
1206
+ bankAccountMap.set(bank.bankIndex.toNumber(), {
1207
+ pubkey: bank.pubkey,
1208
+ isSigner: false,
1209
+ isWritable: true,
1210
+ });
1211
+ if (!bank.oracle.equals(web3_js_1.PublicKey.default)) {
1212
+ oracleAccountMap.set(bank.oracle.toString(), {
1213
+ pubkey: bank.oracle,
1214
+ isSigner: false,
1215
+ isWritable: false,
1216
+ });
1217
+ }
1218
+ }
1219
+ }
1220
+ return [
1221
+ ...oracleAccountMap.values(),
1222
+ ...bankAccountMap.values(),
1223
+ ...marketAccountMap.values(),
1224
+ ];
882
1225
  }
883
1226
  async updateFundingRate(oracle, marketIndex) {
884
1227
  const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateFundingRateIx(oracle, marketIndex)), [], this.opts);