Skip to main content
Vercel is the recommended way to host My Crypto Server. The app is a standard Next.js 16 App Router project, so it deploys with zero config. The flow is:
  1. Deploy the repo to Vercel.
  2. Set a handful of env vars you generate yourself (secrets + your URL).
  3. Connect two integrations from the Vercel marketplace — a Postgres database (Supabase or Neon) and Inngest. These inject their own env vars automatically.
  4. Finish everything else in-app under Integrations (Alchemy, payment providers, email). No more env vars needed.

1. Create your repo and deploy it

  1. Generate your own copy of the source: on the private repo you were invited to (github.com/mycserver/app), click Use this template → Create a new repository. Create it under your own account and keep it private.
    Use the template button — don’t fork and don’t push a manual copy. The template gives you a clean, independent repo owned entirely by you, which is what lets Vercel deploy it without committer-verification issues, and what lets updates arrive later as pull requests.
  2. Import your new repo at vercel.com/new.
  3. Vercel detects everything automatically — leave the build settings exactly as they are and click Deploy.
Don’t worry if the first deploy fails — it will, until the database and env vars below are in place. You’ll redeploy once at the end.

2. Set the main environment variables

In Vercel → your project → Settings → Environment Variables, add these. These are the only ones you set by hand — everything else is injected by an integration or configured in the dashboard later.

Secrets — required

How to generate them

Each of these needs to be a long, random, unguessable string (32+ characters). Generate a different value for each one — never reuse the same secret across variables. If you have a terminal, run this once per variable and paste the output:
That prints a fresh 32-byte random string, e.g. nvtbziY8taKuQeDVxannyXGm4irTAtxzMj0k5p2Qw1c=. Run it three times to get three different values. No terminal? Use a web generator instead — the easiest is the 1Password Password Generator: set the length to 32+ characters, click the refresh icon for a new value, and copy it. Generate one for each variable. Another option is generate-secret.vercel.app/32 — just reload the page for a fresh value each time.
MASTER_PASSPHRASE is the key that encrypts your wallet. If you lose it you lose access to your funds — store a copy in a password manager before you deploy. Changing it later invalidates all previously encrypted keys.

Your URL — required

On your very first deploy you won’t know the final URL yet. Deploy once with a placeholder, copy the URL Vercel gives you, update both vars, and redeploy.
That’s the complete list — five variables. Everything else (chains, confirmations, session timing) has a sensible built-in default, and services like the database, Inngest, Alchemy, and email are configured through integrations, not env vars.

3. Connect the integrations

Both of these live in Vercel → your project → Integrations → Browse Marketplace. Connecting them provisions the service and injects the env vars automatically — you don’t copy any connection strings by hand.

Database: Supabase or Neon

Either works — both are just Postgres. There’s nothing to copy by hand: add the integration, connect it to your project, and the app auto-detects the env vars it injects.
Add the Supabase integration from the marketplace, create a database, and connect it to your project. It injects POSTGRES_URL, POSTGRES_PRISMA_URL, and POSTGRES_URL_NON_POOLING, which the app maps to its pooled and direct connections automatically. The free tier is generous enough to run a real store.
Either way you never touch a connection string — the integration provides both the pooled connection (for request handlers) and the direct one (for migrations). See Database Setup for details.

Workflows: Inngest

Add the Inngest integration from the marketplace. It injects INNGEST_EVENT_KEY and INNGEST_SIGNING_KEY. Inngest runs the durable workflows behind payments — session lifecycle, confirmation waiting, sweeps, and webhook delivery. Its free tier covers roughly 50k steps/month (~4 steps per payment). After your first successful deploy, point Inngest at your app so it discovers your functions: in the Inngest dashboard, sync the app URL https://your-app.vercel.app/api/inngest. You should see 5 functions appear (sessionLifecycle, paymentVerify, webhookDeliver, reconcileAlchemy, cleanupIdempotency).

4. Redeploy

With the env vars and integrations in place, trigger a fresh deploy (Deployments → ⋯ → Redeploy). Everything else is set up automatically — this deploy should go green.

5. Finish setup in the dashboard

Everything else is configured inside the running app — no more env vars.
  1. Visit /setup and create your owner account (email + password).
  2. Complete the onboarding wizard: seed phrase, networks, payout addresses, and the Security step (enable email-OTP 2FA).
  3. Go to Integrations → Alchemy, enter your API key + auth token, and enable it. Payment-detection webhooks are created automatically per chain the first time a session needs one — there’s no provisioning step.
  4. (Optional) Add any payment providers (MoonPay, Mercuryo, NOWPayments, CoinGate, Banxa…) under Integrations → <provider>. Credentials are per-merchant and live in the dashboard, not in env vars.
  5. (Optional) Enable email under Integrations → Resend: paste your Resend API key and a from-address. This powers 2FA codes, team invites, password resets, and checkout receipts. The key is stored encrypted in the database — there’s no email env var.
See Authentication for 2FA, team invites, and API keys.

Troubleshooting

First deploy fails Expected — the app needs a database first. Connect the Supabase or Neon integration to your project, then redeploy. Deploy still fails after connecting the database Make sure the integration is connected to this project (not just installed on your account), then redeploy so it picks up the connection. Inngest functions not appearing Open https://your-app.vercel.app/api/inngest in a browser. If you see a page of data (not an error), it’s working — then sync the app URL in the Inngest dashboard.