Skip to content

Commit ab3ca00

Browse files
committed
export PK button
1 parent 28b8cfa commit ab3ca00

File tree

3 files changed

+226
-50
lines changed

3 files changed

+226
-50
lines changed

quick-starts/react-quick-start/src/App.css

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,42 @@
1-
/* Modern, mobile-first CSS with improved form elements */
1+
/* Modern, mobile-first CSS with Dark Theme */
22
:root {
3-
/* Web3Auth Docs Inspired Colors (Light Mode) */
4-
--primary-color: #0364ff; /* Web3Auth Blue */
5-
--primary-hover: #0050cc;
6-
--bg-color: #ffffff;
7-
--bg-light: #f7f7f7; /* Slightly off-white for cards/inputs */
8-
--bg-hover: #eeeeee;
9-
--border-color: #e0e0e0; /* Lighter border */
10-
--text-color: #1c1e21; /* Darker text */
11-
--text-muted: #5f6368;
12-
--radius: 6px; /* Slightly smaller radius */
13-
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
14-
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1);
15-
/* Font stack remains similar, common sans-serif */
3+
/* Web3Auth Docs Inspired Colors (Dark Mode - Bluish) */
4+
--primary-color: #529dff; /* Slightly adjusted blue */
5+
--primary-hover: #75b5ff;
6+
--bg-color: #171c2a; /* Dark blue-gray background */
7+
--bg-light: #23293d; /* Lighter blue-gray for elements */
8+
--bg-hover: #2f364f; /* Hover state for blue-gray */
9+
--border-color: #3b415c; /* Border matching blue-gray theme */
10+
--text-color: #e1e3e8; /* Light text */
11+
--text-muted: #9399a8;
12+
--radius: 6px;
13+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
14+
--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.4);
1615
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
1716
}
1817

19-
/* Dark Mode Variables */
20-
@media (prefers-color-scheme: dark) {
21-
:root {
22-
/* Web3Auth Docs Inspired Colors (Dark Mode - Bluish) */
23-
--primary-color: #529dff; /* Slightly adjusted blue */
24-
--primary-hover: #75b5ff;
25-
--bg-color: #171c2a; /* Dark blue-gray background */
26-
--bg-light: #23293d; /* Lighter blue-gray for elements */
27-
--bg-hover: #2f364f; /* Hover state for blue-gray */
28-
--border-color: #3b415c; /* Border matching blue-gray theme */
29-
--text-color: #e1e3e8; /* Light text */
30-
--text-muted: #9399a8;
31-
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
32-
--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.4);
33-
}
34-
35-
/* Keep input background consistent with --bg-light */
36-
input, select, textarea {
37-
background-color: var(--bg-light);
38-
border-color: var(--border-color);
39-
color: var(--text-color);
40-
}
18+
/* Keep input background consistent with --bg-light */
19+
input, select, textarea {
20+
background-color: var(--bg-light);
21+
border-color: var(--border-color);
22+
color: var(--text-color);
23+
}
4124

42-
input:focus, select:focus, textarea:focus {
43-
border-color: var(--primary-color);
44-
box-shadow: 0 0 0 3px rgba(64, 144, 255, 0.3);
45-
}
25+
input:focus, select:focus, textarea:focus {
26+
border-color: var(--primary-color);
27+
box-shadow: 0 0 0 3px rgba(64, 144, 255, 0.3);
28+
}
4629

47-
/* Keep button background consistent with --bg-light or slightly darker */
48-
button, .card {
49-
background-color: var(--bg-light);
50-
border-color: var(--border-color);
51-
color: var(--text-color);
52-
}
30+
/* Keep button background consistent with --bg-light or slightly darker */
31+
button, .card {
32+
background-color: var(--bg-light);
33+
border-color: var(--border-color);
34+
color: var(--text-color);
35+
}
5336

54-
button:hover, .card:hover {
55-
background-color: var(--bg-hover);
56-
border-color: var(--text-muted);
57-
}
37+
button:hover, .card:hover {
38+
background-color: var(--bg-hover);
39+
border-color: var(--text-muted);
5840
}
5941

6042
* {

quick-starts/react-quick-start/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useAccount } from "wagmi";
88
import { SendTransaction } from "./components/sendTransaction";
99
import { Balance } from "./components/getBalance";
1010
import { SwitchChain } from "./components/switchNetwork";
11+
import { ExportPrivateKey } from "./components/exportPrivateKey";
1112

1213
function App() {
1314
const {
@@ -56,6 +57,7 @@ function App() {
5657
<SendTransaction />
5758
<Balance />
5859
<SwitchChain />
60+
<ExportPrivateKey />
5961
</div>
6062
);
6163

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import { useState } from "react";
2+
import { useWeb3Auth } from "@web3auth/modal/react";
3+
import { useChainId } from "wagmi";
4+
5+
export function ExportPrivateKey() {
6+
const [privateKey, setPrivateKey] = useState<string>("");
7+
const [loading, setLoading] = useState(false);
8+
const [error, setError] = useState<string>("");
9+
const [copied, setCopied] = useState(false);
10+
const { web3Auth } = useWeb3Auth();
11+
const chainId = useChainId();
12+
13+
// Get network-specific information for private key export method
14+
const getPrivateKeyMethod = () => {
15+
switch (chainId) {
16+
case 420420422: // Passet Hub (Polkadot-based)
17+
case 420420418: // Kusama Asset Hub
18+
case 420420421: // Westend
19+
return "private_key"; // Non-EVM chains
20+
case 1: // Ethereum Mainnet
21+
default:
22+
return "eth_private_key"; // Ethereum/EVM chains
23+
}
24+
};
25+
26+
const getNetworkInfo = () => {
27+
switch (chainId) {
28+
case 420420422:
29+
return { name: 'Passet Hub', type: 'Polkadot-based' };
30+
case 420420418:
31+
return { name: 'Kusama Asset Hub', type: 'Polkadot-based' };
32+
case 420420421:
33+
return { name: 'Westend Network', type: 'Polkadot-based' };
34+
case 1:
35+
return { name: 'Ethereum Mainnet', type: 'EVM' };
36+
default:
37+
return { name: 'Unknown Network', type: 'EVM' };
38+
}
39+
};
40+
41+
const networkInfo = getNetworkInfo();
42+
43+
const exportPrivateKey = async () => {
44+
if (!web3Auth?.provider) {
45+
setError("Web3Auth provider not available");
46+
return;
47+
}
48+
49+
setLoading(true);
50+
setError("");
51+
setPrivateKey("");
52+
setCopied(false);
53+
54+
try {
55+
const method = getPrivateKeyMethod();
56+
console.log(`Requesting private key using method: ${method}`);
57+
58+
const privateKeyHex = await web3Auth.provider.request({
59+
method: method
60+
});
61+
62+
if (privateKeyHex) {
63+
setPrivateKey(privateKeyHex as string);
64+
} else {
65+
setError("Failed to retrieve private key");
66+
}
67+
} catch (err: any) {
68+
console.error("Private key export error:", err);
69+
setError(err.message || "Failed to export private key");
70+
} finally {
71+
setLoading(false);
72+
}
73+
};
74+
75+
const copyToClipboard = async () => {
76+
if (privateKey) {
77+
try {
78+
await navigator.clipboard.writeText(privateKey);
79+
setCopied(true);
80+
setTimeout(() => setCopied(false), 2000);
81+
} catch (err) {
82+
console.error("Failed to copy to clipboard:", err);
83+
}
84+
}
85+
};
86+
87+
const clearPrivateKey = () => {
88+
setPrivateKey("");
89+
setError("");
90+
setCopied(false);
91+
};
92+
93+
return (
94+
<div>
95+
<h2>Export Private Key</h2>
96+
<p style={{ fontSize: '14px', color: 'var(--text-muted)', marginBottom: '10px' }}>
97+
Network: {networkInfo.name} | Type: {networkInfo.type}
98+
</p>
99+
<p style={{ fontSize: '12px', color: '#ff6b35', marginBottom: '15px' }}>
100+
⚠️ <strong>Warning:</strong> Never share your private key with anyone. Store it securely and only use it when necessary.
101+
</p>
102+
103+
<div style={{ marginBottom: '15px' }}>
104+
<button
105+
onClick={exportPrivateKey}
106+
disabled={loading || !web3Auth?.provider}
107+
style={{
108+
padding: '10px 20px',
109+
backgroundColor: loading ? 'var(--text-muted)' : '#ff6b35',
110+
color: 'white',
111+
border: 'none',
112+
borderRadius: 'var(--radius)',
113+
cursor: loading ? 'not-allowed' : 'pointer',
114+
marginRight: '10px'
115+
}}
116+
>
117+
{loading ? 'Exporting...' : 'Export Private Key'}
118+
</button>
119+
120+
{privateKey && (
121+
<button
122+
onClick={clearPrivateKey}
123+
style={{
124+
padding: '10px 20px',
125+
backgroundColor: 'var(--text-muted)',
126+
color: 'white',
127+
border: 'none',
128+
borderRadius: 'var(--radius)',
129+
cursor: 'pointer'
130+
}}
131+
>
132+
Clear
133+
</button>
134+
)}
135+
</div>
136+
137+
{error && (
138+
<div style={{
139+
marginTop: '10px',
140+
padding: '10px',
141+
backgroundColor: '#3d1a1a',
142+
borderRadius: 'var(--radius)',
143+
color: '#ff6b6b',
144+
fontSize: '14px',
145+
border: '1px solid #722020'
146+
}}>
147+
<strong>Error:</strong> {error}
148+
</div>
149+
)}
150+
151+
{privateKey && (
152+
<div style={{
153+
marginTop: '15px',
154+
padding: '15px',
155+
backgroundColor: 'var(--bg-light)',
156+
borderRadius: 'var(--radius)',
157+
border: '2px solid #ff6b35'
158+
}}>
159+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '10px' }}>
160+
<strong style={{ color: 'var(--text-color)' }}>Private Key:</strong>
161+
<button
162+
onClick={copyToClipboard}
163+
style={{
164+
padding: '5px 10px',
165+
backgroundColor: copied ? '#00cc00' : 'var(--primary-color)',
166+
color: 'white',
167+
border: 'none',
168+
borderRadius: 'var(--radius)',
169+
cursor: 'pointer',
170+
fontSize: '12px'
171+
}}
172+
>
173+
{copied ? '✓ Copied!' : 'Copy'}
174+
</button>
175+
</div>
176+
<code style={{
177+
fontSize: '12px',
178+
wordBreak: 'break-all',
179+
display: 'block',
180+
padding: '8px',
181+
backgroundColor: 'var(--bg-color)',
182+
border: '1px solid var(--border-color)',
183+
borderRadius: 'var(--radius)',
184+
color: 'var(--text-color)'
185+
}}>
186+
{privateKey}
187+
</code>
188+
</div>
189+
)}
190+
</div>
191+
);
192+
}

0 commit comments

Comments
 (0)