UNPKG

@five-vm/cli

Version:

High-performance CLI for Five VM development with WebAssembly integration

114 lines 5.09 kB
/** * Five CLI Donate Command * * Sends SOL to the Five VM donation address. */ import chalk from 'chalk'; import ora from 'ora'; import { readFile } from 'fs/promises'; import { homedir } from 'os'; import { join } from 'path'; import { Connection, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Keypair, sendAndConfirmTransaction, Transaction, } from '@solana/web3.js'; const DONATION_ADDRESS = '2A3mhuakqQMCaY3ZeeqyLZP2jmxcS478Jnfd6ZerBaFm'; function getDefaultKeypairPath() { return join(homedir(), '.config', 'solana', 'id.json'); } function getRpcUrl(network, custom) { if (custom) return custom; switch ((network || '').toLowerCase()) { case 'mainnet': case 'mainnet-beta': return 'https://api.mainnet-beta.solana.com'; case 'testnet': return 'https://api.testnet.solana.com'; case 'devnet': default: return 'https://api.devnet.solana.com'; } } async function loadKeypair(path) { const raw = await readFile(path, 'utf8'); // Standard solana-keygen JSON array format const secret = Uint8Array.from(JSON.parse(raw)); return Keypair.fromSecretKey(secret); } export const donateCommand = { name: 'donate', description: 'Donate SOL to support Five VM development', aliases: [], options: [ { flags: '--network <network>', description: 'Solana network (devnet|testnet|mainnet)', defaultValue: 'devnet', }, { flags: '--rpc <url>', description: 'Custom RPC URL (overrides --network)', required: false, }, { flags: '--keypair <path>', description: 'Path to keypair JSON (default: ~/.config/solana/id.json)', required: false, }, ], arguments: [ { name: 'amount', description: 'Amount in whole SOL (integer)', required: true, }, ], examples: [ { command: 'five donate 1', description: 'Donate 1 SOL on devnet' }, { command: 'five donate 2 --network mainnet', description: 'Donate 2 SOL on mainnet' }, { command: 'five donate 1 --rpc https://... --keypair ~/.config/solana/id.json', description: 'Use custom RPC and keypair' }, ], handler: async (args, options, _context) => { const spinner = ora('Preparing donation...').start(); try { const amountStr = args[0]; if (!amountStr) throw new Error('Amount (whole SOL) is required'); const amountSol = parseInt(String(amountStr), 10); if (!Number.isFinite(amountSol) || amountSol <= 0) { throw new Error(`Invalid amount: ${amountStr}. Provide a positive integer number of SOL.`); } const lamports = BigInt(amountSol) * BigInt(LAMPORTS_PER_SOL); const keypairPath = options.keypair || process.env.SOLANA_KEYPAIR || getDefaultKeypairPath(); const payer = await loadKeypair(keypairPath); const rpcUrl = getRpcUrl(options.network, options.rpc); const connection = new Connection(rpcUrl, 'confirmed'); const toPubkey = new PublicKey(DONATION_ADDRESS); spinner.text = 'Building transaction...'; const ix = SystemProgram.transfer({ fromPubkey: payer.publicKey, toPubkey, lamports: Number(lamports) }); const tx = new Transaction().add(ix); spinner.text = 'Sending donation transaction...'; const signature = await sendAndConfirmTransaction(connection, tx, [payer], { commitment: 'confirmed', skipPreflight: false, }); spinner.succeed(chalk.green('Donation sent!')); const border = chalk.magenta('══════════════════════════════════════════════════════════════'); const title = chalk.bgMagenta.white.bold(' THANK YOU FOR SUPPORTING FIVE VM '); const tagline = chalk.yellow('“Husband and dad of 3 just trying to build cool shit. help me today and I help you tomorrow!”'); console.log('\n' + border); console.log(' ' + title); console.log(' ' + tagline); console.log(border + '\n'); console.log(`${chalk.bold.white('Amount:')} ${chalk.yellowBright(amountSol.toString())} ${chalk.yellowBright('SOL')}`); console.log(`${chalk.bold.white('To: ')} ${chalk.magentaBright(DONATION_ADDRESS)}`); console.log(`${chalk.bold.white('Tx: ')} ${chalk.cyanBright(signature)}`); console.log('\n' + chalk.greenBright('Your support helps us ship faster. You rock!') + '\n'); } catch (err) { spinner.fail('Donation failed'); console.error(chalk.red(err?.message || String(err))); throw err; } }, }; export default donateCommand; //# sourceMappingURL=donate.js.map