UNPKG

minimal-xec-wallet

Version:

A minimalist eCash (XEC) wallet npm library, for use in web apps. Supports eTokens.

218 lines (180 loc) • 8.07 kB
/* Send XEC to multiple recipients in a single transaction. This example shows how to create a transaction with multiple outputs. */ const MinimalXECWallet = require('../../index') const WalletHelper = require('../utils/wallet-helper') // Get command line arguments const args = process.argv.slice(2) function showUsage () { console.log('Usage: node send-to-multiple.js <address1> <amount1> <address2> <amount2> [...]') console.log('') console.log('Examples:') console.log(' node send-to-multiple.js ecash:qp1234...abc 50 ecash:qr5678...def 30') console.log(' node send-to-multiple.js ecash:qa1111...111 100 ecash:qb2222...222 25.5 ecash:qc3333...333 75') console.log('') console.log('Parameters:') console.log(' addressN: XEC address starting with ecash:') console.log(' amountN: Amount in XEC (minimum 5.46 XEC per output due to dust limit)') console.log('') console.log('Note: You can send to up to 100 recipients in a single transaction') console.log(' Transaction fee will be automatically calculated and deducted') } function parseRecipients (args) { if (args.length < 4 || args.length % 2 !== 0) { return null } const recipients = [] for (let i = 0; i < args.length; i += 2) { const address = args[i] const amount = parseFloat(args[i + 1]) if (!address || !address.startsWith('ecash:')) { console.log(`āŒ Invalid address at position ${i + 1}: ${address}`) return null } if (isNaN(amount) || amount <= 0) { console.log(`āŒ Invalid amount at position ${i + 2}: ${args[i + 1]}`) return null } if (amount < 5.46) { console.log(`āŒ Amount too small at position ${i + 2}: ${amount} XEC (minimum 5.46 XEC due to dust limit)`) return null } recipients.push({ address, amount }) } return recipients } async function sendToMultiple () { try { console.log('šŸ“¤ Sending XEC to multiple recipients...\n') // Check arguments if (args.length < 4) { console.log('āŒ Not enough arguments') showUsage() return } // Parse recipients const recipients = parseRecipients(args) if (!recipients) { showUsage() return } // Load wallet from file const walletData = WalletHelper.loadWallet() if (!walletData) { console.log(' Run: node examples/wallet-creation/create-new-wallet.js') return } // Create wallet instance from saved data const wallet = new MinimalXECWallet(walletData.mnemonic || walletData.privateKey) await wallet.walletInfoPromise // Initialize wallet await wallet.initialize() console.log('šŸ’° Checking wallet balance...') const balance = await wallet.getXecBalance() // Calculate total amount to send const totalAmount = recipients.reduce((sum, recipient) => sum + recipient.amount, 0) console.log('\nšŸ“‹ Multi-Output Transaction Details:') console.log('═'.repeat(70)) console.log(`From: ${walletData.xecAddress}`) console.log(`Recipients: ${recipients.length}`) console.log(`Total Amount: ${totalAmount.toLocaleString()} XEC`) console.log(`Current Balance: ${balance.toLocaleString()} XEC`) console.log('═'.repeat(70)) // Show all recipients console.log('\nšŸ“Ø Recipients:') recipients.forEach((recipient, index) => { const addressShort = `${recipient.address.substring(0, 20)}...${recipient.address.substring(recipient.address.length - 8)}` console.log(`${index + 1}. ${addressShort}: ${recipient.amount.toLocaleString()} XEC`) }) // Check if we have enough balance (rough estimate) const estimatedFee = recipients.length * 0.01 // Rough estimate: 0.01 XEC per output if (balance < totalAmount + estimatedFee) { console.log('\nāŒ Insufficient balance!') console.log(` Required: ~${(totalAmount + estimatedFee).toLocaleString()} XEC (including estimated fee)`) console.log(` Available: ${balance.toLocaleString()} XEC`) console.log(' Fund your wallet or reduce the amounts') return } // Confirm transaction console.log('\nāš ļø Transaction Confirmation Required') console.log(' This will send real XEC from your wallet!') console.log(' Make sure all recipient addresses are correct.') console.log(` Total recipients: ${recipients.length}`) console.log(` Total amount: ${totalAmount.toLocaleString()} XEC`) const readline = require('readline') const rl = readline.createInterface({ input: process.stdin, output: process.stdout }) const confirmed = await new Promise((resolve) => { rl.question('\nDo you want to proceed? (yes/no): ', (answer) => { rl.close() resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y') }) }) if (!confirmed) { console.log('āŒ Transaction cancelled by user') return } console.log('\nšŸš€ Broadcasting multi-output transaction...') // Prepare the outputs const outputs = recipients.map(recipient => ({ address: recipient.address, amountSat: Math.round(recipient.amount * 100) // Convert XEC to satoshis })) // Send the transaction const txid = await wallet.sendXec(outputs) console.log('\nāœ… Multi-output transaction sent successfully!') console.log('═'.repeat(70)) console.log(`Transaction ID: ${txid}`) console.log(`Recipients: ${recipients.length}`) console.log(`Total Amount: ${totalAmount.toLocaleString()} XEC`) console.log('═'.repeat(70)) // Get updated balance console.log('\nšŸ’° Getting updated balance...') const newBalance = await wallet.getXecBalance() const totalCost = balance - newBalance const feePaid = totalCost - totalAmount console.log('\nšŸ“Š Transaction Summary:') console.log(`Previous Balance: ${balance.toLocaleString()} XEC`) console.log(`Total Sent: ${totalAmount.toLocaleString()} XEC`) console.log(`Fee Paid: ${feePaid.toLocaleString()} XEC`) console.log(`Total Cost: ${totalCost.toLocaleString()} XEC`) console.log(`New Balance: ${newBalance.toLocaleString()} XEC`) console.log('\nšŸ“Ø Delivery Summary:') recipients.forEach((recipient, index) => { const addressShort = `${recipient.address.substring(0, 15)}...${recipient.address.substring(recipient.address.length - 6)}` console.log(`${index + 1}. ${addressShort}: ${recipient.amount.toLocaleString()} XEC āœ…`) }) console.log('\nšŸ”— View Transaction:') console.log(` Explorer: https://explorer.e.cash/tx/${txid}`) console.log(' Note: It may take a few minutes to appear in the explorer') console.log('\nšŸ’” Benefits of Multi-Output Transactions:') console.log(' • Lower total fees compared to separate transactions') console.log(' • Single confirmation for all recipients') console.log(' • More efficient use of blockchain space') } catch (err) { console.error('āŒ Failed to send multi-output transaction:', err.message) // Provide helpful error context if (err.message.includes('insufficient')) { console.log('\nšŸ’ø Insufficient Funds:') console.log(' • Your wallet does not have enough XEC for this transaction') console.log(' • Multi-output transactions require higher fees') console.log(' • Try reducing amounts or number of recipients') } else if (err.message.includes('address')) { console.log('\nšŸ“ Address Error:') console.log(' • Check that all recipient addresses are valid') console.log(' • Make sure they all start with "ecash:"') console.log(' • Verify addresses with recipients') } else if (err.message.includes('network')) { console.log('\n🌐 Network Error:') console.log(' • Check your internet connection') console.log(' • The network might be temporarily unavailable') console.log(' • Try again in a few moments') } process.exit(1) } } // Run the example sendToMultiple()