Skip to content

greenpill-dev-guild/green-goods

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2,004 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Green Goods

Version License

Bringing community and environmental actions onchain to better measure, track and reward impact.

Green Goods is an offline-first platform for documenting ecological and social work and proving impact on-chain. Operators approve gardener submissions, and the protocol anchors results in Ethereum attestation infrastructure.

Getting Started

Prerequisites

Install Node.js 22+ and Git. Install OrbStack or Docker Desktop if you plan to run the full stack or indexer locally. Node includes npm, and npm run setup installs Bun automatically if it is missing.

Optional tools: Foundry is needed for contract work. cloudflared is useful for mobile-device PWA testing. macOS and Linux are supported natively; use WSL2 or a dev container on Windows.

Clone

Clone on GitHub

Use GitHub's Code button to choose the SSH or HTTPS remote that matches your local Git setup. Then run the setup commands from the repo root.

Agent-Assisted Setup

If you are using Codex, Claude Code, or another coding agent, start by loading ONBOARDING.md. It gives the agent the repo context, setup flow, environment model, and first-run checks before it starts changing files.

Read ONBOARDING.md and AGENTS.md, then walk me through first-time setup for this repo.
Start with prerequisites, run npm run setup, check web readiness, start the browser
stack, and explain any env blockers before making changes.

Setup

Install dependencies

npm run setup

After setup, use bun for repo scripts and package operations. npm run setup is the only documented npm entrypoint because fresh machines may not have Bun yet.

Environment defaults

Green Goods uses a single root .env, materialized from .env.template via the 1Password CLI (op inject). Bun, Vite, and Node read it natively — no per-command secret fetch.

bun run env:template:init   # one-time: scaffold .env.template from .env.schema
bun run env:sync             # materialize .env from .env.template (runs `op inject`)
bun run env:check            # validate .env satisfies .env.schema

.env.schema defines the contract; .env.template is the team-shared file with op://Vault/Item/field refs for shared secrets and plain values for non-secrets. Keep personal local-only credentials directly in .env.

Variable Needed for Default setup state
APP_ENV Local tooling mode Generated as development
VITE_CHAIN_ID Client/admin chain selection Generated for Sepolia
VITE_DEV_CHAIN_MODE Optional local fork marker Set by the repo-native dev stack for Green Goods fork mode
VITE_LOCAL_FORK_RPC_URL Optional local fork RPC Set by the repo-native dev stack to http://127.0.0.1:3009
VITE_ENVIO_INDEXER_URL Local indexer reads Generated for local GraphQL; needs the indexer running for live local data
VITE_PINATA_JWT Upload-capable media Add only when testing uploads
VITE_PIMLICO_API_KEY Passkey auth Add only when testing passkey flows
VITE_WALLETCONNECT_PROJECT_ID Wallet auth Add only when testing wallet flows
TELEGRAM_BOT_TOKEN Agent service Add only when running a useful local agent

For shared team secrets, edit .env.template and set the value to op://Vault/Item/field, then run bun run env:sync. For personal local credentials, set the variable directly in the root .env. Never create package-level .env files.

Check readiness

bun run dev:health

bun run dev:health runs the repo-native full-stack doctor. Use bun run dev:doctor -- --profile web when you only need the browser-facing readiness check.

Start stack

bun run dev

Starts the repo-native PM2 full stack and opens the review URLs. The default chain target is an Arbitrum One fork on port 3009, so client/admin reads and wallet writes use chain id 42161 while transactions are mined only in local Anvil state.

Plain local Anvil is still available for contract-only work, but it is explicit-only:

dev stop green-goods:anvil-arbitrum
dev launch green-goods:anvil

For fork-mode transaction testing, use a dedicated dev browser profile and a disposable wallet. The Arbitrum fork launcher keeps Anvil startup output quiet so fork RPC credentials do not appear in logs; local test-account details are written to packages/contracts/.generated/runtime/arbitrum-fork.json with the fork endpoint redacted. Import one of those local-only accounts, configure that wallet to use http://127.0.0.1:3009 on chain 42161, and never use a real everyday wallet profile with Anvil keys. ?mockAuth=operator is only a UI state override; it does not sign transactions.

Testing

bun run dev:smoke:web
bun run dev:smoke:full

Run bun run dev:smoke:web after the browser stack is starting. Run bun run dev:smoke:full after bun run dev when you need proof that the browser surfaces, local agent, local indexer/Hasura/Postgres, and Arbitrum fork are all responding. The local indexer stack mirrors the configured live networks into local Docker services, so reliable lag proof requires ENVIO_API_TOKEN; without it, HyperSync can rate-limit and the full smoke should fail on indexer lag instead of pretending the local mirror is current.

Tech Stack

Stack Overview

  • Node.js 22+ provides npm for first-clone setup.
  • npm run setup installs Bun, installs dependencies, and creates the root .env.
  • Bun is the workspace runtime after setup.
  • .env.schema (key contract) + .env.template (1Password refs) materialize .env via bun run env:sync (op inject).
  • The repo-native PM2 stack manages normal single-repo local dev services.
  • The shared dev workbench is for cross-repo orchestration and narrow targets.
  • Docker powers full-stack indexer development.
  • Storybook runs from the shared package.
  • Full-stack work adds Docker-backed indexer services, the agent, tunnel, and workflow-specific env or secrets.

Core Local URLs

Client and admin can start with generated defaults. Live data, uploads, authenticated onchain flows, and the local agent depend on the matching env and services.

Surface URL Started by
Client PWA + editorial website https://localhost:3001 bun run dev; narrow target: dev launch green-goods:client
Admin https://localhost:3002 bun run dev; narrow target: dev launch green-goods:admin
Docs http://localhost:3003 bun run dev; narrow target: dev launch green-goods:docs
Storybook http://localhost:3004 bun run dev; narrow target: dev launch green-goods:storybook
Agent http://localhost:3005/health bun run dev; narrow target: dev launch green-goods:agent
Indexer http://localhost:3006/v1/graphql bun run dev with Docker running; narrow target: dev launch green-goods:indexer-graphql
Arbitrum fork http://127.0.0.1:3009 started automatically by bun run dev; narrow target: dev launch green-goods:anvil-arbitrum

Dev Commands

Start the local stack

bun run dev

Runs the repo-native Green Goods PM2 stack. The default stack starts the Arbitrum fork, then the app surfaces that depend on it. The client opens both review presentations on port 3001:

For cross-repo orchestration or a narrower workbench target, use the global workbench from anywhere:

dev launch green-goods:client
dev launch green-goods:admin
dev launch green-goods:indexer-graphql

Use local Anvil wallets

Fork-mode transaction testing uses wallet auth, not mock auth:

  1. Start the fork-backed stack with bun run dev.
  2. Open a dedicated dev browser profile.
  3. Add a wallet network named Green Goods Local Arbitrum Fork with RPC http://127.0.0.1:3009, chain id 42161, and currency symbol ETH.
  4. Import one disposable Anvil-funded account from packages/contracts/.generated/runtime/arbitrum-fork.json; the fork endpoint is redacted in that generated file.
  5. Connect that wallet in the app and sign normally.

The fork uses the real Arbitrum deployment artifact, but writes are mined only in local Anvil state. Restarting the fork resets local chain state. Passkey and smart-account writes are intentionally blocked in fork mode until local account abstraction infrastructure exists. ?mockAuth=operator is useful for UI state review, but it does not sign transactions and cannot replace the wallet step.

Start full local stack

Check full-stack readiness first:

bun run dev:doctor -- --profile full

Then start the full repo-native stack:

bun run dev

Use the full stack for Docker/indexer, agent, or local transaction work. Run the full doctor first; some services need workflow-specific env or secrets before they are useful.

After the stack is up, run the non-mutating full-local smoke:

bun run dev:smoke:full

This proves both client presentations, admin, docs, Storybook, local agent health, Anvil chain id 42161, deployed Arbitrum bytecode on the fork, funded Anvil accounts, local Envio/Hasura GraphQL, local indexer service health, and the Postgres TCP listener. The indexer lag check proves the local read model is close enough to live configured chain state for review; set ENVIO_API_TOKEN in the root .env for reliable HyperSync catch-up. It does not submit transactions.

Start production-backed local stack

Green Goods has three local-development modes. Use the production-backed modes only when you intentionally want local browser surfaces to talk to live infrastructure.

Mode Command Chain target Indexer Agent/API Writes
Fully local default bun run dev Arbitrum fork on http://127.0.0.1:3009 with chain id 42161 Local Docker-backed Envio/Hasura on 3006-3008 Local agent on 3005 Wallet writes are mined only in local Anvil state
Hosted production-backed bun run dev:prod Arbitrum One 42161 Hosted production indexer https://agent.greengoods.app Wallet-confirmed writes are real Arbitrum transactions
Local live-indexer mirror bun run dev:prod:mirror Arbitrum One 42161 Local Docker-backed Envio/Hasura indexing live Arbitrum https://agent.greengoods.app Wallet-confirmed writes are real Arbitrum transactions

Start hosted production-backed mode from the repo root:

bun run dev:prod

bun run dev:prod starts the client, admin, docs, and Storybook locally. It does not start local Anvil, the local indexer, the local agent, or a public tunnel. The stack overlays Arbitrum One (VITE_CHAIN_ID=42161), the hosted production indexer, and https://agent.greengoods.app, then runs a read-only production smoke after the local ports are ready.

Live wallet writes are allowed in production-backed modes. If you connect a wallet on Arbitrum One and confirm a transaction, it is a real production transaction and can spend funds. The automatic smoke never submits transactions.

The production smoke proves:

Check What it proves
Local browser ports Client 3001, admin 3002, docs 3003, and Storybook 3004 respond
RPC chain id The configured Arbitrum RPC returns eth_chainId=42161
Contract bytecode At least one deployed Arbitrum contract address from packages/contracts/deployments/42161-latest.json has bytecode
Production agent health https://agent.greengoods.app/health returns HTTP 200 with status: "ok"
Indexer GraphQL Hosted production indexer, or the local mirror in mirror mode, returns Arbitrum chain metadata
Indexer lag Indexed block is within the smoke threshold of Arbitrum head; override with --max-indexer-lag-blocks <blocks> when debugging
Local-service boundary dev:prod skips local indexer services; dev:prod:mirror expects local indexer services

The production smoke does not prove a full click-through, wallet confirmation, or production transaction broadcast. Use this manual live-write checklist when you need that proof:

  1. Use a dedicated QA wallet with only the funds you intend to risk.
  2. Select Arbitrum One in the wallet.
  3. Start bun run dev:prod or bun run dev:prod:mirror.
  4. Navigate to the action you need to validate and stop at wallet confirmation if you only need reachability proof.
  5. Broadcast only when the test intentionally mutates production state.
  6. Record the route, wallet network, expected contract/action, and transaction hash if a broadcast is intentionally submitted.

The hosted production agent has two health surfaces: /health and /ready. The local production smoke intentionally uses /health. /ready is stricter and can return 503 while optional AI/voice model readiness is still loading, even when the agent, webhook, and routine API are usable.

For local indexer development against live Arbitrum, use the mirror mode:

bun run dev:prod:mirror:health
bun run dev:prod:mirror

This starts the same browser surfaces plus the local Docker-backed Postgres/Hasura/Envio stack on ports 3006-3008, while still targeting Arbitrum One rather than the local fork. The mirror smoke checks local GraphQL, the local indexer service, and indexer lag against live Arbitrum head; if it fails lag, the mirror is reachable but not caught up enough to trust for production-data review.

bun run dev:health and bun run dev:prod:mirror:health warn or fail clearly when ENVIO_API_TOKEN is missing for reliable HyperSync catch-up. Without it, the containers can still become healthy, but the local mirror may stall or receive 429 Too Many Requests from HyperSync and smoke should fail on indexer lag. Set ENVIO_API_TOKEN directly in the root .env, or set ENVIO_API_TOKEN_OP_REF in .env.template and run bun run env:sync.

Run the production checks on demand:

bun run dev:prod:health -- --json
bun run dev:prod:mirror:health -- --json
bun run dev:prod:smoke
bun run dev:prod:smoke -- --mode mirror
bun run dev:prod:smoke -- --max-indexer-lag-blocks 5000

Expected production-backed port boundary:

  • dev:prod: 3001-3004 listening; 3005-3009 free.
  • dev:prod:mirror: 3001-3004 and 3006-3008 listening; 3005 and 3009 free.

bun run dev:web, bun run dev:stack, and bun run dev:stack:stop remain available for focused PM2 debugging. Day-to-day agent and developer work should use bun run dev.

Stop local services

bun run dev:stop

Contributing

Guides

Read the Greenpill Dev Guild contributing guide and the full How to Contribute guide before opening a pull request.

Before Pushing

Run each command from the repo root before pushing.

Check formatting

bun run format:check

Run lint

bun run lint

Run tests

bun run test

Build workspace

bun run build

Funded Scoped Work

Paid implementation work is grant-dependent and must be clearly scoped with maintainers before work begins. Green Goods does not run open-ended bounties.

Resources

Documentation

Agent References

  • ONBOARDING.md - paste into Claude Code on day one for a guided setup walkthrough
  • AGENTS.md - runtime rules and repo invariants for Codex and other coding agents
  • CLAUDE.md - Claude Code commands, patterns, and working conventions

Community and Security

Contributors

Languages

  • TypeScript 70.0%
  • Solidity 19.6%
  • JavaScript 6.0%
  • CSS 2.9%
  • Shell 0.8%
  • HTML 0.7%