Skip to content

Instantly share code, notes, and snippets.

@ECBSJ
Created September 25, 2024 16:25
Show Gist options
  • Save ECBSJ/4ba99a13c241ed1ac132cf1a37d2c27d to your computer and use it in GitHub Desktop.
Save ECBSJ/4ba99a13c241ed1ac132cf1a37d2c27d to your computer and use it in GitHub Desktop.
Fetching bitcoin tx metadata needed for `clarity-bitcoin-lib-v5` contract's `was-tx-mined-compact` function parameters.
import mempoolJS from "@mempool/mempool.js"
import { Transaction } from "bitcoinjs-lib"
const {
bitcoin: { transactions, blocks }
} = mempoolJS({
hostname: "mempool.space"
})
export const getTxHex = async txid => {
const txHex = await transactions.getTxHex({ txid })
return txHex
}
export const getTxMerkleProof = async txid => {
// Using mempool.space's GET /api/tx/:txid/merkle-proof
const { block_height, merkle, pos } = await transactions.getTxMerkleProof({ txid })
return { block_height, merkle, pos }
}
export const getBlkHeader = async height => {
let blockHash = await blocks.getBlockHeight({ height })
// Using mempool.space's GET /api/block/:hash/header
const blockHeader = await blocks.getBlockHeader({ hash: blockHash })
return { blockHash, blockHeader }
}
export const removeWitnessData = txHex => {
const tx = Transaction.fromHex(txHex)
if (!tx.hasWitnesses()) {
return txHex
}
// Create a new empty transaction
const newTx = new Transaction()
// Copy version from original transaction
newTx.version = tx.version
// Copy inputs from original transaction
tx.ins.forEach(input => {
newTx.addInput(input.hash, input.index, input.sequence, input.script)
})
// Copy outputs from original transaction
tx.outs.forEach(output => {
newTx.addOutput(output.script, output.value)
})
// Copy locktime from original transaction
newTx.locktime = tx.locktime
return newTx.toHex()
}
import {
callReadOnlyFunction,
bufferCV,
uintCV,
tupleCV,
listCV,
cvToString,
} from "@stacks/transactions"
import { StacksMainnet } from "@stacks/network"
import { hexToBytes } from "@stacks/common"
import { getTxHex, getTxMerkleProof, getBlkHeader, removeWitnessData } from "./btc-tx-data.js"
import { mainnetAddress } from "./wallets.js"
const mainnet = new StacksMainnet()
// From read-only function of below clarity-bitcoin implementation contract:
const contractAddress = "SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9"
const contractName = "clarity-bitcoin-lib-v5"
const functionName = "was-tx-mined-compact"
// fetching btc tx details. You can replace this with any bitcoin transaction id.
let txid = "7ad7414063ab0f7ce7d5b1b6b4a87091094bd0e9be0e6a44925a48e1eb2ca51c"
// fetching and returning non-witness tx hex
let fullTxHex = await getTxHex(txid)
let txHex = removeWitnessData(fullTxHex)
let { block_height, merkle, pos } = await getTxMerkleProof(txid)
let { blockHeader } = await getBlkHeader(block_height)
let txIndex = pos
let hashes = merkle.map(hash => bufferCV(hexToBytes(hash).reverse()))
let treeDepth = merkle.length
let functionArgs = [
// (height)
uintCV(block_height),
// (tx)
bufferCV(Buffer.from(txHex, "hex")),
// (header)
bufferCV(Buffer.from(blockHeader, "hex")),
// (proof)
tupleCV({
"tx-index": uintCV(txIndex),
hashes: listCV(hashes),
"tree-depth": uintCV(treeDepth)
})
]
let result = await callReadOnlyFunction({
contractAddress,
contractName,
functionName,
functionArgs,
network: mainnet,
// this could be any principal address
senderAddress: mainnetAddress
})
console.log(cvToString(result))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment