Testnet: Monad Testnet, test USDC only, unaudited
Open app
On this page You need
All guide pages

Deploy

How-to

Deploy the apps on RenderLink to this section

The render.yaml Blueprint in the repository defines two web services. The contracts already run on Monad Testnet and need no hosting. DEPLOY.md (opens in a new tab) in the repository has every detail; this is the short version.

The two services in render.yaml
ServiceWhat it runs
fairpayThe FairPay app (apps/fairpay/Dockerfile). Free plan; its data lives in Supabase, so restarts and redeploys lose nothing.
faireatsThe standalone FairEats app (root Dockerfile). Free plan with no disk, so its database starts empty after every restart. Leave it out if you only want FairPay.

Careful: don't let two running services share one relayer or faucet key: each keeps its transactions in order only inside its own process, so they can clash on nonces. Give each service its own testnet wallets, or run only one. Never use a key that holds real funds.

  1. Create the Supabase database. Make a project, press Connect and copy the Session pooler connection string. Download Supabase's CA certificate from the database settings (SSL Configuration). The app creates its own tables on first start.
  2. Create the Blueprint on Render. Choose New, then Blueprint, pick the repository and keep the branch main. Allow Render to read only this repository.
  3. Enter the secrets for fairpay: DATABASE_URL (the pooler string), DATABASE_CA (the certificate, for example as a secret file), PUBLIC_ORIGIN, RELAYER_KEY, FAUCET_KEY, MERCHANT_ADDRESS and, optionally, DEMO_OWNER_WALLET so you can manage the demo restaurant. For faireats: RELAYER_KEY, FAUCET_KEY, MERCHANT_ADDRESS and a long random KITCHEN_PIN.
  4. Point it at this website. People open the app on this website at /pay/, and the website forwards /api to the Render service (next section). In the fairpay service's Environment tab set PUBLIC_ORIGIN to https://fairpay.business (exactly, no trailing slash), PUBLIC_APP_PATH to /pay and TRUST_PROXY_HOPS to 4, then redeploy. Sign-in messages must name this address. The server refuses to start in production without PUBLIC_ORIGIN and DATABASE_URL.
  5. Check it. Open /api/config on the website: it should say "storage":"supabase" and report whether the relayer is ready. Open /api/whoami: it should show your own IP address. Then open /pay/, sign in and open Business, FairEats.

Check: the footer of the app says "Data: Supabase". The first start on a new database scans the privacy pool from its deploy block, so private payments wait several minutes; later restarts resume at once.

After it is liveLink to this section

  • Updates: every push to main redeploys both services.
  • Sleep: free instances sleep when idle. The first visit after that takes about 50 seconds; the app shows "Starting the server…" meanwhile.
  • Gas: each private payment costs the relayer about 0.15 MON, and the node wants about 0.26 MON on hand before it accepts one. Top up the relayer and faucet wallets when the logs say "insufficient balance".
  • Logs: in each service's Logs tab. Keys are never logged.
  • Pausing: use Suspend. Deleting the fairpay service leaves its data in Supabase.

What is in the images: built from node:24-bookworm-slim, run as the unprivileged node user. .dockerignore keeps every .env file, the local databases and node_modules out. Prices change; check render.com/pricing (opens in a new tab) and supabase.com/pricing (opens in a new tab).

Back to top

Publish this website on VercelLink to this section

The pages you are reading, the simulated demo at /app/ and the FairPay app's pages at /pay/ are static files. They contain no server, no database and no keys, so they can live on Vercel. The app's server runs on Render, and Vercel forwards every /api request to it, so visitors only ever see this website's address.

The live copy is at fairpay.business. To publish a new version, sign in to the Vercel CLI once (npx vercel login), then run from the repository root:

bash
npm run deploy:vercel

This builds the site and the demo, packs apps/site/dist into Vercel's prebuilt format (apps/site/.vercel/output) and uploads only those static files. Vercel runs no build of its own, and no source code or .env file is uploaded. The headers and rewrites come from apps/site/vercel.json: /guide to the site, /app/* to the demo, /pay/* to the app, /api/* to the app's server on Render, a strict Content-Security-Policy (the app's pages get the few extra permissions its in-browser prover needs), HSTS, nosniff, a referrer policy and a permissions policy that turns off camera, microphone and location. Never add wallet keys to the Vercel project; the only setting it may hold is the optional PROXY_SECRET. Set the same value on the Render fairpay service; Vercel then adds it to every forwarded /api request as a header, so the server can tell requests that came through this website.

Check: open the deployed URL. / shows the landing page, /guide this guide, and /app/ the demo with the "Simulated demo" bar on top, and /pay/ the app. In the browser's network panel, the site and the demo make no requests to any other host; the app talks only to this website, the Monad testnet RPC and, for a private payment, the proving files at snark-artifacts.pse.dev.