@kamino-finance/klend-sdk 7.0.3 → 7.0.4
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 +12 -9
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +13 -47
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/vault.d.ts +15 -6
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +66 -20
- package/dist/classes/vault.js.map +1 -1
- package/dist/client/commands/initFarmsForReserve.d.ts.map +1 -1
- package/dist/client/commands/initFarmsForReserve.js +1 -2
- package/dist/client/commands/initFarmsForReserve.js.map +1 -1
- package/dist/manager/client_kamino_manager.js +4 -0
- package/dist/manager/client_kamino_manager.js.map +1 -1
- package/dist/utils/farmUtils.d.ts +10 -0
- package/dist/utils/farmUtils.d.ts.map +1 -0
- package/dist/utils/farmUtils.js +41 -0
- package/dist/utils/farmUtils.js.map +1 -0
- package/package.json +1 -1
- package/src/classes/manager.ts +30 -64
- package/src/classes/vault.ts +111 -22
- package/src/client/commands/initFarmsForReserve.ts +1 -1
- package/src/manager/client_kamino_manager.ts +4 -0
- package/src/utils/farmUtils.ts +73 -0
package/src/classes/vault.ts
CHANGED
|
@@ -125,6 +125,7 @@ import { getExtendLookupTableInstruction } from '@solana-program/address-lookup-
|
|
|
125
125
|
import { Farms } from '@kamino-finance/farms-sdk';
|
|
126
126
|
import { getFarmIncentives } from '@kamino-finance/farms-sdk/dist/utils/apy';
|
|
127
127
|
import { computeReservesAllocation } from '../utils/vaultAllocation';
|
|
128
|
+
import { getReserveFarmRewardsAPY } from '../utils/farmUtils';
|
|
128
129
|
|
|
129
130
|
export const kaminoVaultId = address('KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd');
|
|
130
131
|
export const kaminoVaultStagingId = address('stKvQfwRsQiKnLtMNVLHKS3exFJmZFsgfzBPWHECUYK');
|
|
@@ -2065,19 +2066,21 @@ export class KaminoVaultClient {
|
|
|
2065
2066
|
|
|
2066
2067
|
/**
|
|
2067
2068
|
* This method calculates the token per share value. This will always change based on interest earned from the vault, but calculating it requires a bunch of rpc requests. Caching this for a short duration would be optimal
|
|
2068
|
-
* @param
|
|
2069
|
+
* @param vaultState - vault state to calculate tokensPerShare for
|
|
2069
2070
|
* @param [slot] - the slot at which we retrieve the tokens per share. Optional. If not provided, the function will fetch the current slot
|
|
2070
2071
|
* @param [vaultReservesMap] - 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
|
|
2071
2072
|
* @param [currentSlot] - the latest confirmed slot. Optional. If provided the function will be faster as it will not have to fetch the latest slot
|
|
2072
2073
|
* @returns - token per share value
|
|
2073
2074
|
*/
|
|
2074
2075
|
async getTokensPerShareSingleVault(
|
|
2075
|
-
|
|
2076
|
+
vaultOrState: KaminoVault | VaultState,
|
|
2076
2077
|
slot?: Slot,
|
|
2077
2078
|
vaultReservesMap?: Map<Address, KaminoReserve>,
|
|
2078
2079
|
currentSlot?: Slot
|
|
2079
2080
|
): Promise<Decimal> {
|
|
2080
|
-
|
|
2081
|
+
// Determine if we have a KaminoVault or VaultState
|
|
2082
|
+
const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState(this.getConnection()) : vaultOrState;
|
|
2083
|
+
|
|
2081
2084
|
if (vaultState.sharesIssued.isZero()) {
|
|
2082
2085
|
return new Decimal(0);
|
|
2083
2086
|
}
|
|
@@ -2649,16 +2652,16 @@ export class KaminoVaultClient {
|
|
|
2649
2652
|
/**
|
|
2650
2653
|
* This will return an VaultOverview object that encapsulates all the information about the vault, including the holdings, reserves details, theoretical APY, utilization ratio and total borrowed amount
|
|
2651
2654
|
* @param vault - the kamino vault to get available liquidity to withdraw for
|
|
2652
|
-
* @param
|
|
2655
|
+
* @param vaultTokenPrice - the price of the token in the vault (e.g. USDC)
|
|
2653
2656
|
* @param [slot] - the slot for which to retrieve the vault overview for. Optional. If not provided the function will fetch the current slot
|
|
2654
2657
|
* @param [vaultReservesMap] - 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
|
|
2655
2658
|
* @param [kaminoMarkets] - a list of all kamino markets. Optional. If provided the function will be significantly faster as it will not have to fetch the markets
|
|
2656
2659
|
* @param [currentSlot] - the latest confirmed slot. Optional. If provided the function will be faster as it will not have to fetch the latest slot
|
|
2657
|
-
* @returns an VaultOverview object with details about the tokens available and invested in the vault, denominated in tokens and USD
|
|
2660
|
+
* @returns an VaultOverview object with details about the tokens available and invested in the vault, denominated in tokens and USD, along sie APYs
|
|
2658
2661
|
*/
|
|
2659
2662
|
async getVaultOverview(
|
|
2660
2663
|
vault: VaultState,
|
|
2661
|
-
|
|
2664
|
+
vaultTokenPrice: Decimal,
|
|
2662
2665
|
slot?: Slot,
|
|
2663
2666
|
vaultReservesMap?: Map<Address, KaminoReserve>,
|
|
2664
2667
|
kaminoMarkets?: KaminoMarket[],
|
|
@@ -2666,30 +2669,34 @@ export class KaminoVaultClient {
|
|
|
2666
2669
|
): Promise<VaultOverview> {
|
|
2667
2670
|
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vault);
|
|
2668
2671
|
|
|
2669
|
-
const vaultHoldingsWithUSDValuePromise =
|
|
2672
|
+
const vaultHoldingsWithUSDValuePromise = this.getVaultHoldingsWithPrice(
|
|
2670
2673
|
vault,
|
|
2671
|
-
|
|
2674
|
+
vaultTokenPrice,
|
|
2672
2675
|
slot,
|
|
2673
2676
|
vaultReservesState,
|
|
2674
2677
|
currentSlot
|
|
2675
2678
|
);
|
|
2676
2679
|
|
|
2677
2680
|
const slotForOverview = slot ? slot : await this.getConnection().getSlot().send();
|
|
2681
|
+
const farmsClient = new Farms(this.getConnection());
|
|
2678
2682
|
|
|
2679
|
-
const vaultTheoreticalAPYPromise =
|
|
2680
|
-
const vaultActualAPYPromise =
|
|
2681
|
-
const totalInvestedAndBorrowedPromise =
|
|
2683
|
+
const vaultTheoreticalAPYPromise = this.getVaultTheoreticalAPY(vault, slotForOverview, vaultReservesState);
|
|
2684
|
+
const vaultActualAPYPromise = this.getVaultActualAPY(vault, slotForOverview, vaultReservesState);
|
|
2685
|
+
const totalInvestedAndBorrowedPromise = this.getTotalBorrowedAndInvested(
|
|
2682
2686
|
vault,
|
|
2683
2687
|
slotForOverview,
|
|
2684
2688
|
vaultReservesState
|
|
2685
2689
|
);
|
|
2686
|
-
const vaultCollateralsPromise =
|
|
2690
|
+
const vaultCollateralsPromise = this.getVaultCollaterals(vault, slotForOverview, vaultReservesState, kaminoMarkets);
|
|
2691
|
+
const reservesOverviewPromise = this.getVaultReservesDetails(vault, slotForOverview, vaultReservesState);
|
|
2692
|
+
const vaultFarmIncentivesPromise = this.getVaultRewardsAPY(vault, vaultTokenPrice, farmsClient, slotForOverview);
|
|
2693
|
+
const vaultReservesFarmIncentivesPromise = this.getVaultReservesFarmsIncentives(
|
|
2687
2694
|
vault,
|
|
2695
|
+
vaultTokenPrice,
|
|
2696
|
+
farmsClient,
|
|
2688
2697
|
slotForOverview,
|
|
2689
|
-
vaultReservesState
|
|
2690
|
-
kaminoMarkets
|
|
2698
|
+
vaultReservesState
|
|
2691
2699
|
);
|
|
2692
|
-
const reservesOverviewPromise = await this.getVaultReservesDetails(vault, slotForOverview, vaultReservesState);
|
|
2693
2700
|
|
|
2694
2701
|
// 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
|
|
2695
2702
|
const [
|
|
@@ -2699,6 +2706,8 @@ export class KaminoVaultClient {
|
|
|
2699
2706
|
totalInvestedAndBorrowed,
|
|
2700
2707
|
vaultCollaterals,
|
|
2701
2708
|
reservesOverview,
|
|
2709
|
+
vaultFarmIncentives,
|
|
2710
|
+
vaultReservesFarmIncentives,
|
|
2702
2711
|
] = await Promise.all([
|
|
2703
2712
|
vaultHoldingsWithUSDValuePromise,
|
|
2704
2713
|
vaultTheoreticalAPYPromise,
|
|
@@ -2706,6 +2715,8 @@ export class KaminoVaultClient {
|
|
|
2706
2715
|
totalInvestedAndBorrowedPromise,
|
|
2707
2716
|
vaultCollateralsPromise,
|
|
2708
2717
|
reservesOverviewPromise,
|
|
2718
|
+
vaultFarmIncentivesPromise,
|
|
2719
|
+
vaultReservesFarmIncentivesPromise,
|
|
2709
2720
|
]);
|
|
2710
2721
|
|
|
2711
2722
|
return {
|
|
@@ -2714,11 +2725,13 @@ export class KaminoVaultClient {
|
|
|
2714
2725
|
vaultCollaterals: vaultCollaterals,
|
|
2715
2726
|
actualSupplyAPY: vaultActualAPYs,
|
|
2716
2727
|
theoreticalSupplyAPY: vaultTheoreticalAPYs,
|
|
2728
|
+
vaultFarmIncentives: vaultFarmIncentives,
|
|
2729
|
+
reservesFarmsIncentives: vaultReservesFarmIncentives,
|
|
2717
2730
|
totalBorrowed: totalInvestedAndBorrowed.totalBorrowed,
|
|
2718
|
-
totalBorrowedUSD: totalInvestedAndBorrowed.totalBorrowed.mul(
|
|
2731
|
+
totalBorrowedUSD: totalInvestedAndBorrowed.totalBorrowed.mul(vaultTokenPrice),
|
|
2719
2732
|
utilizationRatio: totalInvestedAndBorrowed.utilizationRatio,
|
|
2720
2733
|
totalSupplied: totalInvestedAndBorrowed.totalInvested,
|
|
2721
|
-
totalSuppliedUSD: totalInvestedAndBorrowed.totalInvested.mul(
|
|
2734
|
+
totalSuppliedUSD: totalInvestedAndBorrowed.totalInvested.mul(vaultTokenPrice),
|
|
2722
2735
|
};
|
|
2723
2736
|
}
|
|
2724
2737
|
|
|
@@ -3032,11 +3045,18 @@ export class KaminoVaultClient {
|
|
|
3032
3045
|
* Read the APY of the farm built on top of the vault (farm in vaultState.vaultFarm)
|
|
3033
3046
|
* @param vault - the vault to read the farm APY for
|
|
3034
3047
|
* @param vaultTokenPrice - the price of the vault token in USD (e.g. 1.0 for USDC)
|
|
3048
|
+
* @param [farmsClient] - the farms client to use. Optional. If not provided, the function will create a new one
|
|
3035
3049
|
* @param [slot] - the slot to read the farm APY for. Optional. If not provided, the function will read the current slot
|
|
3036
3050
|
* @returns the APY of the farm built on top of the vault
|
|
3037
3051
|
*/
|
|
3038
|
-
async getVaultRewardsAPY(
|
|
3039
|
-
|
|
3052
|
+
async getVaultRewardsAPY(
|
|
3053
|
+
vaultOrState: KaminoVault | VaultState,
|
|
3054
|
+
vaultTokenPrice: Decimal,
|
|
3055
|
+
farmsClient?: Farms,
|
|
3056
|
+
slot?: Slot
|
|
3057
|
+
): Promise<FarmIncentives> {
|
|
3058
|
+
// Determine if we have a KaminoVault or VaultState
|
|
3059
|
+
const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState(this.getConnection()) : vaultOrState;
|
|
3040
3060
|
if (vaultState.vaultFarm === DEFAULT_PUBLIC_KEY) {
|
|
3041
3061
|
return {
|
|
3042
3062
|
incentivesStats: [],
|
|
@@ -3044,12 +3064,74 @@ export class KaminoVaultClient {
|
|
|
3044
3064
|
};
|
|
3045
3065
|
}
|
|
3046
3066
|
|
|
3047
|
-
const tokensPerShare = await this.getTokensPerShareSingleVault(
|
|
3067
|
+
const tokensPerShare = await this.getTokensPerShareSingleVault(vaultState, slot);
|
|
3048
3068
|
const sharePrice = tokensPerShare.mul(vaultTokenPrice);
|
|
3049
3069
|
const stakedTokenMintDecimals = vaultState.sharesMintDecimals.toNumber();
|
|
3050
3070
|
|
|
3051
|
-
const
|
|
3052
|
-
return getFarmIncentives(
|
|
3071
|
+
const kFarmsClient = farmsClient ? farmsClient : new Farms(this.getConnection());
|
|
3072
|
+
return getFarmIncentives(kFarmsClient, vaultState.vaultFarm, sharePrice, stakedTokenMintDecimals);
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
async getVaultReservesFarmsIncentives(
|
|
3076
|
+
vaultOrState: KaminoVault | VaultState,
|
|
3077
|
+
vaultTokenPrice: Decimal,
|
|
3078
|
+
farmsClient?: Farms,
|
|
3079
|
+
slot?: Slot,
|
|
3080
|
+
vaultReservesMap?: Map<Address, KaminoReserve>
|
|
3081
|
+
): Promise<VaultReservesFarmsIncentives> {
|
|
3082
|
+
const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState(this.getConnection()) : vaultOrState;
|
|
3083
|
+
|
|
3084
|
+
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
|
|
3085
|
+
const currentSlot = slot ? slot : await this.getConnection().getSlot({ commitment: 'confirmed' }).send();
|
|
3086
|
+
|
|
3087
|
+
const holdings = await this.getVaultHoldings(vaultState, currentSlot, vaultReservesState);
|
|
3088
|
+
|
|
3089
|
+
const vaultReservesAddresses = vaultState.vaultAllocationStrategy.map(
|
|
3090
|
+
(allocationStrategy) => allocationStrategy.reserve
|
|
3091
|
+
);
|
|
3092
|
+
|
|
3093
|
+
const vaultReservesFarmsIncentives = new Map<Address, FarmIncentives>();
|
|
3094
|
+
let totalIncentivesApy = new Decimal(0);
|
|
3095
|
+
|
|
3096
|
+
const kFarmsClient = farmsClient ? farmsClient : new Farms(this.getConnection());
|
|
3097
|
+
for (const reserveAddress of vaultReservesAddresses) {
|
|
3098
|
+
if (reserveAddress === DEFAULT_PUBLIC_KEY) {
|
|
3099
|
+
continue;
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
const reserveState = vaultReservesState.get(reserveAddress);
|
|
3103
|
+
if (reserveState === undefined) {
|
|
3104
|
+
console.log(`Reserve to read farm incentives for not found: ${reserveAddress}`);
|
|
3105
|
+
vaultReservesFarmsIncentives.set(reserveAddress, {
|
|
3106
|
+
incentivesStats: [],
|
|
3107
|
+
totalIncentivesApy: 0,
|
|
3108
|
+
});
|
|
3109
|
+
continue;
|
|
3110
|
+
}
|
|
3111
|
+
|
|
3112
|
+
const reserveFarmIncentives = await getReserveFarmRewardsAPY(
|
|
3113
|
+
this._rpc,
|
|
3114
|
+
this.recentSlotDurationMs,
|
|
3115
|
+
reserveAddress,
|
|
3116
|
+
vaultTokenPrice,
|
|
3117
|
+
this._kaminoLendProgramId,
|
|
3118
|
+
kFarmsClient,
|
|
3119
|
+
currentSlot,
|
|
3120
|
+
reserveState.state
|
|
3121
|
+
);
|
|
3122
|
+
vaultReservesFarmsIncentives.set(reserveAddress, reserveFarmIncentives.collateralFarmIncentives);
|
|
3123
|
+
|
|
3124
|
+
const investedInReserve = holdings.investedInReserves.get(reserveAddress);
|
|
3125
|
+
const weightedReserveAPY = new Decimal(reserveFarmIncentives.collateralFarmIncentives.totalIncentivesApy)
|
|
3126
|
+
.mul(investedInReserve ?? 0)
|
|
3127
|
+
.div(holdings.totalAUMIncludingFees);
|
|
3128
|
+
totalIncentivesApy = totalIncentivesApy.add(weightedReserveAPY);
|
|
3129
|
+
}
|
|
3130
|
+
|
|
3131
|
+
return {
|
|
3132
|
+
reserveFarmsIncentives: vaultReservesFarmsIncentives,
|
|
3133
|
+
totalIncentivesAPY: totalIncentivesApy,
|
|
3134
|
+
};
|
|
3053
3135
|
}
|
|
3054
3136
|
|
|
3055
3137
|
private appendRemainingAccountsForVaultReserves(
|
|
@@ -3286,6 +3368,8 @@ export type VaultOverview = {
|
|
|
3286
3368
|
vaultCollaterals: Map<Address, MarketOverview>;
|
|
3287
3369
|
theoreticalSupplyAPY: APYs;
|
|
3288
3370
|
actualSupplyAPY: APYs;
|
|
3371
|
+
vaultFarmIncentives: FarmIncentives;
|
|
3372
|
+
reservesFarmsIncentives: VaultReservesFarmsIncentives;
|
|
3289
3373
|
totalBorrowed: Decimal;
|
|
3290
3374
|
totalBorrowedUSD: Decimal;
|
|
3291
3375
|
totalSupplied: Decimal;
|
|
@@ -3293,6 +3377,11 @@ export type VaultOverview = {
|
|
|
3293
3377
|
utilizationRatio: Decimal;
|
|
3294
3378
|
};
|
|
3295
3379
|
|
|
3380
|
+
export type VaultReservesFarmsIncentives = {
|
|
3381
|
+
reserveFarmsIncentives: Map<Address, FarmIncentives>;
|
|
3382
|
+
totalIncentivesAPY: Decimal;
|
|
3383
|
+
};
|
|
3384
|
+
|
|
3296
3385
|
export type VaultFeesPct = {
|
|
3297
3386
|
managementFeePct: Decimal;
|
|
3298
3387
|
performanceFeePct: Decimal;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Address, generateKeyPairSigner, TransactionSigner } from '@solana/kit';
|
|
2
2
|
import {
|
|
3
|
+
DEFAULT_RECENT_SLOT_DURATION_MS,
|
|
3
4
|
initFarmsForReserve as initFarmsForReserveIx,
|
|
4
5
|
KaminoMarket,
|
|
5
6
|
lendingMarketAuthPda,
|
|
@@ -11,7 +12,6 @@ import { getCreateAccountInstruction, SYSTEM_PROGRAM_ADDRESS } from '@solana-pro
|
|
|
11
12
|
import { SYSVAR_RENT_ADDRESS } from '@solana/sysvars';
|
|
12
13
|
import { CliEnv, SendTxMode } from '../tx/CliEnv';
|
|
13
14
|
import { processTx } from '../tx/processor';
|
|
14
|
-
import { DEFAULT_RECENT_SLOT_DURATION_MS } from '@kamino-finance/klend-sdk';
|
|
15
15
|
|
|
16
16
|
export async function initFarmsForReserve(
|
|
17
17
|
env: CliEnv,
|
|
@@ -1318,6 +1318,10 @@ async function main() {
|
|
|
1318
1318
|
);
|
|
1319
1319
|
|
|
1320
1320
|
console.log('vaultOverview', vaultOverview);
|
|
1321
|
+
vaultOverview.reservesFarmsIncentives.reserveFarmsIncentives.forEach((incentive, reserveAddress) => {
|
|
1322
|
+
console.log('reserve ', reserveAddress);
|
|
1323
|
+
console.log('reserve incentive', incentive);
|
|
1324
|
+
});
|
|
1321
1325
|
});
|
|
1322
1326
|
|
|
1323
1327
|
commands
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Address, Rpc, Slot, SolanaRpcApi } from '@solana/kit';
|
|
2
|
+
import { Decimal } from 'decimal.js';
|
|
3
|
+
import { FarmIncentives, Farms } from '@kamino-finance/farms-sdk';
|
|
4
|
+
import { getFarmIncentives } from '@kamino-finance/farms-sdk/dist/utils/apy';
|
|
5
|
+
import { DEFAULT_PUBLIC_KEY } from '@kamino-finance/farms-sdk';
|
|
6
|
+
import { Reserve } from '../@codegen/klend/accounts';
|
|
7
|
+
import { KaminoReserve } from '../lib';
|
|
8
|
+
import { getMintDecimals } from '@kamino-finance/kliquidity-sdk';
|
|
9
|
+
|
|
10
|
+
export interface ReserveIncentives {
|
|
11
|
+
collateralFarmIncentives: FarmIncentives;
|
|
12
|
+
debtFarmIncentives: FarmIncentives;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function getReserveFarmRewardsAPY(
|
|
16
|
+
rpc: Rpc<SolanaRpcApi>,
|
|
17
|
+
recentSlotDurationMs: number,
|
|
18
|
+
reserve: Address,
|
|
19
|
+
reserveLiquidityTokenPrice: Decimal,
|
|
20
|
+
kaminoLendProgramId: Address,
|
|
21
|
+
farmsClient: Farms,
|
|
22
|
+
slot: Slot,
|
|
23
|
+
reserveState?: Reserve,
|
|
24
|
+
cTokenMintDecimals?: number
|
|
25
|
+
): Promise<ReserveIncentives> {
|
|
26
|
+
const reserveIncentives: ReserveIncentives = {
|
|
27
|
+
collateralFarmIncentives: {
|
|
28
|
+
incentivesStats: [],
|
|
29
|
+
totalIncentivesApy: 0,
|
|
30
|
+
},
|
|
31
|
+
debtFarmIncentives: {
|
|
32
|
+
incentivesStats: [],
|
|
33
|
+
totalIncentivesApy: 0,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const reserveAccount = reserveState ? reserveState : await Reserve.fetch(rpc, reserve, kaminoLendProgramId);
|
|
38
|
+
if (!reserveAccount) {
|
|
39
|
+
throw new Error(`Reserve ${reserve} not found`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const kaminoReserve = await KaminoReserve.initializeFromAddress(reserve, rpc, recentSlotDurationMs, reserveAccount);
|
|
43
|
+
|
|
44
|
+
const farmCollateral = kaminoReserve.state.farmCollateral;
|
|
45
|
+
const farmDebt = kaminoReserve.state.farmDebt;
|
|
46
|
+
|
|
47
|
+
const stakedTokenMintDecimals = kaminoReserve.getMintDecimals();
|
|
48
|
+
const reserveCtokenPrice = reserveLiquidityTokenPrice.div(kaminoReserve.getEstimatedCollateralExchangeRate(slot, 0));
|
|
49
|
+
const cTokenMint = kaminoReserve.getCTokenMint();
|
|
50
|
+
const cTokenDecimals = cTokenMintDecimals ? cTokenMintDecimals : await getMintDecimals(rpc, cTokenMint);
|
|
51
|
+
|
|
52
|
+
if (farmCollateral !== DEFAULT_PUBLIC_KEY) {
|
|
53
|
+
const farmIncentivesCollateral = await getFarmIncentives(
|
|
54
|
+
farmsClient,
|
|
55
|
+
farmCollateral,
|
|
56
|
+
reserveCtokenPrice,
|
|
57
|
+
cTokenDecimals
|
|
58
|
+
);
|
|
59
|
+
reserveIncentives.collateralFarmIncentives = farmIncentivesCollateral;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (farmDebt !== DEFAULT_PUBLIC_KEY) {
|
|
63
|
+
const farmIncentivesDebt = await getFarmIncentives(
|
|
64
|
+
farmsClient,
|
|
65
|
+
farmDebt,
|
|
66
|
+
reserveLiquidityTokenPrice,
|
|
67
|
+
stakedTokenMintDecimals
|
|
68
|
+
);
|
|
69
|
+
reserveIncentives.debtFarmIncentives = farmIncentivesDebt;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return reserveIncentives;
|
|
73
|
+
}
|