Skip to main content
Zap uses Supabase project wzrdstudio for creator wallet authentication and bring-your-own-key (BYOK) provider secret storage. All creator API keys are encrypted server-side before being written to the database and are revealed in plaintext only during authenticated live runs — never returned to the browser. The /settings page lets creators connect their wallet and manage BYOK keys; the /api/secrets route proxies all secret operations through the zap-user-secrets edge function.

Environment Variables

The web app requires three Supabase variables. Set them in Vercel and in your local .env.local:
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY is the current Supabase naming convention. NEXT_PUBLIC_SUPABASE_ANON_KEY is the equivalent legacy alias — set whichever matches your Supabase dashboard.

Database Migration

Apply the migration at supabase/migrations/20260703000000_zap_user_secrets.sql before enabling live BYOK runs.
The migration creates or extends the user_secrets table with the full encrypted storage shape:
It also creates wallet_auth_users and wallet_auth_nonces tables, unique indexes, and a full set of Row Level Security policies so that each user can only access their own secrets.
The existing user_secrets table (if present from an earlier deployment) and the legacy manage-user-secrets edge function are not aligned with the encrypted shape above. Apply this migration and redeploy the zap-user-secrets edge function before any live BYOK runs depend on Supabase, or encrypted key retrieval will fail.

Row Level Security

RLS is enabled and forced on user_secrets, wallet_auth_users, and wallet_auth_nonces. The policies enforce:
  • SELECT, INSERT, UPDATE, DELETE on user_secrets are scoped to auth.uid() = user_id
  • SELECT on wallet_auth_users is scoped to auth.uid() = user_id
  • No direct browser access to wallet_auth_nonces — nonce records are written and consumed only by edge functions
Only JWT-protected edge functions return masked secret metadata to the browser. Server-side runtime paths may retrieve plaintext keys only for the authenticated owner of the active run, using the x-zap-server-secret header alongside the user JWT.

Edge Functions

Deploy both functions with supabase functions deploy <name>.

zap-user-secrets

Handles list, save, and delete of encrypted BYOK secrets. Returns masked metadata (e.g. last4) to the browser; returns plaintext only to the Zap server. Required Supabase secrets:
Access model: The ZAP_SECRET_REVEAL_TOKEN must match the value set in Vercel’s environment variables. This shared secret is what restricts plaintext reveals to the Zap server only.

zap-wallet-proof

Handles EIP-191 wallet signature verification and Supabase Auth session minting for wallet-based login. Required Supabase secrets:
Flow:
  1. Client submits a signed EIP-191 payload and a one-time nonce to /api/auth/wallet-proof
  2. The Next.js route proxies the request to zap-wallet-proof (or the function named in ZAP_WALLET_PROOF_FUNCTION)
  3. The function verifies the wallet signature, confirms the nonce has not been used, and records it in wallet_auth_nonces
  4. It creates or reuses a Supabase Auth user mapped in wallet_auth_users (keyed by wallet address)
  5. Supabase Auth mints a session token, which is returned to the client
ZAP_WALLET_TOKEN_TTL_SECONDS controls session lifetime; 604800 equals seven days.
SUPABASE_URL and SUPABASE_SECRET_KEYS are injected automatically by the Supabase Edge Function runtime — do not set them manually. The legacy SUPABASE_SERVICE_ROLE_KEY is also supported if your project uses it.

BYOK Secret Types

The following secret_type values are supported by the zap-user-secrets edge function. Each maps to a provider credential a creator can supply via /settings. Do not use the legacy profiles.*_api_key columns for Zap provider execution. All provider credentials for live runs must go through the encrypted user_secrets table and the zap-user-secrets edge function.