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>
);
};