@drift-labs/vaults-sdk 0.1.0 → 0.1.2

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 (41) hide show
  1. package/README.md +44 -8
  2. package/cli/cli.ts +45 -9
  3. package/cli/commands/applyProfitShare.ts +3 -6
  4. package/cli/commands/deposit.ts +0 -1
  5. package/cli/commands/deriveVaultAddress.ts +15 -0
  6. package/cli/commands/index.ts +4 -1
  7. package/cli/commands/initVault.ts +104 -23
  8. package/cli/commands/initVaultDepositor.ts +0 -1
  9. package/cli/commands/listDepositorsForVault.ts +0 -1
  10. package/cli/commands/managerCancelWithdraw.ts +0 -1
  11. package/cli/commands/managerDeposit.ts +0 -1
  12. package/cli/commands/managerRequestWithdraw.ts +0 -1
  13. package/cli/commands/managerUpdateMarginTradingEnabled.ts +26 -0
  14. package/cli/commands/managerUpdateVault.ts +91 -9
  15. package/cli/commands/managerUpdateVaultDelegate.ts +35 -0
  16. package/cli/commands/managerWithdraw.ts +0 -1
  17. package/cli/commands/requestWithdraw.ts +0 -1
  18. package/cli/commands/vaultDeposit.ts +0 -1
  19. package/cli/commands/vaultWithdraw.ts +0 -1
  20. package/cli/commands/viewVault.ts +4 -4
  21. package/cli/commands/viewVaultDepositor.ts +0 -1
  22. package/cli/commands/withdraw.ts +0 -1
  23. package/cli/utils.ts +15 -8
  24. package/lib/accountSubscribers/index.js +5 -1
  25. package/lib/accounts/index.js +5 -1
  26. package/lib/accounts/vaultAccount.js +1 -1
  27. package/lib/accounts/vaultDepositorAccount.js +1 -1
  28. package/lib/addresses.js +5 -1
  29. package/lib/index.js +5 -1
  30. package/lib/parsers/index.js +5 -1
  31. package/lib/parsers/logParser.d.ts +1 -1
  32. package/lib/types/drift_vaults.d.ts +113 -1
  33. package/lib/types/drift_vaults.js +112 -0
  34. package/lib/types/types.d.ts +13 -13
  35. package/lib/utils.js +6 -2
  36. package/lib/vaultClient.d.ts +22 -0
  37. package/lib/vaultClient.js +85 -24
  38. package/package.json +2 -4
  39. package/src/idl/drift_vaults.json +112 -0
  40. package/src/types/drift_vaults.ts +224 -0
  41. package/src/vaultClient.ts +97 -0
package/README.md CHANGED
@@ -2,10 +2,15 @@
2
2
 
3
3
  This repo has a simple CLI for interacting with the vault (run from this `package.json`):
4
4
 
5
- First create a `.env` and fill it out:
6
- ```
7
- cp .env.example .env
8
- ```
5
+ This CLI utility requires an RPC node and keypair to sign transactions (similar to solana cli). You can either provide these as environment variables or in a `.env` file, or use the `--keypair` and `--url` flags.
6
+
7
+ Required Environment Variables or Flags:
8
+
9
+ Environment Variable| command line flag | Description
10
+ --------------------|-------------------|------------
11
+ RPC_URL | --url | The RPC node to connect to for transactions
12
+ KEYPAIR_PATH | --keypair | Path to keypair to sign transactions
13
+
9
14
 
10
15
  View available commands, run with `--help` in nested commands to get available options for each command
11
16
  ```
@@ -13,13 +18,44 @@ yarn cli --help
13
18
  ```
14
19
 
15
20
 
16
- Init a new vault. This will initialize a new vault and update you as the delegate.
17
- Note that defaults are used for the vault (permissioned, 2% mgmt fee, 20% profit share), take
18
- care to edit these as required.
21
+ Init a new vault. This will initialize a new vault and update you (the manager) as the delegate, unless `--delegate` is specified.
19
22
  ```
20
- yarn cli init-vault --name="super safe vault"
23
+ $ yarn cli init-vault --help
24
+ Usage: cli init-vault [options]
25
+
26
+ Initialize a new vault
27
+
28
+ Options:
29
+ -n, --name <string> Name of the vault to create
30
+ -i, --market-index <number> Spot market index to accept for deposits (default 0 == USDC) (default: "0")
31
+ -r, --redeem-period <number> The period (in seconds) depositors must wait after requesting a withdraw (default: 7 days) (default: "604800")
32
+ -x, --max-tokens <number> The max number of spot marketIndex tokens the vault can accept (default 0 == unlimited) (default: "0")
33
+ -m, --management-fee <percent> The annualized management fee to charge depositors (default: "0")
34
+ -s, --profit-share <percent> The percentage of profits charged by manager (default: "0")
35
+ -p, --permissioned Provide this flag to make the vault permissioned, vault-depositors will need to be initialized by the manager
36
+ (default: false)
37
+ -a, --min-deposit-amount <number The minimum token amount allowed to deposit (default: "0")
38
+ -d, --delegate <publicKey> The address to make the delegate of the vault
39
+ -h, --help display help for command
40
+ ```
41
+
42
+ To update params in a vault:
21
43
  ```
44
+ $ yarn cli manager-update-vault --help
45
+ Usage: cli manager-update-vault [options]
22
46
 
47
+ Update vault params for a manager
48
+
49
+ Options:
50
+ --vault-address <address> Address of the vault to update
51
+ -r, --redeem-period <number> The new redeem period (can only be lowered)
52
+ -x, --max-tokens <number> The max tokens the vault can accept
53
+ -a, --min-deposit-amount <number The minimum token amount allowed to deposit
54
+ -m, --management-fee <percent> The new management fee (can only be lowered)
55
+ -s, --profit-share <percent> The new profit share percentage (can only be lowered)
56
+ -p, --permissioned <boolean> Set the vault as permissioned (true) or open (false) (default: false)
57
+ -h, --help display help for command
58
+ ```
23
59
 
24
60
  Make a deposit into a vault (as a manager, `DEPOSIT_AMOUNT` in human precision):
25
61
  ```
package/cli/cli.ts CHANGED
@@ -1,17 +1,20 @@
1
1
  import {
2
2
  initVault,
3
3
  viewVault,
4
+ deriveVaultAddress,
4
5
  managerDeposit,
5
6
  managerRequestWithdraw,
6
7
  managerCancelWithdraw,
7
8
  managerWithdraw,
8
9
  managerUpdateVault,
10
+ managerUpdateVaultDelegate,
9
11
  applyProfitShare,
10
12
  initVaultDepositor,
11
13
  deposit,
12
14
  requestWithdraw,
13
15
  withdraw,
14
16
  listDepositorsForVault,
17
+ managerUpdateMarginTradingEnabled
15
18
  } from "./commands";
16
19
 
17
20
  import { Command, Option } from 'commander';
@@ -20,19 +23,32 @@ require('dotenv').config();
20
23
 
21
24
  const program = new Command();
22
25
  program
23
- .addOption(new Option("-r, --rpc <url>", "RPC URL to use").env("RPC_URL").makeOptionMandatory(true))
24
- .addOption(new Option("-k, --keypair <fiilepath>", "Path to keypair file").env("KEYPAIR_PATH"))
26
+ .addOption(new Option("-u, --url <url>", "RPC URL to use for requests").env("RPC_URL").makeOptionMandatory(true))
27
+ .addOption(new Option("-k, --keypair <filepath>", "Path to keypair file").env("KEYPAIR_PATH"))
25
28
  .addOption(new Option("--commitment <commitment>", "State commitment to use").default("confirmed"));
26
29
  program
27
- .command("init")
30
+ .command("init-vault")
28
31
  .description("Initialize a new vault")
29
- .option("-n, --name <vaultName>", "Name of the vault to create", "my new vault")
32
+ .requiredOption("-n, --name <string>", "Name of the vault to create")
33
+ .option("-i, --market-index <number>", "Spot market index to accept for deposits (default 0 == USDC)", "0")
34
+ .option("-r, --redeem-period <number>", "The period (in seconds) depositors must wait after requesting a withdraw (default: 7 days)", (7 * 60 * 60 * 24).toString())
35
+ .option("-x, --max-tokens <number>", "The max number of spot marketIndex tokens the vault can accept (default 0 == unlimited)", "0")
36
+ .option("-m, --management-fee <percent>", "The annualized management fee to charge depositors", "0")
37
+ .option("-s, --profit-share <percent>", "The percentage of profits charged by manager", "0")
38
+ .option("-p, --permissioned", "Provide this flag to make the vault permissioned, vault-depositors will need to be initialized by the manager", false)
39
+ .option("-a, --min-deposit-amount <number", "The minimum token amount allowed to deposit", "0")
40
+ .option("-d, --delegate <publicKey>", "The address to make the delegate of the vault")
30
41
  .action((opts) => initVault(program, opts));
31
42
  program
32
43
  .command("view-vault")
33
44
  .description("View Vault account details")
34
45
  .addOption(new Option("--vault-address <address>", "Address of the Vault to view").makeOptionMandatory(true))
35
46
  .action((opts) => viewVault(program, opts));
47
+ program
48
+ .command("derive-vault-address")
49
+ .description("Derives the vault address from its name")
50
+ .addOption(new Option("--vault-name <string>", "Name of the vault").makeOptionMandatory(true))
51
+ .action((opts) => deriveVaultAddress(program, opts));
36
52
  program
37
53
  .command("view-vault-depositor")
38
54
  .description("View VaultDepositor account details")
@@ -43,25 +59,43 @@ program
43
59
  program
44
60
  .command("list-vault-depositors")
45
61
  .description("List VaultDepositors for a Vault")
46
- .addOption(new Option("--vault-address <address>", "Address of the Vault to view").makeOptionMandatory(true))
62
+ .addOption(new Option("--vault-address <address>", "Address of the Vault to list depositors").makeOptionMandatory(true))
47
63
  .action((opts) => listDepositorsForVault(program, opts));
48
64
  program
49
65
  .command("manager-deposit")
50
66
  .description("Make a deposit to your vault")
51
- .addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
67
+ .addOption(new Option("--vault-address <address>", "Address of the vault to deposit to").makeOptionMandatory(true))
52
68
  .addOption(new Option("--amount <amount>", "Amount to deposit (human format, 5 for 5 USDC)").makeOptionMandatory(true))
53
69
  .action((opts) => managerDeposit(program, opts));
54
70
  program
55
71
  .command("manager-request-withdraw")
56
72
  .description("Make a withdraw request from your vault")
57
- .addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
73
+ .addOption(new Option("--vault-address <address>", "Address of the vault to withdraw from").makeOptionMandatory(true))
58
74
  .addOption(new Option("--shares <shares>", "Amount of shares to withdraw (raw precision, as expected by contract)").makeOptionMandatory(true))
59
75
  .action((opts) => managerRequestWithdraw(program, opts));
60
76
  program
61
77
  .command("manager-update-vault")
62
78
  .description("Update vault params for a manager")
63
- .addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
79
+ .addOption(new Option("--vault-address <address>", "Address of the vault to update ").makeOptionMandatory(true))
80
+ .option("-r, --redeem-period <number>", "The new redeem period (can only be lowered)")
81
+ .option("-x, --max-tokens <number>", "The max tokens the vault can accept")
82
+ .option("-a, --min-deposit-amount <number", "The minimum token amount allowed to deposit")
83
+ .option("-m, --management-fee <percent>", "The new management fee (can only be lowered)")
84
+ .option("-s, --profit-share <percent>", "The new profit share percentage (can only be lowered)")
85
+ .option("-p, --permissioned <boolean>", "Set the vault as permissioned (true) or open (false)")
64
86
  .action((opts) => managerUpdateVault(program, opts));
87
+ program
88
+ .command("manager-update-delegate")
89
+ .description("Update vault params for a manager")
90
+ .addOption(new Option("--vault-address <address>", "Address of the vault to update ").makeOptionMandatory(true))
91
+ .addOption(new Option("-d, --delegate <publickey>", "The new delegate authority for the vault").makeOptionMandatory(true))
92
+ .action((opts) => managerUpdateVaultDelegate(program, opts));
93
+ program
94
+ .command("manager-update-margin-trading-enabled")
95
+ .description("Update vault margin trading permissiones a manager")
96
+ .addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
97
+ .addOption(new Option("--enabled <enabled>", "true to enable, false to disable").makeOptionMandatory(true))
98
+ .action((opts) => managerUpdateMarginTradingEnabled(program, opts));
65
99
  program
66
100
  .command("manager-withdraw")
67
101
  .description("Make a withdraw from your vault")
@@ -102,4 +136,6 @@ program
102
136
  .addOption(new Option("--authority <vaultDepositorAuthority>", "VaultDepositor authority address").makeOptionMandatory(false))
103
137
  .action((opts) => withdraw(program, opts));
104
138
 
105
- program.parseAsync().then(() => { });
139
+ program.parseAsync().then(() => {
140
+ process.exit(0);
141
+ });
@@ -36,13 +36,10 @@ export const applyProfitShare = async (program: Command, cmdOpts: OptionValues)
36
36
  }
37
37
  console.log(`Cranking ${ixChunks.length} of ${chunkSize} depositors at a time...`);
38
38
 
39
- const txs = await Promise.all(ixChunks.map((ixs) => driftVault.createAndSendTxn(ixs)));
39
+ const txs = await Promise.all(ixChunks.map((ixs) => driftVault.createAndSendTxn(ixs, {
40
+ units: 2_000_000
41
+ })));
40
42
  for (const tx of txs) {
41
43
  console.log(`Crank tx: https://solscan.io/tx/${tx}`);
42
44
  }
43
-
44
-
45
- // const ix = await driftVault.getApplyProfitShareIx(vaultAddress, );
46
- // console.log(`Withrew ${cmdOpts.shares} shares as vault manager: ${tx}`);
47
- console.log("Done!");
48
45
  };
@@ -31,5 +31,4 @@ export const deposit = async (program: Command, cmdOpts: OptionValues) => {
31
31
  console.log(`depositing: ${depositBN.toString()}`);
32
32
  const tx = await driftVault.deposit(vaultDepositorAddress, depositBN);
33
33
  console.log(`Deposited ${cmdOpts.amount} to vault as manager: ${tx}`);
34
- console.log("Done!");
35
34
  };
@@ -0,0 +1,15 @@
1
+ import {
2
+ OptionValues,
3
+ Command
4
+ } from "commander";
5
+ import { encodeName } from "@drift-labs/sdk";
6
+ import { VAULT_PROGRAM_ID, getVaultAddressSync } from "../../src";
7
+
8
+ export const deriveVaultAddress = async (_program: Command, cmdOpts: OptionValues) => {
9
+
10
+ const vaultName = cmdOpts.vaultName;
11
+ const vaultNameBytes = encodeName(vaultName!);
12
+ const vaultAddress = getVaultAddressSync(VAULT_PROGRAM_ID, vaultNameBytes);
13
+
14
+ console.log(`Vault address: ${vaultAddress.toBase58()}`);
15
+ };
@@ -1,13 +1,16 @@
1
1
  export * from './initVault';
2
2
  export * from './viewVault';
3
+ export * from './deriveVaultAddress';
3
4
  export * from './managerDeposit';
4
5
  export * from './managerRequestWithdraw';
5
6
  export * from './managerCancelWithdraw';
6
7
  export * from './managerWithdraw';
7
8
  export * from './managerUpdateVault';
9
+ export * from './managerUpdateVaultDelegate';
8
10
  export * from './applyProfitShare';
9
11
  export * from './initVaultDepositor';
10
12
  export * from './deposit';
11
13
  export * from './requestWithdraw';
12
14
  export * from './withdraw';
13
- export * from './listDepositorsForVault';
15
+ export * from './listDepositorsForVault';
16
+ export * from './managerUpdateMarginTradingEnabled';
@@ -3,6 +3,8 @@ import {
3
3
  PERCENTAGE_PRECISION,
4
4
  PublicKey,
5
5
  TEN,
6
+ convertToNumber,
7
+ decodeName,
6
8
  } from "@drift-labs/sdk";
7
9
  import {
8
10
  OptionValues,
@@ -21,41 +23,120 @@ export const initVault = async (program: Command, cmdOpts: OptionValues) => {
21
23
  driftVault
22
24
  } = await getCommandContext(program, true);
23
25
 
24
- const spotMarket = driftClient.getSpotMarketAccount(0); // takes USDC deposits
26
+ const newVaultName = cmdOpts.name;
27
+ if (!newVaultName) {
28
+ throw new Error("Must provide vault name with -n/--name");
29
+ }
30
+ const vaultNameBytes = encodeName(newVaultName!);
31
+
32
+ let spotMarketIndex = cmdOpts.marketIndex;
33
+ if (!spotMarketIndex) {
34
+ spotMarketIndex = "0";
35
+ }
36
+ spotMarketIndex = parseInt(spotMarketIndex);
37
+ const spotMarket = driftClient.getSpotMarketAccount(spotMarketIndex); // takes USDC deposits
25
38
  if (!spotMarket) {
26
39
  throw new Error("No spot market found");
27
40
  }
28
41
  const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
42
+ const spotMarketName = decodeName(spotMarket.name);
29
43
 
30
- let newVaultName = cmdOpts.name;
31
- if (!newVaultName) {
32
- newVaultName = "my new vault";
44
+ let redeemPeriodSec = cmdOpts.redeemPeriod;
45
+ if (!redeemPeriodSec) {
46
+ redeemPeriodSec = (7 * 60 * 60 * 24).toString(); // 7 days
47
+ }
48
+ redeemPeriodSec = parseInt(redeemPeriodSec);
49
+
50
+ let maxTokens = cmdOpts.maxTokens;
51
+ if (!maxTokens) {
52
+ maxTokens = "0";
53
+ }
54
+ maxTokens = parseInt(maxTokens);
55
+ const maxTokensBN = new BN(maxTokens).mul(spotPrecision);
56
+
57
+ let managementFee = cmdOpts.managementFee;
58
+ if (!managementFee) {
59
+ managementFee = "0";
60
+ }
61
+ managementFee = parseInt(managementFee);
62
+ const managementFeeBN = new BN(managementFee).mul(PERCENTAGE_PRECISION).div(new BN(100));
63
+
64
+ let profitShare = cmdOpts.profitShare;
65
+ if (!profitShare) {
66
+ profitShare = "0";
67
+ }
68
+ profitShare = parseInt(profitShare);
69
+ const profitShareBN = new BN(profitShare).mul(PERCENTAGE_PRECISION).div(new BN(100));
70
+
71
+ let permissioned = cmdOpts.permissioned;
72
+ if (!permissioned) {
73
+ permissioned = false;
33
74
  }
34
- const vaultNameBytes = encodeName(newVaultName!);
35
- console.log(`Initializing a new vault named '${newVaultName}'`);
75
+
76
+ let minDepositAmount = cmdOpts.minDepositAmount;
77
+ if (!minDepositAmount) {
78
+ minDepositAmount = "0";
79
+ }
80
+ minDepositAmount = parseInt(minDepositAmount);
81
+ const minDepositAmountBN = new BN(minDepositAmount).mul(spotPrecision);
82
+
83
+ let delegate = cmdOpts.delegate;
84
+ if (!delegate) {
85
+ delegate = driftClient.wallet.publicKey;
86
+ } else {
87
+ try {
88
+ delegate = new PublicKey(delegate);
89
+ } catch (err) {
90
+ console.error(`Invalid delegate address: ${err}`);
91
+ delegate = driftClient.wallet.publicKey;
92
+ }
93
+ }
94
+
95
+ console.log(`Initializing a new vault with params:`);
96
+ console.log(` VaultName: ${newVaultName}`);
97
+ console.log(` DepositSpotMarketIndex: ${spotMarketIndex} (${spotMarketName})`);
98
+ console.log(` MaxTokens: ${convertToNumber(maxTokensBN, spotPrecision)} ${spotMarketName}`);
99
+ console.log(` MinDepositAmount: ${convertToNumber(minDepositAmountBN, spotPrecision)} ${spotMarketName}`);
100
+ console.log(` ManagementFee: ${convertToNumber(managementFeeBN, PERCENTAGE_PRECISION) * 100.0}%`);
101
+ console.log(` ProfitShare: ${convertToNumber(profitShareBN, PERCENTAGE_PRECISION) * 100.0}%`);
102
+ console.log(` Permissioned: ${permissioned}`);
103
+ console.log(` Delegate: ${delegate.toBase58()}`);
104
+
105
+ const readline = require('readline').createInterface({
106
+ input: process.stdin,
107
+ output: process.stdout
108
+ });
109
+ console.log('');
110
+ const answer = await new Promise(resolve => {
111
+ readline.question('Is the above information correct? (yes/no) ', (answer) => {
112
+ readline.close();
113
+ resolve(answer);
114
+ });
115
+ });
116
+ if ((answer as string).toLowerCase() !== 'yes') {
117
+ console.log('Initialization cancelled.');
118
+ readline.close();
119
+ process.exit(0);
120
+ }
121
+ console.log('Creating vault...');
36
122
 
37
123
  const initTx = await driftVault.initializeVault({
38
124
  name: vaultNameBytes,
39
- spotMarketIndex: 0,
40
- redeemPeriod: new BN(3 * 60 * 60), // 3 hours
41
- maxTokens: new BN(1000).mul(spotPrecision), // 1000 USDC cap
42
- managementFee: PERCENTAGE_PRECISION.div(new BN(50)), // 2%
43
- profitShare: PERCENTAGE_PRECISION.div(new BN(5)), // 20%
125
+ spotMarketIndex,
126
+ redeemPeriod: new BN(redeemPeriodSec),
127
+ maxTokens: maxTokensBN,
128
+ managementFee: managementFeeBN,
129
+ profitShare: profitShareBN.toNumber(),
44
130
  hurdleRate: 0,
45
- permissioned: false,
46
- minDepositAmount: new BN(10).mul(spotPrecision), // 10 USDC minimum deposit
131
+ permissioned,
132
+ minDepositAmount: minDepositAmountBN,
47
133
  });
48
- console.log(`Initialized vault, tx: ${initTx}`);
134
+ console.log(`Initialized vault, tx: https://solscan.io/tx/${initTx}`);
49
135
 
50
136
  const vaultAddress = getVaultAddressSync(VAULT_PROGRAM_ID, vaultNameBytes);
51
- console.log(`New vault address: ${vaultAddress}`);
137
+ console.log(`\nNew vault address: ${vaultAddress}\n`);
52
138
 
53
- let delegate = cmdOpts.delegate;
54
- if (!delegate) {
55
- delegate = driftClient.wallet.publicKey.toBase58();
56
- }
57
- console.log(`Updating the drift account delegate to: ${delegate}`);
58
- const updateDelegateTx = await driftVault.updateDelegate(vaultAddress, new PublicKey(delegate));
59
- console.log(`update delegate tx: ${updateDelegateTx}`);
60
- console.log("Done!");
139
+ console.log(`Updating the drift account delegate to: ${delegate}...`);
140
+ const updateDelegateTx = await driftVault.updateDelegate(vaultAddress, delegate);
141
+ console.log(`update delegate tx: https://solscan.io/tx/${updateDelegateTx}`);
61
142
  };
@@ -39,5 +39,4 @@ export const initVaultDepositor = async (program: Command, cmdOpts: OptionValues
39
39
  const tx = await driftVault.initializeVaultDepositor(vaultAddress, depositAuthority);
40
40
  console.log(`VaultDepositor initialized for ${depositAuthority}: ${tx}`);
41
41
  console.log(`VaultDepositor address: ${vaultDepositorAddress}`);
42
- console.log("Done!");
43
42
  };
@@ -29,5 +29,4 @@ export const listDepositorsForVault = async (program: Command, cmdOpts: OptionVa
29
29
  console.log(vaultDepositor.publicKey.toBase58());
30
30
  });
31
31
  // printVaultDepositor(vaultDepositor);
32
- console.log("Done!");
33
32
  };
@@ -21,5 +21,4 @@ export const managerCancelWithdraw = async (program: Command, cmdOpts: OptionVal
21
21
 
22
22
  const tx = await driftVault.managerCancelWithdrawRequest(vaultAddress);
23
23
  console.log(`Canceled withdraw as vault manager: https://solscan.io/tx/${tx}`);
24
- console.log("Done!");
25
24
  };
@@ -30,5 +30,4 @@ export const managerDeposit = async (program: Command, cmdOpts: OptionValues) =>
30
30
 
31
31
  const tx = await driftVault.managerDeposit(vaultAddress, depositBN);
32
32
  console.log(`Deposited ${cmdOpts.amount} to vault as manager: ${tx}`);
33
- console.log("Done!");
34
33
  };
@@ -23,5 +23,4 @@ export const managerRequestWithdraw = async (program: Command, cmdOpts: OptionVa
23
23
 
24
24
  const tx = await driftVault.managerRequestWithdraw(vaultAddress, new BN(cmdOpts.shares), WithdrawUnit.SHARES);
25
25
  console.log(`Requested to withraw ${cmdOpts.shares} shares as vault manager: https://solscan.io/tx/${tx}`);
26
- console.log("Done!");
27
26
  };
@@ -0,0 +1,26 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ OptionValues,
4
+ Command
5
+ } from "commander";
6
+ import { getCommandContext } from "../utils";
7
+
8
+ export const managerUpdateMarginTradingEnabled= async (program: Command, cmdOpts: OptionValues) => {
9
+
10
+ let vaultAddress: PublicKey;
11
+ try {
12
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
13
+ } catch (err) {
14
+ console.error("Invalid vault address");
15
+ process.exit(1);
16
+ }
17
+
18
+ const {
19
+ driftVault
20
+ } = await getCommandContext(program, true);
21
+
22
+ const enabled = cmdOpts.enabled ? (cmdOpts.enabled as string).toLowerCase() === "true" : false;
23
+
24
+ const tx = await driftVault.updateMarginTradingEnabled(vaultAddress, enabled);
25
+ console.log(`Updated margin trading vault manager: https://solscan.io/tx/${tx}`);
26
+ };
@@ -4,7 +4,7 @@ import {
4
4
  Command
5
5
  } from "commander";
6
6
  import { getCommandContext } from "../utils";
7
- import { BN } from "@drift-labs/sdk";
7
+ import { BN, PERCENTAGE_PRECISION, TEN, convertToNumber, decodeName } from "@drift-labs/sdk";
8
8
 
9
9
  export const managerUpdateVault = async (program: Command, cmdOpts: OptionValues) => {
10
10
 
@@ -17,20 +17,102 @@ export const managerUpdateVault = async (program: Command, cmdOpts: OptionValues
17
17
  }
18
18
 
19
19
  const {
20
- driftVault
20
+ driftVault,
21
+ driftClient,
21
22
  } = await getCommandContext(program, true);
22
23
 
24
+ const vault = await driftVault.getVault(vaultAddress);
25
+ const spotMarket = driftClient.getSpotMarketAccount(vault.spotMarketIndex);
26
+ if (!spotMarket) {
27
+ throw new Error("No spot market found");
28
+ }
29
+ const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
30
+ const spotMarketName = decodeName(spotMarket.name);
31
+
32
+ let redeemPeriodSec = cmdOpts.redeemPeriod ?? null;
33
+ let redeemPeriodBN: BN | null = null;
34
+ if (redeemPeriodSec !== undefined && redeemPeriodSec !== null) {
35
+ redeemPeriodSec = parseInt(redeemPeriodSec);
36
+ redeemPeriodBN = new BN(redeemPeriodSec);
37
+ }
38
+
39
+ let maxTokens = cmdOpts.maxTokens;
40
+ let maxTokensBN: BN | null = null;
41
+ if (maxTokens !== undefined && maxTokens !== null) {
42
+ maxTokens = parseInt(maxTokens);
43
+ maxTokensBN = new BN(maxTokens).mul(spotPrecision);
44
+ }
45
+
46
+ let managementFee = cmdOpts.managementFee;
47
+ let managementFeeBN: BN | null = null;
48
+ if (managementFee !== undefined && managementFee !== null) {
49
+ managementFee = parseInt(managementFee);
50
+ managementFeeBN = new BN(managementFee).mul(PERCENTAGE_PRECISION).div(new BN(100));
51
+ }
52
+
53
+ let profitShare = cmdOpts.profitShare;
54
+ let profitShareNumber: number | null = null;
55
+ if (profitShare !== undefined && profitShare !== null) {
56
+ profitShare = parseInt(profitShare);
57
+ profitShareNumber = profitShare * PERCENTAGE_PRECISION.toNumber() / 100.0;
58
+ }
59
+
60
+ const permissioned: boolean | null = (cmdOpts.permissioned === null || cmdOpts.permissioned === undefined) ? null : cmdOpts.permissioned;
61
+
62
+ let minDepositAmount = cmdOpts.minDepositAmount;
63
+ let minDepositAmountBN: BN | null = null;
64
+ if (!minDepositAmount) {
65
+ minDepositAmount = parseInt(minDepositAmount);
66
+ minDepositAmountBN = new BN(minDepositAmount).mul(spotPrecision);
67
+ }
68
+
69
+ console.log(`Updating params:`);
70
+ console.log(` RedeemPeriod: ${vault.redeemPeriod.toNumber()} -> ${redeemPeriodBN}`);
71
+ const maxTokensBefore = convertToNumber(vault.maxTokens, spotPrecision);
72
+ const maxTokensAfter = maxTokensBN ? convertToNumber(maxTokensBN, spotPrecision) : 'unchanged';
73
+ console.log(` MaxTokens: ${maxTokensBefore} ${spotMarketName} -> ${maxTokensAfter} ${spotMarketName}`);
74
+ const minDepositAmountBefore = convertToNumber(vault.minDepositAmount, spotPrecision);
75
+ const minDepositAmountAfter = minDepositAmountBN ? convertToNumber(minDepositAmountBN, spotPrecision) : 'unchanged';
76
+ console.log(` MinDepositAmount: ${minDepositAmountBefore} ${spotMarketName} -> ${minDepositAmountAfter} ${spotMarketName}`);
77
+ const managementFeeBefore = convertToNumber(vault.managementFee, PERCENTAGE_PRECISION) * 100.0;
78
+ const managementFeeAfter = managementFeeBN ? `${convertToNumber(managementFeeBN, PERCENTAGE_PRECISION) * 100.0}%` : 'unchanged';
79
+ console.log(` ManagementFee: ${managementFeeBefore}% -> ${managementFeeAfter}`);
80
+ const profitShareBefore = vault.profitShare / PERCENTAGE_PRECISION.toNumber() * 100.0;
81
+ const profitShareAfter = profitShareNumber !== null ? `${profitShareNumber / PERCENTAGE_PRECISION.toNumber() * 100.0}%` : 'unchanged';
82
+ console.log(` ProfitShare: ${profitShareBefore}% -> ${profitShareAfter}`);
83
+ const permissionedBefore = vault.permissioned;
84
+ const permissionedAfter = permissioned !== null ? permissioned : 'unchanged ';
85
+ console.log(` Permissioned: ${permissionedBefore} -> ${permissionedAfter}`);
86
+
87
+ const readline = require('readline').createInterface({
88
+ input: process.stdin,
89
+ output: process.stdout
90
+ });
91
+ console.log('');
92
+ const answer = await new Promise(resolve => {
93
+ readline.question('Is the above information correct? (yes/no) ', (answer) => {
94
+ readline.close();
95
+ resolve(answer);
96
+ });
97
+ });
98
+ if ((answer as string).toLowerCase() !== 'yes') {
99
+ console.log('Vault update canceled.');
100
+ readline.close();
101
+ process.exit(0);
102
+ }
103
+ console.log('Updating vault...');
104
+
105
+ // null means unchanged
23
106
  const newParams = {
24
- redeemPeriod: new BN(30 * 60 * 60 * 24), // 30 days
25
- maxTokens: null,
26
- managementFee: null,
27
- minDepositAmount: null,
28
- profitShare: null,
107
+ redeemPeriod: redeemPeriodBN,
108
+ maxTokens: maxTokensBN,
109
+ minDepositAmount: minDepositAmountBN,
110
+ managementFee: managementFeeBN,
111
+ profitShare: profitShareNumber,
29
112
  hurdleRate: null,
30
- permissioned: null,
113
+ permissioned
31
114
  };
32
115
 
33
116
  const tx = await driftVault.managerUpdateVault(vaultAddress, newParams);
34
117
  console.log(`Updated vault params as vault manager: https://solscan.io/tx/${tx}`);
35
- console.log("Done!");
36
118
  };
@@ -0,0 +1,35 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ OptionValues,
4
+ Command
5
+ } from "commander";
6
+ import { getCommandContext } from "../utils";
7
+
8
+ export const managerUpdateVaultDelegate = async (program: Command, cmdOpts: OptionValues) => {
9
+
10
+ let vaultAddress: PublicKey;
11
+ try {
12
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
13
+ } catch (err) {
14
+ console.error("Invalid vault address");
15
+ process.exit(1);
16
+ }
17
+
18
+ const {
19
+ driftVault
20
+ } = await getCommandContext(program, true);
21
+
22
+ let delegate = cmdOpts.delegate;
23
+ if (!delegate) {
24
+ throw new Error(`Must provide delegate address`);
25
+ } else {
26
+ try {
27
+ delegate = new PublicKey(delegate);
28
+ } catch (err) {
29
+ throw new Error(`Invalid delegate address: ${err}`);
30
+ }
31
+ }
32
+
33
+ const tx = await driftVault.updateDelegate(vaultAddress, delegate);
34
+ console.log(`Updated vault delegate to ${delegate.toBase58()}: https://solscan.io/tx/${tx}`);
35
+ };
@@ -21,5 +21,4 @@ export const managerWithdraw = async (program: Command, cmdOpts: OptionValues) =
21
21
 
22
22
  const tx = await driftVault.managerWithdraw(vaultAddress);
23
23
  console.log(`Withrew as vault manager: https://solscan.io/tx/${tx}`);
24
- console.log("Done!");
25
24
  };
@@ -25,5 +25,4 @@ export const requestWithdraw = async (program: Command, cmdOpts: OptionValues) =
25
25
 
26
26
  const tx = await driftVault.requestWithdraw(vaultDepositorAddress, withdrawAmountBN, WithdrawUnit.SHARES);
27
27
  console.log(`Requsted to withdraw ${cmdOpts.amount} shares from the vault: ${tx}`);
28
- console.log("Done!");
29
28
  };
@@ -39,5 +39,4 @@ export const vaultDeposit = async (program: Command, cmdOpts: OptionValues) => {
39
39
  const tx = await driftVault.initializeVaultDepositor(vaultAddress, depositAuthority);
40
40
  console.log(`VaultDepositor initialized for ${depositAuthority}: ${tx}`);
41
41
  console.log(`VaultDepositor address: ${vaultDepositorAddress}`);
42
- console.log("Done!");
43
42
  };
@@ -39,5 +39,4 @@ export const vaultWithdraw= async (program: Command, cmdOpts: OptionValues) => {
39
39
  const tx = await driftVault.initializeVaultDepositor(vaultAddress, depositAuthority);
40
40
  console.log(`VaultDepositor initialized for ${depositAuthority}: ${tx}`);
41
41
  console.log(`VaultDepositor address: ${vaultDepositorAddress}`);
42
- console.log("Done!");
43
42
  };