@rhinestone/1auth 0.6.0 → 0.6.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
@@ -97,7 +97,7 @@ function applyChainFilters(chainIds, options) {
97
97
  if (!includeTestnets) {
98
98
  filtered = filtered.filter((chainId) => !isTestnet(chainId));
99
99
  }
100
- if (allowlist && allowlist.length > 0) {
100
+ if (allowlist) {
101
101
  const allowed = new Set(allowlist);
102
102
  filtered = filtered.filter((chainId) => allowed.has(chainId));
103
103
  }
@@ -385,6 +385,53 @@ var OneAuthClient = class {
385
385
  }
386
386
  return this.waitForConnectResponse(dialog, iframe, cleanup);
387
387
  }
388
+ /**
389
+ * Open the account management dialog.
390
+ *
391
+ * Shows the account overview with guardian status and recovery setup
392
+ * options. The dialog closes when the user clicks the X button or
393
+ * completes their action.
394
+ *
395
+ * @example
396
+ * ```typescript
397
+ * await client.openAccountDialog();
398
+ * ```
399
+ */
400
+ async openAccountDialog(options) {
401
+ const dialogUrl = this.getDialogUrl();
402
+ const params = new URLSearchParams({
403
+ mode: "iframe"
404
+ });
405
+ const themeParams = this.getThemeParams(options?.theme);
406
+ if (themeParams) {
407
+ const themeParsed = new URLSearchParams(themeParams);
408
+ themeParsed.forEach((value, key) => params.set(key, value));
409
+ }
410
+ const url = `${dialogUrl}/dialog/account?${params.toString()}`;
411
+ const { dialog, iframe, cleanup } = this.createModalDialog(url);
412
+ const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
413
+ mode: "iframe"
414
+ });
415
+ if (!ready) return;
416
+ const dialogOrigin = this.getDialogOrigin();
417
+ return new Promise((resolve) => {
418
+ const handleMessage = (event) => {
419
+ if (event.origin !== dialogOrigin) return;
420
+ if (event.data?.type === "PASSKEY_CLOSE" || event.data?.type === "PASSKEY_DISCONNECT") {
421
+ window.removeEventListener("message", handleMessage);
422
+ dialog.removeEventListener("close", handleClose);
423
+ cleanup();
424
+ resolve();
425
+ }
426
+ };
427
+ const handleClose = () => {
428
+ window.removeEventListener("message", handleMessage);
429
+ resolve();
430
+ };
431
+ window.addEventListener("message", handleMessage);
432
+ dialog.addEventListener("close", handleClose);
433
+ });
434
+ }
388
435
  /**
389
436
  * Check if a user has already granted consent for the requested fields.
390
437
  * This is a read-only check — no dialog is shown.
@@ -680,10 +727,13 @@ var OneAuthClient = class {
680
727
  const themeParams = this.getThemeParams();
681
728
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
682
729
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
683
- const [prepareResult, dialogResult] = await Promise.all([
684
- this.prepareIntent(requestBody),
685
- this.waitForDialogReadyDeferred(dialog, iframe, cleanup)
686
- ]);
730
+ const dialogOrigin = this.getDialogOrigin();
731
+ let earlyPrepareResult = null;
732
+ const preparePromise = this.prepareIntent(requestBody).then((r) => {
733
+ earlyPrepareResult = r;
734
+ return r;
735
+ });
736
+ const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);
687
737
  if (!dialogResult.ready) {
688
738
  return {
689
739
  success: false,
@@ -692,40 +742,85 @@ var OneAuthClient = class {
692
742
  error: { code: "USER_CANCELLED", message: "User closed the dialog" }
693
743
  };
694
744
  }
695
- if (!prepareResult.success) {
696
- this.sendPrepareError(iframe, prepareResult.error.message);
697
- await this.waitForDialogClose(dialog, cleanup);
698
- return {
699
- success: false,
700
- intentId: "",
701
- status: "failed",
702
- error: prepareResult.error
745
+ let currentInitPayload;
746
+ if (earlyPrepareResult) {
747
+ const prepareResult = earlyPrepareResult;
748
+ if (!prepareResult.success) {
749
+ this.sendPrepareError(iframe, prepareResult.error.message);
750
+ await this.waitForDialogClose(dialog, cleanup);
751
+ return {
752
+ success: false,
753
+ intentId: "",
754
+ status: "failed",
755
+ error: prepareResult.error
756
+ };
757
+ }
758
+ prepareResponse = prepareResult.data;
759
+ currentInitPayload = {
760
+ mode: "iframe",
761
+ calls,
762
+ chainId: targetChain,
763
+ transaction: prepareResponse.transaction,
764
+ challenge: prepareResponse.challenge,
765
+ username,
766
+ accountAddress: prepareResponse.accountAddress,
767
+ originMessages: prepareResponse.originMessages,
768
+ tokenRequests: serializedTokenRequests,
769
+ expiresAt: prepareResponse.expiresAt,
770
+ userId: prepareResponse.userId,
771
+ intentOp: prepareResponse.intentOp,
772
+ digestResult: prepareResponse.digestResult,
773
+ tier: prepareResult.tier
774
+ };
775
+ dialogResult.sendInit(currentInitPayload);
776
+ } else {
777
+ currentInitPayload = {
778
+ mode: "iframe",
779
+ calls,
780
+ chainId: targetChain,
781
+ username,
782
+ accountAddress: options.accountAddress,
783
+ tokenRequests: serializedTokenRequests
703
784
  };
785
+ dialogResult.sendInit(currentInitPayload);
786
+ const prepareResult = await preparePromise;
787
+ if (!prepareResult.success) {
788
+ this.sendPrepareError(iframe, prepareResult.error.message);
789
+ await this.waitForDialogClose(dialog, cleanup);
790
+ return {
791
+ success: false,
792
+ intentId: "",
793
+ status: "failed",
794
+ error: prepareResult.error
795
+ };
796
+ }
797
+ prepareResponse = prepareResult.data;
798
+ currentInitPayload = {
799
+ mode: "iframe",
800
+ calls,
801
+ chainId: targetChain,
802
+ transaction: prepareResponse.transaction,
803
+ challenge: prepareResponse.challenge,
804
+ username,
805
+ accountAddress: prepareResponse.accountAddress,
806
+ originMessages: prepareResponse.originMessages,
807
+ tokenRequests: serializedTokenRequests,
808
+ expiresAt: prepareResponse.expiresAt,
809
+ userId: prepareResponse.userId,
810
+ intentOp: prepareResponse.intentOp,
811
+ digestResult: prepareResponse.digestResult,
812
+ tier: prepareResult.tier
813
+ };
814
+ iframe.contentWindow?.postMessage(
815
+ { type: "PASSKEY_INIT", ...currentInitPayload, fullViewport: true },
816
+ dialogOrigin
817
+ );
704
818
  }
705
- prepareResponse = prepareResult.data;
706
- const dialogOrigin = this.getDialogOrigin();
707
- const initPayload = {
708
- mode: "iframe",
709
- calls,
710
- chainId: targetChain,
711
- transaction: prepareResponse.transaction,
712
- challenge: prepareResponse.challenge,
713
- username,
714
- accountAddress: prepareResponse.accountAddress,
715
- originMessages: prepareResponse.originMessages,
716
- tokenRequests: serializedTokenRequests,
717
- expiresAt: prepareResponse.expiresAt,
718
- userId: prepareResponse.userId,
719
- intentOp: prepareResponse.intentOp,
720
- digestResult: prepareResponse.digestResult,
721
- tier: prepareResult.tier
722
- };
723
- dialogResult.sendInit(initPayload);
724
819
  const handleReReady = (event) => {
725
820
  if (event.origin !== dialogOrigin) return;
726
821
  if (event.data?.type === "PASSKEY_READY") {
727
822
  iframe.contentWindow?.postMessage(
728
- { type: "PASSKEY_INIT", ...initPayload, fullViewport: true },
823
+ { type: "PASSKEY_INIT", ...currentInitPayload, fullViewport: true },
729
824
  dialogOrigin
730
825
  );
731
826
  }
@@ -1014,10 +1109,13 @@ var OneAuthClient = class {
1014
1109
  const themeParams = this.getThemeParams();
1015
1110
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
1016
1111
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
1017
- const [prepareResult, dialogResult] = await Promise.all([
1018
- this.prepareBatchIntent(requestBody),
1019
- this.waitForDialogReadyDeferred(dialog, iframe, cleanup)
1020
- ]);
1112
+ const dialogOrigin = this.getDialogOrigin();
1113
+ let earlyBatchResult = null;
1114
+ const preparePromise = this.prepareBatchIntent(requestBody).then((r) => {
1115
+ earlyBatchResult = r;
1116
+ return r;
1117
+ });
1118
+ const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);
1021
1119
  if (!dialogResult.ready) {
1022
1120
  return {
1023
1121
  success: false,
@@ -1026,7 +1124,8 @@ var OneAuthClient = class {
1026
1124
  failureCount: 0
1027
1125
  };
1028
1126
  }
1029
- if (!prepareResult.success) {
1127
+ let currentBatchPayload;
1128
+ const handleBatchPrepareFailure = async (prepareResult) => {
1030
1129
  const failedIntents = prepareResult.failedIntents;
1031
1130
  const failureResults = failedIntents?.map((f) => ({
1032
1131
  index: f.index,
@@ -1044,27 +1143,68 @@ var OneAuthClient = class {
1044
1143
  failureCount: failureResults.length,
1045
1144
  error: prepareResult.error
1046
1145
  };
1047
- }
1048
- let prepareResponse = prepareResult.data;
1049
- const dialogOrigin = this.getDialogOrigin();
1050
- const batchInitPayload = {
1051
- mode: "iframe",
1052
- batchMode: true,
1053
- batchIntents: prepareResponse.intents,
1054
- batchFailedIntents: prepareResponse.failedIntents,
1055
- challenge: prepareResponse.challenge,
1056
- username: options.username,
1057
- accountAddress: prepareResponse.accountAddress,
1058
- userId: prepareResponse.userId,
1059
- expiresAt: prepareResponse.expiresAt,
1060
- tier: prepareResult.tier
1061
1146
  };
1062
- dialogResult.sendInit(batchInitPayload);
1147
+ let prepareResponse;
1148
+ if (earlyBatchResult) {
1149
+ const prepareResult = earlyBatchResult;
1150
+ if (!prepareResult.success) {
1151
+ return handleBatchPrepareFailure(prepareResult);
1152
+ }
1153
+ prepareResponse = prepareResult.data;
1154
+ currentBatchPayload = {
1155
+ mode: "iframe",
1156
+ batchMode: true,
1157
+ batchIntents: prepareResponse.intents,
1158
+ batchFailedIntents: prepareResponse.failedIntents,
1159
+ challenge: prepareResponse.challenge,
1160
+ username: options.username,
1161
+ accountAddress: prepareResponse.accountAddress,
1162
+ userId: prepareResponse.userId,
1163
+ expiresAt: prepareResponse.expiresAt,
1164
+ tier: prepareResult.tier
1165
+ };
1166
+ dialogResult.sendInit(currentBatchPayload);
1167
+ } else {
1168
+ currentBatchPayload = {
1169
+ mode: "iframe",
1170
+ batchMode: true,
1171
+ batchIntents: serializedIntents.map((intent, idx) => ({
1172
+ index: idx,
1173
+ targetChain: intent.targetChain,
1174
+ calls: JSON.stringify(intent.calls)
1175
+ // No: transaction, intentOp, expiresAt, originMessages
1176
+ })),
1177
+ username: options.username,
1178
+ accountAddress: options.accountAddress
1179
+ };
1180
+ dialogResult.sendInit(currentBatchPayload);
1181
+ const prepareResult = await preparePromise;
1182
+ if (!prepareResult.success) {
1183
+ return handleBatchPrepareFailure(prepareResult);
1184
+ }
1185
+ prepareResponse = prepareResult.data;
1186
+ currentBatchPayload = {
1187
+ mode: "iframe",
1188
+ batchMode: true,
1189
+ batchIntents: prepareResponse.intents,
1190
+ batchFailedIntents: prepareResponse.failedIntents,
1191
+ challenge: prepareResponse.challenge,
1192
+ username: options.username,
1193
+ accountAddress: prepareResponse.accountAddress,
1194
+ userId: prepareResponse.userId,
1195
+ expiresAt: prepareResponse.expiresAt,
1196
+ tier: prepareResult.tier
1197
+ };
1198
+ iframe.contentWindow?.postMessage(
1199
+ { type: "PASSKEY_INIT", ...currentBatchPayload, fullViewport: true },
1200
+ dialogOrigin
1201
+ );
1202
+ }
1063
1203
  const handleBatchReReady = (event) => {
1064
1204
  if (event.origin !== dialogOrigin) return;
1065
1205
  if (event.data?.type === "PASSKEY_READY") {
1066
1206
  iframe.contentWindow?.postMessage(
1067
- { type: "PASSKEY_INIT", ...batchInitPayload, fullViewport: true },
1207
+ { type: "PASSKEY_INIT", ...currentBatchPayload, fullViewport: true },
1068
1208
  dialogOrigin
1069
1209
  );
1070
1210
  }
@@ -1802,16 +1942,8 @@ var OneAuthClient = class {
1802
1942
  const themeParams = this.getThemeParams(options?.theme);
1803
1943
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
1804
1944
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
1805
- const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
1806
- mode: "iframe",
1807
- message: options.message,
1808
- challenge: options.challenge || options.message,
1809
- username: options.username,
1810
- accountAddress: options.accountAddress,
1811
- description: options.description,
1812
- metadata: options.metadata
1813
- });
1814
- if (!ready) {
1945
+ const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);
1946
+ if (!dialogResult.ready) {
1815
1947
  return {
1816
1948
  success: false,
1817
1949
  error: {
@@ -1820,7 +1952,29 @@ var OneAuthClient = class {
1820
1952
  }
1821
1953
  };
1822
1954
  }
1955
+ const initPayload = {
1956
+ mode: "iframe",
1957
+ message: options.message,
1958
+ challenge: options.challenge || options.message,
1959
+ username: options.username,
1960
+ accountAddress: options.accountAddress,
1961
+ description: options.description,
1962
+ metadata: options.metadata
1963
+ };
1964
+ dialogResult.sendInit(initPayload);
1965
+ const dialogOrigin = this.getDialogOrigin();
1966
+ const handleReReady = (event) => {
1967
+ if (event.origin !== dialogOrigin) return;
1968
+ if (event.data?.type === "PASSKEY_READY") {
1969
+ iframe.contentWindow?.postMessage(
1970
+ { type: "PASSKEY_INIT", ...initPayload, fullViewport: true },
1971
+ dialogOrigin
1972
+ );
1973
+ }
1974
+ };
1975
+ window.addEventListener("message", handleReReady);
1823
1976
  const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);
1977
+ window.removeEventListener("message", handleReReady);
1824
1978
  cleanup();
1825
1979
  if (signingResult.success) {
1826
1980
  return {
@@ -1888,7 +2042,17 @@ var OneAuthClient = class {
1888
2042
  const themeParams = this.getThemeParams(options?.theme);
1889
2043
  const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ""}`;
1890
2044
  const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);
1891
- const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {
2045
+ const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);
2046
+ if (!dialogResult.ready) {
2047
+ return {
2048
+ success: false,
2049
+ error: {
2050
+ code: "USER_REJECTED",
2051
+ message: "User closed the dialog"
2052
+ }
2053
+ };
2054
+ }
2055
+ const initPayload = {
1892
2056
  mode: "iframe",
1893
2057
  signingMode: "typedData",
1894
2058
  typedData: {
@@ -1901,17 +2065,21 @@ var OneAuthClient = class {
1901
2065
  username: options.username,
1902
2066
  accountAddress: options.accountAddress,
1903
2067
  description: options.description
1904
- });
1905
- if (!ready) {
1906
- return {
1907
- success: false,
1908
- error: {
1909
- code: "USER_REJECTED",
1910
- message: "User closed the dialog"
1911
- }
1912
- };
1913
- }
2068
+ };
2069
+ dialogResult.sendInit(initPayload);
2070
+ const dialogOrigin = this.getDialogOrigin();
2071
+ const handleReReady = (event) => {
2072
+ if (event.origin !== dialogOrigin) return;
2073
+ if (event.data?.type === "PASSKEY_READY") {
2074
+ iframe.contentWindow?.postMessage(
2075
+ { type: "PASSKEY_INIT", ...initPayload, fullViewport: true },
2076
+ dialogOrigin
2077
+ );
2078
+ }
2079
+ };
2080
+ window.addEventListener("message", handleReReady);
1914
2081
  const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);
2082
+ window.removeEventListener("message", handleReReady);
1915
2083
  cleanup();
1916
2084
  if (signingResult.success) {
1917
2085
  return {
@@ -2163,9 +2331,23 @@ var OneAuthClient = class {
2163
2331
  createModalDialog(url) {
2164
2332
  const dialogUrl = this.getDialogUrl();
2165
2333
  const hostUrl = new URL(dialogUrl);
2334
+ const urlParams = new URL(url, window.location.href).searchParams;
2335
+ const themeMode = urlParams.get("theme") || "light";
2336
+ const accentColor = urlParams.get("accent") || "#0090ff";
2337
+ const isDark = themeMode === "dark" || themeMode !== "light" && window.matchMedia("(prefers-color-scheme: dark)").matches;
2338
+ const bgPrimary = isDark ? "#191919" : "#fcfcfc";
2339
+ const bgSecondary = isDark ? "#222222" : "#f9f9f9";
2340
+ const borderColor = isDark ? "#2a2a2a" : "#e0e0e0";
2341
+ const textPrimary = isDark ? "#eeeeee" : "#202020";
2342
+ const textSecondary = isDark ? "#7b7b7b" : "#838383";
2343
+ const bgSurface = isDark ? "#222222" : "#f0f0f0";
2344
+ const ah = accentColor.replace("#", "");
2345
+ const accentRgb = `${parseInt(ah.slice(0, 2), 16)},${parseInt(ah.slice(2, 4), 16)},${parseInt(ah.slice(4, 6), 16)}`;
2346
+ const accentTint = isDark ? `rgba(${accentRgb},0.15)` : `rgba(${accentRgb},0.1)`;
2347
+ const hostname = window.location.hostname;
2166
2348
  const dialog = document.createElement("dialog");
2167
2349
  dialog.dataset.passkey = "";
2168
- dialog.style.opacity = "0";
2350
+ dialog.style.opacity = "1";
2169
2351
  dialog.style.background = "transparent";
2170
2352
  document.body.appendChild(dialog);
2171
2353
  const style = document.createElement("style");
@@ -2183,6 +2365,7 @@ var OneAuthClient = class {
2183
2365
  padding: 0;
2184
2366
  border: none;
2185
2367
  background: transparent;
2368
+ color-scheme: normal;
2186
2369
  outline: none;
2187
2370
  overflow: hidden;
2188
2371
  pointer-events: auto;
@@ -2198,10 +2381,76 @@ var OneAuthClient = class {
2198
2381
  height: 100%;
2199
2382
  border: 0;
2200
2383
  background-color: transparent;
2384
+ color-scheme: normal;
2201
2385
  pointer-events: auto;
2386
+ backdrop-filter: blur(8px);
2387
+ -webkit-backdrop-filter: blur(8px);
2388
+ }
2389
+ dialog[data-passkey] [data-passkey-overlay] {
2390
+ position: fixed;
2391
+ top: 0;
2392
+ left: 0;
2393
+ width: 100%;
2394
+ height: 100%;
2395
+ display: flex;
2396
+ align-items: flex-start;
2397
+ justify-content: center;
2398
+ padding-top: 50px;
2399
+ background: rgba(0, 0, 0, 0.4);
2400
+ backdrop-filter: blur(8px);
2401
+ -webkit-backdrop-filter: blur(8px);
2402
+ z-index: 1;
2403
+ animation: _1auth-backdrop-in 0.2s ease-out;
2404
+ }
2405
+ @media (max-width: 768px) {
2406
+ dialog[data-passkey] [data-passkey-overlay] {
2407
+ align-items: flex-end;
2408
+ padding-top: 0;
2409
+ }
2410
+ }
2411
+ dialog[data-passkey] [data-passkey-card] {
2412
+ width: 340px;
2413
+ overflow: hidden;
2414
+ border-radius: 14px;
2415
+ box-shadow: 0 8px 32px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08);
2416
+ animation: _1auth-card-in 0.2s cubic-bezier(0.32, 0.72, 0, 1);
2417
+ max-height: calc(100dvh - 100px);
2418
+ }
2419
+ @media (max-width: 768px) {
2420
+ dialog[data-passkey] [data-passkey-card] {
2421
+ width: 100%;
2422
+ border-bottom-left-radius: 0;
2423
+ border-bottom-right-radius: 0;
2424
+ animation: _1auth-card-slide 0.3s cubic-bezier(0.32, 0.72, 0, 1);
2425
+ }
2426
+ }
2427
+ @keyframes _1auth-backdrop-in {
2428
+ from { opacity: 0; } to { opacity: 1; }
2429
+ }
2430
+ @keyframes _1auth-card-in {
2431
+ from { opacity: 0; transform: scale(0.96) translateY(8px); }
2432
+ to { opacity: 1; transform: scale(1) translateY(0); }
2433
+ }
2434
+ @keyframes _1auth-card-slide {
2435
+ from { transform: translate3d(0, 100%, 0); }
2436
+ to { transform: translate3d(0, 0, 0); }
2437
+ }
2438
+ @keyframes _1auth-spin {
2439
+ from { transform: rotate(0deg); }
2440
+ to { transform: rotate(360deg); }
2202
2441
  }
2203
2442
  `;
2204
2443
  dialog.appendChild(style);
2444
+ const overlay = document.createElement("div");
2445
+ overlay.dataset.passkeyOverlay = "";
2446
+ const _sp = '<path d="M10 0.5C8.02219 0.5 6.08879 1.08649 4.4443 2.1853C2.79981 3.28412 1.51809 4.8459 0.761209 6.67316C0.00433288 8.50043 -0.1937 10.5111 0.192152 12.4509C0.578004 14.3907 1.53041 16.1725 2.92894 17.5711C4.32746 18.9696 6.10929 19.922 8.0491 20.3078C9.98891 20.6937 11.9996 20.4957 13.8268 19.7388C15.6541 18.9819 17.2159 17.7002 18.3147 16.0557C19.4135 14.4112 20 12.4778 20 10.5C20 7.84783 18.9464 5.3043 17.0711 3.42893C15.1957 1.55357 12.6522 0.5 10 0.5ZM10 17.7727C8.56159 17.7727 7.15549 17.3462 5.95949 16.547C4.7635 15.7479 3.83134 14.6121 3.28088 13.2831C2.73042 11.9542 2.5864 10.4919 2.86702 9.08116C3.14764 7.67039 3.8403 6.37451 4.85741 5.3574C5.87452 4.3403 7.17039 3.64764 8.58116 3.36702C9.99193 3.0864 11.4542 3.23042 12.7832 3.78088C14.1121 4.33133 15.2479 5.26349 16.0471 6.45949C16.8462 7.65548 17.2727 9.06159 17.2727 10.5C17.2727 12.4288 16.5065 14.2787 15.1426 15.6426C13.7787 17.0065 11.9288 17.7727 10 17.7727Z" fill="currentColor" opacity="0.3"/><path d="M10 3.22767C11.7423 3.22846 13.4276 3.8412 14.7556 4.95667C16.0837 6.07214 16.9681 7.61784 17.2512 9.31825C17.3012 9.64364 17.4662 9.94096 17.7169 10.1573C17.9677 10.3737 18.2878 10.4951 18.6205 10.5C18.8211 10.5001 19.0193 10.457 19.2012 10.3735C19.3832 10.2901 19.5445 10.1684 19.674 10.017C19.8036 9.86549 19.8981 9.68789 19.9511 9.49656C20.004 9.30523 20.0141 9.10478 19.9807 8.90918C19.5986 6.56305 18.3843 4.42821 16.5554 2.88726C14.7265 1.34631 12.4025 0.5 10 0.5C7.59751 0.5 5.27354 1.34631 3.44461 2.88726C1.61569 4.42821 0.401366 6.56305 0.0192815 8.90918C-0.0141442 9.10478 -0.00402016 9.30523 0.0489472 9.49656C0.101914 9.68789 0.196449 9.86549 0.325956 10.017C0.455463 10.1684 0.616823 10.2901 0.798778 10.3735C0.980732 10.457 1.1789 10.5001 1.37945 10.5C1.71216 10.4951 2.03235 10.3737 2.28307 10.1573C2.5338 9.94096 2.69883 9.64364 2.74882 9.31825C3.03193 7.61784 3.91633 6.07214 5.24436 4.95667C6.57239 3.8412 8.25775 3.22846 10 3.22767Z" fill="currentColor"/>';
2447
+ overlay.innerHTML = `<div data-passkey-card style="background:${bgPrimary};border:1px solid ${borderColor};font-family:ui-sans-serif,system-ui,sans-serif,'Apple Color Emoji','Segoe UI Emoji'"><div style="height:36px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;background:${bgSecondary};border-bottom:1px solid ${borderColor}"><div style="display:flex;align-items:center;gap:8px"><div style="display:flex;width:20px;height:20px;align-items:center;justify-content:center;border-radius:4px;background:${bgSurface}"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="${textPrimary}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12V7H5a2 2 0 0 1 0-4h14v4"/><path d="M3 5v14a2 2 0 0 0 2 2h16v-5"/><path d="M18 12a2 2 0 0 0 0 4h4v-4Z"/></svg></div><span style="font-size:13px;font-weight:500;color:${textPrimary};max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${hostname}</span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${textSecondary}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></svg></div><div style="display:flex;align-items:center;gap:4px"><div style="display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary}"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg></div><button data-passkey-close style="display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary};border:none;background:none;cursor:pointer;padding:0"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button></div></div><div style="padding:12px"><div style="display:flex;align-items:center;gap:8px"><div style="display:flex;width:32px;height:32px;min-width:32px;align-items:center;justify-content:center;border-radius:50%;background:${accentTint};padding:6px"><svg style="width:100%;height:100%;animation:_1auth-spin 0.8s linear infinite;color:${accentColor}" fill="none" viewBox="0 0 20 21" xmlns="http://www.w3.org/2000/svg">${_sp}</svg></div><div style="font-weight:500;font-size:18px;color:${textPrimary}">Loading...</div></div><div style="margin-top:8px"><div style="font-size:15px;line-height:20px;color:${textPrimary}">This will only take a few moments.</div><div style="font-size:15px;line-height:20px;color:${textSecondary}">Please do not close the window.</div></div></div></div>`;
2448
+ overlay.addEventListener("click", (e) => {
2449
+ if (e.target === overlay) cleanup();
2450
+ });
2451
+ const overlayCloseBtn = overlay.querySelector("[data-passkey-close]");
2452
+ if (overlayCloseBtn) overlayCloseBtn.addEventListener("click", () => cleanup());
2453
+ dialog.appendChild(overlay);
2205
2454
  const iframe = document.createElement("iframe");
2206
2455
  iframe.setAttribute(
2207
2456
  "allow",
@@ -2230,11 +2479,19 @@ var OneAuthClient = class {
2230
2479
  }
2231
2480
  });
2232
2481
  inertObserver.observe(dialog, { attributes: true });
2482
+ let overlayHidden = false;
2483
+ const hideOverlay = () => {
2484
+ if (overlayHidden) return;
2485
+ overlayHidden = true;
2486
+ iframe.style.opacity = "1";
2487
+ requestAnimationFrame(() => {
2488
+ overlay.style.display = "none";
2489
+ });
2490
+ };
2233
2491
  const handleMessage = (event) => {
2234
2492
  if (event.origin !== hostUrl.origin) return;
2235
2493
  if (event.data?.type === "PASSKEY_RENDERED") {
2236
- dialog.style.opacity = "1";
2237
- iframe.style.opacity = "1";
2494
+ hideOverlay();
2238
2495
  }
2239
2496
  if (event.data?.type === "PASSKEY_DISCONNECT") {
2240
2497
  localStorage.removeItem("1auth-user");
@@ -2805,11 +3062,7 @@ function createOneAuthProvider(options) {
2805
3062
  if (typeof value === "number") return Math.trunc(value).toString();
2806
3063
  if (typeof value === "string") {
2807
3064
  if (value.startsWith("0x")) {
2808
- try {
2809
- return BigInt(value).toString();
2810
- } catch {
2811
- return "0";
2812
- }
3065
+ return BigInt(value).toString();
2813
3066
  }
2814
3067
  return value;
2815
3068
  }
@@ -3804,7 +4057,8 @@ function BatchQueueWidget({ onSignAll }) {
3804
4057
  var import_viem7 = require("viem");
3805
4058
  var ETHEREUM_MESSAGE_PREFIX = "Ethereum Signed Message:\n";
3806
4059
  function hashMessage2(message) {
3807
- const prefixed = ETHEREUM_MESSAGE_PREFIX + message.length.toString() + message;
4060
+ const messageBytes = (0, import_viem7.toBytes)(message);
4061
+ const prefixed = ETHEREUM_MESSAGE_PREFIX + messageBytes.length.toString() + message;
3808
4062
  return (0, import_viem7.keccak256)((0, import_viem7.toBytes)(prefixed));
3809
4063
  }
3810
4064
  function verifyMessageHash(message, signedHash) {