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 = ({
{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"