Nieuw Tekstdocument
Nieuw Tekstdocument
// See bottom of file for some helper functions used to make the payment objects
needed.
it('can create (and broadcast via 3PBP) a typical Transaction', async () => {
// these are { payment: Payment; keys: ECPair[] }
const alice1 = createPayment('p2pkh');
const alice2 = createPayment('p2pkh');
// If your signer object's sign method returns a promise, use the following
// await signer2.signAllInputsAsync(alice2.keys[0])
// encode to send back to combiner (signer 1 and 2 are not near each other)
const s1text = signer1.toBase64();
const s2text = signer2.toBase64();
it('can create (and broadcast via 3PBP) a Transaction with an OP_RETURN output',
async () => {
const alice1 = createPayment('p2pkh');
const inputData1 = await getInputData(
2e5,
alice1.payment,
false,
'noredeem',
);
assert.strictEqual(psbt.validateSignaturesOfInput(0), true);
psbt.finalizeAllInputs();
assert.strictEqual(psbt.validateSignaturesOfInput(0), true);
assert.strictEqual(
psbt.validateSignaturesOfInput(0, multisig.keys[0].publicKey),
true,
);
assert.throws(() => {
psbt.validateSignaturesOfInput(0, multisig.keys[3].publicKey);
}, new RegExp('No signatures for this pubkey'));
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 1e4,
});
});
await regtestUtils.verify({
txId: tx.getId(),
address: p2sh.payment.address,
vout: 0,
value: 2e4,
});
});
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input', async
() => {
// the only thing that changes is you don't give a redeemscript for input data
assert.strictEqual(psbt.validateSignaturesOfInput(0), true);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
});
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input with
nonWitnessUtxo', async () => {
// For learning purposes, ignore this test.
// REPEATING ABOVE BUT WITH nonWitnessUtxo by passing false to getInputData
const p2wpkh = createPayment('p2wpkh');
const inputData = await getInputData(
5e4,
p2wpkh.payment,
false,
'noredeem',
);
const psbt = new bitcoin.Psbt({ network: regtest })
.addInput(inputData)
.addOutput({
address: regtestUtils.RANDOM_ADDRESS,
value: 2e4,
})
.signInput(0, p2wpkh.keys[0]);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.broadcast(tx.toHex());
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
});
assert.strictEqual(psbt.validateSignaturesOfInput(0), true);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
});
it(
'can create (and broadcast via 3PBP) a Transaction, w/ a ' +
'P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input',
async () => {
const p2sh = createPayment('p2sh-p2wsh-p2ms(3 of 4)');
const inputData = await getInputData(
5e4,
p2sh.payment,
true,
'p2sh-p2wsh',
);
{
const {
hash,
index,
witnessUtxo,
redeemScript,
witnessScript,
} = inputData;
assert.deepStrictEqual(
{ hash, index, witnessUtxo, redeemScript, witnessScript },
inputData,
);
}
assert.strictEqual(psbt.validateSignaturesOfInput(0), true);
assert.strictEqual(
psbt.validateSignaturesOfInput(0, p2sh.keys[3].publicKey),
true,
);
assert.throws(() => {
psbt.validateSignaturesOfInput(0, p2sh.keys[1].publicKey);
}, new RegExp('No signatures for this pubkey'));
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
},
);
it(
'can create (and broadcast via 3PBP) a Transaction, w/ a ' +
'P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input with nonWitnessUtxo',
async () => {
// For learning purposes, ignore this test.
// REPEATING ABOVE BUT WITH nonWitnessUtxo by passing false to getInputData
const p2sh = createPayment('p2sh-p2wsh-p2ms(3 of 4)');
const inputData = await getInputData(
5e4,
p2sh.payment,
false,
'p2sh-p2wsh',
);
const psbt = new bitcoin.Psbt({ network: regtest })
.addInput(inputData)
.addOutput({
address: regtestUtils.RANDOM_ADDRESS,
value: 2e4,
})
.signInput(0, p2sh.keys[0])
.signInput(0, p2sh.keys[2])
.signInput(0, p2sh.keys[3]);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.broadcast(tx.toHex());
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
},
);
it(
'can create (and broadcast via 3PBP) a Transaction, w/ a ' +
'P2SH(P2MS(2 of 2)) input with nonWitnessUtxo',
async () => {
const myKey = bitcoin.ECPair.makeRandom({ network: regtest });
const myKeys = [
myKey,
bitcoin.ECPair.fromPrivateKey(myKey.privateKey!, { network: regtest }),
];
const p2sh = createPayment('p2sh-p2ms(2 of 2)', myKeys);
const inputData = await getInputData(5e4, p2sh.payment, false, 'p2sh');
const psbt = new bitcoin.Psbt({ network: regtest })
.addInput(inputData)
.addOutput({
address: regtestUtils.RANDOM_ADDRESS,
value: 2e4,
})
.signInput(0, p2sh.keys[0]);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.broadcast(tx.toHex());
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
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;
// You can add extra attributes for updateData into the addInput(s) object(s)
Object.assign(inputData, updateData);
assert.strictEqual(psbt.validateSignaturesOfInput(0), true);
assert.strictEqual(
psbt.validateSignaturesOfInput(0, childNode.publicKey),
true,
);
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
await regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4,
});
});
});
return {
payment,
keys,
};
}