@kamino-finance/klend-sdk 5.2.11 → 5.2.13

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 (120) hide show
  1. package/dist/classes/manager.d.ts +38 -9
  2. package/dist/classes/manager.d.ts.map +1 -1
  3. package/dist/classes/manager.js +44 -10
  4. package/dist/classes/manager.js.map +1 -1
  5. package/dist/classes/types.d.ts +23 -0
  6. package/dist/classes/types.d.ts.map +1 -0
  7. package/dist/classes/types.js +3 -0
  8. package/dist/classes/types.js.map +1 -0
  9. package/dist/classes/utils.js +2 -2
  10. package/dist/classes/utils.js.map +1 -1
  11. package/dist/classes/vault.d.ts +47 -11
  12. package/dist/classes/vault.d.ts.map +1 -1
  13. package/dist/classes/vault.js +367 -49
  14. package/dist/classes/vault.js.map +1 -1
  15. package/dist/client_kamino_manager.d.ts.map +1 -1
  16. package/dist/client_kamino_manager.js +62 -12
  17. package/dist/client_kamino_manager.js.map +1 -1
  18. package/dist/idl_codegen_kamino_vault/accounts/Reserve.js +1 -1
  19. package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts +18 -9
  20. package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts.map +1 -1
  21. package/dist/idl_codegen_kamino_vault/accounts/VaultState.js +62 -42
  22. package/dist/idl_codegen_kamino_vault/accounts/VaultState.js.map +1 -1
  23. package/dist/idl_codegen_kamino_vault/errors/custom.d.ts +112 -80
  24. package/dist/idl_codegen_kamino_vault/errors/custom.d.ts.map +1 -1
  25. package/dist/idl_codegen_kamino_vault/errors/custom.js +214 -158
  26. package/dist/idl_codegen_kamino_vault/errors/custom.js.map +1 -1
  27. package/dist/idl_codegen_kamino_vault/instructions/deposit.d.ts +1 -1
  28. package/dist/idl_codegen_kamino_vault/instructions/deposit.d.ts.map +1 -1
  29. package/dist/idl_codegen_kamino_vault/instructions/deposit.js +1 -1
  30. package/dist/idl_codegen_kamino_vault/instructions/deposit.js.map +1 -1
  31. package/dist/idl_codegen_kamino_vault/instructions/index.d.ts +6 -0
  32. package/dist/idl_codegen_kamino_vault/instructions/index.d.ts.map +1 -1
  33. package/dist/idl_codegen_kamino_vault/instructions/index.js +7 -1
  34. package/dist/idl_codegen_kamino_vault/instructions/index.js.map +1 -1
  35. package/dist/idl_codegen_kamino_vault/instructions/initVault.d.ts +2 -2
  36. package/dist/idl_codegen_kamino_vault/instructions/initVault.d.ts.map +1 -1
  37. package/dist/idl_codegen_kamino_vault/instructions/initVault.js +2 -2
  38. package/dist/idl_codegen_kamino_vault/instructions/initVault.js.map +1 -1
  39. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.d.ts +19 -0
  40. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.d.ts.map +1 -0
  41. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.js +58 -0
  42. package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.js.map +1 -0
  43. package/dist/idl_codegen_kamino_vault/instructions/invest.d.ts +3 -4
  44. package/dist/idl_codegen_kamino_vault/instructions/invest.d.ts.map +1 -1
  45. package/dist/idl_codegen_kamino_vault/instructions/invest.js +2 -3
  46. package/dist/idl_codegen_kamino_vault/instructions/invest.js.map +1 -1
  47. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.d.ts +16 -0
  48. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.d.ts.map +1 -0
  49. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.js +55 -0
  50. package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.js.map +1 -0
  51. package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.js +1 -1
  52. package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.js.map +1 -1
  53. package/dist/idl_codegen_kamino_vault/instructions/withdraw.d.ts +24 -20
  54. package/dist/idl_codegen_kamino_vault/instructions/withdraw.d.ts.map +1 -1
  55. package/dist/idl_codegen_kamino_vault/instructions/withdraw.js +81 -20
  56. package/dist/idl_codegen_kamino_vault/instructions/withdraw.js.map +1 -1
  57. package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.d.ts +21 -0
  58. package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.d.ts.map +1 -0
  59. package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.js +55 -0
  60. package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.js.map +1 -0
  61. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.d.ts +2 -3
  62. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.d.ts.map +1 -1
  63. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.js +3 -4
  64. package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.js.map +1 -1
  65. package/dist/idl_codegen_kamino_vault/types/ReserveConfig.d.ts +78 -20
  66. package/dist/idl_codegen_kamino_vault/types/ReserveConfig.d.ts.map +1 -1
  67. package/dist/idl_codegen_kamino_vault/types/ReserveConfig.js +45 -14
  68. package/dist/idl_codegen_kamino_vault/types/ReserveConfig.js.map +1 -1
  69. package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.d.ts +16 -16
  70. package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.d.ts.map +1 -1
  71. package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.js +16 -16
  72. package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.js.map +1 -1
  73. package/dist/idl_codegen_kamino_vault/types/VaultAllocation.d.ts +5 -5
  74. package/dist/idl_codegen_kamino_vault/types/VaultAllocation.js +7 -7
  75. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts +46 -7
  76. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts.map +1 -1
  77. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js +84 -12
  78. package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js.map +1 -1
  79. package/dist/idl_codegen_kamino_vault/types/index.d.ts +2 -2
  80. package/dist/idl_codegen_kamino_vault/types/index.d.ts.map +1 -1
  81. package/dist/idl_codegen_kamino_vault/types/index.js.map +1 -1
  82. package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
  83. package/dist/lending_operations/repay_with_collateral_calcs.js +10 -1
  84. package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
  85. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  86. package/dist/lending_operations/repay_with_collateral_operations.js +7 -6
  87. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  88. package/dist/leverage/operations.d.ts.map +1 -1
  89. package/dist/leverage/operations.js +12 -8
  90. package/dist/leverage/operations.js.map +1 -1
  91. package/dist/leverage/types.d.ts +1 -0
  92. package/dist/leverage/types.d.ts.map +1 -1
  93. package/package.json +1 -1
  94. package/src/classes/manager.ts +60 -13
  95. package/src/classes/types.ts +28 -0
  96. package/src/classes/utils.ts +2 -2
  97. package/src/classes/vault.ts +527 -54
  98. package/src/client_kamino_manager.ts +119 -15
  99. package/src/idl_codegen_kamino_vault/accounts/Reserve.ts +1 -1
  100. package/src/idl_codegen_kamino_vault/accounts/VaultState.ts +215 -178
  101. package/src/idl_codegen_kamino_vault/errors/custom.ts +213 -157
  102. package/src/idl_codegen_kamino_vault/instructions/deposit.ts +2 -2
  103. package/src/idl_codegen_kamino_vault/instructions/index.ts +15 -0
  104. package/src/idl_codegen_kamino_vault/instructions/initVault.ts +4 -4
  105. package/src/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.ts +58 -0
  106. package/src/idl_codegen_kamino_vault/instructions/invest.ts +5 -7
  107. package/src/idl_codegen_kamino_vault/instructions/updateSharesMetadata.ts +52 -0
  108. package/src/idl_codegen_kamino_vault/instructions/updateVaultConfig.ts +1 -1
  109. package/src/idl_codegen_kamino_vault/instructions/withdraw.ts +106 -40
  110. package/src/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.ts +56 -0
  111. package/src/idl_codegen_kamino_vault/instructions/withdrawPendingFees.ts +5 -7
  112. package/src/idl_codegen_kamino_vault/types/ReserveConfig.ts +100 -28
  113. package/src/idl_codegen_kamino_vault/types/ReserveLiquidity.ts +25 -24
  114. package/src/idl_codegen_kamino_vault/types/VaultAllocation.ts +9 -9
  115. package/src/idl_codegen_kamino_vault/types/VaultConfigField.ts +103 -13
  116. package/src/idl_codegen_kamino_vault/types/index.ts +8 -2
  117. package/src/lending_operations/repay_with_collateral_calcs.ts +18 -1
  118. package/src/lending_operations/repay_with_collateral_operations.ts +9 -7
  119. package/src/leverage/operations.ts +69 -29
  120. package/src/leverage/types.ts +1 -0
@@ -10,6 +10,7 @@ const web3_js_1 = require("@solana/web3.js");
10
10
  const spl_token_1 = require("@solana/spl-token");
11
11
  const lib_1 = require("../lib");
12
12
  const instructions_1 = require("../idl_codegen_kamino_vault/instructions");
13
+ const types_1 = require("../idl_codegen_kamino_vault/types");
13
14
  const accounts_1 = require("../idl_codegen_kamino_vault/accounts");
14
15
  const decimal_js_1 = __importDefault(require("decimal.js"));
15
16
  const utils_1 = require("./utils");
@@ -21,6 +22,7 @@ const fraction_1 = require("./fraction");
21
22
  const utils_2 = require("../utils");
22
23
  const bs58_1 = __importDefault(require("bs58"));
23
24
  const rpc_1 = require("../utils/rpc");
25
+ const kliquidity_sdk_1 = require("@kamino-finance/kliquidity-sdk");
24
26
  exports.kaminoVaultId = new web3_js_1.PublicKey('kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr');
25
27
  exports.kaminoVaultStagingId = new web3_js_1.PublicKey('STkvh7ostar39Fwr4uZKASs1RNNuYMFMTsE77FiRsL2');
26
28
  const TOKEN_VAULT_SEED = 'token_vault';
@@ -51,7 +53,7 @@ class KaminoVaultClient {
51
53
  * This method will create a vault with a given config. The config can be changed later on, but it is recommended to set it up correctly from the start
52
54
  * @param vaultConfig - the config object used to create a vault
53
55
  * @returns vault - keypair, should be used to sign the transaction which creates the vault account
54
- * @returns ixns - an array of instructions to create the vault
56
+ * @returns vault: the keypair of the vault, used to sign the initialization transaction; initVaultIxs: a struct with ixs to initialize the vault and its lookup table + populateLUTIxs, a list to populate the lookup table which has to be executed in a separate transaction
55
57
  */
56
58
  async createVaultIxs(vaultConfig) {
57
59
  const vaultState = web3_js_1.Keypair.generate();
@@ -69,7 +71,7 @@ class KaminoVaultClient {
69
71
  const initVaultAccounts = {
70
72
  adminAuthority: vaultConfig.admin,
71
73
  vaultState: vaultState.publicKey,
72
- tokenMint: vaultConfig.tokenMint,
74
+ baseTokenMint: vaultConfig.tokenMint,
73
75
  tokenVault,
74
76
  baseVaultAuthority,
75
77
  sharesMint,
@@ -79,8 +81,38 @@ class KaminoVaultClient {
79
81
  sharesTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
80
82
  };
81
83
  const initVaultIx = (0, instructions_1.initVault)(initVaultAccounts, this._kaminoVaultProgramId);
82
- // TODO: Add logic to update vault based on vaultConfig
83
- return { vault: vaultState, ixns: [createVaultIx, initVaultIx] };
84
+ // create and set up the vault lookup table
85
+ const slot = await this._connection.getSlot();
86
+ const [createLUTIx, lut] = this.getInitLookupTableIx(vaultConfig.admin, slot);
87
+ const accountsToBeInserted = [
88
+ vaultConfig.admin,
89
+ vaultState.publicKey,
90
+ vaultConfig.tokenMint,
91
+ vaultConfig.tokenMintProgramId,
92
+ baseVaultAuthority,
93
+ sharesMint,
94
+ web3_js_1.SystemProgram.programId,
95
+ web3_js_1.SYSVAR_RENT_PUBKEY,
96
+ spl_token_1.TOKEN_PROGRAM_ID,
97
+ this._kaminoLendProgramId,
98
+ web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
99
+ ];
100
+ const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(vaultConfig.admin, lut, accountsToBeInserted, []);
101
+ const setLUTIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.publicKey, new types_1.VaultConfigField.LookupTable(), lut.toString());
102
+ const ixns = [createVaultIx, initVaultIx, createLUTIx, setLUTIx];
103
+ if (vaultConfig.getPerformanceFeeBps() > 0) {
104
+ const setPerformanceFeeIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.publicKey, new types_1.VaultConfigField.PerformanceFeeBps(), vaultConfig.getPerformanceFeeBps().toString());
105
+ ixns.push(setPerformanceFeeIx);
106
+ }
107
+ if (vaultConfig.getManagementFeeBps() > 0) {
108
+ const setManagementFeeIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.publicKey, new types_1.VaultConfigField.ManagementFeeBps(), vaultConfig.getManagementFeeBps().toString());
109
+ ixns.push(setManagementFeeIx);
110
+ }
111
+ if (vaultConfig.name && vaultConfig.name.length > 0) {
112
+ const setNameIx = this.updateUninitialisedVaultConfigIx(vaultConfig.admin, vaultState.publicKey, new types_1.VaultConfigField.Name(), vaultConfig.name);
113
+ ixns.push(setNameIx);
114
+ }
115
+ return { vault: vaultState, initVaultIxs: { initVaultIxs: ixns, populateLUTIxs: insertIntoLUTIxs } };
84
116
  }
85
117
  /**
86
118
  * This method updates the vault reserve allocation cofnig for an exiting vault reserve, or adds a new reserve to the vault if it does not exist.
@@ -107,16 +139,29 @@ class KaminoVaultClient {
107
139
  weight: new anchor_1.BN(reserveAllocationConfig.targetAllocationWeight),
108
140
  cap: new anchor_1.BN(reserveAllocationConfig.getAllocationCapLamports().floor().toString()),
109
141
  };
110
- return (0, instructions_1.updateReserveAllocation)(updateReserveAllocationArgs, updateReserveAllocationAccounts, this._kaminoVaultProgramId);
142
+ const updateReserveAllocationIx = (0, instructions_1.updateReserveAllocation)(updateReserveAllocationArgs, updateReserveAllocationAccounts, this._kaminoVaultProgramId);
143
+ const accountsToAddToLUT = [
144
+ reserveAllocationConfig.getReserveAddress(),
145
+ cTokenVault,
146
+ ...this.getReserveAccountsToInsertInLut(reserveState),
147
+ ];
148
+ const lendingMarketAuth = (0, utils_2.lendingMarketAuthPda)(reserveState.lendingMarket, this._kaminoLendProgramId)[0];
149
+ accountsToAddToLUT.push(lendingMarketAuth);
150
+ const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(vaultState.adminAuthority, vaultState.vaultLookupTable, accountsToAddToLUT);
151
+ const updateReserveAllocationIxs = {
152
+ updateReserveAllocationIx,
153
+ updateLUTIxs: insertIntoLUTIxs,
154
+ };
155
+ return updateReserveAllocationIxs;
111
156
  }
112
157
  /**
113
- * This method updates the vault config
114
- * @param vault - vault to be updated
115
- * @param mode - the field to be updated
116
- * @param value - the new value for the field to be updated (number or pubkey)
117
- * @returns - a list of instructions
158
+ * Update a field of the vault. If the field is a pubkey it will return an extra instruction to add that account into the lookup table
159
+ * @param vault the vault to update
160
+ * @param mode the field to update (based on VaultConfigFieldKind enum)
161
+ * @param value the value to update the field with
162
+ * @returns a struct that contains the instruction to update the field and an optional list of instructions to update the lookup table
118
163
  */
119
- async updateVaultConfigIx(vault, mode, value) {
164
+ async updateVaultConfigIxs(vault, mode, value) {
120
165
  const vaultState = await vault.getState(this.getConnection());
121
166
  const updateVaultConfigAccs = {
122
167
  adminAuthority: vaultState.adminAuthority,
@@ -128,8 +173,14 @@ class KaminoVaultClient {
128
173
  data: Buffer.from([0]),
129
174
  };
130
175
  if (isNaN(+value)) {
131
- const data = new web3_js_1.PublicKey(value);
132
- updateVaultConfigArgs.data = data.toBuffer();
176
+ if (mode.kind === new types_1.VaultConfigField.Name().kind) {
177
+ const data = Array.from(this.encodeVaultName(value));
178
+ updateVaultConfigArgs.data = Buffer.from(data);
179
+ }
180
+ else {
181
+ const data = new web3_js_1.PublicKey(value);
182
+ updateVaultConfigArgs.data = data.toBuffer();
183
+ }
133
184
  }
134
185
  else {
135
186
  const buffer = Buffer.alloc(8);
@@ -155,6 +206,51 @@ class KaminoVaultClient {
155
206
  const updateVaultConfigIx = (0, instructions_1.updateVaultConfig)(updateVaultConfigArgs, updateVaultConfigAccs, this._kaminoVaultProgramId);
156
207
  updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesAccountMetas);
157
208
  updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesLendingMarkets);
209
+ const updateLUTIxs = [];
210
+ if (mode.kind === new types_1.VaultConfigField.PendingVaultAdmin().kind || mode.kind === new types_1.VaultConfigField.Farm().kind) {
211
+ const newPubkey = new web3_js_1.PublicKey(value);
212
+ const insertIntoLutIxs = await this.insertIntoLookupTableIxs(vaultState.adminAuthority, vaultState.vaultLookupTable, [newPubkey]);
213
+ updateLUTIxs.push(...insertIntoLutIxs);
214
+ }
215
+ const updateVaultConfigIxs = {
216
+ updateVaultConfigIx,
217
+ updateLUTIxs,
218
+ };
219
+ return updateVaultConfigIxs;
220
+ }
221
+ /**
222
+ * This method updates the vault config for a vault that
223
+ * @param vault - address of vault to be updated
224
+ * @param mode - the field to be updated
225
+ * @param value - the new value for the field to be updated (number or pubkey)
226
+ * @returns - a list of instructions
227
+ */
228
+ updateUninitialisedVaultConfigIx(admin, vault, mode, value) {
229
+ const updateVaultConfigAccs = {
230
+ adminAuthority: admin,
231
+ vaultState: vault,
232
+ klendProgram: this._kaminoLendProgramId,
233
+ };
234
+ const updateVaultConfigArgs = {
235
+ entry: mode,
236
+ data: Buffer.from([0]),
237
+ };
238
+ if (isNaN(+value)) {
239
+ if (mode.kind === new types_1.VaultConfigField.Name().kind) {
240
+ const data = Array.from(this.encodeVaultName(value));
241
+ updateVaultConfigArgs.data = Buffer.from(data);
242
+ }
243
+ else {
244
+ const data = new web3_js_1.PublicKey(value);
245
+ updateVaultConfigArgs.data = data.toBuffer();
246
+ }
247
+ }
248
+ else {
249
+ const buffer = Buffer.alloc(8);
250
+ buffer.writeBigUInt64LE(BigInt(value.toString()));
251
+ updateVaultConfigArgs.data = buffer;
252
+ }
253
+ const updateVaultConfigIx = (0, instructions_1.updateVaultConfig)(updateVaultConfigArgs, updateVaultConfigAccs, this._kaminoVaultProgramId);
158
254
  return updateVaultConfigIx;
159
255
  }
160
256
  /**
@@ -162,13 +258,28 @@ class KaminoVaultClient {
162
258
  * @param vault - vault to change the ownership for
163
259
  * @returns - an instruction to be used to be executed
164
260
  */
165
- async acceptVaultOwnershipIx(vault) {
261
+ async acceptVaultOwnershipIxs(vault) {
166
262
  const vaultState = await vault.getState(this.getConnection());
167
263
  const acceptOwneshipAccounts = {
168
264
  pendingAdmin: vaultState.pendingAdmin,
169
265
  vaultState: vault.address,
170
266
  };
171
- return (0, instructions_1.updateAdmin)(acceptOwneshipAccounts, this._kaminoVaultProgramId);
267
+ const acceptVaultOwnershipIx = (0, instructions_1.updateAdmin)(acceptOwneshipAccounts, this._kaminoVaultProgramId);
268
+ // read the current LUT and create a new one for the new admin and backfill it
269
+ const accountsInExistentLUT = (await this.getAccountsInLUT(vaultState.vaultLookupTable)).filter((account) => !account.equals(vaultState.adminAuthority));
270
+ const LUTIxs = [];
271
+ const [initNewLUTIx, newLUT] = this.getInitLookupTableIx(vaultState.pendingAdmin, await this._connection.getSlot());
272
+ LUTIxs.push(initNewLUTIx);
273
+ const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(vaultState.pendingAdmin, newLUT, accountsInExistentLUT);
274
+ LUTIxs.push(...insertIntoLUTIxs);
275
+ const updateVaultConfigIxs = await this.updateVaultConfigIxs(vault, new types_1.VaultConfigField.LookupTable(), newLUT.toString());
276
+ LUTIxs.push(updateVaultConfigIxs.updateVaultConfigIx);
277
+ LUTIxs.push(...updateVaultConfigIxs.updateLUTIxs);
278
+ const acceptVaultOwnershipIxs = {
279
+ acceptVaultOwnershipIx,
280
+ updateLUTIxs: LUTIxs,
281
+ };
282
+ return acceptVaultOwnershipIxs;
172
283
  }
173
284
  /**
174
285
  * 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)
@@ -282,7 +393,7 @@ class KaminoVaultClient {
282
393
  tokenMint: vaultState.tokenMint,
283
394
  baseVaultAuthority: vaultState.baseVaultAuthority,
284
395
  sharesMint: vaultState.sharesMint,
285
- tokenAta: userTokenAta,
396
+ userTokenAta: userTokenAta,
286
397
  userSharesAta: userSharesAta,
287
398
  tokenProgram: tokenProgramID,
288
399
  instructionSysvarAccount: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
@@ -322,6 +433,32 @@ class KaminoVaultClient {
322
433
  * @returns an array of instructions to be executed
323
434
  */
324
435
  async withdrawIxs(user, vault, shareAmount, slot, vaultReservesMap) {
436
+ const vaultState = await vault.getState(this._connection);
437
+ const kaminoVault = new KaminoVault(vault.address, vaultState, vault.programId);
438
+ // if the vault has allocations withdraw otherwise wtihdraw from available ix
439
+ const vaultAllocation = vaultState.vaultAllocationStrategy.find((allocation) => ~allocation.reserve.equals(web3_js_1.PublicKey.default));
440
+ if (vaultAllocation) {
441
+ return this.wihdrdrawWithReserveIxns(user, kaminoVault, shareAmount, slot, vaultReservesMap);
442
+ }
443
+ else {
444
+ return this.withdrawFromAvailableIxns(user, kaminoVault, shareAmount);
445
+ }
446
+ }
447
+ async withdrawFromAvailableIxns(user, vault, shareAmount) {
448
+ const vaultState = await vault.getState(this._connection);
449
+ const kaminoVault = new KaminoVault(vault.address, vaultState, vault.programId);
450
+ const userSharesAta = (0, lib_1.getAssociatedTokenAddress)(vaultState.sharesMint, user);
451
+ const [{ ata: userTokenAta, createAtaIx }] = (0, utils_2.createAtasIdempotent)(user, [
452
+ {
453
+ mint: vaultState.tokenMint,
454
+ tokenProgram: vaultState.tokenProgram,
455
+ },
456
+ ]);
457
+ const shareLamportsToWithdraw = (0, kliquidity_sdk_1.collToLamportsDecimal)(shareAmount, vaultState.sharesMintDecimals.toNumber());
458
+ const withdrawFromAvailableIxn = await this.withdrawFromAvailableIxn(user, kaminoVault, vaultState, userSharesAta, userTokenAta, shareLamportsToWithdraw);
459
+ return [createAtaIx, withdrawFromAvailableIxn];
460
+ }
461
+ async wihdrdrawWithReserveIxns(user, vault, shareAmount, slot, vaultReservesMap) {
325
462
  const vaultState = await vault.getState(this._connection);
326
463
  const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
327
464
  const userSharesAta = (0, lib_1.getAssociatedTokenAddress)(vaultState.sharesMint, user);
@@ -422,7 +559,6 @@ class KaminoVaultClient {
422
559
  payerTokenAccount: payerTokenAta,
423
560
  tokenMint: vaultState.tokenMint,
424
561
  reserveCollateralTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
425
- sharesTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
426
562
  };
427
563
  const investIx = (0, instructions_1.invest)(investAccounts, this._kaminoVaultProgramId);
428
564
  const vaultReserves = this.getVaultReserves(vaultState);
@@ -432,29 +568,46 @@ class KaminoVaultClient {
432
568
  investIx.keys = investIx.keys.concat(vaultReservesAccountMetas);
433
569
  return [createAtaIx, investIx];
434
570
  }
571
+ encodeVaultName(token) {
572
+ const maxArray = new Uint8Array(40);
573
+ const s = new TextEncoder().encode(token);
574
+ maxArray.set(s);
575
+ return maxArray;
576
+ }
577
+ decodeVaultName(token) {
578
+ const maxArray = new Uint8Array(token);
579
+ let s = new TextDecoder().decode(maxArray);
580
+ // Remove trailing zeros and spaces
581
+ s = s.replace(/[\0 ]+$/, '');
582
+ return s;
583
+ }
435
584
  withdrawIxn(user, vault, vaultState, marketAddress, reserve, userSharesAta, userTokenAta, shareAmountLamports, vaultReservesState) {
436
585
  const lendingMarketAuth = (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId)[0];
437
586
  const withdrawAccounts = {
438
- user: user,
439
- vaultState: vault.address,
440
- tokenVault: vaultState.tokenVault,
441
- tokenMint: vaultState.tokenMint,
442
- baseVaultAuthority: vaultState.baseVaultAuthority,
443
- sharesMint: vaultState.sharesMint,
444
- userSharesAta: userSharesAta,
445
- tokenAta: userTokenAta,
446
- tokenProgram: vaultState.tokenProgram,
447
- instructionSysvarAccount: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
448
- reserve: reserve.address,
449
- ctokenVault: getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId),
450
- /** CPI accounts */
451
- lendingMarket: marketAddress,
452
- lendingMarketAuthority: lendingMarketAuth,
453
- reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
454
- reserveCollateralMint: reserve.state.collateral.mintPubkey,
455
- klendProgram: this._kaminoLendProgramId,
456
- reserveCollateralTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
457
- sharesTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
587
+ withdrawFromAvailable: {
588
+ user,
589
+ vaultState: vault.address,
590
+ tokenVault: vaultState.tokenVault,
591
+ baseVaultAuthority: vaultState.baseVaultAuthority,
592
+ userTokenAta: userTokenAta,
593
+ tokenMint: vaultState.tokenMint,
594
+ userSharesAta: userSharesAta,
595
+ sharesMint: vaultState.sharesMint,
596
+ tokenProgram: vaultState.tokenProgram,
597
+ sharesTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
598
+ klendProgram: this._kaminoLendProgramId,
599
+ },
600
+ withdrawFromReserveAccounts: {
601
+ vaultState: vault.address,
602
+ reserve: reserve.address,
603
+ ctokenVault: getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId),
604
+ lendingMarket: marketAddress,
605
+ lendingMarketAuthority: lendingMarketAuth,
606
+ reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
607
+ reserveCollateralMint: reserve.state.collateral.mintPubkey,
608
+ reserveCollateralTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
609
+ instructionSysvarAccount: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
610
+ },
458
611
  };
459
612
  const withdrawArgs = {
460
613
  sharesAmount: new anchor_1.BN(shareAmountLamports.toString()),
@@ -479,6 +632,25 @@ class KaminoVaultClient {
479
632
  withdrawIxn.keys = withdrawIxn.keys.concat(vaultReservesLendingMarkets);
480
633
  return withdrawIxn;
481
634
  }
635
+ async withdrawFromAvailableIxn(user, vault, vaultState, userSharesAta, userTokenAta, shareAmountLamports) {
636
+ const withdrawFromAvailableAccounts = {
637
+ user,
638
+ vaultState: vault.address,
639
+ tokenVault: vaultState.tokenVault,
640
+ baseVaultAuthority: vaultState.baseVaultAuthority,
641
+ userTokenAta: userTokenAta,
642
+ tokenMint: vaultState.tokenMint,
643
+ userSharesAta: userSharesAta,
644
+ sharesMint: vaultState.sharesMint,
645
+ tokenProgram: vaultState.tokenProgram,
646
+ sharesTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
647
+ klendProgram: this._kaminoLendProgramId,
648
+ };
649
+ const withdrawFromAvailableArgs = {
650
+ sharesAmount: new anchor_1.BN(shareAmountLamports.toString()),
651
+ };
652
+ return (0, instructions_1.withdrawFromAvailable)(withdrawFromAvailableArgs, withdrawFromAvailableAccounts, this._kaminoVaultProgramId);
653
+ }
482
654
  async withdrawPendingFeesIxn(vault, vaultState, marketAddress, reserve, adminTokenAta) {
483
655
  const lendingMarketAuth = (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId)[0];
484
656
  const withdrawPendingFeesAccounts = {
@@ -499,7 +671,6 @@ class KaminoVaultClient {
499
671
  klendProgram: this._kaminoLendProgramId,
500
672
  instructionSysvarAccount: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
501
673
  reserveCollateralTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
502
- sharesTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
503
674
  };
504
675
  const withdrawPendingFeesIxn = (0, instructions_1.withdrawPendingFees)(withdrawPendingFeesAccounts, this._kaminoVaultProgramId);
505
676
  const vaultReserves = this.getVaultReserves(vaultState);
@@ -522,6 +693,150 @@ class KaminoVaultClient {
522
693
  withdrawPendingFeesIxn.keys = withdrawPendingFeesIxn.keys.concat(vaultReservesLendingMarkets);
523
694
  return withdrawPendingFeesIxn;
524
695
  }
696
+ /**
697
+ * Sync a vault for lookup table; create and set the LUT for the vault if needed and fill it with all the needed accounts
698
+ * @param vault the vault to sync and set the LUT for if needed
699
+ * @param vaultReserves optional; the state of the reserves in the vault allocation
700
+ * @returns a struct that contains a list of ix to create the LUT and assign it to the vault if needed + a list of ixs to insert all the accounts in the LUT
701
+ */
702
+ async syncVaultLookupTable(vault, vaultReserves) {
703
+ const vaultState = await vault.getState(this._connection);
704
+ const allAccountsToBeInserted = [
705
+ vault.address,
706
+ vaultState.adminAuthority,
707
+ vaultState.baseVaultAuthority,
708
+ vaultState.tokenMint,
709
+ vaultState.tokenVault,
710
+ vaultState.sharesMint,
711
+ vaultState.tokenProgram,
712
+ this._kaminoLendProgramId,
713
+ ];
714
+ vaultState.vaultAllocationStrategy.forEach((allocation) => {
715
+ allAccountsToBeInserted.push(allocation.reserve);
716
+ allAccountsToBeInserted.push(allocation.ctokenVault);
717
+ });
718
+ if (vaultReserves) {
719
+ vaultReserves.forEach((reserve) => {
720
+ allAccountsToBeInserted.push(reserve.state.lendingMarket);
721
+ allAccountsToBeInserted.push(reserve.state.farmCollateral);
722
+ allAccountsToBeInserted.push(reserve.state.farmDebt);
723
+ allAccountsToBeInserted.push(reserve.state.liquidity.supplyVault);
724
+ allAccountsToBeInserted.push(reserve.state.liquidity.feeVault);
725
+ allAccountsToBeInserted.push(reserve.state.collateral.mintPubkey);
726
+ allAccountsToBeInserted.push(reserve.state.collateral.supplyVault);
727
+ });
728
+ }
729
+ else {
730
+ const vaultReservesState = await this.loadVaultReserves(vaultState);
731
+ vaultReservesState.forEach((reserve) => {
732
+ allAccountsToBeInserted.push(reserve.state.lendingMarket);
733
+ allAccountsToBeInserted.push(reserve.state.farmCollateral);
734
+ allAccountsToBeInserted.push(reserve.state.farmDebt);
735
+ allAccountsToBeInserted.push(reserve.state.liquidity.supplyVault);
736
+ allAccountsToBeInserted.push(reserve.state.liquidity.feeVault);
737
+ allAccountsToBeInserted.push(reserve.state.collateral.mintPubkey);
738
+ allAccountsToBeInserted.push(reserve.state.collateral.supplyVault);
739
+ });
740
+ }
741
+ if (!vaultState.vaultFarm.equals(web3_js_1.PublicKey.default)) {
742
+ allAccountsToBeInserted.push(vaultState.vaultFarm);
743
+ }
744
+ const setupLUTIfNeededIxs = [];
745
+ let lut = vaultState.vaultLookupTable;
746
+ if (lut.equals(web3_js_1.PublicKey.default)) {
747
+ const recentSlot = await this._connection.getSlot();
748
+ const [ixn, address] = this.getInitLookupTableIx(vaultState.adminAuthority, recentSlot);
749
+ setupLUTIfNeededIxs.push(ixn);
750
+ lut = address;
751
+ // set the new LUT for the vault
752
+ const updateVaultConfigIxs = await this.updateVaultConfigIxs(vault, new types_1.VaultConfigField.LookupTable(), lut.toString());
753
+ setupLUTIfNeededIxs.push(updateVaultConfigIxs.updateVaultConfigIx);
754
+ }
755
+ const ixns = [];
756
+ let overridenExistentAccounts = undefined;
757
+ if (vaultState.vaultLookupTable.equals(web3_js_1.PublicKey.default)) {
758
+ overridenExistentAccounts = [];
759
+ }
760
+ ixns.push(...(await this.insertIntoLookupTableIxs(vaultState.adminAuthority, lut, allAccountsToBeInserted, overridenExistentAccounts)));
761
+ return {
762
+ setupLUTIfNeededIxs,
763
+ syncLUTIxs: ixns,
764
+ };
765
+ }
766
+ getInitLookupTableIx(payer, slot) {
767
+ const [ixn, address] = web3_js_1.AddressLookupTableProgram.createLookupTable({
768
+ authority: payer,
769
+ payer,
770
+ recentSlot: slot,
771
+ });
772
+ return [ixn, address];
773
+ }
774
+ getReserveAccountsToInsertInLut(reserveState) {
775
+ return [
776
+ reserveState.lendingMarket,
777
+ reserveState.farmCollateral,
778
+ reserveState.farmDebt,
779
+ reserveState.liquidity.mintPubkey,
780
+ reserveState.liquidity.supplyVault,
781
+ reserveState.liquidity.feeVault,
782
+ reserveState.collateral.mintPubkey,
783
+ reserveState.collateral.supplyVault,
784
+ ];
785
+ }
786
+ async insertIntoLookupTableIxs(payer, lookupTable, keys, accountsInLUT) {
787
+ let lutContents = accountsInLUT;
788
+ if (!accountsInLUT) {
789
+ lutContents = await this.getAccountsInLUT(lookupTable);
790
+ }
791
+ else {
792
+ lutContents = accountsInLUT;
793
+ }
794
+ const missingAccounts = keys.filter((key) => !lutContents.includes(key) && !key.equals(web3_js_1.PublicKey.default));
795
+ // deduplicate missing accounts and remove default accounts and convert it back to an array
796
+ const missingAccountsList = new utils_2.PublicKeySet(missingAccounts).toArray();
797
+ const chunkSize = 20;
798
+ const ixns = [];
799
+ for (let i = 0; i < missingAccountsList.length; i += chunkSize) {
800
+ const chunk = missingAccountsList.slice(i, i + chunkSize);
801
+ const ixn = web3_js_1.AddressLookupTableProgram.extendLookupTable({
802
+ lookupTable,
803
+ authority: payer,
804
+ payer,
805
+ addresses: chunk,
806
+ });
807
+ ixns.push(ixn);
808
+ }
809
+ return ixns;
810
+ }
811
+ /**
812
+ *
813
+ * @param connection
814
+ * @param lookupTable
815
+ * @returns
816
+ */
817
+ async getAccountsInLUT(lookupTable) {
818
+ const lutState = await this._connection.getAddressLookupTable(lookupTable);
819
+ if (!lutState || !lutState.value) {
820
+ throw new Error(`Lookup table ${lookupTable} not found`);
821
+ }
822
+ return lutState.value.state.addresses;
823
+ }
824
+ deactivateLookupTableIx(payer, lookupTable) {
825
+ const ixn = web3_js_1.AddressLookupTableProgram.deactivateLookupTable({
826
+ authority: payer,
827
+ lookupTable: lookupTable,
828
+ });
829
+ return ixn;
830
+ }
831
+ /// this require the LUT to be deactivated at least 500 blocks before
832
+ closeLookupTableIx(payer, lookupTable) {
833
+ const ixn = web3_js_1.AddressLookupTableProgram.closeLookupTable({
834
+ authority: payer,
835
+ recipient: payer,
836
+ lookupTable: lookupTable,
837
+ });
838
+ return ixn;
839
+ }
525
840
  /**
526
841
  * This method returns the user shares balance for a given vault
527
842
  * @param user - user to calculate the shares balance for
@@ -668,7 +983,7 @@ class KaminoVaultClient {
668
983
  if (!reserveAllocation) {
669
984
  throw new Error(`Reserve ${reserve.address.toBase58()} not found in vault allocation strategy`);
670
985
  }
671
- const reserveAllocationLiquidityAmountLamports = new decimal_js_1.default(reserveAllocation.cTokenAllocation.toString()).div(reserveCollExchangeRate);
986
+ const reserveAllocationLiquidityAmountLamports = new decimal_js_1.default(reserveAllocation.ctokenAllocation.toString()).div(reserveCollExchangeRate);
672
987
  const reserveAllocationLiquidityAmount = (0, lib_1.lamportsToDecimal)(reserveAllocationLiquidityAmountLamports, vaultState.tokenMintDecimals.toNumber());
673
988
  return reserveAllocationLiquidityAmount;
674
989
  }
@@ -709,7 +1024,7 @@ class KaminoVaultClient {
709
1024
  .div(reserve.state.config.protocolTakeRatePct / 100)
710
1025
  .floor()
711
1026
  .toNumber());
712
- const reserveAllocationLiquidityAmount = new decimal_js_1.default(allocationStrategy.cTokenAllocation.toString()).div(reserveCollExchangeRate);
1027
+ const reserveAllocationLiquidityAmount = new decimal_js_1.default(allocationStrategy.ctokenAllocation.toString()).div(reserveCollExchangeRate);
713
1028
  const reserveAvailableLiquidityAmount = reserve.getLiquidityAvailableAmount();
714
1029
  reserveAllocationAvailableLiquidityToWithdraw.set(allocationStrategy.reserve, decimal_js_1.default.min(reserveAllocationLiquidityAmount, reserveAvailableLiquidityAmount));
715
1030
  });
@@ -841,7 +1156,7 @@ class KaminoVaultClient {
841
1156
  throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
842
1157
  }
843
1158
  const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0);
844
- const reserveAllocationLiquidityAmount = new decimal_js_1.default(allocationStrategy.cTokenAllocation.toString()).div(reserveCollExchangeRate);
1159
+ const reserveAllocationLiquidityAmount = new decimal_js_1.default(allocationStrategy.ctokenAllocation.toString()).div(reserveCollExchangeRate);
845
1160
  vaultHoldings.invested = vaultHoldings.invested.add(reserveAllocationLiquidityAmount);
846
1161
  vaultHoldings.investedInReserves.set(allocationStrategy.reserve, (0, lib_1.lamportsToDecimal)(reserveAllocationLiquidityAmount, decimals));
847
1162
  });
@@ -931,7 +1246,7 @@ class KaminoVaultClient {
931
1246
  throw new Error(`Reserve ${allocationStrategy.reserve.toBase58()} not found`);
932
1247
  }
933
1248
  const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0);
934
- const reserveAllocationLiquidityAmountLamports = new decimal_js_1.default(allocationStrategy.cTokenAllocation.toString()).div(reserveCollExchangeRate);
1249
+ const reserveAllocationLiquidityAmountLamports = new decimal_js_1.default(allocationStrategy.ctokenAllocation.toString()).div(reserveCollExchangeRate);
935
1250
  const reserveAllocationLiquidityAmount = (0, lib_1.lamportsToDecimal)(reserveAllocationLiquidityAmountLamports, vault.tokenMintDecimals.toString());
936
1251
  const utilizationRatio = reserve.getEstimatedUtilizationRatio(slot, 0);
937
1252
  totalInvested = totalInvested.add(reserveAllocationLiquidityAmount);
@@ -1009,12 +1324,12 @@ class KaminoVaultClient {
1009
1324
  return totalAPY.div(totalWeights);
1010
1325
  }
1011
1326
  /**
1012
- * Retrive the total amount of tokenes earned by the vault since its inception after deducting the management and performance fees
1327
+ * Retrive the total amount of interest earned by the vault since its inception, including what was charged as fees
1013
1328
  * @param vaultState the kamino vault state to get total net yield for
1014
- * @returns a decimal representing the net number of tokens earned by the vault since its inception after deducting the management and performance fees
1329
+ * @returns a decimal representing the net number of tokens earned by the vault since its inception
1015
1330
  */
1016
- async getVaultTotalNetYield(vaultState) {
1017
- const netYieldLamports = new fraction_1.Fraction(vaultState.cumulativeNetEarnedYield).toDecimal();
1331
+ async getVaultCumulativeInterest(vaultState) {
1332
+ const netYieldLamports = new fraction_1.Fraction(vaultState.cumulativeEarnedInterestSf).toDecimal();
1018
1333
  return (0, lib_1.lamportsToDecimal)(netYieldLamports, vaultState.tokenMintDecimals.toString());
1019
1334
  }
1020
1335
  } // KaminoVaultClient
@@ -1064,18 +1379,21 @@ class KaminoVaultConfig {
1064
1379
  performanceFeeRate;
1065
1380
  /** The management fee rate of the vault, expressed as a decimal */
1066
1381
  managementFeeRate;
1382
+ /** The name to be stored on cain for the vault (max 40 characters). */
1383
+ name;
1067
1384
  constructor(args) {
1068
1385
  this.admin = args.admin;
1069
1386
  this.tokenMint = args.tokenMint;
1070
1387
  this.performanceFeeRate = args.performanceFeeRate;
1071
1388
  this.managementFeeRate = args.managementFeeRate;
1072
1389
  this.tokenMintProgramId = args.tokenMintProgramId;
1390
+ this.name = args.name;
1073
1391
  }
1074
1392
  getPerformanceFeeBps() {
1075
- return this.performanceFeeRate.mul(10000).toNumber();
1393
+ return this.performanceFeeRate.mul(100).toNumber();
1076
1394
  }
1077
- getManagementFeeRate() {
1078
- return this.managementFeeRate.mul(10000).toNumber();
1395
+ getManagementFeeBps() {
1396
+ return this.managementFeeRate.mul(100).toNumber();
1079
1397
  }
1080
1398
  }
1081
1399
  exports.KaminoVaultConfig = KaminoVaultConfig;