How binding works
Most apps never do this themselves: the libID sign-in flow does it for the user. This page explains what happens, so you know what a binding rests on. The full rules are in the specification.
flowchart TD U["User in the browser"] -- "signs in" --> P["Platform (trusted)"] P -- "Google: signed token" --> G["Proof that Google signed it"] P -- "GitHub, X: two TLS sessions" --> N["Notary signs the sessions (trusted)"] N --> Z["Proof that one token opened both"] G --> B["Wallet sends bind"] Z --> B B --> V["Proof verifier and platform verifier (trusted)"] V --> I["IdentityNames stores the binding (public)"] class P,N,V trusted class I public
The parties marked trusted must behave: the platform says who owns the account, the notary signs only true records, and the verifiers and their owners check proofs correctly. What the last box stores is public on chain: the wallet, the account id and the handle. The Google path needs no notary, because Google signs its tokens itself.
The steps
Section titled “The steps”- The app asks for a binding. It names the wallet and any service fee. These are hashed into an authorization digest, which the proof will be tied to.
- The user signs in to the platform in a popup, with the normal OAuth sign-in. The digest goes into the sign-in request, so the platform’s answer is tied to this one binding.
- The browser collects evidence.
- For Google, the evidence is the signed sign-in token. A zero-knowledge proof shows that Google signed it, without putting the token on chain.
- For GitHub and X, the browser records two sessions with the platform using TLSNotary: getting the access token, and asking who the user is. A notary signs both records. A zero-knowledge proof shows the two sessions used the same token.
- The wallet sends
bindtoIdentityNameswith the proof, payingquoteBindplus any service fee. - The contracts check it.
IdentityNameshands the proof to the proof verifier, which picks the verifier for that platform and version. The verifier checks the proof, the notary signatures and the time limits, and returns the account id, handle andobservedAt. IdentityNameswrites the binding if the proof is for the calling wallet, has not been used, and is newer than what is stored. It emitsIdentityBound.
What it costs
Section titled “What it costs”quoteBind(platformId, version)returns the verification fee. It is zero for Google. For GitHub and X it is two notary fees, one per recorded session.- The app may add a service fee. The user approves it as part of the digest.
- Gas. Most of it goes to verifying the zero-knowledge proof.
Where to read more
Section titled “Where to read more”- Common ceremony rules: the digest, PKCE, and time limits.
- Identity-platform ceremonies: exactly what is read from each platform.