|
| 1 | +import { Injectable, Logger } from '@nestjs/common'; |
| 2 | +import { Server } from 'stellar-sdk'; |
| 3 | +import { ConfigService } from '@nestjs/config'; |
| 4 | +import { isBelowThreshold } from './utils/threshold-evaluator'; |
| 5 | + |
| 6 | +@Injectable() |
| 7 | +export class ReserveMonitorService { |
| 8 | + private readonly logger = new Logger(ReserveMonitorService.name); |
| 9 | + private server: Server; |
| 10 | + |
| 11 | + constructor(private readonly config: ConfigService) { |
| 12 | + this.server = new Server(this.config.get<string>('HORIZON_URL') || 'https://horizon-testnet.stellar.org'); |
| 13 | + } |
| 14 | + |
| 15 | + async checkAssetReserve(assetCode: string, issuer: string, threshold: number): Promise<{ below: boolean; current: number }> { |
| 16 | + try { |
| 17 | + const account = await this.server.loadAccount(issuer); |
| 18 | + const bal = account.balances || []; |
| 19 | + if (assetCode === 'XLM') { |
| 20 | + const native = bal.find((b: any) => b.asset_type === 'native'); |
| 21 | + const current = parseFloat(native?.balance || '0'); |
| 22 | + return { below: isBelowThreshold(current, threshold), current }; |
| 23 | + } |
| 24 | + |
| 25 | + const found = bal.find((b: any) => b.asset_code === assetCode && b.asset_issuer === issuer); |
| 26 | + const current = parseFloat(found?.balance || '0'); |
| 27 | + return { below: isBelowThreshold(current, threshold), current }; |
| 28 | + } catch (err) { |
| 29 | + this.logger.error(`Failed to fetch reserve for ${assetCode}:${issuer}`, err); |
| 30 | + // On error consider it below to trigger alerting downstream |
| 31 | + return { below: true, current: 0 }; |
| 32 | + } |
| 33 | + } |
| 34 | +} |
0 commit comments