@drift-labs/vaults-sdk 0.1.531 → 0.1.533

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.
package/cli/cli.ts CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  requestWithdraw,
17
17
  withdraw,
18
18
  forceWithdraw,
19
+ forceWithdrawAll,
19
20
  listDepositorsForVault,
20
21
  managerUpdateMarginTradingEnabled,
21
22
  decodeLogs,
@@ -148,6 +149,11 @@ program
148
149
  .addOption(new Option("--vault-depositor-authority <vaultDepositorAuthority>", "Authority address of VaultDepositor, must also provide --vault-address").makeOptionMandatory(false))
149
150
  .addOption(new Option("--vault-address <vaultAddress>", "Address of vault, must required if only --vault-deposit-authority is provided").makeOptionMandatory(false))
150
151
  .action((opts) => forceWithdraw(program, opts));
152
+ program
153
+ .command("force-withdraw-all")
154
+ .description("Processes all pending withdrawals that are ready to be redeemed")
155
+ .addOption(new Option("--vault-address <vaultAddress>", "Address of vault, must required if only --vault-deposit-authority is provided").makeOptionMandatory(true))
156
+ .action((opts) => forceWithdrawAll(program, opts));
151
157
  program
152
158
  .command("decode-logs")
153
159
  .description("Decode program logs from a txid")
@@ -1,4 +1,4 @@
1
- import { ComputeBudgetProgram, PublicKey, TransactionInstruction, VersionedTransactionResponse } from "@solana/web3.js";
1
+ import { ComputeBudgetProgram, PublicKey, SendTransactionError, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
2
2
  import {
3
3
  OptionValues,
4
4
  Command
@@ -21,6 +21,7 @@ export const applyProfitShare = async (program: Command, cmdOpts: OptionValues)
21
21
  const {
22
22
  driftVault,
23
23
  driftClient,
24
+ wallet,
24
25
  } = await getCommandContext(program, true);
25
26
 
26
27
  const vault = await driftVault.getVault(vaultAddress);
@@ -72,24 +73,21 @@ export const applyProfitShare = async (program: Command, cmdOpts: OptionValues)
72
73
  units: 170_000,
73
74
  }));
74
75
 
75
- const tx = await driftClient.txSender.getVersionedTransaction(ixs, [], undefined, undefined);
76
+ const message = new TransactionMessage({
77
+ payerKey: driftClient.wallet.publicKey,
78
+ recentBlockhash: (await driftClient.connection.getLatestBlockhash('finalized')).blockhash,
79
+ instructions: ixs,
80
+ }).compileToV0Message();
76
81
 
77
- let attempt = 0;
78
- let txResp: VersionedTransactionResponse | null = null;
79
- while (txResp === null) {
80
- attempt++;
81
- const { txSig } = await driftClient.txSender.sendVersionedTransaction(
82
- tx,
83
- );
84
- console.log(`[${i}]: https://solscan.io/tx/${txSig} (attempt ${attempt})`);
82
+ const tx = await wallet.signVersionedTransaction(new VersionedTransaction(message));
85
83
 
86
- await new Promise(resolve => setTimeout(resolve, 1000));
87
-
88
- txResp = await driftClient.connection.getTransaction(txSig, { commitment: 'confirmed', maxSupportedTransactionVersion: 0 });
84
+ try {
85
+ const txid = await driftClient.connection.sendTransaction(tx);
86
+ console.log(`Sent chunk: ${txid}`);
87
+ } catch (e) {
88
+ console.error(`Error sending chunk: ${e}`);
89
+ console.log((e as SendTransactionError).logs);
89
90
  }
90
- console.log(txResp);
91
-
92
-
93
91
  } catch (e) {
94
92
  console.error(e);
95
93
  continue;
@@ -0,0 +1,101 @@
1
+ import { ComputeBudgetProgram, PublicKey, SendTransactionError, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
2
+ import {
3
+ OptionValues,
4
+ Command
5
+ } from "commander";
6
+ import { getCommandContext } from "../utils";
7
+ import { VaultDepositor } from "../../src";
8
+ import {
9
+ BN,
10
+ convertToNumber
11
+ } from "@drift-labs/sdk";
12
+ import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
13
+
14
+ export const forceWithdrawAll = async (program: Command, cmdOpts: OptionValues) => {
15
+ let vaultAddress: PublicKey | undefined;
16
+ try {
17
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
18
+ } catch (err) {
19
+ throw new Error("Must provide --vault-address");
20
+ }
21
+
22
+ if (!vaultAddress) {
23
+ throw new Error("Failed to derive vault depositor address");
24
+ }
25
+
26
+ const {
27
+ driftVault,
28
+ driftClient,
29
+ wallet,
30
+ } = await getCommandContext(program, true);
31
+
32
+ const vault = await driftVault.getVault(vaultAddress);
33
+ const allVaultDepositors = await driftVault.getAllVaultDepositors(vaultAddress);
34
+ const spotMarket = driftVault.driftClient.getSpotMarketAccount(vault.spotMarketIndex);
35
+ const spotPrecision = new BN(10).pow(new BN(spotMarket!.decimals));
36
+
37
+ const withdrawables: Array<PublicKey> = [];
38
+ for (const vd of allVaultDepositors) {
39
+ const vdAccount = vd.account as VaultDepositor;
40
+ if (vdAccount.lastWithdrawRequest.shares.gt(new BN(0))) {
41
+ const withdrawRequested = vdAccount.lastWithdrawRequest.ts.toNumber();
42
+ const secToWithdrawal = withdrawRequested + vault.redeemPeriod.toNumber() - Date.now() / 1000;
43
+ const withdrawAvailable = secToWithdrawal < 0;
44
+ const pct = vdAccount.lastWithdrawRequest.shares.toNumber() / vd.account.vaultShares.toNumber();
45
+ const daysUntilWithdraw = Math.floor(secToWithdrawal / 86400);
46
+ const hoursUntilWithdraw = Math.floor((secToWithdrawal % 86400) / 3600);
47
+
48
+ if (secToWithdrawal < 0) {
49
+ console.log(`Withdraw available for ${vdAccount.authority.toBase58()}`);
50
+ console.log(` - pending withdrawal: ${vdAccount.lastWithdrawRequest.shares.toString()} ($${convertToNumber(vd.account.lastWithdrawRequest.value, spotPrecision)}), ${(pct * 100.00).toFixed(2)}% of their deposit ${withdrawAvailable ? "<--- WITHDRAWABLE" : ""}`);
51
+ console.log(` - requested at: ${new Date(withdrawRequested * 1000).toISOString()}`);
52
+ console.log(` - can withdraw in: ${daysUntilWithdraw} days and ${hoursUntilWithdraw} hours`);
53
+ }
54
+
55
+ withdrawables.push(vdAccount.pubkey);
56
+ }
57
+ }
58
+
59
+ console.log(`Withdrawing ${withdrawables.length} depositors`);
60
+ const chunkSize = 3;
61
+ for (let i = 0; i < withdrawables.length; i += chunkSize) {
62
+ const chunk = withdrawables.slice(i, i + chunkSize);
63
+ console.log(`Processing chunk ${i / chunkSize + 1} of ${Math.ceil(withdrawables.length / chunkSize)}`);
64
+ const ixs = [];
65
+ for (const depositorAddress of chunk) {
66
+ try {
67
+ ixs.push(...await driftVault.getForceWithdrawIx(depositorAddress));
68
+ } catch (error) {
69
+ console.error(`Error withdrawing for ${depositorAddress.toBase58()}:`, error);
70
+ }
71
+ }
72
+
73
+ const message = new TransactionMessage({
74
+ payerKey: driftClient.wallet.publicKey,
75
+ recentBlockhash: (await driftClient.connection.getLatestBlockhash('finalized')).blockhash,
76
+ instructions: [
77
+ ComputeBudgetProgram.setComputeUnitLimit({
78
+ units: 600_000,
79
+ }),
80
+ ComputeBudgetProgram.setComputeUnitPrice({
81
+ microLamports: 10_000,
82
+ }),
83
+ ...ixs
84
+ ],
85
+ }).compileToV0Message();
86
+
87
+ const tx = await wallet.signVersionedTransaction(new VersionedTransaction(message));
88
+
89
+ console.log(`Sending chunk: ${bs58.encode(tx.signatures[0])}`);
90
+ try {
91
+ const txid = await driftClient.connection.sendTransaction(tx);
92
+ console.log(`Sent chunk: ${txid}`);
93
+ } catch (e) {
94
+ console.error(`Error sending chunk: ${e}`);
95
+ console.log((e as SendTransactionError).logs);
96
+ }
97
+ }
98
+
99
+ // const tx = await driftVault.forceWithdraw(vaultDepositorAddress);
100
+ // console.log(`Forced withdraw from vault: ${tx}`);
101
+ };
@@ -12,6 +12,7 @@ export * from './initVaultDepositor';
12
12
  export * from './deposit';
13
13
  export * from './requestWithdraw';
14
14
  export * from './forceWithdraw';
15
+ export * from './forceWithdrawAll';
15
16
  export * from './withdraw';
16
17
  export * from './listDepositorsForVault';
17
18
  export * from './managerUpdateMarginTradingEnabled';
package/cli/utils.ts CHANGED
@@ -116,6 +116,7 @@ export function printVaultDepositor(vaultDepositor: VaultDepositor) {
116
116
  export async function getCommandContext(program: Command, needToSign: boolean): Promise<{
117
117
  driftClient: DriftClient,
118
118
  driftVault: VaultClient,
119
+ wallet: Wallet,
119
120
  }> {
120
121
 
121
122
  const opts = program.opts();
@@ -189,5 +190,6 @@ export async function getCommandContext(program: Command, needToSign: boolean):
189
190
  return {
190
191
  driftClient,
191
192
  driftVault,
193
+ wallet,
192
194
  };
193
195
  }
@@ -2,4 +2,7 @@ import { PublicKey } from '@solana/web3.js';
2
2
  export declare function getVaultAddressSync(programId: PublicKey, encodedName: number[]): PublicKey;
3
3
  export declare function getVaultDepositorAddressSync(programId: PublicKey, vault: PublicKey, authority: PublicKey): PublicKey;
4
4
  export declare function getTokenVaultAddressSync(programId: PublicKey, vault: PublicKey): PublicKey;
5
+ export declare function getInsuranceFundTokenVaultAddressSync(programId: PublicKey, vault: PublicKey, marketIndex: number): PublicKey;
5
6
  export declare function getVaultProtocolAddressSync(programId: PublicKey, vault: PublicKey): PublicKey;
7
+ export declare function getTokenizedVaultAddressSync(programId: PublicKey, vault: PublicKey, sharesBase: number): PublicKey;
8
+ export declare function getTokenizedVaultMintAddressSync(programId: PublicKey, vault: PublicKey, sharesBase: number): PublicKey;
package/lib/addresses.js CHANGED
@@ -26,7 +26,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.getVaultAddressSync = getVaultAddressSync;
27
27
  exports.getVaultDepositorAddressSync = getVaultDepositorAddressSync;
28
28
  exports.getTokenVaultAddressSync = getTokenVaultAddressSync;
29
+ exports.getInsuranceFundTokenVaultAddressSync = getInsuranceFundTokenVaultAddressSync;
29
30
  exports.getVaultProtocolAddressSync = getVaultProtocolAddressSync;
31
+ exports.getTokenizedVaultAddressSync = getTokenizedVaultAddressSync;
32
+ exports.getTokenizedVaultMintAddressSync = getTokenizedVaultMintAddressSync;
30
33
  const web3_js_1 = require("@solana/web3.js");
31
34
  const anchor = __importStar(require("@coral-xyz/anchor"));
32
35
  function getVaultAddressSync(programId, encodedName) {
@@ -48,9 +51,30 @@ function getTokenVaultAddressSync(programId, vault) {
48
51
  vault.toBuffer(),
49
52
  ], programId)[0];
50
53
  }
54
+ function getInsuranceFundTokenVaultAddressSync(programId, vault, marketIndex) {
55
+ return web3_js_1.PublicKey.findProgramAddressSync([
56
+ Buffer.from(anchor.utils.bytes.utf8.encode('vault_token_account')),
57
+ vault.toBuffer(),
58
+ new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
59
+ ], programId)[0];
60
+ }
51
61
  function getVaultProtocolAddressSync(programId, vault) {
52
62
  return web3_js_1.PublicKey.findProgramAddressSync([
53
63
  Buffer.from(anchor.utils.bytes.utf8.encode('vault_protocol')),
54
64
  vault.toBuffer(),
55
65
  ], programId)[0];
56
66
  }
67
+ function getTokenizedVaultAddressSync(programId, vault, sharesBase) {
68
+ return web3_js_1.PublicKey.findProgramAddressSync([
69
+ Buffer.from(anchor.utils.bytes.utf8.encode('tokenized_vault_depositor')),
70
+ vault.toBuffer(),
71
+ Buffer.from(anchor.utils.bytes.utf8.encode(sharesBase.toString())),
72
+ ], programId)[0];
73
+ }
74
+ function getTokenizedVaultMintAddressSync(programId, vault, sharesBase) {
75
+ return web3_js_1.PublicKey.findProgramAddressSync([
76
+ Buffer.from(anchor.utils.bytes.utf8.encode('mint')),
77
+ vault.toBuffer(),
78
+ Buffer.from(anchor.utils.bytes.utf8.encode(sharesBase.toString())),
79
+ ], programId)[0];
80
+ }