@kamino-finance/klend-sdk
Version:
Typescript SDK for interacting with the Kamino Lending (klend) protocol
468 lines (457 loc) • 21 kB
text/typescript
import { PublicKey } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
import BN from "bn.js" // eslint-disable-line @typescript-eslint/no-unused-vars
import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
import * as borsh from "@coral-xyz/borsh"
export interface ReserveConfigFields {
/** Status of the reserve Active/Obsolete/Hidden */
status: number
/** Asset tier -> 0 - regular (collateral & debt), 1 - isolated collateral, 2 - isolated debt */
assetTier: number
/** Flat rate that goes to the host */
hostFixedInterestRateBps: number
/** [DEPRECATED] Boost for side (debt or collateral) */
reserved2: Array<number>
/** [DEPRECATED] Reward points multiplier per obligation type */
reserved3: Array<number>
/** Protocol take rate is the amount borrowed interest protocol receives, as a percentage */
protocolTakeRatePct: number
/** Cut of the liquidation bonus that the protocol receives, as a percentage */
protocolLiquidationFeePct: number
/**
* Target ratio of the value of borrows to deposits, as a percentage
* 0 if use as collateral is disabled
*/
loanToValuePct: number
/** Loan to value ratio at which an obligation can be liquidated, as percentage */
liquidationThresholdPct: number
/** Minimum bonus a liquidator receives when repaying part of an unhealthy obligation, as bps */
minLiquidationBonusBps: number
/** Maximum bonus a liquidator receives when repaying part of an unhealthy obligation, as bps */
maxLiquidationBonusBps: number
/** Bad debt liquidation bonus for an undercollateralized obligation, as bps */
badDebtLiquidationBonusBps: number
/** Time in seconds that must pass before redemptions are enabled after the deposit limit is crossed */
deleveragingMarginCallPeriodSecs: BN
/**
* The rate at which the deleveraging threshold decreases in slots per bps
* e.g. 1 bps per hour would be 7200 slots per bps (assuming 2 slots per second)
*/
deleveragingThresholdSlotsPerBps: BN
/** Program owner fees assessed, separate from gains due to interest accrual */
fees: types.ReserveFeesFields
/** Borrow rate curve based on utilization */
borrowRateCurve: types.BorrowRateCurveFields
/** Borrow factor in percentage - used for risk adjustment */
borrowFactorPct: BN
/** Maximum deposit limit of liquidity in native units, u64::MAX for inf */
depositLimit: BN
/** Maximum amount borrowed, u64::MAX for inf, 0 to disable borrows (protected deposits) */
borrowLimit: BN
/** Token id from TokenInfos struct */
tokenInfo: types.TokenInfoFields
/** Deposit withdrawl caps - deposit & redeem */
depositWithdrawalCap: types.WithdrawalCapsFields
/** Debt withdrawl caps - borrow & repay */
debtWithdrawalCap: types.WithdrawalCapsFields
elevationGroups: Array<number>
disableUsageAsCollOutsideEmode: number
utilizationLimitBlockBorrowingAbove: number
reserved1: Array<number>
/**
* Maximum amount liquidity of this reserve borrowed outside all elevation groups
* - u64::MAX for inf
* - 0 to disable borrows outside elevation groups
*/
borrowLimitOutsideElevationGroup: BN
/**
* Defines the maximum amount (in lamports of elevation group debt asset)
* that can be borrowed when this reserve is used as collateral.
* - u64::MAX for inf
* - 0 to disable borrows in this elevation group (expected value for the debt asset)
*/
borrowLimitAgainstThisCollateralInElevationGroup: Array<BN>
}
export interface ReserveConfigJSON {
/** Status of the reserve Active/Obsolete/Hidden */
status: number
/** Asset tier -> 0 - regular (collateral & debt), 1 - isolated collateral, 2 - isolated debt */
assetTier: number
/** Flat rate that goes to the host */
hostFixedInterestRateBps: number
/** [DEPRECATED] Boost for side (debt or collateral) */
reserved2: Array<number>
/** [DEPRECATED] Reward points multiplier per obligation type */
reserved3: Array<number>
/** Protocol take rate is the amount borrowed interest protocol receives, as a percentage */
protocolTakeRatePct: number
/** Cut of the liquidation bonus that the protocol receives, as a percentage */
protocolLiquidationFeePct: number
/**
* Target ratio of the value of borrows to deposits, as a percentage
* 0 if use as collateral is disabled
*/
loanToValuePct: number
/** Loan to value ratio at which an obligation can be liquidated, as percentage */
liquidationThresholdPct: number
/** Minimum bonus a liquidator receives when repaying part of an unhealthy obligation, as bps */
minLiquidationBonusBps: number
/** Maximum bonus a liquidator receives when repaying part of an unhealthy obligation, as bps */
maxLiquidationBonusBps: number
/** Bad debt liquidation bonus for an undercollateralized obligation, as bps */
badDebtLiquidationBonusBps: number
/** Time in seconds that must pass before redemptions are enabled after the deposit limit is crossed */
deleveragingMarginCallPeriodSecs: string
/**
* The rate at which the deleveraging threshold decreases in slots per bps
* e.g. 1 bps per hour would be 7200 slots per bps (assuming 2 slots per second)
*/
deleveragingThresholdSlotsPerBps: string
/** Program owner fees assessed, separate from gains due to interest accrual */
fees: types.ReserveFeesJSON
/** Borrow rate curve based on utilization */
borrowRateCurve: types.BorrowRateCurveJSON
/** Borrow factor in percentage - used for risk adjustment */
borrowFactorPct: string
/** Maximum deposit limit of liquidity in native units, u64::MAX for inf */
depositLimit: string
/** Maximum amount borrowed, u64::MAX for inf, 0 to disable borrows (protected deposits) */
borrowLimit: string
/** Token id from TokenInfos struct */
tokenInfo: types.TokenInfoJSON
/** Deposit withdrawl caps - deposit & redeem */
depositWithdrawalCap: types.WithdrawalCapsJSON
/** Debt withdrawl caps - borrow & repay */
debtWithdrawalCap: types.WithdrawalCapsJSON
elevationGroups: Array<number>
disableUsageAsCollOutsideEmode: number
utilizationLimitBlockBorrowingAbove: number
reserved1: Array<number>
/**
* Maximum amount liquidity of this reserve borrowed outside all elevation groups
* - u64::MAX for inf
* - 0 to disable borrows outside elevation groups
*/
borrowLimitOutsideElevationGroup: string
/**
* Defines the maximum amount (in lamports of elevation group debt asset)
* that can be borrowed when this reserve is used as collateral.
* - u64::MAX for inf
* - 0 to disable borrows in this elevation group (expected value for the debt asset)
*/
borrowLimitAgainstThisCollateralInElevationGroup: Array<string>
}
/** Reserve configuration values */
export class ReserveConfig {
/** Status of the reserve Active/Obsolete/Hidden */
readonly status: number
/** Asset tier -> 0 - regular (collateral & debt), 1 - isolated collateral, 2 - isolated debt */
readonly assetTier: number
/** Flat rate that goes to the host */
readonly hostFixedInterestRateBps: number
/** [DEPRECATED] Boost for side (debt or collateral) */
readonly reserved2: Array<number>
/** [DEPRECATED] Reward points multiplier per obligation type */
readonly reserved3: Array<number>
/** Protocol take rate is the amount borrowed interest protocol receives, as a percentage */
readonly protocolTakeRatePct: number
/** Cut of the liquidation bonus that the protocol receives, as a percentage */
readonly protocolLiquidationFeePct: number
/**
* Target ratio of the value of borrows to deposits, as a percentage
* 0 if use as collateral is disabled
*/
readonly loanToValuePct: number
/** Loan to value ratio at which an obligation can be liquidated, as percentage */
readonly liquidationThresholdPct: number
/** Minimum bonus a liquidator receives when repaying part of an unhealthy obligation, as bps */
readonly minLiquidationBonusBps: number
/** Maximum bonus a liquidator receives when repaying part of an unhealthy obligation, as bps */
readonly maxLiquidationBonusBps: number
/** Bad debt liquidation bonus for an undercollateralized obligation, as bps */
readonly badDebtLiquidationBonusBps: number
/** Time in seconds that must pass before redemptions are enabled after the deposit limit is crossed */
readonly deleveragingMarginCallPeriodSecs: BN
/**
* The rate at which the deleveraging threshold decreases in slots per bps
* e.g. 1 bps per hour would be 7200 slots per bps (assuming 2 slots per second)
*/
readonly deleveragingThresholdSlotsPerBps: BN
/** Program owner fees assessed, separate from gains due to interest accrual */
readonly fees: types.ReserveFees
/** Borrow rate curve based on utilization */
readonly borrowRateCurve: types.BorrowRateCurve
/** Borrow factor in percentage - used for risk adjustment */
readonly borrowFactorPct: BN
/** Maximum deposit limit of liquidity in native units, u64::MAX for inf */
readonly depositLimit: BN
/** Maximum amount borrowed, u64::MAX for inf, 0 to disable borrows (protected deposits) */
readonly borrowLimit: BN
/** Token id from TokenInfos struct */
readonly tokenInfo: types.TokenInfo
/** Deposit withdrawl caps - deposit & redeem */
readonly depositWithdrawalCap: types.WithdrawalCaps
/** Debt withdrawl caps - borrow & repay */
readonly debtWithdrawalCap: types.WithdrawalCaps
readonly elevationGroups: Array<number>
readonly disableUsageAsCollOutsideEmode: number
readonly utilizationLimitBlockBorrowingAbove: number
readonly reserved1: Array<number>
/**
* Maximum amount liquidity of this reserve borrowed outside all elevation groups
* - u64::MAX for inf
* - 0 to disable borrows outside elevation groups
*/
readonly borrowLimitOutsideElevationGroup: BN
/**
* Defines the maximum amount (in lamports of elevation group debt asset)
* that can be borrowed when this reserve is used as collateral.
* - u64::MAX for inf
* - 0 to disable borrows in this elevation group (expected value for the debt asset)
*/
readonly borrowLimitAgainstThisCollateralInElevationGroup: Array<BN>
constructor(fields: ReserveConfigFields) {
this.status = fields.status
this.assetTier = fields.assetTier
this.hostFixedInterestRateBps = fields.hostFixedInterestRateBps
this.reserved2 = fields.reserved2
this.reserved3 = fields.reserved3
this.protocolTakeRatePct = fields.protocolTakeRatePct
this.protocolLiquidationFeePct = fields.protocolLiquidationFeePct
this.loanToValuePct = fields.loanToValuePct
this.liquidationThresholdPct = fields.liquidationThresholdPct
this.minLiquidationBonusBps = fields.minLiquidationBonusBps
this.maxLiquidationBonusBps = fields.maxLiquidationBonusBps
this.badDebtLiquidationBonusBps = fields.badDebtLiquidationBonusBps
this.deleveragingMarginCallPeriodSecs =
fields.deleveragingMarginCallPeriodSecs
this.deleveragingThresholdSlotsPerBps =
fields.deleveragingThresholdSlotsPerBps
this.fees = new types.ReserveFees({ ...fields.fees })
this.borrowRateCurve = new types.BorrowRateCurve({
...fields.borrowRateCurve,
})
this.borrowFactorPct = fields.borrowFactorPct
this.depositLimit = fields.depositLimit
this.borrowLimit = fields.borrowLimit
this.tokenInfo = new types.TokenInfo({ ...fields.tokenInfo })
this.depositWithdrawalCap = new types.WithdrawalCaps({
...fields.depositWithdrawalCap,
})
this.debtWithdrawalCap = new types.WithdrawalCaps({
...fields.debtWithdrawalCap,
})
this.elevationGroups = fields.elevationGroups
this.disableUsageAsCollOutsideEmode = fields.disableUsageAsCollOutsideEmode
this.utilizationLimitBlockBorrowingAbove =
fields.utilizationLimitBlockBorrowingAbove
this.reserved1 = fields.reserved1
this.borrowLimitOutsideElevationGroup =
fields.borrowLimitOutsideElevationGroup
this.borrowLimitAgainstThisCollateralInElevationGroup =
fields.borrowLimitAgainstThisCollateralInElevationGroup
}
static layout(property?: string) {
return borsh.struct(
[
borsh.u8("status"),
borsh.u8("assetTier"),
borsh.u16("hostFixedInterestRateBps"),
borsh.array(borsh.u8(), 2, "reserved2"),
borsh.array(borsh.u8(), 8, "reserved3"),
borsh.u8("protocolTakeRatePct"),
borsh.u8("protocolLiquidationFeePct"),
borsh.u8("loanToValuePct"),
borsh.u8("liquidationThresholdPct"),
borsh.u16("minLiquidationBonusBps"),
borsh.u16("maxLiquidationBonusBps"),
borsh.u16("badDebtLiquidationBonusBps"),
borsh.u64("deleveragingMarginCallPeriodSecs"),
borsh.u64("deleveragingThresholdSlotsPerBps"),
types.ReserveFees.layout("fees"),
types.BorrowRateCurve.layout("borrowRateCurve"),
borsh.u64("borrowFactorPct"),
borsh.u64("depositLimit"),
borsh.u64("borrowLimit"),
types.TokenInfo.layout("tokenInfo"),
types.WithdrawalCaps.layout("depositWithdrawalCap"),
types.WithdrawalCaps.layout("debtWithdrawalCap"),
borsh.array(borsh.u8(), 20, "elevationGroups"),
borsh.u8("disableUsageAsCollOutsideEmode"),
borsh.u8("utilizationLimitBlockBorrowingAbove"),
borsh.array(borsh.u8(), 2, "reserved1"),
borsh.u64("borrowLimitOutsideElevationGroup"),
borsh.array(
borsh.u64(),
32,
"borrowLimitAgainstThisCollateralInElevationGroup"
),
],
property
)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static fromDecoded(obj: any) {
return new ReserveConfig({
status: obj.status,
assetTier: obj.assetTier,
hostFixedInterestRateBps: obj.hostFixedInterestRateBps,
reserved2: obj.reserved2,
reserved3: obj.reserved3,
protocolTakeRatePct: obj.protocolTakeRatePct,
protocolLiquidationFeePct: obj.protocolLiquidationFeePct,
loanToValuePct: obj.loanToValuePct,
liquidationThresholdPct: obj.liquidationThresholdPct,
minLiquidationBonusBps: obj.minLiquidationBonusBps,
maxLiquidationBonusBps: obj.maxLiquidationBonusBps,
badDebtLiquidationBonusBps: obj.badDebtLiquidationBonusBps,
deleveragingMarginCallPeriodSecs: obj.deleveragingMarginCallPeriodSecs,
deleveragingThresholdSlotsPerBps: obj.deleveragingThresholdSlotsPerBps,
fees: types.ReserveFees.fromDecoded(obj.fees),
borrowRateCurve: types.BorrowRateCurve.fromDecoded(obj.borrowRateCurve),
borrowFactorPct: obj.borrowFactorPct,
depositLimit: obj.depositLimit,
borrowLimit: obj.borrowLimit,
tokenInfo: types.TokenInfo.fromDecoded(obj.tokenInfo),
depositWithdrawalCap: types.WithdrawalCaps.fromDecoded(
obj.depositWithdrawalCap
),
debtWithdrawalCap: types.WithdrawalCaps.fromDecoded(
obj.debtWithdrawalCap
),
elevationGroups: obj.elevationGroups,
disableUsageAsCollOutsideEmode: obj.disableUsageAsCollOutsideEmode,
utilizationLimitBlockBorrowingAbove:
obj.utilizationLimitBlockBorrowingAbove,
reserved1: obj.reserved1,
borrowLimitOutsideElevationGroup: obj.borrowLimitOutsideElevationGroup,
borrowLimitAgainstThisCollateralInElevationGroup:
obj.borrowLimitAgainstThisCollateralInElevationGroup,
})
}
static toEncodable(fields: ReserveConfigFields) {
return {
status: fields.status,
assetTier: fields.assetTier,
hostFixedInterestRateBps: fields.hostFixedInterestRateBps,
reserved2: fields.reserved2,
reserved3: fields.reserved3,
protocolTakeRatePct: fields.protocolTakeRatePct,
protocolLiquidationFeePct: fields.protocolLiquidationFeePct,
loanToValuePct: fields.loanToValuePct,
liquidationThresholdPct: fields.liquidationThresholdPct,
minLiquidationBonusBps: fields.minLiquidationBonusBps,
maxLiquidationBonusBps: fields.maxLiquidationBonusBps,
badDebtLiquidationBonusBps: fields.badDebtLiquidationBonusBps,
deleveragingMarginCallPeriodSecs: fields.deleveragingMarginCallPeriodSecs,
deleveragingThresholdSlotsPerBps: fields.deleveragingThresholdSlotsPerBps,
fees: types.ReserveFees.toEncodable(fields.fees),
borrowRateCurve: types.BorrowRateCurve.toEncodable(
fields.borrowRateCurve
),
borrowFactorPct: fields.borrowFactorPct,
depositLimit: fields.depositLimit,
borrowLimit: fields.borrowLimit,
tokenInfo: types.TokenInfo.toEncodable(fields.tokenInfo),
depositWithdrawalCap: types.WithdrawalCaps.toEncodable(
fields.depositWithdrawalCap
),
debtWithdrawalCap: types.WithdrawalCaps.toEncodable(
fields.debtWithdrawalCap
),
elevationGroups: fields.elevationGroups,
disableUsageAsCollOutsideEmode: fields.disableUsageAsCollOutsideEmode,
utilizationLimitBlockBorrowingAbove:
fields.utilizationLimitBlockBorrowingAbove,
reserved1: fields.reserved1,
borrowLimitOutsideElevationGroup: fields.borrowLimitOutsideElevationGroup,
borrowLimitAgainstThisCollateralInElevationGroup:
fields.borrowLimitAgainstThisCollateralInElevationGroup,
}
}
toJSON(): ReserveConfigJSON {
return {
status: this.status,
assetTier: this.assetTier,
hostFixedInterestRateBps: this.hostFixedInterestRateBps,
reserved2: this.reserved2,
reserved3: this.reserved3,
protocolTakeRatePct: this.protocolTakeRatePct,
protocolLiquidationFeePct: this.protocolLiquidationFeePct,
loanToValuePct: this.loanToValuePct,
liquidationThresholdPct: this.liquidationThresholdPct,
minLiquidationBonusBps: this.minLiquidationBonusBps,
maxLiquidationBonusBps: this.maxLiquidationBonusBps,
badDebtLiquidationBonusBps: this.badDebtLiquidationBonusBps,
deleveragingMarginCallPeriodSecs:
this.deleveragingMarginCallPeriodSecs.toString(),
deleveragingThresholdSlotsPerBps:
this.deleveragingThresholdSlotsPerBps.toString(),
fees: this.fees.toJSON(),
borrowRateCurve: this.borrowRateCurve.toJSON(),
borrowFactorPct: this.borrowFactorPct.toString(),
depositLimit: this.depositLimit.toString(),
borrowLimit: this.borrowLimit.toString(),
tokenInfo: this.tokenInfo.toJSON(),
depositWithdrawalCap: this.depositWithdrawalCap.toJSON(),
debtWithdrawalCap: this.debtWithdrawalCap.toJSON(),
elevationGroups: this.elevationGroups,
disableUsageAsCollOutsideEmode: this.disableUsageAsCollOutsideEmode,
utilizationLimitBlockBorrowingAbove:
this.utilizationLimitBlockBorrowingAbove,
reserved1: this.reserved1,
borrowLimitOutsideElevationGroup:
this.borrowLimitOutsideElevationGroup.toString(),
borrowLimitAgainstThisCollateralInElevationGroup:
this.borrowLimitAgainstThisCollateralInElevationGroup.map((item) =>
item.toString()
),
}
}
static fromJSON(obj: ReserveConfigJSON): ReserveConfig {
return new ReserveConfig({
status: obj.status,
assetTier: obj.assetTier,
hostFixedInterestRateBps: obj.hostFixedInterestRateBps,
reserved2: obj.reserved2,
reserved3: obj.reserved3,
protocolTakeRatePct: obj.protocolTakeRatePct,
protocolLiquidationFeePct: obj.protocolLiquidationFeePct,
loanToValuePct: obj.loanToValuePct,
liquidationThresholdPct: obj.liquidationThresholdPct,
minLiquidationBonusBps: obj.minLiquidationBonusBps,
maxLiquidationBonusBps: obj.maxLiquidationBonusBps,
badDebtLiquidationBonusBps: obj.badDebtLiquidationBonusBps,
deleveragingMarginCallPeriodSecs: new BN(
obj.deleveragingMarginCallPeriodSecs
),
deleveragingThresholdSlotsPerBps: new BN(
obj.deleveragingThresholdSlotsPerBps
),
fees: types.ReserveFees.fromJSON(obj.fees),
borrowRateCurve: types.BorrowRateCurve.fromJSON(obj.borrowRateCurve),
borrowFactorPct: new BN(obj.borrowFactorPct),
depositLimit: new BN(obj.depositLimit),
borrowLimit: new BN(obj.borrowLimit),
tokenInfo: types.TokenInfo.fromJSON(obj.tokenInfo),
depositWithdrawalCap: types.WithdrawalCaps.fromJSON(
obj.depositWithdrawalCap
),
debtWithdrawalCap: types.WithdrawalCaps.fromJSON(obj.debtWithdrawalCap),
elevationGroups: obj.elevationGroups,
disableUsageAsCollOutsideEmode: obj.disableUsageAsCollOutsideEmode,
utilizationLimitBlockBorrowingAbove:
obj.utilizationLimitBlockBorrowingAbove,
reserved1: obj.reserved1,
borrowLimitOutsideElevationGroup: new BN(
obj.borrowLimitOutsideElevationGroup
),
borrowLimitAgainstThisCollateralInElevationGroup:
obj.borrowLimitAgainstThisCollateralInElevationGroup.map(
(item) => new BN(item)
),
})
}
toEncodable() {
return ReserveConfig.toEncodable(this)
}
}