Skip to content

Instantly share code, notes, and snippets.

@ottosch
Created June 8, 2025 17:05
Show Gist options
  • Save ottosch/7955d8040bc2d46fbb64e3b94ebcb3b8 to your computer and use it in GitHub Desktop.
Save ottosch/7955d8040bc2d46fbb64e3b94ebcb3b8 to your computer and use it in GitHub Desktop.
Code used to create transaction 749fdc72f1c99398899425253875deb1d7e5e040db14014ea57db71c610dad26 - #FreeSamourai
#! /usr/bin/env node
const fs = require("fs");
const bitcoin = require("bitcoinjs-lib");
const ecc = require("tiny-secp256k1");
const { ECPairFactory } = require("ecpair");
const ECPair = ECPairFactory(ecc);
bitcoin.initEccLib(ecc);
const network = bitcoin.networks.bitcoin;
const wif = "<to_be_filled>";
const keyPair = ECPair.fromWIF(wif, network);
const internalPubkey = keyPair.publicKey.subarray(1);
const { output } = bitcoin.payments.p2tr({ internalPubkey, network });
const tweakedKeyPair = keyPair.tweak(
bitcoin.crypto.taggedHash("TapTweak", internalPubkey),
);
const inputValue = 3501;
const burnValue = 1;
const psbt = new bitcoin.Psbt({ network });
psbt.addInput({
hash: "<to_be_filled>",
index: 1,
witnessUtxo: {
script: output,
value: inputValue
},
tapInternalKey: internalPubkey
});
const outputs = asciiFileToOutputs("art.txt");
psbt.addOutputs(outputs);
psbt.signAllInputs(tweakedKeyPair);
psbt.finalizeAllInputs();
const fee = inputValue - burnValue * outputs.length;
const tx = psbt.extractTransaction();
const size = tx.virtualSize();
const feeRate = (fee / size).toFixed(2);
console.log(`Size: ${size} vb`);
console.log(`Fee: ${fee} sats`);
console.log(`Fee: ${feeRate} sat/vb`);
console.log();
console.log("\nTransaction hex:")
console.log(tx.toHex());
function asciiFileToOutputs(filename) {
const content = fs.readFileSync(filename).toString().trim().split("\n");
const outputs = [];
for (const line of content) {
const data = Buffer.from(line, "utf8");
const embed = bitcoin.payments.embed({ data: [data] });
outputs.push({
script: embed.output,
value: burnValue,
});
}
return outputs;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment