From 24e5cc061699cf66e63df7b371d4d1171646d529 Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Fri, 12 Nov 2021 12:39:56 +0900
Subject: [PATCH] Add Taproot example

---
 CHANGELOG.md                |  13 +++++
 README.md                   |   7 +--
 test/integration/taproot.md | 111 ++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+), 4 deletions(-)
 create mode 100644 test/integration/taproot.md

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4e1eb7..f7d8f91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+# 6.0.0
+__removed__
+- bip32: Removed the re-export. Please add as dependency to your app instead.
+- ECPair: Please use bip32 moving forward. ecpair package was created for those who need it.
+- TransactionBuilder: Any internal files used only in TB (classify, templates, etc.) were also removed.
+
+__added__
+- taproot segwit v1 address support (bech32m) via address module (#1676)
+- hashForWitnessV1 method on Transaction class (#1745)
+
+__fixed__
+- Transaction version read/write differed. (#1717)
+
 # 5.2.0
 __changed__
 - Updated PSBT to allow for witnessUtxo and nonWitnessUtxo simultaneously (Re: segwit psbt bug) (#1563)
diff --git a/README.md b/README.md
index d974624..9389a73 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,5 @@
 # BitcoinJS (bitcoinjs-lib)
-[![Build Status](https://travis-ci.org/bitcoinjs/bitcoinjs-lib.png?branch=master)](https://travis-ci.org/bitcoinjs/bitcoinjs-lib)
-[![NPM](https://img.shields.io/npm/v/bitcoinjs-lib.svg)](https://www.npmjs.org/package/bitcoinjs-lib)
-
-[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
+[![Github CI](https://github.com/bitcoinjs/bitcoinjs-lib/actions/workflows/main_ci.yml/badge.svg)](https://github.com/bitcoinjs/bitcoinjs-lib/actions/workflows/main_ci.yml) [![NPM](https://img.shields.io/npm/v/bitcoinjs-lib.svg)](https://www.npmjs.org/package/bitcoinjs-lib) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
 
 A javascript Bitcoin library for node.js and browsers. Written in TypeScript, but committing the JS files to verify.
 
@@ -94,6 +91,8 @@ The below examples are implemented as integration tests, they should be very eas
 Otherwise, pull requests are appreciated.
 Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
 
+- [Taproot Key Spend](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/taproot.md)
+
 - [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.spec.ts)
 - [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.spec.ts)
 - [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.spec.ts)
diff --git a/test/integration/taproot.md b/test/integration/taproot.md
new file mode 100644
index 0000000..2db6eef
--- /dev/null
+++ b/test/integration/taproot.md
@@ -0,0 +1,111 @@
+# Taproot
+
+A simple keyspend example that is possible with the current API is below.
+
+## Current state of taproot support
+
+- [x] segwit v1 address support via bech32m
+- [x] segwit v1 sighash calculation on Transaction class
+
+## TODO
+
+- [ ] p2tr payment API to make script spends easier
+- [ ] Support within the Psbt class
+
+## Example
+
+### Requirements
+- npm dependencies
+  - bitcoinjs-lib v6.x.x
+  - bip32 v3.x.x
+  - tiny-secp256k1 v2.x.x
+  - regtest-client vx.x.x
+- local regtest-server docker container running
+  - `docker run -d -p 8080:8080 junderw/bitcoinjs-regtest-server`
+- node >= v14
+
+```js
+const crypto = require('crypto');
+
+// bitcoinjs-lib v6
+const bitcoin = require('bitcoinjs-lib');
+// bip32 v3 wraps tiny-secp256k1
+const BIP32Wrapper = require('bip32').default;
+const RegtestUtils = require('regtest-client').RegtestUtils;
+// tiny-secp256k1 v2 is an ESM module, so we can't "require", and must import async
+import('tiny-secp256k1')
+  .then(async (ecc) => {
+    // End imports
+
+    // set up dependencies
+    const APIPASS = process.env.APIPASS || 'satoshi';
+    // docker run -d -p 8080:8080 junderw/bitcoinjs-regtest-server
+    const APIURL = process.env.APIURL || 'http://127.0.0.1:8080/1';
+    const regtestUtils = new RegtestUtils({ APIPASS, APIURL });
+
+    const bip32 = BIP32Wrapper(ecc);
+
+    const myKey = bip32.fromSeed(crypto.randomBytes(64), regtestUtils.network);
+    // scriptPubkey
+    const output = Buffer.concat([
+      // witness v1, PUSH_DATA 32 bytes
+      Buffer.from([0x51, 0x20]),
+      // x-only pubkey (remove 1 byte y parity)
+      myKey.publicKey.slice(1, 33),
+    ]);
+    const address = bitcoin.address.fromOutputScript(
+      output,
+      regtestUtils.network
+    );
+    // 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,
+    });
+  })
+  .catch(console.error);
+
+// Function for creating signed tx
+function createSigned(key, txid, vout, amountToSend, scriptPubkeys, values) {
+  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(key.signSchnorr(sighash));
+  // 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;
+}
+```
\ No newline at end of file