Legacy Identity Providers (LIDP)
A Legacy Identity Provider (LIDP) is any traditional identity or social platform that a Zap Settlement Provider (ZSP) uses to verify a user's ownership of an account.
As an open protocol, Zapf allows developers to integrate new LIDPs. By binding these accounts to Nostr public keys, anyone with a Discord, Telegram, X, or GitHub account can receive Lightning payments — even if they've never interacted with Nostr or Lightning before.
Supported LIDPs
| LIDP | Stable Identifier | Verification Method |
|---|---|---|
| Discord | Username (e.g. loki_nakamo) | Bot Challenge — user runs /nostr-verify <pre_auth_code> in a channel; posts npv1 challenge publicly |
| Telegram | @username (e.g. @loki_nakamo) | Bot Challenge — user runs /nostr_verify <pre_auth_code> in a channel; posts npv1 challenge publicly |
| X (Twitter) | @handle | Challenge Token — user posts a message containing the code |
| GitHub | @username | Challenge Token — user creates a Gist containing the code |
@username | Challenge Token — user puts the code in their bio | |
| Profile URL | Challenge Token — user posts the code on their profile | |
| Domain | Domain name | Challenge Token — user adds a TXT DNS record |
user@example.com | OTP — ZSP sends a one-time code to the inbox |
The stable identifier (not the display name) is used as the handle in zap receipts. This means the displayed name stays consistent even if the user changes their display name on the platform.
The Privacy Model
Every connection is identified by a hashed ConnectionKey — the raw identifier (like your Discord user ID or email) is never published to the network in the d tag itself.
However, the Kind 35522 evidence tag always contains user_id and username in cleartext and is publicly readable on the relay. Profile metadata in the Kind 35521 content field is also always public JSON. There is no private mode for identity connections.
Verification Methods
LIDPs use two verification approaches:
1. Challenge Token (X, GitHub, Instagram, Facebook, Domain, Discord, Telegram)
All supported providers (except email) use the same public-proof model: the user publicly posts an npv1 challenge token — a bech32-encoded, session-bound proof — and submits the public URL as evidence.
Direct (X, GitHub, Instagram, Facebook, Domain):
- The user receives the
npv1token from the Zapf web app. - The user publishes it on their account (tweet, gist, bio, DNS TXT record, etc.).
- The user submits the link; the ZSP fetches the content, checks the token is present, and issues a Kind 35522 Attestation.
Bot-assisted (Discord, Telegram):
- The user receives a pre-auth code from the web app.
- The user runs
/nostr-verify <pre_auth_code>(Discord) or/nostr_verify <pre_auth_code>(Telegram) in a community channel. - The bot responds with the
npv1challenge and binds the session on the IA. - The user posts the challenge publicly in the same channel and submits the message link.
- The ZSP verifies the public post and issues a Kind 35522 Attestation.
The bot automates challenge issuance and link-checking; the underlying proof model (public npv1 post + evidence_url) is identical to the direct flow.
2. OTP (Email)
The ZSP sends a one-time code to the user's inbox. The user submits the code to prove ownership. The ZSP issues the attestation immediately upon correct submission.