chore: scaffold PYRE MVP monorepo (structure + docs)
pnpm + TypeScript workspace per design doc §13:
- apps/{web,api,worker} skeletons (Next.js 16, Fastify 5, BullMQ)
- packages/{core,solana,prometheus,db,config} (core has real types/DTOs;
solana/prometheus are stubs)
- programs/pyre-core placeholder (future Anchor, v1.0)
- docs/: PYRE_MVP_DESIGN (canonical), ARCHITECTURE, SECURITY, TOKEN_CLASSIFICATION
- CLAUDE.md, README, .env.example (no private-key var by design)
Skeleton + docs only — no Solana/business logic yet. All workspaces typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
38
packages/config/README.md
Normal file
38
packages/config/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# @pyre/config
|
||||
|
||||
Shared configuration and environment loading for PYRE.
|
||||
|
||||
## Purpose
|
||||
|
||||
Per §13: shared config and environment loading. Provides a typed `Env` interface
|
||||
and a `loadConfig()` loader that maps the variables in the repo-root
|
||||
`.env.example` into typed config.
|
||||
|
||||
## Trust rule
|
||||
|
||||
There is intentionally **no** wallet private-key / mnemonic variable here, and
|
||||
there never will be (§3). All signing happens client-side in the user's wallet.
|
||||
|
||||
## Variables (mirrors `.env.example`)
|
||||
|
||||
- **Solana** — `SOLANA_RPC_URL`, `SOLANA_RPC_WS_URL`, `SOLANA_CLUSTER`
|
||||
- **Database** — `DATABASE_URL`
|
||||
- **Redis** — `REDIS_URL`
|
||||
- **AI** — `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `IMAGE_GEN_PROVIDER`,
|
||||
`IMAGE_GEN_API_KEY`
|
||||
- **App URLs / ports** — `WEB_PORT`, `API_PORT`, `WEB_PUBLIC_URL`,
|
||||
`API_PUBLIC_URL`
|
||||
- **Admin / security** — `ADMIN_API_TOKEN`, `RATE_LIMIT_SCAN_PER_MIN`
|
||||
- **Classification thresholds** — `PROTECTED_USD_THRESHOLD`,
|
||||
`MAX_PRICE_IMPACT_BPS`, `QUOTE_MAX_AGE_MS`
|
||||
- **Optional / later phases** — `IPFS_OR_ARWEAVE_ENDPOINT`,
|
||||
`IPFS_OR_ARWEAVE_TOKEN`, `PUMPFUN_CREATOR_WALLET_PUBKEY` (public key only)
|
||||
|
||||
## Status
|
||||
|
||||
**Skeleton.** Defines `Env`; `loadConfig()` is a stub.
|
||||
|
||||
## TODO
|
||||
|
||||
- Implement `loadConfig()` — read `process.env`, validate/coerce, apply defaults,
|
||||
fail fast on missing required values. Never hardcode secrets.
|
||||
17
packages/config/package.json
Normal file
17
packages/config/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@pyre/config",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "echo \"lint: ok (placeholder)\"",
|
||||
"test": "echo \"test: ok (placeholder)\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
72
packages/config/src/index.ts
Normal file
72
packages/config/src/index.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @pyre/config — shared config & environment loading (SKELETON).
|
||||
*
|
||||
* Responsibilities (§13): shared config and environment loading. Variables mirror
|
||||
* `.env.example` at the repo root.
|
||||
*
|
||||
* TRUST RULE (§3): there is intentionally NO wallet private-key / mnemonic
|
||||
* variable here, and there never will be. All signing happens client-side.
|
||||
*
|
||||
* Do NOT hardcode secrets — values come from the process environment at runtime.
|
||||
*/
|
||||
|
||||
export type SolanaCluster = "mainnet-beta" | "devnet" | "testnet";
|
||||
|
||||
/**
|
||||
* Typed view of the supported environment variables.
|
||||
* Mirrors `.env.example` (sans the deliberately-absent private-key var).
|
||||
*/
|
||||
export interface Env {
|
||||
// ---- Solana ----
|
||||
solanaRpcUrl: string;
|
||||
solanaRpcWsUrl?: string;
|
||||
solanaCluster: SolanaCluster;
|
||||
|
||||
// ---- Database (PostgreSQL) ----
|
||||
databaseUrl: string;
|
||||
|
||||
// ---- Redis (queues, cache, rate limiting) ----
|
||||
redisUrl: string;
|
||||
|
||||
// ---- AI services (Prometheus) ----
|
||||
anthropicApiKey?: string;
|
||||
openaiApiKey?: string;
|
||||
/** e.g. "openai" | "stability" | "replicate". */
|
||||
imageGenProvider?: string;
|
||||
imageGenApiKey?: string;
|
||||
|
||||
// ---- App URLs / ports ----
|
||||
webPort: number;
|
||||
apiPort: number;
|
||||
webPublicUrl: string;
|
||||
apiPublicUrl: string;
|
||||
|
||||
// ---- Admin / security ----
|
||||
adminApiToken?: string;
|
||||
rateLimitScanPerMin: number;
|
||||
|
||||
// ---- Classification safety thresholds ----
|
||||
/** Skip tokens valued above this (USD). */
|
||||
protectedUsdThreshold: number;
|
||||
/** Skip swap routes above this price impact (basis points). */
|
||||
maxPriceImpactBps: number;
|
||||
/** Skip stale quotes older than this (ms). */
|
||||
quoteMaxAgeMs: number;
|
||||
|
||||
// ---- Optional: metadata / launch (later phases) ----
|
||||
ipfsOrArweaveEndpoint?: string;
|
||||
ipfsOrArweaveToken?: string;
|
||||
/** Public key ONLY — operator signs Pump.fun launches manually in the MVP. */
|
||||
pumpfunCreatorWalletPubkey?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and validate configuration from the process environment.
|
||||
*
|
||||
* TODO: read from `process.env` (mapping the variables in `.env.example`),
|
||||
* validate/coerce types, apply defaults, and fail fast on missing required
|
||||
* values. Never hardcode secrets. There is intentionally no private-key var.
|
||||
*/
|
||||
export function loadConfig(): Env {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
8
packages/config/tsconfig.json
Normal file
8
packages/config/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user