@five-vm/cli
Version:
High-performance CLI for Five VM development with WebAssembly integration
114 lines • 5.09 kB
JavaScript
/**
* 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