mirror of https://github.com/lukechilds/vainjs.git
Luke Childs
6 years ago
4 changed files with 125 additions and 153 deletions
@ -0,0 +1,30 @@ |
|||
import test from 'ava'; |
|||
import Vain from '..'; |
|||
|
|||
const invalidCharsets = [ |
|||
{ |
|||
addressFormat: 'p2pkh', |
|||
prefix: '0' |
|||
}, |
|||
{ |
|||
addressFormat: 'p2wpkh-p2sh', |
|||
prefix: '0' |
|||
}, |
|||
{ |
|||
addressFormat: 'p2wpkh', |
|||
prefix: '1' |
|||
} |
|||
]; |
|||
|
|||
invalidCharsets.forEach(options => { |
|||
test(`Vain throws when \`options.prefix\` doesn't match the charset for ${options.addressFormat} addresses`, t => { |
|||
const error = t.throws(() => new Vain(options)); |
|||
t.true(error.message.includes('Invalid characters for address format')); |
|||
}); |
|||
}); |
|||
|
|||
test('Vain throws when `options.prefix` is `undefined`', t => { |
|||
const options = {}; |
|||
const error = t.throws(() => new Vain(options)); |
|||
t.is(error.message, 'Prefix must be set'); |
|||
}); |
@ -0,0 +1,17 @@ |
|||
import test from 'ava'; |
|||
import * as bitcoin from 'bitcoinjs-lib'; |
|||
import Vain from '..'; |
|||
|
|||
test('Vain defaults to p2pkh if no address format is set', t => { |
|||
const options = { |
|||
prefix: 'A' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, wif} = vain.generate(); |
|||
|
|||
const keyPair = bitcoin.ECPair.fromWIF(wif); |
|||
const {address: wifAddress} = bitcoin.payments.p2pkh({pubkey: keyPair.publicKey}); |
|||
|
|||
t.true(address.startsWith(`1${options.prefix}`)); |
|||
t.is(address, wifAddress); |
|||
}); |
@ -1,153 +0,0 @@ |
|||
import test from 'ava'; |
|||
import * as bitcoin from 'bitcoinjs-lib'; |
|||
import * as bip39 from 'bip39'; |
|||
import Vain from '..'; |
|||
|
|||
test('Vain is exported', t => { |
|||
t.not(Vain, undefined); |
|||
}); |
|||
|
|||
test('Vain derives a p2pkh vanity address', t => { |
|||
const options = { |
|||
addressFormat: 'p2pkh', |
|||
prefix: 'A' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, wif} = vain.generate(); |
|||
|
|||
const keyPair = bitcoin.ECPair.fromWIF(wif); |
|||
const {address: wifAddress} = bitcoin.payments.p2pkh({pubkey: keyPair.publicKey}); |
|||
|
|||
t.true(address.startsWith(`1${options.prefix}`)); |
|||
t.is(address, wifAddress); |
|||
}); |
|||
|
|||
test('Vain derives a p2wpkh-p2sh vanity address', t => { |
|||
const options = { |
|||
addressFormat: 'p2wpkh-p2sh', |
|||
prefix: 'A' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, wif} = vain.generate(); |
|||
|
|||
const keyPair = bitcoin.ECPair.fromWIF(wif); |
|||
const {address: wifAddress} = bitcoin.payments.p2sh({ |
|||
redeem: bitcoin.payments.p2wpkh({pubkey: keyPair.publicKey}) |
|||
}); |
|||
|
|||
t.true(address.startsWith(`3${options.prefix}`)); |
|||
t.is(address, wifAddress); |
|||
}); |
|||
|
|||
test('Vain derives a p2wpkh vanity address', t => { |
|||
const options = { |
|||
addressFormat: 'p2wpkh', |
|||
prefix: 'a' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, wif} = vain.generate(); |
|||
|
|||
const keyPair = bitcoin.ECPair.fromWIF(wif); |
|||
const {address: wifAddress} = bitcoin.payments.p2wpkh({pubkey: keyPair.publicKey}); |
|||
|
|||
t.true(address.startsWith(`bc1q${options.prefix}`)); |
|||
t.is(address, wifAddress); |
|||
}); |
|||
|
|||
test('Vain derives a p2pkh vanity seed', async t => { |
|||
const options = { |
|||
keyFormat: 'bip39', |
|||
addressFormat: 'p2pkh', |
|||
prefix: 'A' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, derivationPath, mnemonic} = vain.generate(); |
|||
|
|||
const seed = await bip39.mnemonicToSeed(mnemonic); |
|||
const node = bitcoin.bip32.fromSeed(seed); |
|||
const {publicKey} = node.derivePath(derivationPath); |
|||
const {address: seedAddress} = bitcoin.payments.p2pkh({pubkey: publicKey}); |
|||
|
|||
t.true(address.startsWith(`1${options.prefix}`)); |
|||
t.is(address, seedAddress); |
|||
}); |
|||
|
|||
test('Vain derives a p2wpkh-p2sh vanity seed', async t => { |
|||
const options = { |
|||
keyFormat: 'bip39', |
|||
addressFormat: 'p2wpkh-p2sh', |
|||
prefix: 'A' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, derivationPath, mnemonic} = vain.generate(); |
|||
|
|||
const seed = await bip39.mnemonicToSeed(mnemonic); |
|||
const node = bitcoin.bip32.fromSeed(seed); |
|||
const {publicKey} = node.derivePath(derivationPath); |
|||
const {address: seedAddress} = bitcoin.payments.p2sh({ |
|||
redeem: bitcoin.payments.p2wpkh({pubkey: publicKey}) |
|||
}); |
|||
|
|||
t.true(address.startsWith(`3${options.prefix}`)); |
|||
t.is(address, seedAddress); |
|||
}); |
|||
|
|||
test('Vain derives a p2wpkh vanity seed', async t => { |
|||
const options = { |
|||
keyFormat: 'bip39', |
|||
addressFormat: 'p2wpkh', |
|||
prefix: 'a' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, derivationPath, mnemonic} = vain.generate(); |
|||
|
|||
const seed = await bip39.mnemonicToSeed(mnemonic); |
|||
const node = bitcoin.bip32.fromSeed(seed); |
|||
const {publicKey} = node.derivePath(derivationPath); |
|||
const {address: seedAddress} = bitcoin.payments.p2wpkh({pubkey: publicKey}); |
|||
|
|||
t.true(address.startsWith(`bc1q${options.prefix}`)); |
|||
t.is(address, seedAddress); |
|||
}); |
|||
|
|||
test('Vain defaults to p2pkh if no address format is set', t => { |
|||
const options = { |
|||
prefix: 'A' |
|||
}; |
|||
const vain = new Vain(options); |
|||
const {address, wif} = vain.generate(); |
|||
|
|||
const keyPair = bitcoin.ECPair.fromWIF(wif); |
|||
const {address: wifAddress} = bitcoin.payments.p2pkh({pubkey: keyPair.publicKey}); |
|||
|
|||
t.true(address.startsWith(`1${options.prefix}`)); |
|||
t.is(address, wifAddress); |
|||
}); |
|||
|
|||
test('Vain throws on invalid charset', t => { |
|||
const optionsArray = [ |
|||
{ |
|||
addressFormat: 'p2pkh', |
|||
prefix: '0' |
|||
}, |
|||
{ |
|||
addressFormat: 'p2wpkh-p2sh', |
|||
prefix: '0' |
|||
}, |
|||
{ |
|||
addressFormat: 'p2wpkh', |
|||
prefix: '1' |
|||
} |
|||
]; |
|||
|
|||
optionsArray.forEach(options => { |
|||
const error = t.throws(() => new Vain(options)); |
|||
t.true(error.message.includes('Invalid characters for address format')); |
|||
}); |
|||
}); |
|||
|
|||
test('Vain throws on undefined prefix', t => { |
|||
const options = {}; |
|||
const error = t.throws(() => new Vain(options)); |
|||
t.is(error.message, 'Prefix must be set'); |
|||
}); |
@ -0,0 +1,78 @@ |
|||
import test from 'ava'; |
|||
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 keyFormats = ['wif', 'bip39']; |
|||
|
|||
const testCases = [ |
|||
{ |
|||
options: { |
|||
addressFormat: 'p2pkh', |
|||
prefix: 'A' |
|||
}, |
|||
expectedPrefix: '1A' |
|||
}, |
|||
{ |
|||
options: { |
|||
addressFormat: 'p2wpkh-p2sh', |
|||
prefix: 'A' |
|||
}, |
|||
expectedPrefix: '3A' |
|||
}, |
|||
{ |
|||
options: { |
|||
addressFormat: 'p2wpkh', |
|||
prefix: 'a' |
|||
}, |
|||
expectedPrefix: 'bc1qa' |
|||
} |
|||
]; |
|||
|
|||
keyFormats.forEach(keyFormat => { |
|||
testCases.forEach(({options, expectedPrefix}) => { |
|||
options = {...options, keyFormat}; |
|||
|
|||
test(`Vain generates a valid ${options.keyFormat} ${options.addressFormat} vanity address`, async t => { |
|||
const vain = new Vain(options); |
|||
const {address, ...keyData} = vain.generate(); |
|||
|
|||
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; |
|||
} |
|||
|
|||
default: |
|||
} |
|||
|
|||
const keyAddress = deriveAddress[options.addressFormat](publicKey); |
|||
|
|||
t.true(address.startsWith(expectedPrefix)); |
|||
t.is(address, keyAddress); |
|||
}); |
|||
}); |
|||
}); |
Loading…
Reference in new issue