mezo-org/passport
Table of contents:
Introduction
Purpose
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.
Key Features
-
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.
Getting started
Step by step setup
Note: Because RainbowKit is a React library, Mezo Passport is also designed as a
React library to ensure seamless integration.
Installation
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
Configure
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>
Final steps
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.
Connecting a wallet
There are two ways to connect the Mezo Passport wallet:
- through Wagmi,
- through RainbowKit,
through Wagmi
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.
through RainbowKit
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"/>;
};
Getting addresses and wallet balances
Bitcoin account
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
}
Mezo Matsnet account
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])
Signing a message
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>
)
}
Mezo Matsnet transactions
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
BTC transactions
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