| … | … | @@ -5,7 +5,7 @@ |
| 5 | 5 | * MODULE: CommonJS |
| 6 | 6 | * |
| 7 | 7 | * PURPOSE: |
| 8 | | * Address validation with cryptographic checksum verification |
| 8 | * Address validation with basic format checking |
| 9 | 9 | * |
| 10 | 10 | * USED BY: |
| 11 | 11 | * - wallet-server.cjs (transaction and contact validation) |
| … | … | @@ -13,16 +13,17 @@ |
| 13 | 13 | * KEY EXPORTS: |
| 14 | 14 | * - validateAddress(address, chain, network) - Generic validator |
| 15 | 15 | * - validateBitcoinAddress(address, network) - Bitcoin with Base58Check/Bech32 |
| 16 | | * - validateEthereumAddress(address) - Ethereum with EIP-55 checksum |
| 16 | * - validateEthereumAddress(address) - Ethereum format check only |
| 17 | 17 | * |
| 18 | 18 | * VALIDATION: |
| 19 | | * - Bitcoin: Base58Check (P2PKH, P2SH) and Bech32/Bech32m (SegWit) |
| 20 | | * - Ethereum: EIP-55 mixed-case checksum (keccak256) |
| 19 | * - Bitcoin: Full checksum validation (Base58Check and Bech32/Bech32m) |
| 20 | * - Ethereum: Format check only (EIP-55 checksum disabled - Pear module resolution issues) |
| 21 | 21 | * - Returns: { valid: boolean, reason?: string, warning?: string } |
| 22 | * |
| 23 | * NOTE: EIP-55 checksum validation disabled due to Pear module resolution bug with @noble/hashes |
| 22 | 24 | */ |
| 23 | 25 | |
| 24 | 26 | const crypto = require('bare-crypto') |
| 25 | | const { keccak_256 } = require('@noble/hashes/sha3') |
| 26 | 27 | |
| 27 | 28 | /** |
| 28 | 29 | * Bitcoin Base58 alphabet (no 0, O, I, l to avoid confusion) |
| … | … | @@ -224,7 +225,7 @@ function validateBitcoinAddress(address, network = 'testnet') { |
| 224 | 225 | } |
| 225 | 226 | |
| 226 | 227 | /** |
| 227 | | * Validate Ethereum address with EIP-55 checksum |
| 228 | * Validate Ethereum address (format only, NO EIP-55 checksum) |
| 228 | 229 | * @param {string} address - Ethereum address (0x...) |
| 229 | 230 | * @returns {Object} { valid: boolean, reason?: string, warning?: string } |
| 230 | 231 | */ |
| … | … | @@ -234,42 +235,10 @@ function validateEthereumAddress(address) { |
| 234 | 235 | return { valid: false, reason: 'Invalid Ethereum address format (expected 0x + 40 hex chars)' } |
| 235 | 236 | } |
| 236 | 237 | |
| 237 | | const addressNoPrefix = address.slice(2) |
| 238 | | |
| 239 | | // All lowercase or all uppercase = no checksum (valid but warn) |
| 240 | | if (addressNoPrefix === addressNoPrefix.toLowerCase() || |
| 241 | | addressNoPrefix === addressNoPrefix.toUpperCase()) { |
| 242 | | return { valid: true, warning: 'No EIP-55 checksum (address not checksummed)' } |
| 243 | | } |
| 244 | | |
| 245 | | // Verify EIP-55 checksum using keccak256 |
| 246 | | try { |
| 247 | | // Hash the lowercase address |
| 248 | | const hash = keccak_256(addressNoPrefix.toLowerCase()) |
| 249 | | const hashHex = Buffer.from(hash).toString('hex') |
| 250 | | |
| 251 | | // Check each character |
| 252 | | for (let i = 0; i < 40; i++) { |
| 253 | | const char = addressNoPrefix[i] |
| 254 | | const hashChar = hashHex[i] |
| 255 | | |
| 256 | | // If hash digit >= 8, char should be uppercase; otherwise lowercase |
| 257 | | if (parseInt(hashChar, 16) >= 8) { |
| 258 | | if (char !== char.toUpperCase()) { |
| 259 | | return { valid: false, reason: 'Invalid EIP-55 checksum (character case mismatch)' } |
| 260 | | } |
| 261 | | } else { |
| 262 | | if (char !== char.toLowerCase()) { |
| 263 | | return { valid: false, reason: 'Invalid EIP-55 checksum (character case mismatch)' } |
| 264 | | } |
| 265 | | } |
| 266 | | } |
| 267 | | |
| 268 | | return { valid: true } |
| 269 | | } catch (err) { |
| 270 | | console.error('EIP-55 checksum validation error:', err) |
| 271 | | return { valid: true, warning: 'EIP-55 checksum validation failed, accepting address' } |
| 272 | | } |
| 238 | // EIP-55 checksum validation DISABLED |
| 239 | // bare-crypto doesn't support keccak256, and installing @noble/hashes breaks Pear module resolution |
| 240 | // Accepting all properly formatted addresses regardless of checksum |
| 241 | return { valid: true, warning: 'EIP-55 checksum validation disabled (Pear module resolution limitation)' } |
| 273 | 242 | } |
| 274 | 243 | |
| 275 | 244 | /** |