Skip to content

Commit

Permalink
consolidate export pages. incorporate hannah's feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivia Thet committed Nov 27, 2023
1 parent cf16bf5 commit 77987c0
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 34 deletions.
3 changes: 3 additions & 0 deletions docs/getting-started/Wallets.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ Turnkey also supports raw private keys, but we recommend using Wallets since the
- Wallets can generate millions of addresses for various digital assets
- Wallets can be represented by a checksummed, mnemonic phrase making them easier to backup and recover

## Export keys

Exporting on Turnkey enables you or your end users to export a copy of a Wallet or Private Key from our system at any time. While most Turnkey users opt to keep Wallets within Turnkey's secure infrastructure, the export functionality means you are never locked into Turnkey, and gives you the freedom to design your own backup processes as you see fit. Check out our [Export Wallet guide](../integration-guides/export-wallets.md) to allow your users to securely export their wallets.
22 changes: 0 additions & 22 deletions docs/getting-started/export.md

This file was deleted.

63 changes: 51 additions & 12 deletions docs/integration-guides/export-wallets.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ slug: /integration-guides/export-wallets
---
# Export Wallet

Exporting a [Wallet](../getting-started/Wallets.md) allows your users to back up or transfer a wallet by securely viewing the wallet's [mnemonic](https://learnmeabitcoin.com/technical/mnemonic). We engineered this feature to ensure that the user can export their mnemonic without needing you in the loop.
Turnkey's export functionality allows your end users to backup or transer a [Wallet](../getting-started/Wallets.md) by securely viewing the wallet's [mnemonic phrase](https://learnmeabitcoin.com/technical/mnemonic). We engineered this feature to ensure that the user can export their mnemonic without exposing the mnemonic itsef to Turnkey or your application.

Follow along with the guide below to set up Wallet export for your end users.

## Before you start
Make sure you have created a wallet for your user.
Check out our [Quickstart guide](../getting-started/Quickstart.md) if you need help getting started.
Make sure you have created a wallet for your user. Check out our [Quickstart guide](../getting-started/Quickstart.md) if you need help getting started.


If you'd like to use a sub-organization as a wallet for your user, follow our [Wallet integration guide](./sub-organizations-as-wallets.md).
If you'd like to use a sub-organization as an end-user controlled wallet, follow our [Wallet integration guide](./sub-organizations-as-wallets.md).


## Helper packages

* We have released open-source code to create target encryption keys and decrypt exported wallet mnemonics. We've deployed this a static HTML page hosted on `export.turnkey.com` meant to be embedded as an iframe element (see the code [here](https://github.com/tkhq/frames)). 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 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](https://github.com/tkhq/frames)). 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`](https://www.npmjs.com/package/@turnkey/iframe-stamper)

In the rest of this guide we'll assume you are using these helpers.
Expand All @@ -30,7 +31,9 @@ Here's a diagram summarizing the wallet export flow step-by-step ([direct link](

Let's review these steps in detail:

1. User on `yoursite.xyz` clicks "export", and a new export UI is shown. We recommend this export UI be a new hosted page of your site or application, which contains language explaining to the user the security best practices they should follow once they've successfully exported their wallet. While the UI is in a loading state, your frontend uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to insert a new iframe element:
1. User on `yoursite.xyz` clicks "export", and a new export UI is shown. We recommend setting this export UI as a new hosted page of your site or application that contains language explaining to the user the security best practices they 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 frontend uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to insert a new iframe element:
```js
const iframeStamper = new IframeStamper({
iframeUrl: "https://export.turnkey.com",
Expand All @@ -43,17 +46,19 @@ Let's review these steps in detail:
const publicKey = await iframeStamper.init();

// Set state to not display iframe
let showIframe = false;
let displayIframe = "none";

return (
// The iframe element can be hidden until the wallet is exported
<div
style={{ display: showIframe ? "block" : "none" }}
style={{ display: displayIframe }}
/>
);
```
2. Your code receives the iframe public key. Your app prompts the user to sign a new `EXPORT_WALLET` activity with the wallet ID and the iframe public key in the parameters.
3. Your app 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](https://github.com/tkhq/sdk/tree/main/packages/http#withasyncpolling-helper).
4. Your app injects the export bundle into the iframe for decryption and displays the iframe upon success:
```js
// Inject export bundle into iframe
Expand All @@ -64,15 +69,49 @@ Let's review these steps in detail:
}
// If successfully injected, update the state to display the iframe
showIframe = true;
iframeDisplay = "block";
```

Export is complete! The iframe now displays a numbered 3-column grid of words that form the mnemonic.
Export is complete! The iframe now displays a numbered 3-column grid of words that form the mnemonic, directly to your end user.

<img src="/img/wallet_export_mnemonic.png" />

The exported wallet will remain stored within Turnkey’s infrastructure. In your dashboard, the exported user Wallet will be flagged as “Exported”.

## UI customization

To enable as much customization of brand, theme, and copy, we've limited the only non-customizable UI component in the export iframe to be the grid of words forming the mnemonic.
Everything is customizable in the export iframe except the 3-column grid of mnemonic words. Here's an example of how you can configure the styling of the iframe.
```js
const iframeCss = `
iframe {
width: 400px;
height: 330px;
border: none;
}
`;
return (
<div style={{ display: props.iframeDisplay }} id="your-container">
<style>{iframeCss}</style>
</div>
);
```
## Private Keys
Turnkey also supports exporting raw private keys. To implement export for private keys, follow the same steps above, but instead use the `EXPORT_PRIVATE_KEY` activity and the `injectKeyExportBundle` method on the [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper). At the end of a successful private key export, the iframe displays a hexadecimal-encoded raw private key.
Turnkey also supports exporting raw private keys. To implement export for private keys, follow the same steps above, but instead use the `EXPORT_PRIVATE_KEY` activity and the `injectKeyExportBundle` method from the [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper). At the end of a successful private key export, the iframe displays a hexadecimal-encoded raw private key.
## Cryptographic details
Turnkey's export functionality ensures that neither your application nor Turnkey can view the wallet mnemonic or private key. The following diagram summarizes the flow:

<img src="/img/wallet_export_cryptography.png" />

Our export flow works by anchoring export in a **target encryption key** (TEK). This target encryption key is a standard P-256 key pair and can be created in many ways: completely offline, or online inside of script using the web crypto APIs.

The public part of this key pair is passed as a parameter inside of a signed `EXPORT_WALLET` or `EXPORT_PRIVATE_KEY` activity.

Our enclave encrypts the wallet's mnemonic or raw private key to the user's TEK using the **Hybrid Public Key Encryption standard**, also known as **HPKE** or [RFC 9180](https://datatracker.ietf.org/doc/rfc9180/).

Once the activity succeeds, the encrypted mnemonic or private key can be decrypted by the target public key offline or in an online script.
Binary file added static/img/wallet_export_mnemonic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 77987c0

Please sign in to comment.