Conversation
WalkthroughAdds explicit handling for an internal paymaster batch named "paymaster-batch": it is filtered out from grouping/counting/rendering in batch views and provider logic, and proactively cleaned up in SendModalTokensTabView during creation and on multiple error paths in the paymaster flow. No exported interface changes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant UI as SendModalTokensTabView
participant BM as BatchManager
participant EST as Estimator
participant TX as Sender
U->>UI: Initiate paymaster send (non-payload)
UI->>BM: Delete batch "paymaster-batch" (pre-clean)
UI->>BM: Create batch "paymaster-batch"
UI->>EST: Estimate "paymaster-batch"
alt Estimation fails
EST-->>UI: Error
UI->>BM: Delete batch "paymaster-batch" (cleanup)
UI-->>U: Show error
else Estimation succeeds
UI->>TX: Send "paymaster-batch"
alt Send fails or missing UserOp hash
TX-->>UI: Error
UI->>BM: Delete batch "paymaster-batch" (cleanup)
UI-->>U: Show error
else Send succeeds
TX-->>UI: Success
UI-->>U: Confirm sent
end
end
note over UI,BM: "paymaster-batch" is internal and excluded from UI lists/counts
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying x with
|
| Latest commit: |
5032e5a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5a967e8e.x-e62.pages.dev |
| Branch Preview URL: | https://fix-paymaster-batch-cleanup.x-e62.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/BottomMenuModal/SendModal/SendModalTokensTabView.tsx (2)
1598-1638: Missing cleanup on cost-warning early return leaves stale paymaster-batchIf the “cost higher than amount” warning triggers, we
returnwithout removing the internal batch. This leaves a stalepaymaster-batchuntil the next send attempt (where it’s cleared at the start). Clean it here too.Apply this diff:
if ( !ignoreSafetyWarning && amountInFiat && costAsFiat > amountInFiat ) { setSafetyWarningMessage( t`warning.transactionSafety.costHigherThanAmount` ); setIsSending(false); transactionDebugLog( 'Batch cost warning: estimated cost higher than amount' ); - return; + try { + kit.batch({ batchName }).remove(); + } catch (e) { + console.warn('Failed to clear paymaster batch after cost warning', e); + } + return; }
1979-2002: Ensure paymaster-batch is cleared on any thrown error in onSendIf an exception occurs anywhere in the paymaster path, we currently don’t remove the internal batch in this catch. Add a best-effort cleanup here to cover unforeseen throw paths.
Apply this diff:
} catch (error: unknown) { + // Best-effort cleanup for internal paymaster batch on any thrown error + if (isPaymaster) { + try { + kit.batch({ batchName: 'paymaster-batch' }).remove(); + } catch (e) { + console.warn('Failed to clear paymaster batch in catch()', e); + } + } Sentry.captureException(error, { tags: { component: 'send_flow', action: 'send_error', sendId, },
🧹 Nitpick comments (6)
src/providers/GlobalTransactionsBatchProvider.tsx (1)
79-85: Exclude internal ‘paymaster-batch’ from counts; consider centralizing the sentinel nameFiltering out
paymaster-batchhere is correct and aligned with the PR goal. To avoid string drift across files, consider centralizing the sentinel in a shared constant (e.g., PAYMASTER_BATCH_NAME) or a small helperisInternalBatch(name)used here and in views.src/components/BottomMenuModal/SendModal/SendModalBatchesTabView.tsx (1)
729-736: Also exclude ‘paymaster-batch’ in the render-time filter for defense-in-depthYou already skip it when grouping, but adding the check here prevents future regressions if the grouping prefilter changes.
Apply this diff:
.filter( ({ batchName }) => batchName && batchName !== 'batch-undefined' && - !batchName.includes('pulse-sell') + !batchName.includes('pulse-sell') && + batchName !== 'paymaster-batch' )src/components/BottomMenuModal/SendModal/SendModalTokensTabView.tsx (4)
1516-1521: Good: proactive pre-clean before creating a new paymaster batchThis avoids stale batches. Wrap
remove()in a try/catch to make cleanup best-effort and avoid bubbling an exception that would skip the send flow.Apply this diff:
- if (existingBatches[batchName]) { - kit.batch({ batchName }).remove(); - } + if (existingBatches[batchName]) { + try { + kit.batch({ batchName }).remove(); + } catch (e) { + console.warn('Failed to clear existing paymaster batch', e); + } + }
1728-1746: Optional: clear paymaster-batch after a successful send once userOpHash is obtainedSince
paymaster-batchis internal and hidden, removing it after successful submission prevents accumulation in state until the next action. It doesn’t affect status polling.Apply this diff:
startUserOpPolling({ userOpHash, chainIdForTxHash, recipientAddress: recipient, amountSent: Number(amount), sendId, }); + // Clear internal batch after successful submission + try { + kit.batch({ batchName }).remove(); + } catch (e) { + console.warn('Failed to clear paymaster batch after successful send', e); + }
1523-1531: Guard against empty approveData before adding the approval transactionIf
approveDatahasn’t been computed yet, the approval tx will be invalid. Add a precondition and surface a user-friendly error.Apply this diff:
// 1. Approval transaction + if (!approveData) { + Sentry.captureMessage('Approval data not ready for paymaster batch', { + level: 'warning', + tags: { component: 'send_flow', action: 'missing_approve_data', sendId }, + }); + handleError(t`error.unableToPrepareApproval`); + return; + } kit .transaction({ chainId: selectedAsset.chainId, to: selectedFeeAsset.token, value: '0', data: approveData, })
1516-1521: Cross-file constant for ‘paymaster-batch’The sentinel name appears in multiple files. Extract a shared
PAYMASTER_BATCH_NAME = 'paymaster-batch'(e.g., in a constants module) and replace string literals to prevent drift.Also applies to: 1569-1571, 1657-1659, 1704-1706
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/components/BottomMenuModal/SendModal/SendModalBatchesTabView.tsx(1 hunks)src/components/BottomMenuModal/SendModal/SendModalTokensTabView.tsx(4 hunks)src/providers/GlobalTransactionsBatchProvider.tsx(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: lint
- GitHub Check: unit-tests
- GitHub Check: build
🔇 Additional comments (4)
src/components/BottomMenuModal/SendModal/SendModalBatchesTabView.tsx (1)
83-85: LGTM: hide internal ‘paymaster-batch’ in groupingSkipping
paymaster-batchat the grouping stage matches the intent to keep it internal.src/components/BottomMenuModal/SendModal/SendModalTokensTabView.tsx (3)
1569-1571: Good: cleanup on estimation failureClearing the failed paymaster batch here is correct.
1657-1659: Good: cleanup on send failureClearing the failed paymaster batch after
sendBatcheserror is correct.
1704-1706: Good: cleanup when userOpHash is missingThis prevents leftover internal batches on this error path.
Description
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Summary by CodeRabbit