@drift-labs/sdk 2.31.1-beta.9 → 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 +51 -4
  5. package/lib/driftClient.js +195 -194
  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 +373 -223
  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);
@@ -716,6 +741,21 @@ class DriftClient {
716
741
  amount = typeof amount === 'number' ? new anchor_1.BN(amount) : amount;
717
742
  return amount.mul(numericConstants_1.PRICE_PRECISION);
718
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
+ }
719
759
  getRemainingAccounts(params) {
720
760
  var _a;
721
761
  const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } = this.getRemainingAccountMapsForUsers(params.userAccounts);
@@ -725,30 +765,7 @@ class DriftClient {
725
765
  // if cache has more recent slot than user positions account slot, add market to remaining accounts
726
766
  // otherwise remove from slot
727
767
  if (slot > lastUserSlot) {
728
- const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
729
- perpMarketAccountMap.set(marketIndex, {
730
- pubkey: perpMarketAccount.pubkey,
731
- isSigner: false,
732
- isWritable: false,
733
- });
734
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
735
- pubkey: perpMarketAccount.amm.oracle,
736
- isSigner: false,
737
- isWritable: false,
738
- });
739
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
740
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
741
- pubkey: spotMarketAccount.pubkey,
742
- isSigner: false,
743
- isWritable: false,
744
- });
745
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
746
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
747
- pubkey: spotMarketAccount.oracle,
748
- isSigner: false,
749
- isWritable: false,
750
- });
751
- }
768
+ this.addPerpMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
752
769
  }
753
770
  else {
754
771
  this.perpMarketLastSlotCache.delete(marketIndex);
@@ -758,19 +775,7 @@ class DriftClient {
758
775
  // if cache has more recent slot than user positions account slot, add market to remaining accounts
759
776
  // otherwise remove from slot
760
777
  if (slot > lastUserSlot) {
761
- const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
762
- spotMarketAccountMap.set(marketIndex, {
763
- pubkey: spotMarketAccount.pubkey,
764
- isSigner: false,
765
- isWritable: false,
766
- });
767
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
768
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
769
- pubkey: spotMarketAccount.oracle,
770
- isSigner: false,
771
- isWritable: false,
772
- });
773
- }
778
+ this.addSpotMarketToRemainingAccountMaps(marketIndex, false, oracleAccountMap, spotMarketAccountMap);
774
779
  }
775
780
  else {
776
781
  this.spotMarketLastSlotCache.delete(marketIndex);
@@ -778,91 +783,32 @@ class DriftClient {
778
783
  }
779
784
  }
780
785
  if (params.readablePerpMarketIndex !== undefined) {
781
- const perpMarketAccount = this.getPerpMarketAccount(params.readablePerpMarketIndex);
782
- perpMarketAccountMap.set(params.readablePerpMarketIndex, {
783
- pubkey: perpMarketAccount.pubkey,
784
- isSigner: false,
785
- isWritable: false,
786
- });
787
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
788
- pubkey: perpMarketAccount.amm.oracle,
789
- isSigner: false,
790
- isWritable: false,
791
- });
792
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
793
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
794
- pubkey: spotMarketAccount.pubkey,
795
- isSigner: false,
796
- isWritable: false,
797
- });
798
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
799
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
800
- pubkey: spotMarketAccount.oracle,
801
- isSigner: false,
802
- isWritable: false,
803
- });
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);
804
791
  }
805
792
  }
793
+ for (const perpMarketIndex of this.mustIncludePerpMarketIndexes.values()) {
794
+ this.addPerpMarketToRemainingAccountMaps(perpMarketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
795
+ }
806
796
  if (params.readableSpotMarketIndexes !== undefined) {
807
797
  for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
808
- const spotMarketAccount = this.getSpotMarketAccount(readableSpotMarketIndex);
809
- spotMarketAccountMap.set(readableSpotMarketIndex, {
810
- pubkey: spotMarketAccount.pubkey,
811
- isSigner: false,
812
- isWritable: false,
813
- });
814
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
815
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
816
- pubkey: spotMarketAccount.oracle,
817
- isSigner: false,
818
- isWritable: false,
819
- });
820
- }
798
+ this.addSpotMarketToRemainingAccountMaps(readableSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
821
799
  }
822
800
  }
801
+ for (const spotMarketIndex of this.mustIncludeSpotMarketIndexes.values()) {
802
+ this.addSpotMarketToRemainingAccountMaps(spotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
803
+ }
823
804
  if (params.writablePerpMarketIndexes !== undefined) {
824
805
  for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
825
- const perpMarketAccount = this.getPerpMarketAccount(writablePerpMarketIndex);
826
- perpMarketAccountMap.set(writablePerpMarketIndex, {
827
- pubkey: perpMarketAccount.pubkey,
828
- isSigner: false,
829
- isWritable: true,
830
- });
831
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
832
- pubkey: perpMarketAccount.amm.oracle,
833
- isSigner: false,
834
- isWritable: false,
835
- });
836
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
837
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
838
- pubkey: spotMarketAccount.pubkey,
839
- isSigner: false,
840
- isWritable: false,
841
- });
842
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
843
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
844
- pubkey: spotMarketAccount.oracle,
845
- isSigner: false,
846
- isWritable: false,
847
- });
848
- }
806
+ this.addPerpMarketToRemainingAccountMaps(writablePerpMarketIndex, true, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
849
807
  }
850
808
  }
851
809
  if (params.writableSpotMarketIndexes !== undefined) {
852
810
  for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
853
- const spotMarketAccount = this.getSpotMarketAccount(writableSpotMarketIndex);
854
- spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
855
- pubkey: spotMarketAccount.pubkey,
856
- isSigner: false,
857
- isWritable: true,
858
- });
859
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
860
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
861
- pubkey: spotMarketAccount.oracle,
862
- isSigner: false,
863
- isWritable: false,
864
- });
865
- }
811
+ this.addSpotMarketToRemainingAccountMaps(writableSpotMarketIndex, true, oracleAccountMap, spotMarketAccountMap);
866
812
  }
867
813
  }
868
814
  return [
@@ -871,6 +817,35 @@ class DriftClient {
871
817
  ...perpMarketAccountMap.values(),
872
818
  ];
873
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
+ }
874
849
  getRemainingAccountMapsForUsers(userAccounts) {
875
850
  const oracleAccountMap = new Map();
876
851
  const spotMarketAccountMap = new Map();
@@ -878,63 +853,16 @@ class DriftClient {
878
853
  for (const userAccount of userAccounts) {
879
854
  for (const spotPosition of userAccount.spotPositions) {
880
855
  if (!(0, spotPosition_1.isSpotPositionAvailable)(spotPosition)) {
881
- const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
882
- spotMarketAccountMap.set(spotPosition.marketIndex, {
883
- pubkey: spotMarket.pubkey,
884
- isSigner: false,
885
- isWritable: false,
886
- });
887
- if (!spotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
888
- oracleAccountMap.set(spotMarket.oracle.toString(), {
889
- pubkey: spotMarket.oracle,
890
- isSigner: false,
891
- isWritable: false,
892
- });
893
- }
856
+ this.addSpotMarketToRemainingAccountMaps(spotPosition.marketIndex, false, oracleAccountMap, spotMarketAccountMap);
894
857
  if (!spotPosition.openAsks.eq(numericConstants_1.ZERO) ||
895
858
  !spotPosition.openBids.eq(numericConstants_1.ZERO)) {
896
- const quoteSpotMarket = this.getQuoteSpotMarketAccount();
897
- spotMarketAccountMap.set(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, {
898
- pubkey: quoteSpotMarket.pubkey,
899
- isSigner: false,
900
- isWritable: false,
901
- });
902
- if (!quoteSpotMarket.oracle.equals(web3_js_1.PublicKey.default)) {
903
- oracleAccountMap.set(quoteSpotMarket.oracle.toString(), {
904
- pubkey: quoteSpotMarket.oracle,
905
- isSigner: false,
906
- isWritable: false,
907
- });
908
- }
859
+ this.addSpotMarketToRemainingAccountMaps(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, false, oracleAccountMap, spotMarketAccountMap);
909
860
  }
910
861
  }
911
862
  }
912
863
  for (const position of userAccount.perpPositions) {
913
864
  if (!(0, position_1.positionIsAvailable)(position)) {
914
- const perpMarketAccount = this.getPerpMarketAccount(position.marketIndex);
915
- perpMarketAccountMap.set(position.marketIndex, {
916
- pubkey: perpMarketAccount.pubkey,
917
- isWritable: false,
918
- isSigner: false,
919
- });
920
- oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
921
- pubkey: perpMarketAccount.amm.oracle,
922
- isWritable: false,
923
- isSigner: false,
924
- });
925
- const spotMarketAccount = this.getSpotMarketAccount(perpMarketAccount.quoteSpotMarketIndex);
926
- spotMarketAccountMap.set(perpMarketAccount.quoteSpotMarketIndex, {
927
- pubkey: spotMarketAccount.pubkey,
928
- isSigner: false,
929
- isWritable: false,
930
- });
931
- if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
932
- oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
933
- pubkey: spotMarketAccount.oracle,
934
- isSigner: false,
935
- isWritable: false,
936
- });
937
- }
865
+ this.addPerpMarketToRemainingAccountMaps(position.marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
938
866
  }
939
867
  }
940
868
  }
@@ -1466,13 +1394,8 @@ class DriftClient {
1466
1394
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
1467
1395
  return txSig;
1468
1396
  }
1469
- getOrderParams(optionalOrderParams, marketType) {
1470
- return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams, {
1471
- marketType,
1472
- });
1473
- }
1474
1397
  async getPlacePerpOrderIx(orderParams) {
1475
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
1398
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
1476
1399
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1477
1400
  const remainingAccounts = this.getRemainingAccounts({
1478
1401
  userAccounts: [this.getUserAccount()],
@@ -1645,23 +1568,48 @@ class DriftClient {
1645
1568
  });
1646
1569
  }
1647
1570
  async cancelAndPlaceOrders(cancelOrderParams, placeOrderParams, txParams) {
1648
- 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);
1649
- for (const placeOrderParam of placeOrderParams) {
1650
- const marketType = placeOrderParam.marketType;
1651
- if (!marketType) {
1652
- 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');
1653
1590
  }
1654
- let ix;
1655
- if ((0, types_1.isVariant)(marketType, 'perp')) {
1656
- ix = this.getPlacePerpOrderIx(placeOrderParam);
1591
+ if ((0, types_1.isVariant)(param.marketType, 'perp')) {
1592
+ readablePerpMarketIndex.push(param.marketIndex);
1657
1593
  }
1658
1594
  else {
1659
- ix = this.getPlaceSpotOrderIx(placeOrderParam);
1595
+ readableSpotMarketIndexes.push(param.marketIndex);
1660
1596
  }
1661
- tx.add(ix);
1662
1597
  }
1663
- const { txSig } = await this.sendTransaction(tx, [], this.opts);
1664
- 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
+ });
1665
1613
  }
1666
1614
  async fillPerpOrder(userAccountPublicKey, user, order, makerInfo, referrerInfo, txParams) {
1667
1615
  const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getFillPerpOrderIx(userAccountPublicKey, user, order, makerInfo, referrerInfo), txParams), [], this.opts);
@@ -1747,7 +1695,7 @@ class DriftClient {
1747
1695
  return txSig;
1748
1696
  }
1749
1697
  async getPlaceSpotOrderIx(orderParams) {
1750
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.SPOT);
1698
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
1751
1699
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1752
1700
  const remainingAccounts = this.getRemainingAccounts({
1753
1701
  userAccounts: [this.getUserAccount()],
@@ -1997,6 +1945,25 @@ class DriftClient {
1997
1945
  * @param txParams
1998
1946
  */
1999
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, }) {
2000
1967
  const outMarket = this.getSpotMarketAccount(outMarketIndex);
2001
1968
  const inMarket = this.getSpotMarketAccount(inMarketIndex);
2002
1969
  if (!route) {
@@ -2047,18 +2014,15 @@ class DriftClient {
2047
2014
  inTokenAccount: inAssociatedTokenAccount,
2048
2015
  outTokenAccount: outAssociatedTokenAccount,
2049
2016
  reduceOnly,
2017
+ userAccountPublicKey,
2050
2018
  });
2051
- const instructions = [
2019
+ const ixs = [
2052
2020
  ...preInstructions,
2053
2021
  beginSwapIx,
2054
2022
  ...jupiterInstructions,
2055
2023
  endSwapIx,
2056
2024
  ];
2057
- const tx = (await this.buildTransaction(instructions, txParams, 0, lookupTables));
2058
- const { txSig, slot } = await this.sendTransaction(tx);
2059
- this.spotMarketLastSlotCache.set(outMarketIndex, slot);
2060
- this.spotMarketLastSlotCache.set(inMarketIndex, slot);
2061
- return txSig;
2025
+ return { ixs, lookupTables };
2062
2026
  }
2063
2027
  /**
2064
2028
  * Get the drift begin_swap and end_swap instructions
@@ -2069,11 +2033,14 @@ class DriftClient {
2069
2033
  * @param inTokenAccount the token account to move the tokens being sold
2070
2034
  * @param outTokenAccount the token account to receive the tokens being bought
2071
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
2072
2038
  */
2073
- async getSwapIx({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, }) {
2074
- 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()] : [];
2075
2042
  const remainingAccounts = this.getRemainingAccounts({
2076
- userAccounts: [this.getUserAccount()],
2043
+ userAccounts,
2077
2044
  writableSpotMarketIndexes: [outMarketIndex, inMarketIndex],
2078
2045
  });
2079
2046
  const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
@@ -2081,7 +2048,7 @@ class DriftClient {
2081
2048
  const beginSwapIx = await this.program.instruction.beginSwap(inMarketIndex, outMarketIndex, amountIn, {
2082
2049
  accounts: {
2083
2050
  state: await this.getStatePublicKey(),
2084
- user: userAccountPublicKey,
2051
+ user: userAccountPublicKeyToUse,
2085
2052
  userStats: this.getUserStatsAccountPublicKey(),
2086
2053
  authority: this.authority,
2087
2054
  outSpotMarketVault: outSpotMarket.vault,
@@ -2097,7 +2064,7 @@ class DriftClient {
2097
2064
  const endSwapIx = await this.program.instruction.endSwap(inMarketIndex, outMarketIndex, limitPrice !== null && limitPrice !== void 0 ? limitPrice : null, reduceOnly !== null && reduceOnly !== void 0 ? reduceOnly : null, {
2098
2065
  accounts: {
2099
2066
  state: await this.getStatePublicKey(),
2100
- user: userAccountPublicKey,
2067
+ user: userAccountPublicKeyToUse,
2101
2068
  userStats: this.getUserStatsAccountPublicKey(),
2102
2069
  authority: this.authority,
2103
2070
  outSpotMarketVault: outSpotMarket.vault,
@@ -2112,6 +2079,40 @@ class DriftClient {
2112
2079
  });
2113
2080
  return { beginSwapIx, endSwapIx };
2114
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
+ }
2115
2116
  async triggerOrder(userAccountPublicKey, user, order, txParams) {
2116
2117
  const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getTriggerOrderIx(userAccountPublicKey, user, order), txParams), [], this.opts);
2117
2118
  return txSig;
@@ -2207,7 +2208,7 @@ class DriftClient {
2207
2208
  return txSig;
2208
2209
  }
2209
2210
  async getPlaceAndTakePerpOrderIx(orderParams, makerInfo, referrerInfo) {
2210
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
2211
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
2211
2212
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
2212
2213
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2213
2214
  makerInfo = Array.isArray(makerInfo)
@@ -2268,7 +2269,7 @@ class DriftClient {
2268
2269
  return txSig;
2269
2270
  }
2270
2271
  async getPlaceAndMakePerpOrderIx(orderParams, takerInfo, referrerInfo) {
2271
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.PERP);
2272
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
2272
2273
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
2273
2274
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2274
2275
  const remainingAccounts = this.getRemainingAccounts({
@@ -2308,7 +2309,7 @@ class DriftClient {
2308
2309
  return txSig;
2309
2310
  }
2310
2311
  async getPlaceAndTakeSpotOrderIx(orderParams, fulfillmentConfig, makerInfo, referrerInfo) {
2311
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.SPOT);
2312
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
2312
2313
  const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
2313
2314
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2314
2315
  const userAccounts = [this.getUserAccount()];
@@ -2367,7 +2368,7 @@ class DriftClient {
2367
2368
  return txSig;
2368
2369
  }
2369
2370
  async getPlaceAndMakeSpotOrderIx(orderParams, takerInfo, fulfillmentConfig, referrerInfo) {
2370
- orderParams = this.getOrderParams(orderParams, types_1.MarketType.SPOT);
2371
+ orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.SPOT });
2371
2372
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
2372
2373
  const userAccountPublicKey = await this.getUserAccountPublicKey();
2373
2374
  const remainingAccounts = this.getRemainingAccounts({
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.31.1-beta.8",
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';
package/lib/index.js CHANGED
@@ -39,6 +39,7 @@ __exportStar(require("./accounts/pollingOracleAccountSubscriber"), exports);
39
39
  __exportStar(require("./accounts/pollingTokenAccountSubscriber"), exports);
40
40
  __exportStar(require("./accounts/pollingUserAccountSubscriber"), exports);
41
41
  __exportStar(require("./accounts/pollingUserStatsAccountSubscriber"), exports);
42
+ __exportStar(require("./accounts/mockUserAccountSubscriber"), exports);
42
43
  __exportStar(require("./accounts/types"), exports);
43
44
  __exportStar(require("./addresses/pda"), exports);
44
45
  __exportStar(require("./adminClient"), exports);
@@ -68,6 +69,8 @@ __exportStar(require("./math/orders"), exports);
68
69
  __exportStar(require("./math/repeg"), exports);
69
70
  __exportStar(require("./math/margin"), exports);
70
71
  __exportStar(require("./math/insurance"), exports);
72
+ __exportStar(require("./math/superStake"), exports);
73
+ __exportStar(require("./marinade"), exports);
71
74
  __exportStar(require("./orderParams"), exports);
72
75
  __exportStar(require("./slot/SlotSubscriber"), exports);
73
76
  __exportStar(require("./wallet"), exports);
@@ -0,0 +1,11 @@
1
+ import { AnchorProvider, BN, Program } from '@coral-xyz/anchor';
2
+ import { MarinadeFinance } from './types';
3
+ import { PublicKey, TransactionInstruction } from '@solana/web3.js';
4
+ export declare function getMarinadeFinanceProgram(provider: AnchorProvider): Program<MarinadeFinance>;
5
+ export declare function getMarinadeDepositIx({ program, amount, mSOLAccount, transferFrom, }: {
6
+ amount: BN;
7
+ mSOLAccount: PublicKey;
8
+ transferFrom: PublicKey;
9
+ program: Program<MarinadeFinance>;
10
+ }): Promise<TransactionInstruction>;
11
+ export declare function getMarinadeMSolPrice(program: Program<MarinadeFinance>): Promise<number>;