Monorepo for Aesthetic.Computer aesthetic.computer
at main 125 lines 4.6 kB view raw
1#!/usr/bin/env node 2 3/** 4 * Simple XTZ transfer between wallets 5 * Usage: node transfer.mjs <from-wallet> <to-address> <amount-in-xtz> 6 */ 7 8import { TezosToolkit } from '@taquito/taquito'; 9import { InMemorySigner } from '@taquito/signer'; 10import fs from 'fs'; 11import path from 'path'; 12import { fileURLToPath } from 'url'; 13 14const __filename = fileURLToPath(import.meta.url); 15const __dirname = path.dirname(__filename); 16 17const CONFIG = { 18 mainnet: { 19 name: 'Mainnet', 20 rpc: 'https://mainnet.api.tez.ie', 21 explorer: 'https://tzkt.io' 22 }, 23 ghostnet: { 24 name: 'Ghostnet (Testnet)', 25 rpc: 'https://ghostnet.ecadinfra.com', 26 explorer: 'https://ghostnet.tzkt.io' 27 } 28}; 29 30function loadCredentials(wallet) { 31 const walletPaths = { 32 kidlisp: { path: 'kidlisp/.env', addressKey: 'KIDLISP_ADDRESS', secretKey: 'KIDLISP_KEY' }, 33 aesthetic: { path: 'kidlisp/.env', addressKey: 'AESTHETIC_ADDRESS', secretKey: 'AESTHETIC_KEY' }, 34 staging: { path: 'staging/.env', addressKey: 'STAGING_ADDRESS', secretKey: 'STAGING_KEY' } 35 }; 36 37 const walletConfig = walletPaths[wallet]; 38 if (!walletConfig) { 39 throw new Error(`Unknown wallet: ${wallet}. Use: kidlisp, aesthetic, or staging`); 40 } 41 42 const envPath = path.join(__dirname, walletConfig.path); 43 if (!fs.existsSync(envPath)) { 44 throw new Error(`Wallet credentials not found: ${envPath}`); 45 } 46 47 const credentials = {}; 48 const content = fs.readFileSync(envPath, 'utf8'); 49 for (const line of content.split('\n')) { 50 if (line.startsWith(walletConfig.addressKey + '=') || line.startsWith('ADDRESS=')) { 51 credentials.address = line.split('=')[1].trim().replace(/"/g, ''); 52 } else if (line.startsWith(walletConfig.secretKey + '=') || line.startsWith('KEY=') || line.startsWith('SECRET_KEY=')) { 53 credentials.secretKey = line.split('=')[1].trim().replace(/"/g, ''); 54 } 55 } 56 57 if (!credentials.address || !credentials.secretKey) { 58 throw new Error(`Invalid credentials in ${envPath}`); 59 } 60 61 return credentials; 62} 63 64async function transfer(fromWallet, toAddress, amountXTZ, network = 'mainnet') { 65 console.log('\n╔══════════════════════════════════════════════════════════════╗'); 66 console.log('║ 💸 XTZ Transfer ║'); 67 console.log('╚══════════════════════════════════════════════════════════════╝\n'); 68 69 const credentials = loadCredentials(fromWallet); 70 const config = CONFIG[network]; 71 const tezos = new TezosToolkit(config.rpc); 72 tezos.setProvider({ signer: new InMemorySigner(credentials.secretKey) }); 73 74 console.log(`📡 Network: ${config.name}`); 75 console.log(`👤 From: ${credentials.address} (${fromWallet})`); 76 console.log(`📥 To: ${toAddress}`); 77 console.log(`💰 Amount: ${amountXTZ} XTZ\n`); 78 79 // Check balance 80 console.log('💰 Checking balance...'); 81 const balance = await tezos.tz.getBalance(credentials.address); 82 const balanceXTZ = balance.toNumber() / 1_000_000; 83 console.log(` Current balance: ${balanceXTZ.toFixed(6)} XTZ`); 84 85 if (balanceXTZ < amountXTZ) { 86 throw new Error(`Insufficient balance. Have ${balanceXTZ.toFixed(6)} XTZ, need ${amountXTZ} XTZ`); 87 } 88 89 // Send transfer 90 console.log('\n📤 Sending transfer...'); 91 const op = await tezos.contract.transfer({ 92 to: toAddress, 93 amount: amountXTZ 94 }); 95 96 console.log(` ⏳ Operation hash: ${op.hash}`); 97 console.log(' ⏳ Waiting for confirmation...'); 98 99 await op.confirmation(1); 100 101 console.log('\n✅ Transfer completed!'); 102 console.log(` 🔗 Explorer: ${config.explorer}/${op.hash}\n`); 103 104 // Check new balance 105 const newBalance = await tezos.tz.getBalance(credentials.address); 106 const newBalanceXTZ = newBalance.toNumber() / 1_000_000; 107 console.log(` New balance: ${newBalanceXTZ.toFixed(6)} XTZ\n`); 108} 109 110// Parse CLI args 111const args = process.argv.slice(2); 112if (args.length < 3) { 113 console.error('Usage: node transfer.mjs <from-wallet> <to-address> <amount-in-xtz> [network]'); 114 console.error('Example: node transfer.mjs aesthetic tz1dfoQDuxjwSgxdqJnisyKUxDHweade4Gzt 1.0 mainnet'); 115 process.exit(1); 116} 117 118const [fromWallet, toAddress, amountStr, network = 'mainnet'] = args; 119const amount = parseFloat(amountStr); 120 121transfer(fromWallet, toAddress, amount, network).catch(err => { 122 console.error('\n❌ Transfer failed!'); 123 console.error(` Error: ${err.message}\n`); 124 process.exit(1); 125});