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