Skip to main content

Verification Model

When a client application (like a wallet or a social client) parses a Proxy Request (Kind 5523) or its resultant Zap Receipt (Kind 5521), it needs to resolve the legacy identifier into a native Nostr identity to display a "Verified" rich profile.

This protocol implements a deterministic, network-based verification model to balance speed and security.

The Identity Lookup

The verification flow relies on querying the Nostr network for an Identity Connection (Kind 35521) that binds the target identifier hash to a Nostr Public Key.

How it works:

  1. The client extracts the 3-element identity tag (e.g., ["p", "<ConnectionKey>", "discord"]).
  2. It constructs a filter query targeting the Nostr network (and specifically the ZSP's relays):
{
"kinds": [35521],
"#d": ["<ConnectionKey>"]
}
  1. The client receives the 35521 event.
  2. (Optional but Recommended) The client verifies the s tag signature embedded within the 35521 event to definitively prove a trusted Zap Settlement Provider (ZSP) attested to this linkage.

Verification States

Clients should map the outcome of this query to clear UI indicators:

StateOutcomeRecommended UI
VerifiedValid 35521 event found, mapping the hash to a Nostr Key.✅ Native Nostr Profile
Pending (Fallback)No 35521 event found.⏳ Fallback LIDP Profile (e.g., Discord Avatar fetched from the ZSP API)
Spoofed35521 found, but the ZSP's cryptographic attestation within the s tag is invalid or missing.⚠️ Red Warning ("Unverified / Suspicious")

By following this model, clients ensure that users are only shown verified identities when cryptographic proof has been surfaced, falling back gracefully to custodial profiles when the user hasn't completed their Claim Flow.