# Integrating BTC Connect

As mentioned, the process of integrating BTC Connect starts with configuration.

Before jumping in, it's important to note that this example will follow a `create-react-app` structure; thus, we'll repeatedly refer to the following files within this guide:

* `index.tsx`, our central location for the configuration of BTC Connect.
* `App.tsx`, the central component containing our core application logic (wallet connection and transaction execution).

To begin, we'll need to install several required and optional dependencies, as will be covered below.

### Setup: Dependencies

BTC Connect can be integrated and utilized solely through one SDK, `@particle-network/btc-connectkit`. This library is responsible for handling all three steps of our example application. For the sake of programmatic simplicity, we'll be using a combination of the following libraries:

* `@particle-network/btc-connectkit`, the aforementioned key library for using BTC Connect.
* `@particle-network/chains`, for connecting to SatoshiVM.
* `@particle-network/aa`, to simplify interaction with the associated smart account.
* `ethers`, used hand-in-hand with `@particle-network/aa` to streamline the means of transaction execution.

To install these libraries, you'll need to run one of the two commands highlighted below at the root of your project:

```shell
yarn add @particle-network/btc-connectkit @particle-network/chains @particle-network/aa ethers


# OR


npm install @particle-network/btc-connectkit @particle-network/chains @particle-network/aa ethers


# Any other standard package manager works as well.
```

### Part 1: Configuration and Initialization

Now that you've installed various dependencies and understand the basic structure of this example, you're ready to proceed to the first part of implementing BTC Connect: the process of configuration.

Configuring BTC Connect entails usage of the `ConnectProvider` component imported from `@particle-network/btc-connectkit`.

`ConnectProvider` acts as the central component for configuration, taking a variety of parameters responsible for instance authentication (API keys), wallet modal customization (we'll cover this more momentarily), and supported wallet customization (deciding the range of supported wallets within your application, such as UniSat, OKX, and so on).

Additionally, `ConnectProvider` should wrap the component where you intend to use BTC Connect. This is where our previously defined usage of `App.tsx` and `index.tsx` resurface.

Configuration in this example will happen within `index.tsx`. This file will import the `App` component from `App.tsx`, allowing `ConnectProvider` to wrap it and enabling the usage of BTC Connect within our application (defined within `App.tsx`).

***

With this established, you'll need to render `ConnectProvider` with the following parameters defined (through the `options` and `connectors` parameters):

* `projectId`, `clientKey`, and `appId`. These are required values authenticating your instance of BTC Connect; they fundamentally tie your project to the [Particle dashboard](https://dashboard.particle.network).
  * To retrieve these keys, open the [dashboard](https://dashboard.particle.network) and create a new project alongside a new application; the corresponding **Project ID**, **Client Key**, and **App ID** will need to be defined within their respective parameters, detailed above.
* `aaOptions`, which contains `accountContracts`, taking:
  * `BTC`, an array of objects outlining chain-related configurations for the smart account. These parameters include:
    * `chainIds`, an array of chain IDs referring to the chains you intend to use within your application. Here, we'll be using `SatoshiVMTestnet.id` from `@particle-network/chains`.
    * `version`, the version of the smart account you'd like to use. For now, only `1.0.0` is supported.
* `walletOptions`, settings impacting the optional embedded wallet modal responsible for facilitating interaction with the smart account derived from a user's native Bitcoin wallet.
  * This takes one parameter, `visible`. If set to `true`, the embedded wallet modal will be available through the bottom right corner of your application after the wallet connection. Otherwise, if `false`, the modal will be omitted, leaving the handling of the smart account solely to your application.

Outside of `options`, within `connectors`:

* An array of wallet connectors you'd like to support within your application (such as UniSat, Bitget, or OKX). These connections can be imported from `@particle-network/btc-connectkit`, through:
  * `OKXConnector`.
  * `UnisatConnector`.
  * `BitgetConnector`.

With these parameters filled in, your `index.tsx` file (or its equivalent within your application) should look similar to the example below:

```javascript
import React from "react"
import ReactDOM from "react-dom/client"
import {
    ConnectProvider, // Central component used for configuration
    OKXConnector, // OKX Wallet
    UnisatConnector, // Unisat Wallet
    BitgetConnector, // Bitget Wallet
} from "@particle-network/btc-connectkit"
import { SatoshiVMTestnet } from "@particle-network/chains" // Optional
import App from "./App" // The component you intend to use BTC Connect within

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
    <React.StrictMode>
        <ConnectProvider
            options={{
                projectId: process.env.REACT_APP_PROJECT_ID, // ---
                clientKey: process.env.REACT_APP_CLIENT_KEY, // Retrieved from https://dashboard.particle.network
                appId: process.env.REACT_APP_APP_ID, // ---
                aaOptions: {
                    accountContracts: {
                        BTC: [
                            {
                                chainIds: [SatoshiVMTestnet.id],
                                version: "1.0.0", // Keep as 1.0.0 for now.
                            },
                        ],
                    },
                },
                walletOptions: {
                    // Dictates whether or not the optional embedded wallet modal is shown.
                    visible: true,
                },
            }}
            // Instances of the previously imported connectors
            connectors={[new UnisatConnector(), new OKXConnector(), new BitgetConnector()]}
        >
            <App /> // The component imported above
        </ConnectProvider>
    </React.StrictMode>
)
```

### Part 2: Initiating Wallet Connection

With BTC Connect configured and initialized, you're ready to begin building your application (or integrating BTC Connect within an existing one).

We'll be doing this within the previously mentioned `App.tsx` file (using the `App` component we wrapped within `ConnectProvider`).

Opening and taking a user through the wallet connection menu is quite simple and generally only takes one line of code, although it requires a preliminary setup.

First, it's important to understand how BTC Connect is used programmatically.

BTC Connect has four primary hooks that provide functions to control all core functionality. These are:

* `useETHProvider`, for managing the associated smart account on SatoshiVM.
* `useBTCProvider`, to receive the user's Bitcoin address and execute native BTC transactions.
* `useConnectModal`, for initiating a wallet connection.
* `useAccounts`, for retrieving the user's addresses.

We'll walk through the process of leveraging `useETHProvider` (alongside `@particle-network/aa` and `ethers`) and `useBTCProvider` in part 3. For now, let's focus on `useConnectModal`.

After importing `useConnectModal` from `@particle-network/btc-connectkit`, we'll need to define the `openConnectModal` function (and optionally, the `disconnect` function). An example of this has been included below:

```javascript
import { useETHProvider, useBTCProvider, useConnectModal } from '@particle-network/btc-connectkit';


const App = () => {
  ...

  const { openConnectModal, disconnect } = useConnectModal();
  const { accounts } = useBTCProvider(); // We'll be using this in a moment.

  ...
}
```

`openConnectModal` is the sole function responsible for both initiating and handling end-to-end wallet connections. In this example, we'll wrap `openConnectModal` within a function, `handleLogin`to ensure its execution only happens conditionally.

`handleLogin` will only execute `openConnectModal` *if* the user has yet to connect their wallet. This is indicated by the length of the `accounts` array from `useBTCProvider`, which is populated upon wallet connection.

Upon calling `handleLogin`, if the user has yet to connect, a generalized connection interface will be displayed, allowing a user to choose between the wallets previously defined within the `connectors` parameter through `ConnectProvider`. After choosing and connecting a specific wallet, they'll be ready to use your application either through their native Bitcoin account or the newly assigned smart account (on SatoshiVM).

`handleLogin`, or an equivalent function within your application, may look like the below example.

```javascript
const handleLogin = () => {
    if (!accounts.length) {
        openConnectModal() // Opens a generalized connection interface
    }
}
```

### Part 3: Transaction Execution

Taking a few steps back, let's revisit the hooks discussed in part 2.

As mentioned, the `useETHProvider` and `useBTCProvider` hooks are used to control their associated accounts (smart account and native Bitcoin account).

We'll begin by focusing on `useETHProvider`, using it to send a gasless burn transaction of 0.0001 BTC.

**EVM Transaction**

`useETHProvider` exposes a few objects, but the most important one among them is `smartAccount`. This is the sole object for controlling the smart account generated after the wallet connection.

`smartAccount` can either be used independently, through methods like `smartAccount.sendTransaction`, or it can be used alongside `@particle-network/aa` to define an associated EIP-1193 provider to be used within an instance of Ethers.

The latter is what we’ll use in this example.

Specifically, you'll need to import the following from `@particle-network/aa`:

* `AAWrapProvider`, for constructing the custom EIP-1193 provider.
* `SendTransactionMode`, to designate the fee payment method for transactions sent through the Ethers instance.

This, in tandem with `smartAccount`, a custom Ethers object, can be constructed through a flow similar to the following:

```javascript
import React, { useState, useEffect } from 'react';
import { useETHProvider, useBTCProvider, useConnectModal, useConnector } from '@particle-network/btc-connectkit';
import { AAWrapProvider, SendTransactionMode } from '@particle-network/aa';
import { ethers } from 'ethers';


const App = () => {
  const { smartAccount } = useETHProvider();

  ...

  const customProvider = new ethers.providers.Web3Provider(new AAWrapProvider(smartAccount, SendTransactionMode.Gasless), "any");

  ...
}
```

Therefore, this object, `customProvider`, will allow for the construction and execution of transactions through standard Ethers syntax and structure while directly routing signatures through BTC Connect.

By including `SendTransactionMode.Gasless` within the construction of `AAWrapProvider`, we'll be requesting gas sponsorship on every transaction sent through `customProvider`. Since we’re using the SatoshiVM Testnet, all transactions will be automatically sponsored (gasless). However, if this were on Mainnet, you'd need to deposit USDT to the Paymaster within the [Particle dashboard](https://dashboard.particle.network).

:::info

This method of building a custom EIP-1193 provider with `smartAccount` to use BTC Connect through a standard Web3 library is **not** exclusive to Ethers. `AAWrapProvider` can be used within Web3.js, viem, or any other library with EIP-1193 compatibility.

:::

Using `customProvider` to send a transaction is straightforward, following a typical Ethers flow. As such, developers familiar with Ethers might be used to this.

In this example, we'll be executing a burn transaction of 0.0001 BTC within `executeTxEvm`. This function will construct a simple `tx` object containing fields such as `to` and `value`.

Using a signer object retrieved through `customProvider.getSigner()`, this raw `tx` object can be used to execute a complete transaction ([UserOperation](https://www.erc4337.io/docs/understanding-ERC-4337/user-operation)).

To do this, we'll call `signer.sendTransaction(tx)`, which will prompt the user for confirmation (signature) through the Bitcoin wallet they connected previously. Upon confirmation, the transaction will be executed on SatoshiVM.

Below, you'll find an example for what a function of this nature may look like.

```javascript
const executeTxEvm = async () => {
    const signer = customProvider.getSigner()

    const tx = {
        to: "0x000000000000000000000000000000000000dEaD",
        value: ethers.utils.parseEther("0.01"),
        data: "0x",
    }

    const txResponse = await signer.sendTransaction(tx)
    const txReceipt = await txResponse.wait()

    return txReceipt.transactionHash
}
```

**BTC Transaction**

Alternatively, the same wallet interface can be used to send a native (L1) Bitcoin transaction, using the account attached to the previously connected wallet.

We'll do this through the `sendBitcoin` function from the `useBTCProvider` hook (akin to `smartAccount` from `useETHProvider`, but solely for executing a Bitcoin transaction).

`sendBitcoin` can be defined through `useBTCProvider` using syntax adjacent to the example below.

```javascript
import { useETHProvider, useBTCProvider, useConnectModal } from '@particle-network/btc-connectkit';


const App = () => {
  ...

  const { sendBitcoin, accounts } = useBTCProvider();

  ...
}
```

Executing this function will be as simple as passing in two parameters (this is all that's needed for a P2P transaction on Bitcoin). These parameters are:

* `toAddress`, the recipient of the transaction. In this example, we'll define the recipient as accounts\[0], which will send the BTC back to ourselves, just for the sake of demonstration.
* `satoshis`, the value of the transaction denominated in satoshis.
* Optionally, the `options` parameter can be used to define:
  * `feeRate`, for making manual adjustments to the transaction's gas fee.

We'll execute `sendBitcoin` through `executeTxBtc`, which should look similar to the following snippet:

```javascript
const executeTxBtc = async () => {
    return await sendBitcoin(accounts[0], 1)
}
```

Upon calling `executeTxBtc`, alike `executeTxEvm`, the user will be prompted to confirm and sign the transaction. After this, it'll be sent to Bitcoin for execution.
