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,293 @@
1
+ /*
2
+ Burn tokens (SLP or ALP) using the main wallet API
3
+ Demonstrates safe token destruction with confirmation prompts
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 burn-tokens.js <token_ticker_or_id> [amount]')
14
+ console.log('')
15
+ console.log('Examples:')
16
+ console.log(' node burn-tokens.js FLCT 2 # Burn 2 FLCT tokens')
17
+ console.log(' node burn-tokens.js TGR 1.5 # Burn 1.5 TGR tokens')
18
+ console.log(' node burn-tokens.js FLCT all # Burn all FLCT tokens')
19
+ console.log(' node burn-tokens.js 5e40dda12765...912135 3 # Burn by token ID')
20
+ console.log('')
21
+ console.log('Parameters:')
22
+ console.log(' token_ticker_or_id: Token ticker (FLCT, TGR) or full token ID')
23
+ console.log(' amount: Amount to burn, or "all" to burn everything (optional)')
24
+ console.log('')
25
+ console.log('⚠️ WARNING: Token burning is PERMANENT and IRREVERSIBLE!')
26
+ console.log('✨ Features:')
27
+ console.log(' • Protocol (SLP/ALP) detected automatically')
28
+ console.log(' • Multiple safety confirmations')
29
+ console.log(' • Burn specific amounts or all tokens')
30
+ console.log(' • Uses main wallet API for consistency')
31
+ }
32
+
33
+ async function burnTokens () {
34
+ try {
35
+ console.log('🔥 Burn Tokens (Main Wallet API)...\n')
36
+
37
+ // Check arguments
38
+ if (args.length < 1) {
39
+ console.log('❌ Missing required arguments')
40
+ showUsage()
41
+ return
42
+ }
43
+
44
+ const tokenInput = args[0]
45
+ const amountInput = args[1] || 'prompt'
46
+ const burnAll = amountInput === 'all'
47
+
48
+ // Load wallet
49
+ const walletData = WalletHelper.loadWallet()
50
+ if (!walletData) {
51
+ console.log('❌ No wallet found')
52
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
53
+ return
54
+ }
55
+
56
+ console.log('✅ Wallet loaded:')
57
+ console.log(` Address: ${walletData.xecAddress}`)
58
+ console.log('')
59
+
60
+ // Initialize main wallet (Step 1 integration)
61
+ console.log('🔧 Initializing wallet...')
62
+ const wallet = new MinimalXECWallet(walletData.mnemonic)
63
+
64
+ // Wait for wallet creation and initialization
65
+ await wallet.walletInfoPromise
66
+ await wallet.initialize()
67
+
68
+ console.log('✅ Wallet initialized successfully!')
69
+ console.log('')
70
+
71
+ // Get available tokens using main wallet API
72
+ console.log('📦 Loading available tokens...')
73
+ const tokens = await wallet.listETokens()
74
+
75
+ if (tokens.length === 0) {
76
+ console.log('❌ No tokens found in wallet')
77
+ console.log('')
78
+ console.log('💡 Get some tokens first:')
79
+ console.log(' • Visit eCash faucets for test tokens')
80
+ console.log(' • Use DEX to trade for tokens')
81
+ console.log(' • Receive tokens from other wallets')
82
+ return
83
+ }
84
+
85
+ console.log(`✅ Found ${tokens.length} token type(s):`)
86
+ for (const token of tokens) {
87
+ console.log(` • ${token.ticker} (${token.protocol}): ${token.balance.display} ${token.ticker}`)
88
+ }
89
+ console.log('')
90
+
91
+ // Find the token to burn
92
+ let selectedToken = null
93
+
94
+ // Try to match by ticker first (case-insensitive)
95
+ selectedToken = tokens.find(t =>
96
+ t.ticker.toLowerCase() === tokenInput.toLowerCase()
97
+ )
98
+
99
+ // If not found, try to match by token ID
100
+ if (!selectedToken) {
101
+ selectedToken = tokens.find(t => t.tokenId === tokenInput)
102
+ }
103
+
104
+ if (!selectedToken) {
105
+ console.log(`❌ Token "${tokenInput}" not found in wallet`)
106
+ console.log(`Available tokens: ${tokens.map(t => t.ticker).join(', ')}`)
107
+ return
108
+ }
109
+
110
+ console.log('🎯 Selected Token:')
111
+ console.log('═'.repeat(50))
112
+ console.log(`Ticker: ${selectedToken.ticker}`)
113
+ console.log(`Name: ${selectedToken.name}`)
114
+ console.log(`Protocol: ${selectedToken.protocol}`)
115
+ console.log(`Token ID: ${selectedToken.tokenId}`)
116
+ console.log(`Current Balance: ${selectedToken.balance.display} ${selectedToken.ticker}`)
117
+ console.log(`Decimals: ${selectedToken.decimals}`)
118
+ console.log('')
119
+
120
+ // Handle amount determination
121
+ let amountToBurn
122
+
123
+ if (burnAll) {
124
+ amountToBurn = selectedToken.balance.display
125
+ console.log(`🔥 Burning ALL tokens: ${amountToBurn} ${selectedToken.ticker}`)
126
+ } else if (amountInput === 'prompt') {
127
+ // Prompt for amount
128
+ const readline = require('readline')
129
+ const rl = readline.createInterface({
130
+ input: process.stdin,
131
+ output: process.stdout
132
+ })
133
+
134
+ const amountStr = await new Promise((resolve) => {
135
+ rl.question(`Enter amount to burn (max: ${selectedToken.balance.display} ${selectedToken.ticker}): `, (answer) => {
136
+ rl.close()
137
+ resolve(answer)
138
+ })
139
+ })
140
+
141
+ amountToBurn = parseFloat(amountStr)
142
+ if (isNaN(amountToBurn) || amountToBurn <= 0) {
143
+ console.log('❌ Invalid amount entered')
144
+ return
145
+ }
146
+ } else {
147
+ amountToBurn = parseFloat(amountInput)
148
+ if (isNaN(amountToBurn) || amountToBurn <= 0) {
149
+ console.log('❌ Invalid amount. Must be a positive number')
150
+ showUsage()
151
+ return
152
+ }
153
+ }
154
+
155
+ // Validate sufficient balance
156
+ if (amountToBurn > selectedToken.balance.display) {
157
+ console.log('❌ Insufficient token balance!')
158
+ console.log(` Requested: ${amountToBurn} ${selectedToken.ticker}`)
159
+ console.log(` Available: ${selectedToken.balance.display} ${selectedToken.ticker}`)
160
+ return
161
+ }
162
+
163
+ // Get current XEC balance for fee check
164
+ const xecBalance = await wallet.getXecBalance()
165
+ console.log(`💰 XEC Available: ${xecBalance.toLocaleString()} XEC`)
166
+
167
+ if (xecBalance < 1) {
168
+ console.log('⚠️ Warning: Low XEC balance for transaction fees')
169
+ }
170
+
171
+ // Show burn summary with warnings
172
+ console.log('\n🔥 BURN TRANSACTION SUMMARY:')
173
+ console.log('═'.repeat(50))
174
+ console.log(`Protocol: ${selectedToken.protocol}`)
175
+ console.log(`Token: ${selectedToken.ticker} (${selectedToken.name})`)
176
+ console.log(`Amount to burn: ${amountToBurn} ${selectedToken.ticker}`)
177
+ console.log(`Remaining after burn: ${(selectedToken.balance.display - amountToBurn).toFixed(selectedToken.decimals)} ${selectedToken.ticker}`)
178
+ console.log('Estimated Fee: ~0.01 XEC')
179
+ console.log('')
180
+ console.log('⚠️ WARNING: THIS ACTION IS PERMANENT AND IRREVERSIBLE!')
181
+ console.log(' Burned tokens are destroyed forever and cannot be recovered.')
182
+
183
+ // Multiple confirmation prompts for safety
184
+ const readline = require('readline')
185
+ const rl = readline.createInterface({
186
+ input: process.stdin,
187
+ output: process.stdout
188
+ })
189
+
190
+ // First confirmation
191
+ const confirmed1 = await new Promise((resolve) => {
192
+ rl.question(`\nDo you understand that burning ${amountToBurn} ${selectedToken.ticker} is PERMANENT? (yes/no): `, (answer) => {
193
+ resolve(answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y')
194
+ })
195
+ })
196
+
197
+ if (!confirmed1) {
198
+ rl.close()
199
+ console.log('❌ Burn cancelled - confirmation required')
200
+ return
201
+ }
202
+
203
+ // Second confirmation with exact details
204
+ const confirmed2 = await new Promise((resolve) => {
205
+ rl.question(`\nType "BURN ${amountToBurn} ${selectedToken.ticker}" to confirm: `, (answer) => {
206
+ rl.close()
207
+ resolve(answer === `BURN ${amountToBurn} ${selectedToken.ticker}`)
208
+ })
209
+ })
210
+
211
+ if (!confirmed2) {
212
+ console.log('❌ Burn cancelled - exact confirmation required')
213
+ return
214
+ }
215
+
216
+ console.log('\n🔥 Broadcasting burn transaction...')
217
+ console.log(` Protocol: ${selectedToken.protocol}`)
218
+ console.log(' Using main wallet API with automatic protocol routing')
219
+
220
+ // Burn the tokens using main wallet API (Step 1 integration)
221
+ // The wallet will automatically:
222
+ // - Detect the protocol (SLP/ALP)
223
+ // - Route to appropriate handler
224
+ // - Handle UTXO selection and change
225
+ // - Build and broadcast burn transaction
226
+ let txid
227
+
228
+ if (burnAll) {
229
+ txid = await wallet.burnAllETokens(selectedToken.tokenId, 1.2)
230
+ } else {
231
+ txid = await wallet.burnETokens(selectedToken.tokenId, amountToBurn, 1.2)
232
+ }
233
+
234
+ console.log('\n✅ Token burn transaction sent successfully!')
235
+ console.log('═'.repeat(60))
236
+ console.log(`Transaction ID: ${txid}`)
237
+ console.log(`Protocol: ${selectedToken.protocol}`)
238
+ console.log(`Token: ${selectedToken.ticker}`)
239
+ console.log(`Amount burned: ${amountToBurn} ${selectedToken.ticker}`)
240
+ console.log('Status: PERMANENTLY DESTROYED')
241
+ console.log('═'.repeat(60))
242
+
243
+ console.log('\n🔗 View Transaction:')
244
+ console.log(` Explorer: https://explorer.e.cash/tx/${txid}`)
245
+
246
+ console.log('\n💰 Updated Balances (estimated):')
247
+ console.log(` ${selectedToken.ticker}: ${(selectedToken.balance.display - amountToBurn).toFixed(selectedToken.decimals)} ${selectedToken.ticker}`)
248
+ console.log(` XEC: ~${(xecBalance - 0.01).toFixed(2)} XEC (minus fees)`)
249
+
250
+ console.log('\n💡 Next Steps:')
251
+ console.log(' • Check updated balance: node examples/tokens/list-all-tokens.js')
252
+ console.log(' • Send tokens: node examples/tokens/send-any-token.js')
253
+ console.log(' • Get token info: node examples/tokens/get-token-info.js')
254
+ } catch (err) {
255
+ console.error('\n❌ Failed to burn tokens:', err.message)
256
+
257
+ // Provide context-specific help based on error type
258
+ if (err.message.includes('Token ID is required')) {
259
+ console.log('\n🎯 Token Selection Issue:')
260
+ console.log(' • Verify token ticker or ID is correct')
261
+ console.log(' • Check available tokens: node examples/tokens/list-all-tokens.js')
262
+ } else if (err.message.includes('insufficient')) {
263
+ console.log('\n💸 Balance Issue:')
264
+ console.log(' • Check token balance is sufficient')
265
+ console.log(' • Ensure XEC available for fees')
266
+ console.log(' • Balance check: node examples/tokens/list-all-tokens.js')
267
+ } else if (err.message.includes('must be a positive number')) {
268
+ console.log('\n🔢 Amount Issue:')
269
+ console.log(' • Amount must be greater than 0')
270
+ console.log(' • Use decimal notation (e.g., 1.5)')
271
+ console.log(' • Or use "all" to burn everything')
272
+ } else if (err.message.includes('network') || err.message.includes('chronik')) {
273
+ console.log('\n🌐 Network Issue:')
274
+ console.log(' • Check internet connection')
275
+ console.log(' • Chronik API may be temporarily unavailable')
276
+ console.log(' • Try again in a few moments')
277
+ } else {
278
+ console.log('\n🔧 General Error:')
279
+ console.log(' • Check wallet is properly initialized')
280
+ console.log(' • Verify wallet has tokens and XEC for fees')
281
+ console.log(' • Try listing tokens first to debug')
282
+ }
283
+
284
+ console.log('\nFor debugging, run:')
285
+ console.log(' node examples/tokens/list-all-tokens.js')
286
+ console.log(' node examples/wallet-info/get-balance.js')
287
+
288
+ process.exit(1)
289
+ }
290
+ }
291
+
292
+ // Run the token burner
293
+ burnTokens()
@@ -0,0 +1,169 @@
1
+ /*
2
+ Get specific token balance using the main wallet API
3
+ Demonstrates balance checking with automatic protocol detection
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 get-token-balance.js <token_ticker_or_id>')
14
+ console.log('')
15
+ console.log('Examples:')
16
+ console.log(' node get-token-balance.js FLCT')
17
+ console.log(' node get-token-balance.js TGR')
18
+ console.log(' node get-token-balance.js 5e40dda12765d0b3819286f4bd50ec58a4bf8d7dbfd277152693ad9d34912135')
19
+ console.log('')
20
+ console.log('Parameters:')
21
+ console.log(' token_ticker_or_id: Token ticker (FLCT, TGR) or full token ID')
22
+ console.log('')
23
+ console.log('✨ Features:')
24
+ console.log(' • Protocol (SLP/ALP) detected automatically')
25
+ console.log(' • Displays both display units and raw atoms')
26
+ console.log(' • Uses main wallet API for consistency')
27
+ console.log(' • Works with any token type')
28
+ }
29
+
30
+ async function getTokenBalance () {
31
+ try {
32
+ console.log('💰 Get Token Balance (Main Wallet API)...\n')
33
+
34
+ // Check arguments
35
+ if (args.length < 1) {
36
+ console.log('❌ Missing required arguments')
37
+ showUsage()
38
+ return
39
+ }
40
+
41
+ const tokenInput = args[0]
42
+
43
+ // Load wallet
44
+ const walletData = WalletHelper.loadWallet()
45
+ if (!walletData) {
46
+ console.log('❌ No wallet found')
47
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
48
+ return
49
+ }
50
+
51
+ console.log('✅ Wallet loaded:')
52
+ console.log(` Address: ${walletData.xecAddress}`)
53
+ console.log('')
54
+
55
+ // Initialize main wallet (Step 1 integration)
56
+ console.log('🔧 Initializing wallet...')
57
+ const wallet = new MinimalXECWallet(walletData.mnemonic)
58
+
59
+ // Wait for wallet creation and initialization
60
+ await wallet.walletInfoPromise
61
+ await wallet.initialize()
62
+
63
+ console.log('✅ Wallet initialized successfully!')
64
+ console.log('')
65
+
66
+ // First, try to find token by listing all tokens
67
+ console.log('📦 Searching for token...')
68
+ const tokens = await wallet.listETokens()
69
+
70
+ // Find the token by ticker or ID
71
+ let selectedToken = null
72
+ let tokenId = null
73
+
74
+ // Try to match by ticker first (case-insensitive)
75
+ selectedToken = tokens.find(t =>
76
+ t.ticker.toLowerCase() === tokenInput.toLowerCase()
77
+ )
78
+
79
+ // If not found, try to match by token ID
80
+ if (!selectedToken) {
81
+ selectedToken = tokens.find(t => t.tokenId === tokenInput)
82
+ }
83
+
84
+ // If found in wallet tokens, use that token ID
85
+ if (selectedToken) {
86
+ tokenId = selectedToken.tokenId
87
+ console.log(`✅ Found token in wallet: ${selectedToken.ticker} (${selectedToken.protocol})`)
88
+ } else {
89
+ // If not found in wallet, assume it's a token ID and try anyway
90
+ tokenId = tokenInput
91
+ console.log(`🔍 Token not found in wallet, trying as token ID: ${tokenId.substring(0, 12)}...`)
92
+ }
93
+
94
+ // Get balance using main wallet API
95
+ console.log('\n💰 Getting token balance...')
96
+ const balance = await wallet.getETokenBalance({ tokenId })
97
+
98
+ console.log('')
99
+ console.log('🎯 TOKEN BALANCE DETAILS:')
100
+ console.log('═'.repeat(60))
101
+ console.log(`Token ID: ${balance.tokenId}`)
102
+ console.log(`Ticker: ${balance.ticker}`)
103
+ console.log(`Name: ${balance.name}`)
104
+ console.log(`Protocol: ${balance.protocol}`)
105
+ console.log(`Decimals: ${balance.decimals}`)
106
+ console.log('')
107
+ console.log('💰 Balance Information:')
108
+ console.log(` Display Balance: ${balance.balance.display.toLocaleString()} ${balance.ticker}`)
109
+ console.log(` Raw Atoms: ${balance.balance.atoms}`)
110
+ console.log(` UTXOs: ${balance.utxoCount}`)
111
+
112
+ // Show context about balance
113
+ if (balance.balance.display === 0) {
114
+ console.log('')
115
+ console.log('ℹ️ Zero Balance:')
116
+ console.log(' • You do not currently hold any of this token')
117
+ console.log(' • Token metadata is still accessible')
118
+ console.log(' • Token may have been spent, burned, or never received')
119
+ } else {
120
+ console.log('')
121
+ console.log('💡 Token Actions Available:')
122
+ console.log(` • Send tokens: node examples/tokens/send-any-token.js ${balance.ticker} <address> <amount>`)
123
+ console.log(` • Burn tokens: node examples/tokens/burn-tokens.js ${balance.ticker} <amount>`)
124
+ console.log(` • Get token info: node examples/tokens/get-token-info.js ${balance.ticker}`)
125
+ }
126
+
127
+ // Show wallet summary
128
+ const xecBalance = await wallet.getXecBalance()
129
+ console.log('')
130
+ console.log('📊 WALLET SUMMARY:')
131
+ console.log('═'.repeat(40))
132
+ console.log(`XEC Balance: ${xecBalance.toLocaleString()} XEC`)
133
+ console.log(`Token Balance: ${balance.balance.display.toLocaleString()} ${balance.ticker}`)
134
+ console.log(`Total UTXOs: ${balance.utxoCount} token + XEC UTXOs`)
135
+ } catch (err) {
136
+ console.error('\n❌ Failed to get token balance:', err.message)
137
+
138
+ // Provide context-specific help based on error type
139
+ if (err.message.includes('Token ID is required')) {
140
+ console.log('\n🎯 Token ID Issue:')
141
+ console.log(' • Provide a valid token ticker or full token ID')
142
+ console.log(' • Check available tokens: node examples/tokens/list-all-tokens.js')
143
+ } else if (err.message.includes('not found') || err.message.includes('Invalid token ID')) {
144
+ console.log('\n🔍 Token Not Found:')
145
+ console.log(' • Verify token ticker or ID is correct')
146
+ console.log(' • Token may not exist on this network')
147
+ console.log(' • Check available tokens: node examples/tokens/list-all-tokens.js')
148
+ } else if (err.message.includes('network') || err.message.includes('chronik')) {
149
+ console.log('\n🌐 Network Issue:')
150
+ console.log(' • Check internet connection')
151
+ console.log(' • Chronik API may be temporarily unavailable')
152
+ console.log(' • Try again in a few moments')
153
+ } else {
154
+ console.log('\n🔧 General Error:')
155
+ console.log(' • Check wallet is properly initialized')
156
+ console.log(' • Verify token ID format is correct')
157
+ console.log(' • Try listing tokens first to debug')
158
+ }
159
+
160
+ console.log('\nFor debugging, run:')
161
+ console.log(' node examples/tokens/list-all-tokens.js')
162
+ console.log(' node examples/wallet-info/get-balance.js')
163
+
164
+ process.exit(1)
165
+ }
166
+ }
167
+
168
+ // Run the balance checker
169
+ getTokenBalance()