@swype-org/react-sdk 0.1.241 → 0.1.256

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
@@ -1847,7 +1847,10 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
1847
1847
  // src/paymentHelpers.ts
1848
1848
  var ACTIVE_CREDENTIAL_STORAGE_KEY = "blink_active_credential_id";
1849
1849
  var MOBILE_FLOW_STORAGE_KEY = "blink_mobile_flow";
1850
- var MIN_SEND_AMOUNT_USD = 0.25;
1850
+ var DEFAULT_MIN_SEND_AMOUNT_USD = 0.25;
1851
+ function effectiveMinTransferAmountUsd(depositAmount) {
1852
+ return depositAmount != null ? depositAmount : DEFAULT_MIN_SEND_AMOUNT_USD;
1853
+ }
1851
1854
  function persistMobileFlowState(data) {
1852
1855
  try {
1853
1856
  sessionStorage.setItem(MOBILE_FLOW_STORAGE_KEY, JSON.stringify(data));
@@ -2008,7 +2011,8 @@ function isGuestPreauthCompletedTransferPinPhase(phase) {
2008
2011
  case "one-tap-setup":
2009
2012
  case "token-picker":
2010
2013
  case "login":
2011
- case "otp-verify":
2014
+ // otp-verify not pinned: after OTP, verificationTarget clears but phase can be stale until
2015
+ // resolvePhase runs; pinning would block passkey.
2012
2016
  case "passkey-create":
2013
2017
  case "passkey-verify":
2014
2018
  case "data-loading":
@@ -2021,68 +2025,142 @@ function isGuestPreauthCompletedTransferPinPhase(phase) {
2021
2025
  }
2022
2026
  function resolvePhase(state) {
2023
2027
  const p = state.phase;
2024
- if (state.transfer?.status === "COMPLETED" && state.guestPreauthorizing && isGuestPreauthCompletedTransferPinPhase(p)) {
2025
- return p;
2026
- }
2027
- if (state.transfer?.status === "COMPLETED") {
2028
- return { step: "completed", transfer: state.transfer };
2029
- }
2030
- if (state.transfer?.status === "FAILED") {
2031
- return { step: "failed", transfer: state.transfer, error: state.error ?? "Transfer failed." };
2032
- }
2033
- if (state.creatingTransfer || isTransferInFlight(state.transfer)) {
2034
- return { step: "processing", transfer: state.transfer };
2035
- }
2036
- if (!state.loginRequested && (p.step === "token-picker" || p.step === "one-tap-setup" || p.step === "select-source" || p.step === "confirm-sign" || p.step === "guest-token-picker")) {
2037
- return p;
2028
+ const transferCompleted = state.transfer?.status === "COMPLETED";
2029
+ const needsPasskeyBootstrap = state.privyAuthenticated && !state.activeCredentialId;
2030
+ const guestPreauthPin = transferCompleted && state.guestPreauthorizing && !state.verificationTarget && isGuestPreauthCompletedTransferPinPhase(p);
2031
+ const guestPostPayLogin = transferCompleted && state.isGuestFlow && state.guestPreauthSessionId != null && !state.guestPreauthorizing && !state.verificationTarget && !state.privyAuthenticated;
2032
+ const pinSubflow = !state.loginRequested && (p.step === "token-picker" || p.step === "one-tap-setup" || p.step === "select-source" || p.step === "confirm-sign" || p.step === "guest-token-picker");
2033
+ const guestTokenPicker = state.isGuestFlow && state.selectedProviderId != null && !state.transfer && !state.guestPreauthAccountId;
2034
+ const walletPickerSwitch = p.step === "wallet-picker" && p.reason === "switch" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri);
2035
+ const passkeyBlock = state.passkeyConfigLoaded && !state.activeCredentialId;
2036
+ const passkeyVerify = passkeyBlock && state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded;
2037
+ const c1 = state.guestPreauthSetupCompletePending && state.privyReady && state.privyAuthenticated;
2038
+ const c2 = !c1 && guestPreauthPin;
2039
+ const c3 = !c1 && !c2 && guestPostPayLogin;
2040
+ const c4 = !c1 && !c2 && !c3 && transferCompleted && !state.verificationTarget && !needsPasskeyBootstrap;
2041
+ const c5 = !c1 && !c2 && !c3 && !c4 && state.transfer?.status === "FAILED";
2042
+ const c6 = !c1 && !c2 && !c3 && !c4 && !c5 && (state.creatingTransfer || isTransferInFlight(state.transfer));
2043
+ const c7 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && pinSubflow;
2044
+ const c8 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && state.mobileFlow && state.deeplinkUri != null;
2045
+ const c9 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && p.step === "wallet-setup" && p.mobile == null && state.guestPreauthorizing;
2046
+ const c10 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && guestTokenPicker;
2047
+ const c11 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && walletPickerSwitch;
2048
+ const c12 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !state.privyReady;
2049
+ const c13 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && state.privyAuthenticated && !state.activeCredentialId && !state.passkeyConfigLoaded;
2050
+ const c14 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && state.verificationTarget != null && !state.privyAuthenticated;
2051
+ const c15 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && state.loginRequested;
2052
+ const c16 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && !c15 && passkeyVerify;
2053
+ const c17 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && !c15 && !c16 && passkeyBlock;
2054
+ const c18 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && !c15 && !c16 && !c17 && state.loadingData && state.activeCredentialId != null && hasActiveWallet(state.accounts);
2055
+ const c19 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && !c15 && !c16 && !c17 && !c18 && state.activeCredentialId != null && !hasActiveWallet(state.accounts) && !state.mobileFlow;
2056
+ const c20 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && !c15 && !c16 && !c17 && !c18 && !c19 && state.activeCredentialId != null && hasActiveWallet(state.accounts) && !state.loadingData;
2057
+ const c21 = !c1 && !c2 && !c3 && !c4 && !c5 && !c6 && !c7 && !c8 && !c9 && !c10 && !c11 && !c12 && !c13 && !c14 && !c15 && !c16 && !c17 && !c18 && !c19 && !c20 && state.isGuestFlow;
2058
+ const flags = [
2059
+ c1,
2060
+ c2,
2061
+ c3,
2062
+ c4,
2063
+ c5,
2064
+ c6,
2065
+ c7,
2066
+ c8,
2067
+ c9,
2068
+ c10,
2069
+ c11,
2070
+ c12,
2071
+ c13,
2072
+ c14,
2073
+ c15,
2074
+ c16,
2075
+ c17,
2076
+ c18,
2077
+ c19,
2078
+ c20,
2079
+ c21
2080
+ ];
2081
+ const matchCount = flags.filter(Boolean).length;
2082
+ if (matchCount > 1) {
2083
+ console.error("resolvePhase: multiple exclusive branches matched", {
2084
+ flags: {
2085
+ c1,
2086
+ c2,
2087
+ c3,
2088
+ c4,
2089
+ c5,
2090
+ c6,
2091
+ c7,
2092
+ c8,
2093
+ c9,
2094
+ c10,
2095
+ c11,
2096
+ c12,
2097
+ c13,
2098
+ c14,
2099
+ c15,
2100
+ c16,
2101
+ c17,
2102
+ c18,
2103
+ c19,
2104
+ c20,
2105
+ c21
2106
+ }
2107
+ });
2038
2108
  }
2039
- if (state.mobileFlow && state.deeplinkUri) {
2040
- return {
2109
+ let resolved;
2110
+ if (c1) {
2111
+ resolved = { step: "guest-setup-complete" };
2112
+ } else if (c2) {
2113
+ resolved = p;
2114
+ } else if (c3) {
2115
+ resolved = { step: "login" };
2116
+ } else if (c4) {
2117
+ resolved = { step: "completed", transfer: state.transfer };
2118
+ } else if (c5) {
2119
+ resolved = {
2120
+ step: "failed",
2121
+ transfer: state.transfer,
2122
+ error: state.error ?? "Transfer failed."
2123
+ };
2124
+ } else if (c6) {
2125
+ resolved = { step: "processing", transfer: state.transfer };
2126
+ } else if (c7) {
2127
+ resolved = p;
2128
+ } else if (c8) {
2129
+ resolved = {
2041
2130
  step: "wallet-setup",
2042
2131
  mobile: { deeplinkUri: state.deeplinkUri, providerId: state.selectedProviderId },
2043
2132
  accountId: null
2044
2133
  };
2134
+ } else if (c9) {
2135
+ resolved = p;
2136
+ } else if (c10) {
2137
+ resolved = { step: "guest-token-picker" };
2138
+ } else if (c11) {
2139
+ resolved = p;
2140
+ } else if (c12) {
2141
+ resolved = { step: "initializing" };
2142
+ } else if (c13) {
2143
+ resolved = { step: "initializing" };
2144
+ } else if (c14) {
2145
+ resolved = { step: "otp-verify", target: state.verificationTarget };
2146
+ } else if (c15) {
2147
+ resolved = { step: "login" };
2148
+ } else if (c16) {
2149
+ resolved = { step: "passkey-verify" };
2150
+ } else if (c17) {
2151
+ resolved = { step: "passkey-create", popupFallback: state.passkeyPopupNeeded };
2152
+ } else if (c18) {
2153
+ resolved = { step: "data-loading" };
2154
+ } else if (c19) {
2155
+ resolved = { step: "wallet-picker", reason: "link" };
2156
+ } else if (c20) {
2157
+ resolved = { step: "deposit" };
2158
+ } else if (c21) {
2159
+ resolved = { step: "wallet-picker", reason: "guest-entry" };
2160
+ } else {
2161
+ resolved = { step: "wallet-picker", reason: "entry" };
2045
2162
  }
2046
- if (p.step === "wallet-setup" && p.mobile == null) {
2047
- return p;
2048
- }
2049
- if (state.isGuestFlow && state.selectedProviderId != null && !state.transfer) {
2050
- return { step: "guest-token-picker" };
2051
- }
2052
- if (p.step === "wallet-picker" && !state.creatingTransfer && !(state.mobileFlow && state.deeplinkUri)) {
2053
- return p;
2054
- }
2055
- if (!state.privyReady) {
2056
- return { step: "initializing" };
2057
- }
2058
- if (state.privyAuthenticated && !state.activeCredentialId && !state.passkeyConfigLoaded) {
2059
- return { step: "initializing" };
2060
- }
2061
- if (state.verificationTarget) {
2062
- return { step: "otp-verify", target: state.verificationTarget };
2063
- }
2064
- if (state.loginRequested) {
2065
- return { step: "login" };
2066
- }
2067
- if (state.passkeyConfigLoaded && !state.activeCredentialId) {
2068
- if (state.knownCredentialIds.length > 0 && state.passkeyPopupNeeded) {
2069
- return { step: "passkey-verify" };
2070
- }
2071
- return { step: "passkey-create", popupFallback: state.passkeyPopupNeeded };
2072
- }
2073
- if (state.loadingData && state.activeCredentialId && hasActiveWallet(state.accounts)) {
2074
- return { step: "data-loading" };
2075
- }
2076
- if (state.activeCredentialId && !hasActiveWallet(state.accounts) && !state.mobileFlow) {
2077
- return { step: "wallet-picker", reason: "link" };
2078
- }
2079
- if (state.activeCredentialId && hasActiveWallet(state.accounts) && !state.loadingData) {
2080
- return { step: "deposit" };
2081
- }
2082
- if (state.isGuestFlow) {
2083
- return { step: "wallet-picker", reason: "guest-entry" };
2084
- }
2085
- return { step: "wallet-picker", reason: "entry" };
2163
+ return resolved;
2086
2164
  }
2087
2165
 
2088
2166
  // src/paymentReducer.ts
@@ -2130,13 +2208,26 @@ function createInitialState(config) {
2130
2208
  activePublicKey: null,
2131
2209
  loginRequested: false,
2132
2210
  guestPreauthorizing: false,
2211
+ guestPreauthSetupCompletePending: false,
2133
2212
  privyReady: false,
2134
2213
  privyAuthenticated: false
2135
2214
  };
2136
2215
  }
2137
2216
  function paymentReducer(state, action) {
2138
2217
  const next = applyAction(state, action);
2139
- return { ...next, phase: resolvePhase(next) };
2218
+ const phase = resolvePhase(next);
2219
+ if (action.type === "CODE_SENT") {
2220
+ console.debug("[Swype SDK] login code sent", {
2221
+ resolvedPhase: phase.step,
2222
+ verificationTargetKind: action.target.kind,
2223
+ guestPreauthorizing: next.guestPreauthorizing,
2224
+ transferStatus: next.transfer?.status ?? null,
2225
+ isGuestFlow: next.isGuestFlow,
2226
+ hasGuestPreauthSessionId: next.guestPreauthSessionId != null,
2227
+ loginRequested: next.loginRequested
2228
+ });
2229
+ }
2230
+ return { ...next, phase };
2140
2231
  }
2141
2232
  function applyAction(state, action) {
2142
2233
  switch (action.type) {
@@ -2397,13 +2488,20 @@ function applyAction(state, action) {
2397
2488
  case "ACCOUNT_OWNER_SET":
2398
2489
  return {
2399
2490
  ...state,
2491
+ transfer: null,
2400
2492
  guestPreauthAccountId: null,
2401
2493
  guestPreauthSessionId: null,
2402
2494
  activePublicKey: null,
2403
2495
  error: null,
2404
2496
  guestPreauthorizing: false,
2405
- phase: { step: "one-tap-setup", action: null }
2497
+ isGuestFlow: false,
2498
+ selectedProviderId: null,
2499
+ guestTransferId: null,
2500
+ guestSessionToken: null,
2501
+ guestPreauthSetupCompletePending: true
2406
2502
  };
2503
+ case "GUEST_PREAUTH_SETUP_COMPLETE_DISMISSED":
2504
+ return { ...state, guestPreauthSetupCompletePending: false };
2407
2505
  // ── User intent & error ──────────────────────────────────────
2408
2506
  case "SET_USER_INTENT":
2409
2507
  return { ...state, phase: action.intent };
@@ -2438,7 +2536,8 @@ function applyAction(state, action) {
2438
2536
  activePublicKey: null,
2439
2537
  loginRequested: false,
2440
2538
  oneTapLimitSavedDuringSetup: false,
2441
- guestPreauthorizing: false
2539
+ guestPreauthorizing: false,
2540
+ guestPreauthSetupCompletePending: false
2442
2541
  };
2443
2542
  case "LOGOUT":
2444
2543
  return {
@@ -2454,7 +2553,10 @@ function applyAction(state, action) {
2454
2553
  return {
2455
2554
  ...state,
2456
2555
  privyReady: action.ready,
2457
- privyAuthenticated: action.authenticated
2556
+ privyAuthenticated: action.authenticated,
2557
+ // OTP complete: Privy is source of truth; clear so resolvePhase can leave otp-verify
2558
+ // and guest-preauth pin rules cannot re-pin a stale otp-verify phase.
2559
+ ...action.authenticated ? { verificationTarget: null, loginRequested: false } : {}
2458
2560
  };
2459
2561
  case "SYNC_AMOUNT":
2460
2562
  return { ...state, amount: action.amount };
@@ -2520,7 +2622,10 @@ function screenForPhase(phase) {
2520
2622
  case "wallet-picker":
2521
2623
  return "wallet-picker";
2522
2624
  case "wallet-setup":
2523
- return phase.mobile ? "open-wallet" : "setup-status";
2625
+ if (phase.mobile || phase.guestDesktopExtension) {
2626
+ return "open-wallet";
2627
+ }
2628
+ return "setup-status";
2524
2629
  case "select-source":
2525
2630
  return phase.isDesktop ? "setup" : "select-source";
2526
2631
  case "one-tap-setup":
@@ -2538,6 +2643,8 @@ function screenForPhase(phase) {
2538
2643
  case "completed":
2539
2644
  case "failed":
2540
2645
  return "success";
2646
+ case "guest-setup-complete":
2647
+ return "guest-setup-complete";
2541
2648
  }
2542
2649
  }
2543
2650
  var MUTED = "#7fa4b0";
@@ -4319,13 +4426,13 @@ var waitHintStyle = (color) => ({
4319
4426
  color,
4320
4427
  margin: 0
4321
4428
  });
4322
- var MIN_DEPOSIT = 0.25;
4323
4429
  function DepositScreen({
4324
4430
  merchantName,
4325
4431
  availableBalance,
4326
4432
  remainingLimit,
4327
4433
  tokenCount,
4328
4434
  initialAmount,
4435
+ minDepositFloor,
4329
4436
  processing,
4330
4437
  error,
4331
4438
  onDeposit,
@@ -4361,9 +4468,9 @@ function DepositScreen({
4361
4468
  const selectedProviderName = selectedAccount?.name ?? "Wallet";
4362
4469
  const selectedProviderLogo = KNOWN_LOGOS[selectedProviderName.toLowerCase()];
4363
4470
  const totalAccountBalance = selectedAccount ? selectedAccount.wallets.reduce((sum, w) => sum + w.balance.available.amount, 0) : availableBalance;
4364
- const isLowBalance = availableBalance < MIN_DEPOSIT;
4471
+ const isLowBalance = availableBalance < minDepositFloor;
4365
4472
  const exceedsLimit = remainingLimit != null && amount > remainingLimit && !isLowBalance;
4366
- const canDeposit = amount >= MIN_DEPOSIT && !exceedsLimit && !isLowBalance && !processing;
4473
+ const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !processing;
4367
4474
  return /* @__PURE__ */ jsxs(
4368
4475
  ScreenLayout,
4369
4476
  {
@@ -4498,7 +4605,7 @@ function DepositScreen({
4498
4605
  "Your wallet balance is $",
4499
4606
  availableBalance.toFixed(2),
4500
4607
  " \u2014 you need at least $",
4501
- MIN_DEPOSIT.toFixed(2),
4608
+ minDepositFloor.toFixed(2),
4502
4609
  " to deposit via One-Tap."
4503
4610
  ] }),
4504
4611
  error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle5(tokens), children: error })
@@ -6007,6 +6114,60 @@ var emptyStyle = (color) => ({
6007
6114
  padding: "32px 0",
6008
6115
  lineHeight: 1.5
6009
6116
  });
6117
+ function GuestPreauthSetupCompleteScreen({
6118
+ onClose,
6119
+ onLogout
6120
+ }) {
6121
+ const { tokens } = useBlinkConfig();
6122
+ return /* @__PURE__ */ jsxs(
6123
+ ScreenLayout,
6124
+ {
6125
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
6126
+ /* @__PURE__ */ jsx(PrimaryButton, { onClick: onClose, children: "Close" }),
6127
+ /* @__PURE__ */ jsx(PoweredByFooter, {})
6128
+ ] }),
6129
+ children: [
6130
+ /* @__PURE__ */ jsx(ScreenHeader, { onLogout }),
6131
+ /* @__PURE__ */ jsxs("div", { style: contentStyle9, children: [
6132
+ /* @__PURE__ */ jsx(IconCircle, { variant: "success", size: 64, children: /* @__PURE__ */ jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
6133
+ "path",
6134
+ {
6135
+ d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z",
6136
+ fill: tokens.success
6137
+ }
6138
+ ) }) }),
6139
+ /* @__PURE__ */ jsx("h2", { style: headingStyle12(tokens.text), children: "Setup complete" }),
6140
+ /* @__PURE__ */ jsx("p", { style: subtitleStyle10(tokens.textSecondary), children: "Your account is linked and ready. You can close this window or make another deposit." })
6141
+ ] })
6142
+ ]
6143
+ }
6144
+ );
6145
+ }
6146
+ var contentStyle9 = {
6147
+ display: "flex",
6148
+ flexDirection: "column",
6149
+ alignItems: "center",
6150
+ textAlign: "center",
6151
+ gap: 12,
6152
+ paddingTop: 8
6153
+ };
6154
+ function headingStyle12(color) {
6155
+ return {
6156
+ margin: 0,
6157
+ fontSize: 22,
6158
+ fontWeight: 600,
6159
+ color
6160
+ };
6161
+ }
6162
+ function subtitleStyle10(color) {
6163
+ return {
6164
+ margin: 0,
6165
+ fontSize: 15,
6166
+ lineHeight: 1.45,
6167
+ color,
6168
+ maxWidth: 320
6169
+ };
6170
+ }
6010
6171
  var LINK_SCREENS = /* @__PURE__ */ new Set([
6011
6172
  "create-passkey",
6012
6173
  "verify-passkey",
@@ -6021,6 +6182,7 @@ var DEPOSIT_SCREENS = /* @__PURE__ */ new Set([
6021
6182
  "processing",
6022
6183
  "success"
6023
6184
  ]);
6185
+ var DEFAULT_MIN_DEPOSIT_USD = 0.25;
6024
6186
  function getFlowPhase(screen, phase) {
6025
6187
  if (LINK_SCREENS.has(screen)) return "link";
6026
6188
  if (DEPOSIT_SCREENS.has(screen)) return "deposit";
@@ -6229,6 +6391,7 @@ function StepRendererContent({
6229
6391
  }
6230
6392
  case "deposit": {
6231
6393
  const parsedAmt = depositAmount != null ? depositAmount : 5;
6394
+ const minDepositFloor = depositAmount != null ? depositAmount : DEFAULT_MIN_DEPOSIT_USD;
6232
6395
  return /* @__PURE__ */ jsx(
6233
6396
  DepositScreen,
6234
6397
  {
@@ -6252,7 +6415,8 @@ function StepRendererContent({
6252
6415
  onAddProvider: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
6253
6416
  onSelectToken: handlers.onSelectToken,
6254
6417
  selectedSourceLabel,
6255
- selectedTokenSymbol: selectedSource?.token.symbol
6418
+ selectedTokenSymbol: selectedSource?.token.symbol,
6419
+ minDepositFloor
6256
6420
  }
6257
6421
  );
6258
6422
  }
@@ -6308,6 +6472,14 @@ function StepRendererContent({
6308
6472
  onBack: handlers.onGuestBackFromTokenPicker
6309
6473
  }
6310
6474
  );
6475
+ case "guest-setup-complete":
6476
+ return /* @__PURE__ */ jsx(
6477
+ GuestPreauthSetupCompleteScreen,
6478
+ {
6479
+ onClose: handlers.onGuestSetupCompleteClose,
6480
+ onLogout: handlers.onLogout
6481
+ }
6482
+ );
6311
6483
  case "processing": {
6312
6484
  const polledStatus = pollingTransfer?.status;
6313
6485
  const transferPhase = state.creatingTransfer ? "creating" : polledStatus === "SENDING" || polledStatus === "SENT" ? "sent" : "verifying";
@@ -6401,7 +6573,7 @@ var PaymentErrorBoundary = class extends Component {
6401
6573
  /* @__PURE__ */ jsx("path", { d: "M12 8v5", stroke: "#ef4444", strokeWidth: "1.5", strokeLinecap: "round" }),
6402
6574
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "16", r: "0.75", fill: "#ef4444" })
6403
6575
  ] }) }),
6404
- /* @__PURE__ */ jsx("h2", { style: headingStyle12, children: "Something went wrong" }),
6576
+ /* @__PURE__ */ jsx("h2", { style: headingStyle13, children: "Something went wrong" }),
6405
6577
  /* @__PURE__ */ jsx("p", { style: messageStyle, children: "An unexpected error occurred. Please try again." }),
6406
6578
  /* @__PURE__ */ jsx("button", { type: "button", onClick: this.handleReset, style: buttonStyle3, children: "Try again" })
6407
6579
  ] });
@@ -6421,7 +6593,7 @@ var containerStyle9 = {
6421
6593
  var iconStyle3 = {
6422
6594
  marginBottom: 20
6423
6595
  };
6424
- var headingStyle12 = {
6596
+ var headingStyle13 = {
6425
6597
  fontSize: "1.25rem",
6426
6598
  fontWeight: 700,
6427
6599
  color: "#1a1a1a",
@@ -6770,8 +6942,9 @@ function useTransferHandlers(deps) {
6770
6942
  dispatch({ type: "ACCOUNTS_RELOADED", accounts: accts, providers: prov, defaults });
6771
6943
  }, [getAccessToken, activeCredentialId, selectedAccountId, apiBaseUrl, depositAmount, dispatch]);
6772
6944
  const handlePay = useCallback(async (payAmount, sourceOverrides) => {
6773
- if (isNaN(payAmount) || payAmount < MIN_SEND_AMOUNT_USD) {
6774
- dispatch({ type: "SET_ERROR", error: `Minimum amount is $${MIN_SEND_AMOUNT_USD.toFixed(2)}.` });
6945
+ const minUsd = effectiveMinTransferAmountUsd(depositAmount);
6946
+ if (isNaN(payAmount) || payAmount < minUsd) {
6947
+ dispatch({ type: "SET_ERROR", error: `Minimum amount is $${minUsd.toFixed(2)}.` });
6775
6948
  return;
6776
6949
  }
6777
6950
  if (!sourceOverrides?.sourceId && !sourceId) {
@@ -6850,7 +7023,8 @@ function useTransferHandlers(deps) {
6850
7023
  onComplete,
6851
7024
  idempotencyKey,
6852
7025
  merchantAuthorization,
6853
- dispatch
7026
+ dispatch,
7027
+ depositAmount
6854
7028
  ]);
6855
7029
  const handleConfirmSign = useCallback(async () => {
6856
7030
  const t = transfer ?? polling.transfer;
@@ -6920,18 +7094,31 @@ function useSourceSelectionHandlers(dispatch, authExecutor, options) {
6920
7094
  [selectSourceChoices, selectSourceRecommended]
6921
7095
  );
6922
7096
  const handleConfirmSelectSource = useCallback(() => {
7097
+ const guestPostPayPreauth = !!options?.guestPreauthSessionId && !!options?.isGuestFlow || !!options?.guestPreauthorizing && !!options?.isDesktop;
7098
+ if (guestPostPayPreauth) {
7099
+ dispatch({ type: "REQUEST_LOGIN" });
7100
+ if (options?.guestPreauthAccountId != null) {
7101
+ const intent = {
7102
+ step: "wallet-setup",
7103
+ mobile: null,
7104
+ accountId: options.guestPreauthAccountId,
7105
+ guestDesktopExtension: true
7106
+ };
7107
+ dispatch({ type: "SET_USER_INTENT", intent });
7108
+ }
7109
+ }
6923
7110
  authExecutor.resolveSelectSource({
6924
7111
  chainName: selectSourceChainName,
6925
7112
  tokenSymbol: selectSourceTokenSymbol
6926
7113
  });
6927
- if (options?.guestPreauthorizing && options?.isDesktop) {
6928
- dispatch({ type: "REQUEST_LOGIN" });
6929
- }
6930
7114
  }, [
6931
7115
  authExecutor,
6932
7116
  dispatch,
7117
+ options?.guestPreauthSessionId,
7118
+ options?.guestPreauthAccountId,
6933
7119
  options?.guestPreauthorizing,
6934
7120
  options?.isDesktop,
7121
+ options?.isGuestFlow,
6935
7122
  selectSourceChainName,
6936
7123
  selectSourceTokenSymbol
6937
7124
  ]);
@@ -7789,7 +7976,9 @@ function useOneTapSetupHandlers(deps) {
7789
7976
  authExecutor,
7790
7977
  selectSourceChainName,
7791
7978
  selectSourceTokenSymbol,
7792
- authorizationSessionIdForGuest
7979
+ authorizationSessionIdForGuest,
7980
+ guestPostPayPreauth,
7981
+ guestPreauthAccountId
7793
7982
  } = deps;
7794
7983
  const [savingOneTapLimit, setSavingOneTapLimit] = useState(false);
7795
7984
  const handleSetupOneTap = useCallback(async (limit) => {
@@ -7806,6 +7995,19 @@ function useOneTapSetupHandlers(deps) {
7806
7995
  if (!token) throw new Error("Not authenticated");
7807
7996
  await updateUserConfig(apiBaseUrl, token, { defaultAllowance: limit });
7808
7997
  }
7998
+ const willResolveSession = authExecutor.pendingSelectSource != null || authExecutor.pendingOneTapSetup != null;
7999
+ if (guestPostPayPreauth && willResolveSession) {
8000
+ dispatch({ type: "REQUEST_LOGIN" });
8001
+ if (guestPreauthAccountId != null) {
8002
+ const intent = {
8003
+ step: "wallet-setup",
8004
+ mobile: null,
8005
+ accountId: guestPreauthAccountId,
8006
+ guestDesktopExtension: true
8007
+ };
8008
+ dispatch({ type: "SET_USER_INTENT", intent });
8009
+ }
8010
+ }
7809
8011
  if (authExecutor.pendingSelectSource) {
7810
8012
  const action = authExecutor.pendingSelectSource;
7811
8013
  const recommended = action.metadata?.recommended;
@@ -7825,7 +8027,9 @@ function useOneTapSetupHandlers(deps) {
7825
8027
  } else if (authExecutor.pendingOneTapSetup) {
7826
8028
  authExecutor.resolveOneTapSetup();
7827
8029
  }
7828
- dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
8030
+ if (!guestPostPayPreauth || !willResolveSession) {
8031
+ dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
8032
+ }
7829
8033
  } catch (err) {
7830
8034
  captureException(err);
7831
8035
  dispatch({
@@ -7842,7 +8046,9 @@ function useOneTapSetupHandlers(deps) {
7842
8046
  dispatch,
7843
8047
  selectSourceChainName,
7844
8048
  selectSourceTokenSymbol,
7845
- authorizationSessionIdForGuest
8049
+ authorizationSessionIdForGuest,
8050
+ guestPostPayPreauth,
8051
+ guestPreauthAccountId
7846
8052
  ]);
7847
8053
  return {
7848
8054
  handleSetupOneTap,
@@ -8308,6 +8514,10 @@ function useProcessingEffect(deps) {
8308
8514
  } = deps;
8309
8515
  useEffect(() => {
8310
8516
  if (!polling.transfer) return;
8517
+ if (state.loginRequested || state.verificationTarget) return;
8518
+ if (!state.transfer && (polling.transfer.status === "COMPLETED" || polling.transfer.status === "FAILED")) {
8519
+ return;
8520
+ }
8311
8521
  if (polling.transfer.status === "COMPLETED") {
8312
8522
  clearMobileFlowState();
8313
8523
  dispatch({ type: "TRANSFER_COMPLETED", transfer: polling.transfer });
@@ -8317,7 +8527,15 @@ function useProcessingEffect(deps) {
8317
8527
  clearMobileFlowState();
8318
8528
  dispatch({ type: "TRANSFER_FAILED", transfer: polling.transfer, error: "Transfer failed." });
8319
8529
  }
8320
- }, [polling.transfer, onComplete, dispatch, reloadAccounts]);
8530
+ }, [
8531
+ polling.transfer,
8532
+ state.transfer,
8533
+ state.loginRequested,
8534
+ state.verificationTarget,
8535
+ onComplete,
8536
+ dispatch,
8537
+ reloadAccounts
8538
+ ]);
8321
8539
  useEffect(() => {
8322
8540
  const isProcessing = state.creatingTransfer || state.transfer != null && ["CREATED", "SENDING", "SENT"].includes(state.transfer.status);
8323
8541
  if (!isProcessing) {
@@ -8568,6 +8786,42 @@ function useOneTapAutoResolveEffect(deps) {
8568
8786
  }
8569
8787
  }, [pendingOneTapSetupAction, reloadAccounts, oneTapLimitSavedDuringSetup]);
8570
8788
  }
8789
+
8790
+ // src/guestPreauthClaimWait.ts
8791
+ var GUEST_PREAUTH_SESSION_POLL_INTERVAL_MS = 1e3;
8792
+ var GUEST_PREAUTH_SESSION_POLL_TIMEOUT_MS = 12e4;
8793
+ async function waitForGuestPreauthAuthorizationSession(apiBaseUrl, sessionId, fetchSession, signal, options) {
8794
+ const intervalMs = GUEST_PREAUTH_SESSION_POLL_INTERVAL_MS;
8795
+ const timeoutMs = GUEST_PREAUTH_SESSION_POLL_TIMEOUT_MS;
8796
+ const deadline = Date.now() + timeoutMs;
8797
+ const sleepAbortable = (ms) => new Promise((resolve, reject) => {
8798
+ if (signal.aborted) {
8799
+ reject(new DOMException("Aborted", "AbortError"));
8800
+ return;
8801
+ }
8802
+ const t = setTimeout(() => {
8803
+ signal.removeEventListener("abort", onAbort);
8804
+ resolve();
8805
+ }, ms);
8806
+ const onAbort = () => {
8807
+ clearTimeout(t);
8808
+ signal.removeEventListener("abort", onAbort);
8809
+ reject(new DOMException("Aborted", "AbortError"));
8810
+ };
8811
+ signal.addEventListener("abort", onAbort, { once: true });
8812
+ });
8813
+ while (Date.now() < deadline) {
8814
+ if (signal.aborted) {
8815
+ throw new DOMException("Aborted", "AbortError");
8816
+ }
8817
+ const session = await fetchSession(apiBaseUrl, sessionId);
8818
+ if (session.status === "AUTHORIZED") return;
8819
+ await sleepAbortable(intervalMs);
8820
+ }
8821
+ throw new Error("Authorization session did not become AUTHORIZED in time.");
8822
+ }
8823
+
8824
+ // src/hooks/useGuestPreauthEffect.ts
8571
8825
  function useGuestPreauthEffect(deps) {
8572
8826
  const { state, dispatch, authenticated, apiBaseUrl, reloadAccounts } = deps;
8573
8827
  const { getAccessToken } = usePrivy();
@@ -8581,12 +8835,25 @@ function useGuestPreauthEffect(deps) {
8581
8835
  if (!authenticated) return;
8582
8836
  if (!state.guestSessionToken) return;
8583
8837
  if (settingOwnerRef.current) return;
8584
- const hasActive = state.accounts.some((a) => a.wallets.some((w) => w.status === "ACTIVE"));
8585
- if (!hasActive) return;
8586
8838
  settingOwnerRef.current = true;
8839
+ const abort = new AbortController();
8587
8840
  let cancelled = false;
8588
8841
  const setOwner = async () => {
8589
8842
  try {
8843
+ if (state.guestPreauthSessionId) {
8844
+ try {
8845
+ await waitForGuestPreauthAuthorizationSession(
8846
+ apiBaseUrl,
8847
+ state.guestPreauthSessionId,
8848
+ fetchAuthorizationSession,
8849
+ abort.signal
8850
+ );
8851
+ } catch (waitErr) {
8852
+ if (waitErr instanceof DOMException && waitErr.name === "AbortError") return;
8853
+ throw waitErr;
8854
+ }
8855
+ }
8856
+ if (cancelled) return;
8590
8857
  const token = await getAccessTokenRef.current();
8591
8858
  if (!token || cancelled) return;
8592
8859
  await setAccountOwner(apiBaseUrl, token, state.guestPreauthAccountId, state.guestSessionToken, {
@@ -8611,16 +8878,17 @@ function useGuestPreauthEffect(deps) {
8611
8878
  settingOwnerRef.current = false;
8612
8879
  }
8613
8880
  };
8614
- setOwner();
8881
+ void setOwner();
8615
8882
  return () => {
8616
8883
  cancelled = true;
8884
+ abort.abort();
8617
8885
  };
8618
8886
  }, [
8619
8887
  state.guestPreauthAccountId,
8888
+ state.guestPreauthSessionId,
8620
8889
  state.activeCredentialId,
8621
8890
  state.activePublicKey,
8622
8891
  state.guestSessionToken,
8623
- state.accounts,
8624
8892
  authenticated,
8625
8893
  apiBaseUrl,
8626
8894
  dispatch,
@@ -8691,24 +8959,23 @@ function useGuestPreauthPhaseSyncEffect(deps) {
8691
8959
  ]);
8692
8960
  }
8693
8961
  function useGuestPreauthWalletSetupEffect(deps) {
8694
- const { state, dispatch, authExecutor, isDesktop, privyAuthenticated } = deps;
8962
+ const { state, dispatch, authExecutor, isDesktop } = deps;
8695
8963
  useEffect(() => {
8696
8964
  if (!isDesktop || !state.guestPreauthorizing || !state.guestPreauthSessionId) return;
8965
+ if (!state.guestPreauthAccountId) return;
8697
8966
  if (!authExecutor.executing || authExecutor.pendingSelectSource) return;
8698
- if (!privyAuthenticated || !state.activeCredentialId) return;
8699
8967
  if (state.verificationTarget) return;
8700
- if (state.loginRequested) return;
8701
8968
  const p = state.phase;
8702
- if (p.step === "wallet-setup" && p.mobile == null) {
8703
- const id = state.guestPreauthAccountId;
8704
- if (id != null && p.accountId === id) return;
8969
+ if (p.step === "wallet-setup" && p.mobile == null && p.guestDesktopExtension && p.accountId === state.guestPreauthAccountId) {
8970
+ return;
8705
8971
  }
8706
8972
  dispatch({
8707
8973
  type: "SET_USER_INTENT",
8708
8974
  intent: {
8709
8975
  step: "wallet-setup",
8710
8976
  mobile: null,
8711
- accountId: state.guestPreauthAccountId
8977
+ accountId: state.guestPreauthAccountId,
8978
+ guestDesktopExtension: true
8712
8979
  }
8713
8980
  });
8714
8981
  }, [
@@ -8716,14 +8983,11 @@ function useGuestPreauthWalletSetupEffect(deps) {
8716
8983
  state.guestPreauthorizing,
8717
8984
  state.guestPreauthSessionId,
8718
8985
  state.guestPreauthAccountId,
8719
- state.activeCredentialId,
8720
8986
  state.verificationTarget,
8721
- state.loginRequested,
8722
8987
  state.phase,
8723
8988
  authExecutor.executing,
8724
8989
  authExecutor.pendingSelectSource,
8725
- dispatch,
8726
- privyAuthenticated
8990
+ dispatch
8727
8991
  ]);
8728
8992
  }
8729
8993
  function BlinkPayment(props) {
@@ -8811,6 +9075,9 @@ function BlinkPaymentInner({
8811
9075
  onComplete
8812
9076
  );
8813
9077
  const sourceSelection = useSourceSelectionHandlers(dispatch, authExecutor, {
9078
+ guestPreauthSessionId: state.guestPreauthSessionId,
9079
+ guestPreauthAccountId: state.guestPreauthAccountId,
9080
+ isGuestFlow: state.isGuestFlow,
8814
9081
  guestPreauthorizing: state.guestPreauthorizing,
8815
9082
  isDesktop
8816
9083
  });
@@ -8841,6 +9108,15 @@ function BlinkPaymentInner({
8841
9108
  guestSessionToken: state.guestSessionToken,
8842
9109
  selectedProviderId: state.selectedProviderId
8843
9110
  });
9111
+ const guestPostPayPreauth = useMemo(
9112
+ () => !!state.guestPreauthSessionId && state.isGuestFlow || state.guestPreauthorizing && isDesktop,
9113
+ [
9114
+ state.guestPreauthSessionId,
9115
+ state.isGuestFlow,
9116
+ state.guestPreauthorizing,
9117
+ isDesktop
9118
+ ]
9119
+ );
8844
9120
  const oneTapSetup = useOneTapSetupHandlers({
8845
9121
  dispatch,
8846
9122
  getAccessToken,
@@ -8848,7 +9124,9 @@ function BlinkPaymentInner({
8848
9124
  authExecutor,
8849
9125
  selectSourceChainName: sourceSelection.selectSourceChainName,
8850
9126
  selectSourceTokenSymbol: sourceSelection.selectSourceTokenSymbol,
8851
- authorizationSessionIdForGuest: state.guestPreauthSessionId
9127
+ authorizationSessionIdForGuest: state.guestPreauthSessionId,
9128
+ guestPostPayPreauth,
9129
+ guestPreauthAccountId: state.guestPreauthAccountId
8852
9130
  });
8853
9131
  const guestTransfer = useGuestTransferHandlers({
8854
9132
  dispatch,
@@ -8990,8 +9268,7 @@ function BlinkPaymentInner({
8990
9268
  state,
8991
9269
  dispatch,
8992
9270
  authExecutor,
8993
- isDesktop,
8994
- privyAuthenticated: authenticated
9271
+ isDesktop
8995
9272
  });
8996
9273
  const handlers = useMemo(() => ({
8997
9274
  onSendLoginCode: auth.handleSendLoginCode,
@@ -9031,7 +9308,11 @@ function BlinkPaymentInner({
9031
9308
  onSelectGuestToken: guestTransfer.handleSelectGuestToken,
9032
9309
  onGuestBackFromTokenPicker: guestTransfer.handleGuestBackFromTokenPicker,
9033
9310
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
9034
- onPreauthorize: provider.handlePreauthorize
9311
+ onPreauthorize: provider.handlePreauthorize,
9312
+ onGuestSetupCompleteClose: () => {
9313
+ dispatch({ type: "GUEST_PREAUTH_SETUP_COMPLETE_DISMISSED" });
9314
+ onDismiss?.();
9315
+ }
9035
9316
  }), [
9036
9317
  auth,
9037
9318
  passkey,
@@ -9042,7 +9323,9 @@ function BlinkPaymentInner({
9042
9323
  oneTapSetup,
9043
9324
  guestTransfer,
9044
9325
  handleLogout,
9045
- handleNewPayment
9326
+ handleNewPayment,
9327
+ onDismiss,
9328
+ dispatch
9046
9329
  ]);
9047
9330
  return /* @__PURE__ */ jsx(
9048
9331
  StepRenderer,