Data & on-chain layer
Data stores
PostgreSQL (system of record)
All services share one PostgreSQL 16 database through Prisma 5. The schema is the single source of truth at packages/db/prisma/schema.prisma, and the generated client ships as the @axon/db package. Migrations live in packages/db/prisma/migrations/ and are applied in production by the one‑shot db-migrate container (prisma migrate deploy).
The entities group into a few domains (full reference in Developer → Data model):
- Identity:
User,Profile(PERSONAL / BUSINESS),ProfileWallet,Nonce,RefreshToken. - Agreements:
Agreement,AgreementMilestone,Notification. - Movements:
Transaction,Settlement(+ hash‑chained ledger rows),LedgerAnchor. - Distributions:
Distribution,DistributionRoute,RoutingDecision,PolicyConfig. - Instant funding:
FundingFacility,FundingCoverage,CollectionLedgerEntry. - Ops & audit:
AuditLog,AdminAlert,WebhookEvent,OnboardingGrant.
No cross‑service foreign keys. Links that cross a service boundary are plain string IDs (e.g.
FundingCoverage.settlementId), not Prisma relations. This keeps each service independently deployable; integrity is enforced in code, not by the database.
Redis
Redis 7 holds ephemeral state only: login nonces, rate‑limit windows, and short‑lived caches. Nothing in Redis is a system of record.
On-chain layer (Base)
AXON settles and custodies value on Base (Coinbase's L2). On the pilot this is Base Sepolia (chain id 84532); USDC is represented by MockUSDC.sol.
AXONEscrow.sol
The escrow contract holds USDC for milestone agreements. Key properties:
- Acceptance‑gated: an agreement is created in draft and only becomes fundable after the counterparty calls
acceptAgreement. - Milestone funding & release: the initiator funds each milestone; the counterparty marks it complete, starting a 5‑day timeout after which release is permissionless (funds can't be held hostage).
- Disputes: either party can freeze the agreement and propose a split (
recipientBps); the other accepts to settle the funded pot. - Fee snapshot: the platform fee is captured at funding time (
feeBpsAtFunding) and used at release — the owner can change the live fee for future milestones but cannot retroactively raise fees on funds already escrowed. - Indexed events: every event carries the
offChainIdindexed, so it's filterable on BaseScan and joinable to off‑chain records.
Collection wallet
An AXON‑controlled wallet used by Instant Funding. When a business accepts a facility it grants a USDC allowance to this wallet; the CollectionSweeper later pulls covered USDC out of the business wallet via transferFrom. Every sweep writes a CollectionLedgerEntry for audit.
Operation hashes — linking off-chain to on-chain
Each cross‑cutting operation carries an operationHash: a UUID encoded as a bytes32, byte‑identical to the value passed to the contract as offChainId. This gives a deterministic, two‑way link:
- a database row → its on‑chain event (and BaseScan transaction), and
- an on‑chain event → the off‑chain operation that produced it.
The settlement ledger & anchoring
Every money movement — escrow fund/release, distribution route, instant‑funding coverage — is written to an append‑only, hash‑chained ledger in the settlements service:
- each row's
entryHashis derived from the previous row's hash plus the row's immutable substance (amount, currency, FX, timestamp), forming a tamper‑evident chain; - lifecycle fields (status, txHash) are mutable, but the substance is frozen;
GET /settlements/verifyrecomputes the chain to detect tampering;- an anchor worker periodically pins the chain head (
headHash, sequence) to Base as aLedgerAnchor, so the ledger's integrity can be proven against the chain at a point in time.
This is what lets AXON claim an audit‑ready, provable record of every transaction.