import * as ecc from "@bitcoinerlab/secp256k1";
import BIP32Factory from "bip32";
import * as bip39 from "bip39";
import * as bitcoin from "bitcoinjs-lib";
import { toXOnly } from "bitcoinjs-lib/src/psbt/bip371";
bitcoin.initEccLib(ecc);
const bip32 = BIP32Factory(ecc);
// Replace with your wallet's mnemonic phrase
const mnemonic = "your mnemonic phrase here";
// Fill in your derivation path for Taproot (BIP-86)
// This script is setup as if this account has 1 simple UTXO of more than 100000 sats
const derivationPath = `m/86'/0'/0'/0/0`;
// Replace with recipient address or leave empty for self-transfer
const recipientAddress = "";
// Replace with your Adamik API key from https://dashboard.adamik.io
const ADAMIK_API_KEY = "your-adamik-api-key";
async function main() {
try {
// Create wallet using mnemonic phrase
const seed = await bip39.mnemonicToSeed(mnemonic);
const rootKey = bip32.fromSeed(seed);
const childNode = rootKey.derivePath(derivationPath);
const internalPubkey = toXOnly(Buffer.from(childNode.publicKey));
const { address } = bitcoin.payments.p2tr({
internalPubkey,
});
console.log("Public address of sender:", address);
// Prepare the transaction request
const requestBody = {
transaction: {
data: {
chainId: "bitcoin", // Target Bitcoin
mode: "transfer", // Simple tx
senderAddress: address,
recipientAddress: recipientAddress || address,
amount: "10", // Transaction amount in satoshis
},
},
};
console.log("Encoding transaction...");
// Encode the transaction with Adamik API
const responseEncode = await fetch(
"https://api.adamik.io/api/bitcoin/transaction/encode",
{
method: "POST",
headers: {
Authorization: ADAMIK_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify(requestBody),
}
);
const encodedData = await responseEncode.json();
console.log(
"Encoded transaction data:",
JSON.stringify(encodedData, null, 2)
);
const rawtx = encodedData.transaction.encoded;
console.log("Signing transaction...");
// Create and sign the PSBT (Partially Signed Bitcoin Transaction)
const psbt = bitcoin.Psbt.fromHex(rawtx);
psbt.updateInput(0, {
tapInternalKey: internalPubkey,
});
const tweakedChildNode = childNode.tweak(
bitcoin.crypto.taggedHash("TapTweak", internalPubkey)
);
psbt.signTaprootInput(0, tweakedChildNode);
psbt.finalizeAllInputs();
const signedTransaction = psbt.extractTransaction().toHex();
console.log("Transaction signed");
// Prepare to broadcast the signed transaction
const sendTransactionBody = {
transaction: {
data: encodedData.transaction.data,
encoded: encodedData.transaction.encoded,
signature: signedTransaction,
},
};
console.log("Broadcasting transaction...");
// Broadcast the transaction using Adamik API
const responseBroadcast = await fetch(
"https://api.adamik.io/api/bitcoin/transaction/broadcast",
{
method: "POST",
headers: {
Authorization: ADAMIK_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify(sendTransactionBody),
}
);
const responseData = await responseBroadcast.json();
console.log("Transaction Result:", JSON.stringify(responseData, null, 2));
console.log("Transaction hash:", responseData.hash);
} catch (error) {
console.error("Error:", error);
}
}
main();