Skip to content

Commit 799e84c

Browse files
committed
feat: use namada registry + IBC decoding fixes (#1240)
- Use Namada chain registry. Closes #1217 - Index assets by their original address, not by base denom. Fixes #1220 - Look up registry asset by base denom, alias or address - Use address to index assets in 'Select Asset' list
1 parent 08d7e68 commit 799e84c

22 files changed

+275
-170
lines changed

apps/namadillo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"jotai": "^2.6.3",
2828
"jotai-tanstack-query": "^0.8.5",
2929
"lodash.debounce": "^4.0.8",
30+
"namada-chain-registry": "https://github.com/anoma/namada-chain-registry",
3031
"react": "^18.3.1",
3132
"react-dom": "^18.3.1",
3233
"react-icons": "^5.1.0",

apps/namadillo/src/App/Ibc/IbcTransfer.tsx

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Asset, Chain } from "@chain-registry/types";
1+
import { Chain } from "@chain-registry/types";
22
import { Window as KeplrWindow } from "@keplr-wallet/types";
33
import { mapUndefined } from "@namada/utils";
44
import { TransactionTimeline } from "App/Common/TransactionTimeline";
@@ -8,19 +8,20 @@ import {
88
} from "App/Transfer/TransferModule";
99
import { allDefaultAccountsAtom } from "atoms/accounts";
1010
import {
11+
assetBalanceAtomFamily,
1112
availableChainsAtom,
1213
chainRegistryAtom,
1314
ibcTransferAtom,
1415
} from "atoms/integrations";
1516
import clsx from "clsx";
1617
import { AnimatePresence, motion } from "framer-motion";
17-
import { useAssetAmount } from "hooks/useAssetAmount";
1818
import { useWalletManager } from "hooks/useWalletManager";
1919
import { wallets } from "integrations";
2020
import { KeplrWalletManager } from "integrations/Keplr";
2121
import { useAtomValue } from "jotai";
2222
import { useEffect, useMemo, useState } from "react";
2323
import namadaChain from "registry/namada.json";
24+
import { Address } from "types";
2425
import { IbcTopHeader } from "./IbcTopHeader";
2526

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

48-
const {
49-
balance: availableAmount,
50-
availableAssets,
51-
isLoading: isLoadingBalances,
52-
} = useAssetAmount({
53-
registry,
54-
asset: selectedAsset,
55-
walletAddress: sourceAddress,
56-
});
49+
const { data: availableAssets, isLoading: isLoadingBalances } = useAtomValue(
50+
assetBalanceAtomFamily({
51+
chain: registry?.chain,
52+
walletAddress: sourceAddress,
53+
})
54+
);
55+
56+
const availableAmount = mapUndefined(
57+
(address) => availableAssets?.[address]?.amount,
58+
selectedAssetAddress
59+
);
5760

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

6568
useEffect(() => {
66-
setSelectedAsset(undefined);
69+
setSelectedAssetAddress(undefined);
6770
}, [registry]);
6871

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

96+
const selectedAsset = mapUndefined(
97+
(address) => availableAssets?.[address],
98+
selectedAssetAddress
99+
);
100+
93101
if (!selectedAsset) {
94102
throw new Error("No asset is selected");
95103
}
@@ -182,7 +190,7 @@ export const IbcTransfer: React.FC = () => {
182190
source={{
183191
isLoadingAssets: isLoadingBalances,
184192
availableAssets,
185-
selectedAsset,
193+
selectedAssetAddress,
186194
availableAmount,
187195
availableChains,
188196
onChangeChain,
@@ -191,7 +199,7 @@ export const IbcTransfer: React.FC = () => {
191199
wallet: wallets.keplr,
192200
walletAddress: sourceAddress,
193201
onChangeWallet,
194-
onChangeSelectedAsset: setSelectedAsset,
202+
onChangeSelectedAsset: setSelectedAssetAddress,
195203
}}
196204
destination={{
197205
chain: namadaChain as Chain,

apps/namadillo/src/App/Ibc/IbcWithdraw.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Asset, Chain } from "@chain-registry/types";
1+
import { Chain } from "@chain-registry/types";
22
import { WindowWithNamada } from "@namada/types";
33
import { mapUndefined } from "@namada/utils";
44
import {
@@ -16,6 +16,7 @@ import { useAtomValue } from "jotai";
1616
import { useState } from "react";
1717
import namadaChainRegistry from "registry/namada.json";
1818
import { namadaAsset } from "registry/namadaAsset";
19+
import { Address, AddressWithAssetAndAmountMap } from "types";
1920
import { getSdkInstance } from "utils/sdk";
2021
import { IbcTopHeader } from "./IbcTopHeader";
2122

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

33-
const [selectedAsset, setSelectedAsset] = useState<Asset>();
34+
const [selectedAssetAddress, setSelectedAssetAddress] = useState<Address>();
3435

3536
// TODO: remove hardcoding and display assets other than NAM
3637
const availableAmount = useAtomValue(accountBalanceAtom).data;
37-
const availableAssets = [namadaAsset];
38+
const availableAssets: AddressWithAssetAndAmountMap =
39+
availableAmount ?
40+
{
41+
[namadaAsset.address]: {
42+
asset: namadaAsset,
43+
originalAddress: namadaAsset.address,
44+
amount: availableAmount,
45+
},
46+
}
47+
: {};
3848

3949
const GAS_PRICE = BigNumber(0.000001); // 0.000001 NAM
4050
const GAS_LIMIT = BigNumber(1_000_000);
4151
const transactionFee = {
42-
token: namadaAsset,
52+
originalAddress: namadaAsset.address,
53+
asset: namadaAsset,
4354
amount: GAS_PRICE.multipliedBy(GAS_LIMIT),
4455
};
4556

@@ -115,8 +126,8 @@ export const IbcWithdraw: React.FC = () => {
115126
isShielded: false,
116127
availableAssets,
117128
availableAmount,
118-
selectedAsset,
119-
onChangeSelectedAsset: setSelectedAsset,
129+
selectedAssetAddress,
130+
onChangeSelectedAsset: setSelectedAssetAddress,
120131
}}
121132
destination={{
122133
wallet: wallets.keplr,

apps/namadillo/src/App/Ibc/ShieldAllAssetList.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ import { TokenCurrency } from "App/Common/TokenCurrency";
44
import BigNumber from "bignumber.js";
55
import clsx from "clsx";
66
import { getAssetImageUrl } from "integrations/utils";
7-
import { AddressWithAssetAndBalance } from "types";
7+
import { AddressWithAssetAndAmount } from "types";
88

9-
export type SelectableAddressWithAssetAndBalance =
10-
AddressWithAssetAndBalance & {
11-
checked: boolean;
12-
};
9+
export type SelectableAddressWithAssetAndAmount = AddressWithAssetAndAmount & {
10+
checked: boolean;
11+
};
1312

1413
type ShieldAllAssetListProps = {
15-
assets: SelectableAddressWithAssetAndBalance[];
14+
assets: SelectableAddressWithAssetAndAmount[];
1615
onToggleAsset: (asset: Asset) => void;
1716
};
1817

@@ -24,7 +23,7 @@ export const ShieldAllAssetList = ({
2423
<ul className="max-h-[200px] dark-scrollbar -mr-2">
2524
{assets.map(
2625
(
27-
assetWithBalance: SelectableAddressWithAssetAndBalance,
26+
assetWithBalance: SelectableAddressWithAssetAndAmount,
2827
idx: number
2928
) => {
3029
const image = getAssetImageUrl(assetWithBalance.asset);
@@ -55,7 +54,7 @@ export const ShieldAllAssetList = ({
5554
<TokenCurrency
5655
currencySymbolClassName="hidden"
5756
asset={assetWithBalance.asset}
58-
amount={assetWithBalance.balance || new BigNumber(0)}
57+
amount={assetWithBalance.amount || new BigNumber(0)}
5958
/>
6059
</span>
6160
</li>

apps/namadillo/src/App/Ibc/ShieldAllPanel.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import { TransferTransactionFee } from "App/Transfer/TransferTransactionFee";
1111
import { getTransactionFee } from "integrations/utils";
1212
import { useEffect, useMemo, useState } from "react";
1313
import {
14-
AddressWithAssetAndBalance,
14+
AddressWithAssetAndAmount,
1515
ChainRegistryEntry,
1616
WalletProvider,
1717
} from "types";
1818
import {
19-
SelectableAddressWithAssetAndBalance,
19+
SelectableAddressWithAssetAndAmount,
2020
ShieldAllAssetList,
2121
} from "./ShieldAllAssetList";
2222
import { ShieldAllContainer } from "./ShieldAllContainer";
@@ -26,7 +26,7 @@ type ShieldAllPanelProps = {
2626
wallet: WalletProvider;
2727
walletAddress: string;
2828
isLoading: boolean;
29-
assetList: AddressWithAssetAndBalance[];
29+
assetList: AddressWithAssetAndAmount[];
3030
onShieldAll: (assets: Asset[]) => void;
3131
};
3232

@@ -39,7 +39,7 @@ export const ShieldAllPanel = ({
3939
onShieldAll,
4040
}: ShieldAllPanelProps): JSX.Element => {
4141
const [selectableAssets, setSelectableAssets] = useState<
42-
SelectableAddressWithAssetAndBalance[]
42+
SelectableAddressWithAssetAndAmount[]
4343
>([]);
4444

4545
useEffect(() => {

apps/namadillo/src/App/Transfer/SelectAssetModal.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import { Asset } from "@chain-registry/types";
21
import { Stack } from "@namada/components";
32
import { Search } from "App/Common/Search";
43
import { SelectModal } from "App/Common/SelectModal";
54
import clsx from "clsx";
65
import { useMemo, useState } from "react";
76
import { twMerge } from "tailwind-merge";
8-
import { WalletProvider } from "types";
7+
import { Address, AddressWithAsset, WalletProvider } from "types";
98
import { AssetCard } from "./AssetCard";
109
import { ConnectedWalletInfo } from "./ConnectedWalletInfo";
1110

1211
type SelectWalletModalProps = {
1312
onClose: () => void;
14-
onSelect: (asset: Asset) => void;
15-
assets: Asset[];
13+
onSelect: (address: Address) => void;
14+
assets: AddressWithAsset[];
1615
wallet: WalletProvider;
1716
walletAddress: string;
1817
};
@@ -28,7 +27,7 @@ export const SelectAssetModal = ({
2827

2928
const filteredAssets = useMemo(() => {
3029
return assets.filter(
31-
(asset) =>
30+
({ asset }) =>
3231
asset.name.toLowerCase().indexOf(filter.toLowerCase()) >= 0 ||
3332
asset.symbol.toLowerCase().indexOf(filter.toLowerCase()) >= 0
3433
);
@@ -45,11 +44,11 @@ export const SelectAssetModal = ({
4544
gap={0}
4645
className="max-h-[400px] overflow-auto dark-scrollbar pb-4 mr-[-0.5rem]"
4746
>
48-
{filteredAssets.map((asset: Asset, index: number) => (
49-
<li key={index} className="text-sm">
47+
{filteredAssets.map(({ asset, originalAddress }) => (
48+
<li key={originalAddress} className="text-sm">
5049
<button
5150
onClick={() => {
52-
onSelect(asset);
51+
onSelect(originalAddress);
5352
onClose();
5453
}}
5554
className={twMerge(

0 commit comments

Comments
 (0)