---
# System prepended metadata

title: Miden wallet adapters

---

# Fuel Connector Approach
Fuel ecosystem leverages the fuel sdk coupled with fuel connectors to bridge the gap between non-fuel wallets and the fuel network. The sdk revolves around a connector manager with pluggable connectors. The connectors must conform to an interface and are coupled through events. Internally each connector resolves how, for example, an EVM signature is translated into an acceptable proof for a fuel tx. In the case of fuel, they make heavy use of what they call "predicates", a kind of smart-contract that returns a boolean on arbtritary input. The predicate itself has a fuel address so funds come and go from there. Additionally, Connectors can hold state through an abstraction that's fed to them from the connector manager.

## Flow diagram

Here is a flow diagram of how a Fuel Connector works with a non native Wallet (MetaMask in this case):
![image](https://hackmd.io/_uploads/HJILLstQll.png)

As we can see, the MetaMask Connector comes into play only when sending a transaction (there are some other methods to call, regarding signing, but we only care about sending a transaction for now). It is invoked by the FuelSDK, selecting the currently active connector (or can be invoked directly, it is up to the developer) and calling the "sendTransaction" method. Under the hood this method requests the user to sign the transaction via MetaMask and with that signature it generates a predicate to execute on the Fuel Chain and finishes once the Fuel Chain has accepted the transaction.
If the dApp wants to know our balance, it doesn't use the Fuel Connector, it makes use of the Wallet abstraction that the FuelSDK provides, and this abstraction queries the balance of the predicate address on the Fuel Chain.

## How can it work with Miden?
Balance is not obtainable from the connector interface. It can be manually hacked through another method in a non-standard way. The connector does not automatically relay information to the wallet extension. Dapp developers would need to be aware of this quirk for implementation of the correct method calls. Reproducible accounts can be achieved, using a signed payload as the source of randomness, yet caution is advised because the entire state would, although client side, still live inside the dApp implementing the connector.

Fuel warning when using connector for non-Fuel wallet
![screen_2025-06-11_476x573](https://hackmd.io/_uploads/H1adYl9Vgg.png)

## Pros
A standarized approach with many connector examples and a clear pattern to follow
* It is a Plug n Play solution for Fuel applications
* It supports multiple Wallets (MetaMask, Phantom, Fuel, etc)

## Cons
* It is either an incomplete solution or will need to heavily deviate from standard in order to make it work
* It cannot show balance in-wallet
* We would not have any control over how the dApp developer interacts with Miden
* Miden account would exist dApp side
* It won't conform to the fuel standard
* It leverages very little from fuel libraries

## Conclusions
If we want to create a Fuel Connector to allow developers to easily integrate Miden into their Fuel App, we would only be able to partially support Miden operations. We would be able to send transactions if we bypass the Fuel Chain and just interact with a Wallet to sign the transaction and send it to the Miden Chain but we won't be able to check our Miden balance, as the FuelSDK queries the balance directly from the Fuel Chain and we can't modify that behaviour. If we really wanted to, we could misuse methods from the Fuel Connector, for example "getVersion" to return the balance instead of the connector version. But this would defeat the purpose of allowing developers to interact with Miden as they would with any other chain that the FuelSDK supports, they would need to be aware of these differences in functionality and implement Miden specific code for their app, all while using the FuelSDK, burdening the integration with extra overhead.

# MetaMask Snaps Approach
Metamask Snaps offers a "containerized" environment to execute javascript and potentially extend beyond the capabilities of the standard metamask rpc API. A dApp interacts with the snap through it's extended custom rpc. The snap execution environment does not have access to DOM, Node.js built-ins nor platform-specific APIs. It can only access a global `snap` and the classic `ethereum` object.

A Snap can display a home page within MetaMask that the user can access using the Snaps menu. Other than the settings page and home page, a Snap can modify the MetaMask UI by displaying custom UI in dialogs, transaction insights, signature insights, and notifications (expanded view).

## Flow Diagram
Here is a diagram of how a Snap works:
![image](https://hackmd.io/_uploads/r1JtQAKmee.png)
The Snap provides a safe execution environment and allows for a custom API to be defined, all while safeguarding secrets. A dApp would ask the Snap to send a transaction and after asking for user authorization, the Snap would execute it (using the Miden SDK). But there is a major issue that prevents us from going this route: there's no support for IndexedDB which is the persistence layer of the miden-sdk.

## Pros
* It supports all Miden features
* It is the most secure approach since MetaMask ensures the security of the runtime
* We have full control over how a developer interacts with Miden (it is wrapped inside a MetaMask RPC call but the payload is defined by us)
* It can show balance inside the Snap section in the Wallet
* Transactions can be made from inside the Snap section of the Wallet

## Cons
* It cannot be done with the current implementation of the MidenSDK WebClient
* It can only be used with MetaMask

# Conclusions
MetaMask Snaps does not support IndexedDB which is ingrained into the WASM core of the MidenSDK. There are a couple of alternatives that need further exploration. The first one would be to add support in the rust-client for a new kind of store compatible with Snaps. This is likely the more cumbersome but conservative approach. Another option would be to attempt to internally monkey patch the accesses to IndexeDB calls and reroute them to localStorage or some other kind of Snap supported KVS. This is possibly faster to implement but it's subject to Snaps API changes and audit pipeline.

# Custodial Accounts Approach
A custodial account would just be a remote wallet that we interact with, it needs to take care of authentication and authorization. This solution would support every Miden feature, but comes at the cost of high operational costs and the responsibility of safeguarding user data.

Users would authenticate themselves with the server following a typical OAuth2 flow, where the challenge of the protocol is signing a nonced payload with their private keys. Authentication can occur every time an action is performed or simply once after which the server will mint a JWT for the user.

## Pros
* It supports all Miden features
* It supports multiple Wallets (MetaMask, Phantom, Fuel, etc)
* We have full control over how a developer interacts with Miden

## Cons
* It requires a lot of responsibility around security and availability for the provider
* It has a high operational cost
* It cannot show balance in-wallet

## Conclusions
The Custodial Account system should not be hard to implement, but it requires a high responsibility on the provider side to ensure user funds are safe. From the development side, it would require to develop the backend, that would be functionally a proxy to a MidenSDK running in a backend that also handles authentication and authorization. It would also require to develop an SDK for the frontend side, that handles Wallet integration and calling this backend with the required data.

# Custodial account with custom ETH RPC
As a way to extend the previously described custodial strategy, the backend holding the accounts could be behind an Ethereum RPC node emulator that understands the user's intent an translates it into Miden native concepts. This would allow users to interact with the miden blockchain through their favourite EVM wallets as long as they have support for adding EVM chains (Metamask, Rabby). The node adapter would have to implement at least the following methods for a minimal user experience (see balances, send transations).
* `eth_chainId`
* `eth_getBalance`
* `eth_gasPrice`
* `eth_blockNumber`
* `eth_getBlockByNumber`
* `eth_getTransactionCount`
* `eth_sendRawTransaction`
* `eth_call`

Additionally, token balance requests would need to be decoded out from `eth_call` with `balanceOf` requests and remapped into the resolved Account token vault balance. There's no guarantee this will work across all wallets because many of them often use third-party apis to obtain that info. From our research we can confirm that Metamask uses `eth_call`s while Rabby uses a proprietary API.

The dApps wanting to support evm wallets would need to adhere to a yet to be determined miden typed requests wrapped within an EVM rpc request. To minimize friction it's recommended to distribute a simple SDK that bridges this gap. We recommend using EIP-712 to sign typed data as it allows a user-friendly popup in-wallet. This standard is also supported by all EVM compatible wallets (they need to actually support the `eth_signTypedData_v4` wallet rpc method). An example on metamask:

![out](https://hackmd.io/_uploads/Bycr8e9Exx.png)


![Custodial approachs](https://hackmd.io/_uploads/HJaZigXEgl.png)

## Pros
* Extends all custodial approach pros
* Can see balances in wallet (support may vary by wallet)

## Cons
* Extends all custodial approach cons
* Slightly more complex
* Needs an SDK for ease of implementation
* Miden Account id vs EVM address mismatch in-wallet

# Wrapper around Miden WebClient Approach
Another approach is to create a wrapper for the Miden WebClient that handles integration with the Wallets, it could be a barebones version of what Fuel does for adapters. This would allow full control over how developers interact with Miden, and also allows us to improve the internal implementation without forcing developers to change their dApps. This is by far the most flexible approach.

## How can it work with Miden?
As this approach is so flexible, this supports multiple approaches. We can declare a standard for interacting with Miden (available methods and their interfaces) and control the underlying implementation. For example, for a first version we can either run the Miden WebClient inside the dApp or use a custodial solution, this would be transparent for the dApp developer. For a second version, we could switch to calling a MetaMask Snap if we managed to make it work or even connect to a native Miden Wallet. All this without requiring developers to change their dApp, only update the SDK.

There is currently a similar effort [done in this repository](https://github.com/demox-labs/miden-wallet-adapter/tree/main): A Wallet Adapter for Miden Apps. This wrapper approach is functionally the same, but covering both parts, the Wallet interaction and the Miden interaction. Both efforts could be consolidated, perhaps just developing multiple adapters or a general one, or expand the base abstraction that leverages these adapters.

We can also distribute a set of frontend componets so the dApps have an easy and standardized way to show balance or to access the wallet, for example a header and a burger menu to interact with it. This would help address the issue of not having a wallet to display the actual balance.

## Flow diagram
Here is a diagram of how it would work:
![image](https://hackmd.io/_uploads/SyEutPjmgl.png)


## Pros
* It supports all Miden features
* It supports multiple Wallets (MetaMask, Phantom, Fuel, etc)
* We have full control over how a developer interacts with Miden
* It is the most flexible approach in term of the underlying solution
* It requires similar effort to the rest of the solutions

## Cons
* It cannot show balance in-wallet (at least outside a native Miden Wallet)
* It is not Plug and Play for dApp developers (although it should be simple and similar to other solutions)

# Comparison matrix

| **Approach**                    | **Supports All Miden Features** | **Wallet Compatibility**                 | **Shows Balance In-Wallet**  | **Ecosystem Control**                 | **Account Security**                      |  **Provider Responsibility**   | **Flexibility / Extensibility**                | **Operational Cost** | **Ease of Integration for dApps**      | **Key Cons**                                               |
| ------------------------------- | ------------------------------- | ---------------------------------------- | ---------------------------- | ------------------------------------- | -------------------------------------------------- | --- | ---------------------------------------------- | -------------------- | -------------------------------------- | ---------------------------------------------------------- |
| **Fuel Connector**              | ❌ Partial                      | Multiple (MetaMask, Phantom, Fuel, etc.) | ❌ No                        | ❌ Low (dApp devs must handle quirks) | Low (dApp must be trusted)                  |  Low (everything runs clint side)  | ❌ Low (tied to Fuel standards, limited reuse) | Medium                  | Medium (plug & play, but quirky)       | Cannot check balance, needs non-standard hacks, incomplete |
| **MetaMask Snaps**              | ✅ Yes                          | MetaMask only                            | ✅ Yes (in Snap UI section)  | ✅ High (we define the API & payload) | High (secure runtime by MetaMask, no backend ops)  |  Low (everything runs clint side)   | ❌ Limited (MetaMask ecosystem only)           | Medium                  | Medium (if Snap can be built)          | IndexedDB unsupported, requires SDK changes                |
| **Custodial Accounts**          | ✅ Yes                          | Multiple (except RPC: Metamask) | ✅ Yes with RPC                        | ✅ High (backend fully controls flow) | ✅ High (custodian responsible for funds security) |  High (the provider is responsible for the security)   | ✅ High (backend can evolve)                   | High                 | Medium (requires backend SDK too)      | High responsibility & operational cost                     |
| **Wrapper around Miden Client** | ✅ Yes                          | Multiple (MetaMask, Phantom, Fuel, etc.) | ❌ No (unless native wallet) | ✅ High (full control via SDK)        | Low (dApp must be trusted)   |   Low (everything runs clint side)  | ✅✅ Very high (abstracts underlying impl)     | Medium               | Medium (not plug & play, but flexible) | No native wallet balance display, custom SDK effort needed |
