@swype-org/react-sdk 0.1.226 → 0.1.227

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.cjs CHANGED
@@ -1935,9 +1935,7 @@ function deriveSourceTypeAndId(state) {
1935
1935
  return { sourceType: "accountId", sourceId: "" };
1936
1936
  }
1937
1937
  function createInitialState(config) {
1938
- const isReturningUser = config.activeCredentialId != null;
1939
1938
  return {
1940
- step: isReturningUser ? "login" : "wallet-picker",
1941
1939
  error: null,
1942
1940
  providers: [],
1943
1941
  accounts: [],
@@ -1953,6 +1951,7 @@ function createInitialState(config) {
1953
1951
  registeringPasskey: false,
1954
1952
  verifyingPasskeyPopup: false,
1955
1953
  passkeyPopupNeeded: config.passkeyPopupNeeded,
1954
+ passkeyConfigLoaded: false,
1956
1955
  activeCredentialId: config.activeCredentialId,
1957
1956
  knownCredentialIds: [],
1958
1957
  verificationTarget: null,
@@ -1960,12 +1959,12 @@ function createInitialState(config) {
1960
1959
  mobileFlow: false,
1961
1960
  deeplinkUri: null,
1962
1961
  increasingLimit: false,
1963
- previousStep: null,
1964
1962
  isGuestFlow: false,
1965
1963
  guestTransferId: null,
1966
1964
  guestSessionToken: null,
1967
1965
  guestPreauthAccountId: null,
1968
- activePublicKey: null
1966
+ activePublicKey: null,
1967
+ userIntent: null
1969
1968
  };
1970
1969
  }
1971
1970
  function paymentReducer(state, action) {
@@ -1975,21 +1974,20 @@ function paymentReducer(state, action) {
1975
1974
  return {
1976
1975
  ...state,
1977
1976
  verificationTarget: action.target,
1978
- error: null,
1979
- step: "otp-verify"
1977
+ error: null
1980
1978
  };
1981
1979
  case "BACK_TO_LOGIN":
1982
1980
  return {
1983
1981
  ...state,
1984
1982
  verificationTarget: null,
1985
- error: null,
1986
- step: "login"
1983
+ error: null
1987
1984
  };
1988
1985
  // ── Passkey ──────────────────────────────────────────────────
1989
1986
  case "PASSKEY_CONFIG_LOADED":
1990
1987
  return {
1991
1988
  ...state,
1992
1989
  knownCredentialIds: action.knownIds,
1990
+ passkeyConfigLoaded: true,
1993
1991
  oneTapLimit: action.oneTapLimit ?? state.oneTapLimit
1994
1992
  };
1995
1993
  case "PASSKEY_ACTIVATED":
@@ -2023,9 +2021,6 @@ function paymentReducer(state, action) {
2023
2021
  next.mobileFlow = false;
2024
2022
  next.deeplinkUri = null;
2025
2023
  }
2026
- if (action.resolvedStep !== void 0) {
2027
- next.step = action.resolvedStep;
2028
- }
2029
2024
  return next;
2030
2025
  }
2031
2026
  case "DATA_LOAD_END":
@@ -2049,7 +2044,8 @@ function paymentReducer(state, action) {
2049
2044
  selectedProviderId: action.providerId,
2050
2045
  selectedAccountId: null,
2051
2046
  selectedWalletId: null,
2052
- selectedTokenSymbol: null
2047
+ selectedTokenSymbol: null,
2048
+ userIntent: null
2053
2049
  };
2054
2050
  case "SELECT_ACCOUNT":
2055
2051
  return {
@@ -2057,24 +2053,24 @@ function paymentReducer(state, action) {
2057
2053
  selectedAccountId: action.accountId,
2058
2054
  selectedWalletId: action.walletId,
2059
2055
  selectedTokenSymbol: null,
2060
- step: "deposit"
2056
+ userIntent: null
2061
2057
  };
2062
2058
  case "SELECT_TOKEN":
2063
2059
  return {
2064
2060
  ...state,
2065
2061
  selectedWalletId: action.walletId,
2066
2062
  selectedTokenSymbol: action.tokenSymbol,
2067
- step: "deposit"
2063
+ userIntent: null
2068
2064
  };
2069
2065
  // ── Transfer lifecycle ───────────────────────────────────────
2070
2066
  case "PAY_STARTED":
2071
2067
  return {
2072
2068
  ...state,
2073
- step: action.isSetupRedirect ? "open-wallet" : "processing",
2074
2069
  error: null,
2075
2070
  creatingTransfer: true,
2076
2071
  deeplinkUri: null,
2077
- mobileFlow: false
2072
+ mobileFlow: false,
2073
+ userIntent: null
2078
2074
  };
2079
2075
  case "PAY_ENDED":
2080
2076
  return { ...state, creatingTransfer: false };
@@ -2082,7 +2078,7 @@ function paymentReducer(state, action) {
2082
2078
  return {
2083
2079
  ...state,
2084
2080
  error: action.error,
2085
- step: action.fallbackStep
2081
+ creatingTransfer: false
2086
2082
  };
2087
2083
  case "TRANSFER_CREATED":
2088
2084
  return { ...state, transfer: action.transfer };
@@ -2092,7 +2088,6 @@ function paymentReducer(state, action) {
2092
2088
  return {
2093
2089
  ...state,
2094
2090
  transfer: action.transfer,
2095
- step: "success",
2096
2091
  mobileFlow: false,
2097
2092
  deeplinkUri: null
2098
2093
  };
@@ -2101,17 +2096,20 @@ function paymentReducer(state, action) {
2101
2096
  ...state,
2102
2097
  transfer: action.transfer,
2103
2098
  error: action.error,
2104
- step: "success",
2105
2099
  mobileFlow: false,
2106
2100
  deeplinkUri: null
2107
2101
  };
2108
2102
  case "PROCESSING_TIMEOUT":
2109
- return { ...state, error: action.error, step: "deposit" };
2103
+ return {
2104
+ ...state,
2105
+ error: action.error,
2106
+ transfer: null,
2107
+ creatingTransfer: false
2108
+ };
2110
2109
  case "CONFIRM_SIGN_SUCCESS":
2111
2110
  return {
2112
2111
  ...state,
2113
2112
  transfer: action.transfer,
2114
- step: "processing",
2115
2113
  mobileFlow: false,
2116
2114
  deeplinkUri: null
2117
2115
  };
@@ -2120,8 +2118,7 @@ function paymentReducer(state, action) {
2120
2118
  return {
2121
2119
  ...state,
2122
2120
  mobileFlow: true,
2123
- deeplinkUri: action.deeplinkUri,
2124
- step: "open-wallet"
2121
+ deeplinkUri: action.deeplinkUri
2125
2122
  };
2126
2123
  case "MOBILE_SETUP_COMPLETE":
2127
2124
  return {
@@ -2129,8 +2126,7 @@ function paymentReducer(state, action) {
2129
2126
  transfer: action.transfer ?? state.transfer,
2130
2127
  error: null,
2131
2128
  mobileFlow: false,
2132
- deeplinkUri: null,
2133
- step: "deposit"
2129
+ deeplinkUri: null
2134
2130
  };
2135
2131
  case "MOBILE_SIGN_READY":
2136
2132
  return {
@@ -2138,8 +2134,7 @@ function paymentReducer(state, action) {
2138
2134
  transfer: action.transfer,
2139
2135
  error: null,
2140
2136
  mobileFlow: false,
2141
- deeplinkUri: null,
2142
- step: "confirm-sign"
2137
+ deeplinkUri: null
2143
2138
  };
2144
2139
  case "CLEAR_MOBILE_STATE":
2145
2140
  return { ...state, mobileFlow: false, deeplinkUri: null };
@@ -2149,8 +2144,7 @@ function paymentReducer(state, action) {
2149
2144
  mobileFlow: true,
2150
2145
  deeplinkUri: action.deeplinkUri,
2151
2146
  selectedProviderId: action.providerId ?? state.selectedProviderId,
2152
- error: action.error ?? null,
2153
- step: "open-wallet"
2147
+ error: action.error ?? null
2154
2148
  };
2155
2149
  case "MOBILE_RESUME_SUCCESS":
2156
2150
  return {
@@ -2158,8 +2152,7 @@ function paymentReducer(state, action) {
2158
2152
  transfer: action.transfer,
2159
2153
  error: null,
2160
2154
  mobileFlow: false,
2161
- deeplinkUri: null,
2162
- step: "success"
2155
+ deeplinkUri: null
2163
2156
  };
2164
2157
  case "MOBILE_RESUME_FAILED":
2165
2158
  return {
@@ -2167,8 +2160,7 @@ function paymentReducer(state, action) {
2167
2160
  transfer: action.transfer,
2168
2161
  error: "Transfer failed.",
2169
2162
  mobileFlow: false,
2170
- deeplinkUri: null,
2171
- step: "success"
2163
+ deeplinkUri: null
2172
2164
  };
2173
2165
  case "MOBILE_RESUME_PROCESSING":
2174
2166
  return {
@@ -2176,8 +2168,7 @@ function paymentReducer(state, action) {
2176
2168
  transfer: action.transfer,
2177
2169
  error: null,
2178
2170
  mobileFlow: false,
2179
- deeplinkUri: null,
2180
- step: "processing"
2171
+ deeplinkUri: null
2181
2172
  };
2182
2173
  // ── Increase limit ───────────────────────────────────────────
2183
2174
  case "SET_INCREASING_LIMIT":
@@ -2199,14 +2190,12 @@ function paymentReducer(state, action) {
2199
2190
  guestSessionToken: action.guestSessionToken,
2200
2191
  selectedAccountId: null,
2201
2192
  selectedWalletId: null,
2202
- selectedTokenSymbol: null,
2203
- step: "token-picker"
2193
+ selectedTokenSymbol: null
2204
2194
  };
2205
2195
  case "GUEST_TRANSFER_COMPLETED":
2206
2196
  return {
2207
2197
  ...state,
2208
2198
  transfer: action.transfer,
2209
- step: "success",
2210
2199
  mobileFlow: false,
2211
2200
  deeplinkUri: null,
2212
2201
  isGuestFlow: true,
@@ -2215,27 +2204,24 @@ function paymentReducer(state, action) {
2215
2204
  case "GUEST_PREAUTH_DETECTED":
2216
2205
  return {
2217
2206
  ...state,
2218
- guestPreauthAccountId: action.accountId,
2219
- step: "login"
2207
+ guestPreauthAccountId: action.accountId
2220
2208
  };
2221
2209
  case "ACCOUNT_OWNER_SET":
2222
2210
  return {
2223
2211
  ...state,
2224
2212
  guestPreauthAccountId: null,
2225
2213
  activePublicKey: null,
2226
- step: "deposit",
2227
2214
  error: null
2228
2215
  };
2229
- // ── Navigation & error ───────────────────────────────────────
2230
- case "NAVIGATE":
2231
- return { ...state, step: action.step, previousStep: state.step, error: null };
2216
+ // ── User intent & error ──────────────────────────────────────
2217
+ case "SET_USER_INTENT":
2218
+ return { ...state, userIntent: action.intent };
2232
2219
  case "SET_ERROR":
2233
2220
  return { ...state, error: action.error };
2234
2221
  // ── Lifecycle ────────────────────────────────────────────────
2235
2222
  case "NEW_PAYMENT":
2236
2223
  return {
2237
2224
  ...state,
2238
- step: state.isGuestFlow ? "wallet-picker" : "deposit",
2239
2225
  transfer: null,
2240
2226
  error: null,
2241
2227
  amount: action.depositAmount != null ? action.depositAmount.toString() : "",
@@ -2248,7 +2234,8 @@ function paymentReducer(state, action) {
2248
2234
  guestTransferId: null,
2249
2235
  guestSessionToken: null,
2250
2236
  guestPreauthAccountId: null,
2251
- activePublicKey: null
2237
+ activePublicKey: null,
2238
+ userIntent: null
2252
2239
  };
2253
2240
  case "LOGOUT":
2254
2241
  return {
@@ -2316,6 +2303,87 @@ function isMobileUserAgent(userAgent) {
2316
2303
  function shouldUseWalletConnector(options) {
2317
2304
  return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
2318
2305
  }
2306
+
2307
+ // src/resolveScreen.ts
2308
+ function hasActiveWallet(accounts) {
2309
+ return accounts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
2310
+ }
2311
+ function isTransferTerminal(transfer) {
2312
+ return transfer?.status === "COMPLETED" || transfer?.status === "FAILED";
2313
+ }
2314
+ function isTransferInFlight(transfer) {
2315
+ if (!transfer) return false;
2316
+ return ["CREATED", "SENDING", "SENT"].includes(transfer.status);
2317
+ }
2318
+ function isSetupTransfer(transfer) {
2319
+ if (!transfer) return false;
2320
+ return transfer.sources?.some(
2321
+ (s) => s.wallets && Array.isArray(s.wallets) && s.wallets.length === 0
2322
+ ) ?? false;
2323
+ }
2324
+ function resolveScreen(state) {
2325
+ if (!state.privyReady) {
2326
+ return "loading";
2327
+ }
2328
+ if (state.authenticated && !state.activeCredentialId && !state.passkeyConfigLoaded) {
2329
+ return "loading";
2330
+ }
2331
+ if (!state.authenticated && !state.verificationTarget && !state.isGuestFlow && (state.isReturningUser || state.guestPreauthRedirect)) {
2332
+ return "login";
2333
+ }
2334
+ if (!state.authenticated && state.verificationTarget != null) {
2335
+ return "otp-verify";
2336
+ }
2337
+ if (state.authenticated && !state.activeCredentialId && state.passkeyConfigLoaded && (state.knownCredentialIds.length === 0 || !state.passkeyPopupNeeded)) {
2338
+ return "create-passkey";
2339
+ }
2340
+ if (state.authenticated && !state.activeCredentialId && state.passkeyConfigLoaded && state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded) {
2341
+ return "verify-passkey";
2342
+ }
2343
+ if (isTransferTerminal(state.transfer)) {
2344
+ return "success";
2345
+ }
2346
+ if (state.creatingTransfer || state.transfer != null && isTransferInFlight(state.transfer)) {
2347
+ return "processing";
2348
+ }
2349
+ if (state.transfer?.status === "AUTHORIZED" && !state.isDesktop && !isSetupTransfer(state.transfer)) {
2350
+ return "confirm-sign";
2351
+ }
2352
+ if (state.pendingSelectSource != null) {
2353
+ return state.isDesktop ? "setup" : "select-source";
2354
+ }
2355
+ if (state.pendingOneTapSetup != null && !state.oneTapLimitAlreadySaved) {
2356
+ return "setup";
2357
+ }
2358
+ if (state.mobileFlow || state.inlineAuthorizationExecuting) {
2359
+ return state.isDesktop ? "setup-status" : "open-wallet";
2360
+ }
2361
+ if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer && !state.guestSettingSender) {
2362
+ return "guest-token-picker";
2363
+ }
2364
+ if (state.activeCredentialId && !hasActiveWallet(state.accounts) && !state.mobileFlow || !state.authenticated && !state.isReturningUser && !state.isGuestFlow) {
2365
+ return "wallet-picker";
2366
+ }
2367
+ if (state.loadingData && state.activeCredentialId != null && hasActiveWallet(state.accounts)) {
2368
+ return "loading";
2369
+ }
2370
+ if (state.userIntent === "pick-token" && state.selectedAccount != null) {
2371
+ return "token-picker";
2372
+ }
2373
+ if (state.userIntent === "configure-one-tap") {
2374
+ return "setup";
2375
+ }
2376
+ if (state.userIntent === "switch-wallet") {
2377
+ return "wallet-picker";
2378
+ }
2379
+ if (state.activeCredentialId != null && hasActiveWallet(state.accounts) && !state.loadingData) {
2380
+ return "deposit";
2381
+ }
2382
+ if (state.isGuestFlow) {
2383
+ return "wallet-picker";
2384
+ }
2385
+ return "wallet-picker";
2386
+ }
2319
2387
  var MUTED = "#7fa4b0";
2320
2388
  var LOGO_SIZE = 48;
2321
2389
  function BlinkLoadingScreen() {
@@ -5783,7 +5851,7 @@ var emptyStyle = (color) => ({
5783
5851
  padding: "32px 0",
5784
5852
  lineHeight: 1.5
5785
5853
  });
5786
- var LINK_STEPS = /* @__PURE__ */ new Set([
5854
+ var LINK_SCREENS = /* @__PURE__ */ new Set([
5787
5855
  "create-passkey",
5788
5856
  "verify-passkey",
5789
5857
  "wallet-picker",
@@ -5792,27 +5860,56 @@ var LINK_STEPS = /* @__PURE__ */ new Set([
5792
5860
  "setup",
5793
5861
  "confirm-sign"
5794
5862
  ]);
5795
- var DEPOSIT_STEPS = /* @__PURE__ */ new Set([
5863
+ var DEPOSIT_SCREENS = /* @__PURE__ */ new Set([
5796
5864
  "deposit",
5797
- "low-balance",
5798
5865
  "processing",
5799
5866
  "success"
5800
5867
  ]);
5801
- function getFlowPhase(step, previousStep) {
5802
- if (LINK_STEPS.has(step)) return "link";
5803
- if (DEPOSIT_STEPS.has(step)) return "deposit";
5804
- if (step === "token-picker" || step === "select-source") {
5805
- return previousStep === "setup" ? "link" : "deposit";
5868
+ function getFlowPhase(screen, userIntent) {
5869
+ if (LINK_SCREENS.has(screen)) return "link";
5870
+ if (DEPOSIT_SCREENS.has(screen)) return "deposit";
5871
+ if (screen === "token-picker" || screen === "select-source" || screen === "guest-token-picker") {
5872
+ return userIntent === "configure-one-tap" ? "link" : "deposit";
5806
5873
  }
5807
5874
  return null;
5808
5875
  }
5809
5876
  function StepRenderer(props) {
5810
- const phase = getFlowPhase(props.state.step, props.state.previousStep);
5811
- return /* @__PURE__ */ jsxRuntime.jsx(FlowPhaseProvider, { phase, children: /* @__PURE__ */ jsxRuntime.jsx(StepRendererContent, { ...props }) });
5877
+ const isDesktop = shouldUseWalletConnector({
5878
+ userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
5879
+ });
5880
+ const isReturningUser = props.state.activeCredentialId != null || typeof window !== "undefined" && window.localStorage.getItem("blink_active_credential") != null;
5881
+ const screenState = {
5882
+ privyReady: props.ready,
5883
+ authenticated: props.authenticated,
5884
+ verificationTarget: props.state.verificationTarget,
5885
+ activeCredentialId: props.state.activeCredentialId,
5886
+ knownCredentialIds: props.state.knownCredentialIds,
5887
+ passkeyConfigLoaded: props.state.passkeyConfigLoaded,
5888
+ passkeyPopupNeeded: props.state.passkeyPopupNeeded,
5889
+ accounts: props.state.accounts,
5890
+ isGuestFlow: props.state.isGuestFlow,
5891
+ selectedProviderId: props.state.selectedProviderId,
5892
+ mobileFlow: props.state.mobileFlow,
5893
+ inlineAuthorizationExecuting: props.inlineAuthorizationExecuting,
5894
+ creatingTransfer: props.state.creatingTransfer,
5895
+ transfer: props.state.transfer,
5896
+ pendingSelectSource: props.pendingSelectSource,
5897
+ pendingOneTapSetup: props.pendingOneTapSetup,
5898
+ oneTapLimitAlreadySaved: props.oneTapLimitAlreadySaved,
5899
+ loadingData: props.state.loadingData,
5900
+ isDesktop,
5901
+ isReturningUser,
5902
+ guestPreauthRedirect: props.state.guestPreauthAccountId != null,
5903
+ userIntent: props.state.userIntent,
5904
+ selectedAccount: props.selectedAccount,
5905
+ guestSettingSender: props.guestSettingSender
5906
+ };
5907
+ const screen = resolveScreen(screenState);
5908
+ const phase = getFlowPhase(screen, props.state.userIntent);
5909
+ return /* @__PURE__ */ jsxRuntime.jsx(FlowPhaseProvider, { phase, children: /* @__PURE__ */ jsxRuntime.jsx(StepRendererContent, { ...props, screen, isDesktop }) });
5812
5910
  }
5813
5911
  function StepRendererContent({
5814
5912
  state,
5815
- ready,
5816
5913
  authenticated,
5817
5914
  activeOtpStatus,
5818
5915
  pollingTransfer,
@@ -5842,204 +5939,204 @@ function StepRendererContent({
5842
5939
  onBack,
5843
5940
  onDismiss,
5844
5941
  depositAmount,
5845
- handlers
5942
+ handlers,
5943
+ screen,
5944
+ isDesktop
5846
5945
  }) {
5847
- const { step } = state;
5848
5946
  const selectedWallet = selectedAccount?.wallets.find((w) => w.id === state.selectedWalletId);
5849
5947
  const selectedSourceLabel = selectedSource && selectedWallet ? `${selectedSource.token.symbol} on ${selectedWallet.chain.name}` : void 0;
5850
- if (!ready) {
5851
- return /* @__PURE__ */ jsxRuntime.jsx(BlinkLoadingScreen, {});
5852
- }
5853
- if (step === "login") {
5854
- if (authenticated) {
5948
+ switch (screen) {
5949
+ case "loading":
5855
5950
  return /* @__PURE__ */ jsxRuntime.jsx(BlinkLoadingScreen, {});
5951
+ case "login":
5952
+ return /* @__PURE__ */ jsxRuntime.jsx(
5953
+ LoginScreen,
5954
+ {
5955
+ authInput,
5956
+ onAuthInputChange: handlers.onSetAuthInput,
5957
+ onSubmit: handlers.onSendLoginCode,
5958
+ sending: activeOtpStatus === "sending-code",
5959
+ error: state.error,
5960
+ onBack,
5961
+ merchantInitials: merchantName ? merchantName.slice(0, 2).toUpperCase() : void 0
5962
+ }
5963
+ );
5964
+ case "otp-verify":
5965
+ return /* @__PURE__ */ jsxRuntime.jsx(
5966
+ OtpVerifyScreen,
5967
+ {
5968
+ maskedIdentifier: state.verificationTarget ? maskAuthIdentifier(state.verificationTarget) : "",
5969
+ otpCode,
5970
+ onOtpChange: (code) => {
5971
+ handlers.onSetOtpCode(code);
5972
+ },
5973
+ onVerify: handlers.onVerifyLoginCode,
5974
+ onResend: handlers.onResendLoginCode,
5975
+ onBack: handlers.onBackFromOtp,
5976
+ verifying: activeOtpStatus === "submitting-code" || authenticated,
5977
+ error: state.error
5978
+ }
5979
+ );
5980
+ case "create-passkey":
5981
+ return /* @__PURE__ */ jsxRuntime.jsx(
5982
+ PasskeyScreen,
5983
+ {
5984
+ onCreatePasskey: handlers.onRegisterPasskey,
5985
+ onBack: handlers.onLogout,
5986
+ onLogout: handlers.onLogout,
5987
+ creating: state.registeringPasskey,
5988
+ error: state.error,
5989
+ popupFallback: state.passkeyPopupNeeded,
5990
+ onCreatePasskeyViaPopup: handlers.onCreatePasskeyViaPopup
5991
+ }
5992
+ );
5993
+ case "verify-passkey":
5994
+ return /* @__PURE__ */ jsxRuntime.jsx(
5995
+ PasskeyScreen,
5996
+ {
5997
+ onCreatePasskey: handlers.onRegisterPasskey,
5998
+ onBack: handlers.onLogout,
5999
+ onLogout: handlers.onLogout,
6000
+ creating: state.verifyingPasskeyPopup,
6001
+ error: state.error,
6002
+ popupFallback: true,
6003
+ onCreatePasskeyViaPopup: handlers.onVerifyPasskeyViaPopup
6004
+ }
6005
+ );
6006
+ case "wallet-picker": {
6007
+ const isEntryPoint = !state.isGuestFlow && !authenticated;
6008
+ return /* @__PURE__ */ jsxRuntime.jsx(
6009
+ WalletPickerScreen,
6010
+ {
6011
+ providers: state.providers,
6012
+ pendingConnections,
6013
+ loading: state.creatingTransfer,
6014
+ useDeeplink: !isDesktop,
6015
+ onPrepareProvider: handlers.onPrepareProvider,
6016
+ onSelectProvider: handlers.onSelectProvider,
6017
+ onContinueConnection: handlers.onContinueConnection,
6018
+ onBack: isEntryPoint ? onBack : () => handlers.onSetUserIntent(null),
6019
+ onLogout: authenticated ? handlers.onLogout : void 0,
6020
+ onLogin: handlers.onLogin,
6021
+ showLoginOption: isEntryPoint
6022
+ }
6023
+ );
5856
6024
  }
5857
- return /* @__PURE__ */ jsxRuntime.jsx(
5858
- LoginScreen,
5859
- {
5860
- authInput,
5861
- onAuthInputChange: handlers.onSetAuthInput,
5862
- onSubmit: handlers.onSendLoginCode,
5863
- sending: activeOtpStatus === "sending-code",
5864
- error: state.error,
5865
- onBack,
5866
- merchantInitials: merchantName ? merchantName.slice(0, 2).toUpperCase() : void 0
5867
- }
5868
- );
5869
- }
5870
- if (step === "otp-verify") {
5871
- return /* @__PURE__ */ jsxRuntime.jsx(
5872
- OtpVerifyScreen,
5873
- {
5874
- maskedIdentifier: state.verificationTarget ? maskAuthIdentifier(state.verificationTarget) : "",
5875
- otpCode,
5876
- onOtpChange: (code) => {
5877
- handlers.onSetOtpCode(code);
5878
- },
5879
- onVerify: handlers.onVerifyLoginCode,
5880
- onResend: handlers.onResendLoginCode,
5881
- onBack: handlers.onBackFromOtp,
5882
- verifying: activeOtpStatus === "submitting-code" || authenticated,
5883
- error: state.error
5884
- }
5885
- );
5886
- }
5887
- if (step === "create-passkey") {
5888
- return /* @__PURE__ */ jsxRuntime.jsx(
5889
- PasskeyScreen,
5890
- {
5891
- onCreatePasskey: handlers.onRegisterPasskey,
5892
- onBack: handlers.onLogout,
5893
- onLogout: handlers.onLogout,
5894
- creating: state.registeringPasskey,
5895
- error: state.error,
5896
- popupFallback: state.passkeyPopupNeeded,
5897
- onCreatePasskeyViaPopup: handlers.onCreatePasskeyViaPopup
5898
- }
5899
- );
5900
- }
5901
- if (step === "verify-passkey") {
5902
- return /* @__PURE__ */ jsxRuntime.jsx(
5903
- PasskeyScreen,
5904
- {
5905
- onCreatePasskey: handlers.onRegisterPasskey,
5906
- onBack: handlers.onLogout,
5907
- onLogout: handlers.onLogout,
5908
- creating: state.verifyingPasskeyPopup,
5909
- error: state.error,
5910
- popupFallback: true,
5911
- onCreatePasskeyViaPopup: handlers.onVerifyPasskeyViaPopup
5912
- }
5913
- );
5914
- }
5915
- if (step === "wallet-picker") {
5916
- if (state.isGuestFlow && state.selectedProviderId && state.activeCredentialId) {
5917
- return /* @__PURE__ */ jsxRuntime.jsx(BlinkLoadingScreen, {});
6025
+ case "open-wallet": {
6026
+ const providerName = state.providers.find((p) => p.id === state.selectedProviderId)?.name ?? null;
6027
+ return /* @__PURE__ */ jsxRuntime.jsx(
6028
+ OpenWalletScreen,
6029
+ {
6030
+ walletName: providerName,
6031
+ deeplinkUri: state.deeplinkUri ?? "",
6032
+ loading: !isDesktop ? state.creatingTransfer || !state.deeplinkUri : state.creatingTransfer,
6033
+ useDeeplink: !isDesktop,
6034
+ error: state.error || (!isDesktop ? pollingError : authExecutorError),
6035
+ onRetryStatus: !isDesktop ? handlers.onRetryMobileStatus : void 0,
6036
+ onBack: !isDesktop ? () => handlers.onSetUserIntent(null) : void 0,
6037
+ onLogout: handlers.onLogout
6038
+ }
6039
+ );
5918
6040
  }
5919
- const isEntryPoint = !state.isGuestFlow && !authenticated;
5920
- return /* @__PURE__ */ jsxRuntime.jsx(
5921
- WalletPickerScreen,
5922
- {
5923
- providers: state.providers,
5924
- pendingConnections,
5925
- loading: state.creatingTransfer,
5926
- useDeeplink: !shouldUseWalletConnector({
5927
- userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
5928
- }),
5929
- onPrepareProvider: handlers.onPrepareProvider,
5930
- onSelectProvider: handlers.onSelectProvider,
5931
- onContinueConnection: handlers.onContinueConnection,
5932
- onBack: isEntryPoint ? onBack : () => handlers.onNavigate(state.activeCredentialId ? "deposit" : "create-passkey"),
5933
- onLogout: authenticated ? handlers.onLogout : void 0,
5934
- onLogin: handlers.onLogin,
5935
- showLoginOption: isEntryPoint
5936
- }
5937
- );
5938
- }
5939
- if (step === "open-wallet") {
5940
- const providerName = state.providers.find((p) => p.id === state.selectedProviderId)?.name ?? null;
5941
- const useDeeplink = !shouldUseWalletConnector({
5942
- userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
5943
- });
5944
- return /* @__PURE__ */ jsxRuntime.jsx(
5945
- OpenWalletScreen,
5946
- {
5947
- walletName: providerName,
5948
- deeplinkUri: state.deeplinkUri ?? "",
5949
- loading: useDeeplink ? state.creatingTransfer || !state.deeplinkUri : state.creatingTransfer,
5950
- useDeeplink,
5951
- error: state.error || (useDeeplink ? pollingError : authExecutorError),
5952
- onRetryStatus: useDeeplink ? handlers.onRetryMobileStatus : void 0,
5953
- onBack: useDeeplink ? () => handlers.onNavigate("wallet-picker") : void 0,
5954
- onLogout: handlers.onLogout
5955
- }
5956
- );
5957
- }
5958
- if (step === "setup-status") {
5959
- return /* @__PURE__ */ jsxRuntime.jsx(
5960
- SetupStatusScreen,
5961
- {
5962
- complete: false,
5963
- limit: state.oneTapLimit,
5964
- tokensApproved: 0,
5965
- merchantName,
5966
- onContinue: () => handlers.onNavigate("setup"),
5967
- onLogout: handlers.onLogout,
5968
- error: state.error || authExecutorError
5969
- }
5970
- );
5971
- }
5972
- if (step === "setup") {
5973
- const selectSourceTokenCount = selectSourceChoices.reduce(
5974
- (sum, chain) => sum + chain.tokens.length,
5975
- 0
5976
- );
5977
- const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
5978
- const effectiveSourceLabel = selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
5979
- return /* @__PURE__ */ jsxRuntime.jsx(
5980
- SetupScreen,
5981
- {
5982
- availableBalance: selectedSource ? selectedSource.balance.available.amount : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
5983
- tokenCount: effectiveTokenCount,
5984
- sourceName,
5985
- onSetupOneTap: handlers.onSetupOneTap,
5986
- onBack: () => handlers.onNavigate("deposit"),
5987
- onLogout: handlers.onLogout,
5988
- onAdvanced: handlers.onSelectToken,
5989
- selectedSourceLabel: effectiveSourceLabel,
5990
- loading: savingOneTapLimit,
5991
- error: state.error,
5992
- selectedTokenSymbol: selectedSource?.token.symbol ?? selectSourceTokenSymbol
5993
- }
5994
- );
5995
- }
5996
- if (step === "confirm-sign") {
5997
- const providerName = state.providers.find((p) => p.id === state.selectedProviderId)?.name ?? null;
5998
- return /* @__PURE__ */ jsxRuntime.jsx(
5999
- ConfirmSignScreen,
6000
- {
6001
- walletName: providerName,
6002
- signing: transferSigningSigning,
6003
- error: state.error || transferSigningError,
6004
- onSign: handlers.onConfirmSign,
6005
- onLogout: handlers.onLogout
6006
- }
6007
- );
6008
- }
6009
- if (step === "deposit") {
6010
- if (state.loadingData) {
6011
- return /* @__PURE__ */ jsxRuntime.jsx(BlinkLoadingScreen, {});
6041
+ case "setup-status":
6042
+ return /* @__PURE__ */ jsxRuntime.jsx(
6043
+ SetupStatusScreen,
6044
+ {
6045
+ complete: false,
6046
+ limit: state.oneTapLimit,
6047
+ tokensApproved: 0,
6048
+ merchantName,
6049
+ onContinue: () => handlers.onSetUserIntent("configure-one-tap"),
6050
+ onLogout: handlers.onLogout,
6051
+ error: state.error || authExecutorError
6052
+ }
6053
+ );
6054
+ case "setup": {
6055
+ const selectSourceTokenCount = selectSourceChoices.reduce(
6056
+ (sum, chain) => sum + chain.tokens.length,
6057
+ 0
6058
+ );
6059
+ const effectiveTokenCount = tokenCount > 0 ? tokenCount : selectSourceTokenCount;
6060
+ const effectiveSourceLabel = selectedSourceLabel ?? (selectSourceChainName && selectSourceTokenSymbol ? `${selectSourceTokenSymbol} on ${selectSourceChainName}` : void 0);
6061
+ return /* @__PURE__ */ jsxRuntime.jsx(
6062
+ SetupScreen,
6063
+ {
6064
+ availableBalance: selectedSource ? selectedSource.balance.available.amount : selectSourceAvailableBalance > 0 ? selectSourceAvailableBalance : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
6065
+ tokenCount: effectiveTokenCount,
6066
+ sourceName,
6067
+ onSetupOneTap: handlers.onSetupOneTap,
6068
+ onBack: () => handlers.onSetUserIntent(null),
6069
+ onLogout: handlers.onLogout,
6070
+ onAdvanced: handlers.onSelectToken,
6071
+ selectedSourceLabel: effectiveSourceLabel,
6072
+ loading: savingOneTapLimit,
6073
+ error: state.error,
6074
+ selectedTokenSymbol: selectedSource?.token.symbol ?? selectSourceTokenSymbol
6075
+ }
6076
+ );
6012
6077
  }
6013
- const parsedAmt = depositAmount != null ? depositAmount : 5;
6014
- return /* @__PURE__ */ jsxRuntime.jsx(
6015
- DepositScreen,
6016
- {
6017
- merchantName,
6018
- availableBalance: selectedSource ? selectedSource.balance.available.amount : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
6019
- remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
6020
- tokenCount,
6021
- initialAmount: parsedAmt,
6022
- processing: state.creatingTransfer,
6023
- error: state.error,
6024
- onDeposit: handlers.onPay,
6025
- onSwitchWallet: () => handlers.onNavigate("wallet-picker"),
6026
- onBack: onBack ?? (() => handlers.onLogout()),
6027
- onLogout: handlers.onLogout,
6028
- onIncreaseLimit: handlers.onIncreaseLimit,
6029
- increasingLimit: state.increasingLimit,
6030
- accounts: depositEligibleAccounts,
6031
- selectedAccountId: state.selectedAccountId,
6032
- onSelectAccount: handlers.onSelectAccount,
6033
- onAuthorizeAccount: handlers.onContinueConnection,
6034
- onAddProvider: () => handlers.onNavigate("wallet-picker"),
6035
- onSelectToken: handlers.onSelectToken,
6036
- selectedSourceLabel,
6037
- selectedTokenSymbol: selectedSource?.token.symbol
6078
+ case "confirm-sign": {
6079
+ const providerName = state.providers.find((p) => p.id === state.selectedProviderId)?.name ?? null;
6080
+ return /* @__PURE__ */ jsxRuntime.jsx(
6081
+ ConfirmSignScreen,
6082
+ {
6083
+ walletName: providerName,
6084
+ signing: transferSigningSigning,
6085
+ error: state.error || transferSigningError,
6086
+ onSign: handlers.onConfirmSign,
6087
+ onLogout: handlers.onLogout
6088
+ }
6089
+ );
6090
+ }
6091
+ case "deposit": {
6092
+ const parsedAmt = depositAmount != null ? depositAmount : 5;
6093
+ return /* @__PURE__ */ jsxRuntime.jsx(
6094
+ DepositScreen,
6095
+ {
6096
+ merchantName,
6097
+ availableBalance: selectedSource ? selectedSource.balance.available.amount : selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : maxSourceBalance,
6098
+ remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
6099
+ tokenCount,
6100
+ initialAmount: parsedAmt,
6101
+ processing: state.creatingTransfer,
6102
+ error: state.error,
6103
+ onDeposit: handlers.onPay,
6104
+ onSwitchWallet: () => handlers.onSetUserIntent("switch-wallet"),
6105
+ onBack: onBack ?? (() => handlers.onLogout()),
6106
+ onLogout: handlers.onLogout,
6107
+ onIncreaseLimit: handlers.onIncreaseLimit,
6108
+ increasingLimit: state.increasingLimit,
6109
+ accounts: depositEligibleAccounts,
6110
+ selectedAccountId: state.selectedAccountId,
6111
+ onSelectAccount: handlers.onSelectAccount,
6112
+ onAuthorizeAccount: handlers.onContinueConnection,
6113
+ onAddProvider: () => handlers.onSetUserIntent("switch-wallet"),
6114
+ onSelectToken: handlers.onSelectToken,
6115
+ selectedSourceLabel,
6116
+ selectedTokenSymbol: selectedSource?.token.symbol
6117
+ }
6118
+ );
6119
+ }
6120
+ case "token-picker": {
6121
+ if (!selectedAccount) {
6122
+ return /* @__PURE__ */ jsxRuntime.jsx(BlinkLoadingScreen, {});
6038
6123
  }
6039
- );
6040
- }
6041
- if (step === "token-picker") {
6042
- if (state.isGuestFlow) {
6124
+ return /* @__PURE__ */ jsxRuntime.jsx(
6125
+ TokenPickerScreen,
6126
+ {
6127
+ account: selectedAccount,
6128
+ chains: state.chains,
6129
+ onSelectAuthorized: handlers.onSelectAuthorizedToken,
6130
+ onAuthorizeToken: handlers.onAuthorizeToken,
6131
+ onBack: () => handlers.onSetUserIntent(null),
6132
+ onLogout: handlers.onLogout,
6133
+ depositAmount: depositAmount ?? void 0,
6134
+ selectedTokenSymbol: selectedSource?.token.symbol,
6135
+ selectedWalletId: state.selectedWalletId ?? void 0
6136
+ }
6137
+ );
6138
+ }
6139
+ case "guest-token-picker":
6043
6140
  return /* @__PURE__ */ jsxRuntime.jsx(
6044
6141
  GuestTokenPickerScreen,
6045
6142
  {
@@ -6049,107 +6146,60 @@ function StepRendererContent({
6049
6146
  depositAmount: depositAmount ?? void 0,
6050
6147
  error: state.error,
6051
6148
  onSelect: handlers.onSelectGuestToken,
6052
- onBack: () => handlers.onNavigate("wallet-picker")
6149
+ onBack: () => handlers.onSetUserIntent(null)
6150
+ }
6151
+ );
6152
+ case "processing": {
6153
+ const polledStatus = pollingTransfer?.status;
6154
+ const transferPhase = state.creatingTransfer ? "creating" : polledStatus === "SENDING" || polledStatus === "SENT" ? "sent" : "verifying";
6155
+ return /* @__PURE__ */ jsxRuntime.jsx(
6156
+ TransferStatusScreen,
6157
+ {
6158
+ phase: transferPhase,
6159
+ error: state.error || authExecutorError || transferSigningError || pollingError,
6160
+ onLogout: handlers.onLogout
6053
6161
  }
6054
6162
  );
6055
6163
  }
6056
- if (!selectedAccount) {
6057
- return /* @__PURE__ */ jsxRuntime.jsx(BlinkLoadingScreen, {});
6164
+ case "select-source":
6165
+ return /* @__PURE__ */ jsxRuntime.jsx(
6166
+ SelectSourceScreen,
6167
+ {
6168
+ choices: selectSourceChoices,
6169
+ selectedChainName: selectSourceChainName,
6170
+ selectedTokenSymbol: selectSourceTokenSymbol,
6171
+ recommended: selectSourceRecommended,
6172
+ onChainChange: handlers.onSelectSourceChainChange,
6173
+ onTokenChange: handlers.onSetSelectSourceTokenSymbol,
6174
+ onConfirm: handlers.onConfirmSelectSource,
6175
+ onLogout: handlers.onLogout
6176
+ }
6177
+ );
6178
+ case "success": {
6179
+ const succeeded = state.transfer?.status === "COMPLETED";
6180
+ const displayAmount = state.transfer?.amount?.amount ?? 0;
6181
+ const displayCurrency = state.transfer?.amount?.currency ?? "USD";
6182
+ return /* @__PURE__ */ jsxRuntime.jsx(
6183
+ SuccessScreen,
6184
+ {
6185
+ amount: displayAmount,
6186
+ currency: displayCurrency,
6187
+ succeeded,
6188
+ error: state.error,
6189
+ merchantName,
6190
+ sourceName,
6191
+ remainingLimit: succeeded ? (() => {
6192
+ const limit = selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null;
6193
+ if (limit == null) return null;
6194
+ return limit > displayAmount ? limit - displayAmount : 0;
6195
+ })() : void 0,
6196
+ onDone: onDismiss ?? handlers.onNewPayment,
6197
+ onLogout: handlers.onLogout,
6198
+ onPreauthorize: state.isGuestFlow ? handlers.onPreauthorize : void 0
6199
+ }
6200
+ );
6058
6201
  }
6059
- return /* @__PURE__ */ jsxRuntime.jsx(
6060
- TokenPickerScreen,
6061
- {
6062
- account: selectedAccount,
6063
- chains: state.chains,
6064
- onSelectAuthorized: handlers.onSelectAuthorizedToken,
6065
- onAuthorizeToken: handlers.onAuthorizeToken,
6066
- onBack: () => handlers.onNavigate(state.previousStep === "setup" ? "setup" : "deposit"),
6067
- onLogout: handlers.onLogout,
6068
- depositAmount: depositAmount ?? void 0,
6069
- selectedTokenSymbol: selectedSource?.token.symbol,
6070
- selectedWalletId: state.selectedWalletId
6071
- }
6072
- );
6073
- }
6074
- if (step === "processing") {
6075
- const polledStatus = pollingTransfer?.status;
6076
- const transferPhase = state.creatingTransfer ? "creating" : polledStatus === "SENDING" || polledStatus === "SENT" ? "sent" : "verifying";
6077
- return /* @__PURE__ */ jsxRuntime.jsx(
6078
- TransferStatusScreen,
6079
- {
6080
- phase: transferPhase,
6081
- error: state.error || authExecutorError || transferSigningError || pollingError,
6082
- onLogout: handlers.onLogout
6083
- }
6084
- );
6085
- }
6086
- if (step === "select-source") {
6087
- const cameFromSetup = state.previousStep === "setup";
6088
- return /* @__PURE__ */ jsxRuntime.jsx(
6089
- SelectSourceScreen,
6090
- {
6091
- choices: selectSourceChoices,
6092
- selectedChainName: selectSourceChainName,
6093
- selectedTokenSymbol: selectSourceTokenSymbol,
6094
- recommended: selectSourceRecommended,
6095
- onChainChange: handlers.onSelectSourceChainChange,
6096
- onTokenChange: handlers.onSetSelectSourceTokenSymbol,
6097
- onConfirm: cameFromSetup ? () => handlers.onNavigate("setup") : handlers.onConfirmSelectSource,
6098
- onBack: cameFromSetup ? () => handlers.onNavigate("setup") : void 0,
6099
- onLogout: handlers.onLogout
6100
- }
6101
- );
6102
- }
6103
- if (step === "success") {
6104
- const succeeded = state.transfer?.status === "COMPLETED";
6105
- const displayAmount = state.transfer?.amount?.amount ?? 0;
6106
- const displayCurrency = state.transfer?.amount?.currency ?? "USD";
6107
- return /* @__PURE__ */ jsxRuntime.jsx(
6108
- SuccessScreen,
6109
- {
6110
- amount: displayAmount,
6111
- currency: displayCurrency,
6112
- succeeded,
6113
- error: state.error,
6114
- merchantName,
6115
- sourceName,
6116
- remainingLimit: succeeded ? (() => {
6117
- const limit = selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null;
6118
- if (limit == null) return null;
6119
- return limit > displayAmount ? limit - displayAmount : 0;
6120
- })() : void 0,
6121
- onDone: onDismiss ?? handlers.onNewPayment,
6122
- onLogout: handlers.onLogout,
6123
- onPreauthorize: state.isGuestFlow ? handlers.onPreauthorize : void 0
6124
- }
6125
- );
6126
6202
  }
6127
- if (step === "low-balance") {
6128
- return /* @__PURE__ */ jsxRuntime.jsx(
6129
- DepositScreen,
6130
- {
6131
- merchantName,
6132
- availableBalance: 0,
6133
- remainingLimit: selectedSource != null ? selectedSource.remainingAllowance ?? null : selectedAccount?.remainingAllowance ?? null,
6134
- tokenCount,
6135
- initialAmount: depositAmount ?? 5,
6136
- processing: false,
6137
- error: state.error,
6138
- onDeposit: handlers.onPay,
6139
- onSwitchWallet: () => handlers.onNavigate("wallet-picker"),
6140
- onBack: onBack ?? (() => handlers.onLogout()),
6141
- onLogout: handlers.onLogout,
6142
- accounts: depositEligibleAccounts,
6143
- selectedAccountId: state.selectedAccountId,
6144
- onSelectAccount: handlers.onSelectAccount,
6145
- onAuthorizeAccount: handlers.onContinueConnection,
6146
- onAddProvider: () => handlers.onNavigate("wallet-picker"),
6147
- selectedSourceLabel,
6148
- selectedTokenSymbol: selectedSource?.token.symbol
6149
- }
6150
- );
6151
- }
6152
- return null;
6153
6203
  }
6154
6204
 
6155
6205
  // src/sentry.ts
@@ -6386,52 +6436,6 @@ function useAuthHandlers(dispatch, verificationTarget) {
6386
6436
  handleResendLoginCode
6387
6437
  };
6388
6438
  }
6389
-
6390
- // src/mobileFlow.ts
6391
- function hasActiveWallet(accounts) {
6392
- return accounts.some((account) => account.wallets.some((wallet) => wallet.status === "ACTIVE"));
6393
- }
6394
- function resolvePostAuthStep(state) {
6395
- if (!state.hasPasskey) {
6396
- return { step: "create-passkey", clearPersistedFlow: false };
6397
- }
6398
- if (state.persistedMobileFlow) {
6399
- if (state.persistedMobileFlow.isReauthorization) {
6400
- return { step: "open-wallet", clearPersistedFlow: false };
6401
- }
6402
- if (state.persistedMobileFlow.isSetup && hasActiveWallet(state.accounts)) {
6403
- return { step: "deposit", clearPersistedFlow: true };
6404
- }
6405
- return { step: "open-wallet", clearPersistedFlow: false };
6406
- }
6407
- if (state.mobileSetupInProgress && !hasActiveWallet(state.accounts)) {
6408
- return { step: "open-wallet", clearPersistedFlow: false };
6409
- }
6410
- if ((state.accounts.length === 0 || !hasActiveWallet(state.accounts)) && !state.connectingNewAccount) {
6411
- return { step: "wallet-picker", clearPersistedFlow: false };
6412
- }
6413
- return { step: "deposit", clearPersistedFlow: false };
6414
- }
6415
- function resolveRestoredMobileFlow(transferStatus, isSetup) {
6416
- if (transferStatus === "AUTHORIZED") {
6417
- return isSetup ? { kind: "resume-setup-deposit", step: "deposit", clearPersistedFlow: true } : { kind: "resume-confirm-sign", step: "confirm-sign", clearPersistedFlow: true };
6418
- }
6419
- if (transferStatus === "COMPLETED") {
6420
- return { kind: "resume-success", step: "success", clearPersistedFlow: true };
6421
- }
6422
- if (transferStatus === "FAILED") {
6423
- return { kind: "resume-failed", step: "success", clearPersistedFlow: true };
6424
- }
6425
- if (transferStatus === "SENDING" || transferStatus === "SENT") {
6426
- return { kind: "resume-processing", step: "processing", clearPersistedFlow: true };
6427
- }
6428
- if (isSetup) {
6429
- return { kind: "resume-stale-setup", step: "wallet-picker", clearPersistedFlow: true };
6430
- }
6431
- return { kind: "resume-open-wallet", step: "open-wallet", clearPersistedFlow: false };
6432
- }
6433
-
6434
- // src/hooks/usePasskeyHandlers.ts
6435
6439
  function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds, mobileSetupFlowRef, guestPreauthAccountId) {
6436
6440
  const { user, getAccessToken } = reactAuth.usePrivy();
6437
6441
  const checkingPasskeyRef = react.useRef(false);
@@ -6443,35 +6447,14 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6443
6447
  reportPasskeyActivity(apiBaseUrl, token, credentialId).catch(() => {
6444
6448
  });
6445
6449
  }
6446
- const resolved = resolvePostAuthStep({
6447
- hasPasskey: true,
6448
- accounts,
6449
- persistedMobileFlow: loadMobileFlowState(),
6450
- mobileSetupInProgress: mobileSetupFlowRef.current,
6451
- connectingNewAccount: false
6452
- });
6453
- if (resolved.clearPersistedFlow) clearMobileFlowState();
6454
- dispatch({ type: "NAVIGATE", step: resolved.step });
6455
- }, [getAccessToken, apiBaseUrl, accounts, mobileSetupFlowRef, dispatch]);
6450
+ }, [getAccessToken, apiBaseUrl, dispatch]);
6456
6451
  const completePasskeyRegistration = react.useCallback(async (credentialId, publicKey) => {
6457
6452
  const token = await getAccessToken();
6458
6453
  if (!token) throw new Error("Not authenticated");
6459
6454
  await registerPasskey(apiBaseUrl, token, credentialId, publicKey);
6460
6455
  dispatch({ type: "PASSKEY_ACTIVATED", credentialId, publicKey });
6461
6456
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
6462
- if (guestPreauthAccountId) {
6463
- return;
6464
- }
6465
- const resolved = resolvePostAuthStep({
6466
- hasPasskey: true,
6467
- accounts,
6468
- persistedMobileFlow: loadMobileFlowState(),
6469
- mobileSetupInProgress: mobileSetupFlowRef.current,
6470
- connectingNewAccount: false
6471
- });
6472
- if (resolved.clearPersistedFlow) clearMobileFlowState();
6473
- dispatch({ type: "NAVIGATE", step: resolved.step });
6474
- }, [getAccessToken, apiBaseUrl, accounts, mobileSetupFlowRef, guestPreauthAccountId, dispatch]);
6457
+ }, [getAccessToken, apiBaseUrl, dispatch]);
6475
6458
  const handleRegisterPasskey = react.useCallback(async () => {
6476
6459
  dispatch({ type: "SET_REGISTERING_PASSKEY", value: true });
6477
6460
  dispatch({ type: "SET_ERROR", error: null });
@@ -6535,15 +6518,6 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6535
6518
  const { credentialId } = await createPasskeyViaPopup(popupOptions);
6536
6519
  dispatch({ type: "PASSKEY_ACTIVATED", credentialId });
6537
6520
  localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
6538
- const resolved = resolvePostAuthStep({
6539
- hasPasskey: true,
6540
- accounts,
6541
- persistedMobileFlow: loadMobileFlowState(),
6542
- mobileSetupInProgress: mobileSetupFlowRef.current,
6543
- connectingNewAccount: false
6544
- });
6545
- if (resolved.clearPersistedFlow) clearMobileFlowState();
6546
- dispatch({ type: "NAVIGATE", step: resolved.step });
6547
6521
  } catch (err) {
6548
6522
  captureException(err);
6549
6523
  dispatch({
@@ -6553,7 +6527,7 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6553
6527
  } finally {
6554
6528
  dispatch({ type: "SET_REGISTERING_PASSKEY", value: false });
6555
6529
  }
6556
- }, [user, knownCredentialIds, getAccessToken, apiBaseUrl, activateExistingCredential, accounts, mobileSetupFlowRef, dispatch]);
6530
+ }, [user, knownCredentialIds, getAccessToken, apiBaseUrl, activateExistingCredential, dispatch]);
6557
6531
  const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
6558
6532
  dispatch({ type: "SET_VERIFYING_PASSKEY", value: true });
6559
6533
  dispatch({ type: "SET_ERROR", error: null });
@@ -6572,15 +6546,6 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6572
6546
  reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
6573
6547
  });
6574
6548
  }
6575
- const resolved = resolvePostAuthStep({
6576
- hasPasskey: true,
6577
- accounts,
6578
- persistedMobileFlow: loadMobileFlowState(),
6579
- mobileSetupInProgress: mobileSetupFlowRef.current,
6580
- connectingNewAccount: false
6581
- });
6582
- if (resolved.clearPersistedFlow) clearMobileFlowState();
6583
- dispatch({ type: "NAVIGATE", step: resolved.step });
6584
6549
  } else {
6585
6550
  dispatch({
6586
6551
  type: "SET_ERROR",
@@ -6596,7 +6561,7 @@ function usePasskeyHandlers(dispatch, apiBaseUrl, accounts, knownCredentialIds,
6596
6561
  } finally {
6597
6562
  dispatch({ type: "SET_VERIFYING_PASSKEY", value: false });
6598
6563
  }
6599
- }, [knownCredentialIds, getAccessToken, apiBaseUrl, accounts, mobileSetupFlowRef, dispatch]);
6564
+ }, [knownCredentialIds, getAccessToken, apiBaseUrl, dispatch]);
6600
6565
  return {
6601
6566
  handleRegisterPasskey,
6602
6567
  handleCreatePasskeyViaPopup,
@@ -6649,10 +6614,9 @@ function useTransferHandlers(deps) {
6649
6614
  }
6650
6615
  if (!activeCredentialId) {
6651
6616
  dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
6652
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
6653
6617
  return;
6654
6618
  }
6655
- dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
6619
+ dispatch({ type: "PAY_STARTED" });
6656
6620
  processingStartedAtRef.current = Date.now();
6657
6621
  try {
6658
6622
  if (transfer?.status === "AUTHORIZED") {
@@ -6699,7 +6663,7 @@ function useTransferHandlers(deps) {
6699
6663
  } catch (err) {
6700
6664
  captureException(err);
6701
6665
  const msg = err instanceof Error ? err.message : "Transfer failed";
6702
- dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "deposit" });
6666
+ dispatch({ type: "PAY_ERROR", error: msg });
6703
6667
  onError?.(msg);
6704
6668
  } finally {
6705
6669
  dispatch({ type: "PAY_ENDED" });
@@ -6749,7 +6713,6 @@ function useSourceSelectionHandlers(dispatch, authExecutor) {
6749
6713
  const [selectSourceChainName, setSelectSourceChainName] = react.useState("");
6750
6714
  const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = react.useState("");
6751
6715
  const initializedSelectSourceActionRef = react.useRef(null);
6752
- const preSelectSourceStepRef = react.useRef(null);
6753
6716
  const pendingSelectSourceAction = authExecutor.pendingSelectSource;
6754
6717
  const selectSourceChoices = react.useMemo(() => {
6755
6718
  if (!pendingSelectSourceAction) return [];
@@ -6807,8 +6770,7 @@ function useSourceSelectionHandlers(dispatch, authExecutor) {
6807
6770
  handleSelectSourceChainChange,
6808
6771
  handleConfirmSelectSource,
6809
6772
  pendingSelectSourceAction,
6810
- initializedSelectSourceActionRef,
6811
- preSelectSourceStepRef
6773
+ initializedSelectSourceActionRef
6812
6774
  };
6813
6775
  }
6814
6776
  function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransferIdRef, stateTransfer, refs, onComplete) {
@@ -6827,7 +6789,7 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
6827
6789
  guestPollingActiveRef.current = true;
6828
6790
  let cancelled = false;
6829
6791
  const POLL_INTERVAL_MS = 3e3;
6830
- dispatch({ type: "NAVIGATE", step: "processing" });
6792
+ dispatch({ type: "SET_ERROR", error: null });
6831
6793
  const poll = async () => {
6832
6794
  if (cancelled) return;
6833
6795
  try {
@@ -6961,7 +6923,6 @@ function useProviderHandlers(deps) {
6961
6923
  }
6962
6924
  if (!activeCredentialId) {
6963
6925
  dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
6964
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
6965
6926
  return null;
6966
6927
  }
6967
6928
  const provider = providers.find((p) => p.id === providerId);
@@ -6982,7 +6943,7 @@ function useProviderHandlers(deps) {
6982
6943
  } catch (err) {
6983
6944
  captureException(err);
6984
6945
  const msg = err instanceof Error ? err.message : "Failed to set up wallet";
6985
- dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
6946
+ dispatch({ type: "PAY_ERROR", error: msg });
6986
6947
  onError?.(msg);
6987
6948
  return null;
6988
6949
  }
@@ -6990,7 +6951,7 @@ function useProviderHandlers(deps) {
6990
6951
  const handleGuestSelectProvider = react.useCallback(async (providerId) => {
6991
6952
  if (!merchantAuthorization || !destination) {
6992
6953
  const msg = "Missing payment configuration for guest checkout.";
6993
- dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
6954
+ dispatch({ type: "PAY_ERROR", error: msg });
6994
6955
  onError?.(msg);
6995
6956
  return;
6996
6957
  }
@@ -7012,7 +6973,7 @@ function useProviderHandlers(deps) {
7012
6973
  });
7013
6974
  if (isMobile) {
7014
6975
  if (!result.uri) {
7015
- dispatch({ type: "PAY_ERROR", error: "This wallet is not available on mobile.", fallbackStep: "wallet-picker" });
6976
+ dispatch({ type: "PAY_ERROR", error: "This wallet is not available on mobile." });
7016
6977
  return;
7017
6978
  }
7018
6979
  persistMobileFlowState({
@@ -7030,7 +6991,7 @@ function useProviderHandlers(deps) {
7030
6991
  if (!account.isConnected) {
7031
6992
  const connector = connectors.find((c) => c.type === "injected") ?? connectors[0];
7032
6993
  if (!connector) {
7033
- dispatch({ type: "PAY_ERROR", error: "No wallet extension found. Please install a supported wallet.", fallbackStep: "wallet-picker" });
6994
+ dispatch({ type: "PAY_ERROR", error: "No wallet extension found. Please install a supported wallet." });
7034
6995
  return;
7035
6996
  }
7036
6997
  await connectAsync({ connector });
@@ -7045,7 +7006,7 @@ function useProviderHandlers(deps) {
7045
7006
  } catch (err) {
7046
7007
  captureException(err);
7047
7008
  const msg = err instanceof Error ? err.message : "Failed to start guest checkout";
7048
- dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
7009
+ dispatch({ type: "PAY_ERROR", error: msg });
7049
7010
  onError?.(msg);
7050
7011
  }
7051
7012
  }, [
@@ -7068,7 +7029,6 @@ function useProviderHandlers(deps) {
7068
7029
  dispatch({ type: "SELECT_PROVIDER", providerId });
7069
7030
  if (!activeCredentialId) {
7070
7031
  dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
7071
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
7072
7032
  return;
7073
7033
  }
7074
7034
  const provider = providers.find((p) => p.id === providerId);
@@ -7078,8 +7038,7 @@ function useProviderHandlers(deps) {
7078
7038
  userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
7079
7039
  });
7080
7040
  if (!isMobile) {
7081
- dispatch({ type: "PAY_STARTED", isSetupRedirect: false });
7082
- dispatch({ type: "NAVIGATE", step: "open-wallet" });
7041
+ dispatch({ type: "PAY_STARTED" });
7083
7042
  }
7084
7043
  try {
7085
7044
  let accountId;
@@ -7121,12 +7080,11 @@ function useProviderHandlers(deps) {
7121
7080
  } else {
7122
7081
  await authExecutor.executeSessionById(sessionId);
7123
7082
  await reloadAccounts();
7124
- dispatch({ type: "NAVIGATE", step: "deposit" });
7125
7083
  }
7126
7084
  } catch (err) {
7127
7085
  captureException(err);
7128
7086
  const msg = err instanceof Error ? err.message : "Failed to set up wallet";
7129
- dispatch({ type: "PAY_ERROR", error: msg, fallbackStep: "wallet-picker" });
7087
+ dispatch({ type: "PAY_ERROR", error: msg });
7130
7088
  onError?.(msg);
7131
7089
  } finally {
7132
7090
  if (!isMobile) {
@@ -7190,7 +7148,6 @@ function useProviderHandlers(deps) {
7190
7148
  }
7191
7149
  if (!activeCredentialId) {
7192
7150
  dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
7193
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
7194
7151
  return;
7195
7152
  }
7196
7153
  const acct = accounts.find((a) => a.id === selectedAccountId);
@@ -7236,10 +7193,8 @@ function useProviderHandlers(deps) {
7236
7193
  dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
7237
7194
  triggerDeeplink(session.uri);
7238
7195
  } else {
7239
- dispatch({ type: "NAVIGATE", step: "open-wallet" });
7240
7196
  await authExecutor.executeSessionById(session.id);
7241
7197
  await reloadAccounts();
7242
- dispatch({ type: "NAVIGATE", step: "deposit" });
7243
7198
  }
7244
7199
  } catch (err) {
7245
7200
  captureException(err);
@@ -7271,12 +7226,8 @@ function useProviderHandlers(deps) {
7271
7226
  reauthTokenRef
7272
7227
  ]);
7273
7228
  const handleNavigateToTokenPicker = react.useCallback(() => {
7274
- if (authExecutor.pendingSelectSource) {
7275
- dispatch({ type: "NAVIGATE", step: "select-source" });
7276
- } else {
7277
- dispatch({ type: "NAVIGATE", step: "token-picker" });
7278
- }
7279
- }, [dispatch, authExecutor.pendingSelectSource]);
7229
+ dispatch({ type: "SET_USER_INTENT", intent: "pick-token" });
7230
+ }, [dispatch]);
7280
7231
  const handleSelectAuthorizedToken = react.useCallback((walletId, tokenSymbol) => {
7281
7232
  dispatch({ type: "SELECT_TOKEN", walletId, tokenSymbol });
7282
7233
  }, [dispatch]);
@@ -7287,7 +7238,6 @@ function useProviderHandlers(deps) {
7287
7238
  }
7288
7239
  if (!activeCredentialId) {
7289
7240
  dispatch({ type: "SET_ERROR", error: "Create or verify a passkey on this device before continuing." });
7290
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
7291
7241
  return;
7292
7242
  }
7293
7243
  const acct = accounts.find((a) => a.id === selectedAccountId);
@@ -7329,7 +7279,6 @@ function useProviderHandlers(deps) {
7329
7279
  dispatch({ type: "MOBILE_DEEPLINK_READY", deeplinkUri: session.uri });
7330
7280
  triggerDeeplink(session.uri);
7331
7281
  } else {
7332
- dispatch({ type: "NAVIGATE", step: "open-wallet" });
7333
7282
  await authExecutor.executeSessionById(session.id);
7334
7283
  await reloadAccounts();
7335
7284
  dispatch({ type: "SELECT_TOKEN", walletId: _walletId, tokenSymbol });
@@ -7401,7 +7350,6 @@ function useGuestTransferHandlers(deps) {
7401
7350
  isGuestFlow,
7402
7351
  guestTransferId,
7403
7352
  guestSessionToken,
7404
- step,
7405
7353
  onComplete,
7406
7354
  onError
7407
7355
  } = deps;
@@ -7415,8 +7363,7 @@ function useGuestTransferHandlers(deps) {
7415
7363
  const fetchedRef = react.useRef(false);
7416
7364
  const selectedGuestTokenRef = react.useRef(null);
7417
7365
  react.useEffect(() => {
7418
- if (!isGuestFlow || step !== "token-picker" || fetchedRef.current) return;
7419
- if (!guestTransferId || !guestSessionToken) return;
7366
+ if (!isGuestFlow || !guestTransferId || !guestSessionToken || fetchedRef.current) return;
7420
7367
  const account = getAccount(wagmiConfig2);
7421
7368
  if (!account.address) return;
7422
7369
  fetchedRef.current = true;
@@ -7430,7 +7377,7 @@ function useGuestTransferHandlers(deps) {
7430
7377
  captureException(err);
7431
7378
  dispatch({ type: "SET_ERROR", error: "Failed to fetch token balances." });
7432
7379
  }).finally(() => setLoadingBalances(false));
7433
- }, [isGuestFlow, step, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, dispatch]);
7380
+ }, [isGuestFlow, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, dispatch]);
7434
7381
  react.useEffect(() => {
7435
7382
  if (!isGuestFlow) {
7436
7383
  fetchedRef.current = false;
@@ -7459,7 +7406,6 @@ function useGuestTransferHandlers(deps) {
7459
7406
  entry.tokenAddress
7460
7407
  );
7461
7408
  selectedGuestTokenRef.current = entry;
7462
- dispatch({ type: "NAVIGATE", step: "processing" });
7463
7409
  } catch (err) {
7464
7410
  captureException(err);
7465
7411
  const msg = err instanceof Error ? err.message : "Failed to set transfer sender";
@@ -7470,7 +7416,7 @@ function useGuestTransferHandlers(deps) {
7470
7416
  }
7471
7417
  }, [guestTransferId, guestSessionToken, wagmiConfig2, apiBaseUrl, dispatch, onError]);
7472
7418
  react.useEffect(() => {
7473
- if (!isGuestFlow || step !== "processing" || !guestTransferId || !guestSessionToken) return;
7419
+ if (!isGuestFlow || !guestTransferId || !guestSessionToken || !selectedGuestTokenRef.current) return;
7474
7420
  if (executingBridgeRef.current) return;
7475
7421
  executingBridgeRef.current = true;
7476
7422
  const execute = async () => {
@@ -7484,7 +7430,7 @@ function useGuestTransferHandlers(deps) {
7484
7430
  break;
7485
7431
  }
7486
7432
  if (transfer.status === "FAILED") {
7487
- dispatch({ type: "PAY_ERROR", error: "Transfer failed.", fallbackStep: "wallet-picker" });
7433
+ dispatch({ type: "PAY_ERROR", error: "Transfer failed." });
7488
7434
  return;
7489
7435
  }
7490
7436
  await new Promise((r) => setTimeout(r, GUEST_SIGN_POLL_MS));
@@ -7492,8 +7438,7 @@ function useGuestTransferHandlers(deps) {
7492
7438
  if (!signPayload) {
7493
7439
  dispatch({
7494
7440
  type: "PAY_ERROR",
7495
- error: "Timed out waiting for bridge quote. Please try again.",
7496
- fallbackStep: "wallet-picker"
7441
+ error: "Timed out waiting for bridge quote. Please try again."
7497
7442
  });
7498
7443
  return;
7499
7444
  }
@@ -7513,7 +7458,7 @@ function useGuestTransferHandlers(deps) {
7513
7458
  const walletClient = await getWalletClient(wagmiConfig2);
7514
7459
  const sender = account.address;
7515
7460
  if (!sender) {
7516
- dispatch({ type: "PAY_ERROR", error: "Wallet not connected.", fallbackStep: "wallet-picker" });
7461
+ dispatch({ type: "PAY_ERROR", error: "Wallet not connected." });
7517
7462
  return;
7518
7463
  }
7519
7464
  let lastTxHash = null;
@@ -7538,7 +7483,7 @@ function useGuestTransferHandlers(deps) {
7538
7483
  lastTxHash = txHash;
7539
7484
  }
7540
7485
  if (!lastTxHash) {
7541
- dispatch({ type: "PAY_ERROR", error: "No bridge transactions were executed.", fallbackStep: "wallet-picker" });
7486
+ dispatch({ type: "PAY_ERROR", error: "No bridge transactions were executed." });
7542
7487
  return;
7543
7488
  }
7544
7489
  console.info(`[blink-sdk] type=guest Submitting originTxHash: ${lastTxHash}`);
@@ -7559,22 +7504,21 @@ function useGuestTransferHandlers(deps) {
7559
7504
  }
7560
7505
  dispatch({
7561
7506
  type: "PAY_ERROR",
7562
- error: "Transfer is taking longer than expected. It may still complete.",
7563
- fallbackStep: "wallet-picker"
7507
+ error: "Transfer is taking longer than expected. It may still complete."
7564
7508
  });
7565
7509
  } catch (err) {
7566
7510
  captureException(err);
7567
7511
  const msg = err instanceof Error ? err.message : "Bridge execution failed";
7568
7512
  console.error("[blink-sdk] type=guest Bridge execution error:", err);
7569
7513
  const displayMsg = isUserRejection2(msg) ? "You rejected the transaction. Please approve in your wallet to continue." : msg;
7570
- dispatch({ type: "PAY_ERROR", error: displayMsg, fallbackStep: "wallet-picker" });
7514
+ dispatch({ type: "PAY_ERROR", error: displayMsg });
7571
7515
  onError?.(displayMsg);
7572
7516
  } finally {
7573
7517
  executingBridgeRef.current = false;
7574
7518
  }
7575
7519
  };
7576
7520
  execute();
7577
- }, [isGuestFlow, step, guestTransferId, guestSessionToken, apiBaseUrl, wagmiConfig2, switchChainAsync, dispatch, onComplete, onError]);
7521
+ }, [isGuestFlow, guestTransferId, guestSessionToken, settingSender, apiBaseUrl, wagmiConfig2, switchChainAsync, dispatch, onComplete, onError]);
7578
7522
  return {
7579
7523
  guestTokenEntries,
7580
7524
  loadingBalances,
@@ -7615,12 +7559,10 @@ function useOneTapSetupHandlers(deps) {
7615
7559
  }
7616
7560
  oneTapLimitSavedDuringSetupRef.current = true;
7617
7561
  authExecutor.resolveSelectSource({ chainName, tokenSymbol });
7618
- dispatch({ type: "NAVIGATE", step: "open-wallet" });
7619
7562
  } else if (authExecutor.pendingOneTapSetup) {
7620
7563
  authExecutor.resolveOneTapSetup();
7621
- } else {
7622
- dispatch({ type: "NAVIGATE", step: "deposit" });
7623
7564
  }
7565
+ dispatch({ type: "SET_USER_INTENT", intent: null });
7624
7566
  } catch (err) {
7625
7567
  captureException(err);
7626
7568
  dispatch({
@@ -7641,12 +7583,11 @@ function useOneTapSetupHandlers(deps) {
7641
7583
  // src/dataLoading.ts
7642
7584
  function resolveDataLoadAction({
7643
7585
  authenticated,
7644
- step,
7645
7586
  accountsCount,
7646
7587
  hasActiveCredential,
7647
7588
  loading
7648
7589
  }) {
7649
- if (!authenticated || step === "login" || step === "otp-verify" || accountsCount > 0 || !hasActiveCredential) {
7590
+ if (!authenticated || accountsCount > 0 || !hasActiveCredential) {
7650
7591
  return "reset";
7651
7592
  }
7652
7593
  if (loading) {
@@ -7693,7 +7634,6 @@ function usePaymentEffects(deps) {
7693
7634
  authenticated,
7694
7635
  apiBaseUrl,
7695
7636
  depositAmount,
7696
- useWalletConnectorProp,
7697
7637
  onComplete,
7698
7638
  onError,
7699
7639
  polling,
@@ -7720,7 +7660,6 @@ function usePaymentEffects(deps) {
7720
7660
  setSelectSourceChainName,
7721
7661
  setSelectSourceTokenSymbol,
7722
7662
  initializedSelectSourceActionRef,
7723
- preSelectSourceStepRef,
7724
7663
  oneTapLimitSavedDuringSetupRef,
7725
7664
  handleAuthorizedMobileReturn
7726
7665
  } = deps;
@@ -7740,27 +7679,27 @@ function usePaymentEffects(deps) {
7740
7679
  }
7741
7680
  }, [depositAmount, dispatch]);
7742
7681
  react.useEffect(() => {
7743
- if (authenticated || state.step !== "otp-verify") return;
7682
+ if (authenticated || !state.verificationTarget) return;
7744
7683
  if (activeOtpErrorMessage) dispatch({ type: "SET_ERROR", error: activeOtpErrorMessage });
7745
- }, [activeOtpErrorMessage, authenticated, state.step, dispatch]);
7684
+ }, [activeOtpErrorMessage, authenticated, state.verificationTarget, dispatch]);
7746
7685
  react.useEffect(() => {
7747
- if (state.step === "otp-verify" && /^\d{6}$/.test(otpCode.trim()) && activeOtpStatus === "awaiting-code-input") {
7686
+ if (state.verificationTarget && !authenticated && /^\d{6}$/.test(otpCode.trim()) && activeOtpStatus === "awaiting-code-input") {
7748
7687
  handleVerifyLoginCode();
7749
7688
  }
7750
- }, [otpCode, state.step, activeOtpStatus, handleVerifyLoginCode]);
7689
+ }, [otpCode, state.verificationTarget, authenticated, activeOtpStatus, handleVerifyLoginCode]);
7751
7690
  react.useEffect(() => {
7752
7691
  if (!ready || !authenticated) {
7753
7692
  checkingPasskeyRef.current = false;
7754
7693
  return;
7755
7694
  }
7756
- if (state.step !== "login" && state.step !== "otp-verify") return;
7695
+ if (state.passkeyConfigLoaded || state.activeCredentialId) return;
7757
7696
  if (checkingPasskeyRef.current) return;
7758
7697
  checkingPasskeyRef.current = true;
7759
7698
  let cancelled = false;
7760
7699
  dispatch({ type: "SET_ERROR", error: null });
7761
7700
  setAuthInput("");
7762
7701
  setOtpCode("");
7763
- const restoreOrDeposit = async (credId, token) => {
7702
+ const restoreState = async (credId, token) => {
7764
7703
  const persisted = loadMobileFlowState();
7765
7704
  let accts = [];
7766
7705
  try {
@@ -7768,117 +7707,118 @@ function usePaymentEffects(deps) {
7768
7707
  if (cancelled) return;
7769
7708
  } catch {
7770
7709
  }
7771
- const resolved = resolvePostAuthStep({
7772
- hasPasskey: true,
7773
- accounts: accts,
7774
- persistedMobileFlow: persisted,
7775
- mobileSetupInProgress: false,
7776
- connectingNewAccount: false
7777
- });
7778
- if (resolved.clearPersistedFlow) clearMobileFlowState();
7779
- if (resolved.step === "deposit" && persisted && persisted.isSetup && persisted.transferId) {
7780
- try {
7781
- const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
7782
- if (cancelled) return;
7783
- if (existingTransfer.status === "AUTHORIZED") {
7784
- await handleAuthorizedMobileReturnRef.current(existingTransfer, true);
7785
- return;
7786
- }
7787
- } catch {
7788
- }
7789
- }
7790
- if (resolved.step === "open-wallet" && persisted && persisted.isReauthorization && persisted.sessionId) {
7791
- try {
7792
- const session = await fetchAuthorizationSession(apiBaseUrl, persisted.sessionId);
7793
- if (cancelled) return;
7794
- if (session.status === "AUTHORIZED") {
7795
- clearMobileFlowState();
7796
- dispatch({ type: "NAVIGATE", step: "deposit" });
7797
- if (persisted.reauthorizationToken) {
7798
- dispatch({ type: "SELECT_TOKEN", walletId: persisted.reauthorizationToken.walletId, tokenSymbol: persisted.reauthorizationToken.tokenSymbol });
7799
- }
7800
- return;
7801
- }
7802
- } catch {
7803
- }
7804
- reauthSessionIdRef.current = persisted.sessionId;
7805
- reauthTokenRef.current = persisted.reauthorizationToken ?? null;
7806
- mobileSetupFlowRef.current = true;
7807
- setupAccountIdRef.current = persisted.accountId ?? null;
7808
- dispatch({
7809
- type: "ENTER_MOBILE_FLOW",
7810
- deeplinkUri: persisted.deeplinkUri,
7811
- providerId: persisted.providerId
7812
- });
7813
- return;
7814
- }
7815
- if (resolved.step === "open-wallet" && persisted && persisted.accountId && !persisted.transferId) {
7816
- if (persisted.sessionId) {
7710
+ if (persisted) {
7711
+ if (persisted.isReauthorization && persisted.sessionId) {
7817
7712
  try {
7818
7713
  const session = await fetchAuthorizationSession(apiBaseUrl, persisted.sessionId);
7819
7714
  if (cancelled) return;
7820
7715
  if (session.status === "AUTHORIZED") {
7821
7716
  clearMobileFlowState();
7822
- dispatch({ type: "NAVIGATE", step: "deposit" });
7717
+ if (persisted.reauthorizationToken) {
7718
+ dispatch({ type: "SELECT_TOKEN", walletId: persisted.reauthorizationToken.walletId, tokenSymbol: persisted.reauthorizationToken.tokenSymbol });
7719
+ }
7823
7720
  return;
7824
7721
  }
7825
7722
  } catch {
7826
7723
  }
7724
+ reauthSessionIdRef.current = persisted.sessionId;
7725
+ reauthTokenRef.current = persisted.reauthorizationToken ?? null;
7726
+ mobileSetupFlowRef.current = true;
7727
+ setupAccountIdRef.current = persisted.accountId ?? null;
7728
+ dispatch({
7729
+ type: "ENTER_MOBILE_FLOW",
7730
+ deeplinkUri: persisted.deeplinkUri,
7731
+ providerId: persisted.providerId
7732
+ });
7733
+ return;
7827
7734
  }
7828
- mobileSetupFlowRef.current = true;
7829
- setupAccountIdRef.current = persisted.accountId;
7830
- dispatch({
7831
- type: "ENTER_MOBILE_FLOW",
7832
- deeplinkUri: persisted.deeplinkUri,
7833
- providerId: persisted.providerId
7834
- });
7835
- return;
7836
- }
7837
- if (resolved.step === "open-wallet" && persisted && persisted.transferId) {
7838
- try {
7839
- const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
7840
- if (cancelled) return;
7841
- const mobileResolution = resolveRestoredMobileFlow(
7842
- existingTransfer.status,
7843
- persisted.isSetup
7844
- );
7845
- if (mobileResolution.kind === "resume-setup-deposit") {
7846
- await handleAuthorizedMobileReturnRef.current(existingTransfer, true);
7847
- return;
7848
- }
7849
- if (mobileResolution.kind === "resume-confirm-sign") {
7850
- await handleAuthorizedMobileReturnRef.current(existingTransfer, false);
7851
- return;
7852
- }
7853
- if (mobileResolution.kind === "resume-success") {
7854
- clearMobileFlowState();
7855
- dispatch({ type: "MOBILE_RESUME_SUCCESS", transfer: existingTransfer });
7856
- onCompleteRef.current?.(existingTransfer);
7857
- return;
7858
- }
7859
- if (mobileResolution.kind === "resume-failed") {
7860
- clearMobileFlowState();
7861
- dispatch({ type: "MOBILE_RESUME_FAILED", transfer: existingTransfer });
7862
- return;
7735
+ if (persisted.isSetup && persisted.transferId) {
7736
+ try {
7737
+ const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
7738
+ if (cancelled) return;
7739
+ if (existingTransfer.status === "AUTHORIZED") {
7740
+ await handleAuthorizedMobileReturnRef.current(existingTransfer, true);
7741
+ return;
7742
+ }
7743
+ } catch {
7863
7744
  }
7864
- if (mobileResolution.kind === "resume-processing") {
7865
- clearMobileFlowState();
7866
- dispatch({ type: "MOBILE_RESUME_PROCESSING", transfer: existingTransfer });
7867
- pollingRef.current.startPolling(existingTransfer.id);
7868
- return;
7745
+ }
7746
+ if (persisted.isSetup && accts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"))) {
7747
+ clearMobileFlowState();
7748
+ return;
7749
+ }
7750
+ if (persisted.accountId && !persisted.transferId) {
7751
+ if (persisted.sessionId) {
7752
+ try {
7753
+ const session = await fetchAuthorizationSession(apiBaseUrl, persisted.sessionId);
7754
+ if (cancelled) return;
7755
+ if (session.status === "AUTHORIZED") {
7756
+ clearMobileFlowState();
7757
+ return;
7758
+ }
7759
+ } catch {
7760
+ }
7869
7761
  }
7870
- if (mobileResolution.kind === "resume-stale-setup") {
7871
- clearMobileFlowState();
7872
- if (!cancelled) dispatch({ type: "NAVIGATE", step: "wallet-picker" });
7762
+ mobileSetupFlowRef.current = true;
7763
+ setupAccountIdRef.current = persisted.accountId;
7764
+ dispatch({
7765
+ type: "ENTER_MOBILE_FLOW",
7766
+ deeplinkUri: persisted.deeplinkUri,
7767
+ providerId: persisted.providerId
7768
+ });
7769
+ return;
7770
+ }
7771
+ if (persisted.transferId) {
7772
+ try {
7773
+ const existingTransfer = await fetchTransfer(apiBaseUrl, token, persisted.transferId);
7774
+ if (cancelled) return;
7775
+ if (existingTransfer.status === "COMPLETED") {
7776
+ clearMobileFlowState();
7777
+ dispatch({ type: "MOBILE_RESUME_SUCCESS", transfer: existingTransfer });
7778
+ onCompleteRef.current?.(existingTransfer);
7779
+ return;
7780
+ }
7781
+ if (existingTransfer.status === "FAILED") {
7782
+ clearMobileFlowState();
7783
+ dispatch({ type: "MOBILE_RESUME_FAILED", transfer: existingTransfer });
7784
+ return;
7785
+ }
7786
+ if (existingTransfer.status === "SENDING" || existingTransfer.status === "SENT") {
7787
+ clearMobileFlowState();
7788
+ dispatch({ type: "MOBILE_RESUME_PROCESSING", transfer: existingTransfer });
7789
+ pollingRef.current.startPolling(existingTransfer.id);
7790
+ return;
7791
+ }
7792
+ if (existingTransfer.status === "AUTHORIZED") {
7793
+ if (persisted.isSetup) {
7794
+ await handleAuthorizedMobileReturnRef.current(existingTransfer, true);
7795
+ } else {
7796
+ await handleAuthorizedMobileReturnRef.current(existingTransfer, false);
7797
+ }
7798
+ return;
7799
+ }
7800
+ if (persisted.isSetup) {
7801
+ clearMobileFlowState();
7802
+ return;
7803
+ }
7804
+ } catch (err) {
7805
+ if (cancelled) return;
7806
+ dispatch({
7807
+ type: "ENTER_MOBILE_FLOW",
7808
+ deeplinkUri: persisted.deeplinkUri,
7809
+ providerId: persisted.providerId,
7810
+ error: err instanceof Error ? err.message : "Unable to refresh wallet authorization status."
7811
+ });
7812
+ pollingTransferIdRef.current = persisted.transferId ?? null;
7813
+ mobileSetupFlowRef.current = persisted.isSetup;
7814
+ setupAccountIdRef.current = persisted.accountId ?? null;
7815
+ if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
7873
7816
  return;
7874
7817
  }
7875
- } catch (err) {
7876
- if (cancelled) return;
7877
7818
  dispatch({
7878
7819
  type: "ENTER_MOBILE_FLOW",
7879
7820
  deeplinkUri: persisted.deeplinkUri,
7880
- providerId: persisted.providerId,
7881
- error: err instanceof Error ? err.message : "Unable to refresh wallet authorization status."
7821
+ providerId: persisted.providerId
7882
7822
  });
7883
7823
  pollingTransferIdRef.current = persisted.transferId ?? null;
7884
7824
  mobileSetupFlowRef.current = persisted.isSetup;
@@ -7886,18 +7826,7 @@ function usePaymentEffects(deps) {
7886
7826
  if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
7887
7827
  return;
7888
7828
  }
7889
- dispatch({
7890
- type: "ENTER_MOBILE_FLOW",
7891
- deeplinkUri: persisted.deeplinkUri,
7892
- providerId: persisted.providerId
7893
- });
7894
- pollingTransferIdRef.current = persisted.transferId ?? null;
7895
- mobileSetupFlowRef.current = persisted.isSetup;
7896
- setupAccountIdRef.current = persisted.accountId ?? null;
7897
- if (persisted.transferId) pollingRef.current.startPolling(persisted.transferId);
7898
- return;
7899
7829
  }
7900
- dispatch({ type: "NAVIGATE", step: resolved.step });
7901
7830
  };
7902
7831
  const checkPasskey = async () => {
7903
7832
  try {
@@ -7907,11 +7836,7 @@ function usePaymentEffects(deps) {
7907
7836
  if (token || cancelled) break;
7908
7837
  await new Promise((r) => setTimeout(r, 1e3));
7909
7838
  }
7910
- if (!token) {
7911
- if (!cancelled) dispatch({ type: "NAVIGATE", step: "create-passkey" });
7912
- return;
7913
- }
7914
- if (cancelled) return;
7839
+ if (!token || cancelled) return;
7915
7840
  const { config } = await fetchUserConfig(apiBaseUrl, token);
7916
7841
  if (cancelled) return;
7917
7842
  const allPasskeys = config.passkeys ?? (config.passkey ? [config.passkey] : []);
@@ -7921,11 +7846,10 @@ function usePaymentEffects(deps) {
7921
7846
  oneTapLimit: config.defaultAllowance ?? void 0
7922
7847
  });
7923
7848
  if (allPasskeys.length === 0) {
7924
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
7925
7849
  return;
7926
7850
  }
7927
7851
  if (state.activeCredentialId && allPasskeys.some((p) => p.credentialId === state.activeCredentialId)) {
7928
- await restoreOrDeposit(state.activeCredentialId, token);
7852
+ await restoreState(state.activeCredentialId, token);
7929
7853
  return;
7930
7854
  }
7931
7855
  if (cancelled) return;
@@ -7947,12 +7871,9 @@ function usePaymentEffects(deps) {
7947
7871
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
7948
7872
  reportPasskeyActivity(apiBaseUrl, token, matched).catch(() => {
7949
7873
  });
7950
- await restoreOrDeposit(matched, token);
7951
- return;
7874
+ await restoreState(matched, token);
7952
7875
  }
7953
- dispatch({ type: "NAVIGATE", step: "create-passkey" });
7954
7876
  } catch {
7955
- if (!cancelled) dispatch({ type: "NAVIGATE", step: "create-passkey" });
7956
7877
  }
7957
7878
  };
7958
7879
  checkPasskey();
@@ -7960,11 +7881,10 @@ function usePaymentEffects(deps) {
7960
7881
  cancelled = true;
7961
7882
  checkingPasskeyRef.current = false;
7962
7883
  };
7963
- }, [ready, authenticated, state.step, apiBaseUrl, state.activeCredentialId]);
7884
+ }, [ready, authenticated, apiBaseUrl, state.activeCredentialId, state.passkeyConfigLoaded]);
7964
7885
  react.useEffect(() => {
7965
7886
  const loadAction = resolveDataLoadAction({
7966
7887
  authenticated,
7967
- step: state.step,
7968
7888
  accountsCount: state.accounts.length,
7969
7889
  hasActiveCredential: !!state.activeCredentialId,
7970
7890
  loading: loadingDataRef.current
@@ -7997,24 +7917,16 @@ function usePaymentEffects(deps) {
7997
7917
  const parsedAmt = depositAmount != null ? depositAmount : 0;
7998
7918
  const defaults = resolveDepositSelection(accts, parsedAmt, state.selectedAccountId);
7999
7919
  const persisted = loadMobileFlowState();
8000
- const resolved = resolvePostAuthStep({
8001
- hasPasskey: !!state.activeCredentialId,
8002
- accounts: accts,
8003
- persistedMobileFlow: persisted,
8004
- mobileSetupInProgress: mobileSetupFlowRef.current,
8005
- connectingNewAccount: false
8006
- });
8007
- const correctableSteps = ["deposit", "wallet-picker", "open-wallet"];
7920
+ const clearMobile = persisted?.isSetup && accts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
8008
7921
  dispatch({
8009
7922
  type: "DATA_LOADED",
8010
7923
  providers: prov,
8011
7924
  accounts: accts,
8012
7925
  chains: chn,
8013
7926
  defaults,
8014
- resolvedStep: correctableSteps.includes(state.step) && !state.creatingTransfer ? resolved.step : void 0,
8015
- clearMobileState: resolved.clearPersistedFlow
7927
+ clearMobileState: clearMobile
8016
7928
  });
8017
- if (resolved.clearPersistedFlow) clearMobileFlowState();
7929
+ if (clearMobile) clearMobileFlowState();
8018
7930
  } catch (err) {
8019
7931
  if (!cancelled) {
8020
7932
  captureException(err);
@@ -8037,7 +7949,6 @@ function usePaymentEffects(deps) {
8037
7949
  };
8038
7950
  }, [
8039
7951
  authenticated,
8040
- state.step,
8041
7952
  state.accounts.length,
8042
7953
  apiBaseUrl,
8043
7954
  state.activeCredentialId,
@@ -8046,7 +7957,7 @@ function usePaymentEffects(deps) {
8046
7957
  ]);
8047
7958
  react.useEffect(() => {
8048
7959
  if (authenticated || state.providers.length > 0) return;
8049
- if (state.step !== "wallet-picker") return;
7960
+ if (state.activeCredentialId) return;
8050
7961
  let cancelled = false;
8051
7962
  const loadProviders = async () => {
8052
7963
  try {
@@ -8069,7 +7980,7 @@ function usePaymentEffects(deps) {
8069
7980
  return () => {
8070
7981
  cancelled = true;
8071
7982
  };
8072
- }, [authenticated, state.step, state.providers.length, apiBaseUrl]);
7983
+ }, [authenticated, state.providers.length, state.activeCredentialId, apiBaseUrl]);
8073
7984
  react.useEffect(() => {
8074
7985
  if (!polling.transfer) return;
8075
7986
  if (polling.transfer.status === "COMPLETED") {
@@ -8083,13 +7994,21 @@ function usePaymentEffects(deps) {
8083
7994
  }
8084
7995
  }, [polling.transfer, onComplete, dispatch, reloadAccounts]);
8085
7996
  react.useEffect(() => {
8086
- if (state.step === "deposit" && state.accounts.length > 0 && authenticated && Date.now() - lastAccountFetchRef.current > 15e3) {
7997
+ if (state.accounts.length > 0 && state.activeCredentialId && !state.loadingData && !state.transfer && authenticated && Date.now() - lastAccountFetchRef.current > 15e3) {
8087
7998
  lastAccountFetchRef.current = Date.now();
8088
7999
  reloadAccounts();
8089
8000
  }
8090
- }, [state.step, state.accounts.length, authenticated, reloadAccounts]);
8001
+ }, [
8002
+ state.accounts.length,
8003
+ state.activeCredentialId,
8004
+ state.loadingData,
8005
+ state.transfer,
8006
+ authenticated,
8007
+ reloadAccounts
8008
+ ]);
8091
8009
  react.useEffect(() => {
8092
- if (state.step !== "processing") {
8010
+ const isProcessing = state.creatingTransfer || state.transfer != null && ["CREATED", "SENDING", "SENT"].includes(state.transfer.status);
8011
+ if (!isProcessing) {
8093
8012
  processingStartedAtRef.current = null;
8094
8013
  return;
8095
8014
  }
@@ -8113,7 +8032,15 @@ function usePaymentEffects(deps) {
8113
8032
  }
8114
8033
  const timeoutId = window.setTimeout(handleTimeout, remainingMs);
8115
8034
  return () => window.clearTimeout(timeoutId);
8116
- }, [state.step, polling.transfer, state.transfer, polling.stopPolling, onError, dispatch, processingStartedAtRef]);
8035
+ }, [
8036
+ state.creatingTransfer,
8037
+ state.transfer,
8038
+ polling.transfer,
8039
+ polling.stopPolling,
8040
+ onError,
8041
+ dispatch,
8042
+ processingStartedAtRef
8043
+ ]);
8117
8044
  react.useEffect(() => {
8118
8045
  if (!state.mobileFlow) {
8119
8046
  handlingMobileReturnRef.current = false;
@@ -8126,7 +8053,6 @@ function usePaymentEffects(deps) {
8126
8053
  }, [state.mobileFlow, polling.transfer, handleAuthorizedMobileReturn, handlingMobileReturnRef, mobileSetupFlowRef]);
8127
8054
  react.useEffect(() => {
8128
8055
  if (!state.mobileFlow || !mobileSetupFlowRef.current) return;
8129
- if (state.step !== "open-wallet") return;
8130
8056
  if (!state.activeCredentialId || !setupAccountIdRef.current) return;
8131
8057
  const accountId = setupAccountIdRef.current;
8132
8058
  const credentialId = state.activeCredentialId;
@@ -8219,7 +8145,6 @@ function usePaymentEffects(deps) {
8219
8145
  };
8220
8146
  }, [
8221
8147
  state.mobileFlow,
8222
- state.step,
8223
8148
  state.activeCredentialId,
8224
8149
  apiBaseUrl,
8225
8150
  reloadAccounts,
@@ -8289,46 +8214,22 @@ function usePaymentEffects(deps) {
8289
8214
  setSelectSourceTokenSymbol,
8290
8215
  initializedSelectSourceActionRef
8291
8216
  ]);
8217
+ const pendingOneTapSetupAction = authExecutor.pendingOneTapSetup;
8292
8218
  react.useEffect(() => {
8293
- if (pendingSelectSourceAction && (state.step === "processing" || state.step === "open-wallet" || state.step === "setup-status")) {
8294
- const isDesktop = shouldUseWalletConnector({
8295
- useWalletConnector: useWalletConnectorProp,
8296
- userAgent: typeof navigator === "undefined" ? void 0 : navigator.userAgent
8297
- });
8298
- if (isDesktop && (state.step === "setup-status" || state.step === "open-wallet")) {
8299
- preSelectSourceStepRef.current = state.step;
8300
- dispatch({ type: "NAVIGATE", step: "setup" });
8301
- return;
8302
- }
8303
- preSelectSourceStepRef.current = state.step;
8304
- dispatch({ type: "NAVIGATE", step: "select-source" });
8305
- } else if (!pendingSelectSourceAction && state.step === "select-source") {
8306
- dispatch({ type: "NAVIGATE", step: preSelectSourceStepRef.current ?? "processing" });
8307
- preSelectSourceStepRef.current = null;
8219
+ if (pendingOneTapSetupAction && oneTapLimitSavedDuringSetupRef.current) {
8220
+ oneTapLimitSavedDuringSetupRef.current = false;
8221
+ authExecutor.resolveOneTapSetup();
8308
8222
  }
8309
- }, [pendingSelectSourceAction, state.step, useWalletConnectorProp, dispatch, preSelectSourceStepRef, authExecutor]);
8310
- const pendingOneTapSetupAction = authExecutor.pendingOneTapSetup;
8311
- const preOneTapSetupStepRef = react.useRef(null);
8223
+ }, [pendingOneTapSetupAction, authExecutor, oneTapLimitSavedDuringSetupRef]);
8312
8224
  react.useEffect(() => {
8313
- if (pendingOneTapSetupAction && (state.step === "setup-status" || state.step === "open-wallet")) {
8314
- if (oneTapLimitSavedDuringSetupRef.current) {
8315
- oneTapLimitSavedDuringSetupRef.current = false;
8316
- authExecutor.resolveOneTapSetup();
8317
- } else {
8318
- preOneTapSetupStepRef.current = state.step;
8319
- reloadAccounts().then(() => {
8320
- dispatch({ type: "NAVIGATE", step: "setup" });
8321
- });
8322
- }
8323
- } else if (!pendingOneTapSetupAction && state.step === "setup" && preOneTapSetupStepRef.current) {
8324
- dispatch({ type: "NAVIGATE", step: preOneTapSetupStepRef.current });
8325
- preOneTapSetupStepRef.current = null;
8225
+ if (pendingOneTapSetupAction && !oneTapLimitSavedDuringSetupRef.current) {
8226
+ reloadAccounts();
8326
8227
  }
8327
- }, [pendingOneTapSetupAction, state.step, reloadAccounts, authExecutor, dispatch, oneTapLimitSavedDuringSetupRef]);
8228
+ }, [pendingOneTapSetupAction, reloadAccounts, oneTapLimitSavedDuringSetupRef]);
8328
8229
  react.useEffect(() => {
8329
- if (state.step !== "success") return;
8330
8230
  if (!state.guestSessionToken) return;
8331
8231
  if (state.guestPreauthAccountId) return;
8232
+ if (!state.transfer || state.transfer.status !== "COMPLETED") return;
8332
8233
  let cancelled = false;
8333
8234
  const checkPreauth = async () => {
8334
8235
  try {
@@ -8344,7 +8245,7 @@ function usePaymentEffects(deps) {
8344
8245
  return () => {
8345
8246
  cancelled = true;
8346
8247
  };
8347
- }, [state.step, state.guestSessionToken, state.guestPreauthAccountId, apiBaseUrl, dispatch]);
8248
+ }, [state.transfer, state.guestSessionToken, state.guestPreauthAccountId, apiBaseUrl, dispatch]);
8348
8249
  const settingOwnerRef = react.useRef(false);
8349
8250
  react.useEffect(() => {
8350
8251
  if (!state.guestPreauthAccountId) return;
@@ -8515,7 +8416,6 @@ function BlinkPaymentInner({
8515
8416
  isGuestFlow: state.isGuestFlow,
8516
8417
  guestTransferId: state.guestTransferId,
8517
8418
  guestSessionToken: state.guestSessionToken,
8518
- step: state.step,
8519
8419
  onComplete,
8520
8420
  onError
8521
8421
  });
@@ -8523,14 +8423,13 @@ function BlinkPaymentInner({
8523
8423
  clearMobileFlowState();
8524
8424
  transfer.processingStartedAtRef.current = null;
8525
8425
  transfer.pollingTransferIdRef.current = null;
8526
- sourceSelection.preSelectSourceStepRef.current = null;
8527
8426
  oneTapSetup.oneTapLimitSavedDuringSetupRef.current = false;
8528
8427
  dispatch({
8529
8428
  type: "NEW_PAYMENT",
8530
8429
  depositAmount,
8531
8430
  firstAccountId: state.accounts.length > 0 ? state.accounts[0].id : null
8532
8431
  });
8533
- }, [depositAmount, state.accounts, transfer, sourceSelection, provider, oneTapSetup]);
8432
+ }, [depositAmount, state.accounts, transfer, oneTapSetup]);
8534
8433
  const handleLogout = react.useCallback(async () => {
8535
8434
  try {
8536
8435
  await logout();
@@ -8541,13 +8440,12 @@ function BlinkPaymentInner({
8541
8440
  window.localStorage.removeItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
8542
8441
  }
8543
8442
  polling.stopPolling();
8544
- sourceSelection.preSelectSourceStepRef.current = null;
8545
8443
  passkey.checkingPasskeyRef.current = false;
8546
8444
  oneTapSetup.oneTapLimitSavedDuringSetupRef.current = false;
8547
8445
  auth.setAuthInput("");
8548
8446
  auth.setOtpCode("");
8549
8447
  dispatch({ type: "LOGOUT", depositAmount });
8550
- }, [logout, polling, depositAmount, auth, sourceSelection, provider, passkey, oneTapSetup]);
8448
+ }, [logout, polling, depositAmount, auth, passkey, oneTapSetup]);
8551
8449
  usePaymentEffects({
8552
8450
  state,
8553
8451
  dispatch,
@@ -8555,7 +8453,6 @@ function BlinkPaymentInner({
8555
8453
  authenticated,
8556
8454
  apiBaseUrl,
8557
8455
  depositAmount,
8558
- useWalletConnectorProp,
8559
8456
  onComplete,
8560
8457
  onError,
8561
8458
  polling,
@@ -8582,22 +8479,24 @@ function BlinkPaymentInner({
8582
8479
  setSelectSourceChainName: sourceSelection.setSelectSourceChainName,
8583
8480
  setSelectSourceTokenSymbol: sourceSelection.setSelectSourceTokenSymbol,
8584
8481
  initializedSelectSourceActionRef: sourceSelection.initializedSelectSourceActionRef,
8585
- preSelectSourceStepRef: sourceSelection.preSelectSourceStepRef,
8586
8482
  oneTapLimitSavedDuringSetupRef: oneTapSetup.oneTapLimitSavedDuringSetupRef,
8587
8483
  handleAuthorizedMobileReturn: mobileFlow.handleAuthorizedMobileReturn
8588
8484
  });
8589
8485
  const autoSelectingRef = react.useRef(false);
8590
8486
  react.useEffect(() => {
8591
- if (state.step !== "wallet-picker" || !state.isGuestFlow || !state.selectedProviderId || !state.activeCredentialId || !authenticated || autoSelectingRef.current) return;
8487
+ if (!state.isGuestFlow || !state.selectedProviderId || !state.activeCredentialId || !authenticated || autoSelectingRef.current || state.transfer != null) return;
8488
+ const hasActive = state.accounts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
8489
+ if (hasActive) return;
8592
8490
  autoSelectingRef.current = true;
8593
8491
  provider.handleSelectProvider(state.selectedProviderId).finally(() => {
8594
8492
  autoSelectingRef.current = false;
8595
8493
  });
8596
8494
  }, [
8597
- state.step,
8598
8495
  state.isGuestFlow,
8599
8496
  state.selectedProviderId,
8600
8497
  state.activeCredentialId,
8498
+ state.transfer,
8499
+ state.accounts,
8601
8500
  authenticated,
8602
8501
  provider
8603
8502
  ]);
@@ -8622,7 +8521,7 @@ function BlinkPaymentInner({
8622
8521
  onRetryMobileStatus: mobileFlow.handleRetryMobileStatus,
8623
8522
  onLogout: handleLogout,
8624
8523
  onNewPayment: handleNewPayment,
8625
- onNavigate: (step) => dispatch({ type: "NAVIGATE", step }),
8524
+ onSetUserIntent: (intent) => dispatch({ type: "SET_USER_INTENT", intent }),
8626
8525
  onSetAuthInput: auth.setAuthInput,
8627
8526
  onSetOtpCode: (code) => {
8628
8527
  auth.setOtpCode(code);
@@ -8636,8 +8535,8 @@ function BlinkPaymentInner({
8636
8535
  onSelectAuthorizedToken: provider.handleSelectAuthorizedToken,
8637
8536
  onAuthorizeToken: provider.handleAuthorizeToken,
8638
8537
  onSelectGuestToken: guestTransfer.handleSelectGuestToken,
8639
- onLogin: () => dispatch({ type: "NAVIGATE", step: "login" }),
8640
- onPreauthorize: () => dispatch({ type: "NAVIGATE", step: "login" })
8538
+ onLogin: () => dispatch({ type: "SET_USER_INTENT", intent: null }),
8539
+ onPreauthorize: () => dispatch({ type: "SET_USER_INTENT", intent: null })
8641
8540
  }), [
8642
8541
  auth,
8643
8542
  passkey,
@@ -8660,8 +8559,12 @@ function BlinkPaymentInner({
8660
8559
  pollingTransfer: polling.transfer,
8661
8560
  pollingError: polling.error,
8662
8561
  authExecutorError: authExecutor.error,
8562
+ inlineAuthorizationExecuting: authExecutor.executing,
8663
8563
  transferSigningSigning: transferSigning.signing,
8664
8564
  transferSigningError: transferSigning.error,
8565
+ pendingSelectSource: authExecutor.pendingSelectSource,
8566
+ pendingOneTapSetup: authExecutor.pendingOneTapSetup,
8567
+ oneTapLimitAlreadySaved: oneTapSetup.oneTapLimitSavedDuringSetupRef.current,
8665
8568
  pendingConnections: derived.pendingConnections,
8666
8569
  depositEligibleAccounts: derived.depositEligibleAccounts,
8667
8570
  sourceName: derived.sourceName,
@@ -8722,6 +8625,7 @@ exports.findDevicePasskeyViaPopup = findDevicePasskeyViaPopup;
8722
8625
  exports.getTheme = getTheme;
8723
8626
  exports.lightTheme = lightTheme;
8724
8627
  exports.resolvePasskeyRpId = resolvePasskeyRpId;
8628
+ exports.resolveScreen = resolveScreen;
8725
8629
  exports.useAuthorizationExecutor = useAuthorizationExecutor;
8726
8630
  exports.useBlinkConfig = useBlinkConfig;
8727
8631
  exports.useBlinkDepositAmount = useBlinkDepositAmount;