2021-10-20 12:18:01 +02:00
|
|
|
import { ECPair } from 'ecpair';
|
2019-09-07 06:42:03 +02:00
|
|
|
import { describe, it } from 'mocha';
|
|
|
|
import * as bitcoin from '../..';
|
|
|
|
import { regtestUtils } from './_regtest';
|
|
|
|
const NETWORK = regtestUtils.network;
|
2018-07-20 08:28:14 +02:00
|
|
|
const keyPairs = [
|
2021-10-20 12:18:01 +02:00
|
|
|
ECPair.makeRandom({ network: NETWORK }),
|
|
|
|
ECPair.makeRandom({ network: NETWORK }),
|
2019-09-07 06:42:03 +02:00
|
|
|
];
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
async function buildAndSign(
|
|
|
|
depends: any,
|
|
|
|
prevOutput: any,
|
|
|
|
redeemScript: any,
|
|
|
|
witnessScript: any,
|
2019-09-12 10:35:08 +02:00
|
|
|
): Promise<null> {
|
2019-09-07 06:42:03 +02:00
|
|
|
const unspent = await regtestUtils.faucetComplex(prevOutput, 5e4);
|
2019-09-12 06:15:52 +02:00
|
|
|
const utx = await regtestUtils.fetch(unspent.txId);
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-12 06:15:52 +02:00
|
|
|
const psbt = new bitcoin.Psbt({ network: NETWORK })
|
|
|
|
.addInput({
|
|
|
|
hash: unspent.txId,
|
|
|
|
index: unspent.vout,
|
|
|
|
nonWitnessUtxo: Buffer.from(utx.txHex, 'hex'),
|
|
|
|
...(redeemScript ? { redeemScript } : {}),
|
|
|
|
...(witnessScript ? { witnessScript } : {}),
|
|
|
|
})
|
|
|
|
.addOutput({
|
|
|
|
address: regtestUtils.RANDOM_ADDRESS,
|
|
|
|
value: 2e4,
|
|
|
|
});
|
2019-06-13 06:07:00 +02:00
|
|
|
|
2019-04-07 15:27:16 +02:00
|
|
|
if (depends.signatures) {
|
2019-04-09 08:09:50 +02:00
|
|
|
keyPairs.forEach(keyPair => {
|
2019-09-12 06:15:52 +02:00
|
|
|
psbt.signInput(0, keyPair);
|
2019-09-07 06:42:03 +02:00
|
|
|
});
|
2019-04-07 15:27:16 +02:00
|
|
|
} else if (depends.signature) {
|
2019-09-12 06:15:52 +02:00
|
|
|
psbt.signInput(0, keyPairs[0]);
|
2019-04-07 15:27:16 +02:00
|
|
|
}
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-12 06:15:52 +02:00
|
|
|
return regtestUtils.broadcast(
|
|
|
|
psbt
|
|
|
|
.finalizeAllInputs()
|
|
|
|
.extractTransaction()
|
|
|
|
.toHex(),
|
|
|
|
);
|
2018-07-20 08:28:14 +02:00
|
|
|
}
|
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach(k => {
|
|
|
|
const fixtures = require('../fixtures/' + k);
|
|
|
|
const { depends } = fixtures.dynamic;
|
|
|
|
const fn: any = (bitcoin.payments as any)[k];
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
const base: any = {};
|
|
|
|
if (depends.pubkey) base.pubkey = keyPairs[0].publicKey;
|
|
|
|
if (depends.pubkeys) base.pubkeys = keyPairs.map(x => x.publicKey);
|
|
|
|
if (depends.m) base.m = base.pubkeys.length;
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
const { output } = fn(base);
|
|
|
|
if (!output) throw new TypeError('Missing output');
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-04-09 08:09:50 +02:00
|
|
|
describe('bitcoinjs-lib (payments - ' + k + ')', () => {
|
2019-04-07 15:27:16 +02:00
|
|
|
it('can broadcast as an output, and be spent as an input', async () => {
|
2019-09-07 06:42:03 +02:00
|
|
|
Object.assign(depends, { prevOutScriptType: k });
|
|
|
|
await buildAndSign(depends, output, undefined, undefined);
|
|
|
|
});
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
it(
|
|
|
|
'can (as P2SH(' +
|
|
|
|
k +
|
|
|
|
')) broadcast as an output, and be spent as an input',
|
|
|
|
async () => {
|
|
|
|
const p2sh = bitcoin.payments.p2sh({
|
|
|
|
redeem: { output },
|
|
|
|
network: NETWORK,
|
|
|
|
});
|
|
|
|
Object.assign(depends, { prevOutScriptType: 'p2sh-' + k });
|
|
|
|
await buildAndSign(
|
|
|
|
depends,
|
|
|
|
p2sh.output,
|
|
|
|
p2sh.redeem!.output,
|
|
|
|
undefined,
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2018-07-23 02:37:31 +02:00
|
|
|
// NOTE: P2WPKH cannot be wrapped in P2WSH, consensus fail
|
2019-09-07 06:42:03 +02:00
|
|
|
if (k === 'p2wpkh') return;
|
2018-07-23 02:37:31 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
it(
|
|
|
|
'can (as P2WSH(' +
|
|
|
|
k +
|
|
|
|
')) broadcast as an output, and be spent as an input',
|
|
|
|
async () => {
|
|
|
|
const p2wsh = bitcoin.payments.p2wsh({
|
|
|
|
redeem: { output },
|
|
|
|
network: NETWORK,
|
|
|
|
});
|
|
|
|
Object.assign(depends, { prevOutScriptType: 'p2wsh-' + k });
|
|
|
|
await buildAndSign(
|
|
|
|
depends,
|
|
|
|
p2wsh.output,
|
|
|
|
undefined,
|
|
|
|
p2wsh.redeem!.output,
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
it(
|
|
|
|
'can (as P2SH(P2WSH(' +
|
|
|
|
k +
|
|
|
|
'))) broadcast as an output, and be spent as an input',
|
|
|
|
async () => {
|
|
|
|
const p2wsh = bitcoin.payments.p2wsh({
|
|
|
|
redeem: { output },
|
|
|
|
network: NETWORK,
|
|
|
|
});
|
|
|
|
const p2sh = bitcoin.payments.p2sh({
|
|
|
|
redeem: { output: p2wsh.output },
|
|
|
|
network: NETWORK,
|
|
|
|
});
|
2018-07-20 08:28:14 +02:00
|
|
|
|
2019-09-07 06:42:03 +02:00
|
|
|
Object.assign(depends, { prevOutScriptType: 'p2sh-p2wsh-' + k });
|
|
|
|
await buildAndSign(
|
|
|
|
depends,
|
|
|
|
p2sh.output,
|
|
|
|
p2sh.redeem!.output,
|
|
|
|
p2wsh.redeem!.output,
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|