Appearance
Architecture
System Overview
VelaPay is a 9-repo billing system with a dedicated planning layer. The architecture spans four horizontal layers from on-chain primitives to application surfaces, with a dual-program protocol at the foundation.
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 4: Applications │
│ Dashboard Portal Checkout Admin Web Docs Widget │
│ (Railway) (CF) (CF) (CF) (CF) (CF) (CDN) │
├─────────────────────────────────────────────────────────────────────┤
│ Layer 3: Revenue Finance (Future) │
│ MRR Oracle Lending Marketplace │
├─────────────────────────────────────────────────────────────────────┤
│ Layer 2: Billing Engine │
│ Mandate Registry Stream Engine Usage Meter Keeper Network │
│ Pull Approvals Rate-per-sec Agent Budgets Cron Workers │
├─────────────────────────────────────────────────────────────────────┤
│ Layer 1: Protocol Core + Privacy │
│ Vela Mandate (Transfer Hook) + Arcium MXE + Credentials │
├─────────────────────────────────────────────────────────────────────┤
│ Base Layer │
│ Solana Token-2022 Arcium MXE Network Helius RPC │
└─────────────────────────────────────────────────────────────────────┘Delivery System
┌──────────────────────┐
│ .planning/ layer │ ← Authoritative project state
│ STATE / ROADMAP │
│ REQUIREMENTS │
│ Phase artifacts │
└──────────┬───────────┘
│ informs
▼
┌──────────────────────┐
│ 11 product repos │ ← Independent deploy lifecycles
│ + wiki │
└──────────────────────┘4-Layer Architecture
Base Layer: Solana Token-2022 + Arcium + Helius
The base layer provides the primitive infrastructure that VelaPay builds on.
Solana Token-2022 is the token standard. VelaPay exclusively uses Token-2022 (not legacy SPL Token) because it supports:
- Transfer Hooks — custom programs that run during every
transfer_checked. This is the enforcement mechanism for billing mandates. - Transfer Fees — platform revenue extraction at the token-transfer level.
- Metadata Pointer — on-chain plan terms stored as token metadata.
- Non-Transferable — subscription credentials that can't be traded.
- Interest-Bearing — idle escrow yield (future).
Arcium MXE Network provides Multiparty Computation eXecution Environments. Arcium handles arbitrary computation on encrypted data — usage calculations, analytics, credit scoring, compliance checks — all on ciphertext. No validator, competitor, or chain analyst can observe billing logic inputs or outputs.
Helius is the RPC and indexing backbone:
- Enhanced RPC for on-chain reads (mandate state, credential checks, account deserialization).
- Webhooks for real-time subscription event indexing (mandate creation, pull execution, cancellation, stream events, upgrade events).
- DAS API for credential and asset queries.
Layer 1: Protocol Core + Privacy
Layer 1 is the dual-program Anchor workspace in vela-protocol.
Dual-Program Split
| Program | Role | Why separate |
|---|---|---|
vela-protocol | Creates plans, subscriptions, pull approvals, usage flows, stream mandates, wrapped mint flows, config management, Arcium callbacks, agent mandates | Main business logic program — handles all billing state transitions |
vela-transfer-hook | Enforces PullApproval at Token-2022 transfer time — validates mandate is active, amount is within authorization, period/stream constraints are satisfied | Runs during transfer_checked CPI — must be isolated for security. Any bug here either lets merchants steal or blocks legitimate payments. |
The split exists because the transfer-hook path is invoked synchronously during transfer_checked. It must be:
- Minimal — only validates approval, doesn't compute billing logic.
- Fail-closed — if validation fails for any reason, the transfer fails. No silent overdraft.
- Upgradeable — deployed via BPF Loader Upgradeable with dynamic
ExtraAccountMetaList(8 slots) so the hook can evolve without redeploying the main protocol.
Account Model
Core on-chain accounts:
| Account | Purpose | Key fields |
|---|---|---|
ProtocolConfig | Global config — admin, transfer hook program ID, keeper authority | admin, transfer_hook_program_id, keeper_authority, paused |
Plan | Merchant billing plan definition — amount, period, token mint | merchant, amount, period, mint, version, reserved space |
Mandate | Subscriber's authorization for a specific plan — the billing mandate | plan, subscriber, merchant, period_start, period_end, pull_count, pending_upgrade, version |
StreamMandate | Rate-per-second streaming authorization | subscriber, merchant, authorized_max_rate, last_settled_ts, total_streamed, paused, pending_rate_change |
PullApproval | Ephemeral approval written before a pull — consumed by transfer hook | mandate, amount, expires_at, nonce |
Credential | Non-transferable Token-2022 token proving active subscription | Per-merchant (v1.7+), tracks subscriber↔merchant relationship |
TokenConfig | Per-mint billing rail configuration | mint, decimals, enabled, oracle |
AgentMandate | Scoped agent spending authorization | daily_limit, lifetime_limit, per_service_limit, pull_cooldown |
Credential System
Credentials are Non-Transferable Token-2022 tokens minted to subscribers when they subscribe. They prove an active subscription relationship without exposing billing details. Key properties:
- Per-merchant (v1.7+): Credentials track the subscriber↔merchant relationship, not the plan tier. Plan switching doesn't require re-minting.
- Non-transferable: Cannot be traded or moved between wallets.
- Metadata-bearing: Carry subscription metadata via Metadata Pointer extension.
Layer 2: Billing Engine
Layer 2 is the execution engine that makes billing happen on-chain and off-chain.
Mandate Registry
The mandate registry is the on-chain set of all active billing authorizations. Every subscriber-plan pair creates a Mandate PDA. The registry supports:
- Periodic pulls — merchant or keeper executes
execute_pull, which writes aPullApprovalthen callstransfer_checked. - Streaming — rate-per-second mandates settle accrued debt via
execute_streamwith settle-then-mutate invariant. - Agent mandates — scoped spending limits for AI agents with daily/lifetime/per-service caps.
Stream Engine (v1.8)
The streaming engine is a distinct billing primitive — not "periodic with period=1". Key properties:
- Rate-per-second authorization: Subscribers authorize a maximum rate, not a fixed amount.
- Settle-then-mutate invariant: Every state-changing instruction (pause, resume, rate change, cancel) settles accrued debt first. A single private helper enforces this across all mutation paths.
- Zero silent overdraft: Transfer hook fails closed with typed errors when ATA balance is insufficient.
- Real-time accrual: SDK computes
accruedNow()client-side without RPC calls between settlements. - Checked math: All accrual uses
checked_*operations withu128intermediates againstu64::MAXnear-boundary cases.
Usage Meter
Usage-based billing tracks consumption against plan limits. Usage values flow through Arcium encrypted compute so merchants can bill on private metrics without exposing usage data to chain observers.
Keeper Network
Keepers are Cloudflare Workers that execute billing on behalf of merchants:
- Periodic keeper: Executes scheduled pulls for active mandates.
- Stream settlement keeper: Separate worker (different cadence and failure semantics) that settles accrued streaming debt.
- Synthetic E2E worker (
vela-synthetic): 15-minute cron that validates the full billing pipeline against devnet staging.
Keepers are authorized via ProtocolConfig.keeper_authority and can be monitored, force-retried, and controlled through the admin dashboard.
Layer 3: Revenue Finance (Future)
Layer 3 is the future product vision — financial products built on top of verifiable recurring revenue:
- MRR Oracle: Verifiable on-chain Monthly Recurring Revenue metric derived from active mandates. Enables revenue-based lending.
- Lending: Revenue-backed loans using MRR as collateral. Merchants can borrow against their subscription revenue.
- Marketplace: Subscription marketplace where investors can buy/sell revenue streams.
Layer 3 is out of scope until the billing engine (Layer 2) is proven in production. See 10-future-vision-layer3-and-beyond.md for the full thesis.
Layer 4: Applications
Layer 4 is the user-facing product surfaces. Each runs as an independent deployable unit.
Billing Execution Path
Phase 0 (Current — No Arcium)
Billing works standalone without privacy. All billing data is observable on-chain.
Merchant or Keeper
│
▼
request_validation / usage computation
│
▼
vela-protocol writes PullApproval PDA
│
▼
execute_pull instruction
│
▼
Token-2022 transfer_checked CPI
│
▼
vela-transfer-hook validates:
├─ Mandate is active?
├─ Amount within authorization?
├─ Period constraints satisfied?
├─ PullApproval nonce matches?
└─ Mandate type matches (periodic vs stream)?
│
▼
Transfer succeeds OR fails closed (typed error)Phase 1+ (Future — With Arcium)
Privacy layer adds encrypted billing logic. The execution path gains an Arcium round-trip.
Merchant or Keeper
│
▼
request_validation / usage computation
│
▼
Arcium MXE evaluates encrypted billing logic
├─ Input: encrypted mandate terms, encrypted usage
├─ Computation: amount calculation, limit checks
└─ Output: encrypted PullApproval parameters
│
▼
Arcium callback writes PullApproval
│
▼
execute_pull / execute_stream
│
▼
Token-2022 transfer_checked CPI
│
▼
vela-transfer-hook validates (same as Phase 0)
│
▼
Transfer succeeds OR fails closedThe key insight: the transfer hook validation path is identical in both phases. Arcium only changes how the PullApproval is computed, not how it's enforced. This means the core security property survives the privacy layer addition.
Repo-to-Repo Relationships
Full dependency graph showing how repos depend on each other:
| Source | Depends on | Why |
|---|---|---|
vela-protocol | Solana Token-2022, Arcium | Base layer primitives — transfer hooks, encrypted compute |
vela-sdk | vela-protocol | Encodes program clients, instruction builders, PDAFactory, IDL, account types |
vela-dashboard | vela-sdk, D1, Helius | Merchant plan/subscription flows, protocol reads, event indexing |
vela-checkout | vela-sdk, D1 | Builds checkout and subscription transactions, session management |
vela-portal | vela-sdk, D1 | Subscriber self-service, plan switching, mandate cancellation |
vela-admin | vela-dashboard (service binding) | Uses service binding for backend access and shared protocol data paths |
vela-widget | vela-sdk | Builds checkout transactions in iframe context |
vela-webhook | vela-sdk (events) | Consumes @vela/sdk/events Zod schemas, wraps raw Helius payloads |
vela-web | — | Static landing page, no protocol dependency |
vela-docs | workspace knowledge | Documents SDK and protocol usage |
vela-synthetic | vela-sdk, devnet staging | Runs E2E validation against deployed staging stack |
Service Binding Architecture
vela-admin (Cloudflare Worker)
│
│ Service Binding (internal RPC)
▼
vela-dashboard (Cloudflare Worker)
│
│ D1 binding
▼
D1 Database (merchant data, sessions, analytics)vela-admin never directly accesses D1. All database operations go through service bindings to the dashboard Worker. This ensures:
- Admin auth is isolated from merchant auth.
- Admin traffic never hits merchant-facing endpoints.
- D1 schema changes are coordinated through a single path.
Application Surfaces
vela-protocol — Anchor Program (Rust)
What it does: The on-chain billing primitive. Dual-program Anchor workspace with vela-protocol (main business logic) and vela-transfer-hook (transfer-time enforcement).
Who uses it: Every other repo in the workspace. The SDK wraps it. The dashboard reads from it. The keepers write to it. The transfer hook enforces it.
How it connects: Exports IDL consumed by vela-sdk. Programs deployed to Solana devnet (mainnet target). Transfer hook registered with Token-2022 mints.
Key instructions:
- Periodic:
create_plan,subscribe,execute_pull,cancel,update_plan - Streaming (v1.8):
create_stream_mandate,execute_stream,pause_stream,resume_stream,update_stream_rate,cancel_stream - Upgrades (v1.8):
initiate_upgrade,apply_upgrade,cancel_upgrade - Agent (v1.4):
create_agent_mandate,agent_pull,revoke_agent_mandate,adjust_agent_mandate,pause_agent_mandate,resume_agent_mandate,drain_agent_mandate - Admin:
pause_protocol,unpause_protocol,admin_cancel - Config:
init_token_config,update_token_config,update_config,update_keeper_config
vela-sdk — TypeScript SDK + CLI
What it does: Developer-facing API to the protocol. Instruction builders, account derivation, PDAFactory, CLI tooling, and now @vela/sdk/events for typed webhook event schemas.
Who uses it: vela-dashboard, vela-checkout, vela-portal, vela-widget, vela-webhook all import from @vela/sdk. External developers use it to build on VelaPay.
How it connects: Published to npm as @vela/sdk. Imports Anchor IDL from protocol. Exports VelaClient, PDAFactory, instruction builders, UpgradeBuilder, StreamMandate deserializers, formatAmount/parseAmount, and browser-safe barrel via @vela/sdk/browser.
vela-dashboard — Merchant Dashboard
What it does: Wallet-authenticated (now email-primary) merchant app for plan creation, subscriber management, billing analytics, webhook event indexing, and now webhook endpoint management.
Who uses it: Merchants. The primary product surface for business users.
How it connects: Vite + React SPA + Hono Worker. D1 for merchant data. Helius webhooks for on-chain event indexing. Service binding exposes API to vela-admin. Consumes @vela/sdk for all protocol interactions.
Deployment: Railway (SSR) + Cloudflare (Worker, D1, KV, R2, Queues).
vela-admin — Internal Ops Dashboard
What it does: Wallet-gated SIWS auth for protocol team. Protocol monitoring (TVL, mandates, merchants, volume), keeper monitoring and control, merchant management, emergency controls (pause/unpause/cancel), observability (event stream, reconciliation, cost tracking), immutable audit trail.
Who uses it: Protocol team only. Never exposed to merchant traffic.
How it connects: Separate Cloudflare Worker with service binding to vela-dashboard. Auth gated to ProtocolConfig PDA admin field. All database operations proxied through dashboard Worker.
vela-checkout — Hosted Checkout
What it does: Public checkout at pay.velapay.com. Session API creates checkout sessions. Wallet approval flow with Turnstile gating. Payment links with QR codes and UTM analytics. Invoice pages with PDF generation and email delivery.
Who uses it: Subscribers checking out via merchant payment links, pricing tables, or direct checkout URLs.
How it connects: Hono Worker + React + D1. Consumes @vela/sdk for transaction building. Shares checkout-session creation path with vela-portal switch-plan flow.
vela-portal — Subscriber Self-Service
What it does: Subscriber portal at portal.velapay.com. Magic-link and SIWS auth. Subscription management — view active subscriptions, cancel, switch plans. Invoice downloads. Multi-token rendering via TokenConfig resolution.
Who uses it: Subscribers managing their own subscriptions.
How it connects: Hono Worker + React + D1. Consumes @vela/sdk for mandate interactions. Shares checkout-launch path with vela-checkout for plan switching.
vela-web — Landing Page
What it does: velapay.com. Value proposition, code snippets, developer CTAs. Privacy-friendly Cloudflare Web Analytics.
Who uses it: Potential merchants and developers discovering VelaPay.
How it connects: Astro 6.1 static site. Deployed to Cloudflare Workers. No protocol dependency — purely informational.
vela-docs — Developer Documentation
What it does: docs.velapay.com. 60 MDX pages with audience-based IA (merchants/developers/subscribers). Custom Starlight theme with emerald palette. SDK reference, integration guides, cookbook recipes, Mermaid diagrams.
Who uses it: Developers integrating with VelaPay and merchants setting up their billing.
How it connects: Astro + Starlight. Deployed to Cloudflare Workers. Documents the SDK and protocol produced by other repos. Now includes webhook event reference pages.
vela-widget — Embedded Checkout
What it does: Tiny loader script that merchants embed on their pages. Renders checkout or <vela-pricing-table> in an iframe. Wallet discovery on the parent page, signing bridged via postMessage. Shadow DOM with DSD support, theming, WCAG-conscious interaction.
Who uses it: Merchants embedding checkout on their own websites.
How it connects: Consumes @vela/sdk. Returns to merchant origin via postMessage with strict CSP. Multi-token plan rendering via Phase 46 TokenConfig resolution.
vela-webhook — Webhook Event SDK
What it does: @vela/webhook package — Zod-typed discriminated union over all Vela events, HMAC-SHA256 verifier (Stripe wire format), Svix-style retry dispatcher with DLQ, merchant endpoint CRUD.
Who uses it: Merchants receiving webhook deliveries. Dashboard dispatcher is the first consumer (replaces inline Helius parsing).
How it connects: Workspace package inside vela-sdk monorepo. Consumes @vela/sdk/events schemas. Wraps raw Helius payloads (not a new event feed).
vela-synthetic — E2E Cron Worker
What it does: Cloudflare Cron Worker running every 15 minutes against devnet staging. Validates the full billing pipeline end-to-end. Pages on failure.
Who uses it: Protocol team for continuous staging validation.
How it connects: Runs against deployed staging stack. Consumes @vela/sdk.
Privacy Posture
What an Observer CAN Infer
From on-chain data alone, a chain analyst can determine:
- That a transfer happened between two addresses.
- That addresses interacted with the Vela program.
- That credential and token artifacts exist.
- That protocol actions were executed (subscribe, pull, cancel, stream settle).
- The token mint involved (USDC, PYUSD, etc.).
What an Observer CANNOT Determine
With Arcium MPC (Phase 1+), the following are hidden:
- Billing logic inputs — encrypted mandate terms, usage values, pricing calculations.
- Merchant-private billing records — individual transaction amounts in context, customer-level revenue data.
- Full business meaning — the competitive-significant interpretation of a pull authorization (e.g., which plan tier, what usage threshold triggered it, whether it was a retry).
- Aggregate analytics — total MRR, customer churn rates, revenue concentration — all computed on ciphertext.
Why This Matters
On-chain transparency is a feature for settlement finality but a bug for business competitiveness. If a competitor can see your revenue, pricing, and customer data by reading the chain, you're at a structural disadvantage. VelaPay's privacy posture means:
- Merchants can run subscription businesses without exposing metrics to competitors.
- Subscribers don't have their spending patterns publicly linkable.
- The protocol works identically with or without privacy — security doesn't depend on Arcium.
The privacy posture is only credible because enforcement and validation are split correctly across Token-2022, the transfer hook, and Arcium. The transfer hook validates deterministically; Arcium computes privately. These are independent security domains.
Operational Layer
The architecture is not just code. The .planning/ directory is part of the delivery system and has architectural significance:
- Requirements traceability — Every feature maps to a requirement in
REQUIREMENTS.mdwhich maps to a phase and plan. No orphaned work. - Decision log —
PROJECT.mdandSTATE.mdaccumulate key decisions with rationale and outcomes. This is the architectural decision record. - Execution state —
STATE.mdwith machine-readable frontmatter enables automated state tracking across sessions. - Milestone audits — Every milestone gets an audit that captures what actually shipped vs. what was planned, including accepted tech debt.
- Process evolution —
RETROSPECTIVE.mdrecords how the development process itself evolved, informing future architectural decisions.
The planning layer ensures the architecture doesn't just exist in code but is continuously documented, validated, and corrected as the system evolves.