@openfort/react 1.3.0 → 1.5.0

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.
Files changed (80) hide show
  1. package/build/components/Common/Modal/styles.js +3 -0
  2. package/build/components/Common/Modal/styles.js.map +1 -1
  3. package/build/components/Common/ScrollArea/index.d.ts +5 -1
  4. package/build/components/Common/ScrollArea/index.js +2 -2
  5. package/build/components/Common/ScrollArea/styles.d.ts +4 -1
  6. package/build/components/Common/ScrollArea/styles.js +19 -4
  7. package/build/components/Common/ScrollArea/styles.js.map +1 -1
  8. package/build/components/ConnectModal/index.js +15 -5
  9. package/build/components/ConnectModal/index.js.map +1 -1
  10. package/build/components/PageContent/index.d.ts +2 -1
  11. package/build/components/PageContent/index.js +2 -2
  12. package/build/components/Pages/BuyProviderSelect/styles.d.ts +2 -1
  13. package/build/components/Pages/Connected/EthereumConnected.js +7 -3
  14. package/build/components/Pages/Connected/EthereumConnected.js.map +1 -1
  15. package/build/components/Pages/Deposit/AssetChainLogo.d.ts +5 -2
  16. package/build/components/Pages/Deposit/AssetChainLogo.js +21 -4
  17. package/build/components/Pages/Deposit/AssetChainLogo.js.map +1 -1
  18. package/build/components/Pages/Deposit/DepositAddressBlock.js +1 -1
  19. package/build/components/Pages/Deposit/RouteSelectors.js +11 -1
  20. package/build/components/Pages/Deposit/RouteSelectors.js.map +1 -1
  21. package/build/components/Pages/Deposit/SameChainDepositStatus.d.ts +7 -0
  22. package/build/components/Pages/Deposit/SameChainDepositStatus.js +34 -0
  23. package/build/components/Pages/Deposit/SameChainDepositStatus.js.map +1 -0
  24. package/build/components/Pages/Deposit/SameChainDepositSuccess.d.ts +11 -0
  25. package/build/components/Pages/Deposit/SameChainDepositSuccess.js +30 -0
  26. package/build/components/Pages/Deposit/SameChainDepositSuccess.js.map +1 -0
  27. package/build/components/Pages/Deposit/TestnetNotice.d.ts +10 -0
  28. package/build/components/Pages/Deposit/TestnetNotice.js +131 -0
  29. package/build/components/Pages/Deposit/TestnetNotice.js.map +1 -0
  30. package/build/components/Pages/Deposit/UnsupportedNetworkNotice.d.ts +12 -0
  31. package/build/components/Pages/Deposit/UnsupportedNetworkNotice.js +111 -0
  32. package/build/components/Pages/Deposit/UnsupportedNetworkNotice.js.map +1 -0
  33. package/build/components/Pages/Deposit/index.js +20 -4
  34. package/build/components/Pages/Deposit/index.js.map +1 -1
  35. package/build/components/Pages/Deposit/paymentOptions.d.ts +6 -0
  36. package/build/components/Pages/Deposit/paymentOptions.js +7 -1
  37. package/build/components/Pages/Deposit/paymentOptions.js.map +1 -1
  38. package/build/components/Pages/Deposit/useDepositRoute.d.ts +2 -0
  39. package/build/components/Pages/Deposit/useDepositRoute.js +26 -2
  40. package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -1
  41. package/build/components/Pages/Deposit/useSameChainArrival.d.ts +19 -0
  42. package/build/components/Pages/Deposit/useSameChainArrival.js +86 -0
  43. package/build/components/Pages/Deposit/useSameChainArrival.js.map +1 -0
  44. package/build/components/Pages/DepositCrypto/index.js +26 -3
  45. package/build/components/Pages/DepositCrypto/index.js.map +1 -1
  46. package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +9 -8
  47. package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -1
  48. package/build/components/Pages/DepositWallet/index.js +48 -10
  49. package/build/components/Pages/DepositWallet/index.js.map +1 -1
  50. package/build/components/Pages/SelectToken/styles.d.ts +2 -1
  51. package/build/components/Pages/SendConfirmation/index.js +1 -1
  52. package/build/constants/chainConfigs.js +32 -32
  53. package/build/constants/logos.d.ts +4 -0
  54. package/build/constants/logos.js +25 -1
  55. package/build/constants/logos.js.map +1 -1
  56. package/build/ethereum/hooks/useEthereumWalletAssets.js +39 -3
  57. package/build/ethereum/hooks/useEthereumWalletAssets.js.map +1 -1
  58. package/build/hooks/openfort/useFundingChains.d.ts +6 -0
  59. package/build/hooks/openfort/useFundingChains.js +19 -5
  60. package/build/hooks/openfort/useFundingChains.js.map +1 -1
  61. package/build/hooks/openfort/useUI.d.ts +13 -1
  62. package/build/hooks/openfort/useUI.js +19 -1
  63. package/build/hooks/openfort/useUI.js.map +1 -1
  64. package/build/shared/utils/explorer.js +6 -4
  65. package/build/shared/utils/explorer.js.map +1 -1
  66. package/build/utils/validation.d.ts +9 -0
  67. package/build/utils/validation.js +14 -1
  68. package/build/utils/validation.js.map +1 -1
  69. package/build/version.d.ts +1 -1
  70. package/build/version.js +1 -1
  71. package/build/wagmi/components/ChainSelect/index.js +3 -2
  72. package/build/wagmi/components/ChainSelect/index.js.map +1 -1
  73. package/build/wagmi/components/ChainSelectList/index.js +3 -2
  74. package/build/wagmi/components/ChainSelectList/index.js.map +1 -1
  75. package/build/wagmi/components/SwitchNetworks/index.js +3 -2
  76. package/build/wagmi/components/SwitchNetworks/index.js.map +1 -1
  77. package/build/wagmi/useSwitchChainFiltered.d.ts +199 -0
  78. package/build/wagmi/useSwitchChainFiltered.js +53 -0
  79. package/build/wagmi/useSwitchChainFiltered.js.map +1 -0
  80. package/package.json +1 -1
@@ -0,0 +1,111 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { chainConfigs } from '../../../constants/chainConfigs.js';
3
+ import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
4
+ import styled from '../../../styles/styled/index.js';
5
+ import { useSwitchChainFiltered } from '../../../wagmi/useSwitchChainFiltered.js';
6
+ import Chain from '../../Common/Chain/index.js';
7
+ import { ScrollArea } from '../../Common/ScrollArea/index.js';
8
+ import { isSolana } from './sources.js';
9
+
10
+ /** Readable name for a CAIP-2 chain the rail can't deliver to. */
11
+ function chainName(caip) {
12
+ var _a, _b;
13
+ if (isSolana(caip))
14
+ return 'Solana';
15
+ const id = Number(caip.split(':')[1]);
16
+ return (_b = (_a = chainConfigs.find((c) => c.id === id)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'this network';
17
+ }
18
+ const Card = styled.div `
19
+ text-align: left;
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 10px;
23
+ padding: 14px;
24
+ margin-top: 4px;
25
+ border-radius: 12px;
26
+ background: var(--ck-body-background-secondary, #fafafa);
27
+ border: 1px solid var(--ck-body-divider, #e4e4e7);
28
+ color: var(--ck-body-color);
29
+ `;
30
+ const Title = styled.div `
31
+ font-size: 14px;
32
+ font-weight: 600;
33
+ `;
34
+ const Body = styled.p `
35
+ margin: 0;
36
+ font-size: 13px;
37
+ line-height: 1.45;
38
+ color: var(--ck-body-color-muted, #6b7280);
39
+ `;
40
+ const Label = styled.div `
41
+ font-size: 12px;
42
+ font-weight: 600;
43
+ color: var(--ck-body-color-muted, #6b7280);
44
+ `;
45
+ const SwitchButtons = styled.div `
46
+ display: flex;
47
+ flex-direction: column;
48
+ gap: 8px;
49
+ `;
50
+ const SwitchButton = styled.button `
51
+ appearance: none;
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 10px;
55
+ width: 100%;
56
+ box-sizing: border-box;
57
+ padding: 10px 12px;
58
+ border-radius: 10px;
59
+ border: 1px solid var(--ck-body-divider, #e4e4e7);
60
+ background: var(--ck-body-background, #fff);
61
+ color: var(--ck-body-color);
62
+ font-size: 14px;
63
+ font-weight: 500;
64
+ cursor: pointer;
65
+
66
+ &:hover:not(:disabled) {
67
+ background: var(--ck-secondary-button-hover-background, #f3f3f5);
68
+ }
69
+ &:disabled {
70
+ opacity: 0.55;
71
+ cursor: default;
72
+ }
73
+
74
+ .name {
75
+ flex: 1;
76
+ text-align: left;
77
+ }
78
+ .chevron {
79
+ color: var(--ck-body-color-muted, #6b7280);
80
+ }
81
+ `;
82
+ /**
83
+ * Shown in the deposit flow when the active funding TARGET chain (the embedded
84
+ * wallet's chain) isn't one the rail can deliver to — e.g. Polygon Amoy or a
85
+ * Solana testnet, which Relay's testnet rail doesn't route. Explains why, and
86
+ * (on EVM) offers a one-tap switch to the supported chains. Solana-only contexts
87
+ * have no in-VM switch, so they get the explanation alone.
88
+ */
89
+ function UnsupportedNetworkNotice({ targetChain, railChains, }) {
90
+ const bridge = useEthereumBridge();
91
+ return (jsxs(Card, { children: [jsxs(Title, { children: ["Funding isn't available on ", chainName(targetChain)] }), jsx(Body, { children: isSolana(targetChain)
92
+ ? "Solana isn't supported by the funding rail in test mode. Switch to a supported EVM testnet to add funds."
93
+ : "The funding rail can't deliver to this network. Switch to a supported one to add funds." }), bridge && jsx(SupportedChainSwitcher, { railChains: railChains })] }));
94
+ }
95
+ /**
96
+ * EVM-only: the rail-supported chains the wallet can switch to. Rendered only when
97
+ * an Ethereum bridge is present (wagmi), so the wagmi hook below never runs in a
98
+ * Solana-only provider tree.
99
+ */
100
+ function SupportedChainSwitcher({ railChains }) {
101
+ const { chains, switchChain, isPending } = useSwitchChainFiltered();
102
+ const supported = chains.filter((c) => railChains.some((rc) => rc.id === `eip155:${c.id}`));
103
+ if (supported.length === 0)
104
+ return null;
105
+ return (jsxs(Fragment, { children: [jsx(Label, { children: "Switch to a supported network" }), jsx(ScrollArea, { height: 156, children: jsx(SwitchButtons, { children: supported.map((c) => {
106
+ return (jsxs(SwitchButton, { type: "button", disabled: isPending || !switchChain, onClick: () => switchChain === null || switchChain === void 0 ? void 0 : switchChain({ chainId: c.id }), children: [jsx(Chain, { id: c.id, size: 22 }), jsx("span", { className: "name", children: c.name }), jsx("span", { className: "chevron", "aria-hidden": true, children: "\u203A" })] }, c.id));
107
+ }) }) })] }));
108
+ }
109
+
110
+ export { UnsupportedNetworkNotice };
111
+ //# sourceMappingURL=UnsupportedNetworkNotice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnsupportedNetworkNotice.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,11 +1,13 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { ChainTypeEnum } from '@openfort/openfort-js';
3
+ import { useEffect } from 'react';
3
4
  import { DollarIcon, BuyIcon, WalletIcon, ReceiveIcon, ExternalLinkIcon } from '../../../assets/icons.js';
4
5
  import Logos from '../../../assets/logos.js';
5
6
  import { useFunding } from '../../../hooks/openfort/useFunding.js';
6
7
  import { useFundingChains } from '../../../hooks/openfort/useFundingChains.js';
7
8
  import useIsMobile from '../../../hooks/useIsMobile.js';
8
9
  import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
10
+ import { getPublishableKeyEnvironment } from '../../../utils/validation.js';
9
11
  import { ModalHeading } from '../../Common/Modal/styles.js';
10
12
  import PoweredByFooter from '../../Common/PoweredByFooter/index.js';
11
13
  import { FundingMethod, routes } from '../../Openfort/types.js';
@@ -15,6 +17,9 @@ import { EVM_BUY_CURRENCIES } from '../Buy/evmCurrencies.js';
15
17
  import { SOLANA_BUY_CURRENCIES } from '../Buy/solanaCurrencies.js';
16
18
  import { getPaymentOptions } from './paymentOptions.js';
17
19
  import { DepositContent, OptionList, OptionButton, OptionLeft, OptionIconBadge, OptionInfo, OptionTitle, OptionSubtitle, LogoCluster } from './styles.js';
20
+ import { TestnetNotice } from './TestnetNotice.js';
21
+ import { UnsupportedNetworkNotice } from './UnsupportedNetworkNotice.js';
22
+ import { useFundingTarget } from './useFundingTarget.js';
18
23
 
19
24
  /** The action icon shown in each row's left badge (icons default to 20×20). */
20
25
  const METHOD_ICON = {
@@ -47,14 +52,25 @@ const hideBrokenLogo = (e) => {
47
52
  */
48
53
  const Deposit = () => {
49
54
  var _a;
50
- const { setRoute, setBuyForm, uiConfig } = useOpenfort();
55
+ const { setRoute, setBuyForm, uiConfig, publishableKey, triggerResize } = useOpenfort();
51
56
  const { chainType } = useOpenfortCore();
52
57
  const isMobile = useIsMobile();
53
58
  const { isAvailable } = useFunding();
54
- const { chains } = useFundingChains();
59
+ const { chains, railChains, loading: chainsLoading } = useFundingChains();
60
+ const target = useFundingTarget();
61
+ // The rail can only deliver to chains it lists. If the embedded wallet's target
62
+ // chain (e.g. Polygon Amoy or a Solana testnet) isn't one of them, there's no
63
+ // deposit route at all — show the explanation instead of any method options.
64
+ const targetUnsupported = !chainsLoading && railChains.length > 0 && !railChains.some((c) => c.id === target.chain);
65
+ // Content swaps between the option list and the notice once chains resolve; the
66
+ // modal only re-measures on an explicit resize, so nudge it when that flips.
67
+ useEffect(() => {
68
+ triggerResize();
69
+ }, [targetUnsupported, triggerResize]);
55
70
  const options = getPaymentOptions({
56
71
  isMobile,
57
72
  fundingAvailable: isAvailable,
73
+ testnet: getPublishableKeyEnvironment(publishableKey) === 'test',
58
74
  methods: (_a = uiConfig.funding) === null || _a === void 0 ? void 0 : _a.methods,
59
75
  });
60
76
  // Distinct source-currency logos (USDC, USDT, ETH, …) for the "from address" row.
@@ -104,10 +120,10 @@ const Deposit = () => {
104
120
  }));
105
121
  setRoute(routes.BUY);
106
122
  };
107
- return (jsxs(PageContent, { onBack: routes.CONNECTED, children: [jsx(ModalHeading, { children: "Add funds" }), jsx(DepositContent, { children: jsx(OptionList, { children: options.map((option) => {
123
+ return (jsxs(PageContent, { onBack: routes.CONNECTED, children: [jsx(ModalHeading, { children: "Add funds" }), jsx(TestnetNotice, {}), targetUnsupported ? (jsx(UnsupportedNetworkNotice, { targetChain: target.chain, railChains: railChains })) : (jsx(DepositContent, { children: jsx(OptionList, { children: options.map((option) => {
108
124
  var _a;
109
125
  return (jsxs(OptionButton, { type: "button", disabled: option.disabled, onClick: () => go(option.target), children: [jsxs(OptionLeft, { children: [jsx(OptionIconBadge, { children: METHOD_ICON[option.id] }), jsxs(OptionInfo, { children: [jsx(OptionTitle, { children: option.title }), jsx(OptionSubtitle, { children: (_a = option.disabledReason) !== null && _a !== void 0 ? _a : option.subtitle })] })] }), jsx(LogoCluster, { children: clusterFor(option.id) })] }, option.id));
110
- }) }) }), jsx(PoweredByFooter, {})] }));
126
+ }) }) })), jsx(PoweredByFooter, {})] }));
111
127
  };
112
128
 
113
129
  export { Deposit as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -28,6 +28,12 @@ type PaymentOptionsContext = {
28
28
  isMobile: boolean;
29
29
  /** When the funding backend is unavailable, crypto/CEX rows are disabled. */
30
30
  fundingAvailable: boolean;
31
+ /**
32
+ * Test-key (`pk_test_…`) project. The fiat (card/Apple Pay) and exchange rails
33
+ * settle real money on mainnet only — Stripe/Coinbase can't deliver to a testnet
34
+ * wallet — so they're disabled here. The crypto rails (Relay testnet) stay on.
35
+ */
36
+ testnet?: boolean;
31
37
  /**
32
38
  * Integrator-selected methods, in display order. When set, only these show
33
39
  * (still subject to device/availability gating). Omit to show all.
@@ -51,7 +51,13 @@ function getPaymentOptions(ctx) {
51
51
  ? [...visible].sort((a, b) => Number(b.id === FundingMethod.APPLE_PAY) - Number(a.id === FundingMethod.APPLE_PAY))
52
52
  : visible;
53
53
  return ordered.map((method) => {
54
- const fundingRail = method.target.kind === 'crypto' || method.target.kind === 'wallet' || method.target.kind === 'cex';
54
+ const kind = method.target.kind;
55
+ // Fiat (card/Apple Pay) and exchange rails move real money and only settle on
56
+ // mainnet, so a test-key project can't use them — disable with a clear reason.
57
+ if (ctx.testnet && (kind === 'buy' || kind === 'cex')) {
58
+ return { ...method, disabled: true, disabledReason: 'Not available on testnet' };
59
+ }
60
+ const fundingRail = kind === 'crypto' || kind === 'wallet' || kind === 'cex';
55
61
  if (fundingRail && !ctx.fundingAvailable) {
56
62
  return { ...method, disabled: true, disabledReason: 'Coming soon' };
57
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"paymentOptions.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"paymentOptions.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -25,6 +25,8 @@ export declare function useDepositRoute(kind: DepositRouteKind): {
25
25
  pm: import("../../../hooks/openfort/useFunding").PaymentMethod | null;
26
26
  receiverAddress: string | null;
27
27
  sameChain: boolean;
28
+ targetUnsupported: boolean;
29
+ railChains: FundingChain[];
28
30
  status: import("../../../hooks/openfort/useFunding").SessionStatus | "idle";
29
31
  loading: boolean;
30
32
  error: Error | null;
@@ -25,7 +25,7 @@ function useDepositRoute(kind) {
25
25
  const ethWallet = useEthereumEmbeddedWallet();
26
26
  const solWallet = useSolanaEmbeddedWallet();
27
27
  const { session, status, error, loading, isAvailable, fund, payLink, reset } = useFunding();
28
- const { chains: allChains, loading: chainsLoading } = useFundingChains();
28
+ const { chains: allChains, railChains, loading: chainsLoading } = useFundingChains();
29
29
  const target = useFundingTarget();
30
30
  // The deposit recipient must live on the TARGET chain, so resolve the wallet by
31
31
  // the target's family — not the active chainType, which can disagree with the
@@ -49,6 +49,11 @@ function useDepositRoute(kind) {
49
49
  const activeCurrency = (_c = currencies.find((c) => c.symbol === currencySymbol)) !== null && _c !== void 0 ? _c : currencies[0];
50
50
  const chain = (_d = activeChain === null || activeChain === void 0 ? void 0 : activeChain.id) !== null && _d !== void 0 ? _d : target.chain;
51
51
  const sameChain = chain === target.chain;
52
+ // The rail only delivers to chains in its list; if the active funding TARGET (the
53
+ // embedded wallet's chain — e.g. Polygon Amoy or a Solana testnet) isn't one of
54
+ // them, there's no route. Don't call Relay (it would 400 with a cryptic "invalid
55
+ // currency"); the page prompts a switch to a supported chain instead.
56
+ const targetUnsupported = !chainsLoading && railChains.length > 0 && !railChains.some((c) => c.id === target.chain);
52
57
  const receiverAddress = sameChain
53
58
  ? (address !== null && address !== void 0 ? address : null)
54
59
  : ((_f = (_e = session === null || session === void 0 ? void 0 : session.paymentMethod) === null || _e === void 0 ? void 0 : _e.receiverAddress) !== null && _f !== void 0 ? _f : null);
@@ -56,6 +61,11 @@ function useDepositRoute(kind) {
56
61
  useEffect(() => {
57
62
  if (!address || !isAvailable || !activeChain || !activeCurrency)
58
63
  return;
64
+ if (targetUnsupported) {
65
+ lastKey.current = '';
66
+ reset();
67
+ return;
68
+ }
59
69
  if (sameChain) {
60
70
  lastKey.current = '';
61
71
  reset();
@@ -72,7 +82,19 @@ function useDepositRoute(kind) {
72
82
  destChain: target.chain,
73
83
  });
74
84
  fund({ chain: target.chain, currency: target.currency, address }, paymentMethodFor(activeChain.id, activeCurrency)).catch(() => { });
75
- }, [address, activeChain, activeCurrency, isAvailable, sameChain, fund, reset, target.chain, target.currency, kind]);
85
+ }, [
86
+ address,
87
+ activeChain,
88
+ activeCurrency,
89
+ isAvailable,
90
+ sameChain,
91
+ targetUnsupported,
92
+ fund,
93
+ reset,
94
+ target.chain,
95
+ target.currency,
96
+ kind,
97
+ ]);
76
98
  // Surface an empty source list (e.g. no Coinbase-deliverable chains) for diagnosis.
77
99
  useEffect(() => {
78
100
  if (!isAvailable || chainsLoading || chains.length > 0)
@@ -94,6 +116,8 @@ function useDepositRoute(kind) {
94
116
  pm,
95
117
  receiverAddress,
96
118
  sameChain,
119
+ targetUnsupported,
120
+ railChains,
97
121
  status,
98
122
  loading,
99
123
  error,
@@ -1 +1 @@
1
- {"version":3,"file":"useDepositRoute.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useDepositRoute.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Watches a wallet's native balance and reports when it increases past the first
3
+ * observed value — i.e. a same-chain deposit landed. Same-chain "transfer from
4
+ * address" has no rail session to poll (the deposit address is the wallet
5
+ * itself), so arrival is read straight from the chain RPC.
6
+ *
7
+ * Self-contained single timeout chain (no shared query cache), so it can't fan
8
+ * out into a request storm: one read in flight at a time, with an interval that
9
+ * grows on each tick and resets to brisk when the user returns to the tab (the
10
+ * moment a deposit was likely just made). On arrival, cached balances are
11
+ * invalidated so the asset list refreshes, and polling stops.
12
+ */
13
+ export declare function useSameChainArrival({ address, chainId, enabled, }: {
14
+ address: string;
15
+ chainId: number;
16
+ enabled: boolean;
17
+ }): {
18
+ arrived: boolean;
19
+ };
@@ -0,0 +1,86 @@
1
+ import { useState, useRef, useEffect } from 'react';
2
+ import { createPublicClient, http } from 'viem';
3
+ import { invalidateBalance } from '../../../hooks/useBalance.js';
4
+ import { getDefaultEthereumRpcUrl } from '../../../utils/rpc.js';
5
+ import { useOpenfort } from '../../Openfort/useOpenfort.js';
6
+
7
+ /**
8
+ * Backoff schedule (ms) for the waiting poll: brisk at first, easing off so a
9
+ * long wait doesn't hammer the RPC. The last entry is the steady-state cap.
10
+ */
11
+ const POLL_BACKOFF_MS = [2000, 2000, 3000, 5000, 8000, 12000, 20000];
12
+ /**
13
+ * Watches a wallet's native balance and reports when it increases past the first
14
+ * observed value — i.e. a same-chain deposit landed. Same-chain "transfer from
15
+ * address" has no rail session to poll (the deposit address is the wallet
16
+ * itself), so arrival is read straight from the chain RPC.
17
+ *
18
+ * Self-contained single timeout chain (no shared query cache), so it can't fan
19
+ * out into a request storm: one read in flight at a time, with an interval that
20
+ * grows on each tick and resets to brisk when the user returns to the tab (the
21
+ * moment a deposit was likely just made). On arrival, cached balances are
22
+ * invalidated so the asset list refreshes, and polling stops.
23
+ */
24
+ function useSameChainArrival({ address, chainId, enabled, }) {
25
+ var _a, _b, _c;
26
+ const { walletConfig } = useOpenfort();
27
+ const rpcUrl = (_c = (_b = (_a = walletConfig === null || walletConfig === void 0 ? void 0 : walletConfig.ethereum) === null || _a === void 0 ? void 0 : _a.rpcUrls) === null || _b === void 0 ? void 0 : _b[chainId]) !== null && _c !== void 0 ? _c : getDefaultEthereumRpcUrl(chainId);
28
+ const [arrived, setArrived] = useState(false);
29
+ const baselineRef = useRef(null);
30
+ useEffect(() => {
31
+ if (!enabled || !address)
32
+ return;
33
+ const client = createPublicClient({ transport: http(rpcUrl) });
34
+ let cancelled = false;
35
+ let timer = null;
36
+ let step = 0;
37
+ baselineRef.current = null;
38
+ const read = async () => {
39
+ try {
40
+ const balance = await client.getBalance({ address: address });
41
+ if (cancelled)
42
+ return;
43
+ if (baselineRef.current === null) {
44
+ baselineRef.current = balance;
45
+ }
46
+ else if (balance > baselineRef.current) {
47
+ setArrived(true);
48
+ invalidateBalance();
49
+ return; // deposit landed — stop polling
50
+ }
51
+ }
52
+ catch {
53
+ // transient RPC error — keep polling on the same schedule
54
+ }
55
+ if (cancelled)
56
+ return;
57
+ const delay = POLL_BACKOFF_MS[Math.min(step, POLL_BACKOFF_MS.length - 1)];
58
+ step += 1;
59
+ timer = setTimeout(read, delay);
60
+ };
61
+ // Re-check immediately when the user returns to the tab (deposit likely just
62
+ // made), and reset the schedule back to brisk.
63
+ const onReturn = () => {
64
+ if (cancelled || document.visibilityState !== 'visible')
65
+ return;
66
+ if (timer)
67
+ clearTimeout(timer);
68
+ step = 0;
69
+ read();
70
+ };
71
+ read();
72
+ document.addEventListener('visibilitychange', onReturn);
73
+ window.addEventListener('focus', onReturn);
74
+ return () => {
75
+ cancelled = true;
76
+ if (timer)
77
+ clearTimeout(timer);
78
+ document.removeEventListener('visibilitychange', onReturn);
79
+ window.removeEventListener('focus', onReturn);
80
+ };
81
+ }, [enabled, address, chainId, rpcUrl]);
82
+ return { arrived };
83
+ }
84
+
85
+ export { useSameChainArrival };
86
+ //# sourceMappingURL=useSameChainArrival.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSameChainArrival.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,6 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useEffect } from 'react';
3
+ import { currencyLogoUrl, chainLogoUrl } from '../../../constants/logos.js';
3
4
  import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
4
5
  import { routes } from '../../Openfort/types.js';
5
6
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
@@ -7,7 +8,14 @@ import { PageContent } from '../../PageContent/index.js';
7
8
  import { DepositAddressBlock } from '../Deposit/DepositAddressBlock.js';
8
9
  import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
9
10
  import { RouteSelectors } from '../Deposit/RouteSelectors.js';
11
+ import { SameChainDepositStatus } from '../Deposit/SameChainDepositStatus.js';
12
+ import { SameChainDepositSuccess } from '../Deposit/SameChainDepositSuccess.js';
13
+ import { isSolana } from '../Deposit/sources.js';
14
+ import { TestnetNotice } from '../Deposit/TestnetNotice.js';
15
+ import { UnsupportedNetworkNotice } from '../Deposit/UnsupportedNetworkNotice.js';
10
16
  import { useDepositRoute } from '../Deposit/useDepositRoute.js';
17
+ import { useSameChainArrival } from '../Deposit/useSameChainArrival.js';
18
+ import { caipToChainId } from '../DepositWallet/walletDeeplinks.js';
11
19
 
12
20
  /**
13
21
  * Transfer from address — choose a source chain + token and send to the deposit
@@ -16,15 +24,30 @@ import { useDepositRoute } from '../Deposit/useDepositRoute.js';
16
24
  * "Transfer from wallet" tab.
17
25
  */
18
26
  const DepositCrypto = () => {
19
- var _a, _b, _c, _d;
27
+ var _a, _b, _c, _d, _e;
20
28
  const { triggerResize } = useOpenfort();
21
29
  const route = useDepositRoute('crypto');
22
30
  useEffect(() => {
23
31
  triggerResize();
24
32
  }, [route.receiverAddress, route.loading, route.status, triggerResize]);
33
+ // Same-chain "transfer from address" lands in the wallet itself, so there's no
34
+ // rail session — watch the native balance directly and swap to the success
35
+ // screen once the deposit arrives.
36
+ const sameChainEnabled = route.sameChain && !!route.receiverAddress && !isSolana(route.target.chain);
37
+ const sameChainAddress = (_a = route.receiverAddress) !== null && _a !== void 0 ? _a : '';
38
+ const sameChainId = Number(route.target.chain.split(':')[1]);
39
+ const { arrived } = useSameChainArrival({
40
+ address: sameChainAddress,
41
+ chainId: sameChainId,
42
+ enabled: sameChainEnabled,
43
+ });
25
44
  if (isDepositFlowActive(route.status))
26
45
  return jsx(DepositProgress, { status: route.status });
27
- return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from address" }), jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsx(DepositAddressBlock, { assetLogo: (_b = (_a = route.activeCurrency) === null || _a === void 0 ? void 0 : _a.logo) !== null && _b !== void 0 ? _b : null, chainLogo: (_d = (_c = route.activeChain) === null || _c === void 0 ? void 0 : _c.logo) !== null && _d !== void 0 ? _d : null, receiverAddress: route.receiverAddress, pm: route.pm, sourceCurrency: route.activeCurrency ? { symbol: route.activeCurrency.symbol, decimals: route.activeCurrency.decimals } : null, sameChain: route.sameChain, loading: route.loading, status: route.status }), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] }));
46
+ if (sameChainEnabled && arrived)
47
+ return jsx(SameChainDepositSuccess, { address: sameChainAddress, chainId: sameChainId });
48
+ return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from address" }), jsx(TestnetNotice, {}), route.targetUnsupported ? (jsx(UnsupportedNetworkNotice, { targetChain: route.target.chain, railChains: route.railChains })) : (jsxs(Fragment, { children: [jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsx(DepositAddressBlock, { assetLogo: currencyLogoUrl((_b = route.activeCurrency) === null || _b === void 0 ? void 0 : _b.symbol, (_c = route.activeCurrency) === null || _c === void 0 ? void 0 : _c.logo), chainLogo: chainLogoUrl(caipToChainId((_d = route.activeChain) === null || _d === void 0 ? void 0 : _d.id), (_e = route.activeChain) === null || _e === void 0 ? void 0 : _e.logo), receiverAddress: route.receiverAddress, pm: route.pm, sourceCurrency: route.activeCurrency
49
+ ? { symbol: route.activeCurrency.symbol, decimals: route.activeCurrency.decimals }
50
+ : null, sameChain: route.sameChain, loading: route.loading, status: route.status }), sameChainEnabled && jsx(SameChainDepositStatus, {}), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] }))] }));
28
51
  };
29
52
 
30
53
  export { DepositCrypto as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -5,6 +5,7 @@ import { WalletIcon } from '../../../assets/icons.js';
5
5
  import Logos from '../../../assets/logos.js';
6
6
  import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
7
7
  import { ModalBody } from '../../Common/Modal/styles.js';
8
+ import { ScrollArea } from '../../Common/ScrollArea/index.js';
8
9
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
9
10
  import { DepositStatus } from '../Deposit/DepositStatus.js';
10
11
  import { walletListBtn } from '../Deposit/formStyles.js';
@@ -125,14 +126,14 @@ function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, lo
125
126
  setBusyId(null);
126
127
  }
127
128
  };
128
- return (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, marginTop: 14 }, children: [connectors.length === 0 && jsx(ModalBody, { children: "No browser wallet detected. Install MetaMask or Rabby." }), connectors.map((c) => (jsxs("button", { type: "button", disabled: !amountValid || busyId !== null || loading, style: {
129
- ...walletListBtn,
130
- display: 'flex',
131
- alignItems: 'center',
132
- justifyContent: 'flex-start',
133
- gap: 10,
134
- opacity: !amountValid || busyId !== null ? 0.55 : 1,
135
- }, onClick: () => sendVia(c), children: [jsx(ButtonLogo, { children: brandLogo(c) }), jsx("span", { children: busyId === c.id ? 'Confirm in your wallet…' : `Send via ${c.name}` })] }, c.id))), sent && jsx(DepositStatus, { status: "waiting_payment" }), error && jsx(ModalBody, { style: { color: '#dc2626' }, children: error })] }));
129
+ return (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, flex: '1 1 auto', minHeight: 0 }, children: [connectors.length === 0 && jsx(ModalBody, { children: "No browser wallet detected. Install MetaMask or Rabby." }), connectors.length > 0 && (jsx(ScrollArea, { fill: true, children: jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: connectors.map((c) => (jsxs("button", { type: "button", disabled: !amountValid || busyId !== null || loading, style: {
130
+ ...walletListBtn,
131
+ display: 'flex',
132
+ alignItems: 'center',
133
+ justifyContent: 'flex-start',
134
+ gap: 10,
135
+ opacity: !amountValid || busyId !== null ? 0.55 : 1,
136
+ }, onClick: () => sendVia(c), children: [jsx(ButtonLogo, { children: brandLogo(c) }), jsx("span", { children: busyId === c.id ? 'Confirm in your wallet…' : `Send via ${c.name}` })] }, c.id))) }) })), sent && jsx(DepositStatus, { status: "waiting_payment" }), error && jsx(ModalBody, { style: { color: '#dc2626' }, children: error })] }));
136
137
  }
137
138
 
138
139
  export { DepositWalletDesktop };
@@ -1 +1 @@
1
- {"version":3,"file":"DepositWalletDesktop.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"DepositWalletDesktop.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,9 +2,12 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useState, useEffect } from 'react';
3
3
  import { parseUnits } from 'viem';
4
4
  import Logos from '../../../assets/logos.js';
5
+ import { useEthereumBridge } from '../../../ethereum/OpenfortEthereumBridgeContext.js';
5
6
  import useIsMobile from '../../../hooks/useIsMobile.js';
7
+ import styled from '../../../styles/styled/index.js';
6
8
  import { isIOS } from '../../../utils/index.js';
7
9
  import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
10
+ import { ScrollArea } from '../../Common/ScrollArea/index.js';
8
11
  import { routes } from '../../Openfort/types.js';
9
12
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
10
13
  import { PageContent } from '../../PageContent/index.js';
@@ -15,11 +18,40 @@ import { walletListBtn } from '../Deposit/formStyles.js';
15
18
  import { RouteSelectors } from '../Deposit/RouteSelectors.js';
16
19
  import { isSolana } from '../Deposit/sources.js';
17
20
  import { StepDivider, Skeleton, ButtonLogo } from '../Deposit/styles.js';
21
+ import { TestnetNotice } from '../Deposit/TestnetNotice.js';
22
+ import { UnsupportedNetworkNotice } from '../Deposit/UnsupportedNetworkNotice.js';
18
23
  import { useDepositRoute } from '../Deposit/useDepositRoute.js';
19
24
  import { sanitizeAmountInput } from '../Send/utils.js';
20
25
  import { DepositWalletDesktop } from './DepositWalletDesktop.js';
21
26
  import { OPENFORT_DEPOSIT_PAGE_URL, caipToChainId, buildDepositPageUrl, buildOpenDappLinks } from './walletDeeplinks.js';
22
27
 
28
+ // Flex column capped at the modal viewport so the page never overflows
29
+ // InnerContainer (which caps at 88vh and would otherwise scroll the footer off
30
+ // screen). The 112px accounts for the chrome wrapping this element inside the
31
+ // measured PageContents: PageContentStyle's 48px top padding + PageContents'
32
+ // 29px/24px padding (~101px), plus a small safety margin. The providers region
33
+ // is the only part that shrinks/scrolls, which keeps the footer visible.
34
+ const Layout = styled.div `
35
+ display: flex;
36
+ flex-direction: column;
37
+ min-height: 0;
38
+ max-height: calc(88vh - 112px);
39
+ `;
40
+ const TopFixed = styled.div `
41
+ flex-shrink: 0;
42
+ `;
43
+ // Grows to fill the space between the fixed top and footer; its ScrollArea
44
+ // scrolls internally when the wallet list is taller than the available room.
45
+ const ProvidersRegion = styled.div `
46
+ display: flex;
47
+ flex-direction: column;
48
+ flex: 1 1 auto;
49
+ min-height: 0;
50
+ margin-top: 14px;
51
+ `;
52
+ const FixedFooter = styled.div `
53
+ flex-shrink: 0;
54
+ `;
23
55
  /** Wallet-app brand logos keyed by the deeplink `app` id. */
24
56
  const WALLET_LOGO = {
25
57
  metamask: jsx(Logos.MetaMask, { background: true }),
@@ -43,7 +75,13 @@ const DepositWallet = () => {
43
75
  const { triggerResize, uiConfig } = useOpenfort();
44
76
  const isMobile = useIsMobile();
45
77
  const route = useDepositRoute('crypto');
46
- const [amount, setAmount] = useState('');
78
+ // The desktop send path goes through the wagmi bridge (browser-extension wallets).
79
+ // In Solana-only mode there's no wagmi provider, so fall back to the open-dApp
80
+ // deeplinks for EVM sources too — otherwise the wallet list renders empty.
81
+ const bridge = useEthereumBridge();
82
+ // Prefill a sensible default so the wallet deeplinks are immediately actionable
83
+ // (the funding deposit-address mint uses a fixed nominal amount regardless).
84
+ const [amount, setAmount] = useState('1');
47
85
  const [pressedPreset, setPressedPreset] = useState(null);
48
86
  const depositPageUrl = (_b = (_a = uiConfig.funding) === null || _a === void 0 ? void 0 : _a.depositPageUrl) !== null && _b !== void 0 ? _b : OPENFORT_DEPOSIT_PAGE_URL;
49
87
  // Solana sources have no numeric chain id and no desktop EVM-extension send, so
@@ -92,15 +130,15 @@ const DepositWallet = () => {
92
130
  }, [route.receiverAddress, route.loading, route.status, deeplinks.length, triggerResize]);
93
131
  if (isDepositFlowActive(route.status))
94
132
  return jsx(DepositProgress, { status: route.status });
95
- return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from wallet" }), jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsxs(Section, { children: [jsx(SectionLabel, { children: "Amount" }), jsxs(AmountCard, { children: [jsx(CurrencySymbol, { children: (_m = (_l = route.activeCurrency) === null || _l === void 0 ? void 0 : _l.symbol) !== null && _m !== void 0 ? _m : '' }), jsx(AmountInput, { value: amount, onChange: handleAmountChange, placeholder: "0.00", inputMode: "decimal", autoComplete: "off" })] }), jsx(PresetList, { children: PRESETS.map((preset) => (jsx(PresetButton, { type: "button", "$active": pressedPreset === preset, onClick: () => handlePreset(preset), children: preset }, preset))) })] }), jsx(StepDivider, { children: "Then select the wallet you want to use" }), isMobile || isSolanaSrc ? (jsxs(Fragment, { children: [!depositPageUrl && (jsx(ModalBody, { style: { marginTop: 12 }, children: "Use a deposit address below to fund from your wallet." })), route.loading && !route.pm && (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8, marginTop: 14 }, children: [jsx(Skeleton, { "$h": "44px", "$r": "10px" }), jsx(Skeleton, { "$h": "44px", "$r": "10px" }), jsx(Skeleton, { "$h": "44px", "$r": "10px" })] })), deeplinks.length > 0 && (jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 8, marginTop: 14 }, children: deeplinks.map((d) => (jsxs("a", { href: amountValid ? d.url : undefined, "aria-disabled": !amountValid, target: "_blank", rel: "noreferrer", style: {
96
- ...walletListBtn,
97
- display: 'flex',
98
- alignItems: 'center',
99
- justifyContent: 'center',
100
- gap: 8,
101
- opacity: amountValid ? 1 : 0.55,
102
- pointerEvents: amountValid ? 'auto' : 'none',
103
- }, children: [WALLET_LOGO[d.app] && jsx(ButtonLogo, { children: WALLET_LOGO[d.app] }), d.label, " \u2197"] }, d.app))) }))] })) : (jsx(DepositWalletDesktop, { receiverAddress: route.receiverAddress, activeChain: route.activeChain, activeCurrency: route.activeCurrency, loading: route.loading, amount: amount })), jsx(AddressPageLink, { label: "Or send to a deposit address" }), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] }));
133
+ return (jsxs(PageContent, { onBack: routes.DEPOSIT, children: [jsx(ModalHeading, { children: "Transfer from wallet" }), jsx(TestnetNotice, {}), route.targetUnsupported && (jsx(UnsupportedNetworkNotice, { targetChain: route.target.chain, railChains: route.railChains })), !route.targetUnsupported && (jsxs(Layout, { children: [jsxs(TopFixed, { children: [jsx(RouteSelectors, { chains: route.chains, chain: route.chain, currency: route.currency, chainLabel: "Supported chain", onChainChange: route.setChain, onCurrencyChange: route.setCurrency }), !route.isAvailable && jsx(ModalBody, { children: "Funding isn't available right now." }), jsxs(Section, { children: [jsx(SectionLabel, { children: "Amount" }), jsxs(AmountCard, { children: [jsx(CurrencySymbol, { children: (_m = (_l = route.activeCurrency) === null || _l === void 0 ? void 0 : _l.symbol) !== null && _m !== void 0 ? _m : '' }), jsx(AmountInput, { value: amount, onChange: handleAmountChange, placeholder: "0.00", inputMode: "decimal", autoComplete: "off" })] }), jsx(PresetList, { children: PRESETS.map((preset) => (jsx(PresetButton, { type: "button", "$active": pressedPreset === preset, onClick: () => handlePreset(preset), children: preset }, preset))) })] }), jsx(StepDivider, { children: "Then select the wallet you want to use" })] }), jsx(ProvidersRegion, { children: isMobile || isSolanaSrc || !bridge ? (jsxs(Fragment, { children: [!depositPageUrl && (jsx(ModalBody, { style: { marginTop: 12 }, children: "Use a deposit address below to fund from your wallet." })), route.loading && !route.pm && (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [jsx(Skeleton, { "$h": "44px", "$r": "10px" }), jsx(Skeleton, { "$h": "44px", "$r": "10px" }), jsx(Skeleton, { "$h": "44px", "$r": "10px" })] })), deeplinks.length > 0 && (jsx(ScrollArea, { fill: true, children: jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: deeplinks.map((d) => (jsxs("a", { href: amountValid ? d.url : undefined, "aria-disabled": !amountValid, target: "_blank", rel: "noreferrer", style: {
134
+ ...walletListBtn,
135
+ display: 'flex',
136
+ alignItems: 'center',
137
+ justifyContent: 'center',
138
+ gap: 8,
139
+ opacity: amountValid ? 1 : 0.55,
140
+ pointerEvents: amountValid ? 'auto' : 'none',
141
+ }, children: [WALLET_LOGO[d.app] && jsx(ButtonLogo, { children: WALLET_LOGO[d.app] }), d.label, " \u2197"] }, d.app))) }) }))] })) : (jsx(DepositWalletDesktop, { receiverAddress: route.receiverAddress, activeChain: route.activeChain, activeCurrency: route.activeCurrency, loading: route.loading, amount: amount })) }), jsxs(FixedFooter, { children: [jsx(AddressPageLink, { label: "Or send to a deposit address" }), route.error && jsx(ModalBody, { style: { color: '#dc2626', marginTop: 12 }, children: route.error.message })] })] }))] }));
104
142
  };
105
143
 
106
144
  export { DepositWallet as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,9 +1,10 @@
1
- export declare const SelectTokenContent: import("styled-components").StyledComponent<({ children, width, onBack, logoutOnBack, header }: {
1
+ export declare const SelectTokenContent: import("styled-components").StyledComponent<({ children, width, onBack, logoutOnBack, header, className, }: {
2
2
  children?: React.ReactNode;
3
3
  width?: number | string;
4
4
  onBack?: import("../../PageContent").SetOnBackFunction;
5
5
  logoutOnBack?: boolean;
6
6
  header?: string;
7
+ className?: string;
7
8
  }) => import("react/jsx-runtime").JSX.Element, any, {}, never>;
8
9
  export declare const TokenList: import("styled-components").StyledComponent<"div", any, {}, never>;
9
10
  export declare const TokenButton: import("styled-components").StyledComponent<"button", any, {}, never>;