@drift-labs/vaults-sdk 0.5.20 → 0.5.21
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 +33 -0
- package/cli/commands/index.ts +1 -0
- package/cli/commands/initVault.ts +44 -19
- package/cli/commands/managerApplyProfitShare.ts +32 -0
- package/cli/commands/managerCancelWithdraw.ts +8 -3
- package/cli/commands/managerDeposit.ts +8 -3
- package/cli/commands/managerRequestWithdraw.ts +17 -5
- package/cli/commands/managerUpdateMarginTradingEnabled.ts +9 -4
- package/cli/commands/managerUpdatePoolId.ts +36 -0
- package/cli/commands/managerUpdateVault.ts +9 -4
- package/cli/commands/managerUpdateVaultDelegate.ts +9 -3
- package/cli/commands/managerUpdateVaultManager.ts +77 -0
- package/cli/commands/managerWithdraw.ts +8 -3
- package/cli/utils.ts +14 -1
- package/lib/types/drift_vaults.d.ts +21 -0
- package/lib/types/drift_vaults.js +21 -0
- package/lib/vaultClient.d.ts +68 -8
- package/lib/vaultClient.js +189 -94
- package/package.json +1 -1
- package/src/idl/drift_vaults.json +21 -0
- package/src/types/drift_vaults.ts +42 -0
- package/src/vaultClient.ts +373 -115
package/cli/cli.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
managerCancelWithdraw,
|
|
10
10
|
managerWithdraw,
|
|
11
11
|
managerUpdateVault,
|
|
12
|
+
managerUpdateVaultManager,
|
|
12
13
|
managerUpdateVaultDelegate,
|
|
13
14
|
applyProfitShare,
|
|
14
15
|
initVaultDepositor,
|
|
@@ -25,6 +26,8 @@ import {
|
|
|
25
26
|
|
|
26
27
|
import { Command, Option } from 'commander';
|
|
27
28
|
import { viewVaultDepositor } from "./commands/viewVaultDepositor";
|
|
29
|
+
import { managerUpdatePoolId } from "./commands/managerUpdatePoolId";
|
|
30
|
+
import { managerApplyProfitShare } from "./commands/managerApplyProfitShare";
|
|
28
31
|
|
|
29
32
|
const program = new Command();
|
|
30
33
|
program
|
|
@@ -44,6 +47,8 @@ program
|
|
|
44
47
|
.option("-p, --permissioned", "Provide this flag to make the vault permissioned, vault-depositors will need to be initialized by the manager", false)
|
|
45
48
|
.option("-a, --min-deposit-amount <number", "The minimum token amount allowed to deposit", "0")
|
|
46
49
|
.option("-d, --delegate <publicKey>", "The address to make the delegate of the vault")
|
|
50
|
+
.addOption(new Option("--manager <publickey>", "The manager for the vault").makeOptionMandatory(true))
|
|
51
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
47
52
|
.action((opts) => initVault(program, opts));
|
|
48
53
|
program
|
|
49
54
|
.command("view-vault")
|
|
@@ -72,6 +77,7 @@ program
|
|
|
72
77
|
.description("Make a deposit to your vault")
|
|
73
78
|
.addOption(new Option("--vault-address <address>", "Address of the vault to deposit to").makeOptionMandatory(true))
|
|
74
79
|
.addOption(new Option("--amount <amount>", "Amount to deposit (human format, 5 for 5 USDC)").makeOptionMandatory(true))
|
|
80
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
75
81
|
.action((opts) => managerDeposit(program, opts));
|
|
76
82
|
program
|
|
77
83
|
.command("manager-request-withdraw")
|
|
@@ -79,6 +85,7 @@ program
|
|
|
79
85
|
.addOption(new Option("--vault-address <address>", "Address of the vault to withdraw from").makeOptionMandatory(true))
|
|
80
86
|
.addOption(new Option("--shares <shares>", "Amount of shares to withdraw (raw precision, as expected by contract)").makeOptionMandatory(false))
|
|
81
87
|
.addOption(new Option("--amount <amount>", "Amount of spot asset to withdraw (human format, 5 for 5 USDC)").makeOptionMandatory(false))
|
|
88
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
82
89
|
.action((opts) => managerRequestWithdraw(program, opts));
|
|
83
90
|
program
|
|
84
91
|
.command("manager-update-vault")
|
|
@@ -90,28 +97,54 @@ program
|
|
|
90
97
|
.option("-m, --management-fee <percent>", "The new management fee (can only be lowered)")
|
|
91
98
|
.option("-s, --profit-share <percent>", "The new profit share percentage (can only be lowered)")
|
|
92
99
|
.option("-p, --permissioned <boolean>", "Set the vault as permissioned (true) or open (false)")
|
|
100
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
93
101
|
.action((opts) => managerUpdateVault(program, opts));
|
|
102
|
+
program
|
|
103
|
+
.command("manager-update-vault-manager")
|
|
104
|
+
.description("Update the manager of a vault")
|
|
105
|
+
.addOption(new Option("--vault-address <address>", "Address of the vault to update ").makeOptionMandatory(true))
|
|
106
|
+
.addOption(new Option("--new-manager <publickey>", "The new manager for the vault").makeOptionMandatory(true))
|
|
107
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
108
|
+
.action((opts) => managerUpdateVaultManager(program, opts));
|
|
94
109
|
program
|
|
95
110
|
.command("manager-update-delegate")
|
|
96
111
|
.description("Update vault params for a manager")
|
|
97
112
|
.addOption(new Option("--vault-address <address>", "Address of the vault to update ").makeOptionMandatory(true))
|
|
98
113
|
.addOption(new Option("-d, --delegate <publickey>", "The new delegate authority for the vault").makeOptionMandatory(true))
|
|
114
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
99
115
|
.action((opts) => managerUpdateVaultDelegate(program, opts));
|
|
100
116
|
program
|
|
101
117
|
.command("manager-update-margin-trading-enabled")
|
|
102
118
|
.description("Update vault margin trading permissiones a manager")
|
|
103
119
|
.addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
|
|
104
120
|
.addOption(new Option("--enabled <enabled>", "true to enable, false to disable").makeOptionMandatory(true))
|
|
121
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
105
122
|
.action((opts) => managerUpdateMarginTradingEnabled(program, opts));
|
|
123
|
+
program
|
|
124
|
+
.command("manager-update-pool-id")
|
|
125
|
+
.description("Update the pool id for a vault")
|
|
126
|
+
.addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
|
|
127
|
+
.addOption(new Option("--pool-id <pool-id>", "New pool id for the vault").makeOptionMandatory(true))
|
|
128
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
129
|
+
.action((opts) => managerUpdatePoolId(program, opts));
|
|
130
|
+
program
|
|
131
|
+
.command("manager-apply-profit-share")
|
|
132
|
+
.description("Update the pool id for a vault")
|
|
133
|
+
.addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
|
|
134
|
+
.addOption(new Option("--vault-depositor <address>", "Address of the vault depositor to apply profit share for").makeOptionMandatory(true))
|
|
135
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
136
|
+
.action((opts) => managerApplyProfitShare(program, opts));
|
|
106
137
|
program
|
|
107
138
|
.command("manager-withdraw")
|
|
108
139
|
.description("Make a withdraw from your vault")
|
|
109
140
|
.addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
|
|
141
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
110
142
|
.action((opts) => managerWithdraw(program, opts));
|
|
111
143
|
program
|
|
112
144
|
.command("manager-cancel-withdraw")
|
|
113
145
|
.description("Cancel a pending manager withdraw withdraw from your vault")
|
|
114
146
|
.addOption(new Option("--vault-address <address>", "Address of the vault to view").makeOptionMandatory(true))
|
|
147
|
+
.addOption(new Option("--dump-transaction-message", "Dump the transaction message to the console").makeOptionMandatory(false))
|
|
115
148
|
.action((opts) => managerCancelWithdraw(program, opts));
|
|
116
149
|
program
|
|
117
150
|
.command("apply-profit-share-all")
|
package/cli/commands/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './managerRequestWithdraw';
|
|
|
6
6
|
export * from './managerCancelWithdraw';
|
|
7
7
|
export * from './managerWithdraw';
|
|
8
8
|
export * from './managerUpdateVault';
|
|
9
|
+
export * from './managerUpdateVaultManager';
|
|
9
10
|
export * from './managerUpdateVaultDelegate';
|
|
10
11
|
export * from './applyProfitShare';
|
|
11
12
|
export * from './initVaultDepositor';
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
encodeName,
|
|
15
15
|
getVaultAddressSync,
|
|
16
16
|
} from "../../src";
|
|
17
|
-
import { getCommandContext } from "../utils";
|
|
17
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
18
18
|
import { VAULT_PROGRAM_ID } from "../../src/types/types";
|
|
19
19
|
|
|
20
20
|
export const initVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
@@ -101,6 +101,7 @@ export const initVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
|
101
101
|
console.log(` ProfitShare: ${convertToNumber(profitShareBN, PERCENTAGE_PRECISION) * 100.0}%`);
|
|
102
102
|
console.log(` Permissioned: ${permissioned}`);
|
|
103
103
|
console.log(` Delegate: ${delegate.toBase58()}`);
|
|
104
|
+
console.log(` Manager: ${cmdOpts.manager ? cmdOpts.manager : driftClient.wallet.publicKey.toBase58()}`);
|
|
104
105
|
|
|
105
106
|
const readline = require('readline').createInterface({
|
|
106
107
|
input: process.stdin,
|
|
@@ -118,25 +119,49 @@ export const initVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
|
118
119
|
readline.close();
|
|
119
120
|
process.exit(0);
|
|
120
121
|
}
|
|
121
|
-
console.log('Creating vault...');
|
|
122
|
-
|
|
123
|
-
const initTx = await driftVault.initializeVault({
|
|
124
|
-
name: vaultNameBytes,
|
|
125
|
-
spotMarketIndex,
|
|
126
|
-
redeemPeriod: new BN(redeemPeriodSec),
|
|
127
|
-
maxTokens: maxTokensBN,
|
|
128
|
-
managementFee: managementFeeBN,
|
|
129
|
-
profitShare: profitShareBN.toNumber(),
|
|
130
|
-
hurdleRate: 0,
|
|
131
|
-
permissioned,
|
|
132
|
-
minDepositAmount: minDepositAmountBN,
|
|
133
|
-
});
|
|
134
|
-
console.log(`Initialized vault, tx: https://solscan.io/tx/${initTx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
135
122
|
|
|
136
123
|
const vaultAddress = getVaultAddressSync(VAULT_PROGRAM_ID, vaultNameBytes);
|
|
137
|
-
console.log(`\nNew vault address: ${vaultAddress}\n`);
|
|
138
124
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
126
|
+
const initIx = await driftVault.getInitializeVaultIx({
|
|
127
|
+
name: vaultNameBytes,
|
|
128
|
+
spotMarketIndex,
|
|
129
|
+
redeemPeriod: new BN(redeemPeriodSec),
|
|
130
|
+
maxTokens: maxTokensBN,
|
|
131
|
+
managementFee: managementFeeBN,
|
|
132
|
+
profitShare: profitShareBN.toNumber(),
|
|
133
|
+
hurdleRate: 0,
|
|
134
|
+
permissioned,
|
|
135
|
+
minDepositAmount: minDepositAmountBN,
|
|
136
|
+
manager: cmdOpts.manager,
|
|
137
|
+
});
|
|
138
|
+
const updateDelegateIx = await driftVault.getUpdateDelegateIx(vaultAddress, delegate);
|
|
139
|
+
|
|
140
|
+
console.log(`New vault address will be: ${vaultAddress.toBase58()}`);
|
|
141
|
+
console.log(`Setting trading delegate to: ${delegate.toBase58()}`);
|
|
142
|
+
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log(`Base 58 encoded transaction:`);
|
|
145
|
+
console.log(dumpTransactionMessage(cmdOpts.manager ? new PublicKey(cmdOpts.manager) : driftClient.wallet.publicKey, [initIx, updateDelegateIx]));
|
|
146
|
+
} else {
|
|
147
|
+
const initTx = await driftVault.initializeVault({
|
|
148
|
+
name: vaultNameBytes,
|
|
149
|
+
spotMarketIndex,
|
|
150
|
+
redeemPeriod: new BN(redeemPeriodSec),
|
|
151
|
+
maxTokens: maxTokensBN,
|
|
152
|
+
managementFee: managementFeeBN,
|
|
153
|
+
profitShare: profitShareBN.toNumber(),
|
|
154
|
+
hurdleRate: 0,
|
|
155
|
+
permissioned,
|
|
156
|
+
minDepositAmount: minDepositAmountBN,
|
|
157
|
+
manager: cmdOpts.manager,
|
|
158
|
+
});
|
|
159
|
+
console.log(`Initialized vault, tx: https://solscan.io/tx/${initTx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
160
|
+
|
|
161
|
+
console.log(`\nNew vault address: ${vaultAddress}\n`);
|
|
162
|
+
|
|
163
|
+
console.log(`Updating the drift account delegate to: ${delegate}...`);
|
|
164
|
+
const updateDelegateTx = await driftVault.updateDelegate(vaultAddress, delegate);
|
|
165
|
+
console.log(`update delegate tx: https://solscan.io/tx/${updateDelegateTx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
166
|
+
}
|
|
142
167
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
|
+
|
|
8
|
+
export const managerApplyProfitShare = 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
|
+
driftClient
|
|
21
|
+
} = await getCommandContext(program, true);
|
|
22
|
+
|
|
23
|
+
const vaultDepositorAddress = new PublicKey(cmdOpts.vaultDepositor as string);
|
|
24
|
+
|
|
25
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
26
|
+
const tx = await driftVault.getApplyProfitShareIx(vaultAddress, vaultDepositorAddress);
|
|
27
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
28
|
+
} else {
|
|
29
|
+
const tx = await driftVault.applyProfitShare(vaultAddress, vaultDepositorAddress);
|
|
30
|
+
console.log(`Applied profit share: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
OptionValues,
|
|
4
4
|
Command
|
|
5
5
|
} from "commander";
|
|
6
|
-
import { getCommandContext } from "../utils";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
7
|
|
|
8
8
|
export const managerCancelWithdraw = async (program: Command, cmdOpts: OptionValues) => {
|
|
9
9
|
|
|
@@ -20,6 +20,11 @@ export const managerCancelWithdraw = async (program: Command, cmdOpts: OptionVal
|
|
|
20
20
|
driftClient
|
|
21
21
|
} = await getCommandContext(program, true);
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
24
|
+
const tx = await driftVault.getManagerCancelWithdrawRequestIx(vaultAddress);
|
|
25
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
26
|
+
} else {
|
|
27
|
+
const tx = await driftVault.managerCancelWithdrawRequest(vaultAddress);
|
|
28
|
+
console.log(`Canceled withdraw as vault manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
29
|
+
}
|
|
25
30
|
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
OptionValues,
|
|
5
5
|
Command
|
|
6
6
|
} from "commander";
|
|
7
|
-
import { getCommandContext } from "../utils";
|
|
7
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
8
8
|
|
|
9
9
|
export const managerDeposit = async (program: Command, cmdOpts: OptionValues) => {
|
|
10
10
|
|
|
@@ -29,6 +29,11 @@ export const managerDeposit = async (program: Command, cmdOpts: OptionValues) =>
|
|
|
29
29
|
const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
|
|
30
30
|
const depositBN = new BN(cmdOpts.amount * spotPrecision.toNumber());
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
33
|
+
const txs = await driftVault.getManagerDepositIx(vaultAddress, depositBN);
|
|
34
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, txs));
|
|
35
|
+
} else {
|
|
36
|
+
const tx = await driftVault.managerDeposit(vaultAddress, depositBN);
|
|
37
|
+
console.log(`Deposited ${cmdOpts.amount} to vault as manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
38
|
+
}
|
|
34
39
|
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
OptionValues,
|
|
5
5
|
Command
|
|
6
6
|
} from "commander";
|
|
7
|
-
import { getCommandContext } from "../utils";
|
|
7
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
8
8
|
import { WithdrawUnit } from "../../src/types/types";
|
|
9
9
|
|
|
10
10
|
export const managerRequestWithdraw = async (program: Command, cmdOpts: OptionValues) => {
|
|
@@ -27,8 +27,13 @@ export const managerRequestWithdraw = async (program: Command, cmdOpts: OptionVa
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (cmdOpts.shares && !cmdOpts.amount) {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
31
|
+
const tx = await driftVault.getManagerRequestWithdrawIx(vaultAddress, new BN(cmdOpts.shares), WithdrawUnit.SHARES);
|
|
32
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
33
|
+
} else {
|
|
34
|
+
const tx = await driftVault.managerRequestWithdraw(vaultAddress, new BN(cmdOpts.shares), WithdrawUnit.SHARES);
|
|
35
|
+
console.log(`Requested to withraw ${cmdOpts.shares} shares as vault manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
36
|
+
}
|
|
32
37
|
} else if (cmdOpts.amount && !cmdOpts.shares) {
|
|
33
38
|
const vault = await driftVault.getVault(vaultAddress);
|
|
34
39
|
const spotMarket = driftClient.getSpotMarketAccount(vault.spotMarketIndex);
|
|
@@ -39,8 +44,15 @@ export const managerRequestWithdraw = async (program: Command, cmdOpts: OptionVa
|
|
|
39
44
|
const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
|
|
40
45
|
const amount = parseFloat(cmdOpts.amount);
|
|
41
46
|
const amountBN = numberToSafeBN(amount, spotPrecision);
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
|
|
48
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
49
|
+
const tx = await driftVault.getManagerRequestWithdrawIx(vaultAddress, amountBN, WithdrawUnit.TOKEN);
|
|
50
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
51
|
+
} else {
|
|
52
|
+
const tx = await driftVault.managerRequestWithdraw(vaultAddress, amountBN, WithdrawUnit.TOKEN);
|
|
53
|
+
console.log(`Requested to withdraw ${amount} ${decodeName(spotMarket.name)} as vault manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
|
|
45
57
|
} else {
|
|
46
58
|
console.error("Error: Either shares or amount must be provided, but not both.");
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
OptionValues,
|
|
4
4
|
Command
|
|
5
5
|
} from "commander";
|
|
6
|
-
import { getCommandContext } from "../utils";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
7
|
|
|
8
|
-
export const managerUpdateMarginTradingEnabled= async (program: Command, cmdOpts: OptionValues) => {
|
|
8
|
+
export const managerUpdateMarginTradingEnabled = async (program: Command, cmdOpts: OptionValues) => {
|
|
9
9
|
|
|
10
10
|
let vaultAddress: PublicKey;
|
|
11
11
|
try {
|
|
@@ -22,6 +22,11 @@ export const managerUpdateMarginTradingEnabled= async (program: Command, cmdOpts
|
|
|
22
22
|
|
|
23
23
|
const enabled = cmdOpts.enabled ? (cmdOpts.enabled as string).toLowerCase() === "true" : false;
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
26
|
+
const tx = await driftVault.getUpdateMarginTradingEnabledIx(vaultAddress, enabled);
|
|
27
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
28
|
+
} else {
|
|
29
|
+
const tx = await driftVault.updateMarginTradingEnabled(vaultAddress, enabled);
|
|
30
|
+
console.log(`Updated margin trading vault manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
31
|
+
}
|
|
27
32
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
|
+
|
|
8
|
+
export const managerUpdatePoolId = 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
|
+
driftClient
|
|
21
|
+
} = await getCommandContext(program, true);
|
|
22
|
+
|
|
23
|
+
const poolId = cmdOpts.poolId ? Number(cmdOpts.poolId) : null;
|
|
24
|
+
if (poolId === null) {
|
|
25
|
+
console.error("Invalid pool id");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
30
|
+
const tx = await driftVault.getUpdatePoolIdIx(vaultAddress, poolId);
|
|
31
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
32
|
+
} else {
|
|
33
|
+
const tx = await driftVault.updateUserPoolId(vaultAddress, poolId);
|
|
34
|
+
console.log(`Updated pool id vault manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
OptionValues,
|
|
4
4
|
Command
|
|
5
5
|
} from "commander";
|
|
6
|
-
import { getCommandContext } from "../utils";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
7
|
import { BN, PERCENTAGE_PRECISION, TEN, convertToNumber, decodeName } from "@drift-labs/sdk";
|
|
8
8
|
|
|
9
9
|
export const managerUpdateVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
@@ -122,9 +122,14 @@ export const managerUpdateVault = async (program: Command, cmdOpts: OptionValues
|
|
|
122
122
|
let done = false;
|
|
123
123
|
while (!done) {
|
|
124
124
|
try {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
126
|
+
const tx = await driftVault.getManagerUpdateVaultIx(vaultAddress, newParams);
|
|
127
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
128
|
+
} else {
|
|
129
|
+
const tx = await driftVault.managerUpdateVault(vaultAddress, newParams);
|
|
130
|
+
console.log(`Updated vault params as vault manager: https://solana.fm/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
131
|
+
done = true;
|
|
132
|
+
}
|
|
128
133
|
break;
|
|
129
134
|
} catch (e) {
|
|
130
135
|
const err = e as Error;
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
OptionValues,
|
|
4
4
|
Command
|
|
5
5
|
} from "commander";
|
|
6
|
-
import { getCommandContext } from "../utils";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
7
|
|
|
8
8
|
export const managerUpdateVaultDelegate = async (program: Command, cmdOpts: OptionValues) => {
|
|
9
9
|
|
|
@@ -31,6 +31,12 @@ export const managerUpdateVaultDelegate = async (program: Command, cmdOpts: Opti
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
35
|
+
const tx = await driftVault.getUpdateDelegateIx(vaultAddress, delegate);
|
|
36
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
37
|
+
} else {
|
|
38
|
+
const tx = await driftVault.updateDelegate(vaultAddress, delegate);
|
|
39
|
+
console.log(`Updated vault delegate to ${delegate.toBase58()}: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
|
+
|
|
8
|
+
export const managerUpdateVaultManager = 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
|
+
let manager: PublicKey;
|
|
19
|
+
try {
|
|
20
|
+
manager = new PublicKey(cmdOpts.newManager as string);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.error("Invalid manager address");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
driftVault,
|
|
28
|
+
driftClient,
|
|
29
|
+
} = await getCommandContext(program, true);
|
|
30
|
+
|
|
31
|
+
const vault = await driftVault.getVault(vaultAddress);
|
|
32
|
+
|
|
33
|
+
console.log(`Updating vault manager:`);
|
|
34
|
+
console.log(` Current manager: ${vault.manager.toString()}`);
|
|
35
|
+
console.log(` New manager: ${manager.toString()}`);
|
|
36
|
+
|
|
37
|
+
const readline = require('readline').createInterface({
|
|
38
|
+
input: process.stdin,
|
|
39
|
+
output: process.stdout
|
|
40
|
+
});
|
|
41
|
+
console.log('');
|
|
42
|
+
const answer = await new Promise(resolve => {
|
|
43
|
+
readline.question('Is the above information correct? (yes/no) ', (answer: string) => {
|
|
44
|
+
readline.close();
|
|
45
|
+
resolve(answer);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
if ((answer as string).toLowerCase() !== 'yes') {
|
|
49
|
+
console.log('Vault manager update canceled.');
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
console.log('Updating vault manager...');
|
|
53
|
+
|
|
54
|
+
let done = false;
|
|
55
|
+
while (!done) {
|
|
56
|
+
try {
|
|
57
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
58
|
+
const tx = await driftVault.getManagerUpdateVaultManagerIx(vaultAddress, manager);
|
|
59
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
60
|
+
} else {
|
|
61
|
+
const tx = await driftVault.managerUpdateVaultManager(vaultAddress, manager);
|
|
62
|
+
console.log(`Updated vault manager: https://solana.fm/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
63
|
+
done = true;
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
const err = e as Error;
|
|
68
|
+
if (err.message.includes('TransactionExpiredTimeoutError')) {
|
|
69
|
+
console.log(err.message);
|
|
70
|
+
console.log('Transaction timeout. Retrying...');
|
|
71
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
72
|
+
} else {
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
OptionValues,
|
|
4
4
|
Command
|
|
5
5
|
} from "commander";
|
|
6
|
-
import { getCommandContext } from "../utils";
|
|
6
|
+
import { dumpTransactionMessage, getCommandContext } from "../utils";
|
|
7
7
|
|
|
8
8
|
export const managerWithdraw = async (program: Command, cmdOpts: OptionValues) => {
|
|
9
9
|
|
|
@@ -20,6 +20,11 @@ export const managerWithdraw = async (program: Command, cmdOpts: OptionValues) =
|
|
|
20
20
|
driftClient
|
|
21
21
|
} = await getCommandContext(program, true);
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
if (cmdOpts.dumpTransactionMessage) {
|
|
24
|
+
const tx = await driftVault.getManagerWithdrawIx(vaultAddress);
|
|
25
|
+
console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
|
|
26
|
+
} else {
|
|
27
|
+
const tx = await driftVault.managerWithdraw(vaultAddress);
|
|
28
|
+
console.log(`Withrew as vault manager: https://solscan.io/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet" : ""}`);
|
|
29
|
+
}
|
|
25
30
|
};
|
package/cli/utils.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { BASE_PRECISION, BN, DriftClient, DriftEnv, OraclePriceData, PRICE_PRECISION, QUOTE_PRECISION, SpotMarketAccount, TEN, User, Wallet, WhileValidTxSender, convertToNumber, getSignedTokenAmount, getTokenAmount, loadKeypair } from "@drift-labs/sdk";
|
|
2
2
|
import { VAULT_PROGRAM_ID, Vault, VaultClient, VaultDepositor, decodeName } from "../src";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
-
import { Connection, Keypair } from "@solana/web3.js";
|
|
4
|
+
import { Connection, Keypair, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
|
|
5
5
|
import { AnchorProvider, Wallet as AnchorWallet } from "@coral-xyz/anchor";
|
|
6
6
|
import * as anchor from '@coral-xyz/anchor';
|
|
7
7
|
import { IDL } from "../src/types/drift_vaults";
|
|
8
8
|
import { getLedgerWallet } from "./ledgerWallet";
|
|
9
9
|
import fs from 'fs';
|
|
10
|
+
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
export async function printVault(slot: number, driftClient: DriftClient, vault: Vault, vaultEquity: BN, spotMarket: SpotMarketAccount, spotOracle: OraclePriceData) {
|
|
@@ -202,3 +203,15 @@ export async function getCommandContext(program: Command, needToSign: boolean):
|
|
|
202
203
|
wallet,
|
|
203
204
|
};
|
|
204
205
|
}
|
|
206
|
+
|
|
207
|
+
/// a valid blockhash to allow tx simulation
|
|
208
|
+
export const BLOCKHASH_PLACEHOLDER = 'CHNfFRxxeCTyy1RRnKGsV2dkrJfKwVEa8zE7cZgK4TSe';
|
|
209
|
+
|
|
210
|
+
export function dumpTransactionMessage(payer: PublicKey, ixs: Array<TransactionInstruction>): string {
|
|
211
|
+
const tx = new Transaction();
|
|
212
|
+
tx.add(...ixs);
|
|
213
|
+
tx.feePayer = payer;
|
|
214
|
+
tx.recentBlockhash = BLOCKHASH_PLACEHOLDER;
|
|
215
|
+
|
|
216
|
+
return bs58.encode(tx.serialize({ requireAllSignatures: false }));
|
|
217
|
+
}
|
|
@@ -307,6 +307,27 @@ export type DriftVaults = {
|
|
|
307
307
|
}
|
|
308
308
|
];
|
|
309
309
|
},
|
|
310
|
+
{
|
|
311
|
+
name: 'updateVaultManager';
|
|
312
|
+
accounts: [
|
|
313
|
+
{
|
|
314
|
+
name: 'vault';
|
|
315
|
+
isMut: true;
|
|
316
|
+
isSigner: false;
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: 'manager';
|
|
320
|
+
isMut: false;
|
|
321
|
+
isSigner: true;
|
|
322
|
+
}
|
|
323
|
+
];
|
|
324
|
+
args: [
|
|
325
|
+
{
|
|
326
|
+
name: 'manager';
|
|
327
|
+
type: 'publicKey';
|
|
328
|
+
}
|
|
329
|
+
];
|
|
330
|
+
},
|
|
310
331
|
{
|
|
311
332
|
name: 'updateCumulativeFuelAmount';
|
|
312
333
|
accounts: [
|
|
@@ -310,6 +310,27 @@ exports.IDL = {
|
|
|
310
310
|
},
|
|
311
311
|
],
|
|
312
312
|
},
|
|
313
|
+
{
|
|
314
|
+
name: 'updateVaultManager',
|
|
315
|
+
accounts: [
|
|
316
|
+
{
|
|
317
|
+
name: 'vault',
|
|
318
|
+
isMut: true,
|
|
319
|
+
isSigner: false,
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: 'manager',
|
|
323
|
+
isMut: false,
|
|
324
|
+
isSigner: true,
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
args: [
|
|
328
|
+
{
|
|
329
|
+
name: 'manager',
|
|
330
|
+
type: 'publicKey',
|
|
331
|
+
},
|
|
332
|
+
],
|
|
333
|
+
},
|
|
313
334
|
{
|
|
314
335
|
name: 'updateCumulativeFuelAmount',
|
|
315
336
|
accounts: [
|