@drift-labs/sdk 2.31.1-beta.8 → 2.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/VERSION +1 -1
  2. package/lib/constants/perpMarkets.js +20 -0
  3. package/lib/dlob/orderBookLevels.js +2 -2
  4. package/lib/driftClient.d.ts +53 -5
  5. package/lib/driftClient.js +203 -196
  6. package/lib/idl/drift.json +31 -1
  7. package/lib/index.d.ts +3 -0
  8. package/lib/index.js +3 -0
  9. package/lib/marinade/index.d.ts +11 -0
  10. package/lib/marinade/index.js +36 -0
  11. package/lib/marinade/types.d.ts +1963 -0
  12. package/lib/marinade/types.js +1965 -0
  13. package/lib/math/spotBalance.d.ts +9 -2
  14. package/lib/math/spotBalance.js +54 -6
  15. package/lib/math/superStake.d.ts +22 -0
  16. package/lib/math/superStake.js +108 -0
  17. package/lib/math/utils.d.ts +1 -0
  18. package/lib/math/utils.js +5 -1
  19. package/lib/orderParams.d.ts +18 -5
  20. package/lib/orderParams.js +17 -1
  21. package/lib/user.d.ts +45 -1
  22. package/lib/user.js +227 -9
  23. package/package.json +1 -1
  24. package/src/assert/assert.js +9 -0
  25. package/src/constants/perpMarkets.ts +20 -0
  26. package/src/dlob/orderBookLevels.ts +3 -2
  27. package/src/driftClient.ts +383 -225
  28. package/src/idl/drift.json +31 -1
  29. package/src/index.ts +3 -0
  30. package/src/marinade/idl/idl.json +1962 -0
  31. package/src/marinade/index.ts +64 -0
  32. package/src/marinade/types.ts +3925 -0
  33. package/src/math/spotBalance.ts +83 -5
  34. package/src/math/superStake.ts +148 -0
  35. package/src/math/utils.ts +4 -0
  36. package/src/orderParams.ts +35 -5
  37. package/src/token/index.js +38 -0
  38. package/src/user.ts +453 -15
  39. package/src/util/computeUnits.js +27 -0
  40. package/src/util/promiseTimeout.js +14 -0
  41. package/src/util/tps.js +27 -0
  42. package/tests/spot/test.ts +156 -0
@@ -52,6 +52,8 @@ const market_1 = require("./math/market");
52
52
  const fetch_1 = require("./accounts/fetch");
53
53
  const spotMarket_1 = require("./math/spotMarket");
54
54
  const memcmp_1 = require("./memcmp");
55
+ const marinade_1 = require("./marinade");
56
+ const orderParams_1 = require("./orderParams");
55
57
  /**
56
58
  * # DriftClient
57
59
  * 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.
@@ -69,6 +71,8 @@ class DriftClient {
69
71
  this._isSubscribed = false;
70
72
  this.perpMarketLastSlotCache = new Map();
71
73
  this.spotMarketLastSlotCache = new Map();
74
+ this.mustIncludePerpMarketIndexes = new Set();
75
+ this.mustIncludeSpotMarketIndexes = new Set();
72
76
  this.connection = config.connection;
73
77
  this.wallet = config.wallet;
74
78
  this.opts = config.opts || anchor_1.AnchorProvider.defaultOptions();
@@ -505,6 +509,27 @@ class DriftClient {
505
509
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
506
510
  return txSig;
507
511
  }
512
+ async getUpdateUserMarginTradingEnabledIx(marginTradingEnabled, subAccountId = 0, userAccountPublicKey) {
513
+ const userAccountPublicKeyToUse = userAccountPublicKey ||
514
+ (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId);
515
+ await this.addUser(subAccountId, this.wallet.publicKey);
516
+ let remainingAccounts;
517
+ try {
518
+ remainingAccounts = this.getRemainingAccounts({
519
+ userAccounts: [this.getUserAccount(subAccountId)],
520
+ });
521
+ }
522
+ catch (err) {
523
+ remainingAccounts = [];
524
+ }
525
+ return await this.program.instruction.updateUserMarginTradingEnabled(subAccountId, marginTradingEnabled, {
526
+ accounts: {
527
+ user: userAccountPublicKeyToUse,
528
+ authority: this.wallet.publicKey,
529
+ },
530
+ remainingAccounts,
531
+ });
532
+ }
508
533
  async updateUserMarginTradingEnabled(marginTradingEnabled, subAccountId = 0) {
509
534
  const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId);
510
535
  await this.addUser(subAccountId, this.wallet.publicKey);
@@ -624,10 +649,16 @@ class DriftClient {
624
649
  authority = authority !== null && authority !== void 0 ? authority : this.authority;
625
650
  const userMapKey = this.getUserMapKey(subAccountId, authority);
626
651
  if (!this.users.has(userMapKey)) {
627
- throw new Error(`Clearing House has no user for user id ${userMapKey}`);
652
+ throw new Error(`DriftClient has no user for user id ${userMapKey}`);
628
653
  }
629
654
  return this.users.get(userMapKey);
630
655
  }
656
+ hasUser(subAccountId, authority) {
657
+ subAccountId = subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId;
658
+ authority = authority !== null && authority !== void 0 ? authority : this.authority;
659
+ const userMapKey = this.getUserMapKey(subAccountId, authority);
660
+ return this.users.has(userMapKey);
661
+ }
631
662
  getUsers() {
632
663
  // delegate users get added to the end
633
664
  return [...this.users.values()]
@@ -710,6 +741,21 @@ class DriftClient {
710
741
  amount = typeof amount === 'number' ? new anchor_1.BN(amount) : amount;
711
742
  return amount.mul(numericConstants_1.PRICE_PRECISION);
712
743
  }
744
+ /**
745
+ * Each drift instruction must include perp and sport market accounts in the ix remaining accounts.
746
+ * Use this function to force a subset of markets to be included in the remaining accounts for every ix
747
+ *
748
+ * @param perpMarketIndexes
749
+ * @param spotMarketIndexes
750
+ */
751
+ mustIncludeMarketsInIx({ perpMarketIndexes, spotMarketIndexes, }) {
752
+ perpMarketIndexes.forEach((perpMarketIndex) => {
753
+ this.mustIncludePerpMarketIndexes.add(perpMarketIndex);
754
+ });
755
+ spotMarketIndexes.forEach((spotMarketIndex) => {
756
+ this.mustIncludeSpotMarketIndexes.add(spotMarketIndex);
757
+ });
758
+ }
713
759
  getRemainingAccounts(params) {
714
760
  var _a;
715
761
  const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } = this.getRemainingAccountMapsForUsers(params.userAccounts);
@@ -719,30 +765,7 @@ class DriftClient {
719
765
  // if cache has more recent slot than user positions account slot, add market to remaining accounts
720
766
  // otherwise remove from slot
721
767
  if (slot > lastUserSlot) {
722
- const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
723
- perpMarketAccountMap.set(marketIndex, {
724
- pubkey: perpMarketAccount.pubkey,
725
- isSigner: false,
726
- isWritable: false,
727
- });
728
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
729
- pubkey: perpMarketAccount.amm.oracle,
730
- isSigner: false,
731
- isWritable: false,
732
- });
733
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
734
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
735
- pubkey: spotMarketAccount.pubkey,
736
- isSigner: false,
737
- isWritable: false,
738
- });
739
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
740
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
741
- pubkey: spotMarketAccount.oracle,
742
- isSigner: false,
743
- isWritable: false,
744
- });
745
- }
768
+ this.addPerpMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
746
769
  }
747
770
  else {
748
771
  this.perpMarketLastSlotCache.delete(marketIndex);
@@ -752,19 +775,7 @@ class DriftClient {
752
775
  // if cache has more recent slot than user positions account slot, add market to remaining accounts
753
776
  // otherwise remove from slot
754
777
  if (slot > lastUserSlot) {
755
- const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
756
- spotMarketAccountMap.set(marketIndex, {
757
- pubkey: spotMarketAccount.pubkey,
758
- isSigner: false,
759
- isWritable: false,
760
- });
761
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
762
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
763
- pubkey: spotMarketAccount.oracle,
764
- isSigner: false,
765
- isWritable: false,
766
- });
767
- }
778
+ this.addSpotMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap);
768
779
  }
769
780
  else {
770
781
  this.spotMarketLastSlotCache.delete(marketIndex);
@@ -772,91 +783,32 @@ class DriftClient {
772
783
  }
773
784
  }
774
785
  if (params.readablePerpMarketIndex !== undefined) {
775
- const perpMarketAccount = this.getPerpMarketAccount(params.readablePerpMarketIndex);
776
- perpMarketAccountMap.set(params.readablePerpMarketIndex, {
777
- pubkey: perpMarketAccount.pubkey,
778
- isSigner: false,
779
- isWritable: false,
780
- });
781
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
782
- pubkey: perpMarketAccount.amm.oracle,
783
- isSigner: false,
784
- isWritable: false,
785
- });
786
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
787
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
788
- pubkey: spotMarketAccount.pubkey,
789
- isSigner: false,
790
- isWritable: false,
791
- });
792
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
793
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
794
- pubkey: spotMarketAccount.oracle,
795
- isSigner: false,
796
- isWritable: false,
797
- });
786
+ const readablePerpMarketIndexes = Array.isArray(params.readablePerpMarketIndex)
787
+ ? params.readablePerpMarketIndex
788
+ : [params.readablePerpMarketIndex];
789
+ for (const marketIndex of readablePerpMarketIndexes) {
790
+ this.addPerpMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
798
791
  }
799
792
  }
793
+ for (const perpMarketIndex of this.mustIncludePerpMarketIndexes.values()) {
794
+ this.addPerpMarketToRemainingAccountMaps(perpMarketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
795
+ }
800
796
  if (params.readableSpotMarketIndexes !== undefined) {
801
797
  for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
802
- const spotMarketAccount = this.getSpotMarketAccount(readableSpotMarketIndex);
803
- spotMarketAccountMap.set(readableSpotMarketIndex, {
804
- pubkey: spotMarketAccount.pubkey,
805
- isSigner: false,
806
- isWritable: false,
807
- });
808
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
809
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
810
- pubkey: spotMarketAccount.oracle,
811
- isSigner: false,
812
- isWritable: false,
813
- });
814
- }
798
+ this.addSpotMarketToRemainingAccountMaps(readableSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
815
799
  }
816
800
  }
801
+ for (const spotMarketIndex of this.mustIncludeSpotMarketIndexes.values()) {
802
+ this.addSpotMarketToRemainingAccountMaps(spotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
803
+ }
817
804
  if (params.writablePerpMarketIndexes !== undefined) {
818
805
  for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
819
- const perpMarketAccount = this.getPerpMarketAccount(writablePerpMarketIndex);
820
- perpMarketAccountMap.set(writablePerpMarketIndex, {
821
- pubkey: perpMarketAccount.pubkey,
822
- isSigner: false,
823
- isWritable: true,
824
- });
825
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
826
- pubkey: perpMarketAccount.amm.oracle,
827
- isSigner: false,
828
- isWritable: false,
829
- });
830
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
831
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
832
- pubkey: spotMarketAccount.pubkey,
833
- isSigner: false,
834
- isWritable: false,
835
- });
836
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
837
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
838
- pubkey: spotMarketAccount.oracle,
839
- isSigner: false,
840
- isWritable: false,
841
- });
842
- }
806
+ this.addPerpMarketToRemainingAccountMaps(writablePerpMarketIndex, true, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
843
807
  }
844
808
  }
845
809
  if (params.writableSpotMarketIndexes !== undefined) {
846
810
  for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
847
- const spotMarketAccount = this.getSpotMarketAccount(writableSpotMarketIndex);
848
- spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
849
- pubkey: spotMarketAccount.pubkey,
850
- isSigner: false,
851
- isWritable: true,
852
- });
853
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
854
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
855
- pubkey: spotMarketAccount.oracle,
856
- isSigner: false,
857
- isWritable: false,
858
- });
859
- }
811
+ this.addSpotMarketToRemainingAccountMaps(writableSpotMarketIndex, true, oracleAccountMap, spotMarketAccountMap);
860
812
  }
861
813
  }
862
814
  return [
@@ -865,6 +817,35 @@ class DriftClient {
865
817
  ...perpMarketAccountMap.values(),
866
818
  ];
867
819
  }
820
+ addPerpMarketToRemainingAccountMaps(marketIndex, writable, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap) {
821
+ const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
822
+ perpMarketAccountMap.set(marketIndex, {
823
+ pubkey: perpMarketAccount.pubkey,
824
+ isSigner: false,
825
+ isWritable: writable,
826
+ });
827
+ oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
828
+ pubkey: perpMarketAccount.amm.oracle,
829
+ isSigner: false,
830
+ isWritable: false,
831
+ });
832
+ this.addSpotMarketToRemainingAccountMaps(perpMarketAccount.quoteSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
833
+ }
834
+ addSpotMarketToRemainingAccountMaps(marketIndex, writable, oracleAccountMap, spotMarketAccountMap) {
835
+ const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
836
+ spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
837
+ pubkey: spotMarketAccount.pubkey,
838
+ isSigner: false,
839
+ isWritable: writable,
840
+ });
841
+ if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
842
+ oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
843
+ pubkey: spotMarketAccount.oracle,
844
+ isSigner: false,
845
+ isWritable: false,
846
+ });
847
+ }
848
+ }
868
849
  getRemainingAccountMapsForUsers(userAccounts) {
869
850
  const oracleAccountMap = new Map();
870
851
  const spotMarketAccountMap = new Map();
@@ -872,63 +853,16 @@ class DriftClient {
872
853
  for (const userAccount of userAccounts) {
873
854
  for (const spotPosition of userAccount.spotPositions) {
874
855
  if (!(0, spotPosition_1.isSpotPositionAvailable)(spotPosition)) {
875
- const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
876
- spotMarketAccountMap.set(spotPosition.marketIndex, {
877
- pubkey: spotMarket.pubkey,
878
- isSigner: false,
879
- isWritable: false,
880
- });
881
- if (!spotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
882
- oracleAccountMap.set(spotMarket.oracle.toString(), {
883
- pubkey: spotMarket.oracle,
884
- isSigner: false,
885
- isWritable: false,
886
- });
887
- }
856
+ this.addSpotMarketToRemainingAccountMaps(spotPosition.marketIndex, false, oracleAccountMap, spotMarketAccountMap);
888
857
  if (!spotPosition.openAsks.eq(numericConstants_1.ZERO) ||
889
858
  !spotPosition.openBids.eq(numericConstants_1.ZERO)) {
890
- const quoteSpotMarket = this.getQuoteSpotMarketAccount();
891
- spotMarketAccountMap.set(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, {
892
- pubkey: quoteSpotMarket.pubkey,
893
- isSigner: false,
894
- isWritable: false,
895
- });
896
- if (!quoteSpotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
897
- oracleAccountMap.set(quoteSpotMarket.oracle.toString(), {
898
- pubkey: quoteSpotMarket.oracle,
899
- isSigner: false,
900
- isWritable: false,
901
- });
902
- }
859
+ this.addSpotMarketToRemainingAccountMaps(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, false, oracleAccountMap, spotMarketAccountMap);
903
860
  }
904
861
  }
905
862
  }
906
863
  for (const position of userAccount.perpPositions) {
907
864
  if (!(0, position_1.positionIsAvailable)(position)) {
908
- const perpMarketAccount = this.getPerpMarketAccount(position.marketIndex);
909
- perpMarketAccountMap.set(position.marketIndex, {
910
- pubkey: perpMarketAccount.pubkey,
911
- isWritable: false,
912
- isSigner: false,
913
- });
914
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
915
- pubkey: perpMarketAccount.amm.oracle,
916
- isWritable: false,
917
- isSigner: false,
918
- });
919
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
920
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
921
- pubkey: spotMarketAccount.pubkey,
922
- isSigner: false,
923
- isWritable: false,
924
- });
925
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
926
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
927
- pubkey: spotMarketAccount.oracle,
928
- isSigner: false,
929
- isWritable: false,
930
- });
931
- }
865
+ this.addPerpMarketToRemainingAccountMaps(position.marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
932
866
  }
933
867
  }
934
868
  }
@@ -1082,7 +1016,7 @@ class DriftClient {
1082
1016
  return (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, associatedTokenAddress, this.wallet.publicKey, tokenMintAddress);
1083
1017
  }
1084
1018
  /**
1085
- * Creates the Clearing House User account for a user, and deposits some initial collateral
1019
+ * Creates the User account for a user, and deposits some initial collateral
1086
1020
  * @param amount
1087
1021
  * @param userTokenAccount
1088
1022
  * @param marketIndex
@@ -1460,13 +1394,8 @@ class DriftClient {
1460
1394
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
1461
1395
  return txSig;
1462
1396
  }
1463
- getOrderParams(optionalOrderParams, marketType) {
1464
- return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams, {
1465
- marketType,
1466
- });
1467
- }
1468
1397
  async getPlacePerpOrderIx(orderParams) {
1469
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
1398
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
1470
1399
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1471
1400
  const remainingAccounts = this.getRemainingAccounts({
1472
1401
  userAccounts: [this.getUserAccount()],
@@ -1639,23 +1568,48 @@ class DriftClient {
1639
1568
  });
1640
1569
  }
1641
1570
  async cancelAndPlaceOrders(cancelOrderParams, placeOrderParams, txParams) {
1642
- const tx = (0, utils_1.wrapInTx)(await this.getCancelOrdersIx(cancelOrderParams.marketType, cancelOrderParams.marketIndex, cancelOrderParams.direction), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice);
1643
- for (const placeOrderParam of placeOrderParams) {
1644
- const marketType = placeOrderParam.marketType;
1645
- if (!marketType) {
1646
- throw new Error('marketType must be set on placeOrderParams');
1571
+ const ixs = [
1572
+ await this.getCancelOrdersIx(cancelOrderParams.marketType, cancelOrderParams.marketIndex, cancelOrderParams.direction),
1573
+ await this.getPlaceOrdersIx(placeOrderParams),
1574
+ ];
1575
+ const tx = await this.buildTransaction(ixs, txParams);
1576
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
1577
+ return txSig;
1578
+ }
1579
+ async placeOrders(params, txParams) {
1580
+ const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getPlaceOrdersIx(params), txParams), [], this.opts);
1581
+ return txSig;
1582
+ }
1583
+ async getPlaceOrdersIx(params) {
1584
+ const userAccountPublicKey = await this.getUserAccountPublicKey();
1585
+ const readablePerpMarketIndex = [];
1586
+ const readableSpotMarketIndexes = [];
1587
+ for (const param of params) {
1588
+ if (!param.marketType) {
1589
+ throw new Error('must set param.marketType');
1647
1590
  }
1648
- let ix;
1649
- if ((0, types_1.isVariant)(marketType, 'perp')) {
1650
- ix = this.getPlacePerpOrderIx(placeOrderParam);
1591
+ if ((0, types_1.isVariant)(param.marketType, 'perp')) {
1592
+ readablePerpMarketIndex.push(param.marketIndex);
1651
1593
  }
1652
1594
  else {
1653
- ix = this.getPlaceSpotOrderIx(placeOrderParam);
1595
+ readableSpotMarketIndexes.push(param.marketIndex);
1654
1596
  }
1655
- tx.add(ix);
1656
1597
  }
1657
- const { txSig } = await this.sendTransaction(tx, [], this.opts);
1658
- return txSig;
1598
+ const remainingAccounts = this.getRemainingAccounts({
1599
+ userAccounts: [this.getUserAccount()],
1600
+ readablePerpMarketIndex,
1601
+ readableSpotMarketIndexes,
1602
+ useMarketLastSlotCache: true,
1603
+ });
1604
+ return await this.program.instruction.placeOrders(params, {
1605
+ accounts: {
1606
+ state: await this.getStatePublicKey(),
1607
+ user: userAccountPublicKey,
1608
+ userStats: this.getUserStatsAccountPublicKey(),
1609
+ authority: this.wallet.publicKey,
1610
+ },
1611
+ remainingAccounts,
1612
+ });
1659
1613
  }
1660
1614
  async fillPerpOrder(userAccountPublicKey, user, order, makerInfo, referrerInfo, txParams) {
1661
1615
  const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getFillPerpOrderIx(userAccountPublicKey, user, order, makerInfo, referrerInfo), txParams), [], this.opts);
@@ -1741,7 +1695,7 @@ class DriftClient {
1741
1695
  return txSig;
1742
1696
  }
1743
1697
  async getPlaceSpotOrderIx(orderParams) {
1744
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.SPOT);
1698
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
1745
1699
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1746
1700
  const remainingAccounts = this.getRemainingAccounts({
1747
1701
  userAccounts: [this.getUserAccount()],
@@ -1991,6 +1945,25 @@ class DriftClient {
1991
1945
  * @param txParams
1992
1946
  */
1993
1947
  async swap({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, txParams, }) {
1948
+ const { ixs, lookupTables } = await this.getJupiterSwapIx({
1949
+ jupiterClient,
1950
+ outMarketIndex,
1951
+ inMarketIndex,
1952
+ outAssociatedTokenAccount,
1953
+ inAssociatedTokenAccount,
1954
+ amount,
1955
+ slippageBps,
1956
+ swapMode,
1957
+ route,
1958
+ reduceOnly,
1959
+ });
1960
+ const tx = (await this.buildTransaction(ixs, txParams, 0, lookupTables));
1961
+ const { txSig, slot } = await this.sendTransaction(tx);
1962
+ this.spotMarketLastSlotCache.set(outMarketIndex, slot);
1963
+ this.spotMarketLastSlotCache.set(inMarketIndex, slot);
1964
+ return txSig;
1965
+ }
1966
+ async getJupiterSwapIx({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, route, reduceOnly, userAccountPublicKey, }) {
1994
1967
  const outMarket = this.getSpotMarketAccount(outMarketIndex);
1995
1968
  const inMarket = this.getSpotMarketAccount(inMarketIndex);
1996
1969
  if (!route) {
@@ -2041,18 +2014,15 @@ class DriftClient {
2041
2014
  inTokenAccount: inAssociatedTokenAccount,
2042
2015
  outTokenAccount: outAssociatedTokenAccount,
2043
2016
  reduceOnly,
2017
+ userAccountPublicKey,
2044
2018
  });
2045
- const instructions = [
2019
+ const ixs = [
2046
2020
  ...preInstructions,
2047
2021
  beginSwapIx,
2048
2022
  ...jupiterInstructions,
2049
2023
  endSwapIx,
2050
2024
  ];
2051
- const tx = (await this.buildTransaction(instructions, txParams, 0, lookupTables));
2052
- const { txSig, slot } = await this.sendTransaction(tx);
2053
- this.spotMarketLastSlotCache.set(outMarketIndex, slot);
2054
- this.spotMarketLastSlotCache.set(inMarketIndex, slot);
2055
- return txSig;
2025
+ return { ixs, lookupTables };
2056
2026
  }
2057
2027
  /**
2058
2028
  * Get the drift begin_swap and end_swap instructions
@@ -2063,11 +2033,14 @@ class DriftClient {
2063
2033
  * @param inTokenAccount the token account to move the tokens being sold
2064
2034
  * @param outTokenAccount the token account to receive the tokens being bought
2065
2035
  * @param limitPrice the limit price of the swap
2036
+ * @param reduceOnly
2037
+ * @param userAccountPublicKey optional, specify a custom userAccountPublicKey to use instead of getting the current user account; can be helpful if the account is being created within the current tx
2066
2038
  */
2067
- async getSwapIx({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, }) {
2068
- const userAccountPublicKey = await this.getUserAccountPublicKey();
2039
+ async getSwapIx({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, userAccountPublicKey, }) {
2040
+ const userAccountPublicKeyToUse = userAccountPublicKey || (await this.getUserAccountPublicKey());
2041
+ const userAccounts = this.hasUser() ? [this.getUserAccount()] : [];
2069
2042
  const remainingAccounts = this.getRemainingAccounts({
2070
- userAccounts: [this.getUserAccount()],
2043
+ userAccounts,
2071
2044
  writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
2072
2045
  });
2073
2046
  const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
@@ -2075,7 +2048,7 @@ class DriftClient {
2075
2048
  const beginSwapIx = await this.program.instruction.beginSwap(inMarketIndex, outMarketIndex, amountIn, {
2076
2049
  accounts: {
2077
2050
  state: await this.getStatePublicKey(),
2078
- user: userAccountPublicKey,
2051
+ user: userAccountPublicKeyToUse,
2079
2052
  userStats: this.getUserStatsAccountPublicKey(),
2080
2053
  authority: this.authority,
2081
2054
  outSpotMarketVault: outSpotMarket.vault,
@@ -2091,7 +2064,7 @@ class DriftClient {
2091
2064
  const endSwapIx = await this.program.instruction.endSwap(inMarketIndex, outMarketIndex, limitPrice !== null && limitPrice !== void 0 ? limitPrice : null, reduceOnly !== null && reduceOnly !== void 0 ? reduceOnly : null, {
2092
2065
  accounts: {
2093
2066
  state: await this.getStatePublicKey(),
2094
- user: userAccountPublicKey,
2067
+ user: userAccountPublicKeyToUse,
2095
2068
  userStats: this.getUserStatsAccountPublicKey(),
2096
2069
  authority: this.authority,
2097
2070
  outSpotMarketVault: outSpotMarket.vault,
@@ -2106,6 +2079,40 @@ class DriftClient {
2106
2079
  });
2107
2080
  return { beginSwapIx, endSwapIx };
2108
2081
  }
2082
+ async stakeForMSOL({ amount }) {
2083
+ const ixs = await this.getStakeForMSOLIx({ amount });
2084
+ const tx = await this.buildTransaction(ixs);
2085
+ return this.sendTransaction(tx);
2086
+ }
2087
+ async getStakeForMSOLIx({ amount, userAccountPublicKey, }) {
2088
+ const wSOLMint = this.getSpotMarketAccount(1).mint;
2089
+ const mSOLAccount = await this.getAssociatedTokenAccount(2);
2090
+ const wSOLAccount = await this.getAssociatedTokenAccount(1, false);
2091
+ const wSOLAccountExists = await this.checkIfAccountExists(wSOLAccount);
2092
+ const closeWSOLIx = (0, spl_token_1.createCloseAccountInstruction)(wSOLAccount, this.wallet.publicKey, this.wallet.publicKey);
2093
+ const createWSOLIx = await this.createAssociatedTokenAccountIdempotentInstruction(wSOLAccount, this.wallet.publicKey, this.wallet.publicKey, wSOLMint);
2094
+ const { beginSwapIx, endSwapIx } = await this.getSwapIx({
2095
+ inMarketIndex: 1,
2096
+ outMarketIndex: 2,
2097
+ amountIn: amount,
2098
+ inTokenAccount: wSOLAccount,
2099
+ outTokenAccount: mSOLAccount,
2100
+ userAccountPublicKey,
2101
+ });
2102
+ const program = (0, marinade_1.getMarinadeFinanceProgram)(this.provider);
2103
+ const depositIx = await (0, marinade_1.getMarinadeDepositIx)({
2104
+ program,
2105
+ mSOLAccount: mSOLAccount,
2106
+ transferFrom: this.wallet.publicKey,
2107
+ amount,
2108
+ });
2109
+ const ixs = [];
2110
+ if (!wSOLAccountExists) {
2111
+ ixs.push(createWSOLIx);
2112
+ }
2113
+ ixs.push(beginSwapIx, closeWSOLIx, depositIx, createWSOLIx, endSwapIx);
2114
+ return ixs;
2115
+ }
2109
2116
  async triggerOrder(userAccountPublicKey, user, order, txParams) {
2110
2117
  const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getTriggerOrderIx(userAccountPublicKey, user, order), txParams), [], this.opts);
2111
2118
  return txSig;
@@ -2201,7 +2208,7 @@ class DriftClient {
2201
2208
  return txSig;
2202
2209
  }
2203
2210
  async getPlaceAndTakePerpOrderIx(orderParams, makerInfo, referrerInfo) {
2204
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
2211
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
2205
2212
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
2206
2213
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2207
2214
  makerInfo = Array.isArray(makerInfo)
@@ -2262,7 +2269,7 @@ class DriftClient {
2262
2269
  return txSig;
2263
2270
  }
2264
2271
  async getPlaceAndMakePerpOrderIx(orderParams, takerInfo, referrerInfo) {
2265
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
2272
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
2266
2273
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
2267
2274
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2268
2275
  const remainingAccounts = this.getRemainingAccounts({
@@ -2302,7 +2309,7 @@ class DriftClient {
2302
2309
  return txSig;
2303
2310
  }
2304
2311
  async getPlaceAndTakeSpotOrderIx(orderParams, fulfillmentConfig, makerInfo, referrerInfo) {
2305
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.SPOT);
2312
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
2306
2313
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
2307
2314
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2308
2315
  const userAccounts = [this.getUserAccount()];
@@ -2361,7 +2368,7 @@ class DriftClient {
2361
2368
  return txSig;
2362
2369
  }
2363
2370
  async getPlaceAndMakeSpotOrderIx(orderParams, takerInfo, fulfillmentConfig, referrerInfo) {
2364
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.SPOT);
2371
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
2365
2372
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
2366
2373
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2367
2374
  const remainingAccounts = this.getRemainingAccounts({
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.31.1-beta.7",
2
+ "version": "2.32.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -710,6 +710,36 @@
710
710
  }
711
711
  ]
712
712
  },
713
+ {
714
+ "name": "placeOrders",
715
+ "accounts": [
716
+ {
717
+ "name": "state",
718
+ "isMut": false,
719
+ "isSigner": false
720
+ },
721
+ {
722
+ "name": "user",
723
+ "isMut": true,
724
+ "isSigner": false
725
+ },
726
+ {
727
+ "name": "authority",
728
+ "isMut": false,
729
+ "isSigner": true
730
+ }
731
+ ],
732
+ "args": [
733
+ {
734
+ "name": "params",
735
+ "type": {
736
+ "vec": {
737
+ "defined": "OrderParams"
738
+ }
739
+ }
740
+ }
741
+ ]
742
+ },
713
743
  {
714
744
  "name": "beginSwap",
715
745
  "accounts": [
package/lib/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export * from './accounts/pollingOracleAccountSubscriber';
16
16
  export * from './accounts/pollingTokenAccountSubscriber';
17
17
  export * from './accounts/pollingUserAccountSubscriber';
18
18
  export * from './accounts/pollingUserStatsAccountSubscriber';
19
+ export * from './accounts/mockUserAccountSubscriber';
19
20
  export * from './accounts/types';
20
21
  export * from './addresses/pda';
21
22
  export * from './adminClient';
@@ -45,6 +46,8 @@ export * from './math/orders';
45
46
  export * from './math/repeg';
46
47
  export * from './math/margin';
47
48
  export * from './math/insurance';
49
+ export * from './math/superStake';
50
+ export * from './marinade';
48
51
  export * from './orderParams';
49
52
  export * from './slot/SlotSubscriber';
50
53
  export * from './wallet';