> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Embedded Wallet Differences

> How Bitcoin functions behave differently with embedded wallets

# 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 an `addressType` 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:

```
bc1qw66rqtzzzfew70rjz7gtpehwwunl2wjzums3sz   mainnet
tb1qw66rqtzzzfew70rjz7gtpehwwunl2wjzkatzt3   testnet
```

These are the same wallet, not two addresses. Where a function takes an address, pass the encoding for the network you are signing on.

## signPsbt and signPsbts

<Note>
  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.
</Note>

**`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.

| Condition                           | Result                                                                              |
| ----------------------------------- | ----------------------------------------------------------------------------------- |
| `signingIndexes` omitted            | Every input the wallet owns is signed. Inputs owned by anyone else are skipped.     |
| `signingIndexes` provided           | Only the listed inputs are signed, and each must be one the wallet owns.            |
| `allowedSighash` omitted or `[]`    | No restriction. Whatever type the PSBT declares is accepted.                        |
| `allowedSighash` provided           | An input declaring a type outside the list throws an error, and no input is signed. |
| PSBT input declares no sighash type | `SIGHASH_ALL` (`0x01`), or `SIGHASH_DEFAULT` (`0x00`) on a Taproot wallet.          |

<Note>
  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](/docs/javascript/reference/bitcoin/send-bitcoin) or a standard wallet.
</Note>

<Warning>
  `SIGHASH_NONE` produces a signature that does not commit to the transaction outputs, and `SIGHASH_SINGLE` commits to only one output index. Anyone holding the signed PSBT can change the remaining outputs before broadcasting. Use `allowedSighash` to restrict signing to the types your application expects, for example `[0x01, 0x81]` for `SIGHASH_ALL` and `SIGHASH_ALL | ANYONECANPAY`.
</Warning>

## signMessageWithCustomOptions

<Note>
  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.
</Note>

**`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](/docs/javascript/reference/wallets/sign-message), which needs neither option.

## Functions that behave the same

| Function                                                                                     | Notes                                                                           |
| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [addBitcoinExtension](/docs/javascript/reference/bitcoin/adding-bitcoin-extension)                | Required for both wallet types                                                  |
| [isBitcoinWalletAccount](/docs/javascript/reference/bitcoin/checking-bitcoin-wallet-account-type) | Works for both wallet types                                                     |
| [sendBitcoin](/docs/javascript/reference/bitcoin/send-bitcoin)                                    | Builds, signs, and broadcasts using the wallet's address for the active network |
| [sendRawTransaction](/docs/javascript/reference/bitcoin/send-raw-transaction)                     | Broadcasts a transaction that is already signed, so the wallet does no signing  |

## Related functions

* [signPsbt](/docs/javascript/reference/bitcoin/sign-psbt) - Sign a PSBT
* [signPsbts](/docs/javascript/reference/bitcoin/sign-psbts) - Sign multiple PSBTs
* [signMessageWithCustomOptions](/docs/javascript/reference/bitcoin/sign-message-with-custom-options) - Sign a message with custom options
