@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.
- package/dist/classes/manager.d.ts +38 -9
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +44 -10
- 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/utils.js +2 -2
- package/dist/classes/utils.js.map +1 -1
- package/dist/classes/vault.d.ts +47 -11
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +367 -49
- 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/dist/idl_codegen_kamino_vault/accounts/Reserve.js +1 -1
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts +18 -9
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.js +62 -42
- package/dist/idl_codegen_kamino_vault/accounts/VaultState.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/errors/custom.d.ts +112 -80
- package/dist/idl_codegen_kamino_vault/errors/custom.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/errors/custom.js +214 -158
- package/dist/idl_codegen_kamino_vault/errors/custom.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/deposit.d.ts +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/deposit.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/deposit.js +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/deposit.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/index.d.ts +6 -0
- package/dist/idl_codegen_kamino_vault/instructions/index.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/index.js +7 -1
- package/dist/idl_codegen_kamino_vault/instructions/index.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/initVault.d.ts +2 -2
- package/dist/idl_codegen_kamino_vault/instructions/initVault.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/initVault.js +2 -2
- package/dist/idl_codegen_kamino_vault/instructions/initVault.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.d.ts +19 -0
- package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.d.ts.map +1 -0
- package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.js +58 -0
- package/dist/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.js.map +1 -0
- package/dist/idl_codegen_kamino_vault/instructions/invest.d.ts +3 -4
- package/dist/idl_codegen_kamino_vault/instructions/invest.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/invest.js +2 -3
- package/dist/idl_codegen_kamino_vault/instructions/invest.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.d.ts +16 -0
- package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.d.ts.map +1 -0
- package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.js +55 -0
- package/dist/idl_codegen_kamino_vault/instructions/updateSharesMetadata.js.map +1 -0
- package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.js +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/updateVaultConfig.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/withdraw.d.ts +24 -20
- package/dist/idl_codegen_kamino_vault/instructions/withdraw.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/withdraw.js +81 -20
- package/dist/idl_codegen_kamino_vault/instructions/withdraw.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.d.ts +21 -0
- package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.d.ts.map +1 -0
- package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.js +55 -0
- package/dist/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.js.map +1 -0
- package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.d.ts +2 -3
- package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.js +3 -4
- package/dist/idl_codegen_kamino_vault/instructions/withdrawPendingFees.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/ReserveConfig.d.ts +78 -20
- package/dist/idl_codegen_kamino_vault/types/ReserveConfig.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/ReserveConfig.js +45 -14
- package/dist/idl_codegen_kamino_vault/types/ReserveConfig.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.d.ts +16 -16
- package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.js +16 -16
- package/dist/idl_codegen_kamino_vault/types/ReserveLiquidity.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/VaultAllocation.d.ts +5 -5
- package/dist/idl_codegen_kamino_vault/types/VaultAllocation.js +7 -7
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts +46 -7
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js +84 -12
- package/dist/idl_codegen_kamino_vault/types/VaultConfigField.js.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/index.d.ts +2 -2
- package/dist/idl_codegen_kamino_vault/types/index.d.ts.map +1 -1
- package/dist/idl_codegen_kamino_vault/types/index.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.js +10 -1
- package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.js +7 -6
- package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
- package/dist/leverage/operations.d.ts.map +1 -1
- package/dist/leverage/operations.js +12 -8
- package/dist/leverage/operations.js.map +1 -1
- package/dist/leverage/types.d.ts +1 -0
- package/dist/leverage/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/classes/manager.ts +60 -13
- package/src/classes/types.ts +28 -0
- package/src/classes/utils.ts +2 -2
- package/src/classes/vault.ts +527 -54
- package/src/client_kamino_manager.ts +119 -15
- package/src/idl_codegen_kamino_vault/accounts/Reserve.ts +1 -1
- package/src/idl_codegen_kamino_vault/accounts/VaultState.ts +215 -178
- package/src/idl_codegen_kamino_vault/errors/custom.ts +213 -157
- package/src/idl_codegen_kamino_vault/instructions/deposit.ts +2 -2
- package/src/idl_codegen_kamino_vault/instructions/index.ts +15 -0
- package/src/idl_codegen_kamino_vault/instructions/initVault.ts +4 -4
- package/src/idl_codegen_kamino_vault/instructions/initializeSharesMetadata.ts +58 -0
- package/src/idl_codegen_kamino_vault/instructions/invest.ts +5 -7
- package/src/idl_codegen_kamino_vault/instructions/updateSharesMetadata.ts +52 -0
- package/src/idl_codegen_kamino_vault/instructions/updateVaultConfig.ts +1 -1
- package/src/idl_codegen_kamino_vault/instructions/withdraw.ts +106 -40
- package/src/idl_codegen_kamino_vault/instructions/withdrawFromAvailable.ts +56 -0
- package/src/idl_codegen_kamino_vault/instructions/withdrawPendingFees.ts +5 -7
- package/src/idl_codegen_kamino_vault/types/ReserveConfig.ts +100 -28
- package/src/idl_codegen_kamino_vault/types/ReserveLiquidity.ts +25 -24
- package/src/idl_codegen_kamino_vault/types/VaultAllocation.ts +9 -9
- package/src/idl_codegen_kamino_vault/types/VaultConfigField.ts +103 -13
- package/src/idl_codegen_kamino_vault/types/index.ts +8 -2
- package/src/lending_operations/repay_with_collateral_calcs.ts +18 -1
- package/src/lending_operations/repay_with_collateral_operations.ts +9 -7
- package/src/leverage/operations.ts +69 -29
- package/src/leverage/types.ts +1 -0
package/src/classes/vault.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BN } from '@coral-xyz/anchor';
|
|
2
2
|
import {
|
|
3
3
|
AccountMeta,
|
|
4
|
+
AddressLookupTableProgram,
|
|
4
5
|
Connection,
|
|
5
6
|
GetProgramAccountsResponse,
|
|
6
7
|
Keypair,
|
|
@@ -42,10 +43,13 @@ import {
|
|
|
42
43
|
UpdateVaultConfigArgs,
|
|
43
44
|
WithdrawAccounts,
|
|
44
45
|
WithdrawArgs,
|
|
46
|
+
withdrawFromAvailable,
|
|
47
|
+
WithdrawFromAvailableAccounts,
|
|
48
|
+
WithdrawFromAvailableArgs,
|
|
45
49
|
withdrawPendingFees,
|
|
46
50
|
WithdrawPendingFeesAccounts,
|
|
47
51
|
} from '../idl_codegen_kamino_vault/instructions';
|
|
48
|
-
import { VaultConfigFieldKind } from '../idl_codegen_kamino_vault/types';
|
|
52
|
+
import { VaultConfigField, VaultConfigFieldKind } from '../idl_codegen_kamino_vault/types';
|
|
49
53
|
import { VaultState } from '../idl_codegen_kamino_vault/accounts';
|
|
50
54
|
import Decimal from 'decimal.js';
|
|
51
55
|
import { bpsToPct, getTokenBalanceFromAccountInfoLamports, numberToLamportsDecimal, parseTokenSymbol } from './utils';
|
|
@@ -54,9 +58,17 @@ import { withdraw } from '../idl_codegen_kamino_vault/instructions';
|
|
|
54
58
|
import { PROGRAM_ID } from '../idl_codegen/programId';
|
|
55
59
|
import { DEFAULT_RECENT_SLOT_DURATION_MS, ReserveWithAddress } from './reserve';
|
|
56
60
|
import { Fraction } from './fraction';
|
|
57
|
-
import { createAtasIdempotent, lendingMarketAuthPda } from '../utils';
|
|
61
|
+
import { createAtasIdempotent, lendingMarketAuthPda, PublicKeySet } from '../utils';
|
|
58
62
|
import bs58 from 'bs58';
|
|
59
63
|
import { getAccountOwner, getProgramAccounts } from '../utils/rpc';
|
|
64
|
+
import {
|
|
65
|
+
AcceptVaultOwnershipIxs,
|
|
66
|
+
InitVaultIxs,
|
|
67
|
+
SyncVaultLUTIxs,
|
|
68
|
+
UpdateReserveAllocationIxs,
|
|
69
|
+
UpdateVaultConfigIxs,
|
|
70
|
+
} from './types';
|
|
71
|
+
import { collToLamportsDecimal } from '@kamino-finance/kliquidity-sdk';
|
|
60
72
|
|
|
61
73
|
export const kaminoVaultId = new PublicKey('kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr');
|
|
62
74
|
export const kaminoVaultStagingId = new PublicKey('STkvh7ostar39Fwr4uZKASs1RNNuYMFMTsE77FiRsL2');
|
|
@@ -99,9 +111,9 @@ export class KaminoVaultClient {
|
|
|
99
111
|
* 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
|
|
100
112
|
* @param vaultConfig - the config object used to create a vault
|
|
101
113
|
* @returns vault - keypair, should be used to sign the transaction which creates the vault account
|
|
102
|
-
* @returns
|
|
114
|
+
* @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
|
|
103
115
|
*/
|
|
104
|
-
async createVaultIxs(vaultConfig: KaminoVaultConfig): Promise<{ vault: Keypair;
|
|
116
|
+
async createVaultIxs(vaultConfig: KaminoVaultConfig): Promise<{ vault: Keypair; initVaultIxs: InitVaultIxs }> {
|
|
105
117
|
const vaultState = Keypair.generate();
|
|
106
118
|
const size = VaultState.layout.span + 8;
|
|
107
119
|
|
|
@@ -131,7 +143,7 @@ export class KaminoVaultClient {
|
|
|
131
143
|
const initVaultAccounts: InitVaultAccounts = {
|
|
132
144
|
adminAuthority: vaultConfig.admin,
|
|
133
145
|
vaultState: vaultState.publicKey,
|
|
134
|
-
|
|
146
|
+
baseTokenMint: vaultConfig.tokenMint,
|
|
135
147
|
tokenVault,
|
|
136
148
|
baseVaultAuthority,
|
|
137
149
|
sharesMint,
|
|
@@ -142,9 +154,63 @@ export class KaminoVaultClient {
|
|
|
142
154
|
};
|
|
143
155
|
const initVaultIx = initVault(initVaultAccounts, this._kaminoVaultProgramId);
|
|
144
156
|
|
|
145
|
-
//
|
|
157
|
+
// create and set up the vault lookup table
|
|
158
|
+
const slot = await this._connection.getSlot();
|
|
159
|
+
const [createLUTIx, lut] = this.getInitLookupTableIx(vaultConfig.admin, slot);
|
|
160
|
+
|
|
161
|
+
const accountsToBeInserted = [
|
|
162
|
+
vaultConfig.admin,
|
|
163
|
+
vaultState.publicKey,
|
|
164
|
+
vaultConfig.tokenMint,
|
|
165
|
+
vaultConfig.tokenMintProgramId,
|
|
166
|
+
baseVaultAuthority,
|
|
167
|
+
sharesMint,
|
|
168
|
+
SystemProgram.programId,
|
|
169
|
+
SYSVAR_RENT_PUBKEY,
|
|
170
|
+
TOKEN_PROGRAM_ID,
|
|
171
|
+
this._kaminoLendProgramId,
|
|
172
|
+
SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
173
|
+
];
|
|
174
|
+
const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(vaultConfig.admin, lut, accountsToBeInserted, []);
|
|
175
|
+
|
|
176
|
+
const setLUTIx = this.updateUninitialisedVaultConfigIx(
|
|
177
|
+
vaultConfig.admin,
|
|
178
|
+
vaultState.publicKey,
|
|
179
|
+
new VaultConfigField.LookupTable(),
|
|
180
|
+
lut.toString()
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const ixns = [createVaultIx, initVaultIx, createLUTIx, setLUTIx];
|
|
184
|
+
|
|
185
|
+
if (vaultConfig.getPerformanceFeeBps() > 0) {
|
|
186
|
+
const setPerformanceFeeIx = this.updateUninitialisedVaultConfigIx(
|
|
187
|
+
vaultConfig.admin,
|
|
188
|
+
vaultState.publicKey,
|
|
189
|
+
new VaultConfigField.PerformanceFeeBps(),
|
|
190
|
+
vaultConfig.getPerformanceFeeBps().toString()
|
|
191
|
+
);
|
|
192
|
+
ixns.push(setPerformanceFeeIx);
|
|
193
|
+
}
|
|
194
|
+
if (vaultConfig.getManagementFeeBps() > 0) {
|
|
195
|
+
const setManagementFeeIx = this.updateUninitialisedVaultConfigIx(
|
|
196
|
+
vaultConfig.admin,
|
|
197
|
+
vaultState.publicKey,
|
|
198
|
+
new VaultConfigField.ManagementFeeBps(),
|
|
199
|
+
vaultConfig.getManagementFeeBps().toString()
|
|
200
|
+
);
|
|
201
|
+
ixns.push(setManagementFeeIx);
|
|
202
|
+
}
|
|
203
|
+
if (vaultConfig.name && vaultConfig.name.length > 0) {
|
|
204
|
+
const setNameIx = this.updateUninitialisedVaultConfigIx(
|
|
205
|
+
vaultConfig.admin,
|
|
206
|
+
vaultState.publicKey,
|
|
207
|
+
new VaultConfigField.Name(),
|
|
208
|
+
vaultConfig.name
|
|
209
|
+
);
|
|
210
|
+
ixns.push(setNameIx);
|
|
211
|
+
}
|
|
146
212
|
|
|
147
|
-
return { vault: vaultState,
|
|
213
|
+
return { vault: vaultState, initVaultIxs: { initVaultIxs: ixns, populateLUTIxs: insertIntoLUTIxs } };
|
|
148
214
|
}
|
|
149
215
|
|
|
150
216
|
/**
|
|
@@ -156,7 +222,7 @@ export class KaminoVaultClient {
|
|
|
156
222
|
async updateReserveAllocationIxs(
|
|
157
223
|
vault: KaminoVault,
|
|
158
224
|
reserveAllocationConfig: ReserveAllocationConfig
|
|
159
|
-
): Promise<
|
|
225
|
+
): Promise<UpdateReserveAllocationIxs> {
|
|
160
226
|
const vaultState: VaultState = await vault.getState(this.getConnection());
|
|
161
227
|
const reserveState: Reserve = reserveAllocationConfig.getReserveState();
|
|
162
228
|
|
|
@@ -183,25 +249,47 @@ export class KaminoVaultClient {
|
|
|
183
249
|
cap: new BN(reserveAllocationConfig.getAllocationCapLamports().floor().toString()),
|
|
184
250
|
};
|
|
185
251
|
|
|
186
|
-
|
|
252
|
+
const updateReserveAllocationIx = updateReserveAllocation(
|
|
187
253
|
updateReserveAllocationArgs,
|
|
188
254
|
updateReserveAllocationAccounts,
|
|
189
255
|
this._kaminoVaultProgramId
|
|
190
256
|
);
|
|
257
|
+
|
|
258
|
+
const accountsToAddToLUT = [
|
|
259
|
+
reserveAllocationConfig.getReserveAddress(),
|
|
260
|
+
cTokenVault,
|
|
261
|
+
...this.getReserveAccountsToInsertInLut(reserveState),
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
const lendingMarketAuth = lendingMarketAuthPda(reserveState.lendingMarket, this._kaminoLendProgramId)[0];
|
|
265
|
+
accountsToAddToLUT.push(lendingMarketAuth);
|
|
266
|
+
|
|
267
|
+
const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(
|
|
268
|
+
vaultState.adminAuthority,
|
|
269
|
+
vaultState.vaultLookupTable,
|
|
270
|
+
accountsToAddToLUT
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
const updateReserveAllocationIxs: UpdateReserveAllocationIxs = {
|
|
274
|
+
updateReserveAllocationIx,
|
|
275
|
+
updateLUTIxs: insertIntoLUTIxs,
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
return updateReserveAllocationIxs;
|
|
191
279
|
}
|
|
192
280
|
|
|
193
281
|
/**
|
|
194
|
-
*
|
|
195
|
-
* @param vault
|
|
196
|
-
* @param mode
|
|
197
|
-
* @param value
|
|
198
|
-
* @returns
|
|
282
|
+
* 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
|
|
283
|
+
* @param vault the vault to update
|
|
284
|
+
* @param mode the field to update (based on VaultConfigFieldKind enum)
|
|
285
|
+
* @param value the value to update the field with
|
|
286
|
+
* @returns a struct that contains the instruction to update the field and an optional list of instructions to update the lookup table
|
|
199
287
|
*/
|
|
200
|
-
async
|
|
288
|
+
async updateVaultConfigIxs(
|
|
201
289
|
vault: KaminoVault,
|
|
202
290
|
mode: VaultConfigFieldKind,
|
|
203
291
|
value: string
|
|
204
|
-
): Promise<
|
|
292
|
+
): Promise<UpdateVaultConfigIxs> {
|
|
205
293
|
const vaultState: VaultState = await vault.getState(this.getConnection());
|
|
206
294
|
|
|
207
295
|
const updateVaultConfigAccs: UpdateVaultConfigAccounts = {
|
|
@@ -216,8 +304,13 @@ export class KaminoVaultClient {
|
|
|
216
304
|
};
|
|
217
305
|
|
|
218
306
|
if (isNaN(+value)) {
|
|
219
|
-
|
|
220
|
-
|
|
307
|
+
if (mode.kind === new VaultConfigField.Name().kind) {
|
|
308
|
+
const data = Array.from(this.encodeVaultName(value));
|
|
309
|
+
updateVaultConfigArgs.data = Buffer.from(data);
|
|
310
|
+
} else {
|
|
311
|
+
const data = new PublicKey(value);
|
|
312
|
+
updateVaultConfigArgs.data = data.toBuffer();
|
|
313
|
+
}
|
|
221
314
|
} else {
|
|
222
315
|
const buffer = Buffer.alloc(8);
|
|
223
316
|
buffer.writeBigUInt64LE(BigInt(value.toString()));
|
|
@@ -251,6 +344,70 @@ export class KaminoVaultClient {
|
|
|
251
344
|
updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesAccountMetas);
|
|
252
345
|
updateVaultConfigIx.keys = updateVaultConfigIx.keys.concat(vaultReservesLendingMarkets);
|
|
253
346
|
|
|
347
|
+
const updateLUTIxs = [];
|
|
348
|
+
|
|
349
|
+
if (mode.kind === new VaultConfigField.PendingVaultAdmin().kind || mode.kind === new VaultConfigField.Farm().kind) {
|
|
350
|
+
const newPubkey = new PublicKey(value);
|
|
351
|
+
const insertIntoLutIxs = await this.insertIntoLookupTableIxs(
|
|
352
|
+
vaultState.adminAuthority,
|
|
353
|
+
vaultState.vaultLookupTable,
|
|
354
|
+
[newPubkey]
|
|
355
|
+
);
|
|
356
|
+
updateLUTIxs.push(...insertIntoLutIxs);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const updateVaultConfigIxs: UpdateVaultConfigIxs = {
|
|
360
|
+
updateVaultConfigIx,
|
|
361
|
+
updateLUTIxs,
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
return updateVaultConfigIxs;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* This method updates the vault config for a vault that
|
|
369
|
+
* @param vault - address of vault to be updated
|
|
370
|
+
* @param mode - the field to be updated
|
|
371
|
+
* @param value - the new value for the field to be updated (number or pubkey)
|
|
372
|
+
* @returns - a list of instructions
|
|
373
|
+
*/
|
|
374
|
+
updateUninitialisedVaultConfigIx(
|
|
375
|
+
admin: PublicKey,
|
|
376
|
+
vault: PublicKey,
|
|
377
|
+
mode: VaultConfigFieldKind,
|
|
378
|
+
value: string
|
|
379
|
+
): TransactionInstruction {
|
|
380
|
+
const updateVaultConfigAccs: UpdateVaultConfigAccounts = {
|
|
381
|
+
adminAuthority: admin,
|
|
382
|
+
vaultState: vault,
|
|
383
|
+
klendProgram: this._kaminoLendProgramId,
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
const updateVaultConfigArgs: UpdateVaultConfigArgs = {
|
|
387
|
+
entry: mode,
|
|
388
|
+
data: Buffer.from([0]),
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
if (isNaN(+value)) {
|
|
392
|
+
if (mode.kind === new VaultConfigField.Name().kind) {
|
|
393
|
+
const data = Array.from(this.encodeVaultName(value));
|
|
394
|
+
updateVaultConfigArgs.data = Buffer.from(data);
|
|
395
|
+
} else {
|
|
396
|
+
const data = new PublicKey(value);
|
|
397
|
+
updateVaultConfigArgs.data = data.toBuffer();
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
const buffer = Buffer.alloc(8);
|
|
401
|
+
buffer.writeBigUInt64LE(BigInt(value.toString()));
|
|
402
|
+
updateVaultConfigArgs.data = buffer;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const updateVaultConfigIx = updateVaultConfig(
|
|
406
|
+
updateVaultConfigArgs,
|
|
407
|
+
updateVaultConfigAccs,
|
|
408
|
+
this._kaminoVaultProgramId
|
|
409
|
+
);
|
|
410
|
+
|
|
254
411
|
return updateVaultConfigIx;
|
|
255
412
|
}
|
|
256
413
|
|
|
@@ -259,7 +416,7 @@ export class KaminoVaultClient {
|
|
|
259
416
|
* @param vault - vault to change the ownership for
|
|
260
417
|
* @returns - an instruction to be used to be executed
|
|
261
418
|
*/
|
|
262
|
-
async
|
|
419
|
+
async acceptVaultOwnershipIxs(vault: KaminoVault): Promise<AcceptVaultOwnershipIxs> {
|
|
263
420
|
const vaultState: VaultState = await vault.getState(this.getConnection());
|
|
264
421
|
|
|
265
422
|
const acceptOwneshipAccounts: UpdateAdminAccounts = {
|
|
@@ -267,7 +424,39 @@ export class KaminoVaultClient {
|
|
|
267
424
|
vaultState: vault.address,
|
|
268
425
|
};
|
|
269
426
|
|
|
270
|
-
|
|
427
|
+
const acceptVaultOwnershipIx = updateAdmin(acceptOwneshipAccounts, this._kaminoVaultProgramId);
|
|
428
|
+
|
|
429
|
+
// read the current LUT and create a new one for the new admin and backfill it
|
|
430
|
+
const accountsInExistentLUT = (await this.getAccountsInLUT(vaultState.vaultLookupTable)).filter(
|
|
431
|
+
(account) => !account.equals(vaultState.adminAuthority)
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
const LUTIxs = [];
|
|
435
|
+
const [initNewLUTIx, newLUT] = this.getInitLookupTableIx(vaultState.pendingAdmin, await this._connection.getSlot());
|
|
436
|
+
LUTIxs.push(initNewLUTIx);
|
|
437
|
+
|
|
438
|
+
const insertIntoLUTIxs = await this.insertIntoLookupTableIxs(
|
|
439
|
+
vaultState.pendingAdmin,
|
|
440
|
+
newLUT,
|
|
441
|
+
accountsInExistentLUT
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
LUTIxs.push(...insertIntoLUTIxs);
|
|
445
|
+
|
|
446
|
+
const updateVaultConfigIxs = await this.updateVaultConfigIxs(
|
|
447
|
+
vault,
|
|
448
|
+
new VaultConfigField.LookupTable(),
|
|
449
|
+
newLUT.toString()
|
|
450
|
+
);
|
|
451
|
+
LUTIxs.push(updateVaultConfigIxs.updateVaultConfigIx);
|
|
452
|
+
LUTIxs.push(...updateVaultConfigIxs.updateLUTIxs);
|
|
453
|
+
|
|
454
|
+
const acceptVaultOwnershipIxs: AcceptVaultOwnershipIxs = {
|
|
455
|
+
acceptVaultOwnershipIx,
|
|
456
|
+
updateLUTIxs: LUTIxs,
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
return acceptVaultOwnershipIxs;
|
|
271
460
|
}
|
|
272
461
|
|
|
273
462
|
/**
|
|
@@ -429,7 +618,7 @@ export class KaminoVaultClient {
|
|
|
429
618
|
tokenMint: vaultState.tokenMint,
|
|
430
619
|
baseVaultAuthority: vaultState.baseVaultAuthority,
|
|
431
620
|
sharesMint: vaultState.sharesMint,
|
|
432
|
-
|
|
621
|
+
userTokenAta: userTokenAta,
|
|
433
622
|
userSharesAta: userSharesAta,
|
|
434
623
|
tokenProgram: tokenProgramID,
|
|
435
624
|
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
@@ -483,6 +672,57 @@ export class KaminoVaultClient {
|
|
|
483
672
|
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
484
673
|
): Promise<TransactionInstruction[]> {
|
|
485
674
|
const vaultState = await vault.getState(this._connection);
|
|
675
|
+
const kaminoVault = new KaminoVault(vault.address, vaultState, vault.programId);
|
|
676
|
+
|
|
677
|
+
// if the vault has allocations withdraw otherwise wtihdraw from available ix
|
|
678
|
+
const vaultAllocation = vaultState.vaultAllocationStrategy.find(
|
|
679
|
+
(allocation) => ~allocation.reserve.equals(PublicKey.default)
|
|
680
|
+
);
|
|
681
|
+
|
|
682
|
+
if (vaultAllocation) {
|
|
683
|
+
return this.wihdrdrawWithReserveIxns(user, kaminoVault, shareAmount, slot, vaultReservesMap);
|
|
684
|
+
} else {
|
|
685
|
+
return this.withdrawFromAvailableIxns(user, kaminoVault, shareAmount);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
private async withdrawFromAvailableIxns(
|
|
690
|
+
user: PublicKey,
|
|
691
|
+
vault: KaminoVault,
|
|
692
|
+
shareAmount: Decimal
|
|
693
|
+
): Promise<TransactionInstruction[]> {
|
|
694
|
+
const vaultState = await vault.getState(this._connection);
|
|
695
|
+
const kaminoVault = new KaminoVault(vault.address, vaultState, vault.programId);
|
|
696
|
+
|
|
697
|
+
const userSharesAta = getAssociatedTokenAddress(vaultState.sharesMint, user);
|
|
698
|
+
const [{ ata: userTokenAta, createAtaIx }] = createAtasIdempotent(user, [
|
|
699
|
+
{
|
|
700
|
+
mint: vaultState.tokenMint,
|
|
701
|
+
tokenProgram: vaultState.tokenProgram,
|
|
702
|
+
},
|
|
703
|
+
]);
|
|
704
|
+
|
|
705
|
+
const shareLamportsToWithdraw = collToLamportsDecimal(shareAmount, vaultState.sharesMintDecimals.toNumber());
|
|
706
|
+
const withdrawFromAvailableIxn = await this.withdrawFromAvailableIxn(
|
|
707
|
+
user,
|
|
708
|
+
kaminoVault,
|
|
709
|
+
vaultState,
|
|
710
|
+
userSharesAta,
|
|
711
|
+
userTokenAta,
|
|
712
|
+
shareLamportsToWithdraw
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
return [createAtaIx, withdrawFromAvailableIxn];
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
private async wihdrdrawWithReserveIxns(
|
|
719
|
+
user: PublicKey,
|
|
720
|
+
vault: KaminoVault,
|
|
721
|
+
shareAmount: Decimal,
|
|
722
|
+
slot: number,
|
|
723
|
+
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
724
|
+
): Promise<TransactionInstruction[]> {
|
|
725
|
+
const vaultState = await vault.getState(this._connection);
|
|
486
726
|
|
|
487
727
|
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
|
|
488
728
|
|
|
@@ -619,7 +859,6 @@ export class KaminoVaultClient {
|
|
|
619
859
|
payerTokenAccount: payerTokenAta,
|
|
620
860
|
tokenMint: vaultState.tokenMint,
|
|
621
861
|
reserveCollateralTokenProgram: TOKEN_PROGRAM_ID,
|
|
622
|
-
sharesTokenProgram: TOKEN_PROGRAM_ID,
|
|
623
862
|
};
|
|
624
863
|
|
|
625
864
|
const investIx = invest(investAccounts, this._kaminoVaultProgramId);
|
|
@@ -633,6 +872,21 @@ export class KaminoVaultClient {
|
|
|
633
872
|
return [createAtaIx, investIx];
|
|
634
873
|
}
|
|
635
874
|
|
|
875
|
+
encodeVaultName(token: string): Uint8Array {
|
|
876
|
+
const maxArray = new Uint8Array(40);
|
|
877
|
+
const s: Uint8Array = new TextEncoder().encode(token);
|
|
878
|
+
maxArray.set(s);
|
|
879
|
+
return maxArray;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
decodeVaultName(token: number[]): string {
|
|
883
|
+
const maxArray = new Uint8Array(token);
|
|
884
|
+
let s: string = new TextDecoder().decode(maxArray);
|
|
885
|
+
// Remove trailing zeros and spaces
|
|
886
|
+
s = s.replace(/[\0 ]+$/, '');
|
|
887
|
+
return s;
|
|
888
|
+
}
|
|
889
|
+
|
|
636
890
|
private withdrawIxn(
|
|
637
891
|
user: PublicKey,
|
|
638
892
|
vault: KaminoVault,
|
|
@@ -647,26 +901,30 @@ export class KaminoVaultClient {
|
|
|
647
901
|
const lendingMarketAuth = lendingMarketAuthPda(marketAddress, this._kaminoLendProgramId)[0];
|
|
648
902
|
|
|
649
903
|
const withdrawAccounts: WithdrawAccounts = {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
904
|
+
withdrawFromAvailable: {
|
|
905
|
+
user,
|
|
906
|
+
vaultState: vault.address,
|
|
907
|
+
tokenVault: vaultState.tokenVault,
|
|
908
|
+
baseVaultAuthority: vaultState.baseVaultAuthority,
|
|
909
|
+
userTokenAta: userTokenAta,
|
|
910
|
+
tokenMint: vaultState.tokenMint,
|
|
911
|
+
userSharesAta: userSharesAta,
|
|
912
|
+
sharesMint: vaultState.sharesMint,
|
|
913
|
+
tokenProgram: vaultState.tokenProgram,
|
|
914
|
+
sharesTokenProgram: TOKEN_PROGRAM_ID,
|
|
915
|
+
klendProgram: this._kaminoLendProgramId,
|
|
916
|
+
},
|
|
917
|
+
withdrawFromReserveAccounts: {
|
|
918
|
+
vaultState: vault.address,
|
|
919
|
+
reserve: reserve.address,
|
|
920
|
+
ctokenVault: getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId),
|
|
921
|
+
lendingMarket: marketAddress,
|
|
922
|
+
lendingMarketAuthority: lendingMarketAuth,
|
|
923
|
+
reserveLiquiditySupply: reserve.state.liquidity.supplyVault,
|
|
924
|
+
reserveCollateralMint: reserve.state.collateral.mintPubkey,
|
|
925
|
+
reserveCollateralTokenProgram: TOKEN_PROGRAM_ID,
|
|
926
|
+
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
927
|
+
},
|
|
670
928
|
};
|
|
671
929
|
|
|
672
930
|
const withdrawArgs: WithdrawArgs = {
|
|
@@ -699,6 +957,35 @@ export class KaminoVaultClient {
|
|
|
699
957
|
return withdrawIxn;
|
|
700
958
|
}
|
|
701
959
|
|
|
960
|
+
private async withdrawFromAvailableIxn(
|
|
961
|
+
user: PublicKey,
|
|
962
|
+
vault: KaminoVault,
|
|
963
|
+
vaultState: VaultState,
|
|
964
|
+
userSharesAta: PublicKey,
|
|
965
|
+
userTokenAta: PublicKey,
|
|
966
|
+
shareAmountLamports: Decimal
|
|
967
|
+
): Promise<TransactionInstruction> {
|
|
968
|
+
const withdrawFromAvailableAccounts: WithdrawFromAvailableAccounts = {
|
|
969
|
+
user,
|
|
970
|
+
vaultState: vault.address,
|
|
971
|
+
tokenVault: vaultState.tokenVault,
|
|
972
|
+
baseVaultAuthority: vaultState.baseVaultAuthority,
|
|
973
|
+
userTokenAta: userTokenAta,
|
|
974
|
+
tokenMint: vaultState.tokenMint,
|
|
975
|
+
userSharesAta: userSharesAta,
|
|
976
|
+
sharesMint: vaultState.sharesMint,
|
|
977
|
+
tokenProgram: vaultState.tokenProgram,
|
|
978
|
+
sharesTokenProgram: TOKEN_PROGRAM_ID,
|
|
979
|
+
klendProgram: this._kaminoLendProgramId,
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
const withdrawFromAvailableArgs: WithdrawFromAvailableArgs = {
|
|
983
|
+
sharesAmount: new BN(shareAmountLamports.toString()),
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
return withdrawFromAvailable(withdrawFromAvailableArgs, withdrawFromAvailableAccounts, this._kaminoVaultProgramId);
|
|
987
|
+
}
|
|
988
|
+
|
|
702
989
|
private async withdrawPendingFeesIxn(
|
|
703
990
|
vault: KaminoVault,
|
|
704
991
|
vaultState: VaultState,
|
|
@@ -726,7 +1013,6 @@ export class KaminoVaultClient {
|
|
|
726
1013
|
klendProgram: this._kaminoLendProgramId,
|
|
727
1014
|
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
728
1015
|
reserveCollateralTokenProgram: TOKEN_PROGRAM_ID,
|
|
729
|
-
sharesTokenProgram: TOKEN_PROGRAM_ID,
|
|
730
1016
|
};
|
|
731
1017
|
|
|
732
1018
|
const withdrawPendingFeesIxn = withdrawPendingFees(withdrawPendingFeesAccounts, this._kaminoVaultProgramId);
|
|
@@ -756,6 +1042,189 @@ export class KaminoVaultClient {
|
|
|
756
1042
|
return withdrawPendingFeesIxn;
|
|
757
1043
|
}
|
|
758
1044
|
|
|
1045
|
+
/**
|
|
1046
|
+
* Sync a vault for lookup table; create and set the LUT for the vault if needed and fill it with all the needed accounts
|
|
1047
|
+
* @param vault the vault to sync and set the LUT for if needed
|
|
1048
|
+
* @param vaultReserves optional; the state of the reserves in the vault allocation
|
|
1049
|
+
* @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
|
|
1050
|
+
*/
|
|
1051
|
+
async syncVaultLookupTable(
|
|
1052
|
+
vault: KaminoVault,
|
|
1053
|
+
vaultReserves?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
1054
|
+
): Promise<SyncVaultLUTIxs> {
|
|
1055
|
+
const vaultState = await vault.getState(this._connection);
|
|
1056
|
+
const allAccountsToBeInserted = [
|
|
1057
|
+
vault.address,
|
|
1058
|
+
vaultState.adminAuthority,
|
|
1059
|
+
vaultState.baseVaultAuthority,
|
|
1060
|
+
vaultState.tokenMint,
|
|
1061
|
+
vaultState.tokenVault,
|
|
1062
|
+
vaultState.sharesMint,
|
|
1063
|
+
vaultState.tokenProgram,
|
|
1064
|
+
this._kaminoLendProgramId,
|
|
1065
|
+
];
|
|
1066
|
+
|
|
1067
|
+
vaultState.vaultAllocationStrategy.forEach((allocation) => {
|
|
1068
|
+
allAccountsToBeInserted.push(allocation.reserve);
|
|
1069
|
+
allAccountsToBeInserted.push(allocation.ctokenVault);
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
if (vaultReserves) {
|
|
1073
|
+
vaultReserves.forEach((reserve) => {
|
|
1074
|
+
allAccountsToBeInserted.push(reserve.state.lendingMarket);
|
|
1075
|
+
allAccountsToBeInserted.push(reserve.state.farmCollateral);
|
|
1076
|
+
allAccountsToBeInserted.push(reserve.state.farmDebt);
|
|
1077
|
+
allAccountsToBeInserted.push(reserve.state.liquidity.supplyVault);
|
|
1078
|
+
allAccountsToBeInserted.push(reserve.state.liquidity.feeVault);
|
|
1079
|
+
allAccountsToBeInserted.push(reserve.state.collateral.mintPubkey);
|
|
1080
|
+
allAccountsToBeInserted.push(reserve.state.collateral.supplyVault);
|
|
1081
|
+
});
|
|
1082
|
+
} else {
|
|
1083
|
+
const vaultReservesState = await this.loadVaultReserves(vaultState);
|
|
1084
|
+
vaultReservesState.forEach((reserve) => {
|
|
1085
|
+
allAccountsToBeInserted.push(reserve.state.lendingMarket);
|
|
1086
|
+
allAccountsToBeInserted.push(reserve.state.farmCollateral);
|
|
1087
|
+
allAccountsToBeInserted.push(reserve.state.farmDebt);
|
|
1088
|
+
allAccountsToBeInserted.push(reserve.state.liquidity.supplyVault);
|
|
1089
|
+
allAccountsToBeInserted.push(reserve.state.liquidity.feeVault);
|
|
1090
|
+
allAccountsToBeInserted.push(reserve.state.collateral.mintPubkey);
|
|
1091
|
+
allAccountsToBeInserted.push(reserve.state.collateral.supplyVault);
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
if (!vaultState.vaultFarm.equals(PublicKey.default)) {
|
|
1096
|
+
allAccountsToBeInserted.push(vaultState.vaultFarm);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
const setupLUTIfNeededIxs: TransactionInstruction[] = [];
|
|
1100
|
+
let lut = vaultState.vaultLookupTable;
|
|
1101
|
+
if (lut.equals(PublicKey.default)) {
|
|
1102
|
+
const recentSlot = await this._connection.getSlot();
|
|
1103
|
+
const [ixn, address] = this.getInitLookupTableIx(vaultState.adminAuthority, recentSlot);
|
|
1104
|
+
setupLUTIfNeededIxs.push(ixn);
|
|
1105
|
+
lut = address;
|
|
1106
|
+
|
|
1107
|
+
// set the new LUT for the vault
|
|
1108
|
+
const updateVaultConfigIxs = await this.updateVaultConfigIxs(
|
|
1109
|
+
vault,
|
|
1110
|
+
new VaultConfigField.LookupTable(),
|
|
1111
|
+
lut.toString()
|
|
1112
|
+
);
|
|
1113
|
+
setupLUTIfNeededIxs.push(updateVaultConfigIxs.updateVaultConfigIx);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
const ixns: TransactionInstruction[] = [];
|
|
1117
|
+
let overridenExistentAccounts: PublicKey[] | undefined = undefined;
|
|
1118
|
+
if (vaultState.vaultLookupTable.equals(PublicKey.default)) {
|
|
1119
|
+
overridenExistentAccounts = [];
|
|
1120
|
+
}
|
|
1121
|
+
ixns.push(
|
|
1122
|
+
...(await this.insertIntoLookupTableIxs(
|
|
1123
|
+
vaultState.adminAuthority,
|
|
1124
|
+
lut,
|
|
1125
|
+
allAccountsToBeInserted,
|
|
1126
|
+
overridenExistentAccounts
|
|
1127
|
+
))
|
|
1128
|
+
);
|
|
1129
|
+
|
|
1130
|
+
return {
|
|
1131
|
+
setupLUTIfNeededIxs,
|
|
1132
|
+
syncLUTIxs: ixns,
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
getInitLookupTableIx(payer: PublicKey, slot: number): [TransactionInstruction, PublicKey] {
|
|
1137
|
+
const [ixn, address] = AddressLookupTableProgram.createLookupTable({
|
|
1138
|
+
authority: payer,
|
|
1139
|
+
payer,
|
|
1140
|
+
recentSlot: slot,
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1143
|
+
return [ixn, address];
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
getReserveAccountsToInsertInLut(reserveState: Reserve): PublicKey[] {
|
|
1147
|
+
return [
|
|
1148
|
+
reserveState.lendingMarket,
|
|
1149
|
+
reserveState.farmCollateral,
|
|
1150
|
+
reserveState.farmDebt,
|
|
1151
|
+
reserveState.liquidity.mintPubkey,
|
|
1152
|
+
reserveState.liquidity.supplyVault,
|
|
1153
|
+
reserveState.liquidity.feeVault,
|
|
1154
|
+
reserveState.collateral.mintPubkey,
|
|
1155
|
+
reserveState.collateral.supplyVault,
|
|
1156
|
+
];
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
async insertIntoLookupTableIxs(
|
|
1160
|
+
payer: PublicKey,
|
|
1161
|
+
lookupTable: PublicKey,
|
|
1162
|
+
keys: PublicKey[],
|
|
1163
|
+
accountsInLUT?: PublicKey[]
|
|
1164
|
+
): Promise<TransactionInstruction[]> {
|
|
1165
|
+
let lutContents = accountsInLUT;
|
|
1166
|
+
if (!accountsInLUT) {
|
|
1167
|
+
lutContents = await this.getAccountsInLUT(lookupTable);
|
|
1168
|
+
} else {
|
|
1169
|
+
lutContents = accountsInLUT;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
const missingAccounts = keys.filter((key) => !lutContents!.includes(key) && !key.equals(PublicKey.default));
|
|
1173
|
+
// deduplicate missing accounts and remove default accounts and convert it back to an array
|
|
1174
|
+
const missingAccountsList = new PublicKeySet(missingAccounts).toArray();
|
|
1175
|
+
|
|
1176
|
+
const chunkSize = 20;
|
|
1177
|
+
const ixns: TransactionInstruction[] = [];
|
|
1178
|
+
|
|
1179
|
+
for (let i = 0; i < missingAccountsList.length; i += chunkSize) {
|
|
1180
|
+
const chunk = missingAccountsList.slice(i, i + chunkSize);
|
|
1181
|
+
const ixn = AddressLookupTableProgram.extendLookupTable({
|
|
1182
|
+
lookupTable,
|
|
1183
|
+
authority: payer,
|
|
1184
|
+
payer,
|
|
1185
|
+
addresses: chunk,
|
|
1186
|
+
});
|
|
1187
|
+
ixns.push(ixn);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
return ixns;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
*
|
|
1195
|
+
* @param connection
|
|
1196
|
+
* @param lookupTable
|
|
1197
|
+
* @returns
|
|
1198
|
+
*/
|
|
1199
|
+
async getAccountsInLUT(lookupTable: PublicKey): Promise<PublicKey[]> {
|
|
1200
|
+
const lutState = await this._connection.getAddressLookupTable(lookupTable);
|
|
1201
|
+
if (!lutState || !lutState.value) {
|
|
1202
|
+
throw new Error(`Lookup table ${lookupTable} not found`);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
return lutState.value.state.addresses;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
deactivateLookupTableIx(payer: PublicKey, lookupTable: PublicKey): TransactionInstruction {
|
|
1209
|
+
const ixn = AddressLookupTableProgram.deactivateLookupTable({
|
|
1210
|
+
authority: payer,
|
|
1211
|
+
lookupTable: lookupTable,
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
return ixn;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/// this require the LUT to be deactivated at least 500 blocks before
|
|
1218
|
+
closeLookupTableIx(payer: PublicKey, lookupTable: PublicKey): TransactionInstruction {
|
|
1219
|
+
const ixn = AddressLookupTableProgram.closeLookupTable({
|
|
1220
|
+
authority: payer,
|
|
1221
|
+
recipient: payer,
|
|
1222
|
+
lookupTable: lookupTable,
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
return ixn;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
759
1228
|
/**
|
|
760
1229
|
* This method returns the user shares balance for a given vault
|
|
761
1230
|
* @param user - user to calculate the shares balance for
|
|
@@ -952,7 +1421,7 @@ export class KaminoVaultClient {
|
|
|
952
1421
|
throw new Error(`Reserve ${reserve.address.toBase58()} not found in vault allocation strategy`);
|
|
953
1422
|
}
|
|
954
1423
|
|
|
955
|
-
const reserveAllocationLiquidityAmountLamports = new Decimal(reserveAllocation.
|
|
1424
|
+
const reserveAllocationLiquidityAmountLamports = new Decimal(reserveAllocation.ctokenAllocation.toString()).div(
|
|
956
1425
|
reserveCollExchangeRate
|
|
957
1426
|
);
|
|
958
1427
|
const reserveAllocationLiquidityAmount = lamportsToDecimal(
|
|
@@ -1016,7 +1485,7 @@ export class KaminoVaultClient {
|
|
|
1016
1485
|
.floor()
|
|
1017
1486
|
.toNumber()
|
|
1018
1487
|
);
|
|
1019
|
-
const reserveAllocationLiquidityAmount = new Decimal(allocationStrategy.
|
|
1488
|
+
const reserveAllocationLiquidityAmount = new Decimal(allocationStrategy.ctokenAllocation.toString()).div(
|
|
1020
1489
|
reserveCollExchangeRate
|
|
1021
1490
|
);
|
|
1022
1491
|
const reserveAvailableLiquidityAmount = reserve.getLiquidityAvailableAmount();
|
|
@@ -1195,7 +1664,7 @@ export class KaminoVaultClient {
|
|
|
1195
1664
|
}
|
|
1196
1665
|
|
|
1197
1666
|
const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0);
|
|
1198
|
-
const reserveAllocationLiquidityAmount = new Decimal(allocationStrategy.
|
|
1667
|
+
const reserveAllocationLiquidityAmount = new Decimal(allocationStrategy.ctokenAllocation.toString()).div(
|
|
1199
1668
|
reserveCollExchangeRate
|
|
1200
1669
|
);
|
|
1201
1670
|
|
|
@@ -1332,7 +1801,7 @@ export class KaminoVaultClient {
|
|
|
1332
1801
|
}
|
|
1333
1802
|
|
|
1334
1803
|
const reserveCollExchangeRate = reserve.getEstimatedCollateralExchangeRate(slot, 0);
|
|
1335
|
-
const reserveAllocationLiquidityAmountLamports = new Decimal(allocationStrategy.
|
|
1804
|
+
const reserveAllocationLiquidityAmountLamports = new Decimal(allocationStrategy.ctokenAllocation.toString()).div(
|
|
1336
1805
|
reserveCollExchangeRate
|
|
1337
1806
|
);
|
|
1338
1807
|
const reserveAllocationLiquidityAmount = lamportsToDecimal(
|
|
@@ -1435,12 +1904,12 @@ export class KaminoVaultClient {
|
|
|
1435
1904
|
}
|
|
1436
1905
|
|
|
1437
1906
|
/**
|
|
1438
|
-
* Retrive the total amount of
|
|
1907
|
+
* Retrive the total amount of interest earned by the vault since its inception, including what was charged as fees
|
|
1439
1908
|
* @param vaultState the kamino vault state to get total net yield for
|
|
1440
|
-
* @returns a decimal representing the net number of tokens earned by the vault since its inception
|
|
1909
|
+
* @returns a decimal representing the net number of tokens earned by the vault since its inception
|
|
1441
1910
|
*/
|
|
1442
|
-
async
|
|
1443
|
-
const netYieldLamports = new Fraction(vaultState.
|
|
1911
|
+
async getVaultCumulativeInterest(vaultState: VaultState) {
|
|
1912
|
+
const netYieldLamports = new Fraction(vaultState.cumulativeEarnedInterestSf).toDecimal();
|
|
1444
1913
|
return lamportsToDecimal(netYieldLamports, vaultState.tokenMintDecimals.toString());
|
|
1445
1914
|
}
|
|
1446
1915
|
} // KaminoVaultClient
|
|
@@ -1492,6 +1961,8 @@ export class KaminoVaultConfig {
|
|
|
1492
1961
|
readonly performanceFeeRate: Decimal;
|
|
1493
1962
|
/** The management fee rate of the vault, expressed as a decimal */
|
|
1494
1963
|
readonly managementFeeRate: Decimal;
|
|
1964
|
+
/** The name to be stored on cain for the vault (max 40 characters). */
|
|
1965
|
+
readonly name: string;
|
|
1495
1966
|
|
|
1496
1967
|
constructor(args: {
|
|
1497
1968
|
admin: PublicKey;
|
|
@@ -1499,20 +1970,22 @@ export class KaminoVaultConfig {
|
|
|
1499
1970
|
tokenMintProgramId: PublicKey;
|
|
1500
1971
|
performanceFeeRate: Decimal;
|
|
1501
1972
|
managementFeeRate: Decimal;
|
|
1973
|
+
name: string;
|
|
1502
1974
|
}) {
|
|
1503
1975
|
this.admin = args.admin;
|
|
1504
1976
|
this.tokenMint = args.tokenMint;
|
|
1505
1977
|
this.performanceFeeRate = args.performanceFeeRate;
|
|
1506
1978
|
this.managementFeeRate = args.managementFeeRate;
|
|
1507
1979
|
this.tokenMintProgramId = args.tokenMintProgramId;
|
|
1980
|
+
this.name = args.name;
|
|
1508
1981
|
}
|
|
1509
1982
|
|
|
1510
1983
|
getPerformanceFeeBps(): number {
|
|
1511
|
-
return this.performanceFeeRate.mul(
|
|
1984
|
+
return this.performanceFeeRate.mul(100).toNumber();
|
|
1512
1985
|
}
|
|
1513
1986
|
|
|
1514
|
-
|
|
1515
|
-
return this.managementFeeRate.mul(
|
|
1987
|
+
getManagementFeeBps(): number {
|
|
1988
|
+
return this.managementFeeRate.mul(100).toNumber();
|
|
1516
1989
|
}
|
|
1517
1990
|
}
|
|
1518
1991
|
|