POAPrivacy
Mint POAPs to stealth addresses. Prove attendance without doxxing your physical location.
Problem Statement
Private POAPs with Stealth AddressesThe ProblemStandard POAPs create a public, on-chain link between an identity (e.g., "name.eth"`) and a physical location. This is a privacy risk. Anyone can track your attendance at events, which can compromise personal security.The SolutionThis project severs that link. It mints a POAP to a new, single-use stealth address. On-chain, the transaction appears to go to a random, unlinked account. Only the intended recipient can find and control this address.The Process1. One-Time Setup: User Registration (ERC-6538)A user performs a one-time setup.Key Generation:The wallet creates two key pairs: aspending key(controls the POAP) and aviewing key(finds the POAP).Meta-Address Creation:The corresponding public keys form thestealth meta-address.Registration:The user registers this meta-address in the publicERC-6538 Registry. The registry connects an identity like "name.eth" to the meta-address for lookup.2. The Mint: Issuing the POAP (ERC-5564)The process for a POAP issuer is direct. The user scans a QR code to claim an NFT. The link opens in their browser. They can choose a stealth address or their ENS to receive the POAP to. If they choose their ENS, the POAP is automatically sent to one of the stealth addresses that the user owns.Lookup:The issuer gets the user's identifier ("name.eth"`) and queries the ERC-6538 Registry to get their stealth meta-address.Generate Address:The issuer's system uses the user's meta-address and a new, temporary key ("ephemeral address") to compute the unique stealth address.Mint:The system mints the POAP (an ERC-721 token) to this new stealth address.Announce:The issuer publishes an "Announcement" on the main ERC-5564 Announcer contract. This event contains the data needed for the recipient to find the transaction.3. Discovery and Access: Viewing the POAPThe recipient finds their POAP by opening the website.Scan:The recipient's private viewing key is used to scan allAnnouncementevents on the ERC-5564 contract.Check:A "view tag" in the announcement allows the wallet to discard most non-matching events with minimal computation.Derive Key:When the wallet finds a match, it uses the user'sspending private keyto calculate the private key for the stealth address.Control:The user now controls the POAP. They can import the private key associated with that account in any wallet in order to control their POAP balance and any other currency on that address. The link to their public identity is broken.
Solution
How It's MadePPOAP(Privacy-Preserving Proof of Attendance Protocol) solves a privacy issue in POAPs. Public on-chain data can reveal a person's location. We mint POAPs to single-use, anonymous stealth addresses. This breaks the link between a user's public identity and their event attendance.The project is aNext.jsapplication built withTypeScript.Core TechnologiesFrontend:The UI usesNext.jsandReact. Styling is done withTailwind CSS. Asynchronous state, like fetching POAP data, is managed byTanStack Query.Authentication (Privy):Privyis the authentication layer. It handles user login and wallet connections. This provides a known public identity (e.g.,name.eth) for registry lookups while enabling the private stealth flow.Privacy Engine (Stealth Addresses):ERC-5564:This is the foundation for the privacy mechanism. The logic inapp/utils/stealth-address.jsimplements the cryptographic flow. A sender uses the recipient'sstealth meta-addressto compute a new stealth address that only the recipient can control.ERC-6538:This standard defines theStealth Meta-Address Registry, an on-chain directory. A user can link their public address to their stealth meta-address. The application includes ABIs and functions (getMetaAddress.js,setMetaAddress.js) to use this registry.POAP API Integration:The application uses the official POAP APIs. It uses the Collectors API to validate claims and fetch metadata. It uses the Minting API to execute the mint to the generated stealth address.Passkeys for Key GenerationHandling raw private keys is a poor user experience and a security risk. Our solution usesPasskeys (WebAuthn)to generate these keys deterministically, without direct user interaction with the keys. Theapp/utils/pass-keys.jsmodule contains this logic.The flow is:Credential Creation:A user creates a Passkey for the app. The device generates aPublicKeyCredentialsecured by biometrics.Deterministic Signing:To generate keys, the user authenticates with the Passkey. This signs a static message (e.g.,"cannes-love-poap").Key Derivation (HKDF):The signature is used as input for aKey Derivation Function (HKDF). We use ERC-5564 salts (EIP-5564-spending-key,EIP-5564-viewing-key) to derive the 32-bytespendingandviewingprivate keys.Meta-Address Generation:The system uses these private keys and the@noble/secp256k1library to compute compressed public keys and construct the finalstealth meta-address.This method provides cryptographic privacy through a biometric login. The same Passkey generates the same stealth keys. The keys are not stored; they are derived on-the-fly.The User JourneyUser scans QR code or NFC.User opens a PPOAP claim page (e.g.,/claim/ethcannes).The frontend fetches POAP details from the POAP API.The user selects"Get Anon Address". This starts the Passkey flow (initializeStealthAddress) and derives thestealth meta-address.ThegenerateStealthAddressfunction computes the final, single-usestealthAddress.This address appears in a disabled input field.The user selects"Mint Now". The app sends a request to the POAP API to mint the POAP to thestealthAddress.The on-chain transaction shows a mint to an anonymous address. The user's privacy is protected.
Hackathon
ETHGlobal Cannes
2025
Prizes
- 🏆
Most Creative Use Case2nd place
ENS
- 🏆
🏆 ETHGlobal Cannes 2025 Finalist
ETHGlobal
Contributors
- Skanislav
31 contributions
- gepng
29 contributions
- enjojoy
19 contributions
- rainbowpuffpuff
2 contributions