@rhinestone/1auth 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -34,11 +34,8 @@ __export(index_exports, {
34
34
  BatchQueueWidget: () => BatchQueueWidget,
35
35
  ETHEREUM_MESSAGE_PREFIX: () => ETHEREUM_MESSAGE_PREFIX,
36
36
  OneAuthClient: () => OneAuthClient,
37
- PASSKEY_MESSAGE_PREFIX: () => PASSKEY_MESSAGE_PREFIX,
38
- PasskeyProviderClient: () => OneAuthClient,
39
37
  createOneAuthProvider: () => createOneAuthProvider,
40
38
  createPasskeyAccount: () => createPasskeyAccount,
41
- createPasskeyProvider: () => createPasskeyProvider,
42
39
  createPasskeyWalletClient: () => createPasskeyWalletClient,
43
40
  encodeWebAuthnSignature: () => encodeWebAuthnSignature,
44
41
  getAllSupportedChainsAndTokens: () => getAllSupportedChainsAndTokens,
@@ -200,7 +197,6 @@ var POPUP_WIDTH = 450;
200
197
  var POPUP_HEIGHT = 600;
201
198
  var DEFAULT_EMBED_WIDTH = "400px";
202
199
  var DEFAULT_EMBED_HEIGHT = "500px";
203
- var MODAL_WIDTH = 340;
204
200
  var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
205
201
  var OneAuthClient = class {
206
202
  constructor(config) {
@@ -294,7 +290,28 @@ var OneAuthClient = class {
294
290
  return void 0;
295
291
  }
296
292
  /**
297
- * Open the auth dialog (sign in + sign up).
293
+ * Open the authentication modal (sign in + sign up).
294
+ *
295
+ * Handles both new user registration and returning user login in a single
296
+ * call — the modal shows the appropriate flow based on whether the user
297
+ * has a passkey registered.
298
+ *
299
+ * @param options.username - Pre-fill the username field
300
+ * @param options.theme - Override the theme for this modal invocation
301
+ * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons
302
+ * @returns {@link AuthResult} with user details and typed address
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const result = await client.authWithModal();
307
+ *
308
+ * if (result.success) {
309
+ * console.log('Signed in as:', result.user?.username);
310
+ * console.log('Address:', result.user?.address); // typed `0x${string}`
311
+ * } else if (result.error?.code === 'USER_CANCELLED') {
312
+ * // User closed the modal
313
+ * }
314
+ * ```
298
315
  */
299
316
  async authWithModal(options) {
300
317
  const dialogUrl = this.getDialogUrl();
@@ -334,7 +351,7 @@ var OneAuthClient = class {
334
351
  * const result = await client.connectWithModal();
335
352
  *
336
353
  * if (result.success) {
337
- * console.log('Connected as:', result.username);
354
+ * console.log('Connected as:', result.user?.username);
338
355
  * } else if (result.action === 'switch') {
339
356
  * // User needs to sign in first
340
357
  * const authResult = await client.authWithModal();
@@ -512,17 +529,16 @@ var OneAuthClient = class {
512
529
  *
513
530
  * @example
514
531
  * ```typescript
515
- * // Authenticate with a login challenge
516
532
  * const result = await client.authenticate({
517
533
  * challenge: `Login to MyApp\nTimestamp: ${Date.now()}\nNonce: ${crypto.randomUUID()}`
518
534
  * });
519
535
  *
520
- * if (result.success && result.signature) {
536
+ * if (result.success && result.challenge) {
521
537
  * // Verify signature server-side
522
538
  * const isValid = await verifyOnServer(
523
- * result.username,
524
- * result.signature,
525
- * result.signedHash
539
+ * result.user?.username,
540
+ * result.challenge.signature,
541
+ * result.challenge.signedHash
526
542
  * );
527
543
  * }
528
544
  * ```
@@ -709,7 +725,7 @@ var OneAuthClient = class {
709
725
  if (event.origin !== dialogOrigin) return;
710
726
  if (event.data?.type === "PASSKEY_READY") {
711
727
  iframe.contentWindow?.postMessage(
712
- { type: "PASSKEY_INIT", ...initPayload },
728
+ { type: "PASSKEY_INIT", ...initPayload, fullViewport: true },
713
729
  dialogOrigin
714
730
  );
715
731
  }
@@ -1048,7 +1064,7 @@ var OneAuthClient = class {
1048
1064
  if (event.origin !== dialogOrigin) return;
1049
1065
  if (event.data?.type === "PASSKEY_READY") {
1050
1066
  iframe.contentWindow?.postMessage(
1051
- { type: "PASSKEY_INIT", ...batchInitPayload },
1067
+ { type: "PASSKEY_INIT", ...batchInitPayload, fullViewport: true },
1052
1068
  dialogOrigin
1053
1069
  );
1054
1070
  }
@@ -1381,7 +1397,7 @@ var OneAuthClient = class {
1381
1397
  ready: true,
1382
1398
  sendInit: (initMessage) => {
1383
1399
  iframe.contentWindow?.postMessage(
1384
- { type: "PASSKEY_INIT", ...initMessage },
1400
+ { type: "PASSKEY_INIT", ...initMessage, fullViewport: true },
1385
1401
  dialogOrigin
1386
1402
  );
1387
1403
  }
@@ -2115,7 +2131,8 @@ var OneAuthClient = class {
2115
2131
  teardown();
2116
2132
  iframe.contentWindow?.postMessage({
2117
2133
  type: "PASSKEY_INIT",
2118
- ...initMessage
2134
+ ...initMessage,
2135
+ fullViewport: true
2119
2136
  }, dialogOrigin);
2120
2137
  resolve(true);
2121
2138
  } else if (event.data?.type === "PASSKEY_CLOSE") {
@@ -2138,121 +2155,88 @@ var OneAuthClient = class {
2138
2155
  });
2139
2156
  }
2140
2157
  /**
2141
- * Create a modal dialog with an iframe inside.
2158
+ * Create a modal dialog with a full-viewport iframe inside.
2159
+ * All visual chrome (backdrop, positioning, animations) is rendered
2160
+ * by the passkey app inside the iframe — the SDK just provides
2161
+ * a transparent full-screen container.
2142
2162
  */
2143
2163
  createModalDialog(url) {
2144
2164
  const dialogUrl = this.getDialogUrl();
2145
2165
  const hostUrl = new URL(dialogUrl);
2146
2166
  const dialog = document.createElement("dialog");
2147
2167
  dialog.dataset.passkey = "";
2168
+ dialog.style.opacity = "0";
2169
+ dialog.style.background = "transparent";
2148
2170
  document.body.appendChild(dialog);
2149
2171
  const style = document.createElement("style");
2150
2172
  style.textContent = `
2151
2173
  dialog[data-passkey] {
2152
- padding: 0;
2153
- border: none;
2154
- background: transparent;
2174
+ position: fixed;
2175
+ top: 0;
2176
+ left: 0;
2177
+ width: 100vw;
2178
+ height: 100vh;
2179
+ height: 100dvh;
2155
2180
  max-width: none;
2156
2181
  max-height: none;
2157
2182
  margin: 0;
2158
- position: fixed;
2159
- top: 50px;
2160
- left: 50%;
2161
- transform: translateX(-50%);
2183
+ padding: 0;
2184
+ border: none;
2185
+ background: transparent;
2162
2186
  outline: none;
2187
+ overflow: hidden;
2188
+ pointer-events: auto;
2163
2189
  }
2164
-
2165
2190
  dialog[data-passkey]::backdrop {
2166
- background-color: rgba(0, 0, 0, 0.4);
2167
- backdrop-filter: blur(8px);
2168
- -webkit-backdrop-filter: blur(8px);
2191
+ background: transparent !important;
2169
2192
  }
2170
-
2171
2193
  dialog[data-passkey] iframe {
2194
+ position: fixed;
2195
+ top: 0;
2196
+ left: 0;
2197
+ width: 100%;
2198
+ height: 100%;
2199
+ border: 0;
2172
2200
  background-color: transparent;
2173
- border-radius: 14px;
2174
- border: none;
2175
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);
2176
- transition: height 0.15s ease-out;
2177
- max-height: calc(100vh - 100px);
2178
- max-height: calc(100dvh - 100px);
2179
- }
2180
-
2181
- @media (min-width: 769px) {
2182
- dialog[data-passkey] iframe {
2183
- animation: passkey_zoomIn 0.2s cubic-bezier(0.32, 0.72, 0, 1);
2184
- }
2185
- }
2186
-
2187
- @media (max-width: 768px) {
2188
- dialog[data-passkey] {
2189
- width: 100vw !important;
2190
- height: auto !important;
2191
- max-height: 90vh !important;
2192
- max-height: 90dvh !important;
2193
- top: auto !important;
2194
- bottom: 0 !important;
2195
- left: 0 !important;
2196
- right: 0 !important;
2197
- transform: none !important;
2198
- margin: 0 !important;
2199
- }
2200
-
2201
- dialog[data-passkey] iframe {
2202
- animation: passkey_slideFromBottom 0.3s cubic-bezier(0.32, 0.72, 0, 1);
2203
- border-bottom-left-radius: 0 !important;
2204
- border-bottom-right-radius: 0 !important;
2205
- width: 100% !important;
2206
- max-height: 90vh !important;
2207
- max-height: 90dvh !important;
2208
- box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.15) !important;
2209
- }
2210
- }
2211
-
2212
- @keyframes passkey_zoomIn {
2213
- from {
2214
- opacity: 0;
2215
- transform: scale(0.96) translateY(8px);
2216
- }
2217
- to {
2218
- opacity: 1;
2219
- transform: scale(1) translateY(0);
2220
- }
2221
- }
2222
-
2223
- @keyframes passkey_slideFromBottom {
2224
- from { transform: translate3d(0, 100%, 0); }
2225
- to { transform: translate3d(0, 0, 0); }
2226
- }
2227
-
2228
- @keyframes passkey_shake {
2229
- 0%, 100% { transform: translateX(0); }
2230
- 20% { transform: translateX(-4px); }
2231
- 40% { transform: translateX(4px); }
2232
- 60% { transform: translateX(-4px); }
2233
- 80% { transform: translateX(4px); }
2201
+ pointer-events: auto;
2234
2202
  }
2235
2203
  `;
2236
2204
  dialog.appendChild(style);
2237
2205
  const iframe = document.createElement("iframe");
2238
2206
  iframe.setAttribute(
2239
2207
  "allow",
2240
- "publickey-credentials-get *; publickey-credentials-create *; clipboard-write; identity-credentials-get"
2208
+ [
2209
+ `publickey-credentials-get ${hostUrl.origin}`,
2210
+ `publickey-credentials-create ${hostUrl.origin}`,
2211
+ "clipboard-write",
2212
+ "identity-credentials-get"
2213
+ ].join("; ")
2241
2214
  );
2242
2215
  iframe.setAttribute("aria-label", "Passkey Authentication");
2243
2216
  iframe.setAttribute("tabindex", "0");
2217
+ iframe.setAttribute(
2218
+ "sandbox",
2219
+ "allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
2220
+ );
2244
2221
  iframe.setAttribute("src", url);
2245
2222
  iframe.setAttribute("title", "Passkey");
2246
- iframe.style.border = "none";
2247
- iframe.style.height = "400px";
2248
- iframe.style.width = `${MODAL_WIDTH}px`;
2223
+ iframe.style.opacity = "0";
2249
2224
  dialog.appendChild(iframe);
2225
+ const inertObserver = new MutationObserver((mutations) => {
2226
+ for (const mutation of mutations) {
2227
+ if (mutation.attributeName === "inert") {
2228
+ dialog.removeAttribute("inert");
2229
+ }
2230
+ }
2231
+ });
2232
+ inertObserver.observe(dialog, { attributes: true });
2250
2233
  const handleMessage = (event) => {
2251
2234
  if (event.origin !== hostUrl.origin) return;
2252
- if (event.data?.type === "PASSKEY_RESIZE") {
2253
- const maxHeight = window.innerHeight - 100;
2254
- iframe.style.height = `${Math.min(event.data.height, maxHeight)}px`;
2255
- } else if (event.data?.type === "PASSKEY_DISCONNECT") {
2235
+ if (event.data?.type === "PASSKEY_RENDERED") {
2236
+ dialog.style.opacity = "1";
2237
+ iframe.style.opacity = "1";
2238
+ }
2239
+ if (event.data?.type === "PASSKEY_DISCONNECT") {
2256
2240
  localStorage.removeItem("1auth-user");
2257
2241
  }
2258
2242
  };
@@ -2263,19 +2247,22 @@ var OneAuthClient = class {
2263
2247
  }
2264
2248
  };
2265
2249
  document.addEventListener("keydown", handleEscape);
2266
- dialog.addEventListener("click", (event) => {
2267
- if (event.target === dialog) {
2268
- cleanup();
2269
- }
2270
- });
2271
2250
  dialog.showModal();
2272
2251
  let cleanedUp = false;
2273
2252
  const cleanup = () => {
2274
2253
  if (cleanedUp) return;
2275
2254
  cleanedUp = true;
2255
+ inertObserver.disconnect();
2276
2256
  window.removeEventListener("message", handleMessage);
2277
2257
  document.removeEventListener("keydown", handleEscape);
2278
2258
  dialog.close();
2259
+ if (dialog.parentNode) {
2260
+ for (const sibling of Array.from(dialog.parentNode.children)) {
2261
+ if (sibling !== dialog && sibling instanceof HTMLElement && sibling.hasAttribute("inert")) {
2262
+ sibling.removeAttribute("inert");
2263
+ }
2264
+ }
2265
+ }
2279
2266
  dialog.remove();
2280
2267
  };
2281
2268
  return { dialog, iframe, cleanup };
@@ -2291,7 +2278,8 @@ var OneAuthClient = class {
2291
2278
  dialogReady = true;
2292
2279
  iframe.contentWindow?.postMessage({
2293
2280
  type: "PASSKEY_INIT",
2294
- mode: "iframe"
2281
+ mode: "iframe",
2282
+ fullViewport: true
2295
2283
  }, dialogOrigin);
2296
2284
  return;
2297
2285
  }
@@ -2304,24 +2292,11 @@ var OneAuthClient = class {
2304
2292
  if (data.success) {
2305
2293
  resolve({
2306
2294
  success: true,
2307
- username: data.data?.username,
2308
- address: data.data?.address,
2309
- user: data.data?.user
2310
- });
2311
- } else {
2312
- resolve({
2313
- success: false,
2314
- error: data.error
2315
- });
2316
- }
2317
- } else if (data?.type === "PASSKEY_REGISTER_RESULT") {
2318
- window.removeEventListener("message", handleMessage);
2319
- cleanup();
2320
- if (data.success) {
2321
- resolve({
2322
- success: true,
2323
- username: data.data?.username,
2324
- address: data.data?.address
2295
+ user: {
2296
+ id: data.data?.user?.id,
2297
+ username: data.data?.username,
2298
+ address: data.data?.address
2299
+ }
2325
2300
  });
2326
2301
  } else {
2327
2302
  resolve({
@@ -2380,25 +2355,11 @@ var OneAuthClient = class {
2380
2355
  if (data.success) {
2381
2356
  resolve({
2382
2357
  success: true,
2383
- username: data.data?.username,
2384
- address: data.data?.address,
2385
- user: data.data?.user
2386
- });
2387
- } else {
2388
- resolve({
2389
- success: false,
2390
- error: data.error
2391
- });
2392
- }
2393
- } else if (data?.type === "PASSKEY_REGISTER_RESULT") {
2394
- clearInterval(pollTimer);
2395
- window.removeEventListener("message", handleMessage);
2396
- popup?.close();
2397
- if (data.success) {
2398
- resolve({
2399
- success: true,
2400
- username: data.data?.username,
2401
- address: data.data?.address
2358
+ user: {
2359
+ id: data.data?.user?.id,
2360
+ username: data.data?.username,
2361
+ address: data.data?.address
2362
+ }
2402
2363
  });
2403
2364
  } else {
2404
2365
  resolve({
@@ -2434,11 +2395,15 @@ var OneAuthClient = class {
2434
2395
  if (data.success) {
2435
2396
  resolve({
2436
2397
  success: true,
2437
- username: data.data?.username,
2438
- user: data.data?.user,
2439
- accountAddress: data.data?.accountAddress,
2440
- signature: data.data?.signature,
2441
- signedHash: data.data?.signedHash
2398
+ user: {
2399
+ id: data.data?.user?.id,
2400
+ username: data.data?.username,
2401
+ address: data.data?.accountAddress
2402
+ },
2403
+ challenge: data.data?.signature ? {
2404
+ signature: data.data.signature,
2405
+ signedHash: data.data.signedHash
2406
+ } : void 0
2442
2407
  });
2443
2408
  } else {
2444
2409
  resolve({
@@ -2473,8 +2438,10 @@ var OneAuthClient = class {
2473
2438
  if (data.success) {
2474
2439
  resolve({
2475
2440
  success: true,
2476
- username: data.data?.username,
2477
- address: data.data?.address,
2441
+ user: {
2442
+ username: data.data?.username,
2443
+ address: data.data?.address
2444
+ },
2478
2445
  autoConnected: data.data?.autoConnected
2479
2446
  });
2480
2447
  } else {
@@ -2785,15 +2752,15 @@ function createOneAuthProvider(options) {
2785
2752
  let username;
2786
2753
  let address;
2787
2754
  if (connectResult.success) {
2788
- username = connectResult.username;
2789
- address = connectResult.address;
2755
+ username = connectResult.user?.username;
2756
+ address = connectResult.user?.address;
2790
2757
  } else if (connectResult.action === "switch") {
2791
2758
  const authResult = await client.authWithModal();
2792
2759
  if (!authResult.success) {
2793
2760
  throw new Error(authResult.error?.message || "Authentication failed");
2794
2761
  }
2795
- username = authResult.username;
2796
- address = authResult.address;
2762
+ username = authResult.user?.username;
2763
+ address = authResult.user?.address;
2797
2764
  } else {
2798
2765
  throw new Error(connectResult.error?.message || "Connection cancelled");
2799
2766
  }
@@ -3166,7 +3133,6 @@ function createOneAuthProvider(options) {
3166
3133
  disconnect
3167
3134
  };
3168
3135
  }
3169
- var createPasskeyProvider = createOneAuthProvider;
3170
3136
 
3171
3137
  // src/account.ts
3172
3138
  var import_viem5 = require("viem");
@@ -3837,7 +3803,6 @@ function BatchQueueWidget({ onSignAll }) {
3837
3803
  // src/verify.ts
3838
3804
  var import_viem7 = require("viem");
3839
3805
  var ETHEREUM_MESSAGE_PREFIX = "Ethereum Signed Message:\n";
3840
- var PASSKEY_MESSAGE_PREFIX = ETHEREUM_MESSAGE_PREFIX;
3841
3806
  function hashMessage2(message) {
3842
3807
  const prefixed = ETHEREUM_MESSAGE_PREFIX + message.length.toString() + message;
3843
3808
  return (0, import_viem7.keccak256)((0, import_viem7.toBytes)(prefixed));
@@ -3853,11 +3818,8 @@ function verifyMessageHash(message, signedHash) {
3853
3818
  BatchQueueWidget,
3854
3819
  ETHEREUM_MESSAGE_PREFIX,
3855
3820
  OneAuthClient,
3856
- PASSKEY_MESSAGE_PREFIX,
3857
- PasskeyProviderClient,
3858
3821
  createOneAuthProvider,
3859
3822
  createPasskeyAccount,
3860
- createPasskeyProvider,
3861
3823
  createPasskeyWalletClient,
3862
3824
  encodeWebAuthnSignature,
3863
3825
  getAllSupportedChainsAndTokens,