Update integration test with HD example

This commit is contained in:
junderw 2019-07-19 12:03:32 +09:00
parent 4366b621d7
commit 1c5b0025c8
No known key found for this signature in database
GPG key ID: B256185D3A971908

View file

@ -1,6 +1,8 @@
const { describe, it } = require('mocha');
const assert = require('assert');
const bitcoin = require('../../');
const bip32 = require('bip32');
const rng = require('randombytes');
const regtestUtils = require('./_regtest');
const regtest = regtestUtils.network;
@ -403,24 +405,87 @@ describe('bitcoinjs-lib (transactions with psbt)', () => {
value: 2e4,
});
});
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input using HD', async () => {
const hdRoot = bip32.fromSeed(rng(64));
const masterFingerprint = hdRoot.fingerprint;
const path = "m/84'/0'/0'/0/0";
const childNode = hdRoot.derivePath(path);
const pubkey = childNode.publicKey;
// This information should be added to your input via updateInput
// You can add multiple bip32Derivation objects for multisig, but
// each must have a unique pubkey.
//
// This is useful because as long as you store the masterFingerprint on
// the PSBT Creator's server, you can have the PSBT Creator do the heavy
// lifting with derivation from your m/84'/0'/0' xpub, (deriving only 0/0 )
// and your signer just needs to pass in an HDSigner interface (ie. bip32 library)
const updateData = {
bip32Derivation: [
{
masterFingerprint,
path,
pubkey,
}
]
}
const p2wpkh = createPayment('p2wpkh', [childNode]);
const inputData = await getInputData(5e4, p2wpkh.payment, true, 'noredeem');
{
const { hash, index, witnessUtxo } = inputData;
assert.deepStrictEqual({ hash, index, witnessUtxo }, inputData);
}
// You can add extra attributes for updateData into the addInput(s) object(s)
Object.assign(inputData, updateData)
const psbt = new bitcoin.Psbt({ network: regtest })
.addInput(inputData)
// .updateInput(0, updateData) // if you didn't merge the bip32Derivation with inputData
.addOutput({
address: regtestUtils.RANDOM_ADDRESS,
value: 2e4,
})
.signInputHD(0, hdRoot); // must sign with root!!!
assert.strictEqual(psbt.validateSignatures(0), true);
assert.strictEqual(psbt.validateSignatures(0, childNode.publicKey), true);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
// build and broadcast to the Bitcoin RegTest network
await regtestUtils.broadcast(tx.toHex());
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
});
});
function createPayment(_type, network) {
function createPayment(_type, myKeys, network) {
network = network || regtest;
const splitType = _type.split('-').reverse();
const isMultisig = splitType[0].slice(0, 4) === 'p2ms';
const keys = [];
const keys = myKeys || [];
let m;
if (isMultisig) {
const match = splitType[0].match(/^p2ms\((\d+) of (\d+)\)$/);
m = parseInt(match[1]);
let n = parseInt(match[2]);
while (n > 1) {
if (keys.length > 0 && keys.length !== n) {
throw new Error('Need n keys for multisig')
}
while (!myKeys && n > 1) {
keys.push(bitcoin.ECPair.makeRandom({ network }));
n--;
}
}
keys.push(bitcoin.ECPair.makeRandom({ network }));
if (!myKeys) keys.push(bitcoin.ECPair.makeRandom({ network }));
let payment;
splitType.forEach(type => {