feat: SUBS-814 - optimize gas fees for Shield crypto subscription#39931
feat: SUBS-814 - optimize gas fees for Shield crypto subscription#39931chaitanyapotti merged 12 commits intomainfrom
Conversation
…sactions use min(2 * low, medium) formula to reduce over-funding in gas sponsorship Co-authored-by: Cursor <cursoragent@cursor.com>
disableGasBuffer: true already ensures raw gas estimate is used Co-authored-by: Cursor <cursoragent@cursor.com>
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
✨ Files requiring CODEOWNER review ✨🔐 @MetaMask/web3auth (2 files, +354 -9)
|
decGWEIToHexWEI returns hex strings without 0x prefix. Following codebase convention (toHexWei in metamask.js), wrap with addHexPrefix to ensure proper hex format for maxPriorityFeePerGas and maxFeePerGas. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [9491f11]
UI Startup Metrics (1300 ± 97 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Builds ready [9491f11]
UI Startup Metrics (1300 ± 97 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
|
@cursor review |
Add disableGasBuffer to addTransaction options type definition to properly support TransactionController's gas buffer disable feature. This ensures TypeScript recognizes the option and it's passed through to the background controller. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [2332c81]
UI Startup Metrics (1342 ± 95 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Revert disableGasBuffer approach and use explicit estimateGas call for gas limit estimation. This reduces PR complexity while still achieving gas fee optimization via min(2 * low, medium) formula. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@cursor review |
Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [ac032b2]
UI Startup Metrics (1380 ± 112 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
…ation Only set maxPriorityFeePerGas; let the transaction controller derive maxFeePerGas from suggestedGasFees.medium as its default. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [1cb26ea]
UI Startup Metrics (1350 ± 101 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
| data: approvalData, | ||
| }; | ||
| transactionParams.gas = await estimateGas(transactionParams); | ||
|
|
There was a problem hiding this comment.
Missing validation for null internal account
High Severity
The code uses evmInternalAccount?.address as Hex without validating that evmInternalAccount exists. The selector getInternalAccountBySelectedAccountGroupAndCaip can return null, which causes evmInternalAccount?.address to evaluate to undefined. This undefined value is then cast to Hex and passed as the from parameter to addTransaction, which will fail at runtime.
There was a problem hiding this comment.
we don't change evmInternalAccount in this PR, can skip this issue now
| const { gasFeeEstimates, gasEstimateType } = useGasFeeEstimates( | ||
| networkClientId, | ||
| Boolean(networkClientId), | ||
| ) as unknown as { gasFeeEstimates: GasFeeEstimates; gasEstimateType: string }; |
There was a problem hiding this comment.
Type cast bypasses TypeScript safety
Low Severity
The code uses as unknown as to force type cast the return value from useGasFeeEstimates, completely bypassing TypeScript's type checking. This pattern prevents compile-time detection of type mismatches and could cause runtime errors if the actual return type differs from the assumed type, making the code more fragile to upstream changes.
There was a problem hiding this comment.
useGasFeeEstimates is not ts file, so there are no types
Builds ready [e1d6549]
UI Startup Metrics (1358 ± 102 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|


Description
Optimize gas fees for Shield crypto subscription approval transactions to reduce over-funding during gas sponsorship.
Changes:
min(2 * low, medium)for priority fees on EIP-1559 networksuseGasFeeEstimateshook to get real-time gas estimates for the target chaindisableGasBuffer: trueto prevent automatic gas limit buffering by TransactionControllerestimateGascall (TransactionController handles this internally)Changelog
CHANGELOG entry: Optimized gas fees for Shield crypto subscription transactions to reduce sponsorship costs
Related issues
Fixes: SUBS-814
Manual testing steps
maxPriorityFeePerGasuses the optimized formulaScreenshots/Recordings
Before
N/A - Internal gas fee changes, no UI changes
After
N/A - Internal gas fee changes, no UI changes
Pre-merge author checklist
Pre-merge reviewer checklist
Made with Cursor
Note
Medium Risk
Touches transaction-parameter construction for subscription approval flows; mistakes could lead to underpriced transactions or failures on EIP-1559 networks, though guarded by estimate-type checks and tests.
Overview
Reduces over-funding of Shield crypto subscription approval transactions by overriding the EIP-1559
maxPriorityFeePerGasonshieldSubscriptionApprovetransactions usingmin(2 × low, medium)from liveuseGasFeeEstimatesfor the token’s chain.Adds a focused unit test suite for
useSubscriptionCryptoApprovalTransactioncovering fee-market vs legacy networks and missing/invalid estimates, and updates the Jest console baseline to allow the new test’s Router warnings.Written by Cursor Bugbot for commit e1d6549. This will update automatically on new commits. Configure here.