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