diff --git a/test/integration/taproot.md b/test/integration/taproot.md
index 2db6eef..4010340 100644
--- a/test/integration/taproot.md
+++ b/test/integration/taproot.md
@@ -25,68 +25,108 @@ A simple keyspend example that is possible with the current API is below.
 - node >= v14
 
 ```js
-const crypto = require('crypto');
+// Run this whole file as async
+// Catch any errors at the bottom of the file
+// and exit the process with 1 error code
+(async () => {
 
+// 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'
+);
+
+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
+const ecc = await import('tiny-secp256k1');
+// wrap the bip32 library
+const bip32 = BIP32Wrapper(ecc);
+// 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 });
+// 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 myKey = bip32.fromSeed(crypto.randomBytes(64), regtestUtils.network);
 
-    const bip32 = BIP32Wrapper(ecc);
+const output = createKeySpendOutput(myKey.publicKey);
+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 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 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,
+});
 
-    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 a tweaked p2tr key-spend only address
+// (This is recommended by BIP341)
+function createKeySpendOutput(publicKey) {
+  // x-only pubkey (remove 1 byte y parity)
+  const myXOnlyPubkey = publicKey.slice(1, 33);
+  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)
+function signTweaked(messageHash, key) {
+  const privateKey =
+    key.publicKey[0] === 2
+      ? key.privateKey
+      : ecc.privateAdd(ecc.privateSub(N_LESS_1, key.privateKey), ONE);
+  const tweakHash = bitcoin.crypto.taggedHash(
+    'TapTweak',
+    key.publicKey.slice(1, 33)
+  );
+  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, txid, vout, amountToSend, scriptPubkeys, values) {
@@ -102,10 +142,15 @@ function createSigned(key, txid, vout, amountToSend, scriptPubkeys, values) {
     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));
+  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;
 }
+
+})().catch((err) => {
+  console.error(err);
+  process.exit(1);
+});
 ```
\ No newline at end of file