Skip to content
Alchemy Logo

Export private key

You can export a user's private key, giving them the right to exit at any time. Allowing your users to export their private key is a best practice, as it gives them full control over their account. The private key export method does not rely on external infrastructure, so a user can always export their private key.

A hook to export the private key for an account. It returns the mutation functions to kick off the export process, as well as a component to render the account recovery details in an iframe.

import { useExportAccount } from "@account-kit/react";

import { useExportAccount } from "@account-kit/react";
 
const {
  exportAccount,
  isExported,
  isExporting,
  error,
  ExportAccountComponent,
} = useExportAccount({
  params: {
    iframeContainerId: "my-iframe-container",
  },
});

To add export private key functionality to your app, use the exportPrivateKey method.

import React from "react";
import { useMutation } from "@tanstack/react-query";
import { signer } from "./signer";
 
const TurnkeyExportWalletContainerId = "turnkey-export-wallet-container-id";
const TurnkeyExportWalletElementId = "turnkey-export-wallet-element-id";
 
// This allows us to style the embedded iframe
const iframeCss = `
iframe {
    box-sizing: border-box;
    width: 100%;
    height: 120px;
    border-radius: 8px;
    border-width: 1px;
    border-style: solid;
    border-color: rgba(216, 219, 227, 1);
    padding: 20px;
}
`;
 
export const ExportPrivateKeyView = () => {
  // we are using react-query to handle loading states more easily, but feel free to use w/e state management library you prefer
  const {
    mutate: exportWallet,
    isPending,
    data,
  } = useMutation({
    mutationFn: () =>
      signer.exportWallet({
        iframeContainerId: TurnkeyExportWalletContainerId,
        iframeElementId: TurnkeyExportWalletElementId,
      }),
  });
 
  // Once the user clicks the button, a request will be sent to initialize private key export
  // once the request is complete, the iframe will be rendered with either
  // 1. the private key if the user is logged in with a passkey
  // 2. the seed phrase if the user is logged in with email
  return (
    <div className="flex flex-col gap-2">
      {!data ? (
        <button onClick={() => exportWallet()} disabled={isPending}>
          Export Wallet
        </button>
      ) : (
        <strong>Seed Phrase</strong>
      )}
      <div
        className="w-full"
        style={{ display: !data ? "none" : "block" }}
        id={TurnkeyExportWalletContainerId}
      >
        <style>{iframeCss}</style>
      </div>
    </div>
  );
};
Was this page helpful?