feat: add Ethereum MPC keyring - #627
Conversation
Introduce a 2-party client/server MPC keyring with DKLS23 TSS, cloud backup sync, and vendored MFA wallet libs. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Replaces #440 with a cleaned history rebased onto |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning MetaMask internal reviewing guidelines:
|
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Pass convertV so recovery id 27|28 becomes yParity or EIP-155 v. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace backupId with shareEpoch so create/rotate append and activate epochs only after backup readiness, matching the robust MPC architecture. Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent mid-sign rotate/sync from being overwritten by stale Co-authored-by: Cursor <cursoragent@cursor.com> #applyKeyState snapshots from concurrent signing.
|
Do not merge yet: this PR still vendors MFA wallet packages as local |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e5a53ee. Configure here.
Pass the create/rotate session nonce to storeKeyShareBackup so a delayed backup from an overwritten retry cannot attach to a newer share. Co-authored-by: Cursor <cursoragent@cursor.com>
<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:
* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
Are there any issues or other links reviewers should consult to
understand this pull request better? For instance:
* Fixes #12345
* See: #67890
-->
## Summary
- MPC cloud HTTP calls now send the profile token in an `Authorization:
Bearer <token>` header instead of including `token` in JSON request
bodies.
- The shared `postJson` helper accepts the token as a separate argument
and applies it consistently across all MPC backend requests.
- Token-only endpoints (`getNetId`, `checkKeyShareBackupId`,
`loadKeyShareBackup`) still use POST but now send an empty JSON body
(`{}`).
## Test plan
- [x] Run `packages/keyring-eth-mpc` unit tests (`cloud.test.ts`)
- [x] Verify `getNetId` requests include the Bearer header and send `{}`
as the body
- [x] Verify sign and backup helpers include the Bearer header and omit
`token` from the JSON payload
- [ ] Confirm MPC backend accepts Bearer authentication for affected
endpoints before merge
<!--
Are there any examples of this change being used in another repository?
When considering changes to the MetaMask module template, it's strongly
preferred that the change be experimented with in another repository
first. This gives reviewers a better sense of how the change works,
making it less likely the change will need to be reverted or adjusted
later.
-->
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Auth moves from JSON to Bearer headers across all MPC cloud calls;
clients and the backend must agree before deploy or requests will fail.
>
> **Overview**
> MPC cloud HTTP clients no longer put the profile `token` in JSON
bodies. **`postJson`** now takes the token separately and sets
**`Authorization: Bearer <token>`** on every backend POST.
>
> Endpoints that previously sent only `{ token }` (**`getNetId`**,
**`checkKeyShare`**, **`loadKeyShareBackup`**) now POST **`{}`** with
auth in the header. Create/sign/rotate/backup/register calls keep their
payloads but drop the **`token`** field. Unit tests in
**`cloud.test.ts`** assert the header and that **`body.token`** is
absent.
>
> The unreleased **CHANGELOG** entry is shortened to a single
initial-release line (detailed feature bullets removed).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
400e5b1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Matthias Geihs <matthias.geihs@consensys.net>
<!-- Thanks for your contribution! Take a moment to answer these questions so that reviewers have the information they need to properly understand your changes: * What is the current state of things and why does it need to change? * What is the solution your changes offer and how does it work? Are there any issues or other links reviewers should consult to understand this pull request better? For instance: * Fixes #12345 * See: #67890 --> ## Summary - Add a shared `parseJsonResponse` helper in `packages/keyring-eth-mpc/src/cloud.ts` to centralize JSON parsing and non-OK error handling for cloud API responses. - Introduce `getJson` for Bearer-authenticated GET requests and refactor `postJson` to reuse `parseJsonResponse`. - Update `loadKeyShareBackup` to call `getJson` with GET instead of POST with an empty body. <!-- Are there any examples of this change being used in another repository? When considering changes to the MetaMask module template, it's strongly preferred that the change be experimented with in another repository first. This gives reviewers a better sense of how the change works, making it less likely the change will need to be reverted or adjusted later. --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the HTTP method for loading encrypted key-share backups; behavior depends on the MPC backend accepting GET on that route. > > **Overview** > Refactors MPC cloud HTTP helpers and fixes how encrypted key-share backups are fetched. > > **`cloud.ts`** adds **`parseJsonResponse`** for shared non-OK handling and JSON/empty-body parsing, introduces **`getJson`** for Bearer-authenticated GETs, and routes **`postJson`** through the same parser (generic renamed to **`Result`**). **`loadKeyShareBackup`** now calls **`getJson`** on `/load-key-share-backup` instead of **`postJson`** with an empty body. > > **`cloud.test.ts`** asserts the backup load uses **GET** with **`Authorization: Bearer`** and no POST body. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2690e54. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Matthias Geihs <matthias.geihs@consensys.net> Co-authored-by: Cursor <cursoragent@cursor.com>



Summary
@metamask/eth-mpc-keyring: a 2-party client/server MPC keyring with DKLS23 TSS, cloud backup sync, and vendored MFA wallet libsmainTest plan
yarn workspace @metamask/eth-mpc-keyring testyarn workspace @metamask/eth-mpc-keyring buildMade with Cursor