0xMiden / 0xMiden/wallet

Supported path for moving a Miden Wallet account into miden-client

Open
#537 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
5
Forks
28
Avg merge
9h 50m
Merged PRs (30d)
123

Description

## Summary

There is currently no supported way to use an account created in the Miden Wallet
extension with `miden-client`. The extension exports a password-encrypted JSON file;
`miden-client import` expects a binary `AccountFile` (`.mac`). Passing the former
produces `invalid data` with no further detail, because `AccountFile::read` collapses
every deserialisation failure into `io::ErrorKind::InvalidData`.

This has come up at least twice in the builders chat, from developers who deployed
contracts from the CLI and then wanted to use the same testnet account in a frontend,
or the reverse. Both were told it is not supported and moved on - one by writing a
separate in-app wallet.

## Why this matters before mainnet

The two entry points into the ecosystem are the extension and the CLI, and an account
cannot cross between them. Anyone who starts in one and needs the other today creates
a second account and refunds it from the faucet. That works on testnet and will not
work later.

## What I looked into

I wrote a converter for the key material half of the problem and documented both
formats from source: https://github.com/Zhekinmaksim/miden-acct

It reads the export file, reproduces each derivable account key exactly, and writes
key files and `key_index.json` in the layout `FilesystemKeyStore` reads. Verified
against `@miden-sdk/miden-sdk` 0.15.5, with round-trip tests that encrypt fixtures
using WebCrypto the way `passworder.ts` does and decrypt them independently.

Two findings worth recording regardless of what happens with this issue:

- The extension's HD chain uses `bls12_377 seed` as the master HMAC key, inherited
from `@demox-labs/aleo-hd-key`. A stock BIP32 or SLIP-0010 implementation derives
different key material here without failing, so anyone reimplementing this by
assumption will get a wrong key and a confusing on-chain mismatch.
- Within the export file, the main payload is base64 while `encryptedPasswordCheck` is
hex, and both encrypt `JSON.stringify(value)`. That asymmetry is easy to trip over.

## Where it stops

Key reconstruction is solvable from outside. Producing a full `.mac` is not, because
`AccountFile` needs the complete `Account` - id, vault, storage, code, nonce, seed -
and in the export that state is spread across the web store's IndexedDB tables, whose
layout is an internal detail. Reconstructing an account by reverse-engineering an
unstable schema is the wrong foundation for something holding user funds.

## Question

Which of these would you want, if any?

1. **`miden-client import` accepts a mnemonic plus derivation index.** The client
rebuilds the key and syncs public account state from the node. Smallest surface,
covers the common case, does not help private accounts.
2. **The web client exports a real `.mac`.** Solves it properly, including private
accounts, but the work lives in the wallet and SDK rather than here.
3. **A documented, versioned export schema** that external tools may rely on, so
conversion can stay outside the client.

Happy to implement whichever direction you prefer, or to contribute the format
documentation to the docs if the answer is that this stays out of scope for now.

Contributor guide

Open the contributing guide

Research direction

The issue describes a mismatch between the Miden Wallet extension's encrypted JSON export and miden-client's binary .mac format. Start by examining the wallet's export logic in the TypeScript code (likely in passworder.ts and storage modules) and the client's import command in Rust (AccountFile::read). The converter project at https://github.com/Zhekinmaksim/miden-acct provides a reference for key derivation. 'Done' means a user can move an account between the extension and CLI, either by extending the client or defining a stable export schema.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, typescript
Domain
cli, cryptography
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.