@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.js CHANGED
@@ -612,6 +612,21 @@ function resolveSelectSourceOption(choices, options, chainName, tokenSymbol, rec
612
612
  ));
613
613
  }
614
614
 
615
+ // src/walletFlow.ts
616
+ var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
617
+ function isMobileUserAgent(userAgent) {
618
+ if (!userAgent) {
619
+ return false;
620
+ }
621
+ return MOBILE_USER_AGENT_PATTERN.test(userAgent);
622
+ }
623
+ function shouldUseWalletConnector(options) {
624
+ return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
625
+ }
626
+ function resolveCoinbasePreferenceOptions(userAgent) {
627
+ return isMobileUserAgent(userAgent) ? "all" : "eoaOnly";
628
+ }
629
+
615
630
  // src/walletBridge/protocol.ts
616
631
  var BRIDGE_PROTOCOL_VERSION = 1;
617
632
  function parseBridgeMessage(data) {
@@ -982,18 +997,28 @@ function FingerprintVisitorPing() {
982
997
  return null;
983
998
  }
984
999
  function buildStaticConnectors() {
1000
+ const userAgent = typeof navigator === "undefined" ? null : navigator.userAgent;
985
1001
  return [
986
1002
  // `unstable_shimAsyncInject` covers wallets whose content scripts wire
987
1003
  // up after page load (Phantom, Trust, MetaMask in the iframe).
988
1004
  injected({ unstable_shimAsyncInject: 2e3 }),
989
- // `preference: 'all'` (default) lets the Coinbase Wallet SDK prefer an
990
- // injected provider when one is present. This matters inside Base's
991
- // mobile in-app WebView: with `smartWalletOnly`, the SDK routes signing
992
- // through `keys.coinbase.com`, which in an iOS WKWebView navigates the
993
- // webview itself (full page reload after each signature). With `all`,
994
- // the SDK uses the Base WebView's injected `window.ethereum` directly,
995
- // keeping signing in-process. Desktop/extension users are unaffected.
996
- coinbaseWallet({ appName: "Swype", preference: { options: "all" } })
1005
+ // Coinbase Wallet SDK connection preference is platform-specific
1006
+ // (see `resolveCoinbasePreferenceOptions`):
1007
+ // Desktop → `eoaOnly`: in smart-wallet mode the Base extension hands
1008
+ // the dapp a separate, often-empty smart-wallet account instead of the
1009
+ // user's funded EOA "no assets". `eoaOnly` binds the funded EOA.
1010
+ // Mobile (Base in-app WebView) `all`: signing must use the injected
1011
+ // `window.ethereum`; the SDK path reloads the iOS WKWebView after each
1012
+ // signature.
1013
+ //
1014
+ // Exactly ONE Coinbase connector: two `@coinbase/wallet-sdk` instances in
1015
+ // one page collide on shared `window` listeners + the Communicator (Privy
1016
+ // connector-init timeout, listener leaks, duplicated `client-project-name`
1017
+ // that 400s the connect), so we never register a second one.
1018
+ coinbaseWallet({
1019
+ appName: "Blink",
1020
+ preference: { options: resolveCoinbasePreferenceOptions(userAgent) }
1021
+ })
997
1022
  ];
998
1023
  }
999
1024
  function buildWagmiConfig(bridgedWallets) {
@@ -1143,9 +1168,10 @@ function buildTargetMatchers(target) {
1143
1168
  aliases.add("io.metamask");
1144
1169
  }
1145
1170
  if (value === "base" || value === "base account" || value === "base app" || value.includes("coinbase")) {
1146
- aliases.add("base");
1147
1171
  aliases.add("coinbase");
1148
1172
  aliases.add("coinbasewalletsdk");
1173
+ aliases.add("com.coinbase.wallet");
1174
+ aliases.add("baseaccount");
1149
1175
  }
1150
1176
  if (value.includes("trust")) {
1151
1177
  aliases.add("trust");
@@ -1219,19 +1245,70 @@ async function withTimeout(promise, ms, label) {
1219
1245
  if (timer !== void 0) clearTimeout(timer);
1220
1246
  }
1221
1247
  }
1222
- function isReloadingCoinbaseConnector(connector) {
1248
+ function isCoinbaseSdkConnector(connector) {
1223
1249
  if (!connector) return false;
1224
1250
  return connectorMatchesWallet(
1225
1251
  { id: connector.id, name: connector.name ?? "" },
1226
1252
  { wagmiConnectorId: "coinbaseWalletSDK" }
1227
1253
  );
1228
1254
  }
1255
+ var COINBASE_SDK_STORAGE_PREFIXES = ["-CBWSDK", "-walletlink"];
1256
+ var COINBASE_SIGNER_TYPE_STORAGE_KEY = "-CBWSDK:SignerConfigurator:SignerType";
1257
+ function loadCoinbaseSignerType() {
1258
+ if (typeof window === "undefined" || !window.localStorage) return null;
1259
+ try {
1260
+ return window.localStorage.getItem(COINBASE_SIGNER_TYPE_STORAGE_KEY);
1261
+ } catch {
1262
+ return null;
1263
+ }
1264
+ }
1265
+ function clearCoinbaseWalletSdkSession() {
1266
+ if (typeof window === "undefined" || !window.localStorage) return;
1267
+ try {
1268
+ const store = window.localStorage;
1269
+ const keysToRemove = [];
1270
+ for (let i = 0; i < store.length; i += 1) {
1271
+ const key = store.key(i);
1272
+ if (key && COINBASE_SDK_STORAGE_PREFIXES.some((prefix) => key.startsWith(prefix))) {
1273
+ keysToRemove.push(key);
1274
+ }
1275
+ }
1276
+ keysToRemove.forEach((key) => store.removeItem(key));
1277
+ console.info("[blink-sdk][disconnect] cleared Coinbase Wallet SDK session", {
1278
+ clearedKeys: keysToRemove.length
1279
+ });
1280
+ } catch (err) {
1281
+ console.info("[blink-sdk][disconnect] failed to clear Coinbase Wallet SDK session", err);
1282
+ }
1283
+ }
1284
+ function resetWagmiConnectionInMemory(wagmiConfig, connector) {
1285
+ if (!connector) return;
1286
+ try {
1287
+ const target = connector;
1288
+ const connections = [...wagmiConfig.state.connections.values()];
1289
+ const match = connections.find((conn) => {
1290
+ const live2 = conn.connector;
1291
+ if (target.uid && live2.uid) return live2.uid === target.uid;
1292
+ return live2.id === target.id;
1293
+ });
1294
+ const live = match?.connector;
1295
+ if (!live?.emitter) return;
1296
+ live.emitter.emit("disconnect");
1297
+ console.info("[blink-sdk][disconnect] reset wagmi in-memory connection via emitter", {
1298
+ connectorId: live.id
1299
+ });
1300
+ } catch (err) {
1301
+ console.info("[blink-sdk][disconnect] failed to reset wagmi in-memory connection", err);
1302
+ }
1303
+ }
1229
1304
  async function safeDisconnect(wagmiConfig, connector) {
1230
- if (isReloadingCoinbaseConnector(connector)) {
1305
+ if (isCoinbaseSdkConnector(connector)) {
1231
1306
  console.info(
1232
- "[blink-sdk][disconnect] skipping wagmi disconnect for Coinbase WalletLink connector",
1307
+ "[blink-sdk][disconnect] clearing Coinbase Wallet SDK session instead of wagmi disconnect",
1233
1308
  { connectorId: connector?.id }
1234
1309
  );
1310
+ clearCoinbaseWalletSdkSession();
1311
+ resetWagmiConnectionInMemory(wagmiConfig, connector);
1235
1312
  return;
1236
1313
  }
1237
1314
  await disconnect(wagmiConfig, { connector }).catch(() => {
@@ -3885,6 +3962,23 @@ function isUserRejection(msg) {
3885
3962
  const lower = msg.toLowerCase();
3886
3963
  return lower.includes("rejected") || lower.includes("denied");
3887
3964
  }
3965
+ var EmptyConnectionAccountError = class extends Error {
3966
+ constructor(message = "Wallet connected but returned no account address.") {
3967
+ super(message);
3968
+ this.name = "EmptyConnectionAccountError";
3969
+ }
3970
+ };
3971
+ var EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
3972
+ function assertNonEmptyConnectedAddress(address, ctx) {
3973
+ if (typeof address === "string" && EVM_ADDRESS_RE.test(address)) {
3974
+ return;
3975
+ }
3976
+ appendDebug("error", "OPEN_PROVIDER: empty-or-invalid-connected-address", {
3977
+ ...ctx,
3978
+ address: address ?? null
3979
+ });
3980
+ throw new EmptyConnectionAccountError();
3981
+ }
3888
3982
  function requiresExplicitEvmNonce(account) {
3889
3983
  return connectorMatchesWallet(account?.connector, { providerName: "trust" }) || connectorMatchesWallet(account?.connector, { providerName: "phantom" });
3890
3984
  }
@@ -4118,7 +4212,8 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4118
4212
  accountConnectorId: account.connector?.id ?? null,
4119
4213
  accountConnectorName: account.connector?.name ?? null,
4120
4214
  targetId: targetId ?? null,
4121
- resolvedConnectorId: connector?.id ?? null
4215
+ resolvedConnectorId: connector?.id ?? null,
4216
+ availableConnectorIds: connectors.map((c) => c.id)
4122
4217
  };
4123
4218
  let disconnectedMismatchedConnector = false;
4124
4219
  if (account.isConnected && account.address) {
@@ -4126,6 +4221,7 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4126
4221
  if (connectorMatchesTarget) {
4127
4222
  const hexChainId2 = account.chainId ? `0x${account.chainId.toString(16)}` : void 0;
4128
4223
  const branch = !targetId ? "early-return-no-target" : "early-return-connector-match";
4224
+ assertNonEmptyConnectedAddress(account.address, { ...logContext, branch });
4129
4225
  console.info("[blink-sdk][open-provider] Skipping connectAsync; wagmi already connected.", {
4130
4226
  ...logContext,
4131
4227
  branch
@@ -4149,6 +4245,20 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4149
4245
  disconnectedMismatchedConnector = true;
4150
4246
  }
4151
4247
  if (!disconnectedMismatchedConnector) {
4248
+ const targetIsCoinbase = connectorMatchesWallet(connector, {
4249
+ wagmiConnectorId: "coinbaseWalletSDK"
4250
+ });
4251
+ const isDesktopUa = !isMobileUserAgent(
4252
+ typeof navigator === "undefined" ? null : navigator.userAgent
4253
+ );
4254
+ if (targetIsCoinbase && isDesktopUa && loadCoinbaseSignerType() === "scw") {
4255
+ console.info(
4256
+ "[blink-sdk][open-provider] Clearing stale Coinbase Smart Wallet (scw) session before reconnect so eoaOnly binds the EOA.",
4257
+ logContext
4258
+ );
4259
+ appendDebug("info", "OPEN_PROVIDER: clearing stale scw session before reconnect", logContext);
4260
+ clearCoinbaseWalletSdkSession();
4261
+ }
4152
4262
  console.info("[blink-sdk][open-provider] Attempting silent reconnect.", logContext);
4153
4263
  appendDebug("info", "OPEN_PROVIDER: attempting silent reconnect", logContext);
4154
4264
  const reconnections = await reconnect(wagmiConfig).catch(() => []);
@@ -4163,6 +4273,7 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4163
4273
  reconnectedConnectorId: reconnectedAccount.connector?.id ?? null,
4164
4274
  reconnectionCount: reconnections.length
4165
4275
  };
4276
+ assertNonEmptyConnectedAddress(reconnectedAccount.address, reconnectLogContext);
4166
4277
  console.info(
4167
4278
  "[blink-sdk][open-provider] Silent reconnect succeeded; skipping connectAsync.",
4168
4279
  reconnectLogContext
@@ -4230,6 +4341,10 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4230
4341
  });
4231
4342
  const result = await connectAsync({ connector });
4232
4343
  const hexChainId = `0x${result.chainId.toString(16)}`;
4344
+ assertNonEmptyConnectedAddress(result.accounts[0], {
4345
+ ...logContext,
4346
+ branch: "connectAsync-result"
4347
+ });
4233
4348
  return actionSuccess(
4234
4349
  action,
4235
4350
  `Connected to ${connector.name}. Account: ${result.accounts[0]}, Chain: ${hexChainId}`,
@@ -4237,15 +4352,23 @@ async function executeOpenProvider(action, wagmiConfig, connectors, connectAsync
4237
4352
  );
4238
4353
  } catch (err) {
4239
4354
  const msg = err instanceof Error ? err.message : "Failed to connect wallet";
4240
- if (options?.externalAuthorizationAvailable && isUserRejection(msg) && action.metadata?.chainFamily !== "svm") {
4241
- appendDebug("info", "OPEN_PROVIDER: user-rejection-soft-halt", {
4355
+ const emptyAccount = err instanceof EmptyConnectionAccountError;
4356
+ if (options?.externalAuthorizationAvailable && (isUserRejection(msg) || emptyAccount) && action.metadata?.chainFamily !== "svm") {
4357
+ appendDebug("info", "OPEN_PROVIDER: soft-halt", {
4242
4358
  actionId: action.id,
4243
- externalAuthorizationAvailable: true
4359
+ externalAuthorizationAvailable: true,
4360
+ reason: emptyAccount ? "empty-account" : "user-rejection"
4244
4361
  });
4245
4362
  return actionPending(
4246
4363
  action,
4247
4364
  "awaiting-external-authorization",
4248
- "Wallet connection prompt dismissed \u2014 awaiting completion via cross-device authorization."
4365
+ emptyAccount ? "Wallet returned no account \u2014 awaiting completion via cross-device authorization." : "Wallet connection prompt dismissed \u2014 awaiting completion via cross-device authorization."
4366
+ );
4367
+ }
4368
+ if (emptyAccount) {
4369
+ return actionError(
4370
+ action,
4371
+ "We couldn't read an address from that wallet. Please reconnect and make sure an account is selected."
4249
4372
  );
4250
4373
  }
4251
4374
  if (action.metadata?.chainFamily === "svm") {
@@ -6951,18 +7074,6 @@ function updateTrackedSession(sessions, ownerSessionId, reportedSession, actionS
6951
7074
  }
6952
7075
  }
6953
7076
 
6954
- // src/walletFlow.ts
6955
- var MOBILE_USER_AGENT_PATTERN = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
6956
- function isMobileUserAgent(userAgent) {
6957
- if (!userAgent) {
6958
- return false;
6959
- }
6960
- return MOBILE_USER_AGENT_PATTERN.test(userAgent);
6961
- }
6962
- function shouldUseWalletConnector(options) {
6963
- return options.useWalletConnector ?? !isMobileUserAgent(options.userAgent);
6964
- }
6965
-
6966
7077
  // src/enterAmountInput.ts
6967
7078
  var MAX_FRACTION_DIGITS = 2;
6968
7079
  function isDigit(value) {
@@ -8562,6 +8673,52 @@ var buttonStyle = (color, hovered) => ({
8562
8673
  flexShrink: 0,
8563
8674
  transition: "background 0.15s ease"
8564
8675
  });
8676
+ var INTERCOM_HELP_URL = "https://intercom.help/blinkcash/en/";
8677
+ var TERMS_URL = "https://blink.cash/terms";
8678
+ function SupportFooter() {
8679
+ const { tokens } = useBlinkConfig();
8680
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle2(tokens.textMuted), children: [
8681
+ /* @__PURE__ */ jsx(
8682
+ "a",
8683
+ {
8684
+ href: INTERCOM_HELP_URL,
8685
+ target: "_blank",
8686
+ rel: "noopener noreferrer",
8687
+ style: linkStyle(tokens.textMuted),
8688
+ children: "Help"
8689
+ }
8690
+ ),
8691
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: dotStyle(tokens.textTertiary), children: "\u2022" }),
8692
+ /* @__PURE__ */ jsx(
8693
+ "a",
8694
+ {
8695
+ href: TERMS_URL,
8696
+ target: "_blank",
8697
+ rel: "noopener noreferrer",
8698
+ style: linkStyle(tokens.textMuted),
8699
+ children: "Terms"
8700
+ }
8701
+ )
8702
+ ] });
8703
+ }
8704
+ var containerStyle2 = (color) => ({
8705
+ display: "flex",
8706
+ alignItems: "center",
8707
+ justifyContent: "center",
8708
+ gap: 10,
8709
+ fontSize: "0.8rem",
8710
+ color,
8711
+ padding: "4px 0"
8712
+ });
8713
+ var linkStyle = (color) => ({
8714
+ color,
8715
+ fontWeight: 500,
8716
+ textDecoration: "none"
8717
+ });
8718
+ var dotStyle = (color) => ({
8719
+ color,
8720
+ fontSize: "0.8rem"
8721
+ });
8565
8722
  function SettingsMenu({ onLogout }) {
8566
8723
  const { tokens } = useBlinkConfig();
8567
8724
  const [open, setOpen] = useState(false);
@@ -8577,7 +8734,7 @@ function SettingsMenu({ onLogout }) {
8577
8734
  document.addEventListener("mousedown", handleClickOutside);
8578
8735
  return () => document.removeEventListener("mousedown", handleClickOutside);
8579
8736
  }, [open]);
8580
- return /* @__PURE__ */ jsxs("div", { ref: menuRef, style: containerStyle2, children: [
8737
+ return /* @__PURE__ */ jsxs("div", { ref: menuRef, style: containerStyle3, children: [
8581
8738
  /* @__PURE__ */ jsx(IconButton, { onClick: toggle, "aria-label": "Settings", children: /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: [
8582
8739
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "5", r: "2", fill: "currentColor" }),
8583
8740
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor" }),
@@ -8587,7 +8744,7 @@ function SettingsMenu({ onLogout }) {
8587
8744
  /* @__PURE__ */ jsxs(
8588
8745
  "a",
8589
8746
  {
8590
- href: "https://intercom.help/blinkcash/en/",
8747
+ href: INTERCOM_HELP_URL,
8591
8748
  target: "_blank",
8592
8749
  rel: "noopener noreferrer",
8593
8750
  onClick: () => setOpen(false),
@@ -8624,7 +8781,7 @@ function SettingsMenu({ onLogout }) {
8624
8781
  ] })
8625
8782
  ] });
8626
8783
  }
8627
- var containerStyle2 = {
8784
+ var containerStyle3 = {
8628
8785
  position: "relative"
8629
8786
  };
8630
8787
  var dropdownStyle = (tokens) => ({
@@ -8714,7 +8871,7 @@ var badgeStyle = (color) => ({
8714
8871
  });
8715
8872
  function PoweredByFooter() {
8716
8873
  const { tokens } = useBlinkConfig();
8717
- return /* @__PURE__ */ jsx("div", { style: containerStyle3(tokens.textMuted), children: /* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
8874
+ return /* @__PURE__ */ jsx("div", { style: containerStyle4(tokens.textMuted), children: /* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
8718
8875
  /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
8719
8876
  "path",
8720
8877
  {
@@ -8725,7 +8882,7 @@ function PoweredByFooter() {
8725
8882
  /* @__PURE__ */ jsx("span", { children: "Powered by Blink" })
8726
8883
  ] }) });
8727
8884
  }
8728
- var containerStyle3 = (color) => ({
8885
+ var containerStyle4 = (color) => ({
8729
8886
  display: "flex",
8730
8887
  flexDirection: "column",
8731
8888
  alignItems: "center",
@@ -9435,12 +9592,12 @@ var defaultIcon = /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBo
9435
9592
  ) });
9436
9593
  function InfoBanner({ children, icon }) {
9437
9594
  const { tokens } = useBlinkConfig();
9438
- return /* @__PURE__ */ jsxs("div", { style: containerStyle4(tokens.accent), children: [
9595
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle5(tokens.accent), children: [
9439
9596
  /* @__PURE__ */ jsx("span", { style: iconStyle, children: icon ?? defaultIcon }),
9440
9597
  /* @__PURE__ */ jsx("span", { style: textStyle, children })
9441
9598
  ] });
9442
9599
  }
9443
- var containerStyle4 = (accent) => ({
9600
+ var containerStyle5 = (accent) => ({
9444
9601
  display: "flex",
9445
9602
  alignItems: "flex-start",
9446
9603
  gap: 10,
@@ -9458,7 +9615,7 @@ var iconStyle = {
9458
9615
  };
9459
9616
  var textStyle = { flex: 1 };
9460
9617
  function WarningBanner({ title, children }) {
9461
- return /* @__PURE__ */ jsxs("div", { style: containerStyle5, children: [
9618
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle6, children: [
9462
9619
  /* @__PURE__ */ jsxs("div", { style: headerStyle2, children: [
9463
9620
  /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", style: iconStyle2, children: /* @__PURE__ */ jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z", fill: "#F57C00" }) }),
9464
9621
  /* @__PURE__ */ jsx("strong", { children: title })
@@ -9466,7 +9623,7 @@ function WarningBanner({ title, children }) {
9466
9623
  /* @__PURE__ */ jsx("div", { style: bodyStyle2, children })
9467
9624
  ] });
9468
9625
  }
9469
- var containerStyle5 = {
9626
+ var containerStyle6 = {
9470
9627
  padding: "14px 16px",
9471
9628
  background: "#FFF8E1",
9472
9629
  border: "1px solid #FFE082",
@@ -9516,7 +9673,7 @@ function NotificationBanner({
9516
9673
  }) {
9517
9674
  const { tokens } = useBlinkConfig();
9518
9675
  const color = variant === "negative" ? NEGATIVE_FG : tokens.text;
9519
- return /* @__PURE__ */ jsxs("div", { style: containerStyle6(tokens.bgRecessed), children: [
9676
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle7(tokens.bgRecessed), children: [
9520
9677
  /* @__PURE__ */ jsx("span", { style: { ...iconWrapStyle2, color }, children: icon ?? defaultIcon2 }),
9521
9678
  /* @__PURE__ */ jsxs("div", { style: { ...textColStyle, color }, children: [
9522
9679
  /* @__PURE__ */ jsx("p", { style: titleStyle3, children: title }),
@@ -9524,7 +9681,7 @@ function NotificationBanner({
9524
9681
  ] })
9525
9682
  ] });
9526
9683
  }
9527
- var containerStyle6 = (bg) => ({
9684
+ var containerStyle7 = (bg) => ({
9528
9685
  display: "flex",
9529
9686
  alignItems: "flex-start",
9530
9687
  gap: 16,
@@ -9619,7 +9776,7 @@ function OtpInput({ value, onChange, length = 6, disabled }) {
9619
9776
  onChange(pasted);
9620
9777
  focusInput(Math.min(pasted.length, length - 1));
9621
9778
  }, [onChange, length, focusInput]);
9622
- return /* @__PURE__ */ jsx("div", { style: containerStyle7, children: digits.map((digit, i) => /* @__PURE__ */ jsx(
9779
+ return /* @__PURE__ */ jsx("div", { style: containerStyle8, children: digits.map((digit, i) => /* @__PURE__ */ jsx(
9623
9780
  "input",
9624
9781
  {
9625
9782
  ref: (el) => {
@@ -9640,7 +9797,7 @@ function OtpInput({ value, onChange, length = 6, disabled }) {
9640
9797
  i
9641
9798
  )) });
9642
9799
  }
9643
- var containerStyle7 = {
9800
+ var containerStyle8 = {
9644
9801
  display: "flex",
9645
9802
  gap: 8,
9646
9803
  justifyContent: "center",
@@ -11106,7 +11263,8 @@ function LoginScreen({
11106
11263
  style: secondaryTextStyle(tokens, loading),
11107
11264
  children: secondaryLabel
11108
11265
  }
11109
- )
11266
+ ),
11267
+ /* @__PURE__ */ jsx(SupportFooter, {})
11110
11268
  ] }),
11111
11269
  children: [
11112
11270
  /* @__PURE__ */ jsx(ScreenHeader, { onBack, right: headerRight }),
@@ -11278,7 +11436,7 @@ function DepositOptionsScreen({
11278
11436
  const { tokens, promoTagText } = useBlinkConfig();
11279
11437
  const [manualHovered, setManualHovered] = useState(false);
11280
11438
  const [manualPressed, setManualPressed] = useState(false);
11281
- return /* @__PURE__ */ jsxs(ScreenLayout, { hideScrollbar: true, children: [
11439
+ return /* @__PURE__ */ jsxs(ScreenLayout, { hideScrollbar: true, footer: /* @__PURE__ */ jsx(SupportFooter, {}), children: [
11282
11440
  /* @__PURE__ */ jsx(
11283
11441
  ScreenHeader,
11284
11442
  {
@@ -11433,7 +11591,7 @@ function WelcomeBackScreen({
11433
11591
  const [depositPressed, setDepositPressed] = useState(false);
11434
11592
  const [manualHovered, setManualHovered] = useState(false);
11435
11593
  const [manualPressed, setManualPressed] = useState(false);
11436
- return /* @__PURE__ */ jsxs(ScreenLayout, { children: [
11594
+ return /* @__PURE__ */ jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsx(SupportFooter, {}), children: [
11437
11595
  /* @__PURE__ */ jsx(
11438
11596
  ScreenHeader,
11439
11597
  {
@@ -15146,7 +15304,7 @@ function DepositAddressScreen({
15146
15304
  const waitingForQr = !!depositAddress && !qrReady;
15147
15305
  const awaitingSession = !!selectedOption && !session && !loading;
15148
15306
  const showShimmer = loadingSources || showLoading || waitingForQr || awaitingSession;
15149
- return /* @__PURE__ */ jsxs(ScreenLayout, { children: [
15307
+ return /* @__PURE__ */ jsxs(ScreenLayout, { footer: /* @__PURE__ */ jsx(SupportFooter, {}), children: [
15150
15308
  /* @__PURE__ */ jsx(
15151
15309
  ScreenHeader,
15152
15310
  {