Table of contents:
The Mezo Passport package is built on top of RainbowKit, expanding its functionality to provide additional wallet connection options specifically tailored for Bitcoin wallets and Mezo Matsnet. With this package, developers can integrate Bitcoin wallet support alongside existing Mezo Matsnet (and other Ethereum-compatible (EVM) wallets), creating a more versatile connection experience for users.
One of the key features of this package is its ability to "masquerade" or simulate Bitcoin wallets as Matsnet wallets, allowing them to interact with matsnet-based applications seamlessly. Under the hood, it manages a supporting provider, with it's underlying Matsnet account, that enables standard EVM operations (such as reading data and interacting with smart contracts) while keeping signing operations (such as authorizing transactions) routed to the Bitcoin wallet itself.
Additionally, the package directs transaction execution to a backing smart account, which handles the technical details on the Matnset side. This setup enables users to use their Bitcoin wallet for both matsnet transactions and Bitcoin-specific signing operations without needing to switch wallets or providers manually. Each Mezo Passport Bitcoin wallet has an underlying smart account on n Matsnet chain that validates signatures from the Bitcoin wallet and issues Matsnet transactions.
In essence, this package allows for a more flexible and integrated multi-chain wallet experience by enabling Bitcoin wallets to operate within an EVM environment, making it easier for users to access both Bitcoin and EVM functionalities through a unified connection interface.
-
Wallet Management
The Mezo Passport package provides a set of components that enable users to connect their Bitcoin wallets to your dApp. Beyond simple connection and disconnection, it also supports features like displaying balances, switching networks, and more.
-
Interoperability
The Mezo Passport package provides integrations with the popular viem an wagmi libraries, making it easier to incorporate Bitcoin wallet support into applications that already utilize these libraries. By leveraging these integrations, developers can seamlessly manage wallet connections and streamline interactions across both Bitcoin and EVM ecosystems.
Note: Because RainbowKit is a React library, Mezo Passport is also designed as a React library to ensure seamless integration.
Install Mezo Passport library, RainbowKit and all of it's dependencies:
npm install @mezo-org/passport @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query
Note: We recommend reading through RainbowKit documentation first to fully understand the configuration process.
The configuration process is basically the same as in RainbowKit. Normally, you
would create a wagmi config using createDefaultConfig
from RainbowKit, but
Mezo Passport provides a getConfig
method, which returns a default
configuration for Mezo Matsnet. We just have to pass it further to
WagmiProvider
:
import { RainbowKitProvider } from "@rainbow-me/rainbowkit"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { WagmiProvider } from "wagmi"
import "@rainbow-me/rainbowkit/styles.css"
import { getConfig, mezoMatsnetTestnet } from "@mezo-org/passport"
const queryClient = new QueryClient()
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<WagmiProvider config={getConfig({ appName: "Your app name" })}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider initialChain={mezoMatsnetTestnet}>
{/* Your App component */}
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
</React.StrictMode>,
)
You can pass the same configuration options to getConfig
as you would to
createDefaultConfig
from RainbowKit. For default config you only need to
provide the appName
.
Additionally, you can specify what bitcoin wallet from Mezo Passport you want to
support. By default, the lib supports Unisat, OKX and Xverse wallets. If you
want to include Unisat wallet only, you can pass it through bitcoinWallet
property to getConfig
function:
import { getConfig, unisatWallet } from "@mezo-org/passport"
const customBitcoinWallets = [
{
groupName: "Bitcoin wallets",
wallets: [unisatWallet],
},
]
// and later pass it
<WagmiProvider
config={
getConfig({
appName: "Your app name",
bitcoinWallets: customBitcoinWallets,
})
}
>
(...)
</WagmiProvider>
That's pretty much it when it comes to configuration! As stated earlier, we recommend to read through the RainbowKit documentation for better understanding.
To start adding functionalities, please see Connecting a wallet.
There are two ways to connect the Mezo Passport wallet:
- through Wagmi,
- through RainbowKit,
We can connect to the specific wallet directly through wagmi
:
import {
useChainId,
useConnect,
} from "wagmi"
export const YourApp = () => {
const chainId = useChainId()
const { connectors, connect } = useConnect()
return (
<div>
{connectors.map((connector) => (
<button
type="button"
onClick={() => {
connect({ connector, chainId })
}}
key={connector.id}
>
{connector.name}
</button>
))}
</div>
)
};
This will render a button for each wallet that we've added to the rainbowKit config. This gives us more control over connectors and how we want it to be displayed in our dApp.
We can also implement wallet connection through RainbowKit, where we import the
ConnectButton
component, which will handle the connection process under the
hood:
import { ConnectButton } from "@rainbow-me/rainbowkit"
export const YourApp = () => {
return <ConnectButton label="Connect wallet"/>;
};
For bitcoin account Mezo Passport exports a helper hook -
useBitcoinAccount()
- which can be used to obtain address and balance of the
connected bitcoin account:
import { useBitcoinAccount } from "@mezo-org/passport"
const { btcAddress, btcBalance } = useBitcoinAccount()
useEffect(() => {
console.log("btcAddress: ", btcAddress)
console.log("btcBalance (in satoshi): ", btcBalance.total)
}, [btcAddress, btcBalance])
This hook returns the bitcoin balance in satoshis, in the following format:
{
confirmed: number,
unconfirmed: number,
total: number
}
To get an address and a balance of the underlying Mezo Matsnet account, we can
use wagmi
hooks:
const { address } = useAccount()
const { data } = useBalance({ address })
useEffect(() => {
console.log("ethAddress: ", address)
console.log("balance: ", data.value.toString())
}, [address, data])
The Mezo Passport wallets supports message signing from wagmi
lib, so signing
functions the same way as it does in wagmi
:
import { useSignMessage } from 'wagmi'
function App() {
const { signMessage } = useSignMessage()
return (
<button onClick={() => signMessage({ message: 'hello world' })}>
Sign message
</button>
)
}
Contracts integrations are handled the same way as in RainbowKit and Wagmi.
To send a specific Mezo Matsnet transaction from the underlying Mezo Matsnet
account, we can use a useSendTransaction
hook from @mezo-org/passport
:
import { useSendTransaction } from "@mezo-org/passport"
const { sendTransaction } = useSendTransaction()
const onSendTransaction = async () => {
const result = await sendTransaction(
"<eth_address>",
100000n,
"0x00", // can also pass some specific tx data
)
console.log(result?.hash)
}
sendTransaction
function takes three arguments:
- address for which we want to send eth to
- amount of matsnet btc (in matsnet sats) that we want to send
- additional data that we would like to send with the transaction
With @mezo-org/passport
it's also possible to send BTC transactions from your
original Bitcoin account (not the underlying Mezo Matsnet account). For that, we
can use useSendBitcoin
hook:
import { useSendBitcoin } from "@mezo-org/passport"
const { sendBitcoin } = useSendBitcoin()
const onSendBitcoin = async () => {
const txHash = await sendBitcoin("<btc_address>", 1500)
console.log("txHash: ", txHash)
}
sendBitcoin
function takes two arguments:
- address for which we want to send bitoins to
- amount of bitcoins (in satoshis) that we want to send