A robust send-transaction flow persists the pending transaction request locally before broadcasting, so if the app crashes or loses connectivity mid-flow, it can recover and retry rather than silently losing user intent.
interface PendingTx {
id: string;
to: string;
amountWei: string;
status: "queued" | "broadcasting" | "confirmed" | "failed";
}
function enqueue(queue: PendingTx[], tx: Omit<PendingTx, "status">): PendingTx[] {
return [...queue, { ...tx, status: "queued" }];
}
function markStatus(queue: PendingTx[], id: string, status: PendingTx["status"]): PendingTx[] {
return queue.map((t) => (t.id === id ? { ...t, status } : t));
}On app relaunch, replaying any "queued" or "broadcasting" transactions found in persisted storage (after checking their actual on-chain status first, to avoid double-sends) closes this reliability gap.