@rhinestone/1auth 0.1.0 → 0.1.2

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/index.js CHANGED
@@ -32,8 +32,11 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  BatchQueueProvider: () => BatchQueueProvider,
34
34
  BatchQueueWidget: () => BatchQueueWidget,
35
+ ETHEREUM_MESSAGE_PREFIX: () => ETHEREUM_MESSAGE_PREFIX,
36
+ OneAuthClient: () => OneAuthClient,
35
37
  PASSKEY_MESSAGE_PREFIX: () => PASSKEY_MESSAGE_PREFIX,
36
- PasskeyProviderClient: () => PasskeyProviderClient,
38
+ PasskeyProviderClient: () => OneAuthClient,
39
+ createOneAuthProvider: () => createOneAuthProvider,
37
40
  createPasskeyAccount: () => createPasskeyAccount,
38
41
  createPasskeyProvider: () => createPasskeyProvider,
39
42
  createPasskeyWalletClient: () => createPasskeyWalletClient,
@@ -155,7 +158,13 @@ function resolveTokenAddress(token, chainId) {
155
158
  if ((0, import_viem.isAddress)(token)) {
156
159
  return token;
157
160
  }
158
- return (0, import_sdk.getTokenAddress)(token.toUpperCase(), chainId);
161
+ const match = getSupportedTokens(chainId).find(
162
+ (t) => t.symbol.toUpperCase() === token.toUpperCase()
163
+ );
164
+ if (!match) {
165
+ return (0, import_sdk.getTokenAddress)(token, chainId);
166
+ }
167
+ return match.address;
159
168
  }
160
169
  function isTestnet(chainId) {
161
170
  try {
@@ -189,10 +198,13 @@ var POPUP_HEIGHT = 600;
189
198
  var DEFAULT_EMBED_WIDTH = "400px";
190
199
  var DEFAULT_EMBED_HEIGHT = "500px";
191
200
  var MODAL_WIDTH = 360;
192
- var PasskeyProviderClient = class {
201
+ var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
202
+ var OneAuthClient = class {
193
203
  constructor(config) {
194
- this.config = config;
195
- this.theme = config.theme || {};
204
+ const providerUrl = config.providerUrl || DEFAULT_PROVIDER_URL;
205
+ const dialogUrl = config.dialogUrl || providerUrl;
206
+ this.config = { ...config, providerUrl, dialogUrl };
207
+ this.theme = this.config.theme || {};
196
208
  }
197
209
  /**
198
210
  * Update the theme configuration at runtime
@@ -254,9 +266,7 @@ var PasskeyProviderClient = class {
254
266
  const response = await fetch(
255
267
  `${this.config.providerUrl}/api/intent/status/${intentId}`,
256
268
  {
257
- headers: {
258
- "x-client-id": this.config.clientId
259
- }
269
+ headers: this.config.clientId ? { "x-client-id": this.config.clientId } : {}
260
270
  }
261
271
  );
262
272
  if (response.ok) {
@@ -275,16 +285,16 @@ var PasskeyProviderClient = class {
275
285
  return void 0;
276
286
  }
277
287
  /**
278
- * Show Porto-style "Get started" auth dialog (combines sign in + sign up)
279
- * This is the recommended method for authentication - shows a modal overlay
280
- * with both sign in and create account options.
288
+ * Open the auth dialog (sign in + sign up).
281
289
  */
282
290
  async authWithModal(options) {
283
291
  const dialogUrl = this.getDialogUrl();
284
292
  const params = new URLSearchParams({
285
- clientId: this.config.clientId,
286
293
  mode: "iframe"
287
294
  });
295
+ if (this.config.clientId) {
296
+ params.set("clientId", this.config.clientId);
297
+ }
288
298
  if (options?.username) {
289
299
  params.set("username", options.username);
290
300
  }
@@ -300,6 +310,55 @@ var PasskeyProviderClient = class {
300
310
  const { dialog, iframe, cleanup } = this.createModalDialog(url);
301
311
  return this.waitForModalAuthResponse(dialog, iframe, cleanup);
302
312
  }
313
+ /**
314
+ * Open the connect dialog (lightweight connection without passkey auth).
315
+ *
316
+ * This method shows a simple connection confirmation dialog that doesn't
317
+ * require a passkey signature. Users can optionally enable "auto-connect"
318
+ * to skip this dialog in the future.
319
+ *
320
+ * If the user has never connected before, this will return action: "switch"
321
+ * to indicate that the full auth modal should be opened instead.
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * const result = await client.connectWithModal();
326
+ *
327
+ * if (result.success) {
328
+ * console.log('Connected as:', result.username);
329
+ * } else if (result.action === 'switch') {
330
+ * // User needs to sign in first
331
+ * const authResult = await client.authWithModal();
332
+ * }
333
+ * ```
334
+ */
335
+ async connectWithModal(options) {
336
+ const dialogUrl = this.getDialogUrl();
337
+ const params = new URLSearchParams({
338
+ mode: "iframe"
339
+ });
340
+ if (this.config.clientId) {
341
+ params.set("clientId", this.config.clientId);
342
+ }
343
+ const themeParams = this.getThemeParams(options?.theme);
344
+ if (themeParams) {
345
+ const themeParsed = new URLSearchParams(themeParams);
346
+ themeParsed.forEach((value, key) => params.set(key, value));
347
+ }
348
+ const url = `${dialogUrl}/dialog/connect?${params.toString()}`;
349
+ const { dialog, iframe, cleanup } = this.createModalDialog(url);
350
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
351
+ mode: "iframe"
352
+ });
353
+ if (!ready) {
354
+ return {
355
+ success: false,
356
+ action: "cancel",
357
+ error: { code: "USER_CANCELLED", message: "Connection was cancelled" }
358
+ };
359
+ }
360
+ return this.waitForConnectResponse(dialog, iframe, cleanup);
361
+ }
303
362
  /**
304
363
  * Authenticate a user with an optional challenge to sign.
305
364
  *
@@ -335,9 +394,11 @@ var PasskeyProviderClient = class {
335
394
  async authenticate(options) {
336
395
  const dialogUrl = this.getDialogUrl();
337
396
  const params = new URLSearchParams({
338
- clientId: this.config.clientId,
339
397
  mode: "iframe"
340
398
  });
399
+ if (this.config.clientId) {
400
+ params.set("clientId", this.config.clientId);
401
+ }
341
402
  if (options?.challenge) {
342
403
  params.set("challenge", options.challenge);
343
404
  }
@@ -351,28 +412,30 @@ var PasskeyProviderClient = class {
351
412
  return this.waitForAuthenticateResponse(dialog, iframe, cleanup);
352
413
  }
353
414
  /**
354
- * Show signing in a modal overlay (Porto-style iframe dialog)
415
+ * Show signing in a modal overlay (iframe dialog)
355
416
  */
356
417
  async signWithModal(options) {
357
418
  const dialogUrl = this.getDialogUrl();
358
419
  const themeParams = this.getThemeParams(options?.theme);
359
420
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
360
421
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
361
- const dialogOrigin = this.getDialogOrigin();
362
- await new Promise((resolve) => {
363
- iframe.onload = () => {
364
- iframe.contentWindow?.postMessage({
365
- type: "PASSKEY_INIT",
366
- mode: "iframe",
367
- challenge: options.challenge,
368
- username: options.username,
369
- description: options.description,
370
- transaction: options.transaction,
371
- metadata: options.metadata
372
- }, dialogOrigin);
373
- resolve();
374
- };
422
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
423
+ mode: "iframe",
424
+ challenge: options.challenge,
425
+ username: options.username,
426
+ description: options.description,
427
+ transaction: options.transaction,
428
+ metadata: options.metadata
375
429
  });
430
+ if (!ready) {
431
+ return {
432
+ success: false,
433
+ error: {
434
+ code: "USER_REJECTED",
435
+ message: "User closed the dialog"
436
+ }
437
+ };
438
+ }
376
439
  return this.waitForSigningResponse(dialog, iframe, cleanup);
377
440
  }
378
441
  /**
@@ -405,10 +468,24 @@ var PasskeyProviderClient = class {
405
468
  * ```
406
469
  */
407
470
  async sendIntent(options) {
408
- const signedIntent = options.signedIntent;
471
+ const signedIntent = options.signedIntent ? {
472
+ ...options.signedIntent,
473
+ merchantId: options.signedIntent.merchantId || options.signedIntent.developerId
474
+ } : void 0;
409
475
  const username = signedIntent?.username || options.username;
410
476
  const targetChain = signedIntent?.targetChain || options.targetChain;
411
477
  const calls = signedIntent?.calls || options.calls;
478
+ if (signedIntent && !signedIntent.merchantId) {
479
+ return {
480
+ success: false,
481
+ intentId: "",
482
+ status: "failed",
483
+ error: {
484
+ code: "INVALID_OPTIONS",
485
+ message: "Signed intent requires developerId (clientId)"
486
+ }
487
+ };
488
+ }
412
489
  if (!username && !signedIntent?.accountAddress) {
413
490
  return {
414
491
  success: false,
@@ -431,16 +508,21 @@ var PasskeyProviderClient = class {
431
508
  }
432
509
  };
433
510
  }
511
+ const serializedTokenRequests = options.tokenRequests?.map((r) => ({
512
+ token: r.token,
513
+ amount: r.amount.toString()
514
+ }));
434
515
  let prepareResponse;
516
+ const requestBody = signedIntent || {
517
+ username: options.username,
518
+ targetChain: options.targetChain,
519
+ calls: options.calls,
520
+ tokenRequests: serializedTokenRequests,
521
+ sourceAssets: options.sourceAssets,
522
+ sourceChainId: options.sourceChainId,
523
+ ...this.config.clientId && { clientId: this.config.clientId }
524
+ };
435
525
  try {
436
- const requestBody = signedIntent || {
437
- username: options.username,
438
- targetChain: options.targetChain,
439
- calls: options.calls,
440
- tokenRequests: options.tokenRequests,
441
- sourceAssets: options.sourceAssets,
442
- clientId: this.config.clientId
443
- };
444
526
  const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {
445
527
  method: "POST",
446
528
  headers: {
@@ -477,112 +559,190 @@ var PasskeyProviderClient = class {
477
559
  };
478
560
  }
479
561
  const dialogUrl = this.getDialogUrl();
480
- const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe`;
562
+ const themeParams = this.getThemeParams();
563
+ const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
481
564
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
482
565
  const dialogOrigin = this.getDialogOrigin();
483
- await new Promise((resolve) => {
484
- const handleReady = (event) => {
485
- if (event.origin !== dialogOrigin) return;
486
- if (event.data?.type === "PASSKEY_READY") {
487
- window.removeEventListener("message", handleReady);
488
- iframe.contentWindow?.postMessage({
489
- type: "PASSKEY_INIT",
490
- mode: "iframe",
491
- calls,
492
- chainId: targetChain,
493
- transaction: prepareResponse.transaction,
494
- challenge: prepareResponse.challenge,
495
- username,
496
- accountAddress: prepareResponse.accountAddress,
497
- intentId: prepareResponse.intentId
498
- }, dialogOrigin);
499
- resolve();
500
- }
501
- };
502
- window.addEventListener("message", handleReady);
566
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
567
+ mode: "iframe",
568
+ calls,
569
+ chainId: targetChain,
570
+ transaction: prepareResponse.transaction,
571
+ challenge: prepareResponse.challenge,
572
+ username,
573
+ accountAddress: prepareResponse.accountAddress,
574
+ originMessages: prepareResponse.originMessages,
575
+ tokenRequests: serializedTokenRequests,
576
+ expiresAt: prepareResponse.expiresAt,
577
+ userId: prepareResponse.userId,
578
+ intentOp: prepareResponse.intentOp
503
579
  });
504
- const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);
580
+ if (!ready) {
581
+ return {
582
+ success: false,
583
+ intentId: "",
584
+ status: "failed",
585
+ error: { code: "USER_CANCELLED", message: "User closed the dialog" }
586
+ };
587
+ }
588
+ const signingResult = await this.waitForSigningWithRefresh(
589
+ dialog,
590
+ iframe,
591
+ cleanup,
592
+ dialogOrigin,
593
+ // Refresh callback - called when dialog requests a quote refresh
594
+ async () => {
595
+ console.log("[SDK] Dialog requested quote refresh, re-preparing intent");
596
+ try {
597
+ const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {
598
+ method: "POST",
599
+ headers: { "Content-Type": "application/json" },
600
+ body: JSON.stringify(requestBody),
601
+ credentials: "include"
602
+ });
603
+ if (!refreshResponse.ok) {
604
+ console.error("[SDK] Quote refresh failed:", await refreshResponse.text());
605
+ return null;
606
+ }
607
+ const refreshedData = await refreshResponse.json();
608
+ prepareResponse = refreshedData;
609
+ return {
610
+ intentOp: refreshedData.intentOp,
611
+ expiresAt: refreshedData.expiresAt,
612
+ challenge: refreshedData.challenge,
613
+ originMessages: refreshedData.originMessages,
614
+ transaction: refreshedData.transaction
615
+ };
616
+ } catch (error) {
617
+ console.error("[SDK] Quote refresh error:", error);
618
+ return null;
619
+ }
620
+ }
621
+ );
505
622
  if (!signingResult.success) {
506
623
  return {
507
624
  success: false,
508
- intentId: prepareResponse.intentId,
625
+ intentId: "",
626
+ // No intentId yet - signing was cancelled before execute
509
627
  status: "failed",
510
628
  error: signingResult.error
511
629
  };
512
630
  }
631
+ const dialogExecutedIntent = "intentId" in signingResult && signingResult.intentId;
513
632
  let executeResponse;
514
- try {
515
- const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {
516
- method: "POST",
517
- headers: {
518
- "Content-Type": "application/json"
519
- },
520
- body: JSON.stringify({
521
- intentId: prepareResponse.intentId,
522
- signature: signingResult.signature,
523
- passkey: signingResult.passkey
524
- // Include passkey info for signature encoding
525
- })
526
- });
527
- if (!response.ok) {
528
- const errorData = await response.json().catch(() => ({}));
633
+ if (dialogExecutedIntent) {
634
+ executeResponse = {
635
+ success: true,
636
+ intentId: signingResult.intentId,
637
+ status: "pending"
638
+ };
639
+ } else {
640
+ try {
641
+ const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {
642
+ method: "POST",
643
+ headers: {
644
+ "Content-Type": "application/json"
645
+ },
646
+ body: JSON.stringify({
647
+ // Data from prepare response (no intentId yet - created on execute)
648
+ intentOp: prepareResponse.intentOp,
649
+ userId: prepareResponse.userId,
650
+ targetChain: prepareResponse.targetChain,
651
+ calls: prepareResponse.calls,
652
+ expiresAt: prepareResponse.expiresAt,
653
+ // Signature from dialog
654
+ signature: signingResult.signature,
655
+ passkey: signingResult.passkey
656
+ // Include passkey info for signature encoding
657
+ })
658
+ });
659
+ if (!response.ok) {
660
+ const errorData = await response.json().catch(() => ({}));
661
+ this.sendTransactionStatus(iframe, "failed");
662
+ await this.waitForDialogClose(dialog, cleanup);
663
+ return {
664
+ success: false,
665
+ intentId: "",
666
+ // No intentId - execute failed before creation
667
+ status: "failed",
668
+ error: {
669
+ code: "EXECUTE_FAILED",
670
+ message: errorData.error || "Failed to execute intent"
671
+ }
672
+ };
673
+ }
674
+ executeResponse = await response.json();
675
+ } catch (error) {
529
676
  this.sendTransactionStatus(iframe, "failed");
530
677
  await this.waitForDialogClose(dialog, cleanup);
531
678
  return {
532
679
  success: false,
533
- intentId: prepareResponse.intentId,
680
+ intentId: "",
681
+ // No intentId - network error before creation
534
682
  status: "failed",
535
683
  error: {
536
- code: "EXECUTE_FAILED",
537
- message: errorData.error || "Failed to execute intent"
684
+ code: "NETWORK_ERROR",
685
+ message: error instanceof Error ? error.message : "Network error"
538
686
  }
539
687
  };
540
688
  }
541
- executeResponse = await response.json();
542
- } catch (error) {
543
- this.sendTransactionStatus(iframe, "failed");
544
- await this.waitForDialogClose(dialog, cleanup);
545
- return {
546
- success: false,
547
- intentId: prepareResponse.intentId,
548
- status: "failed",
549
- error: {
550
- code: "NETWORK_ERROR",
551
- message: error instanceof Error ? error.message : "Network error"
552
- }
553
- };
554
689
  }
555
- const closeOn = options.closeOn || "preconfirmed";
556
- const acceptPreconfirmations = closeOn !== "completed";
557
690
  let finalStatus = executeResponse.status;
558
691
  let finalTxHash = executeResponse.transactionHash;
559
692
  if (finalStatus === "pending") {
560
- this.sendTransactionStatus(iframe, "processing");
561
- try {
562
- const waitResponse = await fetch(
563
- `${this.config.providerUrl}/api/intent/wait/${prepareResponse.intentId}?preconfirm=${acceptPreconfirmations}`,
564
- {
565
- headers: {
566
- "x-client-id": this.config.clientId
693
+ this.sendTransactionStatus(iframe, "pending");
694
+ const maxAttempts = 120;
695
+ const pollIntervalMs = 1500;
696
+ let lastStatus = "pending";
697
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
698
+ try {
699
+ const statusResponse = await fetch(
700
+ `${this.config.providerUrl}/api/intent/status/${executeResponse.intentId}`,
701
+ {
702
+ method: "GET",
703
+ headers: this.config.clientId ? { "x-client-id": this.config.clientId } : {}
704
+ }
705
+ );
706
+ if (statusResponse.ok) {
707
+ const statusResult = await statusResponse.json();
708
+ finalStatus = statusResult.status;
709
+ finalTxHash = statusResult.transactionHash;
710
+ if (finalStatus !== lastStatus) {
711
+ this.sendTransactionStatus(iframe, finalStatus, finalTxHash);
712
+ lastStatus = finalStatus;
713
+ }
714
+ const closeOn2 = options.closeOn || "preconfirmed";
715
+ const successStatuses2 = {
716
+ claimed: ["claimed", "preconfirmed", "filled", "completed"],
717
+ preconfirmed: ["preconfirmed", "filled", "completed"],
718
+ filled: ["filled", "completed"],
719
+ completed: ["completed"]
720
+ };
721
+ const isTerminal = finalStatus === "failed" || finalStatus === "expired";
722
+ const isSuccess = successStatuses2[closeOn2]?.includes(finalStatus) ?? false;
723
+ if (isTerminal || isSuccess) {
724
+ break;
567
725
  }
568
726
  }
569
- );
570
- if (waitResponse.ok) {
571
- const waitResult = await waitResponse.json();
572
- finalStatus = waitResult.status === "preconfirmed" || waitResult.status === "completed" ? "completed" : waitResult.status;
573
- finalTxHash = waitResult.transactionHash;
574
- } else {
575
- console.error("Wait endpoint failed:", await waitResponse.text());
576
- }
577
- } catch (waitError) {
578
- console.error("Failed to wait for intent:", waitError);
727
+ } catch (pollError) {
728
+ console.error("Failed to poll intent status:", pollError);
729
+ }
730
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
579
731
  }
580
732
  }
581
- const displayStatus = finalStatus === "completed" ? "confirmed" : finalStatus;
733
+ const closeOn = options.closeOn || "preconfirmed";
734
+ const successStatuses = {
735
+ claimed: ["claimed", "preconfirmed", "filled", "completed"],
736
+ preconfirmed: ["preconfirmed", "filled", "completed"],
737
+ filled: ["filled", "completed"],
738
+ completed: ["completed"]
739
+ };
740
+ const isSuccessStatus = successStatuses[closeOn]?.includes(finalStatus) ?? false;
741
+ const displayStatus = isSuccessStatus ? "confirmed" : finalStatus;
582
742
  this.sendTransactionStatus(iframe, displayStatus, finalTxHash);
583
743
  await this.waitForDialogClose(dialog, cleanup);
584
744
  if (options.waitForHash && !finalTxHash) {
585
- const hash = await this.waitForTransactionHash(prepareResponse.intentId, {
745
+ const hash = await this.waitForTransactionHash(executeResponse.intentId, {
586
746
  timeoutMs: options.hashTimeoutMs,
587
747
  intervalMs: options.hashIntervalMs
588
748
  });
@@ -593,7 +753,7 @@ var PasskeyProviderClient = class {
593
753
  finalStatus = "failed";
594
754
  return {
595
755
  success: false,
596
- intentId: prepareResponse.intentId,
756
+ intentId: executeResponse.intentId,
597
757
  status: finalStatus,
598
758
  transactionHash: finalTxHash,
599
759
  operationId: executeResponse.operationId,
@@ -605,14 +765,204 @@ var PasskeyProviderClient = class {
605
765
  }
606
766
  }
607
767
  return {
608
- success: finalStatus === "completed",
609
- intentId: prepareResponse.intentId,
768
+ success: isSuccessStatus,
769
+ intentId: executeResponse.intentId,
610
770
  status: finalStatus,
611
771
  transactionHash: finalTxHash,
612
772
  operationId: executeResponse.operationId,
613
773
  error: executeResponse.error
614
774
  };
615
775
  }
776
+ /**
777
+ * Send a batch of intents for multi-chain execution with a single passkey tap.
778
+ *
779
+ * This method prepares multiple intents, shows a paginated review,
780
+ * and signs all intents with a single passkey tap via a shared merkle tree.
781
+ *
782
+ * @example
783
+ * ```typescript
784
+ * const result = await client.sendBatchIntent({
785
+ * username: 'alice',
786
+ * intents: [
787
+ * {
788
+ * targetChain: 8453, // Base
789
+ * calls: [{ to: '0x...', data: '0x...', label: 'Swap on Base' }],
790
+ * },
791
+ * {
792
+ * targetChain: 42161, // Arbitrum
793
+ * calls: [{ to: '0x...', data: '0x...', label: 'Mint on Arbitrum' }],
794
+ * },
795
+ * ],
796
+ * });
797
+ *
798
+ * if (result.success) {
799
+ * console.log(`${result.successCount} intents submitted`);
800
+ * }
801
+ * ```
802
+ */
803
+ async sendBatchIntent(options) {
804
+ if (!options.username) {
805
+ return {
806
+ success: false,
807
+ results: [],
808
+ successCount: 0,
809
+ failureCount: 0
810
+ };
811
+ }
812
+ if (!options.intents?.length) {
813
+ return {
814
+ success: false,
815
+ results: [],
816
+ successCount: 0,
817
+ failureCount: 0
818
+ };
819
+ }
820
+ const serializedIntents = options.intents.map((intent) => ({
821
+ targetChain: intent.targetChain,
822
+ calls: intent.calls,
823
+ tokenRequests: intent.tokenRequests?.map((r) => ({
824
+ token: r.token,
825
+ amount: r.amount.toString()
826
+ })),
827
+ sourceAssets: intent.sourceAssets,
828
+ sourceChainId: intent.sourceChainId
829
+ }));
830
+ const requestBody = {
831
+ username: options.username,
832
+ intents: serializedIntents,
833
+ ...this.config.clientId && { clientId: this.config.clientId }
834
+ };
835
+ let prepareResponse;
836
+ try {
837
+ const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {
838
+ method: "POST",
839
+ headers: { "Content-Type": "application/json" },
840
+ body: JSON.stringify(requestBody)
841
+ });
842
+ if (!response.ok) {
843
+ const errorData = await response.json().catch(() => ({}));
844
+ const errorMessage = errorData.error || "Failed to prepare batch intent";
845
+ if (errorMessage.includes("User not found")) {
846
+ localStorage.removeItem("1auth-user");
847
+ }
848
+ return {
849
+ success: false,
850
+ results: [],
851
+ successCount: 0,
852
+ failureCount: 0
853
+ };
854
+ }
855
+ prepareResponse = await response.json();
856
+ } catch {
857
+ return {
858
+ success: false,
859
+ results: [],
860
+ successCount: 0,
861
+ failureCount: 0
862
+ };
863
+ }
864
+ const dialogUrl = this.getDialogUrl();
865
+ const themeParams = this.getThemeParams();
866
+ const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
867
+ const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
868
+ const dialogOrigin = this.getDialogOrigin();
869
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
870
+ mode: "iframe",
871
+ batchMode: true,
872
+ batchIntents: prepareResponse.intents,
873
+ challenge: prepareResponse.challenge,
874
+ username: options.username,
875
+ accountAddress: prepareResponse.accountAddress,
876
+ userId: prepareResponse.userId,
877
+ expiresAt: prepareResponse.expiresAt
878
+ });
879
+ if (!ready) {
880
+ return {
881
+ success: false,
882
+ results: [],
883
+ successCount: 0,
884
+ failureCount: 0
885
+ };
886
+ }
887
+ const batchResult = await new Promise((resolve) => {
888
+ const handleMessage = async (event) => {
889
+ if (event.origin !== dialogOrigin) return;
890
+ const message = event.data;
891
+ if (message?.type === "PASSKEY_REFRESH_QUOTE") {
892
+ console.log("[SDK] Batch dialog requested quote refresh, re-preparing all intents");
893
+ try {
894
+ const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {
895
+ method: "POST",
896
+ headers: { "Content-Type": "application/json" },
897
+ body: JSON.stringify(requestBody)
898
+ });
899
+ if (refreshResponse.ok) {
900
+ const refreshed = await refreshResponse.json();
901
+ prepareResponse = refreshed;
902
+ iframe.contentWindow?.postMessage({
903
+ type: "PASSKEY_REFRESH_COMPLETE",
904
+ batchIntents: refreshed.intents,
905
+ challenge: refreshed.challenge,
906
+ expiresAt: refreshed.expiresAt
907
+ }, dialogOrigin);
908
+ } else {
909
+ iframe.contentWindow?.postMessage({
910
+ type: "PASSKEY_REFRESH_ERROR",
911
+ error: "Failed to refresh batch quotes"
912
+ }, dialogOrigin);
913
+ }
914
+ } catch {
915
+ iframe.contentWindow?.postMessage({
916
+ type: "PASSKEY_REFRESH_ERROR",
917
+ error: "Failed to refresh batch quotes"
918
+ }, dialogOrigin);
919
+ }
920
+ return;
921
+ }
922
+ if (message?.type === "PASSKEY_SIGNING_RESULT") {
923
+ window.removeEventListener("message", handleMessage);
924
+ if (message.success && message.data?.batchResults) {
925
+ const rawResults = message.data.batchResults;
926
+ const results = rawResults.map((r) => ({
927
+ index: r.index,
928
+ success: r.success ?? r.status !== "FAILED",
929
+ intentId: r.intentId || r.operationId || "",
930
+ status: r.status === "FAILED" ? "failed" : "pending",
931
+ error: r.error ? { code: "EXECUTE_FAILED", message: r.error } : void 0
932
+ }));
933
+ const successCount = results.filter((r) => r.success).length;
934
+ await this.waitForDialogClose(dialog, cleanup);
935
+ resolve({
936
+ success: successCount === results.length,
937
+ results,
938
+ successCount,
939
+ failureCount: results.length - successCount
940
+ });
941
+ } else {
942
+ cleanup();
943
+ resolve({
944
+ success: false,
945
+ results: [],
946
+ successCount: 0,
947
+ failureCount: 0
948
+ });
949
+ }
950
+ }
951
+ if (message?.type === "PASSKEY_CLOSE") {
952
+ window.removeEventListener("message", handleMessage);
953
+ cleanup();
954
+ resolve({
955
+ success: false,
956
+ results: [],
957
+ successCount: 0,
958
+ failureCount: 0
959
+ });
960
+ }
961
+ };
962
+ window.addEventListener("message", handleMessage);
963
+ });
964
+ return batchResult;
965
+ }
616
966
  /**
617
967
  * Send transaction status to the dialog iframe
618
968
  */
@@ -689,7 +1039,77 @@ var PasskeyProviderClient = class {
689
1039
  const payload = message?.data;
690
1040
  if (message?.type === "PASSKEY_SIGNING_RESULT") {
691
1041
  window.removeEventListener("message", handleMessage);
692
- if (message.success && payload?.signature) {
1042
+ if (message.success && payload?.intentId) {
1043
+ resolve({
1044
+ success: true,
1045
+ intentId: payload.intentId
1046
+ });
1047
+ } else if (message.success && payload?.signature) {
1048
+ resolve({
1049
+ success: true,
1050
+ signature: payload.signature,
1051
+ passkey: payload.passkey,
1052
+ signedHash: payload.signedHash
1053
+ });
1054
+ } else {
1055
+ resolve({
1056
+ success: false,
1057
+ error: message.error || {
1058
+ code: "SIGNING_FAILED",
1059
+ message: "Signing failed"
1060
+ }
1061
+ });
1062
+ }
1063
+ } else if (message?.type === "PASSKEY_CLOSE") {
1064
+ window.removeEventListener("message", handleMessage);
1065
+ cleanup();
1066
+ resolve({
1067
+ success: false,
1068
+ error: {
1069
+ code: "USER_REJECTED",
1070
+ message: "User closed the dialog"
1071
+ }
1072
+ });
1073
+ }
1074
+ };
1075
+ window.addEventListener("message", handleMessage);
1076
+ });
1077
+ }
1078
+ /**
1079
+ * Wait for signing result with auto-refresh support
1080
+ * This method handles both signing results and quote refresh requests from the dialog
1081
+ */
1082
+ waitForSigningWithRefresh(dialog, iframe, cleanup, dialogOrigin, onRefresh) {
1083
+ console.log("[SDK] waitForSigningWithRefresh, expecting origin:", dialogOrigin);
1084
+ return new Promise((resolve) => {
1085
+ const handleMessage = async (event) => {
1086
+ if (event.origin !== dialogOrigin) return;
1087
+ const message = event.data;
1088
+ if (message?.type === "PASSKEY_REFRESH_QUOTE") {
1089
+ console.log("[SDK] Received quote refresh request from dialog");
1090
+ const refreshedData = await onRefresh();
1091
+ if (refreshedData) {
1092
+ iframe.contentWindow?.postMessage({
1093
+ type: "PASSKEY_REFRESH_COMPLETE",
1094
+ ...refreshedData
1095
+ }, dialogOrigin);
1096
+ } else {
1097
+ iframe.contentWindow?.postMessage({
1098
+ type: "PASSKEY_REFRESH_ERROR",
1099
+ error: "Failed to refresh quote"
1100
+ }, dialogOrigin);
1101
+ }
1102
+ return;
1103
+ }
1104
+ const payload = message?.data;
1105
+ if (message?.type === "PASSKEY_SIGNING_RESULT") {
1106
+ window.removeEventListener("message", handleMessage);
1107
+ if (message.success && payload?.intentId) {
1108
+ resolve({
1109
+ success: true,
1110
+ intentId: payload.intentId
1111
+ });
1112
+ } else if (message.success && payload?.signature) {
693
1113
  resolve({
694
1114
  success: true,
695
1115
  signature: payload.signature,
@@ -755,9 +1175,7 @@ var PasskeyProviderClient = class {
755
1175
  const response = await fetch(
756
1176
  `${this.config.providerUrl}/api/intent/status/${intentId}`,
757
1177
  {
758
- headers: {
759
- "x-client-id": this.config.clientId
760
- }
1178
+ headers: this.config.clientId ? { "x-client-id": this.config.clientId } : {}
761
1179
  }
762
1180
  );
763
1181
  if (!response.ok) {
@@ -792,6 +1210,43 @@ var PasskeyProviderClient = class {
792
1210
  };
793
1211
  }
794
1212
  }
1213
+ /**
1214
+ * Get the history of intents for the authenticated user.
1215
+ *
1216
+ * Requires an active session (user must be logged in).
1217
+ *
1218
+ * @example
1219
+ * ```typescript
1220
+ * // Get recent intents
1221
+ * const history = await client.getIntentHistory({ limit: 10 });
1222
+ *
1223
+ * // Filter by status
1224
+ * const pending = await client.getIntentHistory({ status: 'pending' });
1225
+ *
1226
+ * // Filter by date range
1227
+ * const lastWeek = await client.getIntentHistory({
1228
+ * from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
1229
+ * });
1230
+ * ```
1231
+ */
1232
+ async getIntentHistory(options) {
1233
+ const queryParams = new URLSearchParams();
1234
+ if (options?.limit) queryParams.set("limit", String(options.limit));
1235
+ if (options?.offset) queryParams.set("offset", String(options.offset));
1236
+ if (options?.status) queryParams.set("status", options.status);
1237
+ if (options?.from) queryParams.set("from", options.from);
1238
+ if (options?.to) queryParams.set("to", options.to);
1239
+ const url = `${this.config.providerUrl}/api/intent/history${queryParams.toString() ? `?${queryParams}` : ""}`;
1240
+ const response = await fetch(url, {
1241
+ headers: this.config.clientId ? { "x-client-id": this.config.clientId } : {},
1242
+ credentials: "include"
1243
+ });
1244
+ if (!response.ok) {
1245
+ const errorData = await response.json().catch(() => ({}));
1246
+ throw new Error(errorData.error || "Failed to get intent history");
1247
+ }
1248
+ return response.json();
1249
+ }
795
1250
  /**
796
1251
  * Send a swap intent through the Rhinestone orchestrator
797
1252
  *
@@ -854,17 +1309,21 @@ var PasskeyProviderClient = class {
854
1309
  };
855
1310
  }
856
1311
  };
857
- const fromTokenResult = resolveToken(options.fromToken, "fromToken");
858
- if (!fromTokenResult.address) {
859
- return {
860
- success: false,
861
- intentId: "",
862
- status: "failed",
863
- error: {
864
- code: "INVALID_TOKEN",
865
- message: fromTokenResult.error || `Unknown fromToken: ${options.fromToken}`
866
- }
867
- };
1312
+ let fromTokenAddress;
1313
+ if (options.fromToken) {
1314
+ const fromTokenResult = resolveToken(options.fromToken, "fromToken");
1315
+ if (!fromTokenResult.address) {
1316
+ return {
1317
+ success: false,
1318
+ intentId: "",
1319
+ status: "failed",
1320
+ error: {
1321
+ code: "INVALID_TOKEN",
1322
+ message: fromTokenResult.error || `Unknown fromToken: ${options.fromToken}`
1323
+ }
1324
+ };
1325
+ }
1326
+ fromTokenAddress = fromTokenResult.address;
868
1327
  }
869
1328
  const toTokenResult = resolveToken(options.toToken, "toToken");
870
1329
  if (!toTokenResult.address) {
@@ -878,18 +1337,17 @@ var PasskeyProviderClient = class {
878
1337
  }
879
1338
  };
880
1339
  }
881
- const fromTokenAddress = fromTokenResult.address;
882
1340
  const toTokenAddress = toTokenResult.address;
883
1341
  console.log("[SDK sendSwap] Token resolution:", {
884
- fromToken: options.fromToken,
885
- fromTokenAddress,
1342
+ fromToken: options.fromToken ?? "Any",
1343
+ fromTokenAddress: fromTokenAddress ?? "orchestrator picks",
886
1344
  toToken: options.toToken,
887
1345
  toTokenAddress,
888
1346
  targetChain: options.targetChain
889
1347
  });
890
1348
  const formatTokenLabel = (token, fallback) => {
891
1349
  if (!token.startsWith("0x")) {
892
- return token.toUpperCase();
1350
+ return token;
893
1351
  }
894
1352
  try {
895
1353
  return getTokenSymbol(token, options.targetChain);
@@ -897,15 +1355,11 @@ var PasskeyProviderClient = class {
897
1355
  return fallback;
898
1356
  }
899
1357
  };
900
- const fromSymbol = formatTokenLabel(
901
- options.fromToken,
902
- `${options.fromToken.slice(0, 6)}...${options.fromToken.slice(-4)}`
903
- );
904
1358
  const toSymbol = formatTokenLabel(
905
1359
  options.toToken,
906
1360
  `${options.toToken.slice(0, 6)}...${options.toToken.slice(-4)}`
907
1361
  );
908
- const isFromNativeEth = fromTokenAddress === "0x0000000000000000000000000000000000000000";
1362
+ const isFromNativeEth = fromTokenAddress ? fromTokenAddress === "0x0000000000000000000000000000000000000000" : false;
909
1363
  const isToNativeEth = toTokenAddress === "0x0000000000000000000000000000000000000000";
910
1364
  const KNOWN_DECIMALS = {
911
1365
  ETH: 18,
@@ -915,31 +1369,33 @@ var PasskeyProviderClient = class {
915
1369
  USDT0: 6
916
1370
  };
917
1371
  const getDecimals = (symbol, chainId) => {
918
- const upperSymbol = symbol.toUpperCase();
919
1372
  try {
920
- const decimals = (0, import_sdk.getTokenDecimals)(upperSymbol, chainId);
921
- console.log(`[SDK] getTokenDecimals(${upperSymbol}, ${chainId}) = ${decimals}`);
1373
+ const match = getSupportedTokens(chainId).find(
1374
+ (t) => t.symbol.toUpperCase() === symbol.toUpperCase()
1375
+ );
1376
+ if (match) {
1377
+ console.log(`[SDK] getTokenDecimals(${match.symbol}, ${chainId}) = ${match.decimals}`);
1378
+ return match.decimals;
1379
+ }
1380
+ const decimals = (0, import_sdk.getTokenDecimals)(symbol, chainId);
1381
+ console.log(`[SDK] getTokenDecimals(${symbol}, ${chainId}) = ${decimals}`);
922
1382
  return decimals;
923
1383
  } catch (e) {
924
- console.warn(`[SDK] getTokenDecimals failed for ${upperSymbol}, using fallback`, e);
1384
+ const upperSymbol = symbol.toUpperCase();
1385
+ console.warn(`[SDK] getTokenDecimals failed for ${symbol}, using fallback`, e);
925
1386
  return KNOWN_DECIMALS[upperSymbol] ?? 18;
926
1387
  }
927
1388
  };
928
- const fromDecimals = getDecimals(options.fromToken, options.targetChain);
929
1389
  const toDecimals = getDecimals(options.toToken, options.targetChain);
930
- const isBridge = options.fromToken.toUpperCase() === options.toToken.toUpperCase();
931
- let tokenRequests;
932
- if (!isToNativeEth) {
933
- tokenRequests = [{
934
- token: toTokenAddress,
935
- amount: (0, import_viem2.parseUnits)(options.amount, toDecimals).toString()
936
- }];
937
- }
1390
+ const isBridge = options.fromToken ? options.fromToken.toUpperCase() === options.toToken.toUpperCase() : false;
1391
+ const tokenRequests = [{
1392
+ token: toTokenAddress,
1393
+ amount: (0, import_viem2.parseUnits)(options.amount, toDecimals)
1394
+ }];
938
1395
  console.log("[SDK sendSwap] Building intent:", {
939
1396
  isBridge,
940
1397
  isFromNativeEth,
941
1398
  isToNativeEth,
942
- fromDecimals,
943
1399
  toDecimals,
944
1400
  tokenRequests
945
1401
  });
@@ -950,15 +1406,20 @@ var PasskeyProviderClient = class {
950
1406
  {
951
1407
  // Minimal call - just signals to orchestrator we want the tokenRequests delivered
952
1408
  to: toTokenAddress,
953
- value: "0"
1409
+ value: "0",
1410
+ // SDK provides labels so dialog shows "Buy ETH" not "Send ETH / To: 0x000..."
1411
+ label: `Buy ${toSymbol}`,
1412
+ sublabel: `${options.amount} ${toSymbol}`
954
1413
  }
955
1414
  ],
956
1415
  // Request specific output tokens - this is what actually matters for swaps
957
1416
  tokenRequests,
958
1417
  // Constrain orchestrator to use only the fromToken as input
959
1418
  // This ensures the swap uses the correct source token
960
- // Pass the symbol (not address) so orchestrator can resolve per-chain
961
- sourceAssets: options.sourceAssets || [options.fromToken.toUpperCase()],
1419
+ // Use canonical symbol casing from registry (e.g. "MockUSD" not "MOCKUSD")
1420
+ sourceAssets: options.sourceAssets || (options.fromToken ? [options.fromToken] : void 0),
1421
+ // Pass source chain ID so orchestrator knows which chain to look for tokens on
1422
+ sourceChainId: options.sourceChainId,
962
1423
  closeOn: options.closeOn || "preconfirmed",
963
1424
  waitForHash: options.waitForHash,
964
1425
  hashTimeoutMs: options.hashTimeoutMs,
@@ -967,7 +1428,7 @@ var PasskeyProviderClient = class {
967
1428
  return {
968
1429
  ...result,
969
1430
  quote: result.success ? {
970
- fromToken: fromTokenAddress,
1431
+ fromToken: fromTokenAddress ?? options.fromToken,
971
1432
  toToken: toTokenAddress,
972
1433
  amountIn: options.amount,
973
1434
  amountOut: "",
@@ -1009,26 +1470,23 @@ var PasskeyProviderClient = class {
1009
1470
  const themeParams = this.getThemeParams(options?.theme);
1010
1471
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
1011
1472
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
1012
- const dialogOrigin = this.getDialogOrigin();
1013
- await new Promise((resolve) => {
1014
- const handleReady = (event) => {
1015
- if (event.origin !== dialogOrigin) return;
1016
- if (event.data?.type === "PASSKEY_READY") {
1017
- window.removeEventListener("message", handleReady);
1018
- iframe.contentWindow?.postMessage({
1019
- type: "PASSKEY_INIT",
1020
- mode: "iframe",
1021
- message: options.message,
1022
- challenge: options.challenge || options.message,
1023
- username: options.username,
1024
- description: options.description,
1025
- metadata: options.metadata
1026
- }, dialogOrigin);
1027
- resolve();
1473
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
1474
+ mode: "iframe",
1475
+ message: options.message,
1476
+ challenge: options.challenge || options.message,
1477
+ username: options.username,
1478
+ description: options.description,
1479
+ metadata: options.metadata
1480
+ });
1481
+ if (!ready) {
1482
+ return {
1483
+ success: false,
1484
+ error: {
1485
+ code: "USER_REJECTED",
1486
+ message: "User closed the dialog"
1028
1487
  }
1029
1488
  };
1030
- window.addEventListener("message", handleReady);
1031
- });
1489
+ }
1032
1490
  const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);
1033
1491
  cleanup();
1034
1492
  if (signingResult.success) {
@@ -1097,31 +1555,28 @@ var PasskeyProviderClient = class {
1097
1555
  const themeParams = this.getThemeParams(options?.theme);
1098
1556
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
1099
1557
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
1100
- const dialogOrigin = this.getDialogOrigin();
1101
- await new Promise((resolve) => {
1102
- const handleReady = (event) => {
1103
- if (event.origin !== dialogOrigin) return;
1104
- if (event.data?.type === "PASSKEY_READY") {
1105
- window.removeEventListener("message", handleReady);
1106
- iframe.contentWindow?.postMessage({
1107
- type: "PASSKEY_INIT",
1108
- mode: "iframe",
1109
- signingMode: "typedData",
1110
- typedData: {
1111
- domain: options.domain,
1112
- types: options.types,
1113
- primaryType: options.primaryType,
1114
- message: options.message
1115
- },
1116
- challenge: signedHash,
1117
- username: options.username,
1118
- description: options.description
1119
- }, dialogOrigin);
1120
- resolve();
1558
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
1559
+ mode: "iframe",
1560
+ signingMode: "typedData",
1561
+ typedData: {
1562
+ domain: options.domain,
1563
+ types: options.types,
1564
+ primaryType: options.primaryType,
1565
+ message: options.message
1566
+ },
1567
+ challenge: signedHash,
1568
+ username: options.username,
1569
+ description: options.description
1570
+ });
1571
+ if (!ready) {
1572
+ return {
1573
+ success: false,
1574
+ error: {
1575
+ code: "USER_REJECTED",
1576
+ message: "User closed the dialog"
1121
1577
  }
1122
1578
  };
1123
- window.addEventListener("message", handleReady);
1124
- });
1579
+ }
1125
1580
  const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);
1126
1581
  cleanup();
1127
1582
  if (signingResult.success) {
@@ -1275,9 +1730,7 @@ var PasskeyProviderClient = class {
1275
1730
  const response = await fetch(
1276
1731
  `${this.config.providerUrl}/api/users/${encodeURIComponent(username)}/passkeys`,
1277
1732
  {
1278
- headers: {
1279
- "x-client-id": this.config.clientId
1280
- }
1733
+ headers: this.config.clientId ? { "x-client-id": this.config.clientId } : {}
1281
1734
  }
1282
1735
  );
1283
1736
  if (!response.ok) {
@@ -1296,7 +1749,7 @@ var PasskeyProviderClient = class {
1296
1749
  "Content-Type": "application/json"
1297
1750
  },
1298
1751
  body: JSON.stringify({
1299
- clientId: this.config.clientId,
1752
+ ...this.config.clientId && { clientId: this.config.clientId },
1300
1753
  username: options.username,
1301
1754
  challenge: options.challenge,
1302
1755
  description: options.description,
@@ -1323,7 +1776,45 @@ var PasskeyProviderClient = class {
1323
1776
  );
1324
1777
  }
1325
1778
  /**
1326
- * Create a modal dialog with an iframe inside (Porto-style overlay)
1779
+ * Wait for the dialog iframe to signal ready, then send init data.
1780
+ * Also handles early close (X button, escape, backdrop) during the ready phase.
1781
+ * Returns true if dialog is ready, false if it was closed before becoming ready.
1782
+ */
1783
+ waitForDialogReady(dialog, iframe, cleanup, initMessage) {
1784
+ const dialogOrigin = this.getDialogOrigin();
1785
+ return new Promise((resolve) => {
1786
+ let settled = false;
1787
+ const teardown = () => {
1788
+ if (settled) return;
1789
+ settled = true;
1790
+ window.removeEventListener("message", handleMessage);
1791
+ dialog.removeEventListener("close", handleClose);
1792
+ };
1793
+ const handleMessage = (event) => {
1794
+ if (event.origin !== dialogOrigin) return;
1795
+ if (event.data?.type === "PASSKEY_READY") {
1796
+ teardown();
1797
+ iframe.contentWindow?.postMessage({
1798
+ type: "PASSKEY_INIT",
1799
+ ...initMessage
1800
+ }, dialogOrigin);
1801
+ resolve(true);
1802
+ } else if (event.data?.type === "PASSKEY_CLOSE") {
1803
+ teardown();
1804
+ cleanup();
1805
+ resolve(false);
1806
+ }
1807
+ };
1808
+ const handleClose = () => {
1809
+ teardown();
1810
+ resolve(false);
1811
+ };
1812
+ window.addEventListener("message", handleMessage);
1813
+ dialog.addEventListener("close", handleClose);
1814
+ });
1815
+ }
1816
+ /**
1817
+ * Create a modal dialog with an iframe inside.
1327
1818
  */
1328
1819
  createModalDialog(url) {
1329
1820
  const dialogUrl = this.getDialogUrl();
@@ -1466,12 +1957,24 @@ var PasskeyProviderClient = class {
1466
1957
  };
1467
1958
  return { dialog, iframe, cleanup };
1468
1959
  }
1469
- waitForModalAuthResponse(_dialog, _iframe, cleanup) {
1960
+ waitForModalAuthResponse(_dialog, iframe, cleanup) {
1470
1961
  const dialogOrigin = this.getDialogOrigin();
1471
1962
  return new Promise((resolve) => {
1963
+ let dialogReady = false;
1472
1964
  const handleMessage = (event) => {
1473
1965
  if (event.origin !== dialogOrigin) return;
1474
1966
  const data = event.data;
1967
+ if (data?.type === "PASSKEY_READY") {
1968
+ dialogReady = true;
1969
+ iframe.contentWindow?.postMessage({
1970
+ type: "PASSKEY_INIT",
1971
+ mode: "iframe"
1972
+ }, dialogOrigin);
1973
+ return;
1974
+ }
1975
+ if (!dialogReady && data?.type === "PASSKEY_CLOSE") {
1976
+ return;
1977
+ }
1475
1978
  if (data?.type === "PASSKEY_LOGIN_RESULT") {
1476
1979
  window.removeEventListener("message", handleMessage);
1477
1980
  cleanup();
@@ -1501,6 +2004,11 @@ var PasskeyProviderClient = class {
1501
2004
  error: data.error
1502
2005
  });
1503
2006
  }
2007
+ } else if (data?.type === "PASSKEY_RETRY_POPUP") {
2008
+ window.removeEventListener("message", handleMessage);
2009
+ cleanup();
2010
+ const popupUrl = data.data?.url?.replace("mode=iframe", "mode=popup") || `${this.getDialogUrl()}/dialog/auth?mode=popup${this.config.clientId ? `&clientId=${this.config.clientId}` : ""}`;
2011
+ this.waitForPopupAuthResponse(popupUrl).then(resolve);
1504
2012
  } else if (data?.type === "PASSKEY_CLOSE") {
1505
2013
  window.removeEventListener("message", handleMessage);
1506
2014
  cleanup();
@@ -1516,6 +2024,77 @@ var PasskeyProviderClient = class {
1516
2024
  window.addEventListener("message", handleMessage);
1517
2025
  });
1518
2026
  }
2027
+ /**
2028
+ * Open a popup for auth and wait for the result.
2029
+ * Used when iframe mode fails (e.g., due to password manager interference).
2030
+ */
2031
+ waitForPopupAuthResponse(url) {
2032
+ const dialogOrigin = this.getDialogOrigin();
2033
+ const popup = this.openPopup(url);
2034
+ return new Promise((resolve) => {
2035
+ const pollTimer = setInterval(() => {
2036
+ if (popup?.closed) {
2037
+ clearInterval(pollTimer);
2038
+ window.removeEventListener("message", handleMessage);
2039
+ resolve({
2040
+ success: false,
2041
+ error: {
2042
+ code: "USER_CANCELLED",
2043
+ message: "Authentication was cancelled"
2044
+ }
2045
+ });
2046
+ }
2047
+ }, 500);
2048
+ const handleMessage = (event) => {
2049
+ if (event.origin !== dialogOrigin) return;
2050
+ const data = event.data;
2051
+ if (data?.type === "PASSKEY_LOGIN_RESULT") {
2052
+ clearInterval(pollTimer);
2053
+ window.removeEventListener("message", handleMessage);
2054
+ popup?.close();
2055
+ if (data.success) {
2056
+ resolve({
2057
+ success: true,
2058
+ username: data.data?.username,
2059
+ user: data.data?.user
2060
+ });
2061
+ } else {
2062
+ resolve({
2063
+ success: false,
2064
+ error: data.error
2065
+ });
2066
+ }
2067
+ } else if (data?.type === "PASSKEY_REGISTER_RESULT") {
2068
+ clearInterval(pollTimer);
2069
+ window.removeEventListener("message", handleMessage);
2070
+ popup?.close();
2071
+ if (data.success) {
2072
+ resolve({
2073
+ success: true,
2074
+ username: data.data?.username
2075
+ });
2076
+ } else {
2077
+ resolve({
2078
+ success: false,
2079
+ error: data.error
2080
+ });
2081
+ }
2082
+ } else if (data?.type === "PASSKEY_CLOSE") {
2083
+ clearInterval(pollTimer);
2084
+ window.removeEventListener("message", handleMessage);
2085
+ popup?.close();
2086
+ resolve({
2087
+ success: false,
2088
+ error: {
2089
+ code: "USER_CANCELLED",
2090
+ message: "Authentication was cancelled"
2091
+ }
2092
+ });
2093
+ }
2094
+ };
2095
+ window.addEventListener("message", handleMessage);
2096
+ });
2097
+ }
1519
2098
  waitForAuthenticateResponse(_dialog, _iframe, cleanup) {
1520
2099
  const dialogOrigin = this.getDialogOrigin();
1521
2100
  return new Promise((resolve) => {
@@ -1555,6 +2134,44 @@ var PasskeyProviderClient = class {
1555
2134
  window.addEventListener("message", handleMessage);
1556
2135
  });
1557
2136
  }
2137
+ waitForConnectResponse(_dialog, _iframe, cleanup) {
2138
+ const dialogOrigin = this.getDialogOrigin();
2139
+ return new Promise((resolve) => {
2140
+ const handleMessage = (event) => {
2141
+ if (event.origin !== dialogOrigin) return;
2142
+ const data = event.data;
2143
+ if (data?.type === "PASSKEY_CONNECT_RESULT") {
2144
+ window.removeEventListener("message", handleMessage);
2145
+ cleanup();
2146
+ if (data.success) {
2147
+ resolve({
2148
+ success: true,
2149
+ username: data.data?.username,
2150
+ autoConnected: data.data?.autoConnected
2151
+ });
2152
+ } else {
2153
+ resolve({
2154
+ success: false,
2155
+ action: data.data?.action,
2156
+ error: data.error
2157
+ });
2158
+ }
2159
+ } else if (data?.type === "PASSKEY_CLOSE") {
2160
+ window.removeEventListener("message", handleMessage);
2161
+ cleanup();
2162
+ resolve({
2163
+ success: false,
2164
+ action: "cancel",
2165
+ error: {
2166
+ code: "USER_CANCELLED",
2167
+ message: "Connection was cancelled"
2168
+ }
2169
+ });
2170
+ }
2171
+ };
2172
+ window.addEventListener("message", handleMessage);
2173
+ });
2174
+ }
1558
2175
  waitForModalSigningResponse(requestId, _dialog, _iframe, cleanup) {
1559
2176
  const dialogOrigin = this.getDialogOrigin();
1560
2177
  return new Promise((resolve) => {
@@ -1643,9 +2260,7 @@ var PasskeyProviderClient = class {
1643
2260
  const response = await fetch(
1644
2261
  `${this.config.providerUrl}/api/sign/request/${requestId}`,
1645
2262
  {
1646
- headers: {
1647
- "x-client-id": this.config.clientId
1648
- }
2263
+ headers: this.config.clientId ? { "x-client-id": this.config.clientId } : {}
1649
2264
  }
1650
2265
  );
1651
2266
  if (!response.ok) {
@@ -1749,7 +2364,7 @@ function buildTransactionReview(calls) {
1749
2364
 
1750
2365
  // src/provider.ts
1751
2366
  var DEFAULT_STORAGE_KEY = "1auth-user";
1752
- function createPasskeyProvider(options) {
2367
+ function createOneAuthProvider(options) {
1753
2368
  const { client } = options;
1754
2369
  let chainId = options.chainId;
1755
2370
  const storageKey = options.storageKey || DEFAULT_STORAGE_KEY;
@@ -1780,12 +2395,11 @@ function createPasskeyProvider(options) {
1780
2395
  localStorage.removeItem(storageKey);
1781
2396
  };
1782
2397
  const resolveAccountAddress = async (username) => {
2398
+ const clientId = client.getClientId();
1783
2399
  const response = await fetch(
1784
2400
  `${client.getProviderUrl()}/api/users/${encodeURIComponent(username)}/account`,
1785
2401
  {
1786
- headers: {
1787
- "x-client-id": client.getClientId()
1788
- }
2402
+ headers: clientId ? { "x-client-id": clientId } : {}
1789
2403
  }
1790
2404
  );
1791
2405
  if (!response.ok) {
@@ -1800,12 +2414,21 @@ function createPasskeyProvider(options) {
1800
2414
  if (stored) {
1801
2415
  return [stored.address];
1802
2416
  }
1803
- const result = await client.authWithModal();
1804
- if (!result.success || !result.username) {
1805
- throw new Error(result.error?.message || "Authentication failed");
2417
+ const connectResult = await client.connectWithModal();
2418
+ let username;
2419
+ if (connectResult.success && connectResult.username) {
2420
+ username = connectResult.username;
2421
+ } else if (connectResult.action === "switch") {
2422
+ const authResult = await client.authWithModal();
2423
+ if (!authResult.success || !authResult.username) {
2424
+ throw new Error(authResult.error?.message || "Authentication failed");
2425
+ }
2426
+ username = authResult.username;
2427
+ } else {
2428
+ throw new Error(connectResult.error?.message || "Connection cancelled");
1806
2429
  }
1807
- const address = await resolveAccountAddress(result.username);
1808
- setStoredUser({ username: result.username, address });
2430
+ const address = await resolveAccountAddress(username);
2431
+ setStoredUser({ username, address });
1809
2432
  emit("accountsChanged", [address]);
1810
2433
  emit("connect", { chainId: (0, import_viem4.numberToHex)(chainId) });
1811
2434
  return [address];
@@ -1862,6 +2485,16 @@ function createPasskeyProvider(options) {
1862
2485
  };
1863
2486
  });
1864
2487
  };
2488
+ const normalizeTokenRequests = (requests) => {
2489
+ if (!Array.isArray(requests)) return void 0;
2490
+ return requests.map((r) => {
2491
+ const req = r;
2492
+ return {
2493
+ token: req.token,
2494
+ amount: typeof req.amount === "bigint" ? req.amount : BigInt(String(req.amount || "0"))
2495
+ };
2496
+ });
2497
+ };
1865
2498
  const decodeMessage = (value) => {
1866
2499
  if (!(0, import_viem4.isHex)(value)) return value;
1867
2500
  try {
@@ -1896,19 +2529,40 @@ function createPasskeyProvider(options) {
1896
2529
  }
1897
2530
  return encodeWebAuthnSignature(result.signature);
1898
2531
  };
2532
+ const resolveIntentPayload = async (payload) => {
2533
+ if (!options.signIntent) {
2534
+ return {
2535
+ username: payload.username,
2536
+ targetChain: payload.targetChain,
2537
+ calls: payload.calls,
2538
+ tokenRequests: payload.tokenRequests
2539
+ };
2540
+ }
2541
+ const signedIntent = await options.signIntent({
2542
+ username: payload.username,
2543
+ accountAddress: payload.accountAddress,
2544
+ targetChain: payload.targetChain,
2545
+ calls: payload.calls,
2546
+ tokenRequests: payload.tokenRequests
2547
+ });
2548
+ return { signedIntent };
2549
+ };
1899
2550
  const sendIntent = async (payload) => {
1900
- const closeOn = options.waitForHash ?? true ? "completed" : "preconfirmed";
2551
+ const closeOn = options.closeOn ?? (options.waitForHash ?? true ? "completed" : "preconfirmed");
2552
+ const intentPayload = await resolveIntentPayload(payload);
1901
2553
  const result = await client.sendIntent({
1902
- ...payload,
2554
+ ...intentPayload,
2555
+ tokenRequests: payload.tokenRequests,
2556
+ sourceChainId: payload.sourceChainId,
1903
2557
  closeOn,
1904
2558
  waitForHash: options.waitForHash ?? true,
1905
2559
  hashTimeoutMs: options.hashTimeoutMs,
1906
2560
  hashIntervalMs: options.hashIntervalMs
1907
2561
  });
1908
- if (!result.success || !result.transactionHash) {
2562
+ if (!result.success) {
1909
2563
  throw new Error(result.error?.message || "Transaction failed");
1910
2564
  }
1911
- return result.transactionHash;
2565
+ return result.intentId;
1912
2566
  };
1913
2567
  const request = async ({ method, params }) => {
1914
2568
  switch (method) {
@@ -1961,10 +2615,15 @@ function createPasskeyProvider(options) {
1961
2615
  const user = await ensureUser();
1962
2616
  const targetChain = parseChainId(tx.chainId) ?? chainId;
1963
2617
  const calls = normalizeCalls([tx]);
2618
+ const tokenRequests = normalizeTokenRequests(tx.tokenRequests);
2619
+ const txSourceChainId = parseChainId(tx.sourceChainId);
1964
2620
  return sendIntent({
1965
2621
  username: user.username,
2622
+ accountAddress: user.address,
1966
2623
  targetChain,
1967
- calls
2624
+ calls,
2625
+ tokenRequests,
2626
+ sourceChainId: txSourceChainId
1968
2627
  });
1969
2628
  }
1970
2629
  case "wallet_sendCalls": {
@@ -1973,21 +2632,128 @@ function createPasskeyProvider(options) {
1973
2632
  const user = await ensureUser();
1974
2633
  const targetChain = parseChainId(payload.chainId) ?? chainId;
1975
2634
  const calls = normalizeCalls(payload.calls || []);
2635
+ const tokenRequests = normalizeTokenRequests(payload.tokenRequests);
2636
+ const sourceChainId = parseChainId(payload.sourceChainId);
1976
2637
  if (!calls.length) throw new Error("No calls provided");
1977
2638
  return sendIntent({
1978
2639
  username: user.username,
2640
+ accountAddress: user.address,
1979
2641
  targetChain,
1980
- calls
2642
+ calls,
2643
+ tokenRequests,
2644
+ sourceChainId
1981
2645
  });
1982
2646
  }
1983
2647
  case "wallet_getCapabilities": {
2648
+ const paramList = Array.isArray(params) ? params : [];
2649
+ const requestedChains = paramList[1];
1984
2650
  const chainIds = getSupportedChainIds();
1985
- const tokensByChain = Object.fromEntries(
1986
- chainIds.map((id) => [id, getSupportedTokens(id)])
2651
+ const capabilities = {};
2652
+ for (const chainId2 of chainIds) {
2653
+ const hexChainId = `0x${chainId2.toString(16)}`;
2654
+ if (requestedChains && !requestedChains.includes(hexChainId)) {
2655
+ continue;
2656
+ }
2657
+ capabilities[hexChainId] = {
2658
+ atomic: { status: "supported" },
2659
+ paymasterService: { supported: true },
2660
+ auxiliaryFunds: { supported: true }
2661
+ };
2662
+ }
2663
+ return capabilities;
2664
+ }
2665
+ case "wallet_getAssets": {
2666
+ const { username } = await ensureUser();
2667
+ const clientId = client.getClientId();
2668
+ const response = await fetch(
2669
+ `${client.getProviderUrl()}/api/users/${encodeURIComponent(username)}/portfolio`,
2670
+ {
2671
+ headers: clientId ? { "x-client-id": clientId } : {}
2672
+ }
1987
2673
  );
2674
+ if (!response.ok) {
2675
+ const data = await response.json().catch(() => ({}));
2676
+ throw new Error(data.error || "Failed to get assets");
2677
+ }
2678
+ return response.json();
2679
+ }
2680
+ case "wallet_getCallsStatus": {
2681
+ const paramList = Array.isArray(params) ? params : [];
2682
+ const callsId = paramList[0];
2683
+ if (!callsId) {
2684
+ throw new Error("callsId is required");
2685
+ }
2686
+ const statusClientId = client.getClientId();
2687
+ const response = await fetch(
2688
+ `${client.getProviderUrl()}/api/intent/status/${encodeURIComponent(callsId)}`,
2689
+ {
2690
+ headers: statusClientId ? { "x-client-id": statusClientId } : {}
2691
+ }
2692
+ );
2693
+ if (!response.ok) {
2694
+ const data2 = await response.json().catch(() => ({}));
2695
+ throw new Error(data2.error || "Failed to get calls status");
2696
+ }
2697
+ const data = await response.json();
2698
+ const statusMap = {
2699
+ pending: "PENDING",
2700
+ preconfirmed: "PENDING",
2701
+ completed: "CONFIRMED",
2702
+ failed: "CONFIRMED",
2703
+ expired: "CONFIRMED"
2704
+ };
1988
2705
  return {
1989
- chains: chainIds,
1990
- tokens: tokensByChain
2706
+ status: statusMap[data.status] || "PENDING",
2707
+ receipts: data.transactionHash ? [
2708
+ {
2709
+ logs: [],
2710
+ status: data.status === "completed" ? "0x1" : "0x0",
2711
+ blockHash: data.blockHash,
2712
+ blockNumber: data.blockNumber,
2713
+ transactionHash: data.transactionHash
2714
+ }
2715
+ ] : []
2716
+ };
2717
+ }
2718
+ case "wallet_getCallsHistory": {
2719
+ const paramList = Array.isArray(params) ? params : [];
2720
+ const options2 = paramList[0] || {};
2721
+ const queryParams = new URLSearchParams();
2722
+ if (options2.limit) queryParams.set("limit", String(options2.limit));
2723
+ if (options2.offset) queryParams.set("offset", String(options2.offset));
2724
+ if (options2.status) queryParams.set("status", options2.status);
2725
+ if (options2.from) queryParams.set("from", options2.from);
2726
+ if (options2.to) queryParams.set("to", options2.to);
2727
+ const url = `${client.getProviderUrl()}/api/intent/history${queryParams.toString() ? `?${queryParams}` : ""}`;
2728
+ const historyClientId = client.getClientId();
2729
+ const response = await fetch(url, {
2730
+ headers: historyClientId ? { "x-client-id": historyClientId } : {},
2731
+ credentials: "include"
2732
+ });
2733
+ if (!response.ok) {
2734
+ const data2 = await response.json().catch(() => ({}));
2735
+ throw new Error(data2.error || "Failed to get calls history");
2736
+ }
2737
+ const data = await response.json();
2738
+ const statusMap = {
2739
+ pending: "PENDING",
2740
+ preconfirmed: "PENDING",
2741
+ completed: "CONFIRMED",
2742
+ failed: "CONFIRMED",
2743
+ expired: "CONFIRMED"
2744
+ };
2745
+ return {
2746
+ calls: data.intents.map(
2747
+ (intent) => ({
2748
+ callsId: intent.intentId,
2749
+ // intentId is the orchestrator's ID
2750
+ status: statusMap[intent.status] || "PENDING",
2751
+ receipts: intent.transactionHash ? [{ transactionHash: intent.transactionHash }] : [],
2752
+ chainId: `0x${intent.targetChain.toString(16)}`
2753
+ })
2754
+ ),
2755
+ total: data.total,
2756
+ hasMore: data.hasMore
1991
2757
  };
1992
2758
  }
1993
2759
  default:
@@ -2010,6 +2776,7 @@ function createPasskeyProvider(options) {
2010
2776
  disconnect
2011
2777
  };
2012
2778
  }
2779
+ var createPasskeyProvider = createOneAuthProvider;
2013
2780
 
2014
2781
  // src/account.ts
2015
2782
  var import_viem5 = require("viem");
@@ -2088,7 +2855,7 @@ function createPasskeyAccount(client, params) {
2088
2855
  var import_viem6 = require("viem");
2089
2856
  var import_accounts2 = require("viem/accounts");
2090
2857
  function createPasskeyWalletClient(config) {
2091
- const provider = new PasskeyProviderClient({
2858
+ const provider = new OneAuthClient({
2092
2859
  providerUrl: config.providerUrl,
2093
2860
  clientId: config.clientId,
2094
2861
  dialogUrl: config.dialogUrl
@@ -2112,6 +2879,9 @@ function createPasskeyWalletClient(config) {
2112
2879
  if (!result.success) {
2113
2880
  throw new Error(result.error?.message || "Signing failed");
2114
2881
  }
2882
+ if (!result.signature) {
2883
+ throw new Error("No signature received");
2884
+ }
2115
2885
  return encodeWebAuthnSignature(result.signature);
2116
2886
  };
2117
2887
  const signTransactionImpl = async (transaction) => {
@@ -2132,6 +2902,9 @@ function createPasskeyWalletClient(config) {
2132
2902
  if (!result.success) {
2133
2903
  throw new Error(result.error?.message || "Signing failed");
2134
2904
  }
2905
+ if (!result.signature) {
2906
+ throw new Error("No signature received");
2907
+ }
2135
2908
  return encodeWebAuthnSignature(result.signature);
2136
2909
  };
2137
2910
  const signTypedDataImpl = async (typedData) => {
@@ -2153,8 +2926,35 @@ function createPasskeyWalletClient(config) {
2153
2926
  if (!result.success) {
2154
2927
  throw new Error(result.error?.message || "Signing failed");
2155
2928
  }
2929
+ if (!result.signature) {
2930
+ throw new Error("No signature received");
2931
+ }
2156
2932
  return encodeWebAuthnSignature(result.signature);
2157
2933
  };
2934
+ const buildIntentPayload = async (calls, targetChainOverride) => {
2935
+ const targetChain = targetChainOverride ?? config.chain.id;
2936
+ const intentCalls = calls.map((call) => ({
2937
+ to: call.to,
2938
+ data: call.data || "0x",
2939
+ value: call.value !== void 0 ? call.value.toString() : "0",
2940
+ label: call.label,
2941
+ sublabel: call.sublabel
2942
+ }));
2943
+ if (config.signIntent) {
2944
+ const signedIntent = await config.signIntent({
2945
+ username: config.username,
2946
+ accountAddress: config.accountAddress,
2947
+ targetChain,
2948
+ calls: intentCalls
2949
+ });
2950
+ return { signedIntent };
2951
+ }
2952
+ return {
2953
+ username: config.username,
2954
+ targetChain,
2955
+ calls: intentCalls
2956
+ };
2957
+ };
2158
2958
  const account = (0, import_accounts2.toAccount)({
2159
2959
  address: config.accountAddress,
2160
2960
  signMessage: ({ message }) => signMessageImpl(message),
@@ -2171,24 +2971,18 @@ function createPasskeyWalletClient(config) {
2171
2971
  * Send a single transaction via intent flow
2172
2972
  */
2173
2973
  async sendTransaction(transaction) {
2974
+ const targetChain = typeof transaction.chainId === "number" ? transaction.chainId : transaction.chain?.id;
2174
2975
  const calls = [
2175
2976
  {
2176
2977
  to: transaction.to,
2177
- data: transaction.data,
2978
+ data: transaction.data || "0x",
2178
2979
  value: transaction.value
2179
2980
  }
2180
2981
  ];
2181
2982
  const closeOn = config.waitForHash ?? true ? "completed" : "preconfirmed";
2983
+ const intentPayload = await buildIntentPayload(calls, targetChain);
2182
2984
  const result = await provider.sendIntent({
2183
- username: config.username,
2184
- targetChain: config.chain.id,
2185
- calls: calls.map((call) => ({
2186
- to: call.to,
2187
- data: call.data,
2188
- value: call.value ? call.value.toString() : "0",
2189
- label: call.label,
2190
- sublabel: call.sublabel
2191
- })),
2985
+ ...intentPayload,
2192
2986
  closeOn,
2193
2987
  waitForHash: config.waitForHash ?? true,
2194
2988
  hashTimeoutMs: config.hashTimeoutMs,
@@ -2203,18 +2997,12 @@ function createPasskeyWalletClient(config) {
2203
2997
  * Send multiple calls as a single batched transaction
2204
2998
  */
2205
2999
  async sendCalls(params) {
2206
- const { calls } = params;
3000
+ const { calls, chainId: targetChain, tokenRequests } = params;
2207
3001
  const closeOn = config.waitForHash ?? true ? "completed" : "preconfirmed";
3002
+ const intentPayload = await buildIntentPayload(calls, targetChain);
2208
3003
  const result = await provider.sendIntent({
2209
- username: config.username,
2210
- targetChain: config.chain.id,
2211
- calls: calls.map((call) => ({
2212
- to: call.to,
2213
- data: call.data,
2214
- value: call.value ? call.value.toString() : "0",
2215
- label: call.label,
2216
- sublabel: call.sublabel
2217
- })),
3004
+ ...intentPayload,
3005
+ tokenRequests,
2218
3006
  closeOn,
2219
3007
  waitForHash: config.waitForHash ?? true,
2220
3008
  hashTimeoutMs: config.hashTimeoutMs,
@@ -2658,9 +3446,10 @@ function BatchQueueWidget({ onSignAll }) {
2658
3446
 
2659
3447
  // src/verify.ts
2660
3448
  var import_viem7 = require("viem");
2661
- var PASSKEY_MESSAGE_PREFIX = "Passkey Signed Message:\n";
3449
+ var ETHEREUM_MESSAGE_PREFIX = "Ethereum Signed Message:\n";
3450
+ var PASSKEY_MESSAGE_PREFIX = ETHEREUM_MESSAGE_PREFIX;
2662
3451
  function hashMessage2(message) {
2663
- const prefixed = PASSKEY_MESSAGE_PREFIX + message.length.toString() + message;
3452
+ const prefixed = ETHEREUM_MESSAGE_PREFIX + message.length.toString() + message;
2664
3453
  return (0, import_viem7.keccak256)((0, import_viem7.toBytes)(prefixed));
2665
3454
  }
2666
3455
  function verifyMessageHash(message, signedHash) {
@@ -2672,8 +3461,11 @@ function verifyMessageHash(message, signedHash) {
2672
3461
  0 && (module.exports = {
2673
3462
  BatchQueueProvider,
2674
3463
  BatchQueueWidget,
3464
+ ETHEREUM_MESSAGE_PREFIX,
3465
+ OneAuthClient,
2675
3466
  PASSKEY_MESSAGE_PREFIX,
2676
3467
  PasskeyProviderClient,
3468
+ createOneAuthProvider,
2677
3469
  createPasskeyAccount,
2678
3470
  createPasskeyProvider,
2679
3471
  createPasskeyWalletClient,