walletpress/ARCHITECTURE.md
cryptorugmunch e13bd4d774
Some checks are pending
CI / lint (push) Waiting to run
CI / test (push) Waiting to run
CI / security (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / license (push) Waiting to run
CI / ai-review (push) Waiting to run
docs: apply fleet-template (16-artifact scaffold)
Adds missing standard artifacts:
- README.md (if missing)
- AGENTS.md (AI agent contract)
- PLAN.md (current sprint)
- STATUS.md (where we are)
- DEVELOPMENT.md (dev workflow)
- DEPLOYMENT.md (deploy procedure)
- TESTING.md (test strategy)
- DECISIONS.md (ADR index + templates)
- .github/CODEOWNERS
- .github/workflows/ci.yml

Preserves all existing artifacts.

Refs: RugMunchMedia/fleet-template
2026-07-02 02:07:06 +07:00

462 lines
No EOL
22 KiB
Markdown

# WalletPress — Architecture & Moving-Forward Plan
> **Status:** Canonical. Owner: WalletPress Engineering.
> **Last updated:** 2026-06-30.
> **Audience:** All engineers and agents. Read alongside AUDIT.md and SECURITY.md.
> **Purpose:** What the system is, why it is shaped that way, and where it's going.
---
## The product
**WalletPress** is an open-source (MIT) multi-chain wallet generation & management platform. The repository ships four surfaces:
| Surface | Path | Tech | Purpose |
|---------|------|------|---------|
| **Backend** | `backend/` | Python 3.12, FastAPI, SQLite | Wallet gen, vault, agent, marketplace |
| **WP plugin** | `wp-plugin/` | PHP 8, WordPress | Token gating, payments, login for WP sites |
| **Standalone MCP** | `walletpress-mcp/` | Python, FastMCP | Talk to any WalletPress backend from Claude Code / opencode / Cursor |
| **CLI** | `backend/walletpress_cli.py` | Python | Operator workflow (serve, init, generate, backup, doctor) |
Plus a marketing site (`index.html`, `buy.html`, `docs.html`, etc.) — out of scope for this doc.
---
## Architecture
### High-level
```
┌────────────────────────────────────────────────────────────────────────┐
│ WALLETPRESS BACKEND │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ HTTP API │ │ MCP │ │ CLI │ │ WS Events │ │
│ │ /docs │ │ /mcp/sse │ │ walletpress │ │ /ws/events│ │
│ │ 50+ endpoints│ │ 30+ tools │ │ 9 cmds │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Routers + Services │ │
│ │ chain_vault wallet_analysis hosting x402 agent_safety │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Core │ │
│ │ Vault | Auth | Audit | Proof | AgentSafety | Hosting | TOTP │ │
│ │ Email | Webhooks | License | HostingDB | EventBus | RateLimit │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Wallet Engine │ │
│ │ generator (BIP39/32/44) | chains (55 metadata) | CHAINS.yaml │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Adapters │ │
│ │ langchain | crewai | eliza | openai_agents | vercel_ai │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
▼ (Tailscale or Tailscale+TLS via Caddy)
┌────────────────────────────────────────────────────────────────────────┐
│ OPERATOR (Talisman) │ END USERS │
│ - Dashboard │ - WP plugin users │
│ - x402 marketplace │ - MCP clients │
│ - Backup/restore │ - Bot/automation devs │
└────────────────────────────────────────────────────────────────────────┘
```
### Module map
```
backend/
├── main.py # FastAPI app, lifespan, middleware stack
├── x402_service.py # Pay-per-wallet marketplace (mounted sub-app)
├── walletpress_cli.py # CLI entrypoint
├── client_sdk.py # Python SDK for talking to the API
├── core/
│ ├── config.py # All env-driven config
│ ├── vault.py # AES-GCM encrypted SQLite wallet store
│ ├── auth.py # API key store + scopes
│ ├── audit.py # Append-only JSONL audit log
│ ├── proof.py # Merkle tree attestations + Ed25519 receipts
│ ├── agent_safety.py # HITL, kill switch, spending limits, address book, audit chain
│ ├── hosting.py # Hosted-mode users + Stripe stub
│ ├── rate_limit.py # Token bucket middleware
│ ├── ip_allowlist.py # CIDR allowlist middleware
│ ├── license.py # JWT-signed license keys
│ ├── license_check.py # Middleware that enforces license tier
│ ├── totp.py # 2FA (TOTP)
│ ├── webhooks.py # Outbound webhook delivery + retries
│ ├── email_notify.py # SMTP notifications
│ ├── event_bus.py # In-process pub/sub
│ ├── db_pool.py # SQLite connection pool helper
│ ├── smart_wallet.py # ERC-4337 smart wallet logic (754 lines — review needed)
│ ├── arweave.py # Arweave client wrapper
│ ├── x402_verify.py # On-chain payment verification
│ ├── x402_marketplace.py # Marketplace business logic
│ ├── pdf.py # PDF generation (paper wallet, birth cert)
│ ├── response.py # Response helpers
│ ├── onboarding.py # CLI onboarding / setup wizard
│ └── proof_digest.py # Digest / hashing helpers
├── wallet_engine/
│ ├── chains.py # 55-chain registry + ChainFamily enum
│ ├── chains.yaml # User-overridable chain config
│ └── generator.py # BIP39/BIP32 wallet generator (594 lines)
├── routers/
│ ├── chain_vault.py # Wallet CRUD + paper wallet + export (2249 lines — split)
│ ├── wallet_analysis.py # Address scoring, risk
│ ├── wallet_memory.py # Wallet notes / metadata
│ ├── balance_fetcher.py # Multi-chain balance lookups
│ ├── tx_broadcaster.py # Send tx via RPC
│ ├── test_vectors.py # BIP39 test vector endpoint
│ ├── metrics.py # Prometheus metrics
│ ├── airdrop.py # CSV-driven wallet generation for airdrops
│ ├── retention.py # Data retention policies
│ ├── health_monitor.py # Health probes
│ ├── hosting.py # Hosted user CRUD
│ └── license_router.py # License key admin
├── agent/
│ ├── orchestrator.py # Natural-language → plan
│ ├── mcp_server.py # FastMCP server with 30+ tools
│ ├── scheduler.py # Background DCA / monitor / rotate tasks
│ ├── detector.py # Anomaly detection
│ └── providers.py # 20 AI provider configs
├── adapters/ # Thin wrappers for agent frameworks (stubs)
│ ├── langchain.py
│ ├── crewai.py
│ ├── eliza.py
│ ├── openai_agents.py
│ └── vercel_ai.py
├── plugins/
│ ├── defi.py # DeFi integrations + referral revenue
│ └── sdk.py # Plugin SDK
├── alembic/ # Migration framework (currently unused)
└── tests/ # 63 tests collected
```
---
## Critical user journeys
### Journey 1: User generates a wallet via WP plugin
```
WP admin → POST /wp-json/walletpress/v1/generate
→ WP plugin → backend POST /api/v1/chain-vault/wallets
→ require_auth_on_mutations (X-API-Key check)
→ chain_vault router
→ Vault.put(WalletEntry)
→ ProofOfGeneration.attest()
→ AuditTrail.log()
→ EventBus.publish("wallet.generated")
→ WebSocket broadcast → subscribers
→ Webhook delivery → subscribers
→ return {wallet_id, address, derivation_path}
→ WP plugin displays address + QR
```
**Trust assumptions:** WP plugin has a valid `walletpress_api_key`. Backend has the WP plugin's IP in `WP_ALLOWED_IPS`.
### Journey 2: AI agent executes a plan
```
User prompt: "Generate 5 SOL wallets for the airdrop"
→ MCP tool `agent_plan`
→ Orchestrator.plan_operation()
→ LLM (e.g. GPT-4o via OpenAI-compatible API)
→ Returns JSON plan: [{"tool": "wallet_generate", "args": {"chain": "sol", "count": 5}}]
→ MCP tool `agent_execute(plan, confirm=False)`
→ Orchestrator.execute_plan()
→ For each step:
→ _call_tool("wallet_generate", {...})
→ mcp_server.wallet_generate
→ _write_with_hitl → returns confirmation_id
→ user calls agent_confirm → executes
→ Vault.put()
→ ProofOfGeneration.attest()
→ AgentSafety.audit_log() (with hash chain)
→ returns execution results
```
**Trust assumptions:** LLM doesn't go off-script. Confirmation flow is respected. Audit chain is intact.
### Journey 3: Bot pays via x402 marketplace
```
Bot → POST /api/v1/marketplace/generate
→ x402_service
→ Idempotency check (return existing order if same key)
→ Payment check:
→ credits: balance check + deduct (BROKEN: P0-1)
→ onchain: verify_payment() via Solana RPC
→ free: < MIN_ORDER_USD
→ Generate wallets (in memory)
→ Sign receipt + key-deletion attestation
→ Insert order in marketplace.db
→ Return {wallets, receipt, deletion_attestation}
```
**Trust assumptions:** Receipt signing key is private. Generated keys are not logged anywhere downstream.
### Journey 4: Operator deploys to production
```
$ walletpress deploy --domain example.com
→ check license (Pro required)
→ detect OS
→ install system deps (apt-get)
→ create /opt/walletpress + venv
→ pip install -r requirements.txt
→ generate secrets (openssl rand)
→ write /etc/walletpress/env (mode 0600)
→ install systemd unit
→ enable + start walletpress.service
→ print admin key + vault password (USER MUST SAVE)
```
**Trust assumptions:** The operator reads and saves the credentials. No one else has root on the host. Tailscale mesh is configured.
---
## Why these choices
### Why FastAPI?
- Async-native. We do a lot of I/O (RPC calls, DB queries, LLM calls).
- Auto-generated OpenAPI schema → WordPress plugin gets typed SDK.
- Pydantic validation everywhere.
- Fast iteration with `uvicorn --reload`.
### Why SQLite?
- Single-file deployment. No separate DB process to manage.
- WAL mode handles concurrent reads.
- `sqlite-vec` / FTS5 for search.
- Trade-off: no horizontal scaling. For hosted mode with >100k users, migrate to Postgres (the project already has Postgres on Talos).
### Why a separate x402 sub-app?
- The marketplace has different operational requirements (no admin key needed, no internal vault, scales independently).
- `app.mount("/", x402_app)` in main.py shares the process but the routes are isolated.
- Trade-off: shared memory = shared fate. If x402 hangs, the whole process hangs.
### Why one repo, three deliverables?
- WordPress plugin is the funnel (free).
- Backend is the engine (Pro / hosted).
- CLI is the ops surface (for Pro self-hosters).
- Same repo = atomic changes, no version drift.
### Why MCP?
- AI agents (Claude Code, opencode, Cursor) are the new ops surface.
- MCP = standard protocol. Any agent that speaks MCP can use WalletPress.
- The hosted MCP is the easiest way to give non-developers access to the wallet engine.
### Why BIP39 + BIP32?
- Industry standard. Every wallet supports it.
- Same mnemonic → same address across every tool. Users can verify against MetaMask, Phantom, Trezor.
- Determinism = trust.
---
## Moving-forward plan
The product has shipped v1.0.0-beta. Before v1.0 stable, we need to:
### Phase 0: Stabilize (this week, blocking)
Goal: No P0 or P1 bugs remain. See AUDIT.md.
| Order | Item | Owner | Estimate |
|-------|------|-------|----------|
| 1 | Disable 17 BROKEN chains (P0-4) | @engineer-1 | 1 day |
| 2 | Fix x402 credits verification (P0-1) | @engineer-2 | 0.5 day |
| 3 | Move hosted passwords to Argon2id (P0-2) | @engineer-1 | 1 day |
| 4 | Persist team keys + role enforcement (P0-3) | @engineer-2 | 1 day |
| 5 | KEK file backend (P0-5) | @engineer-1 | 2 days |
| 6 | Implement or rename wallet_sweep + DCA (P0-6 + P1-13) | @engineer-3 | 1 day |
| 7 | Audit chain mutex (P1-12) | @engineer-3 | 0.5 day |
| 8 | Receipt redaction in audit log (P1-5) | @engineer-3 | 0.5 day |
| 9 | Fix x402 verify_order DB path (P1-6) | @engineer-2 | 0.25 day |
| 10 | LLM timeout + rate limit (P1-9, P1-10, P1-11) | @engineer-3 | 1 day |
| 11 | Fix _verify saves on read (P1-1) | @engineer-2 | 0.5 day |
| 12 | Audit trail integrity (P1-4) | @engineer-2 | 1 day |
**Total: ~10 engineer-days.** Cut `v1.0.0-audit` after this phase.
### Phase 1: Fix the 17 broken chains (this sprint)
Per-chain work. Each chain needs:
- Reference SDK installed in dev requirements
- `tests/test_address_vectors.py` golden-vector test
- Implementation in `wallet_engine/generator.py` (or a new per-chain module)
- Update `chains.py` to remove `generation_disabled`
- Update `ADDRESS_GENERATION.md`
Priority order (highest user demand first):
1. **Stellar** (`xlm`) — 30 min, use `stellar-sdk`
2. **Tezos** (`xtz`) — 1 hour, use `pytezos`
3. **Injective** (`inj`) — 1 hour, bech32 + ETH path
4. **Cosmos Hub** (`atom`) — 1 hour, bech32
5. **Osmosis / Sei / Juno / Evmos** — 2 hours each, same pattern
6. **Algorand** (`algo`) — 1 hour, base32 + checksum
7. **TON** (`ton`) — 2 hours, custom format
8. **Filecoin** (`fil`) — 1 hour, blake2b
9. **Nano** (`xno`) — 1 hour, base32 + blake2b
10. **Polkadot / Kusama** — 4 hours, sr25519 (use `substrate-interface`)
11. **Monero** (`xmr`) — 6 hours, custom Monero crypto
12. **Cardano** (`ada`) — 8 hours, Bech32 stake/enterprise
13. **Bitcoin Cash** (`bch`) — 1 hour, cashaddr
14. **XRP** (`xrp`) — 2 hours, custom base58 alphabet
15. **Zcash** (`zec`) — 1 hour, prefix fix
**Total: ~25 engineer-days.** Cut `v1.1.0` after this phase.
### Phase 2: Architectural cleanup (next sprint)
| Item | Why | Estimate |
|------|-----|----------|
| Split `chain_vault.py` (2249 lines) into 4 modules | Maintainability | 2 days |
| Migrate raw SQL → Alembic | Schema migrations | 3 days |
| Consolidate DB paths to one `walletpress.db` | Operations | 1 day |
| Pluggable KeyBackend (env / file / KMS) | P0-5 follow-on | 3 days |
| Per-wallet derived keys (HKDF) | Revocation granularity | 2 days |
| Pydantic models for all MCP tool args | Type safety | 2 days |
| Repository pattern for SQLite stores | Testability | 3 days |
| Replace JSON `KeyStore` + `TeamKeyStore` with SQLite | Persistence | 1 day |
**Total: ~17 engineer-days.** Cut `v1.2.0` after this phase.
### Phase 3: Ship the roadmap (next month)
From ROADMAP.md (now validated against actual code gaps):
| Item | From | Status | Notes |
|------|------|--------|-------|
| #1 Paper wallet PDF | ROADMAP | already exists (`core/pdf.py`) | Verify output |
| #2 SSE progress for batch | ROADMAP | not built | High impact |
| #3 Mnemonic auto-detect chain | ROADMAP | not built | After phase 1 |
| #4 QR codes on addresses | ROADMAP | already built (`?include_qr=true`) | Verify |
| #5 Webhook delivery log + retry | ROADMAP | partial | `webhooks.py` has retries but no UI |
| #6 Per-API-key rate limit | ROADMAP | partial | Falls back to IP — fix |
| #7 Backup + restore CLI | ROADMAP | partial — doesn't encrypt | Add encryption |
| #8 Clean error messages | ROADMAP | partial | Audit each router |
| #9 Temporal wallet cleanup | ROADMAP | built (`temporal_cleanup_loop`) | Verify |
| #10 Full-text search | ROADMAP | built (FTS5) | Verify |
| #11 Email verification | ROADMAP | **not built** | High priority for hosted |
| #12 Login rate limit | ROADMAP | **not built** | High priority |
| #13 Birth certificate PDF | ROADMAP | already built (`core/pdf.py`) | Verify |
| #14 Chain auto-detect on import | ROADMAP | not built | After phase 1 |
| #15 Signed webhook payloads | ROADMAP | already built (HMAC-SHA-256) | Verify |
**Real outstanding: SSE batch, email verification, login rate limit, encrypted backup, chain auto-detect.**
### Phase 4: Operational maturity (month 2)
- Off-site backup replication (Hydra mirror, daily)
- Monitoring + alerting (Loki + GlitchTip + Grafana)
- Load testing (Locust)
- Penetration test (external)
- SBOM + Sigstore for Docker images
- GDPR data export + delete endpoints for hosted
### Phase 5: Desktop + Mobile (month 3+)
From STRATEGY.md:
- **Tauri desktop app** (offline-capable, bundled backend)
- **PWA / React Native** (mobile wallet generator)
These are separate product surfaces. Defer until v1.2.0 ships.
---
## What we are NOT building
To keep the team focused, we're explicitly saying no to:
1. **Browser-extension wallet.** Too much surface area for security bugs. MetaMask owns this. WP plugin + MCP is enough.
2. **On-chain transaction broadcasting as a feature for self-hosted.** Tx broadcasting requires custody decisions and MEV protection. Pro users get signing only. Hosted gets delegated through Stripe KYC'd accounts.
3. **In-app DEX / swap.** Too many chains, too many MEV risks, too much regulatory exposure. The referral kickback via `plugins/defi.py` is enough.
4. **Multi-sig / threshold sig.** Complex. High error rate. Trezor/Ledger own this.
5. **Hardware wallet integration.** Ledger/Trezor already cover this. We're the software layer on top.
---
## Non-goals (for v1.x)
- ICO / token launch tooling
- NFT minting
- DAO tooling
- Web3 identity (DID / verifiable credentials)
- Decentralized storage integration
- Browser extension
---
## Open architectural questions
Need product-side decisions before we build:
1. **Hosted vs self-hosted split.** Today both share a codebase. Should hosted be a fork?
- Pro: cleaner boundary, fewer env vars
- Con: double maintenance burden
- Recommendation: shared codebase, but `if cfg.hosted:` branches in the right places.
2. **MCP as the only AI surface, or also LangChain/CrewAI/Eliza adapters?**
- The adapters are stubs today. Either implement or remove.
- Recommendation: implement only MCP. It's the standard. The others can wrap MCP if needed.
3. **WordPress plugin strategy.**
- The plugin is GPL by WordPress convention. Backend is MIT.
- Recommendation: keep plugin separate, MIT-licensed too. Some users fork.
4. **Postgres migration for hosted mode.**
- SQLite + WAL handles ~100 concurrent users.
- Beyond that, need Postgres.
- Recommendation: phase this when we hit 1000 paid users.
5. **Lightweight Postgres-only deployment.**
- Skip SQLite, always Postgres.
- Recommendation: out of scope for v1. SQLite is part of the value prop.
---
## Cross-product consistency
WalletPress is one of three Rug Munch Media products. To avoid duplicate implementations:
| Concern | WalletPress | RMI | Pry |
|---------|-------------|-----|-----|
| Multi-tenant user mgmt | `core/hosting.py` | (RMI uses Talos Postgres auth) | (Pry is single-tenant) |
| API key store | `core/auth.py` | (RMI uses HTTP-only sessions) | (Pry uses env) |
| Audit trail | `core/audit.py` (JSONL) | RMI `app/audit/` (Postgres) | (Pry logs to stderr) |
| RPC pool | hardcoded list in `chains.py` | `app/databus/` (52 files) | per-job RPC |
| Provider pattern | `agent/providers.py` (20 AI providers) | `app/scanners/shared.py` | per-job |
**Decision:** Each product owns its own. Sharing via a `rugmunch-common` package is rejected — over-engineering for three products. Copy-paste OK if it keeps the products independent.
---
## See also
- `AUDIT.md` — bugs and fixes (priority-ordered)
- `SECURITY.md` — threat model, auth, crypto rules
- `ADDRESS_GENERATION.md` — per-chain truth table
- `BUILDER.md` — daily workflow for agents
- `WALLETPRESS.md` — single-paragraph product summary