@swype-org/react-sdk 0.2.364 → 0.2.372

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
@@ -636,6 +636,21 @@ function resolveSelectSourceOption(choices, options, chainName, tokenSymbol, rec
636
636
  ));
637
637
  }
638
638
 
639
+ // src/walletFlow.ts
640
+ var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
641
+ function isMobileUserAgent(userAgent) {
642
+ if (!userAgent) {
643
+ return false;
644
+ }
645
+ return MOBILE_USER_AGENT_PATTERN.test(userAgent);
646
+ }
647
+ function shouldUseWalletConnector(options) {
648
+ return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
649
+ }
650
+ function resolveCoinbasePreferenceOptions(userAgent) {
651
+ return isMobileUserAgent(userAgent) ? "all" : "eoaOnly";
652
+ }
653
+
639
654
  // src/walletBridge/protocol.ts
640
655
  var BRIDGE_PROTOCOL_VERSION = 1;
641
656
  function parseBridgeMessage(data) {
@@ -1006,18 +1021,28 @@ function FingerprintVisitorPing() {
1006
1021
  return null;
1007
1022
  }
1008
1023
  function buildStaticConnectors() {
1024
+ const userAgent = typeof navigator === "undefined" ? null : navigator.userAgent;
1009
1025
  return [
1010
1026
  // `unstable_shimAsyncInject` covers wallets whose content scripts wire
1011
1027
  // up after page load (Phantom, Trust, MetaMask in the iframe).
1012
1028
  connectors.injected({ unstable_shimAsyncInject: 2e3 }),
1013
- // `preference: 'all'` (default) lets the Coinbase Wallet SDK prefer an
1014
- // injected provider when one is present. This matters inside Base's
1015
- // mobile in-app WebView: with `smartWalletOnly`, the SDK routes signing
1016
- // through `keys.coinbase.com`, which in an iOS WKWebView navigates the
1017
- // webview itself (full page reload after each signature). With `all`,
1018
- // the SDK uses the Base WebView's injected `window.ethereum` directly,
1019
- // keeping signing in-process. Desktop/extension users are unaffected.
1020
- connectors.coinbaseWallet({ appName: "Swype", preference: { options: "all" } })
1029
+ // Coinbase Wallet SDK connection preference is platform-specific
1030
+ // (see `resolveCoinbasePreferenceOptions`):
1031
+ // Desktop → `eoaOnly`: in smart-wallet mode the Base extension hands
1032
+ // the dapp a separate, often-empty smart-wallet account instead of the
1033
+ // user's funded EOA "no assets". `eoaOnly` binds the funded EOA.
1034
+ // Mobile (Base in-app WebView) `all`: signing must use the injected
1035
+ // `window.ethereum`; the SDK path reloads the iOS WKWebView after each
1036
+ // signature.
1037
+ //
1038
+ // Exactly ONE Coinbase connector: two `@coinbase/wallet-sdk` instances in
1039
+ // one page collide on shared `window` listeners + the Communicator (Privy
1040
+ // connector-init timeout, listener leaks, duplicated `client-project-name`
1041
+ // that 400s the connect), so we never register a second one.
1042
+ connectors.coinbaseWallet({
1043
+ appName: "Blink",
1044
+ preference: { options: resolveCoinbasePreferenceOptions(userAgent) }
1045
+ })
1021
1046
  ];
1022
1047
  }
1023
1048
  function buildWagmiConfig(bridgedWallets) {
@@ -1167,9 +1192,10 @@ function buildTargetMatchers(target) {
1167
1192
  aliases.add("io.metamask");
1168
1193
  }
1169
1194
  if (value === "base" || value === "base account" || value === "base app" || value.includes("coinbase")) {
1170
- aliases.add("base");
1171
1195
  aliases.add("coinbase");
1172
1196
  aliases.add("coinbasewalletsdk");
1197
+ aliases.add("com.coinbase.wallet");
1198
+ aliases.add("baseaccount");
1173
1199
  }
1174
1200
  if (value.includes("trust")) {
1175
1201
  aliases.add("trust");
@@ -1243,19 +1269,70 @@ async function withTimeout(promise, ms, label) {
1243
1269
  if (timer !== void 0) clearTimeout(timer);
1244
1270
  }
1245
1271
  }
1246
- function isReloadingCoinbaseConnector(connector) {
1272
+ function isCoinbaseSdkConnector(connector) {
1247
1273
  if (!connector) return false;
1248
1274
  return connectorMatchesWallet(
1249
1275
  { id: connector.id, name: connector.name ?? "" },
1250
1276
  { wagmiConnectorId: "coinbaseWalletSDK" }
1251
1277
  );
1252
1278
  }
1279
+ var COINBASE_SDK_STORAGE_PREFIXES = ["-CBWSDK", "-walletlink"];
1280
+ var COINBASE_SIGNER_TYPE_STORAGE_KEY = "-CBWSDK:SignerConfigurator:SignerType";
1281
+ function loadCoinbaseSignerType() {
1282
+ if (typeof window === "undefined" || !window.localStorage) return null;
1283
+ try {
1284
+ return window.localStorage.getItem(COINBASE_SIGNER_TYPE_STORAGE_KEY);
1285
+ } catch {
1286
+ return null;
1287
+ }
1288
+ }
1289
+ function clearCoinbaseWalletSdkSession() {
1290
+ if (typeof window === "undefined" || !window.localStorage) return;
1291
+ try {
1292
+ const store = window.localStorage;
1293
+ const keysToRemove = [];
1294
+ for (let i = 0; i < store.length; i += 1) {
1295
+ const key = store.key(i);
1296
+ if (key && COINBASE_SDK_STORAGE_PREFIXES.some((prefix) => key.startsWith(prefix))) {
1297
+ keysToRemove.push(key);
1298
+ }
1299
+ }
1300
+ keysToRemove.forEach((key) => store.removeItem(key));
1301
+ console.info("[blink-sdk][disconnect] cleared Coinbase Wallet SDK session", {
1302
+ clearedKeys: keysToRemove.length
1303
+ });
1304
+ } catch (err) {
1305
+ console.info("[blink-sdk][disconnect] failed to clear Coinbase Wallet SDK session", err);
1306
+ }
1307
+ }
1308
+ function resetWagmiConnectionInMemory(wagmiConfig, connector) {
1309
+ if (!connector) return;
1310
+ try {
1311
+ const target = connector;
1312
+ const connections = [...wagmiConfig.state.connections.values()];
1313
+ const match = connections.find((conn) => {
1314
+ const live2 = conn.connector;
1315
+ if (target.uid && live2.uid) return live2.uid === target.uid;
1316
+ return live2.id === target.id;
1317
+ });
1318
+ const live = match?.connector;
1319
+ if (!live?.emitter) return;
1320
+ live.emitter.emit("disconnect");
1321
+ console.info("[blink-sdk][disconnect] reset wagmi in-memory connection via emitter", {
1322
+ connectorId: live.id
1323
+ });
1324
+ } catch (err) {
1325
+ console.info("[blink-sdk][disconnect] failed to reset wagmi in-memory connection", err);
1326
+ }
1327
+ }
1253
1328
  async function safeDisconnect(wagmiConfig, connector) {
1254
- if (isReloadingCoinbaseConnector(connector)) {
1329
+ if (isCoinbaseSdkConnector(connector)) {
1255
1330
  console.info(
1256
- "[blink-sdk][disconnect] skipping wagmi disconnect for Coinbase WalletLink connector",
1331
+ "[blink-sdk][disconnect] clearing Coinbase Wallet SDK session instead of wagmi disconnect",
1257
1332
  { connectorId: connector?.id }
1258
1333
  );
1334
+ clearCoinbaseWalletSdkSession();
1335
+ resetWagmiConnectionInMemory(wagmiConfig, connector);
1259
1336
  return;
1260
1337
  }
1261
1338
  await core.disconnect(wagmiConfig, { connector }).catch(() => {
@@ -3909,6 +3986,23 @@ function isUserRejection(msg) {
3909
3986
  const lower = msg.toLowerCase();
3910
3987
  return lower.includes("rejected") || lower.includes("denied");
3911
3988
  }
3989
+ var EmptyConnectionAccountError = class extends Error {
3990
+ constructor(message = "Wallet connected but returned no account address.") {
3991
+ super(message);
3992
+ this.name = "EmptyConnectionAccountError";
3993
+ }
3994
+ };
3995
+ var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
3996
+ function assertNonEmptyConnectedAddress(address, ctx) {
3997
+ if (typeof address === "string" && EVM_ADDRESS_RE.test(address)) {
3998
+ return;
3999
+ }
4000
+ appendDebug("error", "OPEN_PROVIDER: empty-or-invalid-connected-address", {
4001
+ ...ctx,
4002
+ address: address ?? null
4003
+ });
4004
+ throw new EmptyConnectionAccountError();
4005
+ }
3912
4006
  function requiresExplicitEvmNonce(account) {
3913
4007
  return connectorMatchesWallet(account?.connector, { providerName: "trust" }) || connectorMatchesWallet(account?.connector, { providerName: "phantom" });
3914
4008
  }
@@ -4142,7 +4236,8 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4142
4236
  accountConnectorId: account.connector?.id ?? null,
4143
4237
  accountConnectorName: account.connector?.name ?? null,
4144
4238
  targetId: targetId ?? null,
4145
- resolvedConnectorId: connector?.id ?? null
4239
+ resolvedConnectorId: connector?.id ?? null,
4240
+ availableConnectorIds: connectors.map((c) => c.id)
4146
4241
  };
4147
4242
  let disconnectedMismatchedConnector = false;
4148
4243
  if (account.isConnected && account.address) {
@@ -4150,6 +4245,7 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4150
4245
  if (connectorMatchesTarget) {
4151
4246
  const hexChainId2 = account.chainId ? `0x${account.chainId.toString(16)}` : void 0;
4152
4247
  const branch = !targetId ? "early-return-no-target" : "early-return-connector-match";
4248
+ assertNonEmptyConnectedAddress(account.address, { ...logContext, branch });
4153
4249
  console.info("[blink-sdk][open-provider] Skipping connectAsync; wagmi already connected.", {
4154
4250
  ...logContext,
4155
4251
  branch
@@ -4173,6 +4269,20 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4173
4269
  disconnectedMismatchedConnector = true;
4174
4270
  }
4175
4271
  if (!disconnectedMismatchedConnector) {
4272
+ const targetIsCoinbase = connectorMatchesWallet(connector, {
4273
+ wagmiConnectorId: "coinbaseWalletSDK"
4274
+ });
4275
+ const isDesktopUa = !isMobileUserAgent(
4276
+ typeof navigator === "undefined" ? null : navigator.userAgent
4277
+ );
4278
+ if (targetIsCoinbase && isDesktopUa && loadCoinbaseSignerType() === "scw") {
4279
+ console.info(
4280
+ "[blink-sdk][open-provider] Clearing stale Coinbase Smart Wallet (scw) session before reconnect so eoaOnly binds the EOA.",
4281
+ logContext
4282
+ );
4283
+ appendDebug("info", "OPEN_PROVIDER: clearing stale scw session before reconnect", logContext);
4284
+ clearCoinbaseWalletSdkSession();
4285
+ }
4176
4286
  console.info("[blink-sdk][open-provider] Attempting silent reconnect.", logContext);
4177
4287
  appendDebug("info", "OPEN_PROVIDER: attempting silent reconnect", logContext);
4178
4288
  const reconnections = await core.reconnect(wagmiConfig).catch(() => []);
@@ -4187,6 +4297,7 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4187
4297
  reconnectedConnectorId: reconnectedAccount.connector?.id ?? null,
4188
4298
  reconnectionCount: reconnections.length
4189
4299
  };
4300
+ assertNonEmptyConnectedAddress(reconnectedAccount.address, reconnectLogContext);
4190
4301
  console.info(
4191
4302
  "[blink-sdk][open-provider] Silent reconnect succeeded; skipping connectAsync.",
4192
4303
  reconnectLogContext
@@ -4254,6 +4365,10 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4254
4365
  });
4255
4366
  const result = await connectAsync({ connector });
4256
4367
  const hexChainId = `0x${result.chainId.toString(16)}`;
4368
+ assertNonEmptyConnectedAddress(result.accounts[0], {
4369
+ ...logContext,
4370
+ branch: "connectAsync-result"
4371
+ });
4257
4372
  return actionSuccess(
4258
4373
  action,
4259
4374
  `Connected to ${connector.name}. Account: ${result.accounts[0]}, Chain: ${hexChainId}`,
@@ -4261,15 +4376,23 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4261
4376
  );
4262
4377
  } catch (err) {
4263
4378
  const msg = err instanceof Error ? err.message : "Failed to connect wallet";
4264
- if (options?.externalAuthorizationAvailable && isUserRejection(msg) && action.metadata?.chainFamily !== "svm") {
4265
- appendDebug("info", "OPEN_PROVIDER: user-rejection-soft-halt", {
4379
+ const emptyAccount = err instanceof EmptyConnectionAccountError;
4380
+ if (options?.externalAuthorizationAvailable && (isUserRejection(msg) || emptyAccount) && action.metadata?.chainFamily !== "svm") {
4381
+ appendDebug("info", "OPEN_PROVIDER: soft-halt", {
4266
4382
  actionId: action.id,
4267
- externalAuthorizationAvailable: true
4383
+ externalAuthorizationAvailable: true,
4384
+ reason: emptyAccount ? "empty-account" : "user-rejection"
4268
4385
  });
4269
4386
  return actionPending(
4270
4387
  action,
4271
4388
  "awaiting-external-authorization",
4272
- "Wallet connection prompt dismissed \u2014 awaiting completion via cross-device authorization."
4389
+ emptyAccount ? "Wallet returned no account \u2014 awaiting completion via cross-device authorization." : "Wallet connection prompt dismissed \u2014 awaiting completion via cross-device authorization."
4390
+ );
4391
+ }
4392
+ if (emptyAccount) {
4393
+ return actionError(
4394
+ action,
4395
+ "We couldn't read an address from that wallet. Please reconnect and make sure an account is selected."
4273
4396
  );
4274
4397
  }
4275
4398
  if (action.metadata?.chainFamily === "svm") {
@@ -6975,18 +7098,6 @@ function updateTrackedSession(sessions, ownerSessionId, reportedSession, actionS
6975
7098
  }
6976
7099
  }
6977
7100
 
6978
- // src/walletFlow.ts
6979
- var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
6980
- function isMobileUserAgent(userAgent) {
6981
- if (!userAgent) {
6982
- return false;
6983
- }
6984
- return MOBILE_USER_AGENT_PATTERN.test(userAgent);
6985
- }
6986
- function shouldUseWalletConnector(options) {
6987
- return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
6988
- }
6989
-
6990
7101
  // src/enterAmountInput.ts
6991
7102
  var MAX_FRACTION_DIGITS = 2;
6992
7103
  function isDigit(value) {
@@ -8586,6 +8697,52 @@ var buttonStyle = (color, hovered) => ({
8586
8697
  flexShrink: 0,
8587
8698
  transition: "background 0.15s ease"
8588
8699
  });
8700
+ var INTERCOM_HELP_URL = "https://intercom.help/blinkcash/en/";
8701
+ var TERMS_URL = "https://blink.cash/terms";
8702
+ function SupportFooter() {
8703
+ const { tokens } = useBlinkConfig();
8704
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle2(tokens.textMuted), children: [
8705
+ /* @__PURE__ */ jsxRuntime.jsx(
8706
+ "a",
8707
+ {
8708
+ href: INTERCOM_HELP_URL,
8709
+ target: "_blank",
8710
+ rel: "noopener noreferrer",
8711
+ style: linkStyle(tokens.textMuted),
8712
+ children: "Help"
8713
+ }
8714
+ ),
8715
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: dotStyle(tokens.textTertiary), children: "\u2022" }),
8716
+ /* @__PURE__ */ jsxRuntime.jsx(
8717
+ "a",
8718
+ {
8719
+ href: TERMS_URL,
8720
+ target: "_blank",
8721
+ rel: "noopener noreferrer",
8722
+ style: linkStyle(tokens.textMuted),
8723
+ children: "Terms"
8724
+ }
8725
+ )
8726
+ ] });
8727
+ }
8728
+ var containerStyle2 = (color) => ({
8729
+ display: "flex",
8730
+ alignItems: "center",
8731
+ justifyContent: "center",
8732
+ gap: 10,
8733
+ fontSize: "0.8rem",
8734
+ color,
8735
+ padding: "4px 0"
8736
+ });
8737
+ var linkStyle = (color) => ({
8738
+ color,
8739
+ fontWeight: 500,
8740
+ textDecoration: "none"
8741
+ });
8742
+ var dotStyle = (color) => ({
8743
+ color,
8744
+ fontSize: "0.8rem"
8745
+ });
8589
8746
  function SettingsMenu({ onLogout }) {
8590
8747
  const { tokens } = useBlinkConfig();
8591
8748
  const [open, setOpen] = react.useState(false);
@@ -8601,7 +8758,7 @@ function SettingsMenu({ onLogout }) {
8601
8758
  document.addEventListener("mousedown", handleClickOutside);
8602
8759
  return () => document.removeEventListener("mousedown", handleClickOutside);
8603
8760
  }, [open]);
8604
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: menuRef, style: containerStyle2, children: [
8761
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: menuRef, style: containerStyle3, children: [
8605
8762
  /* @__PURE__ */ jsxRuntime.jsx(IconButton, { onClick: toggle, "aria-label": "Settings", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: [
8606
8763
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "5", r: "2", fill: "currentColor" }),
8607
8764
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor" }),
@@ -8611,7 +8768,7 @@ function SettingsMenu({ onLogout }) {
8611
8768
  /* @__PURE__ */ jsxRuntime.jsxs(
8612
8769
  "a",
8613
8770
  {
8614
- href: "https://intercom.help/blinkcash/en/",
8771
+ href: INTERCOM_HELP_URL,
8615
8772
  target: "_blank",
8616
8773
  rel: "noopener noreferrer",
8617
8774
  onClick: () => setOpen(false),
@@ -8648,7 +8805,7 @@ function SettingsMenu({ onLogout }) {
8648
8805
  ] })
8649
8806
  ] });
8650
8807
  }
8651
- var containerStyle2 = {
8808
+ var containerStyle3 = {
8652
8809
  position: "relative"
8653
8810
  };
8654
8811
  var dropdownStyle = (tokens) => ({
@@ -8738,7 +8895,7 @@ var badgeStyle = (color) => ({
8738
8895
  });
8739
8896
  function PoweredByFooter() {
8740
8897
  const { tokens } = useBlinkConfig();
8741
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle3(tokens.textMuted), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
8898
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle4(tokens.textMuted), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
8742
8899
  /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
8743
8900
  "path",
8744
8901
  {
@@ -8749,7 +8906,7 @@ function PoweredByFooter() {
8749
8906
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Powered by Blink" })
8750
8907
  ] }) });
8751
8908
  }
8752
- var containerStyle3 = (color) => ({
8909
+ var containerStyle4 = (color) => ({
8753
8910
  display: "flex",
8754
8911
  flexDirection: "column",
8755
8912
  alignItems: "center",
@@ -9459,12 +9616,12 @@ var defaultIcon = /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "
9459
9616
  ) });
9460
9617
  function InfoBanner({ children, icon }) {
9461
9618
  const { tokens } = useBlinkConfig();
9462
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle4(tokens.accent), children: [
9619
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle5(tokens.accent), children: [
9463
9620
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: iconStyle, children: icon ?? defaultIcon }),
9464
9621
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: textStyle, children })
9465
9622
  ] });
9466
9623
  }
9467
- var containerStyle4 = (accent) => ({
9624
+ var containerStyle5 = (accent) => ({
9468
9625
  display: "flex",
9469
9626
  alignItems: "flex-start",
9470
9627
  gap: 10,
@@ -9482,7 +9639,7 @@ var iconStyle = {
9482
9639
  };
9483
9640
  var textStyle = { flex: 1 };
9484
9641
  function WarningBanner({ title, children }) {
9485
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle5, children: [
9642
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle6, children: [
9486
9643
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle2, children: [
9487
9644
  /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", style: iconStyle2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z", fill: "#F57C00" }) }),
9488
9645
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: title })
@@ -9490,7 +9647,7 @@ function WarningBanner({ title, children }) {
9490
9647
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: bodyStyle2, children })
9491
9648
  ] });
9492
9649
  }
9493
- var containerStyle5 = {
9650
+ var containerStyle6 = {
9494
9651
  padding: "14px 16px",
9495
9652
  background: "#FFF8E1",
9496
9653
  border: "1px solid #FFE082",
@@ -9540,7 +9697,7 @@ function NotificationBanner({
9540
9697
  }) {
9541
9698
  const { tokens } = useBlinkConfig();
9542
9699
  const color = variant === "negative" ? NEGATIVE_FG : tokens.text;
9543
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle6(tokens.bgRecessed), children: [
9700
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle7(tokens.bgRecessed), children: [
9544
9701
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...iconWrapStyle2, color }, children: icon ?? defaultIcon2 }),
9545
9702
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { ...textColStyle, color }, children: [
9546
9703
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: titleStyle3, children: title }),
@@ -9548,7 +9705,7 @@ function NotificationBanner({
9548
9705
  ] })
9549
9706
  ] });
9550
9707
  }
9551
- var containerStyle6 = (bg) => ({
9708
+ var containerStyle7 = (bg) => ({
9552
9709
  display: "flex",
9553
9710
  alignItems: "flex-start",
9554
9711
  gap: 16,
@@ -9643,7 +9800,7 @@ function OtpInput({ value, onChange, length = 6, disabled }) {
9643
9800
  onChange(pasted);
9644
9801
  focusInput(Math.min(pasted.length, length - 1));
9645
9802
  }, [onChange, length, focusInput]);
9646
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle7, children: digits.map((digit, i) => /* @__PURE__ */ jsxRuntime.jsx(
9803
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle8, children: digits.map((digit, i) => /* @__PURE__ */ jsxRuntime.jsx(
9647
9804
  "input",
9648
9805
  {
9649
9806
  ref: (el) => {
@@ -9664,7 +9821,7 @@ function OtpInput({ value, onChange, length = 6, disabled }) {
9664
9821
  i
9665
9822
  )) });
9666
9823
  }
9667
- var containerStyle7 = {
9824
+ var containerStyle8 = {
9668
9825
  display: "flex",
9669
9826
  gap: 8,
9670
9827
  justifyContent: "center",
@@ -11130,7 +11287,8 @@ function LoginScreen({
11130
11287
  style: secondaryTextStyle(tokens, loading),
11131
11288
  children: secondaryLabel
11132
11289
  }
11133
- )
11290
+ ),
11291
+ /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {})
11134
11292
  ] }),
11135
11293
  children: [
11136
11294
  /* @__PURE__ */ jsxRuntime.jsx(ScreenHeader, { onBack, right: headerRight }),
@@ -11302,7 +11460,7 @@ function DepositOptionsScreen({
11302
11460
  const { tokens, promoTagText } = useBlinkConfig();
11303
11461
  const [manualHovered, setManualHovered] = react.useState(false);
11304
11462
  const [manualPressed, setManualPressed] = react.useState(false);
11305
- return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { hideScrollbar: true, children: [
11463
+ return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { hideScrollbar: true, footer: /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {}), children: [
11306
11464
  /* @__PURE__ */ jsxRuntime.jsx(
11307
11465
  ScreenHeader,
11308
11466
  {
@@ -11457,7 +11615,7 @@ function WelcomeBackScreen({
11457
11615
  const [depositPressed, setDepositPressed] = react.useState(false);
11458
11616
  const [manualHovered, setManualHovered] = react.useState(false);
11459
11617
  const [manualPressed, setManualPressed] = react.useState(false);
11460
- return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
11618
+ return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {}), children: [
11461
11619
  /* @__PURE__ */ jsxRuntime.jsx(
11462
11620
  ScreenHeader,
11463
11621
  {
@@ -15170,7 +15328,7 @@ function DepositAddressScreen({
15170
15328
  const waitingForQr = !!depositAddress && !qrReady;
15171
15329
  const awaitingSession = !!selectedOption && !session && !loading;
15172
15330
  const showShimmer = loadingSources || showLoading || waitingForQr || awaitingSession;
15173
- return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { children: [
15331
+ return /* @__PURE__ */ jsxRuntime.jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsxRuntime.jsx(SupportFooter, {}), children: [
15174
15332
  /* @__PURE__ */ jsxRuntime.jsx(
15175
15333
  ScreenHeader,
15176
15334
  {