Support Topic — Exported private key generates a different Ethereum address than eth_accounts (Sapphire MPC)

Describe your issue or question:

When I export the private key via the Web3Auth modal’s built-in “Export Private Key” screen and import it into MetaMask (“Import Account → Private Key”), MetaMask derives a completely different Ethereum address than the one the application shows (fetched via eth_accounts).

I verified this programmatically using viem’s privateKeyToAddress — the mismatch is confirmed.


Which platform or framework are you using?

React 18 embedded in a Shopify Storefront (Theme extension). Bundle built with Vite 7, deployed as a client-side React app injected into a Liquid template.


Which Web3Auth SDK (name and version) are you using?

@web3auth/modal v10.15.0 — React hooks API (Web3AuthProvider, useWeb3Auth, useWeb3AuthConnect).

Network: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET


What is not working as expected?

The address shown in the app and the address derived from the exported private key do not match. I expected both to represent the same Ethereum EOA.


Code snippets:

web3authContext.js:

import { WEB3AUTH_NETWORK, CHAIN_NAMESPACES } from '@web3auth/modal'

const web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'BDhVeIJW...ldzkE',
    web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
    chainConfig: {
      chainNamespace: CHAIN_NAMESPACES.EIP155,
      chainId: '0x1', // Ethereum Mainnet
      rpcTarget: 'https://rpc.ankr.com/eth',
    },
  },
}
export default web3AuthContextConfig

App.jsx — how the address is fetched:

const accounts = await provider.request({ method: 'eth_accounts' })
const activeAddress = accounts[0] // displayed in UI

Exact errors and logs:

Test 1 — Attempting to get the private key programmatically:

await provider.request({ method: 'eth_private_key' })
// → Error -32603: "The method eth_private_key does not exist/is not available"

This confirms the SDK is running in MPC mode — the full private key never exists in the provider context.

Test 2 — Verifying the exported key with viem:

import { privateKeyToAddress } from 'viem/accounts'

const exportedPK = '0x<key shown in Web3Auth Export Private Key screen>'
console.log(privateKeyToAddress(exportedPK))
// → 0x90B028c26c062DB75c7203F0DEe7C27B2B1B3306

console.log(await provider.request({ method: 'eth_accounts' }))
// → 0xa29286f8ff9219234742e4639fAec01f7ea4AF4c

The two addresses are completely different. The exported key is a valid 32-byte secp256k1 key, but it does NOT correspond to the wallet address the provider uses.

Test 3 — Importing into MetaMask:
Pasting the exported key into MetaMask → “Import Account” produces 0x90B028..., not 0xa29286....


Package details:

Package Version
@web3auth/modal ^10.15.0
react ^18.2.0
viem ^2.45.0
vite ^7.3.1

Question:

In SAPPHIRE_DEVNET MPC mode, what exactly does the “Export Private Key” screen export — is it a tKey share, a partial key, or a seed? Is there any supported way to obtain the actual private key that corresponds to the eth_accounts address so it can be imported into MetaMask or another wallet?

Short answer: this is expected. In Sapphire (MPC) mode the modal’s “Export Private Key” does NOT give you the MPC signing key that eth_accounts returns — it exports a separate, non‑MPC EOA key for compatibility. The real MPC key is split into shares and is never reconstructed or exportable on the client (eth_private_key is unavailable for that reason).

What this means for you:

  • The address from provider.request({ method: ‘eth_accounts’ }) is the MPC wallet address.
  • The key shown in the Web3Auth “Export Private Key” screen is a different, standalone EOA private key (so importing it into MetaMask will produce a different address, as you observed).
  • There is no supported way to extract the actual MPC private key for import into MetaMask or other EOA wallets.

If you need an exportable/importable EOA, you must create the wallet in a non‑MPC mode (tKey/self‑custody) or use an EOA flow (e.g., MetaMask SDK) instead. Also check your Web3Auth dashboard Key Export Settings and avoid toggling flags like useSFAKey/useCoreKitKey in production — changing those or Client ID / Sapphire network / connection config will change derived addresses.

If you want, I can: (A) walk you through switching to a non‑MPC/exportable setup or (B) escalate this to the team if you think something in your integration is misconfigured. Which would you prefer?

Note: This response was generated by an AI bot and may require further verification. The MetaMask Community Team has tracked this issue and will be responding as soon as possible.

Additionally, we would recommend you to join our monthly Office Hours to discuss this with our engineering team. MetaMask Developer Office Hours

Hi @Vinicius_Gouveia ! Please let us know if the above info helps you, or you would need help from us.