@swype-org/react-sdk 0.1.232 → 0.1.237

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
@@ -375,11 +375,12 @@ declare function updateUserConfig(apiBaseUrl: string, token: string, config: {
375
375
  defaultAllowance: number;
376
376
  }): Promise<void>;
377
377
  /**
378
- * Updates the user's default allowance, authenticated by session ID.
378
+ * Updates default allowance for the authorization session.
379
379
  * PATCH /v1/authorization-sessions/{id}/user-config
380
380
  *
381
- * This does not require a bearer token — the session ID itself serves
382
- * as proof of authorization.
381
+ * No bearer token — the session ID is the credential. When the session has no
382
+ * linked user yet (e.g. guest account setup), config is stored on the session
383
+ * and used as the account allowance until the user is claimed.
383
384
  */
384
385
  declare function updateUserConfigBySession(apiBaseUrl: string, sessionId: string, config: {
385
386
  defaultAllowance: number;
@@ -857,7 +858,6 @@ type PaymentPhase = {
857
858
  step: 'select-source';
858
859
  action: AuthorizationAction;
859
860
  isDesktop: boolean;
860
- skipOneTapLimit?: boolean;
861
861
  } | {
862
862
  step: 'one-tap-setup';
863
863
  action: AuthorizationAction | null;
package/dist/index.d.ts CHANGED
@@ -375,11 +375,12 @@ declare function updateUserConfig(apiBaseUrl: string, token: string, config: {
375
375
  defaultAllowance: number;
376
376
  }): Promise<void>;
377
377
  /**
378
- * Updates the user's default allowance, authenticated by session ID.
378
+ * Updates default allowance for the authorization session.
379
379
  * PATCH /v1/authorization-sessions/{id}/user-config
380
380
  *
381
- * This does not require a bearer token — the session ID itself serves
382
- * as proof of authorization.
381
+ * No bearer token — the session ID is the credential. When the session has no
382
+ * linked user yet (e.g. guest account setup), config is stored on the session
383
+ * and used as the account allowance until the user is claimed.
383
384
  */
384
385
  declare function updateUserConfigBySession(apiBaseUrl: string, sessionId: string, config: {
385
386
  defaultAllowance: number;
@@ -857,7 +858,6 @@ type PaymentPhase = {
857
858
  step: 'select-source';
858
859
  action: AuthorizationAction;
859
860
  isDesktop: boolean;
860
- skipOneTapLimit?: boolean;
861
861
  } | {
862
862
  step: 'one-tap-setup';
863
863
  action: AuthorizationAction | null;
package/dist/index.js CHANGED
@@ -2021,7 +2021,6 @@ function resolvePhase(state) {
2021
2021
  if (p.step === "token-picker" || p.step === "one-tap-setup" || p.step === "select-source" || p.step === "confirm-sign" || p.step === "guest-token-picker") {
2022
2022
  return p;
2023
2023
  }
2024
- if (p.step === "wallet-setup") return p;
2025
2024
  if (state.mobileFlow && state.deeplinkUri) {
2026
2025
  return {
2027
2026
  step: "wallet-setup",
@@ -2029,7 +2028,19 @@ function resolvePhase(state) {
2029
2028
  accountId: null
2030
2029
  };
2031
2030
  }
2032
- if (!state.activeCredentialId && !state.passkeyConfigLoaded) {
2031
+ if (p.step === "wallet-setup" && p.mobile == null) {
2032
+ return p;
2033
+ }
2034
+ if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer) {
2035
+ return { step: "guest-token-picker" };
2036
+ }
2037
+ if (p.step === "wallet-picker" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri)) {
2038
+ return p;
2039
+ }
2040
+ if (!state.privyReady) {
2041
+ return { step: "initializing" };
2042
+ }
2043
+ if (state.privyAuthenticated && !state.activeCredentialId && !state.passkeyConfigLoaded) {
2033
2044
  return { step: "initializing" };
2034
2045
  }
2035
2046
  if (state.verificationTarget) {
@@ -2047,9 +2058,6 @@ function resolvePhase(state) {
2047
2058
  if (state.loadingData && state.activeCredentialId && hasActiveWallet(state.accounts)) {
2048
2059
  return { step: "data-loading" };
2049
2060
  }
2050
- if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer) {
2051
- return { step: "guest-token-picker" };
2052
- }
2053
2061
  if (state.activeCredentialId && !hasActiveWallet(state.accounts) && !state.mobileFlow) {
2054
2062
  return { step: "wallet-picker", reason: "link" };
2055
2063
  }
@@ -2106,7 +2114,9 @@ function createInitialState(config) {
2106
2114
  guestPreauthSessionId: null,
2107
2115
  activePublicKey: null,
2108
2116
  loginRequested: false,
2109
- guestPreauthorizing: false
2117
+ guestPreauthorizing: false,
2118
+ privyReady: false,
2119
+ privyAuthenticated: false
2110
2120
  };
2111
2121
  }
2112
2122
  function paymentReducer(state, action) {
@@ -2336,6 +2346,17 @@ function applyAction(state, action) {
2336
2346
  selectedWalletId: null,
2337
2347
  selectedTokenSymbol: null
2338
2348
  };
2349
+ case "GUEST_BACK_FROM_TOKEN_PICKER":
2350
+ return {
2351
+ ...state,
2352
+ selectedProviderId: null,
2353
+ guestTransferId: null,
2354
+ guestSessionToken: null,
2355
+ selectedAccountId: null,
2356
+ selectedWalletId: null,
2357
+ selectedTokenSymbol: null,
2358
+ error: null
2359
+ };
2339
2360
  case "GUEST_TRANSFER_COMPLETED":
2340
2361
  return {
2341
2362
  ...state,
@@ -2349,7 +2370,10 @@ function applyAction(state, action) {
2349
2370
  return {
2350
2371
  ...state,
2351
2372
  guestPreauthAccountId: action.accountId,
2352
- guestPreauthSessionId: action.sessionId ?? state.guestPreauthSessionId
2373
+ guestPreauthSessionId: action.sessionId ?? state.guestPreauthSessionId,
2374
+ selectedAccountId: action.accountId,
2375
+ selectedWalletId: null,
2376
+ selectedTokenSymbol: null
2353
2377
  };
2354
2378
  case "GUEST_PREAUTH_BEGIN":
2355
2379
  return { ...state, guestPreauthorizing: true, error: null };
@@ -2407,7 +2431,15 @@ function applyAction(state, action) {
2407
2431
  depositAmount: action.depositAmount,
2408
2432
  passkeyPopupNeeded: state.passkeyPopupNeeded,
2409
2433
  activeCredentialId: null
2410
- })
2434
+ }),
2435
+ privyReady: action.privyReady,
2436
+ privyAuthenticated: false
2437
+ };
2438
+ case "SYNC_PRIVY_SESSION":
2439
+ return {
2440
+ ...state,
2441
+ privyReady: action.ready,
2442
+ privyAuthenticated: action.authenticated
2411
2443
  };
2412
2444
  case "SYNC_AMOUNT":
2413
2445
  return { ...state, amount: action.amount };
@@ -2475,7 +2507,6 @@ function screenForPhase(phase) {
2475
2507
  case "wallet-setup":
2476
2508
  return phase.mobile ? "open-wallet" : "setup-status";
2477
2509
  case "select-source":
2478
- if (phase.skipOneTapLimit) return "select-source";
2479
2510
  return phase.isDesktop ? "setup" : "select-source";
2480
2511
  case "one-tap-setup":
2481
2512
  return "setup";
@@ -6238,7 +6269,7 @@ function StepRendererContent({
6238
6269
  depositAmount: depositAmount ?? void 0,
6239
6270
  error: state.error,
6240
6271
  onSelect: handlers.onSelectGuestToken,
6241
- onBack: () => handlers.onSetPhase({ step: "wallet-picker", reason: "guest-entry" })
6272
+ onBack: handlers.onGuestBackFromTokenPicker
6242
6273
  }
6243
6274
  );
6244
6275
  case "processing": {
@@ -6520,9 +6551,18 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6520
6551
  const { user, getAccessToken } = usePrivy();
6521
6552
  const checkingPasskeyRef = useRef(false);
6522
6553
  const activateExistingCredential = useCallback(async (credentialId) => {
6523
- dispatch({ type: "PASSKEY_ACTIVATED", credentialId });
6524
- window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
6525
6554
  const token = await getAccessToken();
6555
+ let publicKey;
6556
+ if (token) {
6557
+ try {
6558
+ const { config } = await fetchUserConfig(apiBaseUrl, token);
6559
+ const allPasskeys = config.passkeys ?? (config.passkey ? [config.passkey] : []);
6560
+ publicKey = allPasskeys.find((p) => p.credentialId === credentialId)?.publicKey;
6561
+ } catch {
6562
+ }
6563
+ }
6564
+ dispatch({ type: "PASSKEY_ACTIVATED", credentialId, publicKey });
6565
+ window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
6526
6566
  if (token) {
6527
6567
  reportPasskeyActivity(apiBaseUrl, token, credentialId).catch(() => {
6528
6568
  });
@@ -6595,9 +6635,13 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6595
6635
  authToken: token ?? void 0,
6596
6636
  apiBaseUrl
6597
6637
  });
6598
- const { credentialId } = await createPasskeyViaPopup(popupOptions);
6599
- dispatch({ type: "PASSKEY_ACTIVATED", credentialId });
6638
+ const { credentialId, publicKey } = await createPasskeyViaPopup(popupOptions);
6639
+ dispatch({ type: "PASSKEY_ACTIVATED", credentialId, publicKey });
6600
6640
  localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
6641
+ if (token) {
6642
+ reportPasskeyActivity(apiBaseUrl, token, credentialId).catch(() => {
6643
+ });
6644
+ }
6601
6645
  } catch (err) {
6602
6646
  captureException(err);
6603
6647
  dispatch({
@@ -6613,19 +6657,25 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6613
6657
  dispatch({ type: "SET_ERROR", error: null });
6614
6658
  try {
6615
6659
  const token = await getAccessToken();
6660
+ if (!token) throw new Error("Not authenticated");
6616
6661
  const matched = await findDevicePasskeyViaPopup({
6617
6662
  credentialIds: knownCredentialIds,
6618
6663
  rpId: resolvePasskeyRpId(),
6619
- authToken: token ?? void 0,
6664
+ authToken: token,
6620
6665
  apiBaseUrl
6621
6666
  });
6622
6667
  if (matched) {
6623
- dispatch({ type: "PASSKEY_ACTIVATED", credentialId: matched });
6624
- window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
6625
- if (token) {
6626
- reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
6627
- });
6668
+ let publicKey;
6669
+ try {
6670
+ const { config } = await fetchUserConfig(apiBaseUrl, token);
6671
+ const allPasskeys = config.passkeys ?? (config.passkey ? [config.passkey] : []);
6672
+ publicKey = allPasskeys.find((p) => p.credentialId === matched)?.publicKey;
6673
+ } catch {
6628
6674
  }
6675
+ dispatch({ type: "PASSKEY_ACTIVATED", credentialId: matched, publicKey });
6676
+ window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
6677
+ reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
6678
+ });
6629
6679
  } else {
6630
6680
  dispatch({
6631
6681
  type: "SET_ERROR",
@@ -7674,11 +7724,15 @@ function useGuestTransferHandlers(deps) {
7674
7724
  };
7675
7725
  execute();
7676
7726
  }, [isGuestFlow, guestTransferId, guestSessionToken, settingSender, apiBaseUrl, wagmiConfig2, switchChainAsync, dispatch, onComplete, onError]);
7727
+ const handleGuestBackFromTokenPicker = useCallback(() => {
7728
+ dispatch({ type: "GUEST_BACK_FROM_TOKEN_PICKER" });
7729
+ }, [dispatch]);
7677
7730
  return {
7678
7731
  guestTokenEntries,
7679
7732
  loadingBalances,
7680
7733
  settingSender,
7681
- handleSelectGuestToken
7734
+ handleSelectGuestToken,
7735
+ handleGuestBackFromTokenPicker
7682
7736
  };
7683
7737
  }
7684
7738
  function useOneTapSetupHandlers(deps) {
@@ -7688,15 +7742,24 @@ function useOneTapSetupHandlers(deps) {
7688
7742
  apiBaseUrl,
7689
7743
  authExecutor,
7690
7744
  selectSourceChainName,
7691
- selectSourceTokenSymbol
7745
+ selectSourceTokenSymbol,
7746
+ authorizationSessionIdForGuest
7692
7747
  } = deps;
7693
7748
  const [savingOneTapLimit, setSavingOneTapLimit] = useState(false);
7694
7749
  const handleSetupOneTap = useCallback(async (limit) => {
7695
7750
  setSavingOneTapLimit(true);
7696
7751
  try {
7697
- const token = await getAccessToken();
7698
- if (!token) throw new Error("Not authenticated");
7699
- await updateUserConfig(apiBaseUrl, token, { defaultAllowance: limit });
7752
+ if (authorizationSessionIdForGuest) {
7753
+ await updateUserConfigBySession(
7754
+ apiBaseUrl,
7755
+ authorizationSessionIdForGuest,
7756
+ { defaultAllowance: limit }
7757
+ );
7758
+ } else {
7759
+ const token = await getAccessToken();
7760
+ if (!token) throw new Error("Not authenticated");
7761
+ await updateUserConfig(apiBaseUrl, token, { defaultAllowance: limit });
7762
+ }
7700
7763
  if (authExecutor.pendingSelectSource) {
7701
7764
  const action = authExecutor.pendingSelectSource;
7702
7765
  const recommended = action.metadata?.recommended;
@@ -7726,12 +7789,30 @@ function useOneTapSetupHandlers(deps) {
7726
7789
  } finally {
7727
7790
  setSavingOneTapLimit(false);
7728
7791
  }
7729
- }, [getAccessToken, apiBaseUrl, authExecutor, dispatch, selectSourceChainName, selectSourceTokenSymbol]);
7792
+ }, [
7793
+ getAccessToken,
7794
+ apiBaseUrl,
7795
+ authExecutor,
7796
+ dispatch,
7797
+ selectSourceChainName,
7798
+ selectSourceTokenSymbol,
7799
+ authorizationSessionIdForGuest
7800
+ ]);
7730
7801
  return {
7731
7802
  handleSetupOneTap,
7732
7803
  savingOneTapLimit
7733
7804
  };
7734
7805
  }
7806
+ function usePrivySessionSyncEffect(deps) {
7807
+ const { dispatch, ready, authenticated } = deps;
7808
+ useEffect(() => {
7809
+ dispatch({
7810
+ type: "SYNC_PRIVY_SESSION",
7811
+ ready,
7812
+ authenticated
7813
+ });
7814
+ }, [dispatch, ready, authenticated]);
7815
+ }
7735
7816
  function useOtpEffects(deps) {
7736
7817
  const {
7737
7818
  state,
@@ -7925,7 +8006,18 @@ function usePasskeyCheckEffect(deps) {
7925
8006
  if (token || cancelled) break;
7926
8007
  await new Promise((r) => setTimeout(r, 1e3));
7927
8008
  }
7928
- if (!token || cancelled) return;
8009
+ if (cancelled) return;
8010
+ if (!token) {
8011
+ dispatch({
8012
+ type: "PASSKEY_CONFIG_LOADED",
8013
+ knownIds: []
8014
+ });
8015
+ dispatch({
8016
+ type: "SET_ERROR",
8017
+ error: "Could not refresh your session. Try signing in again."
8018
+ });
8019
+ return;
8020
+ }
7929
8021
  const { config } = await fetchUserConfig(apiBaseUrl, token);
7930
8022
  if (cancelled) return;
7931
8023
  const allPasskeys = config.passkeys ?? (config.passkey ? [config.passkey] : []);
@@ -7936,6 +8028,10 @@ function usePasskeyCheckEffect(deps) {
7936
8028
  });
7937
8029
  if (allPasskeys.length === 0) return;
7938
8030
  if (activeCredentialId && allPasskeys.some((p) => p.credentialId === activeCredentialId)) {
8031
+ const pk = allPasskeys.find((p) => p.credentialId === activeCredentialId)?.publicKey;
8032
+ if (pk) {
8033
+ dispatch({ type: "PASSKEY_ACTIVATED", credentialId: activeCredentialId, publicKey: pk });
8034
+ }
7939
8035
  await restoreState(activeCredentialId, token);
7940
8036
  return;
7941
8037
  }
@@ -7954,13 +8050,22 @@ function usePasskeyCheckEffect(deps) {
7954
8050
  }
7955
8051
  if (cancelled) return;
7956
8052
  if (matched) {
7957
- dispatch({ type: "PASSKEY_ACTIVATED", credentialId: matched });
8053
+ const publicKey = allPasskeys.find((p) => p.credentialId === matched)?.publicKey;
8054
+ dispatch({ type: "PASSKEY_ACTIVATED", credentialId: matched, publicKey });
7958
8055
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
7959
8056
  reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
7960
8057
  });
7961
8058
  await restoreState(matched, token);
7962
8059
  }
7963
- } catch {
8060
+ } catch (err) {
8061
+ dispatch({
8062
+ type: "PASSKEY_CONFIG_LOADED",
8063
+ knownIds: []
8064
+ });
8065
+ dispatch({
8066
+ type: "SET_ERROR",
8067
+ error: err instanceof Error ? err.message : "Unable to load passkey settings."
8068
+ });
7964
8069
  }
7965
8070
  };
7966
8071
  checkPasskey();
@@ -8513,19 +8618,15 @@ function useGuestPreauthPhaseSyncEffect(deps) {
8513
8618
  const intent = {
8514
8619
  step: "select-source",
8515
8620
  action: pending,
8516
- isDesktop,
8517
- skipOneTapLimit: true
8621
+ isDesktop
8518
8622
  };
8519
- if (state.phase.step === "select-source") {
8520
- const ph = state.phase;
8521
- if (ph.skipOneTapLimit && ph.action.id === pending.id) {
8522
- return;
8523
- }
8623
+ if (state.phase.step === "select-source" && state.phase.action.id === pending.id) {
8624
+ return;
8524
8625
  }
8525
8626
  dispatch({ type: "SET_USER_INTENT", intent });
8526
8627
  return;
8527
8628
  }
8528
- if (state.phase.step === "select-source" && state.phase.skipOneTapLimit === true) {
8629
+ if (state.phase.step === "select-source") {
8529
8630
  dispatch({ type: "SET_USER_INTENT", intent: { step: "one-tap-setup", action: null } });
8530
8631
  }
8531
8632
  }, [
@@ -8654,7 +8755,8 @@ function BlinkPaymentInner({
8654
8755
  apiBaseUrl,
8655
8756
  authExecutor,
8656
8757
  selectSourceChainName: sourceSelection.selectSourceChainName,
8657
- selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol
8758
+ selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol,
8759
+ authorizationSessionIdForGuest: state.guestPreauthSessionId
8658
8760
  });
8659
8761
  const guestTransfer = useGuestTransferHandlers({
8660
8762
  dispatch,
@@ -8687,13 +8789,14 @@ function BlinkPaymentInner({
8687
8789
  passkey.checkingPasskeyRef.current = false;
8688
8790
  auth.setAuthInput("");
8689
8791
  auth.setOtpCode("");
8690
- dispatch({ type: "LOGOUT", depositAmount });
8691
- }, [logout, polling, depositAmount, auth, passkey]);
8792
+ dispatch({ type: "LOGOUT", depositAmount, privyReady: ready });
8793
+ }, [logout, polling, depositAmount, auth, passkey, ready]);
8692
8794
  useEffect(() => {
8693
8795
  if (depositAmount != null) {
8694
8796
  dispatch({ type: "SYNC_AMOUNT", amount: depositAmount.toString() });
8695
8797
  }
8696
8798
  }, [depositAmount, dispatch]);
8799
+ usePrivySessionSyncEffect({ dispatch, ready, authenticated });
8697
8800
  useOtpEffects({
8698
8801
  state,
8699
8802
  dispatch,
@@ -8827,6 +8930,7 @@ function BlinkPaymentInner({
8827
8930
  onSelectAuthorizedToken: provider.handleSelectAuthorizedToken,
8828
8931
  onAuthorizeToken: provider.handleAuthorizeToken,
8829
8932
  onSelectGuestToken: guestTransfer.handleSelectGuestToken,
8933
+ onGuestBackFromTokenPicker: guestTransfer.handleGuestBackFromTokenPicker,
8830
8934
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
8831
8935
  onPreauthorize: provider.handlePreauthorize
8832
8936
  }), [