import { Address, Instruction, Option, Slot } from '@solana/kit'; import Decimal from 'decimal.js'; import { KaminoReserve } from './reserve'; import { Obligation } from '../@codegen/klend/accounts'; import { ElevationGroupDescription, KaminoMarket } from './market'; import { ObligationCollateral, ObligationLiquidity } from '../@codegen/klend/types'; import { ObligationType } from '../utils'; import { ActionType } from './action'; import { BorrowOrderSlots, KaminoBorrowOrder } from './borrowOrder'; import { KaminoObligationOrder } from './obligationOrder'; import { RolloverPossibility } from './rolloverTypes'; import type { LedgerInstant } from '../utils/ledger'; export type Position = { reserveAddress: Address; mintAddress: Address; mintFactor: Decimal; /** * Amount of tokens in lamports, including decimal places for interest accrued (no borrow factor weighting) */ amount: Decimal; /** * Market value of the position in USD (no borrow factor weighting) */ marketValueRefreshed: Decimal; }; export type PositionChange = { reserveAddress: Address; amountChangeLamports: Decimal; }; export type MaxWithdrawAmountResult = { /** * Maximum withdraw amount with reserve withdrawal limit applied */ maxWithdrawAmount: Decimal; /** * Maximum withdraw amount for queued withdrawals (no reserve withdrawal limit) */ maxWithdrawAmountQueue: Decimal; }; export type ObligationStats = { userTotalDeposit: Decimal; userTotalCollateralDeposit: Decimal; userTotalLiquidatableDeposit: Decimal; userTotalBorrow: Decimal; userTotalBorrowBorrowFactorAdjusted: Decimal; borrowLimit: Decimal; borrowLiquidationLimit: Decimal; borrowUtilization: Decimal; netAccountValue: Decimal; /** * The obligation's current LTV, *suitable for UI display*. * * Technically, this is a ratio: * - of a sum of all borrows' values multiplied by reserves' borrowFactor (i.e. `userTotalBorrowBorrowFactorAdjusted`) * - to a sum of values of all deposits having reserve's loanToValue > 0 (i.e. `userTotalCollateralDeposit`) * * Please note that this is different from the smart contract's definition of LTV (which divides by a sum of values * of strictly all deposits, i.e. `userTotalDeposit`). Some parts of the SDK (e.g. obligation orders) need to use the * smart contract's LTV definition. */ loanToValue: Decimal; /** * The LTV at which the obligation becomes subject to liquidation, *suitable for UI display*. * * Technically, this is a ratio: * - of a sum of values of all deposits multiplied by reserves' liquidationLtv (i.e. `borrowLiquidationLimit`) * - to a sum of values of all deposits having reserve's liquidationLtv > 0 (i.e. `userTotalLiquidatableDeposit`) * * Please note that this is different from the smart contract's definition of liquidation LTV (which divides by a sum * of values of strictly all deposits, i.e. `userTotalDeposit`). Some parts of the SDK (e.g. obligation orders) need * to use the smart contract's LTV definition. */ liquidationLtv: Decimal; leverage: Decimal; potentialElevationGroupUpdate: number; }; interface BorrowStats { borrows: Map; userTotalBorrow: Decimal; userTotalBorrowBorrowFactorAdjusted: Decimal; positions: number; } interface DepositStats { deposits: Map; userTotalDeposit: Decimal; userTotalCollateralDeposit: Decimal; userTotalLiquidatableDeposit: Decimal; borrowLimit: Decimal; liquidationLtv: Decimal; borrowLiquidationLimit: Decimal; } export declare class KaminoObligation { obligationAddress: Address; state: Obligation; market: KaminoMarket; /** * Deposits stored in a map of reserve address to position */ deposits: Map; /** * Borrows stored in a map of reserve address to position */ borrows: Map; refreshedStats: ObligationStats; obligationTag: number; /** * Every borrow-order slot of the obligation, in the program's index order (the head order followed by the * tail ones). Inactive slots are present too, so an index here is the `orderIdx` the on-chain instructions * take; use {@link getActiveBorrowOrders} to skip the empty ones. */ borrowOrders: BorrowOrderSlots; /** * Initialise a new Obligation from the deserialized state * @param market * @param obligationAddress * @param obligation * @param collateralExchangeRates - rates from the market by reserve address, will be calculated if not provided * @param cumulativeBorrowRates - rates from the market by reserve address, will be calculated if not provided */ constructor(market: KaminoMarket, obligationAddress: Address, obligation: Obligation, collateralExchangeRates: Map, cumulativeBorrowRates: Map); /** * @param reserveAddress1 deposit/collateral reserve. Required for non-Vanilla tags. * @param reserveAddress2 borrow/debt reserve. Required for Multiply/Leverage (both rate kinds). * * Reserves rather than mints because a single mint can map to a float-rate reserve plus * multiple fixed-rate reserves — the caller must specify which one this obligation was * seeded with. Mints for variable-rate tags are looked up internally from the reserve. */ getObligationId(market: KaminoMarket, reserveAddress1?: Option
, reserveAddress2?: Option
): Promise; static load(kaminoMarket: KaminoMarket, obligationAddress: Address): Promise; static loadAll(kaminoMarket: KaminoMarket, obligationAddresses: Address[], slot: Slot): Promise<(KaminoObligation | null)[]>; /** * Construct a KaminoObligation from raw on-chain account data. * Use this when you already have the account bytes (e.g., from a WebSocket * notification) and don't want to make an RPC call. * * Decodes the obligation to find its lendingMarket, looks up the market * from the provided map, computes rates, and returns the hydrated instance. * * Returns null if the obligation's market is not in the map. * Throws if the data does not match the Obligation discriminator. */ static fromAccountData(markets: Map, obligationAddress: Address, data: Buffer | Uint8Array, slot: Slot): KaminoObligation | null; /** * @returns the obligation borrows as a list */ getBorrows(): Array; /** * @returns the obligation borrows as a list */ getDeposits(): Array; /** * Returns obligation orders (including the null ones, i.e. non-active positions in the orders' array). */ getOrders(): Array; /** * Returns active obligation orders (i.e. ones that *may* have their condition met). */ getActiveOrders(): Array; /** * @returns the total deposited value of the obligation (sum of all deposits) */ getDepositedValue(): Decimal; /** * @returns the total borrowed value of the obligation (sum of all borrows -- no borrow factor) */ getBorrowedMarketValue(): Decimal; /** * @returns the total borrowed value of the obligation (sum of all borrows -- with borrow factor weighting) */ getBorrowedMarketValueBFAdjusted(): Decimal; /** * @returns total borrow power of the obligation, relative to max LTV of each asset's reserve */ getMaxAllowedBorrowValue(): Decimal; /** * @returns the borrow value at which the obligation gets liquidatable * (relative to the liquidation threshold of each asset's reserve) */ getUnhealthyBorrowValue(): Decimal; /** * * @returns Market value of the deposit in the specified obligation collateral/deposit asset (USD) */ getDepositMarketValue(deposit: ObligationCollateral): Decimal; getBorrowByReserve(reserve: Address): Position | undefined; getDepositByReserve(reserve: Address): Position | undefined; getBorrowsByMint(mint: Address): Position[]; getBorrowAmountByReserve(reserve: KaminoReserve): Decimal; getDepositsByMint(mint: Address): Position[]; getDepositAmountByReserve(reserve: KaminoReserve): Decimal; /** * * @returns Market value of the borrow in the specified obligation liquidity/borrow asset (USD) (no borrow factor weighting) */ getBorrowMarketValue(borrow: ObligationLiquidity): Decimal; /** * * @returns Market value of the borrow in the specified obligation liquidity/borrow asset (USD) (with borrow factor weighting) */ getBorrowMarketValueBFAdjusted(borrow: ObligationLiquidity): Decimal; /** * @param orderIdx - the slot to read, as taken by the on-chain instructions; `0` is the head order * @returns the borrow order in that slot, active or not * @throws if the obligation has no such slot */ getBorrowOrder(orderIdx: number): KaminoBorrowOrder; /** * @param currentTimestamp current unix time in seconds, used to tell which orders are still fillable * @returns the borrow orders that still have debt left to fill and are still within their fillable deadline, * each with the index it occupies * * An order past its deadline is left out even while the account still carries it: the program only zeroes * expired orders when it next refreshes the obligation, so a state read before that refresh shows an order * which nothing can fill any more. */ getActiveBorrowOrders(currentTimestamp: number): { orderIdx: number; borrowOrder: KaminoBorrowOrder; }[]; /** * @param currentTimestamp current unix time in seconds, used to tell which orders are still fillable * @returns the index of this obligation's only fillable borrow order — the order meant by an operation which * did not name one * @throws if no order is fillable, or if several are */ requireSoleActiveBorrowOrderIdx(currentTimestamp: number): number; static getDebtWithFeesForBorrowAmount(receivedBorrowAmount: Decimal, market: KaminoMarket, reserve: KaminoReserve, hasReferrer: boolean): Decimal; static getBorrowOrderRemainingDebtAmountWithFees(borrowOrder: KaminoBorrowOrder, market: KaminoMarket, reserve: KaminoReserve, hasReferrer: boolean): Decimal; /** * Calculates the current ratio of borrowed value to deposited value (taking *all* deposits into account). * * Please note that the denominator here is different from the one found in `refreshedStats`: * - the {@link ObligationStats#loanToValue} contains a value appropriate for display on the UI (i.e. taking into * account *only* the deposits having `reserve.loanToValue > 0`). * - the computation below follows the logic used by the KLend smart contract, and is appropriate e.g. for evaluating * LTV-based obligation orders. */ loanToValue(): Decimal; /** * Calculates the ratio of borrowed value to deposited value (taking *all* deposits into account) at which the * obligation is subject to liquidation. * * Please note that the denominator here is different from the one found in `refreshedStats`: * - the {@link ObligationStats#liquidationLtv} contains a value appropriate for display on the UI (i.e. taking into * account *only* the deposits having `reserve.liquidationLtv > 0`). * - the computation below follows the logic used by the KLend smart contract, and is appropriate e.g. for evaluating * LTV-based obligation orders. */ liquidationLtv(): Decimal; /** * Calculate the current ratio of borrowed value to deposited value, disregarding the borrow factor. */ noBfLoanToValue(): Decimal; /** * @returns the total number of positions (deposits + borrows) */ getNumberOfPositions(): number; getNetAccountValue(): Decimal; getReferrer(): Option
; /** * Get the loan to value and liquidation loan to value for a collateral token reserve as ratios, accounting for the obligation elevation group if it is active */ getLtvForReserve(market: KaminoMarket, reserveAddress: Address): { maxLtv: Decimal; liquidationLtv: Decimal; }; /** * @returns the potential elevation groups the obligation qualifies for */ getElevationGroups(kaminoMarket: KaminoMarket): Array; static getElevationGroupsForReserves(reserves: Array): Array; static simulateDepositChange(obligationDeposits: ObligationCollateral[], depositChange: PositionChange, collateralExchangeRates: Map): ObligationCollateral[]; static simulateBorrowChange(obligationBorrows: ObligationLiquidity[], borrowChange: PositionChange, cumulativeBorrowRate: Decimal): ObligationLiquidity[]; /** * Calculate the newly modified stats of the obligation */ getSimulatedObligationStats(params: { amountCollateral?: Decimal; amountDebt?: Decimal; action: ActionType; collateralReserveAddress?: Address; debtReserveAddress?: Address; market: KaminoMarket; reserves: Map; slot: Slot; elevationGroupOverride?: number; }): { stats: ObligationStats; deposits: Map; borrows: Map; }; /** * Core static helper: simulates an action on explicit obligation state arrays. * All simulation methods delegate to this. */ static simulateObligationStats(params: { baseDeposits: ObligationCollateral[]; baseBorrows: ObligationLiquidity[]; elevationGroup: number; amountCollateral?: Decimal; amountDebt?: Decimal; action: ActionType; collateralReserveAddress?: Address; debtReserveAddress?: Address; market: KaminoMarket; slot: Slot; }): { stats: ObligationStats; deposits: Map; borrows: Map; }; /** * Simulate obligation stats for a deposit + borrow order fill when no obligation exists yet. * * Starts from empty obligation state, applies the deposit, then simulates the borrow order * fill across all compatible reserves (same worst-case logic as getSimulatedObligationStatsForBorrowOrderFill). * * Useful in the UI when the user fills in a "deposit collateral + create borrow order" form * and wants to see the projected LTV before submitting. */ static getSimulatedObligationStatsForDepositAndBorrowOrderFill(params: { borrowOrder: KaminoBorrowOrder; market: KaminoMarket; slot: Slot; currentTimestamp: number; depositReserveAddress: Address; depositAmountLamports: Decimal; elevationGroupOverride?: number; }): { stats: ObligationStats; deposits: Map; borrows: Map; }; /** * Simulate obligation stats for a borrow order fill across all compatible reserves, * returning the worst-case (highest LTV) result. * * This is useful when the exact fill reserve is unknown (e.g., for fixed-rate borrow orders * where multiple reserves of the same mint exist and the filler bot picks one at fill time). */ getSimulatedObligationStatsForBorrowOrderFill(params: { borrowOrder: KaminoBorrowOrder; market: KaminoMarket; slot: Slot; currentTimestamp: number; elevationGroupOverride?: number; }): { stats: ObligationStats; deposits: Map; borrows: Map; }; /** * Returns the reserves of the order's debt mint that can fill it, mirroring the on-chain * `fill_borrow_order` term + rate gates: * - rate gate: the reserve's peak borrow rate must be `<=` the order's max rate; * - term gate (`is_term_satisfied`): an open-term order is fillable only by an open-term reserve, while a * fixed-term order (min term M) is fillable by an open-term reserve or by a fixed/maturity-term reserve whose * remaining term is `>= M`. The reserve's remaining term is the shortest active cap among its configured * `debtTermSeconds` and/or the seconds until its `debtMaturityTimestamp` (a reserve whose maturity has already * passed is excluded). * * @param currentTimestamp current unix time in seconds, used to compute the remaining term until maturity. */ static getCompatibleBorrowOrderFillReserves(market: KaminoMarket, borrowOrder: KaminoBorrowOrder, currentTimestamp: number): KaminoReserve[]; /** * Selects the reserve to fill a borrow order from, among those that can fill it on-chain * (see {@link getCompatibleBorrowOrderFillReserves}), applying the lender-favorable policy used by the * deposit-and-fill flow: * - a fixed-term order is filled only from a fixed/maturity-term reserve, never an open-term (float) reserve, * even though the on-chain term gate would accept one (a fixed-term order wants a fixed-rate loan); * - among the eligible reserves, the highest peak borrow rate wins, tie-broken by the shortest remaining term * (the shortest active cap among configured term and/or seconds until maturity). * * @param currentTimestamp current unix time in seconds, used to compute the remaining term until maturity. * @returns the selected reserve, or `undefined` if no reserve can fill the order. */ static selectBorrowOrderFillReserve(market: KaminoMarket, borrowOrder: KaminoBorrowOrder, currentTimestamp: number): KaminoReserve | undefined; /** * Core static helper for borrow order fill simulation. * Filters compatible reserves, simulates the borrow on each, returns worst-case (highest LTV). */ private static simulateBorrowOrderFillOnState; private static emptyObligationState; private static emptyObligationDeposits; private static emptyObligationBorrows; /** * Calculates the stats of the obligation after a hypothetical collateral swap. */ getPostSwapCollObligationStats(params: { withdrawAmountLamports: Decimal; withdrawReserveAddress: Address; depositAmountLamports: Decimal; depositReserveAddress: Address; borrowAmountLamports?: Decimal; borrowReserveAddress?: Address; newElevationGroup: number; market: KaminoMarket; slot: Slot; }): ObligationStats; /** * Calculates the stats of the obligation after a hypothetical debt swap. */ getPostSwapDebtObligationStats(params: { repayAmountLamports: Decimal; repayReserveAddress: Address; borrowAmountLamports: Decimal; borrowReserveAddress: Address; newElevationGroup: number; market: KaminoMarket; slot: Slot; }): ObligationStats; estimateObligationInterestRate: (market: KaminoMarket, reserve: KaminoReserve, borrow: ObligationLiquidity, currentSlot: Slot) => Decimal; static getOraclePx: (reserve: KaminoReserve) => Decimal; static calculatePositions(market: KaminoMarket, obligationDeposits: ObligationCollateral[], obligationBorrows: ObligationLiquidity[], elevationGroup: number, collateralExchangeRates: Map, cumulativeBorrowRates: Map | null, getOraclePx?: (reserve: KaminoReserve) => Decimal): { borrows: Map; deposits: Map; refreshedStats: ObligationStats; }; static calculateObligationDeposits(market: KaminoMarket, obligationDeposits: ObligationCollateral[], collateralExchangeRates: Map | null, elevationGroup: number, getPx: (reserve: KaminoReserve) => Decimal): DepositStats; static calculateObligationBorrows(market: KaminoMarket, obligationBorrows: ObligationLiquidity[], cumulativeBorrowRates: Map | null, elevationGroup: number, getPx: (reserve: KaminoReserve) => Decimal): BorrowStats; getMaxLoanLtvAndLiquidationLtvGivenElevationGroup(market: KaminoMarket, elevationGroup: number, slot: Slot): { maxLtv: Decimal; liquidationLtv: Decimal; }; /** * Creates a new KaminoObligation with simulated position changes applied. * This allows you to model what the obligation would look like with deposits/borrows * without actually executing those transactions. * * @param market - The KaminoMarket instance * @param slot - The slot number for rate calculations * @param depositChanges - Optional array of deposit changes to apply * @param borrowChanges - Optional array of borrow changes to apply * @returns A new KaminoObligation instance with the changes applied */ withPositionChanges(market: KaminoMarket, slot: Slot, depositChanges?: PositionChange[], borrowChanges?: PositionChange[]): KaminoObligation; getBorrowPower(market: KaminoMarket, liquidityReserveAddress: Address, slot: Slot, elevationGroup?: number): Decimal; getMaxBorrowAmountV2(market: KaminoMarket, liquidityReserveAddress: Address, slot: Slot, elevationGroup?: number): Decimal; getMaxBorrowAmountV2WithDeposit(market: KaminoMarket, liquidityReserveAddress: Address, slot: Slot, elevationGroup: number | undefined, depositAmountLamports: Decimal, depositReserveAddress: Address): Decimal; isLoanEligibleForElevationGroup(market: KaminoMarket, slot: Slot, elevationGroup: number): boolean; getElevationGroupsForObligation(market: KaminoMarket): ElevationGroupDescription[]; getMaxBorrowAmount(market: KaminoMarket, liquidityReserveAddress: Address, slot: Slot, requestElevationGroup: boolean): Decimal; getMaxWithdrawAmount(market: KaminoMarket, depositReserveAddress: Address, _slot: Slot): MaxWithdrawAmountResult; /** * Same as getMaxWithdrawAmount but assumes a repay is made first, calculating * the new withdraw power after the repay, without overriding the obligation itself. * * @param market - The KaminoMarket instance. * @param depositReserveAddress - The liquidity (deposit) reserve Address. * @param slot - The slot number. * @param repayAmountLamports - The amount to repay in lamports (use U64_MAX for full repay). * @param repayReserveAddress - The reserve address of the borrow being repaid. * @returns The maximum withdraw amounts (both with and without withdrawal queues). * @throws Error if the reserve is not found. */ getMaxWithdrawAmountWithRepay(market: KaminoMarket, depositReserveAddress: Address, slot: Slot, repayAmountLamports: Decimal, repayReserveAddress: Address): MaxWithdrawAmountResult; getObligationLiquidityByReserve(reserveAddress: Address): ObligationLiquidity; /** * * @returns Total borrowed amount for the specified obligation liquidity/borrow asset */ static getBorrowAmount(borrow: ObligationLiquidity): Decimal; /** * * @returns Cumulative borrow rate for the specified obligation liquidity/borrow asset */ static getCumulativeBorrowRate(borrow: ObligationLiquidity): Decimal; /** * Mirrors on-chain `ObligationLiquidity::calculate_interest_for_period`. * Calculates the interest that would accrue on `amount` over `timePeriodSecs` seconds. */ static calculateInterestForPeriod(borrow: ObligationLiquidity, reserve: KaminoReserve, amount: Decimal, timePeriodSecs: number, currentSlot: Slot): Decimal; /** * Mirrors on-chain `ObligationLiquidity::calculate_early_repay_penalty`. * * Returns the penalty (in lamports) for repaying `repayAmountLamports` early on a * borrow position identified by `reserveAddress`. * * Returns 0 when: * - The reserve is open-term (debtTermSeconds == 0) * - lastBorrowedAtTimestamp == 0 (legacy/untracked borrow) * - The debt has matured (elapsed >= debtTermSeconds) */ calculateEarlyRepayPenalty(reserveAddress: Address, repayAmountLamports: Decimal, currentTimestamp: number, currentSlot: Slot): Decimal; /** * Single source of truth for the fixed-term early-repay FUNDING invariant used by every debt-touching SDK op * (swap-debt, repay-with-coll, swap-coll, leverage withdraw/adjust/close): repaying a fixed-term borrow before * maturity debits `principal + penalty` on-chain, so the flash-borrow / coll→debt swap must make * `principal + penalty` available while the repay instruction amount stays the bare principal. * * Returns `{ penaltyLamports, fundingLamports }`, both in the debt reserve's lamports. For open-term reserves, * matured/untracked borrows, and variable-rate reserves the penalty is 0 and `fundingLamports == principal`. * * `currentLedgerInstant` must come from one ledger snapshot (for example {@link getCurrentLedgerInstant}) at the * same commitment as the loaded reserve and obligation state, so the slot used for interest projection and the * block time used for term decay cannot drift independently. * * NOTE on snapshot ordering: `calculateEarlyRepayPenalty` → `calculateInterestForPeriod` projects the remaining-term * interest forward from `currentLedgerInstant.slot`, whereas the on-chain charge projects from the reserve's * `last_update` slot. A ledger instant at or after that update can only over-estimate when the reserve is stale (the * surplus stays as user dust / slightly more collateral withdrawn). An instant older than the reserve snapshot * could under-estimate instead, so the calculation rejects that inconsistent ordering rather than silently sizing. */ calculateEarlyRepayFunding(reserve: KaminoReserve, repayPrincipalLamports: Decimal, currentLedgerInstant: LedgerInstant): { penaltyLamports: Decimal; fundingLamports: Decimal; }; static getRatesForObligation(kaminoMarket: KaminoMarket, deposits: ObligationCollateral[], borrows: ObligationLiquidity[], slot: Slot, additionalReserves?: Address[]): { collateralExchangeRates: Map; cumulativeBorrowRates: Map; }; static addRatesForObligation(kaminoMarket: KaminoMarket, deposits: ObligationCollateral[], borrows: ObligationLiquidity[], collateralExchangeRates: Map, cumulativeBorrowRates: Map, slot: Slot): void; static getCollateralExchangeRatesForObligation(kaminoMarket: KaminoMarket, deposits: ObligationCollateral[], slot: Slot, additionalReserves: Address[]): Map; static addCollateralExchangeRatesForObligation(kaminoMarket: KaminoMarket, collateralExchangeRates: Map, deposits: ObligationCollateral[], slot: Slot): void; static getCumulativeBorrowRatesForObligation(kaminoMarket: KaminoMarket, borrows: ObligationLiquidity[], slot: Slot, additionalReserves?: Address[]): Map; static addCumulativeBorrowRatesForObligation(kaminoMarket: KaminoMarket, cumulativeBorrowRates: Map, borrows: ObligationLiquidity[], slot: Slot): void; /** * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active * @param reserve * @param elevationGroup */ static getBorrowFactorForReserve(reserve: KaminoReserve, elevationGroup: number): Decimal; /** * Get the loan to value and liquidation loan to value for a collateral reserve as ratios, accounting for the obligation elevation group if it is active * @param market * @param reserve * @param elevationGroup */ static getLtvForReserve(market: KaminoMarket, reserve: KaminoReserve, elevationGroup: number): { maxLtv: Decimal; liquidationLtv: Decimal; }; getDepositReserves(): Address[]; getBorrowReserves(): Address[]; getAllReserves(): Address[]; getRefreshObligationIx(opts?: { extraDepositReserves?: Address[]; extraBorrowReserves?: Address[]; skipReserves?: Address[]; }): Promise; /** * Best-effort preflight check of whether this obligation's borrow from `sourceReserveAddress` can be rolled * over into `targetReserveAddress` at `currentTimestamp` (unix seconds): it applies the program's rollover * preconditions, resolves the rollover mode, and computes how much of the position can be rolled. * Synchronous - it reads the passed market, reserves, and this obligation's state only. * * See {@link RolloverPossibility} for exactly what is and isn't covered (it is preflight, not an exact * replica - in-transaction freshness, the reserve program version, token-2022 mint extensions, and * exact fixed-point rounding remain on-chain concerns), and * {@link KaminoAction.buildRolloverFixedTermBorrowTxns} to build the transaction. */ checkRolloverPossible(kaminoMarket: KaminoMarket, sourceReserveAddress: Address, targetReserveAddress: Address, currentTimestamp: number): RolloverPossibility; /** A reserve cannot be used as a rollover source or target while it is obsolete or in emergency mode. */ private static isReserveInactiveForRollover; /** * Mirrors the program's fixed-term rollover-target criteria: the target reserve's max borrow rate must be * within the borrow config's max, and (since the config accepts a fixed-term target) its debt term must meet * the config's minimum. Returns the failing reason, or `undefined` when the target satisfies them. */ private static checkFixedTermRolloverTargetCriteria; /** * The market-config enablement side of resolve_allowed_rollover_time: a fixed-to-fixed or fixed-to-open * rollover needs a non-zero window duration configured, and an open-to-fixed migration needs the market's * migration-to-fixed execution flag. Whether the borrow is currently *within* a window is a separate, * timing concern (see {@link checkWithinRolloverWindow}). */ private static isRolloverExecutionEnabled; /** * The timing side of resolve_allowed_rollover_time + check_within_rollover_window: a fixed-source rollover * is only permitted within `window` seconds before the borrow's term ends. An open-to-fixed migration has * no window (AllowedRolloverTime::Always), so it is always within timing. * * A fixed-to-fixed rollover may narrow or widen the market's window through the borrow's own * `fixedTermRolloverWindowDurationDays` (zero meaning "use the market's"); the fixed-to-open window is * market-level only. */ private static checkWithinRolloverWindow; /** * The rollover window in force for a fixed-term target: the borrow's own * `fixedTermRolloverWindowDurationDays` override when set, otherwise the market's * `fixedTermRolloverWindowDurationSeconds`. */ private static getEffectiveFixedTermRolloverWindowSeconds; /** * Mirrors ObligationLiquidity::get_debt_term_end_timestamp: the borrow's start timestamp plus the reserve's * debt term, or null for an open-term reserve or a borrow that did not track its start timestamp. */ private static getDebtTermEndTimestamp; /** * Mirrors check_rollover_into_existing_slot_possible: when the obligation already borrows from the target, * the two borrows' rollover configs must match and merging must not shorten the remaining debt term. */ private static checkExistingTargetBorrowSlot; private static rolloverConfigsEqual; } export declare function isKaminoObligation(obligation: KaminoObligation | ObligationType): obligation is KaminoObligation; export {}; //# sourceMappingURL=obligation.d.ts.map