Embedded Wallet Differences
The Bitcoin functions work with both external wallets (browser extensions such as Xverse, Unisat, OKX, and Phantom) and Dynamic embedded wallets. Most behave identically. A few accept options that an embedded wallet cannot act on, because an embedded wallet is a single MPC key rather than a wallet application managing several addresses. This page lists every difference. If a function is not mentioned here, it behaves the same for both wallet types.Why the differences exist
An embedded Bitcoin wallet is one key at one fixed derivation path. Three consequences follow, and they explain every entry below. One address type per wallet. The address type is chosen when the wallet is created, either Native SegWit or Taproot, and cannot change afterwards. An external wallet can expose a payment address and a separate ordinals address at the same time, so its functions accept anaddressType to select between them. An embedded wallet has only one address type, so there is nothing to select.
No derived addresses. The derivation path is fixed per address type, with no account or index component, and a user has one Bitcoin embedded wallet. You cannot derive additional receiving addresses from it.
One address, encoded per network. The same key produces a different address string on each network, because only the prefix and checksum differ:
signPsbt and signPsbts
An embedded wallet signs only the inputs that belong to its own address. Inputs owned by other addresses in the PSBT are left untouched, so a PSBT can still be co-signed by another party afterwards.
signature[].address must be your wallet’s own address for the active network. On testnet, use the tb1... encoding. An address the wallet does not own is rejected rather than ignored, so a mistyped or mainnet-encoded address returns an error instead of a PSBT with nothing signed.
signature[].signingIndexes limits signing to a subset of your wallet’s inputs. Requesting an index the wallet does not own throws an error, and no input is signed.
signature[].disableAddressValidation has no effect. On an external wallet the extension verifies key ownership itself before signing, so skipping Dynamic’s check still leaves a check in place. On an embedded wallet the ownership check is the only one, so it always runs.
allowedSighash restricts which signature hash (sighash) types the wallet will sign. The type itself comes from the PSBT (BIP-174 PSBT_IN_SIGHASH_TYPE), so this option can only reject a type, never select one.
Defaults
Two separate settings determine what is signed: which inputs, and which sighash type is accepted. Omitting either one never extends signing beyond the inputs the wallet owns.An empty
allowedSighash means “accept any type”, not “use SIGHASH_ALL”. The type always comes from the PSBT. SIGHASH_ALL is the fallback only when the PSBT itself declares nothing, which is the common case for a PSBT built by sendBitcoin or a standard wallet.signMessageWithCustomOptions
Both options are ignored for embedded wallets. The call succeeds and returns a valid signature over the message, using the wallet’s single address and BIP-322.
addressType has no effect. An embedded wallet has one address type, fixed at creation, so there is nothing to select.
protocol is not supported. Embedded wallets sign messages with BIP-322 only, and Dynamic verifies the BIP-322 hash on the server. Requesting ecdsa does not change the signature that is produced.
To sign a message with an embedded wallet, use signMessage, which needs neither option.
Functions that behave the same
Related functions
- signPsbt - Sign a PSBT
- signPsbts - Sign multiple PSBTs
- signMessageWithCustomOptions - Sign a message with custom options