Skip to content

[Feature] Build an offline-resilient transaction recovery system for interrupted submissions #70

Description

@grantfox-oss

Getting Started

  1. Fork the repository: https://github.com/JointSave-org/Joint_Save
  2. Clone your fork:
   git clone https://github.com/<your-username>/Joint_Save.git
   cd Joint_Save
  1. Create a new branch:
   git checkout -b feat/transaction-recovery-system

Overview

If a user submits a transaction (deposit, withdraw, trigger_payout) and then closes the browser tab, loses internet connectivity, or their device sleeps before the app finishes polling for confirmation, there is currently no way to recover the outcome. The transaction may have actually succeeded on-chain, but the user has no client-side record of it and may assume it failed, risking a double-deposit or duplicate withdrawal attempt. This complements the optimistic-UI work already merged — that makes the UI feel faster, but doesn't yet handle the case where confirmation never arrives because the tab closed.

Requirements

Persisted Pending Transaction Log

  • Before submitting any signed transaction, write a record to localStorage under a key like jointsave:pending-tx:<address>:
  { "hash": "...", "type": "deposit", "poolId": "...", "submittedAt": 1234567890, "amount": "100" }
  • On app load (in web3-provider.tsx or a new TransactionRecoveryProvider), check for any pending transaction records for the connected wallet address
  • For each pending record, query server.getTransaction(hash) to determine the actual outcome:
    • SUCCESS → remove from pending log, show a toast: "Your deposit from earlier completed successfully"
    • FAILED → remove from pending log, show a toast with the failure reason
    • NOT_FOUND after 5 minutes from submittedAt → treat as likely dropped, remove from log, inform the user it may need to be resubmitted

Duplicate Submission Guard

  • Before allowing a new deposit/withdraw/payout submission on the same pool, check if there's already a pending record for that exact pool + action type within the last 2 minutes
  • If so, show a confirmation dialog: "You have a recent pending [action] on this pool. Submit anyway?" rather than blocking outright (the user may have legitimately waited and confirmed it failed)

Acceptance Criteria

  • Closing the tab mid-transaction and reopening the app shows the correct resolved outcome for that transaction
  • Pending transaction records are cleaned up after resolution (no localStorage leak growing unbounded)
  • Duplicate submission guard triggers correctly within the 2-minute window and not after
  • Works correctly across deposit, withdraw, and trigger_payout action types
  • No false positives — a normal single submission never triggers the duplicate warning

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSOfficial CampaignCampaign: Official CampaignfeatureNew functionality to addlow-complexitySimple isolated change

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions