Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Bitcoin addresses from the same mnemonic

Derive the paired BTC account (what Leather/Xverse show next to your Stacks address) with no extra dependencies: BIP84 native segwit or BIP86 taproot, network-aware:

import { mnemonicToBitcoinKeys } from "@secondlayer/stacks/accounts";
 
const btc = mnemonicToBitcoinKeys(mnemonic, { type: "p2tr" });
btc.address; // bc1p…   (path m/86'/0'/0'/0/0)
 
mnemonicToBitcoinKeys(mnemonic, { type: "p2wpkh", network: "testnet" }).address; // tb1q…

Pure derivation: no Bitcoin transaction building or signing. The pubkey→address helpers (publicKeyToP2wpkhAddress, publicKeyToP2trAddress, taprootTweakPubkey) are exported from @secondlayer/stacks/bitcoin, validated against the BIP84/86/341 test vectors.

The sBTC extension uses the same machinery to derive the signers' peg address (where the signers hold BTC and where sweeps pay) straight from the on-chain registry. It is not a deposit address: deposits use their own P2TR deposit script. Network-aware, so testnet gives tb1p… instead of a wrong-network address:

const client = createPublicClient({ chain: mainnet, transport: http() }).extend(sbtc());
await client.sbtc.getSignersAddress();   // bc1p… (format active at the node's burn tip)
await client.sbtc.getSignersPublicKey(); // 33-byte aggregate key (v1 only)

The peg script changes at Bitcoin height 972,295 (SBTC_V2_SIGNING_BURN_HEIGHT_MAINNET):

FormatHeightsPeg output
v1below 972,295p2tr(aggregate pubkey), key path
v2972,295 and abovetr(NUMS_V2, multi_a(threshold, signer/0/0, …)) from the registry signer set

Pass { version: "v1" | "v2" } or { burnBlockHeight } to pick one. Off mainnet, pass version or v2ActivationBurnHeight. From 972,295 until the first v2 sweep confirms, the funds are still at the v1 address. Once DKG is disabled, the registry's aggregate key becomes the marker 0xFF || block hash, and getSignersPublicKey throws SbtcV2MarkerError instead of returning it. deriveSbtcV2PegOutput(keys, threshold) returns the v2 script, scriptPubKey and address from any signer set.