@drift-labs/vaults-sdk 0.1.531 → 0.1.532

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.
@@ -3,15 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VaultClient = void 0;
4
4
  const sdk_1 = require("@drift-labs/sdk");
5
5
  const anchor_1 = require("@coral-xyz/anchor");
6
- const competitions_sdk_1 = require("@drift-labs/competitions-sdk");
7
6
  const addresses_1 = require("./addresses");
8
7
  const web3_js_1 = require("@solana/web3.js");
9
8
  const spl_token_1 = require("@solana/spl-token");
10
9
  const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
11
10
  const math_1 = require("./math");
11
+ const utils_1 = require("./utils");
12
12
  class VaultClient {
13
- constructor({ driftClient, program, cliMode, userMapConfig, }) {
13
+ constructor({ driftClient, program, metaplex, cliMode, userMapConfig, }) {
14
14
  this.driftClient = driftClient;
15
+ this.metaplex = metaplex;
15
16
  this.program = program;
16
17
  this.cliMode = !!cliMode;
17
18
  if (!userMapConfig) {
@@ -574,6 +575,68 @@ class VaultClient {
574
575
  remainingAccounts,
575
576
  });
576
577
  }
578
+ async getApplyRebaseTokenizedDepositorIx(vault, tokenizedVaultDepositor) {
579
+ const vaultAccount = await this.program.account.vault.fetch(vault);
580
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
581
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
582
+ if (!spotMarket) {
583
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
584
+ }
585
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
586
+ userAccounts: [user.getUserAccount()],
587
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
588
+ });
589
+ const accounts = {
590
+ vault,
591
+ tokenizedVaultDepositor,
592
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
593
+ driftState: await this.driftClient.getStatePublicKey(),
594
+ driftSigner: this.driftClient.getStateAccount().signer,
595
+ driftProgram: this.driftClient.program.programId,
596
+ };
597
+ return this.program.instruction.applyRebaseTokenizedDepositor({
598
+ accounts: {
599
+ ...accounts,
600
+ },
601
+ remainingAccounts,
602
+ });
603
+ }
604
+ async applyRebase(vault, vaultDepositor) {
605
+ return await this.createAndSendTxn([
606
+ await this.getApplyRebaseIx(vault, vaultDepositor),
607
+ ]);
608
+ }
609
+ async getApplyRebaseIx(vault, vaultDepositor) {
610
+ const vaultAccount = await this.program.account.vault.fetch(vault);
611
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
612
+ const spotMarket = this.driftClient.getSpotMarketAccount(vaultAccount.spotMarketIndex);
613
+ if (!spotMarket) {
614
+ throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
615
+ }
616
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
617
+ userAccounts: [user.getUserAccount()],
618
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
619
+ });
620
+ const accounts = {
621
+ vault,
622
+ vaultDepositor,
623
+ driftUser: await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, vault),
624
+ driftState: await this.driftClient.getStatePublicKey(),
625
+ driftSigner: this.driftClient.getStateAccount().signer,
626
+ driftProgram: this.driftClient.program.programId,
627
+ };
628
+ return this.program.instruction.applyRebase({
629
+ accounts: {
630
+ ...accounts,
631
+ },
632
+ remainingAccounts,
633
+ });
634
+ }
635
+ async applyRebaseTokenizedDepositor(vault, tokenizedVaultDepositor) {
636
+ return await this.createAndSendTxn([
637
+ await this.getApplyRebaseTokenizedDepositorIx(vault, tokenizedVaultDepositor),
638
+ ]);
639
+ }
577
640
  createInitVaultDepositorIx(vault, authority) {
578
641
  const vaultDepositor = (0, addresses_1.getVaultDepositorAddressSync)(this.program.programId, vault, authority || this.driftClient.wallet.publicKey);
579
642
  const accounts = {
@@ -605,9 +668,14 @@ class VaultClient {
605
668
  authority: authority || this.driftClient.wallet.publicKey,
606
669
  };
607
670
  if (this.cliMode) {
608
- return await this.program.methods
671
+ return this.program.methods
609
672
  .initializeVaultDepositor()
610
- .accounts(accounts)
673
+ .accounts({
674
+ ...accounts,
675
+ payer: authority || this.driftClient.wallet.publicKey,
676
+ rent: web3_js_1.SYSVAR_RENT_PUBKEY,
677
+ systemProgram: web3_js_1.SystemProgram.programId,
678
+ })
611
679
  .rpc();
612
680
  }
613
681
  else {
@@ -615,7 +683,156 @@ class VaultClient {
615
683
  return await this.createAndSendTxn([initIx]);
616
684
  }
617
685
  }
618
- async prepDepositTx(vaultDepositor, amount, initVaultDepositor) {
686
+ async initializeTokenizedVaultDepositor(params) {
687
+ var _a;
688
+ if (!this.metaplex) {
689
+ throw new Error('Metaplex instance is required when constructing VaultClient to initialize a tokenized vault depositor');
690
+ }
691
+ let spotMarketDecimals = 6;
692
+ let sharesBase = 0;
693
+ if (params.decimals === undefined || params.sharesBase === undefined) {
694
+ const vault = await this.program.account.vault.fetch(params.vault);
695
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(vault.spotMarketIndex);
696
+ if (!spotMarketAccount) {
697
+ throw new Error(`DriftClient failed to load vault's spot market (marketIndex: ${vault.spotMarketIndex})`);
698
+ }
699
+ spotMarketDecimals = spotMarketAccount.decimals;
700
+ sharesBase = vault.sharesBase;
701
+ }
702
+ const mintAddress = (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, params.vault, sharesBase);
703
+ const accounts = {
704
+ vault: params.vault,
705
+ vaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, params.vault, sharesBase),
706
+ mintAccount: mintAddress,
707
+ metadataAccount: this.metaplex.nfts().pdas().metadata({
708
+ mint: mintAddress,
709
+ }),
710
+ tokenMetadataProgram: this.metaplex.programs().getTokenMetadata().address,
711
+ payer: this.driftClient.wallet.publicKey,
712
+ };
713
+ const vaultTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mintAddress, params.vault, true);
714
+ const createAtaIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, vaultTokenAta, params.vault, mintAddress);
715
+ if (!this.cliMode) {
716
+ throw new Error('CLI mode is not supported for initializeTokenizedVaultDepositor');
717
+ }
718
+ return await this.program.methods
719
+ .initializeTokenizedVaultDepositor({
720
+ ...params,
721
+ decimals: (_a = params.decimals) !== null && _a !== void 0 ? _a : spotMarketDecimals,
722
+ })
723
+ .preInstructions([
724
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
725
+ microLamports: 50000,
726
+ }),
727
+ ])
728
+ .postInstructions([createAtaIx])
729
+ .accounts(accounts)
730
+ .rpc();
731
+ }
732
+ async createTokenizeSharesIx(vaultDepositor, amount, unit, mint) {
733
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
734
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
735
+ mint =
736
+ mint !== null && mint !== void 0 ? mint : (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, vaultDepositorAccount.vault, vaultAccount.sharesBase);
737
+ const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.driftClient.wallet.publicKey, true);
738
+ const ixs = [];
739
+ const userAtaExists = await this.driftClient.connection.getAccountInfo(userAta);
740
+ if (userAtaExists === null) {
741
+ ixs.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.driftClient.wallet.publicKey, userAta, this.driftClient.wallet.publicKey, mint));
742
+ }
743
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
744
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
745
+ userAccounts: [user.getUserAccount()],
746
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
747
+ });
748
+ ixs.push(await this.program.methods
749
+ // anchor idl bug: https://github.com/coral-xyz/anchor/issues/2914
750
+ // @ts-ignore
751
+ .tokenizeShares(amount, unit)
752
+ .accounts({
753
+ authority: this.driftClient.wallet.publicKey,
754
+ vault: vaultDepositorAccount.vault,
755
+ vaultDepositor,
756
+ tokenizedVaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, vaultDepositorAccount.vault, vaultAccount.sharesBase),
757
+ mint,
758
+ userTokenAccount: userAta,
759
+ driftUser: vaultAccount.user,
760
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
761
+ })
762
+ .remainingAccounts(remainingAccounts)
763
+ .instruction());
764
+ return ixs;
765
+ }
766
+ async tokenizeShares(vaultDepositor, amount, unit, mint, txParams) {
767
+ const ixs = await this.createTokenizeSharesIx(vaultDepositor, amount, unit, mint);
768
+ if (this.cliMode) {
769
+ try {
770
+ const tx = new web3_js_1.Transaction().add(...ixs);
771
+ const txSig = await this.driftClient.txSender.send(tx, undefined, undefined, false);
772
+ return txSig.txSig;
773
+ }
774
+ catch (e) {
775
+ console.error(e);
776
+ throw e;
777
+ }
778
+ }
779
+ else {
780
+ return await this.createAndSendTxn(ixs, txParams);
781
+ }
782
+ }
783
+ async createRedeemTokensIx(vaultDepositor, tokensToBurn, sharesBase) {
784
+ const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
785
+ const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
786
+ const mint = (0, addresses_1.getTokenizedVaultMintAddressSync)(this.program.programId, vaultDepositorAccount.vault, sharesBase !== null && sharesBase !== void 0 ? sharesBase : vaultAccount.sharesBase);
787
+ const userAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, this.driftClient.wallet.publicKey, true);
788
+ const vaultTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, vaultDepositorAccount.vault, true);
789
+ const user = await this.getSubscribedVaultUser(vaultAccount.user);
790
+ const remainingAccounts = this.driftClient.getRemainingAccounts({
791
+ userAccounts: [user.getUserAccount()],
792
+ writableSpotMarketIndexes: [vaultAccount.spotMarketIndex],
793
+ });
794
+ return await this.program.methods
795
+ .redeemTokens(tokensToBurn)
796
+ .accounts({
797
+ authority: this.driftClient.wallet.publicKey,
798
+ vault: vaultDepositorAccount.vault,
799
+ vaultDepositor,
800
+ tokenizedVaultDepositor: (0, addresses_1.getTokenizedVaultAddressSync)(this.program.programId, vaultDepositorAccount.vault, sharesBase !== null && sharesBase !== void 0 ? sharesBase : vaultAccount.sharesBase),
801
+ mint,
802
+ userTokenAccount: userAta,
803
+ vaultTokenAccount: vaultTokenAta,
804
+ driftUser: vaultAccount.user,
805
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
806
+ })
807
+ .remainingAccounts(remainingAccounts)
808
+ .instruction();
809
+ }
810
+ /**
811
+ * Redeems tokens from the vault.
812
+ * @param vaultDepositor
813
+ * @param tokensToBurn
814
+ * @param mint optionally provide a mint, or infer the mint from the current vault share base
815
+ * @param txParams
816
+ * @returns
817
+ */
818
+ async redeemTokens(vaultDepositor, tokensToBurn, sharesBase, txParams) {
819
+ const ix = await this.createRedeemTokensIx(vaultDepositor, tokensToBurn, sharesBase);
820
+ if (this.cliMode) {
821
+ try {
822
+ const tx = new web3_js_1.Transaction().add(ix);
823
+ const txSig = await this.driftClient.txSender.send(tx, undefined, undefined, false);
824
+ return txSig.txSig;
825
+ }
826
+ catch (e) {
827
+ console.error(e);
828
+ throw e;
829
+ }
830
+ }
831
+ else {
832
+ return await this.createAndSendTxn([ix], txParams);
833
+ }
834
+ }
835
+ async prepDepositTx(vaultDepositor, amount, initVaultDepositor, userTokenAccount) {
619
836
  let vaultPubKey;
620
837
  if (initVaultDepositor) {
621
838
  vaultPubKey = initVaultDepositor.vault;
@@ -652,7 +869,7 @@ class VaultClient {
652
869
  driftUser: vaultAccount.user,
653
870
  driftState: driftStateKey,
654
871
  driftSpotMarketVault: spotMarket.vault,
655
- userTokenAccount: (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true),
872
+ userTokenAccount: userTokenAccount !== null && userTokenAccount !== void 0 ? userTokenAccount : (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, this.driftClient.wallet.publicKey, true),
656
873
  driftProgram: this.driftClient.program.programId,
657
874
  tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
658
875
  };
@@ -696,13 +913,13 @@ class VaultClient {
696
913
  * @param txParams
697
914
  * @returns
698
915
  */
699
- async deposit(vaultDepositor, amount, initVaultDepositor, txParams) {
916
+ async deposit(vaultDepositor, amount, initVaultDepositor, txParams, userTokenAccount) {
700
917
  if (this.cliMode) {
701
- const { vaultAccount, accounts, remainingAccounts } = await this.prepDepositTx(vaultDepositor, amount, initVaultDepositor);
918
+ const { vaultAccount, accounts, remainingAccounts } = await this.prepDepositTx(vaultDepositor, amount, initVaultDepositor, userTokenAccount);
702
919
  if (initVaultDepositor) {
703
920
  await this.initializeVaultDepositor(vaultAccount.pubkey, initVaultDepositor.authority);
704
921
  }
705
- return await this.program.methods
922
+ return this.program.methods
706
923
  .deposit(amount)
707
924
  .accounts(accounts)
708
925
  .remainingAccounts(remainingAccounts)
@@ -838,6 +1055,10 @@ class VaultClient {
838
1055
  }
839
1056
  }
840
1057
  async forceWithdraw(vaultDepositor) {
1058
+ const ix = await this.getForceWithdrawIx(vaultDepositor);
1059
+ return await this.createAndSendTxn(ix);
1060
+ }
1061
+ async getForceWithdrawIx(vaultDepositor) {
841
1062
  const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
842
1063
  const vaultAccount = await this.program.account.vault.fetch(vaultDepositorAccount.vault);
843
1064
  const user = await this.getSubscribedVaultUser(vaultAccount.user);
@@ -859,6 +1080,10 @@ class VaultClient {
859
1080
  if (!spotMarket) {
860
1081
  throw new Error(`Spot market ${vaultAccount.spotMarketIndex} not found on driftClient`);
861
1082
  }
1083
+ const [userTokenAccount, createAtaIx] = await (0, utils_1.getOrCreateATAInstruction)(spotMarket.mint, vaultDepositorAccount.authority, this.driftClient.connection, true, this.driftClient.wallet.publicKey);
1084
+ if (createAtaIx) {
1085
+ console.log(`Creating ATA for ${vaultDepositorAccount.authority.toBase58()} to ${userTokenAccount.toBase58()}`);
1086
+ }
862
1087
  const accounts = {
863
1088
  manager: this.driftClient.wallet.publicKey,
864
1089
  vault: vaultDepositorAccount.vault,
@@ -869,34 +1094,20 @@ class VaultClient {
869
1094
  driftState: driftStateKey,
870
1095
  driftSpotMarketVault: spotMarket.vault,
871
1096
  driftSigner: this.driftClient.getStateAccount().signer,
872
- userTokenAccount: (0, spl_token_1.getAssociatedTokenAddressSync)(spotMarket.mint, vaultDepositorAccount.authority, true),
1097
+ userTokenAccount,
873
1098
  driftProgram: this.driftClient.program.programId,
874
1099
  tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
875
1100
  };
876
- if (this.cliMode) {
877
- return await this.program.methods
878
- .forceWithdraw()
879
- .preInstructions([
880
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
881
- units: 500000,
882
- }),
883
- web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
884
- microLamports: 50000,
885
- }),
886
- ])
887
- .accounts(accounts)
888
- .remainingAccounts(remainingAccounts)
889
- .rpc();
890
- }
891
- else {
892
- const forceWithdrawIx = this.program.instruction.forceWithdraw({
893
- accounts: {
894
- ...accounts,
895
- },
896
- remainingAccounts,
897
- });
898
- return await this.createAndSendTxn([forceWithdrawIx]);
1101
+ const ixs = [];
1102
+ if (createAtaIx) {
1103
+ ixs.push(createAtaIx);
899
1104
  }
1105
+ ixs.push(await this.program.methods
1106
+ .forceWithdraw()
1107
+ .accounts(accounts)
1108
+ .remainingAccounts(remainingAccounts)
1109
+ .instruction());
1110
+ return ixs;
900
1111
  }
901
1112
  async cancelRequestWithdraw(vaultDepositor, txParams) {
902
1113
  const vaultDepositorAccount = await this.program.account.vaultDepositor.fetch(vaultDepositor);
@@ -1063,28 +1274,6 @@ class VaultClient {
1063
1274
  })
1064
1275
  .rpc();
1065
1276
  }
1066
- /**
1067
- * Initializes a DriftCompetitions Competitor account for the vault.
1068
- * @param vault vault address to initialize Competitor for
1069
- * @param competitionName name of the competition to initialize for
1070
- * @returns
1071
- */
1072
- async initializeCompetitor(vault, competitionsClient, competitionName) {
1073
- const vaultAccount = await this.program.account.vault.fetch(vault);
1074
- const encodedName = (0, sdk_1.encodeName)(competitionName);
1075
- const competitionAddress = (0, competitions_sdk_1.getCompetitionAddressSync)(competitionsClient.program.programId, encodedName);
1076
- const competitorAddress = (0, competitions_sdk_1.getCompetitorAddressSync)(competitionsClient.program.programId, competitionAddress, vault);
1077
- return await this.program.methods
1078
- .initializeCompetitor()
1079
- .accounts({
1080
- vault: vault,
1081
- competitor: competitorAddress,
1082
- driftCompetitions: competitionAddress,
1083
- driftUserStats: vaultAccount.userStats,
1084
- driftCompetitionsProgram: competitionsClient.program.programId,
1085
- })
1086
- .rpc();
1087
- }
1088
1277
  async protocolRequestWithdraw(vault, amount, withdrawUnit) {
1089
1278
  // @ts-ignore
1090
1279
  const vaultAccount = (await this.program.account.vault.fetch(vault));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/vaults-sdk",
3
- "version": "0.1.531",
3
+ "version": "0.1.532",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "directories": {
@@ -8,11 +8,11 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@coral-xyz/anchor": "0.28.0",
11
- "@drift-labs/competitions-sdk": "0.2.519",
12
11
  "@drift-labs/sdk": "2.98.0-beta.9",
13
12
  "@ledgerhq/hw-app-solana": "^7.1.1",
14
13
  "@ledgerhq/hw-transport": "^6.30.1",
15
14
  "@ledgerhq/hw-transport-node-hid": "^6.28.1",
15
+ "@metaplex-foundation/js": "^0.20.1",
16
16
  "@solana/wallet-adapter-ledger": "^0.9.25",
17
17
  "@solana/web3.js": "1.92.3",
18
18
  "commander": "^11.0.0",
package/src/addresses.ts CHANGED
@@ -54,3 +54,33 @@ export function getVaultProtocolAddressSync(
54
54
  programId
55
55
  )[0];
56
56
  }
57
+
58
+ export function getTokenizedVaultAddressSync(
59
+ programId: PublicKey,
60
+ vault: PublicKey,
61
+ sharesBase: number
62
+ ): PublicKey {
63
+ return PublicKey.findProgramAddressSync(
64
+ [
65
+ Buffer.from(anchor.utils.bytes.utf8.encode('tokenized_vault_depositor')),
66
+ vault.toBuffer(),
67
+ Buffer.from(anchor.utils.bytes.utf8.encode(sharesBase.toString())),
68
+ ],
69
+ programId
70
+ )[0];
71
+ }
72
+
73
+ export function getTokenizedVaultMintAddressSync(
74
+ programId: PublicKey,
75
+ vault: PublicKey,
76
+ sharesBase: number
77
+ ): PublicKey {
78
+ return PublicKey.findProgramAddressSync(
79
+ [
80
+ Buffer.from(anchor.utils.bytes.utf8.encode('mint')),
81
+ vault.toBuffer(),
82
+ Buffer.from(anchor.utils.bytes.utf8.encode(sharesBase.toString())),
83
+ ],
84
+ programId
85
+ )[0];
86
+ }