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