diff --git a/apps/namadillo/src/App/AccountOverview/ShieldedAssetsOverview.tsx b/apps/namadillo/src/App/AccountOverview/ShieldedAssetsOverview.tsx index dab4ee1b6b..dfafae1463 100644 --- a/apps/namadillo/src/App/AccountOverview/ShieldedAssetsOverview.tsx +++ b/apps/namadillo/src/App/AccountOverview/ShieldedAssetsOverview.tsx @@ -1,7 +1,8 @@ import { ActionButton, Panel } from "@namada/components"; import { MaspSyncCover } from "App/Common/MaspSyncCover"; import { ShieldedAssetTable } from "App/Masp/ShieldedAssetTable"; -import { routes } from "App/routes"; +import { params, routes } from "App/routes"; +import { defaultShieldedAccountAtom } from "atoms/accounts"; import { applicationFeaturesAtom } from "atoms/settings"; import clsx from "clsx"; import { useAmountsInFiat } from "hooks/useAmountsInFiat"; @@ -16,6 +17,7 @@ export const ShieldedAssetsOverview = (): JSX.Element => { useAmountsInFiat(); const textContainerClassList = `flex h-full gap-1 items-center justify-center`; const requiresNewShieldedSync = useRequiresNewShieldedSync(); + const shieldedAccount = useAtomValue(defaultShieldedAccountAtom); // Hide TotalBalanceCard if shielded fiat amount is 0 but shielded assets exist const shouldHideBalanceCard = @@ -31,7 +33,7 @@ export const ShieldedAssetsOverview = (): JSX.Element => { footerButtons={ <> & { onChange?: (search: string) => void; + debounceTime?: number; }; export const Search = ({ onChange, className, placeholder, + debounceTime = 300, ...rest }: SearchProps): JSX.Element => { const [displaySearchIcon, setDisplaySearchIcon] = useState(true); const debouncedSearch = useRef( - debounce((value: string) => onChange?.(value), 300) + debounce((value: string) => onChange?.(value), debounceTime) ); // Hideous hack to add padding to placeholder in Firefox. diff --git a/apps/namadillo/src/App/Masp/MaspShield.tsx b/apps/namadillo/src/App/Masp/MaspShield.tsx index 305ad9ce18..1d4120c673 100644 --- a/apps/namadillo/src/App/Masp/MaspShield.tsx +++ b/apps/namadillo/src/App/Masp/MaspShield.tsx @@ -1,6 +1,5 @@ import { Panel } from "@namada/components"; import { AccountType } from "@namada/types"; -import { params, routes } from "App/routes"; import { TransferModule } from "App/Transfer/TransferModule"; import { OnSubmitTransferParams } from "App/Transfer/types"; import { allDefaultAccountsAtom } from "atoms/accounts"; @@ -15,7 +14,6 @@ import invariant from "invariant"; import { useAtom, useAtomValue } from "jotai"; import { createTransferDataFromNamada } from "lib/transactions"; import { useEffect, useState } from "react"; -import { Link, useLocation } from "react-router-dom"; import { AssetWithAmountAndChain } from "types"; interface MaspShieldProps { sourceAddress: string; @@ -50,14 +48,10 @@ export const MaspShield = ({ const chainParameters = useAtomValue(chainParametersAtom); const defaultAccounts = useAtomValue(allDefaultAccountsAtom); const [ledgerStatus, setLedgerStatusStop] = useAtom(ledgerStatusDataAtom); - const { pathname } = useLocation(); // DERIVED VALUES const transparentAddress = defaultAccounts.data?.find( (account) => account.type !== AccountType.ShieldedKeys )?.address; - const shieldedAddress = defaultAccounts.data?.find( - (account) => account.type === AccountType.ShieldedKeys - )?.address; const ledgerAccountInfo = ledgerStatus && { deviceConnected: ledgerStatus.connected, errorMessage: ledgerStatus.errorMessage, @@ -170,7 +164,7 @@ export const MaspShield = ({ isShieldedAddress: true, onChangeAddress: setDestinationAddress, memo, - onChangeMemo: pathname !== routes.shield ? setMemo : undefined, + onChangeMemo: setMemo, }} feeProps={feeProps} isSubmitting={isPerformingTransfer || isSuccess} @@ -183,16 +177,6 @@ export const MaspShield = ({ assetSelectorModalOpen={assetSelectorModalOpen} setAssetSelectorModalOpen={setAssetSelectorModalOpen} /> -
-

Looking to Unshield tokens?

- - Click here. - -
); }; diff --git a/apps/namadillo/src/App/Masp/ShieldedFungibleTable.tsx b/apps/namadillo/src/App/Masp/ShieldedFungibleTable.tsx index c05639e9ee..ad9ab6babd 100644 --- a/apps/namadillo/src/App/Masp/ShieldedFungibleTable.tsx +++ b/apps/namadillo/src/App/Masp/ShieldedFungibleTable.tsx @@ -29,12 +29,6 @@ const initialPage = 0; // Minimum thresholds to earn rewards for each asset const REWARD_THRESHOLDS: Record = { - statom: new BigNumber(10), - stosmo: new BigNumber(100), - sttia: new BigNumber(20), - osmo: new BigNumber(100), - atom: new BigNumber(10), - tia: new BigNumber(20), usdc: new BigNumber(50), }; diff --git a/apps/namadillo/src/App/NamadaTransfer/NamadaTransfer.tsx b/apps/namadillo/src/App/NamadaTransfer/NamadaTransfer.tsx index 95c0f98964..d2935d9103 100644 --- a/apps/namadillo/src/App/NamadaTransfer/NamadaTransfer.tsx +++ b/apps/namadillo/src/App/NamadaTransfer/NamadaTransfer.tsx @@ -1,6 +1,6 @@ import { Panel } from "@namada/components"; import { params } from "App/routes"; -import { isShieldedAddress } from "App/Transfer/common"; +import { isShieldedAddress, isTransparentAddress } from "App/Transfer/common"; import { TransferModule } from "App/Transfer/TransferModule"; import { OnSubmitTransferParams } from "App/Transfer/types"; import { chainParametersAtom } from "atoms/chain/atoms"; @@ -108,6 +108,7 @@ export const NamadaTransfer = ({ }); const isSourceShielded = isShieldedAddress(sourceAddress ?? ""); + const isSourceTransparent = isTransparentAddress(sourceAddress ?? ""); const isTargetShielded = isShieldedAddress(destinationAddress ?? ""); const onSubmitTransfer = async ({ @@ -165,7 +166,11 @@ export const NamadaTransfer = ({ return (
- {`${isSourceShielded ? "Shielded" : "Transparent"} Transfer`} + {`${ + isSourceShielded && !!destinationAddress ? "Shielded" + : isSourceTransparent && !!destinationAddress ? "Transparent" + : "" + } Transfer`}
{ return ( -

Transactions

); diff --git a/apps/namadillo/src/App/Transfer/AddressDropdown.tsx b/apps/namadillo/src/App/Transfer/AddressDropdown.tsx index c2ba3eacb0..4ad622beca 100644 --- a/apps/namadillo/src/App/Transfer/AddressDropdown.tsx +++ b/apps/namadillo/src/App/Transfer/AddressDropdown.tsx @@ -163,6 +163,12 @@ export const AddressDropdown = ({ } }; + const disconnectKeplr = async (): Promise => { + setConnectedWallets((obj) => ({ ...obj, [keplr.key]: false })); + const keplrInstance = await keplr.get(); + if (keplrInstance) await keplrInstance.disable(); + }; + const handleConnectKeplr = useCallback(async (): Promise => { try { setIsConnectingKeplr(true); @@ -185,9 +191,11 @@ export const AddressDropdown = ({ onSelectAddress?.(key.bech32Address); } catch (error) { console.error("Failed to fetch Keplr address after connection:", error); + disconnectKeplr(); } } catch (error) { console.error("Failed to connect to Keplr:", error); + disconnectKeplr(); } finally { setIsConnectingKeplr(false); } diff --git a/apps/namadillo/src/App/Transfer/DestinationAddressModal.tsx b/apps/namadillo/src/App/Transfer/DestinationAddressModal.tsx index 39c0ca70f4..4376c8decd 100644 --- a/apps/namadillo/src/App/Transfer/DestinationAddressModal.tsx +++ b/apps/namadillo/src/App/Transfer/DestinationAddressModal.tsx @@ -13,6 +13,7 @@ import { getChainFromAddress, getChainImageUrl } from "integrations/utils"; import { useAtom, useAtomValue } from "jotai"; import { useCallback, useState } from "react"; import { Address, Asset } from "types"; +import { timestampToRelativeTime } from "utils/dates"; import namadaShieldedIcon from "./assets/namada-shielded.svg"; import namadaTransparentIcon from "./assets/namada-transparent.svg"; import { @@ -38,6 +39,7 @@ type AddressOption = { address: string; icon: string; type: "transparent" | "shielded" | "ibc" | "keplr"; + timestamp?: number; }; type DestinationAddressModalProps = { @@ -120,7 +122,7 @@ export const DestinationAddressModal = ({ // Build recent addresses options const filteredRecentAddresses = filterNonIbcIfSourceIbc(recentAddresses); - const recentAddressOptions: AddressOption[] = filteredRecentAddresses + const recentAddressOptions = filteredRecentAddresses .filter((addresses) => !addressOptionsAddresses.includes(addresses.address)) .filter((addresses) => addresses.address !== sourceAddress) .map((recent) => ({ @@ -132,6 +134,7 @@ export const DestinationAddressModal = ({ : recent.type === "transparent" ? namadaTransparentIcon : getChainImageUrl(getChainFromAddress(recent.address ?? "")), // fallback for IBC type: recent.type, + timestamp: recent.timestamp, })); const validateAddress = (address: string): ValidationResult => { @@ -376,6 +379,13 @@ export const DestinationAddressModal = ({ + {option.timestamp && ( +
+ + {timestampToRelativeTime(option.timestamp)} + +
+ )} ))} diff --git a/apps/namadillo/src/App/Transfer/SelectToken.tsx b/apps/namadillo/src/App/Transfer/SelectToken.tsx index 433462fe68..647085dc38 100644 --- a/apps/namadillo/src/App/Transfer/SelectToken.tsx +++ b/apps/namadillo/src/App/Transfer/SelectToken.tsx @@ -92,25 +92,31 @@ export const SelectToken = ({ const filteredTokens = useMemo(() => { return assetsWithAmounts .filter((assetWithAmount) => { - if (assetWithAmount.amount.eq(0)) return false; - - // Filter by search term + // Filter by search term (if provided) const matchesSearch = - !!filter && + !filter || assetWithAmount.asset.name .toLowerCase() .includes(filter.toLowerCase()); + // Filter by network (if provided) const matchesNetwork = + !selectedNetwork || selectedNetwork === - assetWithAmount.asset.traces?.[0]?.counterparty?.chain_name; - return !selectedNetwork ? true : matchesSearch || matchesNetwork; + assetWithAmount.asset.traces?.[0]?.counterparty?.chain_name; + + // Filter out zero balances + const hasBalance = !assetWithAmount.amount.eq(0); + + // All conditions must be true + return matchesSearch && matchesNetwork && hasBalance; }) .sort((a, b) => Number(b.amount) - Number(a.amount)); }, [assetsWithAmounts, filter, selectedNetwork, assetToNetworkMap]); const handleNetworkSelect = (networkName: string): void => { setSelectedNetwork(selectedNetwork === networkName ? null : networkName); + setFilter(""); // Clear search input when network is selected }; const handleWalletAddressChange = (address: string): void => { @@ -119,6 +125,7 @@ export const SelectToken = ({ }; const handleClose = (): void => { + setFilter(""); onClose(); }; @@ -224,7 +231,10 @@ export const SelectToken = ({ >