@kamino-finance/klend-sdk 7.3.7 → 7.3.9
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/action.d.ts.map +1 -1
- package/dist/classes/action.js +7 -19
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/vault.d.ts +28 -1
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +103 -6
- package/dist/classes/vault.js.map +1 -1
- package/dist/classes/vault_types.d.ts +2 -1
- package/dist/classes/vault_types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/classes/action.ts +13 -23
- package/src/classes/vault.ts +160 -7
- package/src/classes/vault_types.ts +2 -1
package/src/classes/vault.ts
CHANGED
|
@@ -123,7 +123,13 @@ import {
|
|
|
123
123
|
} from './vault_types';
|
|
124
124
|
import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
|
|
125
125
|
import { FullBPSDecimal } from '@kamino-finance/kliquidity-sdk/dist/utils/CreationParameters';
|
|
126
|
-
import {
|
|
126
|
+
import {
|
|
127
|
+
FarmConfigOption,
|
|
128
|
+
FarmIncentives,
|
|
129
|
+
FarmState,
|
|
130
|
+
getUserStatePDA,
|
|
131
|
+
scaleDownWads,
|
|
132
|
+
} from '@kamino-finance/farms-sdk/dist';
|
|
127
133
|
import { getAccountsInLut, initLookupTableIx, insertIntoLookupTableIxs } from '../utils/lookupTable';
|
|
128
134
|
import {
|
|
129
135
|
FARMS_ADMIN_MAINNET,
|
|
@@ -843,6 +849,8 @@ export class KaminoVaultClient {
|
|
|
843
849
|
data: this.getValueForModeAsBuffer(mode, value),
|
|
844
850
|
};
|
|
845
851
|
|
|
852
|
+
await this.updateVaultConfigValidations(mode, value, vaultState);
|
|
853
|
+
|
|
846
854
|
const vaultReserves = this.getVaultReserves(vaultState);
|
|
847
855
|
const vaultReservesState = await this.loadVaultReserves(vaultState);
|
|
848
856
|
|
|
@@ -906,6 +914,24 @@ export class KaminoVaultClient {
|
|
|
906
914
|
return updateVaultConfigIxs;
|
|
907
915
|
}
|
|
908
916
|
|
|
917
|
+
async updateVaultConfigValidations(mode: VaultConfigFieldKind, value: string, vaultState: VaultState) {
|
|
918
|
+
if (
|
|
919
|
+
mode.kind === new VaultConfigField.FirstLossCapitalFarm().kind ||
|
|
920
|
+
mode.kind === new VaultConfigField.Farm().kind
|
|
921
|
+
) {
|
|
922
|
+
const farmAddress = address(value);
|
|
923
|
+
const farmState = await FarmState.fetch(this.getConnection(), farmAddress);
|
|
924
|
+
if (!farmState) {
|
|
925
|
+
throw new Error(`Farm ${farmAddress.toString()} not found for FirstLossCapitalFarm`);
|
|
926
|
+
}
|
|
927
|
+
if (
|
|
928
|
+
mode.kind === new VaultConfigField.FirstLossCapitalFarm().kind &&
|
|
929
|
+
!(await this.isFlcFarmValid(farmState, vaultState))
|
|
930
|
+
) {
|
|
931
|
+
throw new Error(`Farm ${farmAddress.toString()} is not valid for FirstLossCapitalFarm`);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
909
935
|
/**
|
|
910
936
|
* Add or update a reserve whitelist entry. This controls whether the reserve is whitelisted for adding/updating
|
|
911
937
|
* allocations or for invest, depending on the mode parameter.
|
|
@@ -1199,7 +1225,7 @@ export class KaminoVaultClient {
|
|
|
1199
1225
|
* @param tokenAmount - token amount to be deposited, in decimals (will be converted in lamports)
|
|
1200
1226
|
* @param [vaultReservesMap] - optional parameter; a hashmap from each reserve pubkey to the reserve state. Optional. If provided the function will be significantly faster as it will not have to fetch the reserves
|
|
1201
1227
|
* @param [farmState] - the state of the vault farm, if the vault has a farm. Optional. If not provided, it will be fetched
|
|
1202
|
-
* @returns - an instance of DepositIxs which contains the instructions to deposit in vault and the instructions to stake the shares in the farm if the vault has a farm
|
|
1228
|
+
* @returns - an instance of DepositIxs which contains the instructions to deposit in vault and the instructions to stake the shares in the farm if the vault has a farm as well as ixs to stake in the first loss capital farm if the vault has one - only one set on ixs so stake in a farm can be used -> staking can be either done in the farm or in the first loss capital farm
|
|
1203
1229
|
*/
|
|
1204
1230
|
async depositIxs(
|
|
1205
1231
|
user: TransactionSigner,
|
|
@@ -1313,14 +1339,17 @@ export class KaminoVaultClient {
|
|
|
1313
1339
|
const result: DepositIxs = {
|
|
1314
1340
|
depositIxs: [...createAtasIxs, entryIx, ...closeAtasIxs],
|
|
1315
1341
|
stakeInFarmIfNeededIxs: [],
|
|
1342
|
+
stakeInFlcFarmIfNeededIxs: [],
|
|
1316
1343
|
};
|
|
1317
1344
|
|
|
1318
|
-
if (
|
|
1319
|
-
|
|
1345
|
+
if (await vault.hasFarm()) {
|
|
1346
|
+
const stakeSharesIxs = await this.stakeSharesIxs(user, vault, undefined, farmState);
|
|
1347
|
+
result.stakeInFarmIfNeededIxs = stakeSharesIxs;
|
|
1348
|
+
}
|
|
1349
|
+
if (await vault.hasFlcFarm()) {
|
|
1350
|
+
const stakeSharesInFlcFarmIxs = await this.stakeSharesInFlcFarmIxs(user, vault, undefined, undefined);
|
|
1351
|
+
result.stakeInFlcFarmIfNeededIxs = stakeSharesInFlcFarmIxs;
|
|
1320
1352
|
}
|
|
1321
|
-
|
|
1322
|
-
const stakeSharesIxs = await this.stakeSharesIxs(user, vault, undefined, farmState);
|
|
1323
|
-
result.stakeInFarmIfNeededIxs = stakeSharesIxs;
|
|
1324
1353
|
return result;
|
|
1325
1354
|
}
|
|
1326
1355
|
|
|
@@ -1354,6 +1383,42 @@ export class KaminoVaultClient {
|
|
|
1354
1383
|
return getFarmStakeIxs(this.getConnection(), user, sharesToStakeLamports, vaultState.vaultFarm, farmState);
|
|
1355
1384
|
}
|
|
1356
1385
|
|
|
1386
|
+
/**
|
|
1387
|
+
* This function creates instructions to stake the shares in the vault firstLossCapital farm if the vault has a farm
|
|
1388
|
+
* @param user - user to stake
|
|
1389
|
+
* @param vault - vault to deposit into its flc farm (if the state is not provided, it will be fetched)
|
|
1390
|
+
* @param [sharesAmount] - token amount to be deposited, in decimals (will be converted in lamports). Optional. If not provided, the user's share balance will be used
|
|
1391
|
+
* @param [farmState] - the state of the vault flc farm, if the vault has a farm. Optional. If not provided, it will be fetched
|
|
1392
|
+
* @returns - a list of instructions for the user to stake shares into the vault's firstLossCapital farm, including the creation of prerequisite accounts if needed
|
|
1393
|
+
*/
|
|
1394
|
+
async stakeSharesInFlcFarmIxs(
|
|
1395
|
+
user: TransactionSigner,
|
|
1396
|
+
vault: KaminoVault,
|
|
1397
|
+
sharesAmount?: Decimal,
|
|
1398
|
+
farmState?: FarmState
|
|
1399
|
+
): Promise<Instruction[]> {
|
|
1400
|
+
const vaultState = await vault.getState();
|
|
1401
|
+
|
|
1402
|
+
let sharesToStakeLamports = new Decimal(U64_MAX);
|
|
1403
|
+
if (sharesAmount) {
|
|
1404
|
+
sharesToStakeLamports = numberToLamportsDecimal(sharesAmount, vaultState.sharesMintDecimals.toNumber());
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// if tokens to be staked are 0 or vault has no farm there is no stake needed
|
|
1408
|
+
if (sharesToStakeLamports.lte(0) || !(await vault.hasFlcFarm())) {
|
|
1409
|
+
return [];
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// returns the ix to create the farm state account if needed and the ix to stake the shares
|
|
1413
|
+
return getFarmStakeIxs(
|
|
1414
|
+
this.getConnection(),
|
|
1415
|
+
user,
|
|
1416
|
+
sharesToStakeLamports,
|
|
1417
|
+
vaultState.firstLossCapitalFarm,
|
|
1418
|
+
farmState
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1357
1422
|
/**
|
|
1358
1423
|
* This function will return a struct with the instructions to unstake from the farm if necessary and the instructions for the missing ATA creation instructions, as well as one or multiple withdraw instructions, based on how many reserves it's needed to withdraw from. This might have to be split in multiple transactions
|
|
1359
1424
|
* @param user - user to withdraw
|
|
@@ -3096,6 +3161,7 @@ export class KaminoVaultClient {
|
|
|
3096
3161
|
slotForOverview,
|
|
3097
3162
|
tokensPrices
|
|
3098
3163
|
);
|
|
3164
|
+
const vaultFlcFarmStatsPromise = this.getVaultFlcFarmStats(vault);
|
|
3099
3165
|
|
|
3100
3166
|
// all the async part of the functions above just read the vaultReservesState which is read beforehand, so excepting vaultCollateralsPromise they should do no additional network calls
|
|
3101
3167
|
const [
|
|
@@ -3108,6 +3174,7 @@ export class KaminoVaultClient {
|
|
|
3108
3174
|
vaultFarmIncentives,
|
|
3109
3175
|
vaultReservesFarmIncentives,
|
|
3110
3176
|
vaultDelegatedFarmIncentives,
|
|
3177
|
+
vaultFlcFarmStats,
|
|
3111
3178
|
] = await Promise.all([
|
|
3112
3179
|
vaultHoldingsWithUSDValuePromise,
|
|
3113
3180
|
vaultTheoreticalAPYPromise,
|
|
@@ -3118,6 +3185,7 @@ export class KaminoVaultClient {
|
|
|
3118
3185
|
vaultFarmIncentivesPromise,
|
|
3119
3186
|
vaultReservesFarmIncentivesPromise,
|
|
3120
3187
|
vaultDelegatedFarmIncentivesPromise,
|
|
3188
|
+
vaultFlcFarmStatsPromise,
|
|
3121
3189
|
]);
|
|
3122
3190
|
|
|
3123
3191
|
return {
|
|
@@ -3134,6 +3202,7 @@ export class KaminoVaultClient {
|
|
|
3134
3202
|
utilizationRatio: totalInvestedAndBorrowed.utilizationRatio,
|
|
3135
3203
|
totalSupplied: totalInvestedAndBorrowed.totalInvested,
|
|
3136
3204
|
totalSuppliedUSD: totalInvestedAndBorrowed.totalInvested.mul(vaultTokenPrice),
|
|
3205
|
+
flcFarmStats: vaultFlcFarmStats,
|
|
3137
3206
|
};
|
|
3138
3207
|
}
|
|
3139
3208
|
|
|
@@ -3774,6 +3843,69 @@ export class KaminoVaultClient {
|
|
|
3774
3843
|
};
|
|
3775
3844
|
}
|
|
3776
3845
|
|
|
3846
|
+
async getVaultFlcFarmStats(vaultOrState: KaminoVault | VaultState): Promise<FlcFarmStats | undefined> {
|
|
3847
|
+
const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState() : vaultOrState;
|
|
3848
|
+
|
|
3849
|
+
if (vaultState.firstLossCapitalFarm === DEFAULT_PUBLIC_KEY) {
|
|
3850
|
+
return undefined;
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3853
|
+
const kFarmsClient = new Farms(this.getConnection());
|
|
3854
|
+
|
|
3855
|
+
const flcFarmState = await FarmState.fetch(this.getConnection(), vaultState.firstLossCapitalFarm);
|
|
3856
|
+
|
|
3857
|
+
if (!flcFarmState) {
|
|
3858
|
+
return undefined;
|
|
3859
|
+
}
|
|
3860
|
+
|
|
3861
|
+
if (!(await this.isFlcFarmValid(flcFarmState, vaultState))) {
|
|
3862
|
+
return undefined;
|
|
3863
|
+
}
|
|
3864
|
+
|
|
3865
|
+
const userStates = await kFarmsClient.getAllUserStatesForFarm(vaultState.firstLossCapitalFarm);
|
|
3866
|
+
const pendingUnstakes: FarmPendingUnstakeInfo[] = [];
|
|
3867
|
+
|
|
3868
|
+
for (const { userState, key } of userStates) {
|
|
3869
|
+
const pendingWithdrawalUnstake = new Decimal(scaleDownWads(userState.pendingWithdrawalUnstakeScaled));
|
|
3870
|
+
if (pendingWithdrawalUnstake.gt(0)) {
|
|
3871
|
+
pendingUnstakes.push({
|
|
3872
|
+
userStateAddress: key,
|
|
3873
|
+
pendingUnstakeAmountLamports: pendingWithdrawalUnstake,
|
|
3874
|
+
pendingUnstakeAvailableAtTimestamp: userState.pendingWithdrawalUnstakeTs.toNumber(),
|
|
3875
|
+
});
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
|
|
3879
|
+
return {
|
|
3880
|
+
address: vaultState.firstLossCapitalFarm,
|
|
3881
|
+
farmState: flcFarmState,
|
|
3882
|
+
totalStakedShares: new Decimal(scaleDownWads(flcFarmState.totalActiveStakeScaled)),
|
|
3883
|
+
withdrawalCooldownDurationSeconds: flcFarmState.withdrawalCooldownPeriod,
|
|
3884
|
+
isPendingUnstake: pendingUnstakes.length > 0,
|
|
3885
|
+
pendingUnstakeInfo: pendingUnstakes,
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
async isFlcFarmValid(flcFarmState: FarmState, vaultOrState: KaminoVault | VaultState): Promise<boolean> {
|
|
3890
|
+
const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState() : vaultOrState;
|
|
3891
|
+
|
|
3892
|
+
if (flcFarmState.timeUnit !== 0) {
|
|
3893
|
+
// timeUnit = 0 -> seconds
|
|
3894
|
+
return false;
|
|
3895
|
+
}
|
|
3896
|
+
|
|
3897
|
+
if (flcFarmState.withdrawalCooldownPeriod === 0) {
|
|
3898
|
+
// invalid FLC farm, should have > 0 withdrawal cooldown
|
|
3899
|
+
return false;
|
|
3900
|
+
}
|
|
3901
|
+
|
|
3902
|
+
if (flcFarmState.token.mint !== vaultState.sharesMint) {
|
|
3903
|
+
// staked token mint should be the vault shares mint
|
|
3904
|
+
return false;
|
|
3905
|
+
}
|
|
3906
|
+
return true;
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3777
3909
|
/// reads the pending rewards for a user in the vault farm
|
|
3778
3910
|
/// @param user - the user address
|
|
3779
3911
|
/// @param vault - the vault
|
|
@@ -4203,6 +4335,11 @@ export class KaminoVault {
|
|
|
4203
4335
|
return state.vaultFarm !== DEFAULT_PUBLIC_KEY;
|
|
4204
4336
|
}
|
|
4205
4337
|
|
|
4338
|
+
async hasFlcFarm(): Promise<boolean> {
|
|
4339
|
+
const state = await this.getState();
|
|
4340
|
+
return state.firstLossCapitalFarm !== DEFAULT_PUBLIC_KEY;
|
|
4341
|
+
}
|
|
4342
|
+
|
|
4206
4343
|
/**
|
|
4207
4344
|
* This will return an VaultHoldings object which contains the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve
|
|
4208
4345
|
* @returns an VaultHoldings object representing the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve
|
|
@@ -4579,6 +4716,7 @@ export type VaultOverview = {
|
|
|
4579
4716
|
totalSupplied: Decimal;
|
|
4580
4717
|
totalSuppliedUSD: Decimal;
|
|
4581
4718
|
utilizationRatio: Decimal;
|
|
4719
|
+
flcFarmStats: FlcFarmStats | undefined;
|
|
4582
4720
|
};
|
|
4583
4721
|
|
|
4584
4722
|
export type VaultReservesFarmsIncentives = {
|
|
@@ -4586,6 +4724,21 @@ export type VaultReservesFarmsIncentives = {
|
|
|
4586
4724
|
totalIncentivesAPY: Decimal;
|
|
4587
4725
|
};
|
|
4588
4726
|
|
|
4727
|
+
export type FlcFarmStats = {
|
|
4728
|
+
address: Address;
|
|
4729
|
+
farmState: FarmState;
|
|
4730
|
+
totalStakedShares: Decimal;
|
|
4731
|
+
withdrawalCooldownDurationSeconds: number;
|
|
4732
|
+
isPendingUnstake: boolean;
|
|
4733
|
+
pendingUnstakeInfo: FarmPendingUnstakeInfo[];
|
|
4734
|
+
};
|
|
4735
|
+
|
|
4736
|
+
export type FarmPendingUnstakeInfo = {
|
|
4737
|
+
userStateAddress: Address;
|
|
4738
|
+
pendingUnstakeAmountLamports: Decimal;
|
|
4739
|
+
pendingUnstakeAvailableAtTimestamp: number;
|
|
4740
|
+
};
|
|
4741
|
+
|
|
4589
4742
|
export type VaultFeesPct = {
|
|
4590
4743
|
managementFeePct: Decimal;
|
|
4591
4744
|
performanceFeePct: Decimal;
|
|
@@ -50,10 +50,11 @@ export type SyncVaultLUTIxs = {
|
|
|
50
50
|
syncLUTIxs: Instruction[];
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
/** If the stakeInFarmIfNeededIxs exist they have to be executed after the deposit so the shares received from the deposit are staked in the vault farm */
|
|
53
|
+
/** If the stakeInFarmIfNeededIxs/stakeInFlcFarmIfNeededIxs exist they have to be executed after the deposit so the shares received from the deposit are staked in the vault farm. Only one of the stake ixs can be executed, either for the vault farms or the first loss capital farm*/
|
|
54
54
|
export type DepositIxs = {
|
|
55
55
|
depositIxs: Instruction[];
|
|
56
56
|
stakeInFarmIfNeededIxs: Instruction[];
|
|
57
|
+
stakeInFlcFarmIfNeededIxs: Instruction[]; // if the vault has a firstLossCapital farm, these ixs will stake the shares in the flc farm
|
|
57
58
|
};
|
|
58
59
|
|
|
59
60
|
/** the ixs to unstake shares from farm and withdraw them from the vault. The `unstakeFromFarmIfNeededIxs` should be in the tx before `withdrawIxs`*/
|