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,214 @@
1
+ /*
2
+ Validate XEC addresses for correctness.
3
+ This example shows how to check if an address is valid before sending funds.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+
8
+ // Get command line arguments
9
+ const args = process.argv.slice(2)
10
+
11
+ function showUsage () {
12
+ console.log('Usage: node validate-address.js <address1> [address2] [address3] ...')
13
+ console.log('')
14
+ console.log('Examples:')
15
+ console.log(' node validate-address.js ecash:qp1234567890abcdef1234567890abcdef12345678')
16
+ console.log(' node validate-address.js ecash:qr123... ecash:qp456... bitcoincash:qz789...')
17
+ console.log('')
18
+ console.log('Parameters:')
19
+ console.log(' addressN: XEC or other cryptocurrency addresses to validate')
20
+ console.log('')
21
+ console.log('Purpose:')
22
+ console.log(' • Verify address format and checksum')
23
+ console.log(' • Detect common address format errors')
24
+ console.log(' • Prevent sending funds to invalid addresses')
25
+ }
26
+
27
+ function validateSingleAddress (address) {
28
+ console.log(`\nšŸ” Validating: ${address}`)
29
+ console.log('─'.repeat(60))
30
+
31
+ // Basic format checks
32
+ const checks = {
33
+ notEmpty: address && address.length > 0,
34
+ hasPrefix: address && address.includes(':'),
35
+ correctPrefix: address && address.startsWith('ecash:'),
36
+ correctLength: address && address.length >= 40 && address.length <= 60,
37
+ validCharacters: address && /^ecash:[a-z0-9]+$/.test(address)
38
+ }
39
+
40
+ // Show basic format analysis
41
+ console.log('šŸ“‹ Basic Format Analysis:')
42
+ console.log(` Length: ${address ? address.length : 0} characters`)
43
+ console.log(` Prefix: ${address ? address.split(':')[0] : 'none'}`)
44
+ console.log(` Body: ${address ? address.split(':')[1]?.substring(0, 10) + '...' : 'none'}`)
45
+
46
+ // Check against other cryptocurrency formats
47
+ const formatAnalysis = {
48
+ isXEC: address && address.startsWith('ecash:'),
49
+ isBCH: address && address.startsWith('bitcoincash:'),
50
+ isBTC: address && (/^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address) || /^bc1[a-z0-9]{39,59}$/.test(address)),
51
+ isETH: address && /^0x[a-fA-F0-9]{40}$/.test(address),
52
+ isLTC: address && (/^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$/.test(address) || /^ltc1[a-z0-9]{39,59}$/.test(address))
53
+ }
54
+
55
+ console.log('\nšŸ” Format Detection:')
56
+ if (formatAnalysis.isXEC) {
57
+ console.log(' āœ… Detected as XEC (eCash) address')
58
+ } else if (formatAnalysis.isBCH) {
59
+ console.log(' āš ļø Detected as BCH (Bitcoin Cash) address')
60
+ console.log(' This is NOT compatible with XEC!')
61
+ } else if (formatAnalysis.isBTC) {
62
+ console.log(' āš ļø Detected as BTC (Bitcoin) address')
63
+ console.log(' This is NOT compatible with XEC!')
64
+ } else if (formatAnalysis.isETH) {
65
+ console.log(' āš ļø Detected as ETH (Ethereum) address')
66
+ console.log(' This is NOT compatible with XEC!')
67
+ } else if (formatAnalysis.isLTC) {
68
+ console.log(' āš ļø Detected as LTC (Litecoin) address')
69
+ console.log(' This is NOT compatible with XEC!')
70
+ } else {
71
+ console.log(' ā“ Unknown or invalid address format')
72
+ }
73
+
74
+ // Attempt validation using wallet library
75
+ let isValid = false
76
+ let validationError = null
77
+
78
+ try {
79
+ const wallet = new MinimalXECWallet()
80
+ wallet._validateAddress(address)
81
+ isValid = true
82
+ console.log('\nāœ… Validation Result: VALID XEC ADDRESS')
83
+ } catch (err) {
84
+ validationError = err.message
85
+ console.log('\nāŒ Validation Result: INVALID')
86
+ console.log(` Error: ${validationError}`)
87
+ }
88
+
89
+ // Detailed check results
90
+ console.log('\nšŸ“Š Detailed Checks:')
91
+ Object.entries(checks).forEach(([check, passed]) => {
92
+ const status = passed ? 'āœ…' : 'āŒ'
93
+ const checkName = check.replace(/([A-Z])/g, ' $1').toLowerCase()
94
+ console.log(` ${status} ${checkName}`)
95
+ })
96
+
97
+ // Security warnings
98
+ if (!isValid) {
99
+ console.log('\nāš ļø Security Warnings:')
100
+
101
+ if (formatAnalysis.isBCH) {
102
+ console.log(' • This appears to be a Bitcoin Cash address')
103
+ console.log(' • Sending XEC to BCH addresses will result in LOSS OF FUNDS')
104
+ console.log(' • XEC and BCH are different cryptocurrencies')
105
+ } else if (formatAnalysis.isBTC) {
106
+ console.log(' • This appears to be a Bitcoin address')
107
+ console.log(' • Sending XEC to BTC addresses will result in LOSS OF FUNDS')
108
+ } else if (formatAnalysis.isETH) {
109
+ console.log(' • This appears to be an Ethereum address')
110
+ console.log(' • XEC cannot be sent to Ethereum addresses')
111
+ } else {
112
+ console.log(' • Address format is not recognized as valid XEC')
113
+ console.log(' • Double-check the address with the recipient')
114
+ console.log(' • Sending to invalid addresses may result in loss of funds')
115
+ }
116
+ }
117
+
118
+ // Usage recommendations
119
+ console.log('\nšŸ’” Recommendations:')
120
+ if (isValid) {
121
+ console.log(' āœ… Safe to send XEC to this address')
122
+ console.log(' āœ… Address format and checksum are correct')
123
+ console.log(' āœ… Compatible with eCash network')
124
+ } else {
125
+ console.log(' āŒ DO NOT send XEC to this address')
126
+ console.log(' āŒ Verify the address with the recipient')
127
+ console.log(' āŒ Request a proper XEC address (starting with ecash:)')
128
+ }
129
+
130
+ return {
131
+ address,
132
+ isValid,
133
+ format: formatAnalysis,
134
+ error: validationError
135
+ }
136
+ }
137
+
138
+ async function validateAddresses () {
139
+ try {
140
+ console.log('šŸ” XEC Address Validation Tool\n')
141
+
142
+ // Check arguments
143
+ if (args.length === 0) {
144
+ console.log('āŒ No addresses provided')
145
+ showUsage()
146
+ return
147
+ }
148
+
149
+ console.log(`šŸ“‹ Validating ${args.length} address(es):`)
150
+ console.log('═'.repeat(60))
151
+
152
+ const results = []
153
+
154
+ // Validate each address
155
+ for (const address of args) {
156
+ const result = validateSingleAddress(address)
157
+ results.push(result)
158
+ }
159
+
160
+ // Summary
161
+ console.log('\nšŸ“Š Validation Summary:')
162
+ console.log('═'.repeat(60))
163
+
164
+ const validCount = results.filter(r => r.isValid).length
165
+ const invalidCount = results.length - validCount
166
+
167
+ console.log(`Total addresses checked: ${results.length}`)
168
+ console.log(`Valid XEC addresses: ${validCount}`)
169
+ console.log(`Invalid addresses: ${invalidCount}`)
170
+
171
+ if (invalidCount > 0) {
172
+ console.log('\nāš ļø Invalid Addresses Found:')
173
+ results.filter(r => !r.isValid).forEach(result => {
174
+ console.log(` āŒ ${result.address}`)
175
+ console.log(` Error: ${result.error}`)
176
+ })
177
+ }
178
+
179
+ if (validCount > 0) {
180
+ console.log('\nāœ… Valid XEC Addresses:')
181
+ results.filter(r => r.isValid).forEach(result => {
182
+ console.log(` āœ… ${result.address}`)
183
+ })
184
+ }
185
+
186
+ // Best practices
187
+ console.log('\nšŸ’” Best Practices:')
188
+ console.log('─'.repeat(60))
189
+ console.log('• Always validate addresses before sending funds')
190
+ console.log('• Double-check with recipients when in doubt')
191
+ console.log('• XEC addresses must start with "ecash:"')
192
+ console.log('• Never send XEC to Bitcoin, Ethereum, or other crypto addresses')
193
+ console.log('• Use small test amounts for first-time recipients')
194
+ console.log('• Copy addresses carefully to avoid typos')
195
+
196
+ console.log('\nšŸ”— Resources:')
197
+ console.log('─'.repeat(60))
198
+ console.log('• eCash Explorer: https://explorer.e.cash')
199
+ console.log('• Address format docs: https://e.cash/developers')
200
+ console.log('• CashAddr format: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md')
201
+ } catch (err) {
202
+ console.error('āŒ Address validation failed:', err.message)
203
+ process.exit(1)
204
+ }
205
+ }
206
+
207
+ // Show usage if requested
208
+ if (args.includes('--help') || args.includes('-h')) {
209
+ showUsage()
210
+ process.exit(0)
211
+ }
212
+
213
+ // Run the example
214
+ validateAddresses()
@@ -0,0 +1,79 @@
1
+ /*
2
+ Simple UTXO consolidation test to debug wallet issues
3
+ */
4
+
5
+ const MinimalXECWallet = require('../../index')
6
+ const fs = require('fs')
7
+
8
+ async function simpleTest () {
9
+ try {
10
+ console.log('šŸ”§ Simple UTXO Consolidation Test...\n')
11
+
12
+ // Load wallet data directly
13
+ const walletData = JSON.parse(fs.readFileSync('./wallet.json'))
14
+ console.log('āœ… Wallet loaded:')
15
+ console.log(` Address: ${walletData.xecAddress}`)
16
+ console.log('')
17
+
18
+ // Initialize wallet
19
+ console.log('šŸ”§ Initializing wallet...')
20
+ const wallet = new MinimalXECWallet(walletData.mnemonic)
21
+
22
+ await wallet.walletInfoPromise
23
+ console.log('āœ… Wallet info ready')
24
+
25
+ await wallet.initialize()
26
+ console.log('āœ… Wallet initialized')
27
+ console.log('')
28
+
29
+ // Check if wallet is properly initialized
30
+ console.log('šŸ” Wallet State Check:')
31
+ console.log(` isInitialized: ${wallet.isInitialized}`)
32
+ console.log(` walletInfo exists: ${!!wallet.walletInfo}`)
33
+ console.log(` utxos exists: ${!!wallet.utxos}`)
34
+ console.log(` consolidateUtxos exists: ${!!wallet.consolidateUtxos}`)
35
+ console.log('')
36
+
37
+ // Try to get balance
38
+ console.log('šŸ’° Getting balance...')
39
+ try {
40
+ const balance = await wallet.getXecBalance()
41
+ console.log(` Balance: ${JSON.stringify(balance)}`)
42
+ } catch (err) {
43
+ console.log(` Balance error: ${err.message}`)
44
+ }
45
+ console.log('')
46
+
47
+ // Try to get UTXOs
48
+ console.log('šŸ“¦ Getting UTXOs...')
49
+ try {
50
+ const utxos = await wallet.getUtxos()
51
+ console.log(` UTXOs count: ${utxos.length}`)
52
+ if (utxos.length > 0) {
53
+ console.log(` First UTXO: ${JSON.stringify(utxos[0], null, 2)}`)
54
+ }
55
+ } catch (err) {
56
+ console.log(` UTXOs error: ${err.message}`)
57
+ }
58
+ console.log('')
59
+
60
+ // Try consolidation analysis
61
+ console.log('šŸ” Testing consolidation analysis...')
62
+ try {
63
+ const dryRunResult = await wallet.optimize(true)
64
+ console.log(` Dry run success: ${dryRunResult.success}`)
65
+ console.log(` Message: ${dryRunResult.message}`)
66
+ console.log(` Transactions: ${dryRunResult.transactions.length}`)
67
+ } catch (err) {
68
+ console.log(` Consolidation error: ${err.message}`)
69
+ }
70
+ } catch (err) {
71
+ console.error('\nāŒ Test failed:', err.message)
72
+ console.log('\nšŸ”§ Debugging info:')
73
+ console.log(` Error type: ${err.constructor.name}`)
74
+ console.log(` Stack: ${err.stack}`)
75
+ }
76
+ }
77
+
78
+ // Run test
79
+ simpleTest()
@@ -0,0 +1,179 @@
1
+ /*
2
+ Test UTXO consolidation functionality with real wallet
3
+ Demonstrates dry run analysis and actual consolidation capabilities
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ async function testUtxoConsolidation () {
10
+ try {
11
+ console.log('šŸ”§ Testing UTXO Consolidation Functionality...\n')
12
+
13
+ // Load wallet
14
+ const walletData = WalletHelper.loadWallet()
15
+ if (!walletData) {
16
+ console.log('āŒ No wallet found')
17
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
18
+ return
19
+ }
20
+
21
+ console.log('āœ… Wallet loaded:')
22
+ console.log(` Address: ${walletData.xecAddress}`)
23
+ console.log('')
24
+
25
+ // Initialize wallet
26
+ console.log('šŸ”§ Initializing wallet...')
27
+ const wallet = new MinimalXECWallet(walletData.mnemonic)
28
+
29
+ await wallet.walletInfoPromise
30
+ await wallet.initialize()
31
+
32
+ console.log('āœ… Wallet initialized successfully!')
33
+ console.log('')
34
+
35
+ // Get current wallet state
36
+ console.log('šŸ“Š Current Wallet State:')
37
+ const balance = await wallet.getXecBalance()
38
+ const utxos = await wallet.getUtxos()
39
+ console.log(` XEC Balance: ${balance} XEC`)
40
+ console.log(` Total UTXOs: ${utxos.length}`)
41
+ console.log('')
42
+
43
+ // Get UTXO distribution
44
+ console.log('šŸ“ˆ UTXO Distribution Analysis:')
45
+ const distribution = wallet.consolidateUtxos.getUtxoDistribution()
46
+ console.log(` Total UTXOs: ${distribution.total}`)
47
+ console.log(` Dust (< 1000 sats): ${distribution.dust}`)
48
+ console.log(` Small (1000-10000 sats): ${distribution.small}`)
49
+ console.log(` Medium (10000-100000 sats): ${distribution.medium}`)
50
+ console.log(` Large (> 100000 sats): ${distribution.large}`)
51
+ console.log('')
52
+
53
+ // Get optimization savings estimate
54
+ console.log('šŸ’° Optimization Savings Estimate:')
55
+ const savings = wallet.consolidateUtxos.estimateOptimizationSavings()
56
+ console.log(` Current UTXOs: ${savings.currentUtxos}`)
57
+ if (savings.optimalUtxos) {
58
+ console.log(` Optimal UTXOs: ${savings.optimalUtxos}`)
59
+ console.log(` Current fee estimate: ${savings.currentEstimatedFee} satoshis`)
60
+ console.log(` Optimized fee estimate: ${savings.optimizedEstimatedFee} satoshis`)
61
+ console.log(` Potential savings: ${savings.savings} satoshis`)
62
+ } else {
63
+ console.log(` Status: ${savings.reason}`)
64
+ }
65
+ console.log('')
66
+
67
+ // Perform dry run optimization analysis
68
+ console.log('šŸ” Dry Run Optimization Analysis:')
69
+ const dryRunResult = await wallet.optimize(true) // Dry run mode
70
+
71
+ console.log(` Success: ${dryRunResult.success}`)
72
+ console.log(` Analysis: ${dryRunResult.message}`)
73
+ console.log(` Planned transactions: ${dryRunResult.transactions.length}`)
74
+
75
+ if (dryRunResult.analysis) {
76
+ console.log('\n šŸ“‹ Detailed Analysis:')
77
+ console.log(` Should consolidate: ${dryRunResult.analysis.shouldConsolidate}`)
78
+ console.log(` UTXOs to consolidate: ${dryRunResult.analysis.totalUtxos || 'N/A'}`)
79
+ console.log(` Output UTXOs: ${dryRunResult.analysis.outputUtxos || 'N/A'}`)
80
+ console.log(` Total value: ${dryRunResult.analysis.totalValue || 'N/A'} satoshis`)
81
+ if (dryRunResult.analysis.consolidationFee) {
82
+ console.log(` Consolidation fee: ${dryRunResult.analysis.consolidationFee} satoshis`)
83
+ }
84
+ if (dryRunResult.analysis.potentialSavings !== undefined) {
85
+ console.log(` Net benefit: ${dryRunResult.analysis.potentialSavings} satoshis`)
86
+ }
87
+ }
88
+
89
+ // Show consolidation plans if any
90
+ if (dryRunResult.transactions.length > 0) {
91
+ console.log('\n šŸ“ Consolidation Plans:')
92
+ dryRunResult.transactions.forEach((plan, index) => {
93
+ console.log(` Plan ${index + 1}:`)
94
+ console.log(` Input UTXOs: ${plan.inputCount}`)
95
+ console.log(` Input value: ${plan.totalInputValue} satoshis`)
96
+ console.log(` Output value: ${plan.outputValue} satoshis`)
97
+ console.log(` Estimated fee: ${plan.estimatedFee} satoshis`)
98
+ if (plan.savings) {
99
+ console.log(` Future savings: ${plan.savings} satoshis`)
100
+ }
101
+ })
102
+ }
103
+
104
+ console.log('')
105
+
106
+ // User decision for live execution
107
+ if (dryRunResult.analysis && dryRunResult.analysis.shouldConsolidate) {
108
+ console.log('šŸ’” Consolidation Recommendation:')
109
+ console.log(' āœ… UTXO consolidation would be beneficial!')
110
+ console.log(' šŸ“Š Benefits:')
111
+ console.log(` • Reduce UTXOs from ${dryRunResult.analysis.totalUtxos} to ${dryRunResult.analysis.outputUtxos}`)
112
+ console.log(` • Save ${dryRunResult.analysis.potentialSavings} satoshis in future transaction fees`)
113
+ console.log(' • Improve wallet performance and reduce transaction complexity')
114
+ console.log('')
115
+ console.log('āš ļø This is a test script - not executing live consolidation.')
116
+ console.log(' To execute live consolidation, run:')
117
+ console.log(' const result = await wallet.optimize(false) // Live mode')
118
+ console.log('')
119
+ console.log('šŸ”§ Test Parameters:')
120
+ console.log(` Fee rate: ${walletData.fee || '1.2'} sat/byte`)
121
+ console.log(' Dust limit: 200 satoshis')
122
+ console.log(' Max inputs per tx: 200')
123
+ console.log(' Consolidation threshold: 100,000 satoshis')
124
+ } else {
125
+ console.log('ā„¹ļø Consolidation Status:')
126
+ console.log(' No consolidation needed at this time.')
127
+ console.log(' Reasons:')
128
+ if (distribution.total < 5) {
129
+ console.log(' • Too few UTXOs (need at least 5)')
130
+ }
131
+ if (distribution.dust + distribution.small < 5) {
132
+ console.log(' • Not enough small UTXOs to consolidate')
133
+ }
134
+ if (dryRunResult.analysis && dryRunResult.analysis.potentialSavings <= 0) {
135
+ console.log(' • Consolidation would cost more than it saves')
136
+ }
137
+ console.log('')
138
+ console.log('šŸ’” When consolidation becomes beneficial:')
139
+ console.log(' • When you have many small UTXOs (< 100,000 satoshis)')
140
+ console.log(' • When transaction fees are low')
141
+ console.log(' • When you frequently make transactions')
142
+ }
143
+
144
+ console.log('')
145
+ console.log('šŸŽÆ Test Results:')
146
+ console.log(' āœ… UTXO consolidation functionality working correctly')
147
+ console.log(' āœ… Dry run analysis completed successfully')
148
+ console.log(' āœ… Cost-benefit analysis functioning properly')
149
+ console.log(' āœ… Smart consolidation recommendations working')
150
+ } catch (err) {
151
+ console.error('\nāŒ UTXO consolidation test failed:', err.message)
152
+
153
+ // Provide context-specific help
154
+ if (err.message.includes('wallet')) {
155
+ console.log('\nšŸ”§ Wallet Issue:')
156
+ console.log(' • Check wallet is properly initialized')
157
+ console.log(' • Verify wallet has some XEC balance')
158
+ console.log(' • Try reinitializing the wallet')
159
+ } else if (err.message.includes('network') || err.message.includes('chronik')) {
160
+ console.log('\n🌐 Network Issue:')
161
+ console.log(' • Check internet connection')
162
+ console.log(' • Chronik API may be temporarily unavailable')
163
+ console.log(' • Try again in a few moments')
164
+ } else {
165
+ console.log('\nšŸ”§ General Error:')
166
+ console.log(' • Check wallet has been properly funded')
167
+ console.log(' • Verify network connectivity')
168
+ console.log(' • Try with a fresh wallet initialization')
169
+ }
170
+
171
+ console.log('\nFor debugging, check:')
172
+ console.log(' node examples/wallet-info/wallet-details.js')
173
+
174
+ process.exit(1)
175
+ }
176
+ }
177
+
178
+ // Run the consolidation test
179
+ testUtxoConsolidation()