Skip to content

Commit

Permalink
Update CHANGELOG and remove old taproot example
Browse files Browse the repository at this point in the history
  • Loading branch information
junderw committed Dec 7, 2022
1 parent 9ae2089 commit f9e970a
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 269 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 6.1.0
__added__
- taproot support for payments (p2tr) and PSBT. See taproot.spec.ts integration test for examples. (#1742)

# 6.0.2
__fixed__
- p2sh payment now uses empty Buffer for redeem.output when redeemScript is OP_FALSE (#1802)
Expand Down
157 changes: 0 additions & 157 deletions test/integration/taproot.md

This file was deleted.

112 changes: 0 additions & 112 deletions test/integration/taproot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,6 @@ const bip32 = BIP32Factory(ecc);
const ECPair = ECPairFactory(ecc);

describe('bitcoinjs-lib (transaction with taproot)', () => {
it('can create (and broadcast via 3PBP) a taproot keyspend Transaction', async () => {
const myKey = bip32.fromSeed(rng(64), regtest);

const output = createKeySpendOutput(myKey.publicKey);
const address = bitcoin.address.fromOutputScript(output, regtest);
// amount from faucet
const amount = 42e4;
// amount to send
const sendAmount = amount - 1e4;
// get faucet
const unspent = await regtestUtils.faucetComplex(output, amount);

const tx = createSigned(
myKey,
unspent.txId,
unspent.vout,
sendAmount,
[output],
[amount],
);

const hex = tx.toHex();
// console.log('Valid tx sent from:');
// console.log(address);
// console.log('tx hex:');
// console.log(hex);
await regtestUtils.broadcast(hex);
await regtestUtils.verify({
txId: tx.getId(),
address,
vout: 0,
value: sendAmount,
});
});

it('can create (and broadcast via 3PBP) a taproot key-path spend Transaction', async () => {
const internalKey = bip32.fromSeed(rng(64), regtest);
const p2pkhKey = bip32.fromSeed(rng(64), regtest);
Expand Down Expand Up @@ -593,83 +558,6 @@ function buildLeafIndexFinalizer(
};
}

// Order of the curve (N) - 1
const N_LESS_1 = Buffer.from(
'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
'hex',
);
// 1 represented as 32 bytes BE
const ONE = Buffer.from(
'0000000000000000000000000000000000000000000000000000000000000001',
'hex',
);

// Function for creating a tweaked p2tr key-spend only address
// (This is recommended by BIP341)
function createKeySpendOutput(publicKey: Buffer): Buffer {
// x-only pubkey (remove 1 byte y parity)
const myXOnlyPubkey = toXOnly(publicKey);
const commitHash = bitcoin.crypto.taggedHash('TapTweak', myXOnlyPubkey);
const tweakResult = ecc.xOnlyPointAddTweak(myXOnlyPubkey, commitHash);
if (tweakResult === null) throw new Error('Invalid Tweak');
const { xOnlyPubkey: tweaked } = tweakResult;
// scriptPubkey
return Buffer.concat([
// witness v1, PUSH_DATA 32 bytes
Buffer.from([0x51, 0x20]),
// x-only tweaked pubkey
tweaked,
]);
}

// Function for signing for a tweaked p2tr key-spend only address
// (Required for the above address)
interface KeyPair {
publicKey: Buffer;
privateKey?: Buffer;
}
function signTweaked(messageHash: Buffer, key: KeyPair): Uint8Array {
const privateKey =
key.publicKey[0] === 2
? key.privateKey
: ecc.privateAdd(ecc.privateSub(N_LESS_1, key.privateKey!)!, ONE)!;
const tweakHash = bitcoin.crypto.taggedHash(
'TapTweak',
toXOnly(key.publicKey),
);
const newPrivateKey = ecc.privateAdd(privateKey!, tweakHash);
if (newPrivateKey === null) throw new Error('Invalid Tweak');
return ecc.signSchnorr(messageHash, newPrivateKey, Buffer.alloc(32));
}

// Function for creating signed tx
function createSigned(
key: KeyPair,
txid: string,
vout: number,
amountToSend: number,
scriptPubkeys: Buffer[],
values: number[],
): bitcoin.Transaction {
const tx = new bitcoin.Transaction();
tx.version = 2;
// Add input
tx.addInput(Buffer.from(txid, 'hex').reverse(), vout);
// Add output
tx.addOutput(scriptPubkeys[0], amountToSend);
const sighash = tx.hashForWitnessV1(
0, // which input
scriptPubkeys, // All previous outputs of all inputs
values, // All previous values of all inputs
bitcoin.Transaction.SIGHASH_DEFAULT, // sighash flag, DEFAULT is schnorr-only (DEFAULT == ALL)
);
const signature = Buffer.from(signTweaked(sighash, key));
// witness stack for keypath spend is just the signature.
// If sighash is not SIGHASH_DEFAULT (ALL) then you must add 1 byte with sighash value
tx.ins[0].witness = [signature];
return tx;
}

// This logic will be extracted to ecpair
function tweakSigner(signer: bitcoin.Signer, opts: any = {}): bitcoin.Signer {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down

0 comments on commit f9e970a

Please sign in to comment.