|
| 1 | +# TradeFlow Architecture Reference |
| 2 | + |
| 3 | +Welcome to the TradeFlow Web codebase! This document serves as a guide for new contributors and maintainers. It outlines our directory structure, rendering paradigms, Web3 architecture, and guidelines for writing code in this repository. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Codebase Overview |
| 8 | + |
| 9 | +TradeFlow is built using **Next.js 14** (utilizing the App Router), **TypeScript**, **Tailwind CSS**, and integrates with the **Stellar/Soroban** smart contract ecosystem. |
| 10 | + |
| 11 | +Here is the bird's-eye view of the directory structure under `/src`: |
| 12 | + |
| 13 | +```text |
| 14 | +src/ |
| 15 | +├── app/ # Next.js App Router (Routing, layouts, and page definitions) |
| 16 | +│ ├── api/ # API Route Handlers (Server-side endpoints) |
| 17 | +│ ├── marketplace/ # Trade invoice marketplace pages |
| 18 | +│ ├── swap/ # Token swap interfaces |
| 19 | +│ │ └── page.tsx # Swap page entry point |
| 20 | +│ ├── globals.css # Global styles and Tailwind directives |
| 21 | +│ ├── layout.tsx # Root layout wrapper |
| 22 | +│ └── page.tsx # Homepage |
| 23 | +├── components/ # Modular, reusable UI components |
| 24 | +│ ├── ui/ # Low-level presentational primitives (Button, Tooltip, etc.) |
| 25 | +│ ├── layout/ # Shared layout components (Navbar, Sidebar) |
| 26 | +│ ├── ConnectWallet.tsx # Feature-specific modular components |
| 27 | +│ └── InvoiceMintForm.tsx |
| 28 | +├── contexts/ # Specialized React contexts (e.g., Slippage, NetworkCongestion) |
| 29 | +├── hooks/ # Custom hooks (e.g., wallet connection, Soroban events) |
| 30 | +├── lib/ # Shared utility functions and Stellar helper methods |
| 31 | +│ ├── stellar.ts # Lower-level Stellar SDK operations |
| 32 | +│ └── format.ts # Numeric and date formatting utils |
| 33 | +├── providers/ # Application-wide global providers (e.g., QueryClientProvider) |
| 34 | +├── soroban/ # Core Soroban integration layer |
| 35 | +│ ├── contracts/ # TypeScript bindings for Soroban smart contracts |
| 36 | +│ │ └── invoice.ts # Invoice contract bindings |
| 37 | +│ ├── client.ts # Soroban RPC Server client instance manager |
| 38 | +│ └── config.ts # Network details (RPC URL, Passphrase, Contract IDs) |
| 39 | +├── stores/ # Client-side state stores (Zustand state managers) |
| 40 | +│ └── useWeb3Store.ts # Global Web3 wallet and network state store |
| 41 | +└── types/ # Project-wide TypeScript type definitions |
| 42 | +``` |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +## 1. Separation of Concerns: `app/` vs `components/` |
| 47 | + |
| 48 | +To keep the codebase maintainable and scalable, we enforce a strict separation between routing/layouts and modular UI components. |
| 49 | + |
| 50 | +### The `src/app/` Directory (Routing & Layouts) |
| 51 | +* **Purpose**: Defines routes, page templates, layouts, and error boundaries. |
| 52 | +* **Rule**: Files inside `src/app` should act primarily as **compositions** of UI components. Avoid writing complex form validation, raw layout styles, or massive component structures directly inside `page.tsx` or `layout.tsx`. |
| 53 | +* **Conventions**: |
| 54 | + * `page.tsx`: Defines the unique UI for a route. |
| 55 | + * `layout.tsx`: Defines shared UI across multiple pages (e.g., sidebar and header). |
| 56 | + * `error.tsx` / `not-found.tsx`: Error boundaries and fallback pages. |
| 57 | + * `api/` / `route.ts`: Server-side API endpoints (Route Handlers). |
| 58 | + |
| 59 | +### The `src/components/` Directory (Modular UI) |
| 60 | +* **Purpose**: Holds all modular, reusable components. |
| 61 | +* **Organization**: |
| 62 | + 1. **`src/components/ui/`**: Low-level, stateless, presentational primitives. These are the bricks of our application (e.g., `Button.tsx`, `Slider.tsx`, `Tooltip.tsx`). They should not depend on global Web3 state or business logic. |
| 63 | + 2. **`src/components/layout/`**: Components responsible for structural placement (e.g., `Navbar.tsx`, `Sidebar.tsx`). |
| 64 | + 3. **`src/components/` (Root)**: Domain-specific or stateful UI blocks. These components combine UI primitives with state and business logic (e.g., `InvoiceMintForm.tsx`, `ConnectWallet.tsx`, `SwapInterface.tsx`). |
| 65 | + |
| 66 | +--- |
| 67 | + |
| 68 | +## 2. Rendering Paradigms: Server vs. Client Components |
| 69 | + |
| 70 | +Next.js 14 uses **React Server Components (RSC)** by default. Understanding when to use the `'use client'` directive is crucial for application performance, bundle size optimization, and SEO. |
| 71 | + |
| 72 | +### When to Keep it as a Server Component (Default) |
| 73 | +By default, keep components as Server Components. This keeps JS bundle sizes small and allows direct, secure server-side operations. |
| 74 | +* **Use Case**: Static layouts, fetching initial metadata, pure presentation content, and structural wrappers. |
| 75 | + |
| 76 | +### When to Add `'use client'` |
| 77 | +Add the `'use client'` directive at the very top of your file when the component requires client-side interactivity or browser-specific APIs. |
| 78 | +* **Use Case**: |
| 79 | + * Using React state or lifecycle hooks (`useState`, `useReducer`, `useEffect`, `useLayoutEffect`). |
| 80 | + * Using browser APIs (e.g., `window`, `localStorage`, Web3 extension wallets like Freighter). |
| 81 | + * Attaching event listeners (`onClick`, `onChange`, `onSubmit`). |
| 82 | + * Interacting with client-side contexts or hooks (e.g., wallet state, slippage settings). |
| 83 | + |
| 84 | +### Code Comparison |
| 85 | + |
| 86 | +#### 📝 Server Component Example (Default) |
| 87 | +```tsx |
| 88 | +// src/components/ui/Card.tsx |
| 89 | +// No 'use client' is needed here. This runs entirely on the server. |
| 90 | +import React from 'react'; |
| 91 | + |
| 92 | +interface CardProps { |
| 93 | + title: string; |
| 94 | + children: React.ReactNode; |
| 95 | +} |
| 96 | + |
| 97 | +export function Card({ title, children }: CardProps) { |
| 98 | + return ( |
| 99 | + <div className="rounded-xl border border-gray-800 bg-gray-900/50 p-6 backdrop-blur-md"> |
| 100 | + <h3 className="text-lg font-semibold text-white mb-2">{title}</h3> |
| 101 | + <div>{children}</div> |
| 102 | + </div> |
| 103 | + ); |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +#### 📝 Client Component Example (`'use client'`) |
| 108 | +```tsx |
| 109 | +// src/components/AddTrustlineButton.tsx |
| 110 | +'use client'; // Required for click handlers, state, and browser wallets |
| 111 | + |
| 112 | +import { useState } from 'react'; |
| 113 | +import { Button } from './ui/Button'; |
| 114 | + |
| 115 | +export function AddTrustlineButton({ assetCode }: { assetCode: string }) { |
| 116 | + const [isPending, setIsPending] = useState(false); |
| 117 | + |
| 118 | + const handleAddTrustline = async () => { |
| 119 | + setIsPending(true); |
| 120 | + try { |
| 121 | + // Browser wallet/Freighter interaction here... |
| 122 | + console.log(`Adding trustline for ${assetCode}...`); |
| 123 | + } catch (error) { |
| 124 | + console.error(error); |
| 125 | + } finally { |
| 126 | + setIsPending(false); |
| 127 | + } |
| 128 | + }; |
| 129 | + |
| 130 | + return ( |
| 131 | + <Button onClick={handleAddTrustline} disabled={isPending}> |
| 132 | + {isPending ? 'Adding...' : `Add ${assetCode} Trustline`} |
| 133 | + </Button> |
| 134 | + ); |
| 135 | +} |
| 136 | +``` |
| 137 | + |
| 138 | +--- |
| 139 | + |
| 140 | +## 3. Web3 & Soroban Integration Architecture |
| 141 | + |
| 142 | +TradeFlow integrates with the Stellar network and Soroban smart contracts. The interaction layer is structured as follows: |
| 143 | + |
| 144 | +```mermaid |
| 145 | +graph TD |
| 146 | + UI[Client Components / UI] --> Hooks[Custom Hooks: src/hooks] |
| 147 | + Hooks --> Stores[Zustand Stores: src/stores] |
| 148 | + Hooks --> Bindings[Contract Bindings: src/soroban/contracts] |
| 149 | + Bindings --> Client[Soroban Client: src/soroban/client.ts] |
| 150 | + Client --> RPC[Stellar/Soroban RPC] |
| 151 | +``` |
| 152 | + |
| 153 | +### 1. Smart Contract Bindings (`src/soroban/contracts/`) |
| 154 | +TypeScript wrappers representing Soroban smart contracts (e.g., `invoice.ts`). These bindings: |
| 155 | +* Map contract methods to strongly typed TypeScript functions. |
| 156 | +* Serialize JavaScript arguments into XDR format. |
| 157 | +* Deserialize contract return values back into typed JavaScript structures. |
| 158 | + |
| 159 | +### 2. Client & Config (`src/soroban/`) |
| 160 | +* **`config.ts`**: Resolves network-specific configurations (like Testnet or Mainnet RPC endpoints, passphrases, and contract IDs) by reading active network contexts and environment variables. |
| 161 | +* **`client.ts`**: Manages a cached, single instance of the Soroban `Server` client (`getSorobanClient()`). It handles cache clearing automatically when switching networks (e.g., Testnet to Futurenet). |
| 162 | + |
| 163 | +### 3. Global State Providers & Stores |
| 164 | +We manage decentralized application state through a mix of React Contexts and global Zustand stores: |
| 165 | +* **`src/providers/`**: Holds high-level providers that wrap the app layout tree, such as `QueryClientProvider` (for React Query caching). |
| 166 | +* **`src/contexts/`**: Contains specialized providers for targeted slices of configuration/state (e.g., `SlippageContext`, `ExpertModeContext`, `NetworkCongestionContext`). |
| 167 | +* **`src/stores/`**: Holds Zustand state managers for high-performance reactive state. For example: |
| 168 | + * `useWeb3Store.ts` stores user wallet connection state, selected Stellar network details, and active account public keys. |
| 169 | + |
| 170 | +### 4. Custom Hooks (`src/hooks/`) |
| 171 | +Hooks bridge UI components with contract actions. They abstract asynchronous states, event handlers, and feedback mechanisms. |
| 172 | +* `useWalletConnection.ts`: Manages connecting/disconnecting via Freighter, loading balances, and handling browser extension events. |
| 173 | +* `useSorobanEvents.ts`: Listens to RPC event streams for contract emission events. |
| 174 | +* `useTxWithToast.ts`: Executes a transaction and automatically triggers success/error notifications (toasts). |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## Guidelines for Contributors |
| 179 | + |
| 180 | +1. **Keep Presentational Components Clean**: Do not import `useWeb3Store` or `getSorobanClient` into `/components/ui/` elements. Keep them strictly layout and style-oriented. |
| 181 | +2. **Handle Loading and Error States**: Always provide skeleton loader fallbacks (`SkeletonRow`, `TableSkeleton`) and leverage custom error boundaries. |
| 182 | +3. **Verify Network Compatibility**: Before executing a transaction, use the `TransactionGuard` component or `useNetworkDetection` hook to check if the user is connected to the matching Stellar network. |
| 183 | +4. **Follow Linting Rules**: Run `npm run lint` and verify tests pass with `npm run test` before submitting your Pull Request. |
0 commit comments