Context
As part of our SPP3 work, we will be drafting an ENSIP that defines standards for stealth address resolution with ENS names.
Below we are outlining the proposed scope and considerations for this ENSIP and would like to engage the ENS community and Ethereum wallet ecosystem for comments and suggestions, before publishing the full ENSIP draft in September.
This ENSIP will be the basis for all other deliverables of the linked SPP3 application.
The Problem
Most ENS names resolve to one static address. This means that every sender or user looking up an ENS sees the recipient’s entire activity and financial history.
By combining ENS and stealth addresses, users can benefit from the UX of having one static identifier (the ENS name) while protecting their privacy by returning a new address for every resolution.
We have been running this in production with Fluidkey for over 2 years, supporting over $1b in transfer volumes across 28k users.
Now we want to ensure other apps can do the same without having to re-build everything from scratch, while creating a standard that ensures interoperability.
Existing Standards & Background Reading
This ENSIP builds on top of ERC-5564: Stealth Addresses.
An incomplete guide to stealth addresses by Vitalik Buterin is a good starting point to learn more about stealth addresses.
Proposed ENSIP Scope
We propose that the ENSIP specifies the three items that follow. These will enable client-side and gateway-based stealth address resolution from an ENS record as outlined in this diagram:
1. A text record for stealth meta-addresses
A new global text record key, registered per ENSIP-5 conventions:
-
Key:
stealth-meta-address[<schemeId>], e.g.stealth-meta-address[1]for SECP256k1 with view tags -
Value: the ERC-5564 meta-address string verbatim, e.g.
st:eth:0x<spendPubKey><viewPubKey>
Why text records: they work today with every deployed resolver, the ENS manager app, and existing tooling. Any wallet can support registration by writing one record.
The default record is valid across all EVM chains (the same keys derive the same addresses on every EVM chain). Users who want distinct keys per chain can set an optional chain-specific record, stealth-meta-address[<schemeId>][<coinType>], resolved with ENSIP-11 precedence: specific coinType first, falling back to the default. Non-EVM scoping would be an ERC-5564 extension and is out of scope here.
2. The resolution flow
Two paths from the same record:
Client-side: the sender’s wallet reads the text record via a standard text() lookup, generates an ephemeral keypair locally, derives the stealth address per ERC-5564, and sends funds. The ENSIP only specifies which record to read and how to parse it.
Gateway-based (CCIP-Read): an offchain resolver generates the stealth address and returns it with the ephemeral secret, verified onchain before the resolution result is returned (see step 3).
Note that addr() itself may already return one-time stealth addresses (the gateway path like with Fluidkey): wallets then get stealth resolution transparently, without any awareness of this standard. The meta-address record is what makes such resolution verifiable onchain and additionally enables client-side derivation.
3. Onchain verification of gateway responses
For the gateway path, the returned stealth address is verified onchain inside the same read call. Resolution reverts on mismatch, so a gateway can never redirect funds to an address that does not derive from the registered meta-address.
schemeId() → uint256
verifyStealthResolution(bytes32 node, address stealthAddr, bytes calldata verificationData) → address | revert
Each verifying resolver is immutable and verifies exactly one ERC-5564 scheme, advertised via schemeId(). Future schemes (e.g. ZK-based verification) are standardized via the ERC process and deployed as new immutable resolvers, with name owners opting in through normal resolver selection. This ensures security by removing the need for an upgradeable contract.
Each ERC-5564 scheme defines its own verificationData. For schemes verified by recomputing the derivation onchain (e.g. scheme 1), it carries the ephemeral secret. The secret exists only inside the sender’s own read call and is never broadcast.
This is a security feature that ensures offchain resolved names are always verified onchain: a gateway can never redirect funds to an address that does not derive from the registered meta-address. Because verification runs in the read path, it adds zero gas to the payment.
–-
Operational guidance such as caching and key rotation best practices will live in the integration guide rather than the ENSIP, to keep the spec minimal.
We will also implement a stateless bridge contract that follows the ERC-6538 read interface backed entirely by ENS records, but this does not need to be included in the ENSIP in our view.
We’d be grateful for your input and questions on the above.
