diff --git a/README.md b/README.md index 8025ea5..6deeb02 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP). - [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L87) - [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L109) - [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L149) +- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2WPKH input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L174) - [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L184) - [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L17) - [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L24) diff --git a/test/integration/transactions.js b/test/integration/transactions.js index 5358461..73b83c5 100644 --- a/test/integration/transactions.js +++ b/test/integration/transactions.js @@ -171,6 +171,95 @@ describe('bitcoinjs-lib (transactions)', function () { }) }) + it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input (via a P2SH(P2WPKH) transaction)', function (done) { + this.timeout(30000) + + const keyPair = bitcoin.ECPair.makeRandom({ network: regtest }) + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: regtest }) + + // prepare a P2SH(P2WPKH) faucet transaction, as Bitcoin-core doesn't support bare P2WPKH outputs (...yet) + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: regtest }) + + regtestUtils.faucet(p2sh.address, 10e4, function (err, unspent) { + if (err) return done(err) + + const txvb = new bitcoin.TransactionBuilder(regtest) + txvb.addInput(unspent.txId, unspent.vout) + txvb.addOutput(p2wpkh.address, 6e4) // funds a P2WPKH address + txvb.sign(0, keyPair, p2sh.redeem.output, null, unspent.value) + const txv = txvb.build() + + // build and broadcast (the via transaction) to the Bitcoin RegTest network + regtestUtils.broadcast(txv.toHex(), function (err) { + if (err) return done(err) + + // XXX: build the Transaction w/ a P2WPKH input + const txb = new bitcoin.TransactionBuilder(regtest) + txb.addInput(txv.getId(), 0, null, p2wpkh.output) // NOTE: provide the prevOutScript! + txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4) + txb.sign(0, keyPair, null, null, 6e4) // NOTE: no redeem script + const tx = txb.build() + + // build and broadcast (the P2WPKH transaction) to the Bitcoin RegTest network + regtestUtils.broadcast(tx.toHex(), function (err) { + if (err) return done(err) + + regtestUtils.verify({ + txId: tx.getId(), + address: regtestUtils.RANDOM_ADDRESS, + vout: 0, + value: 2e4 + }, done) + }) + }) + }) + }) + + it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input (via a P2SH(P2PK) transaction)', function (done) { + this.timeout(30000) + + const keyPair = bitcoin.ECPair.makeRandom({ network: regtest }) + const p2pk = bitcoin.payments.p2pk({ pubkey: keyPair.publicKey, network: regtest }) + const p2wsh = bitcoin.payments.p2wsh({ redeem: p2pk, network: regtest }) + + // prepare a P2SH(P2PK) faucet transaction, as Bitcoin-core doesn't support bare P2WSH outputs (...yet) + const p2sh = bitcoin.payments.p2sh({ redeem: p2pk, network: regtest }) + + regtestUtils.faucet(p2sh.address, 10e4, function (err, unspent) { + if (err) return done(err) + + const txvb = new bitcoin.TransactionBuilder(regtest) + txvb.addInput(unspent.txId, unspent.vout) + txvb.addOutput(p2wsh.address, 6e4) // funds a P2WPKH address + txvb.sign(0, keyPair, p2sh.redeem.output) + const txv = txvb.build() + + // build and broadcast (the via transaction) to the Bitcoin RegTest network + regtestUtils.broadcast(txv.toHex(), function (err) { + if (err) return done(err) + + // XXX: build the Transaction w/ a P2WSH input + const txb = new bitcoin.TransactionBuilder(regtest) + txb.addInput(txv.getId(), 0, null, p2wsh.output) // NOTE: provide the prevOutScript! + txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4) + txb.sign(0, keyPair, null, null, 6e4, p2wsh.redeem.output) // NOTE: provide a witnessScript! + const tx = txb.build() + + // build and broadcast (the P2WSH transaction) to the Bitcoin RegTest network + regtestUtils.broadcast(tx.toHex(), function (err) { + if (err) return done(err) + + regtestUtils.verify({ + txId: tx.getId(), + address: regtestUtils.RANDOM_ADDRESS, + vout: 0, + value: 2e4 + }, done) + }) + }) + }) + }) + it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', function (done) { this.timeout(50000)