@kamino-finance/klend-sdk
Version:
Typescript SDK for interacting with the Kamino Lending (klend) protocol
324 lines • 14.2 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeTokenName = exports.DefaultConfigParams = exports.DebtConfig = exports.CollateralConfig = exports.AssetReserveConfigCli = exports.AssetReserveConfig = void 0;
exports.getReserveOracleConfigs = getReserveOracleConfigs;
exports.parseOracleType = parseOracleType;
const types_1 = require("../idl_codegen/types");
const decimal_js_1 = __importDefault(require("decimal.js"));
const fraction_1 = require("../classes/fraction");
const bn_js_1 = __importDefault(require("bn.js"));
const classes_1 = require("../classes");
const pubkey_1 = require("./pubkey");
const scope_sdk_1 = require("@kamino-finance/scope-sdk");
class AssetReserveConfig {
mint;
tokenName;
mintDecimals;
mintTokenProgram;
assetReserveConfigParams;
constructor(fields) {
this.mint = fields.mint;
this.tokenName = fields.tokenName;
this.mintDecimals = fields.mintDecimals;
this.mintTokenProgram = fields.mintTokenProgram;
// TODO: verify defaults and ensure opinionated
this.assetReserveConfigParams = exports.DefaultConfigParams;
this.assetReserveConfigParams.priceFeed = fields.priceFeed;
this.assetReserveConfigParams.loanToValuePct = fields.loanToValuePct;
this.assetReserveConfigParams.liquidationThresholdPct = fields.liquidationThresholdPct;
this.assetReserveConfigParams.borrowRateCurve = fields.borrowRateCurve;
this.assetReserveConfigParams.depositLimit = fields.depositLimit;
this.assetReserveConfigParams.borrowLimit = fields.borrowLimit;
}
setAssetConfigParams(assetReserveConfigParams) {
this.assetReserveConfigParams = assetReserveConfigParams;
}
getReserveConfig() {
return buildReserveConfig({
configParams: this.assetReserveConfigParams,
mintDecimals: this.mintDecimals,
tokenName: this.tokenName,
});
}
}
exports.AssetReserveConfig = AssetReserveConfig;
class AssetReserveConfigCli {
mint;
tokenName;
mintDecimals;
mintTokenProgram;
reserveConfig;
assetReserveConfigParams;
constructor(mint, mintTokenProgram, reserveConfig) {
this.reserveConfig = reserveConfig;
this.tokenName = '';
this.mintDecimals = 0;
this.assetReserveConfigParams = exports.DefaultConfigParams;
this.mint = mint;
this.mintTokenProgram = mintTokenProgram;
}
setAssetConfigParams(assetReserveConfigParams) {
this.assetReserveConfigParams = assetReserveConfigParams;
}
setReserveConfig(reserveConfig) {
this.reserveConfig = reserveConfig;
}
getReserveConfig() {
return this.reserveConfig
? this.reserveConfig
: buildReserveConfig({
configParams: this.assetReserveConfigParams,
mintDecimals: this.mintDecimals,
tokenName: this.tokenName,
});
}
}
exports.AssetReserveConfigCli = AssetReserveConfigCli;
class CollateralConfig {
mint;
tokenName;
mintDecimals;
mintTokenProgram;
assetReserveConfigParams;
constructor(fields) {
this.mint = fields.mint;
this.tokenName = fields.tokenName;
this.mintDecimals = fields.mintDecimals;
this.mintTokenProgram = fields.mintTokenProgram;
// TODO: verify defaults and ensure opinionated
this.assetReserveConfigParams = exports.DefaultConfigParams;
this.assetReserveConfigParams.priceFeed = fields.priceFeed;
this.assetReserveConfigParams.loanToValuePct = fields.loanToValuePct;
this.assetReserveConfigParams.liquidationThresholdPct = fields.liquidationThresholdPct;
this.assetReserveConfigParams.borrowLimit = new decimal_js_1.default(0);
}
setAssetConfigParams(assetReserveConfigParams) {
this.assetReserveConfigParams = assetReserveConfigParams;
}
getReserveConfig() {
return buildReserveConfig({
configParams: this.assetReserveConfigParams,
mintDecimals: this.mintDecimals,
tokenName: this.tokenName,
});
}
}
exports.CollateralConfig = CollateralConfig;
class DebtConfig {
mint;
tokenName;
mintDecimals;
mintTokenProgram;
assetReserveConfigParams;
constructor(fields) {
this.mint = fields.mint;
this.tokenName = fields.tokenName;
this.mintDecimals = fields.mintDecimals;
this.mintTokenProgram = fields.mintTokenProgram;
// TODO: verify defaults and ensure opinionated
this.assetReserveConfigParams = exports.DefaultConfigParams;
this.assetReserveConfigParams.priceFeed = fields.priceFeed;
this.assetReserveConfigParams.borrowRateCurve = fields.borrowRateCurve;
}
setAssetConfigParams(assetReserveConfigParams) {
this.assetReserveConfigParams = assetReserveConfigParams;
}
getReserveConfig() {
return buildReserveConfig({
configParams: this.assetReserveConfigParams,
mintDecimals: this.mintDecimals,
tokenName: this.tokenName,
});
}
}
exports.DebtConfig = DebtConfig;
exports.DefaultConfigParams = {
loanToValuePct: 70,
maxLiquidationBonusBps: 500,
minLiquidationBonusBps: 200,
badDebtLiquidationBonusBps: 10,
liquidationThresholdPct: 75,
borrowFeeSf: fraction_1.ZERO_FRACTION,
flashLoanFeeSf: fraction_1.ZERO_FRACTION,
protocolTakeRate: 0,
elevationGroups: [0, 0, 0, 0, 0],
priceFeed: null,
borrowLimit: new decimal_js_1.default(1000.0),
depositLimit: new decimal_js_1.default(1000.0),
borrowRateCurve: new types_1.BorrowRateCurve({
points: [
new types_1.CurvePoint({ utilizationRateBps: 0, borrowRateBps: 1000 }),
new types_1.CurvePoint({ utilizationRateBps: 10000, borrowRateBps: 1000 }),
...Array(9).fill(new types_1.CurvePoint({ utilizationRateBps: 10000, borrowRateBps: 1000 })),
],
}),
maxAgePriceSeconds: 180,
maxAgeTwapSeconds: 240,
};
const encodeTokenName = (tokenName) => {
const buffer = Buffer.alloc(32);
const tokenNameEncoded = new Uint8Array(32);
const s = new TextEncoder().encode(tokenName);
tokenNameEncoded.set(s);
for (let i = 0; i < tokenNameEncoded.length; i++) {
buffer[i] = tokenNameEncoded[i];
}
const result = [...buffer];
return result;
};
exports.encodeTokenName = encodeTokenName;
function buildReserveConfig(fields) {
const reserveConfigFields = {
status: 0,
loanToValuePct: fields.configParams.loanToValuePct,
liquidationThresholdPct: fields.configParams.liquidationThresholdPct,
minLiquidationBonusBps: fields.configParams.minLiquidationBonusBps,
protocolLiquidationFeePct: 0,
protocolTakeRatePct: fields.configParams.protocolTakeRate,
assetTier: 0,
maxLiquidationBonusBps: fields.configParams.maxLiquidationBonusBps,
badDebtLiquidationBonusBps: fields.configParams.badDebtLiquidationBonusBps,
fees: {
borrowFeeSf: fields.configParams.borrowFeeSf.getValue(),
flashLoanFeeSf: fields.configParams.flashLoanFeeSf.getValue(),
padding: Array(6).fill(0),
},
depositLimit: new bn_js_1.default((0, classes_1.numberToLamportsDecimal)(fields.configParams.depositLimit, fields.mintDecimals).floor().toString()),
borrowLimit: new bn_js_1.default((0, classes_1.numberToLamportsDecimal)(fields.configParams.borrowLimit, fields.mintDecimals).floor().toString()),
tokenInfo: {
name: (0, exports.encodeTokenName)(fields.tokenName),
heuristic: new types_1.PriceHeuristic({
lower: new bn_js_1.default(0),
upper: new bn_js_1.default(0),
exp: new bn_js_1.default(0),
}),
maxTwapDivergenceBps: new bn_js_1.default(0),
maxAgePriceSeconds: new bn_js_1.default(fields.configParams.maxAgePriceSeconds),
maxAgeTwapSeconds: new bn_js_1.default(fields.configParams.maxAgeTwapSeconds),
...getReserveOracleConfigs(fields.configParams.priceFeed),
padding: Array(20).fill(new bn_js_1.default(0)),
},
borrowRateCurve: fields.configParams.borrowRateCurve,
depositWithdrawalCap: new types_1.WithdrawalCaps({
configCapacity: new bn_js_1.default(0),
currentTotal: new bn_js_1.default(0),
lastIntervalStartTimestamp: new bn_js_1.default(0),
configIntervalLengthSeconds: new bn_js_1.default(0),
}),
debtWithdrawalCap: new types_1.WithdrawalCaps({
configCapacity: new bn_js_1.default(0),
currentTotal: new bn_js_1.default(0),
lastIntervalStartTimestamp: new bn_js_1.default(0),
configIntervalLengthSeconds: new bn_js_1.default(0),
}),
deleveragingMarginCallPeriodSecs: new bn_js_1.default(0),
borrowFactorPct: new bn_js_1.default(100),
elevationGroups: fields.configParams.elevationGroups,
deleveragingThresholdSlotsPerBps: new bn_js_1.default(7200),
disableUsageAsCollOutsideEmode: 0,
utilizationLimitBlockBorrowingAbove: 0,
hostFixedInterestRateBps: 0,
borrowLimitOutsideElevationGroup: new bn_js_1.default(0),
borrowLimitAgainstThisCollateralInElevationGroup: Array(32).fill(new bn_js_1.default(0)),
reserved1: Array(2).fill(0),
reserved2: Array(2).fill(0),
reserved3: Array(8).fill(0),
};
return new types_1.ReserveConfig(reserveConfigFields);
}
function getReserveOracleConfigs(priceFeed) {
let pythConfiguration = new types_1.PythConfiguration({
price: pubkey_1.NULL_PUBKEY,
});
let switchboardConfiguration = new types_1.SwitchboardConfiguration({
priceAggregator: pubkey_1.NULL_PUBKEY,
twapAggregator: pubkey_1.NULL_PUBKEY,
});
let scopeConfiguration = new types_1.ScopeConfiguration({
priceFeed: pubkey_1.NULL_PUBKEY,
priceChain: [65535, 65535, 65535, 65535],
twapChain: [65535, 65535, 65535, 65535],
});
if (priceFeed) {
const { scopePriceConfigAddress, scopeChain, scopeTwapChain, pythPrice, switchboardPrice, switchboardTwapPrice } = priceFeed;
if (pythPrice) {
pythConfiguration = new types_1.PythConfiguration({ price: pythPrice });
}
if (switchboardPrice) {
switchboardConfiguration = new types_1.SwitchboardConfiguration({
priceAggregator: switchboardPrice ? switchboardPrice : pubkey_1.NULL_PUBKEY,
twapAggregator: switchboardTwapPrice ? switchboardTwapPrice : pubkey_1.NULL_PUBKEY,
});
}
if (scopePriceConfigAddress) {
scopeConfiguration = new types_1.ScopeConfiguration({
priceFeed: scopePriceConfigAddress,
priceChain: scopeChain.concat(Array(4 - scopeChain.length).fill(scope_sdk_1.U16_MAX)),
twapChain: scopeTwapChain.concat(Array(4 - scopeTwapChain.length).fill(scope_sdk_1.U16_MAX)),
});
}
}
return {
pythConfiguration,
switchboardConfiguration,
scopeConfiguration,
};
}
function parseOracleType(type) {
switch (type) {
case new scope_sdk_1.OracleType.Pyth().discriminator:
return 'Pyth';
case new scope_sdk_1.OracleType.SwitchboardV2().discriminator:
return 'SwitchboardV2';
case new scope_sdk_1.OracleType.CToken().discriminator:
return 'CToken';
case new scope_sdk_1.OracleType.KToken().discriminator:
return 'KToken';
case new scope_sdk_1.OracleType.SplStake().discriminator:
return 'SplStake';
case new scope_sdk_1.OracleType.PythEMA().discriminator:
return 'PythEMA';
case new scope_sdk_1.OracleType.DeprecatedPlaceholder1().discriminator:
return 'DeprecatedPlaceholder1';
case new scope_sdk_1.OracleType.DeprecatedPlaceholder2().discriminator:
return 'DeprecatedPlaceholder2';
case new scope_sdk_1.OracleType.MsolStake().discriminator:
return 'MsolStake';
case new scope_sdk_1.OracleType.KTokenToTokenA().discriminator:
return 'KTokenToTokenA';
case new scope_sdk_1.OracleType.KTokenToTokenB().discriminator:
return 'KTokenToTokenB';
case new scope_sdk_1.OracleType.JupiterLpFetch().discriminator:
return 'JupiterLpFetch';
case new scope_sdk_1.OracleType.ScopeTwap().discriminator:
return 'ScopeTwap';
case new scope_sdk_1.OracleType.OrcaWhirlpoolAtoB().discriminator:
return 'OrcaWhirlpoolAtoB';
case new scope_sdk_1.OracleType.OrcaWhirlpoolBtoA().discriminator:
return 'OrcaWhirlpoolBtoA';
case new scope_sdk_1.OracleType.RaydiumAmmV3AtoB().discriminator:
return 'RaydiumAmmV3AtoB';
case new scope_sdk_1.OracleType.RaydiumAmmV3BtoA().discriminator:
return 'RaydiumAmmV3BtoA';
case new scope_sdk_1.OracleType.JupiterLpCompute().discriminator:
return 'JupiterLpCompute';
case new scope_sdk_1.OracleType.MeteoraDlmmAtoB().discriminator:
return 'MeteoraDlmmAtoB';
case new scope_sdk_1.OracleType.MeteoraDlmmBtoA().discriminator:
return 'MeteoraDlmmBtoA';
case new scope_sdk_1.OracleType.JupiterLpScope().discriminator:
return 'JupiterLpScope';
case new scope_sdk_1.OracleType.PythPullBased().discriminator:
return 'PythPullBased';
case new scope_sdk_1.OracleType.PythPullBasedEMA().discriminator:
return 'PythPullBasedEMA';
case new scope_sdk_1.OracleType.FixedPrice().discriminator:
return 'FixedPrice';
default:
return 'Unknown';
}
}
//# sourceMappingURL=managerTypes.js.map