@swype-org/react-sdk 0.2.224 → 0.2.232

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
@@ -1592,6 +1592,93 @@ __export(api_exports, {
1592
1592
  updateUserConfigBySession: () => updateUserConfigBySession,
1593
1593
  waitForActionTransactionReceipt: () => waitForActionTransactionReceipt
1594
1594
  });
1595
+ var DEBUG_BUFFER_CAPACITY = 200;
1596
+ var nextId = 1;
1597
+ var entries = [];
1598
+ var listeners = /* @__PURE__ */ new Set();
1599
+ function notify() {
1600
+ for (const listener of listeners) {
1601
+ try {
1602
+ listener();
1603
+ } catch (err) {
1604
+ console.error("[blink-sdk][debug-log] listener threw:", err);
1605
+ }
1606
+ }
1607
+ }
1608
+ function appendDebug(level, message, data) {
1609
+ const entry = {
1610
+ id: nextId++,
1611
+ ts: Date.now(),
1612
+ level,
1613
+ message,
1614
+ data
1615
+ };
1616
+ const next = entries.length >= DEBUG_BUFFER_CAPACITY ? entries.slice(entries.length - DEBUG_BUFFER_CAPACITY + 1) : entries.slice();
1617
+ next.push(entry);
1618
+ entries = next;
1619
+ const prefix = "[blink-sdk][debug]";
1620
+ const sink = level === "error" ? console.error : level === "warn" ? console.warn : console.info;
1621
+ if (data !== void 0) {
1622
+ sink(`${prefix} ${message}`, data);
1623
+ } else {
1624
+ sink(`${prefix} ${message}`);
1625
+ }
1626
+ notify();
1627
+ }
1628
+ function subscribeDebug(listener) {
1629
+ listeners.add(listener);
1630
+ return () => {
1631
+ listeners.delete(listener);
1632
+ };
1633
+ }
1634
+ function getDebugEntries() {
1635
+ return entries;
1636
+ }
1637
+ function clearDebugEntries() {
1638
+ entries = [];
1639
+ notify();
1640
+ }
1641
+ function useBlinkDebugLog() {
1642
+ return useSyncExternalStore(subscribeDebug, getDebugEntries, getDebugEntries);
1643
+ }
1644
+
1645
+ // src/fetchWithRetry.ts
1646
+ var DEFAULT_MAX_RETRIES = 3;
1647
+ var DEFAULT_BASE_DELAY_MS = 500;
1648
+ var DEFAULT_MAX_JITTER_MS = 200;
1649
+ function isNetworkTypeError(err) {
1650
+ return err instanceof TypeError && /fetch|network|load failed/i.test(err.message);
1651
+ }
1652
+ async function fetchWithRetry(input, init, options) {
1653
+ const maxRetries = DEFAULT_MAX_RETRIES;
1654
+ const baseDelayMs = DEFAULT_BASE_DELAY_MS;
1655
+ const maxJitterMs = DEFAULT_MAX_JITTER_MS;
1656
+ const label = String(input).replace(/https?:\/\/[^/]+/, "");
1657
+ let lastError;
1658
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1659
+ try {
1660
+ return await fetch(input, init);
1661
+ } catch (err) {
1662
+ lastError = err;
1663
+ if (!isNetworkTypeError(err)) {
1664
+ throw err;
1665
+ }
1666
+ if (attempt < maxRetries) {
1667
+ const delay = baseDelayMs * Math.pow(2, attempt) + Math.random() * maxJitterMs;
1668
+ appendDebug("warn", `fetchWithRetry: network error, retrying ${label}`, {
1669
+ attempt: attempt + 1,
1670
+ maxRetries,
1671
+ delayMs: Math.round(delay),
1672
+ error: err instanceof Error ? err.message : String(err)
1673
+ });
1674
+ await new Promise((resolve) => setTimeout(resolve, delay));
1675
+ }
1676
+ }
1677
+ }
1678
+ throw lastError;
1679
+ }
1680
+
1681
+ // src/api.ts
1595
1682
  async function throwApiError(res) {
1596
1683
  const body = await res.json().catch(() => null);
1597
1684
  const detail = body?.error ?? body;
@@ -1604,13 +1691,13 @@ async function fetchProviders(apiBaseUrl, token) {
1604
1691
  if (token) {
1605
1692
  headers.Authorization = `Bearer ${token}`;
1606
1693
  }
1607
- const res = await fetch(`${apiBaseUrl}/v1/providers`, { headers });
1694
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/providers`, { headers });
1608
1695
  if (!res.ok) await throwApiError(res);
1609
1696
  const data = await res.json();
1610
1697
  return data.items;
1611
1698
  }
1612
1699
  async function fetchChains(apiBaseUrl, token) {
1613
- const res = await fetch(`${apiBaseUrl}/v1/chains`, {
1700
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/chains`, {
1614
1701
  headers: { Authorization: `Bearer ${token}` }
1615
1702
  });
1616
1703
  if (!res.ok) await throwApiError(res);
@@ -1619,7 +1706,7 @@ async function fetchChains(apiBaseUrl, token) {
1619
1706
  }
1620
1707
  async function fetchAccounts(apiBaseUrl, token, credentialId) {
1621
1708
  const params = new URLSearchParams({ credentialId });
1622
- const res = await fetch(`${apiBaseUrl}/v1/accounts?${params.toString()}`, {
1709
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/accounts?${params.toString()}`, {
1623
1710
  headers: { Authorization: `Bearer ${token}` }
1624
1711
  });
1625
1712
  if (!res.ok) await throwApiError(res);
@@ -1628,7 +1715,7 @@ async function fetchAccounts(apiBaseUrl, token, credentialId) {
1628
1715
  }
1629
1716
  async function fetchAccount(apiBaseUrl, token, accountId, credentialId) {
1630
1717
  const params = new URLSearchParams({ credentialId });
1631
- const res = await fetch(`${apiBaseUrl}/v1/accounts/${accountId}?${params.toString()}`, {
1718
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/accounts/${accountId}?${params.toString()}`, {
1632
1719
  headers: { Authorization: `Bearer ${token}` }
1633
1720
  });
1634
1721
  if (!res.ok) await throwApiError(res);
@@ -1770,7 +1857,7 @@ async function postTransferQuote(apiBaseUrl, bearerToken, params) {
1770
1857
  return await res.json();
1771
1858
  }
1772
1859
  async function fetchMerchantPublicKey(apiBaseUrl, merchantId) {
1773
- const res = await fetch(
1860
+ const res = await fetchWithRetry(
1774
1861
  `${apiBaseUrl}/v1/merchants/${encodeURIComponent(merchantId)}/public-key`
1775
1862
  );
1776
1863
  if (!res.ok) await throwApiError(res);
@@ -1780,7 +1867,7 @@ async function fetchTransfer(apiBaseUrl, token, transferId, authorizationSession
1780
1867
  if (!token && !authorizationSessionToken) {
1781
1868
  throw new Error("Missing auth credentials for transfer fetch.");
1782
1869
  }
1783
- const res = await fetch(`${apiBaseUrl}/v1/transfers/${transferId}`, {
1870
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/transfers/${transferId}`, {
1784
1871
  headers: {
1785
1872
  ...token ? { Authorization: `Bearer ${token}` } : {},
1786
1873
  ...authorizationSessionToken ? { "x-authorization-session-token": authorizationSessionToken } : {}
@@ -1808,14 +1895,14 @@ async function signTransfer(apiBaseUrl, token, transferId, signedTransfer, autho
1808
1895
  return await res.json();
1809
1896
  }
1810
1897
  async function fetchAuthorizationSession(apiBaseUrl, sessionId) {
1811
- const res = await fetch(
1898
+ const res = await fetchWithRetry(
1812
1899
  `${apiBaseUrl}/v1/authorization-sessions/${sessionId}`
1813
1900
  );
1814
1901
  if (!res.ok) await throwApiError(res);
1815
1902
  return await res.json();
1816
1903
  }
1817
1904
  async function fetchAuthorizationSessionByToken(apiBaseUrl, token) {
1818
- const res = await fetch(
1905
+ const res = await fetchWithRetry(
1819
1906
  `${apiBaseUrl}/v1/authorization-sessions?token=${encodeURIComponent(token)}`
1820
1907
  );
1821
1908
  if (!res.ok) await throwApiError(res);
@@ -1833,7 +1920,7 @@ async function registerPasskey(apiBaseUrl, token, credentialId, publicKey) {
1833
1920
  if (!res.ok) await throwApiError(res);
1834
1921
  }
1835
1922
  async function reportPasskeyActivity(apiBaseUrl, token, credentialId) {
1836
- const res = await fetch(`${apiBaseUrl}/v1/users/config/passkey`, {
1923
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/users/config/passkey`, {
1837
1924
  method: "PATCH",
1838
1925
  headers: {
1839
1926
  "Content-Type": "application/json",
@@ -1844,7 +1931,7 @@ async function reportPasskeyActivity(apiBaseUrl, token, credentialId) {
1844
1931
  if (!res.ok) await throwApiError(res);
1845
1932
  }
1846
1933
  async function fetchUserConfig(apiBaseUrl, token) {
1847
- const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
1934
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/users/config`, {
1848
1935
  headers: { Authorization: `Bearer ${token}` }
1849
1936
  });
1850
1937
  if (!res.ok) await throwApiError(res);
@@ -1916,12 +2003,12 @@ async function createManualTransfer(apiBaseUrl, params) {
1916
2003
  return await res.json();
1917
2004
  }
1918
2005
  async function fetchManualTransferSession(apiBaseUrl, sessionId) {
1919
- const res = await fetch(`${apiBaseUrl}/v1/manual-transfers/${sessionId}`);
2006
+ const res = await fetchWithRetry(`${apiBaseUrl}/v1/manual-transfers/${sessionId}`);
1920
2007
  if (!res.ok) await throwApiError(res);
1921
2008
  return await res.json();
1922
2009
  }
1923
2010
  async function reportActionCompletion(apiBaseUrl, actionId, result) {
1924
- const res = await fetch(
2011
+ const res = await fetchWithRetry(
1925
2012
  `${apiBaseUrl}/v1/authorization-actions/${actionId}`,
1926
2013
  {
1927
2014
  method: "PATCH",
@@ -1945,7 +2032,7 @@ async function waitForActionTransactionReceipt(apiBaseUrl, actionId, txHash) {
1945
2032
  return await res.json();
1946
2033
  }
1947
2034
  async function probeActionCompletion(apiBaseUrl, actionId) {
1948
- const res = await fetch(
2035
+ const res = await fetchWithRetry(
1949
2036
  `${apiBaseUrl}/v1/authorization-actions/${actionId}`,
1950
2037
  {
1951
2038
  method: "PATCH",
@@ -2785,55 +2872,6 @@ async function pollWalletCallsStatus(walletClient, callsId, options = {}) {
2785
2872
  `Batch transaction did not confirm within ${maxAttempts * pollIntervalMs}ms. Last wallet status: ${lastStatusStr}. Please try again.`
2786
2873
  );
2787
2874
  }
2788
- var DEBUG_BUFFER_CAPACITY = 200;
2789
- var nextId = 1;
2790
- var entries = [];
2791
- var listeners = /* @__PURE__ */ new Set();
2792
- function notify() {
2793
- for (const listener of listeners) {
2794
- try {
2795
- listener();
2796
- } catch (err) {
2797
- console.error("[blink-sdk][debug-log] listener threw:", err);
2798
- }
2799
- }
2800
- }
2801
- function appendDebug(level, message, data) {
2802
- const entry = {
2803
- id: nextId++,
2804
- ts: Date.now(),
2805
- level,
2806
- message,
2807
- data
2808
- };
2809
- const next = entries.length >= DEBUG_BUFFER_CAPACITY ? entries.slice(entries.length - DEBUG_BUFFER_CAPACITY + 1) : entries.slice();
2810
- next.push(entry);
2811
- entries = next;
2812
- const prefix = "[blink-sdk][debug]";
2813
- const sink = level === "error" ? console.error : level === "warn" ? console.warn : console.info;
2814
- if (data !== void 0) {
2815
- sink(`${prefix} ${message}`, data);
2816
- } else {
2817
- sink(`${prefix} ${message}`);
2818
- }
2819
- notify();
2820
- }
2821
- function subscribeDebug(listener) {
2822
- listeners.add(listener);
2823
- return () => {
2824
- listeners.delete(listener);
2825
- };
2826
- }
2827
- function getDebugEntries() {
2828
- return entries;
2829
- }
2830
- function clearDebugEntries() {
2831
- entries = [];
2832
- notify();
2833
- }
2834
- function useBlinkDebugLog() {
2835
- return useSyncExternalStore(subscribeDebug, getDebugEntries, getDebugEntries);
2836
- }
2837
2875
 
2838
2876
  // src/withWatchdog.ts
2839
2877
  var DEFAULT_WATCHDOG_INTERVAL_MS = 2e4;
@@ -3536,6 +3574,10 @@ function advanceTrackedEvmNonce(nonceTracker, trackerKey, nextNonce) {
3536
3574
  nonceTracker.set(trackerKey, current == null ? nextNonce : Math.max(current, nextNonce));
3537
3575
  }
3538
3576
  async function waitForWalletClient(wagmiConfig, params = {}) {
3577
+ const initialAccount = getAccount(wagmiConfig);
3578
+ if (!initialAccount.isConnected) {
3579
+ await reconnect(wagmiConfig).catch(() => []);
3580
+ }
3539
3581
  for (let i = 0; i < WALLET_CLIENT_MAX_ATTEMPTS; i++) {
3540
3582
  try {
3541
3583
  const account = getAccount(wagmiConfig);
@@ -6129,7 +6171,7 @@ function assertLinkedTransferBridgeExecuted(params) {
6129
6171
  `Transfer session ${transferSessionId} has no EXECUTE_BRIDGE action. The bridge transaction was never presented to the wallet.`
6130
6172
  );
6131
6173
  }
6132
- if (!completedIds.has(bridgeAction.id)) {
6174
+ if (!completedIds.has(bridgeAction.id) && bridgeAction.status !== "COMPLETED") {
6133
6175
  throw new Error(
6134
6176
  `Deposit flow finished without executing the bridge transaction (action ${bridgeAction.id} on session ${transferSessionId}).`
6135
6177
  );
@@ -6137,6 +6179,47 @@ function assertLinkedTransferBridgeExecuted(params) {
6137
6179
  }
6138
6180
  }
6139
6181
 
6182
+ // src/authorizationOrchestratorOrdering.ts
6183
+ function getPendingActions2(session, completedIds) {
6184
+ return session.actions.filter((a) => a.status === "PENDING" && !completedIds.has(a.id)).sort((a, b) => a.orderIndex - b.orderIndex);
6185
+ }
6186
+ function isSvmSetupAction(action) {
6187
+ if (action.type === "APPROVE_SPL") {
6188
+ return true;
6189
+ }
6190
+ return action.type === "OPEN_PROVIDER" && action.metadata?.chainFamily === "svm";
6191
+ }
6192
+ function isSvmTransferBridgeAction(action) {
6193
+ return action.type === "EXECUTE_BRIDGE" && action.metadata?.chainFamily === "svm";
6194
+ }
6195
+ function isEvmBridgeAction(action) {
6196
+ return action.type === "EXECUTE_BRIDGE" && action.metadata?.chainFamily !== "svm";
6197
+ }
6198
+ function isEvmAccountAction(action) {
6199
+ return action.type === "SIGN_PERMIT2" || action.type === "APPROVE_PERMIT2";
6200
+ }
6201
+ function getMergedPending(sessions, completedIds) {
6202
+ const allActions = [];
6203
+ for (const { session } of sessions) {
6204
+ allActions.push(...getPendingActions2(session, completedIds));
6205
+ }
6206
+ const hasPendingSvmSetupAction = allActions.some((action) => isSvmSetupAction(action));
6207
+ const hasPendingEvmAccountAction = allActions.some((action) => isEvmAccountAction(action));
6208
+ return allActions.sort((a, b) => {
6209
+ const leftIsDeferredSvmBridge = hasPendingSvmSetupAction && isSvmTransferBridgeAction(a);
6210
+ const rightIsDeferredSvmBridge = hasPendingSvmSetupAction && isSvmTransferBridgeAction(b);
6211
+ if (leftIsDeferredSvmBridge !== rightIsDeferredSvmBridge) {
6212
+ return leftIsDeferredSvmBridge ? 1 : -1;
6213
+ }
6214
+ const leftIsDeferredEvmBridge = hasPendingEvmAccountAction && isEvmBridgeAction(a);
6215
+ const rightIsDeferredEvmBridge = hasPendingEvmAccountAction && isEvmBridgeAction(b);
6216
+ if (leftIsDeferredEvmBridge !== rightIsDeferredEvmBridge) {
6217
+ return leftIsDeferredEvmBridge ? 1 : -1;
6218
+ }
6219
+ return a.orderIndex - b.orderIndex;
6220
+ });
6221
+ }
6222
+
6140
6223
  // src/hooks/useAuthorizationOrchestrator.ts
6141
6224
  var ACTION_POLL_INTERVAL_MS2 = 500;
6142
6225
  var ACTION_POLL_MAX_RETRIES2 = 20;
@@ -6150,6 +6233,7 @@ function useAuthorizationOrchestrator(deps) {
6150
6233
  const { authExecutor } = deps;
6151
6234
  const pendingSessionIdsRef = useRef([]);
6152
6235
  const lastRunRef = useRef(null);
6236
+ const inflightRunRef = useRef(null);
6153
6237
  const [pendingSelectSourceAction, setPendingSelectSourceAction] = useState(null);
6154
6238
  const [pendingOneTapAction, setPendingOneTapAction] = useState(null);
6155
6239
  const [orchestratorCompleted, setOrchestratorCompleted] = useState(false);
@@ -6225,7 +6309,7 @@ function useAuthorizationOrchestrator(deps) {
6225
6309
  }
6226
6310
  oneTapPauseRequestedRef.current = false;
6227
6311
  }, []);
6228
- const run = useCallback(
6312
+ const runInternal = useCallback(
6229
6313
  async (sessionId, options) => {
6230
6314
  const apiBaseUrl = resolvedApiBaseUrl;
6231
6315
  if (!apiBaseUrl) {
@@ -6857,6 +6941,21 @@ function useAuthorizationOrchestrator(deps) {
6857
6941
  },
6858
6942
  [resolvedApiBaseUrl, authExecutor, waitForOneTapPause, waitForSourceSelection]
6859
6943
  );
6944
+ const run = useCallback(
6945
+ (sessionId, options) => {
6946
+ const promise = runInternal(sessionId, options);
6947
+ if (inflightRunRef.current === null) {
6948
+ inflightRunRef.current = promise;
6949
+ void promise.finally(() => {
6950
+ if (inflightRunRef.current === promise) {
6951
+ inflightRunRef.current = null;
6952
+ }
6953
+ });
6954
+ }
6955
+ return promise;
6956
+ },
6957
+ [runInternal]
6958
+ );
6860
6959
  const restart = useCallback(async () => {
6861
6960
  const lastRun = lastRunRef.current;
6862
6961
  if (!lastRun) {
@@ -6865,12 +6964,20 @@ function useAuthorizationOrchestrator(deps) {
6865
6964
  appendDebug("info", "orchestrator:restart", {
6866
6965
  sessionId: lastRun.sessionId
6867
6966
  });
6967
+ const inflight = inflightRunRef.current;
6968
+ if (inflight) {
6969
+ cancelPendingFlow();
6970
+ try {
6971
+ await inflight;
6972
+ } catch {
6973
+ }
6974
+ }
6868
6975
  authExecutor.setError(null);
6869
6976
  return run(lastRun.sessionId, {
6870
6977
  ...lastRun.options,
6871
6978
  probeBeforePrompt: true
6872
6979
  });
6873
- }, [authExecutor, run]);
6980
+ }, [authExecutor, run, cancelPendingFlow]);
6874
6981
  return {
6875
6982
  run,
6876
6983
  restart,
@@ -6960,30 +7067,6 @@ async function waitForBatchableActionsReady(options) {
6960
7067
  }
6961
7068
  return batchable.map((action) => updatedActions.get(action.id) ?? action);
6962
7069
  }
6963
- function getMergedPending(sessions, completedIds) {
6964
- const allActions = [];
6965
- for (const { session } of sessions) {
6966
- allActions.push(...getPendingActions(session, completedIds));
6967
- }
6968
- const hasPendingSvmSetupAction = allActions.some((action) => isSvmSetupAction(action));
6969
- return allActions.sort((a, b) => {
6970
- const leftIsDeferredSvmBridge = hasPendingSvmSetupAction && isSvmTransferBridgeAction(a);
6971
- const rightIsDeferredSvmBridge = hasPendingSvmSetupAction && isSvmTransferBridgeAction(b);
6972
- if (leftIsDeferredSvmBridge !== rightIsDeferredSvmBridge) {
6973
- return leftIsDeferredSvmBridge ? 1 : -1;
6974
- }
6975
- return a.orderIndex - b.orderIndex;
6976
- });
6977
- }
6978
- function isSvmSetupAction(action) {
6979
- if (action.type === "APPROVE_SPL") {
6980
- return true;
6981
- }
6982
- return action.type === "OPEN_PROVIDER" && action.metadata?.chainFamily === "svm";
6983
- }
6984
- function isSvmTransferBridgeAction(action) {
6985
- return action.type === "EXECUTE_BRIDGE" && action.metadata?.chainFamily === "svm";
6986
- }
6987
7070
  function getWalletConnectRuntimeKeyForAction(action, ownerSessionId, sessions) {
6988
7071
  const metadataKey = action?.metadata?.walletConnectAccountId;
6989
7072
  if (typeof metadataKey === "string" && metadataKey.length > 0) {
@@ -7512,6 +7595,7 @@ function createInitialState(config) {
7512
7595
  loginRequested: false,
7513
7596
  standardDesktopInlineOpenWallet: false,
7514
7597
  desktopWait: null,
7598
+ setupAuthorizationSessionId: null,
7515
7599
  mobileTokenAuthorizationPending: false,
7516
7600
  privyReady: false,
7517
7601
  privyAuthenticated: false,
@@ -7556,6 +7640,7 @@ function clearAuthenticatedSessionState(state) {
7556
7640
  loginRequested: false,
7557
7641
  standardDesktopInlineOpenWallet: false,
7558
7642
  desktopWait: null,
7643
+ setupAuthorizationSessionId: null,
7559
7644
  mobileTokenAuthorizationPending: false,
7560
7645
  setupDepositAmount: null,
7561
7646
  setupDepositToken: null,
@@ -7751,14 +7836,15 @@ function applyAction(state, action) {
7751
7836
  case "TRANSFER_CREATED":
7752
7837
  return { ...state, transfer: action.transfer, pendingTransferId: null };
7753
7838
  case "TRANSFER_SIGNED":
7754
- return { ...state, transfer: action.transfer };
7839
+ return { ...state, transfer: action.transfer, setupAuthorizationSessionId: null };
7755
7840
  case "TRANSFER_COMPLETED":
7756
7841
  return {
7757
7842
  ...state,
7758
7843
  transfer: action.transfer,
7759
7844
  pendingTransferId: null,
7760
7845
  mobileFlow: false,
7761
- deeplinkUri: null
7846
+ deeplinkUri: null,
7847
+ setupAuthorizationSessionId: null
7762
7848
  };
7763
7849
  case "TRANSFER_FAILED":
7764
7850
  return {
@@ -7804,7 +7890,8 @@ function applyAction(state, action) {
7804
7890
  deeplinkUri: null,
7805
7891
  mobileTokenAuthorizationPending: false,
7806
7892
  guestWalletPrepared: null,
7807
- guestWalletDeeplinksPreparing: false
7893
+ guestWalletDeeplinksPreparing: false,
7894
+ setupAuthorizationSessionId: null
7808
7895
  };
7809
7896
  case "MOBILE_SIGN_READY":
7810
7897
  return {
@@ -7925,6 +8012,10 @@ function applyAction(state, action) {
7925
8012
  walletName: action.walletName,
7926
8013
  walletLogoUrl: action.walletLogoUrl
7927
8014
  },
8015
+ // Mirror sessionId into the longer-lived slice so the wallet
8016
+ // account switch listener stays armed after `desktopWait` is
8017
+ // cleared by the inline-connect effect.
8018
+ setupAuthorizationSessionId: action.sessionId,
7928
8019
  standardDesktopInlineOpenWallet: true
7929
8020
  };
7930
8021
  case "DESKTOP_WAIT_CLEARED":
@@ -7954,6 +8045,7 @@ function applyAction(state, action) {
7954
8045
  oneTapLimitSavedDuringSetup: false,
7955
8046
  standardDesktopInlineOpenWallet: false,
7956
8047
  desktopWait: null,
8048
+ setupAuthorizationSessionId: null,
7957
8049
  savedSelection: null,
7958
8050
  setupDepositAmount: null,
7959
8051
  setupDepositToken: null,
@@ -10951,10 +11043,7 @@ function DepositOptionsScreen({
10951
11043
  name: "Connect Wallet",
10952
11044
  icon: /* @__PURE__ */ jsx(WalletIcon, { color: tokens.text }),
10953
11045
  onClick: onFromWallet,
10954
- right: /* @__PURE__ */ jsxs("span", { style: badgeWithArrowStyle, children: [
10955
- /* @__PURE__ */ jsx(RecommendedBadge, { tokens }),
10956
- /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M9 6l6 6-6 6", stroke: tokens.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
10957
- ] })
11046
+ right: /* @__PURE__ */ jsx("span", { style: badgeWithArrowStyle, children: /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M9 6l6 6-6 6", stroke: tokens.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
10958
11047
  }
10959
11048
  ),
10960
11049
  /* @__PURE__ */ jsx(
@@ -10987,9 +11076,6 @@ function DepositTypeToggle({ tokens }) {
10987
11076
  function ComingSoonBadge({ tokens }) {
10988
11077
  return /* @__PURE__ */ jsx("span", { style: comingSoonBadgeStyle(tokens.bgRecessed, tokens.textMuted), children: "Coming soon" });
10989
11078
  }
10990
- function RecommendedBadge({ tokens }) {
10991
- return /* @__PURE__ */ jsx("span", { style: recommendedBadgeStyle(tokens.successBg, tokens.success), children: "Recommended" });
10992
- }
10993
11079
  function WalletIcon({ color }) {
10994
11080
  return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
10995
11081
  /* @__PURE__ */ jsx(
@@ -11150,19 +11236,6 @@ var badgeWithArrowStyle = {
11150
11236
  display: "flex",
11151
11237
  alignItems: "center"
11152
11238
  };
11153
- var recommendedBadgeStyle = (bg, color) => ({
11154
- display: "inline-flex",
11155
- alignItems: "center",
11156
- justifyContent: "center",
11157
- background: bg,
11158
- color,
11159
- fontSize: 10,
11160
- fontWeight: 500,
11161
- lineHeight: 1,
11162
- padding: "4px 8px",
11163
- borderRadius: 8,
11164
- whiteSpace: "nowrap"
11165
- });
11166
11239
  var linkIconImageStyle = (color) => ({
11167
11240
  width: 24,
11168
11241
  height: 24,
@@ -11294,7 +11367,7 @@ function AmountTooLowScreen({
11294
11367
  }
11295
11368
  );
11296
11369
  }
11297
- var DEFAULT_PRESETS = [50, 100, 200, 500];
11370
+ var DEFAULT_PRESETS = [5, 25, 100, 250];
11298
11371
  function EnterAmountScreen({
11299
11372
  value,
11300
11373
  onDigit,
@@ -11871,7 +11944,7 @@ function PasskeyPopupWelcomeScreen({
11871
11944
  ) }),
11872
11945
  /* @__PURE__ */ jsx("h2", { style: headingStyle5(tokens.text), children: "Try the better way\nto deposit" }),
11873
11946
  /* @__PURE__ */ jsx("p", { style: subtitleStyle3(tokens.textSecondary), children: "From your wallet, to any app, in one tap." }),
11874
- error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle3(tokens), children: error })
11947
+ error && false
11875
11948
  ] })
11876
11949
  ]
11877
11950
  }
@@ -11927,17 +12000,6 @@ var footerButtonStyle = {
11927
12000
  paddingTop: 48,
11928
12001
  paddingBottom: 36
11929
12002
  };
11930
- var errorBannerStyle3 = (tokens) => ({
11931
- background: tokens.errorBg,
11932
- border: `1px solid ${tokens.error}66`,
11933
- borderRadius: 16,
11934
- padding: "11px 14px",
11935
- color: tokens.error,
11936
- fontSize: "0.84rem",
11937
- lineHeight: 1.5,
11938
- width: "100%",
11939
- textAlign: "left"
11940
- });
11941
12003
  function PasskeyReadyScreen({
11942
12004
  onLinkWallet,
11943
12005
  onBack,
@@ -12041,7 +12103,7 @@ function VerifyPasskeyScreen({
12041
12103
  ] }) }),
12042
12104
  /* @__PURE__ */ jsx("h2", { style: headingStyle7(tokens.text), children: "Verify your passkey" }),
12043
12105
  /* @__PURE__ */ jsx("p", { style: subtitleStyle5(tokens.textSecondary), children: subtitle }),
12044
- error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle4(tokens), children: error }),
12106
+ error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle3(tokens), children: error }),
12045
12107
  /* @__PURE__ */ jsx(InfoBanner, { children: "Your passkey is stored securely on your device. Blink never sees your biometric data." })
12046
12108
  ] })
12047
12109
  ]
@@ -12070,7 +12132,7 @@ var subtitleStyle5 = (color) => ({
12070
12132
  lineHeight: 1.5,
12071
12133
  maxWidth: 280
12072
12134
  });
12073
- var errorBannerStyle4 = (tokens) => ({
12135
+ var errorBannerStyle3 = (tokens) => ({
12074
12136
  background: tokens.errorBg,
12075
12137
  border: `1px solid ${tokens.error}66`,
12076
12138
  borderRadius: 16,
@@ -12424,7 +12486,7 @@ function WalletPickerScreen({
12424
12486
  }
12425
12487
  ),
12426
12488
  /* @__PURE__ */ jsx("h1", { style: titleStyle3(tokens.text), children: "Link wallet" }),
12427
- error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle5(tokens), children: error }),
12489
+ error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle4(tokens), children: error }),
12428
12490
  /* @__PURE__ */ jsx("div", { style: sheetStackStyle, children: /* @__PURE__ */ jsx("div", { style: cardStyle2(tokens.bgCardTranslucent), children: showOtherWallets ? /* @__PURE__ */ jsx(
12429
12491
  OtherWalletsPanel,
12430
12492
  {
@@ -12735,7 +12797,7 @@ var loadingWrapperStyle = {
12735
12797
  alignItems: "center",
12736
12798
  justifyContent: "center"
12737
12799
  };
12738
- var errorBannerStyle5 = (tokens) => ({
12800
+ var errorBannerStyle4 = (tokens) => ({
12739
12801
  background: tokens.errorBg,
12740
12802
  border: `1px solid ${tokens.error}66`,
12741
12803
  borderRadius: 16,
@@ -12892,7 +12954,7 @@ function SetupScreen({
12892
12954
  ),
12893
12955
  /* @__PURE__ */ jsx("h2", { style: headingStyle8(tokens.text), children: "Next time deposit\nUSDC in one tap" }),
12894
12956
  /* @__PURE__ */ jsx("p", { style: subtitleStyle6(tokens.textSecondary), children: "Set a cap for passkey deposits.\nYou always stay in control." }),
12895
- error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle6(tokens), children: error }),
12957
+ error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle5(tokens), children: error }),
12896
12958
  /* @__PURE__ */ jsx("div", { style: chipsRowStyle, children: PRESETS.map(({ label, value }) => {
12897
12959
  const active = selectedPreset === value;
12898
12960
  return /* @__PURE__ */ jsx(
@@ -12982,7 +13044,7 @@ var chipStyle = (themeTokens, active) => ({
12982
13044
  color: active ? themeTokens.accentText : themeTokens.text,
12983
13045
  whiteSpace: "nowrap"
12984
13046
  });
12985
- var errorBannerStyle6 = (themeTokens) => ({
13047
+ var errorBannerStyle5 = (themeTokens) => ({
12986
13048
  background: themeTokens.errorBg,
12987
13049
  border: `1px solid ${themeTokens.error}66`,
12988
13050
  borderRadius: 16,
@@ -12993,217 +13055,6 @@ var errorBannerStyle6 = (themeTokens) => ({
12993
13055
  width: "100%",
12994
13056
  textAlign: "left"
12995
13057
  });
12996
- function ManualTransferPasskeyScreen({
12997
- onCreatePasskey,
12998
- loading = false,
12999
- error,
13000
- onBack,
13001
- onClose
13002
- }) {
13003
- const { tokens } = useBlinkConfig();
13004
- return /* @__PURE__ */ jsxs("div", { style: containerStyle8(tokens), children: [
13005
- onBack && /* @__PURE__ */ jsx(
13006
- "button",
13007
- {
13008
- type: "button",
13009
- onClick: onBack,
13010
- "aria-label": "Go back",
13011
- style: { ...navButtonStyle(tokens.bgRecessed, tokens.text), left: 16 },
13012
- children: /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
13013
- "path",
13014
- {
13015
- d: "M15 18l-6-6 6-6",
13016
- stroke: "currentColor",
13017
- strokeWidth: "2",
13018
- strokeLinecap: "round",
13019
- strokeLinejoin: "round"
13020
- }
13021
- ) })
13022
- }
13023
- ),
13024
- onClose && /* @__PURE__ */ jsx(
13025
- "button",
13026
- {
13027
- type: "button",
13028
- onClick: onClose,
13029
- "aria-label": "Close",
13030
- style: { ...navButtonStyle(tokens.bgRecessed, tokens.text), right: 16 },
13031
- children: /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
13032
- "path",
13033
- {
13034
- d: "M6 6l12 12M18 6L6 18",
13035
- stroke: "currentColor",
13036
- strokeWidth: "2",
13037
- strokeLinecap: "round",
13038
- strokeLinejoin: "round"
13039
- }
13040
- ) })
13041
- }
13042
- ),
13043
- /* @__PURE__ */ jsxs("div", { style: contentStyle11, children: [
13044
- /* @__PURE__ */ jsxs("div", { style: heroStyle, children: [
13045
- /* @__PURE__ */ jsx(
13046
- "img",
13047
- {
13048
- src: FACE_ID_ILLUSTRATION,
13049
- alt: "",
13050
- "aria-hidden": "true",
13051
- style: illustrationStyle4
13052
- }
13053
- ),
13054
- /* @__PURE__ */ jsxs("div", { style: copyStackStyle, children: [
13055
- /* @__PURE__ */ jsx("h2", { style: headingStyle9(tokens.text), children: "Next time deposit USDC\nin one tap" }),
13056
- /* @__PURE__ */ jsx("p", { style: subtitleStyle7(tokens.text), children: "Set up once and never bother\nwith QR codes again" }),
13057
- error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle7(tokens), children: error })
13058
- ] })
13059
- ] }),
13060
- /* @__PURE__ */ jsxs(
13061
- "button",
13062
- {
13063
- type: "button",
13064
- onClick: onCreatePasskey,
13065
- disabled: loading,
13066
- style: ctaStyle(tokens, loading),
13067
- children: [
13068
- !loading && /* @__PURE__ */ jsx(
13069
- "img",
13070
- {
13071
- src: BLINK_QR_LOGO,
13072
- alt: "",
13073
- "aria-hidden": "true",
13074
- style: ctaIconStyle
13075
- }
13076
- ),
13077
- "Create Blink Passkey"
13078
- ]
13079
- }
13080
- )
13081
- ] })
13082
- ] });
13083
- }
13084
- var containerStyle8 = (tokens) => ({
13085
- position: "relative",
13086
- display: "flex",
13087
- flexDirection: "column",
13088
- width: "100%",
13089
- maxWidth: 420,
13090
- height: "100%",
13091
- margin: "0 auto",
13092
- overflow: "hidden",
13093
- borderRadius: tokens.radiusLg,
13094
- background: tokens.bgCard,
13095
- backdropFilter: "blur(16px)",
13096
- WebkitBackdropFilter: "blur(16px)",
13097
- fontFamily: tokens.fontFamily,
13098
- boxSizing: "border-box"
13099
- });
13100
- var contentStyle11 = {
13101
- flex: 1,
13102
- minHeight: 0,
13103
- display: "flex",
13104
- flexDirection: "column",
13105
- justifyContent: "space-between",
13106
- alignItems: "center",
13107
- padding: "80px 32px 32px",
13108
- gap: 32,
13109
- boxSizing: "border-box"
13110
- };
13111
- var heroStyle = {
13112
- flex: 1,
13113
- minHeight: 0,
13114
- display: "flex",
13115
- flexDirection: "column",
13116
- justifyContent: "center",
13117
- alignItems: "center",
13118
- gap: 32,
13119
- width: "100%"
13120
- };
13121
- var illustrationStyle4 = {
13122
- width: 200,
13123
- height: 200,
13124
- objectFit: "contain",
13125
- display: "block"
13126
- };
13127
- var copyStackStyle = {
13128
- display: "flex",
13129
- flexDirection: "column",
13130
- alignItems: "center",
13131
- gap: 16,
13132
- width: "100%",
13133
- textAlign: "center"
13134
- };
13135
- var headingStyle9 = (color) => ({
13136
- margin: 0,
13137
- color,
13138
- fontSize: 24,
13139
- fontWeight: 700,
13140
- lineHeight: 1,
13141
- letterSpacing: 0,
13142
- whiteSpace: "pre-line"
13143
- });
13144
- var subtitleStyle7 = (color) => ({
13145
- margin: 0,
13146
- color,
13147
- fontSize: 16,
13148
- fontWeight: 400,
13149
- lineHeight: 1.25,
13150
- whiteSpace: "pre-line"
13151
- });
13152
- var ctaStyle = (tokens, disabled) => ({
13153
- display: "flex",
13154
- alignItems: "center",
13155
- justifyContent: "center",
13156
- gap: 8,
13157
- width: "100%",
13158
- height: 56,
13159
- padding: "4px 24px",
13160
- border: "none",
13161
- borderRadius: 36,
13162
- background: `linear-gradient(180deg, ${tokens.accent}, ${tokens.accentHover})`,
13163
- color: tokens.accentText,
13164
- fontSize: 20,
13165
- fontWeight: 700,
13166
- fontFamily: "inherit",
13167
- cursor: disabled ? "default" : "pointer",
13168
- opacity: disabled ? 0.5 : 1,
13169
- transition: "opacity 0.15s ease",
13170
- boxSizing: "border-box"
13171
- });
13172
- var ctaIconStyle = {
13173
- width: 32,
13174
- height: 32,
13175
- objectFit: "contain",
13176
- display: "block",
13177
- borderRadius: 8
13178
- };
13179
- var navButtonStyle = (bg, color) => ({
13180
- position: "absolute",
13181
- top: 16,
13182
- zIndex: 1,
13183
- width: 44,
13184
- height: 44,
13185
- border: "none",
13186
- borderRadius: 40,
13187
- background: bg,
13188
- color,
13189
- display: "flex",
13190
- alignItems: "center",
13191
- justifyContent: "center",
13192
- cursor: "pointer",
13193
- padding: 0
13194
- });
13195
- var errorBannerStyle7 = (tokens) => ({
13196
- width: "100%",
13197
- borderRadius: 16,
13198
- padding: "11px 14px",
13199
- background: tokens.errorBg,
13200
- border: `1px solid ${tokens.error}66`,
13201
- color: tokens.error,
13202
- fontSize: "0.84rem",
13203
- lineHeight: 1.5,
13204
- textAlign: "left",
13205
- boxSizing: "border-box"
13206
- });
13207
13058
  function SetupSelectDepositSourceScreen({
13208
13059
  tokenOptions,
13209
13060
  selectedTokenSymbol,
@@ -14384,7 +14235,7 @@ function SelectSourceScreen({
14384
14235
  /* @__PURE__ */ jsxs("div", { style: optionContentStyle, children: [
14385
14236
  /* @__PURE__ */ jsxs("span", { style: optionNameStyle(tokens.text), children: [
14386
14237
  chain.chainName,
14387
- isRecommended && /* @__PURE__ */ jsx("span", { style: recommendedBadgeStyle2(tokens.textMuted), children: " recommended" })
14238
+ isRecommended && /* @__PURE__ */ jsx("span", { style: recommendedBadgeStyle(tokens.textMuted), children: " recommended" })
14388
14239
  ] }),
14389
14240
  /* @__PURE__ */ jsxs("span", { style: optionBalanceStyle(tokens.textMuted), children: [
14390
14241
  "$",
@@ -14480,7 +14331,7 @@ var optionNameStyle = (color) => ({
14480
14331
  fontWeight: 600,
14481
14332
  color
14482
14333
  });
14483
- var recommendedBadgeStyle2 = (color) => ({
14334
+ var recommendedBadgeStyle = (color) => ({
14484
14335
  fontSize: "0.7rem",
14485
14336
  fontWeight: 500,
14486
14337
  color,
@@ -14780,7 +14631,7 @@ function TransferStatusLayout({
14780
14631
  onLogout && /* @__PURE__ */ jsx("div", { style: menuOverlayStyle, children: /* @__PURE__ */ jsx(SettingsMenu, { onLogout }) }),
14781
14632
  /* @__PURE__ */ jsxs("div", { style: contentStyle16, children: [
14782
14633
  /* @__PURE__ */ jsx("h2", { style: headingStyle13(tokens.text), children: heading }),
14783
- visibleError && /* @__PURE__ */ jsx("div", { style: errorBannerStyle8(tokens), children: visibleError }),
14634
+ visibleError && /* @__PURE__ */ jsx("div", { style: errorBannerStyle7(tokens), children: visibleError }),
14784
14635
  children
14785
14636
  ] })
14786
14637
  ] })
@@ -14881,7 +14732,7 @@ var headingStyle13 = (color) => ({
14881
14732
  margin: 0,
14882
14733
  textAlign: "center"
14883
14734
  });
14884
- var errorBannerStyle8 = (tokens) => ({
14735
+ var errorBannerStyle7 = (tokens) => ({
14885
14736
  background: tokens.errorBg,
14886
14737
  border: `1px solid ${tokens.error}66`,
14887
14738
  borderRadius: 16,
@@ -15867,7 +15718,7 @@ function GuestTokenPickerScreen({
15867
15718
  /* @__PURE__ */ jsx(ScreenHeader, { onBack }),
15868
15719
  /* @__PURE__ */ jsxs("div", { style: contentStyle20, children: [
15869
15720
  /* @__PURE__ */ jsx("h2", { style: headingStyle16(tokens.text), children: title }),
15870
- error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle9(tokens), children: error }),
15721
+ error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle8(tokens), children: error }),
15871
15722
  entries2.length === 0 ? /* @__PURE__ */ jsx("p", { style: subtitleStyle13(tokens.textMuted), children: emptyMessage ?? "No tokens available." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15872
15723
  /* @__PURE__ */ jsx("label", { style: labelStyle7(tokens.textSecondary), children: "Token" }),
15873
15724
  /* @__PURE__ */ jsx(
@@ -16039,7 +15890,7 @@ var presetButtonStyle = (themeTokens, active) => ({
16039
15890
  background: active ? `${themeTokens.accent}22` : "transparent",
16040
15891
  color: themeTokens.text
16041
15892
  });
16042
- var errorBannerStyle9 = (themeTokens) => ({
15893
+ var errorBannerStyle8 = (themeTokens) => ({
16043
15894
  background: themeTokens.errorBg,
16044
15895
  border: `1px solid ${themeTokens.error}66`,
16045
15896
  borderRadius: 12,
@@ -16140,7 +15991,7 @@ function ManualTransferFlow({
16140
15991
  );
16141
15992
  } else if (screen === "deposit-complete") {
16142
15993
  const transferAmount = Number(session?.deliveredAmountUsd ?? session?.minAmountUsd ?? 0);
16143
- screenContent = passkeyCreated ? /* @__PURE__ */ jsx(
15994
+ screenContent = /* @__PURE__ */ jsx(
16144
15995
  SuccessScreen,
16145
15996
  {
16146
15997
  amount: transferAmount,
@@ -16149,16 +16000,7 @@ function ManualTransferFlow({
16149
16000
  onDone: onDismiss,
16150
16001
  onLogout
16151
16002
  }
16152
- ) : /* @__PURE__ */ jsx(
16153
- ManualTransferPasskeyScreen,
16154
- {
16155
- onCreatePasskey: onCreatePasskey ?? (() => void 0),
16156
- loading: createPasskeyLoading,
16157
- error: createPasskeyError,
16158
- onBack,
16159
- onClose: onDismiss ?? onLogout
16160
- }
16161
- );
16003
+ ) ;
16162
16004
  } else if (screen === "deposit-failed") {
16163
16005
  screenContent = /* @__PURE__ */ jsx(
16164
16006
  BlinkErrorScreen,
@@ -17583,6 +17425,38 @@ function useMobileFlowHandlers(dispatch, polling, reloadAccounts, pollingTransfe
17583
17425
  };
17584
17426
  }
17585
17427
 
17428
+ // src/accountSwitchHelpers.ts
17429
+ var OPEN_PROVIDER_REPLACEMENT_CONFLICT_CODE = "OPEN_PROVIDER_REPLACEMENT_CONFLICT";
17430
+ var ACCOUNT_SWITCH_CONFLICT_MESSAGE = "You can't switch accounts after authorizing the source token. Please switch back to your previous account in your wallet.";
17431
+ async function replaceOpenProviderForAccountSwitch(input) {
17432
+ try {
17433
+ const session = await fetchAuthorizationSession(
17434
+ input.apiBaseUrl,
17435
+ input.sessionId
17436
+ );
17437
+ const openProvider = session.actions.find((a) => a.type === "OPEN_PROVIDER");
17438
+ if (!openProvider) {
17439
+ return { status: "no-open-provider" };
17440
+ }
17441
+ const result = { accounts: [...input.accounts] };
17442
+ if (input.chainId != null) {
17443
+ result.chainId = `0x${input.chainId.toString(16)}`;
17444
+ }
17445
+ const updated = await reportActionCompletion(
17446
+ input.apiBaseUrl,
17447
+ openProvider.id,
17448
+ result
17449
+ );
17450
+ return { status: "success", session: updated };
17451
+ } catch (err) {
17452
+ const error = err instanceof Error ? err : new Error(String(err));
17453
+ if (error.message.includes(OPEN_PROVIDER_REPLACEMENT_CONFLICT_CODE)) {
17454
+ return { status: "conflict" };
17455
+ }
17456
+ return { status: "error", error };
17457
+ }
17458
+ }
17459
+
17586
17460
  // src/hooks/providerSelectionGuards.ts
17587
17461
  function resolveSetupFlowDepositAmount({
17588
17462
  hasActiveWallet: hasActiveWallet2,
@@ -18832,6 +18706,33 @@ function useProviderHandlers(deps) {
18832
18706
  setupFlowDepositAmount,
18833
18707
  dispatch
18834
18708
  ]);
18709
+ const handleWalletAccountSwitch = useCallback(async (change, sessionId) => {
18710
+ const outcome = await replaceOpenProviderForAccountSwitch({
18711
+ apiBaseUrl,
18712
+ sessionId,
18713
+ accounts: change.accounts,
18714
+ chainId: change.chainId
18715
+ });
18716
+ if (outcome.status === "success") {
18717
+ dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
18718
+ try {
18719
+ await orchestrator.restart();
18720
+ } catch (err) {
18721
+ captureException(err);
18722
+ onError?.(err instanceof Error ? err.message : "Failed to refresh authorization session.");
18723
+ }
18724
+ return;
18725
+ }
18726
+ if (outcome.status === "conflict") {
18727
+ onError?.(ACCOUNT_SWITCH_CONFLICT_MESSAGE);
18728
+ return;
18729
+ }
18730
+ if (outcome.status === "error") {
18731
+ captureException(outcome.error);
18732
+ onError?.(outcome.error.message);
18733
+ return;
18734
+ }
18735
+ }, [apiBaseUrl, dispatch, orchestrator, onError]);
18835
18736
  return {
18836
18737
  handlePrepareProvider,
18837
18738
  handleSelectProvider,
@@ -18844,7 +18745,8 @@ function useProviderHandlers(deps) {
18844
18745
  handleAuthorizeToken,
18845
18746
  handlePrepareTokenAuthorization,
18846
18747
  handleCommitTokenAuthorization,
18847
- handlePrepareGuestDeeplinks
18748
+ handlePrepareGuestDeeplinks,
18749
+ handleWalletAccountSwitch
18848
18750
  };
18849
18751
  }
18850
18752
  function useOneTapSetupHandlers(deps) {
@@ -19908,6 +19810,40 @@ function useDepositFeeEstimate({
19908
19810
  }, [fetchQuote]);
19909
19811
  return { quoteId, quoteFee, quoteLoading, quoteError };
19910
19812
  }
19813
+ function useWalletAccountSwitchEffect(deps) {
19814
+ const { enabled = true, isDesktop = true, onAccountChanged } = deps;
19815
+ const account = useAccount();
19816
+ const address = account.address ?? null;
19817
+ const chainId = account.chainId ?? null;
19818
+ const connectorId = account.connector?.id ?? null;
19819
+ const addresses = account.addresses;
19820
+ const baselineRef = useRef(null);
19821
+ useEffect(() => {
19822
+ if (!enabled || !isDesktop) {
19823
+ baselineRef.current = null;
19824
+ return;
19825
+ }
19826
+ if (!address) {
19827
+ return;
19828
+ }
19829
+ if (baselineRef.current === null) {
19830
+ baselineRef.current = address;
19831
+ return;
19832
+ }
19833
+ if (baselineRef.current.toLowerCase() === address.toLowerCase()) {
19834
+ return;
19835
+ }
19836
+ const previous = baselineRef.current;
19837
+ baselineRef.current = address;
19838
+ void onAccountChanged({
19839
+ previousAddress: previous,
19840
+ nextAddress: address,
19841
+ connectorId: connectorId ?? "injected",
19842
+ chainId,
19843
+ accounts: addresses ?? [address]
19844
+ });
19845
+ }, [enabled, isDesktop, address, chainId, connectorId, addresses, onAccountChanged]);
19846
+ }
19911
19847
  function usePersistAmountToActiveSession({
19912
19848
  apiBaseUrl,
19913
19849
  accounts,
@@ -20207,6 +20143,17 @@ function BlinkPaymentInner({
20207
20143
  activeCredentialId: state.activeCredentialId ?? void 0,
20208
20144
  idempotencyKey
20209
20145
  });
20146
+ const accountSwitchSessionId = state.setupAuthorizationSessionId;
20147
+ const handleProviderWalletAccountSwitch = provider.handleWalletAccountSwitch;
20148
+ const onWalletAccountChanged = useCallback(async (change) => {
20149
+ if (!accountSwitchSessionId) return;
20150
+ await handleProviderWalletAccountSwitch(change, accountSwitchSessionId);
20151
+ }, [handleProviderWalletAccountSwitch, accountSwitchSessionId]);
20152
+ useWalletAccountSwitchEffect({
20153
+ enabled: accountSwitchSessionId != null,
20154
+ isDesktop,
20155
+ onAccountChanged: onWalletAccountChanged
20156
+ });
20210
20157
  const clearLocalSessionArtifacts = useCallback(() => {
20211
20158
  popupAuthRef.current = null;
20212
20159
  clearPopupAuth();
@@ -20643,6 +20590,6 @@ function getDeviceBiometricUnlockText() {
20643
20590
  return FALLBACK;
20644
20591
  }
20645
20592
 
20646
- export { AdvancedSourceScreen, AuthorizationSessionCancelledError, BLINK_ERROR_ILLUSTRATION, BLINK_LOGO, BLINK_MASCOT, BLINK_PASSKEY_ILLUSTRATION, BLINK_SUCCESS_ILLUSTRATION, BlinkErrorScreen, BlinkInitialLoadingScreen, BlinkLoadingScreen, BlinkPayment, BlinkProvider, ConfirmSignScreen, DepositCompleteScreen, DepositScreen, DepositTransferStatusScreen, GuestTokenPickerScreen, IconCircle, InfoBanner, LoginScreen, OpenWalletScreen, OtpVerifyScreen, OutlineButton, PASSKEY_READY_ILLUSTRATION, PasskeyIframeBlockedError, PasskeyPopupWelcomeScreen, PasskeyReadyScreen, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectDepositSourceScreen, SelectSourceScreen, SettingsMenu, SetupDepositScreen, SetupScreen, SetupSelectDepositSourceScreen, SetupTransferStatusScreen, Spinner, StepList, StepRenderer, SuccessScreen, TokenPickerScreen, VerifyPasskeyScreen, WalletPickerScreen, appendDebug, api_exports as blinkApi, clearDebugEntries, createInitialState, credentialIdBase64ToBytes, darkTheme, darkThemeNew, darkTransparentTheme, darkTransparentThemeNew, deviceHasPasskey, encodePermit2ApproveCalldata, findDevicePasskey, findDevicePasskeyViaPopup, getAtomicBatchSupportDebugInfo, getDebugEntries, getDeviceBiometricUnlockText, getTheme, getThemeBase, getWalletCapabilities, isAuthorizationSessionCancelled, isExpectedAuthorizationCancellation, isTerminalTransferStatus, isTransferAwaitingCompletion, isTransparentTheme, isUserDismissedAuthorizationError, isVisibleUsdAmountAtTwoDecimals, lightTheme, lightThemeNew, lightTransparentTheme, lightTransparentThemeNew, mapGuestPickerEntries, resolvePasskeyRpId, screenForPhase, subscribeDebug, supportsAtomicBatch, supportsPaymasterService, useAuthorizationExecutor, useAuthorizationOrchestrator, useBlinkConfig, useBlinkDebugLog, useBlinkDepositAmount, useTransferPolling, useTransferSigning };
20593
+ export { ACCOUNT_SWITCH_CONFLICT_MESSAGE, AdvancedSourceScreen, AuthorizationSessionCancelledError, BLINK_ERROR_ILLUSTRATION, BLINK_LOGO, BLINK_MASCOT, BLINK_PASSKEY_ILLUSTRATION, BLINK_SUCCESS_ILLUSTRATION, BlinkErrorScreen, BlinkInitialLoadingScreen, BlinkLoadingScreen, BlinkPayment, BlinkProvider, ConfirmSignScreen, DepositCompleteScreen, DepositScreen, DepositTransferStatusScreen, GuestTokenPickerScreen, IconCircle, InfoBanner, LoginScreen, OpenWalletScreen, OtpVerifyScreen, OutlineButton, PASSKEY_READY_ILLUSTRATION, PasskeyIframeBlockedError, PasskeyPopupWelcomeScreen, PasskeyReadyScreen, PasskeyScreen, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectDepositSourceScreen, SelectSourceScreen, SettingsMenu, SetupDepositScreen, SetupScreen, SetupSelectDepositSourceScreen, SetupTransferStatusScreen, Spinner, StepList, StepRenderer, SuccessScreen, TokenPickerScreen, VerifyPasskeyScreen, WalletPickerScreen, appendDebug, api_exports as blinkApi, clearDebugEntries, createInitialState, credentialIdBase64ToBytes, darkTheme, darkThemeNew, darkTransparentTheme, darkTransparentThemeNew, deviceHasPasskey, encodePermit2ApproveCalldata, findDevicePasskey, findDevicePasskeyViaPopup, getAtomicBatchSupportDebugInfo, getDebugEntries, getDeviceBiometricUnlockText, getTheme, getThemeBase, getWalletCapabilities, isAuthorizationSessionCancelled, isExpectedAuthorizationCancellation, isTerminalTransferStatus, isTransferAwaitingCompletion, isTransparentTheme, isUserDismissedAuthorizationError, isVisibleUsdAmountAtTwoDecimals, lightTheme, lightThemeNew, lightTransparentTheme, lightTransparentThemeNew, mapGuestPickerEntries, replaceOpenProviderForAccountSwitch, resolvePasskeyRpId, screenForPhase, subscribeDebug, supportsAtomicBatch, supportsPaymasterService, useAuthorizationExecutor, useAuthorizationOrchestrator, useBlinkConfig, useBlinkDebugLog, useBlinkDepositAmount, useTransferPolling, useTransferSigning };
20647
20594
  //# sourceMappingURL=index.js.map
20648
20595
  //# sourceMappingURL=index.js.map