Authentication

Zing Protocol uses zkLogin to provide a Web2-style authentication experience. You can sign in with your Google account β€” no seed phrases, no private keys, no crypto complexity. This guide explains how the authentication system works.

How zkLogin Works

zkLogin is a groundbreaking authentication method that bridges Web2 ease-of-use with Web3 capabilities:

  1. Ephemeral Keypair - A temporary keypair is generated in your browser
  2. Nonce Creation - A unique nonce is created for this session
  3. Google OAuth - You authenticate with your Google account
  4. zkProof Generation - A zero-knowledge proof is generated proving you're the Google user
  5. Sui Address Derivation - Your Sui address is deterministically derived from your Google account
// Authentication flow in the app
const login = useWalletStore((s) => s.login)
await login('google') // Initiates Google OAuth flow

// Session data stored in zkloginStorage
interface ZkLoginSession {
  jwt: string // JWT token from Google
  suiAddress: string // Your Sui blockchain address
  maxEpoch: number // Session expiration epoch
  ephemeralSecretKey: string // Temporary signing key
  zkProof: object // Zero-knowledge proof
}

The Authentication Flow

Step 1: Initiate Login

When you click "Continue with Google":

# Frontend generates ephemeral keypair
const ephemeralKeyPair = new Ed25519Keypair();

// Create nonce for this session
const nonce = generateNonce(ephemeralKeyPair.getPublicKey());

// Redirect to Google OAuth
window.location.href = `${googleAuthUrl}?nonce=${nonce}`;

Step 2: Google OAuth

You complete authentication with Google in their standard OAuth flow:

# Google OAuth parameters
{
  client_id: YOUR_GOOGLE_CLIENT_ID,
  redirect_uri: YOUR_APP_REDIRECT_URI,
  response_type: "id_token",
  scope: "openid email profile",
  nonce: PROVIDED_NONCE,
}

Step 3: Return with JWT

Google redirects back with an ID token (JWT):

{
  "sub": "google-user-id",
  "email": "user@gmail.com",
  "name": "Creator Name",
  "picture": "https://...",
  "nonce": "provided-nonce"
}

Step 4: Generate zkProof

The frontend generates a zkProof using the JWT:

// Using @mysten/sui SDK
const zkProof = await generateZkProof({
  jwt: idToken,
  ephemeralPublicKey: ephemeralKeyPair.getPublicKey(),
  maxEpoch: currentEpoch + 10,
  nonce: providedNonce,
})

Step 5: Derive Sui Address

Your Sui address is derived from the Google user ID and a salt:

# Address derivation (simplified)
suiAddress = f(googleUserId, salt, ephemeralPublicKey)

# Example Sui address
0x7a8d9c0b1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b

Session Management

Sessions are persisted in localStorage via zkloginStorage:

// Session is automatically managed by the wallet store
const isConnected = useWalletStore((s) => s.isConnected)
const suiAddress = useWalletStore((s) => s.suiAddress)

// Logout clears the session
const logout = useWalletStore((s) => s.logout)
await logout()

Supported Providers

Currently, only Google is supported for zkLogin:

ProviderStatusNotes
Googleβœ… SupportedFull OAuth + zkLogin integration
TwitchπŸ”œ PlannedComing soon
FacebookπŸ”œ PlannedComing soon
AppleπŸ”œ PlannedComing soon

Security Considerations

Key Features

  • No Seed Phrases - Your Google account is the only auth factor
  • Zero-Knowledge Proofs - Google never sees your Sui address
  • Ephemeral Keys - Temporary keys expire automatically
  • Sui Native - All transactions are native to Sui blockchain

Session Expiration

// Sessions expire after maxEpoch
interface ZkLoginSession {
  maxEpoch: number // After this epoch, session is invalid
}

// To continue using after expiration:
// Must re-authenticate with Google

Using the API

When making API requests, authentication is handled automatically:

# All API requests include the JWT from zkLogin
curl https://api.zing.protocol/v1/articles \
  -H "Authorization: Bearer {jwt_token}"

# The backend validates the JWT and extracts the Sui address

Integration with SDKs

// Using the Zing SDK (when available)
import { ZingClient } from '@zing/sdk'

const client = new ZingClient({
  provider: 'google', // or 'twitch' etc.
})

// SDK handles all zkLogin complexity
await client.connect()

Best Practices

Next Steps

Was this page helpful?