<ExportPrivateKey /> component, which hosts the key inside a screenshot-protected native WebView. In every case the key is rendered inside a sandboxed document and never crosses into your application’s JavaScript.
Usage
- JavaScript
- React
- React Native
import { exportWaasPrivateKey, isWaasWalletAccount } from '@dynamic-labs-sdk/client/waas';
import { client } from './client';
const exportPrivateKey = async () => {
const walletAccounts = client.wallets.getWalletAccounts();
const walletAccount = walletAccounts[0];
if (!isWaasWalletAccount({ walletAccount })) return;
await exportWaasPrivateKey({
walletAccount,
displayContainer: document.getElementById('display-container'),
});
};
// Add a container in your UI to inject the iframe
// E.g: <div id="display-container"></div>
Use a
ref to pass the DOM element to exportWaasPrivateKey:import { exportWaasPrivateKey, isWaasWalletAccount } from '@dynamic-labs-sdk/client/waas';
import { getWalletAccounts } from '@dynamic-labs-sdk/client';
import { useRef } from 'react';
function ExportPrivateKey() {
const containerRef = useRef<HTMLDivElement>(null);
const handleExport = async () => {
const walletAccounts = getWalletAccounts();
const walletAccount = walletAccounts[0];
if (!walletAccount || !isWaasWalletAccount({ walletAccount }) || !containerRef.current) return;
await exportWaasPrivateKey({
walletAccount,
displayContainer: containerRef.current,
});
};
return (
<div>
<button onClick={handleExport}>Export private key</button>
<div ref={containerRef} />
</div>
);
}
On React Native the key is displayed by the Install the package and its Mount Props
To show a spinner while the key resolves, render your own indicator behind the component (the display is transparent while it loads) and hide it on
<ExportPrivateKey /> component from a dedicated package. It renders the key inside a react-native-webview with screenshot/recording protection enabled, and the key never crosses the JS bridge — your app code cannot read, log, or screenshot it.Configure the client for React Native first. See React Native Setup.
react-native-webview peer dependency:- Expo
- Bare React Native
npx expo install @dynamic-labs-sdk/react-native-embedded-wallet-export react-native-webview
npm install @dynamic-labs-sdk/react-native-embedded-wallet-export react-native-webview
cd ios && bundle exec pod install && cd ..
<ExportPrivateKey /> to show the key and unmount it to dismiss — the component owns the display’s lifecycle. Place it inside your own modal or card with a close button.import { ExportPrivateKey } from '@dynamic-labs-sdk/react-native-embedded-wallet-export';
import { getWalletAccounts } from '@dynamic-labs-sdk/client';
import { isWaasWalletAccount } from '@dynamic-labs-sdk/client/waas';
import { useState } from 'react';
import { Button, Modal, View } from 'react-native';
function ExportPrivateKeyScreen() {
const [revealing, setRevealing] = useState(false);
const walletAccount = getWalletAccounts()[0];
if (!walletAccount || !isWaasWalletAccount({ walletAccount })) return null;
return (
<View>
<Button title="Reveal private key" onPress={() => setRevealing(true)} />
<Modal visible={revealing} onRequestClose={() => setRevealing(false)}>
{revealing && (
<ExportPrivateKey
walletAccount={walletAccount}
onError={(error) => {
// Log a non-sensitive representation only — the raw error
// may carry key material.
const errorType =
error instanceof Error ? error.name : typeof error;
console.warn('Private key export failed', { errorType });
setRevealing(false);
}}
/>
)}
<Button title="Done" onPress={() => setRevealing(false)} />
</Modal>
</View>
);
}
Exporting a private key is a sensitive action guarded by the
wallet:export scope, so the SDK requires an elevated session for the export ceremony. If your environment enforces MFA, the user is prompted to step up before the key is shown. See Step-up authentication.| Prop | Type | Description |
|---|---|---|
walletAccount | WalletAccount | The WaaS wallet account to export. Required. |
password | string | Optional password to decrypt the private key. |
onComplete | () => void | Fires once the key is displayed. Receives no key material. |
onError | (error: unknown) => void | Fires on failure. The error never contains key material. |
style | StyleProp<ViewStyle> | Styles the box that hosts the key display; the WebView fills it. |
onComplete. Keep the spinner pointerEvents="none" so it doesn’t intercept taps meant for the key display.Error Handling
- If the specified wallet account is not a WaaS WalletAccount, it will throw an
NotWaasWalletAccountErrorerror.