Export Wallet or Private Key
This is a guide to exporting your wallet or private key from Turnkey. For more information about the security of this flow, check out Enclave secure channels.
Implementation guides
Follow along with the Turnkey CLI, Embedded iframe, NodeJS, and Local Storage guides.
CLI
Install the latest version of Turnkey CLI to access the new import functionality. You can find detailed instructions for installation here.
Steps
Export a wallet (Turnkey activity)
- The
--export-bundle-output
flag (required) is the desired output file path for the “encrypted bundle” that will be returned by Turnkey. This bundle contains the encrypted key material.
Decrypt the bundle
- The
--export-bundle-input
flag (required) is the filepath for the “encrypted bundle” (from the previous step) that will be decrypted. - The
--plaintext-output
flag (optional) is a filepath for the decrypted plaintext to be written to. - The
--signer-quorum-key
flag (optional) is the public key of Turnkey’s signer enclave. This is a static value. - The
--encryption-key-name
flag (optional) is a local encryption key. This is required for import and export using the CLI. A new one can be generated usingturnkey generate encryption-key
. Seeturnkey generate --help
for more details.
Congrats! You’ve exported your wallet 🎉
Private Key support
Export a private key (Turnkey activity)
- The
--export-bundle-output
flag (required) is the desired output file path for the “encrypted bundle” that will be returned by Turnkey. This bundle contains the encrypted key material.
Decrypt the bundle
- The
--export-bundle-input
flag (required) is the file path for the “encrypted bundle” (from the previous step) that will be decrypted. - The
--plaintext-output
flag (optional) is a filepath for the decrypted plaintext to be written to. - The
--signer-quorum-key
flag (optional) is the public key of Turnkey’s signer enclave. This is a static value. - The
--solana-address
flag (optional) is the solana address corresponding to the private key you’re exporting. This will export the private key in a format compatible with most solana wallets (e.g. phantom). If unset, the resulting private key will be plain hex. - The
--encryption-key-name
flag (optional) is a local encryption key. This is required for import and export using the CLI. A new one can be generated usingturnkey generate encryption-key
. Seeturnkey generate --help
for more details.
Congrats! You’ve exported your private key 🎉
Wallet Account support
Export a wallet account (Turnkey activity)
- The
--export-bundle-output
flag (required) is the desired output file path for the “encrypted bundle” that will be returned by Turnkey. This bundle contains the encrypted key material.
Decrypt the bundle
- The
--export-bundle-input
flag (required) is the file path for the “encrypted bundle” (from the previous step) that will be decrypted. - The
--plaintext-output
flag (optional) is a filepath for the decrypted plaintext to be written to. - The
--signer-quorum-key
flag (optional) is the public key of Turnkey’s signer enclave. This is a static value. - The
--solana-address
flag (optional) is the solana address corresponding to the private key you’re exporting. This will export the private key in a format compatible with most solana wallets (e.g. phantom). If unset, the resulting private key will be plain hex. - The
--encryption-key-name
flag (optional) is a local encryption key. This is required for import and export using the CLI. A new one can be generated usingturnkey generate encryption-key
. Seeturnkey generate --help
for more details.
Congrats! You’ve exported your private key 🎉
Embedded iframe
- We have released open-source code to create target encryption keys and decrypt exported wallet mnemonics. We’ve deployed a static HTML page hosted on
export.turnkey.com
meant to be embedded as an iframe element (see the code here). This ensures the mnemonics are encrypted to keys that the user has access to, but that your organization does not (because they live in the iframe, on a separate domain). - We have also built a package to help you insert this iframe and interact with it in the context of export:
@turnkey/iframe-stamper
In the rest of this guide we’ll assume you are using these helpers.
Steps
Here’s a diagram summarizing the wallet export flow step-by-step (direct link):
Let’s review these steps in detail:
When a user on your application clicks “export”, display a new export UI. We recommend setting this export UI as a new hosted page of your application that contains language explaining the security best practices users should follow once they’ve successfully exported their wallet. Remember: once the wallet has been exported, Turnkey can no longer ensure its security.
While the UI is in a loading state, your application uses @turnkey/iframe-stamper
to insert a new iframe element:
Your code receives the iframe public key. Your application prompts the user to
sign a new EXPORT_WALLET
activity with the wallet ID and the iframe public
key in the parameters.
Your application polls for the activity response, which contains an export bundle. Remember: this export bundle is an encrypted mnemonic which can only be decrypted within the iframe.
Need help setting up async polling? Checkout our guide and helper here.
Your application injects the export bundle into the iframe for decryption and displays the iframe upon success:
Export is complete! The iframe now displays a sentence of words separated by spaces.
The exported wallet will remain stored within Turnkey’s infrastructure. In your Turnkey dashboard, the exported user Wallet will be flagged as “Exported”.
Export as Private Keys
Turnkey also supports exporting Wallet Accounts and Private Keys as private keys.
Wallet Accounts
Follow the same steps above for exporting Wallets as mnemonics, but instead use the EXPORT_WALLET_ACCOUNT
activity and the injectKeyExportBundle
method from the @turnkey/iframe-stamper
. You can pass an optional keyFormat
parameter to injectKeyExportBundle()
that will apply either hexadecimal or Solana-specific formatting to the private key that is exported in the iframe. The default key format is HEXADECIMAL
, which is used by MetaMask, MyEtherWallet, Phantom, Ledger, and Trezor for Ethereum keys. For Solana keys, you will need to pass the SOLANA
key format.
Private Keys
Follow the same steps above for exporting Wallets as mnemonics, but instead use the EXPORT_PRIVATE_KEY
activity and the injectKeyExportBundle
method from the @turnkey/iframe-stamper
. You can pass an optional keyFormat
parameter to injectKeyExportBundle()
that will apply either hexadecimal or Solana-specific formatting to the private key that is exported in the iframe. The default key format is HEXADECIMAL
, which is used by MetaMask, MyEtherWallet, Phantom, Ledger, and Trezor for Ethereum keys. For Solana keys, you will need to pass the SOLANA
key format.
At the end of a successful private key export, the iframe displays a private key.
NodeJS
A full example Node script can be found here: https://github.com/tkhq/sdk/tree/main/examples/export-in-node
Steps
Initialize a new Turnkey client
Generate a new P256 Keypair — this will serve as the target that Turnkey will encrypt key material to
Call export (Turnkey activity)
Decrypt encrypted bundle
Congrats! You’ve exported your wallet 🎉
The process is largely similar for both private keys and individual wallet accounts.
Private Key support
Initialize a new Turnkey client
Generate a new P256 Keypair — this will serve as the target that Turnkey will encrypt key material to
Call export (Turnkey activity)
Decrypt encrypted bundle
Congrats! You’ve exported your private key 🎉
Wallet Account support
Initialize a new Turnkey client
Generate a new P256 Keypair — this will serve as the target that Turnkey will encrypt key material to
Call export (Turnkey activity)
Decrypt encrypted bundle
Congrats! You’ve exported your wallet account 🎉
Local Storage
If you do not have access to an iframe (e.g. in a mobile context) or would prefer not to use an iframe, using Local Storage is an alternative method. Note that there are security considerations here due to the fact that anyone in control of your domain can access Local Storage variables.
Steps
Initialize Turnkey client
Generate a new P256 Keypair — this will serve as the target that Turnkey will encrypt key material to
Save the private key in Local Storage
Call export (Turnkey activity)
- Call export (Turnkey activity), using the embedded key as the target key for the
exportWallet
activity:
Decrypt encrypted bundle
Remove embedded key from Local Storage. This is recommended because (1) this key doesn't have to be persistent in the first place, and (2) reduces the risk of pattern detection.
Congrats! You’ve exported your wallet 🎉
The process is largely similar for both private keys and individual wallet accounts.
Private Key support
Initialize Turnkey client
Generate a new P256 Keypair — this will serve as the target that Turnkey will encrypt key material to
Save the private key in Local Storage
Call export (Turnkey activity)
Decrypt encrypted bundle
Remove embedded key from Local Storage. This is recommended because (1) this key doesn't have to be persistent in the first place, and (2) reduces the risk of pattern detection.
Congrats! You’ve exported your private key 🎉
Wallet Account support
Initialize Turnkey client
Generate a new P256 Keypair — this will serve as the target that Turnkey will encrypt key material to
Save the private key in Local Storage
Call export (Turnkey activity)
- Call export (Turnkey activity), using the embedded key as the target key for the
exportWalletAccount
activity:
Decrypt encrypted bundle
Remove embedded key from Local Storage. This is recommended because (1) this key doesn't have to be persistent in the first place, and (2) reduces the risk of pattern detection.
Congrats! You’ve exported your wallet account 🎉
Solana notes
Solana paths do not include an index
. Creating a wallet account with an index specified could lead to unexpected behavior when exporting and importing into another wallet.
When importing into a multichain wallet such as Phantom, see this guide on matching private keys across Solana, Ethereum, and Polygon.
UI customization
Everything is customizable in the import iframe except the sentence of mnemonic words, which is minimally styled: the text is left-aligned and the padding and margins are zero. Here’s an example of how you can configure the styling of the iframe.