@drift-labs/sdk 0.2.0-master.30 → 0.2.0-master.31

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 (50) hide show
  1. package/lib/admin.d.ts +11 -7
  2. package/lib/admin.js +50 -12
  3. package/lib/clearingHouse.d.ts +26 -23
  4. package/lib/clearingHouse.js +290 -652
  5. package/lib/clearingHouseUser.d.ts +1 -1
  6. package/lib/clearingHouseUser.js +9 -12
  7. package/lib/config.js +1 -1
  8. package/lib/constants/numericConstants.d.ts +7 -0
  9. package/lib/constants/numericConstants.js +8 -1
  10. package/lib/constants/spotMarkets.js +4 -4
  11. package/lib/dlob/DLOB.d.ts +6 -5
  12. package/lib/dlob/DLOB.js +130 -88
  13. package/lib/dlob/DLOBNode.d.ts +2 -0
  14. package/lib/dlob/DLOBNode.js +3 -0
  15. package/lib/dlob/NodeList.d.ts +1 -1
  16. package/lib/dlob/NodeList.js +5 -4
  17. package/lib/events/types.d.ts +2 -1
  18. package/lib/events/types.js +1 -0
  19. package/lib/factory/bigNum.d.ts +1 -0
  20. package/lib/factory/bigNum.js +14 -0
  21. package/lib/idl/clearing_house.json +1091 -611
  22. package/lib/math/amm.d.ts +2 -2
  23. package/lib/math/amm.js +31 -28
  24. package/lib/math/market.d.ts +1 -1
  25. package/lib/math/market.js +6 -6
  26. package/lib/math/spotBalance.js +7 -8
  27. package/lib/math/trade.js +11 -11
  28. package/lib/types.d.ts +117 -40
  29. package/lib/types.js +33 -3
  30. package/package.json +4 -2
  31. package/src/admin.ts +129 -29
  32. package/src/clearingHouse.ts +380 -787
  33. package/src/clearingHouseUser.ts +11 -14
  34. package/src/config.ts +1 -1
  35. package/src/constants/numericConstants.ts +7 -0
  36. package/src/constants/spotMarkets.ts +5 -4
  37. package/src/dlob/DLOB.ts +188 -103
  38. package/src/dlob/DLOBNode.ts +5 -0
  39. package/src/dlob/NodeList.ts +9 -5
  40. package/src/events/types.ts +3 -0
  41. package/src/factory/bigNum.ts +23 -0
  42. package/src/idl/clearing_house.json +1091 -611
  43. package/src/math/amm.ts +42 -29
  44. package/src/math/market.ts +9 -4
  45. package/src/math/spotBalance.ts +11 -8
  46. package/src/math/trade.ts +11 -11
  47. package/src/types.ts +81 -40
  48. package/tests/bn/test.ts +12 -7
  49. package/tests/dlob/helpers.ts +56 -33
  50. package/tests/dlob/test.ts +1227 -404
@@ -23,6 +23,7 @@ import {
23
23
  ReferrerInfo,
24
24
  MarketType,
25
25
  SerumV3FulfillmentConfigAccount,
26
+ isVariant,
26
27
  } from './types';
27
28
  import * as anchor from '@project-serum/anchor';
28
29
  import clearingHouseIDL from './idl/clearing_house.json';
@@ -63,11 +64,7 @@ import {
63
64
  } from './accounts/types';
64
65
  import { TxSender } from './tx/types';
65
66
  import { wrapInTx } from './tx/utils';
66
- import {
67
- ONE,
68
- QUOTE_SPOT_MARKET_INDEX,
69
- ZERO,
70
- } from './constants/numericConstants';
67
+ import { QUOTE_SPOT_MARKET_INDEX } from './constants/numericConstants';
71
68
  import { findDirectionToClose, positionIsAvailable } from './math/position';
72
69
  import { getTokenAmount } from './math/spotBalance';
73
70
  import { DEFAULT_USER_NAME, encodeName } from './userName';
@@ -83,6 +80,15 @@ import { WRAPPED_SOL_MINT } from './constants/spotMarkets';
83
80
  import { ClearingHouseUserStats } from './clearingHouseUserStats';
84
81
  import { isSpotPositionAvailable } from './math/spotPosition';
85
82
 
83
+ type RemainingAccountParams = {
84
+ userAccounts: UserAccount[];
85
+ writablePerpMarketIndexes?: number[];
86
+ writableSpotMarketIndexes?: number[];
87
+ readablePerpMarketIndex?: number;
88
+ readableSpotMarketIndex?: number;
89
+ useMarketLastSlotCache?: boolean;
90
+ };
91
+
86
92
  /**
87
93
  * # ClearingHouse
88
94
  * 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.
@@ -440,6 +446,21 @@ export class ClearingHouse {
440
446
  });
441
447
  }
442
448
 
449
+ const state = this.getStateAccount();
450
+ if (!state.whitelistMint.equals(PublicKey.default)) {
451
+ const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
452
+ ASSOCIATED_TOKEN_PROGRAM_ID,
453
+ TOKEN_PROGRAM_ID,
454
+ state.whitelistMint,
455
+ this.wallet.publicKey
456
+ );
457
+ remainingAccounts.push({
458
+ pubkey: associatedTokenPublicKey,
459
+ isWritable: false,
460
+ isSigner: false,
461
+ });
462
+ }
463
+
443
464
  const nameBuffer = encodeName(name);
444
465
  const initializeUserAccountIx =
445
466
  await this.program.instruction.initializeUser(userId, nameBuffer, {
@@ -530,6 +551,28 @@ export class ClearingHouse {
530
551
  );
531
552
  }
532
553
 
554
+ public async deleteUser(userId = 0): Promise<TransactionSignature> {
555
+ const userAccountPublicKey = getUserAccountPublicKeySync(
556
+ this.program.programId,
557
+ this.wallet.publicKey,
558
+ userId
559
+ );
560
+
561
+ const txSig = await this.program.rpc.deleteUser({
562
+ accounts: {
563
+ user: userAccountPublicKey,
564
+ userStats: this.getUserStatsAccountPublicKey(),
565
+ authority: this.wallet.publicKey,
566
+ state: await this.getStatePublicKey(),
567
+ },
568
+ });
569
+
570
+ await this.users.get(userId)?.unsubscribe();
571
+ this.users.delete(userId);
572
+
573
+ return txSig;
574
+ }
575
+
533
576
  public getUser(userId?: number): ClearingHouseUser {
534
577
  userId = userId ?? this.activeUserId;
535
578
  if (!this.users.has(userId)) {
@@ -589,57 +632,30 @@ export class ClearingHouse {
589
632
  );
590
633
  }
591
634
 
592
- getRemainingAccounts(params: {
593
- writablePerpMarketIndex?: number;
594
- writableSpotMarketIndex?: number;
595
- readablePerpMarketIndex?: number;
596
- readableSpotMarketIndex?: number;
597
- }): AccountMeta[] {
598
- const userAccountAndSlot = this.getUserAccountAndSlot();
599
- if (!userAccountAndSlot) {
600
- throw Error(
601
- 'No user account found. Most likely user account does not exist or failed to fetch account'
602
- );
603
- }
604
- const { data: userAccount, slot: lastUserPositionsSlot } =
605
- userAccountAndSlot;
606
-
607
- const oracleAccountMap = new Map<string, AccountMeta>();
608
- const spotMarketAccountMap = new Map<number, AccountMeta>();
609
- const perpMarketAccountMap = new Map<number, AccountMeta>();
610
- for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
611
- // if cache has more recent slot than user positions account slot, add market to remaining accounts
612
- // otherwise remove from slot
613
- if (slot > lastUserPositionsSlot) {
614
- const marketAccount = this.getPerpMarketAccount(marketIndexNum);
615
- perpMarketAccountMap.set(marketIndexNum, {
616
- pubkey: marketAccount.pubkey,
617
- isSigner: false,
618
- isWritable: false,
619
- });
620
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
621
- pubkey: marketAccount.amm.oracle,
622
- isSigner: false,
623
- isWritable: false,
624
- });
625
- } else {
626
- this.marketLastSlotCache.delete(marketIndexNum);
627
- }
628
- }
635
+ getRemainingAccounts(params: RemainingAccountParams): AccountMeta[] {
636
+ const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } =
637
+ this.getRemainingAccountMapsForUsers(params.userAccounts);
629
638
 
630
- for (const position of userAccount.perpPositions) {
631
- if (!positionIsAvailable(position)) {
632
- const marketAccount = this.getPerpMarketAccount(position.marketIndex);
633
- perpMarketAccountMap.set(position.marketIndex, {
634
- pubkey: marketAccount.pubkey,
635
- isSigner: false,
636
- isWritable: false,
637
- });
638
- oracleAccountMap.set(marketAccount.pubkey.toString(), {
639
- pubkey: marketAccount.amm.oracle,
640
- isSigner: false,
641
- isWritable: false,
642
- });
639
+ if (params.useMarketLastSlotCache) {
640
+ const lastUserPositionsSlot = this.getUserAccountAndSlot()?.slot;
641
+ for (const [marketIndex, slot] of this.marketLastSlotCache.entries()) {
642
+ // if cache has more recent slot than user positions account slot, add market to remaining accounts
643
+ // otherwise remove from slot
644
+ if (slot > lastUserPositionsSlot) {
645
+ const marketAccount = this.getPerpMarketAccount(marketIndex);
646
+ perpMarketAccountMap.set(marketIndex, {
647
+ pubkey: marketAccount.pubkey,
648
+ isSigner: false,
649
+ isWritable: false,
650
+ });
651
+ oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
652
+ pubkey: marketAccount.amm.oracle,
653
+ isSigner: false,
654
+ isWritable: false,
655
+ });
656
+ } else {
657
+ this.marketLastSlotCache.delete(marketIndex);
658
+ }
643
659
  }
644
660
  }
645
661
 
@@ -659,39 +675,21 @@ export class ClearingHouse {
659
675
  });
660
676
  }
661
677
 
662
- if (params.writablePerpMarketIndex !== undefined) {
663
- const marketAccount = this.getPerpMarketAccount(
664
- params.writablePerpMarketIndex
665
- );
666
- perpMarketAccountMap.set(params.writablePerpMarketIndex, {
667
- pubkey: marketAccount.pubkey,
668
- isSigner: false,
669
- isWritable: true,
670
- });
671
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
672
- pubkey: marketAccount.amm.oracle,
673
- isSigner: false,
674
- isWritable: false,
675
- });
676
- }
677
-
678
- for (const spotPosition of userAccount.spotPositions) {
679
- if (!isSpotPositionAvailable(spotPosition)) {
680
- const spotMarketAccount = this.getSpotMarketAccount(
681
- spotPosition.marketIndex
678
+ if (params.writablePerpMarketIndexes !== undefined) {
679
+ for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
680
+ const marketAccount = this.getPerpMarketAccount(
681
+ writablePerpMarketIndex
682
682
  );
683
- spotMarketAccountMap.set(spotPosition.marketIndex, {
684
- pubkey: spotMarketAccount.pubkey,
683
+ perpMarketAccountMap.set(writablePerpMarketIndex, {
684
+ pubkey: marketAccount.pubkey,
685
+ isSigner: false,
686
+ isWritable: true,
687
+ });
688
+ oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
689
+ pubkey: marketAccount.amm.oracle,
685
690
  isSigner: false,
686
691
  isWritable: false,
687
692
  });
688
- if (spotMarketAccount.marketIndex !== 0) {
689
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
690
- pubkey: spotMarketAccount.oracle,
691
- isSigner: false,
692
- isWritable: false,
693
- });
694
- }
695
693
  }
696
694
  }
697
695
 
@@ -713,21 +711,23 @@ export class ClearingHouse {
713
711
  }
714
712
  }
715
713
 
716
- if (params.writableSpotMarketIndex !== undefined) {
717
- const spotMarketAccount = this.getSpotMarketAccount(
718
- params.writableSpotMarketIndex
719
- );
720
- spotMarketAccountMap.set(params.writableSpotMarketIndex, {
721
- pubkey: spotMarketAccount.pubkey,
722
- isSigner: false,
723
- isWritable: true,
724
- });
725
- if (spotMarketAccount.marketIndex !== 0) {
726
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
727
- pubkey: spotMarketAccount.oracle,
714
+ if (params.writableSpotMarketIndexes !== undefined) {
715
+ for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
716
+ const spotMarketAccount = this.getSpotMarketAccount(
717
+ writableSpotMarketIndex
718
+ );
719
+ spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
720
+ pubkey: spotMarketAccount.pubkey,
728
721
  isSigner: false,
729
- isWritable: false,
722
+ isWritable: true,
730
723
  });
724
+ if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
725
+ oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
726
+ pubkey: spotMarketAccount.oracle,
727
+ isSigner: false,
728
+ isWritable: false,
729
+ });
730
+ }
731
731
  }
732
732
  }
733
733
 
@@ -738,10 +738,63 @@ export class ClearingHouse {
738
738
  ];
739
739
  }
740
740
 
741
- public getOrder(orderId: BN | number): Order | undefined {
742
- const orderIdBN = orderId instanceof BN ? orderId : new BN(orderId);
743
- return this.getUserAccount()?.orders.find((order) =>
744
- order.orderId.eq(orderIdBN)
741
+ getRemainingAccountMapsForUsers(userAccounts: UserAccount[]): {
742
+ oracleAccountMap: Map<string, AccountMeta>;
743
+ spotMarketAccountMap: Map<number, AccountMeta>;
744
+ perpMarketAccountMap: Map<number, AccountMeta>;
745
+ } {
746
+ const oracleAccountMap = new Map<string, AccountMeta>();
747
+ const spotMarketAccountMap = new Map<number, AccountMeta>();
748
+ const perpMarketAccountMap = new Map<number, AccountMeta>();
749
+
750
+ for (const userAccount of userAccounts) {
751
+ for (const spotPosition of userAccount.spotPositions) {
752
+ if (!isSpotPositionAvailable(spotPosition)) {
753
+ const spotMarket = this.getSpotMarketAccount(
754
+ spotPosition.marketIndex
755
+ );
756
+ spotMarketAccountMap.set(spotPosition.marketIndex, {
757
+ pubkey: spotMarket.pubkey,
758
+ isSigner: false,
759
+ isWritable: false,
760
+ });
761
+
762
+ if (!spotMarket.oracle.equals(PublicKey.default)) {
763
+ oracleAccountMap.set(spotMarket.oracle.toString(), {
764
+ pubkey: spotMarket.oracle,
765
+ isSigner: false,
766
+ isWritable: false,
767
+ });
768
+ }
769
+ }
770
+ }
771
+ for (const position of userAccount.perpPositions) {
772
+ if (!positionIsAvailable(position)) {
773
+ const market = this.getPerpMarketAccount(position.marketIndex);
774
+ perpMarketAccountMap.set(position.marketIndex, {
775
+ pubkey: market.pubkey,
776
+ isWritable: false,
777
+ isSigner: false,
778
+ });
779
+ oracleAccountMap.set(market.amm.oracle.toString(), {
780
+ pubkey: market.amm.oracle,
781
+ isWritable: false,
782
+ isSigner: false,
783
+ });
784
+ }
785
+ }
786
+ }
787
+
788
+ return {
789
+ oracleAccountMap,
790
+ spotMarketAccountMap,
791
+ perpMarketAccountMap,
792
+ };
793
+ }
794
+
795
+ public getOrder(orderId: number): Order | undefined {
796
+ return this.getUserAccount()?.orders.find(
797
+ (order) => order.orderId === orderId
745
798
  );
746
799
  }
747
800
 
@@ -834,21 +887,14 @@ export class ClearingHouse {
834
887
  let remainingAccounts = [];
835
888
  if (userInitialized) {
836
889
  remainingAccounts = this.getRemainingAccounts({
837
- writableSpotMarketIndex: marketIndex,
890
+ userAccounts: [this.getUserAccount()],
891
+ useMarketLastSlotCache: true,
892
+ writableSpotMarketIndexes: [marketIndex],
838
893
  });
839
894
  } else {
840
- const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
841
- if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
842
- remainingAccounts.push({
843
- pubkey: spotMarketAccount.oracle,
844
- isSigner: false,
845
- isWritable: false,
846
- });
847
- }
848
- remainingAccounts.push({
849
- pubkey: spotMarketAccount.pubkey,
850
- isSigner: false,
851
- isWritable: true,
895
+ remainingAccounts = this.getRemainingAccounts({
896
+ userAccounts: [],
897
+ writableSpotMarketIndexes: [marketIndex],
852
898
  });
853
899
  }
854
900
 
@@ -1164,7 +1210,9 @@ export class ClearingHouse {
1164
1210
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1165
1211
 
1166
1212
  const remainingAccounts = this.getRemainingAccounts({
1167
- writableSpotMarketIndex: marketIndex,
1213
+ userAccounts: [this.getUserAccount()],
1214
+ useMarketLastSlotCache: true,
1215
+ writableSpotMarketIndexes: [marketIndex],
1168
1216
  });
1169
1217
 
1170
1218
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
@@ -1228,9 +1276,29 @@ export class ClearingHouse {
1228
1276
  toUserId
1229
1277
  );
1230
1278
 
1231
- const remainingAccounts = this.getRemainingAccounts({
1232
- writableSpotMarketIndex: marketIndex,
1233
- });
1279
+ let remainingAccounts;
1280
+ if (this.users.has(fromUserId)) {
1281
+ remainingAccounts = this.getRemainingAccounts({
1282
+ userAccounts: [this.users.get(fromUserId).getUserAccount()],
1283
+ useMarketLastSlotCache: true,
1284
+ writableSpotMarketIndexes: [marketIndex],
1285
+ });
1286
+ } else {
1287
+ const userAccountPublicKey = getUserAccountPublicKeySync(
1288
+ this.program.programId,
1289
+ this.authority,
1290
+ fromUserId
1291
+ );
1292
+
1293
+ const fromUserAccount = (await this.program.account.user.fetch(
1294
+ userAccountPublicKey
1295
+ )) as UserAccount;
1296
+ remainingAccounts = this.getRemainingAccounts({
1297
+ userAccounts: [fromUserAccount],
1298
+ useMarketLastSlotCache: true,
1299
+ writableSpotMarketIndexes: [marketIndex],
1300
+ });
1301
+ }
1234
1302
 
1235
1303
  return await this.program.instruction.transferDeposit(marketIndex, amount, {
1236
1304
  accounts: {
@@ -1261,6 +1329,7 @@ export class ClearingHouse {
1261
1329
  const spotMarket = this.getSpotMarketAccount(marketIndex);
1262
1330
  return await this.program.instruction.updateSpotMarketCumulativeInterest({
1263
1331
  accounts: {
1332
+ state: await this.getStatePublicKey(),
1264
1333
  spotMarket: spotMarket.pubkey,
1265
1334
  },
1266
1335
  });
@@ -1285,33 +1354,11 @@ export class ClearingHouse {
1285
1354
  const settleeUserAccount = (await this.program.account.user.fetch(
1286
1355
  settleeUserAccountPublicKey
1287
1356
  )) as UserAccount;
1288
- const userPositions = settleeUserAccount.perpPositions;
1289
- const remainingAccounts = [];
1290
-
1291
- let foundMarket = false;
1292
- for (const position of userPositions) {
1293
- if (!positionIsAvailable(position)) {
1294
- const marketPublicKey = await getMarketPublicKey(
1295
- this.program.programId,
1296
- position.marketIndex
1297
- );
1298
- remainingAccounts.push({
1299
- pubkey: marketPublicKey,
1300
- isWritable: true,
1301
- isSigner: false,
1302
- });
1303
-
1304
- if (marketIndex === position.marketIndex) {
1305
- foundMarket = true;
1306
- }
1307
- }
1308
- }
1309
1357
 
1310
- if (!foundMarket) {
1311
- console.log(
1312
- 'Warning: lp is not in the market specified -- tx will likely fail'
1313
- );
1314
- }
1358
+ const remainingAccounts = this.getRemainingAccounts({
1359
+ userAccounts: [settleeUserAccount],
1360
+ writablePerpMarketIndexes: [marketIndex],
1361
+ });
1315
1362
 
1316
1363
  return this.program.instruction.settleLp(marketIndex, {
1317
1364
  accounts: {
@@ -1341,7 +1388,9 @@ export class ClearingHouse {
1341
1388
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1342
1389
 
1343
1390
  const remainingAccounts = this.getRemainingAccounts({
1344
- writablePerpMarketIndex: marketIndex,
1391
+ userAccounts: [this.getUserAccount()],
1392
+ useMarketLastSlotCache: true,
1393
+ writablePerpMarketIndexes: [marketIndex],
1345
1394
  });
1346
1395
 
1347
1396
  if (sharesToBurn == undefined) {
@@ -1382,7 +1431,9 @@ export class ClearingHouse {
1382
1431
  ): Promise<TransactionInstruction> {
1383
1432
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1384
1433
  const remainingAccounts = this.getRemainingAccounts({
1385
- writablePerpMarketIndex: marketIndex,
1434
+ userAccounts: [this.getUserAccount()],
1435
+ useMarketLastSlotCache: true,
1436
+ writablePerpMarketIndexes: [marketIndex],
1386
1437
  });
1387
1438
 
1388
1439
  return this.program.instruction.addLiquidity(amount, marketIndex, {
@@ -1492,6 +1543,8 @@ export class ClearingHouse {
1492
1543
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1493
1544
 
1494
1545
  const remainingAccounts = this.getRemainingAccounts({
1546
+ userAccounts: [this.getUserAccount()],
1547
+ useMarketLastSlotCache: true,
1495
1548
  readablePerpMarketIndex: orderParams.marketIndex,
1496
1549
  });
1497
1550
 
@@ -1599,7 +1652,7 @@ export class ClearingHouse {
1599
1652
  });
1600
1653
  }
1601
1654
 
1602
- public async cancelOrder(orderId?: BN): Promise<TransactionSignature> {
1655
+ public async cancelOrder(orderId?: number): Promise<TransactionSignature> {
1603
1656
  const { txSig } = await this.txSender.send(
1604
1657
  wrapInTx(await this.getCancelOrderIx(orderId)),
1605
1658
  [],
@@ -1608,10 +1661,15 @@ export class ClearingHouse {
1608
1661
  return txSig;
1609
1662
  }
1610
1663
 
1611
- public async getCancelOrderIx(orderId?: BN): Promise<TransactionInstruction> {
1664
+ public async getCancelOrderIx(
1665
+ orderId?: number
1666
+ ): Promise<TransactionInstruction> {
1612
1667
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1613
1668
 
1614
- const remainingAccounts = this.getRemainingAccounts({});
1669
+ const remainingAccounts = this.getRemainingAccounts({
1670
+ userAccounts: [this.getUserAccount()],
1671
+ useMarketLastSlotCache: true,
1672
+ });
1615
1673
 
1616
1674
  return await this.program.instruction.cancelOrder(orderId ?? null, {
1617
1675
  accounts: {
@@ -1642,7 +1700,10 @@ export class ClearingHouse {
1642
1700
  const order = this.getOrderByUserId(userOrderId);
1643
1701
  const oracle = this.getPerpMarketAccount(order.marketIndex).amm.oracle;
1644
1702
 
1645
- const remainingAccounts = this.getRemainingAccounts({});
1703
+ const remainingAccounts = this.getRemainingAccounts({
1704
+ userAccounts: [this.getUserAccount()],
1705
+ useMarketLastSlotCache: true,
1706
+ });
1646
1707
 
1647
1708
  return await this.program.instruction.cancelOrderByUserId(userOrderId, {
1648
1709
  accounts: {
@@ -1658,7 +1719,7 @@ export class ClearingHouse {
1658
1719
  public async fillOrder(
1659
1720
  userAccountPublicKey: PublicKey,
1660
1721
  user: UserAccount,
1661
- order?: Order,
1722
+ order?: Pick<Order, 'marketIndex' | 'orderId'>,
1662
1723
  makerInfo?: MakerInfo,
1663
1724
  referrerInfo?: ReferrerInfo
1664
1725
  ): Promise<TransactionSignature> {
@@ -1695,72 +1756,19 @@ export class ClearingHouse {
1695
1756
 
1696
1757
  const marketIndex = order
1697
1758
  ? order.marketIndex
1698
- : userAccount.orders.find((order) =>
1699
- order.orderId.eq(userAccount.nextOrderId.sub(ONE))
1759
+ : userAccount.orders.find(
1760
+ (order) => order.orderId === userAccount.nextOrderId - 1
1700
1761
  ).marketIndex;
1701
- const marketAccount = this.getPerpMarketAccount(marketIndex);
1702
-
1703
- const oracleAccountMap = new Map<string, AccountMeta>();
1704
- const spotMarketAccountMap = new Map<number, AccountMeta>();
1705
- const perpMarketAccountMap = new Map<number, AccountMeta>();
1706
-
1707
- for (const spotPosition of userAccount.spotPositions) {
1708
- if (!isSpotPositionAvailable(spotPosition)) {
1709
- const spotMarketAccount = this.getSpotMarketAccount(
1710
- spotPosition.marketIndex
1711
- );
1712
- spotMarketAccountMap.set(spotPosition.marketIndex, {
1713
- pubkey: spotMarketAccount.pubkey,
1714
- isSigner: false,
1715
- isWritable: false,
1716
- });
1717
-
1718
- if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
1719
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
1720
- pubkey: spotMarketAccount.oracle,
1721
- isSigner: false,
1722
- isWritable: false,
1723
- });
1724
- }
1725
- }
1726
- }
1727
1762
 
1728
- for (const position of userAccount.perpPositions) {
1729
- if (
1730
- !positionIsAvailable(position) &&
1731
- position.marketIndex !== order.marketIndex
1732
- ) {
1733
- const market = this.getPerpMarketAccount(position.marketIndex);
1734
- perpMarketAccountMap.set(position.marketIndex, {
1735
- pubkey: market.pubkey,
1736
- isWritable: false,
1737
- isSigner: false,
1738
- });
1739
- oracleAccountMap.set(market.amm.oracle.toString(), {
1740
- pubkey: market.amm.oracle,
1741
- isWritable: false,
1742
- isSigner: false,
1743
- });
1744
- }
1763
+ const userAccounts = [userAccount];
1764
+ if (makerInfo !== undefined) {
1765
+ userAccounts.push(makerInfo.makerUserAccount);
1745
1766
  }
1746
-
1747
- perpMarketAccountMap.set(marketIndex, {
1748
- pubkey: marketAccount.pubkey,
1749
- isWritable: true,
1750
- isSigner: false,
1751
- });
1752
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
1753
- pubkey: marketAccount.amm.oracle,
1754
- isWritable: false,
1755
- isSigner: false,
1767
+ const remainingAccounts = this.getRemainingAccounts({
1768
+ userAccounts,
1769
+ writablePerpMarketIndexes: [marketIndex],
1756
1770
  });
1757
1771
 
1758
- const remainingAccounts = [
1759
- ...oracleAccountMap.values(),
1760
- ...spotMarketAccountMap.values(),
1761
- ...perpMarketAccountMap.values(),
1762
- ];
1763
-
1764
1772
  if (makerInfo) {
1765
1773
  remainingAccounts.push({
1766
1774
  pubkey: makerInfo.maker,
@@ -1821,6 +1829,8 @@ export class ClearingHouse {
1821
1829
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1822
1830
 
1823
1831
  const remainingAccounts = this.getRemainingAccounts({
1832
+ userAccounts: [this.getUserAccount()],
1833
+ useMarketLastSlotCache: true,
1824
1834
  readableSpotMarketIndex: orderParams.marketIndex,
1825
1835
  });
1826
1836
 
@@ -1878,86 +1888,30 @@ export class ClearingHouse {
1878
1888
 
1879
1889
  const marketIndex = order
1880
1890
  ? order.marketIndex
1881
- : userAccount.orders.find((order) =>
1882
- order.orderId.eq(userAccount.nextOrderId.sub(ONE))
1891
+ : userAccount.orders.find(
1892
+ (order) => order.orderId === userAccount.nextOrderId - 1
1883
1893
  ).marketIndex;
1884
1894
 
1885
- const oracleAccountMap = new Map<string, AccountMeta>();
1886
- const spotMarketAccountMap = new Map<number, AccountMeta>();
1887
- const perpMarketAccountMap = new Map<number, AccountMeta>();
1888
-
1889
- for (const spotPosition of userAccount.spotPositions) {
1890
- if (!isSpotPositionAvailable(spotPosition)) {
1891
- const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
1892
- spotMarketAccountMap.set(spotPosition.marketIndex, {
1893
- pubkey: spotMarket.pubkey,
1894
- isSigner: false,
1895
- isWritable: false,
1896
- });
1895
+ const userAccounts = [userAccount];
1896
+ if (makerInfo !== undefined) {
1897
+ userAccounts.push(makerInfo.makerUserAccount);
1898
+ }
1899
+ const remainingAccounts = this.getRemainingAccounts({
1900
+ userAccounts,
1901
+ writableSpotMarketIndexes: [marketIndex, QUOTE_SPOT_MARKET_INDEX],
1902
+ });
1897
1903
 
1898
- if (!spotMarket.oracle.equals(PublicKey.default)) {
1899
- oracleAccountMap.set(spotMarket.oracle.toString(), {
1900
- pubkey: spotMarket.oracle,
1901
- isSigner: false,
1902
- isWritable: false,
1903
- });
1904
- }
1905
- }
1906
- }
1907
-
1908
- for (const position of userAccount.perpPositions) {
1909
- if (!positionIsAvailable(position)) {
1910
- const market = this.getPerpMarketAccount(position.marketIndex);
1911
- perpMarketAccountMap.set(position.marketIndex, {
1912
- pubkey: market.pubkey,
1913
- isWritable: false,
1914
- isSigner: false,
1915
- });
1916
- oracleAccountMap.set(market.amm.oracle.toString(), {
1917
- pubkey: market.amm.oracle,
1918
- isWritable: false,
1919
- isSigner: false,
1920
- });
1921
- }
1922
- }
1923
-
1924
- const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1925
- spotMarketAccountMap.set(marketIndex, {
1926
- pubkey: spotMarketAccount.pubkey,
1927
- isWritable: true,
1928
- isSigner: false,
1929
- });
1930
- if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
1931
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
1932
- pubkey: spotMarketAccount.oracle,
1933
- isWritable: false,
1934
- isSigner: false,
1935
- });
1936
- }
1937
- const quoteMarketAccount = this.getQuoteSpotMarketAccount();
1938
- spotMarketAccountMap.set(quoteMarketAccount.marketIndex, {
1939
- pubkey: quoteMarketAccount.pubkey,
1940
- isWritable: true,
1941
- isSigner: false,
1942
- });
1943
-
1944
- const remainingAccounts = [
1945
- ...oracleAccountMap.values(),
1946
- ...spotMarketAccountMap.values(),
1947
- ...perpMarketAccountMap.values(),
1948
- ];
1949
-
1950
- if (makerInfo) {
1951
- remainingAccounts.push({
1952
- pubkey: makerInfo.maker,
1953
- isWritable: true,
1954
- isSigner: false,
1955
- });
1956
- remainingAccounts.push({
1957
- pubkey: makerInfo.makerStats,
1958
- isWritable: true,
1959
- isSigner: false,
1960
- });
1904
+ if (makerInfo) {
1905
+ remainingAccounts.push({
1906
+ pubkey: makerInfo.maker,
1907
+ isWritable: true,
1908
+ isSigner: false,
1909
+ });
1910
+ remainingAccounts.push({
1911
+ pubkey: makerInfo.makerStats,
1912
+ isWritable: true,
1913
+ isSigner: false,
1914
+ });
1961
1915
  }
1962
1916
 
1963
1917
  if (referrerInfo) {
@@ -2047,12 +2001,12 @@ export class ClearingHouse {
2047
2001
  isSigner: false,
2048
2002
  });
2049
2003
  remainingAccounts.push({
2050
- pubkey: spotMarketAccount.vault,
2004
+ pubkey: this.getSpotMarketAccount(marketIndex).vault,
2051
2005
  isWritable: true,
2052
2006
  isSigner: false,
2053
2007
  });
2054
2008
  remainingAccounts.push({
2055
- pubkey: quoteMarketAccount.vault,
2009
+ pubkey: this.getQuoteSpotMarketAccount().vault,
2056
2010
  isWritable: true,
2057
2011
  isSigner: false,
2058
2012
  });
@@ -2101,176 +2055,25 @@ export class ClearingHouse {
2101
2055
  ): Promise<TransactionInstruction> {
2102
2056
  const fillerPublicKey = await this.getUserAccountPublicKey();
2103
2057
 
2104
- const marketIndex = order.marketIndex;
2105
- const marketAccount = this.getPerpMarketAccount(marketIndex);
2106
-
2107
- const oracleAccountMap = new Map<string, AccountMeta>();
2108
- const spotMarketAccountMap = new Map<number, AccountMeta>();
2109
- const perpMarketAccountMap = new Map<number, AccountMeta>();
2110
-
2111
- for (const spotPosition of userAccount.spotPositions) {
2112
- if (!isSpotPositionAvailable(spotPosition)) {
2113
- const spotMarketAccount = this.getSpotMarketAccount(
2114
- spotPosition.marketIndex
2115
- );
2116
- spotMarketAccountMap.set(spotPosition.marketIndex, {
2117
- pubkey: spotMarketAccount.pubkey,
2118
- isSigner: false,
2119
- isWritable: false,
2120
- });
2121
-
2122
- if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
2123
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
2124
- pubkey: spotMarketAccount.oracle,
2125
- isSigner: false,
2126
- isWritable: false,
2127
- });
2128
- }
2129
- }
2130
- }
2131
-
2132
- for (const position of userAccount.perpPositions) {
2133
- if (
2134
- !positionIsAvailable(position) &&
2135
- position.marketIndex !== order.marketIndex
2136
- ) {
2137
- const market = this.getPerpMarketAccount(position.marketIndex);
2138
- perpMarketAccountMap.set(position.marketIndex, {
2139
- pubkey: market.pubkey,
2140
- isWritable: false,
2141
- isSigner: false,
2142
- });
2143
- oracleAccountMap.set(market.amm.oracle.toString(), {
2144
- pubkey: market.amm.oracle,
2145
- isWritable: false,
2146
- isSigner: false,
2147
- });
2148
- }
2058
+ let remainingAccountsParams;
2059
+ if (isVariant(order.marketType, 'perp')) {
2060
+ remainingAccountsParams = {
2061
+ userAccounts: [userAccount],
2062
+ writablePerpMarketIndexes: [order.marketIndex],
2063
+ };
2064
+ } else {
2065
+ remainingAccountsParams = {
2066
+ userAccounts: [userAccount],
2067
+ writableSpotMarketIndexes: [order.marketIndex, QUOTE_SPOT_MARKET_INDEX],
2068
+ };
2149
2069
  }
2150
2070
 
2151
- perpMarketAccountMap.set(marketIndex, {
2152
- pubkey: marketAccount.pubkey,
2153
- isWritable: true,
2154
- isSigner: false,
2155
- });
2156
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
2157
- pubkey: marketAccount.amm.oracle,
2158
- isWritable: false,
2159
- isSigner: false,
2160
- });
2161
-
2162
- const remainingAccounts = [
2163
- ...oracleAccountMap.values(),
2164
- ...spotMarketAccountMap.values(),
2165
- ...perpMarketAccountMap.values(),
2166
- ];
2167
-
2168
- const orderId = order.orderId;
2169
- return await this.program.instruction.triggerOrder(orderId, {
2170
- accounts: {
2171
- state: await this.getStatePublicKey(),
2172
- filler: fillerPublicKey,
2173
- user: userAccountPublicKey,
2174
- authority: this.wallet.publicKey,
2175
- },
2176
- remainingAccounts,
2177
- });
2178
- }
2179
-
2180
- public async triggerSpotOrder(
2181
- userAccountPublicKey: PublicKey,
2182
- user: UserAccount,
2183
- order: Order
2184
- ): Promise<TransactionSignature> {
2185
- const { txSig } = await this.txSender.send(
2186
- wrapInTx(
2187
- await this.getTriggerSpotOrderIx(userAccountPublicKey, user, order)
2188
- ),
2189
- [],
2190
- this.opts
2071
+ const remainingAccounts = this.getRemainingAccounts(
2072
+ remainingAccountsParams
2191
2073
  );
2192
- return txSig;
2193
- }
2194
-
2195
- public async getTriggerSpotOrderIx(
2196
- userAccountPublicKey: PublicKey,
2197
- userAccount: UserAccount,
2198
- order: Order
2199
- ): Promise<TransactionInstruction> {
2200
- const fillerPublicKey = await this.getUserAccountPublicKey();
2201
-
2202
- const marketIndex = order.marketIndex;
2203
- const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
2204
-
2205
- const oracleAccountMap = new Map<string, AccountMeta>();
2206
- const spotMarketAccountMap = new Map<number, AccountMeta>();
2207
- const perpMarketAccountMap = new Map<number, AccountMeta>();
2208
-
2209
- for (const spotPosition of userAccount.spotPositions) {
2210
- if (!isSpotPositionAvailable(spotPosition)) {
2211
- const spotMarketAccount = this.getSpotMarketAccount(
2212
- spotPosition.marketIndex
2213
- );
2214
- spotMarketAccountMap.set(spotPosition.marketIndex, {
2215
- pubkey: spotMarketAccount.pubkey,
2216
- isSigner: false,
2217
- isWritable: false,
2218
- });
2219
-
2220
- if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
2221
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
2222
- pubkey: spotMarketAccount.oracle,
2223
- isSigner: false,
2224
- isWritable: false,
2225
- });
2226
- }
2227
- }
2228
- }
2229
-
2230
- for (const position of userAccount.perpPositions) {
2231
- if (
2232
- !positionIsAvailable(position) &&
2233
- position.marketIndex !== order.marketIndex
2234
- ) {
2235
- const market = this.getPerpMarketAccount(position.marketIndex);
2236
- perpMarketAccountMap.set(position.marketIndex, {
2237
- pubkey: market.pubkey,
2238
- isWritable: false,
2239
- isSigner: false,
2240
- });
2241
- oracleAccountMap.set(market.amm.oracle.toString(), {
2242
- pubkey: market.amm.oracle,
2243
- isWritable: false,
2244
- isSigner: false,
2245
- });
2246
- }
2247
- }
2248
-
2249
- const quoteSpotMarket = this.getQuoteSpotMarketAccount();
2250
- spotMarketAccountMap.set(quoteSpotMarket.marketIndex, {
2251
- pubkey: quoteSpotMarket.pubkey,
2252
- isWritable: true,
2253
- isSigner: false,
2254
- });
2255
- spotMarketAccountMap.set(marketIndex, {
2256
- pubkey: spotMarketAccount.pubkey,
2257
- isWritable: false,
2258
- isSigner: false,
2259
- });
2260
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
2261
- pubkey: spotMarketAccount.oracle,
2262
- isWritable: false,
2263
- isSigner: false,
2264
- });
2265
-
2266
- const remainingAccounts = [
2267
- ...oracleAccountMap.values(),
2268
- ...spotMarketAccountMap.values(),
2269
- ...perpMarketAccountMap.values(),
2270
- ];
2271
2074
 
2272
2075
  const orderId = order.orderId;
2273
- return await this.program.instruction.triggerSpotOrder(orderId, {
2076
+ return await this.program.instruction.triggerOrder(orderId, {
2274
2077
  accounts: {
2275
2078
  state: await this.getStatePublicKey(),
2276
2079
  filler: fillerPublicKey,
@@ -2306,9 +2109,14 @@ export class ClearingHouse {
2306
2109
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
2307
2110
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2308
2111
 
2112
+ const userAccounts = [this.getUserAccount()];
2113
+ if (makerInfo !== undefined) {
2114
+ userAccounts.push(makerInfo.makerUserAccount);
2115
+ }
2309
2116
  const remainingAccounts = this.getRemainingAccounts({
2310
- writablePerpMarketIndex: orderParams.marketIndex,
2311
- writableSpotMarketIndex: QUOTE_SPOT_MARKET_INDEX,
2117
+ userAccounts,
2118
+ useMarketLastSlotCache: true,
2119
+ writablePerpMarketIndexes: [orderParams.marketIndex],
2312
2120
  });
2313
2121
 
2314
2122
  let makerOrderId = null;
@@ -2381,10 +2189,10 @@ export class ClearingHouse {
2381
2189
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
2382
2190
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2383
2191
 
2384
- // todo merge this with getRemainingAccounts
2385
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2386
- counterPartyUserAccount: takerInfo.takerUserAccount,
2387
- writablePerpMarketIndex: orderParams.marketIndex,
2192
+ const remainingAccounts = this.getRemainingAccounts({
2193
+ userAccounts: [this.getUserAccount(), takerInfo.takerUserAccount],
2194
+ useMarketLastSlotCache: true,
2195
+ writablePerpMarketIndexes: [orderParams.marketIndex],
2388
2196
  });
2389
2197
 
2390
2198
  if (referrerInfo) {
@@ -2400,7 +2208,7 @@ export class ClearingHouse {
2400
2208
  });
2401
2209
  }
2402
2210
 
2403
- const takerOrderId = takerInfo!.order!.orderId;
2211
+ const takerOrderId = takerInfo.order.orderId;
2404
2212
  return await this.program.instruction.placeAndMake(
2405
2213
  orderParams,
2406
2214
  takerOrderId,
@@ -2497,70 +2305,12 @@ export class ClearingHouse {
2497
2305
  settleeUserAccount: UserAccount,
2498
2306
  marketIndex: number
2499
2307
  ): Promise<TransactionInstruction> {
2500
- const perpMarketAccountMap = new Map<number, AccountMeta>();
2501
- const oracleAccountMap = new Map<string, AccountMeta>();
2502
- const spotMarketAccountMap = new Map<number, AccountMeta>();
2503
-
2504
- for (const position of settleeUserAccount.perpPositions) {
2505
- if (!positionIsAvailable(position)) {
2506
- const market = this.getPerpMarketAccount(position.marketIndex);
2507
- perpMarketAccountMap.set(position.marketIndex, {
2508
- pubkey: market.pubkey,
2509
- isWritable: false,
2510
- isSigner: false,
2511
- });
2512
- oracleAccountMap.set(market.amm.oracle.toString(), {
2513
- pubkey: market.amm.oracle,
2514
- isWritable: false,
2515
- isSigner: false,
2516
- });
2517
- }
2518
- }
2519
-
2520
- for (const spotPosition of settleeUserAccount.spotPositions) {
2521
- if (!isSpotPositionAvailable(spotPosition)) {
2522
- const spotMarketAccount = this.getSpotMarketAccount(
2523
- spotPosition.marketIndex
2524
- );
2525
- spotMarketAccountMap.set(spotPosition.marketIndex, {
2526
- pubkey: spotMarketAccount.pubkey,
2527
- isSigner: false,
2528
- isWritable: false,
2529
- });
2530
- if (spotMarketAccount.marketIndex !== 0) {
2531
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
2532
- pubkey: spotMarketAccount.oracle,
2533
- isSigner: false,
2534
- isWritable: false,
2535
- });
2536
- }
2537
- }
2538
- }
2539
-
2540
- const marketAccount = this.getPerpMarketAccount(marketIndex);
2541
- perpMarketAccountMap.set(marketIndex, {
2542
- pubkey: marketAccount.pubkey,
2543
- isSigner: false,
2544
- isWritable: true,
2545
- });
2546
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
2547
- pubkey: marketAccount.amm.oracle,
2548
- isSigner: false,
2549
- isWritable: false,
2550
- });
2551
-
2552
- spotMarketAccountMap.set(QUOTE_SPOT_MARKET_INDEX, {
2553
- pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
2554
- isSigner: false,
2555
- isWritable: true,
2308
+ const remainingAccounts = this.getRemainingAccounts({
2309
+ userAccounts: [settleeUserAccount],
2310
+ writablePerpMarketIndexes: [marketIndex],
2311
+ writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
2556
2312
  });
2557
2313
 
2558
- const remainingAccounts = [
2559
- ...oracleAccountMap.values(),
2560
- ...spotMarketAccountMap.values(),
2561
- ...perpMarketAccountMap.values(),
2562
- ];
2563
-
2564
2314
  return await this.program.instruction.settlePnl(marketIndex, {
2565
2315
  accounts: {
2566
2316
  state: await this.getStatePublicKey(),
@@ -2595,69 +2345,12 @@ export class ClearingHouse {
2595
2345
  settleeUserAccount: UserAccount,
2596
2346
  marketIndex: number
2597
2347
  ): Promise<TransactionInstruction> {
2598
- const marketAccountMap = new Map<number, AccountMeta>();
2599
- const oracleAccountMap = new Map<string, AccountMeta>();
2600
- const spotMarketAccountMap = new Map<number, AccountMeta>();
2601
- for (const position of settleeUserAccount.perpPositions) {
2602
- if (!positionIsAvailable(position)) {
2603
- const market = this.getPerpMarketAccount(position.marketIndex);
2604
- marketAccountMap.set(position.marketIndex, {
2605
- pubkey: market.pubkey,
2606
- isWritable: false,
2607
- isSigner: false,
2608
- });
2609
- oracleAccountMap.set(market.amm.oracle.toString(), {
2610
- pubkey: market.amm.oracle,
2611
- isWritable: false,
2612
- isSigner: false,
2613
- });
2614
- }
2615
- }
2616
-
2617
- for (const userBankBalance of settleeUserAccount.spotPositions) {
2618
- if (!userBankBalance.balance.eq(ZERO)) {
2619
- const bankAccount = this.getSpotMarketAccount(
2620
- userBankBalance.marketIndex
2621
- );
2622
- spotMarketAccountMap.set(userBankBalance.marketIndex, {
2623
- pubkey: bankAccount.pubkey,
2624
- isSigner: false,
2625
- isWritable: false,
2626
- });
2627
- if (bankAccount.marketIndex !== 0) {
2628
- oracleAccountMap.set(bankAccount.oracle.toString(), {
2629
- pubkey: bankAccount.oracle,
2630
- isSigner: false,
2631
- isWritable: false,
2632
- });
2633
- }
2634
- }
2635
- }
2636
-
2637
- const marketAccount = this.getPerpMarketAccount(marketIndex);
2638
- marketAccountMap.set(marketIndex, {
2639
- pubkey: marketAccount.pubkey,
2640
- isSigner: false,
2641
- isWritable: true,
2642
- });
2643
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
2644
- pubkey: marketAccount.amm.oracle,
2645
- isSigner: false,
2646
- isWritable: false,
2647
- });
2648
-
2649
- spotMarketAccountMap.set(QUOTE_SPOT_MARKET_INDEX, {
2650
- pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
2651
- isSigner: false,
2652
- isWritable: true,
2348
+ const remainingAccounts = this.getRemainingAccounts({
2349
+ userAccounts: [settleeUserAccount],
2350
+ writablePerpMarketIndexes: [marketIndex],
2351
+ writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
2653
2352
  });
2654
2353
 
2655
- const remainingAccounts = [
2656
- ...oracleAccountMap.values(),
2657
- ...spotMarketAccountMap.values(),
2658
- ...marketAccountMap.values(),
2659
- ];
2660
-
2661
2354
  return await this.program.instruction.settleExpiredPosition(marketIndex, {
2662
2355
  accounts: {
2663
2356
  state: await this.getStatePublicKey(),
@@ -2704,9 +2397,10 @@ export class ClearingHouse {
2704
2397
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2705
2398
  const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
2706
2399
 
2707
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2708
- writablePerpMarketIndex: marketIndex,
2709
- counterPartyUserAccount: userAccount,
2400
+ const remainingAccounts = this.getRemainingAccounts({
2401
+ userAccounts: [this.getUserAccount(), userAccount],
2402
+ useMarketLastSlotCache: true,
2403
+ writablePerpMarketIndexes: [marketIndex],
2710
2404
  });
2711
2405
 
2712
2406
  return await this.program.instruction.liquidatePerp(
@@ -2726,7 +2420,7 @@ export class ClearingHouse {
2726
2420
  );
2727
2421
  }
2728
2422
 
2729
- public async liquidateBorrow(
2423
+ public async liquidateSpot(
2730
2424
  userAccountPublicKey: PublicKey,
2731
2425
  userAccount: UserAccount,
2732
2426
  assetMarketIndex: number,
@@ -2735,7 +2429,7 @@ export class ClearingHouse {
2735
2429
  ): Promise<TransactionSignature> {
2736
2430
  const { txSig } = await this.txSender.send(
2737
2431
  wrapInTx(
2738
- await this.getLiquidateBorrowIx(
2432
+ await this.getLiquidateSpotIx(
2739
2433
  userAccountPublicKey,
2740
2434
  userAccount,
2741
2435
  assetMarketIndex,
@@ -2749,21 +2443,28 @@ export class ClearingHouse {
2749
2443
  return txSig;
2750
2444
  }
2751
2445
 
2752
- public async getLiquidateBorrowIx(
2446
+ public async getLiquidateSpotIx(
2753
2447
  userAccountPublicKey: PublicKey,
2754
2448
  userAccount: UserAccount,
2755
2449
  assetMarketIndex: number,
2756
2450
  liabilityMarketIndex: number,
2757
2451
  maxLiabilityTransfer: BN
2758
2452
  ): Promise<TransactionInstruction> {
2453
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
2454
+ this.program.programId,
2455
+ userAccount.authority
2456
+ );
2457
+
2759
2458
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2459
+ const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
2760
2460
 
2761
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2762
- counterPartyUserAccount: userAccount,
2461
+ const remainingAccounts = this.getRemainingAccounts({
2462
+ userAccounts: [this.getUserAccount(), userAccount],
2463
+ useMarketLastSlotCache: true,
2763
2464
  writableSpotMarketIndexes: [liabilityMarketIndex, assetMarketIndex],
2764
2465
  });
2765
2466
 
2766
- return await this.program.instruction.liquidateBorrow(
2467
+ return await this.program.instruction.liquidateSpot(
2767
2468
  assetMarketIndex,
2768
2469
  liabilityMarketIndex,
2769
2470
  maxLiabilityTransfer,
@@ -2772,7 +2473,9 @@ export class ClearingHouse {
2772
2473
  state: await this.getStatePublicKey(),
2773
2474
  authority: this.wallet.publicKey,
2774
2475
  user: userAccountPublicKey,
2476
+ userStats: userStatsPublicKey,
2775
2477
  liquidator: liquidatorPublicKey,
2478
+ liquidatorStats: liquidatorStatsPublicKey,
2776
2479
  },
2777
2480
  remainingAccounts: remainingAccounts,
2778
2481
  }
@@ -2810,11 +2513,17 @@ export class ClearingHouse {
2810
2513
  liabilityMarketIndex: number,
2811
2514
  maxLiabilityTransfer: BN
2812
2515
  ): Promise<TransactionInstruction> {
2516
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
2517
+ this.program.programId,
2518
+ userAccount.authority
2519
+ );
2520
+
2813
2521
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2522
+ const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
2814
2523
 
2815
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2816
- counterPartyUserAccount: userAccount,
2817
- writablePerpMarketIndex: perpMarketIndex,
2524
+ const remainingAccounts = this.getRemainingAccounts({
2525
+ userAccounts: [this.getUserAccount(), userAccount],
2526
+ writablePerpMarketIndexes: [perpMarketIndex],
2818
2527
  writableSpotMarketIndexes: [liabilityMarketIndex],
2819
2528
  });
2820
2529
 
@@ -2827,7 +2536,9 @@ export class ClearingHouse {
2827
2536
  state: await this.getStatePublicKey(),
2828
2537
  authority: this.wallet.publicKey,
2829
2538
  user: userAccountPublicKey,
2539
+ userStats: userStatsPublicKey,
2830
2540
  liquidator: liquidatorPublicKey,
2541
+ liquidatorStats: liquidatorStatsPublicKey,
2831
2542
  },
2832
2543
  remainingAccounts: remainingAccounts,
2833
2544
  }
@@ -2865,11 +2576,17 @@ export class ClearingHouse {
2865
2576
  assetMarketIndex: number,
2866
2577
  maxPnlTransfer: BN
2867
2578
  ): Promise<TransactionInstruction> {
2579
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
2580
+ this.program.programId,
2581
+ userAccount.authority
2582
+ );
2583
+
2868
2584
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2585
+ const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
2869
2586
 
2870
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2871
- counterPartyUserAccount: userAccount,
2872
- writablePerpMarketIndex: perpMarketIndex,
2587
+ const remainingAccounts = this.getRemainingAccounts({
2588
+ userAccounts: [this.getUserAccount(), userAccount],
2589
+ writablePerpMarketIndexes: [perpMarketIndex],
2873
2590
  writableSpotMarketIndexes: [assetMarketIndex],
2874
2591
  });
2875
2592
 
@@ -2882,7 +2599,9 @@ export class ClearingHouse {
2882
2599
  state: await this.getStatePublicKey(),
2883
2600
  authority: this.wallet.publicKey,
2884
2601
  user: userAccountPublicKey,
2602
+ userStats: userStatsPublicKey,
2885
2603
  liquidator: liquidatorPublicKey,
2604
+ liquidatorStats: liquidatorStatsPublicKey,
2886
2605
  },
2887
2606
  remainingAccounts: remainingAccounts,
2888
2607
  }
@@ -2913,12 +2632,18 @@ export class ClearingHouse {
2913
2632
  userAccount: UserAccount,
2914
2633
  marketIndex: number
2915
2634
  ): Promise<TransactionInstruction> {
2635
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
2636
+ this.program.programId,
2637
+ userAccount.authority
2638
+ );
2639
+
2916
2640
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2641
+ const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
2917
2642
 
2918
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2919
- writablePerpMarketIndex: marketIndex,
2643
+ const remainingAccounts = this.getRemainingAccounts({
2644
+ userAccounts: [this.getUserAccount(), userAccount],
2645
+ writablePerpMarketIndexes: [marketIndex],
2920
2646
  writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
2921
- counterPartyUserAccount: userAccount,
2922
2647
  });
2923
2648
 
2924
2649
  const spotMarket = this.getSpotMarketAccount(marketIndex);
@@ -2931,7 +2656,9 @@ export class ClearingHouse {
2931
2656
  state: await this.getStatePublicKey(),
2932
2657
  authority: this.wallet.publicKey,
2933
2658
  user: userAccountPublicKey,
2659
+ userStats: userStatsPublicKey,
2934
2660
  liquidator: liquidatorPublicKey,
2661
+ liquidatorStats: liquidatorStatsPublicKey,
2935
2662
  spotMarketVault: spotMarket.vault,
2936
2663
  insuranceFundVault: spotMarket.insuranceFundVault,
2937
2664
  clearingHouseSigner: this.getSignerPublicKey(),
@@ -2942,14 +2669,14 @@ export class ClearingHouse {
2942
2669
  );
2943
2670
  }
2944
2671
 
2945
- public async resolveBorrowBankruptcy(
2672
+ public async resolveSpotBankruptcy(
2946
2673
  userAccountPublicKey: PublicKey,
2947
2674
  userAccount: UserAccount,
2948
2675
  marketIndex: number
2949
2676
  ): Promise<TransactionSignature> {
2950
2677
  const { txSig } = await this.txSender.send(
2951
2678
  wrapInTx(
2952
- await this.getResolveBorrowBankruptcyIx(
2679
+ await this.getResolveSpotBankruptcyIx(
2953
2680
  userAccountPublicKey,
2954
2681
  userAccount,
2955
2682
  marketIndex
@@ -2961,25 +2688,33 @@ export class ClearingHouse {
2961
2688
  return txSig;
2962
2689
  }
2963
2690
 
2964
- public async getResolveBorrowBankruptcyIx(
2691
+ public async getResolveSpotBankruptcyIx(
2965
2692
  userAccountPublicKey: PublicKey,
2966
2693
  userAccount: UserAccount,
2967
2694
  marketIndex: number
2968
2695
  ): Promise<TransactionInstruction> {
2696
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
2697
+ this.program.programId,
2698
+ userAccount.authority
2699
+ );
2700
+
2969
2701
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2702
+ const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
2970
2703
 
2971
- const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2704
+ const remainingAccounts = this.getRemainingAccounts({
2705
+ userAccounts: [this.getUserAccount(), userAccount],
2972
2706
  writableSpotMarketIndexes: [marketIndex],
2973
- counterPartyUserAccount: userAccount,
2974
2707
  });
2975
2708
 
2976
2709
  const spotMarket = this.getSpotMarketAccount(marketIndex);
2977
2710
 
2978
- return await this.program.instruction.resolveBorrowBankruptcy(marketIndex, {
2711
+ return await this.program.instruction.resolveSpotBankruptcy(marketIndex, {
2979
2712
  accounts: {
2980
2713
  state: await this.getStatePublicKey(),
2981
2714
  authority: this.wallet.publicKey,
2982
2715
  user: userAccountPublicKey,
2716
+ userStats: userStatsPublicKey,
2717
+ liquidatorStats: liquidatorStatsPublicKey,
2983
2718
  liquidator: liquidatorPublicKey,
2984
2719
  spotMarketVault: spotMarket.vault,
2985
2720
  insuranceFundVault: spotMarket.insuranceFundVault,
@@ -2990,153 +2725,6 @@ export class ClearingHouse {
2990
2725
  });
2991
2726
  }
2992
2727
 
2993
- getRemainingAccountsWithCounterparty(params: {
2994
- counterPartyUserAccount: UserAccount;
2995
- writablePerpMarketIndex?: number;
2996
- writableSpotMarketIndexes?: number[];
2997
- }): AccountMeta[] {
2998
- const counterPartyUserAccount = params.counterPartyUserAccount;
2999
-
3000
- const oracleAccountMap = new Map<string, AccountMeta>();
3001
- const spotMarketAccountMap = new Map<number, AccountMeta>();
3002
- const marketAccountMap = new Map<number, AccountMeta>();
3003
- for (const spotPosition of counterPartyUserAccount.spotPositions) {
3004
- if (!isSpotPositionAvailable(spotPosition)) {
3005
- const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
3006
- spotMarketAccountMap.set(spotPosition.marketIndex, {
3007
- pubkey: spotMarket.pubkey,
3008
- isSigner: false,
3009
- isWritable: false,
3010
- });
3011
-
3012
- if (!spotMarket.oracle.equals(PublicKey.default)) {
3013
- oracleAccountMap.set(spotMarket.oracle.toString(), {
3014
- pubkey: spotMarket.oracle,
3015
- isSigner: false,
3016
- isWritable: false,
3017
- });
3018
- }
3019
- }
3020
- }
3021
- for (const position of counterPartyUserAccount.perpPositions) {
3022
- if (!positionIsAvailable(position)) {
3023
- const market = this.getPerpMarketAccount(position.marketIndex);
3024
- marketAccountMap.set(position.marketIndex, {
3025
- pubkey: market.pubkey,
3026
- isWritable: false,
3027
- isSigner: false,
3028
- });
3029
- oracleAccountMap.set(market.amm.oracle.toString(), {
3030
- pubkey: market.amm.oracle,
3031
- isWritable: false,
3032
- isSigner: false,
3033
- });
3034
- }
3035
- }
3036
-
3037
- const userAccountAndSlot = this.getUserAccountAndSlot();
3038
- if (!userAccountAndSlot) {
3039
- throw Error(
3040
- 'No user account found. Most likely user account does not exist or failed to fetch account'
3041
- );
3042
- }
3043
- const { data: userAccount, slot: lastUserPositionsSlot } =
3044
- userAccountAndSlot;
3045
-
3046
- for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
3047
- // if cache has more recent slot than user positions account slot, add market to remaining accounts
3048
- // otherwise remove from slot
3049
- if (slot > lastUserPositionsSlot) {
3050
- const marketAccount = this.getPerpMarketAccount(marketIndexNum);
3051
- marketAccountMap.set(marketIndexNum, {
3052
- pubkey: marketAccount.pubkey,
3053
- isSigner: false,
3054
- isWritable: false,
3055
- });
3056
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
3057
- pubkey: marketAccount.amm.oracle,
3058
- isSigner: false,
3059
- isWritable: false,
3060
- });
3061
- } else {
3062
- this.marketLastSlotCache.delete(marketIndexNum);
3063
- }
3064
- }
3065
- for (const spotPosition of userAccount.spotPositions) {
3066
- if (!isSpotPositionAvailable(spotPosition)) {
3067
- const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
3068
- spotMarketAccountMap.set(spotPosition.marketIndex, {
3069
- pubkey: spotMarket.pubkey,
3070
- isSigner: false,
3071
- isWritable: false,
3072
- });
3073
-
3074
- if (!spotMarket.oracle.equals(PublicKey.default)) {
3075
- oracleAccountMap.set(spotMarket.oracle.toString(), {
3076
- pubkey: spotMarket.oracle,
3077
- isSigner: false,
3078
- isWritable: false,
3079
- });
3080
- }
3081
- }
3082
- }
3083
- for (const position of userAccount.perpPositions) {
3084
- if (!positionIsAvailable(position)) {
3085
- const market = this.getPerpMarketAccount(position.marketIndex);
3086
- marketAccountMap.set(position.marketIndex, {
3087
- pubkey: market.pubkey,
3088
- isWritable: false,
3089
- isSigner: false,
3090
- });
3091
- oracleAccountMap.set(market.amm.oracle.toString(), {
3092
- pubkey: market.amm.oracle,
3093
- isWritable: false,
3094
- isSigner: false,
3095
- });
3096
- }
3097
- }
3098
-
3099
- if (params.writablePerpMarketIndex !== undefined) {
3100
- const market = this.getPerpMarketAccount(params.writablePerpMarketIndex);
3101
- marketAccountMap.set(market.marketIndex, {
3102
- pubkey: market.pubkey,
3103
- isSigner: false,
3104
- isWritable: true,
3105
- });
3106
- oracleAccountMap.set(market.amm.oracle.toString(), {
3107
- pubkey: market.amm.oracle,
3108
- isSigner: false,
3109
- isWritable: false,
3110
- });
3111
- }
3112
-
3113
- if (params.writableSpotMarketIndexes !== undefined) {
3114
- for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
3115
- const spotMarketAccount = this.getSpotMarketAccount(
3116
- writableSpotMarketIndex
3117
- );
3118
- spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
3119
- pubkey: spotMarketAccount.pubkey,
3120
- isSigner: false,
3121
- isWritable: true,
3122
- });
3123
- if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
3124
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
3125
- pubkey: spotMarketAccount.oracle,
3126
- isSigner: false,
3127
- isWritable: false,
3128
- });
3129
- }
3130
- }
3131
- }
3132
-
3133
- return [
3134
- ...oracleAccountMap.values(),
3135
- ...spotMarketAccountMap.values(),
3136
- ...marketAccountMap.values(),
3137
- ];
3138
- }
3139
-
3140
2728
  public async updateFundingRate(
3141
2729
  oracle: PublicKey,
3142
2730
  marketIndex: number
@@ -3163,10 +2751,10 @@ export class ClearingHouse {
3163
2751
  }
3164
2752
 
3165
2753
  public async settleFundingPayment(
3166
- userAccount: PublicKey
2754
+ userAccountPublicKey: PublicKey
3167
2755
  ): Promise<TransactionSignature> {
3168
2756
  const { txSig } = await this.txSender.send(
3169
- wrapInTx(await this.getSettleFundingPaymentIx(userAccount)),
2757
+ wrapInTx(await this.getSettleFundingPaymentIx(userAccountPublicKey)),
3170
2758
  [],
3171
2759
  this.opts
3172
2760
  );
@@ -3174,33 +2762,28 @@ export class ClearingHouse {
3174
2762
  }
3175
2763
 
3176
2764
  public async getSettleFundingPaymentIx(
3177
- userAccount: PublicKey
2765
+ userAccountPublicKey: PublicKey
3178
2766
  ): Promise<TransactionInstruction> {
3179
- const user = (await this.program.account.user.fetch(
3180
- userAccount
2767
+ const userAccount = (await this.program.account.user.fetch(
2768
+ userAccountPublicKey
3181
2769
  )) as UserAccount;
3182
2770
 
3183
- const userPositions = user.perpPositions;
3184
-
3185
- const remainingAccounts = [];
3186
- for (const position of userPositions) {
2771
+ const writablePerpMarketIndexes = [];
2772
+ for (const position of userAccount.perpPositions) {
3187
2773
  if (!positionIsAvailable(position)) {
3188
- const marketPublicKey = await getMarketPublicKey(
3189
- this.program.programId,
3190
- position.marketIndex
3191
- );
3192
- remainingAccounts.push({
3193
- pubkey: marketPublicKey,
3194
- isWritable: false,
3195
- isSigner: false,
3196
- });
2774
+ writablePerpMarketIndexes.push(position.marketIndex);
3197
2775
  }
3198
2776
  }
3199
2777
 
2778
+ const remainingAccounts = this.getRemainingAccounts({
2779
+ userAccounts: [userAccount],
2780
+ writablePerpMarketIndexes,
2781
+ });
2782
+
3200
2783
  return await this.program.instruction.settleFundingPayment({
3201
2784
  accounts: {
3202
2785
  state: await this.getStatePublicKey(),
3203
- user: userAccount,
2786
+ user: userAccountPublicKey,
3204
2787
  },
3205
2788
  remainingAccounts,
3206
2789
  });
@@ -3274,7 +2857,9 @@ export class ClearingHouse {
3274
2857
  );
3275
2858
 
3276
2859
  const remainingAccounts = this.getRemainingAccounts({
3277
- writableSpotMarketIndex: marketIndex,
2860
+ userAccounts: [this.getUserAccount()],
2861
+ useMarketLastSlotCache: true,
2862
+ writableSpotMarketIndexes: [marketIndex],
3278
2863
  });
3279
2864
 
3280
2865
  return await this.program.rpc.addInsuranceFundStake(marketIndex, amount, {
@@ -3284,7 +2869,9 @@ export class ClearingHouse {
3284
2869
  insuranceFundStake: ifStakeAccountPublicKey,
3285
2870
  userStats: this.getUserStatsAccountPublicKey(),
3286
2871
  authority: this.wallet.publicKey,
2872
+ spotMarketVault: spotMarket.vault,
3287
2873
  insuranceFundVault: spotMarket.insuranceFundVault,
2874
+ clearingHouseSigner: this.getSignerPublicKey(),
3288
2875
  userTokenAccount: collateralAccountPublicKey,
3289
2876
  tokenProgram: TOKEN_PROGRAM_ID,
3290
2877
  },
@@ -3304,7 +2891,9 @@ export class ClearingHouse {
3304
2891
  );
3305
2892
 
3306
2893
  const remainingAccounts = this.getRemainingAccounts({
3307
- writableSpotMarketIndex: marketIndex,
2894
+ userAccounts: [this.getUserAccount()],
2895
+ useMarketLastSlotCache: true,
2896
+ writableSpotMarketIndexes: [marketIndex],
3308
2897
  });
3309
2898
 
3310
2899
  return await this.program.rpc.requestRemoveInsuranceFundStake(
@@ -3318,8 +2907,6 @@ export class ClearingHouse {
3318
2907
  userStats: this.getUserStatsAccountPublicKey(),
3319
2908
  authority: this.wallet.publicKey,
3320
2909
  insuranceFundVault: spotMarketAccount.insuranceFundVault,
3321
- // userTokenAccount: collateralAccountPublicKey,
3322
- // tokenProgram: TOKEN_PROGRAM_ID,
3323
2910
  },
3324
2911
  remainingAccounts,
3325
2912
  }
@@ -3337,7 +2924,9 @@ export class ClearingHouse {
3337
2924
  );
3338
2925
 
3339
2926
  const remainingAccounts = this.getRemainingAccounts({
3340
- writableSpotMarketIndex: marketIndex,
2927
+ userAccounts: [this.getUserAccount()],
2928
+ useMarketLastSlotCache: true,
2929
+ writableSpotMarketIndexes: [marketIndex],
3341
2930
  });
3342
2931
 
3343
2932
  return await this.program.rpc.cancelRequestRemoveInsuranceFundStake(
@@ -3350,8 +2939,6 @@ export class ClearingHouse {
3350
2939
  userStats: this.getUserStatsAccountPublicKey(),
3351
2940
  authority: this.wallet.publicKey,
3352
2941
  insuranceFundVault: spotMarketAccount.insuranceFundVault,
3353
- // userTokenAccount: collateralAccountPublicKey,
3354
- // tokenProgram: TOKEN_PROGRAM_ID,
3355
2942
  },
3356
2943
  remainingAccounts,
3357
2944
  }
@@ -3370,7 +2957,9 @@ export class ClearingHouse {
3370
2957
  );
3371
2958
 
3372
2959
  const remainingAccounts = this.getRemainingAccounts({
3373
- writableSpotMarketIndex: marketIndex,
2960
+ userAccounts: [this.getUserAccount()],
2961
+ useMarketLastSlotCache: true,
2962
+ writableSpotMarketIndexes: [marketIndex],
3374
2963
  });
3375
2964
 
3376
2965
  return await this.program.rpc.removeInsuranceFundStake(marketIndex, {
@@ -3395,7 +2984,9 @@ export class ClearingHouse {
3395
2984
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
3396
2985
 
3397
2986
  const remainingAccounts = this.getRemainingAccounts({
3398
- writableSpotMarketIndex: marketIndex,
2987
+ userAccounts: [this.getUserAccount()],
2988
+ useMarketLastSlotCache: true,
2989
+ writableSpotMarketIndexes: [marketIndex],
3399
2990
  });
3400
2991
 
3401
2992
  return await this.program.rpc.settleRevenueToInsuranceFund(marketIndex, {
@@ -3430,8 +3021,10 @@ export class ClearingHouse {
3430
3021
  perpMarketIndex: number
3431
3022
  ): Promise<TransactionInstruction> {
3432
3023
  const remainingAccounts = this.getRemainingAccounts({
3433
- writablePerpMarketIndex: perpMarketIndex,
3434
- writableSpotMarketIndex: spotMarketIndex,
3024
+ userAccounts: [this.getUserAccount()],
3025
+ useMarketLastSlotCache: true,
3026
+ writablePerpMarketIndexes: [perpMarketIndex],
3027
+ writableSpotMarketIndexes: [spotMarketIndex],
3435
3028
  });
3436
3029
 
3437
3030
  const spotMarket = this.getSpotMarketAccount(spotMarketIndex);