minimal-xec-wallet 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/minimal-xec-wallet.js +66268 -0
  4. package/dist/minimal-xec-wallet.min.js +55 -0
  5. package/examples/README.md +380 -0
  6. package/examples/advanced/browser-compatibility-test.js +263 -0
  7. package/examples/advanced/get-xec-price.js +149 -0
  8. package/examples/advanced/optimize-utxos.js +255 -0
  9. package/examples/advanced/send-op-return.js +216 -0
  10. package/examples/browser-test.html +350 -0
  11. package/examples/key-management/derive-addresses.js +191 -0
  12. package/examples/key-management/export-to-wif.js +114 -0
  13. package/examples/key-management/validate-address.js +214 -0
  14. package/examples/optimization/simple-consolidation-test.js +79 -0
  15. package/examples/optimization/test-utxo-consolidation.js +179 -0
  16. package/examples/test-examples.js +1204 -0
  17. package/examples/tokens/burn-tokens.js +293 -0
  18. package/examples/tokens/get-token-balance.js +169 -0
  19. package/examples/tokens/get-token-info.js +269 -0
  20. package/examples/tokens/list-all-tokens.js +162 -0
  21. package/examples/tokens/send-any-token.js +260 -0
  22. package/examples/tokens/test-main-wallet-integration.js +193 -0
  23. package/examples/transactions/send-all-xec.js +205 -0
  24. package/examples/transactions/send-to-multiple.js +217 -0
  25. package/examples/transactions/send-xec.js +191 -0
  26. package/examples/utils/show-qr.js +119 -0
  27. package/examples/utils/wallet-helper.js +176 -0
  28. package/examples/validation/comprehensive-infrastructure-test.js +210 -0
  29. package/examples/wallet-creation/create-new-wallet.js +67 -0
  30. package/examples/wallet-creation/import-from-wif.js +135 -0
  31. package/examples/wallet-creation/restore-from-mnemonic.js +100 -0
  32. package/examples/wallet-info/get-balance.js +99 -0
  33. package/examples/wallet-info/get-transactions.js +157 -0
  34. package/examples/wallet-info/get-utxos.js +145 -0
  35. package/examples/wallet.json +11 -0
  36. package/lib/adapters/robust-chronik-router.js +507 -0
  37. package/lib/adapters/router.js +651 -0
  38. package/lib/alp-token-handler.js +581 -0
  39. package/lib/browser-wasm-loader.js +271 -0
  40. package/lib/consolidate-utxos.js +338 -0
  41. package/lib/hybrid-token-manager.js +322 -0
  42. package/lib/key-derivation.js +466 -0
  43. package/lib/op-return.js +314 -0
  44. package/lib/security.js +270 -0
  45. package/lib/send-xec.js +396 -0
  46. package/lib/slp-token-handler.js +572 -0
  47. package/lib/token-protocol-detector.js +307 -0
  48. package/lib/utxos.js +303 -0
  49. package/package.json +125 -0
@@ -0,0 +1,149 @@
1
+ /*
2
+ Get the current XEC to USD exchange rate.
3
+ This example shows how to fetch pricing information for XEC.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ async function getXecPrice () {
10
+ try {
11
+ console.log('šŸ’± Getting XEC price information...\n')
12
+
13
+ // Load wallet from file (optional - just for consistency)
14
+ const walletData = WalletHelper.loadWallet()
15
+
16
+ // Create wallet instance (we don't need wallet data for price queries)
17
+ const wallet = new MinimalXECWallet()
18
+ await wallet.walletInfoPromise
19
+
20
+ console.log('šŸ” Fetching XEC price from exchange APIs...')
21
+
22
+ try {
23
+ // Get XEC/USD price
24
+ const xecUsdPrice = await wallet.getXecUsd()
25
+
26
+ console.log('\nšŸ’° XEC Price Information:')
27
+ console.log('═'.repeat(50))
28
+ console.log(`XEC/USD: $${xecUsdPrice.toFixed(8)}`)
29
+ console.log(`1 USD: ${(1 / xecUsdPrice).toLocaleString()} XEC`)
30
+ console.log('═'.repeat(50))
31
+
32
+ // Calculate various amounts in USD
33
+ const commonAmounts = [100, 1000, 10000, 100000, 1000000]
34
+
35
+ console.log('\nšŸ“Š XEC to USD Conversion Table:')
36
+ console.log('─'.repeat(50))
37
+ console.log('XEC Amount USD Value')
38
+ console.log('─'.repeat(50))
39
+
40
+ commonAmounts.forEach(xecAmount => {
41
+ const usdValue = xecAmount * xecUsdPrice
42
+ const xecFormatted = xecAmount.toLocaleString().padEnd(15)
43
+ const usdFormatted = `$${usdValue.toFixed(6)}`
44
+ console.log(`${xecFormatted} ${usdFormatted}`)
45
+ })
46
+
47
+ // Show wallet value if wallet exists
48
+ if (walletData) {
49
+ console.log('\nšŸ¦ Your Wallet Value:')
50
+ console.log('─'.repeat(50))
51
+
52
+ try {
53
+ const walletForPrice = new MinimalXECWallet(walletData.mnemonic || walletData.privateKey)
54
+ await walletForPrice.walletInfoPromise
55
+
56
+ const balance = await walletForPrice.getXecBalance()
57
+ const walletUsdValue = balance * xecUsdPrice
58
+
59
+ console.log(`XEC Balance: ${balance.toLocaleString()} XEC`)
60
+ console.log(`USD Value: $${walletUsdValue.toFixed(6)} USD`)
61
+
62
+ if (walletUsdValue > 0) {
63
+ console.log('\nšŸ’” Value Breakdown:')
64
+ console.log(`• Your ${balance.toLocaleString()} XEC is worth $${walletUsdValue.toFixed(6)}`)
65
+ console.log(`• At current rate of $${xecUsdPrice.toFixed(8)} per XEC`)
66
+ }
67
+ } catch (err) {
68
+ console.log('(Unable to fetch wallet balance for price calculation)')
69
+ }
70
+ }
71
+
72
+ // Market insights
73
+ console.log('\nšŸ“ˆ Market Insights:')
74
+ console.log('─'.repeat(50))
75
+
76
+ // Calculate market cap implications (approximate)
77
+ const totalSupply = 21000000000000 // 21 trillion XEC (approximate)
78
+ const marketCap = totalSupply * xecUsdPrice
79
+
80
+ console.log(`Estimated Market Cap: $${(marketCap / 1000000).toFixed(2)}M USD`)
81
+ console.log(`Price per Million XEC: $${(xecUsdPrice * 1000000).toFixed(2)}`)
82
+ console.log(`Price per Billion XEC: $${(xecUsdPrice * 1000000000).toFixed(2)}`)
83
+
84
+ // Historical context note
85
+ console.log('\nšŸ“ Price Notes:')
86
+ console.log('• XEC prices are highly volatile')
87
+ console.log('• This is real-time data from available APIs')
88
+ console.log('• Prices may vary between exchanges')
89
+ console.log('• Use for informational purposes only')
90
+ console.log('• Not financial advice')
91
+
92
+ // Exchange information
93
+ console.log('\nšŸŖ Where to Trade XEC:')
94
+ console.log('• Binance (XEC/USDT, XEC/BTC)')
95
+ console.log('• KuCoin (XEC/USDT)')
96
+ console.log('• Gate.io (XEC/USDT)')
97
+ console.log('• OKX (XEC/USDT)')
98
+ console.log('• Bitfinex (XEC/USD)')
99
+ console.log('• Check CoinGecko/CoinMarketCap for full list')
100
+ } catch (priceErr) {
101
+ console.log('\nāŒ Price API Error:', priceErr.message)
102
+ console.log('\nšŸ’” Price API Issues:')
103
+ console.log(' • Price APIs may be temporarily unavailable')
104
+ console.log(' • Network connectivity issues')
105
+ console.log(' • API rate limiting')
106
+ console.log('')
107
+ console.log(' Alternative price sources:')
108
+ console.log(' • CoinGecko: https://coingecko.com/en/coins/ecash')
109
+ console.log(' • CoinMarketCap: https://coinmarketcap.com/currencies/ecash/')
110
+ console.log(' • Exchange websites directly')
111
+ }
112
+
113
+ // Additional resources
114
+ console.log('\nšŸ”— Useful Resources:')
115
+ console.log('• eCash Website: https://e.cash')
116
+ console.log('• Price Charts: https://coinmarketcap.com/currencies/ecash/')
117
+ console.log('• Market Data: https://coingecko.com/en/coins/ecash')
118
+ console.log('• Exchange List: https://coinmarketcap.com/currencies/ecash/markets/')
119
+
120
+ console.log('\nšŸ“± Mobile Apps:')
121
+ console.log('• CoinMarketCap app')
122
+ console.log('• CoinGecko app')
123
+ console.log('• Exchange apps (Binance, KuCoin, etc.)')
124
+ } catch (err) {
125
+ console.error('āŒ Failed to get XEC price:', err.message)
126
+
127
+ // Provide helpful error context
128
+ if (err.message.includes('network') || err.message.includes('connection')) {
129
+ console.log('\n🌐 Network Error:')
130
+ console.log(' • Check your internet connection')
131
+ console.log(' • Price APIs might be temporarily unavailable')
132
+ console.log(' • Try again in a few moments')
133
+ console.log('')
134
+ console.log(' Manual price check:')
135
+ console.log(' • Visit https://coinmarketcap.com/currencies/ecash/')
136
+ console.log(' • Or https://coingecko.com/en/coins/ecash')
137
+ } else if (err.message.includes('api') || err.message.includes('rate')) {
138
+ console.log('\n🚫 API Error:')
139
+ console.log(' • Price API might be rate-limited')
140
+ console.log(' • API service might be down')
141
+ console.log(' • Try alternative price sources')
142
+ }
143
+
144
+ process.exit(1)
145
+ }
146
+ }
147
+
148
+ // Run the example
149
+ getXecPrice()
@@ -0,0 +1,255 @@
1
+ /*
2
+ Optimize wallet UTXOs by consolidating them.
3
+ This example shows how to reduce the number of UTXOs to lower future transaction fees.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ // Get command line arguments
10
+ const args = process.argv.slice(2)
11
+ const dryRun = args.includes('--dry-run') || args.includes('-n')
12
+
13
+ function showUsage () {
14
+ console.log('Usage: node optimize-utxos.js [--dry-run]')
15
+ console.log('')
16
+ console.log('Options:')
17
+ console.log(' --dry-run, -n Show optimization plan without executing')
18
+ console.log('')
19
+ console.log('Examples:')
20
+ console.log(' node optimize-utxos.js --dry-run # Preview optimization')
21
+ console.log(' node optimize-utxos.js # Execute optimization')
22
+ console.log('')
23
+ console.log('Purpose:')
24
+ console.log(' • Consolidates multiple small UTXOs into fewer larger ones')
25
+ console.log(' • Reduces future transaction fees')
26
+ console.log(' • Improves wallet performance')
27
+ console.log(' • Cleans up "dust" outputs')
28
+ }
29
+
30
+ async function analyzeUtxos (wallet) {
31
+ console.log('šŸ” Analyzing wallet UTXOs...')
32
+
33
+ const utxoData = await wallet.getUtxos()
34
+ const utxos = utxoData.utxos || []
35
+ const spendableUtxos = utxos.filter(utxo => utxo.blockHeight !== -1)
36
+
37
+ if (spendableUtxos.length === 0) {
38
+ console.log('\nšŸ’ø No spendable UTXOs found!')
39
+ console.log(' Your wallet has no confirmed UTXOs to optimize.')
40
+ return null
41
+ }
42
+
43
+ // Calculate statistics
44
+ const totalValue = spendableUtxos.reduce((sum, utxo) => sum + utxo.value, 0)
45
+ const averageValue = totalValue / spendableUtxos.length
46
+ const values = spendableUtxos.map(utxo => utxo.value).sort((a, b) => a - b)
47
+ const medianValue = values[Math.floor(values.length / 2)]
48
+
49
+ // Categorize UTXOs
50
+ const dustUtxos = spendableUtxos.filter(utxo => utxo.value < 546) // < 5.46 XEC
51
+ const smallUtxos = spendableUtxos.filter(utxo => utxo.value >= 546 && utxo.value < 10000) // 5.46 - 100 XEC
52
+ const mediumUtxos = spendableUtxos.filter(utxo => utxo.value >= 10000 && utxo.value < 100000) // 100 - 1000 XEC
53
+ const largeUtxos = spendableUtxos.filter(utxo => utxo.value >= 100000) // > 1000 XEC
54
+
55
+ console.log('\nšŸ“Š UTXO Analysis:')
56
+ console.log('═'.repeat(60))
57
+ console.log(`Total UTXOs: ${spendableUtxos.length}`)
58
+ console.log(`Total Value: ${(totalValue / 100).toLocaleString()} XEC`)
59
+ console.log(`Average Size: ${(averageValue / 100).toLocaleString()} XEC`)
60
+ console.log(`Median Size: ${(medianValue / 100).toLocaleString()} XEC`)
61
+ console.log('═'.repeat(60))
62
+
63
+ console.log('\nšŸ·ļø UTXO Categories:')
64
+ console.log(`Dust (< 5.46 XEC): ${dustUtxos.length} UTXOs`)
65
+ console.log(`Small (5.46 - 100 XEC): ${smallUtxos.length} UTXOs`)
66
+ console.log(`Medium (100 - 1000 XEC): ${mediumUtxos.length} UTXOs`)
67
+ console.log(`Large (> 1000 XEC): ${largeUtxos.length} UTXOs`)
68
+
69
+ // Calculate potential fee savings
70
+ const currentTxCost = spendableUtxos.length * 150 * 1.2 / 100 // 150 bytes per input * 1.2 sat/byte
71
+ const optimizedTxCost = Math.min(spendableUtxos.length, 5) * 150 * 1.2 / 100 // Assume max 5 UTXOs after optimization
72
+ const potentialSavings = currentTxCost - optimizedTxCost
73
+
74
+ console.log('\nšŸ’° Fee Impact Analysis:')
75
+ console.log(`Current TX cost estimate: ${currentTxCost.toFixed(4)} XEC`)
76
+ console.log(`Optimized TX cost estimate: ${optimizedTxCost.toFixed(4)} XEC`)
77
+ console.log(`Potential savings per TX: ${potentialSavings.toFixed(4)} XEC`)
78
+
79
+ return {
80
+ total: spendableUtxos.length,
81
+ dust: dustUtxos.length,
82
+ small: smallUtxos.length,
83
+ medium: mediumUtxos.length,
84
+ large: largeUtxos.length,
85
+ totalValue,
86
+ needsOptimization: spendableUtxos.length > 10 || dustUtxos.length > 0
87
+ }
88
+ }
89
+
90
+ async function optimizeUtxos () {
91
+ try {
92
+ console.log('⚔ UTXO Optimization Tool\n')
93
+
94
+ if (dryRun) {
95
+ console.log('šŸ” DRY RUN MODE - No transactions will be sent\n')
96
+ }
97
+
98
+ // Load wallet from file
99
+ const walletData = WalletHelper.loadWallet()
100
+ if (!walletData) {
101
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
102
+ return
103
+ }
104
+
105
+ // Create wallet instance from saved data
106
+ const wallet = new MinimalXECWallet(walletData.mnemonic || walletData.privateKey)
107
+ await wallet.walletInfoPromise
108
+
109
+ // Initialize wallet
110
+ await wallet.initialize()
111
+
112
+ console.log('šŸ’° Checking wallet balance...')
113
+ const balance = await wallet.getXecBalance()
114
+
115
+ console.log('\nšŸ“‹ Wallet Information:')
116
+ console.log('═'.repeat(60))
117
+ console.log(`Address: ${walletData.xecAddress}`)
118
+ console.log(`Balance: ${balance.toLocaleString()} XEC`)
119
+ console.log('═'.repeat(60))
120
+
121
+ // Analyze current UTXO state
122
+ const analysis = await analyzeUtxos(wallet)
123
+ if (!analysis) {
124
+ return
125
+ }
126
+
127
+ // Check if optimization is needed
128
+ if (!analysis.needsOptimization) {
129
+ console.log('\nāœ… Your wallet is already optimized!')
130
+ console.log(' • You have a reasonable number of UTXOs')
131
+ console.log(' • No dust UTXOs detected')
132
+ console.log(' • Transaction fees should be minimal')
133
+ return
134
+ }
135
+
136
+ console.log('\nšŸ’” Optimization Recommendations:')
137
+
138
+ if (analysis.dust > 0) {
139
+ console.log(` • Consolidate ${analysis.dust} dust UTXOs (< 5.46 XEC)`)
140
+ }
141
+
142
+ if (analysis.total > 20) {
143
+ console.log(` • Reduce UTXO count from ${analysis.total} to ~5-10`)
144
+ }
145
+
146
+ if (analysis.small > 10) {
147
+ console.log(` • Combine ${analysis.small} small UTXOs`)
148
+ }
149
+
150
+ // In dry run mode, just show the plan
151
+ if (dryRun) {
152
+ console.log('\nšŸ“‹ DRY RUN COMPLETE')
153
+ console.log(' Run without --dry-run to execute optimization')
154
+ console.log(' Estimated optimization fee: ~0.01-0.05 XEC')
155
+ return
156
+ }
157
+
158
+ // Confirm optimization
159
+ console.log('\nāš ļø UTXO Optimization Confirmation')
160
+ console.log(' This will consolidate your UTXOs to improve efficiency.')
161
+ console.log(' Benefits:')
162
+ console.log(' • Lower future transaction fees')
163
+ console.log(' • Faster transaction creation')
164
+ console.log(' • Cleaner wallet state')
165
+ console.log('')
166
+ console.log(' Cost:')
167
+ console.log(' • One-time consolidation fee (~0.01-0.05 XEC)')
168
+ console.log(' • UTXOs will be temporarily locked during confirmation')
169
+
170
+ const readline = require('readline')
171
+ const rl = readline.createInterface({
172
+ input: process.stdin,
173
+ output: process.stdout
174
+ })
175
+
176
+ const confirmed = await new Promise((resolve) => {
177
+ rl.question('\nDo you want to optimize your UTXOs? (yes/no): ', (answer) => {
178
+ rl.close()
179
+ resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y')
180
+ })
181
+ })
182
+
183
+ if (!confirmed) {
184
+ console.log('āŒ UTXO optimization cancelled by user')
185
+ return
186
+ }
187
+
188
+ console.log('\nšŸš€ Starting UTXO optimization...')
189
+
190
+ // Run the optimization
191
+ const result = await wallet.optimize(false) // false = not dry run
192
+
193
+ if (result && result.txid) {
194
+ console.log('\nāœ… UTXO optimization completed successfully!')
195
+ console.log('═'.repeat(60))
196
+ console.log(`Transaction ID: ${result.txid}`)
197
+ console.log(`UTXOs consolidated: ${result.utxosConsolidated || 'Multiple'}`)
198
+ console.log(`Fee paid: ${result.fee ? (result.fee / 100).toLocaleString() + ' XEC' : 'Calculated automatically'}`)
199
+ console.log('═'.repeat(60))
200
+
201
+ // Show updated state
202
+ console.log('\nšŸ’° Getting updated balance...')
203
+ await new Promise(resolve => setTimeout(resolve, 2000)) // Wait 2 seconds
204
+
205
+ const newBalance = await wallet.getXecBalance()
206
+ console.log(`New Balance: ${newBalance.toLocaleString()} XEC`)
207
+
208
+ console.log('\nšŸ”— View Transaction:')
209
+ console.log(` Explorer: https://explorer.e.cash/tx/${result.txid}`)
210
+
211
+ console.log('\nšŸ“ What happened:')
212
+ console.log(' • Multiple small UTXOs were combined into fewer larger ones')
213
+ console.log(' • Future transactions will require lower fees')
214
+ console.log(' • Your wallet is now more efficient')
215
+ console.log(' • Wait for confirmation before making new transactions')
216
+
217
+ console.log('\nā±ļø Next Steps:')
218
+ console.log(' • Wait 1-10 minutes for transaction confirmation')
219
+ console.log(' • Check new UTXO state: node examples/wallet-info/get-utxos.js')
220
+ console.log(' • Your wallet is now optimized for efficient transactions')
221
+ } else {
222
+ console.log('\nāŒ UTXO optimization failed or was not needed')
223
+ console.log(' Possible reasons:')
224
+ console.log(' • UTXOs are already optimal')
225
+ console.log(' • Insufficient balance for optimization fee')
226
+ console.log(' • Network error during optimization')
227
+ }
228
+ } catch (err) {
229
+ console.error('āŒ Failed to optimize UTXOs:', err.message)
230
+
231
+ // Provide helpful error context
232
+ if (err.message.includes('insufficient')) {
233
+ console.log('\nšŸ’ø Insufficient Funds:')
234
+ console.log(' • Your wallet needs enough XEC to pay consolidation fees')
235
+ console.log(' • Try optimizing when you have a larger balance')
236
+ console.log(' • Each consolidation transaction requires a small fee')
237
+ } else if (err.message.includes('network')) {
238
+ console.log('\n🌐 Network Error:')
239
+ console.log(' • Check your internet connection')
240
+ console.log(' • The network might be temporarily unavailable')
241
+ console.log(' • Try again in a few moments')
242
+ }
243
+
244
+ process.exit(1)
245
+ }
246
+ }
247
+
248
+ // Show usage if requested
249
+ if (args.includes('--help') || args.includes('-h')) {
250
+ showUsage()
251
+ process.exit(0)
252
+ }
253
+
254
+ // Run the example
255
+ optimizeUtxos()
@@ -0,0 +1,216 @@
1
+ /*
2
+ Send an OP_RETURN transaction with custom data.
3
+ This example shows how to embed data on the XEC blockchain.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ // Get command line arguments
10
+ const args = process.argv.slice(2)
11
+
12
+ function showUsage () {
13
+ console.log('Usage: node send-op-return.js <message> [xec_amount]')
14
+ console.log('')
15
+ console.log('Examples:')
16
+ console.log(' node send-op-return.js "Hello XEC blockchain!"')
17
+ console.log(' node send-op-return.js "Document hash: abc123..." 5.46')
18
+ console.log(' node send-op-return.js "Timestamp: 2024-01-01" 0')
19
+ console.log('')
20
+ console.log('Parameters:')
21
+ console.log(' message: Text to embed in the blockchain (max 220 bytes)')
22
+ console.log(' xec_amount: Optional XEC to send to yourself (default: 0)')
23
+ console.log('')
24
+ console.log('Note: OP_RETURN data is permanent and publicly visible!')
25
+ }
26
+
27
+ async function sendOpReturn () {
28
+ try {
29
+ console.log('šŸ“ Sending OP_RETURN transaction...\n')
30
+
31
+ // Check arguments
32
+ if (args.length < 1) {
33
+ console.log('āŒ No message provided')
34
+ showUsage()
35
+ return
36
+ }
37
+
38
+ const message = args[0]
39
+ const xecAmount = args.length > 1 ? parseFloat(args[1]) : 0
40
+
41
+ // Validate message
42
+ if (!message || message.length === 0) {
43
+ console.log('āŒ Message cannot be empty')
44
+ showUsage()
45
+ return
46
+ }
47
+
48
+ if (message.length > 220) {
49
+ console.log('āŒ Message too long. Maximum 220 characters allowed.')
50
+ console.log(` Your message: ${message.length} characters`)
51
+ return
52
+ }
53
+
54
+ // Validate amount
55
+ if (isNaN(xecAmount) || xecAmount < 0) {
56
+ console.log('āŒ Invalid XEC amount. Must be 0 or positive number')
57
+ showUsage()
58
+ return
59
+ }
60
+
61
+ // Load wallet from file
62
+ const walletData = WalletHelper.loadWallet()
63
+ if (!walletData) {
64
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
65
+ return
66
+ }
67
+
68
+ // Create wallet instance from saved data
69
+ const wallet = new MinimalXECWallet(walletData.mnemonic || walletData.privateKey)
70
+ await wallet.walletInfoPromise
71
+
72
+ // Initialize wallet
73
+ await wallet.initialize()
74
+
75
+ console.log('šŸ’° Checking wallet balance...')
76
+ const balance = await wallet.getXecBalance()
77
+
78
+ console.log('\nšŸ“‹ OP_RETURN Transaction Details:')
79
+ console.log('═'.repeat(60))
80
+ console.log(`From: ${walletData.xecAddress}`)
81
+ console.log(`Message: "${message}"`)
82
+ console.log(`Message Length: ${message.length} bytes`)
83
+ console.log(`XEC Amount: ${xecAmount.toLocaleString()} XEC`)
84
+ console.log(`Current Balance: ${balance.toLocaleString()} XEC`)
85
+ console.log('═'.repeat(60))
86
+
87
+ // Check balance
88
+ const estimatedFee = 0.01 // Rough estimate
89
+ const totalCost = xecAmount + estimatedFee
90
+
91
+ if (balance < totalCost) {
92
+ console.log('\nāŒ Insufficient balance!')
93
+ console.log(` Required: ~${totalCost.toLocaleString()} XEC (including estimated fee)`)
94
+ console.log(` Available: ${balance.toLocaleString()} XEC`)
95
+ console.log(' Fund your wallet or reduce the XEC amount')
96
+ return
97
+ }
98
+
99
+ // Show what OP_RETURN means
100
+ console.log('\nšŸ“š About OP_RETURN:')
101
+ console.log(' • OP_RETURN allows embedding data in blockchain transactions')
102
+ console.log(' • Data is permanent and publicly visible')
103
+ console.log(' • Useful for timestamps, document hashes, certificates')
104
+ console.log(' • Data cannot be spent (provably unspendable)')
105
+
106
+ // Encode message to hex
107
+ const messageHex = Buffer.from(message, 'utf8').toString('hex')
108
+ console.log(`\nšŸ”— Encoded Message: ${messageHex}`)
109
+
110
+ // Confirm transaction
111
+ console.log('\nāš ļø OP_RETURN Transaction Confirmation')
112
+ console.log(' This data will be permanently stored on the blockchain!')
113
+ console.log(' Make sure you want to make this information public.')
114
+
115
+ const readline = require('readline')
116
+ const rl = readline.createInterface({
117
+ input: process.stdin,
118
+ output: process.stdout
119
+ })
120
+
121
+ const confirmed = await new Promise((resolve) => {
122
+ rl.question('\nDo you want to proceed? (yes/no): ', (answer) => {
123
+ rl.close()
124
+ resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y')
125
+ })
126
+ })
127
+
128
+ if (!confirmed) {
129
+ console.log('āŒ Transaction cancelled by user')
130
+ return
131
+ }
132
+
133
+ console.log('\nšŸš€ Broadcasting OP_RETURN transaction...')
134
+
135
+ // Prepare XEC outputs (optional)
136
+ let xecOutputs = []
137
+ if (xecAmount > 0) {
138
+ xecOutputs = [{
139
+ address: walletData.xecAddress,
140
+ amountSat: Math.round(xecAmount * 100)
141
+ }]
142
+ }
143
+
144
+ // Send OP_RETURN transaction
145
+ const txid = await wallet.sendOpReturn(
146
+ message, // message
147
+ '6d02', // prefix (memo protocol)
148
+ xecOutputs, // optional XEC outputs
149
+ 1.2 // sats per byte fee rate
150
+ )
151
+
152
+ console.log('\nāœ… OP_RETURN transaction sent successfully!')
153
+ console.log('═'.repeat(60))
154
+ console.log(`Transaction ID: ${txid}`)
155
+ console.log(`Message: "${message}"`)
156
+ console.log(`Message Hex: ${messageHex}`)
157
+ console.log(`XEC Amount: ${xecAmount.toLocaleString()} XEC`)
158
+ console.log('═'.repeat(60))
159
+
160
+ // Get updated balance
161
+ console.log('\nšŸ’° Getting updated balance...')
162
+ const newBalance = await wallet.getXecBalance()
163
+ const feePaid = balance - newBalance - xecAmount
164
+
165
+ console.log('\nšŸ“Š Transaction Summary:')
166
+ console.log(`Previous Balance: ${balance.toLocaleString()} XEC`)
167
+ console.log(`XEC Sent: ${xecAmount.toLocaleString()} XEC`)
168
+ console.log(`Fee Paid: ${feePaid.toLocaleString()} XEC`)
169
+ console.log(`New Balance: ${newBalance.toLocaleString()} XEC`)
170
+
171
+ console.log('\nšŸ”— View Transaction:')
172
+ console.log(` Explorer: https://explorer.e.cash/tx/${txid}`)
173
+ console.log(' Note: Look for the OP_RETURN output in the transaction details')
174
+
175
+ console.log('\nšŸ“ OP_RETURN Data Location:')
176
+ console.log(' • Your message is now permanently stored on the XEC blockchain')
177
+ console.log(' • Anyone can view it by examining the transaction')
178
+ console.log(' • The data is in the OP_RETURN output of the transaction')
179
+ console.log(' • Blockchain explorers will show the hex data')
180
+
181
+ console.log('\nšŸ’” Use Cases for OP_RETURN:')
182
+ console.log(' • Document timestamping')
183
+ console.log(' • Certificate verification')
184
+ console.log(' • Digital signatures')
185
+ console.log(' • Public announcements')
186
+ console.log(' • Hash commitments')
187
+
188
+ // Ensure process exits cleanly
189
+ process.exit(0)
190
+ } catch (err) {
191
+ console.error('āŒ Failed to send OP_RETURN:', err.message)
192
+
193
+ // Provide helpful error context
194
+ if (err.message.includes('insufficient')) {
195
+ console.log('\nšŸ’ø Insufficient Funds:')
196
+ console.log(' • Your wallet does not have enough XEC for this transaction')
197
+ console.log(' • OP_RETURN transactions still require fees')
198
+ console.log(' • Try reducing the XEC amount or fund your wallet')
199
+ } else if (err.message.includes('size') || err.message.includes('large')) {
200
+ console.log('\nšŸ“ Size Error:')
201
+ console.log(' • Your message might be too large')
202
+ console.log(' • Try a shorter message')
203
+ console.log(' • Maximum recommended: 220 bytes')
204
+ } else if (err.message.includes('network')) {
205
+ console.log('\n🌐 Network Error:')
206
+ console.log(' • Check your internet connection')
207
+ console.log(' • The network might be temporarily unavailable')
208
+ console.log(' • Try again in a few moments')
209
+ }
210
+
211
+ process.exit(1)
212
+ }
213
+ }
214
+
215
+ // Run the example
216
+ sendOpReturn()