Skip to content

Commit

Permalink
feat: integrate with namada registry
Browse files Browse the repository at this point in the history
  • Loading branch information
emccorson committed Nov 11, 2024
1 parent 08d7e68 commit 357ccf1
Show file tree
Hide file tree
Showing 21 changed files with 273 additions and 166 deletions.
1 change: 1 addition & 0 deletions apps/namadillo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"jotai": "^2.6.3",
"jotai-tanstack-query": "^0.8.5",
"lodash.debounce": "^4.0.8",
"namada-chain-registry": "https://github.com/anoma/namada-chain-registry#add-housefire-ibc",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.1.0",
Expand Down
38 changes: 23 additions & 15 deletions apps/namadillo/src/App/Ibc/IbcTransfer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Asset, Chain } from "@chain-registry/types";
import { Chain } from "@chain-registry/types";
import { Window as KeplrWindow } from "@keplr-wallet/types";
import { mapUndefined } from "@namada/utils";
import { TransactionTimeline } from "App/Common/TransactionTimeline";
Expand All @@ -8,19 +8,20 @@ import {
} from "App/Transfer/TransferModule";
import { allDefaultAccountsAtom } from "atoms/accounts";
import {
assetBalanceAtomFamily,
availableChainsAtom,
chainRegistryAtom,
ibcTransferAtom,
} from "atoms/integrations";
import clsx from "clsx";
import { AnimatePresence, motion } from "framer-motion";
import { useAssetAmount } from "hooks/useAssetAmount";
import { useWalletManager } from "hooks/useWalletManager";
import { wallets } from "integrations";
import { KeplrWalletManager } from "integrations/Keplr";
import { useAtomValue } from "jotai";
import { useEffect, useMemo, useState } from "react";
import namadaChain from "registry/namada.json";
import { Address } from "types";
import { IbcTopHeader } from "./IbcTopHeader";

import * as cosmos from "chain-registry/mainnet/cosmoshub";
Expand All @@ -33,7 +34,7 @@ export const IbcTransfer: React.FC = () => {
const chainRegistry = useAtomValue(chainRegistryAtom);
const availableChains = useAtomValue(availableChainsAtom);
const [shielded, setShielded] = useState<boolean>(true);
const [selectedAsset, setSelectedAsset] = useState<Asset>();
const [selectedAssetAddress, setSelectedAssetAddress] = useState<Address>();
const [currentStep, setCurrentStep] = useState(0);
const [generalErrorMessage, setGeneralErrorMessage] = useState("");
const performIbcTransfer = useAtomValue(ibcTransferAtom);
Expand All @@ -45,15 +46,17 @@ export const IbcTransfer: React.FC = () => {
chainId,
} = useWalletManager(keplr);

const {
balance: availableAmount,
availableAssets,
isLoading: isLoadingBalances,
} = useAssetAmount({
registry,
asset: selectedAsset,
walletAddress: sourceAddress,
});
const { data: availableAssets, isLoading: isLoadingBalances } = useAtomValue(
assetBalanceAtomFamily({
chain: registry?.chain,
walletAddress: sourceAddress,
})
);

const availableAmount = mapUndefined(
(address) => availableAssets?.[address]?.amount,
selectedAssetAddress
);

const transactionFee = useMemo(() => {
if (typeof registry !== "undefined") {
Expand All @@ -63,7 +66,7 @@ export const IbcTransfer: React.FC = () => {
}, [registry]);

useEffect(() => {
setSelectedAsset(undefined);
setSelectedAssetAddress(undefined);
}, [registry]);

const namadaAddress = useMemo(() => {
Expand All @@ -90,6 +93,11 @@ export const IbcTransfer: React.FC = () => {
throw new Error("Chain ID is undefined");
}

const selectedAsset = mapUndefined(
(address) => availableAssets?.[address],
selectedAssetAddress
);

if (!selectedAsset) {
throw new Error("No asset is selected");
}
Expand Down Expand Up @@ -182,7 +190,7 @@ export const IbcTransfer: React.FC = () => {
source={{
isLoadingAssets: isLoadingBalances,
availableAssets,
selectedAsset,
selectedAssetAddress,
availableAmount,
availableChains,
onChangeChain,
Expand All @@ -191,7 +199,7 @@ export const IbcTransfer: React.FC = () => {
wallet: wallets.keplr,
walletAddress: sourceAddress,
onChangeWallet,
onChangeSelectedAsset: setSelectedAsset,
onChangeSelectedAsset: setSelectedAssetAddress,
}}
destination={{
chain: namadaChain as Chain,
Expand Down
23 changes: 17 additions & 6 deletions apps/namadillo/src/App/Ibc/IbcWithdraw.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Asset, Chain } from "@chain-registry/types";
import { Chain } from "@chain-registry/types";
import { WindowWithNamada } from "@namada/types";
import { mapUndefined } from "@namada/utils";
import {
Expand All @@ -16,6 +16,7 @@ import { useAtomValue } from "jotai";
import { useState } from "react";
import namadaChainRegistry from "registry/namada.json";
import { namadaAsset } from "registry/namadaAsset";
import { Address, AddressWithAssetAndAmountMap } from "types";
import { getSdkInstance } from "utils/sdk";
import { IbcTopHeader } from "./IbcTopHeader";

Expand All @@ -30,16 +31,26 @@ export const IbcWithdraw: React.FC = () => {
const namadaChainParams = useAtomValue(chainParametersAtom);
const namadaChain = useAtomValue(chainAtom);

const [selectedAsset, setSelectedAsset] = useState<Asset>();
const [selectedAssetAddress, setSelectedAssetAddress] = useState<Address>();

// TODO: remove hardcoding and display assets other than NAM
const availableAmount = useAtomValue(accountBalanceAtom).data;
const availableAssets = [namadaAsset];
const availableAssets: AddressWithAssetAndAmountMap =
availableAmount ?
{
[namadaAsset.address]: {
asset: namadaAsset,
address: namadaAsset.address,
amount: availableAmount,
},
}
: {};

const GAS_PRICE = BigNumber(0.000001); // 0.000001 NAM
const GAS_LIMIT = BigNumber(1_000_000);
const transactionFee = {
token: namadaAsset,
address: namadaAsset.address,
asset: namadaAsset,
amount: GAS_PRICE.multipliedBy(GAS_LIMIT),
};

Expand Down Expand Up @@ -115,8 +126,8 @@ export const IbcWithdraw: React.FC = () => {
isShielded: false,
availableAssets,
availableAmount,
selectedAsset,
onChangeSelectedAsset: setSelectedAsset,
selectedAssetAddress,
onChangeSelectedAsset: setSelectedAssetAddress,
}}
destination={{
wallet: wallets.keplr,
Expand Down
15 changes: 7 additions & 8 deletions apps/namadillo/src/App/Ibc/ShieldAllAssetList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { TokenCurrency } from "App/Common/TokenCurrency";
import BigNumber from "bignumber.js";
import clsx from "clsx";
import { getAssetImageUrl } from "integrations/utils";
import { AddressWithAssetAndBalance } from "types";
import { AddressWithAssetAndAmount } from "types";

export type SelectableAddressWithAssetAndBalance =
AddressWithAssetAndBalance & {
checked: boolean;
};
export type SelectableAddressWithAssetAndAmount = AddressWithAssetAndAmount & {
checked: boolean;
};

type ShieldAllAssetListProps = {
assets: SelectableAddressWithAssetAndBalance[];
assets: SelectableAddressWithAssetAndAmount[];
onToggleAsset: (asset: Asset) => void;
};

Expand All @@ -24,7 +23,7 @@ export const ShieldAllAssetList = ({
<ul className="max-h-[200px] dark-scrollbar -mr-2">
{assets.map(
(
assetWithBalance: SelectableAddressWithAssetAndBalance,
assetWithBalance: SelectableAddressWithAssetAndAmount,
idx: number
) => {
const image = getAssetImageUrl(assetWithBalance.asset);
Expand Down Expand Up @@ -55,7 +54,7 @@ export const ShieldAllAssetList = ({
<TokenCurrency
currencySymbolClassName="hidden"
asset={assetWithBalance.asset}
amount={assetWithBalance.balance || new BigNumber(0)}
amount={assetWithBalance.amount || new BigNumber(0)}
/>
</span>
</li>
Expand Down
8 changes: 4 additions & 4 deletions apps/namadillo/src/App/Ibc/ShieldAllPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import { TransferTransactionFee } from "App/Transfer/TransferTransactionFee";
import { getTransactionFee } from "integrations/utils";
import { useEffect, useMemo, useState } from "react";
import {
AddressWithAssetAndBalance,
AddressWithAssetAndAmount,
ChainRegistryEntry,
WalletProvider,
} from "types";
import {
SelectableAddressWithAssetAndBalance,
SelectableAddressWithAssetAndAmount,
ShieldAllAssetList,
} from "./ShieldAllAssetList";
import { ShieldAllContainer } from "./ShieldAllContainer";
Expand All @@ -26,7 +26,7 @@ type ShieldAllPanelProps = {
wallet: WalletProvider;
walletAddress: string;
isLoading: boolean;
assetList: AddressWithAssetAndBalance[];
assetList: AddressWithAssetAndAmount[];
onShieldAll: (assets: Asset[]) => void;
};

Expand All @@ -39,7 +39,7 @@ export const ShieldAllPanel = ({
onShieldAll,
}: ShieldAllPanelProps): JSX.Element => {
const [selectableAssets, setSelectableAssets] = useState<
SelectableAddressWithAssetAndBalance[]
SelectableAddressWithAssetAndAmount[]
>([]);

useEffect(() => {
Expand Down
15 changes: 7 additions & 8 deletions apps/namadillo/src/App/Transfer/SelectAssetModal.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { Asset } from "@chain-registry/types";
import { Stack } from "@namada/components";
import { Search } from "App/Common/Search";
import { SelectModal } from "App/Common/SelectModal";
import clsx from "clsx";
import { useMemo, useState } from "react";
import { twMerge } from "tailwind-merge";
import { WalletProvider } from "types";
import { Address, AddressWithAsset, WalletProvider } from "types";
import { AssetCard } from "./AssetCard";
import { ConnectedWalletInfo } from "./ConnectedWalletInfo";

type SelectWalletModalProps = {
onClose: () => void;
onSelect: (asset: Asset) => void;
assets: Asset[];
onSelect: (address: Address) => void;
assets: AddressWithAsset[];
wallet: WalletProvider;
walletAddress: string;
};
Expand All @@ -28,7 +27,7 @@ export const SelectAssetModal = ({

const filteredAssets = useMemo(() => {
return assets.filter(
(asset) =>
({ asset }) =>
asset.name.toLowerCase().indexOf(filter.toLowerCase()) >= 0 ||
asset.symbol.toLowerCase().indexOf(filter.toLowerCase()) >= 0
);
Expand All @@ -45,11 +44,11 @@ export const SelectAssetModal = ({
gap={0}
className="max-h-[400px] overflow-auto dark-scrollbar pb-4 mr-[-0.5rem]"
>
{filteredAssets.map((asset: Asset, index: number) => (
<li key={index} className="text-sm">
{filteredAssets.map(({ asset, address }) => (
<li key={address} className="text-sm">
<button
onClick={() => {
onSelect(asset);
onSelect(address);
onClose();
}}
className={twMerge(
Expand Down
Loading

0 comments on commit 357ccf1

Please sign in to comment.