Skip to content

feat: add Ethereum MPC Money Keyring - #627

Open
matthiasgeihs wants to merge 39 commits into
mainfrom
mg/mpc-keyring
Open

matthiasgeihs wants to merge 39 commits into
mainfrom
mg/mpc-keyring

Conversation

@matthiasgeihs

@matthiasgeihs matthiasgeihs commented Sep 2, 2026 •

Copy link
Copy Markdown

Summary

  • Add @metamask/eth-mpc-keyring: a 2-party client/server MPC keyring with DKLS23 TSS, cloud backup sync, and vendored MFA wallet libs
  • Support create/import init, key-share rotate/check/sync, and signing (transactions, personal_sign, typed data, EIP-7702 authorizations)
  • Replaces the earlier WIP in feat: add MPC keyring #440 with a cleaned history rebased on main

Test plan

  • yarn workspace @metamask/eth-mpc-keyring test
  • yarn workspace @metamask/eth-mpc-keyring build
  • Smoke-check create/import and signing against a staging cloud/relayer if available

Made with Cursor

matthiasgeihs and others added 2 commits September 2, 2026 15:41
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>
@matthiasgeihs
matthiasgeihs requested a review from a team as a code owner September 2, 2026 13:54
@matthiasgeihs

Copy link
Copy Markdown
Author

Replaces #440 with a cleaned history rebased onto main.

@socket-security

socket-security Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​metamask/​mfa-wallet-interface@​0.1.0711007092100
Added@​metamask/​mfa-wallet-dkls23@​0.1.0721007192100
Added@​metamask/​mfa-wallet-cl24@​0.1.0751008392100
Added@​metamask/​cryptography@​1.1.2781007595100
Added@​metamask/​mfa-wallet-network@​0.1.07710010092100

View full report

@socket-security

socket-security Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Warning

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Priority Alert  (click "▶" to expand/collapse) Action
Low priority
Network access: npm centrifuge in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: packages/keyring-eth-money-mpc/package.json → npm/@metamask/mfa-wallet-network@0.1.0 → npm/centrifuge@5.7.4

ℹ Read more on: This package | This alert | What is network access?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/centrifuge@5.7.4. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn

View full report

@cursor
cursor Bot requested review from ccharly and hmalik88 September 2, 2026 14:03
Comment thread packages/keyring-eth-mpc/src/mpc-keyring.ts Outdated
Comment thread packages/keyring-eth-money-mpc/src/mpc-money-keyring.ts
Comment thread packages/keyring-eth-money-mpc/src/mpc-money-keyring.ts
Comment thread packages/keyring-eth-mpc/src/mpc-keyring.ts Outdated
matthiasgeihs and others added 4 commits September 2, 2026 16:12
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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: high. Not approved — this adds a new Ethereum MPC keyring with TSS signing, cloud backup, and vendored MFA libraries, which is above the low-risk approval threshold. Human review is needed.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

matthiasgeihs and others added 2 commits September 2, 2026 16:48
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@matthiasgeihs
matthiasgeihs marked this pull request as draft September 2, 2026 14:50
matthiasgeihs and others added 2 commits September 3, 2026 13:02
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.
@matthiasgeihs

Copy link
Copy Markdown
Author

Do not merge yet: this PR still vendors MFA wallet packages as local .tgz files under packages/keyring-eth-mpc/. It should not be merged until those tarballs are replaced with published npm dependencies.

@matthiasgeihs
matthiasgeihs marked this pull request as ready for review September 3, 2026 12:19

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/keyring-eth-money-mpc/src/mpc-money-keyring.ts
matthiasgeihs and others added 3 commits September 3, 2026 14:42
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>
@ccharly ccharly added the DO-NOT-MERGE PRs related to this issue should not be merged label Sep 10, 2026
@danroc danroc added DO-NOT-MERGE PRs related to this issue should not be merged and removed DO-NOT-MERGE PRs related to this issue should not be merged labels Sep 16, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
matthiasgeihs and others added 2 commits September 28, 2026 10:46
Run init inside #serializeOp with the initialized check inside the queue, so overlapping init calls run key generation or import once. The second call waits, sees the initialized state and returns.

Co-authored-by: Cursor <cursoragent@cursor.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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 043a708. Configure here.


if (hasInitializedFields(state)) {
throw new Error('Invalid state');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid state accepted as setup

Low Severity

deserialize checks SetupParamsStruct before hasInitializedFields, so a payload that has the initialized fields but fails the struct is treated as setup whenever mode is create or import. That drops the key material and later init can create or import a different key instead of rejecting the state.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 043a708. Configure here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed in fef54748ebba63d98ca358492315d9b37a9c9880

The SDK dropped the -lib suffix and the util package. The keyring now uses the network package's identity serializer and scoped session id.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ieow

ieow commented Sep 29, 2026

Copy link
Copy Markdown

@metamaskbot publish-preview

@ccharly
ccharly added this pull request to stack #642 September 29, 2026 12:22
@github-actions

Copy link
Copy Markdown

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "2.0.0-4b24aef",
  "@metamask-previews/hw-wallet-sdk": "1.0.0-4b24aef",
  "@metamask-previews/keyring-api": "24.1.0-4b24aef",
  "@metamask-previews/eth-hd-keyring": "15.0.0-4b24aef",
  "@metamask-previews/eth-ledger-bridge-keyring": "13.1.0-4b24aef",
  "@metamask-previews/eth-money-keyring": "4.0.0-4b24aef",
  "@metamask-previews/eth-mpc-keyring": "0.0.0-4b24aef",
  "@metamask-previews/eth-qr-keyring": "3.0.0-4b24aef",
  "@metamask-previews/eth-simple-keyring": "13.0.0-4b24aef",
  "@metamask-previews/eth-trezor-keyring": "11.0.0-4b24aef",
  "@metamask-previews/keyring-internal-api": "12.1.0-4b24aef",
  "@metamask-previews/keyring-internal-snap-client": "11.1.0-4b24aef",
  "@metamask-previews/keyring-sdk": "3.1.0-4b24aef",
  "@metamask-previews/eth-snap-keyring": "24.1.0-4b24aef",
  "@metamask-previews/keyring-snap-client": "10.0.0-4b24aef",
  "@metamask-previews/keyring-snap-sdk": "10.0.0-4b24aef",
  "@metamask-previews/keyring-utils": "5.0.0-4b24aef"
}

@ccharly
ccharly removed this pull request from stack #642 September 30, 2026 12:25
Keep the V1 MPC keyring implementation together with the V2 adapter already on main.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment on lines +26 to +34
/**
* Generate a session nonce: random bytes from the RNG, hex-encoded.
*
* @param rng - The random number generator.
* @returns Hex-encoded 32-byte random nonce.
*/
export function generateSessionNonce(rng: RandomNumberGenerator): Hex {
return bytesToHex(rng.generateRandomBytes(SESSION_NONCE_BYTE_LENGTH));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I meant cryptography.ts actually 🙈 Similarly to our new @metamask/cryptography.

No real benefits, just that we would keep general utils in util and other crypto-utils like, in their own files. So tests are separated etc.

Anyway, not really a blocker.

Comment on lines +36 to +104
/**
* Encrypt plaintext with AES-GCM. The IV is prepended to the ciphertext.
*
* @param key - 16- or 32-byte AES key.
* @param plaintext - Bytes to encrypt.
* @param iv - 12-byte IV.
* @returns `iv || ciphertext || tag`.
*/
export async function encryptBytes(
key: Uint8Array,
plaintext: Uint8Array,
iv: Uint8Array,
): Promise<Uint8Array> {
if (iv.length !== AES_GCM_IV_LENGTH) {
throw new Error('Invalid IV length');
}
if (key.length !== 16 && key.length !== 32) {
throw new Error('Invalid backup encryption key length');
}

const cryptoKey = await globalThis.crypto.subtle.importKey(
'raw',
key,
'AES-GCM',
false,
['encrypt'],
);
const ciphertext = await globalThis.crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
cryptoKey,
plaintext,
);
return concatBytes(iv, new Uint8Array(ciphertext));
}

/**
* Decrypt a payload produced by {@link encryptBytes}.
*
* @param key - 16- or 32-byte AES key.
* @param payload - `iv || ciphertext || tag`.
* @returns The plaintext bytes.
*/
export async function decryptBytes(
key: Uint8Array,
payload: Uint8Array,
): Promise<Uint8Array> {
if (payload.length <= AES_GCM_IV_LENGTH) {
throw new Error('Invalid ciphertext');
}
if (key.length !== 16 && key.length !== 32) {
throw new Error('Invalid backup encryption key length');
}

const iv = payload.slice(0, AES_GCM_IV_LENGTH);
const ciphertext = payload.slice(AES_GCM_IV_LENGTH);
const cryptoKey = await globalThis.crypto.subtle.importKey(
'raw',
key,
'AES-GCM',
false,
['decrypt'],
);
const plaintext = await globalThis.crypto.subtle.decrypt(
{ name: 'AES-GCM', iv },
cryptoKey,
ciphertext,
);
return new Uint8Array(plaintext);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could re-use @metamask/cryptography for this one now.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 58428ae042879ecf40f744cf6c839a5a89801be9

Comment thread packages/keyring-eth-mpc/src/util.ts Outdated
Comment on lines +111 to +120
/**
* Convert a public key to an address.
*
* @param pubKey - The public key to convert.
* @returns The address.
*/
export function publicToAddressHex(pubKey: Uint8Array): Hex {
const addrBytes = publicToAddress(pubKey);
return bytesToHex(addrBytes);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a duplicate with publicKeyToAddressHex below (we could keep the latter, since it allows other public key format if needed).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done ba93edcd7999680c8bc999430af082948fdc7189

Comment on lines +525 to +548
/**
* Sign a transaction using the specified account.
*
* @param address - The address of the account.
* @param tx - The transaction to sign.
* @param _opts - The options for signing the transaction.
* @returns The signed transaction.
*/
async signTransaction(
address: Hex,
tx: TypedTransaction,
_opts = {},
): Promise<TypedTransaction> {
const message = tx.getHashedMessageToSign();

const signature = await this.#signHash(address, message);

const { r, s, v } = parseEthSig(signature);

// convertV adapts the message-style recovery id (27|28) to typed-tx
// yParity (0|1) or legacy EIP-155 v, matching `TypedTransaction.sign()`.
const signedTx = tx.addSignature(v, r, s, true);
return signedTx;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to discuss: Worth discussing if we should implement this one or not. The MoneyKeyring is not, so we might want to "disable" it too maybe.

(Though, this keyring is mostly generic, so that makes sense to have it there, maybe just disabling this method on the KeyringAccount on the v2 wrapper would be enough, since the v2 wrapper would reject it)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Should we do what we did for the MoneyKeyring, just have the "generic" part (e.g HD keyring) and then have a more "specific"/"scoped"/"restricted" keyring for the Money keyring with MPC support

tl;dr; We keep it generic + create a MoneyMpcKeyring just for the Money context

Comment on lines +685 to +691
this.#applyKeyState({
keyShare,
netCreds,
serverNetId,
shareEpoch: INITIAL_SHARE_EPOCH,
tssSetup,
});

@ccharly ccharly Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to discuss: Similar comments than for rotateKeyShares and the potential missing client share (already discussed there)

Comment thread packages/keyring-eth-mpc/src/cloud.ts Outdated
token: string;
}): Promise<PartyId> {
const data = await postJson<{ netId: string }>(
`${opts.baseURL}/net-id`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what our other components are using for this...

Having it explicit makes it clear which version we are depending one, but it would also require a new release of the keyring if somehow we go with a new /v3. That being said, v3 would means breaking changes, so meaning we might have to update the keyring part regardless.

I'll keep this open for now and revisit once I checked our other patterns.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to discuss: (improvements for later) maybe we could move this entire networking logic in a mpc-service package, which would use BaseDataService. This way, we have a proper service to map all backend endpoints + re-use internal networking tooling (network status, custom network policy, etc..)

Though, that means the keyring would depend on another package + use the messenger.

Probably worth discussing this further.

Comment thread packages/keyring-eth-money-mpc/src/mpc-money-keyring.ts
async syncKeyShare(): Promise<void> {
return this.#serializeOp(async () => {
const state = this.#assertState();
const token = await this.#getProfileToken({ twoFactor: true });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: Do we want to use 1FA or 2FA? The reasoning is, if you have access to your SRP, then you can decrypt the device key share -> same level of access

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably switching to 1FA here. Will do in a follow up PR.

Comment thread packages/keyring-eth-mpc/src/cloud.ts Outdated
@ccharly

ccharly commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

@metamaskbot publish-preview

@github-actions

Copy link
Copy Markdown

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "2.1.1-ddf7c58",
  "@metamask-previews/hw-wallet-sdk": "1.0.0-ddf7c58",
  "@metamask-previews/keyring-api": "24.2.0-ddf7c58",
  "@metamask-previews/eth-hd-keyring": "15.0.1-ddf7c58",
  "@metamask-previews/eth-ledger-bridge-keyring": "13.1.1-ddf7c58",
  "@metamask-previews/eth-money-keyring": "4.0.1-ddf7c58",
  "@metamask-previews/eth-mpc-keyring": "0.0.0-ddf7c58",
  "@metamask-previews/eth-qr-keyring": "3.0.1-ddf7c58",
  "@metamask-previews/eth-simple-keyring": "13.0.1-ddf7c58",
  "@metamask-previews/eth-trezor-keyring": "11.0.1-ddf7c58",
  "@metamask-previews/keyring-internal-api": "12.1.1-ddf7c58",
  "@metamask-previews/keyring-internal-snap-client": "11.1.1-ddf7c58",
  "@metamask-previews/keyring-sdk": "4.0.0-ddf7c58",
  "@metamask-previews/eth-snap-keyring": "24.1.1-ddf7c58",
  "@metamask-previews/keyring-snap-client": "10.0.1-ddf7c58",
  "@metamask-previews/keyring-snap-sdk": "10.0.1-ddf7c58",
  "@metamask-previews/keyring-utils": "5.0.0-ddf7c58",
  "@metamask-previews/watch-only-keyring": "0.1.1-ddf7c58"
}

@matthiasgeihs matthiasgeihs removed the DO-NOT-MERGE PRs related to this issue should not be merged label Oct 12, 2026
matthiasgeihs and others added 11 commits October 12, 2026 17:50
Map relative .js specifiers back to TypeScript sources so the MPC keyring tests can load. Also point the skipLibCheck note at the MFA network package.

Co-authored-by: Cursor <cursoragent@cursor.com>
…etup mode

A payload with invalid initialized fields and mode was accepted as setup because extra keys are ignored, which dropped the key material.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop publicToAddressHex and compare recovered keys with publicKeyToAddressHex, which accepts raw and SEC1 keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse the shared AES-GCM helpers for key-share backup encryption.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ounts (#669)

## Summary
- Rename the package from `keyring-eth-mpc` /
`@metamask/eth-mpc-keyring` to `keyring-eth-money-mpc` /
`@metamask/eth-money-mpc-keyring`.
- Rename the V1 and V2 keyring classes to `MpcMoneyKeyring`, and the
controller type to `MPC Money Keyring`.
- Update the related public types, source filenames, and monorepo
references (README, tsconfig, Yarn constraints, PR title scope).

## Test plan
- [ ] `yarn workspace @metamask/eth-money-mpc-keyring test`
- [ ] Confirm the controller still registers the keyring under `MPC
Money Keyring`
- [ ] Confirm `KeyringType.Mpc` and
`KeyringAccountEntropyTypeOption.Mpc` are unchanged


Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
Money accounts do not sign transactions, so drop signTransaction and the helpers that only existed for it.

Co-authored-by: Cursor <cursoragent@cursor.com>
@matthiasgeihs

Copy link
Copy Markdown
Author

Changelog check failed because we removed keyring-eth-mpc.

Changelog check failed for package keyring-eth-mpc: CHANGELOG.md not found at packages/keyring-eth-mpc/CHANGELOG.md

https://github.com/MetaMask/accounts/actions/runs/38461132928/job/115516282911?pr=627

==> Disabling changelog check

@matthiasgeihs matthiasgeihs changed the title feat: add Ethereum MPC keyring feat: add Ethereum MPC Money Keyring Oct 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants