- Home
- / Blog
- / Keys & Addresses
- / xpub, ypub and zpub: Extended Public Keys Explained
xpub, ypub and zpub: Extended Public Keys Explained
An extended public key, or xpub, is one string from which a wallet can calculate every receiving and change address of an account, without being able to spend from any of them. Its first four letters hint at the address type: a ypub or a zpub is the same key as an xpub with different version bytes, added so that a wallet would know whether to make addresses that start with 3 or with bc1q. This guide explains what is inside an extended key, which prefix belongs to which address type, how to convert between them, where wallets show yours and why it should stay private. The keys come from your seed phrase through a derivation path.
What an Extended Public Key Does
In a BIP32 wallet, every key in the tree comes with a 32-byte chain code. A public key plus its chain code is an extended public key, and it is enough to derive that key’s non-hardened children: the account key at m/84'/0'/0' produces the receiving addresses at …/0/0, …/0/1 and so on, and the change addresses at …/1/i. That is why one xpub can stand for a whole account.
- It cannot spend. An extended public key holds no private key, so it cannot sign transactions.
- It cannot climb the tree. The levels above the account are hardened, and a hardened child cannot be derived from a public key. Your account xpub reveals nothing about your other accounts or coins.
- It sees everything in its account. Every past and future address of that account, every balance and the whole history.
So an xpub is what you give to software that only needs to watch: a watch-only wallet on your phone, a payment server that creates a fresh address for each invoice, or the coordinator of a multisig wallet that needs every cosigner’s public key.
xpub, ypub and zpub at a Glance
BIP32 defined one mainnet version for public keys, which encodes as xpub, and one for private keys, xprv (tpub and tprv on testnet). It said nothing about address types, so a wallet given an xpub had to guess. SLIP-132 registered more version bytes so that the prefix would tell:
| Prefix | Version bytes | Address type | Standard | Addresses start with |
|---|---|---|---|---|
| xpub | 0488b21e | Legacy (P2PKH) or P2SH | BIP44 | 1 or 3 |
| ypub | 049d7cb2 | Nested SegWit (P2WPKH in P2SH) | BIP49 | 3 |
| zpub | 04b24746 | Native SegWit (P2WPKH) | BIP84 | bc1q |
| Ypub | 0295b43f | Multisig, nested SegWit (P2WSH in P2SH) | — | 3 |
| Zpub | 02aa7ed3 | Multisig, native SegWit (P2WSH) | — | bc1q |
On testnet the same pattern gives tpub, upub and vpub (Upub and Vpub for multisig), and other coins registered their own, such as Ltub and Mtub for Litecoin. Each public prefix has a private twin: xprv, yprv and zprv. Those are full private keys for the account and deserve the same protection as the seed phrase. Taproot accounts (BIP86) have no prefix of their own and use a plain xpub.
What Is Inside an xpub
BIP32 serializes an extended key as 78 bytes and encodes them in Base58Check, which adds a 4-byte checksum, so the string always has 111 characters. Here are the fields of the native SegWit account key of the public test phrase (abandon abandon … about):
| Field | Bytes | In the example |
|---|---|---|
| Version | 4 | 04b24746 (zpub) or 0488b21e (xpub) |
| Depth | 1 | 03: three steps below the master key, m/84'/0'/0' |
| Parent fingerprint | 4 | 7ef32bdb: identifies the parent key, m/84'/0' |
| Child number | 4 | 80000000: account 0, hardened |
| Chain code | 32 | 4a53a0ab21b9dc95… |
| Public key | 33 | 02707a62fdacc26e…, a compressed secp256k1 key |
Only the first four bytes differ between the xpub and the zpub of an account. Because they come first, though, the whole Base58 string changes, and the two look like unrelated keys.
Test Vectors: Four Standards, One Phrase
These are the account keys of the BIP39 test phrase, whose master key fingerprint is 73c5da0a. The phrase is public, so never send funds to it. Each key derives, on its own, the first receiving address of its standard, the same addresses as in our derivation path guide:
| Standard | Account path | Prefix used | First address, …/0/0 |
|---|---|---|---|
| BIP44 | m/44'/0'/0' | xpub | 1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA |
| BIP49 | m/49'/0'/0' | ypub | 37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf |
| BIP84 | m/84'/0'/0' | zpub | bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu |
| BIP86 | m/86'/0'/0' | xpub | bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr |
BIP44 xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj
BIP49 ypub6Ww3ibxVfGzLrAH1PNcjyAWenMTbbAosGNB6VvmSEgytSER9azLDWCxoJwW7Ke7icmizBMXrzBx9979FfaHxHcrArf3zbeJJJUZPf663zsP
= xpub6C6nQwHaWbSrzs5tZ1q7m5R9cPK9eYpNMFesiXsYrgc1P8bvLLAet9JfHjYXKjToD8cBRswJXXbbFpXgwsswVPAZzKMa1jUp2kVkGVUaJa7
BIP84 zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs
= xpub6CatWdiZiodmUeTDp8LT5or8nmbKNcuyvz7WyksVFkKB4RHwCD3XyuvPEbvqAQY3rAPshWcMLoP2fMFMKHPJ4ZeZXYVUhLv1VMrjPC7PW6V
BIP86 xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ
The BIP84 and BIP86 keys are the official test vectors of those BIPs, and SLIP-132 lists the same xpub, ypub and zpub in its own test vectors; we derived all of them again with the @scure/bip32 library. The seed phrase to private key converter shows the account extended keys of any test phrase, always with the xpub prefix.
Taproot and Descriptors: No New Prefixes
SLIP-132 has no prefix for Taproot: BIP86 accounts use a plain xpub, as the table above shows. Instead of adding prefixes, wallets moved to output script descriptors, which write the address type, the key origin and the key in one line:
wpkh([73c5da0a/84h/0h/0h]xpub6CatWdiZiodmUeTDp8LT5or8nmbKNcuyvz7WyksVFkKB4RHwCD3XyuvPEbvqAQY3rAPshWcMLoP2fMFMKHPJ4ZeZXYVUhLv1VMrjPC7PW6V/0/*)
tr([73c5da0a/86h/0h/0h]xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)
Descriptors are defined in BIP380 to BIP386: pkh() and sh() in BIP381, wpkh() in BIP382 and tr() in BIP386. Bitcoin Core has supported them since version 0.17. BIP380 calls extra version bytes a layer violation, because key derivation should stay separate from the script type, and its key expressions accept only BIP32’s own xpub and xprv encodings. Bitcoin Core therefore rejects a ypub or zpub in a descriptor: convert it to an xpub first. BTCPay Server follows the same idea with its own notation. A plain xpub means native SegWit, xpub…-[p2sh] nested SegWit and xpub…-[legacy] legacy addresses, and a ypub or zpub you enter is converted to an xpub when the wallet is set up.
Converting a zpub to an xpub
Since only the version bytes differ, converting is a matter of decoding the Base58Check string, swapping the first four bytes and encoding it again; the key and the addresses stay the same. Electrum does it from the command line or its console: electrum -o convert_xkey <key> p2wpkh re-encodes a key as a zpub, p2wpkh-p2sh as a ypub and standard as an xpub (in the Console tab, convert_xkey('zpub…', 'standard')). Sparrow shows both forms of a SegWit key and has a button to switch between them. Convert only public keys, and never paste an xprv, yprv or zprv into a website.
A plain xpub does not carry its address type with it. If you import the xpub of a native SegWit account, tell the wallet: choose Native Segwit in Sparrow, use a wpkh() descriptor in Bitcoin Core, or convert the key to a zpub for Electrum, which reads the type from the prefix. Otherwise the wallet derives legacy addresses that hold nothing.
Where Wallets Show Your xpub
Each wallet below was checked against its latest release in October 2026:
| Wallet | Where to find it | What it shows |
|---|---|---|
| Electrum 4.8 | Wallet → Information → Master Public Key | xpub, ypub or zpub by script type; Ypub or Zpub for multisig |
| Sparrow 2.5 | Settings → Keystores → the keystore’s xpub field | xpub, with a switch to show a SegWit key as ypub or zpub |
| BlueWallet 8 | Wallet → … → Show Wallet XPUB | zpub (BIP84), ypub (BIP49), xpub (legacy); Taproot as a tr() descriptor |
| Trezor Suite | Account → Details → Public key (XPUB) → Show public key | A descriptor with zpub, ypub or xpub; Taproot as tr() with an xpub |
| Ledger Wallet | Account → settings icon (Edit account) → Advanced | Always xpub, with a note naming its address type |
| Bitcoin Core | listdescriptors in the console (Window → Node window) | Plain xpubs inside descriptors |
A few details matter when you move a key between them:
- Electrum takes the address type from the prefix when you create a watch-only wallet from a master public key: an xpub gives legacy addresses, a ypub nested SegWit and a zpub native SegWit. It has no Taproot wallets.
- Sparrow keeps the address type in the wallet’s Script Type setting and accepts xpub, ypub and zpub for a watch-only wallet; if the prefix and the setting disagree, it warns about a script type mismatch.
- BlueWallet, given a plain xpub to watch, tries it as legacy, nested and native SegWit and offers each version that has history.
- Trezor Suite asks you to confirm on the device before it shows the key. Its mobile app can also watch an xpub you scan or paste.
- Ledger Wallet reminds you to choose the same address type when you import its xpub into another wallet, because the prefix will not say.
- Bitcoin Core makes a watch-only wallet with
importdescriptorsin a wallet with private keys disabled; the descriptor sets the address type.
Importing an xpub as a Watch-Only Wallet
A watch-only wallet built from your xpub shows balances and creates receiving addresses while the private keys stay on your hardware wallet or offline computer. To spend, you build the transaction in the watch-only wallet and sign it with the device that holds the keys, usually as a PSBT. Three settings decide whether the balance appears:
- The address type. In Electrum the prefix decides it; in Sparrow and Bitcoin Core the script type setting or the descriptor does. Taproot accounts always arrive as a plain xpub or a
tr()descriptor. - The account. An xpub covers one account only. Funds in a second account need that account’s xpub.
- The gap limit. Wallets stop scanning after a run of unused addresses, usually 20, so addresses far ahead of the last used one can stay hidden.
Keep Your xpub Private
An xpub cannot move funds, but it takes away your privacy: whoever has it can list every address of the account, past and future, see every balance and payment, and follow you as you receive coins. Give it only to software you control or trust, such as your own payment server or watch-only wallet.
There is also a security catch. BIP32 warns that knowing a parent extended public key plus any non-hardened private key that descends from it is equivalent to knowing the parent extended private key. If your account xpub has leaked and you export the private key of a single address, for example to import it into another app, an attacker who gets that key can compute the private keys of the entire account. Keep both secret, and prefer moving funds with ordinary transactions over exporting keys.
Frequently Asked Questions
Can someone steal my bitcoin with my xpub?
Not with the xpub alone: it holds no private key. It reveals every address and balance of the account, and together with any one private key from the same account it gives away all of them, so keep it private.
Why does one wallet show an xpub and another a zpub for the same account?
Wallets that follow SLIP-132 put the address type into the prefix: Electrum and BlueWallet show a zpub for a native SegWit account. Ledger Wallet, Bitcoin Core and, by default, Sparrow show a plain xpub and store the address type separately. Both are the same key, as the test vectors above show.
Is there a prefix for Taproot?
No. SLIP-132 registered none, and BIP86 accounts use a plain xpub. A tr() descriptor records that the key is meant for Taproot.
What is the difference between an xpub and an xprv?
The xprv is the private half: it contains the private key and can derive every private key of the account, so it can spend. The xpub can only derive public keys and addresses.
Does a 12-word and a 24-word phrase give a different xpub?
Yes, because they are different seeds. So does the same phrase with a BIP39 passphrase: each passphrase leads to a different master key and a different set of xpubs.