@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.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  buildTransactionReview,
3
3
  createOneAuthProvider,
4
- createPasskeyProvider,
5
4
  encodeWebAuthnSignature,
6
5
  getAllSupportedChainsAndTokens,
7
6
  getChainById,
@@ -19,7 +18,7 @@ import {
19
18
  isTestnet,
20
19
  isTokenAddressSupported,
21
20
  resolveTokenAddress
22
- } from "./chunk-X73ALCGW.mjs";
21
+ } from "./chunk-N4BLW5UR.mjs";
23
22
 
24
23
  // src/client.ts
25
24
  import { parseUnits, hashTypedData } from "viem";
@@ -27,7 +26,6 @@ var POPUP_WIDTH = 450;
27
26
  var POPUP_HEIGHT = 600;
28
27
  var DEFAULT_EMBED_WIDTH = "400px";
29
28
  var DEFAULT_EMBED_HEIGHT = "500px";
30
- var MODAL_WIDTH = 340;
31
29
  var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
32
30
  var OneAuthClient = class {
33
31
  constructor(config) {
@@ -121,7 +119,28 @@ var OneAuthClient = class {
121
119
  return void 0;
122
120
  }
123
121
  /**
124
- * Open the auth dialog (sign in + sign up).
122
+ * Open the authentication modal (sign in + sign up).
123
+ *
124
+ * Handles both new user registration and returning user login in a single
125
+ * call — the modal shows the appropriate flow based on whether the user
126
+ * has a passkey registered.
127
+ *
128
+ * @param options.username - Pre-fill the username field
129
+ * @param options.theme - Override the theme for this modal invocation
130
+ * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons
131
+ * @returns {@link AuthResult} with user details and typed address
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const result = await client.authWithModal();
136
+ *
137
+ * if (result.success) {
138
+ * console.log('Signed in as:', result.user?.username);
139
+ * console.log('Address:', result.user?.address); // typed `0x${string}`
140
+ * } else if (result.error?.code === 'USER_CANCELLED') {
141
+ * // User closed the modal
142
+ * }
143
+ * ```
125
144
  */
126
145
  async authWithModal(options) {
127
146
  const dialogUrl = this.getDialogUrl();
@@ -161,7 +180,7 @@ var OneAuthClient = class {
161
180
  * const result = await client.connectWithModal();
162
181
  *
163
182
  * if (result.success) {
164
- * console.log('Connected as:', result.username);
183
+ * console.log('Connected as:', result.user?.username);
165
184
  * } else if (result.action === 'switch') {
166
185
  * // User needs to sign in first
167
186
  * const authResult = await client.authWithModal();
@@ -339,17 +358,16 @@ var OneAuthClient = class {
339
358
  *
340
359
  * @example
341
360
  * ```typescript
342
- * // Authenticate with a login challenge
343
361
  * const result = await client.authenticate({
344
362
  * challenge: `Login to MyApp\nTimestamp: ${Date.now()}\nNonce: ${crypto.randomUUID()}`
345
363
  * });
346
364
  *
347
- * if (result.success && result.signature) {
365
+ * if (result.success && result.challenge) {
348
366
  * // Verify signature server-side
349
367
  * const isValid = await verifyOnServer(
350
- * result.username,
351
- * result.signature,
352
- * result.signedHash
368
+ * result.user?.username,
369
+ * result.challenge.signature,
370
+ * result.challenge.signedHash
353
371
  * );
354
372
  * }
355
373
  * ```
@@ -536,7 +554,7 @@ var OneAuthClient = class {
536
554
  if (event.origin !== dialogOrigin) return;
537
555
  if (event.data?.type === "PASSKEY_READY") {
538
556
  iframe.contentWindow?.postMessage(
539
- { type: "PASSKEY_INIT", ...initPayload },
557
+ { type: "PASSKEY_INIT", ...initPayload, fullViewport: true },
540
558
  dialogOrigin
541
559
  );
542
560
  }
@@ -875,7 +893,7 @@ var OneAuthClient = class {
875
893
  if (event.origin !== dialogOrigin) return;
876
894
  if (event.data?.type === "PASSKEY_READY") {
877
895
  iframe.contentWindow?.postMessage(
878
- { type: "PASSKEY_INIT", ...batchInitPayload },
896
+ { type: "PASSKEY_INIT", ...batchInitPayload, fullViewport: true },
879
897
  dialogOrigin
880
898
  );
881
899
  }
@@ -1208,7 +1226,7 @@ var OneAuthClient = class {
1208
1226
  ready: true,
1209
1227
  sendInit: (initMessage) => {
1210
1228
  iframe.contentWindow?.postMessage(
1211
- { type: "PASSKEY_INIT", ...initMessage },
1229
+ { type: "PASSKEY_INIT", ...initMessage, fullViewport: true },
1212
1230
  dialogOrigin
1213
1231
  );
1214
1232
  }
@@ -1942,7 +1960,8 @@ var OneAuthClient = class {
1942
1960
  teardown();
1943
1961
  iframe.contentWindow?.postMessage({
1944
1962
  type: "PASSKEY_INIT",
1945
- ...initMessage
1963
+ ...initMessage,
1964
+ fullViewport: true
1946
1965
  }, dialogOrigin);
1947
1966
  resolve(true);
1948
1967
  } else if (event.data?.type === "PASSKEY_CLOSE") {
@@ -1965,121 +1984,88 @@ var OneAuthClient = class {
1965
1984
  });
1966
1985
  }
1967
1986
  /**
1968
- * Create a modal dialog with an iframe inside.
1987
+ * Create a modal dialog with a full-viewport iframe inside.
1988
+ * All visual chrome (backdrop, positioning, animations) is rendered
1989
+ * by the passkey app inside the iframe — the SDK just provides
1990
+ * a transparent full-screen container.
1969
1991
  */
1970
1992
  createModalDialog(url) {
1971
1993
  const dialogUrl = this.getDialogUrl();
1972
1994
  const hostUrl = new URL(dialogUrl);
1973
1995
  const dialog = document.createElement("dialog");
1974
1996
  dialog.dataset.passkey = "";
1997
+ dialog.style.opacity = "0";
1998
+ dialog.style.background = "transparent";
1975
1999
  document.body.appendChild(dialog);
1976
2000
  const style = document.createElement("style");
1977
2001
  style.textContent = `
1978
2002
  dialog[data-passkey] {
1979
- padding: 0;
1980
- border: none;
1981
- background: transparent;
2003
+ position: fixed;
2004
+ top: 0;
2005
+ left: 0;
2006
+ width: 100vw;
2007
+ height: 100vh;
2008
+ height: 100dvh;
1982
2009
  max-width: none;
1983
2010
  max-height: none;
1984
2011
  margin: 0;
1985
- position: fixed;
1986
- top: 50px;
1987
- left: 50%;
1988
- transform: translateX(-50%);
2012
+ padding: 0;
2013
+ border: none;
2014
+ background: transparent;
1989
2015
  outline: none;
2016
+ overflow: hidden;
2017
+ pointer-events: auto;
1990
2018
  }
1991
-
1992
2019
  dialog[data-passkey]::backdrop {
1993
- background-color: rgba(0, 0, 0, 0.4);
1994
- backdrop-filter: blur(8px);
1995
- -webkit-backdrop-filter: blur(8px);
2020
+ background: transparent !important;
1996
2021
  }
1997
-
1998
2022
  dialog[data-passkey] iframe {
2023
+ position: fixed;
2024
+ top: 0;
2025
+ left: 0;
2026
+ width: 100%;
2027
+ height: 100%;
2028
+ border: 0;
1999
2029
  background-color: transparent;
2000
- border-radius: 14px;
2001
- border: none;
2002
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);
2003
- transition: height 0.15s ease-out;
2004
- max-height: calc(100vh - 100px);
2005
- max-height: calc(100dvh - 100px);
2006
- }
2007
-
2008
- @media (min-width: 769px) {
2009
- dialog[data-passkey] iframe {
2010
- animation: passkey_zoomIn 0.2s cubic-bezier(0.32, 0.72, 0, 1);
2011
- }
2012
- }
2013
-
2014
- @media (max-width: 768px) {
2015
- dialog[data-passkey] {
2016
- width: 100vw !important;
2017
- height: auto !important;
2018
- max-height: 90vh !important;
2019
- max-height: 90dvh !important;
2020
- top: auto !important;
2021
- bottom: 0 !important;
2022
- left: 0 !important;
2023
- right: 0 !important;
2024
- transform: none !important;
2025
- margin: 0 !important;
2026
- }
2027
-
2028
- dialog[data-passkey] iframe {
2029
- animation: passkey_slideFromBottom 0.3s cubic-bezier(0.32, 0.72, 0, 1);
2030
- border-bottom-left-radius: 0 !important;
2031
- border-bottom-right-radius: 0 !important;
2032
- width: 100% !important;
2033
- max-height: 90vh !important;
2034
- max-height: 90dvh !important;
2035
- box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.15) !important;
2036
- }
2037
- }
2038
-
2039
- @keyframes passkey_zoomIn {
2040
- from {
2041
- opacity: 0;
2042
- transform: scale(0.96) translateY(8px);
2043
- }
2044
- to {
2045
- opacity: 1;
2046
- transform: scale(1) translateY(0);
2047
- }
2048
- }
2049
-
2050
- @keyframes passkey_slideFromBottom {
2051
- from { transform: translate3d(0, 100%, 0); }
2052
- to { transform: translate3d(0, 0, 0); }
2053
- }
2054
-
2055
- @keyframes passkey_shake {
2056
- 0%, 100% { transform: translateX(0); }
2057
- 20% { transform: translateX(-4px); }
2058
- 40% { transform: translateX(4px); }
2059
- 60% { transform: translateX(-4px); }
2060
- 80% { transform: translateX(4px); }
2030
+ pointer-events: auto;
2061
2031
  }
2062
2032
  `;
2063
2033
  dialog.appendChild(style);
2064
2034
  const iframe = document.createElement("iframe");
2065
2035
  iframe.setAttribute(
2066
2036
  "allow",
2067
- "publickey-credentials-get *; publickey-credentials-create *; clipboard-write; identity-credentials-get"
2037
+ [
2038
+ `publickey-credentials-get ${hostUrl.origin}`,
2039
+ `publickey-credentials-create ${hostUrl.origin}`,
2040
+ "clipboard-write",
2041
+ "identity-credentials-get"
2042
+ ].join("; ")
2068
2043
  );
2069
2044
  iframe.setAttribute("aria-label", "Passkey Authentication");
2070
2045
  iframe.setAttribute("tabindex", "0");
2046
+ iframe.setAttribute(
2047
+ "sandbox",
2048
+ "allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
2049
+ );
2071
2050
  iframe.setAttribute("src", url);
2072
2051
  iframe.setAttribute("title", "Passkey");
2073
- iframe.style.border = "none";
2074
- iframe.style.height = "400px";
2075
- iframe.style.width = `${MODAL_WIDTH}px`;
2052
+ iframe.style.opacity = "0";
2076
2053
  dialog.appendChild(iframe);
2054
+ const inertObserver = new MutationObserver((mutations) => {
2055
+ for (const mutation of mutations) {
2056
+ if (mutation.attributeName === "inert") {
2057
+ dialog.removeAttribute("inert");
2058
+ }
2059
+ }
2060
+ });
2061
+ inertObserver.observe(dialog, { attributes: true });
2077
2062
  const handleMessage = (event) => {
2078
2063
  if (event.origin !== hostUrl.origin) return;
2079
- if (event.data?.type === "PASSKEY_RESIZE") {
2080
- const maxHeight = window.innerHeight - 100;
2081
- iframe.style.height = `${Math.min(event.data.height, maxHeight)}px`;
2082
- } else if (event.data?.type === "PASSKEY_DISCONNECT") {
2064
+ if (event.data?.type === "PASSKEY_RENDERED") {
2065
+ dialog.style.opacity = "1";
2066
+ iframe.style.opacity = "1";
2067
+ }
2068
+ if (event.data?.type === "PASSKEY_DISCONNECT") {
2083
2069
  localStorage.removeItem("1auth-user");
2084
2070
  }
2085
2071
  };
@@ -2090,19 +2076,22 @@ var OneAuthClient = class {
2090
2076
  }
2091
2077
  };
2092
2078
  document.addEventListener("keydown", handleEscape);
2093
- dialog.addEventListener("click", (event) => {
2094
- if (event.target === dialog) {
2095
- cleanup();
2096
- }
2097
- });
2098
2079
  dialog.showModal();
2099
2080
  let cleanedUp = false;
2100
2081
  const cleanup = () => {
2101
2082
  if (cleanedUp) return;
2102
2083
  cleanedUp = true;
2084
+ inertObserver.disconnect();
2103
2085
  window.removeEventListener("message", handleMessage);
2104
2086
  document.removeEventListener("keydown", handleEscape);
2105
2087
  dialog.close();
2088
+ if (dialog.parentNode) {
2089
+ for (const sibling of Array.from(dialog.parentNode.children)) {
2090
+ if (sibling !== dialog && sibling instanceof HTMLElement && sibling.hasAttribute("inert")) {
2091
+ sibling.removeAttribute("inert");
2092
+ }
2093
+ }
2094
+ }
2106
2095
  dialog.remove();
2107
2096
  };
2108
2097
  return { dialog, iframe, cleanup };
@@ -2118,7 +2107,8 @@ var OneAuthClient = class {
2118
2107
  dialogReady = true;
2119
2108
  iframe.contentWindow?.postMessage({
2120
2109
  type: "PASSKEY_INIT",
2121
- mode: "iframe"
2110
+ mode: "iframe",
2111
+ fullViewport: true
2122
2112
  }, dialogOrigin);
2123
2113
  return;
2124
2114
  }
@@ -2131,24 +2121,11 @@ var OneAuthClient = class {
2131
2121
  if (data.success) {
2132
2122
  resolve({
2133
2123
  success: true,
2134
- username: data.data?.username,
2135
- address: data.data?.address,
2136
- user: data.data?.user
2137
- });
2138
- } else {
2139
- resolve({
2140
- success: false,
2141
- error: data.error
2142
- });
2143
- }
2144
- } else if (data?.type === "PASSKEY_REGISTER_RESULT") {
2145
- window.removeEventListener("message", handleMessage);
2146
- cleanup();
2147
- if (data.success) {
2148
- resolve({
2149
- success: true,
2150
- username: data.data?.username,
2151
- address: data.data?.address
2124
+ user: {
2125
+ id: data.data?.user?.id,
2126
+ username: data.data?.username,
2127
+ address: data.data?.address
2128
+ }
2152
2129
  });
2153
2130
  } else {
2154
2131
  resolve({
@@ -2207,25 +2184,11 @@ var OneAuthClient = class {
2207
2184
  if (data.success) {
2208
2185
  resolve({
2209
2186
  success: true,
2210
- username: data.data?.username,
2211
- address: data.data?.address,
2212
- user: data.data?.user
2213
- });
2214
- } else {
2215
- resolve({
2216
- success: false,
2217
- error: data.error
2218
- });
2219
- }
2220
- } else if (data?.type === "PASSKEY_REGISTER_RESULT") {
2221
- clearInterval(pollTimer);
2222
- window.removeEventListener("message", handleMessage);
2223
- popup?.close();
2224
- if (data.success) {
2225
- resolve({
2226
- success: true,
2227
- username: data.data?.username,
2228
- address: data.data?.address
2187
+ user: {
2188
+ id: data.data?.user?.id,
2189
+ username: data.data?.username,
2190
+ address: data.data?.address
2191
+ }
2229
2192
  });
2230
2193
  } else {
2231
2194
  resolve({
@@ -2261,11 +2224,15 @@ var OneAuthClient = class {
2261
2224
  if (data.success) {
2262
2225
  resolve({
2263
2226
  success: true,
2264
- username: data.data?.username,
2265
- user: data.data?.user,
2266
- accountAddress: data.data?.accountAddress,
2267
- signature: data.data?.signature,
2268
- signedHash: data.data?.signedHash
2227
+ user: {
2228
+ id: data.data?.user?.id,
2229
+ username: data.data?.username,
2230
+ address: data.data?.accountAddress
2231
+ },
2232
+ challenge: data.data?.signature ? {
2233
+ signature: data.data.signature,
2234
+ signedHash: data.data.signedHash
2235
+ } : void 0
2269
2236
  });
2270
2237
  } else {
2271
2238
  resolve({
@@ -2300,8 +2267,10 @@ var OneAuthClient = class {
2300
2267
  if (data.success) {
2301
2268
  resolve({
2302
2269
  success: true,
2303
- username: data.data?.username,
2304
- address: data.data?.address,
2270
+ user: {
2271
+ username: data.data?.username,
2272
+ address: data.data?.address
2273
+ },
2305
2274
  autoConnected: data.data?.autoConnected
2306
2275
  });
2307
2276
  } else {
@@ -3164,7 +3133,6 @@ function BatchQueueWidget({ onSignAll }) {
3164
3133
  // src/verify.ts
3165
3134
  import { keccak256, toBytes } from "viem";
3166
3135
  var ETHEREUM_MESSAGE_PREFIX = "Ethereum Signed Message:\n";
3167
- var PASSKEY_MESSAGE_PREFIX = ETHEREUM_MESSAGE_PREFIX;
3168
3136
  function hashMessage2(message) {
3169
3137
  const prefixed = ETHEREUM_MESSAGE_PREFIX + message.length.toString() + message;
3170
3138
  return keccak256(toBytes(prefixed));
@@ -3179,11 +3147,8 @@ export {
3179
3147
  BatchQueueWidget,
3180
3148
  ETHEREUM_MESSAGE_PREFIX,
3181
3149
  OneAuthClient,
3182
- PASSKEY_MESSAGE_PREFIX,
3183
- OneAuthClient as PasskeyProviderClient,
3184
3150
  createOneAuthProvider,
3185
3151
  createPasskeyAccount,
3186
- createPasskeyProvider,
3187
3152
  createPasskeyWalletClient,
3188
3153
  encodeWebAuthnSignature,
3189
3154
  getAllSupportedChainsAndTokens,