Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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 =
Expand All @@ -31,7 +33,7 @@ export const ShieldedAssetsOverview = (): JSX.Element => {
footerButtons={
<>
<ActionButton
href={routes.transfer}
href={`${routes.transfer}?${params.source}=${shieldedAccount?.address || ""}`}
outlineColor="yellow"
size="xs"
className="w-auto px-4"
Expand Down
4 changes: 3 additions & 1 deletion apps/namadillo/src/App/Common/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ type SearchProps = Omit<
"onChange" | "onFocus" | "onBlur" | "type"
> & {
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.
Expand Down
18 changes: 1 addition & 17 deletions apps/namadillo/src/App/Masp/MaspShield.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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}
Expand All @@ -183,16 +177,6 @@ export const MaspShield = ({
assetSelectorModalOpen={assetSelectorModalOpen}
setAssetSelectorModalOpen={setAssetSelectorModalOpen}
/>
<div className="flex flex-row font-normal justify-center mt-10 gap-2">
<h4>Looking to Unshield tokens?</h4>
<Link
className="text-yellow underline"
to={`${routes.transfer}?${params.source}=${shieldedAddress || ""}&${params.destination}=${transparentAddress}`}
title={`View pending transactions`}
>
Click here.
</Link>
</div>
</Panel>
);
};
6 changes: 0 additions & 6 deletions apps/namadillo/src/App/Masp/ShieldedFungibleTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ const initialPage = 0;

// Minimum thresholds to earn rewards for each asset
const REWARD_THRESHOLDS: Record<string, BigNumber> = {
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),
};

Expand Down
9 changes: 7 additions & 2 deletions apps/namadillo/src/App/NamadaTransfer/NamadaTransfer.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -108,6 +108,7 @@ export const NamadaTransfer = ({
});

const isSourceShielded = isShieldedAddress(sourceAddress ?? "");
const isSourceTransparent = isTransparentAddress(sourceAddress ?? "");
const isTargetShielded = isShieldedAddress(destinationAddress ?? "");

const onSubmitTransfer = async ({
Expand Down Expand Up @@ -165,7 +166,11 @@ export const NamadaTransfer = ({
return (
<Panel className="min-h-[600px] rounded-sm flex flex-col flex-1 py-9">
<header className="text-yellow text-center mb-8 gap-6">
{`${isSourceShielded ? "Shielded" : "Transparent"} Transfer`}
{`${
isSourceShielded && !!destinationAddress ? "Shielded"
: isSourceTransparent && !!destinationAddress ? "Transparent"
: ""
} Transfer`}
</header>
<TransferModule
source={{
Expand Down
1 change: 0 additions & 1 deletion apps/namadillo/src/App/Transactions/TransactionDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const TransactionDetails = (): JSX.Element => {

return (
<Panel className="flex-1 h-full">
<h1 className="mb-12">Transactions</h1>
<TransactionReceipt transaction={transaction} />
</Panel>
);
Expand Down
8 changes: 8 additions & 0 deletions apps/namadillo/src/App/Transfer/AddressDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ export const AddressDropdown = ({
}
};

const disconnectKeplr = async (): Promise<void> => {
setConnectedWallets((obj) => ({ ...obj, [keplr.key]: false }));
const keplrInstance = await keplr.get();
if (keplrInstance) await keplrInstance.disable();
};

const handleConnectKeplr = useCallback(async (): Promise<void> => {
try {
setIsConnectingKeplr(true);
Expand All @@ -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);
}
Expand Down
12 changes: 11 additions & 1 deletion apps/namadillo/src/App/Transfer/DestinationAddressModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -38,6 +39,7 @@ type AddressOption = {
address: string;
icon: string;
type: "transparent" | "shielded" | "ibc" | "keplr";
timestamp?: number;
};

type DestinationAddressModalProps = {
Expand Down Expand Up @@ -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) => ({
Expand All @@ -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 => {
Expand Down Expand Up @@ -376,6 +379,13 @@ export const DestinationAddressModal = ({
</span>
</div>
</div>
{option.timestamp && (
<div className="flex flex-col items-end">
<span className="text-xs text-neutral-500">
{timestampToRelativeTime(option.timestamp)}
</span>
</div>
)}
</button>
))}
</Stack>
Expand Down
33 changes: 23 additions & 10 deletions apps/namadillo/src/App/Transfer/SelectToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -119,6 +125,7 @@ export const SelectToken = ({
};

const handleClose = (): void => {
setFilter("");
onClose();
};

Expand Down Expand Up @@ -224,7 +231,10 @@ export const SelectToken = ({
>
<li>
<button
onClick={() => setSelectedNetwork(null)}
onClick={() => {
setFilter(""); // Clear search input when "All Networks" is selected
setSelectedNetwork(null);
}}
className={`flex items-center gap-3 p-2 w-full rounded-sm transition-colors ${
selectedNetwork === null ?
"bg-white/5 border border-white/20"
Expand All @@ -240,9 +250,10 @@ export const SelectToken = ({
{allNetworks.map((network) => (
<li key={network.chain_name}>
<button
onClick={() =>
handleNetworkSelect(network.chain_name.toLowerCase())
}
onClick={() => {
setFilter("");
handleNetworkSelect(network.chain_name.toLowerCase());
}}
className={`flex items-center gap-3 p-2 w-full rounded-sm transition-colors ${
selectedNetwork === network.chain_name ?
"bg-white/5 border border-white/20"
Expand Down Expand Up @@ -277,6 +288,8 @@ export const SelectToken = ({
<Search
placeholder="Insert token name or symbol"
onChange={setFilter}
value={filter}
debounceTime={0}
/>
</div>

Expand Down
4 changes: 1 addition & 3 deletions apps/namadillo/src/App/Transfer/TransferDestination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,7 @@ export const TransferDestination = ({
</div>
: <button
type="button"
disabled={
isShieldingTransaction || isSubmitting || !sourceAsset
}
disabled={isShieldingTransaction || isSubmitting}
onClick={handleOpenModal}
className={clsx(
"flex justify-between items-center bg-neutral-900 p-2 rounded-sm w-full",
Expand Down
30 changes: 29 additions & 1 deletion apps/namadillo/src/App/Transfer/TransferModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { CurrentStatus } from "App/Common/CurrentStatus";
import { IconTooltip } from "App/Common/IconTooltip";
import { InlineError } from "App/Common/InlineError";
import { params, routes } from "App/routes";
import {
defaultShieldedAccountAtom,
defaultTransparentAccountAtom,
} from "atoms/accounts";
import {
namadaShieldedAssetsAtom,
namadaTransparentAssetsAtom,
Expand Down Expand Up @@ -32,7 +36,11 @@ import { TransferArrow } from "./TransferArrow";
import { TransferDestination } from "./TransferDestination";
import { TransferSource } from "./TransferSource";
import { TransferModuleProps, ValidationResult } from "./types";
import { getButtonText, validateTransferForm } from "./utils";
import {
determineTransferType,
getButtonText,
validateTransferForm,
} from "./utils";

export const TransferModule = ({
source,
Expand All @@ -59,6 +67,8 @@ export const TransferModule = ({
namadaShieldedAssetsAtom
: namadaTransparentAssetsAtom
);
const shieldedAccount = useAtomValue(defaultShieldedAccountAtom);
const transparentAccount = useAtomValue(defaultTransparentAccountAtom);
const [searchParams, setSearchParams] = useSearchParams();
const asset = searchParams.get(params.asset) || "";
const assetsWithAmounts = useAssetsWithAmounts(sourceAddress);
Expand Down Expand Up @@ -102,6 +112,12 @@ export const TransferModule = ({
validationResult,
availableAmountMinusFees,
buttonTextErrors,
transactionType: determineTransferType({
sourceAddress,
destinationAddress,
}),
sourceAddress,
destinationAddress,
});
};

Expand Down Expand Up @@ -332,6 +348,18 @@ export const TransferModule = ({
setAssetSelectorModalOpen(false);
}}
/>
{isShielding && !isSubmitting && (
<div className="flex flex-row font-normal justify-center mt-10 gap-2">
<h4>Looking to Unshield tokens?</h4>
<Link
className="text-yellow underline"
to={`${routes.transfer}?${params.source}=${shieldedAccount?.address || ""}&${params.destination}=${transparentAccount?.address || ""}`}
title={`View pending transactions`}
>
Click here.
</Link>
</div>
)}
</>
);
};
Loading