System Architecture (Technical)
Audience: Contributors who need an end-to-end view across packages. Networks: Arbitrum One (42161), Celo (42220), Base Sepolia (84532). Deployment data lives in
packages/contracts/deployments/*.json. Updated Novemberβ―2024. External references: Review Envio docs and EAS docs when working on indexer or attestation flows.
This guide maps the Green Goods monorepo, summarising package responsibilities, technology stacks, and operational entry points. It pulls together the essentials that previously lived in package-level READMEs.
System Layers
Client (
packages/client) β offline-first PWA for gardeners and operators. Persists submissions locally, syncs to the contracts/indexer pipeline, and handles sign-in via Pimlico passkeys and WalletConnect.Admin (
packages/admin) β administrative console for garden setup, membership management, and contract lifecycle actions. Provides operator-scoped views via the indexer.Indexer (
packages/indexer) β Envio project ingesting contract events and exposing a GraphQL API consumed by both frontends.Contracts (
packages/contracts) β Solidity suite implementing gardens, actions, attestation resolvers, and the Karma GAP bridge. Managed throughdeploy.jswrappers.
All packages share the root .env; Base Sepolia (84532) is the default network. Use bun dev at the repository root for a full stack dev environment.
Package Snapshots
Client PWA
Stack: React 18, Vite, Tailwind v4, Radix UI, TanStack Query (with offline persister), Viem, Zustand.
Auth: Pimlico passkey smart accounts (primary) and Reown AppKit wallet connections. Privy variables exist only for legacy migrations.
Offline architecture: IndexedDB queue (
src/modules/offline), service worker viavite-plugin-pwa, background sync to replay submissions.Useful commands:
bun --filter client dev # HTTPS dev server on https://localhost:3001 bun --filter client test # Vitest suite bun --filter client format # Biome formatterKey docs:
packages/client/AGENTS.mdcovers offline patterns, queue APIs, and Pimlico setup.
Admin Dashboard
Stack: React 18, Tailwind v4, Zustand, XState workflows, Urql (GraphQL + subscriptions), Viem.
Roles: Admin allow list (see
src/config.ts) and operator scope resolved from the indexer via theuseRolehook.Features: Garden creation & membership management, contract deployment helpers, Karma GAP impact viewing (via SDK), planned impact exports.
Commands:
Note: Karma GAP data is fetched through the SDK using
gapProjectUIDexposed by the indexer; see the appendix below.
Indexer (Envio)
Purpose: Tracks gardens, actions, submissions, approvals, and attestation metadata for frontends.
Runbook:
Troubleshooting: Use
bun resetor./reset-indexer.shto clear Docker volumes when Envio state is corrupted. ReScript-generated artifacts live ingenerated/; runnpm install --legacy-peer-depsinside that folder if codegen complains about missing packages.GAP queries: Gardens expose
gapProjectUIDin GraphQL; consumers should fetch impacts/milestones with the Karma GAP SDK (see the hook skeleton inpackages/indexer/KARMA_GAP_QUERIES.md).
Contracts
Scope: GardenToken (ERC-721), GardenAccount (ERC-6551), ActionRegistry, Work/Assessment resolvers, Karma GAP integration (
KarmaLib).Tooling: Foundry (forge/anvil), custom deployment scripts (
script/deploy.js,script/upgrade.js), schema config inconfig/schemas.json(read-only).Commands:
Checklist: See the Contracts Handbook for deployment, upgrade, schema, and validation procedures.
Data & Integration Flow
Garden creation (admin) β
GardenTokenmints and initialises aGardenAccount(token-bound account). Supported chains create a Karma GAP project viaKarmaLib.Action setup (admin) β
ActionRegistryentries define allowable work activities.Work submission (client) β Offline queue stores media + metadata, then submits on reconnect. Indexer captures
WorkSubmittedevents.Approval (operator) β
WorkApprovalResolvervalidates roles, records EAS attestation, and, when available, creates a GAP impact attestation viaGardenAccount.Assessment (operator) β
AssessmentResolvergenerates milestone attestations (also synced to GAP where supported).Consumption β Frontends query Envio for state. GAP impact data is fetched directly with the SDK using stored project UIDs.
Karma GAP At a Glance
Supported chains: Optimism, Arbitrum, Celo, Base Sepolia, Sepolia, Optimism Sepolia, Sei, Sei Testnet.
UID storage:
GardenAccount.gapProjectUID(bytes32) exposed through the indexer as strings.SDK usage: Install
@show-karma/karma-gap-sdk, map chain ID to network string, and fetch impacts/milestones using the project UID. Example hook lives inpackages/indexer/KARMA_GAP_QUERIES.md.Resilience: GAP calls are best-effort; failures emit logs but do not revert the parent transaction.
Related References
Product Overview β condensed product & data map
Developer Docs β environment, testing, troubleshooting
Contracts Handbook β lifecycle workflows
Package-specific deep dives remain in their respective
AGENTS.mdand README files for implementation details.
Last updated