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.
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/minimal-xec-wallet.js +66268 -0
- package/dist/minimal-xec-wallet.min.js +55 -0
- package/examples/README.md +380 -0
- package/examples/advanced/browser-compatibility-test.js +263 -0
- package/examples/advanced/get-xec-price.js +149 -0
- package/examples/advanced/optimize-utxos.js +255 -0
- package/examples/advanced/send-op-return.js +216 -0
- package/examples/browser-test.html +350 -0
- package/examples/key-management/derive-addresses.js +191 -0
- package/examples/key-management/export-to-wif.js +114 -0
- package/examples/key-management/validate-address.js +214 -0
- package/examples/optimization/simple-consolidation-test.js +79 -0
- package/examples/optimization/test-utxo-consolidation.js +179 -0
- package/examples/test-examples.js +1204 -0
- package/examples/tokens/burn-tokens.js +293 -0
- package/examples/tokens/get-token-balance.js +169 -0
- package/examples/tokens/get-token-info.js +269 -0
- package/examples/tokens/list-all-tokens.js +162 -0
- package/examples/tokens/send-any-token.js +260 -0
- package/examples/tokens/test-main-wallet-integration.js +193 -0
- package/examples/transactions/send-all-xec.js +205 -0
- package/examples/transactions/send-to-multiple.js +217 -0
- package/examples/transactions/send-xec.js +191 -0
- package/examples/utils/show-qr.js +119 -0
- package/examples/utils/wallet-helper.js +176 -0
- package/examples/validation/comprehensive-infrastructure-test.js +210 -0
- package/examples/wallet-creation/create-new-wallet.js +67 -0
- package/examples/wallet-creation/import-from-wif.js +135 -0
- package/examples/wallet-creation/restore-from-mnemonic.js +100 -0
- package/examples/wallet-info/get-balance.js +99 -0
- package/examples/wallet-info/get-transactions.js +157 -0
- package/examples/wallet-info/get-utxos.js +145 -0
- package/examples/wallet.json +11 -0
- package/lib/adapters/robust-chronik-router.js +507 -0
- package/lib/adapters/router.js +651 -0
- package/lib/alp-token-handler.js +581 -0
- package/lib/browser-wasm-loader.js +271 -0
- package/lib/consolidate-utxos.js +338 -0
- package/lib/hybrid-token-manager.js +322 -0
- package/lib/key-derivation.js +466 -0
- package/lib/op-return.js +314 -0
- package/lib/security.js +270 -0
- package/lib/send-xec.js +396 -0
- package/lib/slp-token-handler.js +572 -0
- package/lib/token-protocol-detector.js +307 -0
- package/lib/utxos.js +303 -0
- 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()
|