# mezo-org/passport

**Table of contents:**

- [Introduction](#introduction)
  - [Purpose](#purpose)
  - [Key features](#key-features)
- [Getting Started](#getting-started)
  - [Step-by-step setup](#step-by-step-setup)
    - [Installation](#installation)
    - [Configure](#configure)
    - [Bitcoin wallet config](#bitcoin-wallet-config)
    - [Wrap providers](#wrap-providers)
    - [Final steps](#final-steps)
  - [Connecting a wallet](#connecting-a-wallet)
    - [through RainbowKit](#final-steps)
    - [through wagmi](#final-steps)
  - [Getting addresses and wallet balances](#getting-addresses-wallet-balances)
  - [Signing a message](#signing-a-message)
  - [BTC transactions](#btc-transactions)
  - [ETH transactions](#eth-transactions)

## 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](https://www.rainbowkit.com/) 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`:

```tsx
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, mezoTestnet } 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={mezoTestnet}>
          {/* 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:

```tsx
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).

### Connecting a wallet

There are two ways to connect the Mezo Passport wallet:

1. through Wagmi,
2. through RainbowKit,

#### through Wagmi

We can connect to the specific wallet directly through `wagmi`:

```tsx
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:

```tsx
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:

```ts
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:

```ts
{
  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:

```ts
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`:

```tsx
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`:

```ts
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:

- <string> address for which we want to send eth to
- <bigint> amount of matsnet btc (in matsnet sats) that we want to send
- <string> 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:

```ts
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:

- <string> address for which we want to send bitoins to
- <number> amount of bitcoins (in satoshis) that we want to send
