Skip to content

Deployment

Home · Top · Table of Contents

Table of Contents

Kevin K. Le (LinkedIn) — Founder, Founding Engineer, and Current Lead Engineer; Software Engineer at the Oregon Blockchain Group, University of Oregon.

Kellen Snider — Founding Engineer; Software Engineer at the Oregon Blockchain Group, University of Oregon. His vision, ideas, and dedication during TrustLedger's Ethereum development were invaluable to the codebase we build on today.

See CREDITS.md.

This document explains how to deploy TrustLedger locally, to Ethereum Sepolia, and as a containerized frontend with the current Foundry, Hardhat, GitHub Actions, Docker, and Kubernetes files.

Network Status

Home · Top · Table of Contents

Network Chain ID Deployment Support
Local Hardhat 31337 Hardhat deploy script and frontend env sync.
Ethereum Sepolia 11155111 Hardhat script, Foundry script, and deploy.yml.
Arbitrum One 42161 Configured in Hardhat and Foundry; no dedicated workflow.
Base 8453 Configured in Hardhat and Foundry; no dedicated workflow.
Optimism 10 Configured in Hardhat and Foundry; no dedicated workflow.

TODO: Arbitrum Sepolia is not configured in source as of 2026-06-08.

Prerequisites

Home · Top · Table of Contents

Create .env from .env.example and fill the variables needed for your target. Read Environment for the full matrix and the Configuration Beyond .env checklist. Deployment also depends on configured provider dashboards, GitHub or Vercel secrets, GitHub CLI access for security-alert scripts, Foundry, Gitleaks, WalletConnect/Reown, email sender verification, and monitoring setup.

For Ethereum Sepolia deploys, set:

SEPOLIA_RPC_URL=
DEPLOYER_PRIVATE_KEY=
ETHERSCAN_API_KEY=

For Vercel deployment through GitHub Actions, set these GitHub Actions secrets:

VERCEL_TOKEN=
VERCEL_ORG_ID=
VERCEL_PROJECT_ID=

Local Hardhat Deployment

Home · Top · Table of Contents

Start a local chain:

npm run node

In another terminal, deploy the contracts:

npm run hardhat:deploy:local

The Hardhat deploy script writes artifacts/deployed-addresses.json. On local chain 31337, it also runs scripts/sync-frontend-env.ts, which writes src/.env.local with contract addresses.

Ethereum Sepolia Deployment With Foundry

Home · Top · Table of Contents

Run a dry run first:

npm run foundry:deploy:sepolia:dry-run

Broadcast and verify:

npm run foundry:deploy:sepolia

The script uses contracts/script/Deploy.s.sol. It deploys and wires contracts in this order:

Order Contract
1 JurorRegistry
2 TrustLedger
3 Arbitration
4 ReputationRegistry

Deploy.s.sol precomputes addresses before deployment so constructor dependencies match the final addresses. After deployment, it calls TrustLedger.initReputationRegistry.

Ethereum Sepolia Deployment With Hardhat

Home · Top · Table of Contents

Compile first:

npm run compile

Deploy:

npm run hardhat:deploy:sepolia

Use this path when you need the TypeScript deploy script output or local Hardhat conventions. Use the Foundry path when you need the same flow as the GitHub deployment workflow.

GitHub Actions Deployment

Home · Top · Table of Contents

.github/workflows/deploy.yml is manual-only through workflow_dispatch. It is named Deploy (Ethereum Sepolia) and uses environment ethereum-sepolia.

The workflow:

  • Installs Node dependencies.
  • Installs Foundry.
  • Builds the frontend.
  • Runs Solidity tests.
  • Runs forge script with SEPOLIA_RPC_URL, DEPLOYER_PRIVATE_KEY, and optional verification.
  • Parses contracts/broadcast/Deploy.s.sol/11155111/run-latest.json.
  • Writes contract addresses and deploy blocks into Vercel environment variables.
  • Runs vercel deploy --prod from src/.

Frontend Address Sync

Home · Top · Table of Contents

For local Hardhat deployments, use:

npm run sync:frontend:env

For Sepolia deployments, deploy.yml sets both default and _SEPOLIA frontend variables in Vercel. See Environment for all address variable names.

Production Frontend URL

Home · Top · Table of Contents

Use https://trustledger-zeta.vercel.app/en as the canonical production frontend URL for manual checks, documentation references, and agent runs. Do not reintroduce the previous src-trustledger.vercel.app hostname unless historical deployment context is explicitly needed.

Container Frontend Deployment

Home · Top · Table of Contents

Build the standalone frontend image:

docker build -f docker/Dockerfile.frontend \
  -t ghcr.io/kevinle3212/trustledger-frontend:main .

Apply the Kubernetes base after setting non-secret values in k8s/configmap.yaml and creating trustledger-frontend-secrets when needed:

npm run k8s:secret:generate
kubectl apply -f k8s/secret.yaml
kubectl kustomize k8s
kubectl apply -k k8s
kubectl -n trustledger rollout status deployment/trustledger-frontend

Read Kubernetes for image tagging, secrets, health checks, ingress, autoscaling, and reproducibility notes.

Vercel builds the same npm run vercel-build script from src/, but the app intentionally disables Next.js standalone output when VERCEL=1. Vercel's builder performs its own serverless packaging, while Docker and Kubernetes need the traced standalone server copied into the runtime image. Keep outputFileTracingRoot disabled during Vercel builds; forcing it to the repository root from the nested src/ app causes Vercel to look for duplicated paths such as /vercel/path0/path0/.next/* during packaging.

Database Migrations

Home · Top · Table of Contents

Prisma migrations are applied automatically during the Vercel build so the off-chain Postgres schema (Neon) always matches the deployed app. npm run vercel-build runs npm run vercel:migrate (src/scripts/vercel-migrate.mjs) before next build, which calls the idempotent prisma migrate deploy (only un-applied migrations run). Behaviour is gated on VERCEL_ENV so a build never mutates the wrong database:

  • Production — migrations are required. Set DIRECT_URL (the direct, non-pooled Neon connection string) in the Production environment. A missing DIRECT_URL or a failed migration fails the build, so the app is never promoted ahead of its schema.
  • Preview — migrations run only when DIRECT_URL is set for the preview environment (for example a Neon preview branch); otherwise they are skipped so preview builds never touch the production database or fail for lack of a direct connection.
  • Local / CI builds — skipped (VERCEL_ENV is unset).

To apply migrations manually against a configured DATABASE_URL / DIRECT_URL, run npm run db:migrate from src/. Never log or commit connection strings; set DATABASE_URL and DIRECT_URL only in the deployment secret store.

Verification Notes

Home · Top · Table of Contents

Foundry verification uses the [etherscan] entries in contracts/foundry.toml. Hardhat verification uses the etherscan.apiKey map in hardhat.config.ts.

Both configs use Solidity 0.8.24, optimizer enabled, optimizer_runs = 200, and via_ir = true.

Authors and Contributors

Home · Top · Table of Contents

  • Kevin K. Le — Founder, Founding Engineer, and Current Lead Engineer (LinkedIn)
  • Kellen Snider — Founding Engineer (LinkedIn)

See CREDITS.md for the complete acknowledgement list.

Home · Top · Table of Contents

This document is part of TrustLedger, an open-source decentralized escrow and arbitration protocol. Use of this software and documentation is subject to the Terms and Conditions, Privacy Policy, and Risk Disclosure. See LEGAL.md for the full compliance and licensing overview.