0Pools architecture
The product architecture of 0Pools: product surfaces, partner API, quote controls, ledger, status, settlement, and operations.
0Pools sits between user-facing products and the liquidity operations behind each pool. It lets approved products draw from a shared pool layer through stable records: entitlement, quote, trade, status, webhook, balance, and ledger.
Architecture at a glance
Four layers
| Layer | Purpose | Partner sees |
|---|---|---|
| Product layer | 0Gate, 0Base, partner apps, dashboards. | Product-specific states and approved user UX. |
| Partner API layer | Pool discovery, quote, transact, status, trade, balance. | Partner-scoped records only. |
| Network layer | Entitlements, quote controls, trade lifecycle, ledger joins. | IDs, statuses, amounts, fees, timestamps. |
| Behind-the-scenes operations | Venue execution, settlement adapters, reconciliation, treasury. | Not exposed through the partner API; represented by availability and status outcomes. |
Control flow
Control flow is about authorization and intent:
- Partner key proves environment and organization.
- Entitlement proves the partner can see or use the pool.
- Quote request proves the exact side, amount, pair, network, and delivery target.
- Transact request proves acceptance and carries idempotency.
- Status/webhook proves the trade outcome.
Money flow
Money flow is intentionally more restricted than control flow.
The API avoids treating a browser click as money movement. Settlement is represented by server records.
Data flow
| Data | Source of truth |
|---|---|
| Pool availability | Discovery and quote responses. |
| Supported sides/networks/limits | Capabilities. |
| Price accepted by user | Firm quote. |
| Execution id | Trade. |
| Final outcome | Status poll or terminal webhook. |
| Finance movement | Balance ledger and partner ledger. |
Why the architecture matters
Before a shared pool layer, every product had to create its own liquidity state, quote state, retry policy, and support joins. 0Pools centralizes those primitives so product surfaces can differ without fragmenting the money infrastructure underneath.
What not to copy into partner UX
Do not expose private route names, venue names, exchange balances, treasury wallets, market maker terms, rebalancing levels, or worker names. The partner product should talk in terms of quote, expiry, amount, network, pending, settled, failed, released, and returned.
Production architecture review
A production architecture review should prove that the partner product is not treating browser state, webhooks, or dashboards as the only source of truth.
| Boundary | Production rule | Evidence to keep |
|---|---|---|
| Client to partner server | Client requests quotes and displays status; it does not hold secret keys. | No sk_* key in browser bundles or mobile config. |
| Partner server to 0Pools | Server performs discovery, firm quote, transact, status reads. | API logs with request id and idempotency key. |
| Webhook to ledger | Webhooks are verified, stored, deduplicated, then processed. | Event table with signature result and processing attempt. |
| Ledger to finance | Ledger writes are append-only and joinable by trade id. | Daily close report with unmatched exceptions. |
Recommended service split
Architecture acceptance checks
- Secret keys never leave server-controlled infrastructure.
- Quote creation and transact execution are logged with request ids.
- Webhook processing is idempotent and replay-safe.
- Ledger mutation is driven by terminal status, not a frontend callback.
- Support can search by partner order id, quote id, transact id, event id, and ledger id.
Implementation depth
This page is about mapping the 0Pools architecture into product, control, money, and data layers. For developers, the durable boundary is simple: your product should depend on partner API boundaries, state transitions, and records; it should not depend on execution implementation details, connector choices, worker topology, or treasury operations. That boundary is what lets 0Pools improve liquidity operations without forcing every partner to rebuild product code.
Product scenario
An engineering team decides what belongs in its app, what belongs in its backend, and what should be left to 0Pools. The architecture prevents browsers and mobile clients from executing money movement directly.
Before and after in practice
| Before 0Pools | With 0Pools |
|---|---|
| Product code, venue logic, and ledger updates are coupled, so a UI change can accidentally affect money movement. | The browser is display-only, the partner server calls 0Pools, and terminal events drive ledger mutation. |
| Product teams infer liquidity behavior from provider-specific screens or manual notes. | Product teams branch on 0Pools objects: pool, quote, trade, balance, webhook, and ledger. |
| Support asks engineering to reconstruct state from logs. | Support starts from request id, quote id, trade id, event id, and ledger id. |
System flow
Records to keep
| Record | Why it matters | Example |
|---|---|---|
client_reference | Links the user journey to backend state. | mobile_checkout_123 |
server_request_id | Traces API calls. | req_... |
trade_view | The partner-facing execution record. | pt_test_456 |
ledger_posting | The finance mutation triggered by terminal status. | ledger_789 |
A useful implementation stores these records before adding optional analytics. Analytics can be rebuilt from durable state; missing ids usually cannot be reconstructed after a customer-impacting failure.
Example product record
{
"product_area": "architecture",
"partner_reference": "partner_order_123",
"pool_id": "EUR-USDT",
"quote_id": "pq_test_123",
"transact_id": "pt_test_456",
"status": "reserved",
"request_id": "req_01HZY0POOLS",
"reconciliation_state": "open"
}This record is intentionally partner-facing. It references 0Pools objects and your own product ids, but it does not include provider routes, treasury balances, raw provider payloads, or customer secrets.
Failure modes and recovery
| Failure mode | Product response |
|---|---|
| Secret key in browser | Move all quote/transact calls to the server. |
| UI owns settlement | Use webhook/polling state as source of truth. |
| Route or provider detail exposed | Render pool and status, not route or provider names. |
| No data boundary | Separate user, order, quote, trade, and ledger tables. |
Use-case patterns
| Pattern | How 0Pools helps |
|---|---|
| System design review | Confirm which service owns each action. |
| Security review | Keep secret keys and execution server-side. |
| Scale planning | Add workers around durable state, not UI callbacks. |
Developer checklist
- Read runtime discovery and capabilities before rendering enabled actions.
- Create firm quotes only when the user is ready to accept the terms.
- Execute from your server with an idempotency key.
- Treat webhooks and status reads as the source of truth for settlement state.
- Reconcile by durable ids first, then by amount and timestamp.
- Do not branch product behavior on provider names, route names, reserve balances, or treasury assumptions.