Seed phrases are the #1 reason mainstream users bounce off crypto. ZK Social Login removes them: the user taps “Sign in with Google” and walks away with a real on-chain smart account on YouthChain — fully self-custodial, no key to write down or leak. Under the hood, a Groth16 zero-knowledge proof attests that a valid Google JWT authorizes a short-lived session key, without revealing the user’s sub, aud, or email. That session key signs ordinary transactions. It’s the same model as Sui zkLogin and Aptos Keyless.
Proof of concept — testnet only. Not audited. Do not use on mainnet. The full flow is validated end-to-end with a real production Google JWT, but the trusted-setup ceremony, salt-service custody, recovery, and audit are still open (see Security model).

How it works

1

Ephemeral session key

The app generates a throwaway session keypair and computes nonce = Poseidon(ephemeralPubkey, sessionExpiry, randomness).
2

Google OAuth

Google signs an id_token (JWT) that embeds that nonce — cryptographically binding the login to the session key.
3

Prove (server-side)

The zk-backend derives the user’s salt (HKDF, stateless) and produces a Groth16 proof that the JWT is validly signed and binds the ephemeral key — without revealing sub, aud, or email. This takes ~1–2 minutes on the first login.
4

Account & transact

The proof unlocks a deterministic CREATE2 smart account (address = f(iss, aud, sub, salt) — same Google account always maps to the same wallet). The session key signs transactions; the relayer submits them via execute (anti-replay, gas paid for you).

What you integrate

You touch two things: the OAuth step, and the SDK. Everything else — salt derivation, proving, relaying, contracts — is encapsulated by the zk-backend and the SDK.
1

Install the SDK

Pure TypeScript, runs in Node and React Native, and carries only ethers + poseidon-lite (the heavy proving key stays server-side).
2

Wire Google Sign-In

Run native Google Sign-In (e.g. AppAuth / Expo AuthSession) with the nonce from the SDK. Google returns the id_token — that’s all the SDK needs from you.
3

One call: JWT → wallet → transaction

SDK surface

The public API is the YouthWallet class plus a few protocol helpers.
The ~1–2 min proving time only happens once per session (the first login). Show a “Creating your wallet…” state. On-device proving (seconds, via Mopro) is a phase-2 optimization.

The backend dependency

The SDK requires a hosted zk-backend. The prover needs the ~588 MB Groth16 proving key, so it cannot run on-device. Point backendUrl at your deployment.
The zk-backend (Fastify) exposes: A 4 vCPU / 8 GB host is enough for the MVP.

Testnet configuration

Deployed on the YouthChain EVM testnet.
The Client ID (aud) is part of the account address (f(iss, aud, sub, salt)). Changing it later changes every user’s address. Fine for the MVP; pin the canonical aud before production.

Security model

Honest about the trade-offs of a POC:
  • Trust boundary. Key theft requires both Google and the salt service to collude. Google alone never learns the salt; the backend alone has no JWT bound to the right nonce.
  • The relayer custodies nothing — it only pays gas.
  • JWK rotation is handled by an on-chain JwksRegistry (owner-gated) fed by a poller that tracks Google’s ~weekly RSA key rotation.
  • Ephemeral sessions. One proof authorizes one session key with a fixed expiry; the next login rotates it.
Open decisions before production: a real Groth16 trusted-setup ceremony, salt-service key custody, multi-provider account recovery, a security audit, and pinning the canonical aud.

Next steps

Blockchain integration

The rest of the on-chain flow — faucet, transactions, engagement rewards.

Mobile integration

Wiring engagement actions and rewards into a mobile app.