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 fetches the Kind 35522 from the relay URL in the e tag to confirm a trusted Identity Authority (IA) attested to this linkage. If the relay returns the event and it is not expired, the connection is considered Verified.

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 Kind 35522 fetched from the e tag relay is invalid, missing, or revoked.⚠️ 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.