|
|
@ -3,93 +3,99 @@ import * as bitcoin from 'bitcoinjs-lib'; |
|
|
|
import * as bip39 from 'bip39'; |
|
|
|
import Vain from '..'; |
|
|
|
|
|
|
|
const deriveAddress = { |
|
|
|
p2pkh: pubkey => { |
|
|
|
return bitcoin.payments.p2pkh({pubkey}).address; |
|
|
|
}, |
|
|
|
'p2wpkh-p2sh': pubkey => { |
|
|
|
return bitcoin.payments.p2sh({ |
|
|
|
redeem: bitcoin.payments.p2wpkh({pubkey}) |
|
|
|
}).address; |
|
|
|
}, |
|
|
|
p2wpkh: pubkey => { |
|
|
|
return bitcoin.payments.p2wpkh({pubkey}).address; |
|
|
|
} |
|
|
|
const addressFormats = { |
|
|
|
p2pkh: require('../src/address-formats/p2pkh'), |
|
|
|
'p2wpkh-p2sh': require('../src/address-formats/p2wpkh-p2sh'), |
|
|
|
p2wpkh: require('../src/address-formats/p2wpkh'), |
|
|
|
p2sh: require('../src/address-formats/p2sh') |
|
|
|
}; |
|
|
|
|
|
|
|
const xpub = 'xpub6EDZZg3os4RaLxfPpnGBb7ajm6ccyjRs3PGZ5jNK31rPnbpyKb7dc87cEPaLEjFYDBGCQT8VMm8q8MVj2tj7HPBu8syxu82cdHLCNaQmT42'; |
|
|
|
|
|
|
|
const testCases = [ |
|
|
|
{ |
|
|
|
options: { |
|
|
|
addressFormat: 'p2pkh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
expectedPrefix: '1A' |
|
|
|
keyFormat: 'wif', |
|
|
|
addressFormat: 'p2pkh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
{ |
|
|
|
options: { |
|
|
|
addressFormat: 'p2wpkh-p2sh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
expectedPrefix: '3A' |
|
|
|
keyFormat: 'wif', |
|
|
|
addressFormat: 'p2wpkh-p2sh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
{ |
|
|
|
options: { |
|
|
|
addressFormat: 'p2wpkh', |
|
|
|
prefix: 'a' |
|
|
|
}, |
|
|
|
expectedPrefix: 'bc1qa' |
|
|
|
} |
|
|
|
]; |
|
|
|
|
|
|
|
const additionalOptionCombos = [ |
|
|
|
keyFormat: 'wif', |
|
|
|
addressFormat: 'p2wpkh', |
|
|
|
prefix: 'a' |
|
|
|
}, |
|
|
|
{ |
|
|
|
keyFormat: 'wif' |
|
|
|
keyFormat: 'bip39', |
|
|
|
addressFormat: 'p2pkh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
{ |
|
|
|
keyFormat: 'bip39' |
|
|
|
keyFormat: 'bip39', |
|
|
|
addressFormat: 'p2wpkh-p2sh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
{ |
|
|
|
keyFormat: 'bip39', |
|
|
|
addressFormat: 'p2wpkh', |
|
|
|
prefix: 'a' |
|
|
|
}, |
|
|
|
{ |
|
|
|
keyFormat: 'xpub', |
|
|
|
xpub: 'xpub6EDZZg3os4RaLxfPpnGBb7ajm6ccyjRs3PGZ5jNK31rPnbpyKb7dc87cEPaLEjFYDBGCQT8VMm8q8MVj2tj7HPBu8syxu82cdHLCNaQmT42' |
|
|
|
xpub, |
|
|
|
addressFormat: 'p2pkh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
{ |
|
|
|
keyFormat: 'xpub', |
|
|
|
xpub, |
|
|
|
addressFormat: 'p2wpkh-p2sh', |
|
|
|
prefix: 'A' |
|
|
|
}, |
|
|
|
{ |
|
|
|
keyFormat: 'xpub', |
|
|
|
xpub, |
|
|
|
addressFormat: 'p2wpkh', |
|
|
|
prefix: 'a' |
|
|
|
} |
|
|
|
]; |
|
|
|
|
|
|
|
additionalOptionCombos.forEach(additionalOptions => { |
|
|
|
testCases.forEach(({options, expectedPrefix}) => { |
|
|
|
options = {...options, ...additionalOptions}; |
|
|
|
testCases.forEach(options => { |
|
|
|
test(`Vain generates a valid ${options.keyFormat} ${options.addressFormat} vanity address`, async t => { |
|
|
|
const addressFormat = addressFormats[options.addressFormat]; |
|
|
|
const vain = new Vain(options); |
|
|
|
const {address, ...keyData} = vain.generate(); |
|
|
|
|
|
|
|
test(`Vain generates a valid ${options.keyFormat} ${options.addressFormat} vanity address`, async t => { |
|
|
|
const vain = new Vain(options); |
|
|
|
const {address, ...keyData} = vain.generate(); |
|
|
|
let key; |
|
|
|
|
|
|
|
let publicKey; |
|
|
|
|
|
|
|
switch (options.keyFormat) { |
|
|
|
case 'wif': { |
|
|
|
({publicKey} = bitcoin.ECPair.fromWIF(keyData.wif)); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case 'bip39': { |
|
|
|
const seed = await bip39.mnemonicToSeed(keyData.mnemonic); |
|
|
|
const node = bitcoin.bip32.fromSeed(seed); |
|
|
|
({publicKey} = node.derivePath(keyData.derivationPath)); |
|
|
|
break; |
|
|
|
} |
|
|
|
switch (options.keyFormat) { |
|
|
|
case 'wif': { |
|
|
|
key = bitcoin.ECPair.fromWIF(keyData.wif); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case 'xpub': { |
|
|
|
const node = bitcoin.bip32.fromBase58(keyData.xpub); |
|
|
|
({publicKey} = node.derivePath(keyData.derivationPath)); |
|
|
|
break; |
|
|
|
} |
|
|
|
case 'bip39': { |
|
|
|
const seed = await bip39.mnemonicToSeed(keyData.mnemonic); |
|
|
|
const node = bitcoin.bip32.fromSeed(seed); |
|
|
|
key = node.derivePath(keyData.derivationPath); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
case 'xpub': { |
|
|
|
const node = bitcoin.bip32.fromBase58(keyData.xpub); |
|
|
|
key = node.derivePath(keyData.derivationPath); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
const keyAddress = deriveAddress[options.addressFormat](publicKey); |
|
|
|
default: |
|
|
|
} |
|
|
|
|
|
|
|
const keyAddress = addressFormat.derive(key); |
|
|
|
|
|
|
|
t.true(address.startsWith(expectedPrefix)); |
|
|
|
t.is(address, keyAddress); |
|
|
|
}); |
|
|
|
t.true(address.startsWith(addressFormat.prefix + options.prefix)); |
|
|
|
t.is(address, keyAddress); |
|
|
|
}); |
|
|
|
}); |
|
|
|