I wrote the following function to build and sign a Taproot (P2TR) transaction using @cmdcode/tapscript: My intention is to support spending on both key and script paths.
The problem is that it doesn’t work as expected.
Script-Path spending often fails validation (e.g. block error, invalid witness, or failed script execution).
Can someone review my code and point out what’s wrong with my logic or implementation? I especially appreciate the advice on how to fix performance improvements in script path failures and key path cases.
import { Address, Signer, Tap, Tx } from '@cmdcode/tapscript';
protected buildTaprootTx(
senderKey: { publicKey: Uint8Array; privateKey: Uint8Array },
utxos: Array<{ txid: string; vout: number; value: number }>,
recipient: string,
amountSat: number,
feeSat: number,
mode: 'key' | 'script' | 'both',
scriptLeaves: Array = (),
opReturnData?: Uint8Array | string,
changeAddr?: string
): string {
// ... (full code as in my gist, see link below)
}
Complete code
question:
What am I doing wrong, especially when it comes to script path spending?
Is there a better way to configure or optimize features for performance and accuracy?
If you find any obvious bugs or misconceptions in how you use TapRoot key/Script Path Logic, please point them out.
Code reviews, suggestions, or references to practical examples are highly appreciated. thank you!
Discover more from Earlybirds Invest
Subscribe to get the latest posts sent to your email.

