Getting Started
- Fork the repository: https://github.com/JointSave-org/Joint_Save
- Clone your fork:
git clone https://github.com/<your-username>/Joint_Save.git
cd Joint_Save
- 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
Getting Started
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
localStorageunder a key likejointsave:pending-tx:<address>:{ "hash": "...", "type": "deposit", "poolId": "...", "submittedAt": 1234567890, "amount": "100" }web3-provider.tsxor a newTransactionRecoveryProvider), check for any pending transaction records for the connected wallet addressserver.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 reasonNOT_FOUNDafter 5 minutes fromsubmittedAt→ treat as likely dropped, remove from log, inform the user it may need to be resubmittedDuplicate Submission Guard
Acceptance Criteria