@swype-org/react-sdk 0.2.215 → 0.2.220

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
@@ -1040,6 +1040,7 @@ function BlinkProvider({
1040
1040
  privyAppId,
1041
1041
  minTransferAmountUsd,
1042
1042
  enableFullWidget = false,
1043
+ isMobileApp = false,
1043
1044
  children
1044
1045
  }) {
1045
1046
  const queryClientRef = useRef(null);
@@ -1078,9 +1079,10 @@ function BlinkProvider({
1078
1079
  minTransferAmountUsd: resolvedMinTransferAmountUsd,
1079
1080
  depositAmount,
1080
1081
  setDepositAmount,
1081
- enableFullWidget
1082
+ enableFullWidget,
1083
+ isMobileApp
1082
1084
  }),
1083
- [apiBaseUrl, theme, resolvedMinTransferAmountUsd, depositAmount, setDepositAmount, enableFullWidget]
1085
+ [apiBaseUrl, theme, resolvedMinTransferAmountUsd, depositAmount, setDepositAmount, enableFullWidget, isMobileApp]
1084
1086
  );
1085
1087
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClientRef.current, children: /* @__PURE__ */ jsx(WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: /* @__PURE__ */ jsx(
1086
1088
  PrivyProvider,
@@ -2137,7 +2139,19 @@ async function getWalletCapabilities(walletClient, address, chainId) {
2137
2139
  params: chainScopedParams ?? legacyParams
2138
2140
  });
2139
2141
  if (result && typeof result === "object" && !Array.isArray(result)) {
2140
- return result;
2142
+ const caps = result;
2143
+ const hexKey = chainId != null ? `0x${chainId.toString(16)}` : null;
2144
+ const chainMissing = chainScopedParams && hexKey && !caps[hexKey] && !caps[String(chainId)];
2145
+ if (chainMissing) {
2146
+ const legacyResult = await walletClient.request({
2147
+ method: "wallet_getCapabilities",
2148
+ params: legacyParams
2149
+ });
2150
+ if (legacyResult && typeof legacyResult === "object" && !Array.isArray(legacyResult)) {
2151
+ return legacyResult;
2152
+ }
2153
+ }
2154
+ return caps;
2141
2155
  }
2142
2156
  return {};
2143
2157
  } catch (err) {
@@ -6041,6 +6055,8 @@ var ACTION_POLL_INTERVAL_MS2 = 500;
6041
6055
  var ACTION_POLL_MAX_RETRIES2 = 20;
6042
6056
  var REPORT_COMPLETION_TIMEOUT_MS = 9e4;
6043
6057
  var REPORT_COMPLETION_TIMEOUT_MESSAGE = "REPORT_COMPLETION_TIMEOUT";
6058
+ var APPROVE_PERMIT2_CONFIRMING_MESSAGE = "Your Permit2 approval transaction was submitted and is still confirming on-chain. Please wait a moment and retry. Do not approve again in your wallet.";
6059
+ var SIGN_PERMIT2_CONFIRMING_MESSAGE = "Your Permit2 signature was submitted and is still confirming on-chain. Please wait a moment and retry. Do not sign again in your wallet.";
6044
6060
  function useAuthorizationOrchestrator(deps) {
6045
6061
  const blinkConfig = useOptionalBlinkConfig();
6046
6062
  const resolvedApiBaseUrl = deps.apiBaseUrl ?? blinkConfig?.apiBaseUrl;
@@ -6054,6 +6070,8 @@ function useAuthorizationOrchestrator(deps) {
6054
6070
  const selectSourceRejectRef = useRef(null);
6055
6071
  const oneTapResolverRef = useRef(null);
6056
6072
  const oneTapRejectRef = useRef(null);
6073
+ const submittedApprovePermit2ActionIdsRef = useRef(/* @__PURE__ */ new Set());
6074
+ const submittedSignPermit2ActionIdsRef = useRef(/* @__PURE__ */ new Set());
6057
6075
  const oneTapPauseRequestedRef = useRef(false);
6058
6076
  const addSession = useCallback((sessionId) => {
6059
6077
  pendingSessionIdsRef.current.push(sessionId);
@@ -6476,6 +6494,12 @@ function useAuthorizationOrchestrator(deps) {
6476
6494
  completedIds.add(batchedAction.id);
6477
6495
  oneTapCompletedActionIds.delete(batchedAction.id);
6478
6496
  authExecutor.addResult(result2);
6497
+ if (isSubmittedApprovePermit2Result(batchedAction, result2)) {
6498
+ submittedApprovePermit2ActionIdsRef.current.add(batchedAction.id);
6499
+ }
6500
+ if (isSubmittedSignPermit2Result(batchedAction, result2)) {
6501
+ submittedSignPermit2ActionIdsRef.current.add(batchedAction.id);
6502
+ }
6479
6503
  const batchedOwnerSessionId = actionSessionMap.get(batchedAction.id) ?? ownerSessionId;
6480
6504
  const reportedSession2 = await reportActionCompletionWithLogging(
6481
6505
  apiBaseUrl,
@@ -6503,7 +6527,9 @@ function useAuthorizationOrchestrator(deps) {
6503
6527
  continue;
6504
6528
  }
6505
6529
  }
6506
- const isPrePromptProbableActionType = action.type === "SIGN_PERMIT2" || action.type === "APPROVE_PERMIT2" || action.type === "APPROVE_SPL";
6530
+ const approvePermit2WasSubmitted = action.type === "APPROVE_PERMIT2" && submittedApprovePermit2ActionIdsRef.current.has(action.id);
6531
+ const signPermit2WasSubmitted = action.type === "SIGN_PERMIT2" && submittedSignPermit2ActionIdsRef.current.has(action.id);
6532
+ const isPrePromptProbableActionType = action.type === "SIGN_PERMIT2" || action.type === "APPROVE_SPL" || approvePermit2WasSubmitted;
6507
6533
  if (isPrePromptProbableActionType && probeBeforePrompt && !preProbedIds.has(action.id)) {
6508
6534
  preProbedIds.add(action.id);
6509
6535
  appendDebug("info", `${action.type}: pre-prompt probe start`, {
@@ -6536,13 +6562,19 @@ function useAuthorizationOrchestrator(deps) {
6536
6562
  });
6537
6563
  continue;
6538
6564
  }
6539
- appendDebug("info", `${action.type}: pre-prompt probe did not detect; presenting wallet`, {
6565
+ appendDebug("info", approvePermit2WasSubmitted || signPermit2WasSubmitted ? `${action.type}: submitted action not detected yet; waiting for confirmation` : `${action.type}: pre-prompt probe did not detect; presenting wallet`, {
6540
6566
  actionId: action.id,
6541
6567
  ownerSessionId,
6542
6568
  reason: probe.reason,
6543
6569
  status: probe.status,
6544
6570
  code: probe.code
6545
6571
  });
6572
+ if (approvePermit2WasSubmitted) {
6573
+ throw new Error(APPROVE_PERMIT2_CONFIRMING_MESSAGE);
6574
+ }
6575
+ if (signPermit2WasSubmitted) {
6576
+ throw new Error(SIGN_PERMIT2_CONFIRMING_MESSAGE);
6577
+ }
6546
6578
  }
6547
6579
  appendDebug("info", `orchestrator:executeAction start ${action.type}`, {
6548
6580
  actionId: action.id,
@@ -6576,6 +6608,9 @@ function useAuthorizationOrchestrator(deps) {
6576
6608
  const probedIds = action.type === "APPROVE_PERMIT2" ? approvePermit2ProbedIds : action.type === "EXECUTE_BRIDGE" ? executeBridgeProbedIds : null;
6577
6609
  if (probedIds && !probedIds.has(action.id)) {
6578
6610
  probedIds.add(action.id);
6611
+ if (action.type === "APPROVE_PERMIT2") {
6612
+ submittedApprovePermit2ActionIdsRef.current.add(action.id);
6613
+ }
6579
6614
  appendDebug("warn", `${action.type}: client error with nonce advancement, probing on-chain`, {
6580
6615
  actionId: action.id,
6581
6616
  ownerSessionId,
@@ -6616,6 +6651,9 @@ function useAuthorizationOrchestrator(deps) {
6616
6651
  status: probe.status,
6617
6652
  code: probe.code
6618
6653
  });
6654
+ if (action.type === "APPROVE_PERMIT2" && probe.reason === "not-found") {
6655
+ throw new Error(APPROVE_PERMIT2_CONFIRMING_MESSAGE);
6656
+ }
6619
6657
  }
6620
6658
  }
6621
6659
  if (result.status === "error" && action.type === "EXECUTE_BRIDGE" && result.message === EXECUTE_BRIDGE_TX_TIMEOUT_MESSAGE && !executeBridgeProbedIds.has(action.id)) {
@@ -6677,6 +6715,12 @@ function useAuthorizationOrchestrator(deps) {
6677
6715
  completedIds.add(action.id);
6678
6716
  oneTapCompletedActionIds.delete(action.id);
6679
6717
  authExecutor.addResult(result);
6718
+ if (isSubmittedApprovePermit2Result(action, result)) {
6719
+ submittedApprovePermit2ActionIdsRef.current.add(action.id);
6720
+ }
6721
+ if (isSubmittedSignPermit2Result(action, result)) {
6722
+ submittedSignPermit2ActionIdsRef.current.add(action.id);
6723
+ }
6680
6724
  const reportedSession = await reportActionCompletionWithLogging(
6681
6725
  apiBaseUrl,
6682
6726
  action,
@@ -6764,6 +6808,25 @@ function createSelectSourceResult(action, selection) {
6764
6808
  }
6765
6809
  };
6766
6810
  }
6811
+ function isSubmittedApprovePermit2Result(action, result) {
6812
+ if (action.type !== "APPROVE_PERMIT2" || result.status !== "success") {
6813
+ return false;
6814
+ }
6815
+ if (!result.data || typeof result.data !== "object") {
6816
+ return false;
6817
+ }
6818
+ return typeof result.data.txHash === "string";
6819
+ }
6820
+ function isSubmittedSignPermit2Result(action, result) {
6821
+ if (action.type !== "SIGN_PERMIT2" || result.status !== "success") {
6822
+ return false;
6823
+ }
6824
+ if (!result.data || typeof result.data !== "object") {
6825
+ return false;
6826
+ }
6827
+ const data = result.data;
6828
+ return typeof data.signature === "string" || data.batchApprove === true;
6829
+ }
6767
6830
  function getLeadingBatchableActions(mergedPending) {
6768
6831
  const firstAction = mergedPending[0];
6769
6832
  if (!firstAction || !isBatchableAction(firstAction)) {
@@ -7131,6 +7194,9 @@ function resolveStickyPhase(state) {
7131
7194
  if (currentPhase.step === "manual-transfer" && !state.loginRequested) {
7132
7195
  return currentPhase;
7133
7196
  }
7197
+ if (currentPhase.step === "deposit-options" && !state.loginRequested) {
7198
+ return currentPhase;
7199
+ }
7134
7200
  if (!state.loginRequested && state.setupFlowScreen === "one-tap-setup") {
7135
7201
  return { step: "one-tap-setup", action: null };
7136
7202
  }
@@ -7648,6 +7714,8 @@ function applyAction(state, action) {
7648
7714
  pendingTransferId: null,
7649
7715
  creatingTransfer: false
7650
7716
  };
7717
+ case "CANCEL_LOGIN_REQUEST":
7718
+ return { ...state, loginRequested: false, error: null };
7651
7719
  case "SET_ERROR":
7652
7720
  return { ...state, error: action.error };
7653
7721
  case "AMOUNT_TOO_LOW":
@@ -7829,10 +7897,10 @@ function planConfirmSetupDeposit(input) {
7829
7897
  };
7830
7898
  }
7831
7899
  function ScreenLayout({ children, footer }) {
7832
- const { tokens, theme } = useBlinkConfig();
7900
+ const { tokens, theme, isMobileApp } = useBlinkConfig();
7833
7901
  const isRedesign = theme.endsWith("New");
7834
7902
  const useAccentWash = !isRedesign;
7835
- const sheetRadius = isRedesign ? tokens.radiusLg : void 0;
7903
+ const sheetRadius = isRedesign && !isMobileApp ? tokens.radiusLg : void 0;
7836
7904
  const sheetClass = sheetRadius ? "blink-screen-sheet blink-screen-sheet--responsive-radius" : "blink-screen-sheet";
7837
7905
  return /* @__PURE__ */ jsxs("div", { className: sheetClass, style: containerStyle(tokens.bgCard, useAccentWash, sheetRadius, tokens.fontFamily), children: [
7838
7906
  sheetRadius && /* @__PURE__ */ jsx("style", { children: responsiveRadiusCss }),
@@ -9236,7 +9304,7 @@ var labelStyle4 = (color, disabled) => ({
9236
9304
  var rightSlotStyle2 = {
9237
9305
  display: "inline-flex",
9238
9306
  alignItems: "center",
9239
- justifyContent: "center",
9307
+ justifyContent: "flex-end",
9240
9308
  minWidth: 40,
9241
9309
  minHeight: 40,
9242
9310
  flexShrink: 0,
@@ -9536,9 +9604,9 @@ function LoginScreen({
9536
9604
  const { tokens } = useBlinkConfig();
9537
9605
  const heading = heroTitle ?? "Deposit instantly\nwith Blink";
9538
9606
  const primaryAction = preferSignup ? onLoginWithPasskey : onSignupWithPasskey;
9539
- const primaryLabel = preferSignup ? "I already have a Blink Passkey" : "Create a Passkey";
9607
+ const primaryLabel = preferSignup ? "Sign in with Blink" : "Create a Passkey";
9540
9608
  const secondaryAction = preferSignup ? onSignupWithPasskey : onLoginWithPasskey;
9541
- const secondaryLabel = preferSignup ? " Create a Passkey" : "I already have a Blink Passkey";
9609
+ const secondaryLabel = preferSignup ? " Create a Passkey" : "Sign in with Blink";
9542
9610
  const headerRight = onClose ? /* @__PURE__ */ jsx(
9543
9611
  "button",
9544
9612
  {
@@ -9578,7 +9646,7 @@ function LoginScreen({
9578
9646
  /* @__PURE__ */ jsx(
9579
9647
  ScreenHeader,
9580
9648
  {
9581
- onBack: onClose ? void 0 : onBack,
9649
+ onBack,
9582
9650
  right: headerRight,
9583
9651
  left: /* @__PURE__ */ jsx(
9584
9652
  "img",
@@ -9734,9 +9802,13 @@ function DepositOptionsScreen({
9734
9802
  /* @__PURE__ */ jsx(
9735
9803
  SourceRow,
9736
9804
  {
9737
- name: "Wallet",
9805
+ name: "Connect Wallet",
9738
9806
  icon: /* @__PURE__ */ jsx(WalletIcon, { color: tokens.text }),
9739
- onClick: onFromWallet
9807
+ onClick: onFromWallet,
9808
+ right: /* @__PURE__ */ jsxs("span", { style: badgeWithArrowStyle, children: [
9809
+ /* @__PURE__ */ jsx(RecommendedBadge, { tokens }),
9810
+ /* @__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" }) })
9811
+ ] })
9740
9812
  }
9741
9813
  ),
9742
9814
  /* @__PURE__ */ jsx(
@@ -9764,38 +9836,14 @@ function DepositOptionsScreen({
9764
9836
  );
9765
9837
  }
9766
9838
  function DepositTypeToggle({ tokens }) {
9767
- return /* @__PURE__ */ jsxs(
9768
- "div",
9769
- {
9770
- role: "tablist",
9771
- "aria-label": "Deposit type",
9772
- "aria-disabled": "true",
9773
- style: toggleContainerStyle(tokens.bgRecessed),
9774
- children: [
9775
- /* @__PURE__ */ jsx(ToggleSegment, { selected: true, label: "Crypto", tokens }),
9776
- /* @__PURE__ */ jsx(ToggleSegment, { selected: false, label: "Cash", subLabel: "Coming soon", tokens })
9777
- ]
9778
- }
9779
- );
9780
- }
9781
- function ToggleSegment({ selected, label, subLabel, tokens }) {
9782
- return /* @__PURE__ */ jsxs(
9783
- "div",
9784
- {
9785
- role: "tab",
9786
- "aria-selected": selected,
9787
- "aria-disabled": "true",
9788
- style: toggleSegmentStyle(selected, tokens),
9789
- children: [
9790
- /* @__PURE__ */ jsx("span", { children: label }),
9791
- subLabel ? /* @__PURE__ */ jsx("span", { style: toggleSubLabelStyle, children: subLabel }) : null
9792
- ]
9793
- }
9794
- );
9839
+ return /* @__PURE__ */ jsx(Fragment, {});
9795
9840
  }
9796
9841
  function ComingSoonBadge({ tokens }) {
9797
9842
  return /* @__PURE__ */ jsx("span", { style: comingSoonBadgeStyle(tokens.bgRecessed, tokens.textMuted), children: "Coming soon" });
9798
9843
  }
9844
+ function RecommendedBadge({ tokens }) {
9845
+ return /* @__PURE__ */ jsx("span", { style: recommendedBadgeStyle(tokens.successBg, tokens.success), children: "Recommended" });
9846
+ }
9799
9847
  function WalletIcon({ color }) {
9800
9848
  return /* @__PURE__ */ jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
9801
9849
  /* @__PURE__ */ jsx(
@@ -9932,39 +9980,25 @@ var cardStyle = (bg) => ({
9932
9980
  borderRadius: 28,
9933
9981
  padding: "8px 8px 8px 20px"
9934
9982
  });
9935
- var toggleContainerStyle = (bg) => ({
9936
- display: "flex",
9937
- width: "100%",
9938
- background: bg,
9939
- borderRadius: 999,
9940
- padding: 4,
9941
- boxSizing: "border-box"
9942
- });
9943
- var toggleSegmentStyle = (selected, tokens) => ({
9944
- flex: 1,
9945
- display: "flex",
9946
- flexDirection: "column",
9983
+ var comingSoonBadgeStyle = (bg, color) => ({
9984
+ display: "inline-flex",
9947
9985
  alignItems: "center",
9948
9986
  justifyContent: "center",
9949
- textAlign: "center",
9950
- padding: "10px 16px",
9951
- borderRadius: 999,
9952
- fontSize: "0.95rem",
9953
- fontWeight: 600,
9954
- lineHeight: 1.15,
9955
- color: selected ? tokens.text : tokens.textMuted,
9956
- background: selected ? tokens.bg : "transparent",
9957
- boxShadow: selected ? tokens.shadow : "none",
9958
- cursor: "default",
9959
- userSelect: "none"
9960
- });
9961
- var toggleSubLabelStyle = {
9962
- fontSize: "0.7rem",
9987
+ background: bg,
9988
+ color,
9989
+ fontSize: 10,
9963
9990
  fontWeight: 500,
9964
- marginTop: 2,
9965
- opacity: 0.85
9991
+ lineHeight: 1,
9992
+ padding: "4px 8px",
9993
+ borderRadius: 8,
9994
+ marginRight: 8,
9995
+ whiteSpace: "nowrap"
9996
+ });
9997
+ var badgeWithArrowStyle = {
9998
+ display: "flex",
9999
+ alignItems: "center"
9966
10000
  };
9967
- var comingSoonBadgeStyle = (bg, color) => ({
10001
+ var recommendedBadgeStyle = (bg, color) => ({
9968
10002
  display: "inline-flex",
9969
10003
  alignItems: "center",
9970
10004
  justifyContent: "center",
@@ -9975,7 +10009,6 @@ var comingSoonBadgeStyle = (bg, color) => ({
9975
10009
  lineHeight: 1,
9976
10010
  padding: "4px 8px",
9977
10011
  borderRadius: 8,
9978
- marginRight: 8,
9979
10012
  whiteSpace: "nowrap"
9980
10013
  });
9981
10014
  var linkIconImageStyle = (color) => ({
@@ -10901,70 +10934,59 @@ function WalletPickerScreen({
10901
10934
  ),
10902
10935
  /* @__PURE__ */ jsx("h1", { style: titleStyle3(tokens.text), children: "Link wallet" }),
10903
10936
  error && /* @__PURE__ */ jsx("div", { style: errorBannerStyle5(tokens), children: error }),
10904
- /* @__PURE__ */ jsxs("div", { style: sheetStackStyle, children: [
10905
- /* @__PURE__ */ jsx("div", { style: cardStyle2(tokens.bgCardTranslucent), children: showOtherWallets ? /* @__PURE__ */ jsx(
10906
- OtherWalletsPanel,
10907
- {
10908
- wallets: filteredReownWallets,
10909
- loading: reownLoading,
10910
- error: reownError,
10911
- search: reownSearch,
10912
- onSearchChange: setReownSearch,
10913
- onRetry: () => {
10914
- setReownWallets([]);
10915
- setReownFetchAttempt((attempt) => attempt + 1);
10916
- },
10917
- onSelectWallet: (wallet) => {
10918
- void onSelectWalletConnectWallet(wallet);
10919
- }
10937
+ /* @__PURE__ */ jsx("div", { style: sheetStackStyle, children: /* @__PURE__ */ jsx("div", { style: cardStyle2(tokens.bgCardTranslucent), children: showOtherWallets ? /* @__PURE__ */ jsx(
10938
+ OtherWalletsPanel,
10939
+ {
10940
+ wallets: filteredReownWallets,
10941
+ loading: reownLoading,
10942
+ error: reownError,
10943
+ search: reownSearch,
10944
+ onSearchChange: setReownSearch,
10945
+ onRetry: () => {
10946
+ setReownWallets([]);
10947
+ setReownFetchAttempt((attempt) => attempt + 1);
10948
+ },
10949
+ onSelectWallet: (wallet) => {
10950
+ void onSelectWalletConnectWallet(wallet);
10920
10951
  }
10921
- ) : showWalletListSpinner ? /* @__PURE__ */ jsx("div", { style: spinnerRowStyle, children: /* @__PURE__ */ jsx(Spinner, { label: providersLoading ? "Loading wallets..." : "Preparing wallet links..." }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
10922
- visibleProviders.map((provider) => {
10923
- const logoSrc = "logoURI" in provider && provider.logoURI || KNOWN_LOGOS[provider.name.toLowerCase()];
10924
- const directPreparedSession = directPreparedSessions[provider.id];
10925
- const isRowPreparing = preparing && selectedProviderId === provider.id;
10926
- const rowLoader = isRowPreparing ? /* @__PURE__ */ jsx(Spinner, { size: 20 }) : void 0;
10927
- if (usesDirectLinkCards) {
10928
- if (directPreparedSession?.uri) {
10929
- const navigation = classifyWalletDeeplinkNavigation(directPreparedSession.uri);
10930
- const openWithJavaScript = shouldOpenWithJavaScript(navigation);
10931
- return /* @__PURE__ */ jsx(
10932
- SourceRow,
10933
- {
10934
- logo: logoSrc,
10935
- name: provider.name,
10936
- href: directPreparedSession.uri,
10937
- target: navigation.anchorTarget,
10938
- rel: navigation.anchorRel,
10939
- onClick: (e) => {
10940
- if (openWithJavaScript) {
10941
- e.preventDefault();
10942
- }
10943
- setSelectedProviderId(provider.id);
10944
- if (directPreparedSession.sessionId) {
10945
- void setAuthorizationSessionProvider(
10946
- apiBaseUrl,
10947
- directPreparedSession.sessionId,
10948
- provider.id
10949
- ).catch((err) => {
10950
- captureException(err);
10951
- });
10952
- }
10953
- if (openWithJavaScript) {
10954
- openDeeplink(directPreparedSession.uri);
10955
- }
10956
- void onSelectProvider(provider.id, directPreparedSession);
10957
- }
10958
- },
10959
- provider.id
10960
- );
10961
- }
10952
+ }
10953
+ ) : showWalletListSpinner ? /* @__PURE__ */ jsx("div", { style: spinnerRowStyle, children: /* @__PURE__ */ jsx(Spinner, { label: providersLoading ? "Loading wallets..." : "Preparing wallet links..." }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
10954
+ visibleProviders.map((provider) => {
10955
+ const logoSrc = "logoURI" in provider && provider.logoURI || KNOWN_LOGOS[provider.name.toLowerCase()];
10956
+ const directPreparedSession = directPreparedSessions[provider.id];
10957
+ const isRowPreparing = preparing && selectedProviderId === provider.id;
10958
+ const rowLoader = isRowPreparing ? /* @__PURE__ */ jsx(Spinner, { size: 20 }) : void 0;
10959
+ if (usesDirectLinkCards) {
10960
+ if (directPreparedSession?.uri) {
10961
+ const navigation = classifyWalletDeeplinkNavigation(directPreparedSession.uri);
10962
+ const openWithJavaScript = shouldOpenWithJavaScript(navigation);
10962
10963
  return /* @__PURE__ */ jsx(
10963
10964
  SourceRow,
10964
10965
  {
10965
10966
  logo: logoSrc,
10966
10967
  name: provider.name,
10967
- disabled: true
10968
+ href: directPreparedSession.uri,
10969
+ target: navigation.anchorTarget,
10970
+ rel: navigation.anchorRel,
10971
+ onClick: (e) => {
10972
+ if (openWithJavaScript) {
10973
+ e.preventDefault();
10974
+ }
10975
+ setSelectedProviderId(provider.id);
10976
+ if (directPreparedSession.sessionId) {
10977
+ void setAuthorizationSessionProvider(
10978
+ apiBaseUrl,
10979
+ directPreparedSession.sessionId,
10980
+ provider.id
10981
+ ).catch((err) => {
10982
+ captureException(err);
10983
+ });
10984
+ }
10985
+ if (openWithJavaScript) {
10986
+ openDeeplink(directPreparedSession.uri);
10987
+ }
10988
+ void onSelectProvider(provider.id, directPreparedSession);
10989
+ }
10968
10990
  },
10969
10991
  provider.id
10970
10992
  );
@@ -10974,36 +10996,35 @@ function WalletPickerScreen({
10974
10996
  {
10975
10997
  logo: logoSrc,
10976
10998
  name: provider.name,
10977
- right: rowLoader,
10978
- onClick: () => {
10979
- void handleRowSelect(provider.id);
10980
- }
10999
+ disabled: true
10981
11000
  },
10982
11001
  provider.id
10983
11002
  );
10984
- }),
10985
- /* @__PURE__ */ jsx(
11003
+ }
11004
+ return /* @__PURE__ */ jsx(
10986
11005
  SourceRow,
10987
11006
  {
10988
- name: "Other",
10989
- icon: /* @__PURE__ */ jsx(OtherWalletsIcon, { color: tokens.textMuted }),
11007
+ logo: logoSrc,
11008
+ name: provider.name,
11009
+ right: rowLoader,
10990
11010
  onClick: () => {
10991
- setShowOtherWallets(true);
11011
+ void handleRowSelect(provider.id);
10992
11012
  }
10993
- }
10994
- )
10995
- ] }) }),
10996
- /* @__PURE__ */ jsx("div", { style: disabledCardStyle(tokens.bgRecessed), children: /* @__PURE__ */ jsx(
11013
+ },
11014
+ provider.id
11015
+ );
11016
+ }),
11017
+ /* @__PURE__ */ jsx(
10997
11018
  SourceRow,
10998
11019
  {
10999
- disabled: true,
11000
- disabledColor: tokens.textTertiary,
11001
- name: "Bank account",
11002
- icon: /* @__PURE__ */ jsx(BankIcon, { color: tokens.textTertiary }),
11003
- right: /* @__PURE__ */ jsx("span", { style: comingSoonStyle(tokens.textTertiary), children: "Coming soon" })
11020
+ name: "Other",
11021
+ icon: /* @__PURE__ */ jsx(OtherWalletsIcon, {}),
11022
+ onClick: () => {
11023
+ setShowOtherWallets(true);
11024
+ }
11004
11025
  }
11005
- ) })
11006
- ] })
11026
+ )
11027
+ ] }) }) })
11007
11028
  ] });
11008
11029
  }
11009
11030
  function OtherWalletsPanel({
@@ -11072,77 +11093,29 @@ function ReownWalletLogo({ wallet }) {
11072
11093
  }
11073
11094
  );
11074
11095
  }
11075
- function OtherWalletsIcon({ color }) {
11076
- return /* @__PURE__ */ jsxs("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
11077
- /* @__PURE__ */ jsx(
11078
- "path",
11079
- {
11080
- d: "M7.5 9.5C10 7.2 14 7.2 16.5 9.5",
11081
- stroke: color,
11082
- strokeWidth: "1.8",
11083
- strokeLinecap: "round"
11084
- }
11085
- ),
11086
- /* @__PURE__ */ jsx(
11087
- "path",
11088
- {
11089
- d: "M4.5 6.5C8.7 2.9 15.3 2.9 19.5 6.5",
11090
- stroke: color,
11091
- strokeWidth: "1.8",
11092
- strokeLinecap: "round"
11093
- }
11094
- ),
11095
- /* @__PURE__ */ jsx(
11096
- "path",
11097
- {
11098
- d: "M10 12.5C11.1 11.7 12.9 11.7 14 12.5",
11099
- stroke: color,
11100
- strokeWidth: "1.8",
11101
- strokeLinecap: "round"
11102
- }
11103
- ),
11104
- /* @__PURE__ */ jsx(
11105
- "path",
11106
- {
11107
- d: "M12 16H12.01",
11108
- stroke: color,
11109
- strokeWidth: "2.4",
11110
- strokeLinecap: "round"
11111
- }
11112
- )
11113
- ] });
11114
- }
11115
- function BankIcon({ color }) {
11116
- return /* @__PURE__ */ jsxs("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
11117
- /* @__PURE__ */ jsx(
11118
- "path",
11119
- {
11120
- d: "M3 10L12 4L21 10",
11121
- stroke: color,
11122
- strokeWidth: "1.8",
11123
- strokeLinecap: "round",
11124
- strokeLinejoin: "round"
11125
- }
11126
- ),
11127
- /* @__PURE__ */ jsx(
11128
- "path",
11129
- {
11130
- d: "M5 10V18M9 10V18M15 10V18M19 10V18",
11131
- stroke: color,
11132
- strokeWidth: "1.8",
11133
- strokeLinecap: "round"
11134
- }
11135
- ),
11136
- /* @__PURE__ */ jsx(
11137
- "path",
11138
- {
11139
- d: "M3 20H21",
11140
- stroke: color,
11141
- strokeWidth: "1.8",
11142
- strokeLinecap: "round"
11143
- }
11144
- )
11145
- ] });
11096
+ function OtherWalletsIcon() {
11097
+ return /* @__PURE__ */ jsxs(
11098
+ "svg",
11099
+ {
11100
+ width: "34",
11101
+ height: "34",
11102
+ viewBox: "0 0 400 400",
11103
+ fill: "none",
11104
+ xmlns: "http://www.w3.org/2000/svg",
11105
+ "aria-hidden": "true",
11106
+ style: { borderRadius: "50%" },
11107
+ children: [
11108
+ /* @__PURE__ */ jsx("circle", { cx: "200", cy: "200", fill: "#3396ff", r: "199.5", stroke: "#66b1ff" }),
11109
+ /* @__PURE__ */ jsx(
11110
+ "path",
11111
+ {
11112
+ d: "m122.519 148.965c42.791-41.729 112.171-41.729 154.962 0l5.15 5.022c2.14 2.086 2.14 5.469 0 7.555l-17.617 17.18c-1.07 1.043-2.804 1.043-3.874 0l-7.087-6.911c-29.853-29.111-78.253-29.111-108.106 0l-7.59 7.401c-1.07 1.043-2.804 1.043-3.874 0l-17.617-17.18c-2.14-2.086-2.14-5.469 0-7.555zm191.397 35.529 15.679 15.29c2.14 2.086 2.14 5.469 0 7.555l-70.7 68.944c-2.139 2.087-5.608 2.087-7.748 0l-50.178-48.931c-.535-.522-1.402-.522-1.937 0l-50.178 48.931c-2.139 2.087-5.608 2.087-7.748 0l-70.7015-68.945c-2.1396-2.086-2.1396-5.469 0-7.555l15.6795-15.29c2.1396-2.086 5.6085-2.086 7.7481 0l50.1789 48.932c.535.522 1.402.522 1.937 0l50.177-48.932c2.139-2.087 5.608-2.087 7.748 0l50.179 48.932c.535.522 1.402.522 1.937 0l50.179-48.931c2.139-2.087 5.608-2.087 7.748 0z",
11113
+ fill: "#fff"
11114
+ }
11115
+ )
11116
+ ]
11117
+ }
11118
+ );
11146
11119
  }
11147
11120
  function isAbortError(err) {
11148
11121
  return err instanceof DOMException && err.name === "AbortError";
@@ -11191,19 +11164,6 @@ var cardStyle2 = (bg) => ({
11191
11164
  borderRadius: 28,
11192
11165
  padding: "8px 8px 8px 20px"
11193
11166
  });
11194
- var disabledCardStyle = (bg) => ({
11195
- display: "flex",
11196
- flexDirection: "column",
11197
- background: bg,
11198
- borderRadius: 28,
11199
- padding: "8px 8px 8px 20px"
11200
- });
11201
- var comingSoonStyle = (color) => ({
11202
- fontSize: "1rem",
11203
- color,
11204
- paddingRight: 8,
11205
- whiteSpace: "nowrap"
11206
- });
11207
11167
  var spinnerRowStyle = {
11208
11168
  display: "flex",
11209
11169
  alignItems: "center",
@@ -12324,13 +12284,14 @@ function DepositScreen({
12324
12284
  (opt) => opt.balance == null || isSelectableDepositSourceAmountUsd(opt.balance, minDepositFloor)
12325
12285
  ) ?? [];
12326
12286
  const hasTokenDropdown = selectableTokenOptions.length > 0 && onPickToken != null;
12287
+ const canOpenInlineSheet = onPickToken != null && (hasTokenDropdown || (accounts?.length ?? 0) > 0);
12327
12288
  const handleOpenSourceSheet = useCallback(() => {
12328
- if (hasTokenDropdown) {
12289
+ if (canOpenInlineSheet) {
12329
12290
  setTokenPickerOpen((v) => !v);
12330
12291
  } else {
12331
12292
  onSelectToken?.();
12332
12293
  }
12333
- }, [hasTokenDropdown, onSelectToken]);
12294
+ }, [canOpenInlineSheet, onSelectToken]);
12334
12295
  const handleCloseSourceSheet = useCallback(() => {
12335
12296
  setTokenPickerOpen(false);
12336
12297
  }, []);
@@ -12342,9 +12303,9 @@ function DepositScreen({
12342
12303
  const exceedsLimit = remainingLimit != null && amount > remainingLimit && !isLowBalance && !needsAuthorization;
12343
12304
  const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !insufficientFunds && !needsAuthorization && !processing;
12344
12305
  const hasAccountPill = !!accounts && accounts.length > 0;
12345
- const pillClickable = hasTokenDropdown || !!onSelectToken;
12306
+ const pillClickable = canOpenInlineSheet || !!onSelectToken;
12346
12307
  const tokenAriaLabel = selectedTokenSymbol && selectedChainName ? `Selected token: ${selectedTokenSymbol} on ${selectedChainName}` : selectedTokenSymbol ? `Selected token: ${selectedTokenSymbol}` : "Select token";
12347
- if (tokenPickerOpen && hasTokenDropdown) {
12308
+ if (tokenPickerOpen && canOpenInlineSheet) {
12348
12309
  const depositSourceAccounts = (accounts ?? []).map((a) => {
12349
12310
  const preferred = getPreferredDepositWallet(a, amount);
12350
12311
  return {
@@ -12405,8 +12366,8 @@ function DepositScreen({
12405
12366
  onClick: handleOpenSourceSheet,
12406
12367
  style: redesignPillButtonStyle(pillClickable),
12407
12368
  "aria-label": tokenAriaLabel,
12408
- "aria-expanded": hasTokenDropdown ? tokenPickerOpen : void 0,
12409
- "aria-haspopup": hasTokenDropdown ? "listbox" : void 0,
12369
+ "aria-expanded": canOpenInlineSheet ? tokenPickerOpen : void 0,
12370
+ "aria-haspopup": canOpenInlineSheet ? "listbox" : void 0,
12410
12371
  children: /* @__PURE__ */ jsx(
12411
12372
  SourcePill,
12412
12373
  {
@@ -12519,8 +12480,8 @@ function SuccessScreen({
12519
12480
  onLogout,
12520
12481
  returnMessage
12521
12482
  }) {
12522
- const { tokens } = useBlinkConfig();
12523
- const headerRight = succeeded && onDone ? /* @__PURE__ */ jsx(
12483
+ const { tokens, isMobileApp } = useBlinkConfig();
12484
+ const headerRight = succeeded && onDone && !isMobileApp ? /* @__PURE__ */ jsx(
12524
12485
  "button",
12525
12486
  {
12526
12487
  type: "button",
@@ -12721,7 +12682,7 @@ function SelectSourceScreen({
12721
12682
  /* @__PURE__ */ jsxs("div", { style: optionContentStyle, children: [
12722
12683
  /* @__PURE__ */ jsxs("span", { style: optionNameStyle(tokens.text), children: [
12723
12684
  chain.chainName,
12724
- isRecommended && /* @__PURE__ */ jsx("span", { style: recommendedBadgeStyle(tokens.textMuted), children: " recommended" })
12685
+ isRecommended && /* @__PURE__ */ jsx("span", { style: recommendedBadgeStyle2(tokens.textMuted), children: " recommended" })
12725
12686
  ] }),
12726
12687
  /* @__PURE__ */ jsxs("span", { style: optionBalanceStyle(tokens.textMuted), children: [
12727
12688
  "$",
@@ -12817,7 +12778,7 @@ var optionNameStyle = (color) => ({
12817
12778
  fontWeight: 600,
12818
12779
  color
12819
12780
  });
12820
- var recommendedBadgeStyle = (color) => ({
12781
+ var recommendedBadgeStyle2 = (color) => ({
12821
12782
  fontSize: "0.7rem",
12822
12783
  fontWeight: 500,
12823
12784
  color,
@@ -15327,10 +15288,10 @@ function buildLoginScreenProps({ flow, handlers }) {
15327
15288
  onSignupWithPasskey: handlers.onSignupWithPasskey,
15328
15289
  loading: flow.passkeyLoading,
15329
15290
  error: flow.state.error,
15330
- // Login is the root screen, so "back" and "close" both dismiss the widget.
15331
- // Exposing onClose lets LoginScreen render the Figma-redesign top-right
15332
- // (X) button instead of the legacy back arrow.
15333
- onClose: flow.onBack,
15291
+ // Inside a native mobile in-app browser the host's chrome handles
15292
+ // dismissal, so suppress the in-screen (X) close button.
15293
+ onClose: flow.isMobileApp ? void 0 : flow.onBack,
15294
+ onBack: flow.state.enableFullWidget ? handlers.onCancelLogin : void 0,
15334
15295
  merchantInitials: flow.merchantName ? flow.merchantName.slice(0, 2).toUpperCase() : void 0
15335
15296
  };
15336
15297
  }
@@ -15345,8 +15306,9 @@ function buildDepositOptionsScreenProps({ flow, handlers }) {
15345
15306
  // Deposit-options is the root screen for the full-widget flow, so the
15346
15307
  // top-right (X) closes the widget through the same `onBack` the host
15347
15308
  // provides. Falling back to `undefined` hides the close button when the
15348
- // host did not pass an onBack (matches LoginScreen behavior).
15349
- onClose: flow.onBack
15309
+ // host did not pass an onBack (matches LoginScreen behavior). Inside a
15310
+ // native mobile in-app browser the host chrome handles dismissal.
15311
+ onClose: flow.isMobileApp ? void 0 : flow.onBack
15350
15312
  };
15351
15313
  }
15352
15314
  function buildPasskeyReadyScreenProps({ handlers }) {
@@ -15584,7 +15546,7 @@ function buildDepositScreenProps({
15584
15546
  error: state.error,
15585
15547
  onDeposit: handlers.onPay,
15586
15548
  onSwitchWallet: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
15587
- onBack: onBack ?? (() => handlers.onLogout()),
15549
+ onBack: state.enableFullWidget ? () => handlers.onSetPhase({ step: "deposit-options" }) : onBack ?? (() => handlers.onLogout()),
15588
15550
  onLogout: handlers.onLogout,
15589
15551
  onIncreaseLimit: handlers.onIncreaseLimit,
15590
15552
  increasingLimit: state.increasingLimit,
@@ -15597,7 +15559,7 @@ function buildDepositScreenProps({
15597
15559
  // the inline sheet can't render). Hosts with sources get the inline
15598
15560
  // SelectDepositSourceScreen via onPickToken below.
15599
15561
  onSelectToken: handlers.onSelectToken,
15600
- tokenOptions: depositTokenOptions.length > 0 ? depositTokenOptions : void 0,
15562
+ tokenOptions: depositTokenOptions,
15601
15563
  useDeeplink: !flow.isDesktop,
15602
15564
  onPickToken: (symbol, chainName, walletId) => {
15603
15565
  const match = depositTokenOptions.find(
@@ -15751,13 +15713,15 @@ function buildAmountTooLowScreenProps({
15751
15713
  flow,
15752
15714
  handlers
15753
15715
  }) {
15754
- const { state, onDismiss } = flow;
15716
+ const { state, onDismiss, isMobileApp } = flow;
15755
15717
  const minAmountUsd = state.phase.step === "amount-too-low" ? state.phase.minAmountUsd : state.amountTooLow?.minAmountUsd ?? flow.minTransferAmountUsd;
15756
15718
  const canRetry = flow.depositAmount == null;
15757
15719
  return {
15758
15720
  minAmountUsd,
15759
15721
  onRetry: canRetry ? handlers.onNewPayment : void 0,
15760
- onClose: onDismiss
15722
+ // Inside a native mobile in-app browser the host's chrome handles
15723
+ // dismissal, so suppress the in-screen (X) close button.
15724
+ onClose: isMobileApp ? void 0 : onDismiss
15761
15725
  };
15762
15726
  }
15763
15727
  function StepRenderer(props) {
@@ -18924,7 +18888,7 @@ function BlinkPaymentInner({
18924
18888
  onBack,
18925
18889
  onDismiss
18926
18890
  }) {
18927
- const { apiBaseUrl, depositAmount, minTransferAmountUsd, enableFullWidget } = useBlinkConfig();
18891
+ const { apiBaseUrl, depositAmount, minTransferAmountUsd, enableFullWidget, isMobileApp } = useBlinkConfig();
18928
18892
  const { ready, authenticated, logout, getAccessToken } = usePrivy();
18929
18893
  const popupAuthRef = useRef(loadPopupAuth());
18930
18894
  const popupAuthValid = (() => {
@@ -19436,6 +19400,11 @@ function BlinkPaymentInner({
19436
19400
  onNewPayment: handleNewPayment,
19437
19401
  onSetPhase: (phase) => {
19438
19402
  clearScreenErrors();
19403
+ if (phase.step === "deposit") {
19404
+ dispatch({ type: "SET_SETUP_DEPOSIT_AMOUNT", amount: null });
19405
+ dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
19406
+ dispatch({ type: "SET_SETUP_FLOW_SCREEN", screen: null });
19407
+ }
19439
19408
  dispatch({ type: "SET_USER_INTENT", intent: phase });
19440
19409
  },
19441
19410
  onAddProviderFromDeposit: (amount) => {
@@ -19449,6 +19418,11 @@ function BlinkPaymentInner({
19449
19418
  authExecutor.cancelPendingExecution();
19450
19419
  clearScreenErrors();
19451
19420
  dispatch({ type: "RESTORE_SELECTION" });
19421
+ dispatch({ type: "SET_SETUP_DEPOSIT_AMOUNT", amount: null });
19422
+ dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
19423
+ dispatch({ type: "SET_SETUP_FLOW_SCREEN", screen: null });
19424
+ dispatch({ type: "DESKTOP_WAIT_CLEARED" });
19425
+ dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: false });
19452
19426
  dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
19453
19427
  },
19454
19428
  onSelectSourceChainChange: sourceSelection.handleSelectSourceChainChange,
@@ -19461,6 +19435,7 @@ function BlinkPaymentInner({
19461
19435
  onPrepareTokenAuthorization: provider.handlePrepareTokenAuthorization,
19462
19436
  onCommitTokenAuthorization: provider.handleCommitTokenAuthorization,
19463
19437
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
19438
+ onCancelLogin: () => dispatch({ type: "CANCEL_LOGIN_REQUEST" }),
19464
19439
  onSetDepositAmount: handleSetDepositAmount,
19465
19440
  onSetDepositToken: handleSetDepositToken,
19466
19441
  onConfirmSetupDeposit: handleConfirmSetupDeposit
@@ -19492,6 +19467,7 @@ function BlinkPaymentInner({
19492
19467
  authenticated: effectiveAuthenticated,
19493
19468
  passkeyLoading: auth.passkeyLoginStatus !== "initial" && auth.passkeyLoginStatus !== "done" && auth.passkeyLoginStatus !== "error" || auth.passkeySignupStatus !== "initial" && auth.passkeySignupStatus !== "done" && auth.passkeySignupStatus !== "error" || auth.passkeySignupPopupActive,
19494
19469
  isDesktop,
19470
+ isMobileApp: isMobileApp ?? false,
19495
19471
  merchantName,
19496
19472
  onBack,
19497
19473
  onDismiss,