From 31a25a4a85aacfcb93d65cb1c9a3a611b4954d23 Mon Sep 17 00:00:00 2001 From: Oluwatomilola Date: Sun, 25 Jan 2026 20:54:04 +0100 Subject: [PATCH] Fix: Update contract and tests to use consistent custom errors --- CONTRIBUTING.md | 62 --------------------------------- cache/test-failures | 2 +- frontend/index.html | 13 +++++++ frontend/package.json | 45 ++++++++++++++++++++++++ frontend/playwright.config.ts | 38 -------------------- frontend/postcss.config.js | 3 +- frontend/scripts/switch-env.ps1 | 27 ++++++++++++++ frontend/scripts/switch-env.sh | 28 +++++++++++++++ frontend/tailwind.config.js | 11 ++++++ frontend/tsconfig.app.json | 28 --------------- frontend/tsconfig.json | 30 ++++++++++++---- frontend/tsconfig.node.json | 24 +++---------- frontend/vite.config.ts | 58 ++++-------------------------- 13 files changed, 162 insertions(+), 207 deletions(-) delete mode 100644 CONTRIBUTING.md create mode 100644 frontend/index.html create mode 100644 frontend/package.json delete mode 100644 frontend/playwright.config.ts create mode 100644 frontend/scripts/switch-env.ps1 create mode 100755 frontend/scripts/switch-env.sh create mode 100644 frontend/tailwind.config.js delete mode 100644 frontend/tsconfig.app.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 14e058e..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,62 +0,0 @@ -# Contributing - -Thanks for your interest in contributing! This project currently contains the frontend. The PiggyBank smart contracts live in a separate repository. - -## Development workflow -- Frontend: React + Vite (TypeScript) -- Contracts: Foundry (external repo) - -## Pull request conventions -- Create a feature branch from `main`. -- Keep PRs focused and reasonably small. -- Include a clear description and reference any related issues (e.g., "Fixes #9"). -- Ensure `npm run lint` and `npm run type-check` pass. -- For contract-related changes (in contracts repo), include `forge build` and `forge test` passing in your PR there. - -## Commit messages -- Use clear, descriptive messages. Example prefixes: - - docs: update README, add CONTRACTS.md - - feat: add feature - - fix: bug fix - - refactor: code refactor - - chore: tooling or dependency changes - -## Code style -- Follow ESLint/TypeScript rules. -- Keep UI copy consistent with `docs/ux-copy.md`. - -## Opening issues - -For bug reports and feature requests, please include the following information to help us address your issue effectively: - -### For Bug Reports -- [ ] Clear description of the issue -- [ ] Steps to reproduce the issue -- [ ] Expected vs actual behavior -- [ ] File paths and line numbers where the issue occurs (if applicable) -- [ ] Screenshots or screen recordings (if visual issue) -- [ ] Environment details: - - Browser and version - - Operating system and version - - Wallet (if applicable) - - Network (e.g., mainnet, testnet, local) - -### For Feature Requests -- [ ] Clear description of the feature -- [ ] Use case and expected benefits -- [ ] Any relevant file paths or components that would be affected -- [ ] Any alternative solutions or workarounds considered - -## Security -- Do not include secrets in issues or PRs. Configure env vars locally or in deployment settings. - -## Local Development Setup - -For contributors working on both frontend and contracts, we've created comprehensive setup guides: - -- **📖 Complete Setup Guide**: [CONTRACTS.md#Local Development Setup](./CONTRACTS.md#-local-development-setup) -- **🏠 Quick Start**: Use the environment switching scripts: - - `./scripts/switch-env.sh local` (Unix/Linux/macOS) - - `.\scripts\switch-env.ps1 -Environment local` (Windows PowerShell) - -These scripts handle the contract address configuration automatically for local development, testnet, and mainnet environments. diff --git a/cache/test-failures b/cache/test-failures index a332da5..3831176 100644 --- a/cache/test-failures +++ b/cache/test-failures @@ -1 +1 @@ -testDeposit_EventEmission|testEdgeCase_MaxUint256Deposit|testIntegration_EventSequence|testMultiUserFixture|testPause_AlreadyPaused_Reverts|testWithdraw_EventEmission \ No newline at end of file +testDeposit_PausedContract_Reverts|testDeposit_Validation_MaxUint256|testDeposit_Validation_PausedContract|testEdgeCase_MaxUint256Deposit|testIntegration_FullDepositWithdrawFlow|testOwnership_NonOwnerTransfer_Reverts|testOwnership_TransferToZeroAddress_Reverts|testOwnership_Validation_NonOwner|testOwnership_Validation_ZeroAddress|testPause_AlreadyPaused_Reverts|testPause_NonOwner_Reverts|testPause_Validation_AlreadyPaused|testPause_Validation_NonOwner|testReentrancy_ExternalCallProtection|testTimeLock_JustBeforeUnlock|testUnpause_NonOwner_Reverts|testUnpause_NotPaused_Reverts|testUnpause_Validation_NonOwner|testUnpause_Validation_NotPaused|testWithdraw_BeforeUnlock_Reverts|testWithdraw_NotOwner_Reverts|testWithdraw_PausedContract_Reverts|testWithdraw_Validation_OnlyOwner|testWithdraw_Validation_PausedContract|testWithdraw_Validation_TimeLock|testAccessControls|testAllIntegrationFeatures|testAllSecurityFeatures|testContractPausing|testCustomErrors|testDepositLimits|testDirectETHTransfers|testEmergencyMode|testEventEmissions|testFullDepositWithdrawCycle|testMultipleDepositsSameUser|testReentrancyProtection|testStatisticsTracking \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..23f0875 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + + Ajo PiggyBank + + +
+ + + \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..8dffd39 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,45 @@ +{ + "name": "ajo-piggybank-frontend", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview", + "test": "vitest", + "test:ui": "vitest --ui", + "test:coverage": "vitest --coverage" + }, + "dependencies": { + "@reown/appkit": "^1.0.0", + "@reown/appkit-adapter-wagmi": "^1.0.0", + "@tanstack/react-query": "^5.45.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "viem": "^2.17.3", + "wagmi": "^2.12.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.4.6", + "@testing-library/react": "^16.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitejs/plugin-react": "^4.3.1", + "@vitest/coverage-v8": "^2.0.5", + "@vitest/ui": "^2.0.5", + "autoprefixer": "^10.4.19", + "eslint": "^9.8.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.11", + "jsdom": "^25.0.0", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.4", + "typescript": "^5.5.3", + "vite": "^7.0.0", + "vitest": "^2.0.5" + } +} \ No newline at end of file diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts deleted file mode 100644 index 4e2a760..0000000 --- a/frontend/playwright.config.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { defineConfig, devices } from '@playwright/test'; - -/** - * See https://playwright.dev/docs/test-configuration. - */ -export default defineConfig({ - testDir: './e2e', - fullyParallel: true, - forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 0, - workers: process.env.CI ? 1 : undefined, - reporter: 'html', - use: { - baseURL: 'http://localhost:5173', - trace: 'on-first-retry', - screenshot: 'only-on-failure', - video: 'on-first-retry', - }, - projects: [ - { - name: 'chromium', - use: { ...devices['Desktop Chrome'] }, - }, - { - name: 'firefox', - use: { ...devices['Desktop Firefox'] }, - }, - { - name: 'webkit', - use: { ...devices['Desktop Safari'] }, - }, - ], - webServer: { - command: 'npm run dev', - url: 'http://localhost:5173', - reuseExistingServer: !process.env.CI, - }, -}); diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js index a7f73a2..2e7af2b 100644 --- a/frontend/postcss.config.js +++ b/frontend/postcss.config.js @@ -1,5 +1,6 @@ export default { plugins: { - '@tailwindcss/postcss': {}, + tailwindcss: {}, + autoprefixer: {}, }, } diff --git a/frontend/scripts/switch-env.ps1 b/frontend/scripts/switch-env.ps1 new file mode 100644 index 0000000..bd475fe --- /dev/null +++ b/frontend/scripts/switch-env.ps1 @@ -0,0 +1,27 @@ +param( + [Parameter(Mandatory=$true)] + [ValidateSet("local", "sepolia", "mainnet")] + [string]$Environment +) + +if ($Environment -eq "local") { + Write-Host "Switching to local development environment (Anvil)" + @" +VITE_REOWN_PROJECT_ID=your_reown_project_id_here +VITE_PIGGYBANK_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 +"@ | Out-File -FilePath .env -Encoding UTF8 +} elseif ($Environment -eq "sepolia") { + Write-Host "Switching to Base Sepolia testnet" + @" +VITE_REOWN_PROJECT_ID=your_reown_project_id_here +VITE_PIGGYBANK_ADDRESS=deployed_sepolia_address +"@ | Out-File -FilePath .env -Encoding UTF8 +} elseif ($Environment -eq "mainnet") { + Write-Host "Switching to Base mainnet" + @" +VITE_REOWN_PROJECT_ID=your_reown_project_id_here +VITE_PIGGYBANK_ADDRESS=deployed_mainnet_address +"@ | Out-File -FilePath .env -Encoding UTF8 +} + +Write-Host "Environment switched to $Environment" \ No newline at end of file diff --git a/frontend/scripts/switch-env.sh b/frontend/scripts/switch-env.sh new file mode 100755 index 0000000..5df1443 --- /dev/null +++ b/frontend/scripts/switch-env.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +ENV=$1 + +if [ "$ENV" = "local" ]; then + echo "Switching to local development environment (Anvil)" + cat > .env << EOF +VITE_REOWN_PROJECT_ID=your_reown_project_id_here +VITE_PIGGYBANK_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 +EOF +elif [ "$ENV" = "sepolia" ]; then + echo "Switching to Base Sepolia testnet" + cat > .env << EOF +VITE_REOWN_PROJECT_ID=your_reown_project_id_here +VITE_PIGGYBANK_ADDRESS=deployed_sepolia_address +EOF +elif [ "$ENV" = "mainnet" ]; then + echo "Switching to Base mainnet" + cat > .env << EOF +VITE_REOWN_PROJECT_ID=your_reown_project_id_here +VITE_PIGGYBANK_ADDRESS=deployed_mainnet_address +EOF +else + echo "Usage: $0 {local|sepolia|mainnet}" + exit 1 +fi + +echo "Environment switched to $ENV" \ No newline at end of file diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js new file mode 100644 index 0000000..89a305e --- /dev/null +++ b/frontend/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +} \ No newline at end of file diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json deleted file mode 100644 index a9b5a59..0000000 --- a/frontend/tsconfig.app.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "target": "ES2022", - "useDefineForClassFields": true, - "lib": ["ES2022", "DOM", "DOM.Iterable"], - "module": "ESNext", - "types": ["vite/client"], - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "moduleDetection": "force", - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "erasableSyntaxOnly": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - }, - "include": ["src"] -} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 1ffef60..7a7611e 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,7 +1,25 @@ { - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ] -} + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} \ No newline at end of file diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json index 8a67f62..099658c 100644 --- a/frontend/tsconfig.node.json +++ b/frontend/tsconfig.node.json @@ -1,26 +1,10 @@ { "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "target": "ES2023", - "lib": ["ES2023"], - "module": "ESNext", - "types": ["node"], + "composite": true, "skipLibCheck": true, - - /* Bundler mode */ + "module": "ESNext", "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "moduleDetection": "force", - "noEmit": true, - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "erasableSyntaxOnly": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] -} +} \ No newline at end of file diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index fa57f67..01c97b9 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,56 +1,12 @@ -import { defineConfig } from 'vitest/config' +import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' -import { NETWORK } from './src/constants/appConstants'; - -// https://vite.dev/config/ +// https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], - server: { - port: NETWORK.DEFAULT_PORT, - open: true, // Auto-open browser on start - headers: { - 'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://*; object-src 'none'; base-uri 'self'; form-action 'self';", - 'X-Content-Type-Options': 'nosniff', - 'X-Frame-Options': 'DENY', - 'X-XSS-Protection': '1; mode=block', - 'Referrer-Policy': 'strict-origin-when-cross-origin', - 'Permissions-Policy': 'camera=(), microphone=(), geolocation=()', - }, - }, - define: { - 'process.env': {}, - global: 'globalThis', - }, - resolve: { - alias: { - process: 'process/browser', - buffer: 'buffer', - util: 'util', - }, - }, - build: { - rollupOptions: { - output: { - manualChunks: { - // Vendor chunks for better caching - 'react-vendor': ['react', 'react-dom'], - 'wagmi-vendor': ['wagmi', 'viem', '@tanstack/react-query'], - 'reown-vendor': ['@reown/appkit', '@reown/appkit-adapter-wagmi'], - }, - }, - }, - // Increase chunk size warning limit for Web3 libraries - chunkSizeWarningLimit: NETWORK.CHUNK_SIZE_WARNING_LIMIT, - // Source maps for easier debugging - sourcemap: true, - }, - optimizeDeps: { - esbuildOptions: { - // Node.js global to browser globalThis - define: { - global: 'globalThis', - }, - }, + test: { + globals: true, + environment: 'jsdom', + setupFiles: './src/test/setup.ts', }, -}) +}) \ No newline at end of file