diff --git a/apps/namadillo/.gitignore b/apps/namadillo/.gitignore index 320fb3dfbc..812f78443a 100644 --- a/apps/namadillo/.gitignore +++ b/apps/namadillo/.gitignore @@ -8,3 +8,4 @@ /test-results/ /playwright-report/ /playwright/.cache/ +/public/localnet-config.toml diff --git a/apps/namadillo/package.json b/apps/namadillo/package.json index 5edafd7cfc..ef30b9d1f5 100644 --- a/apps/namadillo/package.json +++ b/apps/namadillo/package.json @@ -10,7 +10,7 @@ "@chain-registry/client": "^1.53.5", "@cosmjs/encoding": "^0.32.3", "@keplr-wallet/types": "^0.12.136", - "@namada/indexer-client": "0.0.30", + "@namada/indexer-client": "0.0.31", "@tailwindcss/container-queries": "^0.1.1", "@tanstack/query-core": "^5.40.0", "@tanstack/react-query": "^5.40.0", diff --git a/apps/namadillo/public/config.toml b/apps/namadillo/public/config.toml index b6365d412f..29d5b71031 100644 --- a/apps/namadillo/public/config.toml +++ b/apps/namadillo/public/config.toml @@ -2,3 +2,4 @@ #indexer_url = "" #rpc_url = "" #masp_indexer_url = "" +#localnet_enabled = false diff --git a/apps/namadillo/src/App/Ibc/IbcWithdraw.tsx b/apps/namadillo/src/App/Ibc/IbcWithdraw.tsx index 9015386bc0..7406899a55 100644 --- a/apps/namadillo/src/App/Ibc/IbcWithdraw.tsx +++ b/apps/namadillo/src/App/Ibc/IbcWithdraw.tsx @@ -55,8 +55,8 @@ export const IbcWithdraw: React.FC = () => { const transactionFee = mapUndefined( ({ gasLimit, gasPrice }) => ({ - originalAddress: namadaAsset.address, - asset: namadaAsset, + originalAddress: namadaAsset().address, + asset: namadaAsset(), amount: gasPrice.multipliedBy(gasLimit), }), gasConfig diff --git a/apps/namadillo/src/App/Setup/ChainLoader.tsx b/apps/namadillo/src/App/Setup/ChainLoader.tsx index 43a0874244..f4ac85a7da 100644 --- a/apps/namadillo/src/App/Setup/ChainLoader.tsx +++ b/apps/namadillo/src/App/Setup/ChainLoader.tsx @@ -2,6 +2,7 @@ import { AtomErrorBoundary } from "App/Common/AtomErrorBoundary"; import { ErrorBox } from "App/Common/ErrorBox"; import { routes } from "App/routes"; import { chainAtom } from "atoms/chain"; +import { localnetConfigAtom } from "atoms/integrations"; import { useAtomValue } from "jotai"; import { ReactNode } from "react"; import { useLocation, useNavigate } from "react-router-dom"; @@ -31,6 +32,8 @@ export const ChainLoader = ({ children: ReactNode; }): JSX.Element => { const chain = useAtomValue(chainAtom); + useAtomValue(localnetConfigAtom); + const errorContainerProps = { className: "bg-black max-w-full rounded-sm w-full text-white min-h-full", }; diff --git a/apps/namadillo/src/App/Transfer/AssetImage.tsx b/apps/namadillo/src/App/Transfer/AssetImage.tsx index 0f3d0c4cbe..cfead89cf6 100644 --- a/apps/namadillo/src/App/Transfer/AssetImage.tsx +++ b/apps/namadillo/src/App/Transfer/AssetImage.tsx @@ -21,7 +21,7 @@ export const AssetImage = ({ {altText} {isShielded !== undefined && ( - + )} diff --git a/apps/namadillo/src/App/Transfer/__tests__/TransferDestination.test.tsx b/apps/namadillo/src/App/Transfer/__tests__/TransferDestination.test.tsx index 5c8673aeab..903b08ccdc 100644 --- a/apps/namadillo/src/App/Transfer/__tests__/TransferDestination.test.tsx +++ b/apps/namadillo/src/App/Transfer/__tests__/TransferDestination.test.tsx @@ -102,8 +102,8 @@ describe("Component: TransferDestination", () => { ); diff --git a/apps/namadillo/src/atoms/accounts/atoms.ts b/apps/namadillo/src/atoms/accounts/atoms.ts index 99bad14eee..beb67bd445 100644 --- a/apps/namadillo/src/atoms/accounts/atoms.ts +++ b/apps/namadillo/src/atoms/accounts/atoms.ts @@ -7,7 +7,6 @@ import { queryDependentFn } from "atoms/utils"; import BigNumber from "bignumber.js"; import { NamadaKeychain } from "hooks/useNamadaKeychain"; import { atomWithMutation, atomWithQuery } from "jotai-tanstack-query"; -import { chainConfigByName } from "registry"; import { fetchAccountBalance, fetchAccounts, @@ -89,7 +88,6 @@ export const accountBalanceAtom = atomWithQuery((get) => { const tokenAddress = get(nativeTokenAddressAtom); const enablePolling = get(shouldUpdateBalanceAtom); const api = get(indexerApiAtom); - const chainConfig = chainConfigByName("namada"); return { // TODO: subscribe to indexer events when it's done @@ -99,10 +97,7 @@ export const accountBalanceAtom = atomWithQuery((get) => { return await fetchNamAccountBalance( api, defaultAccount.data, - tokenAddress.data!, - // As this is a nam balance specific atom, we can safely assume that the - // first currency is the native token - chainConfig.currencies[0].coinDecimals + tokenAddress.data! ); }, [tokenAddress, defaultAccount]), }; @@ -111,7 +106,7 @@ export const accountBalanceAtom = atomWithQuery((get) => { // TODO combine the `accountBalanceAtom` with the `transparentBalanceAtom` // Then execute only once the `fetchAccountBalance`, deleting the `fetchNamAccountBalance` export const transparentBalanceAtom = atomWithQuery< - { address: string; amount: BigNumber }[] + { address: string; minDenomAmount: BigNumber }[] >((get) => { const enablePolling = get(shouldUpdateBalanceAtom); const api = get(indexerApiAtom); @@ -124,7 +119,7 @@ export const transparentBalanceAtom = atomWithQuery< const response = await fetchAccountBalance(api, defaultAccountQuery.data); return response.map((item) => ({ address: item.tokenAddress, - amount: new BigNumber(item.balance), + minDenomAmount: BigNumber(item.minDenomAmount), })); }, [defaultAccountQuery]), }; diff --git a/apps/namadillo/src/atoms/accounts/services.ts b/apps/namadillo/src/atoms/accounts/services.ts index d63ca6671e..206eac0883 100644 --- a/apps/namadillo/src/atoms/accounts/services.ts +++ b/apps/namadillo/src/atoms/accounts/services.ts @@ -2,6 +2,7 @@ import { Balance, DefaultApi } from "@namada/indexer-client"; import { Account } from "@namada/types"; import BigNumber from "bignumber.js"; import { NamadaKeychain } from "hooks/useNamadaKeychain"; +import { namadaAsset, toDisplayAmount } from "utils"; export const fetchAccounts = async (): Promise => { const namada = await new NamadaKeychain().get(); @@ -17,26 +18,22 @@ export const fetchDefaultAccount = async (): Promise => { export const fetchNamAccountBalance = async ( api: DefaultApi, account: Account | undefined, - tokenAddress: string, - decimals: number + tokenAddress: string ): Promise => { if (!account) return BigNumber(0); const balancesResponse = await api.apiV1AccountAddressGet(account.address); const balance = balancesResponse.data - // TODO: add filter to the api call .filter(({ tokenAddress: ta }) => ta === tokenAddress) - .map(({ tokenAddress, balance }) => { + .map(({ tokenAddress, minDenomAmount }) => { return { token: tokenAddress, - amount: balance, + amount: toDisplayAmount(namadaAsset(), new BigNumber(minDenomAmount)), }; }) .at(0); - return balance ? - BigNumber(balance.amount).shiftedBy(-decimals) - : BigNumber(0); + return balance ? BigNumber(balance.amount) : BigNumber(0); }; export const fetchAccountBalance = async ( diff --git a/apps/namadillo/src/atoms/balance/atoms.ts b/apps/namadillo/src/atoms/balance/atoms.ts index 22f3f80858..678e5807af 100644 --- a/apps/namadillo/src/atoms/balance/atoms.ts +++ b/apps/namadillo/src/atoms/balance/atoms.ts @@ -90,7 +90,7 @@ export const shieldedSyncAtom = atomWithQuery( ); export const shieldedBalanceAtom = atomWithQuery< - { address: string; amount: BigNumber }[] + { address: string; minDenomAmount: BigNumber }[] >((get) => { const enablePolling = get(shouldUpdateBalanceAtom); const viewingKeysQuery = get(viewingKeysAtom); @@ -130,11 +130,7 @@ export const shieldedBalanceAtom = atomWithQuery< ); const shieldedBalance = response.map(([address, amount]) => ({ address, - amount: - // Sdk returns the nam amount as `nam` instead of `namnam` - namTokenAddressQuery.data === address ? - new BigNumber(amount).shiftedBy(6) - : new BigNumber(amount), + minDenomAmount: BigNumber(amount), })); return shieldedBalance; }, [viewingKeysQuery, tokenAddressesQuery, namTokenAddressQuery]), diff --git a/apps/namadillo/src/atoms/balance/functions.ts b/apps/namadillo/src/atoms/balance/functions.ts index d253d1b9a0..e93b7c8144 100644 --- a/apps/namadillo/src/atoms/balance/functions.ts +++ b/apps/namadillo/src/atoms/balance/functions.ts @@ -81,13 +81,13 @@ const tnamAddressToDenomTrace = ( }; export const mapNamadaAddressesToAssets = async ( - balances: { address: string; amount: BigNumber }[], + balances: { address: string; minDenomAmount: BigNumber }[], tokenAddresses: (NativeToken | IbcToken)[], chainId: string ): Promise => { - const coins = balances.map(({ address, amount }) => ({ + const coins = balances.map(({ address, minDenomAmount }) => ({ denom: address, - amount: amount.toString(), // TODO: don't convert back to string + minDenomAmount: minDenomAmount.toString(), // TODO: don't convert back to string })); return await mapCoinsToAssets(coins, chainId, (tnamAddress) => diff --git a/apps/namadillo/src/atoms/fees/services.ts b/apps/namadillo/src/atoms/fees/services.ts index 6a9572d909..c532cfd811 100644 --- a/apps/namadillo/src/atoms/fees/services.ts +++ b/apps/namadillo/src/atoms/fees/services.ts @@ -4,6 +4,7 @@ import BigNumber from "bignumber.js"; import invariant from "invariant"; import { GasTable } from "types"; import { txKinds } from "types/txKind"; +import { namadaAsset, toDisplayAmount } from "utils"; import { txKindToIndexer } from "./functions"; export const fetchGasLimit = async (api: DefaultApi): Promise => { @@ -33,7 +34,10 @@ export const fetchMinimumGasPrice = async ( ({ token }) => token === nativeToken ); invariant(!!nativeTokenCost, "Error querying minimum gas price"); - const asBigNumber = new BigNumber(nativeTokenCost.amount); + const asBigNumber = toDisplayAmount( + namadaAsset(), + BigNumber(nativeTokenCost.minDenomAmount) + ); invariant( !asBigNumber.isNaN(), "Error converting minimum gas price to BigNumber" diff --git a/apps/namadillo/src/atoms/integrations/atoms.ts b/apps/namadillo/src/atoms/integrations/atoms.ts index 0d78ad61dc..1c31459b0a 100644 --- a/apps/namadillo/src/atoms/integrations/atoms.ts +++ b/apps/namadillo/src/atoms/integrations/atoms.ts @@ -2,7 +2,7 @@ import { AssetList, Chain } from "@chain-registry/types"; import { ExtensionKey, IbcTransferProps } from "@namada/types"; import { defaultAccountAtom } from "atoms/accounts"; import { chainAtom, chainParametersAtom } from "atoms/chain"; -import { settingsAtom } from "atoms/settings"; +import { defaultServerConfigAtom, settingsAtom } from "atoms/settings"; import { queryDependentFn } from "atoms/utils"; import BigNumber from "bignumber.js"; import { atom } from "jotai"; @@ -20,6 +20,7 @@ import { TransferTransactionData, } from "types"; import { + addLocalnetToRegistry, createIbcTx, getIbcChannels, getKnownChains, @@ -28,6 +29,7 @@ import { mapCoinsToAssets, } from "./functions"; import { + fetchLocalnetTomlConfig, IbcTransferParams, queryAndStoreRpc, queryAssetBalances, @@ -198,3 +200,28 @@ export const createIbcTxAtom = atomWithMutation((get) => { }, }; }); + +export const localnetConfigAtom = atomWithQuery((get) => { + const config = get(defaultServerConfigAtom); + + return { + queryKey: ["localnet-config", config], + staleTime: Infinity, + retry: false, + + ...queryDependentFn(async () => { + try { + const localnetConfig = await fetchLocalnetTomlConfig(); + addLocalnetToRegistry(localnetConfig); + + return { + chainId: localnetConfig.chain_id, + tokenAddress: localnetConfig.token_address, + }; + } catch (_) { + // If file not found just ignore + return null; + } + }, [Boolean(config.data?.localnet_enabled)]), + }; +}); diff --git a/apps/namadillo/src/atoms/integrations/functions.ts b/apps/namadillo/src/atoms/integrations/functions.ts index 227a4781a2..9b84cb4684 100644 --- a/apps/namadillo/src/atoms/integrations/functions.ts +++ b/apps/namadillo/src/atoms/integrations/functions.ts @@ -1,5 +1,4 @@ -import { Asset, Chain } from "@chain-registry/types"; -import { Coin } from "@cosmjs/launchpad"; +import { Asset, AssetList, Chain, IBCInfo } from "@chain-registry/types"; import { QueryClient, setupIbcExtension } from "@cosmjs/stargate"; import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; import { Account, IbcTransferProps } from "@namada/types"; @@ -24,7 +23,9 @@ import { AddressWithAssetAndAmountMap, ChainRegistryEntry, ChainSettings, + Coin, GasConfig, + LocalnetToml, } from "types"; import { toBaseAmount, toDisplayAmount } from "utils"; import { getSdkInstance } from "utils/sdk"; @@ -230,7 +231,7 @@ export const mapCoinsToAssets = async ( const results = await Promise.allSettled( coins.map(async (coin: Coin): Promise => { - const { amount, denom } = coin; + const { minDenomAmount, denom } = coin; const asset = typeof chainName === "undefined" || typeof assets === "undefined" ? @@ -243,9 +244,9 @@ export const mapCoinsToAssets = async ( )) || unknownAsset(denom); - const baseBalance = BigNumber(amount); + const baseBalance = BigNumber(minDenomAmount); if (baseBalance.isNaN()) { - throw new Error(`Balance is invalid, got ${amount}`); + throw new Error(`Balance is invalid, got ${minDenomAmount}`); } // We always represent amounts in their display denom, so convert here const displayBalance = toDisplayAmount(asset, baseBalance); @@ -370,3 +371,66 @@ export const createIbcTx = async ( ); return transactionPair; }; + +export const namadaLocal = (chainId: string): Chain => ({ + ...internalDevnetChain, + chain_name: "localnet", + chain_id: chainId, +}); + +export const namadaLocalAsset = (tokenAddress: string): AssetList => ({ + ...internalDevnetAssets, + chain_name: "localnet", + assets: internalDevnetAssets.assets.map((asset) => + asset.symbol === "NAM" ? + { + ...asset, + address: tokenAddress, + } + : asset + ), +}); + +export const namadaLocalRelayer = ( + chain1Channel: string, + chain2Channel: string +): IBCInfo => ({ + ...internalDevnetCosmosTestnetIbc, + chain_1: { + ...internalDevnetCosmosTestnetIbc.chain_1, + chain_name: "localnet", + }, + chain_2: { + ...internalDevnetCosmosTestnetIbc.chain_2, + chain_name: "cosmosicsprovidertestnet", + }, + channels: [ + { + ...internalDevnetCosmosTestnetIbc.channels[0], + chain_1: { + ...internalDevnetCosmosTestnetIbc.channels[0].chain_1, + channel_id: chain1Channel, + }, + chain_2: { + ...internalDevnetCosmosTestnetIbc.channels[0].chain_2, + channel_id: chain2Channel, + }, + }, + ], +}); + +export const addLocalnetToRegistry = (config: LocalnetToml): void => { + const { chain_id, token_address, chain_1_channel, chain_2_channel } = config; + + const localChain: ChainRegistryEntry = { + chain: namadaLocal(chain_id), + assets: namadaLocalAsset(token_address), + ibc: [namadaLocalRelayer(chain_1_channel, chain_2_channel)], + }; + + cosmosRegistry.chains.push(localChain.chain); + cosmosRegistry.assets.push(localChain.assets); + cosmosRegistry.ibc.push(...localChain.ibc!); + + mainnetChains.push(localChain); +}; diff --git a/apps/namadillo/src/atoms/integrations/services.ts b/apps/namadillo/src/atoms/integrations/services.ts index a5b56b8d7b..98c399117a 100644 --- a/apps/namadillo/src/atoms/integrations/services.ts +++ b/apps/namadillo/src/atoms/integrations/services.ts @@ -1,5 +1,5 @@ import { Chain } from "@chain-registry/types"; -import { Coin, OfflineSigner } from "@cosmjs/launchpad"; +import { OfflineSigner } from "@cosmjs/launchpad"; import { coins } from "@cosmjs/proto-signing"; import { DeliverTxResponse, @@ -11,9 +11,12 @@ import { queryForAck, queryForIbcTimeout } from "atoms/transactions"; import BigNumber from "bignumber.js"; import { getDefaultStore } from "jotai"; import { createIbcTransferMessage } from "lib/transactions"; +import toml from "toml"; import { AddressWithAsset, + Coin, IbcTransferTransactionData, + LocalnetToml, TransferStep, } from "types"; import { toBaseAmount } from "utils"; @@ -68,7 +71,12 @@ export const queryAssetBalances = async ( rpc: string ): Promise => { const client = await StargateClient.connect(rpc); - return ((await client.getAllBalances(owner)) as Coin[]) || []; + const balances = (await client.getAllBalances(owner)) || []; + + return balances.map((balance) => ({ + denom: balance.denom, + minDenomAmount: balance.amount, + })); }; export const submitIbcTransfer = async ( @@ -116,7 +124,7 @@ export const submitIbcTransfer = async ( sourceAddress, receiver, baseAmount, - asset.asset.base, + asset.originalAddress, memo ); @@ -189,3 +197,8 @@ export const updateIbcTransactionStatus = async ( }); } }; + +export const fetchLocalnetTomlConfig = async (): Promise => { + const response = await fetch("/localnet-config.toml"); + return toml.parse(await response.text()) as LocalnetToml; +}; diff --git a/apps/namadillo/src/atoms/staking/atoms.ts b/apps/namadillo/src/atoms/staking/atoms.ts index 1f90ece279..4f862711bb 100644 --- a/apps/namadillo/src/atoms/staking/atoms.ts +++ b/apps/namadillo/src/atoms/staking/atoms.ts @@ -15,6 +15,7 @@ import BigNumber from "bignumber.js"; import { atomWithMutation, atomWithQuery } from "jotai-tanstack-query"; import { atomFamily } from "jotai/utils"; import { AddressBalance, BuildTxAtomParams, StakingTotals } from "types"; +import { namadaAsset, toDisplayAmount } from "utils"; import { toStakingTotal } from "./functions"; import { createBondTx, @@ -110,7 +111,10 @@ export const claimableRewardsAtom = atomWithQuery((get) => { if (!current.validator) return prev; return { ...prev, - [current.validator?.address]: new BigNumber(current.amount || 0), + [current.validator?.address]: toDisplayAmount( + namadaAsset(), + BigNumber(current.minDenomAmount || 0) + ), }; }, {} diff --git a/apps/namadillo/src/atoms/syncStatus/atoms.ts b/apps/namadillo/src/atoms/syncStatus/atoms.ts index fcdb092954..425e8f2cda 100644 --- a/apps/namadillo/src/atoms/syncStatus/atoms.ts +++ b/apps/namadillo/src/atoms/syncStatus/atoms.ts @@ -1,11 +1,8 @@ -import { - accountBalanceAtom, - transparentBalanceAtom, -} from "atoms/accounts/atoms"; -import { shieldedBalanceAtom } from "atoms/balance/atoms"; -import { allProposalsAtom, votedProposalsAtom } from "atoms/proposals/atoms"; +import { accountBalanceAtom, transparentBalanceAtom } from "atoms/accounts"; +import { shieldedBalanceAtom } from "atoms/balance"; +import { allProposalsAtom, votedProposalsAtom } from "atoms/proposals"; import { indexerHeartbeatAtom, rpcHeartbeatAtom } from "atoms/settings/atoms"; -import { allValidatorsAtom, myValidatorsAtom } from "atoms/validators/atoms"; +import { allValidatorsAtom, myValidatorsAtom } from "atoms/validators"; import { atom } from "jotai"; export const syncStatusAtom = atom((get) => { diff --git a/apps/namadillo/src/atoms/validators/functions.ts b/apps/namadillo/src/atoms/validators/functions.ts index d457bdb15e..25f1d4e819 100644 --- a/apps/namadillo/src/atoms/validators/functions.ts +++ b/apps/namadillo/src/atoms/validators/functions.ts @@ -8,6 +8,7 @@ import { import { singleUnitDurationFromInterval } from "@namada/utils"; import BigNumber from "bignumber.js"; import { Address, BondEntry, MyValidator, UnbondEntry, Validator } from "types"; +import { namadaAsset, toDisplayAmount } from "utils"; export const toValidator = ( indexerValidator: IndexerValidator, @@ -105,23 +106,37 @@ export const toMyValidators = ( for (const bond of indexerBonds) { const { address } = bond.validator; + const amount = toDisplayAmount( + namadaAsset(), + BigNumber(bond.minDenomAmount) + ); createEntryIfDoesntExist(bond.validator); - incrementAmount(address, "stakedAmount", bond.amount); - addBondToAddress(address, "bondItems", { ...bond } as BondEntry); + incrementAmount(address, "stakedAmount", amount); + const bondEntry: BondEntry = { + amount, + }; + addBondToAddress(address, "bondItems", bondEntry); } for (const unbond of indexerUnbonds) { const { address } = unbond.validator; + const amount = toDisplayAmount( + namadaAsset(), + BigNumber(unbond.minDenomAmount) + ); createEntryIfDoesntExist(unbond.validator); const unbondingDetails: UnbondEntry = { - ...unbond, + amount, + withdrawEpoch: unbond.withdrawEpoch, + withdrawTime: unbond.withdrawTime, + canWithdraw: unbond.canWithdraw, timeLeft: calculateUnbondingTimeLeft(unbond), }; addBondToAddress(address, "unbondItems", unbondingDetails); if (unbond.canWithdraw) { - incrementAmount(address, "withdrawableAmount", unbond.amount); + incrementAmount(address, "withdrawableAmount", amount); } else { - incrementAmount(address, "unbondedAmount", unbond.amount); + incrementAmount(address, "unbondedAmount", amount); } } diff --git a/apps/namadillo/src/setupTests.ts b/apps/namadillo/src/setupTests.ts index 70f3a0e472..864382a85c 100644 --- a/apps/namadillo/src/setupTests.ts +++ b/apps/namadillo/src/setupTests.ts @@ -1,6 +1,11 @@ import "@testing-library/jest-dom"; +import { atom } from "jotai"; jest.mock("atoms/integrations", () => ({ getRestApiAddressByIndex: jest.fn(), getRpcByIndex: jest.fn(), })); + +jest.mock("atoms/integrations/atoms", () => ({ + localnetConfigAtom: atom({ data: undefined }), +})); diff --git a/apps/namadillo/src/types.ts b/apps/namadillo/src/types.ts index 782eebfc5b..5f522e7231 100644 --- a/apps/namadillo/src/types.ts +++ b/apps/namadillo/src/types.ts @@ -1,9 +1,5 @@ import { Asset, AssetList, Chain, IBCInfo } from "@chain-registry/types"; -import { - Bond as IndexerBond, - Unbond as IndexerUnbond, - ValidatorStatus, -} from "@namada/indexer-client"; +import { ValidatorStatus } from "@namada/indexer-client"; import { Account, ChainKey, @@ -58,6 +54,7 @@ export type SettingsTomlOptions = { indexer_url?: string; masp_indexer_url?: string; rpc_url?: string; + localnet_enabled?: boolean; }; export type ChainParameters = { @@ -93,11 +90,17 @@ export type Validator = Unique & { export type ValidatorFilterOptions = "all" | "active" | ValidatorStatus; -export type UnbondEntry = Omit & { +export type UnbondEntry = { + amount: BigNumber; + withdrawEpoch: string; + withdrawTime: string; + canWithdraw: boolean; timeLeft?: string; }; -export type BondEntry = Omit; +export type BondEntry = { + amount: BigNumber; +}; export type MyValidator = { stakedAmount?: BigNumber; @@ -193,6 +196,11 @@ export type AddressWithAssetAndAmount = AddressWithAsset & { amount: BigNumber; }; +export type Coin = { + denom: string; + minDenomAmount: string; +}; + export type AddressWithAssetAndAmountMap = Record< Address, AddressWithAssetAndAmount @@ -342,3 +350,10 @@ export type ChainStatus = { height: number; epoch: number; }; + +export type LocalnetToml = { + chain_id: string; + token_address: string; + chain_1_channel: string; + chain_2_channel: string; +}; diff --git a/apps/namadillo/src/utils/index.ts b/apps/namadillo/src/utils/index.ts index 2249913b74..61da2acae9 100644 --- a/apps/namadillo/src/utils/index.ts +++ b/apps/namadillo/src/utils/index.ts @@ -1,7 +1,9 @@ import { Asset, AssetDenomUnit } from "@chain-registry/types"; import { ProposalStatus, ProposalTypeString } from "@namada/types"; +import { localnetConfigAtom } from "atoms/integrations/atoms"; import BigNumber from "bignumber.js"; import * as fns from "date-fns"; +import { getDefaultStore } from "jotai"; import { DateTime } from "luxon"; import internalDevnetAssets from "namada-chain-registry/namadainternaldevnet/assetlist.json"; import { useEffect } from "react"; @@ -122,10 +124,26 @@ const findDisplayUnit = (asset: Asset): AssetDenomUnit | undefined => { }; // TODO update to mainnet asset -export const namadaAsset = internalDevnetAssets.assets[0]; +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const namadaAsset = () => { + const store = getDefaultStore(); + const config = store.get(localnetConfigAtom); + + const configTokenAddress = config.data?.tokenAddress; + const registryAsset = internalDevnetAssets.assets[0]; + const asset = + configTokenAddress ? + { + ...registryAsset, + address: configTokenAddress, + } + : registryAsset; + + return asset satisfies Asset; +}; export const isNamadaAsset = (asset: Asset): boolean => - asset.symbol === namadaAsset.symbol; + asset.symbol === namadaAsset().symbol; export const toDisplayAmount = ( asset: Asset, @@ -142,7 +160,6 @@ export const toBaseAmount = ( asset: Asset, displayAmount: BigNumber ): BigNumber => { - if (isNamadaAsset(asset)) return displayAmount; const displayUnit = findDisplayUnit(asset); if (!displayUnit) { return displayAmount; diff --git a/packages/shared/lib/src/query.rs b/packages/shared/lib/src/query.rs index 9075307c4b..b2ba741953 100644 --- a/packages/shared/lib/src/query.rs +++ b/packages/shared/lib/src/query.rs @@ -24,7 +24,7 @@ use namada_sdk::parameters::storage; use namada_sdk::proof_of_stake::Epoch; use namada_sdk::queries::RPC; use namada_sdk::rpc::{ - self, format_denominated_amount, get_public_key_at, get_token_balance, get_total_staked_tokens, + self, get_public_key_at, get_token_balance, get_total_staked_tokens, is_steward, query_epoch, query_masp_epoch, query_native_token, query_proposal_by_id, query_proposal_votes, query_storage_value, }; @@ -465,9 +465,7 @@ impl Query { for (token, amount) in result { mapped_result.push(( token.clone(), - format_denominated_amount(&self.client, &WebIo, &token, amount) - .await - .clone(), + amount.to_string() )) } diff --git a/yarn.lock b/yarn.lock index 65bf215976..74fec17f13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3581,12 +3581,12 @@ __metadata: languageName: unknown linkType: soft -"@namada/indexer-client@npm:0.0.30": - version: 0.0.30 - resolution: "@namada/indexer-client@npm:0.0.30" +"@namada/indexer-client@npm:0.0.31": + version: 0.0.31 + resolution: "@namada/indexer-client@npm:0.0.31" dependencies: axios: "npm:^1.6.1" - checksum: d61b03c4f1ac44f506a945047f9ebc935bbfd5c3335bea9045d225f025c96a47cb6feb3c90687832a0a89285fcb566266a7fb30a4d87cd4fe0acfd5537f99c95 + checksum: 45bf4c05f590f3daee46aa217a5bcf7cd0ee08f3a0dcf8f6a89f8458786ffa99035d2cad8b87c7b28080aeca34e10cfd7b3eee905a2e26f740e43ca883c1252c languageName: node linkType: hard @@ -3627,7 +3627,7 @@ __metadata: "@cosmjs/encoding": "npm:^0.32.3" "@eslint/js": "npm:^9.9.1" "@keplr-wallet/types": "npm:^0.12.136" - "@namada/indexer-client": "npm:0.0.30" + "@namada/indexer-client": "npm:0.0.31" "@playwright/test": "npm:^1.24.1" "@release-it/keep-a-changelog": "npm:^5.0.0" "@svgr/webpack": "npm:^6.5.1"