banner
import { ECPairFactory, ECPairInterface } from 'ecpair';
import { initEccLib, networks, payments, Psbt, Transaction, address, script, opcodes, crypto, Network } from 'bitcoinjs-lib';
import * as ecc from 'tiny-secp256k1';
import axios from 'axios';

initEccLib(ecc);
const ECPair = ECPairFactory(ecc);

const network = networks.bitcoin

function tweakSigner(signer: ECPairInterface, opts: any = {}): any {
  let privateKey: Buffer | undefined = signer.privateKey;
  if (!privateKey) {
    throw new Error('Private key is required for tweaking signer');
  }
  const publicKey = toXOnly(signer.publicKey);
  const tweakedPrivateKey = ecc.privateAdd(
    privateKey,
    tapTweakHash(publicKey, opts.tweakHash)
  );
  if (!tweakedPrivateKey) {
    throw new Error('Invalid tweaked private key');
  }
  return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {
    network: opts.network,
  });
}

function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {
  return crypto.taggedHash(
    'TapTweak',
    Buffer.concat(h ? [pubKey, h] : [pubKey])
  );
}

function toXOnly(pubkey: Buffer): Buffer {
  return pubkey.slice(1, 33);
}

async function getUTXOs(address: string) {
  const response = await axios.get(`https://mempool-testnet.fractalbitcoin.io/api/address/${address}/utxo`);
  const utxos = response.data
  let availableUTXO = utxos.filter((k: any) => (k?.status.confirmed && k.value > 546))
  availableUTXO = availableUTXO.sort((a: any, b: any) => b.value - a.value);
  return availableUTXO;
}

export async function main() {
  const private_key = 'L5Pe2yFCjshJrXoJHkXe8xEQofYHXvNKcxGS6XqNiiS7XzETRVPF' // setting private key
  const keyPair = ECPair.fromWIF(private_key, network);

  const mainWallet = payments.p2tr({
    internalPubkey: toXOnly(keyPair.publicKey),
    network: network
  });

  const utxos = await getUTXOs(String(mainWallet.address))
  console.log(utxos)
  const utxo = utxos[0]

  const finalPsbt = new Psbt({ network });

  const tweakedSigner = tweakSigner(keyPair, { network });

  finalPsbt.addInput({
    hash: utxo.txid,
    index: utxo.vout,
    witnessUtxo: {
      script: mainWallet.output!,
      value: utxo.value,
    },
    tapInternalKey: toXOnly(keyPair.publicKey)
  });

  finalPsbt.addOutput({
    address: mainWallet.address!,
    value: 10000,
  });

  finalPsbt.signInput(0, tweakedSigner);  // this will get error

}

main();

Then I got error: Error: Can not sign for input #0 with the key 03c3f349586717e8707ef8e0d74
I think the possible reason is utxo vout is 0
How to fix this? Thanks.

This can online edit : codesandbox online test

banner

Converter

Source: CurrencyRate
Top Selling Multipurpose WP Theme

Newsletter

Subscribe my Newsletter for new blog posts, tips & new photos. Let's stay updated!

banner

Leave a Comment

Layer 1
Your Crypto & Blockchain Beacon

CryptoInsightful

Welcome to CryptoInsightful.com, your trusted source for in-depth analysis, news, and insights into the world of cryptocurrencies, blockchain technology, NFTs (Non-Fungible Tokens), and cybersecurity. Our mission is to empower you with the knowledge and understanding you need to navigate the rapidly evolving landscape of digital assets and emerging technologies.