#!/usr/bin/env node /** * Generate a service wallet (secp256k1 key pair) for website-skeleton. * Creates .env file with VITE_SKELETON_SERVICE_PUBLIC_KEY and .env.private with private key. */ import { getPublicKey, utils as secpUtils } from '@noble/secp256k1'; import { bytesToHex } from '@noble/hashes/utils'; import { writeFileSync, existsSync } from 'fs'; import { join } from 'path'; import { webcrypto } from 'crypto'; // Set up crypto for @noble/secp256k1 in Node.js if (typeof globalThis.crypto === 'undefined') { globalThis.crypto = webcrypto; } // Generate key pair const privateKeyBytes = secpUtils.randomSecretKey(); const publicKeyBytes = getPublicKey(privateKeyBytes, true); // compressed const privateKey = bytesToHex(privateKeyBytes); const publicKey = bytesToHex(publicKeyBytes); // Verify format if (publicKey.length !== 66 || (!publicKey.startsWith('02') && !publicKey.startsWith('03'))) { throw new Error(`Invalid public key format: ${publicKey}`); } if (privateKey.length !== 64) { throw new Error(`Invalid private key format: ${privateKey}`); } // Paths const envPath = join(process.cwd(), '.env'); const envPrivatePath = join(process.cwd(), '.env.private'); // Check if .env already exists if (existsSync(envPath)) { console.warn('⚠️ .env already exists. Backing up to .env.backup'); const { readFileSync } = await import('fs'); const backup = readFileSync(envPath, 'utf-8'); writeFileSync(join(process.cwd(), '.env.backup'), backup); } // Write .env with public key const envContent = `# Service wallet public key for website-skeleton # Generated on ${new Date().toISOString()} # Service UUID: skeleton-service-uuid-4nkweb-2026 VITE_SKELETON_SERVICE_PUBLIC_KEY=${publicKey} `; writeFileSync(envPath, envContent, { mode: 0o600 }); // Write .env.private with private key (more restrictive permissions) const envPrivateContent = `# Service wallet private key for website-skeleton # ⚠️ SECRET: Keep this file secure and never commit it to version control # Generated on ${new Date().toISOString()} # Service UUID: skeleton-service-uuid-4nkweb-2026 # # This private key is used to sign service operations. # Store it securely and never share it. SKELETON_SERVICE_PRIVATE_KEY=${privateKey} `; writeFileSync(envPrivatePath, envPrivateContent, { mode: 0o400 }); console.log('✅ Service wallet generated successfully!'); console.log(''); console.log('📁 Files created:'); console.log(` - .env (public key, mode 600)`); console.log(` - .env.private (private key, mode 400)`); console.log(''); console.log('🔑 Public key (for VITE_SKELETON_SERVICE_PUBLIC_KEY):'); console.log(` ${publicKey}`); console.log(''); console.log('🔐 Private key (stored in .env.private):'); console.log(` ${privateKey}`); console.log(''); console.log('⚠️ Security notes:'); console.log(' - .env.private contains the private key - keep it secure'); console.log(' - Add .env.private to .gitignore if not already present'); console.log(' - The public key in .env is safe to commit'); console.log(' - Never share the private key');