ERC PR : TODO
DEMO : Link
Abstract
With EIP-5792, applications can communicate advanced execution preferences to wallets via capabilities. This proposal introduces the privacyPaymaster capability, enabling applications to request that compatible wallets fund gas using a user-controlled, privacy-preserving paymaster.
The dapp expresses intent; the wallet enforces privacy.
All gas payment logic — including paymaster selection, gas payment preparation, and gas payment authorization — is performed within the wallet, without exposing user identity, internal state, or paymaster details to the application.
Motivation
Today, gas payment is an implicit identity leak.
Even when users employ privacy-preserving mechanisms for value transfer, the address paying for gas remains publicly visible and linkable across interactions. This creates a persistent identity layer that existing privacy tools do not fully address.
Existing solutions such as paymasterService (ERC-7677) rely on application-specified external services. These introduce trusted third parties capable of correlating activity, censorship and liveness dependencies, and leakage of user intent and metadata.
Users who configure privacy-preserving paymasters in their wallets currently have no standardized way to signal this capability to applications, ensure wallets automatically use privacy-preserving gas payment, or prevent fallback to identity-linked gas.
This proposal defines a capability that restores control to the user. The wallet determines how gas is paid. The dapp only declares intent. No external service is required for correctness. No user state is exposed. Unlike paymasterService, where the dapp selects the gas sponsor, privacyPaymaster ensures the user — via their wallet — is the sole authority over how gas is funded.
Specification
The key words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” are to be interpreted as described in RFC 2119.
Overview
The privacyPaymaster capability is implemented entirely by the wallet. The wallet maintains one or more user-configured privacy paymaster providers. The underlying mechanism — whether zero-knowledge proofs, stealth funding, or any other construction — is an implementation detail and is not exposed to the application.
When a wallet_sendCalls request includes the privacyPaymaster capability, the wallet:
- Validates the capability object.
- Selects an appropriate provider from internal configuration.
- Estimates gas internally.
- Assembles the final transaction with all fields finalized.
- Prepares gas payment using the selected provider entirely client-side.
- Incorporates the resulting gas payment authorization into the transaction.
- Presents the final transaction to the user for approval.
- Submits for execution.
Note for implementors: This specification is agnostic to the underlying AA execution model. The following illustrates how the abstract terms above map to concrete models:
- ERC-4337: The transaction object is a
UserOperation, gas payment authorization ispaymasterAndData, and submission is to a bundler.- EIP-7702: The transaction object is a type
0x04set-code transaction. When used with ERC-4337 infrastructure, thepaymasterAndDatamodel applies. Without it, gas payment authorization is handled by the delegated contract’s paymaster module and submission is to the standard mempool.- EIP-8141 (Draft — targeted for Hegotá): The transaction object is a Frame Transaction (type
0x06). Gas payment authorization is expressed in the VERIFY frame’sAPPROVEcall. Submission is directly to the mempool without a bundler.
Wallets MUST apply the constructs appropriate to their execution model. The normative requirements above apply regardless of which model is used.
The application is not involved in provider selection, gas estimation, gas payment preparation, or paymaster configuration.
Capability Response
Wallets signal support via wallet_getCapabilities on each chain where a privacy paymaster is configured.
{
"0x2105": {
"privacyPaymaster": {
"supported": true
}
},
"0xa": {
"privacyPaymaster": {
"supported": true
}
}
}
A chain absent in the response, or present with "supported": false, indicates no privacy paymaster is configured for that chain.
The capability response MUST NOT include provider configuration, balances, or any internal user state.
Capability Request
Applications include the privacyPaymaster capability in wallet_sendCalls to request privacy-preserving gas payment.
{
"version": "2.0.0",
"chainId": "0x2105",
"calls": [
{
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"data": "0xd09de08a"
}
],
"capabilities": {
"privacyPaymaster": {
"optional": false
}
}
}
The optional field MUST be explicitly set to either true or false. An empty capability object (i.e., optional field absent) is invalid and MUST be rejected by the wallet with error code 5700, consistent with EIP-5792 error handling.
Best effort example, where the wallet uses a privacy paymaster if available, otherwise proceeds normally:
{
"version": "2.0.0",
"chainId": "0x2105",
"calls": [
{
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"data": "0xd09de08a"
}
],
"capabilities": {
"privacyPaymaster": {
"optional": true
}
}
}
Invalid example, where the wallet MUST reject with error 5700:
{
"version": "2.0.0",
"chainId": "0x2105",
"calls": [
{
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"data": "0xd09de08a"
}
],
"capabilities": {
"privacyPaymaster": {}
}
}
When optional is false:
- The wallet MUST use a privacy paymaster for gas payment.
- If the capability cannot be satisfied (no configured provider, insufficient balance, preparation failure), the wallet MUST reject the request.
- The wallet MUST NOT silently fall back to an alternative gas payment method.
When optional is true:
- The wallet SHOULD use a privacy paymaster if one is configured and satisfiable.
- If the capability cannot be satisfied, the wallet MAY proceed with default gas payment behavior.
Wallet Requirements
Wallets that support the privacyPaymaster capability:
-
MUST signal support via
wallet_getCapabilitieson each chain where a privacy paymaster is configured. -
MUST maintain user-configured provider(s) internally. Provider selection, contract addresses, and implementation specifics MUST NOT be exposed to the application.
-
MUST NOT expose provider configuration, balances, or any internal user state to the application in any capability field or response.
-
MUST ensure that gas payment preparation does not leak user identity, transaction intent, or linkage between gas funding and usage.
-
MUST present the final transaction to the user for approval before submission.
-
MUST reject a
wallet_sendCallsrequest where theprivacyPaymastercapability object is empty with error code5700. -
MUST reject a
wallet_sendCallsrequest ifoptionalisfalseand the capability cannot be satisfied. -
MUST NOT silently fall back to an alternative gas payment method if
optionalisfalse. -
MUST prioritize
privacyPaymasterover anypaymasterServicecapability present in the same request whenprivacyPaymastercan be satisfied. -
MUST ensure that gas payment authorizations cannot be reused across transactions and that replay attacks are prevented.
-
SHOULD allow users to designate a default provider in wallet settings when multiple providers are configured.
Rationale
Separation of responsibilities
The dapp declares intent. The wallet enforces execution. The provider implements the mechanism. This layering minimizes trust assumptions and prevents identity leakage at every level. It is the same principle that motivates wallet_-namespaced RPCs in EIP-5792 — pushing execution authority into the wallet rather than the application.
Why a new capability instead of extending paymasterService
The paymasterService capability (ERC-7677) is fundamentally server-driven: the dapp supplies a URL and the wallet makes RPC calls to an external service. The privacyPaymaster capability inverts this entirely — the wallet is the sole actor. There is no URL, no external RPC, and no server involvement required for correctness. These are architecturally incompatible models that warrant separate capability keys.
Why the dapp specifies no provider details
Exposing provider configuration would enable dapp-side fingerprinting, leak implementation details, and increase attack surface. All such data remains wallet-internal. The dapp’s only role is to declare intent: enforce or optionally request privacy-preserving gas payment.
Why an empty capability object is invalid
Unlike paymasterService which requires a url field, privacyPaymaster carries no required configuration from the dapp. However, optional determines fundamentally different wallet behavior — enforced rejection versus graceful fallback. Allowing an empty object would introduce ambiguity about the dapp’s intent and risk silent, undetected privacy failures. Requiring explicit optional ensures dapps are deliberate about their privacy requirements, consistent with the spirit of EIP-5792 capability design.
Why internal user state is excluded from capability fields
Internal wallet state such as balance or spending history must not be exposed to dapps. Exposing it would allow dapps to fingerprint users, track activity, and potentially correlate on-chain events with specific users — directly undermining the privacy guarantee the capability exists to provide.
Why optional: false enforces rejection rather than silent fallback
Silent fallback from privacy gas to identity-linked gas is a privacy failure mode the user cannot detect. Making rejection explicit when optional is false ensures users and apps have a clear, auditable signal that privacy guarantees were or were not upheld.
Why privacyPaymaster takes priority over paymasterService
If both capabilities are present in a wallet_sendCalls request, privacyPaymaster reflects explicit user configuration for privacy-preserving gas. Allowing paymasterService to override it would violate user intent and re-introduce the identity linkage the user configured to avoid.
Security Considerations
Client-side preparation integrity
All gas payment preparation MUST occur client-side within the wallet’s isolated execution context. Provider-specific secret material MUST NOT be accessible to content scripts, injected page scripts, or dapp-controlled execution contexts.
Silent fallback prevention
Wallets MUST NOT silently downgrade to identity-linked gas payment when optional is false. Any failure in the gas payment preparation phase MUST surface as an explicit error to the dapp and user.
Submission layer considerations
The submission layer observes transactions before inclusion and may attempt to correlate them. Wallets SHOULD consider the trust model of the submission endpoint and the potential for timing or metadata correlation at that layer.
Replay and double-spend protection
Wallets and paymaster providers MUST ensure that gas payment authorizations cannot be reused across transactions and that replay attacks are prevented.
paymasterService conflict
A dapp may include both paymasterService and privacyPaymaster in the same request. Wallets MUST prioritize privacyPaymaster when it is configured and satisfiable, ignoring the paymasterService field entirely in that case.
Non-Goals
This proposal does not:
- Standardize the privacy mechanism used by providers.
- Define paymaster contract interfaces or on-chain protocol requirements.
- Guarantee specific anonymity set sizes or privacy levels.
- Prescribe submission-layer behavior or submission-layer privacy properties.
- Replace or modify
paymasterService(ERC-7677) for application-sponsored gas use cases.
Backwards Compatibility
This ERC introduces a new capability key privacyPaymaster. Wallets that do not implement this capability will not include it in wallet_getCapabilities responses. Apps SHOULD check for capability support before including privacyPaymaster in wallet_sendCalls requests, or SHOULD mark it as optional: true to gracefully degrade on unsupported wallets.
Apps that include privacyPaymaster with optional: false on wallets that do not support it will receive a standard EIP-5792 unsupported capability error (5700), consistent with existing EIP-5792 error handling.
The wallet_getCallsStatus response is unaffected by this capability. The dapp uses the standard EIP-5792 wallet_getCallsStatus flow to track transaction status. Whether gas was paid via a privacy paymaster or another mechanism is not reflected in the status response, consistent with the principle that gas payment details are wallet-internal.
Copyright
Copyright and related rights waived via CC0.