@kamino-finance/klend-sdk
Version:
Typescript SDK for interacting with the Kamino Lending (klend) protocol
250 lines • 13.9 kB
TypeScript
import { Address, Commitment, GetAccountInfoApi, GetBalanceApi, GetMinimumBalanceForRentExemptionApi, GetMultipleAccountsApi, GetProgramAccountsApi, GetSlotApi, GetTokenAccountBalanceApi, Rpc, Slot } from '@solana/kit';
import { KaminoObligation } from './obligation';
import { KaminoReserve, KaminoReserveRpcApi } from './reserve';
import { LendingMarket, ReferrerTokenState, Reserve, UserMetadata } from '../@codegen/klend/accounts';
import { AllOracleAccounts, ObligationType } from '../utils';
import Decimal from 'decimal.js';
import { Scope } from '@kamino-finance/scope-sdk';
import { OraclePrices } from '@kamino-finance/scope-sdk/dist/@codegen/scope/accounts/OraclePrices';
import { KaminoPrices } from '@kamino-finance/kliquidity-sdk';
export type KaminoMarketRpcApi = GetAccountInfoApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetSlotApi & GetMinimumBalanceForRentExemptionApi & GetTokenAccountBalanceApi & GetBalanceApi;
export interface ReserveRewardInfo {
rewardsPerSecond: Decimal;
rewardsRemaining: Decimal;
rewardApr: Decimal;
rewardMint: Address;
totalInvestmentUsd: Decimal;
rewardPrice: number;
}
export declare class KaminoMarket {
private readonly rpc;
readonly address: Address;
state: LendingMarket;
reserves: Map<Address, KaminoReserve>;
reservesActive: Map<Address, KaminoReserve>;
readonly programId: Address;
private readonly recentSlotDurationMs;
readonly scopeFeeds: Set<Address>;
private constructor();
/**
* Load a new market with all of its associated reserves
* @param rpc
* @param marketAddress
* @param recentSlotDurationMs
* @param programId
* @param withReserves
*/
static load(rpc: Rpc<KaminoMarketRpcApi>, marketAddress: Address, recentSlotDurationMs: number, programId?: Address, withReserves?: boolean): Promise<KaminoMarket | null>;
static loadWithReserves(connection: Rpc<KaminoMarketRpcApi>, market: LendingMarket, reserves: Map<Address, KaminoReserve>, marketAddress: Address, recentSlotDurationMs: number, programId?: Address): KaminoMarket;
static loadMultiple(connection: Rpc<KaminoMarketRpcApi>, markets: Address[], recentSlotDurationMs: number, programId?: Address, withReserves?: boolean, oracleAccounts?: AllOracleAccounts): Promise<Map<Address, KaminoMarket>>;
static loadMultipleWithReserves(connection: Rpc<KaminoMarketRpcApi>, markets: Address[], reserves: Map<Address, Map<Address, KaminoReserve>>, recentSlotDurationMs: number, programId?: Address): Promise<Map<Address, KaminoMarket>>;
reload(): Promise<void>;
reloadSingleReserve(reservePk: Address, reserveData?: Reserve): Promise<void>;
/**
* Get the address of this market
* @return market address public key
*/
getAddress(): Address;
/**
* Get a list of reserves for this market
*/
getReserves(): Array<KaminoReserve>;
getElevationGroup(elevationGroup: number): import("../@codegen/klend/types").ElevationGroup;
/**
* Returns this market's elevation group of the given ID, or `null` for the default group `0`, or throws an error
* (including the given description) if the requested group does not exist.
*/
getExistingElevationGroup(elevationGroupId: number, description?: string): ElevationGroupDescription | null;
getMinNetValueObligation(): Decimal;
/**
* Get the authority PDA of this market
* @return market authority public key
*/
getLendingMarketAuthority(): Promise<Address>;
getName(): string;
getObligationDepositByWallet(owner: Address, mint: Address, obligationType: ObligationType): Promise<Decimal>;
getObligationBorrowByWallet(owner: Address, mint: Address, obligationType: ObligationType): Promise<Decimal>;
getTotalDepositTVL(): Decimal;
getTotalBorrowTVL(): Decimal;
getMaxLeverageForPair(collTokenMint: Address, debtTokenMint: Address): number;
getCommonElevationGroupsForPair(collReserve: KaminoReserve, debtReserve: KaminoReserve): number[];
getMaxAndLiquidationLtvAndBorrowFactorForPair(collTokenMint: Address, debtTokenMint: Address): {
maxLtv: number;
liquidationLtv: number;
borrowFactor: number;
};
getTotalProductTvl(productType: ObligationType): Promise<{
tvl: Decimal;
borrows: Decimal;
deposits: Decimal;
avgLeverage: Decimal;
}>;
/**
*
* @returns Number of active obligations in the market
*/
getNumberOfObligations(): Promise<number>;
getObligationByWallet(Address: Address, obligationType: ObligationType): Promise<KaminoObligation | null>;
/**
* @returns The max borrowable amount for leverage positions
*/
getMaxLeverageBorrowableAmount(collReserve: KaminoReserve, debtReserve: KaminoReserve, slot: Slot, requestElevationGroup: boolean, obligation?: KaminoObligation): Decimal;
loadReserves(oracleAccounts?: AllOracleAccounts): Promise<void>;
refreshAll(): Promise<void>;
getReserveByAddress(address: Address): KaminoReserve | undefined;
/**
* Returns this market's reserve of the given address, or throws an error (including the given description) if such
* reserve does not exist.
*/
getExistingReserveByAddress(address: Address, description?: string): KaminoReserve;
getReserveByMint(address: Address): KaminoReserve | undefined;
/**
* Returns this market's reserve of the given mint address, or throws an error (including the given description) if
* such reserve does not exist.
*/
getExistingReserveByMint(address: Address, description?: string): KaminoReserve;
getReserveBySymbol(symbol: string): KaminoReserve | undefined;
/**
* Returns this market's reserve of the given symbol, or throws an error (including the given description) if
* such reserve does not exist.
*/
getExistingReserveBySymbol(symbol: string, description?: string): KaminoReserve;
getReserveMintBySymbol(symbol: string): Address | undefined;
getReserveFarmInfo(mint: Address, getRewardPrice: (mint: Address) => Promise<number>): Promise<{
borrowingRewards: ReserveRewardInfo;
depositingRewards: ReserveRewardInfo;
}>;
getRewardInfoForFarm(farmAddress: Address, totalInvestmentUsd: Decimal, getRewardPrice: (mint: Address) => Promise<number>): Promise<ReserveRewardInfo>;
calculateRewardAPR(rewardPerSecondLamports: number, rewardPriceUsd: number, totalInvestmentUsd: Decimal, rewardDecimals: number): Decimal;
/**
* Get all obligations for lending market, optionally filter by obligation tag
* This function will likely require an RPC capable of returning more than the default 100k rows in a single scan
*
* @param tag
*/
getAllObligationsForMarket(tag?: number): Promise<KaminoObligation[]>;
/**
* Get all obligations for lending market from an async generator filled with batches of 100 obligations each
* @param tag
* @example
* const obligationsGenerator = market.batchGetAllObligationsForMarket();
* for await (const obligations of obligationsGenerator) {
* console.log('got a batch of # obligations:', obligations.length);
* }
*/
batchGetAllObligationsForMarket(tag?: number): AsyncGenerator<KaminoObligation[], void, unknown>;
getAllObligationsByTag(tag: number, market: Address): Promise<KaminoObligation[]>;
/**
* Retrieves all obligations that have deposited into the specified reserve.
*
* Iterates through all possible deposit slots up to DEPOSITS_LIMIT, applying filters to fetch obligations
* from the program accounts where the deposited reserve matches the provided address. For each matching
* obligation, it decodes the account data, validates ownership, and constructs KaminoObligation instances
* with calculated rates.
*
* @param {Address} reserve - The address of the reserve to filter deposited obligations by.
* @returns {Promise<KaminoObligation[]>} A promise that resolves to an array of KaminoObligation objects representing all obligations that have deposited into the specified reserve.
* @throws {Error} If an account is invalid or does not belong to this program, or if obligation parsing fails.
*/
getAllObligationsByDepositedReserve(reserve: Address): Promise<KaminoObligation[]>;
/**
* Retrieves all obligations that have borrowed from the specified reserve.
*
* Iterates through all possible borrow slots up to BORROWS_LIMIT, applying filters to fetch obligations
* from the program accounts where the borrowed reserve matches the provided address. For each matching
* obligation, it decodes the account data, validates ownership, and constructs KaminoObligation instances
* with calculated rates.
*
* @param {Address} reserve - The address of the reserve to filter borrowed obligations by.
* @returns {Promise<KaminoObligation[]>} A promise that resolves to an array of KaminoObligation objects
* representing all obligations that have borrowed from the specified reserve.
* @throws {Error} If an account is invalid or does not belong to this program, or if obligation parsing fails.
*/
getAllObligationsByBorrowedReserve(reserve: Address): Promise<KaminoObligation[]>;
getAllUserObligations(user: Address, commitment?: Commitment, slot?: bigint): Promise<KaminoObligation[]>;
getAllUserObligationsForReserve(user: Address, reserve: Address): Promise<KaminoObligation[]>;
getUserVanillaObligation(user: Address): Promise<KaminoObligation>;
isReserveInObligation(obligation: KaminoObligation, reserve: Address): boolean;
getUserObligationsByTag(tag: number, user: Address): Promise<KaminoObligation[]>;
getObligationByAddress(address: Address): Promise<KaminoObligation | null>;
getMultipleObligationsByAddress(addresses: Address[]): Promise<(KaminoObligation | null)[]>;
/**
* Get the user metadata PDA and fetch and return the user metadata state if it exists
* @return [address, userMetadataState] - The address of the user metadata PDA and the user metadata state, or null if it doesn't exist
*/
getUserMetadata(user: Address): Promise<[Address, UserMetadata | null]>;
getReferrerTokenStateForReserve(referrer: Address, reserve: Address): Promise<[Address, ReferrerTokenState | null]>;
getAllReferrerTokenStates(referrer: Address): Promise<Map<Address, ReferrerTokenState>>;
getAllReferrerFeesUnclaimed(referrer: Address): Promise<Map<Address, Decimal>>;
getReferrerFeesUnclaimedForReserve(referrer: Address, reserve: KaminoReserve): Promise<Decimal>;
getReferrerFeesCumulativeForReserve(referrer: Address, reserve: KaminoReserve): Promise<Decimal>;
getAllReferrerFeesCumulative(referrer: Address): Promise<Map<Address, Decimal>>;
getReferrerUrl(baseUrl: string, referrer: Address): string;
getReferrerFromUrl(baseUrl: string, url: string): Address<string>;
/**
* Get the underlying rpc passed when instantiating this market
* @return rpc
*/
getRpc(): Rpc<KaminoMarketRpcApi>;
/**
* Get all scope OraclePrices accounts for all market reserves
* @param scope
*/
getReserveOraclePrices(scope: Scope): Promise<Map<Address, OraclePrices>>;
/**
* Get all Scope prices used by all the market reserves
*/
getAllScopePrices(scope: Scope, allOraclePrices: Map<Address, OraclePrices>): Promise<KaminoPrices>;
/**
* Get all Scope/Pyth/Switchboard prices used by all the market reserves
*/
getAllPrices(oracleAccounts?: AllOracleAccounts): Promise<KlendPrices>;
getCumulativeBorrowRatesByReserve(slot: Slot): Map<Address, Decimal>;
getCollateralExchangeRatesByReserve(slot: Slot): Map<Address, Decimal>;
private setPriceIfExist;
getRecentSlotDurationMs(): number;
getMarketElevationGroupDescriptions(): ElevationGroupDescription[];
getElevationGroupsForMintsCombination(collLiquidityMints: Address[], debtLiquidityMint?: Address): ElevationGroupDescription[];
getElevationGroupsForReservesCombination(collReserves: Address[], debtReserve?: Address): ElevationGroupDescription[];
}
export type BorrowCapsAndCounters = {
utilizationCap: Decimal;
utilizationCurrentValue: Decimal;
netWithdrawalCap: Decimal;
netWithdrawalCurrentValue: Decimal;
netWithdrawalLastUpdateTs: Decimal;
netWithdrawalIntervalDurationSeconds: Decimal;
globalDebtCap: Decimal;
globalTotalBorrowed: Decimal;
debtOutsideEmodeCap: Decimal;
borrowedOutsideEmode: Decimal;
debtAgainstCollateralReserveCaps: {
collateralReserve: Address;
elevationGroup: number;
maxDebt: Decimal;
currentValue: Decimal;
}[];
};
export type ElevationGroupDescription = {
collateralReserves: Set<Address>;
collateralLiquidityMints: Set<Address>;
debtReserve: Address;
debtLiquidityMint: Address;
elevationGroup: number;
maxReservesAsCollateral: number;
};
export type KlendPrices = {
scope: KaminoPrices;
pyth: KaminoPrices;
switchboard: KaminoPrices;
};
export declare function getReservesForMarket(marketAddress: Address, rpc: Rpc<KaminoReserveRpcApi>, programId: Address, recentSlotDurationMs: number, oracleAccounts?: AllOracleAccounts): Promise<Map<Address, KaminoReserve>>;
export declare function getSingleReserve(reservePk: Address, rpc: Rpc<KaminoReserveRpcApi>, recentSlotDurationMs: number, reserveData?: Reserve, oracleAccounts?: AllOracleAccounts): Promise<KaminoReserve>;
export declare function getReservesActive(reserves: Map<Address, KaminoReserve>): Map<Address, KaminoReserve>;
/**
*
* @param kaminoMarket
* @param reserves
*/
export declare function getTokenIdsForScopeRefresh(kaminoMarket: KaminoMarket, reserves: Address[]): Map<Address, number[]>;
//# sourceMappingURL=market.d.ts.map