diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..fcd49e62 --- /dev/null +++ b/.env.example @@ -0,0 +1,100 @@ +# ======================================== +# PezkuwiChain - Configuration Template +# ======================================== +# Copy this file to .env and update with your actual values +# WARNING: Never commit .env file to git! + +# ======================================== +# NETWORK CONFIGURATION +# ======================================== +VITE_NETWORK=local +# Options: mainnet, staging, testnet, beta, development, local + +# Network Endpoints (WebSocket) +VITE_MAINNET_WS=wss://mainnet.pezkuwichain.io +VITE_STAGING_WS=wss://staging.pezkuwichain.io +VITE_TESTNET_WS=wss://testnet.pezkuwichain.io +VITE_BETA_WS=wss://beta.pezkuwichain.io +VITE_DEVELOPMENT_WS=ws://127.0.0.1:9944 +VITE_LOCAL_WS=ws://127.0.0.1:9945 + +# Default active endpoint +VITE_CHAIN_ENDPOINT=ws://127.0.0.1:9944 + +# ======================================== +# AUTHENTICATION & SECURITY +# ======================================== +# IMPORTANT: These credentials are for DEMO/TESTING ONLY +# DO NOT use in production! DO NOT commit actual passwords! + +# Demo founder account (leave empty for production) +VITE_DEMO_FOUNDER_EMAIL= +VITE_DEMO_FOUNDER_PASSWORD= +VITE_DEMO_FOUNDER_ID=founder-001 + +# Enable demo mode (false in production) +VITE_ENABLE_DEMO_MODE=true + +# ======================================== +# SUPABASE CONFIGURATION +# ======================================== +# Get your credentials from: https://supabase.com/dashboard + +VITE_SUPABASE_URL=your_supabase_project_url +VITE_SUPABASE_ANON_KEY=your_supabase_anon_key + +# ======================================== +# SUBSTRATE ASSET IDs +# ======================================== +# These correspond to assets in the Assets pallet + +VITE_ASSET_PEZ=1 +VITE_ASSET_HEZ=2 +VITE_ASSET_USDT=3 +VITE_ASSET_BTC=4 +VITE_ASSET_ETH=5 +VITE_ASSET_DOT=6 + +# ======================================== +# CHAIN SPECIFICATIONS +# ======================================== +VITE_CHAIN_NAME=PezkuwiChain +VITE_CHAIN_TOKEN_SYMBOL=PEZ +VITE_CHAIN_TOKEN_DECIMALS=12 +VITE_CHAIN_SS58_FORMAT=42 + +# Chain IDs (generated from genesis hash) +VITE_MAINNET_CHAIN_ID=0x1234abcd +VITE_STAGING_CHAIN_ID=0x5678efgh +VITE_TESTNET_CHAIN_ID=0x9abcijkl +VITE_BETA_CHAIN_ID=0xdef0mnop +VITE_DEV_CHAIN_ID=0xlocaldev +VITE_LOCAL_CHAIN_ID=0xlocaltest + +# ======================================== +# EXPLORER & EXTERNAL SERVICES +# ======================================== + +# Polkadot.js Apps (default explorer) +VITE_EXPLORER_URL=https://polkadot.js.org/apps/?rpc= + +# Custom block explorer (when available) +VITE_CUSTOM_EXPLORER_URL=https://explorer.pezkuwichain.io + +# WebSocket for real-time updates +VITE_WS_URL=wss://ws.pezkuwichain.io + +# ======================================== +# FEATURE FLAGS +# ======================================== +VITE_ENABLE_KYC=false +VITE_ENABLE_P2P_MARKET=true +VITE_ENABLE_GOVERNANCE=true +VITE_ENABLE_STAKING=true + +# ======================================== +# DEVELOPMENT & DEBUGGING +# ======================================== +VITE_DEBUG_MODE=false +VITE_LOG_LEVEL=info +VITE_API_TIMEOUT=30000 \ No newline at end of file diff --git a/.git-hooks/README.md b/.git-hooks/README.md new file mode 100644 index 00000000..09b1df73 --- /dev/null +++ b/.git-hooks/README.md @@ -0,0 +1,251 @@ +# Git Hooks - PezkuwiChain + +## = Overview + +This directory contains Git hook templates that help prevent security issues and maintain code quality. + +--- + +## =' Installation + +### Quick Install (Recommended) + +Run this command from the project root: + +```bash +cp .git-hooks/pre-commit.example .git/hooks/pre-commit +chmod +x .git/hooks/pre-commit +``` + +### Verify Installation + +```bash +# Check if hook is installed +ls -la .git/hooks/pre-commit + +# Test the hook +git add . +git commit -m "test" --dry-run +``` + +--- + +## = Available Hooks + +### pre-commit + +**Purpose:** Prevents committing sensitive data and enforces code quality + +**Checks:** +- L Blocks `.env` files from being committed +- L Blocks files with sensitive patterns (passwords, API keys, etc.) +- L Blocks secret files (.key, .pem, .cert, etc.) +- Warns about large files (>500KB) +- Warns about debug code (console.log, debugger) +- Warns about hardcoded credentials + +**Example output:** +``` += Running pre-commit security checks... +Checking for .env files... +Scanning for sensitive patterns... +Checking for secret files... +Checking for large files... +Checking for debug code... + All security checks passed! +``` + +--- + +## = Configuration + +### Bypass Hook (Not Recommended) + +If you absolutely need to bypass the hook: + +```bash +git commit --no-verify -m "message" +``` + + **WARNING:** Only bypass if you're sure there are no secrets! + +### Customize Checks + +Edit `.git-hooks/pre-commit.example` and adjust: + +- `PATTERNS` - Secret detection patterns +- `SECRET_FILES` - File patterns to block +- `MAX_FILE_SIZE` - Maximum file size in KB +- `DEBUG_PATTERNS` - Debug code patterns + +--- + +## > Testing + +### Test with Sample Commits + +```bash +# Test 1: Try to commit .env (should fail) +echo "SECRET=test" > .env +git add .env +git commit -m "test" +# Expected: L ERROR: Attempting to commit .env file! + +# Test 2: Try to commit hardcoded password (should fail) +echo 'const password = "mysecret123"' >> test.ts +git add test.ts +git commit -m "test" +# Expected: L ERROR: Potential secrets detected! + +# Test 3: Normal commit (should pass) +echo 'const x = 1' >> test.ts +git add test.ts +git commit -m "test" +# Expected: All security checks passed! +``` + +--- + +## = What Each Check Does + +### 1. `.env` File Check +```bash +# Blocks any .env file +.env +.env.local +.env.production +.env.staging +``` + +### 2. Sensitive Pattern Detection +Searches for patterns like: +- `password = "..."` +- `api_key = "..."` +- `secret = "..."` +- `token = "..."` +- Private key headers +- AWS access keys + +### 3. Secret File Detection +Blocks files matching: +- `*.key`, `*.pem`, `*.cert` +- `*.p12`, `*.pfx` +- `*secret*`, `*credential*` +- `.npmrc`, `.dockercfg` + +### 4. Large File Warning +Warns if file is larger than 500KB: +``` + WARNING: Large file detected: image.png (1024KB) +Consider using Git LFS for large files +``` + +### 5. Debug Code Detection +Warns about: +- `console.log()` +- `debugger` +- `TODO security` +- `FIXME security` + +### 6. Hardcoded Credentials Check +Special check for `AuthContext.tsx`: +```typescript +// L BAD - Will be blocked +const password = "mysecret123" + +// GOOD - Will pass +const password = import.meta.env.VITE_PASSWORD +``` + +--- + +## = Troubleshooting + +### Hook Not Running + +```bash +# Check if hook exists +ls -la .git/hooks/pre-commit + +# Check if executable +chmod +x .git/hooks/pre-commit + +# Verify hook content +cat .git/hooks/pre-commit +``` + +### False Positives + +If the hook incorrectly flags a file: + +1. Review the pattern that triggered +2. Confirm the file is safe +3. Use `--no-verify` to bypass (with caution) +4. Update the pattern in `.git-hooks/pre-commit.example` + +### Hook Errors + +```bash +# If hook fails to run +bash -x .git/hooks/pre-commit + +# Check for syntax errors +bash -n .git/hooks/pre-commit +``` + +--- + +## = Integration with CI/CD + +The pre-commit hook works alongside: + +### GitHub Actions +- `.github/workflows/security-check.yml` - Automated security scanning +- Runs on every PR and push to main +- Catches issues missed locally + +### Pre-push Hook (Optional) +You can also add a pre-push hook: +```bash +# .git-hooks/pre-push.example +#!/bin/bash +npm test +npm run lint +``` + +--- + +## = Best Practices + +1. **Install hooks immediately** after cloning the repo +2. **Never use `--no-verify`** unless absolutely necessary +3. **Keep hooks updated** - run `git pull` regularly +4. **Test hooks** before committing important changes +5. **Report false positives** to improve the hook + +--- + +## = Additional Resources + +### Git Hooks Documentation +- [Git Hooks Official Docs](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) +- [Pre-commit Framework](https://pre-commit.com/) + +### Security Tools +- [git-secrets](https://github.com/awslabs/git-secrets) +- [gitleaks](https://github.com/zricethezav/gitleaks) +- [TruffleHog](https://github.com/trufflesecurity/trufflehog) + +--- + +## < Support + +If you encounter issues: + +1. Check this README +2. Review `SECURITY.md` in project root +3. Contact: security@pezkuwichain.io + +--- + +**Last Updated:** October 28, 2024 diff --git a/.git-hooks/pre-commit.example b/.git-hooks/pre-commit.example new file mode 100755 index 00000000..8815a9fe --- /dev/null +++ b/.git-hooks/pre-commit.example @@ -0,0 +1,177 @@ +#!/bin/bash +# ======================================== +# Pre-commit Hook for PezkuwiChain +# ======================================== +# This hook prevents committing sensitive data +# +# INSTALLATION: +# cp .git-hooks/pre-commit.example .git/hooks/pre-commit +# chmod +x .git/hooks/pre-commit + +set -e + +# Colors for output +RED='\033[0;31m' +YELLOW='\033[1;33m' +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +echo "= Running pre-commit security checks..." + +# ======================================== +# 1. CHECK FOR .ENV FILES +# ======================================== +echo "Checking for .env files..." + +if git diff --cached --name-only | grep -E "^\.env$"; then + echo -e "${RED}L ERROR: Attempting to commit .env file!${NC}" + echo -e "${YELLOW}The .env file contains sensitive data and should never be committed.${NC}" + echo "" + echo "To fix this:" + echo " git reset HEAD .env" + echo " git add .env.example # Commit the example file instead" + exit 1 +fi + +if git diff --cached --name-only | grep -E "^\.env\.(local|production|staging)$"; then + echo -e "${RED}L ERROR: Attempting to commit environment-specific .env file!${NC}" + exit 1 +fi + +# ======================================== +# 2. CHECK FOR SENSITIVE PATTERNS +# ======================================== +echo "Scanning for sensitive patterns..." + +# Patterns to search for +PATTERNS=( + "password\s*=\s*['\"][^'\"]*['\"]" + "api[_-]?key\s*=\s*['\"][^'\"]*['\"]" + "secret\s*=\s*['\"][^'\"]*['\"]" + "token\s*=\s*['\"][^'\"]*['\"]" + "private[_-]?key" + "BEGIN RSA PRIVATE KEY" + "BEGIN PRIVATE KEY" + "aws_secret_access_key" + "AKIA[0-9A-Z]{16}" +) + +FOUND_SECRETS=false + +for pattern in "${PATTERNS[@]}"; do + if git diff --cached | grep -iE "$pattern" > /dev/null; then + if [ "$FOUND_SECRETS" = false ]; then + echo -e "${RED}L ERROR: Potential secrets detected in staged files!${NC}" + FOUND_SECRETS=true + fi + echo -e "${YELLOW}Found pattern: $pattern${NC}" + fi +done + +if [ "$FOUND_SECRETS" = true ]; then + echo "" + echo -e "${YELLOW}Detected patterns that might contain secrets.${NC}" + echo "Please review your changes and ensure no sensitive data is being committed." + echo "" + echo "To bypass this check (NOT RECOMMENDED):" + echo " git commit --no-verify" + exit 1 +fi + +# ======================================== +# 3. CHECK FOR COMMON SECRET FILES +# ======================================== +echo "Checking for secret files..." + +SECRET_FILES=( + "*.key" + "*.pem" + "*.cert" + "*.p12" + "*.pfx" + "*secret*" + "*credential*" + ".npmrc" + ".dockercfg" + ".docker/config.json" +) + +for file_pattern in "${SECRET_FILES[@]}"; do + if git diff --cached --name-only | grep -i "$file_pattern" > /dev/null; then + echo -e "${RED}L ERROR: Attempting to commit secret file matching: $file_pattern${NC}" + echo "These files should be added to .gitignore" + exit 1 + fi +done + +# ======================================== +# 4. CHECK FOR LARGE FILES +# ======================================== +echo "Checking for large files..." + +# Maximum file size in KB +MAX_FILE_SIZE=500 + +while IFS= read -r file; do + if [ -f "$file" ]; then + file_size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null) + file_size_kb=$((file_size / 1024)) + + if [ "$file_size_kb" -gt "$MAX_FILE_SIZE" ]; then + echo -e "${YELLOW} WARNING: Large file detected: $file (${file_size_kb}KB)${NC}" + echo "Consider using Git LFS for large files" + fi + fi +done < <(git diff --cached --name-only) + +# ======================================== +# 5. CHECK FOR DEBUG CODE +# ======================================== +echo "Checking for debug code..." + +DEBUG_PATTERNS=( + "console\.log" + "debugger" + "TODO.*security" + "FIXME.*security" + "XXX.*security" +) + +for pattern in "${DEBUG_PATTERNS[@]}"; do + if git diff --cached | grep -E "$pattern" > /dev/null; then + echo -e "${YELLOW} WARNING: Found debug code: $pattern${NC}" + echo "Consider removing debug code before committing" + fi +done + +# ======================================== +# 6. VERIFY ENVIRONMENT VARIABLES USAGE +# ======================================== +echo "Checking environment variable usage..." + +# Check for direct credential usage instead of env vars +if git diff --cached | grep -E "(password|api[_-]?key|secret).*['\"][^'\"]{20,}['\"]" > /dev/null; then + echo -e "${YELLOW} WARNING: Potential hardcoded credentials detected${NC}" + echo "Please use environment variables instead:" + echo " import.meta.env.VITE_API_KEY" +fi + +# ======================================== +# 7. CHECK SPECIFIC FILES +# ======================================== +echo "Checking specific configuration files..." + +# Check if AuthContext has hardcoded credentials +if git diff --cached -- "src/contexts/AuthContext.tsx" | grep -E "password.*:" | grep -vE "import\.meta\.env" > /dev/null; then + echo -e "${RED}L ERROR: AuthContext.tsx may contain hardcoded credentials${NC}" + echo "Ensure all credentials use environment variables" + exit 1 +fi + +# ======================================== +# SUCCESS +# ======================================== +echo -e "${GREEN} All security checks passed!${NC}" +echo "" + +exit 0 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..9986f500 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,93 @@ +# ======================================== +# Git Attributes for PezkuwiChain +# ======================================== +# Prevents merge conflicts and ensures consistent file handling + +# ======================================== +# ENVIRONMENT FILES - NO MERGE +# ======================================== +# Prevent .env files from being merged +# Always use local version (ours) in case of conflict +.env merge=ours +.env.* merge=ours + +# But allow .env.example to be merged normally +!.env.example + +# ======================================== +# SENSITIVE FILES - NO DIFF +# ======================================== +# Prevent sensitive files from showing diffs +*.key diff=secret +*.pem diff=secret +*.cert diff=secret +*.p12 diff=secret +*.pfx diff=secret +*secret* diff=secret +*password* diff=secret +*credential* diff=secret + +# ======================================== +# LINE ENDINGS +# ======================================== +# Auto normalize line endings +* text=auto + +# Specific file types +*.js text eol=lf +*.jsx text eol=lf +*.ts text eol=lf +*.tsx text eol=lf +*.json text eol=lf +*.md text eol=lf +*.yml text eol=lf +*.yaml text eol=lf + +# Windows batch files +*.bat text eol=crlf +*.cmd text eol=crlf + +# Shell scripts +*.sh text eol=lf + +# ======================================== +# BINARY FILES +# ======================================== +# Mark as binary (no text conversion) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary +*.gz binary +*.zip binary +*.7z binary +*.ttf binary +*.eot binary +*.woff binary +*.woff2 binary +*.pyc binary + +# ======================================== +# GENERATED FILES +# ======================================== +# Mark generated files +dist/** linguist-generated=true +build/** linguist-generated=true +coverage/** linguist-generated=true +*.min.js linguist-generated=true +*.min.css linguist-generated=true + +# ======================================== +# LOCK FILES +# ======================================== +# Always use local version for lock files in conflicts +package-lock.json merge=ours +yarn.lock merge=ours +pnpm-lock.yaml merge=ours diff --git a/.github/workflows/security-check.yml b/.github/workflows/security-check.yml new file mode 100644 index 00000000..cc28f4e0 --- /dev/null +++ b/.github/workflows/security-check.yml @@ -0,0 +1,251 @@ +name: Security Check + +# ======================================== +# Automated Security Scanning +# ======================================== +# This workflow runs on every PR and push to main +# to detect potential security issues + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + # Allow manual trigger + workflow_dispatch: + +jobs: + # ======================================== + # SECRET SCANNING + # ======================================== + secret-scan: + name: Scan for Secrets + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history for better scanning + + - name: TruffleHog Secret Scan + uses: trufflesecurity/trufflehog@main + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified + + - name: Gitleaks Secret Scan + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} + + # ======================================== + # FILE VALIDATION + # ======================================== + file-validation: + name: Validate Files + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Check for .env files + run: | + echo "Checking for .env files..." + if git ls-files | grep -E "^\.env$"; then + echo "L ERROR: .env file found in repository!" + exit 1 + fi + echo " No .env files found" + + - name: Check for sensitive files + run: | + echo "Checking for sensitive files..." + sensitive_patterns=( + "*.key" + "*.pem" + "*.cert" + "*.p12" + "*.pfx" + "*secret*" + "*credential*" + ) + + found_sensitive=false + for pattern in "${sensitive_patterns[@]}"; do + if git ls-files | grep -i "$pattern"; then + echo " WARNING: Potential sensitive file found: $pattern" + found_sensitive=true + fi + done + + if [ "$found_sensitive" = true ]; then + echo "Please review files above and ensure they're not sensitive" + exit 1 + fi + echo " No sensitive files found" + + - name: Verify .gitignore + run: | + echo "Verifying .gitignore contains .env..." + if ! grep -q "^\.env$" .gitignore; then + echo "L ERROR: .env not found in .gitignore!" + exit 1 + fi + echo " .gitignore is properly configured" + + # ======================================== + # CODE QUALITY & SECURITY + # ======================================== + code-security: + name: Code Security Analysis + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run ESLint Security Plugin + run: | + npm install --save-dev eslint-plugin-security + # Run eslint with security rules (if configured) + # npm run lint:security || true + continue-on-error: true + + - name: Check for hardcoded secrets in code + run: | + echo "Scanning TypeScript files for potential secrets..." + + # Check for potential hardcoded passwords + if grep -r -i "password.*=.*['\"][^'\"]\{8,\}['\"]" src/ --include="*.ts" --include="*.tsx"; then + echo " WARNING: Potential hardcoded password found" + echo "Please use environment variables instead" + fi + + # Check for API keys + if grep -r -E "api[_-]?key.*=.*['\"][^'\"]{20,}['\"]" src/ --include="*.ts" --include="*.tsx"; then + echo " WARNING: Potential hardcoded API key found" + echo "Please use environment variables instead" + fi + + echo " Code scan completed" + + # ======================================== + # DEPENDENCY SECURITY + # ======================================== + dependency-security: + name: Dependency Security Audit + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Run npm audit + run: | + npm audit --audit-level=moderate + continue-on-error: true + + - name: Check for known vulnerabilities + uses: snyk/actions/node@master + continue-on-error: true + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=high + + # ======================================== + # ENVIRONMENT VALIDATION + # ======================================== + env-validation: + name: Environment Configuration Check + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Verify .env.example exists + run: | + if [ ! -f .env.example ]; then + echo "L ERROR: .env.example not found!" + echo "Please create .env.example with safe default values" + exit 1 + fi + echo " .env.example exists" + + - name: Check .env.example for secrets + run: | + echo "Checking .env.example for actual secrets..." + + # .env.example should NOT contain real secrets + if grep -E "(password|key|secret|token)=.{20,}" .env.example; then + echo " WARNING: .env.example may contain real credentials!" + echo "Example files should only have placeholder values" + exit 1 + fi + + echo " .env.example contains no real secrets" + + - name: Validate environment variable usage + run: | + echo "Checking that environment variables are used correctly..." + + # Check AuthContext for proper env var usage + if [ -f "src/contexts/AuthContext.tsx" ]; then + if grep -q "import.meta.env" src/contexts/AuthContext.tsx; then + echo " AuthContext uses environment variables" + else + echo " WARNING: AuthContext may not be using environment variables" + fi + fi + + # ======================================== + # SUMMARY + # ======================================== + security-summary: + name: Security Check Summary + needs: [secret-scan, file-validation, code-security, dependency-security, env-validation] + runs-on: ubuntu-latest + if: always() + + steps: + - name: Security Summary + run: | + echo "======================================" + echo "Security Check Summary" + echo "======================================" + echo "" + echo "Secret Scan: ${{ needs.secret-scan.result }}" + echo "File Validation: ${{ needs.file-validation.result }}" + echo "Code Security: ${{ needs.code-security.result }}" + echo "Dependency Security: ${{ needs.dependency-security.result }}" + echo "Environment Validation: ${{ needs.env-validation.result }}" + echo "" + + if [ "${{ needs.secret-scan.result }}" == "failure" ] || \ + [ "${{ needs.file-validation.result }}" == "failure" ]; then + echo "L CRITICAL: Security issues detected!" + exit 1 + fi + + echo " All critical security checks passed" diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..ca904b4a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,272 @@ +# Security Policy - PezkuwiChain Web Application + +## = Overview + +This document outlines security practices and policies for the PezkuwiChain web application. We take security seriously and encourage responsible disclosure of vulnerabilities. + +--- + +## = Supported Versions + +| Version | Supported | Status | +| ------- | ------------------ | ------ | +| main | Yes | Active Development | +| < 1.0 | Use at own risk | Pre-release | + +--- + +## = Reporting a Vulnerability + +**Please DO NOT report security vulnerabilities through public GitHub issues.** + +Instead, please report them to: **security@pezkuwichain.io** + +You should receive a response within 48 hours. If the issue is confirmed, we will: +1. Acknowledge receipt of your report +2. Provide an estimated timeline for a fix +3. Notify you when the issue is resolved +4. Credit you in our security acknowledgments (if desired) + +--- + +## = Security Best Practices + +### For Developers + +#### 1. Environment Variables +- L **NEVER** commit `.env` files to git +- **ALWAYS** use `.env.example` as a template +- Use environment variables for all sensitive data +- Rotate secrets regularly + +```bash +# BAD - Never do this +git add .env +git commit -m "Add config" + +# GOOD - Use example file +cp .env.example .env +# Then edit .env locally +``` + +#### 2. Credentials Management +- L **NEVER** hardcode passwords, API keys, or secrets +- Use environment variables: `import.meta.env.VITE_API_KEY` +- Use secret management tools (Vault, AWS Secrets Manager) +- Enable demo mode only for development: `VITE_ENABLE_DEMO_MODE=false` in production + +#### 3. Git Hygiene +```bash +# Before committing, check for secrets +git diff + +# Use pre-commit hooks (see .git-hooks/) +git secrets --scan + +# Check git history for leaked secrets +git log --all --full-history --source -- .env +``` + +#### 4. Code Review Checklist +- [ ] No hardcoded credentials +- [ ] Environment variables used correctly +- [ ] No sensitive data in logs +- [ ] Input validation implemented +- [ ] XSS protection in place +- [ ] CSRF tokens used where needed + +--- + +## = Security Measures Implemented + +### 1. Environment Variable Protection +- `.env` is gitignored +- `.gitattributes` prevents merge conflicts +- Example file (`.env.example`) provided with safe defaults + +### 2. Wallet Security +- Polkadot.js extension integration (secure key management) +- No private keys stored in application +- Transaction signing happens in extension +- Message signing with user confirmation + +### 3. Authentication +- Supabase Auth integration +- Demo mode controllable via environment flag +- Session management +- Admin role verification + +### 4. API Security +- WebSocket connections to trusted endpoints only +- RPC call validation +- Rate limiting (TODO: implement) +- Input sanitization + +### 5. Frontend Security +- Content Security Policy (TODO: implement) +- XSS protection via React +- HTTPS only in production +- Secure cookie settings + +--- + +## Known Security Considerations + +### Current State (Development) + +#### = Medium Priority +1. **Demo Mode Credentials** + - Located in `.env` file + - Should be disabled in production: `VITE_ENABLE_DEMO_MODE=false` + - Credentials should be rotated before mainnet launch + +2. **Mock Data** + - Some components still use placeholder data + - See TODO comments in code + - Will be replaced with real blockchain queries + +3. **Endpoint Security** + - WebSocket endpoints are configurable + - Ensure production endpoints use WSS (secure WebSocket) + - Validate SSL certificates + +#### = Low Priority +1. **Transaction Simulation** + - Some swap/staking transactions are simulated + - Marked with TODO comments + - Safe for development, not for production + +--- + +## = Security Checklist Before Production + +### Pre-Launch Requirements + +- [ ] **Environment Variables** + - [ ] All secrets in environment variables + - [ ] Demo mode disabled + - [ ] Founder credentials removed or rotated + - [ ] Production endpoints configured + +- [ ] **Code Audit** + - [ ] No TODO comments with security implications + - [ ] All mock data removed + - [ ] Real blockchain queries implemented + - [ ] Error messages don't leak sensitive info + +- [ ] **Infrastructure** + - [ ] HTTPS/WSS enforced + - [ ] CORS configured properly + - [ ] Rate limiting enabled + - [ ] DDoS protection in place + - [ ] Monitoring and alerting configured + +- [ ] **Testing** + - [ ] Security penetration testing completed + - [ ] Wallet connection tested + - [ ] Transaction signing tested + - [ ] Error handling tested + +- [ ] **Documentation** + - [ ] Security policy updated + - [ ] Deployment guide includes security steps + - [ ] Incident response plan documented + +--- + +## = Deployment Security + +### Production Environment + +```bash +# Production .env example +VITE_NETWORK=mainnet +VITE_ENABLE_DEMO_MODE=false # CRITICAL +VITE_MAINNET_WS=wss://mainnet.pezkuwichain.io +VITE_DEBUG_MODE=false +``` + +### Environment Validation Script + +```typescript +// src/config/validate-env.ts +export function validateProductionEnv() { + if (import.meta.env.PROD) { + // Ensure demo mode is disabled + if (import.meta.env.VITE_ENABLE_DEMO_MODE === 'true') { + throw new Error('Demo mode must be disabled in production!'); + } + + // Ensure secure endpoints + if (!import.meta.env.VITE_MAINNET_WS?.startsWith('wss://')) { + throw new Error('Production must use secure WebSocket (wss://)'); + } + + // Add more checks... + } +} +``` + +--- + +## = Resources + +### Security Tools +- [git-secrets](https://github.com/awslabs/git-secrets) - Prevents committing secrets +- [gitleaks](https://github.com/zricethezav/gitleaks) - Detects hardcoded secrets +- [TruffleHog](https://github.com/trufflesecurity/trufflehog) - Scans for secrets in git history + +### Substrate Security +- [Polkadot Security Best Practices](https://wiki.polkadot.network/docs/learn-security) +- [Substrate Security](https://docs.substrate.io/learn/runtime-development/#security) + +### Web3 Security +- [Smart Contract Security Best Practices](https://consensys.github.io/smart-contract-best-practices/) +- [OWASP Top 10](https://owasp.org/www-project-top-ten/) + +--- + +## < Incident Response + +If a security incident occurs: + +1. **Immediate Actions** + - Assess the scope and impact + - Contain the incident (disable affected features) + - Preserve evidence (logs, screenshots) + +2. **Notification** + - Notify security@pezkuwichain.io + - Inform affected users (if applicable) + - Report to relevant authorities (if required) + +3. **Remediation** + - Apply security patches + - Rotate compromised credentials + - Update security measures + +4. **Post-Incident** + - Conduct root cause analysis + - Update security policies + - Implement preventive measures + +--- + +## Security Acknowledgments + +We thank the following individuals for responsibly disclosing security issues: + +*(List will be updated as vulnerabilities are reported and fixed)* + +--- + +## = Version History + +| Date | Version | Changes | +|------------|---------|----------------------------------| +| 2024-10-28 | 1.0 | Initial security policy created | + +--- + +**Last Updated:** October 28, 2024 +**Contact:** security@pezkuwichain.io diff --git a/src/components/TokenSwap.tsx b/src/components/TokenSwap.tsx index e810a61e..1d00f694 100644 --- a/src/components/TokenSwap.tsx +++ b/src/components/TokenSwap.tsx @@ -1,11 +1,15 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { ArrowDownUp, Settings, Info, TrendingUp, Clock } from 'lucide-react'; import { Card } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { usePolkadot } from '@/contexts/PolkadotContext'; +import { ASSET_IDS, formatBalance } from '@/lib/wallet'; +import { toast } from '@/components/ui/use-toast'; const TokenSwap = () => { + const { api, isApiReady, selectedAccount } = usePolkadot(); const [fromToken, setFromToken] = useState('PEZ'); const [toToken, setToToken] = useState('HEZ'); const [fromAmount, setFromAmount] = useState(''); @@ -14,21 +18,112 @@ const TokenSwap = () => { const [showConfirm, setShowConfirm] = useState(false); const [isSwapping, setIsSwapping] = useState(false); - const exchangeRate = fromToken === 'PEZ' ? 2.5 : 0.4; + // Real balances from blockchain + const [fromBalance, setFromBalance] = useState('0'); + const [toBalance, setToBalance] = useState('0'); + const [exchangeRate, setExchangeRate] = useState(2.5); // Will be fetched from pool + const [isLoadingBalances, setIsLoadingBalances] = useState(false); + const toAmount = fromAmount ? (parseFloat(fromAmount) * exchangeRate).toFixed(4) : ''; + // Fetch balances from blockchain + useEffect(() => { + const fetchBalances = async () => { + if (!api || !isApiReady || !selectedAccount) { + return; + } + + setIsLoadingBalances(true); + try { + const fromAssetId = ASSET_IDS[fromToken as keyof typeof ASSET_IDS]; + const toAssetId = ASSET_IDS[toToken as keyof typeof ASSET_IDS]; + + // Fetch balances from Assets pallet + const [fromAssetBalance, toAssetBalance] = await Promise.all([ + api.query.assets.account(fromAssetId, selectedAccount.address), + api.query.assets.account(toAssetId, selectedAccount.address), + ]); + + // Format balances (12 decimals for PEZ/HEZ tokens) + const fromBal = fromAssetBalance.toJSON() as any; + const toBal = toAssetBalance.toJSON() as any; + + setFromBalance(fromBal ? formatBalance(fromBal.balance.toString(), 12) : '0'); + setToBalance(toBal ? formatBalance(toBal.balance.toString(), 12) : '0'); + } catch (error) { + console.error('Failed to fetch balances:', error); + toast({ + title: 'Error', + description: 'Failed to fetch token balances', + variant: 'destructive', + }); + } finally { + setIsLoadingBalances(false); + } + }; + + fetchBalances(); + }, [api, isApiReady, selectedAccount, fromToken, toToken]); + + // TODO: Fetch exchange rate from DEX pool + // This should query the liquidity pool to get real-time exchange rates + useEffect(() => { + // Placeholder: In real implementation, query pool reserves + // const fetchExchangeRate = async () => { + // if (!api || !isApiReady) return; + // const pool = await api.query.dex.pools([fromAssetId, toAssetId]); + // // Calculate rate from pool reserves + // }; + + // Mock exchange rate for now + const mockRate = fromToken === 'PEZ' ? 2.5 : 0.4; + setExchangeRate(mockRate); + }, [api, isApiReady, fromToken, toToken]); + const handleSwap = () => { setFromToken(toToken); setToToken(fromToken); + setFromAmount(''); }; - const handleConfirmSwap = () => { + const handleConfirmSwap = async () => { + if (!api || !selectedAccount) { + toast({ + title: 'Error', + description: 'Please connect your wallet', + variant: 'destructive', + }); + return; + } + setIsSwapping(true); - setTimeout(() => { - setIsSwapping(false); + try { + // TODO: Implement actual swap transaction + // const fromAssetId = ASSET_IDS[fromToken]; + // const toAssetId = ASSET_IDS[toToken]; + // const amount = parseAmount(fromAmount, 12); + // await api.tx.dex.swap(fromAssetId, toAssetId, amount, minReceive).signAndSend(...); + + // Simulated swap for now + await new Promise(resolve => setTimeout(resolve, 2000)); + + toast({ + title: 'Success', + description: `Swapped ${fromAmount} ${fromToken} for ${toAmount} ${toToken}`, + }); + setShowConfirm(false); setFromAmount(''); - }, 2000); + } catch (error: any) { + console.error('Swap failed:', error); + toast({ + title: 'Error', + description: error.message || 'Swap transaction failed', + variant: 'destructive', + }); + } finally { + setIsSwapping(false); + } }; const liquidityData = [ @@ -58,7 +153,9 @@ const TokenSwap = () => {