import { Connection, PublicKey } from '@solana/web3.js';
import { KaminoObligation } from './kamino-sdk';
class AutoDeleverageMonitor {
constructor(
private connection: Connection,
private obligation: PublicKey
) {}
async checkDeleveragingStatus() {
const obligationData = await this.loadObligation();
if (obligationData.autodeleverageMarginCallStartedTimestamp === 0) {
console.log("✓ Obligation not marked for deleveraging");
return {
marked: false,
targetLtv: null,
markedAt: null,
timeRemaining: null,
};
}
const markedAt = obligationData.autodeleverageMarginCallStartedTimestamp;
const targetLtv = obligationData.autodeleverageTargetLtvPct;
const currentTime = Math.floor(Date.now() / 1000);
// Fetch lending market to get grace period
const lendingMarketData = await this.loadLendingMarket(
obligationData.lendingMarket
);
const gracePeriod = lendingMarketData.individualAutodeleverageMarginCallPeriodSecs;
const deadline = markedAt + gracePeriod;
const timeRemaining = Math.max(0, deadline - currentTime);
console.log(`⚠️ MARKED FOR DELEVERAGING`);
console.log(` Target LTV: ${targetLtv}%`);
console.log(` Marked At: ${new Date(markedAt * 1000)}`);
console.log(` Time Remaining: ${this.formatTime(timeRemaining)}`);
return {
marked: true,
targetLtv,
markedAt,
timeRemaining,
deadline,
};
}
async calculateCurrentLTV(): Promise<number> {
const obligationData = await this.loadObligation();
const depositedValue = obligationData.depositedValueSf;
const borrowedValue = obligationData.borrowedAssetsMarketValueSf;
if (depositedValue === 0) return 0;
return (borrowedValue / depositedValue) * 100;
}
async suggestDeleverageActions() {
const status = await this.checkDeleveragingStatus();
if (!status.marked) return [];
const currentLtv = await this.calculateCurrentLTV();
const targetLtv = status.targetLtv!;
if (currentLtv <= targetLtv) {
return ["Current LTV is below target - contact market owner to unmark"];
}
const ltvReduction = currentLtv - targetLtv;
return [
`Option 1: Repay ${ltvReduction.toFixed(2)}% of debt`,
`Option 2: Deposit more collateral to reduce LTV`,
`Option 3: Combination of repayment and collateral deposit`,
`⏰ Time remaining: ${this.formatTime(status.timeRemaining!)}`,
];
}
private formatTime(seconds: number): string {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
return `${hours}h ${minutes}m`;
}
private async loadObligation() {
// Load and deserialize obligation account
const accountInfo = await this.connection.getAccountInfo(this.obligation);
return deserializeObligation(accountInfo!.data);
}
private async loadLendingMarket(lendingMarket: PublicKey) {
const accountInfo = await this.connection.getAccountInfo(lendingMarket);
return deserializeLendingMarket(accountInfo!.data);
}
}
// Usage
const monitor = new AutoDeleverageMonitor(connection, userObligation);
// Check status
const status = await monitor.checkDeleveragingStatus();
// Get suggestions
const actions = await monitor.suggestDeleverageActions();
actions.forEach(action => console.log(action));