@aladas-org/cryptocalc
Version:
Cryptocurrency wallet generator
133 lines (111 loc) • 4.98 kB
JavaScript
// tests/unit/crypto/simple_wallet_format.test.js
// Tests PURS pour le format Simple Wallet
class SimpleWalletValidator {
// Vérifie que c'est une adresse P2PKH (commence par 1)
static isP2PKHAddress(address) {
if (typeof address !== 'string') return false;
// Format P2PKH: commence par 1, 26-35 caractères alphanum
const p2pkhRegex = /^1[1-9A-HJ-NP-Za-km-z]{25,34}$/;
return p2pkhRegex.test(address);
}
// Vérifie WIF pour Simple Wallet (souvent non-compressed = commence par 5)
static isSimpleWalletWIF(wif) {
if (typeof wif !== 'string') return false;
// WIF mainnet non-compressed
const wifRegex = /^5[1-9A-HJ-NP-Za-km-z]{49,50}$/;
return wifRegex.test(wif);
}
// Vérifie qu'il n'y a pas de composants HD
static isNonHDWallet(walletData) {
if (!walletData || typeof walletData !== 'object') return false;
const hdKeys = ['derivationPath', 'xpub', 'xpriv', 'accountIndex', 'changeIndex'];
return !hdKeys.some(key => key in walletData);
}
// Calcule l'adresse attendue depuis la clé privée (simplifié)
static getExpectedAddressType(privateKeyHex) {
// Pour Simple Wallet, l'adresse dépend de la compression
// Retourne 'P2PKH' pour non-compressed (commence par 1)
return 'P2PKH';
}
// Valide une paire clé privée/adresse
static validateKeyPair(privateKeyWIF, address) {
if (!this.isSimpleWalletWIF(privateKeyWIF)) return false;
if (!this.isP2PKHAddress(address)) return false;
// Les deux doivent être mainnet
const isMainnetWIF = privateKeyWIF.startsWith('5') ||
privateKeyWIF.startsWith('L') ||
privateKeyWIF.startsWith('K');
const isMainnetAddress = address.startsWith('1') ||
address.startsWith('3') ||
address.startsWith('bc1');
return isMainnetWIF && isMainnetAddress;
}
}
describe('Simple Wallet Bitcoin Format', () => {
describe('Adresses P2PKH (Simple Wallet)', () => {
const p2pkhAddresses = [
'1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', // Satoshi
'1BitcoinEaterAddressDontSendf59kuE',
'12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX',
'1MDUoxL1bGvMxhuoDYx6i11ePytECAk9QK'
];
p2pkhAddresses.forEach(address => {
test(`Adresse P2PKH valide: ${address.substring(0, 8)}...`, () => {
expect(SimpleWalletValidator.isP2PKHAddress(address)).toBe(true);
expect(address.startsWith('1')).toBe(true);
});
});
const nonP2pkhAddresses = [
'3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy', // P2SH (commence par 3)
'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4', // Bech32
'2A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', // Fake
'not-an-address'
];
nonP2pkhAddresses.forEach(address => {
test(`NON P2PKH: ${address}`, () => {
expect(SimpleWalletValidator.isP2PKHAddress(address)).toBe(false);
});
});
});
describe('WIF Simple Wallet', () => {
test('WIF non-compressed (commence par 5)', () => {
const wif = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ';
expect(SimpleWalletValidator.isSimpleWalletWIF(wif)).toBe(true);
});
test('WIF compressed (commence par L/K) - accepté aussi', () => {
const wifCompressed = 'KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ';
// Notre regex accepte seulement '5', mais on pourrait l'étendre
expect(wifCompressed.startsWith('K')).toBe(true);
});
});
describe('Validation Simple Wallet vs HD Wallet', () => {
test('Simple Wallet ne contient pas de champs HD', () => {
const simpleWallet = {
address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
privateKey: 'abc123',
publicKey: '04...'
};
const hdWallet = {
address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
privateKey: 'abc123',
derivationPath: "m/44'/0'/0'/0/0",
xpub: 'xpub...'
};
expect(SimpleWalletValidator.isNonHDWallet(simpleWallet)).toBe(true);
expect(SimpleWalletValidator.isNonHDWallet(hdWallet)).toBe(false);
});
});
describe('Validation paire clé/adresse', () => {
test('Paire valide P2PKH + WIF mainnet', () => {
// Exemple théorique
const wif = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ';
const address = '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa';
// Note: ces deux ne correspondent pas vraiment, c'est pour la structure
expect(SimpleWalletValidator.validateKeyPair(wif, address)).toBe(true);
});
test('Paire invalide', () => {
expect(SimpleWalletValidator.validateKeyPair('not-wif', '1Address')).toBe(false);
expect(SimpleWalletValidator.validateKeyPair('5WIF...', 'bc1Address')).toBe(false);
});
});
});