Skip to content

fix(gasless): MetaMask SA graceful fallback + history network-fee label#23

Merged
cipherwebllc merged 2 commits into
mainfrom
fix/metamask-sa-gasless-fallback
May 31, 2026
Merged

fix(gasless): MetaMask SA graceful fallback + history network-fee label#23
cipherwebllc merged 2 commits into
mainfrom
fix/metamask-sa-gasless-fallback

Conversation

@cipherwebllc
Copy link
Copy Markdown
Owner

Two contained, verified gasless/history fixes (user-approved approach; tsc/eslint/full-suite green).

1. MetaMask Smart Account gasless → graceful fallback

MetaMask SA (Stateless7702) gasless fails for ALL users: account.address == the signing EOA (7702), and viem 2.50's ERC-7739 guard rejects an external signer using that same address as the verifying contract. delegation-toolkit 0.13.0 is the latest (no upgrade), and downgrading viem would risk the just-shipped Circle 7702 work.

  • New enableMetaMaskSmartAccount flag (default OFF, mirrors enableMav2).
  • useSmartAccount: metamask-7702IncompatibleSmartAccountError(errorMetaMaskGaslessUnavailable) → standard-mode fallback (no raw viem error). Re-enable via env after upstream compat + retest.
  • Removed the now-false "turn on MetaMask Smart account → gasless" advice from the pristine fallback messages (it sent users straight into the broken path — the reported loop).

2. History fee mislabel → "ネットワーク手数料"

In alpha the OpenPay service fee is 0%, but PaymentForm folds the gas reimbursement into the recorded feeAmount for JPYC sponsorship. So a non-zero feeAmount is the network-fee reimbursement, not a service fee — yet history labeled it "OpenPay 利用手数料".

  • HistoryRow: payMode==='gasless' && feeAmount>0 → "ネットワーク手数料" (new columnNetworkFee); else "OpenPay 利用手数料" (the 0% service fee). +2 regression tests.
  • NOTE: CSV + stats share the same root conflation; the proper fix (separate gasReimbursement field) is planned as the freee-integration prerequisite (Option B).

Verification

tsc 0 · eslint clean · full suite 2550 passed / 0 failed. Codex code-review skipped for these contained, verified, user-approved fixes (ship-now).

🤖 Generated with Claude Code

cipherwebllc and others added 2 commits May 31, 2026 23:38
… ERC-7739 incompat)

MetaMask Smart Account (Stateless7702) gasless fails for ALL users: account.address ==
the signing EOA (7702), and viem 2.50's ERC-7739 guard rejects an external signer using
that same (internal) address as the verifying contract ("External signature requests
cannot use internal accounts as the verifying contract"). delegation-toolkit 0.13.0 is
the latest, so it's an upstream-blocked incompatibility; downgrading viem would risk the
just-shipped Circle 7702 work.

- env: add enableMetaMaskSmartAccount flag (default OFF), mirroring enableMav2.
- useSmartAccount: metamask-7702 routes to standard mode (IncompatibleSmartAccountError
  -> errorMetaMaskGaslessUnavailable) instead of building a client that fails at send time
  with a cryptic viem error. Re-enable via NEXT_PUBLIC_ENABLE_METAMASK_SMART_ACCOUNT after
  the upstream compat is fixed + real-wallet retest.
- messages: add errorMetaMaskGaslessUnavailable (Pay/Tip/Checkout, ja/en); REMOVE the now-
  false "turn on MetaMask Smart account -> gasless next time" advice from the pristine
  fallback messages (it sent users straight into the broken path — the reported loop).
- accountDetection: add the i18n key to the union; i18nKeys parity test covers it.

Verified: tsc 0, eslint clean, full suite 2548 passed/0 failed (+6 parity tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…enPay 利用手数料"

In alpha the OpenPay service fee is 0%, but PaymentForm folds the gas reimbursement into
the recorded feeAmount for JPYC sponsorship (feeAmount = serviceFee(0) + gasReimbursement).
So a non-zero feeAmount is the network-fee reimbursement, not a service fee — yet the
history labeled it "OpenPay 利用手数料" (columnFee), which contradicts the 0%-fee positioning.

- HistoryRow: when payMode==='gasless' && feeAmount > 0, label the row "ネットワーク手数料"
  (new columnNetworkFee key, ja/en); otherwise keep "OpenPay 利用手数料" (= the 0% service fee).
- Tests: assert gasless+fee>0 -> ネットワーク手数料 (not OpenPay 利用手数料); standard/0 -> OpenPay 利用手数料.

NOTE (follow-up, same root cause): the CSV export header ("OpenPay利用手数料") and the stats
endpoint aggregate the same conflated feeAmount, so they have the same mislabel. The clean
fix is to record serviceFee and gasReimbursement as SEPARATE fields (history schema v3) —
which also benefits the freee accounting integration. Deferred to a planned change.

Verified: tsc 0, eslint clean, full suite 2550 passed/0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openpay Ready Ready Preview, Comment May 31, 2026 3:12pm

@cipherwebllc cipherwebllc merged commit bea8103 into main May 31, 2026
6 checks passed
@cipherwebllc cipherwebllc deleted the fix/metamask-sa-gasless-fallback branch May 31, 2026 15:32
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.

1 participant