/** * @file status-api.ts * @notice Status API for bridge transfer tracking */ import { ethers } from 'ethers'; import { WorkflowEngine, TransferStatus } from './workflow-engine'; import { BridgeEscrowVault } from '../../contracts/bridge/interop'; export interface TransferStatusResponse { transferId: string; status: TransferStatus; depositor: string; asset: string; amount: string; destinationType: number; destinationData: string; timestamp: number; timeout: number; refunded: boolean; executionData?: { txHash?: string; blockNumber?: number; finalityBlocks?: number; xrplTxHash?: string; fabricTxId?: string; error?: string; }; route?: { chainId: number; chainName: string; provider: string; estimatedTime: number; fee: string; healthScore: number; }; isRefundable: boolean; refundDeadline?: number; } export class StatusAPI { private workflowEngine: WorkflowEngine; private provider: ethers.Provider; private escrowVault: ethers.Contract; constructor( workflowEngine: WorkflowEngine, rpcUrl: string, escrowVaultAddress: string, escrowAbi: any[] ) { this.workflowEngine = workflowEngine; this.provider = new ethers.JsonRpcProvider(rpcUrl); this.escrowVault = new ethers.Contract(escrowVaultAddress, escrowAbi, this.provider); } /** * Get transfer status */ async getStatus(transferId: string): Promise { // Get on-chain transfer data const transfer = await this.escrowVault.getTransfer(transferId); // Get workflow status const workflowStatus = this.workflowEngine.getStatus(transferId); // Check refund eligibility const isRefundable = await this.workflowEngine.isRefundable(transferId); // Calculate refund deadline const refundDeadline = transfer.timestamp + transfer.timeout; return { transferId, status: workflowStatus || this.mapOnChainStatus(transfer.status), depositor: transfer.depositor, asset: transfer.asset, amount: transfer.amount.toString(), destinationType: Number(transfer.destinationType), destinationData: ethers.toUtf8String(transfer.destinationData), timestamp: Number(transfer.timestamp), timeout: Number(transfer.timeout), refunded: transfer.refunded, isRefundable, refundDeadline: Number(refundDeadline) }; } /** * Get status for multiple transfers */ async getBatchStatus(transferIds: string[]): Promise { return Promise.all(transferIds.map(id => this.getStatus(id))); } /** * Get transfers by depositor */ async getTransfersByDepositor( depositor: string, limit: number = 50, offset: number = 0 ): Promise { // This would typically query a database or indexer // For now, return empty array - implement with event indexing return []; } /** * Get transfers by status */ async getTransfersByStatus( status: TransferStatus, limit: number = 50, offset: number = 0 ): Promise { // This would typically query a database or indexer // For now, return empty array - implement with event indexing return []; } /** * Map on-chain status to workflow status */ private mapOnChainStatus(status: number): TransferStatus { const statusMap: Record = { 0: TransferStatus.INITIATED, 1: TransferStatus.DEPOSIT_CONFIRMED, 2: TransferStatus.ROUTE_SELECTED, 3: TransferStatus.EXECUTING, 4: TransferStatus.DESTINATION_SENT, 5: TransferStatus.FINALITY_CONFIRMED, 6: TransferStatus.COMPLETED, 7: TransferStatus.FAILED, 8: TransferStatus.REFUND_PENDING, 9: TransferStatus.REFUNDED }; return statusMap[status] || TransferStatus.INITIATED; } }