> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cryptocheckout.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments

> Which project is which, what is authoritative, and the stale references that have caused deploys to the wrong place.

## Production

| Service          | Identifier                                                         |
| ---------------- | ------------------------------------------------------------------ |
| Site             | `https://cryptocheckout.ai` — apex 307s to `www.cryptocheckout.ai` |
| Vercel project   | `cryptocheckout-ai`, `prj_ev4UHfhlyOQmvaZ2eiUCr9fs0Hih`            |
| Vercel team      | `team_VeffPonv4Vh09AGnpUeHKvM7` / `arc-finlabs-projects`           |
| Supabase project | `pocyrcfbpfvthtyvupqk`                                             |

<Danger>
  The older `cryptocheckout-ai-wjb4` / `prj_qRnTtn9by5Y9TE9NabY32j4Us5hC` reference is **stale**. It appears in old documents and will deploy to the wrong place. If you re-run `vercel link`, always pick `prj_ev4U…` and never let the CLI auto-create a new project.
</Danger>

The `prj_ev4U…` project owns both the apex and the `www` domain, and is what `vercel --prod` must target.

## Chains

There is one live environment for contracts: **testnet**.

| Network      | Chains                                                                                                        |
| ------------ | ------------------------------------------------------------------------------------------------------------- |
| EVM testnet  | Base Sepolia, Ethereum Sepolia, Arbitrum Sepolia, Optimism Sepolia, Polygon Amoy, Avalanche Fuji, BNB testnet |
| TRON testnet | Nile                                                                                                          |
| Mainnet      | **None.** `deployments.json` `mainnet` is empty by design.                                                    |

Note that production Supabase and production Vercel point at **testnet** contracts. "Production" refers to the hosted application, not to mainnet money.

## Local development

```bash theme={null}
npm run dev     # Vite on port 8080 — NOT 5173
```

<Warning>
  The dev server runs on **port 8080**. The 5173 default appears in older documents and in the loopback origin allowlist that caused a real security issue.
</Warning>

Local development points at the **production** Supabase project by default. The dev server only hosts the SPA bundle; authentication, edge functions, and data all go to production. Be deliberate about what you click.

## Secrets and configuration

| File                       | Contents                                                                        | Committed   |
| -------------------------- | ------------------------------------------------------------------------------- | ----------- |
| `.env`                     | Local environment, including `SUPABASE_ACCESS_TOKEN` and `DEPLOYER_PRIVATE_KEY` | No          |
| `.env.example`             | Template                                                                        | Yes         |
| `.claude.local.md`         | Test wallet keys and paths                                                      | No          |
| `/tmp/v0-test-wallets.env` | Merchant and partner test wallet keys                                           | Not in repo |

<Danger>
  Test wallets hold real testnet funds and minted JWTs are bearer tokens for them. Never commit either.
</Danger>

The SIWE JWT signing secret lives in `vault.secrets.SUPABASE_JWT_SECRET` and is read at function boot via the `read_secret` RPC. It must match the key PostgREST validates against, or every RLS-gated read fails with PGRST301.

Because the Supabase MCP cannot set per-function secrets, `_shared/jwt.ts` falls back to the auto-set `SUPABASE_SERVICE_ROLE_KEY` when `SIWE_JWT_SECRET` is unset. Override it via environment later if secret-rotation independence is wanted.

## Outstanding environment work

<Warning>
  `SIWE_ALLOWED_DOMAINS` and `SIWE_ALLOWED_ORIGINS` are **not** set explicitly on the production project. They should be, and `siwe-verify` and `siwe-whoami` redeployed. The code now fails safe without them, but relying on a code-level fallback for an origin allowlist is not the right end state.
</Warning>

## Restoring grants after a schema reset

After `DROP SCHEMA public CASCADE`, Supabase's event triggers do **not** restore the standard `service_role` and `anon` grants. Run these immediately after migrations apply, or every edge function hits "permission denied for table merchants" at runtime:

```sql theme={null}
GRANT ALL ON ALL TABLES IN SCHEMA public TO postgres, service_role;
-- plus the equivalents for anon and authenticated
-- plus ALTER DEFAULT PRIVILEGES for future tables
```

## Widget data access

`merchants_public` is a view that inherits the underlying `merchants` RLS. The widget needs anonymous SELECT, provided by the `merchants_widget_public_read` policy scoped to `active = true`. Owner-only updates stay behind `merchants_self_select`.
