@rhinestone/1auth 0.1.2 → 0.5.0
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/dist/{chunk-TACK3LJN.mjs → chunk-N4BLW5UR.mjs} +49 -25
- package/dist/chunk-N4BLW5UR.mjs.map +1 -0
- package/dist/{client-DyYGKWj3.d.mts → client-Di8SBnPO.d.mts} +242 -85
- package/dist/{client-DyYGKWj3.d.ts → client-Di8SBnPO.d.ts} +242 -85
- package/dist/index.d.mts +5 -9
- package/dist/index.d.ts +5 -9
- package/dist/index.js +559 -178
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +513 -155
- package/dist/index.mjs.map +1 -1
- package/dist/{provider-CNTZPPFz.d.ts → provider-8anOtc87.d.mts} +2 -8
- package/dist/{provider-Ctr7HQHR.d.mts → provider-CFnLQt5m.d.ts} +2 -8
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +16 -9
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +16 -9
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +2 -5
- package/dist/server.d.ts +2 -5
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +2 -2
- package/dist/server.mjs.map +1 -1
- package/dist/wagmi.d.mts +2 -2
- package/dist/wagmi.d.ts +2 -2
- package/dist/wagmi.js +48 -23
- package/dist/wagmi.js.map +1 -1
- package/dist/wagmi.mjs +3 -3
- package/dist/wagmi.mjs.map +1 -1
- package/package.json +7 -6
- package/dist/chunk-TACK3LJN.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildTransactionReview,
|
|
3
3
|
createOneAuthProvider,
|
|
4
|
-
createPasskeyProvider,
|
|
5
4
|
encodeWebAuthnSignature,
|
|
6
5
|
getAllSupportedChainsAndTokens,
|
|
7
6
|
getChainById,
|
|
@@ -19,7 +18,7 @@ import {
|
|
|
19
18
|
isTestnet,
|
|
20
19
|
isTokenAddressSupported,
|
|
21
20
|
resolveTokenAddress
|
|
22
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-N4BLW5UR.mjs";
|
|
23
22
|
|
|
24
23
|
// src/client.ts
|
|
25
24
|
import { parseUnits, hashTypedData } from "viem";
|
|
@@ -27,7 +26,7 @@ var POPUP_WIDTH = 450;
|
|
|
27
26
|
var POPUP_HEIGHT = 600;
|
|
28
27
|
var DEFAULT_EMBED_WIDTH = "400px";
|
|
29
28
|
var DEFAULT_EMBED_HEIGHT = "500px";
|
|
30
|
-
var MODAL_WIDTH =
|
|
29
|
+
var MODAL_WIDTH = 340;
|
|
31
30
|
var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
|
|
32
31
|
var OneAuthClient = class {
|
|
33
32
|
constructor(config) {
|
|
@@ -35,6 +34,12 @@ var OneAuthClient = class {
|
|
|
35
34
|
const dialogUrl = config.dialogUrl || providerUrl;
|
|
36
35
|
this.config = { ...config, providerUrl, dialogUrl };
|
|
37
36
|
this.theme = this.config.theme || {};
|
|
37
|
+
if (typeof document !== "undefined") {
|
|
38
|
+
this.injectPreconnect(providerUrl);
|
|
39
|
+
if (dialogUrl !== providerUrl) {
|
|
40
|
+
this.injectPreconnect(dialogUrl);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
44
|
/**
|
|
40
45
|
* Update the theme configuration at runtime
|
|
@@ -115,7 +120,28 @@ var OneAuthClient = class {
|
|
|
115
120
|
return void 0;
|
|
116
121
|
}
|
|
117
122
|
/**
|
|
118
|
-
* Open the
|
|
123
|
+
* Open the authentication modal (sign in + sign up).
|
|
124
|
+
*
|
|
125
|
+
* Handles both new user registration and returning user login in a single
|
|
126
|
+
* call — the modal shows the appropriate flow based on whether the user
|
|
127
|
+
* has a passkey registered.
|
|
128
|
+
*
|
|
129
|
+
* @param options.username - Pre-fill the username field
|
|
130
|
+
* @param options.theme - Override the theme for this modal invocation
|
|
131
|
+
* @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons
|
|
132
|
+
* @returns {@link AuthResult} with user details and typed address
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const result = await client.authWithModal();
|
|
137
|
+
*
|
|
138
|
+
* if (result.success) {
|
|
139
|
+
* console.log('Signed in as:', result.user?.username);
|
|
140
|
+
* console.log('Address:', result.user?.address); // typed `0x${string}`
|
|
141
|
+
* } else if (result.error?.code === 'USER_CANCELLED') {
|
|
142
|
+
* // User closed the modal
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
119
145
|
*/
|
|
120
146
|
async authWithModal(options) {
|
|
121
147
|
const dialogUrl = this.getDialogUrl();
|
|
@@ -155,7 +181,7 @@ var OneAuthClient = class {
|
|
|
155
181
|
* const result = await client.connectWithModal();
|
|
156
182
|
*
|
|
157
183
|
* if (result.success) {
|
|
158
|
-
* console.log('Connected as:', result.username);
|
|
184
|
+
* console.log('Connected as:', result.user?.username);
|
|
159
185
|
* } else if (result.action === 'switch') {
|
|
160
186
|
* // User needs to sign in first
|
|
161
187
|
* const authResult = await client.authWithModal();
|
|
@@ -189,6 +215,133 @@ var OneAuthClient = class {
|
|
|
189
215
|
}
|
|
190
216
|
return this.waitForConnectResponse(dialog, iframe, cleanup);
|
|
191
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Check if a user has already granted consent for the requested fields.
|
|
220
|
+
* This is a read-only check — no dialog is shown.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* const result = await client.checkConsent({
|
|
225
|
+
* username: "alice",
|
|
226
|
+
* fields: ["email"],
|
|
227
|
+
* });
|
|
228
|
+
* if (result.hasConsent) {
|
|
229
|
+
* console.log(result.data?.email);
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
async checkConsent(options) {
|
|
234
|
+
const clientId = options.clientId ?? this.config.clientId;
|
|
235
|
+
if (!clientId) {
|
|
236
|
+
return {
|
|
237
|
+
hasConsent: false
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
const username = options.username ?? options.accountAddress;
|
|
241
|
+
if (!username) {
|
|
242
|
+
return {
|
|
243
|
+
hasConsent: false
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
const res = await fetch(`${this.config.providerUrl || "https://passkey.1auth.box"}/api/consent`, {
|
|
248
|
+
method: "POST",
|
|
249
|
+
headers: {
|
|
250
|
+
"Content-Type": "application/json",
|
|
251
|
+
...clientId ? { "x-client-id": clientId } : {}
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify({
|
|
254
|
+
username,
|
|
255
|
+
requestedFields: options.fields,
|
|
256
|
+
clientId
|
|
257
|
+
})
|
|
258
|
+
});
|
|
259
|
+
if (!res.ok) {
|
|
260
|
+
return { hasConsent: false };
|
|
261
|
+
}
|
|
262
|
+
const data = await res.json();
|
|
263
|
+
return {
|
|
264
|
+
hasConsent: data.hasConsent ?? false,
|
|
265
|
+
data: data.data,
|
|
266
|
+
grantedAt: data.grantedAt
|
|
267
|
+
};
|
|
268
|
+
} catch {
|
|
269
|
+
return { hasConsent: false };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Request consent from the user to share their data.
|
|
274
|
+
*
|
|
275
|
+
* First checks if consent was already granted (returns cached data immediately).
|
|
276
|
+
* If not, opens the consent dialog where the user can review and approve sharing.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* const result = await client.requestConsent({
|
|
281
|
+
* username: "alice",
|
|
282
|
+
* fields: ["email", "deviceNames"],
|
|
283
|
+
* });
|
|
284
|
+
* if (result.success) {
|
|
285
|
+
* console.log(result.data?.email);
|
|
286
|
+
* console.log(result.cached); // true if no dialog was shown
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
async requestConsent(options) {
|
|
291
|
+
const clientId = options.clientId ?? this.config.clientId;
|
|
292
|
+
if (!clientId) {
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
error: { code: "INVALID_REQUEST", message: "clientId is required (set in config or options)" }
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
const username = options.username ?? options.accountAddress;
|
|
299
|
+
if (!username) {
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
error: { code: "INVALID_REQUEST", message: "username or accountAddress is required" }
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (!options.fields || options.fields.length === 0) {
|
|
306
|
+
return {
|
|
307
|
+
success: false,
|
|
308
|
+
error: { code: "INVALID_REQUEST", message: "At least one field is required" }
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const existing = await this.checkConsent({ ...options, clientId });
|
|
312
|
+
if (existing.hasConsent && existing.data) {
|
|
313
|
+
return {
|
|
314
|
+
success: true,
|
|
315
|
+
data: existing.data,
|
|
316
|
+
grantedAt: existing.grantedAt,
|
|
317
|
+
cached: true
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
const dialogUrl = this.getDialogUrl();
|
|
321
|
+
const params = new URLSearchParams({
|
|
322
|
+
mode: "iframe",
|
|
323
|
+
username,
|
|
324
|
+
clientId,
|
|
325
|
+
fields: options.fields.join(",")
|
|
326
|
+
});
|
|
327
|
+
const themeParams = this.getThemeParams(options.theme);
|
|
328
|
+
if (themeParams) {
|
|
329
|
+
const themeParsed = new URLSearchParams(themeParams);
|
|
330
|
+
themeParsed.forEach((value, key) => params.set(key, value));
|
|
331
|
+
}
|
|
332
|
+
const url = `${dialogUrl}/dialog/consent?${params.toString()}`;
|
|
333
|
+
const { dialog, iframe, cleanup } = this.createModalDialog(url);
|
|
334
|
+
const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
|
|
335
|
+
mode: "iframe"
|
|
336
|
+
});
|
|
337
|
+
if (!ready) {
|
|
338
|
+
return {
|
|
339
|
+
success: false,
|
|
340
|
+
error: { code: "USER_CANCELLED", message: "User closed the dialog" }
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
return this.waitForConsentResponse(dialog, iframe, cleanup);
|
|
344
|
+
}
|
|
192
345
|
/**
|
|
193
346
|
* Authenticate a user with an optional challenge to sign.
|
|
194
347
|
*
|
|
@@ -206,17 +359,16 @@ var OneAuthClient = class {
|
|
|
206
359
|
*
|
|
207
360
|
* @example
|
|
208
361
|
* ```typescript
|
|
209
|
-
* // Authenticate with a login challenge
|
|
210
362
|
* const result = await client.authenticate({
|
|
211
363
|
* challenge: `Login to MyApp\nTimestamp: ${Date.now()}\nNonce: ${crypto.randomUUID()}`
|
|
212
364
|
* });
|
|
213
365
|
*
|
|
214
|
-
* if (result.success && result.
|
|
366
|
+
* if (result.success && result.challenge) {
|
|
215
367
|
* // Verify signature server-side
|
|
216
368
|
* const isValid = await verifyOnServer(
|
|
217
|
-
* result.username,
|
|
218
|
-
* result.signature,
|
|
219
|
-
* result.signedHash
|
|
369
|
+
* result.user?.username,
|
|
370
|
+
* result.challenge.signature,
|
|
371
|
+
* result.challenge.signedHash
|
|
220
372
|
* );
|
|
221
373
|
* }
|
|
222
374
|
* ```
|
|
@@ -316,7 +468,8 @@ var OneAuthClient = class {
|
|
|
316
468
|
}
|
|
317
469
|
};
|
|
318
470
|
}
|
|
319
|
-
|
|
471
|
+
const accountAddress = signedIntent?.accountAddress || options.accountAddress;
|
|
472
|
+
if (!username && !accountAddress) {
|
|
320
473
|
return {
|
|
321
474
|
success: false,
|
|
322
475
|
intentId: "",
|
|
@@ -345,6 +498,7 @@ var OneAuthClient = class {
|
|
|
345
498
|
let prepareResponse;
|
|
346
499
|
const requestBody = signedIntent || {
|
|
347
500
|
username: options.username,
|
|
501
|
+
accountAddress: options.accountAddress,
|
|
348
502
|
targetChain: options.targetChain,
|
|
349
503
|
calls: options.calls,
|
|
350
504
|
tokenRequests: serializedTokenRequests,
|
|
@@ -352,48 +506,35 @@ var OneAuthClient = class {
|
|
|
352
506
|
sourceChainId: options.sourceChainId,
|
|
353
507
|
...this.config.clientId && { clientId: this.config.clientId }
|
|
354
508
|
};
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const errorData = await response.json().catch(() => ({}));
|
|
365
|
-
const errorMessage = errorData.error || "Failed to prepare intent";
|
|
366
|
-
if (errorMessage.includes("User not found")) {
|
|
367
|
-
localStorage.removeItem("1auth-user");
|
|
368
|
-
}
|
|
369
|
-
return {
|
|
370
|
-
success: false,
|
|
371
|
-
intentId: "",
|
|
372
|
-
status: "failed",
|
|
373
|
-
error: {
|
|
374
|
-
code: errorMessage.includes("User not found") ? "USER_NOT_FOUND" : "PREPARE_FAILED",
|
|
375
|
-
message: errorMessage
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
prepareResponse = await response.json();
|
|
380
|
-
} catch (error) {
|
|
509
|
+
const dialogUrl = this.getDialogUrl();
|
|
510
|
+
const themeParams = this.getThemeParams();
|
|
511
|
+
const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
|
|
512
|
+
const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
|
|
513
|
+
const [prepareResult, dialogResult] = await Promise.all([
|
|
514
|
+
this.prepareIntent(requestBody),
|
|
515
|
+
this.waitForDialogReadyDeferred(dialog, iframe, cleanup)
|
|
516
|
+
]);
|
|
517
|
+
if (!dialogResult.ready) {
|
|
381
518
|
return {
|
|
382
519
|
success: false,
|
|
383
520
|
intentId: "",
|
|
384
521
|
status: "failed",
|
|
385
|
-
error: {
|
|
386
|
-
code: "NETWORK_ERROR",
|
|
387
|
-
message: error instanceof Error ? error.message : "Network error"
|
|
388
|
-
}
|
|
522
|
+
error: { code: "USER_CANCELLED", message: "User closed the dialog" }
|
|
389
523
|
};
|
|
390
524
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
525
|
+
if (!prepareResult.success) {
|
|
526
|
+
this.sendPrepareError(iframe, prepareResult.error.message);
|
|
527
|
+
await this.waitForDialogClose(dialog, cleanup);
|
|
528
|
+
return {
|
|
529
|
+
success: false,
|
|
530
|
+
intentId: "",
|
|
531
|
+
status: "failed",
|
|
532
|
+
error: prepareResult.error
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
prepareResponse = prepareResult.data;
|
|
395
536
|
const dialogOrigin = this.getDialogOrigin();
|
|
396
|
-
const
|
|
537
|
+
const initPayload = {
|
|
397
538
|
mode: "iframe",
|
|
398
539
|
calls,
|
|
399
540
|
chainId: targetChain,
|
|
@@ -405,16 +546,21 @@ var OneAuthClient = class {
|
|
|
405
546
|
tokenRequests: serializedTokenRequests,
|
|
406
547
|
expiresAt: prepareResponse.expiresAt,
|
|
407
548
|
userId: prepareResponse.userId,
|
|
408
|
-
intentOp: prepareResponse.intentOp
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
549
|
+
intentOp: prepareResponse.intentOp,
|
|
550
|
+
digestResult: prepareResponse.digestResult,
|
|
551
|
+
tier: prepareResult.tier
|
|
552
|
+
};
|
|
553
|
+
dialogResult.sendInit(initPayload);
|
|
554
|
+
const handleReReady = (event) => {
|
|
555
|
+
if (event.origin !== dialogOrigin) return;
|
|
556
|
+
if (event.data?.type === "PASSKEY_READY") {
|
|
557
|
+
iframe.contentWindow?.postMessage(
|
|
558
|
+
{ type: "PASSKEY_INIT", ...initPayload },
|
|
559
|
+
dialogOrigin
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
window.addEventListener("message", handleReReady);
|
|
418
564
|
const signingResult = await this.waitForSigningWithRefresh(
|
|
419
565
|
dialog,
|
|
420
566
|
iframe,
|
|
@@ -441,7 +587,8 @@ var OneAuthClient = class {
|
|
|
441
587
|
expiresAt: refreshedData.expiresAt,
|
|
442
588
|
challenge: refreshedData.challenge,
|
|
443
589
|
originMessages: refreshedData.originMessages,
|
|
444
|
-
transaction: refreshedData.transaction
|
|
590
|
+
transaction: refreshedData.transaction,
|
|
591
|
+
digestResult: refreshedData.digestResult
|
|
445
592
|
};
|
|
446
593
|
} catch (error) {
|
|
447
594
|
console.error("[SDK] Quote refresh error:", error);
|
|
@@ -449,6 +596,7 @@ var OneAuthClient = class {
|
|
|
449
596
|
}
|
|
450
597
|
}
|
|
451
598
|
);
|
|
599
|
+
window.removeEventListener("message", handleReReady);
|
|
452
600
|
if (!signingResult.success) {
|
|
453
601
|
return {
|
|
454
602
|
success: false,
|
|
@@ -480,6 +628,7 @@ var OneAuthClient = class {
|
|
|
480
628
|
targetChain: prepareResponse.targetChain,
|
|
481
629
|
calls: prepareResponse.calls,
|
|
482
630
|
expiresAt: prepareResponse.expiresAt,
|
|
631
|
+
digestResult: prepareResponse.digestResult,
|
|
483
632
|
// Signature from dialog
|
|
484
633
|
signature: signingResult.signature,
|
|
485
634
|
passkey: signingResult.passkey
|
|
@@ -521,10 +670,21 @@ var OneAuthClient = class {
|
|
|
521
670
|
let finalTxHash = executeResponse.transactionHash;
|
|
522
671
|
if (finalStatus === "pending") {
|
|
523
672
|
this.sendTransactionStatus(iframe, "pending");
|
|
673
|
+
let userClosedEarly = false;
|
|
674
|
+
const dialogOrigin2 = this.getDialogOrigin();
|
|
675
|
+
const earlyCloseHandler = (event) => {
|
|
676
|
+
if (event.origin !== dialogOrigin2) return;
|
|
677
|
+
if (event.data?.type === "PASSKEY_CLOSE") {
|
|
678
|
+
userClosedEarly = true;
|
|
679
|
+
cleanup();
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
window.addEventListener("message", earlyCloseHandler);
|
|
524
683
|
const maxAttempts = 120;
|
|
525
684
|
const pollIntervalMs = 1500;
|
|
526
685
|
let lastStatus = "pending";
|
|
527
686
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
687
|
+
if (userClosedEarly) break;
|
|
528
688
|
try {
|
|
529
689
|
const statusResponse = await fetch(
|
|
530
690
|
`${this.config.providerUrl}/api/intent/status/${executeResponse.intentId}`,
|
|
@@ -559,6 +719,21 @@ var OneAuthClient = class {
|
|
|
559
719
|
}
|
|
560
720
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
561
721
|
}
|
|
722
|
+
window.removeEventListener("message", earlyCloseHandler);
|
|
723
|
+
if (userClosedEarly) {
|
|
724
|
+
cleanup();
|
|
725
|
+
return {
|
|
726
|
+
success: false,
|
|
727
|
+
intentId: executeResponse.intentId,
|
|
728
|
+
status: finalStatus,
|
|
729
|
+
transactionHash: finalTxHash,
|
|
730
|
+
operationId: executeResponse.operationId,
|
|
731
|
+
error: {
|
|
732
|
+
code: "USER_CANCELLED",
|
|
733
|
+
message: "User closed the dialog"
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
}
|
|
562
737
|
}
|
|
563
738
|
const closeOn = options.closeOn || "preconfirmed";
|
|
564
739
|
const successStatuses = {
|
|
@@ -569,8 +744,9 @@ var OneAuthClient = class {
|
|
|
569
744
|
};
|
|
570
745
|
const isSuccessStatus = successStatuses[closeOn]?.includes(finalStatus) ?? false;
|
|
571
746
|
const displayStatus = isSuccessStatus ? "confirmed" : finalStatus;
|
|
747
|
+
const closePromise = this.waitForDialogClose(dialog, cleanup);
|
|
572
748
|
this.sendTransactionStatus(iframe, displayStatus, finalTxHash);
|
|
573
|
-
await
|
|
749
|
+
await closePromise;
|
|
574
750
|
if (options.waitForHash && !finalTxHash) {
|
|
575
751
|
const hash = await this.waitForTransactionHash(executeResponse.intentId, {
|
|
576
752
|
timeoutMs: options.hashTimeoutMs,
|
|
@@ -631,7 +807,7 @@ var OneAuthClient = class {
|
|
|
631
807
|
* ```
|
|
632
808
|
*/
|
|
633
809
|
async sendBatchIntent(options) {
|
|
634
|
-
if (!options.username) {
|
|
810
|
+
if (!options.username && !options.accountAddress) {
|
|
635
811
|
return {
|
|
636
812
|
success: false,
|
|
637
813
|
results: [],
|
|
@@ -655,35 +831,24 @@ var OneAuthClient = class {
|
|
|
655
831
|
amount: r.amount.toString()
|
|
656
832
|
})),
|
|
657
833
|
sourceAssets: intent.sourceAssets,
|
|
658
|
-
sourceChainId: intent.sourceChainId
|
|
834
|
+
sourceChainId: intent.sourceChainId,
|
|
835
|
+
moduleInstall: intent.moduleInstall
|
|
659
836
|
}));
|
|
660
837
|
const requestBody = {
|
|
661
|
-
username: options.username,
|
|
838
|
+
...options.username && { username: options.username },
|
|
839
|
+
...options.accountAddress && { accountAddress: options.accountAddress },
|
|
662
840
|
intents: serializedIntents,
|
|
663
841
|
...this.config.clientId && { clientId: this.config.clientId }
|
|
664
842
|
};
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
const errorMessage = errorData.error || "Failed to prepare batch intent";
|
|
675
|
-
if (errorMessage.includes("User not found")) {
|
|
676
|
-
localStorage.removeItem("1auth-user");
|
|
677
|
-
}
|
|
678
|
-
return {
|
|
679
|
-
success: false,
|
|
680
|
-
results: [],
|
|
681
|
-
successCount: 0,
|
|
682
|
-
failureCount: 0
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
prepareResponse = await response.json();
|
|
686
|
-
} catch {
|
|
843
|
+
const dialogUrl = this.getDialogUrl();
|
|
844
|
+
const themeParams = this.getThemeParams();
|
|
845
|
+
const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
|
|
846
|
+
const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
|
|
847
|
+
const [prepareResult, dialogResult] = await Promise.all([
|
|
848
|
+
this.prepareBatchIntent(requestBody),
|
|
849
|
+
this.waitForDialogReadyDeferred(dialog, iframe, cleanup)
|
|
850
|
+
]);
|
|
851
|
+
if (!dialogResult.ready) {
|
|
687
852
|
return {
|
|
688
853
|
success: false,
|
|
689
854
|
results: [],
|
|
@@ -691,29 +856,50 @@ var OneAuthClient = class {
|
|
|
691
856
|
failureCount: 0
|
|
692
857
|
};
|
|
693
858
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
859
|
+
if (!prepareResult.success) {
|
|
860
|
+
const failedIntents = prepareResult.failedIntents;
|
|
861
|
+
const failureResults = failedIntents?.map((f) => ({
|
|
862
|
+
index: f.index,
|
|
863
|
+
success: false,
|
|
864
|
+
intentId: "",
|
|
865
|
+
status: "failed",
|
|
866
|
+
error: { message: f.error, code: "PREPARE_FAILED" }
|
|
867
|
+
})) ?? [];
|
|
868
|
+
this.sendPrepareError(iframe, prepareResult.error);
|
|
869
|
+
await this.waitForDialogClose(dialog, cleanup);
|
|
870
|
+
return {
|
|
871
|
+
success: false,
|
|
872
|
+
results: failureResults,
|
|
873
|
+
successCount: 0,
|
|
874
|
+
failureCount: failureResults.length,
|
|
875
|
+
error: prepareResult.error
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
let prepareResponse = prepareResult.data;
|
|
698
879
|
const dialogOrigin = this.getDialogOrigin();
|
|
699
|
-
const
|
|
880
|
+
const batchInitPayload = {
|
|
700
881
|
mode: "iframe",
|
|
701
882
|
batchMode: true,
|
|
702
883
|
batchIntents: prepareResponse.intents,
|
|
884
|
+
batchFailedIntents: prepareResponse.failedIntents,
|
|
703
885
|
challenge: prepareResponse.challenge,
|
|
704
886
|
username: options.username,
|
|
705
887
|
accountAddress: prepareResponse.accountAddress,
|
|
706
888
|
userId: prepareResponse.userId,
|
|
707
|
-
expiresAt: prepareResponse.expiresAt
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
889
|
+
expiresAt: prepareResponse.expiresAt,
|
|
890
|
+
tier: prepareResult.tier
|
|
891
|
+
};
|
|
892
|
+
dialogResult.sendInit(batchInitPayload);
|
|
893
|
+
const handleBatchReReady = (event) => {
|
|
894
|
+
if (event.origin !== dialogOrigin) return;
|
|
895
|
+
if (event.data?.type === "PASSKEY_READY") {
|
|
896
|
+
iframe.contentWindow?.postMessage(
|
|
897
|
+
{ type: "PASSKEY_INIT", ...batchInitPayload },
|
|
898
|
+
dialogOrigin
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
window.addEventListener("message", handleBatchReReady);
|
|
717
903
|
const batchResult = await new Promise((resolve) => {
|
|
718
904
|
const handleMessage = async (event) => {
|
|
719
905
|
if (event.origin !== dialogOrigin) return;
|
|
@@ -760,13 +946,21 @@ var OneAuthClient = class {
|
|
|
760
946
|
status: r.status === "FAILED" ? "failed" : "pending",
|
|
761
947
|
error: r.error ? { code: "EXECUTE_FAILED", message: r.error } : void 0
|
|
762
948
|
}));
|
|
763
|
-
const
|
|
949
|
+
const prepareFailures = (prepareResponse.failedIntents ?? []).map((f) => ({
|
|
950
|
+
index: f.index,
|
|
951
|
+
success: false,
|
|
952
|
+
intentId: "",
|
|
953
|
+
status: "failed",
|
|
954
|
+
error: { code: "PREPARE_FAILED", message: f.error }
|
|
955
|
+
}));
|
|
956
|
+
const allResults = [...results, ...prepareFailures].sort((a, b) => a.index - b.index);
|
|
957
|
+
const successCount = allResults.filter((r) => r.success).length;
|
|
764
958
|
await this.waitForDialogClose(dialog, cleanup);
|
|
765
959
|
resolve({
|
|
766
|
-
success: successCount ===
|
|
767
|
-
results,
|
|
960
|
+
success: successCount === allResults.length,
|
|
961
|
+
results: allResults,
|
|
768
962
|
successCount,
|
|
769
|
-
failureCount:
|
|
963
|
+
failureCount: allResults.length - successCount
|
|
770
964
|
});
|
|
771
965
|
} else {
|
|
772
966
|
cleanup();
|
|
@@ -791,6 +985,7 @@ var OneAuthClient = class {
|
|
|
791
985
|
};
|
|
792
986
|
window.addEventListener("message", handleMessage);
|
|
793
987
|
});
|
|
988
|
+
window.removeEventListener("message", handleBatchReReady);
|
|
794
989
|
return batchResult;
|
|
795
990
|
}
|
|
796
991
|
/**
|
|
@@ -994,6 +1189,143 @@ var OneAuthClient = class {
|
|
|
994
1189
|
dialog.addEventListener("close", handleClose);
|
|
995
1190
|
});
|
|
996
1191
|
}
|
|
1192
|
+
/**
|
|
1193
|
+
* Inject a preconnect link tag to pre-warm DNS + TLS for a given URL.
|
|
1194
|
+
*/
|
|
1195
|
+
injectPreconnect(url) {
|
|
1196
|
+
try {
|
|
1197
|
+
const origin = new URL(url).origin;
|
|
1198
|
+
if (document.querySelector(`link[rel="preconnect"][href="${origin}"]`)) return;
|
|
1199
|
+
const link = document.createElement("link");
|
|
1200
|
+
link.rel = "preconnect";
|
|
1201
|
+
link.href = origin;
|
|
1202
|
+
link.crossOrigin = "anonymous";
|
|
1203
|
+
document.head.appendChild(link);
|
|
1204
|
+
} catch {
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Wait for the dialog iframe to signal ready without sending init data.
|
|
1209
|
+
* Returns a sendInit function the caller uses once prepare data is available.
|
|
1210
|
+
*/
|
|
1211
|
+
waitForDialogReadyDeferred(dialog, iframe, cleanup) {
|
|
1212
|
+
const dialogOrigin = this.getDialogOrigin();
|
|
1213
|
+
return new Promise((resolve) => {
|
|
1214
|
+
let settled = false;
|
|
1215
|
+
const teardown = () => {
|
|
1216
|
+
if (settled) return;
|
|
1217
|
+
settled = true;
|
|
1218
|
+
clearTimeout(readyTimeout);
|
|
1219
|
+
window.removeEventListener("message", handleMessage);
|
|
1220
|
+
dialog.removeEventListener("close", handleClose);
|
|
1221
|
+
};
|
|
1222
|
+
const handleMessage = (event) => {
|
|
1223
|
+
if (event.origin !== dialogOrigin) return;
|
|
1224
|
+
if (event.data?.type === "PASSKEY_READY") {
|
|
1225
|
+
teardown();
|
|
1226
|
+
resolve({
|
|
1227
|
+
ready: true,
|
|
1228
|
+
sendInit: (initMessage) => {
|
|
1229
|
+
iframe.contentWindow?.postMessage(
|
|
1230
|
+
{ type: "PASSKEY_INIT", ...initMessage },
|
|
1231
|
+
dialogOrigin
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
});
|
|
1235
|
+
} else if (event.data?.type === "PASSKEY_CLOSE") {
|
|
1236
|
+
teardown();
|
|
1237
|
+
cleanup();
|
|
1238
|
+
resolve({ ready: false });
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1241
|
+
const handleClose = () => {
|
|
1242
|
+
teardown();
|
|
1243
|
+
resolve({ ready: false });
|
|
1244
|
+
};
|
|
1245
|
+
const readyTimeout = setTimeout(() => {
|
|
1246
|
+
teardown();
|
|
1247
|
+
cleanup();
|
|
1248
|
+
resolve({ ready: false });
|
|
1249
|
+
}, 1e4);
|
|
1250
|
+
window.addEventListener("message", handleMessage);
|
|
1251
|
+
dialog.addEventListener("close", handleClose);
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Prepare an intent by calling the orchestrator for a quote.
|
|
1256
|
+
* Returns the prepare response and the origin tier from the response header.
|
|
1257
|
+
*/
|
|
1258
|
+
async prepareIntent(requestBody) {
|
|
1259
|
+
try {
|
|
1260
|
+
const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {
|
|
1261
|
+
method: "POST",
|
|
1262
|
+
headers: { "Content-Type": "application/json" },
|
|
1263
|
+
body: JSON.stringify(requestBody)
|
|
1264
|
+
});
|
|
1265
|
+
if (!response.ok) {
|
|
1266
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1267
|
+
const errorMessage = errorData.error || "Failed to prepare intent";
|
|
1268
|
+
if (errorMessage.includes("User not found")) {
|
|
1269
|
+
localStorage.removeItem("1auth-user");
|
|
1270
|
+
}
|
|
1271
|
+
return {
|
|
1272
|
+
success: false,
|
|
1273
|
+
error: {
|
|
1274
|
+
code: errorMessage.includes("User not found") ? "USER_NOT_FOUND" : "PREPARE_FAILED",
|
|
1275
|
+
message: errorMessage
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
const tier = response.headers.get("X-Origin-Tier");
|
|
1280
|
+
return { success: true, data: await response.json(), tier };
|
|
1281
|
+
} catch (error) {
|
|
1282
|
+
return {
|
|
1283
|
+
success: false,
|
|
1284
|
+
error: {
|
|
1285
|
+
code: "NETWORK_ERROR",
|
|
1286
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Prepare a batch intent by calling the orchestrator for quotes on all intents.
|
|
1293
|
+
*/
|
|
1294
|
+
async prepareBatchIntent(requestBody) {
|
|
1295
|
+
try {
|
|
1296
|
+
const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {
|
|
1297
|
+
method: "POST",
|
|
1298
|
+
headers: { "Content-Type": "application/json" },
|
|
1299
|
+
body: JSON.stringify(requestBody)
|
|
1300
|
+
});
|
|
1301
|
+
if (!response.ok) {
|
|
1302
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1303
|
+
const errorMessage = errorData.error || "Failed to prepare batch intent";
|
|
1304
|
+
if (errorMessage.includes("User not found")) {
|
|
1305
|
+
localStorage.removeItem("1auth-user");
|
|
1306
|
+
}
|
|
1307
|
+
return {
|
|
1308
|
+
success: false,
|
|
1309
|
+
error: errorMessage,
|
|
1310
|
+
failedIntents: errorData.failedIntents
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
const tier = response.headers.get("X-Origin-Tier");
|
|
1314
|
+
return { success: true, data: await response.json(), tier };
|
|
1315
|
+
} catch {
|
|
1316
|
+
return { success: false, error: "Network error" };
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Send a prepare error message to the dialog iframe.
|
|
1321
|
+
*/
|
|
1322
|
+
sendPrepareError(iframe, error) {
|
|
1323
|
+
const dialogOrigin = this.getDialogOrigin();
|
|
1324
|
+
iframe.contentWindow?.postMessage(
|
|
1325
|
+
{ type: "PASSKEY_PREPARE_ERROR", error },
|
|
1326
|
+
dialogOrigin
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
997
1329
|
/**
|
|
998
1330
|
* Poll for intent status
|
|
999
1331
|
*
|
|
@@ -1305,6 +1637,7 @@ var OneAuthClient = class {
|
|
|
1305
1637
|
message: options.message,
|
|
1306
1638
|
challenge: options.challenge || options.message,
|
|
1307
1639
|
username: options.username,
|
|
1640
|
+
accountAddress: options.accountAddress,
|
|
1308
1641
|
description: options.description,
|
|
1309
1642
|
metadata: options.metadata
|
|
1310
1643
|
});
|
|
@@ -1396,6 +1729,7 @@ var OneAuthClient = class {
|
|
|
1396
1729
|
},
|
|
1397
1730
|
challenge: signedHash,
|
|
1398
1731
|
username: options.username,
|
|
1732
|
+
accountAddress: options.accountAddress,
|
|
1399
1733
|
description: options.description
|
|
1400
1734
|
});
|
|
1401
1735
|
if (!ready) {
|
|
@@ -1469,7 +1803,7 @@ var OneAuthClient = class {
|
|
|
1469
1803
|
iframe.style.borderRadius = "12px";
|
|
1470
1804
|
iframe.style.boxShadow = "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)";
|
|
1471
1805
|
iframe.id = `passkey-embed-${requestId}`;
|
|
1472
|
-
iframe.allow = "publickey-credentials-get *; publickey-credentials-create
|
|
1806
|
+
iframe.allow = "publickey-credentials-get *; publickey-credentials-create *; identity-credentials-get";
|
|
1473
1807
|
iframe.onload = () => {
|
|
1474
1808
|
options.onReady?.();
|
|
1475
1809
|
};
|
|
@@ -1617,6 +1951,7 @@ var OneAuthClient = class {
|
|
|
1617
1951
|
const teardown = () => {
|
|
1618
1952
|
if (settled) return;
|
|
1619
1953
|
settled = true;
|
|
1954
|
+
clearTimeout(readyTimeout);
|
|
1620
1955
|
window.removeEventListener("message", handleMessage);
|
|
1621
1956
|
dialog.removeEventListener("close", handleClose);
|
|
1622
1957
|
};
|
|
@@ -1639,6 +1974,11 @@ var OneAuthClient = class {
|
|
|
1639
1974
|
teardown();
|
|
1640
1975
|
resolve(false);
|
|
1641
1976
|
};
|
|
1977
|
+
const readyTimeout = setTimeout(() => {
|
|
1978
|
+
teardown();
|
|
1979
|
+
cleanup();
|
|
1980
|
+
resolve(false);
|
|
1981
|
+
}, 1e4);
|
|
1642
1982
|
window.addEventListener("message", handleMessage);
|
|
1643
1983
|
dialog.addEventListener("close", handleClose);
|
|
1644
1984
|
});
|
|
@@ -1679,7 +2019,9 @@ var OneAuthClient = class {
|
|
|
1679
2019
|
border-radius: 14px;
|
|
1680
2020
|
border: none;
|
|
1681
2021
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
1682
|
-
transition:
|
|
2022
|
+
transition: height 0.15s ease-out;
|
|
2023
|
+
max-height: calc(100vh - 100px);
|
|
2024
|
+
max-height: calc(100dvh - 100px);
|
|
1683
2025
|
}
|
|
1684
2026
|
|
|
1685
2027
|
@media (min-width: 769px) {
|
|
@@ -1741,14 +2083,10 @@ var OneAuthClient = class {
|
|
|
1741
2083
|
const iframe = document.createElement("iframe");
|
|
1742
2084
|
iframe.setAttribute(
|
|
1743
2085
|
"allow",
|
|
1744
|
-
"publickey-credentials-get *; publickey-credentials-create *; clipboard-write"
|
|
2086
|
+
"publickey-credentials-get *; publickey-credentials-create *; clipboard-write; identity-credentials-get"
|
|
1745
2087
|
);
|
|
1746
2088
|
iframe.setAttribute("aria-label", "Passkey Authentication");
|
|
1747
2089
|
iframe.setAttribute("tabindex", "0");
|
|
1748
|
-
iframe.setAttribute(
|
|
1749
|
-
"sandbox",
|
|
1750
|
-
"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
|
|
1751
|
-
);
|
|
1752
2090
|
iframe.setAttribute("src", url);
|
|
1753
2091
|
iframe.setAttribute("title", "Passkey");
|
|
1754
2092
|
iframe.style.border = "none";
|
|
@@ -1758,10 +2096,8 @@ var OneAuthClient = class {
|
|
|
1758
2096
|
const handleMessage = (event) => {
|
|
1759
2097
|
if (event.origin !== hostUrl.origin) return;
|
|
1760
2098
|
if (event.data?.type === "PASSKEY_RESIZE") {
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
iframe.style.width = `${event.data.width}px`;
|
|
1764
|
-
}
|
|
2099
|
+
const maxHeight = window.innerHeight - 100;
|
|
2100
|
+
iframe.style.height = `${Math.min(event.data.height, maxHeight)}px`;
|
|
1765
2101
|
} else if (event.data?.type === "PASSKEY_DISCONNECT") {
|
|
1766
2102
|
localStorage.removeItem("1auth-user");
|
|
1767
2103
|
}
|
|
@@ -1779,7 +2115,10 @@ var OneAuthClient = class {
|
|
|
1779
2115
|
}
|
|
1780
2116
|
});
|
|
1781
2117
|
dialog.showModal();
|
|
2118
|
+
let cleanedUp = false;
|
|
1782
2119
|
const cleanup = () => {
|
|
2120
|
+
if (cleanedUp) return;
|
|
2121
|
+
cleanedUp = true;
|
|
1783
2122
|
window.removeEventListener("message", handleMessage);
|
|
1784
2123
|
document.removeEventListener("keydown", handleEscape);
|
|
1785
2124
|
dialog.close();
|
|
@@ -1811,22 +2150,11 @@ var OneAuthClient = class {
|
|
|
1811
2150
|
if (data.success) {
|
|
1812
2151
|
resolve({
|
|
1813
2152
|
success: true,
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
success: false,
|
|
1820
|
-
error: data.error
|
|
1821
|
-
});
|
|
1822
|
-
}
|
|
1823
|
-
} else if (data?.type === "PASSKEY_REGISTER_RESULT") {
|
|
1824
|
-
window.removeEventListener("message", handleMessage);
|
|
1825
|
-
cleanup();
|
|
1826
|
-
if (data.success) {
|
|
1827
|
-
resolve({
|
|
1828
|
-
success: true,
|
|
1829
|
-
username: data.data?.username
|
|
2153
|
+
user: {
|
|
2154
|
+
id: data.data?.user?.id,
|
|
2155
|
+
username: data.data?.username,
|
|
2156
|
+
address: data.data?.address
|
|
2157
|
+
}
|
|
1830
2158
|
});
|
|
1831
2159
|
} else {
|
|
1832
2160
|
resolve({
|
|
@@ -1885,8 +2213,11 @@ var OneAuthClient = class {
|
|
|
1885
2213
|
if (data.success) {
|
|
1886
2214
|
resolve({
|
|
1887
2215
|
success: true,
|
|
1888
|
-
|
|
1889
|
-
|
|
2216
|
+
user: {
|
|
2217
|
+
id: data.data?.user?.id,
|
|
2218
|
+
username: data.data?.username,
|
|
2219
|
+
address: data.data?.address
|
|
2220
|
+
}
|
|
1890
2221
|
});
|
|
1891
2222
|
} else {
|
|
1892
2223
|
resolve({
|
|
@@ -1894,14 +2225,43 @@ var OneAuthClient = class {
|
|
|
1894
2225
|
error: data.error
|
|
1895
2226
|
});
|
|
1896
2227
|
}
|
|
1897
|
-
} else if (data?.type === "
|
|
2228
|
+
} else if (data?.type === "PASSKEY_CLOSE") {
|
|
1898
2229
|
clearInterval(pollTimer);
|
|
1899
2230
|
window.removeEventListener("message", handleMessage);
|
|
1900
2231
|
popup?.close();
|
|
2232
|
+
resolve({
|
|
2233
|
+
success: false,
|
|
2234
|
+
error: {
|
|
2235
|
+
code: "USER_CANCELLED",
|
|
2236
|
+
message: "Authentication was cancelled"
|
|
2237
|
+
}
|
|
2238
|
+
});
|
|
2239
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
window.addEventListener("message", handleMessage);
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
waitForAuthenticateResponse(_dialog, _iframe, cleanup) {
|
|
2245
|
+
const dialogOrigin = this.getDialogOrigin();
|
|
2246
|
+
return new Promise((resolve) => {
|
|
2247
|
+
const handleMessage = (event) => {
|
|
2248
|
+
if (event.origin !== dialogOrigin) return;
|
|
2249
|
+
const data = event.data;
|
|
2250
|
+
if (data?.type === "PASSKEY_AUTHENTICATE_RESULT") {
|
|
2251
|
+
window.removeEventListener("message", handleMessage);
|
|
2252
|
+
cleanup();
|
|
1901
2253
|
if (data.success) {
|
|
1902
2254
|
resolve({
|
|
1903
2255
|
success: true,
|
|
1904
|
-
|
|
2256
|
+
user: {
|
|
2257
|
+
id: data.data?.user?.id,
|
|
2258
|
+
username: data.data?.username,
|
|
2259
|
+
address: data.data?.accountAddress
|
|
2260
|
+
},
|
|
2261
|
+
challenge: data.data?.signature ? {
|
|
2262
|
+
signature: data.data.signature,
|
|
2263
|
+
signedHash: data.data.signedHash
|
|
2264
|
+
} : void 0
|
|
1905
2265
|
});
|
|
1906
2266
|
} else {
|
|
1907
2267
|
resolve({
|
|
@@ -1910,9 +2270,8 @@ var OneAuthClient = class {
|
|
|
1910
2270
|
});
|
|
1911
2271
|
}
|
|
1912
2272
|
} else if (data?.type === "PASSKEY_CLOSE") {
|
|
1913
|
-
clearInterval(pollTimer);
|
|
1914
2273
|
window.removeEventListener("message", handleMessage);
|
|
1915
|
-
|
|
2274
|
+
cleanup();
|
|
1916
2275
|
resolve({
|
|
1917
2276
|
success: false,
|
|
1918
2277
|
error: {
|
|
@@ -1925,27 +2284,28 @@ var OneAuthClient = class {
|
|
|
1925
2284
|
window.addEventListener("message", handleMessage);
|
|
1926
2285
|
});
|
|
1927
2286
|
}
|
|
1928
|
-
|
|
2287
|
+
waitForConnectResponse(_dialog, _iframe, cleanup) {
|
|
1929
2288
|
const dialogOrigin = this.getDialogOrigin();
|
|
1930
2289
|
return new Promise((resolve) => {
|
|
1931
2290
|
const handleMessage = (event) => {
|
|
1932
2291
|
if (event.origin !== dialogOrigin) return;
|
|
1933
2292
|
const data = event.data;
|
|
1934
|
-
if (data?.type === "
|
|
2293
|
+
if (data?.type === "PASSKEY_CONNECT_RESULT") {
|
|
1935
2294
|
window.removeEventListener("message", handleMessage);
|
|
1936
2295
|
cleanup();
|
|
1937
2296
|
if (data.success) {
|
|
1938
2297
|
resolve({
|
|
1939
2298
|
success: true,
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
2299
|
+
user: {
|
|
2300
|
+
username: data.data?.username,
|
|
2301
|
+
address: data.data?.address
|
|
2302
|
+
},
|
|
2303
|
+
autoConnected: data.data?.autoConnected
|
|
1945
2304
|
});
|
|
1946
2305
|
} else {
|
|
1947
2306
|
resolve({
|
|
1948
2307
|
success: false,
|
|
2308
|
+
action: data.data?.action,
|
|
1949
2309
|
error: data.error
|
|
1950
2310
|
});
|
|
1951
2311
|
}
|
|
@@ -1954,9 +2314,10 @@ var OneAuthClient = class {
|
|
|
1954
2314
|
cleanup();
|
|
1955
2315
|
resolve({
|
|
1956
2316
|
success: false,
|
|
2317
|
+
action: "cancel",
|
|
1957
2318
|
error: {
|
|
1958
2319
|
code: "USER_CANCELLED",
|
|
1959
|
-
message: "
|
|
2320
|
+
message: "Connection was cancelled"
|
|
1960
2321
|
}
|
|
1961
2322
|
});
|
|
1962
2323
|
}
|
|
@@ -1964,26 +2325,28 @@ var OneAuthClient = class {
|
|
|
1964
2325
|
window.addEventListener("message", handleMessage);
|
|
1965
2326
|
});
|
|
1966
2327
|
}
|
|
1967
|
-
|
|
2328
|
+
waitForConsentResponse(_dialog, _iframe, cleanup) {
|
|
1968
2329
|
const dialogOrigin = this.getDialogOrigin();
|
|
1969
2330
|
return new Promise((resolve) => {
|
|
1970
2331
|
const handleMessage = (event) => {
|
|
1971
2332
|
if (event.origin !== dialogOrigin) return;
|
|
1972
2333
|
const data = event.data;
|
|
1973
|
-
if (data?.type === "
|
|
2334
|
+
if (data?.type === "PASSKEY_CONSENT_RESULT") {
|
|
1974
2335
|
window.removeEventListener("message", handleMessage);
|
|
1975
2336
|
cleanup();
|
|
1976
2337
|
if (data.success) {
|
|
1977
2338
|
resolve({
|
|
1978
2339
|
success: true,
|
|
1979
|
-
|
|
1980
|
-
|
|
2340
|
+
data: data.data,
|
|
2341
|
+
grantedAt: data.data?.grantedAt
|
|
1981
2342
|
});
|
|
1982
2343
|
} else {
|
|
1983
2344
|
resolve({
|
|
1984
2345
|
success: false,
|
|
1985
|
-
|
|
1986
|
-
|
|
2346
|
+
error: data.error ?? {
|
|
2347
|
+
code: "USER_REJECTED",
|
|
2348
|
+
message: "User denied the consent request"
|
|
2349
|
+
}
|
|
1987
2350
|
});
|
|
1988
2351
|
}
|
|
1989
2352
|
} else if (data?.type === "PASSKEY_CLOSE") {
|
|
@@ -1991,10 +2354,9 @@ var OneAuthClient = class {
|
|
|
1991
2354
|
cleanup();
|
|
1992
2355
|
resolve({
|
|
1993
2356
|
success: false,
|
|
1994
|
-
action: "cancel",
|
|
1995
2357
|
error: {
|
|
1996
2358
|
code: "USER_CANCELLED",
|
|
1997
|
-
message: "
|
|
2359
|
+
message: "User closed the dialog"
|
|
1998
2360
|
}
|
|
1999
2361
|
});
|
|
2000
2362
|
}
|
|
@@ -2800,7 +3162,6 @@ function BatchQueueWidget({ onSignAll }) {
|
|
|
2800
3162
|
// src/verify.ts
|
|
2801
3163
|
import { keccak256, toBytes } from "viem";
|
|
2802
3164
|
var ETHEREUM_MESSAGE_PREFIX = "Ethereum Signed Message:\n";
|
|
2803
|
-
var PASSKEY_MESSAGE_PREFIX = ETHEREUM_MESSAGE_PREFIX;
|
|
2804
3165
|
function hashMessage2(message) {
|
|
2805
3166
|
const prefixed = ETHEREUM_MESSAGE_PREFIX + message.length.toString() + message;
|
|
2806
3167
|
return keccak256(toBytes(prefixed));
|
|
@@ -2815,11 +3176,8 @@ export {
|
|
|
2815
3176
|
BatchQueueWidget,
|
|
2816
3177
|
ETHEREUM_MESSAGE_PREFIX,
|
|
2817
3178
|
OneAuthClient,
|
|
2818
|
-
PASSKEY_MESSAGE_PREFIX,
|
|
2819
|
-
OneAuthClient as PasskeyProviderClient,
|
|
2820
3179
|
createOneAuthProvider,
|
|
2821
3180
|
createPasskeyAccount,
|
|
2822
|
-
createPasskeyProvider,
|
|
2823
3181
|
createPasskeyWalletClient,
|
|
2824
3182
|
encodeWebAuthnSignature,
|
|
2825
3183
|
getAllSupportedChainsAndTokens,
|