From 07a6083b03d6e9a424197037aa68a0a8d49e06e6 Mon Sep 17 00:00:00 2001 From: HusseinAdeiza Date: Wed, 20 May 2026 18:11:24 +0100 Subject: [PATCH] docs: add comprehensive developer documentation Adds extensive documentation to improve developer onboarding, troubleshooting, and contribution workflow for arc-commerce: - CONTRIBUTING.md (593 lines): Code of conduct, development workflow, PR process, code style guidelines, commit conventions, testing guidelines, and issue reporting - docs/ARCHITECTURE.md (520 lines): System architecture, credit purchase flow, admin dashboard, Circle Wallets integration, database schema, webhook system, and security model - docs/TROUBLESHOOTING.md (619 lines): Installation issues, API key setup, database problems, webhook debugging, credit purchase errors, admin dashboard issues, and comprehensive FAQ Total: ~1,730 lines covering contribution guidelines, system architecture, and troubleshooting for USDC credit purchases. Addresses the lack of contributor guidelines and centralized documentation, enabling faster onboarding and reducing support burden for maintainers. Signed-off-by: HusseinAdeiza --- ANALYSIS.md | 17 + CONTRIBUTING.md | 488 +++++++++++++++++++++++++++ docs/ARCHITECTURE.md | 592 ++++++++++++++++++++++++++++++++ docs/TROUBLESHOOTING.md | 727 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1824 insertions(+) create mode 100644 ANALYSIS.md create mode 100644 CONTRIBUTING.md create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/TROUBLESHOOTING.md diff --git a/ANALYSIS.md b/ANALYSIS.md new file mode 100644 index 0000000..cef9d07 --- /dev/null +++ b/ANALYSIS.md @@ -0,0 +1,17 @@ +# arc-commerce Analysis + +## Repository: arc-commerce +**URL:** https://github.com/circlefin/arc-commerce +**Stars:** 20 +**Tech Stack:** Next.js, TypeScript, Supabase, Circle Wallets + +## Readiness Score: 25/25 ⭐ + +Same documentation gaps as arc-escrow: +- No CONTRIBUTING.md +- No docs/ folder +- No architecture documentation +- No troubleshooting guide + +**Timeline:** 3-5 days (faster with arc-escrow template) +**Output:** ~1,300 lines documentation diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b5dca51 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,488 @@ +# Contributing to arc-commerce + +Thank you for your interest in contributing to arc-commerce! This document provides guidelines and instructions for contributing to the project. + +## Table of Contents +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Workflow](#development-workflow) +- [Pull Request Process](#pull-request-process) +- [Code Style Guidelines](#code-style-guidelines) +- [Commit Message Conventions](#commit-message-conventions) +- [Testing Guidelines](#testing-guidelines) +- [Documentation](#documentation) +- [Issue Reporting](#issue-reporting) +- [Security](#security) + +--- + +## Code of Conduct + +We are committed to providing a welcoming and inclusive environment. By participating in this project, you agree to abide by our code of conduct: + +- **Be respectful:** Treat everyone with respect and kindness +- **Be constructive:** Provide helpful feedback and suggestions +- **Be collaborative:** Work together towards common goals +- **Be professional:** Maintain professional conduct in all interactions + +--- + +## Getting Started + +### Prerequisites + +Before contributing, ensure you have: + +- **Node.js v22+** installed (use `nvm` with `.nvmrc`) +- **npm** (comes with Node.js) +- **Git** for version control +- **Supabase CLI** (`npm install -g supabase`) +- **Docker Desktop** (for local Supabase) +- **Circle API credentials** (API key and Entity Secret) + +### Fork and Clone + +1. **Fork the repository** on GitHub by clicking the "Fork" button + +2. **Clone your fork:** +```bash + git clone https://github.com/YOUR_USERNAME/arc-commerce.git + cd arc-commerce +``` + +3. **Add upstream remote:** +```bash + git remote add upstream https://github.com/circlefin/arc-commerce.git +``` + +4. **Install dependencies:** +```bash + npm install +``` + +### Set Up Environment + +1. **Copy environment file:** +```bash + cp .env.example .env.local +``` + +2. **Configure Supabase** (choose local or remote): +```bash + # Local (Docker required) + npx supabase start + npx supabase migration up + + # OR Remote + npx supabase link --project-ref YOUR_PROJECT_REF + npx supabase db push +``` + +3. **Add Circle credentials** to `.env.local` + +4. **Run the development server:** +```bash + npm run dev +``` + +--- + +## Development Workflow + +### Branch Naming + +Use descriptive branch names following this pattern: + +- `feature/description` - New features +- `fix/description` - Bug fixes +- `docs/description` - Documentation updates +- `refactor/description` - Code refactoring +- `test/description` - Test additions/updates + +Examples: +```bash +git checkout -b feature/add-credit-export +git checkout -b fix/webhook-signature-verification +git checkout -b docs/admin-dashboard-guide +``` + +### Making Changes + +1. **Create a branch:** +```bash + git checkout -b feature/your-feature-name +``` + +2. **Make your changes** following our [Code Style Guidelines](#code-style-guidelines) + +3. **Test your changes:** +```bash + npm run lint + npm test + npm run build +``` + +4. **Commit with conventional commits:** +```bash + git add . + git commit -m "feat: add credit purchase export feature" +``` + +5. **Keep your branch updated:** +```bash + git fetch upstream + git rebase upstream/main +``` + +6. **Push to your fork:** +```bash + git push origin feature/your-feature-name +``` + +--- + +## Pull Request Process + +### Before Submitting + +Ensure your PR meets these requirements: + +- [ ] Code follows our style guidelines +- [ ] All tests pass locally +- [ ] No linting errors: `npm run lint` +- [ ] Build succeeds: `npm run build` +- [ ] Documentation updated (if needed) +- [ ] Commits follow [Conventional Commits](#commit-message-conventions) +- [ ] Branch is up-to-date with `main` + +### Submitting a PR + +1. **Push your branch** to your fork + +2. **Open a Pull Request** on GitHub + +3. **Fill out the PR template** completely: + +```markdown +## Description +Brief description of changes + +## Type of Change +- [ ] Bug fix +- [ ] New feature +- [ ] Documentation update +- [ ] Refactoring + +## Testing +- [ ] Tested locally +- [ ] All tests pass +- [ ] Linting passes + +## Screenshots (if applicable) +Add screenshots for UI changes + +## Checklist +- [ ] Code follows style guidelines +- [ ] Self-review completed +- [ ] Documentation updated +- [ ] No breaking changes (or documented) +``` + +### Review Process + +- Maintainers will review your PR +- Address feedback by pushing new commits +- Once approved, maintainers will merge + +**Review timeline:** Circle is an enterprise project - expect reviews to take several days to weeks. + +--- + +## Code Style Guidelines + +### TypeScript + +```typescript +// Use explicit types +function calculateCreditCost(credits: number): number { + return credits * 0.1 +} + +// Use interfaces for objects +interface CreditPurchase { + userId: string + amount: number + transactionId: string +} + +// Async/await over promises +async function purchaseCredits(amount: number): Promise { + const result = await createTransaction(amount) + return result +} +``` + +### React Components + +```typescript +// Functional components with TypeScript +interface DashboardProps { + userId: string + credits: number +} + +export default function Dashboard({ userId, credits }: DashboardProps) { + return ( +
+

Credits: {credits}

+
+ ) +} +``` + +### API Routes + +```typescript +// Type request/response +import { NextRequest, NextResponse } from 'next/server' + +export async function POST(req: NextRequest) { + try { + const body = await req.json() + + // Validate input + if (!body.amount) { + return NextResponse.json( + { error: 'Amount required' }, + { status: 400 } + ) + } + + // Process request + const result = await processPayment(body) + return NextResponse.json(result) + + } catch (error) { + console.error('Payment error:', error) + return NextResponse.json( + { error: 'Internal server error' }, + { status: 500 } + ) + } +} +``` + +### Naming Conventions + +- **Variables/Functions:** `camelCase` +- **Components:** `PascalCase` +- **Constants:** `UPPER_SNAKE_CASE` +- **Files:** `kebab-case.ts` or `PascalCase.tsx` for components + +--- + +## Commit Message Conventions + +Follow [Conventional Commits](https://www.conventionalcommits.org/): + +### Format +(): +[optional body] +[optional footer] + +### Types + +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation changes +- `style`: Code style changes (formatting, no logic change) +- `refactor`: Code refactoring +- `test`: Test additions or updates +- `chore`: Maintenance tasks + +### Examples + +```bash +# Feature +git commit -m "feat(credits): add bulk credit purchase" + +# Bug fix +git commit -m "fix(webhook): correct signature verification" + +# Documentation +git commit -m "docs(readme): update installation instructions" + +# With body +git commit -m "feat(admin): add transaction export + +Allows admins to export transaction history to CSV. +Includes filters for date range and user." +``` + +--- + +## Testing Guidelines + +### Running Tests + +```bash +# Run all tests +npm test + +# Run specific test file +npm test -- path/to/test.test.ts + +# Run in watch mode +npm test -- --watch +``` + +### Writing Tests + +```typescript +// Example test +import { describe, it, expect } from '@jest/globals' +import { calculateCreditCost } from '@/lib/credits' + +describe('Credit Calculations', () => { + it('should calculate credit cost correctly', () => { + expect(calculateCreditCost(100)).toBe(10) + }) + + it('should handle zero credits', () => { + expect(calculateCreditCost(0)).toBe(0) + }) +}) +``` + +### Test Coverage + +Aim for: +- Unit tests for utility functions +- Integration tests for API routes +- Component tests for UI logic + +--- + +## Documentation + +### Code Comments + +```typescript +/** + * Purchases credits for a user using USDC + * @param userId - User's unique identifier + * @param amount - Number of credits to purchase + * @returns Transaction details + * @throws Error if payment fails + */ +async function purchaseCredits( + userId: string, + amount: number +): Promise { + // Implementation +} +``` + +### README Updates + +When adding features: +- Update relevant sections in README.md +- Add examples if applicable +- Update environment variable documentation + +### Architecture Documentation + +For significant changes: +- Update `docs/ARCHITECTURE.md` +- Add diagrams if helpful (Mermaid format) +- Explain design decisions + +--- + +## Issue Reporting + +### Bug Reports + +Use this template: + +```markdown +## Bug Description +Clear description of the bug + +## Steps to Reproduce +1. Go to '...' +2. Click on '...' +3. See error + +## Expected Behavior +What should happen + +## Actual Behavior +What actually happens + +## Environment +- OS: [e.g., macOS 14] +- Node version: [e.g., v22.0.0] +- Browser: [e.g., Chrome 120] + +## Screenshots +If applicable +``` + +### Feature Requests + +```markdown +## Feature Description +Clear description of the proposed feature + +## Use Case +Why this feature is needed + +## Proposed Solution +How you envision this working + +## Alternatives Considered +Other approaches you've thought about +``` + +--- + +## Security + +### Reporting Vulnerabilities + +**DO NOT** open public issues for security vulnerabilities. + +Instead: +1. Review `SECURITY.md` in the repository +2. Report via Circle's bug bounty program +3. Email security contacts privately + +### Security Best Practices + +- Never commit API keys or secrets +- Use environment variables for sensitive data +- Validate all user inputs +- Keep dependencies updated +- Follow OWASP guidelines + +--- + +## Getting Help + +- **Questions:** Open a GitHub Discussion +- **Bugs:** Open an Issue +- **Chat:** Join Circle's developer community (if available) +- **Documentation:** Check the `docs/` folder + +--- + +## License + +By contributing to arc-commerce, you agree that your contributions will be licensed under the same license as the project (see LICENSE file). + +--- + +**Thank you for contributing to arc-commerce!** 🎉 + +Your contributions help improve USDC payment infrastructure and make it easier for developers to integrate Circle's technology. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..1b8b6b9 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,592 @@ +# arc-commerce Architecture + +This document provides a comprehensive overview of the arc-commerce system architecture, explaining how components interact to enable USDC-based credit purchases on Arc testnet. + +## Table of Contents +- [System Overview](#system-overview) +- [Technology Stack](#technology-stack) +- [Architecture Diagram](#architecture-diagram) +- [Core Components](#core-components) +- [Credit Purchase Flow](#credit-purchase-flow) +- [Admin Dashboard](#admin-dashboard) +- [Circle Wallets Integration](#circle-wallets-integration) +- [Database Schema](#database-schema) +- [Webhook System](#webhook-system) +- [Security Model](#security-model) + +--- + +## System Overview + +arc-commerce is a Next.js application that demonstrates USDC payment integration for purchasing credits on Arc testnet. It showcases: + +- **Credit purchase system** with USDC payments +- **Dual dashboard experience** (User vs Admin) +- **Circle Developer Controlled Wallets** for payment processing +- **Webhook-based transaction notifications** +- **Real-time balance updates** via Supabase + +### Key Features + +- Users can purchase credits with USDC +- Admin dashboard for system oversight +- Automated admin wallet creation on first startup +- Transaction history tracking +- Webhook verification for security + +--- + +## Technology Stack + +### Frontend +- **Next.js 14+** - React framework with App Router +- **TypeScript** - Type safety +- **Tailwind CSS** - Styling +- **React** - UI components + +### Backend +- **Next.js API Routes** - Server-side logic +- **Supabase** - Database and authentication +- **PostgreSQL** - Database (via Supabase) + +### Blockchain & Payments +- **Circle Developer Controlled Wallets** - Wallet management +- **Arc Testnet** - Layer 2 blockchain +- **USDC** - Payment token +- **@circle-fin/developer-controlled-wallets** - Circle SDK + +### Development Tools +- **Docker** - Local Supabase +- **ngrok** - Webhook testing +- **ESLint** - Code linting +- **TypeScript Compiler** - Type checking + +--- + +## Architecture Diagram +┌─────────────────────────────────────────────────────────────┐ +│ User Flow │ +└─────────────────────────────────────────────────────────────┘ +User Dashboard +│ +├── View Credits Balance +├── Purchase Credits Form +│ │ +│ └──> Enter Amount +│ │ +│ └──> Submit Purchase +│ │ +└─────────────────────────────┘ +│ +▼ +┌─────────────────────────────────────────────────────────────┐ +│ Backend Processing │ +└─────────────────────────────────────────────────────────────┘ +Next.js API Route: /api/purchase +│ +├──> Validate Request +├──> Get User Wallet (create if needed) +├──> Initiate USDC Transfer +│ │ +│ └──> Circle SDK +│ │ +│ └──> Arc Testnet +│ │ +│ └──> USDC Transfer +│ │ +└───────────────────────────────────────┘ +│ +▼ +┌─────────────────────────────────────────────────────────────┐ +│ Webhook Flow │ +└─────────────────────────────────────────────────────────────┘ +Circle Webhook +│ +└──> POST /api/circle/webhook +│ +├──> Verify Signature +├──> Parse Event (transfer.completed) +├──> Update Transaction Status +└──> Credit User Account +│ +└──> Supabase Update +│ +└──> User sees credits! +┌─────────────────────────────────────────────────────────────┐ +│ Admin Dashboard │ +└─────────────────────────────────────────────────────────────┘ +Admin View +│ +├── All Users +├── All Wallets +├── All Transactions +└── System Statistics + +--- + +## Core Components + +### 1. User Dashboard (`/dashboard`) + +**Purpose:** Allow users to view and purchase credits + +**Features:** +- Display current credit balance +- Credit purchase form +- Transaction history +- Real-time updates + +**Location:** `app/dashboard/page.tsx` + +### 2. Admin Dashboard (`/admin`) + +**Purpose:** System oversight and management + +**Features:** +- View all users +- View all wallets +- View all transactions +- System statistics + +**Access:** Restricted to `admin@admin.com` (configured via `ADMIN_EMAIL`) + +**Location:** `app/admin/page.tsx` + +### 3. Purchase API Route (`/api/purchase`) + +**Purpose:** Process credit purchases + +**Flow:** +1. Authenticate user +2. Validate purchase amount +3. Get or create user wallet +4. Initiate USDC transfer from user to admin wallet +5. Create transaction record (pending) +6. Return transaction ID + +**Location:** `app/api/purchase/route.ts` + +### 4. Webhook Handler (`/api/circle/webhook`) + +**Purpose:** Receive and process Circle transaction events + +**Flow:** +1. Verify webhook signature +2. Parse event payload +3. Update transaction status +4. Credit user account (if completed) +5. Handle failures + +**Location:** `app/api/circle/webhook/route.ts` + +--- + +## Credit Purchase Flow + +### Step-by-Step Process + +User Initiates Purchase +└─> User enters credit amount +└─> Clicks "Purchase Credits" +Frontend Validation +└─> Validates amount > 0 +└─> Calculates USDC cost +└─> Confirms with user +API Request +POST /api/purchase +Body: { amount: 100, usdcCost: 10 } +Backend Processing +├─> Authenticate user (Supabase) +├─> Validate request +├─> Get user wallet ID (or create) +├─> Call Circle SDK to initiate transfer: +│ transferUSDC({ +│ from: userWalletId, +│ to: adminWalletId, +│ amount: usdcCost +│ }) +└─> Create transaction record: +{ +user_id, +amount: 100 credits, +usdc_cost: 10, +status: 'pending', +circle_transfer_id +} +USDC Transfer (On-Chain) +└─> Circle executes transfer on Arc testnet +└─> User wallet → Admin wallet +Webhook Notification +└─> Circle sends webhook: transfer.completed +└─> Signature verified +└─> Transaction updated: status = 'completed' +└─> User credits incremented by 100 +User Dashboard Update +└─> Real-time update via Supabase subscription +└─> New balance displayed + + +### Transaction States + +```typescript +type TransactionStatus = + | 'pending' // Transfer initiated + | 'completed' // Transfer confirmed, credits added + | 'failed' // Transfer failed +``` + +--- + +## Admin Dashboard + +### Purpose + +Provides system administrators with oversight of: +- User accounts +- Wallet addresses +- Transaction history +- System health + +### Access Control + +```typescript +// Middleware checks if user email matches ADMIN_EMAIL +const isAdmin = user.email === process.env.ADMIN_EMAIL + +if (!isAdmin) { + redirect('/dashboard') +} +``` + +### Admin Features + +**1. User Management** +- View all registered users +- See user credit balances +- Track user activity + +**2. Wallet Overview** +- List all user wallets +- View wallet addresses +- Monitor wallet creation + +**3. Transaction History** +- All system transactions +- Filter by status +- Export capabilities (future) + +**4. System Statistics** +- Total users +- Total transactions +- Total USDC processed +- Credit circulation + +### Admin Wallet + +**Purpose:** Receives all USDC payments from users + +**Creation:** Automatically generated on first app startup + +**Management:** +- Stored in database (wallets table) +- Address accessible to all API routes +- Used as destination for all purchases + +--- + +## Circle Wallets Integration + +### Wallet Types + +**1. Admin Wallet** +- Single wallet for entire system +- Receives all user payments +- Created automatically on startup + +**2. User Wallets** +- One wallet per user +- Created on first purchase +- Stored with user ID + +### Wallet Creation Flow + +```typescript +import { initiateDeveloperControlledWalletsClient } from '@circle-fin/developer-controlled-wallets' + +const client = initiateDeveloperControlledWalletsClient({ + apiKey: process.env.CIRCLE_API_KEY!, + entitySecret: process.env.CIRCLE_ENTITY_SECRET!, +}) + +// Create wallet +const response = await client.createWallets({ + blockchains: ['ARC-TESTNET'], + count: 1, + walletSetId: 'default', +}) + +const wallet = response.data?.wallets?.[0] +// Store wallet.id and wallet.address in database +``` + +### USDC Transfer Flow + +```typescript +// Transfer USDC from user to admin +const transfer = await client.createTransaction({ + walletId: userWalletId, + blockchain: 'ARC-TESTNET', + tokenAddress: process.env.CIRCLE_USDC_TOKEN_ID, + destinationAddress: adminWalletAddress, + amounts: [usdcAmount.toString()], + fee: { + type: 'level', + config: { feeLevel: 'MEDIUM' }, + }, +}) + +// Returns transfer ID for tracking +const transferId = transfer.data?.id +``` + +### SDK Configuration + +```typescript +const client = initiateDeveloperControlledWalletsClient({ + apiKey: process.env.CIRCLE_API_KEY, + entitySecret: process.env.CIRCLE_ENTITY_SECRET, +}) +``` + +**Environment Variables:** +- `CIRCLE_API_KEY` - Circle API authentication +- `CIRCLE_ENTITY_SECRET` - Entity secret for wallet operations +- `CIRCLE_BLOCKCHAIN` - Target blockchain (ARC-TESTNET) +- `CIRCLE_USDC_TOKEN_ID` - USDC token address + +--- + +## Database Schema + +### Tables + +**1. users** +```sql +CREATE TABLE users ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + email TEXT UNIQUE NOT NULL, + created_at TIMESTAMPTZ DEFAULT NOW(), + credits INTEGER DEFAULT 0, + wallet_id TEXT, -- Circle wallet ID + wallet_address TEXT -- On-chain address +); +``` + +**2. transactions** +```sql +CREATE TABLE transactions ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + user_id UUID REFERENCES users(id), + credit_amount INTEGER NOT NULL, + usdc_cost NUMERIC(10,2) NOT NULL, + status TEXT NOT NULL, -- 'pending' | 'completed' | 'failed' + circle_transfer_id TEXT, -- Circle transaction ID + created_at TIMESTAMPTZ DEFAULT NOW(), + completed_at TIMESTAMPTZ +); +``` + +**3. wallets** +```sql +CREATE TABLE wallets ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + user_id UUID REFERENCES users(id), + wallet_id TEXT NOT NULL, -- Circle wallet ID + wallet_address TEXT NOT NULL, -- On-chain address + blockchain TEXT DEFAULT 'ARC-TESTNET', + created_at TIMESTAMPTZ DEFAULT NOW(), + is_admin BOOLEAN DEFAULT FALSE +); +``` + +### Row-Level Security (RLS) + +**Users Table:** +```sql +-- Users can only see their own data +CREATE POLICY "Users can view own data" + ON users FOR SELECT + USING (auth.uid() = id); + +-- Admins can see all users +CREATE POLICY "Admins can view all users" + ON users FOR SELECT + USING ( + (SELECT email FROM users WHERE id = auth.uid()) = 'admin@admin.com' + ); +``` + +**Transactions Table:** +```sql +-- Users can view their own transactions +CREATE POLICY "Users can view own transactions" + ON transactions FOR SELECT + USING (user_id = auth.uid()); + +-- Admins can view all transactions +CREATE POLICY "Admins can view all transactions" + ON transactions FOR SELECT + USING ( + (SELECT email FROM users WHERE id = auth.uid()) = 'admin@admin.com' + ); +``` + +--- + +## Webhook System + +### Purpose + +Receive real-time notifications from Circle when transactions complete + +### Endpoint +POST /api/circle/webhook + +### Signature Verification + +```typescript +import crypto from 'crypto' + +function verifyWebhookSignature( + payload: string, + signature: string, + secret: string +): boolean { + const hmac = crypto.createHmac('sha256', secret) + const digest = hmac.update(payload).digest('hex') + return crypto.timingSafeEqual( + Buffer.from(signature), + Buffer.from(digest) + ) +} +``` + +### Event Types + +**transfer.completed** +```json +{ + "type": "transfer.completed", + "data": { + "id": "transfer-id", + "from": "user-wallet-address", + "to": "admin-wallet-address", + "amount": "10.00", + "status": "completed" + } +} +``` + +**transfer.failed** +```json +{ + "type": "transfer.failed", + "data": { + "id": "transfer-id", + "error": "insufficient_balance" + } +} +``` + +### Processing Flow + +1. Receive webhook POST request +2. Verify signature using Circle's public key +3. Parse event type and data +4. Match transfer ID to pending transaction +5. Update transaction status +6. If completed: credit user account +7. Return 200 OK to acknowledge receipt + +--- + +## Security Model + +### Authentication + +- **Supabase Auth** - User authentication +- **JWT tokens** - Session management +- **Email verification** - Account security + +### Authorization + +- **RLS policies** - Database access control +- **Admin checks** - Admin-only routes +- **User isolation** - Users can only access their own data + +### API Security + +- **Environment variables** - Secrets never committed +- **Webhook signatures** - Verify Circle events +- **Input validation** - Sanitize all inputs +- **Error handling** - No sensitive data in errors + +### Wallet Security + +- **Server-side only** - Wallet operations in API routes +- **Entity secret** - Required for wallet operations +- **No private key storage** - Circle manages keys + +### Rate Limiting + +**Supabase:** +- Email signups: 2 per hour (default) +- Can be configured via Supabase dashboard + +**Future:** +- API route rate limiting +- Purchase limits per user + +--- + +## Deployment Considerations + +### Environment Variables + +All sensitive configuration via environment variables: +- Circle credentials +- Supabase credentials +- Admin email +- Webhook secrets + +### Database Migrations + +- Use Supabase migrations for schema changes +- Test migrations in dev before production +- Keep migration files in version control + +### Webhook Configuration + +- Use HTTPS in production +- Configure webhook URL in Circle Console +- Test with ngrok in development + +### Monitoring + +- Log all transactions +- Monitor webhook delivery +- Track failed purchases +- Alert on errors + +--- + +## Further Reading + +- [Circle Developer Controlled Wallets](https://developers.circle.com/wallets/dev-controlled) +- [Next.js Documentation](https://nextjs.org/docs) +- [Supabase Documentation](https://supabase.com/docs) +- [Arc Testnet](https://developers.circle.com/arc) + +--- + +**This architecture enables seamless USDC credit purchases with real-time updates and comprehensive admin oversight.** diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 0000000..149722c --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -0,0 +1,727 @@ +# arc-commerce Troubleshooting Guide + +This guide helps you resolve common issues when developing with arc-commerce. + +## Table of Contents +- [Installation Issues](#installation-issues) +- [API Key Setup](#api-key-setup) +- [Database Issues](#database-issues) +- [Webhook Issues](#webhook-issues) +- [Credit Purchase Errors](#credit-purchase-errors) +- [Admin Dashboard Issues](#admin-dashboard-issues) +- [Runtime Errors](#runtime-errors) +- [Deployment Issues](#deployment-issues) +- [FAQ](#faq) + +--- + +## Installation Issues + +### Node Version Mismatch + +**Problem:** README requires Node v22+, but you have v20 + +**Error:** +Warning: The current Node version v20.x.x does not meet the required version v22+ + +**Solutions:** + +1. **Install Node v22 with nvm:** +```bash + nvm install 22 + nvm use 22 + node --version # Should show v22.x.x +``` + +2. **Or continue with v20:** (may work but not officially supported) +```bash + # arc-commerce likely works on v20, test it + npm install + npm run dev +``` + +### npm Install Warnings + +**Problem:** Deprecation warnings during `npm install` + +**Common warnings:** +npm warn deprecated inflight@1.0.6 +npm warn deprecated @humanwhocodes/config-array@0.11.14 + +**Solution:** These are generally safe to ignore. They're from dependencies and don't affect functionality. + +### npm Vulnerabilities + +**Problem:** `npm install` reports vulnerabilities + +**Output:** +21 vulnerabilities (15 moderate, 6 high) + +**Solution:** + +1. **Check if fixable:** +```bash + npm audit fix +``` + +2. **Most are in dev dependencies:** Generally safe for development + +3. **For production:** Address before deploying: +```bash + npm audit fix --force # Use with caution +``` + +### Docker Not Running + +**Problem:** `npx supabase start` fails + +**Error:** +Error: Cannot connect to the Docker daemon + +**Solution:** + +1. **Start Docker Desktop** +2. **Wait for Docker to fully start** (check icon) +3. **Try again:** +```bash + npx supabase start +``` + +--- + +## API Key Setup + +### Circle API Key Not Working + +**Problem:** API requests fail with authentication error + +**Error:** +Error: Invalid API key + +**Solutions:** + +1. **Verify API key format:** +```bash + # Should start with: TEST_API_KEY:xxx or LIVE_API_KEY:xxx + echo $CIRCLE_API_KEY +``` + +2. **Check environment file:** +```bash + cat .env.local | grep CIRCLE_API_KEY +``` + +3. **Regenerate key:** + - Go to https://console.circle.com + - Navigate to **Settings → API Keys** + - Create new **Sandbox** key (for testnet) + - Update `.env.local` + +### Entity Secret Issues + +**Problem:** Wallet creation fails + +**Error:** +Error: Invalid entity secret + +**Solutions:** + +1. **Verify entity secret exists:** +```bash + cat .env.local | grep CIRCLE_ENTITY_SECRET +``` + +2. **Generate new entity secret:** + - Go to Circle Console → **Settings → Entity Secrets** + - Click **"Generate Entity Secret"** + - **Copy immediately** (can't view again!) + - Update `.env.local` + +3. **Format check:** Should be a long alphanumeric string + +### Admin Wallet Not Created + +**Problem:** App starts but admin wallet missing + +**Error:** +Error: Admin wallet not found + +**Solutions:** + +1. **Check database:** +```bash + # Local Supabase + npx supabase db reset + npx supabase migration up + + # Then restart app + npm run dev +``` + +2. **Verify admin email:** +```bash + # Must match ADMIN_EMAIL in .env.local + cat .env.local | grep ADMIN_EMAIL +``` + +3. **Check logs:** Look for wallet creation errors on startup + +4. **Manual creation:** Check admin initialization code in `lib/admin.ts` + +--- + +## Database Issues + +### Supabase Connection Failed + +**Problem:** Can't connect to Supabase + +**Error:** +Error: Failed to connect to Supabase + +**Solutions:** + +**Local Supabase:** +```bash +# Check if running +npx supabase status + +# If not running, start it +npx supabase start + +# Verify URL matches .env.local +npx supabase status | grep "API URL" +``` + +**Remote Supabase:** +```bash +# Test connection +curl https://your-project.supabase.co/rest/v1/ + +# Verify credentials in Supabase dashboard: +# Settings → API → Project URL and keys +``` + +### Migration Errors + +**Problem:** Database migrations fail + +**Error:** +Error applying migration + +**Solutions:** + +1. **Reset database (local):** +```bash + npx supabase db reset + npx supabase migration up +``` + +2. **Check migration files:** +```bash + ls supabase/migrations/ + # Should see .sql files +``` + +3. **Manual migration (remote):** +```bash + npx supabase db push +``` + +### RLS Policy Errors + +**Problem:** "Row level security policy violation" + +**Error:** +Error: new row violates row-level security policy + +**Solutions:** + +1. **Verify RLS enabled:** +```sql + -- In Supabase SQL Editor + SELECT tablename, rowsecurity + FROM pg_tables + WHERE schemaname = 'public'; +``` + +2. **Check policies exist:** +```sql + SELECT * FROM pg_policies; +``` + +3. **Disable RLS temporarily (dev only):** +```sql + ALTER TABLE users DISABLE ROW LEVEL SECURITY; + -- Remember to re-enable! +``` + +### Email Rate Limit + +**Problem:** "Email rate limit exceeded" + +**Error:** +Error: Email rate limit exceeded. Please try again later. + +**Solutions:** + +**Local Supabase:** +```bash +# Check Inbucket for emails +open http://127.0.0.1:54324 + +# Adjust rate limit in supabase/config.toml +[auth.rate_limit] +emails = 10 # Increase from 2 +``` + +**Remote Supabase:** +- Use unique email addresses +- Wait 1 hour between signups +- Configure custom SMTP (Settings → Auth → SMTP) +- Manually add users via dashboard + +--- + +## Webhook Issues + +### Webhooks Not Received + +**Problem:** Transactions stuck in "pending" status + +**Checklist:** + +1. **ngrok running?** +```bash + # In separate terminal + ngrok http 3000 + # Copy HTTPS URL +``` + +2. **Webhook URL configured in Circle Console?** + - Go to Circle Console → **Webhooks** + - Add endpoint: `https://your-ngrok-url.ngrok.io/api/circle/webhook` + - Save changes + +3. **Test webhook endpoint:** +```bash + curl -X POST http://localhost:3000/api/circle/webhook \ + -H "Content-Type: application/json" \ + -d '{"type":"test"}' + + # Should return 200 OK +``` + +4. **Check Circle webhook logs:** + - Circle Console → Webhooks → Your endpoint + - View delivery attempts and errors + +### Webhook Signature Verification Failed + +**Problem:** Webhooks rejected + +**Error:** +Error: Invalid webhook signature + +**Solutions:** + +1. **Get webhook secret from Circle Console** +2. **Add to environment:** +```bash + # .env.local + CIRCLE_WEBHOOK_SECRET=your-webhook-secret +``` + +3. **Verify signature logic:** +```typescript + // Check implementation in /api/circle/webhook/route.ts + const signature = request.headers.get('circle-signature') + // Should match HMAC SHA256 of payload +``` + +4. **Test with Circle's test events** in Console + +--- + +## Credit Purchase Errors + +### Purchase Fails Immediately + +**Problem:** Purchase API returns error + +**Common errors:** + +**1. User wallet not found:** +Error: User wallet not created +**Solution:** +- Wallet should auto-create on first purchase +- Check wallet creation logic in `/api/purchase/route.ts` +- Verify Circle credentials + +**2. Insufficient USDC:** +Error: Insufficient balance +**Solution:** +- Get testnet USDC from [Circle Faucet](https://faucet.circle.com/) +- Enter your wallet address (shown in dashboard) +- Wait for transaction confirmation + +**3. Invalid amount:** +Error: Invalid credit amount +**Solution:** +- Check amount is positive number +- Verify USDC calculation logic + +### Transaction Stuck in Pending + +**Problem:** Purchase doesn't complete + +**Debugging:** + +1. **Check transaction status:** +```bash + # In Supabase SQL Editor + SELECT * FROM transactions + WHERE status = 'pending' + ORDER BY created_at DESC; +``` + +2. **Verify webhook received:** + - Check ngrok request log + - Check Circle webhook delivery status + - Check app logs for webhook processing + +3. **Manual completion (dev only):** +```sql + -- Update transaction + UPDATE transactions + SET status = 'completed', + completed_at = NOW() + WHERE id = 'transaction-id'; + + -- Credit user + UPDATE users + SET credits = credits + 100 + WHERE id = 'user-id'; +``` + +### Credits Not Added After Payment + +**Problem:** USDC transferred but credits not updated + +**Debugging:** + +1. **Check webhook processed:** +```bash + # Check app logs + # Should see: "Webhook received: transfer.completed" +``` + +2. **Verify transaction updated:** +```sql + SELECT * FROM transactions + WHERE circle_transfer_id = 'transfer-id'; +``` + +3. **Check user credits:** +```sql + SELECT id, email, credits + FROM users + WHERE id = 'user-id'; +``` + +4. **Manual fix:** +```sql + UPDATE users + SET credits = credits + [amount] + WHERE id = 'user-id'; +``` + +--- + +## Admin Dashboard Issues + +### Can't Access Admin Dashboard + +**Problem:** Redirected to user dashboard + +**Solutions:** + +1. **Verify admin email:** +```bash + cat .env.local | grep ADMIN_EMAIL + # Default: admin@admin.com +``` + +2. **Check logged-in email matches:** + - Log out + - Log in with admin@admin.com + - Password: 123456 (default) + +3. **Verify admin check logic:** +```typescript + // In app/admin/page.tsx + const isAdmin = user.email === process.env.ADMIN_EMAIL +``` + +### Admin Dashboard Shows No Data + +**Problem:** Dashboard empty despite having users/transactions + +**Solutions:** + +1. **Check RLS policies allow admin access:** +```sql + -- Admin should see all users + SELECT * FROM users; -- Run as admin +``` + +2. **Verify admin policy exists:** +```sql + SELECT * FROM pg_policies + WHERE tablename = 'users' + AND policyname LIKE '%admin%'; +``` + +3. **Add missing admin policy:** +```sql + CREATE POLICY "Admins can view all users" + ON users FOR SELECT + USING ( + (SELECT email FROM users WHERE id = auth.uid()) = 'admin@admin.com' + ); +``` + +--- + +## Runtime Errors + +### Wallet Creation Fails + +**Problem:** "Error creating wallet" + +**Solutions:** + +1. **Verify Circle credentials:** +```bash + cat .env.local | grep CIRCLE +``` + +2. **Check Circle SDK initialized:** +```typescript + import { initiateDeveloperControlledWalletsClient } from '@circle-fin/developer-controlled-wallets' + + const client = initiateDeveloperControlledWalletsClient({ + apiKey: process.env.CIRCLE_API_KEY!, + entitySecret: process.env.CIRCLE_ENTITY_SECRET!, + }) +``` + +3. **Test wallet creation:** +```bash + # Create test script + node scripts/test-wallet-creation.js +``` + +### USDC Transfer Fails + +**Problem:** Transfer API call fails + +**Common issues:** + +1. **Invalid wallet ID:** +Error: Wallet not found + - Verify wallet exists in database + - Check wallet ID format + +2. **Invalid token address:** +Error: Invalid token address + - Verify `CIRCLE_USDC_TOKEN_ID` in `.env.local` + - Should match Arc testnet USDC address + +3. **Insufficient balance:** +Error: Insufficient balance for transfer + - Get USDC from faucet + - Check actual wallet balance + +### Authentication Errors + +**Problem:** User not authenticated + +**Error:** +Error: Not authenticated + +**Solutions:** + +1. **Check Supabase client:** +```typescript + import { createClient } from '@/lib/supabase/client' + const supabase = createClient() + const { data: { user } } = await supabase.auth.getUser() +``` + +2. **Verify session:** +```bash + # Check browser localStorage + # Should have supabase.auth.token +``` + +3. **Re-login:** + - Log out + - Clear browser cache + - Log back in + +--- + +## Deployment Issues + +### Environment Variables Not Working + +**Problem:** App can't find environment variables in production + +**Solutions:** + +1. **Verify variables set in deployment platform:** + - Vercel: Settings → Environment Variables + - Add all from `.env.local` + +2. **Check variable names:** + - Must be EXACT match (case-sensitive) + - No typos + +3. **Redeploy after adding variables:** + - Changes require new deployment + +### Build Fails + +**Problem:** `npm run build` fails in production + +**Common issues:** + +1. **TypeScript errors:** +```bash + # Fix locally first + npx tsc --noEmit + # Fix all errors shown +``` + +2. **Missing environment variables:** +```bash + # Add all required vars to deployment platform +``` + +3. **Linting errors:** +```bash + npm run lint + # Fix all errors +``` + +--- + +## FAQ + +### Q: How do I get testnet USDC? + +**A:** Use the [Circle Faucet](https://faucet.circle.com/) +1. Get your wallet address from dashboard +2. Visit faucet +3. Select Arc Testnet +4. Request USDC +5. Wait for confirmation (~1 minute) + +### Q: Why is my purchase stuck? + +**A:** Usually webhook not received: +1. Check ngrok is running +2. Verify webhook URL in Circle Console +3. Check webhook logs in Circle Console +4. Test endpoint manually + +### Q: How do I reset everything? + +**A:** Fresh start: +```bash +# Stop everything +npx supabase stop + +# Clear database +rm -rf supabase/.branches + +# Restart +npx supabase start +npx supabase migration up +npm run dev +``` + +### Q: Can I test without real USDC? + +**A:** Yes, use Arc testnet: +- Testnet USDC is free (use faucet) +- No real money involved +- Reset anytime + +### Q: How do I add more admins? + +**A:** Current design: single admin +To add more: +1. Modify admin check to use array: +```typescript + const adminEmails = [ + 'admin@admin.com', + 'admin2@admin.com' + ] + const isAdmin = adminEmails.includes(user.email) +``` +2. Update RLS policies +3. Redeploy + +### Q: What's the credit-to-USDC ratio? + +**A:** Configurable in your code: +```typescript +// Example: 1 USDC = 10 credits +const USDC_PER_CREDIT = 0.1 +``` + +### Q: Can users withdraw USDC? + +**A:** Not in current implementation +- System is one-way (USDC → Credits) +- Add withdrawal feature requires: + - Reverse transfer logic + - Credit deduction + - Admin approval (optional) + +### Q: How do I handle refunds? + +**A:** Manual process currently: +1. Reverse credit transaction in database +2. Initiate USDC transfer back to user +3. Update transaction status + +### Q: Why do I see npm warnings? + +**A:** Common and usually safe: +- Deprecation warnings: Dependencies will update +- Vulnerabilities: Mostly in dev dependencies +- Ignore unless critical + +### Q: How do I monitor transactions? + +**A:** Multiple ways: +1. Admin dashboard (UI) +2. Supabase dashboard (database) +3. Circle Console (webhooks) +4. Application logs (errors) + +--- + +## Still Having Issues? + +1. **Check GitHub Issues:** https://github.com/circlefin/arc-commerce/issues +2. **Circle Documentation:** https://developers.circle.com +3. **Supabase Docs:** https://supabase.com/docs +4. **Open a Discussion:** Share your problem with the community + +--- + +**Remember:** This is a sample application for testnet. For production use, implement additional error handling, monitoring, and security measures.