Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
35 changes: 35 additions & 0 deletions wata-board-frontend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Environment Variables for Wata Board Frontend
# Copy this file to .env and fill in your actual values

# Network Configuration
# Options: testnet, mainnet
VITE_NETWORK=testnet

# API Configuration
# Backend API URL for production (in development, uses proxy)
VITE_API_URL=https://your-api-domain.com

# CORS Configuration
# Frontend URL for CORS (matches your deployment domain)
VITE_FRONTEND_URL=https://your-frontend-domain.com

# Stellar Contract Configuration
# The contract ID for the Wata Board smart contract on Stellar network
# These will be automatically selected based on VITE_NETWORK, but you can override them
VITE_CONTRACT_ID_TESTNET=CDRRJ7IPYDL36YSK5ZQLBG3LICULETIBXX327AGJQNTWXNKY2UMDO4DA
VITE_CONTRACT_ID_MAINNET=MAINNET_CONTRACT_ID_HERE

# Stellar RPC URL
# The RPC endpoint for connecting to the Stellar Soroban network
# These will be automatically selected based on VITE_NETWORK, but you can override them
VITE_RPC_URL_TESTNET=https://soroban-testnet.stellar.org
VITE_RPC_URL_MAINNET=https://soroban.stellar.org

# Network Passphrase
# These will be automatically selected based on VITE_NETWORK, but you can override them
VITE_NETWORK_PASSPHRASE_TESTNET=Test SDF Network ; September 2015
VITE_NETWORK_PASSPHRASE_MAINNET=Public Global Stellar Network ; September 2015

# Application Settings (Optional)
# VITE_APP_NAME=Wata-Board
# VITE_APP_VERSION=1.0.0
24 changes: 24 additions & 0 deletions wata-board-frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
55 changes: 55 additions & 0 deletions wata-board-frontend/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Production Dockerfile for Wata-Board Frontend
# Multi-stage build for optimized production image

# Build stage
FROM node:18-alpine AS builder

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production && npm cache clean --force

# Copy the rest of the application
COPY . .

# Build the application
RUN npm run build

# Production stage
FROM nginx:alpine AS production

# Install security updates
RUN apk update && apk upgrade && \
apk add --no-cache curl && \
rm -rf /var/cache/apk/*

# Copy built application from builder stage
COPY --from=builder /app/dist /var/www/wata-board-frontend/dist

# Copy Nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Create non-root user for security
RUN addgroup -g 1001 -S nginx && \
adduser -S nginx -u 1001 -G nginx

# Create logs directory
RUN mkdir -p /var/log/nginx && \
chown -R nginx:nginx /var/log/nginx && \
chown -R nginx:nginx /var/www/wata-board-frontend

# Switch to non-root user
USER nginx

# Expose ports
EXPOSE 80 443

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/health || exit 1

# Start Nginx
CMD ["nginx", "-g", "daemon off;"]
101 changes: 101 additions & 0 deletions wata-board-frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Wata-Board Frontend

Frontend UI for **Wata-Board** — a decentralized utility payment platform on **Stellar / Soroban**.

This is a **React + TypeScript + Vite** app styled with **Tailwind** and wired to **Freighter Wallet** for signing transactions.

## Prerequisites

- **Node.js** (v18+ LTS recommended)
- **Freighter Wallet** browser extension
- Stellar testnet account with XLM

## Quick Start

```bash
# Install dependencies
npm install

# Run development server
npm run dev

# Open http://localhost:5173
```

## Available Scripts

| Script | Description |
|--------|-------------|
| `npm run dev` | Start Vite dev server with hot reload |
| `npm run build` | Create production build with type checking |
| `npm run lint` | Run ESLint on all files |
| `npm run preview` | Preview production build locally |

## Project Structure

```
src/
├── App.tsx # Main payment interface
├── contracts/ # Soroban contract bindings
│ ├── src/index.ts # Generated client code
│ ├── package.json
│ └── tsconfig.json
├── main.tsx # React entry point
├── index.css # Global styles
└── assets/ # Static assets
```

## Smart Contract Integration

- **Contract ID**: `CDRRJ7IPYDL36YSK5ZQLBG3LICULETIBXX327AGJQNTWXNKY2UMDO4DA`
- **Network**: Stellar Testnet
- **RPC**: `https://soroban-testnet.stellar.org`

## Features

- **Meter Payment**: Enter meter ID and amount to pay utility bills
- **Freighter Integration**: Sign transactions with browser wallet
- **Real-time Status**: Track transaction progress and results
- **Testnet Ready**: Pre-configured for Stellar testnet

## Environment Variables

Create `.env` in the project root:

```env
VITE_CONTRACT_ID=CDRRJ7IPYDL36YSK5ZQLBG3LICULETIBXX327AGJQNTWXNKY2UMDO4DA
VITE_RPC_URL=https://soroban-testnet.stellar.org
```

## Freighter Setup

1. Install [Freighter Wallet](https://www.freighter.app/) extension
2. Create or import an account
3. Switch to **Testnet** in settings
4. Fund account with testnet XLM from [Stellar Laboratory](https://laboratory.stellar.org/#account-creator?network=test)

## Troubleshooting

| Issue | Solution |
|-------|----------|
| "Freighter not found" | Install extension and refresh page |
| "Transaction failed" | Check testnet XLM balance |
| "Build errors" | Run `npm install` to update deps |

## Notes

- The app is currently configured for **Stellar Testnet** only
- Contract bindings in `src/contracts/` are auto-generated from Soroban CLI
- Amount must be a positive whole number

## Dependencies

- **React** 19.2.0
- **Stellar SDK** 14.5.0
- **Freighter API** 6.0.1
- **Tailwind CSS** 4.1.18
- **Vite** 8.0.0-beta.13

## License

ISC
46 changes: 46 additions & 0 deletions wata-board-frontend/README_TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
```bash
# Run all tests (all browsers)
npm run test

# Run tests in specific browser
npx playwright test --project=firefox
npx playwright test --project=webkit
npx playwright test --project="Mobile Safari"

# Run tests in UI mode
npx playwright test --ui

# Debug a specific test
npx playwright test tests/integration/payment.spec.ts --debug
```

## Cross-Browser Testing

Playwright is configured to run tests across:
- **Chromium** (Desktop Chrome, Google Chrome, Microsoft Edge)
- **Firefox** (Desktop Firefox)
- **Webkit** (Desktop Safari)
- **Mobile Viewports** (Pixel 5, iPhone 12)

If a browser is missing in your environment, install it with:
```bash
npx playwright install
```

## Test Suites

- `tests/integration/payment.spec.ts`: Tests the core payment flow, including Freighter wallet connection, fee estimation, and transaction submission. Uses extensive mocking to simulate the Stellar network and wallet-bridge.
- `tests/integration/scheduling.spec.ts`: Tests the recurring payment scheduling feature.
- `tests/crash.spec.ts`: Smoke test to ensure the app renders without crashing.

## Infrastructure

To handle environmental differences and lack of a real wallet in CI, we use several techniques:
1. **Wallet Injection**: Mock objects are injected into `window.freighter` and `window.freighterApi` via `page.addInitScript`.
2. **Network Interception**: Playwright's `page.route` intercepts calls to Stellar Horizon (**/horizon/**) to provide consistent account and ledger data.
3. **Transaction Mocking**: To bypass internal SDK validation issues in Playwright, the app supports `window.__MOCK_STELLAR_TRANSACTION__` which allows tests to provide a stubbed transaction object.

## Troubleshooting

- **"Cannot read properties of undefined (reading 'type')"**: This often occurs when the Stellar SDK `TransactionBuilder` or `Operation` receives malformed data. Check the mocks in use and ensure all required properties (id, sequenceNumber, etc.) are present.
- **Timeouts**: The app performs async operations like fee estimation. Tests are configured with 15s timeouts to accommodate these.
23 changes: 23 additions & 0 deletions wata-board-frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
42 changes: 42 additions & 0 deletions wata-board-frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Pay utility bills using cryptocurrency on the Stellar blockchain" />
<meta name="theme-color" content="#0ea5e9" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="Wata-Board" />
<meta name="application-name" content="Wata-Board" />
<meta name="msapplication-TileColor" content="#0f172a" />
<meta name="msapplication-config" content="/browserconfig.xml" />

<!-- PWA Manifest -->
<link rel="manifest" href="/manifest.json" />

<!-- Icons for different platforms -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#0ea5e9" />

<!-- Preload critical resources for offline -->
<link rel="preload" href="/sw.js" as="script" crossorigin="anonymous" />

<title>Wata-Board - Decentralized Utility Payments</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>

<!-- Fallback for offline mode -->
<noscript>
<div style="text-align: center; padding: 50px; font-family: system-ui, sans-serif;">
<h1>JavaScript Required</h1>
<p>Wata-Board requires JavaScript to function. Please enable JavaScript in your browser settings.</p>
</div>
</noscript>
</body>
</html>
Loading