import {p2pkh, OutScript} from '@scure/btc-signer/payment';
import {getInputType, getPrevOut, Transaction} from '@scure/btc-signer/transaction';
import {concatBytes} from '@scure/btc-signer/utils';
import secp256k1 from 'secp256k1';
const publicKey = "<the wallet's public key>";
const publicKeyBuffer = Buffer.from(publicKey, 'hex');
const tx = new Transaction({version: 1, allowLegacyWitnessUtxo: true});
// add as many outputs as needed, in this example there is only one
tx.addOutputAddress(outputAddress, outputAmount);
tx.addInput({
txid, // buffer of utxo txid
index: 0, // index of the output in the tx
witnessUtxo: {
amount: inputAmount,
script: p2pkh(publicKeyBuffer).script
}
});
// Loop through each input and sign it
for (let i = 0; i < tx.inputsLength; i++) {
const input = tx.getInput(i);
const inputType = getInputType(input, tx.opts.allowLegacyWitnessUtxo);
const prevOut = getPrevOut(input);
let script = inputType.lastScript;
if (inputType.last.type === 'wpkh') {
script = OutScript.encode({type: 'pkh', hash: inputType.last.hash});
}
const hash = tx.preimageWitnessV0(i, script, inputType.sighash, prevOut.amount);
const signature = ''; // call Privy's raw sign function with bytesToHex(hash), returns '0x...'
// convert to DER format
const derSig = secp256k1.signatureImport(signature);
// update the input with the signature
tx.updateInput(
i,
{
partialSig: [[publicKeyBuffer, concatBytes(derSig, new Uint8Array([inputType.sighash]))]]
},
true
);
}
// finalize the transaction. It is now ready to be sent!
tx.finalize();