import BN from 'bn.js'; import { Address, Instruction, Slot, TransactionSigner, Rpc, GetMinimumBalanceForRentExemptionApi, Option, GetProgramAccountsApi, GetAccountInfoApi, GetMultipleAccountsApi } from '@solana/kit'; import Decimal from 'decimal.js'; import { AllOracleAccounts, MarketWithAddress, ReserveKind, TokenOracleData } from '../utils'; import { FeeCalculation, Fees, ReserveDataType, ReserveRewardYield } from './shared'; import { Reserve, WithdrawTicket } from '../@codegen/klend/accounts'; import { ReserveConfig, UpdateConfigModeKind } from '../@codegen/klend/types'; import { ConfigUpdater, PriorityOrderedConfigUpdater } from './configItems'; import { Fraction } from './fraction'; import { ActionType } from './action'; import { BorrowCapsAndCounters, KaminoMarket } from './market'; import { KaminoPrices } from '@kamino-finance/kliquidity-sdk'; import { RewardInfo } from '@kamino-finance/farms-sdk'; import { KaminoCdnData } from './cdnClient'; export type KaminoReserveRpcApi = GetProgramAccountsApi & GetAccountInfoApi & GetMultipleAccountsApi; export declare const DEFAULT_RECENT_SLOT_DURATION_MS = 400; /** * The terms a fresh fixed-term borrow into a fixed-rate reserve is (re-)originated with. Surfaced by SDK flows that * originate or reset fixed-term debt (swap-debt into a fixed-rate target, swap-collateral via-debt re-borrow, leverage * deposit/increase) so clients can show the user the new term/rate/maturity. All fields are `undefined` for * variable/open-term reserves. */ export type FixedTermReorigination = { /** * The reserve's configured fixed debt term, in seconds. This is orthogonal to the reserve-wide * `debt_maturity_timestamp`, matching the term that on-chain early-repay penalty calculations use. */ newDebtTermSeconds: number; /** * The independent reserve-wide `debt_maturity_timestamp`, or `0` when none is configured. This is not the * per-borrow term end; that derives from `last_borrowed_at + newDebtTermSeconds`. */ newDebtTermMaturityTimestamp: number; /** The fixed borrow rate (bps) the new debt accrues at. */ newBorrowRateBps: number; /** Whether any prior auto-rollover config is dropped on (re)origination — always true for the SDK's flash flows. */ rolloverReset: boolean; }; export declare class KaminoReserve { state: Reserve; address: Address; symbol: string; tokenOraclePrice: TokenOracleData; stats: ReserveDataType; private farmData; private rpc; private readonly recentSlotDurationMs; private metadata?; private reserveKind; private scaledUiAmountMultiplier; /** The klend program that owns this reserve (and its parent lending market); used by all account fetches this instance makes. */ private readonly programId; /** * Snapshot of the parent market's `LendingMarket::reserveRewardsMaxAprBps`, captured when this * instance was constructed and, like `state` itself, refreshed on {@link reloadState}/{@link load}. * * All estimation methods use it to mirror the rewards-distribution step of the on-chain * `refresh_reserve`; `0` means the market has reserve rewards disabled. */ reserveRewardsMaxAprBps: number; constructor(state: Reserve, address: Address, tokenOraclePrice: TokenOracleData, connection: Rpc, recentSlotDurationMs: number, reserveRewardsMaxAprBps: number, scaledUiAmountMultiplier?: Decimal, programId?: Address); static initialize(address: Address, state: Reserve, tokenOraclePrice: TokenOracleData, rpc: Rpc, recentSlotDurationMs: number, reserveRewardsMaxAprBps: number, cdnResourcesData?: KaminoCdnData, scaledUiAmountMultiplier?: Decimal, programId?: Address): KaminoReserve; /** * Construct a KaminoReserve from raw on-chain account data. * Use this when you have raw bytes from a WebSocket notification and * an existing oracle price (e.g. from a cached price query). * * Note that the reserve account bytes alone are not enough for fully accurate reserve math: * `reserveRewardsMaxAprBps` lives on the parent `LendingMarket` account, so callers must supply * a snapshot of it read from that account (`kaminoMarket.state.reserveRewardsMaxAprBps`) — * do not hardcode a value. Long-lived subscribers should refresh the snapshot when the market * account changes. * * Throws if the data does not match the Reserve discriminator. */ static fromAccountData(reserveAddress: Address, data: Buffer | Uint8Array, tokenOraclePrice: TokenOracleData, rpc: Rpc, recentSlotDurationMs: number, reserveRewardsMaxAprBps: number, cdnResourcesData?: KaminoCdnData, programId?: Address): KaminoReserve; /** * `reserveRewardsMaxAprBps` is the parent market's `LendingMarket::reserveRewardsMaxAprBps`; * pass it when you already hold the market state to save a network call, otherwise the * reserve's lending market is fetched to read it. */ static initializeFromAddress(address: Address, rpc: Rpc, recentSlotDurationMs: number, reserveState?: Reserve, oracleAccounts?: AllOracleAccounts, scaledUiAmountMultiplier?: Decimal, reserveRewardsMaxAprBps?: number, programId?: Address): Promise; static createReserveKind(state: Reserve): ReserveKind; /** * @returns the scaledUiAmount multiplier for this reserve's liquidity mint. * Returns 1 for mints without the ScaledUiAmountConfig extension. */ getScaledUiAmountMultiplier(): Decimal; /** * @returns the parsed token symbol of the reserve */ getTokenSymbol(): string; /** * @returns list of logo names and human readable oracle descriptions */ getOracleMetadata(): Promise<[string, string][]>; /** * @returns the total borrowed amount of the reserve in lamports */ getBorrowedAmount(): Decimal; /** * @returns the available liquidity amount of the reserve in lamports, as credited at the last refresh * * This is what the reserve holds right now, so it is the amount to use when mirroring the program at * the reserve's current state (see {@link getQueuedLiquidityAmountAtCurrentRate}). Use * {@link getEstimatedLiquidityAvailableAmount} when projecting to a later slot instead. */ getLiquidityAvailableAmount(): Decimal; /** * @returns the available liquidity amount of the reserve in lamports, estimated at `slot`: the amount * credited at the last refresh plus whatever a refresh at `slot` would distribute into it * * The on-chain `distribute_rewards` credits `total_available_amount`, so — unlike interest accrual — * the reserve rewards make this amount a function of the slot being asked about. This is the value to * pair with anything derived from {@link getEstimatedCollateralExchangeRate}, so that both sides come * from one simulated refresh. */ getEstimatedLiquidityAvailableAmount(slot: Slot, referralFeeBps: number): Decimal; /** @returns the total amount of ctokens queued for withdrawal */ getQueuedCTokens(): Decimal; /** * @returns the total amount of liquidity queued for withdrawal, valued at the exchange rate estimated * for `slot`. Floored, like the on-chain `Reserve::queued_liquidity_amount`. */ getQueuedLiquidityAmount(slot: Slot, referralFeeBps: number): Decimal; /** * @returns the the part of reserve liquidity available for *non-priority* purposes (e.g. borrowing, * regular withdrawals), estimated at `slot` * * Mirrors the on-chain `Reserve::freely_available_liquidity_amount`, which takes the available * liquidity and the value of the withdraw queue from the same refreshed state — so both sides here * come from one simulated refresh. */ getFreelyAvailableLiquidityAmount(slot: Slot, referralFeeBps: number): Decimal; /** * * @returns the last cached price stored in the reserve in USD */ getReserveMarketPrice(): Decimal; /** * @returns the current market price of the reserve in USD */ getOracleMarketPrice(): Decimal; /** * @returns the total accumulated protocol fees of the reserve */ getAccumulatedProtocolFees(): Decimal; /** * @returns the total accumulated referrer fees of the reserve */ getAccumulatedReferrerFees(): Decimal; /** * @returns the total pending referrer fees of the reserve */ getPendingReferrerFees(): Decimal; getScaledBorrowedAmount(): Decimal; getScaledLiquidityAvailableAmount(): Decimal; getScaledTotalSupply(): Decimal; getScaledAccumulatedProtocolFees(): Decimal; getScaledAccumulatedReferrerFees(): Decimal; getScaledPendingReferrerFees(): Decimal; /** * * @returns the flash loan fee percentage of the reserve */ getFlashLoanFee: () => Decimal; /** * * @returns the origination fee percentage of the reserve */ getBorrowFee: () => Decimal; /** * * @returns the fixed interest rate allocated to the host */ getFixedHostInterestRate: () => Decimal; /** * Use getEstimatedTotalSupply() for the most accurate value * @returns the stale total liquidity supply of the reserve from the last refresh */ getTotalSupply(): Decimal; /** @returns {@link getTotalSupply} in scaled-fraction units, for exact on-chain-matching fixed-point math */ getTotalSupplySf(): BN; /** * Calculates the total liquidity supply of the reserve */ getEstimatedTotalSupply(slot: Slot, referralFeeBps: number): Decimal; /** * Use getEstimatedCumulativeBorrowRate() for the most accurate value * @returns the stale cumulative borrow rate of the reserve from the last refresh */ getCumulativeBorrowRate(): Decimal; /** * @Returns estimated cumulative borrow rate of the reserve. * * This is a running scale factor, not a rate: an obligation's debt is recovered by scaling it by the * ratio between two readings (see the on-chain `ObligationLiquidity::accrue_interest`). It must * therefore grow by the same factor {@link getEstimatedDebtAndSupply} grows the reserve's borrowed * amount by, which is why both take it from {@link compoundInterest}. */ getEstimatedCumulativeBorrowRate(currentSlot: Slot, referralFeeBps: number): Decimal; /** * Mirrors on-chain `Reserve::calculate_future_cumulative_borrow_rate`. * Projects the cumulative borrow rate to a future slot. */ calculateFutureCumulativeBorrowRate(futureSlot: Slot): Decimal; /** * Use getEstimatedCollateralExchangeRate() for the most accurate value * @returns the stale exchange rate between the collateral tokens and the liquidity - this is a decimal number scaled by 1e18 */ getCollateralExchangeRate(): Decimal; /** * * @returns the estimated exchange rate between the collateral tokens and the liquidity - this is a decimal number scaled by 1e18 */ getEstimatedCollateralExchangeRate(slot: Slot, referralFeeBps: number): Decimal; /** * Computes the amount of liquidity tokens that corresponds to a given amount of cTokens * @param cTokens - the amount of cTokens to convert to liquidity tokens * @param exchangeRate - the exchange rate to use. If not provided, the estimated exchange rate will be used * @param slot - the slot to use to estimate exchange rate. If exchangeRate is provided, this parameter is ignored, if exchangeRate is not provided this parameter is required * @param referralFeeBps - the referral fee percentage to use for the estimated exchange rate. Defaults to 0. If exchangeRate is provided, this parameter is ignored. * @returns the amount of liquidity tokens that corresponds to the given amount of cTokens */ cTokensToLiquidity(cTokens: Decimal, slot: Slot, exchangeRate?: Decimal, referralFeeBps?: number): Decimal; /** * Computes the amount of liquidity tokens that corresponds to a given amount of cTokens * @param cTokens - the amount of cTokens to convert to liquidity tokens * @param exchangeRate - the exchange rate to use * @returns the amount of liquidity tokens that corresponds to the given amount of cTokens */ static cTokensToLiquidity(cTokens: Decimal, exchangeRate: Decimal): Decimal; /** * Computes the amount of cTokens that corresponds to a given amount of liquidity * @param liquidity - the amount of liquidity to convert to cTokens * @param exchangeRate - the exchange rate to use. If not provided, the estimated exchange rate will be used * @param slot - the slot to use to estimate exchange rate. If exchangeRate is provided, this parameter is ignored, if exchangeRate is not provided this parameter is required * @param referralFeeBps - the referral fee percentage to use for the estimated exchange rate. Defaults to 0. If exchangeRate is provided, this parameter is ignored. * @returns the amount of cTokens that corresponds to the given amount of liquidity */ liquidityToCTokens(liquidity: Decimal, slot: Slot, exchangeRate?: Decimal, referralFeeBps?: number): Decimal; /** * Computes the amount of cTokens that corresponds to a given amount of liquidity * @param liquidity - the amount of liquidity to convert to cTokens * @param exchangeRate - the exchange rate to use * @returns the amount of cTokens that corresponds to the given amount of liquidity */ static liquidityToCTokens(liquidity: Decimal, exchangeRate: Decimal): Decimal; /** * * @returns the total USD value of the existing collateral in the reserve */ getDepositTvl: () => Decimal; /** * * Get the total USD value of the borrowed assets from the reserve */ getBorrowTvl: () => Decimal; /** * @returns 10^mint_decimals */ getMintFactor(): Decimal; /** * @returns the raw (no borrow factor) market value of the given liquidity amount, in scaled-fraction USD, * mirroring the on-chain `liquidity_amount_to_market_value` (truncating toward zero). */ getMarketValueFromLiquidityAmount(liquidityAmount: Fraction): Fraction; /** * @returns mint_decimals of the liquidity token */ getMintDecimals(): number; /** * @returns the collateral farm address if it is set, otherwise none */ getCollateralFarmAddress(): Option
; /** * @returns the debt farm address if it is set, otherwise none */ getDebtFarmAddress(): Option
; /** * @Returns true if the total liquidity supply of the reserve is greater than the deposit limit */ depositLimitCrossed(): boolean; /** * @Returns true if the total borrowed amount of the reserve is greater than the borrow limit */ borrowLimitCrossed(): boolean; /** * * @returns the max capacity of the deposit withdrawal cap */ getDepositWithdrawalCapCapacity(): Decimal; /** * * @returns the current capacity of the deposit withdrawal cap */ getDepositWithdrawalCapCurrent(currentUnixTimestamp: number): Decimal; /** * * @returns the max capacity of the debt withdrawal cap */ getDebtWithdrawalCapCapacity(): Decimal; /** * * @returns the borrow limit of the reserve outside the elevation group */ getBorrowLimitOutsideElevationGroup(): Decimal; /** * * @returns the borrowed amount of the reserve outside the elevation group */ getBorrowedAmountOutsideElevationGroup(): Decimal; /** * * @returns the borrow limit against the collateral reserve in the elevation group */ getBorrowLimitAgainstCollateralInElevationGroup(elevationGroupIndex: number): Decimal; /** * * @returns the borrowed amount against the collateral reserve in the elevation group */ getBorrowedAmountAgainstCollateralInElevationGroup(elevationGroupIndex: number): Decimal; private getWithdrawalCapCurrent; /** * * @returns the current capacity of the debt withdrawal cap */ getDebtWithdrawalCapCurrent(currentUnixTimestamp: number): Decimal; /** * @returns the liquidity (floored, valued at the current collateral exchange rate) the reserve has set aside * to honor queued collateral withdrawals. Mirrors the on-chain `Reserve::queued_liquidity_amount` (current, * non-estimated rate), unlike {@link getQueuedLiquidityAmount} which estimates the rate to a given slot. */ getQueuedLiquidityAmountAtCurrentRate(): Decimal; /** * @returns the most restrictive amount of liquidity (a u64 lamport count) that can be borrowed from this * reserve outside any elevation group, mirroring the on-chain * `Reserve::borrowable_liquidity_amount_outside_elevation_group`: the minimum of freely-available liquidity, * the reserve borrow cap, the outside-elevation-group borrow limit, the utilization-rate limit, and the debt * withdrawal cap. Never negative. */ getBorrowableLiquidityAmountOutsideElevationGroup(currentUnixTimestamp: number): BN; /** * @returns whether the reserve is already over any of its borrow caps - the reserve borrow limit (`>`), the * outside-elevation-group borrow limit (`>`), or the utilization limit (`>=`, which deliberately blocks at * the boundary on-chain). Used by a same-reserve rollover, which re-borrows the same amount and so only * requires the reserve to be within its existing limits rather than to have spare capacity. */ isOverBorrowLimits(): boolean; /** * Pure form of {@link getBorrowableLiquidityAmountOutsideElevationGroup} (mirrors the on-chain * `Reserve::borrowable_liquidity_amount_outside_elevation_group`): the most restrictive of the integer caps * (freely-available liquidity, the reserve borrow cap, the outside-elevation-group borrow limit, and - when * active - the debt withdrawal cap) together with the utilization-rate limit. The utilization limit is * computed in `Fraction` arithmetic as `(totalSupply * pct% - totalBorrow - DELTA)` floored (or the full * `totalSupply` floored when no limit is configured), matching the program's fixed-point math. The integer * caps are u64 lamport counts; `withdrawalCapRemaining` is null when no withdrawal cap is active. Never * negative. */ static computeBorrowableLiquidityOutsideElevationGroup(inputs: { freelyAvailable: BN; remainingBorrowCap: BN; remainingOutsideElevationLimit: BN; totalSupply: Fraction; totalBorrow: Fraction; utilizationLimitPct: number; withdrawalCapRemaining: BN | null; }): BN; /** * Pure form of {@link isOverBorrowLimits}: whether the reserve is over the borrow limit (`>`), the * outside-elevation-group borrow limit (`>`), or the utilization limit (`>=`, which blocks at the boundary). */ static computeIsOverBorrowLimits(inputs: { borrowedAmount: Decimal; reserveBorrowLimit: Decimal; borrowedAmountOutsideElevation: Decimal; borrowLimitOutsideElevation: Decimal; utilizationLimitPct: number; totalSupply: Decimal; }): boolean; getBorrowFactor(): Decimal; /** * @returns the reserve's borrow factor as a {@link Fraction}, mirroring the on-chain `get_borrow_factor`: * `max(1, borrow_factor_pct%)`. */ getBorrowFactorFraction(): Fraction; /** * Borrow-interest component of the supply APR (i.e. utilization × borrow-rate × (1 − take)). * * Utilization and borrow rate are both evaluated from the same estimated reserve state, * including the rewards distribution implied by {@link reserveRewardsMaxAprBps}. * * Does NOT include the reserve-rewards distribution contribution itself (the inflation-of-cToken- * exchange-rate yield); see {@link calculateTheoreticalReserveRewardsSupplyAPR} for that component. Callers * that want the combined depositor yield should add the two. */ calculateSupplyAPR(slot: Slot, referralFeeBps: number): number; /** * Returns the rewards-distribution component of the supply APR — the annualized rate at * which the on-chain `distribute_rewards` step inflates the cToken exchange rate. * * Exposed separately from {@link calculateSupplyAPR} (which returns the borrow-interest yield * only) so that callers can render or use the two components independently. * * Returns the lesser of: * - `rewardsAmountPerSlot * SLOTS_PER_YEAR / total_supply` — the configured per-slot drip rate, * - `reserveRewardsMaxAprBps / FULL_BPS` — the market-level cap. * * Returns `0` only when rewards are configured off (market cap is `0` or RPS is `0`), or * when `total_supply` is zero (no depositors to earn the rate). * * Note on `rewardsAmountAvailable`: the realized rewards yield drops to zero whenever the * on-chain budget is depleted (until an admin tops it up). The SDK cannot predict topup * cadence, so this function returns the **steady-state rate** — what depositors earn while * the budget is non-zero. */ calculateTheoreticalReserveRewardsSupplyAPR(slot: Slot, referralFeeBps: number): number; /** * Rewards-distribution supply APR the reserve is earning right now: equals * {@link calculateTheoreticalReserveRewardsSupplyAPR} while the on-chain rewards budget is funded, and `0` * once `rewardsAmountAvailable` is depleted (the on-chain `distribute_rewards` step distributes * nothing until an admin tops the budget up). * * Use this for reporting current/actual yield; use {@link calculateTheoreticalReserveRewardsSupplyAPR} for * the steady-state rate (eg. theoretical APY projections). */ calculateEffectiveReserveRewardsSupplyAPR(slot: Slot, referralFeeBps: number): number; /** * Mirrors the on-chain `refresh_reserve` (`accrue_interest` → `distribute_rewards`) and returns * the post-refresh debt and supply. The rewards-distribution step is driven by * {@link reserveRewardsMaxAprBps} (`0`, i.e. rewards disabled on the market, makes it a no-op). */ getEstimatedDebtAndSupply(slot: Slot, referralFeeBps: number): { totalBorrow: Decimal; totalSupply: Decimal; }; /** * The amount the `distribute_rewards` step of a refresh at `slot` would move out of * `rewardsAmountAvailable` and into the reserve's available liquidity. */ private getEstimatedDistributedRewards; /** * Debt and supply after the `accrue_interest` step only — the pre-distribution state. * * This is what the on-chain code sees while accruing interest: the borrow index * ({@link getEstimatedCumulativeBorrowRate}) and the rewards-distribution APR cap * ({@link calculateTheoreticalReserveRewardsSupplyAPR}, {@link simulateDistributeRewards}) are all * evaluated against this state, never against the post-distribution one. */ private getEstimatedDebtAndSupplyPreRewards; /** * Mirrors on-chain `Reserve::distribute_rewards` (programs/klend/src/state/reserve.rs). * * Computes how much of `rewards_amount_available` would be moved into `total_available_amount` * during a refresh at the given slot, capped by the per-slot RPS budget and the market-level * APR ({@link reserveRewardsMaxAprBps}). * * `postAccrueTotalSupply` must be the supply *after* `accrue_interest` has run for the same * `slotsElapsed` (this is what the on-chain code uses for the APR cap). * * Every quantity the on-chain formula operates on is an integer, so this is computed in `bigint` * to match it exactly: the `total_supply * apr_bps * slots_elapsed` product exceeds the 20 * significant digits {@link Decimal} keeps by default long before it exceeds the program's `u128`, * and rounding it would shift the final floor by a lamport. */ private simulateDistributeRewards; getEstimatedAccumulatedProtocolFees(slot: Slot, referralFeeBps: number): { accumulatedProtocolFees: Decimal; compoundedVariableProtocolFee: Decimal; compoundedFixedHostFee: Decimal; }; calculateUtilizationRatio(): number; getEstimatedUtilizationRatio(slot: Slot, referralFeeBps: number): number; calcSimulatedUtilizationRatio(amount: Decimal, action: ActionType, slot: Slot, referralFeeBps: number, outflowAmount?: Decimal): number; getMaxBorrowAmountWithCollReserve(market: KaminoMarket, collReserve: KaminoReserve): Decimal; /** * Simulated borrow rate for a hypothetical deposit/withdraw, evaluated at the rewards-aware * post-action utilization (see {@link reserveRewardsMaxAprBps}). */ calcSimulatedBorrowRate(amount: Decimal, action: ActionType, slot: Slot, referralFeeBps: number, outflowAmount?: Decimal): number; /** * Simulated borrow APR. Same semantics as {@link calcSimulatedBorrowRate} plus the fixed * host interest component. */ calcSimulatedBorrowAPR(amount: Decimal, action: ActionType, slot: Slot, referralFeeBps: number, outflowAmount?: Decimal): number; /** * Borrow-interest component of the supply APR for a simulated deposit/withdraw — symmetric * with {@link calculateSupplyAPR}. Does NOT include the reserve-rewards distribution * component; see {@link calculateTheoreticalReserveRewardsSupplyAPR} for the snapshot rewards rate * (callers can add the two for the combined depositor yield). */ calcSimulatedSupplyAPR(amount: Decimal, action: ActionType, slot: Slot, referralFeeBps: number, outflowAmount?: Decimal): number; slotAdjustmentFactor(): number; calculateBorrowRate(): number; /** * The reserve's peak (worst-case) borrow rate in bps: the maximum point of its borrow-rate curve. * Mirrors on-chain `ReserveConfig::max_borrow_rate_bps`, used to gate borrow-order fills against the * order's max acceptable rate. The borrow-rate curve is a fixed-length on-chain array, so an empty one means * the reserve is misconfigured and this throws. */ getMaxBorrowRateBps(): number; /** * The reserve's remaining debt term in seconds, or `undefined` if it is open-term (a float reserve with neither * a fixed term nor a maturity timestamp). If both `debtTermSeconds` and `debtMaturityTimestamp` are set, the * shorter remaining cap is returned, because the on-chain `fill_borrow_order` instruction checks both. * * @param currentTimestamp current unix time in seconds, used for the seconds-until-maturity case. */ getRemainingDebtTermSeconds(currentTimestamp: number): BN | undefined; /** * Estimated borrow rate, evaluated at the rewards-aware utilization implied by * {@link reserveRewardsMaxAprBps}. */ calculateEstimatedBorrowRate(slot: Slot, referralFeeBps: number): number; /** * Borrow APR (curve-driven borrow rate + fixed host interest). The utilization that feeds * the curve is computed with the rewards-distribution simulation of * {@link reserveRewardsMaxAprBps} applied. */ calculateBorrowAPR(slot: Slot, referralFeeBps: number): number; calculateBorrowAPRFixedRate(): number; /** * For a fixed-rate (fixed-term) reserve, returns the terms a fresh borrow into this reserve would be (re-)originated * with, so callers can surface that an obligation's debt term/rate/maturity is being (re)stamped. A direct borrow * stamps `last_borrowed_at = now` and does NOT carry over any prior auto-rollover config (so `rolloverReset` is * always true for the SDK's flash-based flows). Returns `undefined` for open-term (variable) reserves. * * `debt_term_seconds` and `debt_maturity_timestamp` are independent on-chain axes: a direct borrow stamps the full * configured term for early-repay calculations, while the reserve-wide maturity remains an absolute timestamp. */ getFixedTermReorigination(): FixedTermReorigination | undefined; /** * Throws if a fresh borrow into this reserve would be rejected on-chain because the reserve-wide debt maturity has * been reached (`ReserveDebtMaturityReached`). No-op for reserves without a configured `debt_maturity_timestamp`. * Use this to preflight the (re-)origination of debt before building a swap-debt / swap-collateral / leverage tx so * callers get a clear error instead of an opaque on-chain revert. * * This low-level helper retains a wall-clock default, but transaction builders pass the block time from a * `LedgerInstant` fetched at the same commitment as their loaded state. Other callers that need a deterministic * clock should likewise pass a cluster-derived `currentTimestamp` (e.g. from `getBlockTime`). The on-chain check * runs against cluster time at execution, so a borrow that crosses maturity after this preflight still fails * cleanly at simulation with the on-chain error. * * @param currentTimestamp unix seconds (defaults to the current wall clock) */ assertCanOriginateDebt(currentTimestamp?: number): void; /** * @returns the mint of the reserve liquidity token */ getLiquidityMint(): Address; /** * @returns the token program of the reserve liquidity mint */ getLiquidityTokenProgram(): Address; /** * @returns the mint of the reserve collateral token , i.e. the cToken minted for depositing the liquidity token */ getCTokenMint(): Address; /** * Returns the reserve kind (FloatRateReserveKind or FixedRateReserveKind) for this reserve. * * @returns The reserve kind instance */ getKind(): ReserveKind; calculateFees(amountLamports: Decimal, borrowFeeRate: Decimal, feeCalculation: FeeCalculation, referralFeeBps: number, hasReferrer: boolean): Fees; calculateFlashLoanFees(flashLoanAmountLamports: Decimal, referralFeeBps: number, hasReferrer: boolean): Fees; load(tokenOraclePrice: TokenOracleData): Promise; reloadState(): Promise; /** * Borrow-interest supply APY (does not include reserve-rewards distribution; see * {@link calculateTheoreticalReserveRewardsSupplyAPR} for that). The borrow rate that feeds this is * evaluated at the rewards-aware utilization (see {@link reserveRewardsMaxAprBps}). */ totalSupplyAPY(currentSlot: Slot): number; /** * Borrow APY. The curve-driven borrow rate is evaluated at the rewards-aware utilization * (see {@link reserveRewardsMaxAprBps}). */ totalBorrowAPY(currentSlot: Slot): number; totalBorrowAPYFixedRate(): number; loadFarmStates(_farmsProgramId?: Address): Promise; getRewardYields(prices: KaminoPrices, farmsProgramId?: Address): Promise; calculateRewardYield(prices: KaminoPrices, rewardInfo: RewardInfo, isDebtReward: boolean, farmTotalStakeLamports: Decimal): { apy: Decimal; apr: Decimal; }; private formatReserveData; /** * Compound current borrow rate over elapsed slots * * This also calculates protocol fees, which are taken for all obligations that have borrowed from current reserve. * * This also calculates referral fees, which are taken into pendingReferralFees. * * https://github.com/Kamino-Finance/klend/blob/release/1.3.0/programs/klend/src/state/reserve.rs#L517 * * @param slotsElapsed * @param referralFeeBps */ private compoundInterest; /** * Approximation to match the smart contract calculation * https://github.com/Kamino-Finance/klend/blob/release/1.3.0/programs/klend/src/state/reserve.rs#L1026 * @param rate * @param elapsedSlots */ private approximateCompoundedInterest; getBorrowCapForReserve(market: KaminoMarket): BorrowCapsAndCounters; getLiquidityAvailableForDebtReserveGivenCaps(market: KaminoMarket, elevationGroups: number[], collateralReserves?: Address[]): Decimal[]; /** * Fetches all withdraw tickets for this reserve (across all users). * * Useful for computing "queued before you" by comparing ticket sequence numbers. * * @param programId - The lending program ID (defaults to the program that owns this reserve) * @returns Array of all withdraw tickets for this reserve */ getAllWithdrawTickets(programId?: Address): Promise; /** * Fetches all withdraw tickets for this reserve owned by the given user. * * @param userWallet - The user's wallet address * @param programId - The lending program ID (defaults to the program that owns this reserve) * @returns Array of withdraw tickets for the user on this reserve */ getWithdrawTicketsForUser(userWallet: Address, programId?: Address): Promise; } export declare function createReserveIxs(rpc: Rpc, owner: TransactionSigner, ownerLiquiditySource: Address, lendingMarket: Address, liquidityMint: Address, liquidityMintTokenProgram: Address, reserveAddress: TransactionSigner, programId: Address): Promise; export declare function updateReserveConfigIx(signer: TransactionSigner, marketAddress: Address, reserveAddress: Address, mode: UpdateConfigModeKind, value: Uint8Array, programId: Address, skipConfigIntegrityValidation?: boolean): Promise; export declare const RESERVE_CONFIG_UPDATER: ConfigUpdater; export declare const ENTIRE_RESERVE_CONFIG_UPDATER: PriorityOrderedConfigUpdater; export declare const GLOBAL_ADMIN_ONLY_MODES: Set; export declare function isGlobalAdminOnly(mode: UpdateConfigModeKind): boolean; export type ReserveConfigUpdateIx = { ix: Instruction; requiresGlobalAdmin: boolean; }; export declare function parseForChangesReserveConfigAndGetIxs(marketWithAddress: MarketWithAddress, reserve: Reserve | undefined, reserveAddress: Address, reserveConfig: ReserveConfig, programId: Address, lendingMarketOwner?: TransactionSigner, globalAdminSigner?: TransactionSigner): Promise; export type ReserveWithAddress = { address: Address; state: Reserve; }; export declare function shouldSkipValidation(mode: UpdateConfigModeKind, reserve: Reserve | undefined): boolean; export declare function buildReserveConfigPriority(previous: ReserveConfig | undefined, changed: ReserveConfig): (mode: UpdateConfigModeKind) => number; export declare function priorityOf(mode: UpdateConfigModeKind, liquidationThresholdIncreasing?: boolean, autodeleverageDisabling?: boolean, maxLiquidationBonusShouldUpdateFirst?: boolean): number; //# sourceMappingURL=reserve.d.ts.map