diff --git a/frontend/.env.example b/frontend/.env.example index 0192f65..99eba79 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -39,4 +39,4 @@ VITE_REOWN_PROJECT_ID= # - Testnet and mainnet addresses are different and NOT interchangeable # - The frontend will fail to load if this address is incorrect or missing # - Contract must be verified on the blockchain explorer for best transparency -VITE_PIGGYBANK_ADDRESS= 0x3d0F26B383c810500550b0A4213505E46782f77C \ No newline at end of file +VITE_PIGGYBANK_ADDRESS= "0x3d0F26B383c810500550b0A4213505E46782f77C" \ No newline at end of file diff --git a/frontend/e2e/deposit-flow.spec.ts b/frontend/e2e/deposit-flow.spec.ts deleted file mode 100644 index 134d830..0000000 --- a/frontend/e2e/deposit-flow.spec.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test.describe('Deposit Flow', () => { - test.beforeEach(async ({ page }) => { - // Mock wallet connection before each test - await page.goto('/'); - await page.evaluate(() => { - window.ethereum = { - isMetaMask: true, - request: async (request: { method: string, params?: unknown[] }) => { - if (request.method === 'eth_requestAccounts') { - return ['0x1234567890123456789012345678901234567890']; - } - if (request.method === 'eth_sendTransaction') { - return '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'; - } - if (request.method === 'eth_chainId') { - return '0x1'; - } - return null; - }, - on: () => {}, - removeListener: () => {}, - }; - }); - - // Connect wallet - await page.getByRole('button', { name: /connect wallet/i }).click(); - await expect(page.getByText(/0x1234...7890/)).toBeVisible(); - }); - - test('should allow depositing ETH', async ({ page }) => { - // Fill in deposit amount - const amountInput = page.getByLabel(/amount/i); - await amountInput.fill('0.1'); - await expect(amountInput).toHaveValue('0.1'); - - // Mock contract interaction - await page.evaluate(() => { - window.piggyBankContract = { - deposit: () => ({ - wait: async () => ({ - status: 1, - transactionHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', - }), - }), - }; - }); - - // Submit deposit - const depositButton = page.getByRole('button', { name: /deposit eth/i }); - await depositButton.click(); - - // Check for success message - await expect(page.getByText(/deposit successful/i)).toBeVisible(); - }); - - test('should show error for invalid amount', async ({ page }) => { - // Try to submit without entering an amount - const depositButton = page.getByRole('button', { name: /deposit eth/i }); - await depositButton.click(); - - // Check for error message - await expect(page.getByText(/please enter a valid amount/i)).toBeVisible(); - }); -}); diff --git a/frontend/e2e/test-utils.ts b/frontend/e2e/test-utils.ts deleted file mode 100644 index a3eeeef..0000000 --- a/frontend/e2e/test-utils.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Page } from '@playwright/test'; - -declare global { - interface Window { - piggyBankContract?: unknown; - } -} - -/** - * Mocks a connected wallet with the specified address - * @param page Playwright page object - * @param address Wallet address to mock (defaults to a test address) - */ -export async function mockWalletConnection(page: Page, address = '0x1234567890123456789012345678901234567890') { - await page.evaluate((walletAddress) => { - // Mock window.ethereum - window.ethereum = { - isMetaMask: true, - request: async (request: { method: string, params?: unknown[] }) => { - if (request.method === 'eth_requestAccounts') { - return [walletAddress]; - } - if (request.method === 'eth_sendTransaction') { - return '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'; - } - if (request.method === 'eth_chainId') { - return '0x1'; // Mainnet - } - return null; - }, - on: () => {}, - removeListener: () => {}, - }; - }, address); -} - -/** - * Mocks the PiggyBank contract with the specified state - * @param page Playwright page object - * @param options Contract state options - */ -export async function mockPiggyBankContract( - page: Page, - options: { - balance?: string; - unlockTime?: number; - owner?: string; - } = {} -) { - await page.evaluate((opts) => { - const defaultOptions = { - balance: '1000000000000000000', // 1 ETH in wei - unlockTime: Math.floor(Date.now() / 1000) - 3600, // 1 hour in the past - owner: '0x1234567890123456789012345678901234567890', - ...opts, - }; - - window.piggyBankContract = { - balanceOf: () => defaultOptions.balance, - unlockTime: () => defaultOptions.unlockTime, - owner: () => defaultOptions.owner, - deposit: () => ({ - wait: async () => ({ - status: 1, - transactionHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd', - }), - }), - withdraw: () => ({ - wait: async () => ({ - status: 1, - transactionHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdee', - }), - }), - }; - }, options); -} - -/** - * Connects a wallet in the UI - * @param page Playwright page object - */ -export async function connectWallet(page: Page) { - const connectButton = page.getByRole('button', { name: /connect wallet/i }); - await connectButton.click(); - await expect(page.getByText(/0x1234...7890/)).toBeVisible(); -} - -/** - * Makes a deposit through the UI - * @param page Playwright page object - * @param amount Amount of ETH to deposit - */ -export async function makeDeposit(page: Page, amount: string) { - const amountInput = page.getByLabel(/amount/i); - await amountInput.fill(amount); - - const depositButton = page.getByRole('button', { name: /deposit eth/i }); - await depositButton.click(); - - // Wait for the transaction to complete - await expect(page.getByText(/deposit successful/i)).toBeVisible(); -} diff --git a/frontend/e2e/wallet-connect.spec.ts b/frontend/e2e/wallet-connect.spec.ts deleted file mode 100644 index 7ae7d88..0000000 --- a/frontend/e2e/wallet-connect.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test.describe('Wallet Connection', () => { - test('should connect and disconnect wallet', async ({ page }) => { - // Navigate to the app - await page.goto('/'); - - // Check if the connect wallet button is visible - const connectButton = page.getByRole('button', { name: /connect wallet/i }); - await expect(connectButton).toBeVisible(); - - // Mock wallet connection - await page.evaluate(() => { - window.ethereum = { - isMetaMask: true, - request: async (request: { method: string }) => { - if (request.method === 'eth_requestAccounts') { - return ['0x1234567890123456789012345678901234567890']; - } - return null; - }, - on: () => {}, - removeListener: () => {}, - }; - }); - - // Click connect button - await connectButton.click(); - - // Wait for the wallet to connect - const walletAddress = page.getByText(/0x1234...7890/); - await expect(walletAddress).toBeVisible(); - - // Check if the deposit form is visible after connection - const depositForm = page.getByRole('form', { name: /deposit form/i }); - await expect(depositForm).toBeVisible(); - }); -}); diff --git a/frontend/e2e/withdraw-flow.spec.ts b/frontend/e2e/withdraw-flow.spec.ts deleted file mode 100644 index 14c5f63..0000000 --- a/frontend/e2e/withdraw-flow.spec.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test.describe('Withdraw Flow', () => { - test.beforeEach(async ({ page }) => { - // Mock wallet connection and contract state - await page.goto('/'); - await page.evaluate(() => { - // Mock wallet - window.ethereum = { - isMetaMask: true, - request: async (request: { method: string, params?: unknown[] }) => { - if (request.method === 'eth_requestAccounts') { - return ['0x1234567890123456789012345678901234567890']; - } - if (request.method === 'eth_sendTransaction') { - return '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'; - } - if (request.method === 'eth_chainId') { - return '0x1'; - } - return null; - }, - on: () => {}, - removeListener: () => {}, - }; - - // Mock contract with balance and unlocked state - window.piggyBankContract = { - balanceOf: () => '1000000000000000000', // 1 ETH in wei - unlockTime: () => Math.floor(Date.now() / 1000) - 3600, // 1 hour in the past - withdraw: () => ({ - wait: async () => ({ - status: 1, - transactionHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdee', - }), - }), - }; - }); - - // Connect wallet - await page.getByRole('button', { name: /connect wallet/i }).click(); - await expect(page.getByText(/0x1234...7890/)).toBeVisible(); - }); - - test('should allow withdrawing when unlocked', async ({ page }) => { - // Check that withdraw button is enabled - const withdrawButton = page.getByRole('button', { name: /withdraw all/i }); - await expect(withdrawButton).toBeEnabled(); - - // Mock the transaction confirmation - await page.evaluate(() => { - (window as unknown as { confirm: () => boolean }).confirm = () => true; - }); - - // Click withdraw button - await withdrawButton.click(); - - // Check for success message - await expect(page.getByText(/withdrawn/i)).toBeVisible(); - }); - - test('should show locked state when funds are locked', async ({ page }) => { - // Update mock to show locked state - await page.evaluate(() => { - (window as unknown as { piggyBankContract: Record }).piggyBankContract = { - ...(window as unknown as { piggyBankContract: Record }).piggyBankContract, - unlockTime: () => Math.floor(Date.now() / 1000) + 3600, // 1 hour in the future - }; - }); - - // Reload the page to get the updated contract state - await page.reload(); - - // Check that withdraw button is disabled - const withdrawButton = page.getByRole('button', { name: /withdraw all/i }); - await expect(withdrawButton).toBeDisabled(); - - // Check for locked funds message - await expect(page.getByText(/your funds are still locked/i)).toBeVisible(); - }); -}); diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/scripts/switch-env.ps1 b/frontend/scripts/switch-env.ps1 deleted file mode 100644 index 8248596..0000000 --- a/frontend/scripts/switch-env.ps1 +++ /dev/null @@ -1,187 +0,0 @@ -# Environment switching script for PiggyBank frontend -# Usage: .\scripts\switch-env.ps1 {local|sepolia|mainnet} -# PowerShell version for Windows users - -param( - [Parameter(Mandatory=$false)] - [ValidateSet("local", "sepolia", "mainnet")] - [string]$Environment -) - -Write-Host "๐Ÿ”ง PiggyBank Frontend Environment Switcher (PowerShell)" -ForegroundColor Cyan -Write-Host "=========================================================" -ForegroundColor Cyan -Write-Host "" - -# Check if environment parameter provided -if (-not $Environment) { - Write-Host "โŒ Error: No environment specified" -ForegroundColor Red - Write-Host "" - Write-Host "Usage: .\scripts\switch-env.ps1 {local|sepolia|mainnet}" -ForegroundColor Yellow - Write-Host "" - Write-Host "Available environments:" -ForegroundColor Green - Write-Host " local - Local Anvil/Hardhat development" -ForegroundColor White - Write-Host " sepolia - Base Sepolia testnet" -ForegroundColor White - Write-Host " mainnet - Base mainnet" -ForegroundColor White - exit 1 -} - -# Define environment variables -$contractAddress = "" -$networkInfo = "" - -switch ($Environment) { - "local" { - Write-Host "๐Ÿ  Switching to LOCAL development environment" -ForegroundColor Green - Write-Host "Using local Anvil/Hardhat blockchain" -ForegroundColor Gray - $contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" # Default Anvil address - $networkInfo = @{ - "Network" = "Local (Anvil/Hardhat)" - "Contract" = $contractAddress - "RPC" = "http://localhost:8545" - } - Write-Host "" - Write-Host "๐Ÿ“‹ Environment Setup:" -ForegroundColor Yellow - } - "sepolia" { - Write-Host "๐Ÿงช Switching to BASE SEPOLIA testnet" -ForegroundColor Yellow - Write-Host "Using Base Sepolia testnet" -ForegroundColor Gray - Write-Host "" - Write-Host "โš ๏ธ IMPORTANT: Replace with your actual testnet contract address" -ForegroundColor Yellow - $contractAddress = "0x1234567890123456789012345678901234567890" # Placeholder - $networkInfo = @{ - "Network" = "Base Sepolia Testnet" - "Contract" = "$contractAddress (PLACEHOLDER - UPDATE ME)" - "RPC" = "https://sepolia.base.org" - } - Write-Host "" - Write-Host "๐Ÿ“‹ Environment Setup:" -ForegroundColor Yellow - Write-Host "๐Ÿ“Œ To deploy your own testnet contract:" -ForegroundColor Cyan - Write-Host " 1. Run: forge create PiggyBank --rpc-url `$RPC_URL --private-key `$PRIVATE_KEY --constructor-args 3600" -ForegroundColor White - Write-Host " 2. Update CONTRACT_ADDRESS with your deployed address" -ForegroundColor White - } - "mainnet" { - Write-Host "๐Ÿš€ Switching to BASE MAINNET" -ForegroundColor Red - Write-Host "Using Base mainnet" -ForegroundColor Gray - Write-Host "" - Write-Host "โš ๏ธ WARNING: This is PRODUCTION environment!" -ForegroundColor Red - Write-Host "โš ๏ธ IMPORTANT: Replace with your actual mainnet contract address" -ForegroundColor Yellow - $contractAddress = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" # Placeholder - $networkInfo = @{ - "Network" = "Base Mainnet (PRODUCTION)" - "Contract" = "$contractAddress (PLACEHOLDER - UPDATE ME)" - "RPC" = "https://mainnet.base.org" - } - Write-Host "" - Write-Host "๐Ÿ“‹ Environment Setup:" -ForegroundColor Yellow - Write-Host "๐Ÿ“Œ To deploy your own mainnet contract:" -ForegroundColor Cyan - Write-Host " 1. Run: forge create PiggyBank --rpc-url `$RPC_URL --private-key `$PRIVATE_KEY --constructor-args 31536000" -ForegroundColor White - Write-Host " 2. Update CONTRACT_ADDRESS with your deployed address" -ForegroundColor White - } - default { - Write-Host "โŒ Error: Unknown environment '$Environment'" -ForegroundColor Red - Write-Host "" - Write-Host "Usage: .\scripts\switch-env.ps1 {local|sepolia|mainnet}" -ForegroundColor Yellow - exit 1 - } -} - -# Display network information -foreach ($key in $networkInfo.Keys) { - Write-Host " $key`: $($networkInfo[$key])" -ForegroundColor White -} - -# Check if .env.example exists -if (-not (Test-Path ".env.example")) { - Write-Host "" - Write-Host "โŒ Error: .env.example not found" -ForegroundColor Red - Write-Host "Make sure you're running this script from the frontend directory" -ForegroundColor Yellow - exit 1 -} - -# Copy .env.example to .env if .env doesn't exist -if (-not (Test-Path ".env")) { - Write-Host "" - Write-Host "๐Ÿ“ Creating .env from .env.example..." -ForegroundColor Cyan - Copy-Item ".env.example" ".env" -} - -# Update VITE_PIGGYBANK_ADDRESS in .env -Write-Host "" -Write-Host "๐Ÿ”„ Updating VITE_PIGGYBANK_ADDRESS in .env..." -ForegroundColor Cyan - -try { - $envContent = Get-Content ".env" -Raw - $updatedContent = $envContent -replace "^VITE_PIGGYBANK_ADDRESS=.*", "VITE_PIGGYBANK_ADDRESS=$contractAddress" - $updatedContent | Set-Content ".env" - - Write-Host "" - Write-Host "โœ… Environment configuration updated:" -ForegroundColor Green - Write-Host " VITE_PIGGYBANK_ADDRESS=$contractAddress" -ForegroundColor White -} catch { - Write-Host "" - Write-Host "โš ๏ธ Cannot automatically update .env file" -ForegroundColor Yellow - Write-Host "๐Ÿ“ Please manually update VITE_PIGGYBANK_ADDRESS in your .env file:" -ForegroundColor Cyan - Write-Host " Current: VITE_PIGGYBANK_ADDRESS=your_deployed_piggybank_contract_address_here" -ForegroundColor Gray - Write-Host " Replace with: VITE_PIGGYBANK_ADDRESS=$contractAddress" -ForegroundColor White -} - -# Verify the update -Write-Host "" -Write-Host "๐Ÿ“„ Current .env configuration:" -ForegroundColor Yellow -try { - $envLines = Get-Content ".env" | Where-Object { $_ -match "^VITE_(REOWN_PROJECT_ID|PIGGYBANK_ADDRESS)" } - if ($envLines) { - $envLines | ForEach-Object { Write-Host " $_" -ForegroundColor White } - } else { - Write-Host " (Check .env file manually)" -ForegroundColor Gray - } -} catch { - Write-Host " (Unable to read .env file)" -ForegroundColor Gray -} - -Write-Host "" -Write-Host "๐ŸŽฏ Next Steps:" -ForegroundColor Yellow - -switch ($Environment) { - "local" { - Write-Host "1. Start local blockchain: anvil" -ForegroundColor White - Write-Host "2. Deploy contract if needed: forge create PiggyBank --rpc-url http://localhost:8545 --constructor-args 3600" -ForegroundColor White - Write-Host "3. Start frontend: npm run dev" -ForegroundColor White - Write-Host "4. Connect MetaMask to localhost network" -ForegroundColor White - } - "sepolia" { - Write-Host "1. Deploy to testnet if needed" -ForegroundColor White - Write-Host "2. Update .env with your actual testnet contract address" -ForegroundColor White - Write-Host "3. Start frontend: npm run dev" -ForegroundColor White - Write-Host "4. Connect MetaMask to Base Sepolia network" -ForegroundColor White - Write-Host "5. Get testnet ETH from faucet" -ForegroundColor White - } - "mainnet" { - Write-Host "1. Deploy to mainnet if needed" -ForegroundColor White - Write-Host "2. Update .env with your actual mainnet contract address" -ForegroundColor White - Write-Host "3. Start frontend: npm run dev" -ForegroundColor White - Write-Host "4. Connect MetaMask to Base network" -ForegroundColor White - Write-Host "5. Use with real ETH" -ForegroundColor White - } -} - -Write-Host "" -Write-Host "๐Ÿ“š For detailed setup instructions, see:" -ForegroundColor Cyan -Write-Host " - CONTRACTS.md#-local-development-setup" -ForegroundColor White -Write-Host " - frontend/README.md" -ForegroundColor White -Write-Host "" -Write-Host "๐Ÿš€ Ready to start development with $Environment environment!" -ForegroundColor Green -Write-Host "" - -# Offer to start development server -$response = Read-Host "๐Ÿค” Would you like to start the development server now? (y/N)" -if ($response -match "^[Yy]$") { - Write-Host "" - Write-Host "๐Ÿš€ Starting development server..." -ForegroundColor Green - Write-Host " Frontend will be available at: http://localhost:3000" -ForegroundColor Cyan - Write-Host " Press Ctrl+C to stop the server" -ForegroundColor Gray - Write-Host "" - npm run dev -} else { - Write-Host "๐Ÿ‘ Environment setup complete! Run 'npm run dev' when ready to start the frontend." -ForegroundColor Green -} \ No newline at end of file diff --git a/frontend/scripts/switch-env.sh b/frontend/scripts/switch-env.sh deleted file mode 100644 index 3ff98b2..0000000 --- a/frontend/scripts/switch-env.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/bin/bash -# Environment switching script for PiggyBank frontend -# Usage: ./scripts/switch-env.sh {local|sepolia|mainnet} - -set -e - -echo "๐Ÿ”ง PiggyBank Frontend Environment Switcher" -echo "==========================================" - -# Check if correct argument provided -if [ $# -eq 0 ]; then - echo "โŒ Error: No environment specified" - echo "" - echo "Usage: $0 {local|sepolia|mainnet}" - echo "" - echo "Available environments:" - echo " local - Local Anvil/Hardhat development" - echo " sepolia - Base Sepolia testnet" - echo " mainnet - Base mainnet" - exit 1 -fi - -# Define environment variables -ENVIRONMENT="$1" -ENV_FILE="./.env" - -case "$ENVIRONMENT" in - "local") - echo "๐Ÿ  Switching to LOCAL development environment" - echo "Using local Anvil/Hardhat blockchain" - CONTRACT_ADDRESS="0x5FbDB2315678afecb367f032d93F642f64180aa3" # Default Anvil address - echo "" - echo "๐Ÿ“‹ Environment Setup:" - echo " Network: Local (Anvil/Hardhat)" - echo " Contract: $CONTRACT_ADDRESS" - echo " RPC: http://localhost:8545" - ;; - "sepolia") - echo "๐Ÿงช Switching to BASE SEPOLIA testnet" - echo "Using Base Sepolia testnet" - echo "" - echo "โš ๏ธ IMPORTANT: Replace with your actual testnet contract address" - CONTRACT_ADDRESS="0x1234567890123456789012345678901234567890" # Placeholder - echo "" - echo "๐Ÿ“‹ Environment Setup:" - echo " Network: Base Sepolia Testnet" - echo " Contract: $CONTRACT_ADDRESS (PLACEHOLDER - UPDATE ME)" - echo " RPC: https://sepolia.base.org" - echo "" - echo "๐Ÿ“Œ To deploy your own testnet contract:" - echo " 1. Run: forge create PiggyBank --rpc-url \$RPC_URL --private-key \$PRIVATE_KEY --constructor-args 3600" - echo " 2. Update CONTRACT_ADDRESS with your deployed address" - ;; - "mainnet") - echo "๐Ÿš€ Switching to BASE MAINNET" - echo "Using Base mainnet" - echo "" - echo "โš ๏ธ WARNING: This is PRODUCTION environment!" - echo "โš ๏ธ IMPORTANT: Replace with your actual mainnet contract address" - CONTRACT_ADDRESS="0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" # Placeholder - echo "" - echo "๐Ÿ“‹ Environment Setup:" - echo " Network: Base Mainnet (PRODUCTION)" - echo " Contract: $CONTRACT_ADDRESS (PLACEHOLDER - UPDATE ME)" - echo " RPC: https://mainnet.base.org" - echo "" - echo "๐Ÿ“Œ To deploy your own mainnet contract:" - echo " 1. Run: forge create PiggyBank --rpc-url \$RPC_URL --private-key \$PRIVATE_KEY --constructor-args 31536000" - echo " 2. Update CONTRACT_ADDRESS with your deployed address" - ;; - *) - echo "โŒ Error: Unknown environment '$ENVIRONMENT'" - echo "" - echo "Usage: $0 {local|sepolia|mainnet}" - exit 1 - ;; -esac - -# Check if .env.example exists -if [ ! -f ".env.example" ]; then - echo "โŒ Error: .env.example not found" - echo "Make sure you're running this script from the frontend directory" - exit 1 -fi - -# Copy .env.example to .env if .env doesn't exist -if [ ! -f ".env" ]; then - echo "๐Ÿ“ Creating .env from .env.example..." - cp .env.example .env -fi - -# Update VITE_PIGGYBANK_ADDRESS in .env -echo "๐Ÿ”„ Updating VITE_PIGGYBANK_ADDRESS in .env..." - -# Use different methods for different operating systems -if command -v gsed >/dev/null 2>&1; then - # macOS with gsed installed - gsed -i.bak "s|^VITE_PIGGYBANK_ADDRESS=.*|VITE_PIGGYBANK_ADDRESS=$CONTRACT_ADDRESS|" .env - rm .env.bak 2>/dev/null || true -elif command -v sed >/dev/null 2>&1; then - # Linux/Unix with sed - sed -i.bak "s|^VITE_PIGGYBANK_ADDRESS=.*|VITE_PIGGYBANK_ADDRESS=$CONTRACT_ADDRESS|" .env - rm .env.bak 2>/dev/null || true -else - # Fallback - manual replacement - echo "" - echo "โš ๏ธ Cannot automatically update .env file (sed not available)" - echo "๐Ÿ“ Please manually update VITE_PIGGYBANK_ADDRESS in your .env file:" - echo " Current: VITE_PIGGYBANK_ADDRESS=your_deployed_piggybank_contract_address_here" - echo " Replace with: VITE_PIGGYBANK_ADDRESS=$CONTRACT_ADDRESS" - echo "" -fi - -# Verify the update -if command -v grep >/dev/null 2>&1; then - echo "" - echo "โœ… Environment configuration updated:" - echo " VITE_PIGGYBANK_ADDRESS=$CONTRACT_ADDRESS" - echo "" - echo "๐Ÿ“„ Current .env configuration:" - grep -E "^VITE_(REOWN_PROJECT_ID|PIGGYBANK_ADDRESS)" .env 2>/dev/null || echo " (Check .env file manually)" -fi - -echo "" -echo "๐ŸŽฏ Next Steps:" -case "$ENVIRONMENT" in - "local") - echo "1. Start local blockchain: anvil" - echo "2. Deploy contract if needed: forge create PiggyBank --rpc-url http://localhost:8545 --constructor-args 3600" - echo "3. Start frontend: npm run dev" - echo "4. Connect MetaMask to localhost network" - ;; - "sepolia") - echo "1. Deploy to testnet if needed" - echo "2. Update .env with your actual testnet contract address" - echo "3. Start frontend: npm run dev" - echo "4. Connect MetaMask to Base Sepolia network" - echo "5. Get testnet ETH from faucet" - ;; - "mainnet") - echo "1. Deploy to mainnet if needed" - echo "2. Update .env with your actual mainnet contract address" - echo "3. Start frontend: npm run dev" - echo "4. Connect MetaMask to Base network" - echo "5. Use with real ETH" - ;; -esac - -echo "" -echo "๐Ÿ“š For detailed setup instructions, see:" -echo " - CONTRACTS.md#-local-development-setup" -echo " - frontend/README.md" -echo "" -echo "๐Ÿš€ Ready to start development with $ENVIRONMENT environment!" -echo "" - -# Offer to start development server -read -p "๐Ÿค” Would you like to start the development server now? (y/N): " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "๐Ÿš€ Starting development server..." - echo " Frontend will be available at: http://localhost:3000" - echo " Press Ctrl+C to stop the server" - echo "" - npm run dev -else - echo "๐Ÿ‘ Environment setup complete! Run 'npm run dev' when ready to start the frontend." -fi \ No newline at end of file diff --git a/frontend/src/hooks/usePiggyBank.ts b/frontend/src/hooks/usePiggyBank.ts index b257f86..9ae5806 100644 --- a/frontend/src/hooks/usePiggyBank.ts +++ b/frontend/src/hooks/usePiggyBank.ts @@ -14,7 +14,7 @@ interface Transaction { } export function usePiggyBank() { - const { address, isConnected } = useAccount() + const { address } = useAccount() const { writeContract, data: hash, isPending } = useWriteContract() const [transactions, setTransactions] = useState([]) const refetchTimeoutRef = useRef(null) @@ -153,18 +153,6 @@ export function usePiggyBank() { withdraw() }, [withdraw]) - // Get contract statistics using the aggregated function - const { data: contractStats } = useReadContract({ - address: PIGGYBANK_ADDRESS, - abi: PIGGYBANK_ABI, - functionName: 'getContractStats', - query: { enabled: !!address && address === owner }, - }) - - // Extract individual values from contractStats tuple - const totalDeposits = contractStats && contractStats.length >= 3 ? contractStats[0] : undefined - const totalWithdrawals = contractStats && contractStats.length >= 3 ? contractStats[1] : undefined - // Compute owner flag for convenience in components and tests const isOwner = useMemo(() => { return !!address && !!owner && address.toLowerCase() === owner.toLowerCase() diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 9f50323..618111c 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,29 +1,4 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import { WagmiConfig } from 'wagmi' -import { QueryClientProvider } from '@tanstack/react-query' -import './index.css' -import App from './App.tsx' -import { wagmiAdapter, queryClient } from './config/wagmi' -import { validateEnvironment } from './utils/validateEnv' - -// Validate environment variables on startup -const validation = validateEnvironment() - -// Throw error in strict mode (CI/production) if validation fails -if (!validation.isValid && validation.isStrict) { - throw new Error( - 'Environment validation failed. Required environment variables are missing. ' + - 'Check console for details.' - ) -} - -createRoot(document.getElementById('root')!).render( - - - - - - +import React, { StrictMode } from 'react' + , ) diff --git a/frontend/src/test/setup.ts b/frontend/src/test/setup.ts index aa6c1b2..e69de29 100644 --- a/frontend/src/test/setup.ts +++ b/frontend/src/test/setup.ts @@ -1,35 +0,0 @@ -import '@testing-library/jest-dom' -import { expect, afterEach, vi } from 'vitest' -import { cleanup } from '@testing-library/react' -import { JSDOM } from 'jsdom' - -const dom = new JSDOM('', { - url: 'http://localhost' -}) - -global.window = dom.window as any -global.document = dom.window.document -global.navigator = dom.window.navigator - -// Cleanup after each test -afterEach(() => { - cleanup() -}) - -// Mock window.matchMedia -Object.defineProperty(window, 'matchMedia', { - writable: true, - value: vi.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: vi.fn(), - removeListener: vi.fn(), - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), - })), -}) - -// Extend expect with custom matchers if needed -export { expect }