Skip to content

Conversation

@TaprootFreak
Copy link
Collaborator

Summary

  • Fix critical bug in gasless transaction flow ordering
  • EIP-5792 (wallet_sendCalls) now checked before EIP-7702
  • MetaMask 12.20+ handles EIP-7702 internally when using wallet_sendCalls with paymasterService

Problem

The previous code checked EIP-7702 first, which failed because:

  1. Direct EIP-7702 signing requires API changes (EntryPoint v0.8, signature format)
  2. MetaMask handles EIP-7702 internally via wallet_sendCalls - no direct signing needed

Re-opened

Previous PR #863 was accidentally merged. This is a new PR from the original branch.

Test Plan

  • 42 unit tests pass
  • E2E test with MetaMask 13.13.1+ on Sepolia
  • Verify gasless sell flow works for users with 0 ETH

@TaprootFreak TaprootFreak force-pushed the fix/gasless-eip5792-priority branch from 3ee97d6 to 0f8873b Compare January 9, 2026 10:19
@github-actions
Copy link

github-actions bot commented Jan 9, 2026

🤖 PR Review Bot

⚠️ Security: 0 critical, 42 high vulnerabilities


This is an automated review. Please address the issues above.

@TaprootFreak TaprootFreak force-pushed the fix/gasless-eip5792-priority branch from 0f8873b to 99e90ac Compare January 9, 2026 10:34
The tx-helper hook was checking EIP-7702 first, causing failures because:
1. MetaMask 12.20+ handles EIP-7702 internally via wallet_sendCalls
2. Direct EIP-7702 signing has issues (wrong EntryPoint, signature format)

Changes:
- Reorder checks: EIP-5792 first, EIP-7702 as fallback
- Add comprehensive unit tests for gasless flow priority (42 tests)
- Add integration tests for Pimlico paymaster API
- Update E2E tests for multi-wallet support

Priority order now:
1. EIP-5792 (wallet_sendCalls with paymasterService) - MetaMask native
2. EIP-7702 (signEip7702Authorization + confirmSell) - fallback
3. Standard transaction (createTransactionMetaMask)
- Add requirePaymaster parameter to sendCallsWithPaymaster()
- Set optional:false when depositTx.eip5792 exists (user has 0 ETH)
- Remove fallback to standard TX when gasless fails (would fail anyway)
- Fetch paymentInfo with depositTx for EIP-5792 in sell/swap screens
- Update config comment to reflect MetaMask 13.13.1

When user has 0 ETH and wallet doesn't support paymasterService,
MetaMask now returns error code 5700 which propagates to UI
instead of silently attempting an impossible transaction.
- Add API test scripts for gasless flows (EIP-7702, permit, Pimlico)
- Add Synpress test specs for gasless debugging
- Add debug screenshots for MetaMask interactions
- Remove unused variables (index, chainId parameters)
- Replace non-null assertions with conditional spreading
- Remove unused imports (act from @testing-library/react)
- Prefix unused variables with underscore (_originalWindow)
- Update EIP-5792 tests to expect version 2.0.0 format
@TaprootFreak TaprootFreak force-pushed the fix/gasless-eip5792-priority branch from d8c9e29 to bf2140c Compare January 13, 2026 23:38
await page.locator(`[data-testid="import-srp__srp-word-${i}"]`).fill(words[i]);
}
console.log(' Entered seed phrase via individual inputs');
seedEntered = true;
}
await page.waitForTimeout(500);
await page.keyboard.type(seedPhrase, { delay: 30 });
seedFilled = true;

async function getWalletBalances(wallet: ethers.HDNodeWallet): Promise<{ eth: string; usdt: string }> {
const provider = new ethers.JsonRpcProvider(SEPOLIA_RPC);
const connectedWallet = wallet.connect(provider);

const API_URL = process.env.API_URL || 'https://dev.api.dfx.swiss/v1';
const TEST_SEED = process.env.TEST_SEED_2; // Wallet 2 with 0 ETH
const PIMLICO_API_KEY = 'pim_G7dVkmZhrWG76Wq52th5tV'; // From test logs
console.log(' ✓ Got paymaster stub data\n');

// Add paymaster data to userOp
const userOpWithPaymaster = {
/**
* Debug test for gasless transaction - captures all errors
*/
import { test, expect, BrowserContext, Page } from '@playwright/test';
await page.screenshot({ path: 'e2e/screenshots/debug-07-final.png' });
}

async function findPopup(context: BrowserContext): Promise<Page | null> {
return null;
}

async function handleMetaMaskPopup(popup: Page): Promise<string> {
@TaprootFreak
Copy link
Collaborator Author

Code-Review: Produktionscode

Zusammenfassung der Änderungen

Datei Änderung
tx-helper.hook.ts EIP-7702 Flow komplett entfernt, nur noch EIP-5792
metamask.hook.ts sendCallsWithPaymaster auf Version 2.0.0 aktualisiert
sell.screen.tsx Extra receiveFor() Call vor sendTransaction
sell-info.screen.tsx Extra receiveFor() Call vor sendTransaction
swap.screen.tsx Extra receiveFor() Call vor sendTransaction

Probleme gefunden

1. Toter Code - ungenutzte Typen (tx-helper.hook.ts:23-24)

type _SellWithGasless = Sell & GaslessPaymentInfo;
type _SwapWithGasless = Swap & GaslessPaymentInfo;

Diese Typen werden definiert aber nirgends verwendet. Auch GaslessPaymentInfo (Zeile 18-21) wird nicht mehr gebraucht, da der EIP-7702 Flow entfernt wurde.

2. signEip7702Authorization nicht mehr importiert aber existiert noch

  • In tx-helper.hook.ts wurde signEip7702Authorization aus dem Import entfernt
  • Die Funktion existiert aber noch in metamask.hook.ts:322-352
  • Sollte entweder ganz entfernt oder für zukünftige Verwendung behalten werden

3. Doppelter API-Call in allen Screens

// sell.screen.tsx:498-500
const paymentInfoWithTx = await receiveFor(data, true);  // ← Neuer Call
await sendTransaction(paymentInfoWithTx).then(setSellTxId);

Bei jeder Transaktion wird jetzt receiveFor() erneut aufgerufen, obwohl paymentInfo bereits existiert. Das bedeutet:

  • Extra Latenz für den User
  • Extra Last auf dem Backend
  • Was passiert wenn der User genug ETH für Gas hat? Wird trotzdem der Extra-Call gemacht?

4. supportsEip5792Paymaster nicht mehr verwendet

Die Capability-Prüfung wurde entfernt (laut Kommentar weil MetaMask es nicht bewirbt aber unterstützt). Die Funktion existiert noch in metamask.hook.ts:278-293 - sollte sie entfernt werden?


Was macht Sinn

  1. EIP-5792 vor EIP-7702 priorisieren - ✅ Ja, sinnvoll. MetaMask handhabt EIP-7702 intern via wallet_sendCalls
  2. Version 2.0.0 - ✅ Ja, korrekt für aktuelle MetaMask-Versionen
  3. optional: false - ✅ Ja, gibt klaren Fehler wenn Paymaster nicht unterstützt
  4. Value zu Hex konvertieren - ✅ Ja, MetaMask-Anforderung

Empfehlung

Der tote Code sollte aufgeräumt werden:

  • GaslessPaymentInfo Interface entfernen
  • _SellWithGasless / _SwapWithGasless Typen entfernen
  • Entscheiden ob signEip7702Authorization und supportsEip5792Paymaster bleiben sollen (für zukünftige Nutzung) oder entfernt werden

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants