End-to-end checklist for deploying Nova Launch to production. Follow steps in order. Each section has a checkpoint — do not proceed until it passes.
Before starting, confirm:
- You have
sorobanCLI installed andadminidentity configured - You have funded mainnet accounts (
admin,treasury) -
STELLAR_NETWORK=mainnetis set in your shell or.env.mainnet - The WASM artifact is built and optimized (see Step 1)
- Backend
.envis populated (seebackend/.env.example) - Frontend
.envis populated (seefrontend/.env.example)
cd contracts/token-factory
cargo build --target wasm32-unknown-unknown --release
soroban contract optimize \
--wasm target/wasm32-unknown-unknown/release/token_factory.wasmCheckpoint: File target/wasm32-unknown-unknown/release/token_factory.optimized.wasm exists and is non-zero.
# From repo root
STELLAR_NETWORK=mainnet ./scripts/deploy-testnet.shThe script writes
deployment-mainnet.jsonand.env.mainnetwith the new contract ID.
Checkpoint:
cat deployment-mainnet.json | jq .contractId
# Expected: 56-character string starting with "C"./scripts/update-frontend-env.sh
# Then copy mainnet values:
cp .env.mainnet frontend/.envVerify frontend/.env contains:
VITE_FACTORY_CONTRACT_ID=<56-char contract ID>
VITE_NETWORK=mainnet
Checkpoint: grep VITE_FACTORY_CONTRACT_ID frontend/.env returns the contract ID from Step 2.
cd backend
npx prisma migrate deployCheckpoint: Command exits 0. No pending migrations remain:
npx prisma migrate status
# Expected: "All migrations have been applied"cd backend
ENABLE_EVENT_LISTENER=true npm startCheckpoint:
curl -s http://localhost:3000/health | jq .data.status
# Expected: "ok"cd frontend
npm run build
# Deploy dist/ to your hosting provider (Vercel, Netlify, etc.)
vercel --prod # or equivalentCheckpoint: The deployed URL loads without a blank screen or boot error banner.
Run the full smoke test against the live deployment:
STELLAR_NETWORK=mainnet \
FACTORY_CONTRACT_ID=$(jq -r .contractId deployment-mainnet.json) \
./scripts/smoke-test.shExpected output: all checks pass with ✓.
For a full frontend + backend + chain integration check:
./scripts/fullstack-smoke-test.shCheckpoint: No ✗ lines in output.
./scripts/verify-deployment.shCheckpoint: Script exits 0 and prints Deployment verified.
If any step fails after contract deployment:
# Find the backup created by upgrade-contract.sh or deploy-testnet.sh
ls backups/
# Restore previous contract
./scripts/rollback-upgrade.sh backups/<timestamp> mainnetAfter rollback:
- Re-run Step 3 to point frontend at the restored contract ID.
- Re-run Step 7 smoke test to confirm the rollback is functional.
See rollback-upgrade.sh for details.
| Check | Command | Expected |
|---|---|---|
| Contract state | soroban contract invoke --id $CONTRACT_ID --network mainnet -- get_state |
JSON with is_paused: false |
| Backend health | curl /health |
{"data":{"status":"ok",...}} |
| Frontend loads | Open deployed URL | No error banner |
| Wallet connects | Connect Freighter | Address shown in header |
| Fee display | Open Deploy page | Shows 7 XLM base fee |
| Explorer links | Click any tx link | Opens stellar.expert/explorer/public |
| Variable | Where | Description |
|---|---|---|
STELLAR_NETWORK |
shell / .env.mainnet |
testnet or mainnet |
FACTORY_CONTRACT_ID |
.env.mainnet |
Deployed contract address |
VITE_FACTORY_CONTRACT_ID |
frontend/.env |
Same value, Vite prefix |
VITE_NETWORK |
frontend/.env |
testnet or mainnet |
ENABLE_EVENT_LISTENER |
backend env | true to start chain listener |
DATABASE_URL |
backend env | Postgres connection string |
| Script | Purpose |
|---|---|
scripts/deploy-testnet.sh |
Deploy contract (works for mainnet via STELLAR_NETWORK=mainnet) |
scripts/update-frontend-env.sh |
Sync contract ID to frontend/.env |
scripts/rollback-upgrade.sh |
Restore previous contract from backup |
scripts/smoke-test.sh |
Contract-level smoke tests |
scripts/fullstack-smoke-test.sh |
Frontend + backend + chain integration |
scripts/verify-deployment.sh |
Post-deploy verification |