The parties
The flow
1
Your backend creates an authorization request
It names your verifier DID, a reason shown to the user, and a callback URL that includes a session ID. Your backend stores the request so it can check the answer later.
2
The user opens it in the wallet
Your frontend Base64-encodes the request into a Universal Link that opens the Billions Wallet. The wallet shows the user what’s being asked.
3
The wallet answers with a signed token
If the user approves, the wallet signs a JWZ (JSON Web Zero-knowledge) token. For a credential request, it also generates a zero-knowledge proof against the credential.
4
The wallet posts the token to your callback
The token arrives at your callback URL, tagged with the session ID.
5
Your backend verifies it
It verifies the token against the stored request. The verified response gives you the user’s DID and, for a credential request, the proof.
Login versus credential verification
Stopping repeat claims
A credential proof carries a nullifier: a privacy-preserving identifier derived from the person’s identity and anullifierSessionId that your app chooses for a campaign. Keep that value fixed and the same person always produces the same nullifier, so you can record the nullifiers you accept and refuse repeats, even from a different account. Use a different value for a different campaign and the same person’s nullifiers can’t be linked between them. Each request still gets its own session ID, which ties the wallet’s answer to that request. This is what makes one-reward-per-person possible without learning who anyone is.
Related
- Credentials: what each credential proves.