@swype-org/react-sdk 0.1.18 → 0.1.20

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.d.cts CHANGED
@@ -169,11 +169,16 @@ interface ListResponse<T> {
169
169
  /** User configuration preferences */
170
170
  interface UserConfig {
171
171
  defaultAllowance?: number;
172
- /** Registered WebAuthn passkey credential, or null if none registered */
172
+ /** Most recent registered WebAuthn passkey credential, or null if none registered */
173
173
  passkey?: {
174
174
  credentialId: string;
175
175
  publicKey: string;
176
176
  } | null;
177
+ /** All registered WebAuthn passkey credentials for this user */
178
+ passkeys?: {
179
+ credentialId: string;
180
+ publicKey: string;
181
+ }[];
177
182
  }
178
183
  /** Theme mode */
179
184
  type ThemeMode = 'light' | 'dark';
@@ -300,11 +305,17 @@ type AccessTokenGetter = () => Promise<string | null | undefined>;
300
305
  * Creates a WebAuthn passkey credential.
301
306
  * Used for upfront passkey registration before the authorization flow.
302
307
  *
303
- * @param userIdentifier - A string used to identify the user in the
304
- * WebAuthn ceremony (e.g. wallet address or Privy user ID).
308
+ * @param params.userId - Globally unique user identifier (e.g. Privy DID).
309
+ * Used as the WebAuthn `user.id` handle so each user gets a distinct
310
+ * credential slot on the authenticator.
311
+ * @param params.displayName - Human-readable label shown in the OS passkey
312
+ * prompt (e.g. the user's email address or name).
305
313
  * @returns The base64-encoded credentialId and publicKey.
306
314
  */
307
- declare function createPasskeyCredential(userIdentifier: string): Promise<{
315
+ declare function createPasskeyCredential(params: {
316
+ userId: string;
317
+ displayName: string;
318
+ }): Promise<{
308
319
  credentialId: string;
309
320
  publicKey: string;
310
321
  }>;
@@ -359,7 +370,8 @@ interface UseAuthorizationExecutorOptions {
359
370
  * - OPEN_PROVIDER — connect the user's wallet
360
371
  * - SELECT_SOURCE — pause for user chain+token selection
361
372
  * - SWITCH_CHAIN — switch the wallet to the required chain
362
- * - CREATE_SMART_ACCOUNT — server-side smart account deployment
373
+ * - CREATE_SMART_ACCOUNT — server-side smart account creation (legacy)
374
+ * - DEPLOY_SMART_ACCOUNT — server-side on-chain deployment via no-op UserOp
363
375
  * - APPROVE_PERMIT2 — ERC-20 approve(permit2, maxUint256) from EOA
364
376
  * - SIGN_PERMIT2 — EIP-712 Permit2 allowance signature from EOA
365
377
  *
package/dist/index.d.ts CHANGED
@@ -169,11 +169,16 @@ interface ListResponse<T> {
169
169
  /** User configuration preferences */
170
170
  interface UserConfig {
171
171
  defaultAllowance?: number;
172
- /** Registered WebAuthn passkey credential, or null if none registered */
172
+ /** Most recent registered WebAuthn passkey credential, or null if none registered */
173
173
  passkey?: {
174
174
  credentialId: string;
175
175
  publicKey: string;
176
176
  } | null;
177
+ /** All registered WebAuthn passkey credentials for this user */
178
+ passkeys?: {
179
+ credentialId: string;
180
+ publicKey: string;
181
+ }[];
177
182
  }
178
183
  /** Theme mode */
179
184
  type ThemeMode = 'light' | 'dark';
@@ -300,11 +305,17 @@ type AccessTokenGetter = () => Promise<string | null | undefined>;
300
305
  * Creates a WebAuthn passkey credential.
301
306
  * Used for upfront passkey registration before the authorization flow.
302
307
  *
303
- * @param userIdentifier - A string used to identify the user in the
304
- * WebAuthn ceremony (e.g. wallet address or Privy user ID).
308
+ * @param params.userId - Globally unique user identifier (e.g. Privy DID).
309
+ * Used as the WebAuthn `user.id` handle so each user gets a distinct
310
+ * credential slot on the authenticator.
311
+ * @param params.displayName - Human-readable label shown in the OS passkey
312
+ * prompt (e.g. the user's email address or name).
305
313
  * @returns The base64-encoded credentialId and publicKey.
306
314
  */
307
- declare function createPasskeyCredential(userIdentifier: string): Promise<{
315
+ declare function createPasskeyCredential(params: {
316
+ userId: string;
317
+ displayName: string;
318
+ }): Promise<{
308
319
  credentialId: string;
309
320
  publicKey: string;
310
321
  }>;
@@ -359,7 +370,8 @@ interface UseAuthorizationExecutorOptions {
359
370
  * - OPEN_PROVIDER — connect the user's wallet
360
371
  * - SELECT_SOURCE — pause for user chain+token selection
361
372
  * - SWITCH_CHAIN — switch the wallet to the required chain
362
- * - CREATE_SMART_ACCOUNT — server-side smart account deployment
373
+ * - CREATE_SMART_ACCOUNT — server-side smart account creation (legacy)
374
+ * - DEPLOY_SMART_ACCOUNT — server-side on-chain deployment via no-op UserOp
363
375
  * - APPROVE_PERMIT2 — ERC-20 approve(permit2, maxUint256) from EOA
364
376
  * - SIGN_PERMIT2 — EIP-712 Permit2 allowance signature from EOA
365
377
  *
package/dist/index.js CHANGED
@@ -698,7 +698,7 @@ function parseSignTypedDataPayload(typedData) {
698
698
  function getPendingActions(session, completedIds) {
699
699
  return session.actions.filter((a) => a.status === "PENDING" && !completedIds.has(a.id)).sort((a, b) => a.orderIndex - b.orderIndex);
700
700
  }
701
- async function createPasskeyCredential(userIdentifier) {
701
+ async function createPasskeyCredential(params) {
702
702
  const challenge = new Uint8Array(32);
703
703
  crypto.getRandomValues(challenge);
704
704
  const rpId = resolvePasskeyRpId();
@@ -708,9 +708,9 @@ async function createPasskeyCredential(userIdentifier) {
708
708
  challenge,
709
709
  rp: { name: "Swype", id: rpId },
710
710
  user: {
711
- id: new TextEncoder().encode(userIdentifier),
712
- name: userIdentifier,
713
- displayName: "Swype User"
711
+ id: new TextEncoder().encode(params.userId),
712
+ name: params.displayName,
713
+ displayName: params.displayName
714
714
  },
715
715
  pubKeyCredParams: [
716
716
  { alg: -7, type: "public-key" },
@@ -1084,6 +1084,8 @@ function useAuthorizationExecutor(options) {
1084
1084
  return executeSwitchChain(action, wagmiConfig2, switchChainAsync);
1085
1085
  case "APPROVE_PERMIT2":
1086
1086
  return executeApprovePermit2(action, wagmiConfig2);
1087
+ case "DEPLOY_SMART_ACCOUNT":
1088
+ return actionSuccess(action, "Smart account deployment acknowledged.");
1087
1089
  case "SIGN_PERMIT2":
1088
1090
  return executeSignPermit2(action, wagmiConfig2, apiBaseUrl ?? "", sessionIdRef.current);
1089
1091
  default:
@@ -2113,7 +2115,7 @@ function SwypePayment({
2113
2115
  useWalletConnector
2114
2116
  }) {
2115
2117
  const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
2116
- const { ready, authenticated, login, logout, getAccessToken } = usePrivy();
2118
+ const { ready, authenticated, user, login, logout, getAccessToken } = usePrivy();
2117
2119
  const [step, setStep] = useState("login");
2118
2120
  const [error, setError] = useState(null);
2119
2121
  const [providers, setProviders] = useState([]);
@@ -2164,28 +2166,34 @@ function SwypePayment({
2164
2166
  if (!token || cancelled) return;
2165
2167
  const { config } = await fetchUserConfig(apiBaseUrl, token);
2166
2168
  if (cancelled) return;
2167
- if (config.passkey?.credentialId) {
2168
- const hasKey = activeCredentialId ? activeCredentialId === config.passkey.credentialId : await deviceHasPasskey(config.passkey.credentialId);
2169
+ const allPasskeys = config.passkeys ?? (config.passkey ? [config.passkey] : []);
2170
+ if (allPasskeys.length === 0) {
2171
+ setStep("register-passkey");
2172
+ return;
2173
+ }
2174
+ if (activeCredentialId && allPasskeys.some((p) => p.credentialId === activeCredentialId)) {
2175
+ if (depositAmount != null && depositAmount > 0) {
2176
+ setStep("ready");
2177
+ } else {
2178
+ setStep("enter-amount");
2179
+ }
2180
+ return;
2181
+ }
2182
+ for (const pk of allPasskeys) {
2169
2183
  if (cancelled) return;
2170
- if (hasKey) {
2171
- if (!activeCredentialId) {
2172
- setActiveCredentialId(config.passkey.credentialId);
2173
- window.localStorage.setItem(
2174
- ACTIVE_CREDENTIAL_STORAGE_KEY,
2175
- config.passkey.credentialId
2176
- );
2177
- }
2184
+ if (await deviceHasPasskey(pk.credentialId)) {
2185
+ setActiveCredentialId(pk.credentialId);
2186
+ window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, pk.credentialId);
2178
2187
  if (depositAmount != null && depositAmount > 0) {
2179
2188
  setStep("ready");
2180
2189
  } else {
2181
2190
  setStep("enter-amount");
2182
2191
  }
2183
- } else {
2184
- setStep("register-passkey");
2192
+ return;
2185
2193
  }
2186
- } else {
2187
- setStep("register-passkey");
2188
2194
  }
2195
+ if (cancelled) return;
2196
+ setStep("register-passkey");
2189
2197
  } catch {
2190
2198
  if (!cancelled) {
2191
2199
  if (depositAmount != null && depositAmount > 0) {
@@ -2700,7 +2708,11 @@ function SwypePayment({
2700
2708
  try {
2701
2709
  const token = await getAccessToken();
2702
2710
  if (!token) throw new Error("Not authenticated");
2703
- const { credentialId, publicKey } = await createPasskeyCredential("Swype User");
2711
+ const passkeyDisplayName = user?.email?.address ?? user?.google?.name ?? user?.id ?? "Swype User";
2712
+ const { credentialId, publicKey } = await createPasskeyCredential({
2713
+ userId: user?.id ?? "unknown",
2714
+ displayName: passkeyDisplayName
2715
+ });
2704
2716
  await registerPasskey(apiBaseUrl, token, credentialId, publicKey);
2705
2717
  setActiveCredentialId(credentialId);
2706
2718
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);