@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 +6 -0
- package/cli/commands/applyProfitShare.ts +14 -16
- package/cli/commands/forceWithdrawAll.ts +101 -0
- package/cli/commands/index.ts +1 -0
- package/cli/utils.ts +2 -0
- package/lib/addresses.d.ts +3 -0
- package/lib/addresses.js +24 -0
- package/lib/types/drift_vaults.d.ts +673 -60
- package/lib/types/drift_vaults.js +668 -55
- package/lib/utils.d.ts +2 -1
- package/lib/utils.js +20 -1
- package/lib/vaultClient.d.ts +39 -8
- package/lib/vaultClient.js +347 -44
- package/package.json +2 -2
- package/src/addresses.ts +45 -0
- package/src/idl/drift_vaults.json +1527 -207
- package/src/types/drift_vaults.ts +1322 -96
- package/src/utils.ts +37 -1
- package/src/vaultClient.ts +642 -60
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
+
};
|
package/cli/commands/index.ts
CHANGED
|
@@ -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
|
}
|
package/lib/addresses.d.ts
CHANGED
|
@@ -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
|
+
}
|