Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 129 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,148 @@
The frontend interface for the TradeFlow protocol, enabling decentralized invoice factoring and RWA lending on Stellar.

## 🚀 Features

- **Freighter Wallet Integration**: Secure on-chain identity and signing.
- **Real-time Risk Analytics**: Fetched from the TradeFlow-API risk engine.
- **Smart Contract Interaction**: Direct minting of Invoice NFTs via Soroban.

## 🛠 Tech Stack
- **Framework**: Next.js 14

- **Framework**: Next.js 16
- **Blockchain**: Stellar SDK & Freighter API
- **Styling**: Tailwind CSS & Lucide Icons
- **State Management**: React Query & Zustand

## 🚦 Status

- **Development**: Active
- **CI/CD**: Passing

---

## ⚡ Quick Start (Under 5 Minutes)

### Prerequisites

Make sure you have these installed:

| Software | Version | Notes |
|------------------------|------------------|--------------------------------------------|
| Node.js | 20.x or later | Use nvm if needed (recommended) |
| npm | 10.x or later | Included with Node.js |

Optional (for full Soroban smart contract development):
- Rust + Soroban CLI
- Docker (for local Stellar network)

### 1. Clone the Repository

```bash
git clone https://github.com/[your-org]/TradeFlow-Web.git
cd TradeFlow-Web
```

### 2. Install Dependencies

```bash
npm install
```

### 3. Set Up Environment Variables

Copy the example env file and configure:

```bash
cp .env.example .env.local
```

Edit `.env.local` with your values:

| Variable | Required | Description |
|-----------------------------------|----------|-----------------------------------------------------------------------------|
| `NEXT_PUBLIC_SOROBAN_RPC_URL` | Yes | Stellar Soroban RPC URL (defaults to Testnet) |
| `NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE` | Yes | Stellar network passphrase (defaults to Testnet) |
| `NEXT_PUBLIC_INVOICE_CONTRACT_ID` | No | Deployed invoice smart contract ID (for minting) |
| `NEXT_PUBLIC_API_URL` | No | Backend API URL (uses mock data if unset) |
| `PINATA_API_KEY` | No | Pinata API key (for IPFS uploads) |
| `PINATA_SECRET_API_KEY` | No | Pinata secret key (for IPFS uploads) |
| `NEXT_PUBLIC_SENTRY_DSN` | No | Sentry DSN for error tracking |

### 4. Start Development Server

```bash
npm run dev
```

The app will be available at `http://localhost:3000`

### 5. Install Freighter Wallet (Optional but Recommended)

To interact with Stellar features, install the Freighter browser extension:
- [Chrome](https://chrome.google.com/webstore/detail/freighter/bcacfldlkkdbjoeigpddcpfmlplgoago)
- [Firefox](https://addons.mozilla.org/en-US/firefox/addon/freighter-wallet/)

---

## 🧪 Available Scripts

| Script | Description |
|--------------------|----------------------------------------------------------|
| `npm run dev` | Start development server at localhost:3000 |
| `npm run build` | Build for production |
| `npm start` | Start production server |
| `npm run lint` | Run ESLint |
| `npm run typecheck`| Run TypeScript type checking |
| `npm run test` | Run Jest tests |
| `npm run test:watch` | Run tests in watch mode |

---

## 🔧 Troubleshooting

### Common Issues

#### 1. Node.js Version Mismatch
```
Error: Unsupported Node.js version
```
**Solution**: Install Node.js 20.x or later. Use `nvm` to manage versions:
```bash
nvm install 20
nvm use 20
```

#### 2. npm Install Fails
```
npm ERR! code ERESOLVE
```
**Solution**: Clear npm cache and retry:
```bash
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
```

#### 3. Freighter Wallet Not Connecting
- Ensure Freighter is installed and unlocked
- Check that you're on the correct network (Testnet/Public) in Freighter settings
- Try refreshing the page

#### 4. Stellar Network Errors
- Verify `NEXT_PUBLIC_STELLAR_NETWORK` and RPC URL are correct in `.env.local`
- Check network status: https://status.stellar.org/

#### 5. Missing Contract ID
If you don't have a deployed contract, the minting feature won't work, but the rest of the app will still function.

### Need Help?
If you're still having issues, check the [ARCHITECTURE.md](ARCHITECTURE.md) file for deeper technical details.

<!-- git add .
git commit -m "feat: connect Soroban contract bindings to Next.js frontend (#187)
---

- Add lib/soroban with config, client, and invoice contract wrappers
- Add useInvoice and useMintInvoice hooks
- Wire hooks into InvoiceMintForm and marketplace/inv-123 page
- Pull contract ID and network passphrase from env vars"
## 📚 Documentation

git push origin Soroban -->
- [API Contract](docs/API_CONTRACT.md) - Frontend/backend API contract
- [Architecture](ARCHITECTURE.md) - System architecture overview
- [State Management with Zustand](docs/ZUSTAND_WEB3_IMPLEMENTATION.md)
- [Sentry Integration](docs/SENTRY_INTEGRATION.md)
107 changes: 107 additions & 0 deletions docs/API_CONTRACT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# API Contract

This document defines the exact JSON contract between frontend and backend APIs. **NO KEY NAMES SHOULD BE CHANGED WITHOUT PRIOR NOTIFICATION TO FRONTEND TEAM**.

## Version
v1.0.0

---

## Endpoints

### 1. GET /invoices

Returns paginated list of invoice summaries.

#### Query Parameters
| Name | Type | Required | Default | Description |
|-----------|--------|----------|---------|------------------------------------------|
| page | number | No | 1 | Current page number (1-based) |
| limit | number | No | 20 | Items per page (max 100) |
| minApy | number | No | 0 | Minimum APY filter |
| maxApy | number | No | 100 | Maximum APY filter |
| tiers | string | No | - | Comma-separated risk tiers (A,B,C,D) |

#### Response Shape
```json
{
"data": [
{
"id": "string",
"riskScore": "number",
"status": "string",
"amount": "number | string",
"apy": "number (optional)",
"riskTier": "string (optional: 'A'|'B'|'C'|'D')"
}
],
"pagination": {
"currentPage": "number",
"totalPages": "number",
"totalItems": "number",
"itemsPerPage": "number",
"hasNextPage": "boolean",
"hasPreviousPage": "boolean"
}
}
```

#### TypeScript Interface (frontend)
`InvoicesResponse` in `types/api.ts`

---

### 2. GET /v1/risk

Returns risk assessment for a specific invoice.

#### Query Parameters
| Name | Type | Required | Description |
|-----------|--------|----------|------------------------------------------|
| invoiceId | string | Yes | Invoice identifier |

#### Response Shape (200 OK)
```json
{
"invoiceId": "string",
"riskScore": "number",
"scoreRange": {
"min": "number (optional)",
"max": "number (optional)"
},
"grade": "string (optional)",
"factors": {
"string": "number"
} (optional),
"updatedAt": "string (ISO 8601, optional)"
}
```

#### TypeScript Interface (frontend)
`RiskScoreResponse` in `types/api.ts`

---

## Error Response Standard

All error responses follow this shape:

```json
{
"error": {
"message": "string (human-readable UI-safe message)",
"code": "string (machine-readable, optional)",
"details": "unknown (optional, for debugging only)"
}
}
```

#### TypeScript Interface (frontend)
`ApiErrorResponse` in `types/api.ts`

---

## Future Enhancements

- Integrate Orval or RTK Query code-gen to auto-generate TypeScript types from OpenAPI spec
- Add Swagger/OpenAPI UI for interactive documentation
11 changes: 11 additions & 0 deletions types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ export interface HealthResponse {

/**
* Parameters for GET /v1/risk.
*
* @see {@link docs/API_CONTRACT.md}
*/
export interface GetRiskScoreParams {
invoiceId: string;
Expand All @@ -88,6 +90,8 @@ export interface GetRiskScoreParams {
*
* - riskScore is expected to be a numeric score (typically 0-100).
* - factors is an optional map of contributing factor names to weights/scores.
*
* @see {@link docs/API_CONTRACT.md#2-get-v1risk}
*/
export interface RiskScoreResponse {
invoiceId: string;
Expand All @@ -104,6 +108,8 @@ export interface RiskScoreResponse {

/**
* Minimal invoice summary used by the dashboard table.
*
* @see {@link docs/API_CONTRACT.md#1-get-invoices}
*/
export interface InvoiceSummary {
id: string;
Expand All @@ -115,6 +121,11 @@ export interface InvoiceSummary {
[key: string]: unknown;
}

/**
* GET /invoices response.
*
* @see {@link docs/API_CONTRACT.md#1-get-invoices}
*/
export interface InvoicesResponse {
data: InvoiceSummary[];
pagination: {
Expand Down
Loading