Skip to content

Task 2-2: Paymaster Balance Monitoring

Phase: 2 Priority: Medium Module: biconomy Depends on: Không có Reference: docs/bountyhunter-blockchain-p2/details/feature-evm-integration/SPEC.md

Background

Hiện tại không có cơ chế nào theo dõi số dư Paymaster của Biconomy. Khi Paymaster cạn tiền, các giao dịch gasless sẽ thất bại âm thầm — job có thể treo trong queue hoặc fail với lỗi không rõ ràng, ảnh hưởng trực tiếp đến trải nghiệm người dùng. Cần có scheduled job kiểm tra định kỳ và cảnh báo kịp thời trước khi hết số dư.

Tasks

Note: @nestjs/schedule cần được import vào BiconomyModule (hoặc AppModule). Kiểm tra xem ScheduleModule.forRoot() đã được import chưa trước khi thêm — nếu chưa, thêm vào module root. Inject HttpService (từ @nestjs/axios) để gọi Biconomy API. @Cron decorator import từ @nestjs/schedule.

  • [ ] Kiểm tra BiconomyModule đã import ScheduleModule.forRoot() chưa; nếu chưa, thêm vào AppModule hoặc BiconomyModule
  • [ ] Tạo method checkPaymasterBalance() trong BiconomyService (hoặc tạo PaymasterMonitorService riêng):
    @Cron('0 */6 * * *') // Mỗi 6 tiếng
    async checkPaymasterBalance(): Promise<void> {
      for (const chainId of GASLESS_SUPPORTED_NETWORK) {
        const apiKey = BICONOMY_KEY[chainId]?.paymasterApiKey;
        if (!apiKey) continue;
    
        try {
          const balance = await this.fetchPaymasterBalance(apiKey, chainId);
          const threshold = this.configService.get<number>('PAYMASTER_LOW_BALANCE_THRESHOLD', 0.1);
    
          if (balance < threshold) {
            this.logger.error(
              `[PAYMASTER_MONITOR] chainId=${chainId} balance=${balance} BELOW threshold=${threshold} — refill required!`
            );
            // TODO: gọi webhook alert nếu có
          } else {
            this.logger.log(
              `[PAYMASTER_MONITOR] chainId=${chainId} balance=${balance} OK`
            );
          }
        } catch (error) {
          this.logger.error(
            `[PAYMASTER_MONITOR] Failed to check balance for chainId=${chainId}: ${error.message}`
          );
        }
      }
    }
    
  • [ ] Implement fetchPaymasterBalance(apiKey, chainId) gọi Biconomy Paymaster API để lấy số dư
  • [ ] Thêm PAYMASTER_LOW_BALANCE_THRESHOLD vào .env.example (đơn vị: ETH/BNB tương ứng chain)
  • [ ] Nếu project có webhook alert infrastructure, gọi thêm để notify team

Verification / Acceptance Criteria

  • [ ] Scheduled job chạy đúng theo cron expression (có thể test bằng cách set interval ngắn hơn trong dev)
  • [ ] Log [PAYMASTER_MONITOR] xuất hiện mỗi 6 tiếng trong production logs
  • [ ] Khi balance < threshold → log ở level ERROR với thông tin đầy đủ chainId và số dư
  • [ ] Khi balance đủ → log ở level LOG (info)
  • [ ] Module import ScheduleModule.forRoot() không duplicate (chỉ import 1 lần ở root)
  • [ ] TypeScript compile không có lỗi

Files to Modify

  • src/biconomy/biconomy.service.ts (thêm checkPaymasterBalance method)
  • src/biconomy/biconomy.module.ts (import ScheduleModule nếu chưa có)
  • .env.example (thêm PAYMASTER_LOW_BALANCE_THRESHOLD)