Configuring and implementing BTC Connect within an application built on BOB.
BTC Connect is the first account abstraction protocol for the Bitcoin ecosystem. It unifies smart accounts on Bitcoin Layer-2s and standard BTC accounts through native wallet interfaces. To achieve this, Particle Network has deployed ERC-4337 AA infrastructure natively on BOB (Build on Bitcoin), which developers can tap into to leverage Bitcoin-specific smart accounts.
BTC Connect achieves this by, firstly, allowing users to connect to your dApp with their UniSat, OKX, TokenPocket, Bybit, Wizz, Xverse, or Bitget wallet. Upon connecting, a smart account is generated on BitLayer and assigned to their BTC account. This smart account can then be used and authenticated directly through their BTC wallet, providing native Bitcoin users a simple interface to interact with applications on BOB, a leading Bitcoin Layer-2.
BTC Connect natively supports BOB within its flagship SDK, @particle-network/btc-connectkit
, and has been deployed on Testnet. This document will provide an initial introduction and step-by-step guide to working with BTC Connect on BOB through this SDK.
This document will provide a step-by-step guide to configuring and implementing BTC Connect within an application built on BOB. The snippets placed throughout this page will be from a create-react-app
demo application, which can be found here. This application primarily leverages @particle-network/btc-connectkit
, Particle Network’s flagship React-based SDK for BTC Connect.
As mentioned, BTC Connect is primarily implemented through its React-based SDK, @particle-network/btc-connectkit
. Therefore, ensure your project meets the following conditions before starting an integration:
create-react-app
, Next.js
, etc. application structure, with core dependencies installed such as react
and ethers
(or web3
, viem
, and so on).@particle-network/btc-connectkit
version 1.0.0-alpha.20 or higher installed, alongside, optionally, version 1.4.3 of @particle-network/chains
.Before diving into the programmatic implementation of BTC Connect, you’ll first need to retrieve three key values from the Particle dashboard to authenticate the SDK (@particle-network/btc-connectkit
).
To do this, follow the steps listed below.
Register or log in to the Particle dashboard.
Create a new project or enter an existing project.
Create a new web application (or skip this step if you already have one).
Retrieve the aforementioned values (your Project ID, Client Key, and App ID); if applicable, save these to environment variables within your application.
BTC Connect is configured and initialized through its central React component, ConnectProvider
(similar to AuthCoreContextProvider
from Particle Network’s other SDKs if you’ve used them before).
ConnectProvider
will wrap the application component (for example, App
) where you intend to use BTC Connect, handling customization, API authentication, and wallet selection (such as UniSat, OKX, and so on).
Within a standard create-react-app
structure, this configuration will take place within the index.tsx
file. In this file (or the equivalent for your project), import the following objects from @particle-network/btc-connectkit
:
ConnectProvider
, the React component used for configuration.OKXConnector
UnisatConnector
BitgetConnector
TokenPocketConnector
BybitConnector
WizzConnector
Once these are imported, you’ll need to define two collection of values through ConnectProvider
as you render your application.
The first of these will be options
, used to handle customizations for the smart account implementation, chain, and embedded wallet modal, and will be followed by connectors
for establishing the supported wallets within your application.
To configure options
, you’ll need to define the following properties:
projectId
, clientKey
, and appId
. These were previously retrieved from the Particle dashboard.aaOptions
, which contains accountContracts
, taking:
BTC
, the smart account implementation you’ll be leveraging.
chainIds
, one or multiple chains that your application will support. In this case, you can either use BOB’s chain ID, 111
, or BOBTestnet.id
from @particle-network/chains
.version
, the version of the BTC smart account you intend to use. For BOB, this should be 2.0.0
. If you intend to use more than just BOB, you may need to define another instance of BTC
using version
1.0.0
. For more information on which chains support 1.0.0
and which support 2.0.0
, head over to Particle Network’s documentation.walletOptions
, which contains:
visible
, a Boolean determining whether or not Particle Network’s embedded wallet modal will be shown after a user connects their Bitcoin wallet. If set to true
, users will have direct access to their associated smart accounts through this embedded interface. Otherwise, if false
, developers will need to retrieve and reflect wallet information, such as balances, independently.Second to options
, you’ll also need to define connectors
, which should contain an array of initialized wallet connector objects (for example, new UnisatConnector()
) indicating the native Bitcoin wallets you’d like to be supported within your application.
Wrapping this all up, your index.tsx
file, or the equivalent within your project, should look similar in principle to the snippet shown below:
Moving on from configuration and to application implementation, you’ll need to decide on a mechanism in which you’ll drive wallet connectivity through BTC Connect.
To this end, you have two options:
ConnectProvider
.As a simple way to facilitate wallet connection through a “Connect Wallet” button or similar point of interaction, BTC Connect has a built-in connection interface handling everything for you. Visually, this looks like the screenshot below, deviating depending on the specific wallets you’re supporting.
This modal can be displayed on-screen through BTC Connect’s useConnectModal
React hook, imported from @particle-network/btc-connectkit
.
From useConnectModal
, you’ll need to define openConnectModal
. Upon (synchronously) calling openConnectModal
, the above interface will be opened for the user, prompting wallet connection.
In most cases, openConnectModal
should be bound to a “Connect Wallet” button.
Below is a snippet showcasing this approach.
Alternatively, if you intend to include Bitcoin wallet connectivity from BTC Connect in your existing custom connection interface, or if you’d like to build a new one from scratch, you’ll need to facilitate wallet connection through shortcuts.
Wallet shortcuts can be executed through the useConnector
React hook from @particle-network/btc-connectkit
, allowing you to prompt an individual wallet for connection, rather than opening the aforementioned BTC Connect interface.
From useConnector
, you’ll need the connect
function. connect
simply takes a string representing the wallet you’d like to connect to, such as 'unisat'
or 'okx'
. An example of this can be found below.
Calls to connect
can be plugged into any interface or UI element to circumvent the BTC Connect modal.
Once a user has connected with their Bitcoin wallet, you’re ready to leverage the resulting EVM account (a smart contract wallet) for transactions within your application.
Implementing and leveraging the attached EVM account can be achieved through one of two ways:
sendUserOp
, buildUserOp
, and getFeeQuotes
methods.Both will achieve the same goal (executing transactions using the user’s EVM account), although vary in terms of complexity depending on your existing setup. If you’re already using Ethers, Web3.js, or viem, you’ll want to go for option 2. Otherwise, if you’re building an application exclusively around BTC Connect, option 1 may be more suitable.
Interaction with BOB, regardless of the option you choose, will start with the useETHProvider
hook from @particle-network/btc-connectkit
.
In the context of using BTC Connect’s built-in transaction execution functions, you’ll need to leverage one of or multiple of the following:
sendUserOp
, the standard function for transaction execution (in the case of ERC-4337, also known as a UserOperation).buildUserOp
, for constructing a complete UserOperation object; only needed if you intend to use external paymasters, bundlers, or alter granular UserOperation details.getFeeQuotes
, used for the construction of UserOperations with deviating fee payment mechanisms, such as gasless transactions. This will be needed if you intend to sponsor transactions.sendUserOp
can be used to either execute a standard transaction following a traditional structure, including fields such as to,
value,
and data,
or a UserOperation (from buildUserOp
) can be passed in.
A snippet showcasing an example of traditional transaction execution with sendUserOp
has been included below.
In the case that you’d like to send a gasless (sponsored) transaction, you’ll need to first use the getFeeQuotes
function before calling sendUserOp
.
getFeeQuotes
takes the same transaction structure as is shown above and returns two types of UserOperations:
verifyingPaymasterGasless.userOp
and verifyingPaymasterGasless.userOpHash
for gasless transactions.verifyingPaymasterNative.userOp
and verifyingPaymasterNative.userOpHash
for standard transactions with gas paid for by the user (the same as if you were to use sendUserOp
in standalone).To leverage the objects returned within verifyingPaymasterGasless
and, therefore, send a gasless transaction, the aforementioned snippet will change slightly to rather pass in a userOp
and userOpHash
instead of a tx
object directly, as shown below.
Often as an easier path, an external library such as Ethers can be used directly with BTC Connect to facilitate transaction construction and execution.
The aforementioned useETHProvider
hook includes an EIP-1193 provider object, provider
, which can be plugged directly into Ethers to construct an instance tied to the user’s BOB/EVM account, as shown below.
With an instance of Ethers (or another equivalent library) constructed, transactions can be executed as they would normally be; signatures will be automatically routed to the user’s Bitcoin wallet.
Thus, if your application already uses Ethers or a related library, BTC Connect can be plugged in directly to an existing or parallel provider object, working with your pre-established transaction flow.
Below is an example of this through a sample function, executeTxEvm
, which burns 0.01 ETH on BOB.
Due to the nature of a user connecting their native Bitcoin wallet to your application on BOB, you have the added flexibility of executing transactions on Bitcoin. This includes standard P2P BTC transfers alongside inscription transfers.
Bitcoin functionality can be accessed through the useBTCProvider
hook from @particle-network/btc-connectkit
, providing the following objects:
sendBitcoin
provider
getNetwork
switchNetwork
signMessage
getPublicKey
accounts
As an example, let’s use sendBitcoin
to send 1 satoshi back to the sending address.
To achieve this, sendBitcoin
can be called with the following parameters:
toAddress
, the recipient address; in this case, we’ll use accounts[0]
(the sender).satoshis
, the value of the transaction in satoshis; this will be 1
here.options
, an optional object containing:
feeRate
, for adjusting transaction fees; we’ll leave this as default.sendBitcoin
, the user will be prompted to confirm the transaction, just as they would the EVM transactions previously covered on this document.As a parallel to executeTxEvm
, the execution of a transaction on Bitcoin may look adjacent to the snippet below:
At this point, you’ve gone through the process of:
@particle-network/btc-connectkit
.To dive in further and continue exploring the process of leveraging BTC Connect, take a look at Particle Network’s 5-minute startup guide.
Additionally, a complete demo repository showcasing the usage of BTC Connect on BOB is available here, and you can try it in your own browser here.