@kamino-finance/klend-sdk 5.0.6 → 5.1.0

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_KAMINO_MANAGER.md +154 -17
  2. package/dist/classes/action.d.ts +5 -1
  3. package/dist/classes/action.d.ts.map +1 -1
  4. package/dist/classes/action.js +39 -26
  5. package/dist/classes/action.js.map +1 -1
  6. package/dist/classes/manager.d.ts +22 -0
  7. package/dist/classes/manager.d.ts.map +1 -1
  8. package/dist/classes/manager.js +29 -0
  9. package/dist/classes/manager.js.map +1 -1
  10. package/dist/classes/vault.d.ts +30 -0
  11. package/dist/classes/vault.d.ts.map +1 -1
  12. package/dist/classes/vault.js +177 -0
  13. package/dist/classes/vault.js.map +1 -1
  14. package/dist/client_kamino_manager.d.ts.map +1 -1
  15. package/dist/client_kamino_manager.js +113 -1
  16. package/dist/client_kamino_manager.js.map +1 -1
  17. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts +10 -10
  18. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts.map +1 -1
  19. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js +52 -51
  20. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js.map +1 -1
  21. package/dist/leverage/operations.d.ts.map +1 -1
  22. package/dist/leverage/operations.js +3 -9
  23. package/dist/leverage/operations.js.map +1 -1
  24. package/dist/referrals/instructions.d.ts +2 -1
  25. package/dist/referrals/instructions.d.ts.map +1 -1
  26. package/dist/referrals/instructions.js +13 -8
  27. package/dist/referrals/instructions.js.map +1 -1
  28. package/dist/utils/ata.d.ts +1 -2
  29. package/dist/utils/ata.d.ts.map +1 -1
  30. package/dist/utils/ata.js +8 -15
  31. package/dist/utils/ata.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/classes/action.ts +41 -33
  34. package/src/classes/manager.ts +34 -0
  35. package/src/classes/vault.ts +250 -0
  36. package/src/client.ts +4 -20
  37. package/src/client_kamino_manager.ts +174 -1
  38. package/src/idl_codegen_kamino_vault/types/VaultConfigField.ts +116 -117
  39. package/src/leverage/operations.ts +3 -9
  40. package/src/referrals/instructions.ts +16 -9
  41. package/src/utils/ata.ts +8 -14
@@ -27,16 +27,27 @@ import {
27
27
  // CloseVaultAccounts,
28
28
  DepositAccounts,
29
29
  DepositArgs,
30
+ giveUpPendingFees,
31
+ GiveUpPendingFeesAccounts,
32
+ GiveUpPendingFeesArgs,
30
33
  initVault,
31
34
  InitVaultAccounts,
32
35
  invest,
33
36
  InvestAccounts,
37
+ updateAdmin,
38
+ UpdateAdminAccounts,
34
39
  updateReserveAllocation,
35
40
  UpdateReserveAllocationAccounts,
36
41
  UpdateReserveAllocationArgs,
42
+ updateVaultConfig,
43
+ UpdateVaultConfigAccounts,
44
+ UpdateVaultConfigArgs,
37
45
  WithdrawAccounts,
38
46
  WithdrawArgs,
47
+ withdrawPendingFees,
48
+ WithdrawPendingFeesAccounts,
39
49
  } from '../idl_codegen_kamino_vault/instructions';
50
+ import { VaultConfigFieldKind } from '../idl_codegen_kamino_vault/types';
40
51
  import { VaultState } from '../idl_codegen_kamino_vault/accounts';
41
52
  import Decimal from 'decimal.js';
42
53
  import { numberToLamportsDecimal, parseTokenSymbol } from './utils';
@@ -180,6 +191,188 @@ export class KaminoVaultClient {
180
191
  );
181
192
  }
182
193
 
194
+ /**
195
+ * This method updates the vault config
196
+ * @param vault - vault to be updated
197
+ * @param mode - the field to be updated
198
+ * @param value - the new value for the field to be updated (number or pubkey)
199
+ * @returns - a list of instructions
200
+ */
201
+ async updateVaultConfigIx(
202
+ vault: KaminoVault,
203
+ mode: VaultConfigFieldKind,
204
+ value: string
205
+ ): Promise<TransactionInstruction> {
206
+ const vaultState: VaultState = await vault.getState(this.getConnection());
207
+
208
+ const updateVaultConfigAccs: UpdateVaultConfigAccounts = {
209
+ adminAuthority: vaultState.adminAuthority,
210
+ vaultState: vault.address,
211
+ klendProgram: this._kaminoLendProgramId,
212
+ };
213
+
214
+ const updateVaultConfigArgs: UpdateVaultConfigArgs = {
215
+ entry: mode,
216
+ data: Buffer.from([0]),
217
+ };
218
+
219
+ if (isNaN(+value)) {
220
+ const data = new PublicKey(value);
221
+ updateVaultConfigArgs.data = data.toBuffer();
222
+ } else {
223
+ const buffer = Buffer.alloc(8);
224
+ buffer.writeBigUInt64LE(BigInt(value.toString()));
225
+ updateVaultConfigArgs.data = buffer;
226
+ }
227
+
228
+ const vaultReserves = this.getVaultReserves(vaultState);
229
+ const vaultReservesState = await this.loadVaultReserves(vaultState);
230
+
231
+ let vaultReservesAccountMetas: AccountMeta[] = [];
232
+ let vaultReservesLendingMarkets: AccountMeta[] = [];
233
+ vaultReserves.forEach((reserve) => {
234
+ const reserveState = vaultReservesState.get(reserve);
235
+ if (reserveState === undefined) {
236
+ throw new Error(`Reserve ${reserve.toBase58()} not found`);
237
+ }
238
+ vaultReservesAccountMetas = vaultReservesAccountMetas.concat([
239
+ { pubkey: reserve, isSigner: false, isWritable: true },
240
+ ]);
241
+ vaultReservesLendingMarkets = vaultReservesLendingMarkets.concat([
242
+ { pubkey: reserveState.state.lendingMarket, isSigner: false, isWritable: false },
243
+ ]);
244
+ });
245
+
246
+ const updateVaultConfigIx = updateVaultConfig(
247
+ updateVaultConfigArgs,
248
+ updateVaultConfigAccs,
249
+ this._kaminoVaultProgramId
250
+ );
251
+
252
+ updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesAccountMetas);
253
+ updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesLendingMarkets);
254
+
255
+ return updateVaultConfigIx;
256
+ }
257
+
258
+ /**
259
+ * This function creates the instruction for the `pendingAdmin` of the vault to accept to become the owner of the vault (step 2/2 of the ownership transfer)
260
+ * @param vault - vault to change the ownership for
261
+ * @returns - an instruction to be used to be executed
262
+ */
263
+ async acceptVaultOwnershipIx(vault: KaminoVault): Promise<TransactionInstruction> {
264
+ const vaultState: VaultState = await vault.getState(this.getConnection());
265
+
266
+ const acceptOwneshipAccounts: UpdateAdminAccounts = {
267
+ pendingAdmin: vaultState.pendingAdmin,
268
+ vaultState: vault.address,
269
+ };
270
+
271
+ return updateAdmin(acceptOwneshipAccounts, this._kaminoVaultProgramId);
272
+ }
273
+
274
+ /**
275
+ * This function creates the instruction for the admin to give up a part of the pending fees (which will be accounted as part of the vault)
276
+ * @param vault - vault to give up pending fees for
277
+ * @param maxAmountToGiveUp - the maximum amount of fees to give up, in tokens
278
+ * @returns - an instruction to be used to be executed
279
+ */
280
+ async giveUpPendingFeesIx(vault: KaminoVault, maxAmountToGiveUp: Decimal): Promise<TransactionInstruction> {
281
+ const vaultState: VaultState = await vault.getState(this.getConnection());
282
+
283
+ const giveUpPendingFeesAccounts: GiveUpPendingFeesAccounts = {
284
+ adminAuthority: vaultState.adminAuthority,
285
+ vaultState: vault.address,
286
+ klendProgram: this._kaminoLendProgramId,
287
+ };
288
+
289
+ const maxAmountToGiveUpLamports = numberToLamportsDecimal(
290
+ maxAmountToGiveUp,
291
+ vaultState.tokenMintDecimals.toNumber()
292
+ );
293
+ const giveUpPendingFeesArgs: GiveUpPendingFeesArgs = {
294
+ maxAmountToGiveUp: new BN(maxAmountToGiveUpLamports.toString()),
295
+ };
296
+
297
+ return giveUpPendingFees(giveUpPendingFeesArgs, giveUpPendingFeesAccounts, this._kaminoVaultProgramId);
298
+ }
299
+
300
+ /**
301
+ * This method withdraws all the pending fees from the vault to the owner's token ATA
302
+ * @param vault - vault for which the admin withdraws the pending fees
303
+ * @param slot - current slot, used to estimate the interest earned in the different reserves with allocation from the vault
304
+ * @returns - list of instructions to withdraw all pending fees
305
+ */
306
+ async withdrawPendingFeesIxs(vault: KaminoVault, slot: number): Promise<TransactionInstruction[]> {
307
+ const vaultState: VaultState = await vault.getState(this.getConnection());
308
+ const { atas, createAtaIxs } = await getAtasWithCreateIxnsIfMissing(this._connection, vaultState.adminAuthority, [
309
+ {
310
+ mint: vaultState.tokenMint,
311
+ tokenProgram: TOKEN_PROGRAM_ID,
312
+ },
313
+ ]);
314
+ const adminTokenAta = atas[0];
315
+
316
+ const tokensToWithdraw = new Fraction(vaultState.pendingFeesSf).toDecimal();
317
+ let tokenLeftToWithdraw = tokensToWithdraw;
318
+ tokenLeftToWithdraw = tokenLeftToWithdraw.sub(new Decimal(vaultState.tokenAvailable.toString()));
319
+ const reservesToWithdraw: PublicKey[] = [];
320
+
321
+ if (tokenLeftToWithdraw.lte(0)) {
322
+ // Availabe enough to withdraw all - using first reserve as it does not matter
323
+ reservesToWithdraw.push(vaultState.vaultAllocationStrategy[0].reserve);
324
+ } else {
325
+ // Get decreasing order sorted available liquidity to withdraw from each reserve allocated to
326
+ const reserveAllocationAvailableLiquidityToWithdraw = await this.getReserveAllocationAvailableLiquidityToWithdraw(
327
+ vault,
328
+ slot
329
+ );
330
+ // sort
331
+ const reserveAllocationAvailableLiquidityToWithdrawSorted = new PubkeyHashMap(
332
+ [...reserveAllocationAvailableLiquidityToWithdraw.entries()].sort((a, b) => b[1].sub(a[1]).toNumber())
333
+ );
334
+
335
+ reserveAllocationAvailableLiquidityToWithdrawSorted.forEach((availableLiquidityToWithdraw, key) => {
336
+ if (tokenLeftToWithdraw.gt(0)) {
337
+ reservesToWithdraw.push(key);
338
+ tokenLeftToWithdraw = tokenLeftToWithdraw.sub(availableLiquidityToWithdraw);
339
+ }
340
+ });
341
+ }
342
+
343
+ const reserveStates = await Reserve.fetchMultiple(this._connection, reservesToWithdraw, this._kaminoLendProgramId);
344
+ const withdrawIxns: TransactionInstruction[] = await Promise.all(
345
+ reservesToWithdraw.map(async (reserve, index) => {
346
+ if (reserveStates[index] === null) {
347
+ throw new Error(`Reserve ${reserve.toBase58()} not found`);
348
+ }
349
+
350
+ const reserveState = reserveStates[index]!;
351
+
352
+ const market = reserveState.lendingMarket;
353
+ const marketState = await LendingMarket.fetch(this._connection, market, this._kaminoLendProgramId);
354
+ if (marketState === null) {
355
+ throw new Error(`Market ${market.toBase58()} not found`);
356
+ }
357
+
358
+ const marketWithAddress = {
359
+ address: market,
360
+ state: marketState,
361
+ };
362
+
363
+ return this.withdrawPendingFeesIxn(
364
+ vault,
365
+ vaultState,
366
+ marketWithAddress,
367
+ { address: reserve, state: reserveState },
368
+ adminTokenAta
369
+ );
370
+ })
371
+ );
372
+
373
+ return [...createAtaIxs, ...withdrawIxns];
374
+ }
375
+
183
376
  // async closeVaultIx(vault: KaminoVault): Promise<TransactionInstruction> {
184
377
  // const vaultState: VaultState = await vault.getState(this.getConnection());
185
378
 
@@ -511,6 +704,63 @@ export class KaminoVaultClient {
511
704
  return withdrawIxn;
512
705
  }
513
706
 
707
+ private async withdrawPendingFeesIxn(
708
+ vault: KaminoVault,
709
+ vaultState: VaultState,
710
+ marketWithAddress: MarketWithAddress,
711
+ reserve: ReserveWithAddress,
712
+ adminTokenAta: PublicKey
713
+ ): Promise<TransactionInstruction> {
714
+ const lendingMarketAuth = lendingMarketAuthPda(marketWithAddress.address, this._kaminoLendProgramId)[0];
715
+
716
+ const withdrawPendingFeesAccounts: WithdrawPendingFeesAccounts = {
717
+ adminAuthority: vaultState.adminAuthority,
718
+ vaultState: vault.address,
719
+ reserve: reserve.address,
720
+ tokenVault: vaultState.tokenVault,
721
+ ctokenVault: getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId),
722
+ baseVaultAuthority: vaultState.baseVaultAuthority,
723
+ tokenAta: adminTokenAta,
724
+ tokenMint: vaultState.tokenMint,
725
+ tokenProgram: TOKEN_PROGRAM_ID,
726
+ /** CPI accounts */
727
+ lendingMarket: marketWithAddress.address,
728
+ lendingMarketAuthority: lendingMarketAuth,
729
+ reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
730
+ reserveCollateralMint: reserve.state.collateral.mintPubkey,
731
+ klendProgram: this._kaminoLendProgramId,
732
+ instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
733
+ reserveCollateralTokenProgram: TOKEN_PROGRAM_ID,
734
+ sharesTokenProgram: TOKEN_PROGRAM_ID,
735
+ };
736
+
737
+ const withdrawPendingFeesIxn = withdrawPendingFees(withdrawPendingFeesAccounts, this._kaminoVaultProgramId);
738
+
739
+ const vaultReserves = this.getVaultReserves(vaultState);
740
+ const vaultReservesState = await this.loadVaultReserves(vaultState);
741
+
742
+ let vaultReservesAccountMetas: AccountMeta[] = [];
743
+ let vaultReservesLendingMarkets: AccountMeta[] = [];
744
+
745
+ vaultReserves.forEach((reserve) => {
746
+ const reserveState = vaultReservesState.get(reserve);
747
+ if (reserveState === undefined) {
748
+ throw new Error(`Reserve ${reserve.toBase58()} not found`);
749
+ }
750
+
751
+ vaultReservesAccountMetas = vaultReservesAccountMetas.concat([
752
+ { pubkey: reserve, isSigner: false, isWritable: true },
753
+ ]);
754
+ vaultReservesLendingMarkets = vaultReservesLendingMarkets.concat([
755
+ { pubkey: reserveState.state.lendingMarket, isSigner: false, isWritable: false },
756
+ ]);
757
+ });
758
+ withdrawPendingFeesIxn.keys = withdrawPendingFeesIxn.keys.concat(vaultReservesAccountMetas);
759
+ withdrawPendingFeesIxn.keys = withdrawPendingFeesIxn.keys.concat(vaultReservesLendingMarkets);
760
+
761
+ return withdrawPendingFeesIxn;
762
+ }
763
+
514
764
  /**
515
765
  * This method returns the user shares balance for a given vault
516
766
  * @param user - user to calculate the shares balance for
package/src/client.ts CHANGED
@@ -279,11 +279,7 @@ async function deposit(connection: Connection, wallet: Keypair, token: string, d
279
279
  );
280
280
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
281
281
 
282
- const tx = await buildVersionedTransaction(connection, wallet.publicKey, [
283
- ...kaminoAction.setupIxs,
284
- ...kaminoAction.lendingIxs,
285
- ...kaminoAction.cleanupIxs,
286
- ]);
282
+ const tx = await buildVersionedTransaction(connection, wallet.publicKey, KaminoAction.actionToIxs(kaminoAction));
287
283
 
288
284
  console.log('Deposit SetupIxns:', kaminoAction.setupIxsLabels);
289
285
  console.log('Deposit LendingIxns:', kaminoAction.lendingIxsLabels);
@@ -303,11 +299,7 @@ async function withdraw(connection: Connection, wallet: Keypair, token: string,
303
299
  );
304
300
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
305
301
 
306
- const tx = await buildVersionedTransaction(connection, wallet.publicKey, [
307
- ...kaminoAction.setupIxs,
308
- ...kaminoAction.lendingIxs,
309
- ...kaminoAction.cleanupIxs,
310
- ]);
302
+ const tx = await buildVersionedTransaction(connection, wallet.publicKey, KaminoAction.actionToIxs(kaminoAction));
311
303
 
312
304
  console.log('Withdraw SetupIxns:', kaminoAction.setupIxsLabels);
313
305
  console.log('Withdraw LendingIxns:', kaminoAction.lendingIxsLabels);
@@ -327,11 +319,7 @@ async function borrow(connection: Connection, wallet: Keypair, token: string, bo
327
319
  );
328
320
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
329
321
 
330
- const tx = await buildVersionedTransaction(connection, wallet.publicKey, [
331
- ...kaminoAction.setupIxs,
332
- ...kaminoAction.lendingIxs,
333
- ...kaminoAction.cleanupIxs,
334
- ]);
322
+ const tx = await buildVersionedTransaction(connection, wallet.publicKey, KaminoAction.actionToIxs(kaminoAction));
335
323
 
336
324
  console.log('Borrow SetupIxns:', kaminoAction.setupIxsLabels);
337
325
  console.log('Borrow LendingIxns:', kaminoAction.lendingIxsLabels);
@@ -352,11 +340,7 @@ async function repay(connection: Connection, wallet: Keypair, token: string, bor
352
340
  );
353
341
  console.log('User obligation', kaminoAction.obligation!.obligationAddress.toString());
354
342
 
355
- const tx = await buildVersionedTransaction(connection, wallet.publicKey, [
356
- ...kaminoAction.setupIxs,
357
- ...kaminoAction.lendingIxs,
358
- ...kaminoAction.cleanupIxs,
359
- ]);
343
+ const tx = await buildVersionedTransaction(connection, wallet.publicKey, KaminoAction.actionToIxs(kaminoAction));
360
344
 
361
345
  console.log('Repay SetupIxns:', kaminoAction.setupIxsLabels);
362
346
  console.log('Repay LendingIxns:', kaminoAction.lendingIxsLabels);
@@ -47,6 +47,11 @@ import { PythConfiguration, SwitchboardConfiguration } from './idl_codegen_kamin
47
47
  import * as fs from 'fs';
48
48
  import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
49
49
  import { MarketWithAddress } from './utils/managerTypes';
50
+ import {
51
+ ManagementFeeBps,
52
+ PendingVaultAdmin,
53
+ PerformanceFeeBps,
54
+ } from './idl_codegen_kamino_vault/types/VaultConfigField';
50
55
 
51
56
  dotenv.config({
52
57
  path: `.env${process.env.ENV ? '.' + process.env.ENV : ''}`,
@@ -247,6 +252,175 @@ async function main() {
247
252
  mode === 'execute' && console.log('Vault created:', vaultKp.publicKey.toBase58());
248
253
  });
249
254
 
255
+ commands
256
+ .command('update-vault-pending-admin')
257
+ .requiredOption('--vault <string>', 'Vault address')
258
+ .requiredOption('--new-admin <string>', 'Pubkey of the new admin')
259
+ .requiredOption(
260
+ `--mode <string>`,
261
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
262
+ )
263
+ .option(`--staging`, 'If true, will use the staging programs')
264
+ .option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
265
+ .action(async ({ vault, newAdmin, mode, staging, multisig }) => {
266
+ const env = initializeClient(mode === 'multisig', staging);
267
+ const vaultAddress = new PublicKey(vault);
268
+
269
+ if (mode === 'multisig' && !multisig) {
270
+ throw new Error('If using multisig mode, multisig is required');
271
+ }
272
+
273
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
274
+
275
+ const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
276
+ const instruction = await kaminoManager.updateVaultConfigIx(kaminoVault, new PendingVaultAdmin(), newAdmin);
277
+
278
+ const updateVaultPendingAdminSig = await processTxn(env.client, env.payer, [instruction], mode, 2500, []);
279
+
280
+ mode === 'execute' && console.log('Pending admin updated:', updateVaultPendingAdminSig);
281
+ });
282
+
283
+ commands
284
+ .command('update-vault-mgmt-fee')
285
+ .requiredOption('--vault <string>', 'Vault address')
286
+ .requiredOption('--fee-bps <string>', 'Pubkey of the new admin')
287
+ .requiredOption(
288
+ `--mode <string>`,
289
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
290
+ )
291
+ .option(`--staging`, 'If true, will use the staging programs')
292
+ .option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
293
+ .action(async ({ vault, feeBps, mode, staging, multisig }) => {
294
+ const env = initializeClient(mode === 'multisig', staging);
295
+ const vaultAddress = new PublicKey(vault);
296
+
297
+ if (mode === 'multisig' && !multisig) {
298
+ throw new Error('If using multisig mode, multisig is required');
299
+ }
300
+
301
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
302
+
303
+ const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
304
+ const instruction = await kaminoManager.updateVaultConfigIx(kaminoVault, new ManagementFeeBps(), feeBps);
305
+
306
+ const updateVaultConfigSig = await processTxn(env.client, env.payer, [instruction], mode, 2500, []);
307
+
308
+ mode === 'execute' && console.log('Management fee updated:', updateVaultConfigSig);
309
+ });
310
+
311
+ commands
312
+ .command('update-vault-perf-fee')
313
+ .requiredOption('--vault <string>', 'Vault address')
314
+ .requiredOption('--fee-bps <string>', 'Pubkey of the new admin')
315
+ .requiredOption(
316
+ `--mode <string>`,
317
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
318
+ )
319
+ .option(`--staging`, 'If true, will use the staging programs')
320
+ .option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
321
+ .action(async ({ vault, feeBps, mode, staging, multisig }) => {
322
+ const env = initializeClient(mode === 'multisig', staging);
323
+ const vaultAddress = new PublicKey(vault);
324
+
325
+ if (mode === 'multisig' && !multisig) {
326
+ throw new Error('If using multisig mode, multisig is required');
327
+ }
328
+
329
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
330
+
331
+ const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
332
+ const instruction = await kaminoManager.updateVaultConfigIx(kaminoVault, new PerformanceFeeBps(), feeBps);
333
+
334
+ const updateVaultPerfFeeSig = await processTxn(env.client, env.payer, [instruction], mode, 2500, []);
335
+
336
+ mode === 'execute' && console.log('Performance fee updated:', updateVaultPerfFeeSig);
337
+ });
338
+
339
+ commands
340
+ .command('accept-vault-ownership')
341
+ .requiredOption('--vault <string>', 'Vault address')
342
+ .requiredOption(
343
+ `--mode <string>`,
344
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
345
+ )
346
+ .option(`--staging`, 'If true, will use the staging programs')
347
+ .option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
348
+ .action(async ({ vault, mode, staging, multisig }) => {
349
+ const env = initializeClient(mode === 'multisig', staging);
350
+ const vaultAddress = new PublicKey(vault);
351
+
352
+ if (mode === 'multisig' && !multisig) {
353
+ throw new Error('If using multisig mode, multisig is required');
354
+ }
355
+
356
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
357
+
358
+ const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
359
+ const instruction = await kaminoManager.acceptVaultOwnershipIx(kaminoVault);
360
+
361
+ const acceptVaultOwnershipSig = await processTxn(env.client, env.payer, [instruction], mode, 2500, []);
362
+
363
+ mode === 'execute' && console.log('Vault ownership accepted:', acceptVaultOwnershipSig);
364
+ });
365
+
366
+ commands
367
+ .command('give-up-pending-fees')
368
+ .requiredOption('--vault <string>', 'Vault address')
369
+ .requiredOption('--max-amount-to-give-up <string>', 'Max amount to give up')
370
+ .requiredOption(
371
+ `--mode <string>`,
372
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
373
+ )
374
+ .option(`--staging`, 'If true, will use the staging programs')
375
+ .option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
376
+ .action(async ({ vault, maxAmountToGiveUp, mode, staging, multisig }) => {
377
+ const env = initializeClient(mode === 'multisig', staging);
378
+ const vaultAddress = new PublicKey(vault);
379
+
380
+ if (mode === 'multisig' && !multisig) {
381
+ throw new Error('If using multisig mode, multisig is required');
382
+ }
383
+
384
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
385
+
386
+ const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
387
+ const instruction = await kaminoManager.giveUpPendingFeesIx(kaminoVault, new Decimal(maxAmountToGiveUp));
388
+
389
+ const giveUpPendingFeesSig = await processTxn(env.client, env.payer, [instruction], mode, 2500, []);
390
+
391
+ mode === 'execute' && console.log('Give up pending fees tx:', giveUpPendingFeesSig);
392
+ });
393
+
394
+ commands
395
+ .command('withdraw-pending-fees')
396
+ .requiredOption('--vault <string>', 'Vault address')
397
+ .requiredOption(
398
+ `--mode <string>`,
399
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
400
+ )
401
+ .option(`--staging`, 'If true, will use the staging programs')
402
+ .option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
403
+ .action(async ({ vault, mode, staging, multisig }) => {
404
+ const env = initializeClient(mode === 'multisig', staging);
405
+ const vaultAddress = new PublicKey(vault);
406
+
407
+ if (mode === 'multisig' && !multisig) {
408
+ throw new Error('If using multisig mode, multisig is required');
409
+ }
410
+
411
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
412
+
413
+ const kaminoVault = new KaminoVault(vaultAddress, undefined, env.kVaultProgramId);
414
+ const instructions = await kaminoManager.withdrawPendingFeesIxs(
415
+ kaminoVault,
416
+ await env.connection.getSlot('confirmed')
417
+ );
418
+
419
+ const withdrawPendingFeesSig = await processTxn(env.client, env.payer, instructions, mode, 2500, []);
420
+
421
+ mode === 'execute' && console.log('Pending fees withdrawn:', withdrawPendingFeesSig);
422
+ });
423
+
250
424
  commands
251
425
  .command('update-vault-reserve-allocation')
252
426
  .requiredOption('--vault <string>', 'Vault address')
@@ -301,7 +475,6 @@ async function main() {
301
475
  // .requiredOption('--vault <string>', 'Vault address')
302
476
  // .option(`--staging`, 'If true, will use the staging programs')
303
477
  // .action(async ({vault, staging}) => {
304
- // console.log("silviuuuu vault", vault);
305
478
  // const env = initializeClient(false, staging);
306
479
  // const vaultAddress = new PublicKey(vault);
307
480