@kamino-finance/klend-sdk 5.2.12 → 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.
- package/dist/classes/manager.d.ts +36 -7
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +41 -7
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/types.d.ts +23 -0
- package/dist/classes/types.d.ts.map +1 -0
- package/dist/classes/types.js +3 -0
- package/dist/classes/types.js.map +1 -0
- package/dist/classes/vault.d.ts +44 -8
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +333 -17
- package/dist/classes/vault.js.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +62 -12
- package/dist/client_kamino_manager.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/manager.ts +57 -10
- package/src/classes/types.ts +28 -0
- package/src/classes/vault.ts +493 -22
- package/src/client_kamino_manager.ts +119 -15
package/dist/classes/vault.js
CHANGED
|
@@ -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
|
|
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();
|
|
@@ -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
|
-
//
|
|
83
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
114
|
-
* @param vault
|
|
115
|
-
* @param mode
|
|
116
|
-
* @param value
|
|
117
|
-
* @returns
|
|
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
|
|
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
|
-
|
|
132
|
-
|
|
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
|
|
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
|
-
|
|
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)
|
|
@@ -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);
|
|
@@ -431,6 +568,19 @@ class KaminoVaultClient {
|
|
|
431
568
|
investIx.keys = investIx.keys.concat(vaultReservesAccountMetas);
|
|
432
569
|
return [createAtaIx, investIx];
|
|
433
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
|
+
}
|
|
434
584
|
withdrawIxn(user, vault, vaultState, marketAddress, reserve, userSharesAta, userTokenAta, shareAmountLamports, vaultReservesState) {
|
|
435
585
|
const lendingMarketAuth = (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId)[0];
|
|
436
586
|
const withdrawAccounts = {
|
|
@@ -482,6 +632,25 @@ class KaminoVaultClient {
|
|
|
482
632
|
withdrawIxn.keys = withdrawIxn.keys.concat(vaultReservesLendingMarkets);
|
|
483
633
|
return withdrawIxn;
|
|
484
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
|
+
}
|
|
485
654
|
async withdrawPendingFeesIxn(vault, vaultState, marketAddress, reserve, adminTokenAta) {
|
|
486
655
|
const lendingMarketAuth = (0, utils_2.lendingMarketAuthPda)(marketAddress, this._kaminoLendProgramId)[0];
|
|
487
656
|
const withdrawPendingFeesAccounts = {
|
|
@@ -524,6 +693,150 @@ class KaminoVaultClient {
|
|
|
524
693
|
withdrawPendingFeesIxn.keys = withdrawPendingFeesIxn.keys.concat(vaultReservesLendingMarkets);
|
|
525
694
|
return withdrawPendingFeesIxn;
|
|
526
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
|
+
}
|
|
527
840
|
/**
|
|
528
841
|
* This method returns the user shares balance for a given vault
|
|
529
842
|
* @param user - user to calculate the shares balance for
|
|
@@ -1066,18 +1379,21 @@ class KaminoVaultConfig {
|
|
|
1066
1379
|
performanceFeeRate;
|
|
1067
1380
|
/** The management fee rate of the vault, expressed as a decimal */
|
|
1068
1381
|
managementFeeRate;
|
|
1382
|
+
/** The name to be stored on cain for the vault (max 40 characters). */
|
|
1383
|
+
name;
|
|
1069
1384
|
constructor(args) {
|
|
1070
1385
|
this.admin = args.admin;
|
|
1071
1386
|
this.tokenMint = args.tokenMint;
|
|
1072
1387
|
this.performanceFeeRate = args.performanceFeeRate;
|
|
1073
1388
|
this.managementFeeRate = args.managementFeeRate;
|
|
1074
1389
|
this.tokenMintProgramId = args.tokenMintProgramId;
|
|
1390
|
+
this.name = args.name;
|
|
1075
1391
|
}
|
|
1076
1392
|
getPerformanceFeeBps() {
|
|
1077
|
-
return this.performanceFeeRate.mul(
|
|
1393
|
+
return this.performanceFeeRate.mul(100).toNumber();
|
|
1078
1394
|
}
|
|
1079
|
-
|
|
1080
|
-
return this.managementFeeRate.mul(
|
|
1395
|
+
getManagementFeeBps() {
|
|
1396
|
+
return this.managementFeeRate.mul(100).toNumber();
|
|
1081
1397
|
}
|
|
1082
1398
|
}
|
|
1083
1399
|
exports.KaminoVaultConfig = KaminoVaultConfig;
|