@swype-org/react-sdk 0.1.237 → 0.1.251

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
@@ -828,7 +828,7 @@ interface NormalizedAuthIdentifier {
828
828
  value: string;
829
829
  }
830
830
 
831
- type ScreenName = 'loading' | 'login' | 'otp-verify' | 'create-passkey' | 'verify-passkey' | 'success' | 'processing' | 'confirm-sign' | 'select-source' | 'setup' | 'open-wallet' | 'setup-status' | 'guest-token-picker' | 'wallet-picker' | 'token-picker' | 'deposit';
831
+ type ScreenName = 'loading' | 'login' | 'otp-verify' | 'create-passkey' | 'verify-passkey' | 'success' | 'processing' | 'confirm-sign' | 'select-source' | 'setup' | 'open-wallet' | 'setup-status' | 'guest-token-picker' | 'wallet-picker' | 'token-picker' | 'deposit' | 'guest-setup-complete';
832
832
  interface MobileFlowState {
833
833
  deeplinkUri: string;
834
834
  providerId: string | null;
@@ -854,6 +854,8 @@ type PaymentPhase = {
854
854
  step: 'wallet-setup';
855
855
  mobile: MobileFlowState | null;
856
856
  accountId: string | null;
857
+ /** Desktop: use OpenWalletScreen (extension popups) instead of SetupStatusScreen. */
858
+ guestDesktopExtension?: boolean;
857
859
  } | {
858
860
  step: 'select-source';
859
861
  action: AuthorizationAction;
@@ -880,6 +882,8 @@ type PaymentPhase = {
880
882
  step: 'failed';
881
883
  transfer: Transfer;
882
884
  error: string;
885
+ } | {
886
+ step: 'guest-setup-complete';
883
887
  };
884
888
  declare function screenForPhase(phase: PaymentPhase): ScreenName;
885
889
 
package/dist/index.d.ts CHANGED
@@ -828,7 +828,7 @@ interface NormalizedAuthIdentifier {
828
828
  value: string;
829
829
  }
830
830
 
831
- type ScreenName = 'loading' | 'login' | 'otp-verify' | 'create-passkey' | 'verify-passkey' | 'success' | 'processing' | 'confirm-sign' | 'select-source' | 'setup' | 'open-wallet' | 'setup-status' | 'guest-token-picker' | 'wallet-picker' | 'token-picker' | 'deposit';
831
+ type ScreenName = 'loading' | 'login' | 'otp-verify' | 'create-passkey' | 'verify-passkey' | 'success' | 'processing' | 'confirm-sign' | 'select-source' | 'setup' | 'open-wallet' | 'setup-status' | 'guest-token-picker' | 'wallet-picker' | 'token-picker' | 'deposit' | 'guest-setup-complete';
832
832
  interface MobileFlowState {
833
833
  deeplinkUri: string;
834
834
  providerId: string | null;
@@ -854,6 +854,8 @@ type PaymentPhase = {
854
854
  step: 'wallet-setup';
855
855
  mobile: MobileFlowState | null;
856
856
  accountId: string | null;
857
+ /** Desktop: use OpenWalletScreen (extension popups) instead of SetupStatusScreen. */
858
+ guestDesktopExtension?: boolean;
857
859
  } | {
858
860
  step: 'select-source';
859
861
  action: AuthorizationAction;
@@ -880,6 +882,8 @@ type PaymentPhase = {
880
882
  step: 'failed';
881
883
  transfer: Transfer;
882
884
  error: string;
885
+ } | {
886
+ step: 'guest-setup-complete';
883
887
  };
884
888
  declare function screenForPhase(phase: PaymentPhase): ScreenName;
885
889
 
package/dist/index.js CHANGED
@@ -2001,16 +2001,41 @@ function isTransferInFlight(transfer) {
2001
2001
  if (!transfer) return false;
2002
2002
  return ["CREATED", "SENDING", "SENT"].includes(transfer.status);
2003
2003
  }
2004
+ function isGuestPreauthCompletedTransferPinPhase(phase) {
2005
+ switch (phase.step) {
2006
+ case "completed":
2007
+ case "select-source":
2008
+ case "one-tap-setup":
2009
+ case "token-picker":
2010
+ case "login":
2011
+ // otp-verify not pinned: after OTP, verificationTarget clears but phase can be stale until
2012
+ // resolvePhase runs; pinning would block passkey.
2013
+ case "passkey-create":
2014
+ case "passkey-verify":
2015
+ case "data-loading":
2016
+ return true;
2017
+ case "wallet-setup":
2018
+ return phase.mobile == null;
2019
+ default:
2020
+ return false;
2021
+ }
2022
+ }
2004
2023
  function resolvePhase(state) {
2005
2024
  const p = state.phase;
2006
- if (p.step === "select-source" && state.transfer?.status === "COMPLETED" && state.guestPreauthorizing) {
2025
+ if (state.guestPreauthSetupCompletePending && state.privyReady && state.privyAuthenticated) {
2026
+ return { step: "guest-setup-complete" };
2027
+ }
2028
+ if (state.transfer?.status === "COMPLETED" && state.guestPreauthorizing && !state.verificationTarget && isGuestPreauthCompletedTransferPinPhase(p)) {
2007
2029
  return p;
2008
2030
  }
2009
- if (state.transfer?.status === "COMPLETED" && state.guestPreauthorizing) {
2010
- return { step: "processing", transfer: state.transfer };
2031
+ if (state.transfer?.status === "COMPLETED" && state.isGuestFlow && state.guestPreauthSessionId && !state.guestPreauthorizing && !state.verificationTarget && !state.privyAuthenticated) {
2032
+ return { step: "login" };
2011
2033
  }
2012
- if (state.transfer?.status === "COMPLETED") {
2013
- return { step: "completed", transfer: state.transfer };
2034
+ if (state.transfer?.status === "COMPLETED" && !state.verificationTarget) {
2035
+ const needsPasskeyBootstrap = state.privyAuthenticated && !state.activeCredentialId;
2036
+ if (!needsPasskeyBootstrap) {
2037
+ return { step: "completed", transfer: state.transfer };
2038
+ }
2014
2039
  }
2015
2040
  if (state.transfer?.status === "FAILED") {
2016
2041
  return { step: "failed", transfer: state.transfer, error: state.error ?? "Transfer failed." };
@@ -2018,7 +2043,7 @@ function resolvePhase(state) {
2018
2043
  if (state.creatingTransfer || isTransferInFlight(state.transfer)) {
2019
2044
  return { step: "processing", transfer: state.transfer };
2020
2045
  }
2021
- if (p.step === "token-picker" || p.step === "one-tap-setup" || p.step === "select-source" || p.step === "confirm-sign" || p.step === "guest-token-picker") {
2046
+ if (!state.loginRequested && (p.step === "token-picker" || p.step === "one-tap-setup" || p.step === "select-source" || p.step === "confirm-sign" || p.step === "guest-token-picker")) {
2022
2047
  return p;
2023
2048
  }
2024
2049
  if (state.mobileFlow && state.deeplinkUri) {
@@ -2028,10 +2053,10 @@ function resolvePhase(state) {
2028
2053
  accountId: null
2029
2054
  };
2030
2055
  }
2031
- if (p.step === "wallet-setup" && p.mobile == null) {
2056
+ if (p.step === "wallet-setup" && p.mobile == null && state.guestPreauthorizing) {
2032
2057
  return p;
2033
2058
  }
2034
- if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer) {
2059
+ if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer && !state.guestPreauthAccountId) {
2035
2060
  return { step: "guest-token-picker" };
2036
2061
  }
2037
2062
  if (p.step === "wallet-picker" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri)) {
@@ -2043,7 +2068,7 @@ function resolvePhase(state) {
2043
2068
  if (state.privyAuthenticated && !state.activeCredentialId && !state.passkeyConfigLoaded) {
2044
2069
  return { step: "initializing" };
2045
2070
  }
2046
- if (state.verificationTarget) {
2071
+ if (state.verificationTarget && !state.privyAuthenticated) {
2047
2072
  return { step: "otp-verify", target: state.verificationTarget };
2048
2073
  }
2049
2074
  if (state.loginRequested) {
@@ -2115,13 +2140,26 @@ function createInitialState(config) {
2115
2140
  activePublicKey: null,
2116
2141
  loginRequested: false,
2117
2142
  guestPreauthorizing: false,
2143
+ guestPreauthSetupCompletePending: false,
2118
2144
  privyReady: false,
2119
2145
  privyAuthenticated: false
2120
2146
  };
2121
2147
  }
2122
2148
  function paymentReducer(state, action) {
2123
2149
  const next = applyAction(state, action);
2124
- return { ...next, phase: resolvePhase(next) };
2150
+ const phase = resolvePhase(next);
2151
+ if (action.type === "CODE_SENT") {
2152
+ console.debug("[Swype SDK] login code sent", {
2153
+ resolvedPhase: phase.step,
2154
+ verificationTargetKind: action.target.kind,
2155
+ guestPreauthorizing: next.guestPreauthorizing,
2156
+ transferStatus: next.transfer?.status ?? null,
2157
+ isGuestFlow: next.isGuestFlow,
2158
+ hasGuestPreauthSessionId: next.guestPreauthSessionId != null,
2159
+ loginRequested: next.loginRequested
2160
+ });
2161
+ }
2162
+ return { ...next, phase };
2125
2163
  }
2126
2164
  function applyAction(state, action) {
2127
2165
  switch (action.type) {
@@ -2382,13 +2420,20 @@ function applyAction(state, action) {
2382
2420
  case "ACCOUNT_OWNER_SET":
2383
2421
  return {
2384
2422
  ...state,
2423
+ transfer: null,
2385
2424
  guestPreauthAccountId: null,
2386
2425
  guestPreauthSessionId: null,
2387
2426
  activePublicKey: null,
2388
2427
  error: null,
2389
2428
  guestPreauthorizing: false,
2390
- phase: { step: "one-tap-setup", action: null }
2429
+ isGuestFlow: false,
2430
+ selectedProviderId: null,
2431
+ guestTransferId: null,
2432
+ guestSessionToken: null,
2433
+ guestPreauthSetupCompletePending: true
2391
2434
  };
2435
+ case "GUEST_PREAUTH_SETUP_COMPLETE_DISMISSED":
2436
+ return { ...state, guestPreauthSetupCompletePending: false };
2392
2437
  // ── User intent & error ──────────────────────────────────────
2393
2438
  case "SET_USER_INTENT":
2394
2439
  return { ...state, phase: action.intent };
@@ -2423,7 +2468,8 @@ function applyAction(state, action) {
2423
2468
  activePublicKey: null,
2424
2469
  loginRequested: false,
2425
2470
  oneTapLimitSavedDuringSetup: false,
2426
- guestPreauthorizing: false
2471
+ guestPreauthorizing: false,
2472
+ guestPreauthSetupCompletePending: false
2427
2473
  };
2428
2474
  case "LOGOUT":
2429
2475
  return {
@@ -2439,7 +2485,10 @@ function applyAction(state, action) {
2439
2485
  return {
2440
2486
  ...state,
2441
2487
  privyReady: action.ready,
2442
- privyAuthenticated: action.authenticated
2488
+ privyAuthenticated: action.authenticated,
2489
+ // OTP complete: Privy is source of truth; clear so resolvePhase can leave otp-verify
2490
+ // and guest-preauth pin rules cannot re-pin a stale otp-verify phase.
2491
+ ...action.authenticated ? { verificationTarget: null, loginRequested: false } : {}
2443
2492
  };
2444
2493
  case "SYNC_AMOUNT":
2445
2494
  return { ...state, amount: action.amount };
@@ -2505,7 +2554,10 @@ function screenForPhase(phase) {
2505
2554
  case "wallet-picker":
2506
2555
  return "wallet-picker";
2507
2556
  case "wallet-setup":
2508
- return phase.mobile ? "open-wallet" : "setup-status";
2557
+ if (phase.mobile || phase.guestDesktopExtension) {
2558
+ return "open-wallet";
2559
+ }
2560
+ return "setup-status";
2509
2561
  case "select-source":
2510
2562
  return phase.isDesktop ? "setup" : "select-source";
2511
2563
  case "one-tap-setup":
@@ -2523,6 +2575,8 @@ function screenForPhase(phase) {
2523
2575
  case "completed":
2524
2576
  case "failed":
2525
2577
  return "success";
2578
+ case "guest-setup-complete":
2579
+ return "guest-setup-complete";
2526
2580
  }
2527
2581
  }
2528
2582
  var MUTED = "#7fa4b0";
@@ -5992,6 +6046,60 @@ var emptyStyle = (color) => ({
5992
6046
  padding: "32px 0",
5993
6047
  lineHeight: 1.5
5994
6048
  });
6049
+ function GuestPreauthSetupCompleteScreen({
6050
+ onClose,
6051
+ onLogout
6052
+ }) {
6053
+ const { tokens } = useBlinkConfig();
6054
+ return /* @__PURE__ */ jsxs(
6055
+ ScreenLayout,
6056
+ {
6057
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
6058
+ /* @__PURE__ */ jsx(PrimaryButton, { onClick: onClose, children: "Close" }),
6059
+ /* @__PURE__ */ jsx(PoweredByFooter, {})
6060
+ ] }),
6061
+ children: [
6062
+ /* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
6063
+ /* @__PURE__ */ jsxs("div", { style: contentStyle9, children: [
6064
+ /* @__PURE__ */ jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
6065
+ "path",
6066
+ {
6067
+ d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z",
6068
+ fill: tokens.success
6069
+ }
6070
+ ) }) }),
6071
+ /* @__PURE__ */ jsx("h2", { style: headingStyle12(tokens.text), children: "Setup complete" }),
6072
+ /* @__PURE__ */ jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: "Your account is linked and ready. You can close this window or make another deposit." })
6073
+ ] })
6074
+ ]
6075
+ }
6076
+ );
6077
+ }
6078
+ var contentStyle9 = {
6079
+ display: "flex",
6080
+ flexDirection: "column",
6081
+ alignItems: "center",
6082
+ textAlign: "center",
6083
+ gap: 12,
6084
+ paddingTop: 8
6085
+ };
6086
+ function headingStyle12(color) {
6087
+ return {
6088
+ margin: 0,
6089
+ fontSize: 22,
6090
+ fontWeight: 600,
6091
+ color
6092
+ };
6093
+ }
6094
+ function subtitleStyle10(color) {
6095
+ return {
6096
+ margin: 0,
6097
+ fontSize: 15,
6098
+ lineHeight: 1.45,
6099
+ color,
6100
+ maxWidth: 320
6101
+ };
6102
+ }
5995
6103
  var LINK_SCREENS = /* @__PURE__ */ new Set([
5996
6104
  "create-passkey",
5997
6105
  "verify-passkey",
@@ -6042,7 +6150,8 @@ function StepRendererContent({
6042
6150
  pollingError,
6043
6151
  authExecutorError,
6044
6152
  transferSigningSigning,
6045
- transferSigningError
6153
+ transferSigningError,
6154
+ pendingSelectSource
6046
6155
  } = remote;
6047
6156
  const {
6048
6157
  pendingConnections,
@@ -6242,6 +6351,26 @@ function StepRendererContent({
6242
6351
  }
6243
6352
  case "token-picker": {
6244
6353
  if (!selectedAccount) {
6354
+ if (pendingSelectSource && selectSourceChoices.length > 0) {
6355
+ return /* @__PURE__ */ jsx(
6356
+ SelectSourceScreen,
6357
+ {
6358
+ choices: selectSourceChoices,
6359
+ selectedChainName: selectSourceChainName,
6360
+ selectedTokenSymbol: selectSourceTokenSymbol,
6361
+ recommended: selectSourceRecommended,
6362
+ onChainChange: handlers.onSelectSourceChainChange,
6363
+ onTokenChange: handlers.onSetSelectSourceTokenSymbol,
6364
+ onConfirm: handlers.onConfirmSelectSource,
6365
+ onBack: () => handlers.onSetPhase({
6366
+ step: "select-source",
6367
+ action: pendingSelectSource,
6368
+ isDesktop
6369
+ }),
6370
+ onLogout: handlers.onLogout
6371
+ }
6372
+ );
6373
+ }
6245
6374
  return /* @__PURE__ */ jsx(BlinkLoadingScreen, {});
6246
6375
  }
6247
6376
  return /* @__PURE__ */ jsx(
@@ -6272,6 +6401,14 @@ function StepRendererContent({
6272
6401
  onBack: handlers.onGuestBackFromTokenPicker
6273
6402
  }
6274
6403
  );
6404
+ case "guest-setup-complete":
6405
+ return /* @__PURE__ */ jsx(
6406
+ GuestPreauthSetupCompleteScreen,
6407
+ {
6408
+ onClose: handlers.onGuestSetupCompleteClose,
6409
+ onLogout: handlers.onLogout
6410
+ }
6411
+ );
6275
6412
  case "processing": {
6276
6413
  const polledStatus = pollingTransfer?.status;
6277
6414
  const transferPhase = state.creatingTransfer ? "creating" : polledStatus === "SENDING" || polledStatus === "SENT" ? "sent" : "verifying";
@@ -6365,7 +6502,7 @@ var PaymentErrorBoundary = class extends Component {
6365
6502
  /* @__PURE__ */ jsx("path", { d: "M12 8v5", stroke: "#ef4444", strokeWidth: "1.5", strokeLinecap: "round" }),
6366
6503
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "16", r: "0.75", fill: "#ef4444" })
6367
6504
  ] }) }),
6368
- /* @__PURE__ */ jsx("h2", { style: headingStyle12, children: "Something went wrong" }),
6505
+ /* @__PURE__ */ jsx("h2", { style: headingStyle13, children: "Something went wrong" }),
6369
6506
  /* @__PURE__ */ jsx("p", { style: messageStyle, children: "An unexpected error occurred. Please try again." }),
6370
6507
  /* @__PURE__ */ jsx("button", { type: "button", onClick: this.handleReset, style: buttonStyle3, children: "Try again" })
6371
6508
  ] });
@@ -6385,7 +6522,7 @@ var containerStyle9 = {
6385
6522
  var iconStyle3 = {
6386
6523
  marginBottom: 20
6387
6524
  };
6388
- var headingStyle12 = {
6525
+ var headingStyle13 = {
6389
6526
  fontSize: "1.25rem",
6390
6527
  fontWeight: 700,
6391
6528
  color: "#1a1a1a",
@@ -6839,15 +6976,15 @@ function useTransferHandlers(deps) {
6839
6976
  pollingTransferIdRef
6840
6977
  };
6841
6978
  }
6842
- function useSourceSelectionHandlers(dispatch, authExecutor) {
6979
+ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
6843
6980
  const [selectSourceChainName, setSelectSourceChainName] = useState("");
6844
6981
  const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = useState("");
6845
6982
  const initializedSelectSourceActionRef = useRef(null);
6846
6983
  const pendingSelectSourceAction = authExecutor.pendingSelectSource;
6847
6984
  const selectSourceChoices = useMemo(() => {
6848
6985
  if (!pendingSelectSourceAction) return [];
6849
- const options = pendingSelectSourceAction.metadata?.options ?? [];
6850
- return buildSelectSourceChoices(options);
6986
+ const options2 = pendingSelectSourceAction.metadata?.options ?? [];
6987
+ return buildSelectSourceChoices(options2);
6851
6988
  }, [pendingSelectSourceAction]);
6852
6989
  const selectSourceRecommended = useMemo(() => {
6853
6990
  if (!pendingSelectSourceAction) return null;
@@ -6855,16 +6992,16 @@ function useSourceSelectionHandlers(dispatch, authExecutor) {
6855
6992
  }, [pendingSelectSourceAction]);
6856
6993
  const selectSourceAvailableBalance = useMemo(() => {
6857
6994
  if (!pendingSelectSourceAction) return 0;
6858
- const options = pendingSelectSourceAction.metadata?.options ?? [];
6995
+ const options2 = pendingSelectSourceAction.metadata?.options ?? [];
6859
6996
  const recommended = selectSourceRecommended;
6860
6997
  if (recommended) {
6861
- const match = options.find(
6998
+ const match = options2.find(
6862
6999
  (opt) => opt.chainName === recommended.chainName && opt.tokenSymbol === recommended.tokenSymbol
6863
7000
  );
6864
7001
  if (match) return Number(match.rawBalance) / Math.pow(10, match.decimals);
6865
7002
  }
6866
7003
  let max = 0;
6867
- for (const opt of options) {
7004
+ for (const opt of options2) {
6868
7005
  const bal = Number(opt.rawBalance) / Math.pow(10, opt.decimals);
6869
7006
  if (bal > max) max = bal;
6870
7007
  }
@@ -6884,11 +7021,34 @@ function useSourceSelectionHandlers(dispatch, authExecutor) {
6884
7021
  [selectSourceChoices, selectSourceRecommended]
6885
7022
  );
6886
7023
  const handleConfirmSelectSource = useCallback(() => {
7024
+ const guestPostPayPreauth = !!options?.guestPreauthSessionId && !!options?.isGuestFlow || !!options?.guestPreauthorizing && !!options?.isDesktop;
7025
+ if (guestPostPayPreauth) {
7026
+ dispatch({ type: "REQUEST_LOGIN" });
7027
+ if (options?.guestPreauthAccountId != null) {
7028
+ const intent = {
7029
+ step: "wallet-setup",
7030
+ mobile: null,
7031
+ accountId: options.guestPreauthAccountId,
7032
+ guestDesktopExtension: true
7033
+ };
7034
+ dispatch({ type: "SET_USER_INTENT", intent });
7035
+ }
7036
+ }
6887
7037
  authExecutor.resolveSelectSource({
6888
7038
  chainName: selectSourceChainName,
6889
7039
  tokenSymbol: selectSourceTokenSymbol
6890
7040
  });
6891
- }, [authExecutor, selectSourceChainName, selectSourceTokenSymbol]);
7041
+ }, [
7042
+ authExecutor,
7043
+ dispatch,
7044
+ options?.guestPreauthSessionId,
7045
+ options?.guestPreauthAccountId,
7046
+ options?.guestPreauthorizing,
7047
+ options?.isDesktop,
7048
+ options?.isGuestFlow,
7049
+ selectSourceChainName,
7050
+ selectSourceTokenSymbol
7051
+ ]);
6892
7052
  return {
6893
7053
  selectSourceChainName,
6894
7054
  selectSourceTokenSymbol,
@@ -8262,6 +8422,10 @@ function useProcessingEffect(deps) {
8262
8422
  } = deps;
8263
8423
  useEffect(() => {
8264
8424
  if (!polling.transfer) return;
8425
+ if (state.loginRequested || state.verificationTarget) return;
8426
+ if (!state.transfer && (polling.transfer.status === "COMPLETED" || polling.transfer.status === "FAILED")) {
8427
+ return;
8428
+ }
8265
8429
  if (polling.transfer.status === "COMPLETED") {
8266
8430
  clearMobileFlowState();
8267
8431
  dispatch({ type: "TRANSFER_COMPLETED", transfer: polling.transfer });
@@ -8271,7 +8435,15 @@ function useProcessingEffect(deps) {
8271
8435
  clearMobileFlowState();
8272
8436
  dispatch({ type: "TRANSFER_FAILED", transfer: polling.transfer, error: "Transfer failed." });
8273
8437
  }
8274
- }, [polling.transfer, onComplete, dispatch, reloadAccounts]);
8438
+ }, [
8439
+ polling.transfer,
8440
+ state.transfer,
8441
+ state.loginRequested,
8442
+ state.verificationTarget,
8443
+ onComplete,
8444
+ dispatch,
8445
+ reloadAccounts
8446
+ ]);
8275
8447
  useEffect(() => {
8276
8448
  const isProcessing = state.creatingTransfer || state.transfer != null && ["CREATED", "SENDING", "SENT"].includes(state.transfer.status);
8277
8449
  if (!isProcessing) {
@@ -8522,6 +8694,42 @@ function useOneTapAutoResolveEffect(deps) {
8522
8694
  }
8523
8695
  }, [pendingOneTapSetupAction, reloadAccounts, oneTapLimitSavedDuringSetup]);
8524
8696
  }
8697
+
8698
+ // src/guestPreauthClaimWait.ts
8699
+ var GUEST_PREAUTH_SESSION_POLL_INTERVAL_MS = 1e3;
8700
+ var GUEST_PREAUTH_SESSION_POLL_TIMEOUT_MS = 12e4;
8701
+ async function waitForGuestPreauthAuthorizationSession(apiBaseUrl, sessionId, fetchSession, signal, options) {
8702
+ const intervalMs = GUEST_PREAUTH_SESSION_POLL_INTERVAL_MS;
8703
+ const timeoutMs = GUEST_PREAUTH_SESSION_POLL_TIMEOUT_MS;
8704
+ const deadline = Date.now() + timeoutMs;
8705
+ const sleepAbortable = (ms) => new Promise((resolve, reject) => {
8706
+ if (signal.aborted) {
8707
+ reject(new DOMException("Aborted", "AbortError"));
8708
+ return;
8709
+ }
8710
+ const t = setTimeout(() => {
8711
+ signal.removeEventListener("abort", onAbort);
8712
+ resolve();
8713
+ }, ms);
8714
+ const onAbort = () => {
8715
+ clearTimeout(t);
8716
+ signal.removeEventListener("abort", onAbort);
8717
+ reject(new DOMException("Aborted", "AbortError"));
8718
+ };
8719
+ signal.addEventListener("abort", onAbort, { once: true });
8720
+ });
8721
+ while (Date.now() < deadline) {
8722
+ if (signal.aborted) {
8723
+ throw new DOMException("Aborted", "AbortError");
8724
+ }
8725
+ const session = await fetchSession(apiBaseUrl, sessionId);
8726
+ if (session.status === "AUTHORIZED") return;
8727
+ await sleepAbortable(intervalMs);
8728
+ }
8729
+ throw new Error("Authorization session did not become AUTHORIZED in time.");
8730
+ }
8731
+
8732
+ // src/hooks/useGuestPreauthEffect.ts
8525
8733
  function useGuestPreauthEffect(deps) {
8526
8734
  const { state, dispatch, authenticated, apiBaseUrl, reloadAccounts } = deps;
8527
8735
  const { getAccessToken } = usePrivy();
@@ -8535,12 +8743,25 @@ function useGuestPreauthEffect(deps) {
8535
8743
  if (!authenticated) return;
8536
8744
  if (!state.guestSessionToken) return;
8537
8745
  if (settingOwnerRef.current) return;
8538
- const hasActive = state.accounts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
8539
- if (!hasActive) return;
8540
8746
  settingOwnerRef.current = true;
8747
+ const abort = new AbortController();
8541
8748
  let cancelled = false;
8542
8749
  const setOwner = async () => {
8543
8750
  try {
8751
+ if (state.guestPreauthSessionId) {
8752
+ try {
8753
+ await waitForGuestPreauthAuthorizationSession(
8754
+ apiBaseUrl,
8755
+ state.guestPreauthSessionId,
8756
+ fetchAuthorizationSession,
8757
+ abort.signal
8758
+ );
8759
+ } catch (waitErr) {
8760
+ if (waitErr instanceof DOMException && waitErr.name === "AbortError") return;
8761
+ throw waitErr;
8762
+ }
8763
+ }
8764
+ if (cancelled) return;
8544
8765
  const token = await getAccessTokenRef.current();
8545
8766
  if (!token || cancelled) return;
8546
8767
  await setAccountOwner(apiBaseUrl, token, state.guestPreauthAccountId, state.guestSessionToken, {
@@ -8565,16 +8786,17 @@ function useGuestPreauthEffect(deps) {
8565
8786
  settingOwnerRef.current = false;
8566
8787
  }
8567
8788
  };
8568
- setOwner();
8789
+ void setOwner();
8569
8790
  return () => {
8570
8791
  cancelled = true;
8792
+ abort.abort();
8571
8793
  };
8572
8794
  }, [
8573
8795
  state.guestPreauthAccountId,
8796
+ state.guestPreauthSessionId,
8574
8797
  state.activeCredentialId,
8575
8798
  state.activePublicKey,
8576
8799
  state.guestSessionToken,
8577
- state.accounts,
8578
8800
  authenticated,
8579
8801
  apiBaseUrl,
8580
8802
  dispatch,
@@ -8615,6 +8837,9 @@ function useGuestPreauthPhaseSyncEffect(deps) {
8615
8837
  if (!state.guestPreauthorizing || !isDesktop) return;
8616
8838
  const pending = authExecutor.pendingSelectSource;
8617
8839
  if (pending) {
8840
+ if (state.phase.step === "token-picker") {
8841
+ return;
8842
+ }
8618
8843
  const intent = {
8619
8844
  step: "select-source",
8620
8845
  action: pending,
@@ -8628,6 +8853,10 @@ function useGuestPreauthPhaseSyncEffect(deps) {
8628
8853
  }
8629
8854
  if (state.phase.step === "select-source") {
8630
8855
  dispatch({ type: "SET_USER_INTENT", intent: { step: "one-tap-setup", action: null } });
8856
+ return;
8857
+ }
8858
+ if (state.phase.step === "token-picker") {
8859
+ dispatch({ type: "SET_USER_INTENT", intent: { step: "one-tap-setup", action: null } });
8631
8860
  }
8632
8861
  }, [
8633
8862
  state.guestPreauthorizing,
@@ -8637,6 +8866,38 @@ function useGuestPreauthPhaseSyncEffect(deps) {
8637
8866
  dispatch
8638
8867
  ]);
8639
8868
  }
8869
+ function useGuestPreauthWalletSetupEffect(deps) {
8870
+ const { state, dispatch, authExecutor, isDesktop } = deps;
8871
+ useEffect(() => {
8872
+ if (!isDesktop || !state.guestPreauthorizing || !state.guestPreauthSessionId) return;
8873
+ if (!state.guestPreauthAccountId) return;
8874
+ if (!authExecutor.executing || authExecutor.pendingSelectSource) return;
8875
+ if (state.verificationTarget) return;
8876
+ const p = state.phase;
8877
+ if (p.step === "wallet-setup" && p.mobile == null && p.guestDesktopExtension && p.accountId === state.guestPreauthAccountId) {
8878
+ return;
8879
+ }
8880
+ dispatch({
8881
+ type: "SET_USER_INTENT",
8882
+ intent: {
8883
+ step: "wallet-setup",
8884
+ mobile: null,
8885
+ accountId: state.guestPreauthAccountId,
8886
+ guestDesktopExtension: true
8887
+ }
8888
+ });
8889
+ }, [
8890
+ isDesktop,
8891
+ state.guestPreauthorizing,
8892
+ state.guestPreauthSessionId,
8893
+ state.guestPreauthAccountId,
8894
+ state.verificationTarget,
8895
+ state.phase,
8896
+ authExecutor.executing,
8897
+ authExecutor.pendingSelectSource,
8898
+ dispatch
8899
+ ]);
8900
+ }
8640
8901
  function BlinkPayment(props) {
8641
8902
  const resetKey = useRef(0);
8642
8903
  const handleBoundaryReset = useCallback(() => {
@@ -8721,7 +8982,13 @@ function BlinkPaymentInner({
8721
8982
  mobileFlowRefs,
8722
8983
  onComplete
8723
8984
  );
8724
- const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor);
8985
+ const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor, {
8986
+ guestPreauthSessionId: state.guestPreauthSessionId,
8987
+ guestPreauthAccountId: state.guestPreauthAccountId,
8988
+ isGuestFlow: state.isGuestFlow,
8989
+ guestPreauthorizing: state.guestPreauthorizing,
8990
+ isDesktop
8991
+ });
8725
8992
  const provider = useProviderHandlers({
8726
8993
  dispatch,
8727
8994
  getAccessToken,
@@ -8894,6 +9161,12 @@ function BlinkPaymentInner({
8894
9161
  dispatch,
8895
9162
  desktopGuestPreauth: isDesktop
8896
9163
  });
9164
+ useGuestPreauthWalletSetupEffect({
9165
+ state,
9166
+ dispatch,
9167
+ authExecutor,
9168
+ isDesktop
9169
+ });
8897
9170
  const handlers = useMemo(() => ({
8898
9171
  onSendLoginCode: auth.handleSendLoginCode,
8899
9172
  onVerifyLoginCode: auth.handleVerifyLoginCode,
@@ -8932,7 +9205,11 @@ function BlinkPaymentInner({
8932
9205
  onSelectGuestToken: guestTransfer.handleSelectGuestToken,
8933
9206
  onGuestBackFromTokenPicker: guestTransfer.handleGuestBackFromTokenPicker,
8934
9207
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
8935
- onPreauthorize: provider.handlePreauthorize
9208
+ onPreauthorize: provider.handlePreauthorize,
9209
+ onGuestSetupCompleteClose: () => {
9210
+ dispatch({ type: "GUEST_PREAUTH_SETUP_COMPLETE_DISMISSED" });
9211
+ onDismiss?.();
9212
+ }
8936
9213
  }), [
8937
9214
  auth,
8938
9215
  passkey,
@@ -8943,7 +9220,9 @@ function BlinkPaymentInner({
8943
9220
  oneTapSetup,
8944
9221
  guestTransfer,
8945
9222
  handleLogout,
8946
- handleNewPayment
9223
+ handleNewPayment,
9224
+ onDismiss,
9225
+ dispatch
8947
9226
  ]);
8948
9227
  return /* @__PURE__ */ jsx(
8949
9228
  StepRenderer,