@zerodev/wallet-react 0.0.1-alpha.0 → 0.0.1-alpha.1

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @zerodev/wallet-react
2
2
 
3
+ ## 0.0.1-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: changed default aaUrl to staging url
8
+
3
9
  ## 0.0.1-alpha.0
4
10
 
5
11
  ### Patch Changes
package/README.md ADDED
@@ -0,0 +1,269 @@
1
+ # @zerodev/wallet-react
2
+
3
+ React hooks and Wagmi connector for ZeroDev Wallet SDK with EIP-7702 gasless transactions.
4
+
5
+ ## Features
6
+
7
+ - **Wagmi Integration** - Works seamlessly with the Wagmi ecosystem
8
+ - **Multiple Auth Methods** - Passkey (WebAuthn), Email OTP, OAuth (Google)
9
+ - **Gasless Transactions** - All transactions are gasless via EIP-7702
10
+ - **Session Management** - Auto-refresh with configurable thresholds
11
+ - **Multi-Chain** - Lazy kernel account creation per chain
12
+ - **TypeScript** - Full type safety with proper generics
13
+ - **React Query** - Built on TanStack Query for optimal UX
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @zerodev/wallet-react @zerodev/wallet-core wagmi viem
19
+ # or
20
+ yarn add @zerodev/wallet-react @zerodev/wallet-core wagmi viem
21
+ # or
22
+ pnpm add @zerodev/wallet-react @zerodev/wallet-core wagmi viem
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ### 1. Configure Wagmi
28
+
29
+ ```typescript
30
+ import { createConfig, http } from 'wagmi'
31
+ import { sepolia } from 'wagmi/chains'
32
+ import { zeroDevWallet } from '@zerodev/wallet-react'
33
+
34
+ const config = createConfig({
35
+ chains: [sepolia],
36
+ connectors: [
37
+ zeroDevWallet({
38
+ projectId: 'YOUR_PROJECT_ID',
39
+ aaUrl: 'YOUR_AA_PROVIDER_URL',
40
+ chains: [sepolia],
41
+ oauthConfig: {
42
+ googleClientId: 'YOUR_GOOGLE_CLIENT_ID',
43
+ redirectUri: 'http://localhost:3000',
44
+ },
45
+ })
46
+ ],
47
+ transports: {
48
+ [sepolia.id]: http('YOUR_RPC_URL'),
49
+ },
50
+ })
51
+ ```
52
+
53
+ ### 2. Wrap Your App
54
+
55
+ ```typescript
56
+ import { WagmiProvider } from 'wagmi'
57
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
58
+
59
+ const queryClient = new QueryClient()
60
+
61
+ function App() {
62
+ return (
63
+ <WagmiProvider config={config}>
64
+ <QueryClientProvider client={queryClient}>
65
+ <YourApp />
66
+ </QueryClientProvider>
67
+ </WagmiProvider>
68
+ )
69
+ }
70
+ ```
71
+
72
+ ### 3. Authenticate Users
73
+
74
+ ```typescript
75
+ import { useRegisterPasskey, useAuthenticateOAuth, OAUTH_PROVIDERS } from '@zerodev/wallet-react'
76
+
77
+ function LoginPage() {
78
+ const registerPasskey = useRegisterPasskey()
79
+ const authenticateOAuth = useAuthenticateOAuth()
80
+
81
+ return (
82
+ <>
83
+ <button
84
+ onClick={() => registerPasskey.mutate({ email: 'user@example.com' })}
85
+ disabled={registerPasskey.isPending}
86
+ >
87
+ {registerPasskey.isPending ? 'Registering...' : 'Register with Passkey'}
88
+ </button>
89
+
90
+ <button
91
+ onClick={() => authenticateOAuth.mutate({ provider: OAUTH_PROVIDERS.GOOGLE })}
92
+ disabled={authenticateOAuth.isPending}
93
+ >
94
+ {authenticateOAuth.isPending ? 'Authenticating...' : 'Login with Google'}
95
+ </button>
96
+ </>
97
+ )
98
+ }
99
+ ```
100
+
101
+ ### 4. Use Standard Wagmi Hooks
102
+
103
+ ```typescript
104
+ import { useConnection, useSendTransaction, useDisconnect } from 'wagmi'
105
+ import { parseEther } from 'viem'
106
+
107
+ function Dashboard() {
108
+ const { address } = useConnection()
109
+ const { sendTransaction } = useSendTransaction()
110
+ const { disconnect } = useDisconnect()
111
+
112
+ return (
113
+ <>
114
+ <p>Address: {address}</p>
115
+
116
+ <button onClick={() =>
117
+ sendTransaction({
118
+ to: '0x...',
119
+ value: parseEther('0.01')
120
+ })
121
+ }>
122
+ Send Gasless Transaction
123
+ </button>
124
+
125
+ <button onClick={() => disconnect()}>
126
+ Logout
127
+ </button>
128
+ </>
129
+ )
130
+ }
131
+ ```
132
+
133
+ ## Authentication Methods
134
+
135
+ ### Passkey (WebAuthn)
136
+
137
+ ```typescript
138
+ const registerPasskey = useRegisterPasskey()
139
+ const loginPasskey = useLoginPasskey()
140
+
141
+ // Register new passkey
142
+ await registerPasskey.mutateAsync({ email: 'user@example.com' })
143
+
144
+ // Login with existing passkey
145
+ await loginPasskey.mutateAsync({ email: 'user@example.com' })
146
+ ```
147
+
148
+ ### OAuth (Google)
149
+
150
+ ```typescript
151
+ const authenticateOAuth = useAuthenticateOAuth()
152
+
153
+ // Opens popup automatically, handles token exchange
154
+ await authenticateOAuth.mutateAsync({
155
+ provider: OAUTH_PROVIDERS.GOOGLE
156
+ })
157
+ ```
158
+
159
+ ### Email OTP
160
+
161
+ ```typescript
162
+ const sendOTP = useSendOTP()
163
+ const verifyOTP = useVerifyOTP()
164
+
165
+ // Send OTP code
166
+ const { otpId, subOrganizationId } = await sendOTP.mutateAsync({
167
+ email: 'user@example.com'
168
+ })
169
+
170
+ // Verify OTP code
171
+ await verifyOTP.mutateAsync({
172
+ code: '123456',
173
+ otpId,
174
+ subOrganizationId
175
+ })
176
+ ```
177
+
178
+ ## Configuration Options
179
+
180
+ ```typescript
181
+ type ZeroDevWalletConnectorParams = {
182
+ projectId: string // Required: Your ZeroDev project ID
183
+ organizationId?: string // Optional: Turnkey organization ID
184
+ proxyBaseUrl?: string // Optional: KMS proxy URL
185
+ aaUrl: string // Required: Bundler/paymaster URL
186
+ chains: readonly Chain[] // Required: Supported chains
187
+ rpId?: string // Optional: WebAuthn RP ID
188
+ sessionStorage?: StorageAdapter // Optional: Custom session storage
189
+ autoRefreshSession?: boolean // Optional: Auto-refresh (default: true)
190
+ sessionWarningThreshold?: number // Optional: Refresh threshold in ms (default: 60000)
191
+ oauthConfig?: OAuthConfig // Optional: OAuth configuration
192
+ }
193
+
194
+ type OAuthConfig = {
195
+ googleClientId?: string
196
+ redirectUri: string
197
+ }
198
+ ```
199
+
200
+ ## Advanced Usage
201
+
202
+ ### Custom Callbacks
203
+
204
+ ```typescript
205
+ const registerPasskey = useRegisterPasskey({
206
+ mutation: {
207
+ onSuccess: () => {
208
+ console.log('Registration successful!')
209
+ router.push('/dashboard')
210
+ },
211
+ onError: (error) => {
212
+ console.error('Registration failed:', error)
213
+ analytics.track('auth_failed', { method: 'passkey' })
214
+ }
215
+ }
216
+ })
217
+ ```
218
+
219
+ ### Manual Session Refresh
220
+
221
+ ```typescript
222
+ const refreshSession = useRefreshSession()
223
+
224
+ await refreshSession.mutateAsync({})
225
+ ```
226
+
227
+ ### Export Wallet
228
+
229
+ ```typescript
230
+ const exportWallet = useExportWallet()
231
+
232
+ await exportWallet.mutateAsync({
233
+ iframeContainerId: 'export-container'
234
+ })
235
+ ```
236
+
237
+ ## API Reference
238
+
239
+ ### Hooks
240
+
241
+ All hooks follow the TanStack Query mutation pattern:
242
+
243
+ - `useRegisterPasskey()` - Register with passkey
244
+ - `useLoginPasskey()` - Login with passkey
245
+ - `useAuthenticateOAuth()` - OAuth (Google popup)
246
+ - `useSendOTP()` - Send OTP via email
247
+ - `useVerifyOTP()` - Verify OTP code
248
+ - `useRefreshSession()` - Manually refresh session
249
+ - `useExportWallet()` - Export wallet seed phrase
250
+
251
+ ### Connector
252
+
253
+ - `zeroDevWallet(params)` - Wagmi connector factory
254
+
255
+ ### Constants
256
+
257
+ - `OAUTH_PROVIDERS.GOOGLE` - Google OAuth provider constant
258
+
259
+ ### Types
260
+
261
+ - `OAuthProvider` - OAuth provider type
262
+ - `OAuthConfig` - OAuth configuration type
263
+ - `ZeroDevWalletConnectorParams` - Connector parameters
264
+ - `ZeroDevWalletState` - Store state type
265
+ - `ZeroDevProvider` - EIP-1193 provider type
266
+
267
+ ## License
268
+
269
+ MIT
@@ -105,12 +105,12 @@ function zeroDevWallet(params) {
105
105
  store.getState().setKernelAccount(activeChainId, kernelAccount);
106
106
  const kernelClient = (0, sdk_1.createKernelAccountClient)({
107
107
  account: kernelAccount,
108
- bundlerTransport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(activeChainId, params.aaUrl)),
108
+ bundlerTransport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(params.projectId, activeChainId, params.aaUrl)),
109
109
  chain,
110
110
  client: publicClient,
111
111
  paymaster: (0, sdk_1.createZeroDevPaymasterClient)({
112
112
  chain,
113
- transport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(activeChainId, params.aaUrl)),
113
+ transport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(params.projectId, activeChainId, params.aaUrl)),
114
114
  }),
115
115
  });
116
116
  store.getState().setKernelClient(activeChainId, kernelClient);
@@ -184,12 +184,12 @@ function zeroDevWallet(params) {
184
184
  store.getState().setKernelAccount(chainId, kernelAccount);
185
185
  const kernelClient = (0, sdk_1.createKernelAccountClient)({
186
186
  account: kernelAccount,
187
- bundlerTransport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(chainId, params.aaUrl)),
187
+ bundlerTransport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(params.projectId, chainId, params.aaUrl)),
188
188
  chain,
189
189
  client: publicClient,
190
190
  paymaster: (0, sdk_1.createZeroDevPaymasterClient)({
191
191
  chain,
192
- transport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(chainId, params.aaUrl)),
192
+ transport: (0, viem_1.http)((0, aaUtils_js_1.getAAUrl)(params.projectId, chainId, params.aaUrl)),
193
193
  }),
194
194
  });
195
195
  store.getState().setKernelClient(chainId, kernelClient);
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZERODEV_AA_URL = void 0;
4
- exports.ZERODEV_AA_URL = 'https://rpc.zerodev.app/api/v3/';
4
+ exports.ZERODEV_AA_URL = 'https://staging-meta-aa-provider.onrender.com/api/v3/';
@@ -2,6 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAAUrl = getAAUrl;
4
4
  const constants_js_1 = require("../constants.js");
5
- function getAAUrl(chainId, aaUrl) {
6
- return aaUrl || `${constants_js_1.ZERODEV_AA_URL}${chainId}/chain/${chainId}`;
5
+ function getAAUrl(projectId, chainId, aaUrl) {
6
+ return aaUrl || `${constants_js_1.ZERODEV_AA_URL}${projectId}/chain/${chainId}`;
7
7
  }
@@ -118,12 +118,12 @@ export function zeroDevWallet(params) {
118
118
  // Create and store kernel client for transactions
119
119
  const kernelClient = createKernelAccountClient({
120
120
  account: kernelAccount,
121
- bundlerTransport: http(getAAUrl(activeChainId, params.aaUrl)),
121
+ bundlerTransport: http(getAAUrl(params.projectId, activeChainId, params.aaUrl)),
122
122
  chain,
123
123
  client: publicClient,
124
124
  paymaster: createZeroDevPaymasterClient({
125
125
  chain,
126
- transport: http(getAAUrl(activeChainId, params.aaUrl)),
126
+ transport: http(getAAUrl(params.projectId, activeChainId, params.aaUrl)),
127
127
  }),
128
128
  });
129
129
  store.getState().setKernelClient(activeChainId, kernelClient);
@@ -205,12 +205,12 @@ export function zeroDevWallet(params) {
205
205
  store.getState().setKernelAccount(chainId, kernelAccount);
206
206
  const kernelClient = createKernelAccountClient({
207
207
  account: kernelAccount,
208
- bundlerTransport: http(getAAUrl(chainId, params.aaUrl)),
208
+ bundlerTransport: http(getAAUrl(params.projectId, chainId, params.aaUrl)),
209
209
  chain,
210
210
  client: publicClient,
211
211
  paymaster: createZeroDevPaymasterClient({
212
212
  chain,
213
- transport: http(getAAUrl(chainId, params.aaUrl)),
213
+ transport: http(getAAUrl(params.projectId, chainId, params.aaUrl)),
214
214
  }),
215
215
  });
216
216
  store.getState().setKernelClient(chainId, kernelClient);
@@ -1 +1 @@
1
- export const ZERODEV_AA_URL = 'https://rpc.zerodev.app/api/v3/';
1
+ export const ZERODEV_AA_URL = 'https://staging-meta-aa-provider.onrender.com/api/v3/';
@@ -1,4 +1,4 @@
1
1
  import { ZERODEV_AA_URL } from '../constants.js';
2
- export function getAAUrl(chainId, aaUrl) {
3
- return aaUrl || `${ZERODEV_AA_URL}${chainId}/chain/${chainId}`;
2
+ export function getAAUrl(projectId, chainId, aaUrl) {
3
+ return aaUrl || `${ZERODEV_AA_URL}${projectId}/chain/${chainId}`;
4
4
  }
@@ -6,7 +6,7 @@ export type ZeroDevWalletConnectorParams = {
6
6
  projectId: string;
7
7
  organizationId?: string;
8
8
  proxyBaseUrl?: string;
9
- aaUrl: string;
9
+ aaUrl?: string;
10
10
  chains: readonly Chain[];
11
11
  rpId?: string;
12
12
  sessionStorage?: StorageAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,aAAa,CAAA;AAOrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,OAAO,EAAE,KAAK,KAAK,EAA4B,MAAM,MAAM,CAAA;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAK7C,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,4BAA4B,GACnC,iBAAiB,CAiTnB"}
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,aAAa,CAAA;AAOrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,OAAO,EAAE,KAAK,KAAK,EAA4B,MAAM,MAAM,CAAA;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAK7C,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,4BAA4B,GACnC,iBAAiB,CAyTnB"}
@@ -1,2 +1,2 @@
1
- export declare const ZERODEV_AA_URL = "https://rpc.zerodev.app/api/v3/";
1
+ export declare const ZERODEV_AA_URL = "https://staging-meta-aa-provider.onrender.com/api/v3/";
2
2
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,oCAAoC,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,0DAC8B,CAAA"}
@@ -1,2 +1,2 @@
1
- export declare function getAAUrl(chainId: number, aaUrl?: string): string;
1
+ export declare function getAAUrl(projectId: string, chainId: number, aaUrl?: string): string;
2
2
  //# sourceMappingURL=aaUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aaUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/aaUtils.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,UAEvD"}
1
+ {"version":3,"file":"aaUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/aaUtils.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,UAE1E"}