@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.cjs CHANGED
@@ -1064,6 +1064,7 @@ function BlinkProvider({
1064
1064
  privyAppId,
1065
1065
  minTransferAmountUsd,
1066
1066
  enableFullWidget = false,
1067
+ isMobileApp = false,
1067
1068
  children
1068
1069
  }) {
1069
1070
  const queryClientRef = react.useRef(null);
@@ -1102,9 +1103,10 @@ function BlinkProvider({
1102
1103
  minTransferAmountUsd: resolvedMinTransferAmountUsd,
1103
1104
  depositAmount,
1104
1105
  setDepositAmount,
1105
- enableFullWidget
1106
+ enableFullWidget,
1107
+ isMobileApp
1106
1108
  }),
1107
- [apiBaseUrl, theme, resolvedMinTransferAmountUsd, depositAmount, setDepositAmount, enableFullWidget]
1109
+ [apiBaseUrl, theme, resolvedMinTransferAmountUsd, depositAmount, setDepositAmount, enableFullWidget, isMobileApp]
1108
1110
  );
1109
1111
  return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClientRef.current, children: /* @__PURE__ */ jsxRuntime.jsx(wagmi.WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: /* @__PURE__ */ jsxRuntime.jsx(
1110
1112
  reactAuth.PrivyProvider,
@@ -2161,7 +2163,19 @@ async function getWalletCapabilities(walletClient, address, chainId) {
2161
2163
  params: chainScopedParams ?? legacyParams
2162
2164
  });
2163
2165
  if (result && typeof result === "object" && !Array.isArray(result)) {
2164
- return result;
2166
+ const caps = result;
2167
+ const hexKey = chainId != null ? `0x${chainId.toString(16)}` : null;
2168
+ const chainMissing = chainScopedParams && hexKey && !caps[hexKey] && !caps[String(chainId)];
2169
+ if (chainMissing) {
2170
+ const legacyResult = await walletClient.request({
2171
+ method: "wallet_getCapabilities",
2172
+ params: legacyParams
2173
+ });
2174
+ if (legacyResult && typeof legacyResult === "object" && !Array.isArray(legacyResult)) {
2175
+ return legacyResult;
2176
+ }
2177
+ }
2178
+ return caps;
2165
2179
  }
2166
2180
  return {};
2167
2181
  } catch (err) {
@@ -6065,6 +6079,8 @@ var ACTION_POLL_INTERVAL_MS2 = 500;
6065
6079
  var ACTION_POLL_MAX_RETRIES2 = 20;
6066
6080
  var REPORT_COMPLETION_TIMEOUT_MS = 9e4;
6067
6081
  var REPORT_COMPLETION_TIMEOUT_MESSAGE = "REPORT_COMPLETION_TIMEOUT";
6082
+ 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.";
6083
+ 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.";
6068
6084
  function useAuthorizationOrchestrator(deps) {
6069
6085
  const blinkConfig = useOptionalBlinkConfig();
6070
6086
  const resolvedApiBaseUrl = deps.apiBaseUrl ?? blinkConfig?.apiBaseUrl;
@@ -6078,6 +6094,8 @@ function useAuthorizationOrchestrator(deps) {
6078
6094
  const selectSourceRejectRef = react.useRef(null);
6079
6095
  const oneTapResolverRef = react.useRef(null);
6080
6096
  const oneTapRejectRef = react.useRef(null);
6097
+ const submittedApprovePermit2ActionIdsRef = react.useRef(/* @__PURE__ */ new Set());
6098
+ const submittedSignPermit2ActionIdsRef = react.useRef(/* @__PURE__ */ new Set());
6081
6099
  const oneTapPauseRequestedRef = react.useRef(false);
6082
6100
  const addSession = react.useCallback((sessionId) => {
6083
6101
  pendingSessionIdsRef.current.push(sessionId);
@@ -6500,6 +6518,12 @@ function useAuthorizationOrchestrator(deps) {
6500
6518
  completedIds.add(batchedAction.id);
6501
6519
  oneTapCompletedActionIds.delete(batchedAction.id);
6502
6520
  authExecutor.addResult(result2);
6521
+ if (isSubmittedApprovePermit2Result(batchedAction, result2)) {
6522
+ submittedApprovePermit2ActionIdsRef.current.add(batchedAction.id);
6523
+ }
6524
+ if (isSubmittedSignPermit2Result(batchedAction, result2)) {
6525
+ submittedSignPermit2ActionIdsRef.current.add(batchedAction.id);
6526
+ }
6503
6527
  const batchedOwnerSessionId = actionSessionMap.get(batchedAction.id) ?? ownerSessionId;
6504
6528
  const reportedSession2 = await reportActionCompletionWithLogging(
6505
6529
  apiBaseUrl,
@@ -6527,7 +6551,9 @@ function useAuthorizationOrchestrator(deps) {
6527
6551
  continue;
6528
6552
  }
6529
6553
  }
6530
- const isPrePromptProbableActionType = action.type === "SIGN_PERMIT2" || action.type === "APPROVE_PERMIT2" || action.type === "APPROVE_SPL";
6554
+ const approvePermit2WasSubmitted = action.type === "APPROVE_PERMIT2" && submittedApprovePermit2ActionIdsRef.current.has(action.id);
6555
+ const signPermit2WasSubmitted = action.type === "SIGN_PERMIT2" && submittedSignPermit2ActionIdsRef.current.has(action.id);
6556
+ const isPrePromptProbableActionType = action.type === "SIGN_PERMIT2" || action.type === "APPROVE_SPL" || approvePermit2WasSubmitted;
6531
6557
  if (isPrePromptProbableActionType && probeBeforePrompt && !preProbedIds.has(action.id)) {
6532
6558
  preProbedIds.add(action.id);
6533
6559
  appendDebug("info", `${action.type}: pre-prompt probe start`, {
@@ -6560,13 +6586,19 @@ function useAuthorizationOrchestrator(deps) {
6560
6586
  });
6561
6587
  continue;
6562
6588
  }
6563
- appendDebug("info", `${action.type}: pre-prompt probe did not detect; presenting wallet`, {
6589
+ appendDebug("info", approvePermit2WasSubmitted || signPermit2WasSubmitted ? `${action.type}: submitted action not detected yet; waiting for confirmation` : `${action.type}: pre-prompt probe did not detect; presenting wallet`, {
6564
6590
  actionId: action.id,
6565
6591
  ownerSessionId,
6566
6592
  reason: probe.reason,
6567
6593
  status: probe.status,
6568
6594
  code: probe.code
6569
6595
  });
6596
+ if (approvePermit2WasSubmitted) {
6597
+ throw new Error(APPROVE_PERMIT2_CONFIRMING_MESSAGE);
6598
+ }
6599
+ if (signPermit2WasSubmitted) {
6600
+ throw new Error(SIGN_PERMIT2_CONFIRMING_MESSAGE);
6601
+ }
6570
6602
  }
6571
6603
  appendDebug("info", `orchestrator:executeAction start ${action.type}`, {
6572
6604
  actionId: action.id,
@@ -6600,6 +6632,9 @@ function useAuthorizationOrchestrator(deps) {
6600
6632
  const probedIds = action.type === "APPROVE_PERMIT2" ? approvePermit2ProbedIds : action.type === "EXECUTE_BRIDGE" ? executeBridgeProbedIds : null;
6601
6633
  if (probedIds && !probedIds.has(action.id)) {
6602
6634
  probedIds.add(action.id);
6635
+ if (action.type === "APPROVE_PERMIT2") {
6636
+ submittedApprovePermit2ActionIdsRef.current.add(action.id);
6637
+ }
6603
6638
  appendDebug("warn", `${action.type}: client error with nonce advancement, probing on-chain`, {
6604
6639
  actionId: action.id,
6605
6640
  ownerSessionId,
@@ -6640,6 +6675,9 @@ function useAuthorizationOrchestrator(deps) {
6640
6675
  status: probe.status,
6641
6676
  code: probe.code
6642
6677
  });
6678
+ if (action.type === "APPROVE_PERMIT2" && probe.reason === "not-found") {
6679
+ throw new Error(APPROVE_PERMIT2_CONFIRMING_MESSAGE);
6680
+ }
6643
6681
  }
6644
6682
  }
6645
6683
  if (result.status === "error" && action.type === "EXECUTE_BRIDGE" && result.message === EXECUTE_BRIDGE_TX_TIMEOUT_MESSAGE && !executeBridgeProbedIds.has(action.id)) {
@@ -6701,6 +6739,12 @@ function useAuthorizationOrchestrator(deps) {
6701
6739
  completedIds.add(action.id);
6702
6740
  oneTapCompletedActionIds.delete(action.id);
6703
6741
  authExecutor.addResult(result);
6742
+ if (isSubmittedApprovePermit2Result(action, result)) {
6743
+ submittedApprovePermit2ActionIdsRef.current.add(action.id);
6744
+ }
6745
+ if (isSubmittedSignPermit2Result(action, result)) {
6746
+ submittedSignPermit2ActionIdsRef.current.add(action.id);
6747
+ }
6704
6748
  const reportedSession = await reportActionCompletionWithLogging(
6705
6749
  apiBaseUrl,
6706
6750
  action,
@@ -6788,6 +6832,25 @@ function createSelectSourceResult(action, selection) {
6788
6832
  }
6789
6833
  };
6790
6834
  }
6835
+ function isSubmittedApprovePermit2Result(action, result) {
6836
+ if (action.type !== "APPROVE_PERMIT2" || result.status !== "success") {
6837
+ return false;
6838
+ }
6839
+ if (!result.data || typeof result.data !== "object") {
6840
+ return false;
6841
+ }
6842
+ return typeof result.data.txHash === "string";
6843
+ }
6844
+ function isSubmittedSignPermit2Result(action, result) {
6845
+ if (action.type !== "SIGN_PERMIT2" || result.status !== "success") {
6846
+ return false;
6847
+ }
6848
+ if (!result.data || typeof result.data !== "object") {
6849
+ return false;
6850
+ }
6851
+ const data = result.data;
6852
+ return typeof data.signature === "string" || data.batchApprove === true;
6853
+ }
6791
6854
  function getLeadingBatchableActions(mergedPending) {
6792
6855
  const firstAction = mergedPending[0];
6793
6856
  if (!firstAction || !isBatchableAction(firstAction)) {
@@ -7155,6 +7218,9 @@ function resolveStickyPhase(state) {
7155
7218
  if (currentPhase.step === "manual-transfer" && !state.loginRequested) {
7156
7219
  return currentPhase;
7157
7220
  }
7221
+ if (currentPhase.step === "deposit-options" && !state.loginRequested) {
7222
+ return currentPhase;
7223
+ }
7158
7224
  if (!state.loginRequested && state.setupFlowScreen === "one-tap-setup") {
7159
7225
  return { step: "one-tap-setup", action: null };
7160
7226
  }
@@ -7672,6 +7738,8 @@ function applyAction(state, action) {
7672
7738
  pendingTransferId: null,
7673
7739
  creatingTransfer: false
7674
7740
  };
7741
+ case "CANCEL_LOGIN_REQUEST":
7742
+ return { ...state, loginRequested: false, error: null };
7675
7743
  case "SET_ERROR":
7676
7744
  return { ...state, error: action.error };
7677
7745
  case "AMOUNT_TOO_LOW":
@@ -7853,10 +7921,10 @@ function planConfirmSetupDeposit(input) {
7853
7921
  };
7854
7922
  }
7855
7923
  function ScreenLayout({ children, footer }) {
7856
- const { tokens, theme } = useBlinkConfig();
7924
+ const { tokens, theme, isMobileApp } = useBlinkConfig();
7857
7925
  const isRedesign = theme.endsWith("New");
7858
7926
  const useAccentWash = !isRedesign;
7859
- const sheetRadius = isRedesign ? tokens.radiusLg : void 0;
7927
+ const sheetRadius = isRedesign && !isMobileApp ? tokens.radiusLg : void 0;
7860
7928
  const sheetClass = sheetRadius ? "blink-screen-sheet blink-screen-sheet--responsive-radius" : "blink-screen-sheet";
7861
7929
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: sheetClass, style: containerStyle(tokens.bgCard, useAccentWash, sheetRadius, tokens.fontFamily), children: [
7862
7930
  sheetRadius && /* @__PURE__ */ jsxRuntime.jsx("style", { children: responsiveRadiusCss }),
@@ -9260,7 +9328,7 @@ var labelStyle4 = (color, disabled) => ({
9260
9328
  var rightSlotStyle2 = {
9261
9329
  display: "inline-flex",
9262
9330
  alignItems: "center",
9263
- justifyContent: "center",
9331
+ justifyContent: "flex-end",
9264
9332
  minWidth: 40,
9265
9333
  minHeight: 40,
9266
9334
  flexShrink: 0,
@@ -9560,9 +9628,9 @@ function LoginScreen({
9560
9628
  const { tokens } = useBlinkConfig();
9561
9629
  const heading = heroTitle ?? "Deposit instantly\nwith Blink";
9562
9630
  const primaryAction = preferSignup ? onLoginWithPasskey : onSignupWithPasskey;
9563
- const primaryLabel = preferSignup ? "I already have a Blink Passkey" : "Create a Passkey";
9631
+ const primaryLabel = preferSignup ? "Sign in with Blink" : "Create a Passkey";
9564
9632
  const secondaryAction = preferSignup ? onSignupWithPasskey : onLoginWithPasskey;
9565
- const secondaryLabel = preferSignup ? " Create a Passkey" : "I already have a Blink Passkey";
9633
+ const secondaryLabel = preferSignup ? " Create a Passkey" : "Sign in with Blink";
9566
9634
  const headerRight = onClose ? /* @__PURE__ */ jsxRuntime.jsx(
9567
9635
  "button",
9568
9636
  {
@@ -9602,7 +9670,7 @@ function LoginScreen({
9602
9670
  /* @__PURE__ */ jsxRuntime.jsx(
9603
9671
  ScreenHeader,
9604
9672
  {
9605
- onBack: onClose ? void 0 : onBack,
9673
+ onBack,
9606
9674
  right: headerRight,
9607
9675
  left: /* @__PURE__ */ jsxRuntime.jsx(
9608
9676
  "img",
@@ -9758,9 +9826,13 @@ function DepositOptionsScreen({
9758
9826
  /* @__PURE__ */ jsxRuntime.jsx(
9759
9827
  SourceRow,
9760
9828
  {
9761
- name: "Wallet",
9829
+ name: "Connect Wallet",
9762
9830
  icon: /* @__PURE__ */ jsxRuntime.jsx(WalletIcon, { color: tokens.text }),
9763
- onClick: onFromWallet
9831
+ onClick: onFromWallet,
9832
+ right: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: badgeWithArrowStyle, children: [
9833
+ /* @__PURE__ */ jsxRuntime.jsx(RecommendedBadge, { tokens }),
9834
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 6l6 6-6 6", stroke: tokens.textMuted, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
9835
+ ] })
9764
9836
  }
9765
9837
  ),
9766
9838
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -9788,38 +9860,14 @@ function DepositOptionsScreen({
9788
9860
  );
9789
9861
  }
9790
9862
  function DepositTypeToggle({ tokens }) {
9791
- return /* @__PURE__ */ jsxRuntime.jsxs(
9792
- "div",
9793
- {
9794
- role: "tablist",
9795
- "aria-label": "Deposit type",
9796
- "aria-disabled": "true",
9797
- style: toggleContainerStyle(tokens.bgRecessed),
9798
- children: [
9799
- /* @__PURE__ */ jsxRuntime.jsx(ToggleSegment, { selected: true, label: "Crypto", tokens }),
9800
- /* @__PURE__ */ jsxRuntime.jsx(ToggleSegment, { selected: false, label: "Cash", subLabel: "Coming soon", tokens })
9801
- ]
9802
- }
9803
- );
9804
- }
9805
- function ToggleSegment({ selected, label, subLabel, tokens }) {
9806
- return /* @__PURE__ */ jsxRuntime.jsxs(
9807
- "div",
9808
- {
9809
- role: "tab",
9810
- "aria-selected": selected,
9811
- "aria-disabled": "true",
9812
- style: toggleSegmentStyle(selected, tokens),
9813
- children: [
9814
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
9815
- subLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: toggleSubLabelStyle, children: subLabel }) : null
9816
- ]
9817
- }
9818
- );
9863
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
9819
9864
  }
9820
9865
  function ComingSoonBadge({ tokens }) {
9821
9866
  return /* @__PURE__ */ jsxRuntime.jsx("span", { style: comingSoonBadgeStyle(tokens.bgRecessed, tokens.textMuted), children: "Coming soon" });
9822
9867
  }
9868
+ function RecommendedBadge({ tokens }) {
9869
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: recommendedBadgeStyle(tokens.successBg, tokens.success), children: "Recommended" });
9870
+ }
9823
9871
  function WalletIcon({ color }) {
9824
9872
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
9825
9873
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -9956,39 +10004,25 @@ var cardStyle = (bg) => ({
9956
10004
  borderRadius: 28,
9957
10005
  padding: "8px 8px 8px 20px"
9958
10006
  });
9959
- var toggleContainerStyle = (bg) => ({
9960
- display: "flex",
9961
- width: "100%",
9962
- background: bg,
9963
- borderRadius: 999,
9964
- padding: 4,
9965
- boxSizing: "border-box"
9966
- });
9967
- var toggleSegmentStyle = (selected, tokens) => ({
9968
- flex: 1,
9969
- display: "flex",
9970
- flexDirection: "column",
10007
+ var comingSoonBadgeStyle = (bg, color) => ({
10008
+ display: "inline-flex",
9971
10009
  alignItems: "center",
9972
10010
  justifyContent: "center",
9973
- textAlign: "center",
9974
- padding: "10px 16px",
9975
- borderRadius: 999,
9976
- fontSize: "0.95rem",
9977
- fontWeight: 600,
9978
- lineHeight: 1.15,
9979
- color: selected ? tokens.text : tokens.textMuted,
9980
- background: selected ? tokens.bg : "transparent",
9981
- boxShadow: selected ? tokens.shadow : "none",
9982
- cursor: "default",
9983
- userSelect: "none"
9984
- });
9985
- var toggleSubLabelStyle = {
9986
- fontSize: "0.7rem",
10011
+ background: bg,
10012
+ color,
10013
+ fontSize: 10,
9987
10014
  fontWeight: 500,
9988
- marginTop: 2,
9989
- opacity: 0.85
10015
+ lineHeight: 1,
10016
+ padding: "4px 8px",
10017
+ borderRadius: 8,
10018
+ marginRight: 8,
10019
+ whiteSpace: "nowrap"
10020
+ });
10021
+ var badgeWithArrowStyle = {
10022
+ display: "flex",
10023
+ alignItems: "center"
9990
10024
  };
9991
- var comingSoonBadgeStyle = (bg, color) => ({
10025
+ var recommendedBadgeStyle = (bg, color) => ({
9992
10026
  display: "inline-flex",
9993
10027
  alignItems: "center",
9994
10028
  justifyContent: "center",
@@ -9999,7 +10033,6 @@ var comingSoonBadgeStyle = (bg, color) => ({
9999
10033
  lineHeight: 1,
10000
10034
  padding: "4px 8px",
10001
10035
  borderRadius: 8,
10002
- marginRight: 8,
10003
10036
  whiteSpace: "nowrap"
10004
10037
  });
10005
10038
  var linkIconImageStyle = (color) => ({
@@ -10925,70 +10958,59 @@ function WalletPickerScreen({
10925
10958
  ),
10926
10959
  /* @__PURE__ */ jsxRuntime.jsx("h1", { style: titleStyle3(tokens.text), children: "Link wallet" }),
10927
10960
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorBannerStyle5(tokens), children: error }),
10928
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: sheetStackStyle, children: [
10929
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle2(tokens.bgCardTranslucent), children: showOtherWallets ? /* @__PURE__ */ jsxRuntime.jsx(
10930
- OtherWalletsPanel,
10931
- {
10932
- wallets: filteredReownWallets,
10933
- loading: reownLoading,
10934
- error: reownError,
10935
- search: reownSearch,
10936
- onSearchChange: setReownSearch,
10937
- onRetry: () => {
10938
- setReownWallets([]);
10939
- setReownFetchAttempt((attempt) => attempt + 1);
10940
- },
10941
- onSelectWallet: (wallet) => {
10942
- void onSelectWalletConnectWallet(wallet);
10943
- }
10961
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: sheetStackStyle, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle2(tokens.bgCardTranslucent), children: showOtherWallets ? /* @__PURE__ */ jsxRuntime.jsx(
10962
+ OtherWalletsPanel,
10963
+ {
10964
+ wallets: filteredReownWallets,
10965
+ loading: reownLoading,
10966
+ error: reownError,
10967
+ search: reownSearch,
10968
+ onSearchChange: setReownSearch,
10969
+ onRetry: () => {
10970
+ setReownWallets([]);
10971
+ setReownFetchAttempt((attempt) => attempt + 1);
10972
+ },
10973
+ onSelectWallet: (wallet) => {
10974
+ void onSelectWalletConnectWallet(wallet);
10944
10975
  }
10945
- ) : showWalletListSpinner ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: spinnerRowStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: providersLoading ? "Loading wallets..." : "Preparing wallet links..." }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10946
- visibleProviders.map((provider) => {
10947
- const logoSrc = "logoURI" in provider && provider.logoURI || KNOWN_LOGOS[provider.name.toLowerCase()];
10948
- const directPreparedSession = directPreparedSessions[provider.id];
10949
- const isRowPreparing = preparing && selectedProviderId === provider.id;
10950
- const rowLoader = isRowPreparing ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 20 }) : void 0;
10951
- if (usesDirectLinkCards) {
10952
- if (directPreparedSession?.uri) {
10953
- const navigation = classifyWalletDeeplinkNavigation(directPreparedSession.uri);
10954
- const openWithJavaScript = shouldOpenWithJavaScript(navigation);
10955
- return /* @__PURE__ */ jsxRuntime.jsx(
10956
- SourceRow,
10957
- {
10958
- logo: logoSrc,
10959
- name: provider.name,
10960
- href: directPreparedSession.uri,
10961
- target: navigation.anchorTarget,
10962
- rel: navigation.anchorRel,
10963
- onClick: (e) => {
10964
- if (openWithJavaScript) {
10965
- e.preventDefault();
10966
- }
10967
- setSelectedProviderId(provider.id);
10968
- if (directPreparedSession.sessionId) {
10969
- void setAuthorizationSessionProvider(
10970
- apiBaseUrl,
10971
- directPreparedSession.sessionId,
10972
- provider.id
10973
- ).catch((err) => {
10974
- captureException(err);
10975
- });
10976
- }
10977
- if (openWithJavaScript) {
10978
- openDeeplink(directPreparedSession.uri);
10979
- }
10980
- void onSelectProvider(provider.id, directPreparedSession);
10981
- }
10982
- },
10983
- provider.id
10984
- );
10985
- }
10976
+ }
10977
+ ) : showWalletListSpinner ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: spinnerRowStyle, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: providersLoading ? "Loading wallets..." : "Preparing wallet links..." }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10978
+ visibleProviders.map((provider) => {
10979
+ const logoSrc = "logoURI" in provider && provider.logoURI || KNOWN_LOGOS[provider.name.toLowerCase()];
10980
+ const directPreparedSession = directPreparedSessions[provider.id];
10981
+ const isRowPreparing = preparing && selectedProviderId === provider.id;
10982
+ const rowLoader = isRowPreparing ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 20 }) : void 0;
10983
+ if (usesDirectLinkCards) {
10984
+ if (directPreparedSession?.uri) {
10985
+ const navigation = classifyWalletDeeplinkNavigation(directPreparedSession.uri);
10986
+ const openWithJavaScript = shouldOpenWithJavaScript(navigation);
10986
10987
  return /* @__PURE__ */ jsxRuntime.jsx(
10987
10988
  SourceRow,
10988
10989
  {
10989
10990
  logo: logoSrc,
10990
10991
  name: provider.name,
10991
- disabled: true
10992
+ href: directPreparedSession.uri,
10993
+ target: navigation.anchorTarget,
10994
+ rel: navigation.anchorRel,
10995
+ onClick: (e) => {
10996
+ if (openWithJavaScript) {
10997
+ e.preventDefault();
10998
+ }
10999
+ setSelectedProviderId(provider.id);
11000
+ if (directPreparedSession.sessionId) {
11001
+ void setAuthorizationSessionProvider(
11002
+ apiBaseUrl,
11003
+ directPreparedSession.sessionId,
11004
+ provider.id
11005
+ ).catch((err) => {
11006
+ captureException(err);
11007
+ });
11008
+ }
11009
+ if (openWithJavaScript) {
11010
+ openDeeplink(directPreparedSession.uri);
11011
+ }
11012
+ void onSelectProvider(provider.id, directPreparedSession);
11013
+ }
10992
11014
  },
10993
11015
  provider.id
10994
11016
  );
@@ -10998,36 +11020,35 @@ function WalletPickerScreen({
10998
11020
  {
10999
11021
  logo: logoSrc,
11000
11022
  name: provider.name,
11001
- right: rowLoader,
11002
- onClick: () => {
11003
- void handleRowSelect(provider.id);
11004
- }
11023
+ disabled: true
11005
11024
  },
11006
11025
  provider.id
11007
11026
  );
11008
- }),
11009
- /* @__PURE__ */ jsxRuntime.jsx(
11027
+ }
11028
+ return /* @__PURE__ */ jsxRuntime.jsx(
11010
11029
  SourceRow,
11011
11030
  {
11012
- name: "Other",
11013
- icon: /* @__PURE__ */ jsxRuntime.jsx(OtherWalletsIcon, { color: tokens.textMuted }),
11031
+ logo: logoSrc,
11032
+ name: provider.name,
11033
+ right: rowLoader,
11014
11034
  onClick: () => {
11015
- setShowOtherWallets(true);
11035
+ void handleRowSelect(provider.id);
11016
11036
  }
11017
- }
11018
- )
11019
- ] }) }),
11020
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: disabledCardStyle(tokens.bgRecessed), children: /* @__PURE__ */ jsxRuntime.jsx(
11037
+ },
11038
+ provider.id
11039
+ );
11040
+ }),
11041
+ /* @__PURE__ */ jsxRuntime.jsx(
11021
11042
  SourceRow,
11022
11043
  {
11023
- disabled: true,
11024
- disabledColor: tokens.textTertiary,
11025
- name: "Bank account",
11026
- icon: /* @__PURE__ */ jsxRuntime.jsx(BankIcon, { color: tokens.textTertiary }),
11027
- right: /* @__PURE__ */ jsxRuntime.jsx("span", { style: comingSoonStyle(tokens.textTertiary), children: "Coming soon" })
11044
+ name: "Other",
11045
+ icon: /* @__PURE__ */ jsxRuntime.jsx(OtherWalletsIcon, {}),
11046
+ onClick: () => {
11047
+ setShowOtherWallets(true);
11048
+ }
11028
11049
  }
11029
- ) })
11030
- ] })
11050
+ )
11051
+ ] }) }) })
11031
11052
  ] });
11032
11053
  }
11033
11054
  function OtherWalletsPanel({
@@ -11096,77 +11117,29 @@ function ReownWalletLogo({ wallet }) {
11096
11117
  }
11097
11118
  );
11098
11119
  }
11099
- function OtherWalletsIcon({ color }) {
11100
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
11101
- /* @__PURE__ */ jsxRuntime.jsx(
11102
- "path",
11103
- {
11104
- d: "M7.5 9.5C10 7.2 14 7.2 16.5 9.5",
11105
- stroke: color,
11106
- strokeWidth: "1.8",
11107
- strokeLinecap: "round"
11108
- }
11109
- ),
11110
- /* @__PURE__ */ jsxRuntime.jsx(
11111
- "path",
11112
- {
11113
- d: "M4.5 6.5C8.7 2.9 15.3 2.9 19.5 6.5",
11114
- stroke: color,
11115
- strokeWidth: "1.8",
11116
- strokeLinecap: "round"
11117
- }
11118
- ),
11119
- /* @__PURE__ */ jsxRuntime.jsx(
11120
- "path",
11121
- {
11122
- d: "M10 12.5C11.1 11.7 12.9 11.7 14 12.5",
11123
- stroke: color,
11124
- strokeWidth: "1.8",
11125
- strokeLinecap: "round"
11126
- }
11127
- ),
11128
- /* @__PURE__ */ jsxRuntime.jsx(
11129
- "path",
11130
- {
11131
- d: "M12 16H12.01",
11132
- stroke: color,
11133
- strokeWidth: "2.4",
11134
- strokeLinecap: "round"
11135
- }
11136
- )
11137
- ] });
11138
- }
11139
- function BankIcon({ color }) {
11140
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
11141
- /* @__PURE__ */ jsxRuntime.jsx(
11142
- "path",
11143
- {
11144
- d: "M3 10L12 4L21 10",
11145
- stroke: color,
11146
- strokeWidth: "1.8",
11147
- strokeLinecap: "round",
11148
- strokeLinejoin: "round"
11149
- }
11150
- ),
11151
- /* @__PURE__ */ jsxRuntime.jsx(
11152
- "path",
11153
- {
11154
- d: "M5 10V18M9 10V18M15 10V18M19 10V18",
11155
- stroke: color,
11156
- strokeWidth: "1.8",
11157
- strokeLinecap: "round"
11158
- }
11159
- ),
11160
- /* @__PURE__ */ jsxRuntime.jsx(
11161
- "path",
11162
- {
11163
- d: "M3 20H21",
11164
- stroke: color,
11165
- strokeWidth: "1.8",
11166
- strokeLinecap: "round"
11167
- }
11168
- )
11169
- ] });
11120
+ function OtherWalletsIcon() {
11121
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11122
+ "svg",
11123
+ {
11124
+ width: "34",
11125
+ height: "34",
11126
+ viewBox: "0 0 400 400",
11127
+ fill: "none",
11128
+ xmlns: "http://www.w3.org/2000/svg",
11129
+ "aria-hidden": "true",
11130
+ style: { borderRadius: "50%" },
11131
+ children: [
11132
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "200", cy: "200", fill: "#3396ff", r: "199.5", stroke: "#66b1ff" }),
11133
+ /* @__PURE__ */ jsxRuntime.jsx(
11134
+ "path",
11135
+ {
11136
+ 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",
11137
+ fill: "#fff"
11138
+ }
11139
+ )
11140
+ ]
11141
+ }
11142
+ );
11170
11143
  }
11171
11144
  function isAbortError(err) {
11172
11145
  return err instanceof DOMException && err.name === "AbortError";
@@ -11215,19 +11188,6 @@ var cardStyle2 = (bg) => ({
11215
11188
  borderRadius: 28,
11216
11189
  padding: "8px 8px 8px 20px"
11217
11190
  });
11218
- var disabledCardStyle = (bg) => ({
11219
- display: "flex",
11220
- flexDirection: "column",
11221
- background: bg,
11222
- borderRadius: 28,
11223
- padding: "8px 8px 8px 20px"
11224
- });
11225
- var comingSoonStyle = (color) => ({
11226
- fontSize: "1rem",
11227
- color,
11228
- paddingRight: 8,
11229
- whiteSpace: "nowrap"
11230
- });
11231
11191
  var spinnerRowStyle = {
11232
11192
  display: "flex",
11233
11193
  alignItems: "center",
@@ -12348,13 +12308,14 @@ function DepositScreen({
12348
12308
  (opt) => opt.balance == null || isSelectableDepositSourceAmountUsd(opt.balance, minDepositFloor)
12349
12309
  ) ?? [];
12350
12310
  const hasTokenDropdown = selectableTokenOptions.length > 0 && onPickToken != null;
12311
+ const canOpenInlineSheet = onPickToken != null && (hasTokenDropdown || (accounts?.length ?? 0) > 0);
12351
12312
  const handleOpenSourceSheet = react.useCallback(() => {
12352
- if (hasTokenDropdown) {
12313
+ if (canOpenInlineSheet) {
12353
12314
  setTokenPickerOpen((v) => !v);
12354
12315
  } else {
12355
12316
  onSelectToken?.();
12356
12317
  }
12357
- }, [hasTokenDropdown, onSelectToken]);
12318
+ }, [canOpenInlineSheet, onSelectToken]);
12358
12319
  const handleCloseSourceSheet = react.useCallback(() => {
12359
12320
  setTokenPickerOpen(false);
12360
12321
  }, []);
@@ -12366,9 +12327,9 @@ function DepositScreen({
12366
12327
  const exceedsLimit = remainingLimit != null && amount > remainingLimit && !isLowBalance && !needsAuthorization;
12367
12328
  const canDeposit = amount >= minDepositFloor && !exceedsLimit && !isLowBalance && !insufficientFunds && !needsAuthorization && !processing;
12368
12329
  const hasAccountPill = !!accounts && accounts.length > 0;
12369
- const pillClickable = hasTokenDropdown || !!onSelectToken;
12330
+ const pillClickable = canOpenInlineSheet || !!onSelectToken;
12370
12331
  const tokenAriaLabel = selectedTokenSymbol && selectedChainName ? `Selected token: ${selectedTokenSymbol} on ${selectedChainName}` : selectedTokenSymbol ? `Selected token: ${selectedTokenSymbol}` : "Select token";
12371
- if (tokenPickerOpen && hasTokenDropdown) {
12332
+ if (tokenPickerOpen && canOpenInlineSheet) {
12372
12333
  const depositSourceAccounts = (accounts ?? []).map((a) => {
12373
12334
  const preferred = getPreferredDepositWallet(a, amount);
12374
12335
  return {
@@ -12429,8 +12390,8 @@ function DepositScreen({
12429
12390
  onClick: handleOpenSourceSheet,
12430
12391
  style: redesignPillButtonStyle(pillClickable),
12431
12392
  "aria-label": tokenAriaLabel,
12432
- "aria-expanded": hasTokenDropdown ? tokenPickerOpen : void 0,
12433
- "aria-haspopup": hasTokenDropdown ? "listbox" : void 0,
12393
+ "aria-expanded": canOpenInlineSheet ? tokenPickerOpen : void 0,
12394
+ "aria-haspopup": canOpenInlineSheet ? "listbox" : void 0,
12434
12395
  children: /* @__PURE__ */ jsxRuntime.jsx(
12435
12396
  SourcePill,
12436
12397
  {
@@ -12543,8 +12504,8 @@ function SuccessScreen({
12543
12504
  onLogout,
12544
12505
  returnMessage
12545
12506
  }) {
12546
- const { tokens } = useBlinkConfig();
12547
- const headerRight = succeeded && onDone ? /* @__PURE__ */ jsxRuntime.jsx(
12507
+ const { tokens, isMobileApp } = useBlinkConfig();
12508
+ const headerRight = succeeded && onDone && !isMobileApp ? /* @__PURE__ */ jsxRuntime.jsx(
12548
12509
  "button",
12549
12510
  {
12550
12511
  type: "button",
@@ -12745,7 +12706,7 @@ function SelectSourceScreen({
12745
12706
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: optionContentStyle, children: [
12746
12707
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: optionNameStyle(tokens.text), children: [
12747
12708
  chain.chainName,
12748
- isRecommended && /* @__PURE__ */ jsxRuntime.jsx("span", { style: recommendedBadgeStyle(tokens.textMuted), children: " recommended" })
12709
+ isRecommended && /* @__PURE__ */ jsxRuntime.jsx("span", { style: recommendedBadgeStyle2(tokens.textMuted), children: " recommended" })
12749
12710
  ] }),
12750
12711
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: optionBalanceStyle(tokens.textMuted), children: [
12751
12712
  "$",
@@ -12841,7 +12802,7 @@ var optionNameStyle = (color) => ({
12841
12802
  fontWeight: 600,
12842
12803
  color
12843
12804
  });
12844
- var recommendedBadgeStyle = (color) => ({
12805
+ var recommendedBadgeStyle2 = (color) => ({
12845
12806
  fontSize: "0.7rem",
12846
12807
  fontWeight: 500,
12847
12808
  color,
@@ -15351,10 +15312,10 @@ function buildLoginScreenProps({ flow, handlers }) {
15351
15312
  onSignupWithPasskey: handlers.onSignupWithPasskey,
15352
15313
  loading: flow.passkeyLoading,
15353
15314
  error: flow.state.error,
15354
- // Login is the root screen, so "back" and "close" both dismiss the widget.
15355
- // Exposing onClose lets LoginScreen render the Figma-redesign top-right
15356
- // (X) button instead of the legacy back arrow.
15357
- onClose: flow.onBack,
15315
+ // Inside a native mobile in-app browser the host's chrome handles
15316
+ // dismissal, so suppress the in-screen (X) close button.
15317
+ onClose: flow.isMobileApp ? void 0 : flow.onBack,
15318
+ onBack: flow.state.enableFullWidget ? handlers.onCancelLogin : void 0,
15358
15319
  merchantInitials: flow.merchantName ? flow.merchantName.slice(0, 2).toUpperCase() : void 0
15359
15320
  };
15360
15321
  }
@@ -15369,8 +15330,9 @@ function buildDepositOptionsScreenProps({ flow, handlers }) {
15369
15330
  // Deposit-options is the root screen for the full-widget flow, so the
15370
15331
  // top-right (X) closes the widget through the same `onBack` the host
15371
15332
  // provides. Falling back to `undefined` hides the close button when the
15372
- // host did not pass an onBack (matches LoginScreen behavior).
15373
- onClose: flow.onBack
15333
+ // host did not pass an onBack (matches LoginScreen behavior). Inside a
15334
+ // native mobile in-app browser the host chrome handles dismissal.
15335
+ onClose: flow.isMobileApp ? void 0 : flow.onBack
15374
15336
  };
15375
15337
  }
15376
15338
  function buildPasskeyReadyScreenProps({ handlers }) {
@@ -15608,7 +15570,7 @@ function buildDepositScreenProps({
15608
15570
  error: state.error,
15609
15571
  onDeposit: handlers.onPay,
15610
15572
  onSwitchWallet: () => handlers.onSetPhase({ step: "wallet-picker", reason: "switch" }),
15611
- onBack: onBack ?? (() => handlers.onLogout()),
15573
+ onBack: state.enableFullWidget ? () => handlers.onSetPhase({ step: "deposit-options" }) : onBack ?? (() => handlers.onLogout()),
15612
15574
  onLogout: handlers.onLogout,
15613
15575
  onIncreaseLimit: handlers.onIncreaseLimit,
15614
15576
  increasingLimit: state.increasingLimit,
@@ -15621,7 +15583,7 @@ function buildDepositScreenProps({
15621
15583
  // the inline sheet can't render). Hosts with sources get the inline
15622
15584
  // SelectDepositSourceScreen via onPickToken below.
15623
15585
  onSelectToken: handlers.onSelectToken,
15624
- tokenOptions: depositTokenOptions.length > 0 ? depositTokenOptions : void 0,
15586
+ tokenOptions: depositTokenOptions,
15625
15587
  useDeeplink: !flow.isDesktop,
15626
15588
  onPickToken: (symbol, chainName, walletId) => {
15627
15589
  const match = depositTokenOptions.find(
@@ -15775,13 +15737,15 @@ function buildAmountTooLowScreenProps({
15775
15737
  flow,
15776
15738
  handlers
15777
15739
  }) {
15778
- const { state, onDismiss } = flow;
15740
+ const { state, onDismiss, isMobileApp } = flow;
15779
15741
  const minAmountUsd = state.phase.step === "amount-too-low" ? state.phase.minAmountUsd : state.amountTooLow?.minAmountUsd ?? flow.minTransferAmountUsd;
15780
15742
  const canRetry = flow.depositAmount == null;
15781
15743
  return {
15782
15744
  minAmountUsd,
15783
15745
  onRetry: canRetry ? handlers.onNewPayment : void 0,
15784
- onClose: onDismiss
15746
+ // Inside a native mobile in-app browser the host's chrome handles
15747
+ // dismissal, so suppress the in-screen (X) close button.
15748
+ onClose: isMobileApp ? void 0 : onDismiss
15785
15749
  };
15786
15750
  }
15787
15751
  function StepRenderer(props) {
@@ -18948,7 +18912,7 @@ function BlinkPaymentInner({
18948
18912
  onBack,
18949
18913
  onDismiss
18950
18914
  }) {
18951
- const { apiBaseUrl, depositAmount, minTransferAmountUsd, enableFullWidget } = useBlinkConfig();
18915
+ const { apiBaseUrl, depositAmount, minTransferAmountUsd, enableFullWidget, isMobileApp } = useBlinkConfig();
18952
18916
  const { ready, authenticated, logout, getAccessToken } = reactAuth.usePrivy();
18953
18917
  const popupAuthRef = react.useRef(loadPopupAuth());
18954
18918
  const popupAuthValid = (() => {
@@ -19460,6 +19424,11 @@ function BlinkPaymentInner({
19460
19424
  onNewPayment: handleNewPayment,
19461
19425
  onSetPhase: (phase) => {
19462
19426
  clearScreenErrors();
19427
+ if (phase.step === "deposit") {
19428
+ dispatch({ type: "SET_SETUP_DEPOSIT_AMOUNT", amount: null });
19429
+ dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
19430
+ dispatch({ type: "SET_SETUP_FLOW_SCREEN", screen: null });
19431
+ }
19463
19432
  dispatch({ type: "SET_USER_INTENT", intent: phase });
19464
19433
  },
19465
19434
  onAddProviderFromDeposit: (amount) => {
@@ -19473,6 +19442,11 @@ function BlinkPaymentInner({
19473
19442
  authExecutor.cancelPendingExecution();
19474
19443
  clearScreenErrors();
19475
19444
  dispatch({ type: "RESTORE_SELECTION" });
19445
+ dispatch({ type: "SET_SETUP_DEPOSIT_AMOUNT", amount: null });
19446
+ dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
19447
+ dispatch({ type: "SET_SETUP_FLOW_SCREEN", screen: null });
19448
+ dispatch({ type: "DESKTOP_WAIT_CLEARED" });
19449
+ dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: false });
19476
19450
  dispatch({ type: "SET_USER_INTENT", intent: { step: "deposit" } });
19477
19451
  },
19478
19452
  onSelectSourceChainChange: sourceSelection.handleSelectSourceChainChange,
@@ -19485,6 +19459,7 @@ function BlinkPaymentInner({
19485
19459
  onPrepareTokenAuthorization: provider.handlePrepareTokenAuthorization,
19486
19460
  onCommitTokenAuthorization: provider.handleCommitTokenAuthorization,
19487
19461
  onLogin: () => dispatch({ type: "REQUEST_LOGIN" }),
19462
+ onCancelLogin: () => dispatch({ type: "CANCEL_LOGIN_REQUEST" }),
19488
19463
  onSetDepositAmount: handleSetDepositAmount,
19489
19464
  onSetDepositToken: handleSetDepositToken,
19490
19465
  onConfirmSetupDeposit: handleConfirmSetupDeposit
@@ -19516,6 +19491,7 @@ function BlinkPaymentInner({
19516
19491
  authenticated: effectiveAuthenticated,
19517
19492
  passkeyLoading: auth.passkeyLoginStatus !== "initial" && auth.passkeyLoginStatus !== "done" && auth.passkeyLoginStatus !== "error" || auth.passkeySignupStatus !== "initial" && auth.passkeySignupStatus !== "done" && auth.passkeySignupStatus !== "error" || auth.passkeySignupPopupActive,
19518
19493
  isDesktop,
19494
+ isMobileApp: isMobileApp ?? false,
19519
19495
  merchantName,
19520
19496
  onBack,
19521
19497
  onDismiss,