Skip to main content

Getting Started


Setting Up Your Work Environment

Before cloning, make sure these tools are installed:

ToolMin VersionPurposeInstall
Node.js22+Runtime for scripts and toolingnodejs.org
Bun1.x+Package manager and monorepo runnercurl -fsSL https://bun.sh/install | bash
GitanyVersion controlgit-scm.com
FoundryanySolidity compiler and testing (forge)curl -L https://foundry.paradigm.xyz | bash && foundryup
DockeranyRuns the Envio indexer locallydocker.com
cloudflaredanyHTTPS tunnel for mobile device testingbrew install cloudflared

Foundry, Docker, and cloudflared are only required for their respective workflows (contracts, indexer, mobile testing). The setup script warns but does not block if they are missing.


Running Development Setup

git clone https://github.com/greenpill-dev-guild/green-goods.git
cd green-goods
bun setup # checks deps, installs packages, creates .env
bun dev # starts all services via PM2

What bun setup does

The setup script (scripts/setup.js) runs through four steps:

  1. Dependency check -- verifies Node.js 22+, Bun 1.x, Git, Docker, and Foundry are available. Missing optional tools produce warnings, not errors.
  2. Install packages -- runs bun install across all workspaces if node_modules does not exist yet.
  3. Environment file -- generates .env from .env.schema defaults if no .env exists. For standard local 1Password CLI installs, prefer root-only *_OP_REF=op://... entries in .env. Reserve OP_ENVIRONMENT bulk loading for CI, service-account flows, or newer CLI builds that support it.
  4. Next steps -- prints the commands to start developing.

Required Secrets & Variables

Green Goods uses a single root .env bootstrap plus committed .env.schema validation — never create package-level env files. Key variables:

VariableRole
APP_ENVEnvironment selector (development, test, staging, production)
ETHERSCAN_API_KEY_OP_REFExample local 1Password secret reference in root .env (op://vault/item/field) for stable desktop-app auth
OP_ENVIRONMENT1Password environment name/id used only for bulk injection in CI, service-account flows, or local beta-capable CLI installs
OP_SERVICE_ACCOUNT_TOKEN1Password service account token (required in CI/deployed environments, optional locally if you want service-account auth)
VITE_CHAIN_IDSets the target chain at build time (e.g. 11155111 for Sepolia, 42161 for Arbitrum)
PINATA_JWTPinata JWT for the shared IPFS upload path
SEPOLIA_RPC_URLRPC endpoint for Sepolia fork tests

Use .env.schema as the full environment contract. Variables prefixed with VITE_ are embedded into frontend bundles at build time.

For normal local development, sign in to the standard op CLI with desktop app integration enabled, keep OP_ENABLE_ENVIRONMENT_LOAD=false, and add root .env entries like ETHERSCAN_API_KEY_OP_REF=op://vault/item/field for the secrets you need. varlock run resolves those references directly.

For CI workflows or local service-account usage, set OP_SERVICE_ACCOUNT_TOKEN, set OP_ENVIRONMENT, and enable OP_ENABLE_ENVIRONMENT_LOAD=true when you want Varlock to bulk-load a 1Password Environment.

Running services

All at once

bun dev launches every service through PM2:

PM2 processPackageDefault port
clientpackages/client3001
adminpackages/admin3002
docsdocs3003
indexerpackages/indexer (Docker / GraphQL)8080
agentpackages/agent--
tunnelcloudflared HTTPS tunnel--
storybookpackages/shared6006

Stop everything with bun dev:stop.

Individual packages

You can also run packages directly without PM2:

bun dev:client      # Gardener PWA
bun dev:admin # Operator dashboard
bun dev:docs # Docusaurus site
bun dev:indexer # Envio indexer (Docker Compose)
bun dev:contracts # Anvil local chain
bun dev:agent # Agent bot

Mobile device testing

Green Goods is a mobile-first PWA, so testing on a real phone is essential. When you run bun dev, a cloudflared tunnel starts automatically alongside the other services. It creates a temporary public HTTPS URL (e.g. https://random-words.trycloudflare.com) that points to your local client on port 3001.

Once the tunnel is ready, the landing page QR code automatically switches to the tunnel URL. Open https://localhost:3001 on your laptop and scan the QR code with your phone — you'll get the full PWA experience including service worker, install prompts, and passkey auth.

# Tunnel starts automatically with bun dev.
# To run it standalone (e.g. for the admin dashboard):
bun run dev:tunnel # default: port 3001
bun run dev:tunnel -- --port 3002 # admin on port 3002

If cloudflared is not installed, the tunnel service exits silently and the QR code falls back to window.location.origin. Install it with brew install cloudflared.

Alternative: ADB port forwarding

If you prefer a wired connection, plug in your Android device with USB debugging enabled and run:

adb reverse tcp:3001 tcp:3001

Then navigate to https://localhost:3001 on Android Chrome. Since localhost is a secure context, the service worker registers without a trusted CA certificate.

First-run checklist

  1. 1

    Read project rules

    Start with `AGENTS.md`, `CLAUDE.md`, and `.claude/context/*` for conventions.

  2. 2

    Configure env bootstrap

    Set `APP_ENV` in root `.env`. For local 1Password on the stable CLI, add `*_OP_REF=op://...` entries there and keep `OP_ENABLE_ENVIRONMENT_LOAD=false`. Use root `.env` only -- never add package-level env files.

  3. 3

    Start services

    Run `bun dev` and verify client, admin, indexer, and docs start cleanly.

  4. 4

    Run the quality gate

    Run `bun run test`, `bun lint`, and `bun build` before pushing changes.

Development workflow

The standard edit-test-build-lint cycle:

# 1. Run tests for the package you changed (always `bun run test`, never `bun test`)
cd packages/shared && bun run test

# 2. Lint the workspace
bun lint

# 3. Build (respects dependency order: contracts -> shared -> indexer -> client/admin)
bun build

# 4. Format before committing
bun format
bun test vs bun run test

bun test invokes Bun's built-in test runner, which ignores your Vitest config. Always use bun run test to run the package.json script with proper environment setup.


Troubleshooting & Common Issues

SymptomCauseFix
forge: command not foundFoundry not installedcurl -L https://foundry.paradigm.xyz | bash && foundryup
Indexer fails to startDocker not runningStart Docker Desktop, then retry bun dev:indexer
VITE_CHAIN_ID is undefinedMissing .envRun bun setup or run APP_ENV=development bunx varlock load --path .env.schema --format env --compact > .env
Port 3001/3002 in useAnother dev server runningKill the process or change the port in the package's Vite config
bun install hangsStale lockfileDelete node_modules and bun.lockb, then bun install
No QR code on landing pagecloudflared not installedbrew install cloudflared, then restart bun dev
Tunnel URL not appearingClient not ready yetThe tunnel waits up to 60s for port 3001 — check PM2 logs with npx pm2 logs tunnel

Non-negotiables

  • All React hooks live in packages/shared -- client and admin only have components and views.
  • The target chain derives from VITE_CHAIN_ID at build time. There is no runtime chain switching.
  • Deployment changes go through bun deploy:* wrappers, never raw forge commands.
  • User-facing strings must be added to all three translation files (en.json, es.json, pt.json).

Next page

Next best action

Keep momentum by moving to the next high-value step in this journey.

Architecture