@openfort/react 1.2.0 → 1.3.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 (86) hide show
  1. package/build/assets/logos.d.ts +3 -0
  2. package/build/assets/logos.js +2 -0
  3. package/build/assets/logos.js.map +1 -1
  4. package/build/components/Common/SolanaChain/index.d.ts +8 -0
  5. package/build/components/Common/SolanaChain/index.js +40 -0
  6. package/build/components/Common/SolanaChain/index.js.map +1 -0
  7. package/build/components/ConnectModal/index.js +2 -0
  8. package/build/components/ConnectModal/index.js.map +1 -1
  9. package/build/components/Openfort/types.d.ts +17 -11
  10. package/build/components/Openfort/types.js +1 -0
  11. package/build/components/Openfort/types.js.map +1 -1
  12. package/build/components/Pages/Buy/coinbaseApi.d.ts +1 -1
  13. package/build/components/Pages/Buy/coinbaseApi.js +2 -13
  14. package/build/components/Pages/Buy/coinbaseApi.js.map +1 -1
  15. package/build/components/Pages/Buy/evmCurrencies.d.ts +11 -0
  16. package/build/components/Pages/Buy/evmCurrencies.js +27 -0
  17. package/build/components/Pages/Buy/evmCurrencies.js.map +1 -0
  18. package/build/components/Pages/Buy/index.js +8 -1
  19. package/build/components/Pages/Buy/index.js.map +1 -1
  20. package/build/components/Pages/Buy/onrampApi.d.ts +8 -1
  21. package/build/components/Pages/Buy/onrampApi.js +24 -14
  22. package/build/components/Pages/Buy/onrampApi.js.map +1 -1
  23. package/build/components/Pages/Buy/solanaCurrencies.d.ts +9 -0
  24. package/build/components/Pages/Buy/solanaCurrencies.js +25 -0
  25. package/build/components/Pages/Buy/solanaCurrencies.js.map +1 -0
  26. package/build/components/Pages/Buy/stripeApi.d.ts +1 -1
  27. package/build/components/Pages/Buy/stripeApi.js +2 -13
  28. package/build/components/Pages/Buy/stripeApi.js.map +1 -1
  29. package/build/components/Pages/BuyComplete/index.js +7 -1
  30. package/build/components/Pages/BuyComplete/index.js.map +1 -1
  31. package/build/components/Pages/BuyProcessing/index.js +9 -5
  32. package/build/components/Pages/BuyProcessing/index.js.map +1 -1
  33. package/build/components/Pages/BuySelectProvider/index.js +10 -5
  34. package/build/components/Pages/BuySelectProvider/index.js.map +1 -1
  35. package/build/components/Pages/Connected/SolanaConnected.js +3 -2
  36. package/build/components/Pages/Connected/SolanaConnected.js.map +1 -1
  37. package/build/components/Pages/Deposit/DepositProgress.js +3 -2
  38. package/build/components/Pages/Deposit/DepositProgress.js.map +1 -1
  39. package/build/components/Pages/Deposit/DepositSuccess.js +2 -1
  40. package/build/components/Pages/Deposit/DepositSuccess.js.map +1 -1
  41. package/build/components/Pages/Deposit/index.js +16 -2
  42. package/build/components/Pages/Deposit/index.js.map +1 -1
  43. package/build/components/Pages/Deposit/paymentOptions.js +3 -3
  44. package/build/components/Pages/Deposit/useDepositRoute.d.ts +0 -1
  45. package/build/components/Pages/Deposit/useDepositRoute.js +10 -11
  46. package/build/components/Pages/Deposit/useDepositRoute.js.map +1 -1
  47. package/build/components/Pages/Deposit/useFundingTarget.d.ts +2 -4
  48. package/build/components/Pages/Deposit/useFundingTarget.js +3 -5
  49. package/build/components/Pages/Deposit/useFundingTarget.js.map +1 -1
  50. package/build/components/Pages/DepositCex/index.js +7 -8
  51. package/build/components/Pages/DepositCex/index.js.map +1 -1
  52. package/build/components/Pages/DepositWallet/DepositWalletDesktop.d.ts +4 -1
  53. package/build/components/Pages/DepositWallet/DepositWalletDesktop.js +11 -20
  54. package/build/components/Pages/DepositWallet/DepositWalletDesktop.js.map +1 -1
  55. package/build/components/Pages/DepositWallet/index.d.ts +5 -5
  56. package/build/components/Pages/DepositWallet/index.js +36 -31
  57. package/build/components/Pages/DepositWallet/index.js.map +1 -1
  58. package/build/components/Pages/DepositWallet/walletDeeplinks.d.ts +6 -4
  59. package/build/components/Pages/DepositWallet/walletDeeplinks.js +3 -1
  60. package/build/components/Pages/DepositWallet/walletDeeplinks.js.map +1 -1
  61. package/build/components/Pages/SelectToken/SolanaSelectToken.d.ts +1 -0
  62. package/build/components/Pages/SelectToken/SolanaSelectToken.js +50 -0
  63. package/build/components/Pages/SelectToken/SolanaSelectToken.js.map +1 -0
  64. package/build/components/Pages/SelectToken/index.js +13 -2
  65. package/build/components/Pages/SelectToken/index.js.map +1 -1
  66. package/build/components/Pages/Send/SolanaSend.js +32 -31
  67. package/build/components/Pages/Send/SolanaSend.js.map +1 -1
  68. package/build/components/Pages/Send/utils.js +4 -1
  69. package/build/components/Pages/Send/utils.js.map +1 -1
  70. package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js +57 -13
  71. package/build/components/Pages/SendConfirmation/SolanaSendConfirmation.js.map +1 -1
  72. package/build/components/Pages/SendConfirmation/styles.d.ts +0 -5
  73. package/build/components/Pages/SendConfirmation/styles.js +1 -39
  74. package/build/components/Pages/SendConfirmation/styles.js.map +1 -1
  75. package/build/hooks/openfort/useFunding.js +7 -7
  76. package/build/hooks/openfort/useFundingChains.js +4 -6
  77. package/build/hooks/openfort/useFundingChains.js.map +1 -1
  78. package/build/shared/hooks/useAsyncData.js +15 -2
  79. package/build/shared/hooks/useAsyncData.js.map +1 -1
  80. package/build/solana/transfer.d.ts +35 -6
  81. package/build/solana/transfer.js +112 -18
  82. package/build/solana/transfer.js.map +1 -1
  83. package/build/solana/types.d.ts +8 -0
  84. package/build/version.d.ts +1 -1
  85. package/build/version.js +1 -1
  86. package/package.json +5 -1
@@ -11,8 +11,9 @@ import { routes } from '../../Openfort/types.js';
11
11
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
12
12
  import { PageContent } from '../../PageContent/index.js';
13
13
  import { isCoinbaseSupported } from '../Buy/coinbaseApi.js';
14
- import { getAllQuotes } from '../Buy/onrampApi.js';
14
+ import { resolveOnrampNetwork, getAllQuotes } from '../Buy/onrampApi.js';
15
15
  import { getProviders } from '../Buy/providers.js';
16
+ import { SOLANA_BUY_CURRENCIES } from '../Buy/solanaCurrencies.js';
16
17
  import { isStripeSupported } from '../Buy/stripeApi.js';
17
18
  import { ProviderList, ProviderButton, ProviderInfo, ProviderNameRow, ProviderName, ProviderBadge, ProviderMeta, ProviderRight, ProviderQuote, ProviderFiat, ContinueButtonWrapper } from '../Buy/styles.js';
18
19
  import { createCurrencyFormatter, formatTokenAmount } from '../Buy/utils.js';
@@ -28,6 +29,9 @@ const BuySelectProvider = () => {
28
29
  const isConnected = wallet.status === 'connected';
29
30
  const address = isConnected ? wallet.address : undefined;
30
31
  const chainId = isConnected && chainType === ChainTypeEnum.EVM ? wallet.chainId : undefined;
32
+ // The onramp destination network: 'solana' for SVM, else the EVM network (undefined
33
+ // until the EVM chainId resolves, which keeps quote fetching gated as before).
34
+ const network = resolveOnrampNetwork(chainType, chainId);
31
35
  const [quotes, setQuotes] = useState({});
32
36
  const [isLoadingQuote, setIsLoadingQuote] = useState(false);
33
37
  const [coinbaseError, setCoinbaseError] = useState(false);
@@ -43,7 +47,8 @@ const BuySelectProvider = () => {
43
47
  return null;
44
48
  return numeric;
45
49
  }, [buyForm.amount]);
46
- const { data: assets } = useEthereumWalletAssets();
50
+ const { data: ethAssets } = useEthereumWalletAssets();
51
+ const assets = chainType === ChainTypeEnum.SVM ? SOLANA_BUY_CURRENCIES : ethAssets;
47
52
  const matchedToken = useMemo(() => assets === null || assets === void 0 ? void 0 : assets.find((asset) => isSameToken(asset, buyForm.asset)), [assets, buyForm.asset]);
48
53
  const selectedTokenOption = matchedToken !== null && matchedToken !== void 0 ? matchedToken : assets === null || assets === void 0 ? void 0 : assets[0];
49
54
  const selectedToken = selectedTokenOption !== null && selectedTokenOption !== void 0 ? selectedTokenOption : buyForm.asset;
@@ -77,7 +82,7 @@ const BuySelectProvider = () => {
77
82
  // Fetch quotes from all providers
78
83
  useEffect(() => {
79
84
  const fetchQuotes = async () => {
80
- if (!address || !chainId || !fiatAmount || fiatAmount <= 0) {
85
+ if (!address || !network || !fiatAmount || fiatAmount <= 0) {
81
86
  setQuotes({});
82
87
  setCoinbaseError(false);
83
88
  setStripeError(false);
@@ -89,7 +94,7 @@ const BuySelectProvider = () => {
89
94
  try {
90
95
  const allQuotes = await getAllQuotes({
91
96
  token: selectedToken,
92
- chainId,
97
+ network,
93
98
  publishableKey,
94
99
  sourceAmount: fiatAmount.toFixed(2),
95
100
  sourceCurrency: buyForm.currency,
@@ -120,7 +125,7 @@ const BuySelectProvider = () => {
120
125
  selectedToken.metadata,
121
126
  selectedToken.type,
122
127
  buyForm.currency,
123
- chainId,
128
+ network,
124
129
  address,
125
130
  publishableKey,
126
131
  refetchTrigger,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -15,12 +15,13 @@ import Avatar from '../../Common/Avatar/index.js';
15
15
  import Button from '../../Common/Button/index.js';
16
16
  import { TextLinkButton } from '../../Common/Button/styles.js';
17
17
  import { CopyText } from '../../Common/CopyToClipboard/CopyText.js';
18
+ import SolanaChain from '../../Common/SolanaChain/index.js';
18
19
  import { useThemeContext } from '../../ConnectKitThemeProvider/ConnectKitThemeProvider.js';
19
20
  import { routes } from '../../Openfort/types.js';
20
21
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
21
22
  import { PageContent } from '../../PageContent/index.js';
22
23
  import { ConnectedPageLayout } from './ConnectedPageLayout.js';
23
- import { LinkedProvidersToggle, Balance, ActionButton } from './styles.js';
24
+ import { LinkedProvidersToggle, Balance, ChainSelectorContainer, ActionButton } from './styles.js';
24
25
  import { truncateSolanaAddress } from '../../../utils/format.js';
25
26
 
26
27
  const SolanaConnected = () => {
@@ -90,7 +91,7 @@ const SolanaConnected = () => {
90
91
  : undefined;
91
92
  const avatar = address ? CustomAvatar ? jsx(CustomAvatar, { address: address }) : jsx(Avatar, { address: address }) : jsx("span", {});
92
93
  const balanceNode = balanceSol != null && !isBalanceLoading ? (jsx(TextLinkButton, { type: "button", onClick: () => setRoute(routes.SOL_ASSET_INVENTORY), children: jsxs(Balance, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, children: [nFormatter(Number(balanceSol)), " SOL"] }, "solana-balance") })) : null;
93
- return (jsx(PageContent, { onBack: null, header: locales.profileScreen_heading, children: jsx(ConnectedPageLayout, { address: address !== null && address !== void 0 ? address : '', displayName: jsx(CopyText, { value: address !== null && address !== void 0 ? address : '', children: truncateSolanaAddress(address !== null && address !== void 0 ? address : '', separator) }), avatar: avatar, balance: balanceNode, actions: jsxs(Fragment, { children: [jsx(ActionButton, { icon: jsx(SendIcon, {}), onClick: () => {
94
+ return (jsx(PageContent, { onBack: null, header: locales.profileScreen_heading, children: jsx(ConnectedPageLayout, { address: address !== null && address !== void 0 ? address : '', displayName: jsx(CopyText, { value: address !== null && address !== void 0 ? address : '', children: truncateSolanaAddress(address !== null && address !== void 0 ? address : '', separator) }), avatar: avatar, beforeAvatar: jsx(ChainSelectorContainer, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.2 }, children: jsx(SolanaChain, {}) }), balance: balanceNode, actions: jsxs(Fragment, { children: [jsx(ActionButton, { icon: jsx(SendIcon, {}), onClick: () => {
94
95
  // Nothing to send on an empty wallet — prompt to add funds first (mirrors EVM).
95
96
  const hasBalance = lamports != null && BigInt(lamports) > BigInt(0);
96
97
  context.setRoute(hasBalance ? routes.SOL_SEND : routes.NO_ASSETS_AVAILABLE);
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaConnected.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"SolanaConnected.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -4,6 +4,7 @@ import styled from '../../../styles/styled/index.js';
4
4
  import { logger } from '../../../utils/logger.js';
5
5
  import Button from '../../Common/Button/index.js';
6
6
  import { ModalHeading, ModalBody } from '../../Common/Modal/styles.js';
7
+ import PoweredByFooter from '../../Common/PoweredByFooter/index.js';
7
8
  import { Spinner } from '../../Common/Spinner/index.js';
8
9
  import { routes } from '../../Openfort/types.js';
9
10
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
@@ -96,14 +97,14 @@ function DepositProgress({ status }) {
96
97
  return jsx(DepositSuccess, {});
97
98
  if (status === 'bounced' || status === 'expired') {
98
99
  const ui = OUTCOME[status];
99
- return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: ui === null || ui === void 0 ? void 0 : ui.heading }), jsx(ModalBody, { children: ui === null || ui === void 0 ? void 0 : ui.body }), jsx(Button, { variant: "primary", onClick: () => setRoute(status === 'expired' ? routes.DEPOSIT : routes.CONNECTED), children: status === 'expired' ? 'Start over' : 'See balance' })] }));
100
+ return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: ui === null || ui === void 0 ? void 0 : ui.heading }), jsx(ModalBody, { children: ui === null || ui === void 0 ? void 0 : ui.body }), jsx(Button, { variant: "primary", onClick: () => setRoute(status === 'expired' ? routes.DEPOSIT : routes.CONNECTED), children: status === 'expired' ? 'Start over' : 'See balance' }), jsx(PoweredByFooter, {})] }));
100
101
  }
101
102
  // processing → bridging active (step 1); succeeded (pre-confirmed) → delivering active (step 2).
102
103
  const activeStep = status === 'succeeded' ? 2 : 1;
103
104
  return (jsxs(PageContent, { children: [jsx(ModalHeading, { children: "Completing your deposit" }), jsx(ModalBody, { children: "Keep this open \u2014 your funds are on the way." }), jsx(StepList, { children: STEPS.map((step, i) => {
104
105
  const state = stepStateFor(i, activeStep);
105
106
  return (jsxs(StepRow, { "$state": state, children: [state === 'active' ? jsx(Spinner, {}) : jsx(StepMark, { "$state": state, children: state === 'done' ? '✓' : '' }), jsx("span", { children: step.label })] }, step.key));
106
- }) })] }));
107
+ }) }), jsx(PoweredByFooter, {})] }));
107
108
  }
108
109
 
109
110
  export { DepositProgress, isDepositFlowActive };
@@ -1 +1 @@
1
- {"version":3,"file":"DepositProgress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"DepositProgress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,6 +2,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useEffect } from 'react';
3
3
  import Button from '../../Common/Button/index.js';
4
4
  import Loader from '../../Common/Loading/index.js';
5
+ import PoweredByFooter from '../../Common/PoweredByFooter/index.js';
5
6
  import { routes } from '../../Openfort/types.js';
6
7
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
7
8
  import { PageContent } from '../../PageContent/index.js';
@@ -17,7 +18,7 @@ function DepositSuccess() {
17
18
  useEffect(() => {
18
19
  triggerResize();
19
20
  }, [triggerResize]);
20
- return (jsxs(PageContent, { children: [jsx(Loader, { isSuccess: true, header: "Deposit received", description: "Funds delivered to your wallet" }), jsx(Button, { variant: "primary", onClick: () => setRoute(routes.ASSET_INVENTORY), children: "See balance" })] }));
21
+ return (jsxs(PageContent, { children: [jsx(Loader, { isSuccess: true, header: "Deposit received", description: "Funds delivered to your wallet" }), jsx(Button, { variant: "primary", onClick: () => setRoute(routes.ASSET_INVENTORY), children: "See balance" }), jsx(PoweredByFooter, {})] }));
21
22
  }
22
23
 
23
24
  export { DepositSuccess };
@@ -1 +1 @@
1
- {"version":3,"file":"DepositSuccess.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"DepositSuccess.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,13 +1,18 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { ChainTypeEnum } from '@openfort/openfort-js';
2
3
  import { DollarIcon, BuyIcon, WalletIcon, ReceiveIcon, ExternalLinkIcon } from '../../../assets/icons.js';
3
4
  import Logos from '../../../assets/logos.js';
4
5
  import { useFunding } from '../../../hooks/openfort/useFunding.js';
5
6
  import { useFundingChains } from '../../../hooks/openfort/useFundingChains.js';
6
7
  import useIsMobile from '../../../hooks/useIsMobile.js';
8
+ import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
7
9
  import { ModalHeading } from '../../Common/Modal/styles.js';
10
+ import PoweredByFooter from '../../Common/PoweredByFooter/index.js';
8
11
  import { FundingMethod, routes } from '../../Openfort/types.js';
9
12
  import { useOpenfort } from '../../Openfort/useOpenfort.js';
10
13
  import { PageContent } from '../../PageContent/index.js';
14
+ import { EVM_BUY_CURRENCIES } from '../Buy/evmCurrencies.js';
15
+ import { SOLANA_BUY_CURRENCIES } from '../Buy/solanaCurrencies.js';
11
16
  import { getPaymentOptions } from './paymentOptions.js';
12
17
  import { DepositContent, OptionList, OptionButton, OptionLeft, OptionIconBadge, OptionInfo, OptionTitle, OptionSubtitle, LogoCluster } from './styles.js';
13
18
 
@@ -43,6 +48,7 @@ const hideBrokenLogo = (e) => {
43
48
  const Deposit = () => {
44
49
  var _a;
45
50
  const { setRoute, setBuyForm, uiConfig } = useOpenfort();
51
+ const { chainType } = useOpenfortCore();
46
52
  const isMobile = useIsMobile();
47
53
  const { isAvailable } = useFunding();
48
54
  const { chains } = useFundingChains();
@@ -87,13 +93,21 @@ const Deposit = () => {
87
93
  }
88
94
  // Fiat rails reuse the existing Buy flow; preselect the chosen provider so
89
95
  // Apple Pay / Card land on the right rail.
90
- setBuyForm((prev) => ({ ...prev, providerId: target.providerId }));
96
+ setBuyForm((prev) => ({
97
+ ...prev,
98
+ providerId: target.providerId,
99
+ // Default the card-buy to USDC per chain family. Without this the EVM default
100
+ // resolves to the wallet's (often empty) asset list — "no supported tokens" —
101
+ // and the Solana native default would resolve to SOL (isSameToken treats any
102
+ // two natives as equal).
103
+ asset: chainType === ChainTypeEnum.SVM ? SOLANA_BUY_CURRENCIES[0] : EVM_BUY_CURRENCIES[0],
104
+ }));
91
105
  setRoute(routes.BUY);
92
106
  };
93
107
  return (jsxs(PageContent, { onBack: routes.CONNECTED, children: [jsx(ModalHeading, { children: "Add funds" }), jsx(DepositContent, { children: jsx(OptionList, { children: options.map((option) => {
94
108
  var _a;
95
109
  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));
96
- }) }) })] }));
110
+ }) }) }), jsx(PoweredByFooter, {})] }));
97
111
  };
98
112
 
99
113
  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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -17,19 +17,19 @@ const ALL_METHODS = [
17
17
  {
18
18
  id: FundingMethod.WALLET,
19
19
  title: 'Transfer from wallet',
20
- subtitle: 'Min $1 · No fee · 10 sec',
20
+ subtitle: 'Min $1 · Bridge fee · 10 sec',
21
21
  target: { kind: 'wallet' },
22
22
  },
23
23
  {
24
24
  id: FundingMethod.ADDRESS,
25
25
  title: 'Transfer from address',
26
- subtitle: 'Min $1 · No fee · 10 sec',
26
+ subtitle: 'Min $1 · Bridge fee · 10 sec',
27
27
  target: { kind: 'crypto' },
28
28
  },
29
29
  {
30
30
  id: FundingMethod.EXCHANGE,
31
31
  title: 'Transfer from Exchange',
32
- subtitle: 'Min $1 · Network fee · 2 min',
32
+ subtitle: 'Min $5 · Network fee · 2 min',
33
33
  target: { kind: 'cex' },
34
34
  },
35
35
  ];
@@ -21,7 +21,6 @@ export declare function useDepositRoute(kind: DepositRouteKind): {
21
21
  target: {
22
22
  chain: string;
23
23
  currency: string;
24
- address?: string;
25
24
  };
26
25
  pm: import("../../../hooks/openfort/useFunding").PaymentMethod | null;
27
26
  receiverAddress: string | null;
@@ -1,9 +1,7 @@
1
- import { ChainTypeEnum } from '@openfort/openfort-js';
2
1
  import { useState, useRef, useEffect } from 'react';
3
2
  import { useEthereumEmbeddedWallet } from '../../../ethereum/hooks/useEthereumEmbeddedWallet.js';
4
3
  import { useFunding } from '../../../hooks/openfort/useFunding.js';
5
4
  import { useFundingChains, nominalUnits } from '../../../hooks/openfort/useFundingChains.js';
6
- import { useOpenfortCore } from '../../../openfort/useOpenfort.js';
7
5
  import { useSolanaEmbeddedWallet } from '../../../solana/hooks/useSolanaEmbeddedWallet.js';
8
6
  import { logger } from '../../../utils/logger.js';
9
7
  import { isCexDeliverable } from './cexChains.js';
@@ -24,20 +22,21 @@ function paymentMethodFor(chain, currency) {
24
22
  */
25
23
  function useDepositRoute(kind) {
26
24
  var _a, _b, _c, _d, _e, _f, _g, _h;
27
- const { chainType } = useOpenfortCore();
28
25
  const ethWallet = useEthereumEmbeddedWallet();
29
26
  const solWallet = useSolanaEmbeddedWallet();
30
- // Funds land in the active chain's embedded wallet (EVM or Solana).
31
- const wallet = chainType === ChainTypeEnum.SVM ? solWallet : ethWallet;
32
27
  const { session, status, error, loading, isAvailable, fund, payLink, reset } = useFunding();
33
28
  const { chains: allChains, loading: chainsLoading } = useFundingChains();
34
29
  const target = useFundingTarget();
35
- // Drop the destination chain funding is cross-chain; same-chain is a plain
36
- // transfer with no Relay route, so it shouldn't appear as a source option.
37
- const sourceChains = allChains.filter((c) => c.id !== target.chain);
38
- // The CEX rail rides Coinbase Onramp, which only delivers to a fixed set of EVM
39
- // chains offer those as the pay-with sources.
40
- const chains = kind === 'cex' ? sourceChains.filter((c) => isCexDeliverable(c.id)) : sourceChains;
30
+ // The deposit recipient must live on the TARGET chain, so resolve the wallet by
31
+ // the target's family not the active chainType, which can disagree with the
32
+ // target (e.g. an EVM session whose funding target is still Solana) and would
33
+ // send an EVM address as the recipient for a Solana destination.
34
+ const wallet = isSolana(target.chain) ? solWallet : ethWallet;
35
+ // Sources are the full Relay list, including the destination chain itself so
36
+ // same-chain deposits (e.g. Solana → Solana) are offered as a plain transfer to
37
+ // the wallet address, alongside the cross-chain bridge routes. The CEX rail rides
38
+ // Coinbase Onramp, which only delivers to a fixed set of EVM chains.
39
+ const chains = kind === 'cex' ? allChains.filter((c) => isCexDeliverable(c.id)) : allChains;
41
40
  // Where funds land: the active embedded wallet (the Relay deposit recipient).
42
41
  const address = wallet.status === 'connected' ? wallet.address : undefined;
43
42
  const [chainId, setChainId] = useState('');
@@ -1 +1 @@
1
- {"version":3,"file":"useDepositRoute.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useDepositRoute.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,12 +2,10 @@
2
2
  * The destination route Deposit-hub funding settles into. Integrators override the
3
3
  * chain and currency via `uiConfig.funding.{targetChain,targetCurrency}`; both
4
4
  * default to USDC on the active chain type (Base for EVM, Solana mainnet for SVM)
5
- * so the flow works with zero configuration. `address` is the optional integrator
6
- * override (`uiConfig.funding.targetAddress`); when unset, callers fall back to the
7
- * active embedded wallet for the destination chain family.
5
+ * so the flow works with zero configuration. The deposit recipient is always the
6
+ * active embedded wallet for the destination chain family — callers resolve it.
8
7
  */
9
8
  export declare function useFundingTarget(): {
10
9
  chain: string;
11
10
  currency: string;
12
- address?: string;
13
11
  };
@@ -7,19 +7,17 @@ import { DEST_CHAIN_SOL, DEST_CHAIN, DEST_USDC_SOL, DEST_USDC } from './sources.
7
7
  * The destination route Deposit-hub funding settles into. Integrators override the
8
8
  * chain and currency via `uiConfig.funding.{targetChain,targetCurrency}`; both
9
9
  * default to USDC on the active chain type (Base for EVM, Solana mainnet for SVM)
10
- * so the flow works with zero configuration. `address` is the optional integrator
11
- * override (`uiConfig.funding.targetAddress`); when unset, callers fall back to the
12
- * active embedded wallet for the destination chain family.
10
+ * so the flow works with zero configuration. The deposit recipient is always the
11
+ * active embedded wallet for the destination chain family — callers resolve it.
13
12
  */
14
13
  function useFundingTarget() {
15
- var _a, _b, _c, _d, _e;
14
+ var _a, _b, _c, _d;
16
15
  const { uiConfig } = useOpenfort();
17
16
  const { chainType } = useOpenfortCore();
18
17
  const isSolana = chainType === ChainTypeEnum.SVM;
19
18
  return {
20
19
  chain: (_b = (_a = uiConfig.funding) === null || _a === void 0 ? void 0 : _a.targetChain) !== null && _b !== void 0 ? _b : (isSolana ? DEST_CHAIN_SOL : DEST_CHAIN),
21
20
  currency: (_d = (_c = uiConfig.funding) === null || _c === void 0 ? void 0 : _c.targetCurrency) !== null && _d !== void 0 ? _d : (isSolana ? DEST_USDC_SOL : DEST_USDC),
22
- address: (_e = uiConfig.funding) === null || _e === void 0 ? void 0 : _e.targetAddress,
23
21
  };
24
22
  }
25
23
 
@@ -1 +1 @@
1
- {"version":3,"file":"useFundingTarget.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useFundingTarget.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -17,7 +17,7 @@ import { isCexDeliverable, CEX_CHAIN_NAMES } from '../Deposit/cexChains.js';
17
17
  import { isDepositFlowActive, DepositProgress } from '../Deposit/DepositProgress.js';
18
18
  import { DepositStatus } from '../Deposit/DepositStatus.js';
19
19
  import { walletListBtn } from '../Deposit/formStyles.js';
20
- import { DEST_USDC } from '../Deposit/sources.js';
20
+ import { isSolana, DEST_USDC } from '../Deposit/sources.js';
21
21
  import { StepDivider, ButtonLogo } from '../Deposit/styles.js';
22
22
  import { useFundingTarget } from '../Deposit/useFundingTarget.js';
23
23
  import { sanitizeForParsing, sanitizeAmountInput } from '../Send/utils.js';
@@ -55,7 +55,7 @@ const hideBrokenLogo = (e) => {
55
55
  * success / failed screen. No Relay routing; Binance is gated until its rail lands.
56
56
  */
57
57
  const DepositCex = () => {
58
- var _a, _b, _c, _d, _e, _f, _g;
58
+ var _a, _b, _c, _d, _e, _f;
59
59
  const { triggerResize } = useOpenfort();
60
60
  const target = useFundingTarget();
61
61
  // CEX (Coinbase pay-link + session) is served by the Openfort API, not the
@@ -73,20 +73,19 @@ const DepositCex = () => {
73
73
  // wallet, Solana targets the Solana (SVM) embedded account — never cross families
74
74
  // (an EVM address on a Solana target would be rejected / mis-delivered). Accounts
75
75
  // come from the core store so EVM-only apps don't need the Solana React context.
76
- const isEvmTarget = target.chain.startsWith('eip155:');
77
76
  const solanaAddress = (_a = embeddedAccounts === null || embeddedAccounts === void 0 ? void 0 : embeddedAccounts.find((acc) => acc.chainType === ChainTypeEnum.SVM)) === null || _a === void 0 ? void 0 : _a.address;
78
- const address = (_b = target.address) !== null && _b !== void 0 ? _b : (isEvmTarget ? wallet.address : solanaAddress);
77
+ const address = isSolana(target.chain) ? solanaAddress : wallet.address;
79
78
  const chainSupported = isCexDeliverable(target.chain);
80
79
  // Resolve the destination asset + chain for the "Arrives as …" line. The live
81
80
  // chain list is curated for source selection, so the destination may be absent;
82
81
  // only claim a symbol we resolved, or USDC for the zero-config default.
83
82
  const destChain = chains.find((c) => c.id === target.chain);
84
- const destChainName = (_d = (_c = destChain === null || destChain === void 0 ? void 0 : destChain.name) !== null && _c !== void 0 ? _c : CEX_CHAIN_NAMES[target.chain]) !== null && _d !== void 0 ? _d : target.chain;
83
+ const destChainName = (_c = (_b = destChain === null || destChain === void 0 ? void 0 : destChain.name) !== null && _b !== void 0 ? _b : CEX_CHAIN_NAMES[target.chain]) !== null && _c !== void 0 ? _c : target.chain;
85
84
  const destAsset = destChain === null || destChain === void 0 ? void 0 : destChain.currencies.find((c) => c.address.toLowerCase() === target.currency.toLowerCase());
86
85
  const isDefaultUsdc = target.currency.toLowerCase() === DEST_USDC.toLowerCase();
87
- const destAssetLabel = (_e = destAsset === null || destAsset === void 0 ? void 0 : destAsset.symbol) !== null && _e !== void 0 ? _e : (isDefaultUsdc ? 'USDC' : null);
88
- const destAssetLogo = (_f = destAsset === null || destAsset === void 0 ? void 0 : destAsset.logo) !== null && _f !== void 0 ? _f : null;
89
- const destChainLogo = (_g = destChain === null || destChain === void 0 ? void 0 : destChain.logo) !== null && _g !== void 0 ? _g : null;
86
+ const destAssetLabel = (_d = destAsset === null || destAsset === void 0 ? void 0 : destAsset.symbol) !== null && _d !== void 0 ? _d : (isDefaultUsdc ? 'USDC' : null);
87
+ const destAssetLogo = (_e = destAsset === null || destAsset === void 0 ? void 0 : destAsset.logo) !== null && _e !== void 0 ? _e : null;
88
+ const destChainLogo = (_f = destChain === null || destChain === void 0 ? void 0 : destChain.logo) !== null && _f !== void 0 ? _f : null;
90
89
  // Mint the destination-bound session up-front (per target wallet), so the click
91
90
  // that opens Coinbase is a single fast pay-link call and stays popup-safe.
92
91
  //
@@ -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,9 @@ type Props = {
5
5
  activeChain: FundingChain | undefined;
6
6
  activeCurrency: FundingCurrency | undefined;
7
7
  loading: boolean;
8
+ /** Amount to send, in the source token's units. Owned by the parent so the
9
+ * amount input + presets are shared with the mobile (deeplink) path. */
10
+ amount: string;
8
11
  };
9
12
  /**
10
13
  * Desktop "transfer from wallet": send the source token to the Relay deposit
@@ -13,5 +16,5 @@ type Props = {
13
16
  * Openfort embedded account (that one is the destination, not the source).
14
17
  * Once the deposit lands, the funding session's status polling drives progress.
15
18
  */
16
- export declare function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading }: Props): import("react/jsx-runtime").JSX.Element | null;
19
+ export declare function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading, amount }: Props): import("react/jsx-runtime").JSX.Element | null;
17
20
  export {};
@@ -1,10 +1,11 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useState } from 'react';
2
+ import { useState, useEffect } from 'react';
3
3
  import { parseUnits, formatUnits, encodeFunctionData, erc20Abi } from 'viem';
4
4
  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 { useOpenfort } from '../../Openfort/useOpenfort.js';
8
9
  import { DepositStatus } from '../Deposit/DepositStatus.js';
9
10
  import { walletListBtn } from '../Deposit/formStyles.js';
10
11
  import { ButtonLogo } from '../Deposit/styles.js';
@@ -39,22 +40,6 @@ function walletErrorMessage(e) {
39
40
  }
40
41
  return typeof e === 'string' ? e : 'Transaction failed';
41
42
  }
42
- /** Keep only digits and a single decimal point. */
43
- function sanitizeAmount(v) {
44
- const cleaned = v.replace(/[^0-9.]/g, '');
45
- const [whole, ...rest] = cleaned.split('.');
46
- return rest.length ? `${whole}.${rest.join('')}` : cleaned;
47
- }
48
- const inputStyle = {
49
- width: '100%',
50
- padding: '12px 14px',
51
- borderRadius: 12,
52
- border: '1px solid var(--ck-body-divider, #e4e4e7)',
53
- background: 'var(--ck-body-background-secondary, #fafafa)',
54
- color: 'var(--ck-body-color, #111)',
55
- fontSize: 16,
56
- outline: 'none',
57
- };
58
43
  /**
59
44
  * Desktop "transfer from wallet": send the source token to the Relay deposit
60
45
  * address straight from the user's EXTERNAL browser-extension wallet
@@ -62,12 +47,18 @@ const inputStyle = {
62
47
  * Openfort embedded account (that one is the destination, not the source).
63
48
  * Once the deposit lands, the funding session's status polling drives progress.
64
49
  */
65
- function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading }) {
50
+ function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, loading, amount }) {
66
51
  const bridge = useEthereumBridge();
67
- const [amount, setAmount] = useState('');
52
+ const { triggerResize } = useOpenfort();
68
53
  const [busyId, setBusyId] = useState(null);
69
54
  const [error, setError] = useState(null);
70
55
  const [sent, setSent] = useState(false);
56
+ // Grow the modal when the busy / error / sent feedback toggles, so the "Confirm
57
+ // in your wallet…" and insufficient-balance messages are revealed instead of
58
+ // clipped below the fold (which reads as "nothing happened" after a click).
59
+ useEffect(() => {
60
+ triggerResize();
61
+ }, [busyId, error, sent, triggerResize]);
71
62
  if (!bridge)
72
63
  return null; // EVM-only (no wagmi) — nothing to send through
73
64
  // bridge.connectors already excludes the Openfort embedded connector, so these
@@ -134,7 +125,7 @@ function DepositWalletDesktop({ receiverAddress, activeChain, activeCurrency, lo
134
125
  setBusyId(null);
135
126
  }
136
127
  };
137
- return (jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, marginTop: 14 }, children: [jsx("input", { value: amount, onChange: (e) => setAmount(sanitizeAmount(e.target.value)), placeholder: `Amount${activeCurrency ? ` in ${activeCurrency.symbol}` : ''}`, inputMode: "decimal", style: inputStyle }), 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: {
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: {
138
129
  ...walletListBtn,
139
130
  display: 'flex',
140
131
  alignItems: 'center',
@@ -1 +1 @@
1
- {"version":3,"file":"DepositWalletDesktop.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"DepositWalletDesktop.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Transfer from wallet. On mobile, leads with open-dApp deeplinks that send the
3
- * user into their wallet app's in-app browser pointed at the hosted deposit page
4
- * (with the address/chain/token/amount prefilled). On desktop, sends straight
5
- * from the browser-extension wallet. Either way the manual deposit-address / QR
6
- * path stays available below.
2
+ * Transfer from wallet. Pick a source chain/token and an amount, then choose the
3
+ * wallet to send from. On mobile that's open-dApp deeplinks into the wallet app's
4
+ * in-app browser (address/chain/token/amount prefilled); on desktop it's a direct
5
+ * send from a browser-extension wallet. The manual deposit-address / QR path stays
6
+ * available below.
7
7
  */
8
8
  declare const DepositWallet: () => import("react/jsx-runtime").JSX.Element;
9
9
  export default DepositWallet;