> For the complete documentation index, see [llms.txt](/llms.txt).

# Integrate Embedded Wallets with the Bitcoin Blockchain

When using the Embedded Wallets Web SDK (formerly Web3Auth) for non-EVM chains like [Bitcoin](https://developer.bitcoin.org/), you can access the user's private key from the provider. With this private key, you can use the appropriate Bitcoin libraries to perform actions such as retrieving the user's account information, fetching their balance, signing transactions, and sending transactions. We've highlighted a few methods here to help you get started quickly.

note

The SDKs are now branded as MetaMask Embedded Wallet SDKs (formerly Web3Auth Plug and Play SDKs). Package names and APIs remain Web3Auth (for example, Web3Auth React SDK), and code snippets may reference `web3auth` identifiers.

## Installation[​](#installation "Direct link to Installation")

- npm
- Yarn
- pnpm
- Bun

```
npm install --save bitcoinjs-lib ecpair axios

```

```
yarn add bitcoinjs-lib ecpair axios

```

```
pnpm add bitcoinjs-lib ecpair axios

```

```
bun add bitcoinjs-lib ecpair axios

```

## Initializing provider[​](#initializing-provider "Direct link to Initializing provider")

### Getting the `chainConfig`[​](#getting-the-chainconfig "Direct link to getting-the-chainconfig")

- Mainnet
- Testnet

- Chain Namespace: OTHER
- Chain ID: Bitcoin
- Public RPC URL: `https://api.blockcypher.com/v1/btc/main` (Avoid using public rpcTarget in production)
- Display Name: Bitcoin Mainnet
- Block Explorer Link: `https://blockstream.info/`
- Ticker: BTC
- Ticker Name: Bitcoin

- Chain Namespace: OTHER
- Chain ID: Bitcoin
- Public RPC URL: `https://api.blockcypher.com/v1/btc/test3` (Avoid using public rpcTarget in production)
- Display Name: Bitcoin Testnet
- Block Explorer Link: `https://blockstream.info/testnet/`
- Ticker: tBTC
- Ticker Name: Bitcoin Testnet

## Get Bitcoin account and keypair[​](#get-bitcoin-account-and-keypair "Direct link to Get Bitcoin account and keypair")

Once a user logs in, the Embedded Wallets SDK returns a provider. Since there isn't a native provider for Bitcoin, we use the private key directly to create the KeyPair using the necessary Bitcoin libraries.

Using the function, `web3auth.provider.request({method: "private_key"})` from Web3Auth provider, the application can have access to the user's private key. This private key can be used to derive the Bitcoin KeyPair using the `bitcoinjs-lib` library.

```
import { IProvider } from '@web3auth/base'
import ecc from '@bitcoinerlab/secp256k1'
import ECPairFactory from 'ecpair'
import { Psbt, networks, payments, crypto, initEccLib } from 'bitcoinjs-lib'
import axios from 'axios'

/*
  Use code from the above Initializing Provider here
*/

// web3authProvider is web3auth.provider from above
const privateKey = await web3authProvider.request({ method: 'private_key' })

const keyPair = ECPair.fromPrivateKey(Buffer.from(privateKey, 'hex'))
const bufPubKey = keyPair.publicKey
const xOnlyPubKey = bufPubKey.subarray(1, 33)
const tweakedChildNode = keyPair.tweak(crypto.taggedHash('TapTweak', xOnlyPubKey))
const { address, output } = payments.p2tr({
  pubkey: Buffer.from(tweakedChildNode.publicKey.subarray(1, 33)),
  network,
})

```

The code above uses the `privateKey` to create a `keyPair` using the `ECPair` class from the `bitcoinjs-lib` library. The `keyPair` is then used to derive the `xOnlyPubKey`, and `tweakedChildNode` using the `tweak` method. The `address` and `output` are then generated using the `payments.p2tr` method.

**Key Points**:

- **`keyPair`**: This is the Bitcoin key pair derived from the provided private key from Web3Auth using the `ECPair` class. The key pair consists of the private key and the public key. The private key is used to sign transactions, while the public key is used to generate the Bitcoin address.
- **`xOnlyPubKey`**: This represents the x-coordinate of the public key, excluding the prefix byte. Taproot uses Schnorr signatures, which require only the x-coordinate of the public key. This x-only format is more efficient and is a key aspect of the Taproot design.
- **`tweakedChildNode`**: This is the resulting key after tweaking the original public key. Taproot involves tweaking the public key using a tagged hash, which modifies the public key in a way that remains cryptographically secure but incorporates additional data or functionality.
- **`address`**: This is the Bitcoin Taproot address derived from the provided public key &emdash; it's used to receive Bitcoin.
- **`output`**: This is the output script associated with the address. In Bitcoin transactions, an output script (also known as a scriptPubKey) defines the conditions that must be met to spend the funds sent to an address. For Taproot addresses, the output script enforces the spending conditions defined by the Taproot upgrade.

## Get balance[​](#get-balance "Direct link to Get balance")

```
/*
  Use `address` from above
*/
const response = await axios.get(`https://blockstream.info/testnet/api/address/${address}/utxo`)
const utxos = response.data.filter(
  (utxo: { status: { confirmed: boolean } }) => utxo.status.confirmed
)
const balance = utxos.reduce((acc: any, utxo: { value: any }) => acc + utxo.value, 0)
console.log('Bitcoin Balance: ', balance)

```

The code above fetches the UTXOs for the given `address` and filters out the unconfirmed UTXOs. The balance is then calculated by summing the value of the UTXOs.

## Send transaction[​](#send-transaction "Direct link to Send transaction")

```
/*
  Use `address`, `output`, `tweakedChildNode`, `xOnlyPubKey`, `utxos` from above.
*/
const utxo = utxos[0]
const feeResponse = await axios.get('https://blockstream.info/testnet/api/fee-estimates')
// For mainnet use https://blockstream.info/api/fee-estimates
const maxFee = Math.max(...(Object.values(feeResponse.data) as number[]))
const fee = maxFee * 1.2
if (amount <= fee) {
  const errorMsg = `Insufficient funds: ${amount} <= ${fee}`
  uiConsole(errorMsg)
  throw new Error(errorMsg)
}

const sendAmount = amount - Math.floor(fee)

const psbt = new Psbt({ network })
  .addInput({
    hash: utxo.txid,
    index: utxo.vout,
    witnessUtxo: { value: utxo.value, script: output! },
    tapInternalKey: xOnlyPubKey,
  })
  .addOutput({
    value: sendAmount,
    address: 'tb1ph9cxmts2r8z56mfzyhem74pep0kfz2k0pc56uhujzx0c3v2rrgssx8zc5q',
  })

psbt.signInput(0, tweakedChildNode)
psbt.finalizeAllInputs()
const txHex = psbt.extractTransaction().toHex()

try {
  const response = await axios.post(`https://blockstream.info/testnet/api/tx`, txHex)
  // For mainnet use https://blockstream.info/api/tx
  console.log('Transaction sent successfully:', response.data)
  return response.data
} catch (error) {
  console.error('Error sending transaction:', error)
  throw error
}

```

The code above sends a transaction to the Bitcoin blockchain. The code fetches the fee estimates from the Bitcoin blockchain and calculates the fee for the transaction. The code then creates a PSBT object and adds the input and output to the PSBT object. The input is signed using the `tweakedChildNode` and the PSBT object is finalized. The transaction is then sent to the Bitcoin blockchain.

## Example[​](#example "Direct link to Example")

You can find a complete example of the Bitcoin Taproot integration in [this GitHub Repo](https://github.com/Web3Auth/web3auth-examples/tree/main/other/bitcoin-example).
