Appearance
Repo Contracts
This page answers the operational question: which repo owns this behavior, and which repos must change together?
Ownership Map
| Repo | Owns | Must not own |
|---|---|---|
vela-protocol | On-chain state, instruction accounts, account layouts, transfer-hook enforcement, events, IDL | App display labels, hosted UX, webhook retry policy |
vela-sdk | Protocol builders plus public Payment Intent, refund, Commerce error, and event types | Merchant database state, RPC verification policy, app-specific UI |
vela-dashboard | Merchant app, Commerce APIs/data, D1 schema, RPC verification, documents, audit, outbox/fan-out, keeper orchestration | Protocol account layouts not mediated by SDK; customer wallet signing |
vela-webhook | Public HMAC verifier, event schemas, fixtures, retry/idempotency helpers | Event production, merchant routing, delivery persistence |
vela-checkout | Public /pay/:id, /session/:id, payment-link, and invoice experiences; wallet/QR interaction | Merchant-authenticated writes, verification policy, canonical business state |
vela-mail | Typed invoice and receipt email presentation and transport | Payment/refund state, PDF generation, or document persistence |
vela-widget | Embedded checkout loader and iframe UX | Backend billing truth |
vela-portal | Subscriber self-service, cancellations, plan switching, invoice view | Merchant admin state |
vela-admin | Protocol ops, emergency controls, audit trail, token config admin UI | Merchant-facing flows |
vela-docs | Public developer explanation | Private ops secrets or internal-only decisions |
vela-web | Marketing and conversion | Protocol integration logic |
internal-wiki | Internal operations, architecture, decisions, release history | Public API promises |
Dependency Graph
text
vela-protocol
-> vela-sdk
-> vela-dashboard
-> vela-webhook
-> vela-checkout
-> vela-widget
-> vela-portal
-> vela-admin
-> vela-demo
-> vela-docs
-> internal-wikivela-web is mostly independent.
Contract Surfaces
Protocol to SDK
Owned by vela-protocol, consumed by vela-sdk.
| Surface | Files/artifacts |
|---|---|
| Program IDs | declare_id!(), Anchor.toml, config/program-ids.json, generated program IDs |
| IDL | target/idl/*.json, SDK idl/*.json |
| Instruction accounts | Rust instruction contexts, SDK builders |
| Account layout | Rust account structs, SDK deserializers/types |
| Event shape | Rust event structs, SDK event schemas |
| Error codes | Rust errors, SDK error translation |
Rule: SDK must be updated before runtime consumers move.
SDK to Runtime Apps
Owned by vela-sdk, consumed by app repos.
| Surface | Consumers |
|---|---|
createVelaClient | Demo, docs examples, apps |
| Raw builders | Dashboard, checkout, widget, portal, admin |
@velapay/sdk/browser / browser-safe exports | Checkout, widget |
| Event schemas | Webhook package, dashboard worker |
| Token helpers | Dashboard, checkout, portal, docs |
| Generated program IDs | Dashboard, admin, docs |
Rule: if apps need to duplicate SDK logic, consider moving that logic into the SDK first.
Dashboard to Admin
Owned by vela-dashboard, consumed by vela-admin.
| Surface | Contract |
|---|---|
| Service binding routes | Admin uses internal dashboard Worker APIs |
| D1 schema | Dashboard owns migrations and database model |
| Audit/event views | Admin displays operational data from dashboard paths |
Rule: admin should not bypass dashboard-owned data access unless deliberately creating a new operational boundary.
Protocol Events to Webhook Consumers
Owned by protocol and SDK event schemas, delivered by dashboard/webhook.
| Field | Rule |
|---|---|
mint | Canonical token identity |
token_symbol | Required string display metadata; may be empty |
signature, slot, mandate | Required envelope fields |
| event discriminator | Must remain stable or ship a new schema version |
Rule: consumers may enrich display labels but must preserve raw event truth.
Which Repo Do I Change?
| Need | Start here | Then check |
|---|---|---|
| Add protocol instruction | vela-protocol | vela-sdk, dashboard/checkout/widget/admin/docs |
| Add account field | vela-protocol | vela-sdk deserializers, dashboard indexers, admin, docs |
| Change plan creation | vela-protocol + vela-sdk | dashboard, checkout, widget, demo, docs |
| Change subscription transaction | vela-sdk | checkout, widget, portal, dashboard |
| Change event payload | vela-protocol + vela-sdk/events | vela-webhook, dashboard worker, docs |
| Change webhook delivery | vela-dashboard | vela-webhook, docs |
| Change hosted checkout UX | vela-checkout | widget if embedded flow mirrors it |
| Change Payment Intent or refund API | vela-dashboard + vela-sdk | checkout, webhook package, docs |
| Change commerce event payload | vela-sdk/events + vela-dashboard | vela-webhook, merchant docs and fixtures |
| Change receipt or credit-note PDF pipeline | vela-dashboard | checkout, exports, customer and auditor views; update vela-mail only when email presentation changes |
| Change portal cancellation/switching | vela-portal | checkout/session APIs, SDK |
| Change admin token config | vela-admin | protocol token config, SDK builders |
| Change docs examples | vela-docs | SDK README and demo |
| Change internal process | internal-wiki | README links and nav |
Search Recipes
Find program ID references:
sh
rg -n "CVM6UqbwKgHckZzm8R2qbN3BWhCTdk1PsSeEQLchkwKT|3agVoFp4NZFuKbVqCV8HbjSZn1xW4Utk4U1Wir3TKjZ9" \
/Users/laitsky/Developments/vela-labs \
-g '!node_modules' -g '!dist' -g '!build' -g '!target'Find token assumption drift:
sh
rg -n "USDC-only|sUSDC|wrappedUsdcMint|billingMint|token_symbol|UNKNOWN" \
/Users/laitsky/Developments/vela-labs/vela-* \
-g '!node_modules' -g '!dist' -g '!build' -g '!target'Find instruction-builder consumers:
sh
rg -n "build[A-Za-z]+Instruction|createPlan\\(|createSubscription\\(|wrapAndSubscribe|pullPayment" \
/Users/laitsky/Developments/vela-labs/vela-* \
-g '!node_modules' -g '!dist' -g '!build' -g '!target'Compatibility Smells
Treat these as review triggers:
- app code imports a generated IDL directly instead of SDK helpers
- app code derives PDAs manually
- event consumer overwrites
mintor normalizestoken_symbol - UI assumes every token is USDC
- worker catches and hides protocol errors with generic fallback
- docs show old account requirements
- tests pass only because fixtures hardcode wrapped USDC