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' deposit address straight from the on-chain registry — 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… (derived from get-current-aggregate-pubkey)
await client.sbtc.getSignersPublicKey(); // 33-byte aggregate key