-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Context & Impact
Forms for stream creation, token distribution, and offramp transactions have no protection against rapid repeated submissions. A user can double-click the submit button or press Enter multiple times, triggering duplicate blockchain transactions. There is no debounce on submit handlers and no disabled state during transaction processing beyond a basic isSubmitting flag that may not cover all edge cases.
Why this matters: Duplicate blockchain transactions waste gas fees and can cause unintended double-payments. In the distribution flow, this could mean sending tokens twice to all recipients. In stream creation, it could create duplicate streams. These are irreversible on-chain actions.
Scope
- Disable submit buttons immediately on first click and keep them disabled until the transaction completes or fails
- Add visual loading state (spinner) to submit buttons during processing
- Prevent form re-submission via Enter key while a transaction is in flight
- Add a cooldown period after successful submission to prevent accidental rapid re-creation
- Ensure all three flows are covered: stream creation, distribution, and offramp
Implementation Guidelines
- Use React Hook Form's
isSubmittingstate consistently across all forms - Disable the submit button with
disabled={isSubmitting}AND add a spinner/loading indicator - Add
pointer-events-noneCSS during submission as an additional guard - For Enter key submission, check
isSubmittingin theonSubmithandler before proceeding - After success, add a 2-second cooldown before re-enabling the button
- Consider a global
useTransactionGuardhook that manages submission state
Acceptance Criteria
- Stream creation button is disabled during transaction submission
- Distribution button is disabled during transaction submission
- Offramp button is disabled during transaction submission
- All submit buttons show a loading spinner during processing
- Double-clicking a submit button does not trigger duplicate transactions
- Pressing Enter rapidly does not trigger duplicate submissions
- A 2-second cooldown prevents immediate re-submission after success
- Failed submissions re-enable the button for retry
Getting Started
- Review
src/components/modules/payment-stream/PaymentStreamForm.tsx— check submit button state - Review
src/components/organisms/DistributionForm.tsx— check submit handling - Review
src/components/offramp/OfframpForm.tsx— check submit handling - Ensure all use
isSubmittingfrom React Hook Form or mutation state - Add spinner component to all submit buttons during loading
- Add
pointer-events-noneas CSS backup during submission - Test by clicking submit rapidly — verify only one transaction is created
PR Submission Guide
This section applies to every PR for this issue. Follow it exactly.
Before You Start
- Fork the repository first if you haven't already — all contributions must come from a fork
- Pull the latest
mainbranch:git checkout main && git pull origin main - Create your feature branch from
main:git checkout -b feat/<issue-number>-form-rate-limiting
While Working
- Make atomic commits — one concern per commit, each commit must build
- Use Conventional Commits:
feat(scope): description,fix(scope): description - Keep your branch up to date:
git pull origin main --rebaseregularly
Before Submitting the PR
- Pull latest
mainand rebase:git checkout main && git pull origin main && git checkout <your-branch> && git rebase main - Ensure the build passes:
pnpm build - Ensure linting passes:
pnpm lint - Record a screen recording of your implementation showing the feature/fix working in the browser. Attach it to the PR.
PR Requirements
- Link this issue in your PR description using
Closes #<issue-number> - Fill out the full PR template — Summary, What Was Implemented, Implementation Details, How to Test
- Attach your screen recording demonstrating the implementation
- Request a review from a maintainer
PRs without a screen recording or without a linked issue will not be reviewed. Failure to meet PR requirements may lead to PR rejection.