-
-
Notifications
You must be signed in to change notification settings - Fork 0
Development Guide
This guide covers the development workflow for contributing to the Mappers Protocol monorepo: workspace conventions, package relationships, code generation, and best practices.
Mappers uses pnpm workspaces to manage a monorepo with three categories of packages:
| Category | Path | Purpose |
|---|---|---|
| Applications | apps/* |
Deployable services (API server, dashboard) |
| Libraries | lib/* |
Shared packages consumed by apps |
| Infrastructure |
programs/, oracle/, tests/, scripts/
|
Smart contract, oracle, and test code |
The workspace is defined in pnpm-workspace.yaml. Only packages listed under packages: participate in the workspace.
This project uses pnpm exclusively. The preinstall script rejects npm and yarn:
# Correct
pnpm install
pnpm add <package>
pnpm run <script>
# Will fail
npm install
yarn installInternal packages reference each other using workspace:* protocol:
{
"dependencies": {
"@workspace/db": "workspace:*",
"@workspace/api-zod": "workspace:*"
}
}This ensures packages always resolve to the local workspace version, never a published registry version.
lib/api-spec (OpenAPI definition)
|
|-- codegen --> lib/api-zod (Zod schemas)
|-- codegen --> lib/api-client-react (React Query hooks)
lib/db (Drizzle schema)
lib/sdk (MappersClient + OracleClient)
apps/api-server
imports: lib/db, lib/api-zod
apps/dashboard
imports: lib/api-client-react
The workspace uses composite project references for fast incremental builds:
-
tsconfig.base.json— shared compiler options (all packages extend this) -
tsconfig.json(root) — references all lib packages fortsc --build - Each package has its own
tsconfig.jsonextending the base
# Check only lib packages (fast, no app code)
pnpm run typecheck:libs
# Check everything (libs first, then apps)
pnpm run typecheck
# Full build (typecheck + package builds)
pnpm run buildThe typecheck:libs step must pass before apps can be checked, because apps import types from lib packages.
The API contract is defined as an OpenAPI specification in lib/api-spec/. From it, orval generates:
-
lib/api-zod/src/generated/— Zod validation schemas for every request and response -
lib/api-client-react/src/generated/— TanStack Query hooks with full type safety
cd lib/api-spec
pnpm run codegenThis runs orval and then type-checks the workspace to verify consistency.
- After modifying the OpenAPI spec
- After adding, removing, or renaming an API endpoint
- After changing request/response shapes
Do not manually edit files in */generated/ directories. They will be overwritten on the next codegen run.
-
Define the endpoint in the OpenAPI spec (
lib/api-spec/) -
Regenerate —
cd lib/api-spec && pnpm run codegen -
Implement the handler in
apps/api-server/src/routes/ -
Use the hook in
apps/dashboard/via the generated TanStack Query hook
The generated Zod schemas automatically validate request params and bodies in the API server. The generated React hooks automatically type the response data in the dashboard.
The database layer uses Drizzle ORM with PostgreSQL.
The schema is defined in lib/db/src/schema/. Each table has a dedicated file:
// lib/db/src/schema/jobs.ts
export const jobsTable = pgTable("jobs", {
id: serial("id").primaryKey(),
jobId: text("job_id").notNull().unique(),
clientPubkey: text("client_pubkey").notNull(),
// ...
});cd lib/db
pnpm run push # Push schema to database
pnpm run push-force # Force push (destructive — use with caution)Drizzle Kit's push command compares the TypeScript schema to the actual database and applies the diff. It does not generate migration files — it pushes directly.
- Create a new file in
lib/db/src/schema/(e.g.,users.ts) - Export the table and any derived schemas
- Re-export from
lib/db/src/schema/index.ts - Run
pnpm run pushto apply to the database
The escrow program lives in programs/project_mappers/src/lib.rs.
anchor build# Localnet (spins up a local validator)
anchor test
# Devnet (uses existing devnet deployment)
anchor test --provider.cluster devnetanchor deploy --provider.cluster devnetThe program IDL is output to idl.json at the repo root and also copied to oracle/idl.json.
The oracle is a standalone Node.js service (not in the pnpm workspace):
cd oracle
npm install
npm run devIt uses its own package.json and tsconfig.json. Changes to the oracle do not require rebuilding workspace packages.
The project uses Prettier for code formatting:
# Format all files
npx prettier --write .
# Check formatting (CI)
npx prettier --check .The .prettierignore file excludes generated files, build outputs, and lock files.
The workspace enforces a minimum release age of 1 day (1440 minutes) for all npm packages via pnpm-workspace.yaml:
minimumReleaseAge: 1440This means freshly published npm versions cannot be installed until they've been available for at least 24 hours — providing a buffer for the community to detect and report malicious packages.
If you absolutely must install a package within its first 24 hours, add it to minimumReleaseAgeExclude. This should be extremely rare and temporary.
-
Package naming: Apps use
@workspace/<name>, the SDK uses@mappers-protocol/sdk -
Module format: All packages use ESM (
"type": "module") -
Exports: Packages export via
"exports"field inpackage.json, pointing to source TypeScript (not compiled JS) -
No barrel re-exports of large modules: Each package has a focused
index.ts - Amounts as strings: All lamport amounts are stored and transmitted as strings (u64 safety)
| Task | Command |
|---|---|
| Install dependencies | pnpm install |
| Full build | pnpm run build |
| Type-check only | pnpm run typecheck |
| Run anchor tests | pnpm run test:anchor |
| Start API server | cd apps/api-server && pnpm run dev |
| Start dashboard | cd apps/dashboard && pnpm run dev |
| Start oracle | cd oracle && npm run dev |
| Push DB schema | cd lib/db && pnpm run push |
| Regenerate API code | cd lib/api-spec && pnpm run codegen |
| Format code | npx prettier --write . |
See Getting Started for first-time setup, or Architecture for the system design.
Mappers Protocol — Open-source freelance settlement infrastructure on Solana. Licensed under MIT.
Reference
Contributing