@zerodev/wallet-react 0.0.1-alpha.5 → 0.0.1-alpha.7
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 +21 -0
- package/README.md +17 -14
- package/dist/_cjs/actions.js +53 -24
- package/dist/_cjs/connector.js +44 -3
- package/dist/_cjs/hooks/useExportPrivateKey.js +18 -0
- package/dist/_cjs/hooks/useGetUserEmail.js +19 -0
- package/dist/_cjs/index.js +8 -1
- package/dist/_cjs/oauth.js +60 -55
- package/dist/_esm/actions.js +65 -27
- package/dist/_esm/connector.js +56 -5
- package/dist/_esm/hooks/useExportPrivateKey.js +18 -0
- package/dist/_esm/hooks/useGetUserEmail.js +19 -0
- package/dist/_esm/index.js +3 -1
- package/dist/_esm/oauth.js +71 -53
- package/dist/_types/actions.d.ts +41 -6
- package/dist/_types/actions.d.ts.map +1 -1
- package/dist/_types/connector.d.ts +0 -2
- 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/hooks/useGetUserEmail.d.ts +20 -0
- package/dist/_types/hooks/useGetUserEmail.d.ts.map +1 -0
- package/dist/_types/index.d.ts +4 -2
- package/dist/_types/index.d.ts.map +1 -1
- package/dist/_types/oauth.d.ts +25 -12
- package/dist/_types/oauth.d.ts.map +1 -1
- package/dist/_types/store.d.ts +7 -3
- 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 +122 -44
- package/src/connector.ts +68 -7
- package/src/hooks/useExportPrivateKey.ts +57 -0
- package/src/hooks/useGetUserEmail.ts +54 -0
- package/src/index.ts +9 -2
- package/src/oauth.ts +97 -78
- package/src/store.ts +9 -4
- package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @zerodev/wallet-react
|
|
2
2
|
|
|
3
|
+
## 0.0.1-alpha.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add OTP authentication via Turnkey Auth Proxy
|
|
8
|
+
- Add OAuth backend PKCE flow
|
|
9
|
+
- Add getUserEmail method and React hook
|
|
10
|
+
- Fix passkey login endpoint
|
|
11
|
+
- Fix signature verification with JSON canonicalization
|
|
12
|
+
- Rename turnkeySession to session in OAuth response
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @zerodev/wallet-core@0.0.1-alpha.7
|
|
15
|
+
|
|
16
|
+
## 0.0.1-alpha.6
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- feat: Added private key export feature
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @zerodev/wallet-core@0.0.1-alpha.6
|
|
23
|
+
|
|
3
24
|
## 0.0.1-alpha.5
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -38,10 +38,6 @@ const config = createConfig({
|
|
|
38
38
|
projectId: 'YOUR_PROJECT_ID',
|
|
39
39
|
aaUrl: 'YOUR_AA_PROVIDER_URL',
|
|
40
40
|
chains: [sepolia],
|
|
41
|
-
oauthConfig: {
|
|
42
|
-
googleClientId: 'YOUR_GOOGLE_CLIENT_ID',
|
|
43
|
-
redirectUri: 'http://localhost:3000',
|
|
44
|
-
},
|
|
45
41
|
})
|
|
46
42
|
],
|
|
47
43
|
transports: {
|
|
@@ -150,7 +146,8 @@ await loginPasskey.mutateAsync({ email: 'user@example.com' })
|
|
|
150
146
|
```typescript
|
|
151
147
|
const authenticateOAuth = useAuthenticateOAuth()
|
|
152
148
|
|
|
153
|
-
// Opens popup
|
|
149
|
+
// Opens popup, backend handles PKCE and token exchange
|
|
150
|
+
// No callback page or OAuth library needed - SDK handles everything
|
|
154
151
|
await authenticateOAuth.mutateAsync({
|
|
155
152
|
provider: OAUTH_PROVIDERS.GOOGLE
|
|
156
153
|
})
|
|
@@ -182,18 +179,12 @@ type ZeroDevWalletConnectorParams = {
|
|
|
182
179
|
projectId: string // Required: Your ZeroDev project ID
|
|
183
180
|
organizationId?: string // Optional: Turnkey organization ID
|
|
184
181
|
proxyBaseUrl?: string // Optional: KMS proxy URL
|
|
185
|
-
aaUrl
|
|
182
|
+
aaUrl?: string // Optional: Bundler/paymaster URL
|
|
186
183
|
chains: readonly Chain[] // Required: Supported chains
|
|
187
184
|
rpId?: string // Optional: WebAuthn RP ID
|
|
188
185
|
sessionStorage?: StorageAdapter // Optional: Custom session storage
|
|
189
186
|
autoRefreshSession?: boolean // Optional: Auto-refresh (default: true)
|
|
190
187
|
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
188
|
}
|
|
198
189
|
```
|
|
199
190
|
|
|
@@ -224,16 +215,28 @@ const refreshSession = useRefreshSession()
|
|
|
224
215
|
await refreshSession.mutateAsync({})
|
|
225
216
|
```
|
|
226
217
|
|
|
227
|
-
### Export Wallet
|
|
218
|
+
### Export Wallet (Seed Phrase)
|
|
228
219
|
|
|
229
220
|
```typescript
|
|
230
221
|
const exportWallet = useExportWallet()
|
|
231
222
|
|
|
223
|
+
// Container element must exist: <div id="export-container" />
|
|
232
224
|
await exportWallet.mutateAsync({
|
|
233
225
|
iframeContainerId: 'export-container'
|
|
234
226
|
})
|
|
235
227
|
```
|
|
236
228
|
|
|
229
|
+
### Export Private Key
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const exportPrivateKey = useExportPrivateKey()
|
|
233
|
+
|
|
234
|
+
// Container element must exist: <div id="export-container" />
|
|
235
|
+
await exportPrivateKey.mutateAsync({
|
|
236
|
+
iframeContainerId: 'export-container'
|
|
237
|
+
})
|
|
238
|
+
```
|
|
239
|
+
|
|
237
240
|
## API Reference
|
|
238
241
|
|
|
239
242
|
### Hooks
|
|
@@ -247,6 +250,7 @@ All hooks follow the TanStack Query mutation pattern:
|
|
|
247
250
|
- `useVerifyOTP()` - Verify OTP code
|
|
248
251
|
- `useRefreshSession()` - Manually refresh session
|
|
249
252
|
- `useExportWallet()` - Export wallet seed phrase
|
|
253
|
+
- `useExportPrivateKey()` - Export wallet private key
|
|
250
254
|
|
|
251
255
|
### Connector
|
|
252
256
|
|
|
@@ -259,7 +263,6 @@ All hooks follow the TanStack Query mutation pattern:
|
|
|
259
263
|
### Types
|
|
260
264
|
|
|
261
265
|
- `OAuthProvider` - OAuth provider type
|
|
262
|
-
- `OAuthConfig` - OAuth configuration type
|
|
263
266
|
- `ZeroDevWalletConnectorParams` - Connector parameters
|
|
264
267
|
- `ZeroDevWalletState` - Store state type
|
|
265
268
|
- `ZeroDevProvider` - EIP-1193 provider type
|
package/dist/_cjs/actions.js
CHANGED
|
@@ -6,8 +6,11 @@ exports.authenticateOAuth = authenticateOAuth;
|
|
|
6
6
|
exports.sendOTP = sendOTP;
|
|
7
7
|
exports.verifyOTP = verifyOTP;
|
|
8
8
|
exports.refreshSession = refreshSession;
|
|
9
|
+
exports.getUserEmail = getUserEmail;
|
|
9
10
|
exports.exportWallet = exportWallet;
|
|
11
|
+
exports.exportPrivateKey = exportPrivateKey;
|
|
10
12
|
const actions_1 = require("@wagmi/core/actions");
|
|
13
|
+
const wallet_core_1 = require("@zerodev/wallet-core");
|
|
11
14
|
const oauth_js_1 = require("./oauth.js");
|
|
12
15
|
function getZeroDevConnector(config) {
|
|
13
16
|
const connector = config.connectors.find((c) => c.id === 'zerodev-wallet');
|
|
@@ -62,40 +65,29 @@ async function authenticateOAuth(config, parameters) {
|
|
|
62
65
|
if (!wallet)
|
|
63
66
|
throw new Error('Wallet not initialized');
|
|
64
67
|
if (!oauthConfig) {
|
|
65
|
-
throw new Error('
|
|
66
|
-
}
|
|
67
|
-
let clientId = parameters.clientId;
|
|
68
|
-
if (!clientId) {
|
|
69
|
-
clientId = oauthConfig.googleClientId;
|
|
70
|
-
}
|
|
71
|
-
if (!clientId) {
|
|
72
|
-
throw new Error(`Client ID not configured for ${parameters.provider}`);
|
|
73
|
-
}
|
|
74
|
-
if (!oauthConfig.redirectUri) {
|
|
75
|
-
throw new Error('OAuth redirect URI is not configured.');
|
|
68
|
+
throw new Error('Wallet not initialized. Please wait for connector setup.');
|
|
76
69
|
}
|
|
77
70
|
const publicKey = await wallet.getPublicKey();
|
|
78
71
|
if (!publicKey) {
|
|
79
72
|
throw new Error('Failed to get wallet public key');
|
|
80
73
|
}
|
|
81
|
-
const
|
|
82
|
-
const oauthUrl = (0, oauth_js_1.buildOAuthUrl)({
|
|
74
|
+
const oauthUrl = (0, oauth_js_1.buildBackendOAuthUrl)({
|
|
83
75
|
provider: parameters.provider,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
backendUrl: oauthConfig.backendUrl,
|
|
77
|
+
projectId: oauthConfig.projectId,
|
|
78
|
+
publicKey,
|
|
79
|
+
returnTo: `${window.location.origin}?oauth_success=true&oauth_provider=${parameters.provider}`,
|
|
87
80
|
});
|
|
88
81
|
const authWindow = (0, oauth_js_1.openOAuthPopup)(oauthUrl);
|
|
89
82
|
if (!authWindow) {
|
|
90
83
|
throw new Error(`Failed to open ${parameters.provider} login window.`);
|
|
91
84
|
}
|
|
92
85
|
return new Promise((resolve, reject) => {
|
|
93
|
-
(0, oauth_js_1.
|
|
86
|
+
const cleanup = (0, oauth_js_1.listenForOAuthMessage)(authWindow, window.location.origin, async () => {
|
|
94
87
|
try {
|
|
95
88
|
await wallet.auth({
|
|
96
89
|
type: 'oauth',
|
|
97
90
|
provider: parameters.provider,
|
|
98
|
-
credential: idToken,
|
|
99
91
|
});
|
|
100
92
|
const [session, eoaAccount] = await Promise.all([
|
|
101
93
|
wallet.getSession(),
|
|
@@ -109,7 +101,10 @@ async function authenticateOAuth(config, parameters) {
|
|
|
109
101
|
catch (err) {
|
|
110
102
|
reject(err);
|
|
111
103
|
}
|
|
112
|
-
},
|
|
104
|
+
}, (error) => {
|
|
105
|
+
cleanup();
|
|
106
|
+
reject(error);
|
|
107
|
+
});
|
|
113
108
|
});
|
|
114
109
|
}
|
|
115
110
|
async function sendOTP(config, parameters) {
|
|
@@ -129,7 +124,6 @@ async function sendOTP(config, parameters) {
|
|
|
129
124
|
});
|
|
130
125
|
return {
|
|
131
126
|
otpId: result.otpId,
|
|
132
|
-
subOrganizationId: result.subOrganizationId,
|
|
133
127
|
};
|
|
134
128
|
}
|
|
135
129
|
async function verifyOTP(config, parameters) {
|
|
@@ -143,7 +137,6 @@ async function verifyOTP(config, parameters) {
|
|
|
143
137
|
mode: 'verifyOtp',
|
|
144
138
|
otpId: parameters.otpId,
|
|
145
139
|
otpCode: parameters.code,
|
|
146
|
-
subOrganizationId: parameters.subOrganizationId,
|
|
147
140
|
});
|
|
148
141
|
const [session, eoaAccount] = await Promise.all([
|
|
149
142
|
wallet.getSession(),
|
|
@@ -165,24 +158,34 @@ async function refreshSession(config, parameters = {}) {
|
|
|
165
158
|
store.getState().setSession(newSession || null);
|
|
166
159
|
return newSession;
|
|
167
160
|
}
|
|
161
|
+
async function getUserEmail(config, parameters) {
|
|
162
|
+
const connector = parameters.connector ?? getZeroDevConnector(config);
|
|
163
|
+
const store = await connector.getStore();
|
|
164
|
+
const wallet = store.getState().wallet;
|
|
165
|
+
if (!wallet)
|
|
166
|
+
throw new Error('Wallet not initialized');
|
|
167
|
+
return await wallet.client.getUserEmail({
|
|
168
|
+
organizationId: parameters.organizationId,
|
|
169
|
+
projectId: parameters.projectId,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
168
172
|
async function exportWallet(config, parameters) {
|
|
169
173
|
const connector = parameters.connector ?? getZeroDevConnector(config);
|
|
170
174
|
const store = await connector.getStore();
|
|
171
175
|
const wallet = store.getState().wallet;
|
|
172
176
|
if (!wallet)
|
|
173
177
|
throw new Error('Wallet not initialized');
|
|
174
|
-
const { exportWallet: exportWalletSdk, createIframeStamper } = await Promise.resolve().then(() => require('@zerodev/wallet-core'));
|
|
175
178
|
const iframeContainer = document.getElementById(parameters.iframeContainerId);
|
|
176
179
|
if (!iframeContainer) {
|
|
177
180
|
throw new Error('Iframe container not found');
|
|
178
181
|
}
|
|
179
|
-
const iframeStamper = await createIframeStamper({
|
|
182
|
+
const iframeStamper = await (0, wallet_core_1.createIframeStamper)({
|
|
180
183
|
iframeUrl: 'https://export.turnkey.com',
|
|
181
184
|
iframeContainer,
|
|
182
185
|
iframeElementId: 'export-wallet-iframe',
|
|
183
186
|
});
|
|
184
187
|
const publicKey = await iframeStamper.init();
|
|
185
|
-
const { exportBundle, organizationId } = await
|
|
188
|
+
const { exportBundle, organizationId } = await (0, wallet_core_1.exportWallet)({
|
|
186
189
|
wallet,
|
|
187
190
|
targetPublicKey: publicKey,
|
|
188
191
|
});
|
|
@@ -191,3 +194,29 @@ async function exportWallet(config, parameters) {
|
|
|
191
194
|
throw new Error('Failed to inject export bundle');
|
|
192
195
|
}
|
|
193
196
|
}
|
|
197
|
+
async function exportPrivateKey(config, parameters) {
|
|
198
|
+
const connector = parameters.connector ?? getZeroDevConnector(config);
|
|
199
|
+
const store = await connector.getStore();
|
|
200
|
+
const wallet = store.getState().wallet;
|
|
201
|
+
if (!wallet)
|
|
202
|
+
throw new Error('Wallet not initialized');
|
|
203
|
+
const iframeContainer = document.getElementById(parameters.iframeContainerId);
|
|
204
|
+
if (!iframeContainer) {
|
|
205
|
+
throw new Error('Iframe container not found');
|
|
206
|
+
}
|
|
207
|
+
const iframeStamper = await (0, wallet_core_1.createIframeStamper)({
|
|
208
|
+
iframeUrl: 'https://export.turnkey.com',
|
|
209
|
+
iframeContainer,
|
|
210
|
+
iframeElementId: 'export-private-key-iframe',
|
|
211
|
+
});
|
|
212
|
+
const publicKey = await iframeStamper.init();
|
|
213
|
+
const { exportBundle, organizationId } = await (0, wallet_core_1.exportPrivateKey)({
|
|
214
|
+
wallet,
|
|
215
|
+
targetPublicKey: publicKey,
|
|
216
|
+
...(parameters.address && { address: parameters.address }),
|
|
217
|
+
});
|
|
218
|
+
const success = await iframeStamper.injectKeyExportBundle(exportBundle, organizationId, parameters.keyFormat ?? 'Hexadecimal');
|
|
219
|
+
if (success !== true) {
|
|
220
|
+
throw new Error('Failed to inject export bundle');
|
|
221
|
+
}
|
|
222
|
+
}
|
package/dist/_cjs/connector.js
CHANGED
|
@@ -6,9 +6,48 @@ const sdk_1 = require("@zerodev/sdk");
|
|
|
6
6
|
const constants_1 = require("@zerodev/sdk/constants");
|
|
7
7
|
const wallet_core_1 = require("@zerodev/wallet-core");
|
|
8
8
|
const viem_1 = require("viem");
|
|
9
|
+
const oauth_js_1 = require("./oauth.js");
|
|
9
10
|
const provider_js_1 = require("./provider.js");
|
|
10
11
|
const store_js_1 = require("./store.js");
|
|
11
12
|
const aaUtils_js_1 = require("./utils/aaUtils.js");
|
|
13
|
+
const OAUTH_SUCCESS_PARAM = 'oauth_success';
|
|
14
|
+
const OAUTH_PROVIDER_PARAM = 'oauth_provider';
|
|
15
|
+
async function detectAndHandleOAuthCallback(wallet, store) {
|
|
16
|
+
if (typeof window === 'undefined')
|
|
17
|
+
return false;
|
|
18
|
+
const params = new URLSearchParams(window.location.search);
|
|
19
|
+
const isOAuthCallback = params.get(OAUTH_SUCCESS_PARAM) === 'true';
|
|
20
|
+
if (!isOAuthCallback)
|
|
21
|
+
return false;
|
|
22
|
+
if (window.opener) {
|
|
23
|
+
(0, oauth_js_1.handleOAuthCallback)(OAUTH_SUCCESS_PARAM);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
console.log('OAuth callback detected, completing authentication...');
|
|
27
|
+
const provider = (params.get(OAUTH_PROVIDER_PARAM) ||
|
|
28
|
+
'google');
|
|
29
|
+
try {
|
|
30
|
+
await wallet.auth({ type: 'oauth', provider });
|
|
31
|
+
const [session, eoaAccount] = await Promise.all([
|
|
32
|
+
wallet.getSession(),
|
|
33
|
+
wallet.toAccount(),
|
|
34
|
+
]);
|
|
35
|
+
store.getState().setEoaAccount(eoaAccount);
|
|
36
|
+
store.getState().setSession(session || null);
|
|
37
|
+
params.delete(OAUTH_SUCCESS_PARAM);
|
|
38
|
+
params.delete(OAUTH_PROVIDER_PARAM);
|
|
39
|
+
const newUrl = params.toString()
|
|
40
|
+
? `${window.location.pathname}?${params.toString()}`
|
|
41
|
+
: window.location.pathname;
|
|
42
|
+
window.history.replaceState({}, '', newUrl);
|
|
43
|
+
console.log('OAuth authentication completed');
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error('OAuth authentication failed:', error);
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
12
51
|
function zeroDevWallet(params) {
|
|
13
52
|
return (0, core_1.createConnector)((wagmiConfig) => {
|
|
14
53
|
let store;
|
|
@@ -29,9 +68,10 @@ function zeroDevWallet(params) {
|
|
|
29
68
|
});
|
|
30
69
|
store = (0, store_js_1.createZeroDevWalletStore)();
|
|
31
70
|
store.getState().setWallet(wallet);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
71
|
+
store.getState().setOAuthConfig({
|
|
72
|
+
backendUrl: params.proxyBaseUrl || `${wallet_core_1.KMS_SERVER_URL}/api/v1`,
|
|
73
|
+
projectId: params.projectId,
|
|
74
|
+
});
|
|
35
75
|
provider = (0, provider_js_1.createProvider)({
|
|
36
76
|
store,
|
|
37
77
|
config: params,
|
|
@@ -44,6 +84,7 @@ function zeroDevWallet(params) {
|
|
|
44
84
|
store.getState().setEoaAccount(eoaAccount);
|
|
45
85
|
store.getState().setSession(session);
|
|
46
86
|
}
|
|
87
|
+
await detectAndHandleOAuthCallback(wallet, store);
|
|
47
88
|
console.log('ZeroDevWallet connector initialized');
|
|
48
89
|
};
|
|
49
90
|
return {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useExportPrivateKey = useExportPrivateKey;
|
|
5
|
+
const react_query_1 = require("@tanstack/react-query");
|
|
6
|
+
const wagmi_1 = require("wagmi");
|
|
7
|
+
const actions_js_1 = require("../actions.js");
|
|
8
|
+
function useExportPrivateKey(parameters = {}) {
|
|
9
|
+
const { mutation } = parameters;
|
|
10
|
+
const config = (0, wagmi_1.useConfig)(parameters);
|
|
11
|
+
return (0, react_query_1.useMutation)({
|
|
12
|
+
...mutation,
|
|
13
|
+
async mutationFn(variables) {
|
|
14
|
+
return (0, actions_js_1.exportPrivateKey)(config, variables);
|
|
15
|
+
},
|
|
16
|
+
mutationKey: ['exportPrivateKey'],
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useGetUserEmail = useGetUserEmail;
|
|
5
|
+
const react_query_1 = require("@tanstack/react-query");
|
|
6
|
+
const wagmi_1 = require("wagmi");
|
|
7
|
+
const actions_js_1 = require("../actions.js");
|
|
8
|
+
function useGetUserEmail(parameters) {
|
|
9
|
+
const { organizationId, projectId, query } = parameters;
|
|
10
|
+
const config = (0, wagmi_1.useConfig)(parameters);
|
|
11
|
+
return (0, react_query_1.useQuery)({
|
|
12
|
+
...query,
|
|
13
|
+
queryKey: ['getUserEmail', { organizationId, projectId }],
|
|
14
|
+
queryFn: async () => {
|
|
15
|
+
return (0, actions_js_1.getUserEmail)(config, { organizationId, projectId });
|
|
16
|
+
},
|
|
17
|
+
enabled: Boolean(organizationId && projectId),
|
|
18
|
+
});
|
|
19
|
+
}
|
package/dist/_cjs/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createZeroDevWalletStore = exports.OAUTH_PROVIDERS = exports.useVerifyOTP = exports.useSendOTP = exports.useRegisterPasskey = exports.useRefreshSession = exports.useLoginPasskey = exports.useExportWallet = exports.useAuthenticateOAuth = exports.zeroDevWallet = void 0;
|
|
3
|
+
exports.createZeroDevWalletStore = exports.OAUTH_PROVIDERS = exports.listenForOAuthMessage = exports.handleOAuthCallback = exports.buildBackendOAuthUrl = exports.useVerifyOTP = exports.useSendOTP = exports.useRegisterPasskey = exports.useRefreshSession = exports.useLoginPasskey = exports.useGetUserEmail = exports.useExportWallet = exports.useExportPrivateKey = exports.useAuthenticateOAuth = exports.zeroDevWallet = void 0;
|
|
4
4
|
var connector_js_1 = require("./connector.js");
|
|
5
5
|
Object.defineProperty(exports, "zeroDevWallet", { enumerable: true, get: function () { return connector_js_1.zeroDevWallet; } });
|
|
6
6
|
var useAuthenticateOAuth_js_1 = require("./hooks/useAuthenticateOAuth.js");
|
|
7
7
|
Object.defineProperty(exports, "useAuthenticateOAuth", { enumerable: true, get: function () { return useAuthenticateOAuth_js_1.useAuthenticateOAuth; } });
|
|
8
|
+
var useExportPrivateKey_js_1 = require("./hooks/useExportPrivateKey.js");
|
|
9
|
+
Object.defineProperty(exports, "useExportPrivateKey", { enumerable: true, get: function () { return useExportPrivateKey_js_1.useExportPrivateKey; } });
|
|
8
10
|
var useExportWallet_js_1 = require("./hooks/useExportWallet.js");
|
|
9
11
|
Object.defineProperty(exports, "useExportWallet", { enumerable: true, get: function () { return useExportWallet_js_1.useExportWallet; } });
|
|
12
|
+
var useGetUserEmail_js_1 = require("./hooks/useGetUserEmail.js");
|
|
13
|
+
Object.defineProperty(exports, "useGetUserEmail", { enumerable: true, get: function () { return useGetUserEmail_js_1.useGetUserEmail; } });
|
|
10
14
|
var useLoginPasskey_js_1 = require("./hooks/useLoginPasskey.js");
|
|
11
15
|
Object.defineProperty(exports, "useLoginPasskey", { enumerable: true, get: function () { return useLoginPasskey_js_1.useLoginPasskey; } });
|
|
12
16
|
var useRefreshSession_js_1 = require("./hooks/useRefreshSession.js");
|
|
@@ -18,6 +22,9 @@ Object.defineProperty(exports, "useSendOTP", { enumerable: true, get: function (
|
|
|
18
22
|
var useVerifyOTP_js_1 = require("./hooks/useVerifyOTP.js");
|
|
19
23
|
Object.defineProperty(exports, "useVerifyOTP", { enumerable: true, get: function () { return useVerifyOTP_js_1.useVerifyOTP; } });
|
|
20
24
|
var oauth_js_1 = require("./oauth.js");
|
|
25
|
+
Object.defineProperty(exports, "buildBackendOAuthUrl", { enumerable: true, get: function () { return oauth_js_1.buildBackendOAuthUrl; } });
|
|
26
|
+
Object.defineProperty(exports, "handleOAuthCallback", { enumerable: true, get: function () { return oauth_js_1.handleOAuthCallback; } });
|
|
27
|
+
Object.defineProperty(exports, "listenForOAuthMessage", { enumerable: true, get: function () { return oauth_js_1.listenForOAuthMessage; } });
|
|
21
28
|
Object.defineProperty(exports, "OAUTH_PROVIDERS", { enumerable: true, get: function () { return oauth_js_1.OAUTH_PROVIDERS; } });
|
|
22
29
|
var store_js_1 = require("./store.js");
|
|
23
30
|
Object.defineProperty(exports, "createZeroDevWalletStore", { enumerable: true, get: function () { return store_js_1.createZeroDevWalletStore; } });
|
package/dist/_cjs/oauth.js
CHANGED
|
@@ -1,42 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OAUTH_PROVIDERS = void 0;
|
|
4
|
-
exports.buildOAuthUrl = buildOAuthUrl;
|
|
5
4
|
exports.openOAuthPopup = openOAuthPopup;
|
|
6
|
-
exports.extractOAuthToken = extractOAuthToken;
|
|
7
|
-
exports.pollOAuthPopup = pollOAuthPopup;
|
|
8
5
|
exports.generateOAuthNonce = generateOAuthNonce;
|
|
6
|
+
exports.buildBackendOAuthUrl = buildBackendOAuthUrl;
|
|
7
|
+
exports.listenForOAuthMessage = listenForOAuthMessage;
|
|
8
|
+
exports.handleOAuthCallback = handleOAuthCallback;
|
|
9
9
|
const viem_1 = require("viem");
|
|
10
10
|
exports.OAUTH_PROVIDERS = {
|
|
11
11
|
GOOGLE: 'google',
|
|
12
12
|
};
|
|
13
|
-
const GOOGLE_AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
|
|
14
13
|
const POPUP_WIDTH = 500;
|
|
15
14
|
const POPUP_HEIGHT = 600;
|
|
16
|
-
function buildOAuthUrl(params) {
|
|
17
|
-
const { provider, clientId, redirectUri, nonce, state } = params;
|
|
18
|
-
if (provider !== exports.OAUTH_PROVIDERS.GOOGLE) {
|
|
19
|
-
throw new Error(`Unsupported OAuth provider: ${provider}`);
|
|
20
|
-
}
|
|
21
|
-
const authUrl = new URL(GOOGLE_AUTH_URL);
|
|
22
|
-
authUrl.searchParams.set('client_id', clientId);
|
|
23
|
-
authUrl.searchParams.set('redirect_uri', redirectUri);
|
|
24
|
-
authUrl.searchParams.set('response_type', 'id_token');
|
|
25
|
-
authUrl.searchParams.set('scope', 'openid email profile');
|
|
26
|
-
authUrl.searchParams.set('nonce', nonce);
|
|
27
|
-
authUrl.searchParams.set('prompt', 'select_account');
|
|
28
|
-
let stateParam = `provider=${provider}`;
|
|
29
|
-
if (state) {
|
|
30
|
-
const additionalState = Object.entries(state)
|
|
31
|
-
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
|
32
|
-
.join('&');
|
|
33
|
-
if (additionalState) {
|
|
34
|
-
stateParam += `&${additionalState}`;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
authUrl.searchParams.set('state', stateParam);
|
|
38
|
-
return authUrl.toString();
|
|
39
|
-
}
|
|
40
15
|
function openOAuthPopup(url) {
|
|
41
16
|
const width = POPUP_WIDTH;
|
|
42
17
|
const height = POPUP_HEIGHT;
|
|
@@ -48,37 +23,67 @@ function openOAuthPopup(url) {
|
|
|
48
23
|
}
|
|
49
24
|
return authWindow;
|
|
50
25
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
26
|
+
function generateOAuthNonce(publicKey) {
|
|
27
|
+
return (0, viem_1.sha256)(publicKey).replace(/^0x/, '');
|
|
28
|
+
}
|
|
29
|
+
function buildBackendOAuthUrl(params) {
|
|
30
|
+
const { provider, backendUrl, projectId, publicKey, returnTo } = params;
|
|
31
|
+
if (provider !== exports.OAUTH_PROVIDERS.GOOGLE) {
|
|
32
|
+
throw new Error(`Unsupported OAuth provider: ${provider}`);
|
|
57
33
|
}
|
|
58
|
-
|
|
34
|
+
const oauthUrl = new URL(`${backendUrl}/oauth/google/login`);
|
|
35
|
+
oauthUrl.searchParams.set('project_id', projectId);
|
|
36
|
+
oauthUrl.searchParams.set('pub_key', publicKey.replace(/^0x/, ''));
|
|
37
|
+
oauthUrl.searchParams.set('return_to', returnTo);
|
|
38
|
+
return oauthUrl.toString();
|
|
59
39
|
}
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const token = extractOAuthToken(url);
|
|
71
|
-
if (token) {
|
|
72
|
-
authWindow.close();
|
|
73
|
-
clearInterval(interval);
|
|
74
|
-
onSuccess(token);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
40
|
+
function listenForOAuthMessage(authWindow, expectedOrigin, onSuccess, onError) {
|
|
41
|
+
let cleaned = false;
|
|
42
|
+
const handleMessage = (event) => {
|
|
43
|
+
if (event.origin !== expectedOrigin)
|
|
44
|
+
return;
|
|
45
|
+
if (!event.data || typeof event.data !== 'object')
|
|
46
|
+
return;
|
|
47
|
+
if (event.data.type === 'oauth_success') {
|
|
48
|
+
cleanup();
|
|
49
|
+
onSuccess();
|
|
77
50
|
}
|
|
78
|
-
|
|
51
|
+
else if (event.data.type === 'oauth_error') {
|
|
52
|
+
cleanup();
|
|
53
|
+
onError(new Error(event.data.error || 'OAuth authentication failed'));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const checkWindowClosed = setInterval(() => {
|
|
57
|
+
if (authWindow.closed) {
|
|
58
|
+
cleanup();
|
|
59
|
+
onError(new Error('Authentication window was closed'));
|
|
79
60
|
}
|
|
80
61
|
}, 500);
|
|
62
|
+
const cleanup = () => {
|
|
63
|
+
if (cleaned)
|
|
64
|
+
return;
|
|
65
|
+
cleaned = true;
|
|
66
|
+
window.removeEventListener('message', handleMessage);
|
|
67
|
+
clearInterval(checkWindowClosed);
|
|
68
|
+
};
|
|
69
|
+
window.addEventListener('message', handleMessage);
|
|
70
|
+
return cleanup;
|
|
81
71
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
72
|
+
function handleOAuthCallback(successParam = 'oauth_success') {
|
|
73
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
74
|
+
const isSuccess = urlParams.get(successParam) === 'true';
|
|
75
|
+
const error = urlParams.get('error');
|
|
76
|
+
if (window.opener) {
|
|
77
|
+
if (isSuccess) {
|
|
78
|
+
window.opener.postMessage({ type: 'oauth_success' }, window.location.origin);
|
|
79
|
+
window.close();
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (error) {
|
|
83
|
+
window.opener.postMessage({ type: 'oauth_error', error }, window.location.origin);
|
|
84
|
+
window.close();
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
84
89
|
}
|