Agent
packages/agent is the bot and webhook service: it receives inbound platform messages, routes
them through handlers, and serves the public HTTP API. It's how people interact with Green Goods
from messaging platforms without installing anything, and how external systems read public garden
data.
Inside src
index.ts boots the runtime, which starts the platform adapters and the HTTP API in order and
drains them on shutdown. A message arrives through a platform adapter, is matched to a handler,
and the handler talks to the services; the API routes read the same services for public data.
| Directory | What lives there |
|---|---|
src/index.ts | The entry point: starts the Telegram bot and the HTTP API |
src/runtime/ | Startup and shutdown wiring, with the reporting that says what came up and what did not |
src/handlers/ | Inbound message and command handlers, such as start, join, submit, and approve |
src/platforms/ | Messaging platform adapters (Telegram today) |
src/api/ | The HTTP routes, public and authenticated, including funding; the API Index inventories every public one |
src/services/ | Service dependencies behind stable helper APIs: the database, reporting, and the protocol clients |
src/config.ts, src/i18n.ts, src/types.ts | Configuration, message translations, and the shared types the handlers speak |
src/__tests__/ | Vitest suites for handlers, adapters, and services |
Run and test
bun run --cwd packages/agent test
bun run --cwd packages/agent typecheck
Response-shape changes ripple through platform adapters quickly, so run both whenever handlers,
adapters, or service contracts move. bun run --cwd packages/agent test --scope unit --coverage backs
security-sensitive changes.
How it connects
The agent is a server, so it doesn't use shared's React hooks. It imports shared's plain modules instead: the public API contracts, types, chain config, and a few protocol helpers. It's also the one surface that manages wallets on behalf of users, so its security posture is stricter than the rest.
Conventions that will bite you
- Never store plaintext private keys. Key material flows only through the crypto helpers, and the database service is the single persistence boundary: keys are encrypted before insert and decrypted on read.
- Logs may carry platform ids, addresses, and transaction hashes, never raw key material.
- Externally triggered actions are rate-limited, and user-facing failures stay generic; internal error detail never leaks to users.
- Keep handlers pure where possible and inject the dependencies that need mocking.
Go deeper
packages/agent/AGENTS.mdis the full package contract, including the key-material flow.- API Index lists every public route the agent registers, with its methods, the Shared constant that names its path where one exists, and the file that registers it.