From 01b596ff620f99600b0056ff27b679e2ede64995 Mon Sep 17 00:00:00 2001 From: rupesh-kumar-sah Date: Wed, 7 Oct 2026 19:50:59 +0545 Subject: [PATCH] docs: add top-level architecture doc tying contracts, backend, and frontend together Closes #20 --- docs/ARCHITECTURE.md | 132 +++++++++++++++++++++++++++++++++++++++++++ docs/architecture.md | 78 ------------------------- 2 files changed, 132 insertions(+), 78 deletions(-) create mode 100644 docs/ARCHITECTURE.md delete mode 100644 docs/architecture.md diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..4e2b628 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,132 @@ +# System Architecture: End-to-End Data Flow & Protocols + +This document provides the canonical architectural specification for the Azable protocol, establishing how the **Soroban Smart Contracts**, **Backend Indexer & Services**, and **Next.js Web Frontend** coordinate to power decentralized, streaming payroll and token distributions on Stellar. + +--- + +## 1. High-Level System Topology + +Azable connects on-chain streaming logic with responsive, real-time analytics dashboards through a loosely-coupled, event-driven pipeline: + +```mermaid +flowchart TD + subgraph "On-Chain Layer (Stellar / Soroban)" + SC["Payment Stream & Distributor Contracts"] + SL["Stellar Ledger & Event Log"] + SC -->|"Emits Events"| SL + end + + subgraph "Backend Services Layer (Node.js / NestJS)" + IX["Event Indexer Engine"] + DB[("PostgreSQL Database")] + AN["Analytics Service (analytics.service.ts)"] + GQL["GraphQL / REST API Gateway (/streams)"] + AUTH["SEP-10 Auth Controller"] + + SL -->|"RPC Ingestion"| IX + IX -->|"Normalized Records"| DB + DB --> AN + AN --> GQL + end + + subgraph "Frontend Client Layer (Next.js)" + UI["Web Dashboard UI"] + FW["Freighter Wallet"] + + UI <-->|"SEP-10 Challenge / Verify"| AUTH + UI <-->|"Queries / Subscriptions"| GQL + FW -->|"Signs Invocations"| SC + end +``` + +--- + +## 2. Payment-Stream Event Ingestion & Dashboard Data Flow + +When a user initiates or claims a payment stream on-chain, the transaction flows through the ingestion pipeline before appearing in real-time on the analytics dashboard: + +``` +[User / Freighter] + │ + ▼ (1) create_stream() / withdraw() +[Soroban Smart Contract] + │ + ▼ (2) Contract Event Emitted (topic: 'stream_created' / 'stream_withdraw') +[Stellar Core / Soroban RPC] + │ + ▼ (3) Polled / Streamed via Indexer Engine +[Backend Indexer Service] + │ + ▼ (4) Idempotent UPSERT into relational tables +[PostgreSQL Database (Prisma ORM)] + │ + ▼ (5) Aggregated / Cached by `/streams` routes +[Analytics Service (analytics.service.ts)] + │ + ▼ (6) Resolvers serve cached / structured payload +[GraphQL / REST Gateway] + │ + ▼ (7) TanStack Query cache invalidation +[Next.js Dashboard UI] +``` + +### Flow Breakdown: +1. **Contract Execution**: The client triggers `create_stream()` on the Soroban payment contract, setting sender, recipient, token, start time, end time, and deposit amount. +2. **Event Emission**: The contract emits an immutable Soroban event containing the `stream_id`, timestamps, rates, and addresses. +3. **Ingestion & Indexing**: The backend indexer process polls the Soroban RPC `getEvents` endpoint, validates sequence order, and parses the XDR topics and values. +4. **Relational Persistence**: Events are normalized and written to PostgreSQL with strict idempotency (keyed on transaction hash + event index). +5. **Analytics & Aggregation**: `analytics.service.ts` updates computed metrics (total value locked, real-time streamed volume, claimed ratios). +6. **Delivery**: The Next.js frontend queries the GraphQL/REST API, rendering dynamic progress bars and streaming tickers in the UI. + +--- + +## 3. SEP-10 Inspired Authentication Protocol + +To protect private endpoints and multi-tenant stream metadata without centralized credentials, Azable implements a non-custodial cryptographic authentication flow inspired by SEP-10: + +```mermaid +sequenceDiagram + autonumber + actor User as User / Freighter + participant UI as Next.js Frontend + participant Auth as Backend Auth Service + participant SDK as Stellar SDK / Horizon + + User->>UI: Connect Wallet (G-Address) + UI->>Auth: GET /auth/challenge?account=G... + Auth->>Auth: Generate challenge transaction with server key & random nonce + Auth-->>UI: Return Challenge XDR (time-bounded) + UI->>User: Request Signature via Freighter + User-->>UI: Signed Challenge XDR + UI->>Auth: POST /auth/verify { signedXdr } + Auth->>SDK: Verify server & client Ed25519 signatures + Auth->>Auth: Check network passphrase & time bounds + Auth-->>UI: Return JWT Access Token + UI->>UI: Store Session in Memory / LocalStorage + UI->>Auth: Authenticated API / GraphQL Request (Bearer Token) + Auth-->>UI: Authorized Stream Operations +``` + +### Security Guarantees: +- **Replay Protection**: Every challenge transaction contains an ephemeral sequence number and narrow time boundary (valid for 5 minutes). +- **Network Isolation**: Signed transactions specify the target network passphrase (`Test SDF Future Network ; October 2022` or `Public Global Stellar Network ; September 2015`), preventing cross-network replay attacks. +- **Stateless Verification**: The backend issues a cryptographically signed JWT containing the verified Stellar public key and role permissions. + +--- + +## 4. Subsystem Components & Responsibilities + +| Subsystem | Directory | Primary Technology | Core Responsibility | +| :--- | :--- | :--- | :--- | +| **Smart Contracts** | `contracts/` | Soroban Rust SDK | Enforces streaming math, escrow balances, pause/cancel state, and token transfers. | +| **Backend Indexer** | `services/backend/` | NestJS, Prisma, PostgreSQL | Ingests ledger events, guarantees monotonic state persistence, and provides SEP-10 authentication. | +| **Web Frontend** | `apps/web/` | Next.js 14, Tailwind, Freighter | User interface for stream creation, real-time payment withdrawal, and organization analytics. | +| **Shared SDK** | `packages/sdk/` | TypeScript, `@stellar/stellar-sdk` | Contract bindings, XDR parsers, and reusable client helpers. | + +--- + +## 5. Failure Modes & Resilience Patterns + +- **Indexer Divergence**: If the backend indexer experiences RPC downtime, it resumes from the last indexed ledger sequence stored in the `IndexerSyncState` table. +- **Client Fallback**: If backend APIs are unreachable, the frontend SDK supports direct read-only RPC simulation to query contract stream states directly from Soroban persistent storage. +- **Transaction Rollback**: Soroban contract operations are fully atomic; failed token transfers or precondition violations abort the transaction and prevent partial storage commits. diff --git a/docs/architecture.md b/docs/architecture.md deleted file mode 100644 index be47696..0000000 --- a/docs/architecture.md +++ /dev/null @@ -1,78 +0,0 @@ -# Architecture - -This document provides a high-level overview of the Azable Stellar project's architecture, which is composed of three main parts: a web frontend, a TypeScript SDK, and Soroban smart contracts. - -## High-Level Architecture - -The following diagram illustrates the interaction between the main components of the system: - -```mermaid -graph TD - A[User] --> B{Frontend (Next.js)} - B <--> C{Backend (Node.js API)} - B --> SDK{SDK (@azable/sdk)} - C --> SDK - SDK --> D{Soroban Smart Contracts} - D --> E((Stellar Blockchain)) - B --> F[(IPFS - Decentralized Storage)] - C --> F - - subgraph "Client-Side" - A - B - end - - subgraph "Off-Chain / API" - C - SDK - end - - subgraph "Decentralized Network" - D - E - F - end -``` - -### Components - -- **Frontend (Next.js):** The user-facing web application that allows users to interact with the Azable. -- **SDK (@azable/sdk):** A TypeScript library that abstracts the communication with the Soroban smart contracts, providing a simple API for the frontend. -- **Soroban Smart Contracts:** The on-chain logic that governs payment streams and token distribution. -- **Stellar Blockchain:** The underlying blockchain where the smart contracts are deployed and transactions are recorded. - -## Contract Architecture - -The smart contract layer is composed of two main contracts, organized as a Cargo workspace. - -```mermaid -graph TD - subgraph "Soroban Smart Contracts" - P[Payment Stream Contract] - D[Distributor Contract] - end - - P -->|Manages| S[Streams]; - D -->|Performs| T[Token Distributions]; - - subgraph "Payment Stream Functions" - P_Create["create_stream()"] - P_Withdraw["withdraw()"] - P_Pause["pause_stream()"] - P_Cancel["cancel_stream()"] - end - - subgraph "Distributor Functions" - D_Equal["distribute_equal()"] - D_Weighted["distribute_weighted()"] - end - - P_Create & P_Withdraw & P_Pause & P_Cancel --> P - D_Equal & D_Weighted --> D - -``` - -### Contracts - -- **Payment Stream Contract:** Manages the lifecycle of payment streams, including creation, withdrawal, pausing, and cancellation. -- **Distributor Contract:** Handles the distribution of tokens to multiple recipients, with support for both equal and weighted distributions.