@zerodev/wallet-react 0.0.1-alpha.4 → 0.0.1-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +14 -1
- package/dist/_cjs/actions.js +30 -3
- package/dist/_cjs/connector.js +7 -12
- package/dist/_cjs/hooks/useExportPrivateKey.js +18 -0
- package/dist/_cjs/index.js +3 -1
- package/dist/_cjs/provider.js +5 -2
- package/dist/_cjs/store.js +4 -9
- package/dist/_esm/actions.js +31 -1
- package/dist/_esm/connector.js +7 -13
- package/dist/_esm/hooks/useExportPrivateKey.js +18 -0
- package/dist/_esm/index.js +1 -0
- package/dist/_esm/provider.js +5 -2
- package/dist/_esm/store.js +4 -10
- package/dist/_types/actions.d.ts +19 -0
- package/dist/_types/actions.d.ts.map +1 -1
- package/dist/_types/connector.d.ts.map +1 -1
- package/dist/_types/hooks/useExportPrivateKey.d.ts +18 -0
- package/dist/_types/hooks/useExportPrivateKey.d.ts.map +1 -0
- package/dist/_types/index.d.ts +1 -0
- package/dist/_types/index.d.ts.map +1 -1
- package/dist/_types/provider.d.ts.map +1 -1
- package/dist/_types/store.d.ts +4 -4
- package/dist/_types/store.d.ts.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/actions.ts +64 -4
- package/src/connector.ts +8 -14
- package/src/hooks/useExportPrivateKey.ts +57 -0
- package/src/index.ts +1 -0
- package/src/provider.ts +5 -2
- package/src/store.ts +6 -12
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerodev/wallet-react",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.6",
|
|
4
4
|
"description": "React hooks for ZeroDev Wallet SDK",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/_cjs/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"wagmi": "^3.0.0",
|
|
31
31
|
"zustand": "^5.0.3",
|
|
32
32
|
"ox": "^0.3.0",
|
|
33
|
-
"@zerodev/wallet-core": "0.0.1-alpha.
|
|
33
|
+
"@zerodev/wallet-core": "0.0.1-alpha.6"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/react": "^19",
|
package/src/actions.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { Config, Connector } from '@wagmi/core'
|
|
2
2
|
import { connect as wagmiConnect } from '@wagmi/core/actions'
|
|
3
|
+
import {
|
|
4
|
+
createIframeStamper,
|
|
5
|
+
exportPrivateKey as exportPrivateKeySdk,
|
|
6
|
+
exportWallet as exportWalletSdk,
|
|
7
|
+
} from '@zerodev/wallet-core'
|
|
3
8
|
import type { OAuthProvider } from './oauth.js'
|
|
4
9
|
import {
|
|
5
10
|
buildOAuthUrl,
|
|
@@ -362,10 +367,6 @@ export async function exportWallet(
|
|
|
362
367
|
|
|
363
368
|
if (!wallet) throw new Error('Wallet not initialized')
|
|
364
369
|
|
|
365
|
-
const { exportWallet: exportWalletSdk, createIframeStamper } = await import(
|
|
366
|
-
'@zerodev/wallet-core'
|
|
367
|
-
)
|
|
368
|
-
|
|
369
370
|
const iframeContainer = document.getElementById(parameters.iframeContainerId)
|
|
370
371
|
if (!iframeContainer) {
|
|
371
372
|
throw new Error('Iframe container not found')
|
|
@@ -400,3 +401,62 @@ export declare namespace exportWallet {
|
|
|
400
401
|
type ReturnType = void
|
|
401
402
|
type ErrorType = Error
|
|
402
403
|
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Export private key
|
|
407
|
+
*/
|
|
408
|
+
export async function exportPrivateKey(
|
|
409
|
+
config: Config,
|
|
410
|
+
parameters: {
|
|
411
|
+
iframeContainerId: string
|
|
412
|
+
address?: string
|
|
413
|
+
keyFormat?: 'Hexadecimal' | 'Solana'
|
|
414
|
+
connector?: Connector
|
|
415
|
+
},
|
|
416
|
+
): Promise<void> {
|
|
417
|
+
const connector = parameters.connector ?? getZeroDevConnector(config)
|
|
418
|
+
|
|
419
|
+
// @ts-expect-error - getStore is a custom method
|
|
420
|
+
const store = await connector.getStore()
|
|
421
|
+
const wallet = store.getState().wallet
|
|
422
|
+
|
|
423
|
+
if (!wallet) throw new Error('Wallet not initialized')
|
|
424
|
+
|
|
425
|
+
const iframeContainer = document.getElementById(parameters.iframeContainerId)
|
|
426
|
+
if (!iframeContainer) {
|
|
427
|
+
throw new Error('Iframe container not found')
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const iframeStamper = await createIframeStamper({
|
|
431
|
+
iframeUrl: 'https://export.turnkey.com',
|
|
432
|
+
iframeContainer,
|
|
433
|
+
iframeElementId: 'export-private-key-iframe',
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
const publicKey = await iframeStamper.init()
|
|
437
|
+
const { exportBundle, organizationId } = await exportPrivateKeySdk({
|
|
438
|
+
wallet,
|
|
439
|
+
targetPublicKey: publicKey,
|
|
440
|
+
...(parameters.address && { address: parameters.address }),
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
const success = await iframeStamper.injectKeyExportBundle(
|
|
444
|
+
exportBundle,
|
|
445
|
+
organizationId,
|
|
446
|
+
parameters.keyFormat ?? 'Hexadecimal',
|
|
447
|
+
)
|
|
448
|
+
if (success !== true) {
|
|
449
|
+
throw new Error('Failed to inject export bundle')
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export declare namespace exportPrivateKey {
|
|
454
|
+
type Parameters = {
|
|
455
|
+
iframeContainerId: string
|
|
456
|
+
address?: string
|
|
457
|
+
keyFormat?: 'Hexadecimal' | 'Solana'
|
|
458
|
+
connector?: Connector
|
|
459
|
+
}
|
|
460
|
+
type ReturnType = void
|
|
461
|
+
type ErrorType = Error
|
|
462
|
+
}
|
package/src/connector.ts
CHANGED
|
@@ -75,10 +75,6 @@ export function zeroDevWallet(
|
|
|
75
75
|
store = createZeroDevWalletStore()
|
|
76
76
|
store.getState().setWallet(wallet)
|
|
77
77
|
|
|
78
|
-
// Initialize chainIds
|
|
79
|
-
const chainIds = params.chains.map((c) => c.id)
|
|
80
|
-
store.setState({ chainIds })
|
|
81
|
-
|
|
82
78
|
// Store OAuth config if provided
|
|
83
79
|
if (params.oauthConfig) {
|
|
84
80
|
store.getState().setOAuthConfig(params.oauthConfig)
|
|
@@ -132,10 +128,8 @@ export function zeroDevWallet(
|
|
|
132
128
|
const state = store.getState()
|
|
133
129
|
|
|
134
130
|
// Determine active chain
|
|
135
|
-
const activeChainId =
|
|
136
|
-
|
|
137
|
-
throw new Error('No chain configured')
|
|
138
|
-
}
|
|
131
|
+
const activeChainId =
|
|
132
|
+
chainId ?? state.activeChainId ?? params.chains[0].id
|
|
139
133
|
|
|
140
134
|
// If reconnecting and already have kernel account, return immediately
|
|
141
135
|
if (isReconnecting && state.kernelAccounts.has(activeChainId)) {
|
|
@@ -198,7 +192,7 @@ export function zeroDevWallet(
|
|
|
198
192
|
}
|
|
199
193
|
|
|
200
194
|
// Set as active chain
|
|
201
|
-
store.getState().
|
|
195
|
+
store.getState().setActiveChainId(activeChainId)
|
|
202
196
|
|
|
203
197
|
// Get fresh state after updates
|
|
204
198
|
const freshState = store.getState()
|
|
@@ -229,7 +223,7 @@ export function zeroDevWallet(
|
|
|
229
223
|
|
|
230
224
|
async getAccounts() {
|
|
231
225
|
if (!store) return []
|
|
232
|
-
const { eoaAccount, kernelAccounts,
|
|
226
|
+
const { eoaAccount, kernelAccounts, activeChainId } = store.getState()
|
|
233
227
|
|
|
234
228
|
// Return EOA address if we have it (EIP-7702: EOA address = kernel address)
|
|
235
229
|
if (eoaAccount) {
|
|
@@ -237,15 +231,15 @@ export function zeroDevWallet(
|
|
|
237
231
|
}
|
|
238
232
|
|
|
239
233
|
// Fallback: check kernel accounts
|
|
240
|
-
const activeAccount =
|
|
241
|
-
? kernelAccounts.get(
|
|
234
|
+
const activeAccount = activeChainId
|
|
235
|
+
? kernelAccounts.get(activeChainId)
|
|
242
236
|
: null
|
|
243
237
|
return activeAccount ? [activeAccount.address] : []
|
|
244
238
|
},
|
|
245
239
|
|
|
246
240
|
async getChainId() {
|
|
247
241
|
if (!store) return params.chains[0].id
|
|
248
|
-
return store.getState().
|
|
242
|
+
return store.getState().activeChainId ?? params.chains[0].id
|
|
249
243
|
},
|
|
250
244
|
|
|
251
245
|
async getProvider() {
|
|
@@ -264,7 +258,7 @@ export function zeroDevWallet(
|
|
|
264
258
|
}
|
|
265
259
|
|
|
266
260
|
// Update active chain
|
|
267
|
-
store.getState().
|
|
261
|
+
store.getState().setActiveChainId(chainId)
|
|
268
262
|
|
|
269
263
|
// Create kernel account for new chain if doesn't exist
|
|
270
264
|
if (!state.kernelAccounts.has(chainId)) {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type UseMutationOptions,
|
|
5
|
+
type UseMutationResult,
|
|
6
|
+
useMutation,
|
|
7
|
+
} from '@tanstack/react-query'
|
|
8
|
+
import { type Config, type ResolvedRegister, useConfig } from 'wagmi'
|
|
9
|
+
import { exportPrivateKey } from '../actions.js'
|
|
10
|
+
|
|
11
|
+
type ConfigParameter<config extends Config = Config> = {
|
|
12
|
+
config?: Config | config | undefined
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Hook to export private key
|
|
17
|
+
*/
|
|
18
|
+
export function useExportPrivateKey<
|
|
19
|
+
config extends Config = ResolvedRegister['config'],
|
|
20
|
+
context = unknown,
|
|
21
|
+
>(
|
|
22
|
+
parameters: useExportPrivateKey.Parameters<config, context> = {},
|
|
23
|
+
): useExportPrivateKey.ReturnType<context> {
|
|
24
|
+
const { mutation } = parameters
|
|
25
|
+
const config = useConfig(parameters)
|
|
26
|
+
|
|
27
|
+
return useMutation({
|
|
28
|
+
...mutation,
|
|
29
|
+
async mutationFn(variables: exportPrivateKey.Parameters) {
|
|
30
|
+
return exportPrivateKey(config, variables)
|
|
31
|
+
},
|
|
32
|
+
mutationKey: ['exportPrivateKey'],
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export declare namespace useExportPrivateKey {
|
|
37
|
+
type Parameters<
|
|
38
|
+
config extends Config = Config,
|
|
39
|
+
context = unknown,
|
|
40
|
+
> = ConfigParameter<config> & {
|
|
41
|
+
mutation?:
|
|
42
|
+
| UseMutationOptions<
|
|
43
|
+
exportPrivateKey.ReturnType,
|
|
44
|
+
exportPrivateKey.ErrorType,
|
|
45
|
+
exportPrivateKey.Parameters,
|
|
46
|
+
context
|
|
47
|
+
>
|
|
48
|
+
| undefined
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type ReturnType<context = unknown> = UseMutationResult<
|
|
52
|
+
exportPrivateKey.ReturnType,
|
|
53
|
+
exportPrivateKey.ErrorType,
|
|
54
|
+
exportPrivateKey.Parameters,
|
|
55
|
+
context
|
|
56
|
+
>
|
|
57
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { ZeroDevWalletConnectorParams } from './connector.js'
|
|
2
2
|
export { zeroDevWallet } from './connector.js'
|
|
3
3
|
export { useAuthenticateOAuth } from './hooks/useAuthenticateOAuth.js'
|
|
4
|
+
export { useExportPrivateKey } from './hooks/useExportPrivateKey.js'
|
|
4
5
|
export { useExportWallet } from './hooks/useExportWallet.js'
|
|
5
6
|
export { useLoginPasskey } from './hooks/useLoginPasskey.js'
|
|
6
7
|
export { useRefreshSession } from './hooks/useRefreshSession.js'
|
package/src/provider.ts
CHANGED
|
@@ -115,7 +115,10 @@ export function createProvider({
|
|
|
115
115
|
|
|
116
116
|
async request({ method, params }: { method: string; params?: any[] }) {
|
|
117
117
|
const state = store.getState()
|
|
118
|
-
const activeChainId = state.
|
|
118
|
+
const activeChainId = state.activeChainId
|
|
119
|
+
if (!activeChainId) {
|
|
120
|
+
throw new Error('No active chain')
|
|
121
|
+
}
|
|
119
122
|
|
|
120
123
|
switch (method) {
|
|
121
124
|
case 'eth_accounts': {
|
|
@@ -219,7 +222,7 @@ export function createProvider({
|
|
|
219
222
|
const chainId_number = parseInt(chainId, 16)
|
|
220
223
|
|
|
221
224
|
// Update active chain
|
|
222
|
-
store.getState().
|
|
225
|
+
store.getState().setActiveChainId(chainId_number)
|
|
223
226
|
|
|
224
227
|
// Emit chainChanged event
|
|
225
228
|
emitter.emit('chainChanged', chainId)
|
package/src/store.ts
CHANGED
|
@@ -19,7 +19,7 @@ export type ZeroDevWalletState = {
|
|
|
19
19
|
session: ZeroDevWalletSession | null
|
|
20
20
|
|
|
21
21
|
// Multi-chain support
|
|
22
|
-
|
|
22
|
+
activeChainId: number | null
|
|
23
23
|
kernelAccounts: Map<number, SmartAccount<KernelSmartAccountImplementation>>
|
|
24
24
|
kernelClients: Map<number, KernelAccountClient>
|
|
25
25
|
|
|
@@ -38,7 +38,7 @@ export type ZeroDevWalletState = {
|
|
|
38
38
|
) => void
|
|
39
39
|
setKernelClient: (chainId: number, client: KernelAccountClient) => void
|
|
40
40
|
setSession: (session: ZeroDevWalletSession | null) => void
|
|
41
|
-
|
|
41
|
+
setActiveChainId: (chainId: number | null) => void
|
|
42
42
|
setIsExpiring: (isExpiring: boolean) => void
|
|
43
43
|
setOAuthConfig: (config: OAuthConfig | null) => void
|
|
44
44
|
clear: () => void
|
|
@@ -53,7 +53,7 @@ export const createZeroDevWalletStore = () =>
|
|
|
53
53
|
wallet: null,
|
|
54
54
|
eoaAccount: null,
|
|
55
55
|
session: null,
|
|
56
|
-
|
|
56
|
+
activeChainId: null,
|
|
57
57
|
kernelAccounts: new Map(),
|
|
58
58
|
kernelClients: new Map(),
|
|
59
59
|
isExpiring: false,
|
|
@@ -78,13 +78,7 @@ export const createZeroDevWalletStore = () =>
|
|
|
78
78
|
|
|
79
79
|
setSession: (session) => set({ session }),
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
const { chainIds } = get()
|
|
83
|
-
// Move chainId to front, remove duplicates
|
|
84
|
-
set({
|
|
85
|
-
chainIds: [chainId, ...chainIds.filter((id) => id !== chainId)],
|
|
86
|
-
})
|
|
87
|
-
},
|
|
81
|
+
setActiveChainId: (chainId) => set({ activeChainId: chainId }),
|
|
88
82
|
|
|
89
83
|
setIsExpiring: (isExpiring) => set({ isExpiring }),
|
|
90
84
|
|
|
@@ -97,7 +91,7 @@ export const createZeroDevWalletStore = () =>
|
|
|
97
91
|
kernelAccounts: new Map(),
|
|
98
92
|
kernelClients: new Map(),
|
|
99
93
|
isExpiring: false,
|
|
100
|
-
|
|
94
|
+
activeChainId: null,
|
|
101
95
|
}),
|
|
102
96
|
}),
|
|
103
97
|
{
|
|
@@ -105,7 +99,7 @@ export const createZeroDevWalletStore = () =>
|
|
|
105
99
|
// Only persist session data, not clients or accounts
|
|
106
100
|
partialize: (state) => ({
|
|
107
101
|
session: state.session,
|
|
108
|
-
|
|
102
|
+
activeChainId: state.activeChainId,
|
|
109
103
|
}),
|
|
110
104
|
},
|
|
111
105
|
),
|