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,67 @@
1
+ /*
2
+ Create a new XEC wallet with a randomly generated mnemonic.
3
+ This example shows how to create a new wallet and save it to wallet.json.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ async function createNewWallet () {
10
+ try {
11
+ console.log('šŸš€ Creating new XEC wallet...\n')
12
+
13
+ // Check if wallet already exists
14
+ if (WalletHelper.walletExists()) {
15
+ console.log('āš ļø Wallet already exists!')
16
+ console.log(' Delete existing wallet first or use restore-from-mnemonic.js')
17
+ console.log(' Existing wallet path:', WalletHelper.getWalletPath())
18
+
19
+ // Show existing wallet info
20
+ const existingWallet = WalletHelper.loadWallet()
21
+ if (existingWallet) {
22
+ WalletHelper.displayWalletInfo(existingWallet)
23
+ }
24
+ return
25
+ }
26
+
27
+ // Create new wallet (no parameters = new random mnemonic)
28
+ const wallet = new MinimalXECWallet()
29
+
30
+ // Wait for wallet creation to complete
31
+ await wallet.walletInfoPromise
32
+
33
+ console.log('āœ… New wallet created successfully!\n')
34
+
35
+ // Display the wallet information
36
+ console.log('šŸ“‹ New Wallet Details:')
37
+ console.log('═'.repeat(50))
38
+ console.log(`Mnemonic: ${wallet.walletInfo.mnemonic}`)
39
+ console.log(`XEC Address: ${wallet.walletInfo.xecAddress}`)
40
+ console.log(`HD Path: ${wallet.walletInfo.hdPath}`)
41
+ console.log('═'.repeat(50))
42
+
43
+ // Save to wallet.json file
44
+ const saved = WalletHelper.saveWallet(wallet.walletInfo, 'New XEC Wallet')
45
+
46
+ if (saved) {
47
+ console.log('\nšŸŽ‰ Wallet ready for use!')
48
+ console.log(' You can now run other examples to interact with your wallet')
49
+ console.log(' Next steps:')
50
+ console.log(' • Fund your wallet by sending XEC to:', wallet.walletInfo.xecAddress)
51
+ console.log(' • Check balance: node examples/wallet-info/get-balance.js')
52
+ console.log(' • View transactions: node examples/wallet-info/get-transactions.js')
53
+ }
54
+
55
+ // Security reminder
56
+ console.log('\nšŸ” SECURITY REMINDER:')
57
+ console.log(' • Keep your mnemonic phrase safe and private')
58
+ console.log(' • Anyone with your mnemonic can access your funds')
59
+ console.log(' • Consider backing up your wallet: the mnemonic is in wallet.json')
60
+ } catch (err) {
61
+ console.error('āŒ Failed to create wallet:', err.message)
62
+ process.exit(1)
63
+ }
64
+ }
65
+
66
+ // Run the example
67
+ createNewWallet()
@@ -0,0 +1,135 @@
1
+ /*
2
+ Import an XEC wallet from a WIF (Wallet Import Format) private key.
3
+ This example shows how to import a single private key and save it to wallet.json.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ // Get WIF from command line argument or prompt for input
10
+ const readline = require('readline')
11
+
12
+ async function getWifFromUser () {
13
+ // Check if WIF provided as command line argument
14
+ const args = process.argv.slice(2)
15
+ if (args.length === 1 && (args[0].length === 52 || args[0].length === 64)) {
16
+ return args[0]
17
+ }
18
+
19
+ // Prompt user for WIF
20
+ const rl = readline.createInterface({
21
+ input: process.stdin,
22
+ output: process.stdout
23
+ })
24
+
25
+ return new Promise((resolve) => {
26
+ rl.question('Enter your WIF private key (K/L/5 for mainnet, c/9 for testnet) or hex private key: ', (wif) => {
27
+ rl.close()
28
+ resolve(wif.trim())
29
+ })
30
+ })
31
+ }
32
+
33
+ async function importFromWif () {
34
+ try {
35
+ console.log('šŸ“„ Importing XEC wallet from private key...\n')
36
+
37
+ // Check if wallet already exists
38
+ if (WalletHelper.walletExists()) {
39
+ console.log('āš ļø Wallet already exists!')
40
+ console.log(' This will overwrite your existing wallet.')
41
+
42
+ // Create backup first
43
+ const backupPath = WalletHelper.backupWallet()
44
+ if (backupPath) {
45
+ console.log(` Backup created: ${backupPath}`)
46
+ }
47
+ }
48
+
49
+ // Get WIF from user
50
+ const wif = await getWifFromUser()
51
+
52
+ if (!wif) {
53
+ console.error('āŒ No private key provided.')
54
+ console.log(' Usage: node import-from-wif.js <WIF_OR_HEX_PRIVATE_KEY>')
55
+ console.log(' WIF example: L1234...abcd (52 characters starting with K or L)')
56
+ console.log(' Hex example: 1234567890abcdef... (64 hex characters)')
57
+ process.exit(1)
58
+ }
59
+
60
+ console.log('šŸ” Validating private key...')
61
+
62
+ // Create a temporary wallet instance to validate WIF
63
+ const tempWallet = new MinimalXECWallet()
64
+ await tempWallet.walletInfoPromise
65
+
66
+ // Check if it's a valid WIF format
67
+ const isValidWIF = tempWallet.validateWIF(wif)
68
+ const isHex = wif.length === 64 && /^[a-fA-F0-9]+$/.test(wif)
69
+
70
+ if (!isValidWIF && !isHex) {
71
+ console.error('āŒ Invalid private key format.')
72
+ console.log(' Expected formats:')
73
+ console.log(' • WIF: 51-52 characters (K/L/5 for mainnet, c/9 for testnet)')
74
+ console.log(' • Hex: 64 hexadecimal characters')
75
+ console.log(` Provided: ${wif.length} characters`)
76
+ if (wif.length >= 50 && wif.length <= 53) {
77
+ console.log(' Note: This looks like a WIF but failed validation (invalid checksum?)')
78
+ }
79
+ process.exit(1)
80
+ }
81
+
82
+ // Create wallet from WIF/hex private key
83
+ const wallet = new MinimalXECWallet(wif)
84
+
85
+ // Wait for wallet creation to complete
86
+ await wallet.walletInfoPromise
87
+
88
+ console.log('āœ… Wallet imported successfully!\n')
89
+
90
+ // Display the wallet information
91
+ console.log('šŸ“‹ Imported Wallet Details:')
92
+ console.log('═'.repeat(50))
93
+ console.log(`XEC Address: ${wallet.walletInfo.xecAddress}`)
94
+ console.log(`Key Type: ${isValidWIF ? 'WIF' : 'Hex'} Private Key`)
95
+ console.log(`HD Path: ${wallet.walletInfo.hdPath || 'N/A (single key import)'}`)
96
+ if (isValidWIF) {
97
+ console.log(`Compression: ${wallet.walletInfo.isCompressed ? 'Compressed' : 'Uncompressed'}`)
98
+ console.log(`Original WIF: ${wallet.walletInfo.wif}`)
99
+ }
100
+ console.log('═'.repeat(50))
101
+
102
+ // Save to wallet.json file
103
+ const saved = WalletHelper.saveWallet(wallet.walletInfo, 'Imported XEC Wallet')
104
+
105
+ if (saved) {
106
+ console.log('\nšŸŽ‰ Wallet imported and ready for use!')
107
+ console.log(' You can now run other examples to interact with your wallet')
108
+ console.log(' Next steps:')
109
+ console.log(' • Check balance: node examples/wallet-info/get-balance.js')
110
+ console.log(' • View UTXOs: node examples/wallet-info/get-utxos.js')
111
+ console.log(' • Send XEC: node examples/transactions/send-xec.js')
112
+ }
113
+
114
+ // Important note for imported keys
115
+ console.log('\nšŸ“ IMPORTANT NOTE:')
116
+ if (!wallet.walletInfo.mnemonic) {
117
+ console.log(' • This wallet was imported from a single private key')
118
+ console.log(' • No mnemonic phrase available for recovery')
119
+ console.log(' • Make sure to backup your private key safely')
120
+ console.log(' • For HD wallet features, use restore-from-mnemonic.js instead')
121
+ }
122
+
123
+ // Security reminder
124
+ console.log('\nšŸ” SECURITY REMINDER:')
125
+ console.log(' • Your private key is now stored in wallet.json')
126
+ console.log(' • Keep this file secure and private')
127
+ console.log(' • Anyone with your private key can access your funds')
128
+ } catch (err) {
129
+ console.error('āŒ Failed to import wallet:', err.message)
130
+ process.exit(1)
131
+ }
132
+ }
133
+
134
+ // Run the example
135
+ importFromWif()
@@ -0,0 +1,100 @@
1
+ /*
2
+ Restore an existing XEC wallet from a 12-word mnemonic phrase.
3
+ This example shows how to recover a wallet and save it to wallet.json.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ // Get mnemonic from command line argument or prompt for input
10
+ const readline = require('readline')
11
+
12
+ async function getMnemonicFromUser () {
13
+ // Check if mnemonic provided as command line argument
14
+ const args = process.argv.slice(2)
15
+ if (args.length >= 12) {
16
+ return args.join(' ')
17
+ }
18
+
19
+ // Prompt user for mnemonic
20
+ const rl = readline.createInterface({
21
+ input: process.stdin,
22
+ output: process.stdout
23
+ })
24
+
25
+ return new Promise((resolve) => {
26
+ rl.question('Enter your 12-word mnemonic phrase: ', (mnemonic) => {
27
+ rl.close()
28
+ resolve(mnemonic.trim())
29
+ })
30
+ })
31
+ }
32
+
33
+ async function restoreFromMnemonic () {
34
+ try {
35
+ console.log('šŸ”„ Restoring XEC wallet from mnemonic...\n')
36
+
37
+ // Check if wallet already exists
38
+ if (WalletHelper.walletExists()) {
39
+ console.log('āš ļø Wallet already exists!')
40
+ console.log(' This will overwrite your existing wallet.')
41
+
42
+ // Create backup first
43
+ const backupPath = WalletHelper.backupWallet()
44
+ if (backupPath) {
45
+ console.log(` Backup created: ${backupPath}`)
46
+ }
47
+ }
48
+
49
+ // Get mnemonic from user
50
+ const mnemonic = await getMnemonicFromUser()
51
+
52
+ if (!mnemonic || mnemonic.split(' ').length !== 12) {
53
+ console.error('āŒ Invalid mnemonic. Please provide a 12-word mnemonic phrase.')
54
+ console.log(' Usage: node restore-from-mnemonic.js word1 word2 ... word12')
55
+ console.log(' Or run without arguments to be prompted for input')
56
+ process.exit(1)
57
+ }
58
+
59
+ console.log('šŸ” Validating mnemonic...')
60
+
61
+ // Create wallet from mnemonic
62
+ const wallet = new MinimalXECWallet(mnemonic)
63
+
64
+ // Wait for wallet creation to complete
65
+ await wallet.walletInfoPromise
66
+
67
+ console.log('āœ… Wallet restored successfully!\n')
68
+
69
+ // Display the wallet information
70
+ console.log('šŸ“‹ Restored Wallet Details:')
71
+ console.log('═'.repeat(50))
72
+ console.log(`XEC Address: ${wallet.walletInfo.xecAddress}`)
73
+ console.log(`HD Path: ${wallet.walletInfo.hdPath}`)
74
+ console.log('═'.repeat(50))
75
+
76
+ // Save to wallet.json file
77
+ const saved = WalletHelper.saveWallet(wallet.walletInfo, 'Restored XEC Wallet')
78
+
79
+ if (saved) {
80
+ console.log('\nšŸŽ‰ Wallet restored and ready for use!')
81
+ console.log(' You can now run other examples to interact with your wallet')
82
+ console.log(' Next steps:')
83
+ console.log(' • Check balance: node examples/wallet-info/get-balance.js')
84
+ console.log(' • View UTXOs: node examples/wallet-info/get-utxos.js')
85
+ console.log(' • View transactions: node examples/wallet-info/get-transactions.js')
86
+ }
87
+
88
+ // Security reminder
89
+ console.log('\nšŸ” SECURITY REMINDER:')
90
+ console.log(' • Your mnemonic phrase is now stored in wallet.json')
91
+ console.log(' • Keep this file secure and private')
92
+ console.log(' • Consider encrypting sensitive data for production use')
93
+ } catch (err) {
94
+ console.error('āŒ Failed to restore wallet:', err.message)
95
+ process.exit(1)
96
+ }
97
+ }
98
+
99
+ // Run the example
100
+ restoreFromMnemonic()
@@ -0,0 +1,99 @@
1
+ /*
2
+ Get the XEC balance of your wallet.
3
+ This example shows how to check your wallet's balance using the saved wallet.json.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ async function getBalance () {
10
+ try {
11
+ console.log('šŸ’° Getting XEC wallet balance...\n')
12
+
13
+ // Load wallet from file
14
+ const walletData = WalletHelper.loadWallet()
15
+ if (!walletData) {
16
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
17
+ return
18
+ }
19
+
20
+ // Create wallet instance from saved data
21
+ const wallet = new MinimalXECWallet(walletData.mnemonic || walletData.privateKey)
22
+ await wallet.walletInfoPromise
23
+
24
+ console.log('šŸ” Fetching balance from blockchain...')
25
+
26
+ // Get detailed balance for the wallet
27
+ const detailedBalance = await wallet.getDetailedBalance()
28
+
29
+ console.log('\nšŸ“Š Balance Information:')
30
+ console.log('═'.repeat(50))
31
+ console.log(`XEC Address: ${walletData.xecAddress}`)
32
+ console.log(`Total Balance: ${detailedBalance.total.toLocaleString()} XEC`)
33
+ console.log(` • Confirmed: ${detailedBalance.confirmed.toLocaleString()} XEC`)
34
+ console.log(` • Unconfirmed: ${detailedBalance.unconfirmed.toLocaleString()} XEC`)
35
+ console.log(`Total Satoshis: ${detailedBalance.satoshis.total.toLocaleString()}`)
36
+
37
+ // Show confirmation status
38
+ if (detailedBalance.unconfirmed > 0) {
39
+ console.log(`ā³ ${detailedBalance.unconfirmed} XEC pending confirmation`)
40
+ }
41
+ if (detailedBalance.confirmed > 0) {
42
+ console.log(`āœ… ${detailedBalance.confirmed} XEC confirmed`)
43
+ }
44
+ console.log('═'.repeat(50))
45
+
46
+ // Show balance in different formats
47
+ if (detailedBalance.total > 0) {
48
+ console.log('\nšŸ’µ Balance Breakdown:')
49
+ console.log(`• ${detailedBalance.total} XEC`)
50
+ console.log(`• ${detailedBalance.satoshis.total} satoshis`)
51
+ console.log(`• ${(detailedBalance.total / 1000000).toFixed(6)} Million XEC`)
52
+
53
+ // Approximate USD value (if price available)
54
+ try {
55
+ const xecUsdPrice = await wallet.getXecUsd()
56
+ if (xecUsdPrice > 0) {
57
+ const usdValue = detailedBalance.total * xecUsdPrice
58
+ console.log(`• ~$${usdValue.toFixed(6)} USD (at $${xecUsdPrice.toFixed(8)} per XEC)`)
59
+ }
60
+ } catch (err) {
61
+ console.log('• USD value unavailable (price API error)')
62
+ }
63
+ } else {
64
+ console.log('\nšŸ’ø Your wallet is empty!')
65
+ console.log(' To receive XEC, share your address:', walletData.xecAddress)
66
+ console.log(' You can fund your wallet from:')
67
+ console.log(' • A eCash exchange')
68
+ console.log(' • Another XEC wallet')
69
+ console.log(' • eCash faucets (for testnet)')
70
+ }
71
+
72
+ // Show additional info for empty wallets
73
+ if (detailedBalance.total === 0) {
74
+ console.log('\nšŸ”— Useful Links:')
75
+ console.log(' • Block Explorer: https://explorer.e.cash')
76
+ console.log(' • CashTab Wallet: https://cashtab.com')
77
+ console.log(' • eCash.org: https://e.cash')
78
+ }
79
+ } catch (err) {
80
+ console.error('āŒ Failed to get balance:', err.message)
81
+
82
+ // Provide helpful error context
83
+ if (err.message.includes('network') || err.message.includes('connection')) {
84
+ console.log('\n🌐 Network Error:')
85
+ console.log(' • Check your internet connection')
86
+ console.log(' • Chronik indexer might be temporarily unavailable')
87
+ console.log(' • Try again in a few moments')
88
+ } else if (err.message.includes('address')) {
89
+ console.log('\nšŸ“ Address Error:')
90
+ console.log(' • Your wallet.json might be corrupted')
91
+ console.log(' • Try restoring from mnemonic')
92
+ }
93
+
94
+ process.exit(1)
95
+ }
96
+ }
97
+
98
+ // Run the example
99
+ getBalance()
@@ -0,0 +1,157 @@
1
+ /*
2
+ Get the transaction history of your wallet.
3
+ This example shows how to view all transactions associated with your wallet address.
4
+ */
5
+
6
+ const MinimalXECWallet = require('../../index')
7
+ const WalletHelper = require('../utils/wallet-helper')
8
+
9
+ async function getTransactions () {
10
+ try {
11
+ console.log('šŸ“œ Getting wallet transaction history...\n')
12
+
13
+ // Load wallet from file
14
+ const walletData = WalletHelper.loadWallet()
15
+ if (!walletData) {
16
+ console.log(' Run: node examples/wallet-creation/create-new-wallet.js')
17
+ return
18
+ }
19
+
20
+ // Create wallet instance from saved data
21
+ const wallet = new MinimalXECWallet(walletData.mnemonic || walletData.privateKey)
22
+ await wallet.walletInfoPromise
23
+
24
+ console.log('šŸ”— Fetching transaction history from blockchain...')
25
+
26
+ // Get transaction history (default: descending order - newest first)
27
+ const transactions = await wallet.getTransactions()
28
+
29
+ console.log('\nšŸ“‹ Transaction History:')
30
+ console.log('═'.repeat(80))
31
+ console.log(`XEC Address: ${walletData.xecAddress}`)
32
+ console.log(`Total Transactions: ${transactions.length}`)
33
+ console.log('═'.repeat(80))
34
+
35
+ if (transactions.length === 0) {
36
+ console.log('\nšŸ“­ No transactions found!')
37
+ console.log(' Your wallet address has no transaction history.')
38
+ console.log(' This means:')
39
+ console.log(' • This is a new wallet that has never been used')
40
+ console.log(' • The address has never received or sent any XEC')
41
+ console.log('')
42
+ console.log(' To get started:')
43
+ console.log(' • Send some XEC to your address:', walletData.xecAddress)
44
+ console.log(' • Use a faucet (for testnet)')
45
+ console.log(' • Receive XEC from another wallet')
46
+ return
47
+ }
48
+
49
+ // Analyze transactions
50
+ let receivedCount = 0
51
+ let sentCount = 0
52
+ let totalReceived = 0
53
+ let totalSent = 0
54
+
55
+ console.log('\nšŸ“Š Transaction List (most recent first):')
56
+ console.log('─'.repeat(80))
57
+
58
+ transactions.slice(0, 10).forEach((tx, index) => {
59
+ const txidShort = `${tx.txid.substring(0, 12)}...${tx.txid.substring(52)}`
60
+ const isConfirmed = tx.block !== null
61
+ const status = isConfirmed ? 'āœ… Confirmed' : 'ā³ Pending'
62
+
63
+ console.log(`${index + 1}. ${txidShort} - ${status}`)
64
+
65
+ if (isConfirmed) {
66
+ const date = new Date(tx.block.timestamp * 1000).toLocaleString()
67
+ console.log(` Block: ${tx.block.height} | Time: ${date}`)
68
+ } else {
69
+ console.log(' Block: Unconfirmed | Time: Pending')
70
+ }
71
+
72
+ // Analyze inputs and outputs to determine if this was received or sent
73
+ let isReceived = false
74
+ let isSent = false
75
+ let netAmount = 0
76
+
77
+ // Check outputs for our address
78
+ tx.outputs.forEach(output => {
79
+ if (output.script && output.script.includes(walletData.xecAddress.replace('ecash:', ''))) {
80
+ isReceived = true
81
+ netAmount += parseInt(output.value)
82
+ }
83
+ })
84
+
85
+ // Check inputs for our address (indicates we sent this transaction)
86
+ tx.inputs.forEach(input => {
87
+ if (input.prevOut && input.prevOut.script &&
88
+ input.prevOut.script.includes(walletData.xecAddress.replace('ecash:', ''))) {
89
+ isSent = true
90
+ netAmount -= parseInt(input.prevOut.value)
91
+ }
92
+ })
93
+
94
+ if (isReceived && !isSent) {
95
+ console.log(` šŸ“„ Received: ${(netAmount / 100).toLocaleString()} XEC`)
96
+ receivedCount++
97
+ totalReceived += netAmount
98
+ } else if (isSent && !isReceived) {
99
+ console.log(` šŸ“¤ Sent: ${(Math.abs(netAmount) / 100).toLocaleString()} XEC`)
100
+ sentCount++
101
+ totalSent += Math.abs(netAmount)
102
+ } else if (isSent && isReceived) {
103
+ const action = netAmount > 0 ? 'Net Received' : 'Net Sent'
104
+ console.log(` šŸ”„ ${action}: ${(Math.abs(netAmount) / 100).toLocaleString()} XEC`)
105
+ }
106
+
107
+ console.log(` Inputs: ${tx.inputs.length} | Outputs: ${tx.outputs.length}`)
108
+ console.log()
109
+ })
110
+
111
+ if (transactions.length > 10) {
112
+ console.log(`... and ${transactions.length - 10} more transactions`)
113
+ console.log('šŸ’” Use transaction explorer for full history')
114
+ }
115
+
116
+ // Transaction summary
117
+ console.log('\nšŸ“ˆ Transaction Summary:')
118
+ console.log('─'.repeat(80))
119
+ console.log(`Total Transactions: ${transactions.length}`)
120
+ console.log(`Received Transactions: ${receivedCount}`)
121
+ console.log(`Sent Transactions: ${sentCount}`)
122
+ console.log(`Total Received: ${(totalReceived / 100).toLocaleString()} XEC`)
123
+ console.log(`Total Sent: ${(totalSent / 100).toLocaleString()} XEC`)
124
+ console.log(`Net Balance: ${((totalReceived - totalSent) / 100).toLocaleString()} XEC`)
125
+
126
+ // Show pending transactions warning
127
+ const pendingTxs = transactions.filter(tx => tx.block === null)
128
+ if (pendingTxs.length > 0) {
129
+ console.log('\nāš ļø Pending Transactions:')
130
+ console.log(` You have ${pendingTxs.length} unconfirmed transaction(s)`)
131
+ console.log(' These transactions are waiting to be included in a block')
132
+ console.log(' Confirmation usually takes 1-10 minutes')
133
+ }
134
+
135
+ // Explorer links
136
+ console.log('\nšŸ”— Explore More:')
137
+ console.log(` Address Explorer: https://explorer.e.cash/address/${walletData.xecAddress}`)
138
+ if (transactions.length > 0) {
139
+ console.log(` Latest TX: https://explorer.e.cash/tx/${transactions[0].txid}`)
140
+ }
141
+ } catch (err) {
142
+ console.error('āŒ Failed to get transactions:', err.message)
143
+
144
+ // Provide helpful error context
145
+ if (err.message.includes('network') || err.message.includes('connection')) {
146
+ console.log('\n🌐 Network Error:')
147
+ console.log(' • Check your internet connection')
148
+ console.log(' • Chronik indexer might be temporarily unavailable')
149
+ console.log(' • Try again in a few moments')
150
+ }
151
+
152
+ process.exit(1)
153
+ }
154
+ }
155
+
156
+ // Run the example
157
+ getTransactions()