Skip to content

Commit a0a1248

Browse files
authored
Merge pull request #324 from Alhaji-naira/docs/add-architecture-guide
docs: add ARCHITECTURE.md overview guide
2 parents 3bac99b + 3edfa3c commit a0a1248

1 file changed

Lines changed: 183 additions & 0 deletions

File tree

ARCHITECTURE.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
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

Comments
 (0)