Reference
SDK reference
zkauth-client exports ZKAuthSDK, the official JavaScript/TypeScript client. It runs the password crypto locally (Argon2id, Poseidon, Groth16 via snarkjs), so the password never leaves the device, and keeps your session in memory after login.
Constructor
import { ZKAuthSDK } from 'zkauth-client'
const zkauth = new ZKAuthSDK({ apiKey: process.env.ZKAUTH_API_KEY!, // zka_live_... or zka_test_... baseUrl: 'https://api.zkauth.dev', // optional timeout: 30000, // optional, ms debug: false, // optional})| Option | Type | Notes |
|---|---|---|
apiKey | string | Required. Project key. |
baseUrl | string | Defaults to the hosted engine. |
timeout | number | Request timeout in ms (default 30000). |
debug | boolean | Verbose logging. |
clientId | string | Optional; fetched automatically if omitted. |
Authentication
register(params)
Derives a salt and commitment from the password on the client and registers the user. deviceInfo is required.
const res = await zkauth.register({ email: 'ada@example.com', password: 'SecurePassword123!', // min 8 chars, stays on device deviceInfo: { deviceName: 'Chrome on Mac', deviceType: 'desktop' },})// res.data -> { userId, email, emailVerified, verificationToken?, deviceId }login(params)
Fetches the salt, generates a Groth16 proof locally, and exchanges it for a session. The token is returned and also stored on the instance.
const res = await zkauth.login({ email: 'ada@example.com', password: 'SecurePassword123!', deviceInfo: { deviceName: 'Chrome on Mac', deviceType: 'desktop' },})// res.data -> { user, session, mfaRequired?, deviceApprovalRequired? }const token = res.data.session.tokenSession helpers
await zkauth.getCurrentUser() // -> User | nullzkauth.isAuthenticated() // -> booleanzkauth.getSession() // -> Session | nullawait zkauth.logout() // clears the in-memory sessionverifyEmail(token) / getSalt(email)
// register() may return data.verificationToken in devawait zkauth.verifyEmail(token)Password reset
A reset can require approval depending on your project’s policy. Reset email links return to your allowlisted callback URL with zkauth_action=password_reset and token, then your app calls resetPassword with the new password.
await zkauth.forgotPassword({ email: 'ada@example.com' })await zkauth.verifyResetToken(token)await zkauth.resetPassword({ token, newPassword: 'NewSecret123!', email })Devices
List, trust, verify, and remove devices for the authenticated user.
await zkauth.getDevices() // -> Device[]await zkauth.registerDevice({ deviceInfo }) // trust a new deviceawait zkauth.verifyDevice({ deviceId, proof, publicSignals, proofNonce, proofTimestamp })await zkauth.removeDevice(deviceId)MFA status
getMFAStatus() -> { mfaEnabled, totpEnabled, backupCodesGenerated, availableMethods }.
TOTP setup, recovery codes, session management, and the transparency endpoints aren’t wrapped by the client yet; call them over the HTTPS API with your session token.
OPAQUE & WebAuthn helpers
Thin wrappers over the engine’s OPAQUE and WebAuthn endpoints, for building those browser flows through your proxy:
opaqueStatus(),opaqueRegistrationResponse(),opaqueRegistrationFinish(),opaqueLoginStart(),opaqueLoginFinish()webAuthnRegistrationOptions(),webAuthnRegistrationVerify(),webAuthnAuthenticationOptions(),webAuthnAuthenticationVerify()
Events
Subscribe to lifecycle events: login, logout, register, session_expired, mfa_required, device_approval_required, error.
const off = zkauth.on('login', (user) => console.log('signed in', user.email))zkauth.on('session_expired', () => redirectToLogin())off() // unsubscribeErrors
Failures throw a ZKAuthError with a code from ZKAuthErrorCode (e.g. AUTHENTICATION_ERROR, VALIDATION_ERROR, SESSION_EXPIRED, UNAUTHORIZED).
import { ZKAuthError, ZKAuthErrorCode } from 'zkauth-client'
try { await zkauth.login({ email, password })} catch (e) { if (e instanceof ZKAuthError && e.code === ZKAuthErrorCode.AUTHENTICATION_ERROR) { // wrong credentials / failed proof }}Wire it into a framework in Examples.