Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chalabi/cross chain x #194

Merged
merged 70 commits into from
Feb 6, 2025
Merged

chalabi/cross chain x #194

merged 70 commits into from
Feb 6, 2025

Conversation

chalabi2
Copy link
Collaborator

@chalabi2 chalabi2 commented Jan 9, 2025

This PR introduces full support for IBC transfer transactions to and from Manifest, enabling functionality for both users and groups. Initially, support is limited to Osmosis as the additional chain.

When reviewing, please note that we currently need to manually configure the ibc and assetList settings while waiting for updates to the GitHub chain-registry and the Cosmology chain-registry npm package. To eliminate this dependency, we could consider maintaining our own registry or npm package. This approach would accommodate token factory tokens originating from either side, as well as other IBC assets. As we expand support to additional chains—including EVM chains and other Cosmos networks—this self-managed registry could streamline the integration process.

Summary by CodeRabbit

  • New Features
    • Enhanced cross-chain transfers with distinct source and destination selectors, including auto-switch logic when both selections match.
    • Expanded support for Osmosis and Axelar networks, enabling users to view and manage token balances and transfers across multiple blockchains.
    • Improved wallet connectivity that now connects to multiple chains concurrently with streamlined connection and disconnection flows.

  • Chores
    • Updated environment configurations and dependencies, plus new utility scripts to support the augmented multi-chain capabilities.

Copy link
Contributor

coderabbitai bot commented Jan 9, 2025

Walkthrough

Multiple components have been updated to integrate dynamic chain configurations and Osmosis-specific data. The changes include revised props and state management in cross-chain components; new hooks and utilities for fetching and formatting token and IBC data; updates to configuration files with additional chain and environment variables; enhancements in fee estimation, wallet connection, and transaction handling; modifications to tests and scripts; and improvements in asset display and denomination formatting.

Changes

File(s) Change Summary
components/bank/{sendBox.tsx, tokenList.tsx, modals/sendModal.tsx, forms/ibcSendForm.tsx} Added Osmosis-related props, new state variables (selectedFromChain/ToChain), useEffect/useMemo for dynamic chain selection, and updated rendering logic for cross-chain transfers.
components/factory/{DenomImage.tsx, TokenDetailsForm.tsx, modals/updateDenomMetadata.tsx} & components/bank/handlers/createMessageUtils.tsx Modified asset image conditions, auto-updated denom units with useEffect, and enhanced token message formatting via formatDenom and denomToAsset.
components/groups/components/myGroups.tsx & utils/ibc.ts Enhanced IBC asset handling with denom normalization, asset filtering updates, and added functions for IBC denom processing.
config/{defaults.ts, env.ts, index.ts} Removed defaults configuration; reorganized env with new chain properties (Osmosis, Axelar) and walletConnectKey.
hooks/{useFeeEstimation.ts, useLcdQueryClient.ts, useQueries.ts, useTx.tsx} Removed unused coin logic; added Osmosis LCD client and query hooks; updated fee/gas price logic and tx explorer URL with proposal-specific handling.
pages/{_app.tsx, bank.tsx} Updated ChainProvider to include Manifest, Osmosis, Axelar; injected new Osmosis hooks and balances in Bank page.
package.json, README.md, .env.test Updated scripts and dependencies; added new environment variables for Osmosis and Axelar chains; revised documentation for testnet configurations.
tests/{components/bank/, forms/, render.tsx, mock.ts} Updated mocks and assertions to support new chain props; improved cleanup via mock.restore for test isolation.
contexts/skipGoContext.tsx & components/{react/modal.tsx, wallet.tsx} Introduced SkipProvider for client creation; updated wallet connection/disconnection logic using aggregated chain states via useChains.
scripts/{ibcTransferAll.ts, printAllTokens.ts} Enhanced IBC transfer and token metadata scripts with detailed logging, error handling, and comprehensive environment configurations.
utils/{constants.ts, format.ts, yupExtensions.ts} Added Osmosis token constant; refined denomination formatting and extended address validation to include ‘osmo’ prefixes.

Sequence Diagram(s)

sequenceDiagram
   participant U as User
   participant SB as SendBox Component
   participant EF as useEffect Hook
   participant GF as getAvailableToChains
   participant IF as IbcSendForm

   U->>SB: Initiate cross-chain transfer
   SB->>EF: Monitor selectedFromChain & selectedToChain
   EF->>GF: Request available destination chains
   GF-->>EF: Return filtered chain list
   EF->>SB: Update selectedToChain if needed
   SB->>IF: Pass updated chain selections
   IF->>U: Render updated transfer UI
Loading

Possibly related PRs

Suggested labels

bug, render

Suggested reviewers

  • fmorency

Poem

I’m a rabbit in a maze of code so bright,
Hopping ‘cross chains from morning till night,
Osmosis and transfers now weave in my trail,
With hooks and updates that never fail,
My little paws tap through lines with delight,
🐇 Leaping in rhythms, a code bunny in flight!

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@chalabi2 chalabi2 marked this pull request as ready for review January 11, 2025 02:47
@chalabi2 chalabi2 requested a review from fmorency January 11, 2025 02:47
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (17)
components/bank/forms/sendForm.tsx (2)

228-230: Enhance token display name handling logic

The current implementation makes assumptions about token prefixes that might not always hold true:

  1. The 'u' prefix is assumed to always represent micro units
  2. There's no validation for empty strings after removing prefixes

Consider this safer implementation:

- tokenDisplayName.startsWith('u')
-   ? tokenDisplayName.slice(1).toUpperCase()
-   : truncateString(tokenDisplayName, 10).toUpperCase();
+ tokenDisplayName.startsWith('u')
+   ? (tokenDisplayName.length > 1 
+      ? tokenDisplayName.slice(1).toUpperCase() 
+      : tokenDisplayName.toUpperCase())
+   : truncateString(tokenDisplayName, 10).toUpperCase();

Also, consider maintaining a mapping of known token prefixes to their display formats for better maintainability.


Line range hint 41-51: Consider enhancing cross-chain support documentation

While the component is chain-agnostic, it would be beneficial to document how it handles different chain-specific requirements, especially:

  • Fee estimation variations
  • Chain-specific token display rules
  • Balance type differences

Consider adding JSDoc comments to clarify:

/**
 * Form component for sending tokens across supported chains.
 * @param balances - Combined balance information from supported chains
 * @param selectedDenom - Selected denomination, should be compatible across chains
 * ...
 */
utils/ibc.ts (1)

181-212: Replace mockIbcData with actual IBC data

The mockIbcData constant is currently used to provide IBC connection and channel information. To ensure accurate and up-to-date data, replace this mock data with dynamic data retrieved from a reliable source, such as the chain registry or IBC module queries.

pages/bank.tsx (1)

229-231: Include Osmosis loading states in isLoading

The isLoading state currently considers isBalancesLoading, resolvedLoading, and isMetadatasLoading. Since you've introduced Osmosis balances and metadata, consider including isOsmosisBalancesLoading and resolvedOsmosisLoading to accurately reflect the loading state when Osmosis data is being fetched.

components/bank/forms/ibcSendForm.tsx (1)

158-167: Review fee buffer logic for different tokens

In the validation schema, the leave-for-fees test only applies when selectedToken.denom === 'umfx'. If users are sending tokens from Osmosis or other chains, consider whether the fee buffer logic should also apply to those tokens to prevent failed transactions due to insufficient fees.

config/env.ts (1)

5-15: LGTM! Consider documenting the new environment variables.

The new Osmosis testnet environment variables follow consistent patterns and have appropriate fallbacks. Consider updating the project's documentation to include these new variables and their expected values.

hooks/useLcdQueryClient.ts (1)

23-37: Consider refactoring to reduce code duplication.

While the implementation is correct, there's significant code duplication between useOsmosisLcdQueryClient and useLcdQueryClient. Consider creating a shared factory function:

-export const useOsmosisLcdQueryClient = () => {
-  const lcdQueryClient = useQuery({
-    queryKey: ['lcdQueryClientOsmosis', env.osmosisTestnetApiUrl],
-    queryFn: () =>
-      createLcdQueryClient({
-        restEndpoint: env.osmosisTestnetApiUrl,
-      }),
-    enabled: !!env.osmosisTestnetApiUrl,
-    staleTime: Infinity,
-  });
-
-  return {
-    lcdQueryClient: lcdQueryClient.data,
-  };
-};

+const createLcdQueryHook = (chainType: 'Cosmos' | 'Osmosis') => () => {
+  const apiUrl = chainType === 'Cosmos' ? env.apiUrl : env.osmosisTestnetApiUrl;
+  const lcdQueryClient = useQuery({
+    queryKey: [`lcdQueryClient${chainType}`, apiUrl],
+    queryFn: () =>
+      createLcdQueryClient({
+        restEndpoint: apiUrl,
+      }),
+    enabled: !!apiUrl,
+    staleTime: Infinity,
+  });
+
+  return {
+    lcdQueryClient: lcdQueryClient.data,
+  };
+};
+
+export const useLcdQueryClient = createLcdQueryHook('Cosmos');
+export const useOsmosisLcdQueryClient = createLcdQueryHook('Osmosis');
components/factory/components/DenomImage.tsx (1)

101-101: Update alt text for Osmosis token

The alt text "MFX Token Icon" is incorrect when displaying Osmosis tokens. This affects accessibility.

-          alt="MFX Token Icon"
+          alt={denom?.base?.includes('umfx') ? 'MFX Token Icon' : 'Osmosis Token Icon'}

Also applies to: 109-111

utils/yupExtensions.ts (1)

92-92: Consider moving chain prefixes to configuration

The list of valid prefixes could be moved to configuration to improve maintainability and align with the PR's objective of removing hardcoded values.

-      const validPrefixes = ['manifest', 'manifestvaloper', 'manifestvalcons', 'osmo'];
+      const validPrefixes = env.VALID_BECH32_PREFIXES;

This would require adding the configuration to your environment setup:

// config/env.ts
export default {
  // ... other config
  VALID_BECH32_PREFIXES: ['manifest', 'manifestvaloper', 'manifestvalcons', 'osmo'] as const,
}
components/bank/components/sendBox.tsx (1)

44-45: Consider memoizing chain selection handlers

The chain selection handlers could be memoized to prevent unnecessary re-renders.

+  const handleFromChainChange = useCallback((chain: string) => {
+    setSelectedFromChain(chain);
+  }, []);
+
+  const handleToChainChange = useCallback((chain: string) => {
+    setSelectedToChain(chain);
+  }, []);

   // In JSX
-  setSelectedFromChain={setSelectedFromChain}
-  setSelectedToChain={setSelectedToChain}
+  setSelectedFromChain={handleFromChainChange}
+  setSelectedToChain={handleToChainChange}

Also applies to: 100-103

components/bank/components/tokenList.tsx (1)

118-127: Enhance denomination display logic.

The current implementation could be simplified and made more maintainable.

Consider extracting the denomination display logic into a separate utility function:

-<p className="text-sm text-[#00000099] dark:text-[#FFFFFF99]">
-  {balance.metadata?.denom_units[0]?.denom.startsWith('ibc')
-    ? balance.metadata?.denom_units[0]?.aliases[0]
-    : balance.metadata?.denom_units[0]?.denom.split('/').pop()}
-</p>
+<p className="text-sm text-[#00000099] dark:text-[#FFFFFF99]">
+  {getDenominationDisplay(balance.metadata)}
+</p>

Add this utility function:

function getDenominationDisplay(metadata: DenomMetadata | null): string {
  if (!metadata?.denom_units?.[0]?.denom) return '';
  const { denom } = metadata.denom_units[0];
  return denom.startsWith('ibc') 
    ? metadata.denom_units[0].aliases?.[0] ?? ''
    : denom.split('/').pop() ?? '';
}
components/bank/components/historyBox.tsx (2)

220-238: Consider caching asset information.

The denomToAsset function is called multiple times for the same denomination, which could be optimized.

Consider using useMemo to cache the asset information:

const assetInfo = useMemo(() => denomToAsset(env.chain, amt.denom), [env.chain, amt.denom]);

Line range hint 251-309: Simplify denomination handling logic.

The code duplicates the IBC denomination handling logic in multiple places.

Consider extracting the common logic into a utility function:

function getBaseDenom(denom: string, assetInfo: AssetInfo | null): string {
  if (denom.startsWith('ibc/') && assetInfo?.traces?.[0]?.counterparty?.base_denom) {
    return assetInfo.traces[0].counterparty.base_denom.slice(1);
  }
  return formatDenom(denom);
}
hooks/useQueries.ts (2)

689-715: Consider adding error type information.

While the implementation is correct, consider adding type information for the error in the return object to improve error handling downstream.

  return {
    balances: balancesQuery.data?.balances,
    isBalancesLoading: balancesQuery.isLoading,
    isBalancesError: balancesQuery.isError,
+   error: balancesQuery.error as Error | null,
    refetchBalances: balancesQuery.refetch,
  };

745-771: Consider consolidating duplicate code.

The Osmosis hooks share significant code with their non-Osmosis counterparts. Consider extracting the common logic into a shared utility function.

// Example shared utility function
const createBalanceHook = (useClient: () => { lcdQueryClient: any }, queryKeyPrefix: string) => {
  return (address: string) => {
    const { lcdQueryClient } = useClient();
    
    const fetchBalances = async () => {
      if (!lcdQueryClient) {
        throw new Error('LCD Client not ready');
      }
      return await lcdQueryClient.cosmos.bank.v1beta1.allBalances({
        address,
        resolveDenom: true,
      });
    };

    const balancesQuery = useQuery({
      queryKey: [`${queryKeyPrefix}-resolved`, address],
      queryFn: fetchBalances,
      enabled: !!lcdQueryClient && !!address,
      staleTime: Infinity,
    });

    return {
      balances: balancesQuery.data?.balances,
      isBalancesLoading: balancesQuery.isLoading,
      isBalancesError: balancesQuery.isError,
      refetchBalances: balancesQuery.refetch,
    };
  };
};

// Usage
export const useTokenBalancesResolved = createBalanceHook(useLcdQueryClient, 'balances');
export const useOsmosisTokenBalancesResolved = createBalanceHook(useOsmosisLcdQueryClient, 'osmosisBalances');
hooks/useFeeEstimation.ts (1)

28-28: Consider using an environment variable for chain comparison.

Instead of hardcoding 'manifesttestnet', consider using an environment variable for better maintainability.

-  GasPrice.fromString(`${gasPrice}${chainName === 'manifesttestnet' ? 'umfx' : 'uosmo'}`)
+  GasPrice.fromString(`${gasPrice}${chainName === env.chain ? 'umfx' : 'uosmo'}`)
components/groups/components/myGroups.tsx (1)

264-289: LGTM! Robust IBC token metadata handling.

The implementation properly handles IBC token metadata with appropriate fallbacks for missing data.

Consider adding error handling for malformed IBC denoms.

While the implementation is solid, consider adding error handling for malformed IBC denoms.

  if (coreBalance.denom.startsWith('ibc/')) {
+   try {
      const assetInfo = denomToAsset(env.chain, coreBalance.denom);
+     if (!assetInfo) {
+       throw new Error('Asset info not found');
+     }
      // ... rest of the code
+   } catch (error) {
+     console.warn(`Failed to process IBC token ${coreBalance.denom}:`, error);
+     return {
+       denom: coreBalance.denom,
+       coreDenom: coreBalance.denom,
+       amount: coreBalance.amount,
+       metadata: null,
+     };
+   }
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 738ad4e and dc163e0.

⛔ Files ignored due to path filters (2)
  • public/osmosis.png is excluded by !**/*.png
  • public/osmosis.svg is excluded by !**/*.svg
📒 Files selected for processing (26)
  • components/bank/components/historyBox.tsx (4 hunks)
  • components/bank/components/sendBox.tsx (4 hunks)
  • components/bank/components/tokenList.tsx (4 hunks)
  • components/bank/forms/ibcSendForm.tsx (11 hunks)
  • components/bank/forms/sendForm.tsx (1 hunks)
  • components/bank/modals/sendModal.tsx (3 hunks)
  • components/bank/modals/txInfo.tsx (2 hunks)
  • components/factory/components/DenomImage.tsx (1 hunks)
  • components/factory/forms/TokenDetailsForm.tsx (1 hunks)
  • components/groups/components/groupControls.tsx (2 hunks)
  • components/groups/components/myGroups.tsx (3 hunks)
  • components/groups/forms/groups/ConfirmationForm.tsx (2 hunks)
  • components/groups/modals/voteModal.tsx (2 hunks)
  • config/defaults.ts (0 hunks)
  • config/env.ts (1 hunks)
  • config/index.ts (0 hunks)
  • hooks/useFeeEstimation.ts (1 hunks)
  • hooks/useLcdQueryClient.ts (1 hunks)
  • hooks/useQueries.ts (4 hunks)
  • hooks/useTx.tsx (2 hunks)
  • package.json (1 hunks)
  • pages/_app.tsx (5 hunks)
  • pages/bank.tsx (7 hunks)
  • utils/constants.ts (1 hunks)
  • utils/ibc.ts (5 hunks)
  • utils/yupExtensions.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • config/index.ts
  • config/defaults.ts
🧰 Additional context used
🪛 GitHub Check: build
components/bank/forms/ibcSendForm.tsx

[failure] 95-95: TypeError: null is not an object (evaluating 'searchParams.get')

  at IbcSendForm (/home/runner/work/manifest-app/manifest-app/components/bank/forms/ibcSendForm.tsx:95:25)
  at renderWithHooks (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:16305:18)
  at mountIndeterminateComponent (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:20074:13)
  at beginWork$1 (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:27426:14)
  at performUnitOfWork (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26560:12)
  at workLoopSync (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26466:5)
  at renderRootSync (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26434:7)
  at recoverFromConcurrentError (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:25850:20)
  at performConcurrentWorkOnRoot (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:25750:22)
  at flushActQueue (/home/runner/work/manifest-app/manifest-app/node_modules/react/cjs/react.development.js:2667:24)
  at act (/home/runner/work/manifest-app/manifest-app/node_modules/react/cjs/react.development.js:2582:11)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/node_modules/@testing-library/react/dist/act-compat.js:47:25)
  at renderRoot (/home/runner/work/manifest-app/manifest-app/node_modules/@testing-library/react/dist/pure.js:180:18)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/components/bank/forms/__tests__/ibcSendForm.test.tsx:54:5)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/components/bank/forms/__tests__/ibcSendForm.test.tsx:53:26)

[failure] 95-95: TypeError: null is not an object (evaluating 'searchParams.get')

  at IbcSendForm (/home/runner/work/manifest-app/manifest-app/components/bank/forms/ibcSendForm.tsx:95:25)
  at renderWithHooks (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:16305:18)
  at mountIndeterminateComponent (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:20074:13)
  at beginWork$1 (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:27426:14)
  at performUnitOfWork (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26560:12)
  at workLoopSync (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26466:5)
  at renderRootSync (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26434:7)
  at recoverFromConcurrentError (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:25850:20)
  at performSyncWorkOnRoot (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26096:20)
  at flushSyncCallbacks (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
  at flushActQueue (/home/runner/work/manifest-app/manifest-app/node_modules/react/cjs/react.development.js:2667:24)
  at act (/home/runner/work/manifest-app/manifest-app/node_modules/react/cjs/react.development.js:2582:11)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/node_modules/@testing-library/react/dist/act-compat.js:47:25)
  at eventWrapper (/home/runner/work/manifest-app/manifest-app/node_modules/@testing-library/react/dist/pure.js:107:20)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/components/bank/components/__tests__/sendBox.test.tsx:45:15)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/components/bank/components/__tests__/sendBox.test.tsx:41:57)

[failure] 95-95: TypeError: null is not an object (evaluating 'searchParams.get')

  at IbcSendForm (/home/runner/work/manifest-app/manifest-app/components/bank/forms/ibcSendForm.tsx:95:25)
  at renderWithHooks (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:16305:18)
  at mountIndeterminateComponent (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:20074:13)
  at beginWork$1 (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:27426:14)
  at performUnitOfWork (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26560:12)
  at workLoopSync (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26466:5)
  at renderRootSync (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26434:7)
  at recoverFromConcurrentError (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:25850:20)
  at performSyncWorkOnRoot (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:26096:20)
  at flushSyncCallbacks (/home/runner/work/manifest-app/manifest-app/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
  at flushActQueue (/home/runner/work/manifest-app/manifest-app/node_modules/react/cjs/react.development.js:2667:24)
  at act (/home/runner/work/manifest-app/manifest-app/node_modules/react/cjs/react.development.js:2582:11)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/node_modules/@testing-library/react/dist/act-compat.js:47:25)
  at eventWrapper (/home/runner/work/manifest-app/manifest-app/node_modules/@testing-library/react/dist/pure.js:107:20)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/components/bank/components/__tests__/sendBox.test.tsx:51:15)
  at <anonymous> (/home/runner/work/manifest-app/manifest-app/components/bank/components/__tests__/sendBox.test.tsx:49:79)
🪛 GitHub Actions: Test and Coverage
components/bank/forms/ibcSendForm.tsx

[error] 95-95: TypeError: null is not an object (evaluating 'searchParams.get'). The useSearchParams hook is returning null, but the code attempts to call .get() on it without null checking.

🔇 Additional comments (19)
utils/ibc.ts (2)

131-131: Confirm inclusion criteria in filterAssets function

The filterAssets function now includes assets where type_asset is 'ics20' or not specified (!type_asset). Please verify that this change is intentional and that it won't introduce unintended assets into the filtered list.


148-155: Ensure correct trace selection in denomToAsset function

In the denomToAsset function, when handling IBC hashes, you're accessing asset.traces[0].counterparty.base_denom. If an asset has multiple traces, traces[0] may not always correspond to the desired counterparty. Please confirm that using the first trace is appropriate in all cases, or consider implementing logic to select the correct trace.

components/bank/forms/ibcSendForm.tsx (1)

85-90: Ensure fee estimation uses correct chain

In the useTx and useFeeEstimation hooks, you're conditionally checking selectedFromChain against env.osmosisTestnetChain to determine which chain to use. Double-check that env.osmosisTestnetChain accurately reflects the chain ID and that this logic does not cause issues when additional chains are added.

utils/constants.ts (1)

17-29: LGTM! Token metadata is correctly defined.

The OSMOSIS_TOKEN_DATA constant follows the established pattern and correctly defines the token denominations with proper exponents.

components/groups/modals/voteModal.tsx (1)

18-20: LGTM! Verify chain name usage across the codebase.

Successfully replaced hardcoded chain name with environment variable. Let's verify similar usage across the codebase.

✅ Verification successful

Chain name usage is consistent across the codebase

The remaining hardcoded 'manifest' references are legitimate as they are used for address validation patterns, test data, and UI-specific cases. All chain-related hooks consistently use env.chain, with appropriate handling of IBC functionality where different chains are needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining hardcoded 'manifest' chain references
rg -i "['\"](manifest|osmosis)['\"]" --type ts --type tsx

# Search for potential missed chain-related environment variable usage
rg "useChain\(['\"]" --type ts --type tsx

Length of output: 165


Script:

#!/bin/bash
# Search for hardcoded chain references without file type restriction
rg -i "['\"]manifest['\"]"
rg -i "['\"]osmosis['\"]"

# Search for chain-related hook usage
rg "use(Chain|Tx|FeeEstimation)\("

# Search for env.chain usage to verify consistent pattern
rg "env\.chain"

Length of output: 14895

components/bank/modals/sendModal.tsx (1)

20-23: LGTM! Clean integration of Osmosis balance handling

The changes properly integrate Osmosis balance functionality through well-defined props and consistent prop passing.

Also applies to: 39-42, 109-112

components/bank/modals/txInfo.tsx (1)

78-97: LGTM! Enhanced IBC token display handling.

The changes improve the display of IBC tokens by retrieving and showing the base denomination instead of the raw IBC hash. The implementation correctly:

  • Handles IBC token detection
  • Retrieves asset metadata
  • Formats amounts with proper decimal places
hooks/useTx.tsx (2)

49-50: LGTM! Dynamic explorer URL configuration.

The change removes hardcoded chain references by dynamically selecting the explorer URL based on the chain name.


Line range hint 111-134: LGTM! Enhanced proposal submission feedback.

The implementation properly:

  • Detects proposal submission transactions
  • Extracts proposal ID from events
  • Provides relevant feedback with proposal-specific links
components/factory/forms/TokenDetailsForm.tsx (1)

Line range hint 48-56: LGTM! Automatic denom units management.

The useEffect hook properly maintains denomUnits consistency by:

  • Including both full denom and display units
  • Setting correct exponent values
  • Updating on relevant field changes
components/groups/forms/groups/ConfirmationForm.tsx (1)

9-9: LGTM! Removed hardcoded chain references.

The changes properly:

  • Import environment configuration
  • Replace hardcoded chain references with env.chain
  • Maintain consistent behavior across different chains

Also applies to: 33-34

pages/_app.tsx (3)

12-19: LGTM! Clean import restructuring.

The imports have been updated to source chain configurations directly from the chain registry, improving maintainability by removing hardcoded values.


79-79: LGTM! Enhanced message type support.

The addition of IBC proto registry and amino converters enables proper handling of IBC-related messages.

Also applies to: 85-85


192-195: Verify Osmosis testnet endpoints configuration.

The Osmosis testnet endpoints and chain configuration have been added. Please ensure that:

  1. The environment variables osmosisTestnetRpcUrl and osmosisTestnetApiUrl are properly configured.
  2. The chain registry assets and configuration for both chains are compatible.

Also applies to: 205-207

✅ Verification successful

Environment variables and chain registry configuration are properly set up

The implementation shows correct configuration:

  • Environment variables are properly defined in config/env.ts and used correctly throughout the application
  • Chain registry configuration in utils/ibc.ts shows compatible asset lists and correct IBC channel setup

Note: Consider adding these environment variables to an .env.example file for documentation purposes:

NEXT_PUBLIC_OSMOSIS_TESTNET_API_URL=
NEXT_PUBLIC_OSMOSIS_TESTNET_RPC_URL=
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify environment variables and chain registry configuration

# Test 1: Check if environment variables are defined
echo "Checking environment variables..."
grep -r "osmosisTestnetRpcUrl\|osmosisTestnetApiUrl" .env* || echo "Environment variables not found in .env files"

# Test 2: Verify chain registry configuration
echo "Checking chain registry imports..."
fd -e ts -e js -x rg -l "chain-registry/testnet/(manifesttestnet|osmosistestnet)"

Length of output: 420


Script:

#!/bin/bash
# Check for environment variable usage and template files
echo "Checking for environment variable usage..."
rg "osmosisTestnetRpcUrl|osmosisTestnetApiUrl" -A 2 -B 2

echo -e "\nChecking for .env template files..."
fd -g ".env*"

echo -e "\nChecking chain registry configuration..."
cat ./utils/ibc.ts

Length of output: 9342

components/bank/components/tokenList.tsx (2)

19-22: LGTM! Well-structured prop additions.

The new Osmosis-related props are properly typed and marked as optional, maintaining backward compatibility.


251-254: LGTM! Proper prop forwarding with fallbacks.

The Osmosis-related props are properly forwarded to the SendModal component with appropriate default values.

components/groups/components/groupControls.tsx (1)

17-17: LGTM! Removed hardcoded chain identifier.

The change from hardcoded 'manifest' to env.chain improves configurability and maintainability.

Also applies to: 25-25, 231-231

hooks/useQueries.ts (1)

635-659: LGTM! Well-structured hook for Osmosis token metadata.

The implementation follows the established pattern and includes proper error handling.

package.json (1)

7-7: Verify the impact of removing host binding.

Removing -H 0.0.0.0 might affect accessibility of the dev server from other devices on the network. Ensure this change doesn't impact your development workflow.

pages/bank.tsx Outdated Show resolved Hide resolved
components/bank/forms/ibcSendForm.tsx Outdated Show resolved Hide resolved
components/bank/components/sendBox.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
components/bank/forms/ibcSendForm.tsx (1)

Line range hint 146-152: Incorrect recipient address validation based on destination chain

The recipient address validation currently uses .manifestAddress(), which may not be appropriate when the destination chain is not Manifest. Update the validation to check the recipient address format according to the selectedToChain.

Apply this diff to adjust the validation:

recipient: Yup.string().required('Recipient is required')
-  .manifestAddress(),
+  .test(
+    'is-valid-address',
+    'Invalid recipient address',
+    function (value) {
+      if (!value) return false;
+      const { selectedToChain } = this.parent;
+      if (selectedToChain === env.chain) {
+        return isValidManifestAddress(value);
+      } else if (selectedToChain === env.osmosisTestnetChain) {
+        return isValidOsmosisAddress(value);
+      }
+      return false;
+    }
+  ),

You'll need to implement isValidManifestAddress and isValidOsmosisAddress functions to properly validate addresses for each chain.

🧹 Nitpick comments (4)
scripts/ibcTransferAll.ts (4)

91-93: Avoid fragile URL manipulation for REST endpoint

Replacing 'rpc' with 'rest' in the OSMOSIS_RPC URL is fragile and could lead to errors if the URL structure changes. Consider specifying the REST endpoint explicitly or parsing the URL more robustly.

Apply this diff to improve URL handling:

- const response = await axios.get(
-   `${OSMOSIS_RPC.replace('rpc', 'rest')}/ibc/apps/transfer/v1/denom_traces/${hash}`
- );
+ const osmosisRestUrl = OSMOSIS_RPC.replace('rpc', 'rest');
+ const denomTraceUrl = `${osmosisRestUrl}/ibc/apps/transfer/v1/denom_traces/${hash}`;
+ const response = await axios.get(denomTraceUrl);

Alternatively, define the REST endpoint explicitly in your environment configuration:

// Environment Configuration
const env = {
  rpcUrl: 'https://nodes.liftedinit.tech/manifest/testnet/rpc',
  osmosisTestnetRpcUrl: 'https://rpc.osmotest5.osmosis.zone',
+ osmosisTestnetRestUrl: 'https://rest.osmotest5.osmosis.zone',
  chain: 'manifest-testnet',
  osmosisTestnetChain: 'osmo-test-5',
};

And then use it directly:

- const response = await axios.get(
-   `${OSMOSIS_RPC.replace('rpc', 'rest')}/ibc/apps/transfer/v1/denom_traces/${hash}`
- );
+ const response = await axios.get(
+   `${env.osmosisTestnetRestUrl}/ibc/apps/transfer/v1/denom_traces/${hash}`
+ );

151-153: Make the transfer amount configurable

Currently, the script transfers '1' unit of each token. Consider making the transfer amount configurable or transferring the entire balance to suit different use cases.

Apply this diff to transfer the full balance of each token:

      token: {
        denom: token.denom,
-       amount: '1',
+       amount: token.amount,
      },

167-168: Set fees and gas limits dynamically

Hardcoding the fee amount and gas limit may lead to transaction failures or unnecessary costs. Consider estimating the gas and setting the fee dynamically based on transaction requirements.

Apply this diff to estimate fees dynamically:

- const fee = {
-   amount: [{ denom: 'umfx', amount: '5500' }],
-   gas: '5000000',
- };

+ const estimatedFee = await manifestClient.simulate(manifestAccount.address, messages, '');
+ const fee = {
+   amount: estimatedFee.amount,
+   gas: estimatedFee.gas.toString(),
+ };

18-26: Extend getIbcInfo to support additional chain combinations

Currently, getIbcInfo only supports transfers between manifest-testnet and osmo-test-5. Consider extending this function to support additional chain combinations for future scalability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc163e0 and aa9301f.

📒 Files selected for processing (4)
  • .gitignore (1 hunks)
  • components/bank/components/sendBox.tsx (4 hunks)
  • components/bank/forms/ibcSendForm.tsx (11 hunks)
  • scripts/ibcTransferAll.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Test and Coverage
components/bank/forms/ibcSendForm.tsx

[error] 476-476: TypeError: Cannot call map() on undefined. The 'availableToChains' variable is undefined when attempting to use map() function.

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
.gitignore (2)

41-41: Verify the purpose and content of the certificates directory.

Given this PR's focus on IBC transfers, please confirm:

  1. Are these certificates used for chain communication?
  2. Does this directory contain any sensitive production certificates that should be managed differently?

Let's check if there are any certificates committed before this change:

✅ Verification successful

Preemptive .gitignore entry for certificates is a good security practice

The absence of any certificate files or references in the codebase suggests this is a preemptive .gitignore entry, which is a recommended practice to prevent accidental commitment of sensitive security files that will be generated during IBC setup.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any certificate files that might have been committed
fd -e crt -e pem -e key -e cer

Length of output: 32


Script:

#!/bin/bash
# Search for certificate-related patterns in code and documentation
rg -i "certificate" --type-add 'docs:*.{md,txt,rst}' -g '!{node_modules,dist,build}/*' -A 2

# Look for configuration templates or examples
fd -e yaml -e yml -e json -e example -e template -e sample | xargs rg -i "certificate"

Length of output: 178


43-43: Clarify the purpose and naming of demons.json.

The file name demons.json is unclear and potentially concerning. Could you please:

  1. Explain its purpose in relation to the Osmosis integration
  2. Consider a more descriptive name that reflects its functionality
  3. Confirm if it contains any sensitive data that requires special handling

Let's check if this file exists and examine its structure:

scripts/ibcTransferAll.ts (1)

141-142: Verify the correctness of timeoutInNanos calculation

Ensure that timeoutInNanos is calculated correctly to prevent premature timeouts or excessive delays in the IBC transfers. Verify that the units are consistent and accurately represent the intended timeout duration.

components/bank/components/sendBox.tsx (1)

64-70: Chain selection validation implemented correctly

The useEffect hook properly ensures that the source and destination chains are not the same by updating the selectedToChain when necessary. This addresses the previous concern about missing chain selection validation.

components/bank/forms/ibcSendForm.tsx (1)

202-206: Verify the sender address corresponds to the selectedFromChain

Ensure that the sender address used in the transfer message matches the address format and prefix of the selectedFromChain. This prevents issues where an incorrect address could cause transaction failures.

scripts/ibcTransferAll.ts Outdated Show resolved Hide resolved
components/bank/forms/ibcSendForm.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
components/bank/forms/ibcSendForm.tsx (2)

159-160: Extract magic number to a named constant.

The MIN_FEE_BUFFER value should be extracted to a named constant at the module level for better maintainability.

+const MIN_FEE_BUFFER = 0.09;
 const hasInsufficientBuffer = value > balance - MIN_FEE_BUFFER;

Line range hint 189-213: Document the timeout calculation and extract magic numbers.

The timeout calculation uses magic numbers (1.2e6 and 1e6) without explanation. Consider extracting these to named constants and adding a comment explaining the timeout logic.

+// Timeout after 20 minutes (1.2e6 milliseconds)
+const TIMEOUT_WINDOW_MS = 1.2e6;
+// Convert to nanoseconds (1e6 nanoseconds per millisecond)
+const MS_TO_NANOS = 1e6;
 const stamp = Date.now();
-const timeoutInNanos = (stamp + 1.2e6) * 1e6;
+const timeoutInNanos = (stamp + TIMEOUT_WINDOW_MS) * MS_TO_NANOS;
components/groups/components/myGroups.tsx (1)

284-285: Avoid duplication between uri and uri_hash fields

In lines 284-285, both uri and uri_hash are assigned the same value, which is the URI of the asset logo. If uri_hash is intended to store a hash of the URI (e.g., for verification), consider computing the hash of the URI instead of assigning the URI itself.

Apply this diff to compute an actual hash for uri_hash:

+ import crypto from 'crypto';

...

  uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
- uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
+ uri_hash: assetInfo?.logo_URIs
+   ? crypto.createHash('sha256').update(assetInfo.logo_URIs.svg ?? assetInfo.logo_URIs.png).digest('hex')
+   : '',

Ensure that you handle the import of the crypto module correctly and that it's compatible with your build environment.

components/bank/components/historyBox.tsx (1)

235-236: Avoid duplication between uri and uri_hash fields

Similar to the previous file, in lines 235-236, both uri and uri_hash are assigned the same value. If uri_hash is meant to store a hash of the URI, compute the hash instead.

Apply this diff:

  uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
- uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
+ uri_hash: assetInfo?.logo_URIs
+   ? crypto.createHash('sha256').update(assetInfo.logo_URIs.svg ?? assetInfo.logo_URIs.png).digest('hex')
+   : '',

Ensure the crypto module is imported and available.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa9301f and dbeeec5.

📒 Files selected for processing (5)
  • components/bank/components/historyBox.tsx (4 hunks)
  • components/bank/forms/ibcSendForm.tsx (11 hunks)
  • components/bank/modals/txInfo.tsx (2 hunks)
  • components/groups/components/myGroups.tsx (2 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • components/bank/modals/txInfo.tsx
🔇 Additional comments (7)
components/bank/forms/ibcSendForm.tsx (5)

Line range hint 1-35: LGTM! Well-organized imports.

The imports are properly structured and all necessary for the IBC transfer functionality.


Line range hint 37-81: LGTM! Well-structured props definition.

Props are properly typed with Readonly and include comprehensive support for both individual and group IBC transfers.


83-102: Fix null reference error with useSearchParams.

The useSearchParams hook may return null, leading to potential runtime errors.


87-92: LGTM! Well-implemented chain-specific hooks.

The tx and fee estimation hooks are properly configured based on the selected chain.


276-529: LGTM! Well-implemented chain selection UI.

The chain selection UI is well-structured with proper accessibility attributes and keyboard navigation support.

components/groups/components/myGroups.tsx (1)

14-14: Importing denomToAsset is appropriate

The import of denomToAsset is necessary for processing IBC token denominations correctly.

components/bank/components/historyBox.tsx (1)

4-4: Importing denomToAsset and env is appropriate

The imports of denomToAsset and env are necessary for processing asset information and accessing environment variables.

components/bank/forms/ibcSendForm.tsx Outdated Show resolved Hide resolved
components/groups/components/myGroups.tsx Outdated Show resolved Hide resolved
components/bank/components/historyBox.tsx Outdated Show resolved Hide resolved
components/bank/components/historyBox.tsx Outdated Show resolved Hide resolved
components/bank/components/historyBox.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@fmorency fmorency left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chalabi2. A few questions

  • How hard will it be to add new denoms, e.g., ATOM, ...?
  • Can you address the CR comments?
  • Can you fix the tests?
  • Can you provide the values for the new env. variables?

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
config/env.ts Outdated Show resolved Hide resolved
config/env.ts Outdated Show resolved Hide resolved
config/env.ts Outdated Show resolved Hide resolved
pages/_app.tsx Outdated Show resolved Hide resolved
pages/bank.tsx Outdated Show resolved Hide resolved
scripts/ibcTransferAll.ts Outdated Show resolved Hide resolved
scripts/ibcTransferAll.ts Outdated Show resolved Hide resolved
@@ -0,0 +1,232 @@
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment on the purpose of this script

chalabi2 and others added 7 commits January 14, 2025 12:35
Co-authored-by: Félix C. Morency <[email protected]>
Signed-off-by: Joseph Chalabi <[email protected]>
Co-authored-by: Félix C. Morency <[email protected]>
Signed-off-by: Joseph Chalabi <[email protected]>
Co-authored-by: Félix C. Morency <[email protected]>
Signed-off-by: Joseph Chalabi <[email protected]>
Co-authored-by: Félix C. Morency <[email protected]>
Signed-off-by: Joseph Chalabi <[email protected]>
Co-authored-by: Félix C. Morency <[email protected]>
Signed-off-by: Joseph Chalabi <[email protected]>
Co-authored-by: Félix C. Morency <[email protected]>
Signed-off-by: Joseph Chalabi <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
hooks/useQueries.ts (2)

635-771: Consider extracting common hook logic to reduce duplication.

The Osmosis hooks mirror their non-Osmosis counterparts with very similar implementations. Consider creating a higher-order hook factory to reduce code duplication.

Example implementation:

const createTokenBalancesHook = (useClient: () => { lcdQueryClient: any }, prefix: string) => 
  (address: string) => {
    const { lcdQueryClient } = useClient();

    const fetchBalances = async () => {
      if (!lcdQueryClient) {
        throw new Error('LCD Client not ready');
      }
      return await lcdQueryClient.cosmos.bank.v1beta1.allBalances({
        address,
        resolveDenom: false,
      });
    };

    const balancesQuery = useQuery({
      queryKey: [`${prefix}Balances`, address],
      queryFn: fetchBalances,
      enabled: !!lcdQueryClient && !!address,
      staleTime: Infinity,
    });

    return {
      balances: balancesQuery.data?.balances,
      isBalancesLoading: balancesQuery.isLoading,
      isBalancesError: balancesQuery.isError,
      refetchBalances: balancesQuery.refetch,
    };
  };

// Usage:
export const useTokenBalances = createTokenBalancesHook(useLcdQueryClient, '');
export const useTokenBalancesOsmosis = createTokenBalancesHook(useOsmosisLcdQueryClient, 'osmosis');

773-863: Enhance type safety and error handling in message formatting.

While the message formatting implementation is solid, consider these improvements:

  1. Add type annotations for the message parameter
  2. Consider using a discriminated union type for different message types
  3. Add error handling for malformed messages

Example implementation:

type BaseMessage = {
  '@type': string;
};

type SendMessage = BaseMessage & {
  '@type': '/cosmos.bank.v1beta1.MsgSend';
  fromAddress: string;
  toAddress: string;
  amount: TransactionAmount[];
};

type MintMessage = BaseMessage & {
  '@type': '/osmosis.tokenfactory.v1beta1.MsgMint';
  sender: string;
  mintToAddress: string;
  amount: TransactionAmount;
};

// Add other message types...

type Message = SendMessage | MintMessage; // | other message types

const _formatMessage = (
  message: Message,
  address: string
): {
  data: {
    tx_type: HistoryTxType;
    from_address: string;
    to_address: string;
    amount: TransactionAmount[];
  };
}[] => {
  try {
    switch (message['@type']) {
      // ... existing cases ...
      default:
        console.warn(`Unsupported message type: ${message['@type']}`);
        return [];
    }
  } catch (error) {
    console.error('Error formatting message:', error);
    return [];
  }
};
components/react/modal.tsx (1)

97-108: Consider memoizing chain-specific values individually.

While the current implementation works, memoizing individual chain values could prevent unnecessary re-renders when only one chain's state changes.

-  const chainStates = useMemo(() => {
-    return Object.values(chains).map(chain => ({
-      connect: chain.connect,
-      openView: chain.openView,
-      status: chain.status,
-      username: chain.username,
-      address: chain.address,
-      disconnect: chain.disconnect,
-    }));
-  }, [chains]);
+  const manifestChainState = useMemo(() => ({
+    connect: chains?.manifesttestnet?.connect,
+    openView: chains?.manifesttestnet?.openView,
+    status: chains?.manifesttestnet?.status,
+    username: chains?.manifesttestnet?.username,
+    address: chains?.manifesttestnet?.address,
+    disconnect: chains?.manifesttestnet?.disconnect,
+  }), [chains?.manifesttestnet]);
+
+  const osmosisChainState = useMemo(() => ({
+    connect: chains?.osmosis?.connect,
+    openView: chains?.osmosis?.openView,
+    status: chains?.osmosis?.status,
+    username: chains?.osmosis?.username,
+    address: chains?.osmosis?.address,
+    disconnect: chains?.osmosis?.disconnect,
+  }), [chains?.osmosis]);
pages/bank.tsx (1)

167-238: Refactor duplicated IBC token handling logic.

The IBC token handling logic is duplicated between combinedBalances and combinedOsmosisBalances. Consider extracting this into a shared utility function.

+ const processIbcToken = (assetInfo: any, coreBalance: any) => {
+   const baseDenom = assetInfo?.traces?.[1]?.counterparty?.base_denom ?? coreBalance.denom;
+   return {
+     denom: baseDenom,
+     coreDenom: coreBalance.denom,
+     amount: coreBalance.amount,
+     metadata: {
+       description: assetInfo?.description ?? '',
+       denom_units: assetInfo?.denom_units?.map(unit => unit ? ({
+         ...unit,
+         aliases: unit.aliases || [],
+       }) : null).filter(Boolean) ?? [],
+       base: assetInfo?.base ?? '',
+       display: assetInfo?.display ?? '',
+       name: assetInfo?.name ?? '',
+       symbol: assetInfo?.symbol ?? '',
+       uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? undefined,
+       uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? undefined,
+     },
+   };
+ };

Then use it in both places:

 if (coreBalance.denom.startsWith('ibc/')) {
   const assetInfo = denomToAsset(env.chain, coreBalance.denom);
-  // ... existing implementation
+  return processIbcToken(assetInfo, coreBalance);
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 625ce3a and d9af353.

📒 Files selected for processing (7)
  • components/groups/components/myGroups.tsx (2 hunks)
  • components/react/modal.tsx (3 hunks)
  • hooks/useQueries.ts (4 hunks)
  • package.json (3 hunks)
  • pages/_app.tsx (6 hunks)
  • pages/bank.tsx (6 hunks)
  • tests/mock.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/mock.ts
  • package.json
  • components/groups/components/myGroups.tsx
🧰 Additional context used
📓 Learnings (1)
pages/bank.tsx (1)
Learnt from: chalabi2
PR: liftedinit/manifest-app#194
File: pages/bank.tsx:257-268
Timestamp: 2025-01-11T03:29:20.686Z
Learning: In the bank page of manifest-app, only assets in the user's Manifest wallet are displayed in the main asset list with search functionality. IBC assets (including Osmosis balances) are handled separately within the ibcSendForm component.
🔇 Additional comments (13)
hooks/useQueries.ts (1)

5-5: LGTM! Import changes align with IBC support.

The added imports for Osmosis LCD client and IBC denom normalization are necessary for the cross-chain functionality.

Also applies to: 7-7

components/react/modal.tsx (3)

39-40: LGTM! New imports support multi-chain functionality.

The new imports enable access to chain configurations and multi-chain state management, aligning with the PR's objective of adding Osmosis chain support.


110-112: LGTM! Robust disconnect implementation.

The concurrent disconnection of all chains using Promise.all is an efficient approach.


467-467: LGTM! Updated disconnect handler.

The Connected view now uses the new multi-chain disconnect function.

pages/_app.tsx (5)

54-54: Track the TODO for future cleanup.

The current manual asset list injection is a temporary solution. Once the chain registry is updated, this should be revisited to use the official registry.

Could you create a tracking issue to ensure this technical debt is addressed when the chain registry is updated?


72-94: LGTM! Comprehensive registry configuration.

The signerOptions configuration correctly merges all necessary registries and amino converters, including the new IBC support.


192-195: LGTM! Endpoint configuration follows established pattern.

The Osmosis testnet endpoint configuration correctly follows the same pattern as the Manifest chain, using environment variables for the URLs.


228-266: LGTM! Clean component hierarchy with proper provider order.

The component structure maintains a clean hierarchy with proper provider order and responsive layout design. The addition of SkipProvider is well-placed for IBC transfer support.


205-207: Verify environment variable configuration.

The ChainProvider configuration looks correct, but ensure that all required environment variables (osmosisRpcUrl, osmosisApiUrl) are properly documented and configured in the deployment environment.

Run this script to verify the environment variables:

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check if required environment variables are defined in .env files

# Test: Search for Osmosis-related environment variables
rg -l "osmosisRpcUrl|osmosisApiUrl" .env*

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Script: List all occurrences of osmosis-related environment variables in .env* files
# This helps verify that both osmosisRpcUrl and osmosisApiUrl are properly configured.
echo "Searching for osmosisRpcUrl and osmosisApiUrl in all .env* files..."
rg -n "osmosisRpcUrl|osmosisApiUrl" .env*

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Script: Search the entire repository for osmosis-related environment variable usage
# This will help us determine if 'osmosisRpcUrl' and 'osmosisApiUrl' are referenced anywhere,
# which might indicate they are defined or expected to be provided in another configuration file.
echo "Searching repository for 'osmosisRpcUrl'..."
rg -n "osmosisRpcUrl" .

echo "-----------------------------------------"

echo "Searching repository for 'osmosisApiUrl'..."
rg -n "osmosisApiUrl" .

Length of output: 852


Environment Variable Configuration Verified

The repository properly references osmosisRpcUrl and osmosisApiUrl in its configuration via process.env.NEXT_PUBLIC_OSMOSIS_RPC_URL and process.env.NEXT_PUBLIC_OSMOSIS_API_URL (see ./config/env.ts and their usage in pages/_app.tsx and hooks). Although these values aren’t explicitly defined in the tracked .env files, they are expected to be provided by the deployment environment. Ensure that the deployment documentation clearly specifies these environment variables.

pages/bank.tsx (4)

1-24: LGTM! Import changes for multi-chain support.

The addition of Osmosis-specific hooks and the switch to useChains for multi-chain support is well-structured.


310-323: 🛠️ Refactor suggestion

Add default values for Osmosis-related props.

The TokenList component receives new props without default values, which could lead to runtime errors.

 <TokenList
   refetchBalances={refetchBalances || resolveRefetch}
-  refetchOsmosisBalances={refetchOsmosisBalances}
-  resolveOsmosisRefetch={resolveOsmosisRefetch}
-  isOsmosisBalancesLoading={isOsmosisBalancesLoading}
-  osmosisBalances={combinedOsmosisBalances ?? []}
+  refetchOsmosisBalances={refetchOsmosisBalances || (() => {})}
+  resolveOsmosisRefetch={resolveOsmosisRefetch || (() => {})}
+  isOsmosisBalancesLoading={isOsmosisBalancesLoading || false}
+  osmosisBalances={combinedOsmosisBalances ?? []}
   isLoading={isLoading}
   balances={combinedBalances}
   refetchHistory={refetchHistory}
   address={chains.manifesttestnet.address ?? ''}
   pageSize={tokenListPageSize}
   searchTerm={searchTerm}
   chains={chains}
 />

Likely invalid or redundant comment.


129-153: ⚠️ Potential issue

Improve null handling in IBC token processing.

The current implementation has potential null reference issues when accessing nested properties.

 if (coreBalance.denom.startsWith('ibc/')) {
   const assetInfo = denomToAsset(env.chain, coreBalance.denom);
-  const baseDenom = assetInfo?.traces?.[1]?.counterparty?.base_denom;
+  const baseDenom = assetInfo?.traces?.[1]?.counterparty?.base_denom ?? coreBalance.denom;

   return {
-    denom: baseDenom ?? '', // normalized denom (e.g., 'umfx')
+    denom: baseDenom, // normalized denom (e.g., 'umfx')
     coreDenom: coreBalance.denom, // full IBC trace
     amount: coreBalance.amount,
     metadata: {
       description: assetInfo?.description ?? '',
       denom_units:
-        assetInfo?.denom_units?.map(unit => ({
+        assetInfo?.denom_units?.map(unit => unit ? ({
           ...unit,
           aliases: unit.aliases || [],
-        })) ?? [],
+        }) : null).filter(Boolean) ?? [],
       base: assetInfo?.base ?? '',
       display: assetInfo?.display ?? '',
       name: assetInfo?.name ?? '',
       symbol: assetInfo?.symbol ?? '',
-      uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
-      uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
+      uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? undefined,
+      uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? undefined,
     },
   };
 }

Likely invalid or redundant comment.


32-37: 🛠️ Refactor suggestion

Add error handling for wallet connections.

The wallet connection check should handle potential connection errors to improve user experience.

+ const [connectionError, setConnectionError] = useState<string | null>(null);
  const chains = useChains([env.chain, env.osmosisChain]);
  const isWalletConnected = useMemo(
    () => Object.values(chains).every(chain => chain.isWalletConnected),
    [chains]
  );
+ 
+ useEffect(() => {
+   if (!isWalletConnected) {
+     Object.values(chains).forEach(chain => {
+       chain.connect().catch(error => {
+         console.error(`Failed to connect to chain: ${chain.chain.chain_name}`, error);
+         setConnectionError(`Failed to connect to ${chain.chain.chain_name}`);
+       });
+     });
+   }
+ }, [chains, isWalletConnected]);

Likely invalid or redundant comment.

await Promise.all(chainStates.map(chain => chain.disconnect()));
};

const current = chains?.manifesttestnet?.walletRepo?.current;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify chain identifier consistency.

Ensure that 'manifesttestnet' matches the chain identifier defined in the environment configuration.


🏁 Script executed:

#!/bin/bash
# Description: Check chain identifier consistency

# Search for chain identifier definitions
rg -A 2 "chain\s*=\s*['\"]manifesttestnet['\"]" 

Length of output: 53


🏁 Script executed:

#!/bin/bash
echo "=== Searching for 'manifesttestnet' across the entire repository ==="
rg -i "manifesttestnet" .

echo ""
echo "=== Searching for potential chain configuration definitions (e.g., using ':' or '=' operators) ==="
rg -i "chain\s*[:=]" .

Length of output: 9679

Chain Identifier Inconsistency Detected

  • The code in components/react/modal.tsx (line 114) uses manifesttestnet.
  • The environment configuration (e.g., in .env.test via NEXT_PUBLIC_CHAIN) is set to manifest.
  • This discrepancy may lead to mismatches when fetching chain-related configurations or assets.

Please review and align the chain identifiers either by updating the environment variable to "manifesttestnet" or by modifying the code to match the configured value.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
tests/render.tsx (1)

5-5: LGTM! Consider adding test configurations for chain-specific features.

The integration of Osmosis chain and asset lists is well-structured. To enhance test coverage, consider adding test configurations for:

  • Different chain combinations
  • Asset list variations
  • Error states
 const defaultOptions = {
   chains: [defaultChain, osmosisChain],
   assetLists: [...defaultAssetLists, ...osmosisAssetList],
+  // Add test-specific configurations
+  testConfigs: {
+    skipChainValidation: false,
+    mockIBCTransfers: false,
+    simulateNetworkErrors: false
+  },
   wallets: [],
 };

Also applies to: 10-11

components/bank/components/__tests__/sendBox.test.tsx (1)

29-46: Consider enhancing the IbcSendForm mock with error states.

While the mock provides basic chain selection functionality, it could be enhanced to simulate error conditions.

 mock.module('@/components/bank/forms/ibcSendForm', () => ({
   default: (props: any) => {
     return (
       <div data-testid="ibc-send-form">
+        {props.error && <div data-testid="error-message">{props.error}</div>}
         <div className="dropdown">
           <label tabIndex={0} aria-label="from-chain-selector" className="btn">
             {props.selectedFromChain?.name || 'Select Chain'}
           </label>
+          {props.isFromChainError && (
+            <div data-testid="from-chain-error">Invalid selection</div>
+          )}
         </div>
         <div className="dropdown">
           <label tabIndex={0} aria-label="to-chain-selector" className="btn">
             {props.selectedToChain?.name || 'Select Chain'}
           </label>
+          {props.isToChainError && (
+            <div data-testid="to-chain-error">Invalid selection</div>
+          )}
         </div>
       </div>
     );
   },
 }));
components/bank/forms/__tests__/ibcSendForm.test.tsx (2)

20-35: Consider parameterizing chain configurations for better test maintainability.

Extract chain configurations to a separate test utility file for reuse across tests.

+// testUtils/chainConfigs.ts
+export const testChainConfigs = {
+  manifest: {
+    id: 'manifest',
+    name: 'Manifest',
+    icon: 'https://osmosis.zone/assets/icons/osmo-logo-icon.svg',
+    prefix: 'manifest',
+    chainID: 'manifest-1',
+  },
+  osmosis: {
+    id: 'osmosistestnet',
+    name: 'Osmosis',
+    icon: 'https://osmosis.zone/assets/icons/osmo-logo-icon.svg',
+    prefix: 'osmo',
+    chainID: 'osmo-test-1',
+  },
+};

155-176: Add tests for chain selection error handling.

Consider adding tests for:

  • Network errors during chain selection
  • Invalid chain configurations
  • Chain validation failures
test('handles chain selection errors', async () => {
  const mockError = new Error('Chain validation failed');
  renderWithProps({
    setSelectedFromChain: jest.fn().mockRejectedValue(mockError)
  });
  
  const fromChainSelector = screen.getByLabelText('from-chain-selector');
  fireEvent.click(fromChainSelector);
  
  // Verify error handling
  expect(await screen.findByTestId('error-message')).toBeInTheDocument();
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9af353 and 5e98218.

📒 Files selected for processing (4)
  • components/bank/components/__tests__/sendBox.test.tsx (3 hunks)
  • components/bank/forms/__tests__/ibcSendForm.test.tsx (4 hunks)
  • tests/mock.ts (1 hunks)
  • tests/render.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/mock.ts
🔇 Additional comments (6)
tests/render.tsx (1)

21-23: LGTM! Provider hierarchy is correctly structured.

The SkipProvider is properly placed to wrap the ToastProvider, maintaining the correct context hierarchy.

components/bank/components/__tests__/sendBox.test.tsx (3)

21-26: LGTM! Image mock is properly implemented.

The next/image mock correctly handles required props and maintains accessibility with alt text.


74-88: Enhance test coverage for cross-chain transfer edge cases.

While the basic flow is tested, consider adding tests for:

  • Invalid chain selections
  • Network errors during chain switching
  • Validation failures

90-98: LGTM! Chain selection test is well-structured.

The test properly verifies the presence of chain selectors after mode switch.

components/bank/forms/__tests__/ibcSendForm.test.tsx (2)

37-65: LGTM! Props configuration is comprehensive.

The default props properly cover all required IBC transfer functionality.


178-200: LGTM! Same chain prevention test is well-implemented.

The test properly verifies that the same chain cannot be selected for both source and destination.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🔭 Outside diff range comments (1)
components/bank/components/sendBox.tsx (1)

91-118: Enhance accessibility for tab buttons.

Add ARIA roles and keyboard navigation for better accessibility.

+  const handleKeyDown = (e: React.KeyboardEvent) => {
+    if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
+      setActiveTab(activeTab === 'send' ? 'cross-chain' : 'send');
+    }
+  };

   return (
-    <div className="rounded-2xl w-full  ">
+    <div className="rounded-2xl w-full" role="tablist">
       <div className="flex mb-4 md:mb-6 w-full h-[3.5rem] rounded-xl p-1 bg-[#0000000A] dark:bg-[#FFFFFF0F]">
         <button
           aria-label="send-tab"
+          role="tab"
+          aria-selected={activeTab === 'send'}
+          onKeyDown={handleKeyDown}
           className={`flex-1 py-2 px-4 text-sm font-medium rounded-xl transition-colors ${
♻️ Duplicate comments (1)
components/react/modal.tsx (1)

114-114: ⚠️ Potential issue

Fix chain identifier inconsistency.

The code uses manifesttestnet but environment configuration uses manifest. This mismatch could cause runtime errors.

Apply this diff to fix the chain identifier:

-  const current = chains?.manifesttestnet?.walletRepo?.current;
+  const current = chains?.[env.chain]?.walletRepo?.current;
🧹 Nitpick comments (6)
utils/format.ts (1)

34-50: LGTM! Consider caching asset info lookup.

The IBC denom handling is well-implemented. For performance optimization, consider memoizing the asset info lookup if this function is called frequently with the same parameters.

+const assetInfoCache = new Map<string, Asset>();
+
 export function formatDenom(denom: string): string {
-  const assetInfo = denomToAsset(env.chain, denom);
+  const cacheKey = `${env.chain}:${denom}`;
+  let assetInfo = assetInfoCache.get(cacheKey);
+  if (!assetInfo) {
+    assetInfo = denomToAsset(env.chain, denom);
+    if (assetInfo) {
+      assetInfoCache.set(cacheKey, assetInfo);
+    }
+  }
utils/ibc.ts (1)

19-25: Add type assertion for chain_name comparison.

Consider adding type assertion to ensure chain_name is string for comparison.

 const filterAssets = (chainName: string, assetList: AssetList[]): Asset[] => {
   return (
     assetList
-      .find(({ chain_name }) => chain_name === chainName)
+      .find(({ chain_name }: { chain_name: string }) => chain_name === chainName)
       ?.assets?.filter(({ type_asset }) => type_asset === 'ics20' || !type_asset) || []
   );
 };
components/bank/components/sendBox.tsx (1)

47-72: Consider extracting chain configuration to a separate file.

The chain configuration could be moved to a dedicated configuration file for better maintainability.

+// chains.config.ts
+export const chainConfig: IbcChain[] = [
+  {
+    id: env.chain,
+    name: 'Manifest',
+    icon: 'logo.svg',
+    prefix: 'manifest',
+    chainID: env.chainId,
+  },
+  // ... other chains
+];

+// sendBox.tsx
-const ibcChains = useMemo<IbcChain[]>(
-  () => [
-    {
-      id: env.chain,
-      // ... chain config
-    },
-    // ... other chains
-  ],
-  []
-);
+const ibcChains = useMemo<IbcChain[]>(() => chainConfig, []);
components/bank/forms/ibcSendForm.tsx (2)

87-95: Extract token display name formatting to a utility function.

The token display name formatting logic is duplicated in multiple places.

+// utils/formatting.ts
+export const formatTokenDisplayName = (displayName: string) => {
+  if (displayName.startsWith('factory')) {
+    return displayName.split('/').pop()?.toUpperCase();
+  }
+  if (displayName.startsWith('u')) {
+    return displayName.slice(1).toUpperCase();
+  }
+  return truncateString(displayName, 10).toUpperCase();
+};

-const formatTokenDisplayName = (displayName: string) => {
-  if (displayName.startsWith('factory')) {
-    return displayName.split('/').pop()?.toUpperCase();
-  }
-  if (displayName.startsWith('u')) {
-    return displayName.slice(1).toUpperCase();
-  }
-  return truncateString(displayName, 10).toUpperCase();
-};

169-185: Improve fee buffer configuration.

The fee warning logic uses hardcoded values and only applies to 'umfx' tokens.

+// Constants for fee calculation
+const FEE_CONFIG = {
+  MIN_FEE_BUFFER: 0.09,
+  FEE_TOKENS: ['umfx', 'uosmo'],
+  WARNING_MESSAGE: (token: string) => `Remember to leave ${token} for fees!`,
+};

 .test('leave-for-fees', '', function (value) {
   const { selectedToken } = this.parent;
-  if (!selectedToken || !value || selectedToken.denom !== 'umfx') return true;
+  if (!selectedToken || !value || !FEE_CONFIG.FEE_TOKENS.includes(selectedToken.denom)) {
+    return true;
+  }

   const exponent = selectedToken.metadata?.denom_units[1]?.exponent ?? 6;
   const balance = parseFloat(selectedToken.amount) / Math.pow(10, exponent);

-  const MIN_FEE_BUFFER = 0.09;
-  const hasInsufficientBuffer = value > balance - MIN_FEE_BUFFER;
+  const hasInsufficientBuffer = value > balance - FEE_CONFIG.MIN_FEE_BUFFER;

   if (hasInsufficientBuffer) {
-    setFeeWarning('Remember to leave tokens for fees!');
+    setFeeWarning(FEE_CONFIG.WARNING_MESSAGE(selectedToken.denom));
   } else {
     setFeeWarning('');
   }
.env.test (1)

6-13: Chain Configuration: Validate Variable Consistency and Intent
The chain configuration now supports Manifest, Osmosis, and Axelar testnets. Consider standardizing the formatting—specifically, review the use of quotes for chain IDs (e.g., NEXT_PUBLIC_CHAIN_ID and NEXT_PUBLIC_AXELAR_CHAIN_ID) to ensure consistency across all variables.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e98218 and 4b61039.

⛔ Files ignored due to path filters (1)
  • bun.lockb is excluded by !**/bun.lockb
📒 Files selected for processing (13)
  • .env.test (1 hunks)
  • components/bank/components/sendBox.tsx (4 hunks)
  • components/bank/forms/ibcSendForm.tsx (10 hunks)
  • components/bank/handlers/createMessageUtils.tsx (2 hunks)
  • components/factory/forms/TokenDetailsForm.tsx (1 hunks)
  • components/react/modal.tsx (3 hunks)
  • components/wallet.tsx (2 hunks)
  • config/env.ts (1 hunks)
  • package.json (3 hunks)
  • pages/_app.tsx (6 hunks)
  • pages/bank.tsx (6 hunks)
  • utils/format.ts (2 hunks)
  • utils/ibc.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/factory/forms/TokenDetailsForm.tsx
  • package.json
🧰 Additional context used
📓 Learnings (1)
pages/bank.tsx (1)
Learnt from: chalabi2
PR: liftedinit/manifest-app#194
File: pages/bank.tsx:257-268
Timestamp: 2025-01-11T03:29:20.686Z
Learning: In the bank page of manifest-app, only assets in the user's Manifest wallet are displayed in the main asset list with search functionality. IBC assets (including Osmosis balances) are handled separately within the ibcSendForm component.
🔇 Additional comments (24)
components/bank/handlers/createMessageUtils.tsx (2)

17-17: LGTM! Good variable extraction.

Extracting formatDenom(denom) to a variable improves code readability.


2-2: Verify if the denomToAsset import is needed.

The denomToAsset function is imported but not used in this file. Consider removing it if it's not needed.

Let's verify the usage:

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for denomToAsset usage in the file
rg "denomToAsset" "components/bank/handlers/createMessageUtils.tsx"

Length of output: 151


Unused Import & Approving Variable Extraction

  • The denomToAsset import is only found in the import statement and is not used anywhere in the file. Consider removing it if it's not needed.
  • The extraction of formatDenom(denom) into a variable improves clarity and is approved.
components/react/modal.tsx (3)

99-108: LGTM! Well-structured chain state management.

The memoized chainStates implementation efficiently extracts common properties from each chain and prevents unnecessary re-renders.


110-112: LGTM! Efficient concurrent disconnection.

The disconnect function efficiently handles multiple chain disconnections using Promise.all.


97-97: Verify chain configuration consistency.

The chain configuration uses environment variables. Ensure that env.chain, env.osmosisChain, and env.axelarChain are properly defined in the environment configuration.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check chain configuration in environment files

echo "=== Searching for chain configuration in environment files ==="
fd -e env -e env.local -e env.development -e env.production -e env.test --exec rg -l "chain|CHAIN"

echo -e "\n=== Searching for chain-related environment variable usage ==="
rg "env\.(chain|osmosisChain|axelarChain)"

Length of output: 8955


Chain configuration consistency verified.
The search results confirm that the chain identifiers (env.chain, env.osmosisChain, and env.axelarChain) are consistently referenced across multiple components, including the modal in question. There’s no evidence of inconsistency in their usage.

config/env.ts (1)

1-34: LGTM! Well-organized environment configuration.

The environment variables are logically grouped and consistently formatted. The use of comments to separate different categories (Wallet, Chains, Ops, Explorer URLs, RPC and API URLs) improves readability.

components/bank/components/sendBox.tsx (1)

77-85: LGTM! Chain selection validation is well-implemented.

The useEffect hook properly handles the case when the same chain is selected for both source and destination.

pages/_app.tsx (5)

12-20: LGTM! Chain registry imports look good.

The imports from the chain registry are correctly structured and include all necessary assets and chains for IBC support.


55-55: Address the TODO comment.

The comment indicates that asset list injections are temporary until the chain registry is updated.

Would you like me to help track this technical debt by creating an issue to remove asset list injections once the chain registry is updated?


206-208: LGTM! Chain configuration looks good.

The ChainProvider is correctly configured with all necessary chains and their respective asset lists.


229-268: LGTM! Component hierarchy and styling look good.

The updated component hierarchy with SkipProvider wrapping ThemeProvider and ContactsModalProvider is correctly implemented.


193-196: Verify RPC and REST endpoints for Osmosis.

The endpoint configuration for Osmosis looks correct, but let's verify the endpoints are accessible.

components/wallet.tsx (2)

38-88: LGTM! Multi-chain wallet management looks good.

The implementation correctly handles multiple chains using the useChains hook and properly manages chain states.


59-70: LGTM! Chain status management looks good.

The status computation correctly aggregates the state of all chains.

pages/bank.tsx (2)

312-315: 🛠️ Refactor suggestion

Add default values for Osmosis-related props.

The TokenList component receives new props without default values.

 <TokenList
   refetchBalances={refetchBalances || resolveRefetch}
-  refetchOsmosisBalances={refetchOsmosisBalances}
-  resolveOsmosisRefetch={resolveOsmosisRefetch}
-  isOsmosisBalancesLoading={isOsmosisBalancesLoading}
-  osmosisBalances={combinedOsmosisBalances ?? []}
+  refetchOsmosisBalances={refetchOsmosisBalances || (() => {})}
+  resolveOsmosisRefetch={resolveOsmosisRefetch || (() => {})}
+  isOsmosisBalancesLoading={isOsmosisBalancesLoading || false}
+  osmosisBalances={combinedOsmosisBalances ?? []}
   isLoading={isLoading}
   balances={combinedBalances}
   refetchHistory={refetchHistory}

Likely invalid or redundant comment.


129-153: ⚠️ Potential issue

Add null checks for IBC token handling.

The current implementation has potential null reference issues when accessing nested properties.

 if (coreBalance.denom.startsWith('ibc/')) {
   const assetInfo = denomToAsset(env.chain, coreBalance.denom);
-  const baseDenom = assetInfo?.traces?.[1]?.counterparty?.base_denom;
+  const baseDenom = assetInfo?.traces?.[1]?.counterparty?.base_denom ?? coreBalance.denom;

   return {
-    denom: baseDenom ?? '', // normalized denom (e.g., 'umfx')
+    denom: baseDenom, // normalized denom (e.g., 'umfx')
     coreDenom: coreBalance.denom, // full IBC trace
     amount: coreBalance.amount,
     metadata: {
       description: assetInfo?.description ?? '',
       denom_units:
-        assetInfo?.denom_units?.map(unit => ({
+        assetInfo?.denom_units?.map(unit => unit ? ({
           ...unit,
           aliases: unit.aliases || [],
-        })) ?? [],
+        }) : null).filter(Boolean) ?? [],
       base: assetInfo?.base ?? '',
       display: assetInfo?.display ?? '',
       name: assetInfo?.name ?? '',
       symbol: assetInfo?.symbol ?? '',
-      uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
-      uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? '',
+      uri: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? undefined,
+      uri_hash: assetInfo?.logo_URIs?.svg ?? assetInfo?.logo_URIs?.png ?? undefined,
     },
   };
 }

Likely invalid or redundant comment.

components/bank/forms/ibcSendForm.tsx (1)

861-863: 🛠️ Refactor suggestion

Remove unimplemented function.

The useSkip function is not implemented and appears to be unused.

-function useSkip(getCosmosSigner: () => Promise<import('@cosmjs/amino').OfflineAminoSigner>) {
-  throw new Error('Function not implemented.');
-}

Likely invalid or redundant comment.

.env.test (7)

1-5: Wallet Configuration: Ensure Test Keys Are Appropriately Scoped
The wallet section includes test keys and identifiers for WalletConnect and Web3Auth. Please double-check that these dummy values remain confined to the test environment and are not inadvertently promoted to production.


14-16: Ops and Environment Tier: Confirm Test Settings
The operational variable (NEXT_PUBLIC_CHAIN_TIER) is correctly set to testnet. Verify that this configuration aligns with your intended test environment and update as needed for production deployments.


17-19: Explorer URLs: Validate Endpoint Accessibility
The explorer endpoints for Manifest, Osmosis, and Axelar have been defined. Please ensure that these URLs point to the correct testnet explorers and are accessible, as they are critical for transaction tracking and debugging.


20-21: Indexer URL: Confirm Intentional Placeholder
The indexer URL is left empty in this test configuration. Ensure that this is deliberate and document the future plans (if any) for indexer integration so that it doesn’t cause confusion later.


22-24: RPC URLs (Main Chain): Placeholder Values Check
The main RPC and API URLs are currently unset. If these are intended to be provided dynamically or not needed for testnet operations, please confirm that the application logic correctly handles empty values.


25-27: Osmosis RPC URLs: Update When Available
The Osmosis API and RPC URLs are placeholders at this time. Verify whether these will be populated later or if additional default handling is implemented in the code; otherwise, update these values once the endpoints are defined.


28-30: Axelar RPC URLs: Ensure Future Configuration
Similar to the Osmosis configuration, the Axelar API and RPC URLs are empty. Confirm that there’s a plan to update these values when integrating with the Axelar testnet, avoiding potential connectivity issues.

Comment on lines +100 to +108
export const getIbcDenom = (chainName: string, denom: string) => {
const allAssets = getAllAssets(chainName);

// Find the asset that has this denom as its counterparty base_denom
const ibcAsset = allAssets.find(asset => asset.traces?.[0]?.counterparty?.base_denom === denom);

// Return the IBC hash (base) if found
return ibcAsset?.base;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for chainName parameter.

The function should validate the chainName parameter to prevent undefined behavior.

 export const getIbcDenom = (chainName: string, denom: string) => {
+  if (!chainName) {
+    throw new Error('chainName is required');
+  }
   const allAssets = getAllAssets(chainName);

   // Find the asset that has this denom as its counterparty base_denom
   const ibcAsset = allAssets.find(asset => asset.traces?.[0]?.counterparty?.base_denom === denom);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const getIbcDenom = (chainName: string, denom: string) => {
const allAssets = getAllAssets(chainName);
// Find the asset that has this denom as its counterparty base_denom
const ibcAsset = allAssets.find(asset => asset.traces?.[0]?.counterparty?.base_denom === denom);
// Return the IBC hash (base) if found
return ibcAsset?.base;
};
export const getIbcDenom = (chainName: string, denom: string) => {
if (!chainName) {
throw new Error('chainName is required');
}
const allAssets = getAllAssets(chainName);
// Find the asset that has this denom as its counterparty base_denom
const ibcAsset = allAssets.find(asset => asset.traces?.[0]?.counterparty?.base_denom === denom);
// Return the IBC hash (base) if found
return ibcAsset?.base;
};

Comment on lines 34 to 52
export const denomToAsset = (chainName: string, denom: string) => {
return getAllAssets(chainName).find(asset => asset.base === denom);
const allAssets = getAllAssets(chainName);

// Only handle IBC hashes
if (denom.startsWith('ibc/')) {
// Find the asset that has this IBC hash as its base
const asset = allAssets.find(asset => asset.base === denom);
if (asset?.traces?.[0]?.counterparty?.base_denom) {
// Return the original denom from the counterparty chain
return {
...asset,
base: asset.traces[0].counterparty.base_denom,
};
}
}

// Return original asset if not an IBC hash
return allAssets.find(asset => asset.base === denom);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for invalid IBC denoms.

The function should handle malformed IBC denoms gracefully.

 export const denomToAsset = (chainName: string, denom: string) => {
+  if (!denom) {
+    return undefined;
+  }
   const allAssets = getAllAssets(chainName);

   // Only handle IBC hashes
   if (denom.startsWith('ibc/')) {
+    if (denom.length < 5) { // "ibc/" + at least 1 char
+      return undefined;
+    }
     // Find the asset that has this IBC hash as its base
     const asset = allAssets.find(asset => asset.base === denom);
     if (asset?.traces?.[0]?.counterparty?.base_denom) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const denomToAsset = (chainName: string, denom: string) => {
return getAllAssets(chainName).find(asset => asset.base === denom);
const allAssets = getAllAssets(chainName);
// Only handle IBC hashes
if (denom.startsWith('ibc/')) {
// Find the asset that has this IBC hash as its base
const asset = allAssets.find(asset => asset.base === denom);
if (asset?.traces?.[0]?.counterparty?.base_denom) {
// Return the original denom from the counterparty chain
return {
...asset,
base: asset.traces[0].counterparty.base_denom,
};
}
}
// Return original asset if not an IBC hash
return allAssets.find(asset => asset.base === denom);
};
export const denomToAsset = (chainName: string, denom: string) => {
if (!denom) {
return undefined;
}
const allAssets = getAllAssets(chainName);
// Only handle IBC hashes
if (denom.startsWith('ibc/')) {
if (denom.length < 5) { // "ibc/" + at least 1 char
return undefined;
}
// Find the asset that has this IBC hash as its base
const asset = allAssets.find(asset => asset.base === denom);
if (asset?.traces?.[0]?.counterparty?.base_denom) {
// Return the original denom from the counterparty chain
return {
...asset,
base: asset.traces[0].counterparty.base_denom,
};
}
}
// Return original asset if not an IBC hash
return allAssets.find(asset => asset.base === denom);
};

Comment on lines +51 to +57
const connect = async () => {
await Promise.all(chainStates.map(chain => chain.connect()));
};

const openView = () => {
chainStates[0]?.openView();
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for chain connection.

The connect function should handle potential connection failures.

 const connect = async () => {
-  await Promise.all(chainStates.map(chain => chain.connect()));
+  try {
+    await Promise.all(chainStates.map(chain => chain.connect()));
+  } catch (error) {
+    console.error('Failed to connect to chains:', error);
+    throw new Error('Failed to connect to one or more chains');
+  }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const connect = async () => {
await Promise.all(chainStates.map(chain => chain.connect()));
};
const openView = () => {
chainStates[0]?.openView();
};
const connect = async () => {
try {
await Promise.all(chainStates.map(chain => chain.connect()));
} catch (error) {
console.error('Failed to connect to chains:', error);
throw new Error('Failed to connect to one or more chains');
}
};
const openView = () => {
chainStates[0]?.openView();
};

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
components/wallet.tsx (1)

222-224: Update IconWallet and WalletNotConnected components for multi-chain support.

These components still use the single-chain approach (useChain) while WalletSection has been updated to support multiple chains. This inconsistency could lead to maintenance issues and confusion.

Consider updating these components to use the same multi-chain approach as WalletSection.

Also applies to: 333-334

🧹 Nitpick comments (6)
components/wallet.tsx (1)

40-40: Extract chain configuration to a constant or configuration file.

Consider moving the chain array to a configuration constant or file for better maintainability and reusability.

-  const chains = useChains([env.chain, env.osmosisChain, env.axelarChain]);
+  const SUPPORTED_CHAINS = [env.chain, env.osmosisChain, env.axelarChain] as const;
+  const chains = useChains(SUPPORTED_CHAINS);
components/bank/forms/__tests__/ibcSendForm.test.tsx (4)

20-35: Move chain configuration to a separate mock file.

The chain configuration data should be moved to a dedicated mock file (e.g., @/tests/mockChains.ts) to improve maintainability and reusability across test files.


24-24: Update chain icons to use distinct values.

Both Manifest and Osmosis chains are using the same icon URL. Consider using distinct icons to better reflect the actual implementation.

-      icon: 'https://osmosis.zone/assets/icons/osmo-logo-icon.svg',
+      icon: 'https://manifest.zone/assets/icons/manifest-logo-icon.svg',

Also applies to: 31-31


90-92: Improve debug logging in CI.

Consider using a more structured debug output that includes the test name and expectations:

-      console.log('Container HTML:', container.innerHTML);
+      console.log(`
+        Test: renders form with correct details
+        Expected elements:
+        - IBC send form
+        Actual HTML:
+        ${container.innerHTML}
+      `);

172-218: Refactor duplicate chain selection logic.

The chain selection logic is duplicated between handles chain selection correctly and prevents selecting same chain for source and destination tests. Consider extracting this into a helper function:

const selectFromChain = async (chainName: string) => {
  const fromChainSelector = screen.getByLabelText('from-chain-selector');
  fireEvent.click(fromChainSelector);

  const options = screen.getAllByRole('option', { name: chainName });
  const enabledOption = options.find(
    option => !option.className.includes('opacity-50')
  );
  fireEvent.click(enabledOption!);
};
tests/render.tsx (1)

18-22: Consider documenting the chain order significance.

The configuration looks good and supports multiple chains as intended. Consider adding a comment to explain if the order of chains in the array is significant (e.g., if the first chain is considered the default).

 const defaultOptions = {
+  // Order matters: First chain is considered the default
   chains: [manifestChain, osmosisChain, axelarChain],
   assetLists: [manifestAssets, osmosisAssets, axelarAssets],
   wallets: [],
 };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b61039 and ff6887c.

📒 Files selected for processing (4)
  • components/bank/forms/__tests__/ibcSendForm.test.tsx (3 hunks)
  • components/wallet.tsx (2 hunks)
  • package.json (3 hunks)
  • tests/render.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🔇 Additional comments (7)
components/wallet.tsx (3)

53-55: Add error handling for chain connection.

The connect function should handle potential connection failures.


57-59: Clarify the behavior of openView function.

The function only opens the view for the first chain, which might be confusing for users. Consider either:

  1. Opening views for all chains
  2. Adding a parameter to specify which chain's view to open
  3. Adding a comment explaining why only the first chain's view is opened

74-84: Review the strategy for selecting user information.

The current implementation takes the first available username/address from any chain. This might lead to inconsistencies if different chains have different user information. Consider:

  1. Using the primary chain's information consistently
  2. Showing information from all chains
  3. Adding a comment explaining the selection strategy
components/bank/forms/__tests__/ibcSendForm.test.tsx (2)

78-81: LGTM! Good test hygiene.

Adding jest.clearAllMocks() to the cleanup is a good practice to ensure proper test isolation.


83-96: Document why the test is skipped.

The test is marked with test.skip without explanation. Either:

  • Add a comment explaining why it's skipped and create a tracking issue, or
  • Fix and enable the test if it's no longer needed to be skipped
tests/render.tsx (2)

6-16: LGTM! Verify testnet package versions.

The imports are well-organized and align with the PR objectives for cross-chain support.

Let's verify we're using the latest versions of the testnet packages:

✅ Verification successful

🌐 Web query:

What is the latest version of chain-registry npm package?

Length of output: 2232


Testnet Package Versions Verified

The test file's imports from chain-registry/testnet/... are correctly aligned with the latest release. The web query confirms that the chain-registry package is at version 1.69.114, so the usage in tests/render.tsx is up-to-date.


24-37: Consider adding tests for SkipProvider integration.

The updated provider hierarchy looks good. Since SkipProvider is a new addition, ensure it's properly tested in the context of this render utility.

Let's check if there are tests for the SkipProvider:

Comment on lines 172 to 218
test('handles chain selection correctly', async () => {
renderWithProps();

const fromChainSelector = screen.getByLabelText('from-chain-selector');
fireEvent.click(fromChainSelector);

const manifestOptions = screen.getAllByRole('option', { name: 'Manifest' });
const enabledManifestOption = manifestOptions.find(
option => !option.className.includes('opacity-50')
);
fireEvent.click(enabledManifestOption!);

expect(screen.getByLabelText('from-chain-selector')).toHaveTextContent('Manifest');

const toChainSelector = screen.getByLabelText('to-chain-selector');
fireEvent.click(toChainSelector);

const osmosisOption = screen.getAllByRole('option', { name: 'Osmosis' });
fireEvent.click(osmosisOption[0]);

expect(screen.getByLabelText('to-chain-selector')).toHaveTextContent('Osmosis');
});

test('prevents selecting same chain for source and destination', async () => {
renderWithProps();

const fromChainSelector = screen.getByLabelText('from-chain-selector');
fireEvent.click(fromChainSelector);

const manifestOptions = screen.getAllByRole('option', { name: 'Manifest' });
const enabledManifestOption = manifestOptions.find(
option => !option.className.includes('opacity-50')
);
fireEvent.click(enabledManifestOption!);

// Verify Manifest is not available in destination chain options
const toChainSelector = screen.getByLabelText('to-chain-selector');
fireEvent.click(toChainSelector);

// Check that there's only one active Manifest option (the source)
const activeManifestOptions = screen.getAllByRole('option', { name: 'Manifest' });
const activeManifestOption = activeManifestOptions.find(
option => !option.className.includes('opacity-50')
);
expect(activeManifestOption).toBeDefined();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add test cases for error scenarios.

The test suite is missing coverage for important error scenarios:

  • Invalid addresses
  • Insufficient balances
  • Network errors during chain selection
  • Failed transactions

Consider adding these test cases to ensure robust error handling.

Would you like me to help generate the missing test cases?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
components/bank/forms/__tests__/ibcSendForm.test.tsx (3)

20-35: Move chain configuration to a separate mock file.

Consider extracting the defaultChains configuration to a separate mock file (e.g., @/tests/mockChains.ts) to improve maintainability and reusability across test files.


24-24: Update chain icons to use distinct values.

Both Manifest and Osmosis chains are using the same icon URL. Consider using distinct mock icons for better test clarity.

-      icon: 'https://osmosis.zone/assets/icons/osmo-logo-icon.svg',
+      icon: 'https://manifest.example.com/assets/icons/manifest-logo-icon.svg',

Also applies to: 31-31


207-207: Use optional chaining for safer property access.

Use optional chaining to safely access the textContent property.

-      return link && link.textContent?.includes('Manifest');
+      return link?.textContent?.includes('Manifest');
🧰 Tools
🪛 Biome (1.9.4)

[error] 207-207: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff6887c and 00f9268.

📒 Files selected for processing (1)
  • components/bank/forms/__tests__/ibcSendForm.test.tsx (4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
components/bank/forms/__tests__/ibcSendForm.test.tsx

[error] 207-207: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 GitHub Actions: Test and Coverage
components/bank/forms/__tests__/ibcSendForm.test.tsx

[error] 1-1: Ignored nodes: comments, script, style

🔇 Additional comments (1)
components/bank/forms/__tests__/ibcSendForm.test.tsx (1)

73-213: Add test coverage for error scenarios.

The test suite is missing coverage for important error scenarios:

  • Invalid addresses
  • Insufficient balances
  • Network errors during chain selection
  • Failed transactions

Would you like me to help generate the missing test cases?

🧰 Tools
🪛 Biome (1.9.4)

[error] 207-207: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
components/bank/components/__tests__/tokenList.test.tsx (1)

1-168:

🧩 Analysis chain

Add test coverage for new Osmosis-related functionality.

Based on the AI summary, the TokenList component has been updated with several new Osmosis-related props (osmosisBalances, isOsmosisBalancesLoading, refetchOsmosisBalances, etc.), but the test suite doesn't cover these new features. Please add test cases to verify:

  1. Rendering of Osmosis balances
  2. Loading states for Osmosis data
  3. Refetch functionality for Osmosis balances
  4. Integration with the new chains prop

Let me verify the new props in the TokenList component:


🏁 Script executed:

#!/bin/bash
# Description: Verify the new Osmosis-related props in TokenList component

# Search for the TokenList component definition
ast-grep --pattern 'interface TokenListProps {
  $$$
}'

Length of output: 1307


Missing test coverage for new Osmosis functionality

The new Osmosis-related props (such as osmosisBalances, isOsmosisBalancesLoading, refetchOsmosisBalances, resolveOsmosisRefetch, and chains) have been added to the TokenList component. However, the current test suite in components/bank/components/__tests__/tokenList.test.tsx does not include any test cases that verify:

  • Correct rendering of Osmosis balances when provided.
  • Display of loading states when isOsmosisBalancesLoading is true.
  • Proper functionality of the refetchOsmosisBalances (and optionally resolveOsmosisRefetch) callback.
  • Integration of the new chains prop.

Actionable Items:

  • Add a test case to render the TokenList with non-empty osmosisBalances and verify the correct presentation.
  • Create a test to ensure that the loading skeleton (or equivalent indicator) appears when isOsmosisBalancesLoading is true.
  • Implement a test that simulates a trigger for refetchOsmosisBalances and potentially resolveOsmosisRefetch, confirming they are called.
  • Include a test case that verifies proper handling/integration of the chains prop.
🧹 Nitpick comments (4)
components/bank/forms/__tests__/sendForm.test.tsx (1)

81-95: Improve test readability and reliability.

The current test implementation could be more maintainable. Consider:

  1. Breaking down the test into smaller, focused test cases
  2. Using test helpers for common setup operations
  3. Following the Arrange-Act-Assert pattern more explicitly

Here's a suggested refactor:

-  test('send button is enabled when inputs are valid', () => {
+  test('enables send button when all inputs are valid', () => {
+    // Arrange
     renderWithProps();
+    const recipientInput = screen.getByPlaceholderText('Enter address');
+    const amountInput = screen.getByPlaceholderText('0.00');
+    const tokenSelector = screen.getByLabelText('token-selector');
+
+    // Act
+    fireEvent.change(recipientInput, {
+      target: { value: 'manifest1recipient' },
+    });
+    fireEvent.change(amountInput, {
+      target: { value: '100' },
+    });
-    fireEvent.change(screen.getByPlaceholderText('Enter address'), {
-      target: { value: 'manifest1recipient' },
-    });
-    fireEvent.change(screen.getByPlaceholderText('0.00'), {
-      target: { value: '100' },
-    });
-    const tokenSelector = screen.getByLabelText('token-selector');
     fireEvent.click(tokenSelector);
-    const dropdownItems = screen.getAllByText('TOKEN 1');
-    fireEvent.click(dropdownItems[dropdownItems.length - 1]);
+    const tokenOption = screen.getAllByText('TOKEN 1')[0];
+    fireEvent.click(tokenOption);
+
+    // Assert
     const sendButton = screen.getByRole('button', { name: 'send-btn' });
     expect(sendButton).not.toBeDisabled();
   });
components/bank/forms/__tests__/ibcSendForm.test.tsx (3)

1-78: LGTM! Consider extracting test data to a separate file.

The mock setup and helper function are well-structured. The defaultChains array and defaultProps object provide comprehensive test data.

Consider extracting the defaultChains array to a separate test data file (e.g., __mocks__/chains.ts) to improve reusability across test files and maintain consistency.


168-189: Enhance chain selection test coverage.

While the test verifies basic chain selection functionality, consider adding assertions for:

  • Callback functions (setSelectedFromChain, setSelectedToChain)
  • Chain address updates
 test('handles chain selection correctly', async () => {
-  renderWithProps();
+  const setSelectedFromChain = jest.fn();
+  const setSelectedToChain = jest.fn();
+  renderWithProps({ setSelectedFromChain, setSelectedToChain });

   const fromChainSelector = screen.getByLabelText('from-chain-selector');
   fireEvent.click(fromChainSelector);
   // ... existing code ...
+  expect(setSelectedFromChain).toHaveBeenCalledWith(expect.objectContaining({
+    name: 'Manifest'
+  }));
+  expect(setSelectedToChain).toHaveBeenCalledWith(expect.objectContaining({
+    name: 'Osmosis'
+  }));
 });

191-236: LGTM! Consider these minor improvements.

The test effectively verifies the prevention of same chain selection. Two suggestions for improvement:

  1. Use optional chaining for safer property access
  2. Add assertions for error messages or tooltips shown to users when attempting to select the same chain
-return link && link.textContent?.includes('Manifest');
+return link?.textContent?.includes('Manifest');
🧰 Tools
🪛 Biome (1.9.4)

[error] 229-229: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00f9268 and 1ed0bc4.

📒 Files selected for processing (5)
  • .env.test (1 hunks)
  • components/bank/components/__tests__/sendBox.test.tsx (3 hunks)
  • components/bank/components/__tests__/tokenList.test.tsx (1 hunks)
  • components/bank/forms/__tests__/ibcSendForm.test.tsx (4 hunks)
  • components/bank/forms/__tests__/sendForm.test.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/bank/components/tests/sendBox.test.tsx
  • .env.test
🧰 Additional context used
🪛 Biome (1.9.4)
components/bank/forms/__tests__/ibcSendForm.test.tsx

[error] 229-229: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (5)
components/bank/forms/__tests__/sendForm.test.tsx (2)

38-41: LGTM! Enhanced test cleanup implementation.

The addition of mock.restore() after cleanup() improves test isolation by ensuring both DOM elements and mocked modules are properly reset between tests.


24-31: Add test coverage for IBC transfer functionality.

While the test props include Osmosis chain configuration, there are no test cases verifying IBC transfer behavior. Consider adding tests for:

  • IBC transfer form validation
  • Chain selection handling
  • Cross-chain address validation
  • IBC transfer specific error cases

Would you like me to provide example test cases for these scenarios?

components/bank/components/__tests__/tokenList.test.tsx (1)

59-62: LGTM! Good practice adding mock cleanup.

The addition of mock.restore() in the afterEach block is a good practice as it ensures proper cleanup of mocked modules between tests, preventing potential test interference.

components/bank/forms/__tests__/ibcSendForm.test.tsx (2)

80-92: LGTM! Test setup and basic rendering test are well-structured.

The cleanup is thorough with mock.restore(), and the basic rendering test verifies essential form elements.


94-166: Add test cases for error scenarios.

The test suite is missing coverage for important error scenarios:

  • Invalid addresses
  • Insufficient balances
  • Network errors during chain selection
  • Failed transactions

Would you like me to help generate the missing test cases?

Copy link
Contributor

@fmorency fmorency left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Please provide an up-to-date .env file I can use to test this PR.

@@ -31,6 +31,10 @@ NEXT_PUBLIC_RPC_URL=
NEXT_PUBLIC_API_URL=
NEXT_PUBLIC_EXPLORER_URL=
NEXT_PUBLIC_INDEXER_URL=
NEXT_PUBLIC_OSMOSIS_CHAIN_ID=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add missing env. var.

@@ -45,6 +49,10 @@ where
- `NEXT_PUBLIC_API_URL` is the chain API URL
- `NEXT_PUBLIC_EXPLORER_URL` is the block explorer URL
- `NEXT_PUBLIC_INDEXER_URL` is the YACI indexer URL
- `NEXT_PUBLIC_OSMOSIS_CHAIN_ID` is the osmosis chain ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add missing env. var.

{
id: 'manifest',
name: 'Manifest',
icon: 'https://osmosis.zone/assets/icons/osmo-logo-icon.svg',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong icon?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
components/bank/forms/ibcSendForm.tsx (4)

87-95: 🛠️ Refactor suggestion

Extract duplicated token display name formatting logic.

The token display name formatting logic is duplicated in multiple places (lines 682, 730-732, 768-770). Extract this into a reusable utility function to improve maintainability.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 89-89: components/bank/forms/ibcSendForm.tsx#L89
Added line #L89 was not covered by tests


[warning] 92-92: components/bank/forms/ibcSendForm.tsx#L92
Added line #L92 was not covered by tests


119-123: ⚠️ Potential issue

Add missing dependencies to useEffect.

The useEffect hook's dependency array is missing ibcChains. This could lead to stale closures if ibcChains changes.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 121-121: components/bank/forms/ibcSendForm.tsx#L121
Added line #L121 was not covered by tests


218-262: ⚠️ Potential issue

Add error handling for Skip protocol integration.

The Skip protocol integration lacks proper error handling and validation of the route response.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 216-262: components/bank/forms/ibcSendForm.tsx#L216-L262
Added lines #L216 - L262 were not covered by tests


866-868: 🛠️ Refactor suggestion

Remove unimplemented function.

The useSkip function is not implemented and appears to be unused. Consider removing it.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 866-866: components/bank/forms/ibcSendForm.tsx#L866
Added line #L866 was not covered by tests

🧹 Nitpick comments (2)
components/bank/forms/ibcSendForm.tsx (2)

297-348: Remove commented code.

Large blocks of commented code should be removed if they are no longer needed. If they are kept for reference, add a comment explaining why.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 296-348: components/bank/forms/ibcSendForm.tsx#L296-L348
Added lines #L296 - L348 were not covered by tests


457-483: Extract duplicated chain selection event handlers.

The chain selection event handlers for keyboard and click events are duplicated. Extract these into a reusable function to reduce code duplication and improve maintainability.

Apply this diff to extract the event handlers:

+const handleChainSelection = (
+  chain: IbcChain,
+  selectedChain: IbcChain,
+  setSelectedChain: (chain: IbcChain) => void,
+  event: React.MouseEvent | React.KeyboardEvent
+) => {
+  if (chain.id === selectedChain.id) {
+    return;
+  }
+  setSelectedChain(chain);
+  // Get the dropdown element and remove focus
+  const dropdown = (event.target as HTMLElement).closest('.dropdown');
+  if (dropdown) {
+    (dropdown as HTMLElement).removeAttribute('open');
+    (dropdown.querySelector('label') as HTMLElement)?.focus();
+    (dropdown.querySelector('label') as HTMLElement)?.blur();
+  }
+};

-onClick={e => {
-  if (chain.id === selectedFromChain.id) {
-    return;
-  }
-  setSelectedFromChain(chain);
-  // Get the dropdown element and remove focus
-  const dropdown = (e.target as HTMLElement).closest('.dropdown');
-  if (dropdown) {
-    (dropdown as HTMLElement).removeAttribute('open');
-    (dropdown.querySelector('label') as HTMLElement)?.focus();
-    (dropdown.querySelector('label') as HTMLElement)?.blur();
-  }
-}}
+onClick={e => handleChainSelection(chain, selectedFromChain, setSelectedFromChain, e)}

-onKeyDown={e => {
-  if (e.key === 'Enter' || e.key === ' ') {
-    e.preventDefault();
-    if (chain.id === selectedFromChain.id) {
-      return;
-    }
-    setSelectedFromChain(chain);
-    // Get the dropdown element and remove focus
-    const dropdown = (e.target as HTMLElement).closest('.dropdown');
-    if (dropdown) {
-      (dropdown as HTMLElement).removeAttribute('open');
-      (dropdown.querySelector('label') as HTMLElement)?.focus();
-      (dropdown.querySelector('label') as HTMLElement)?.blur();
-    }
-  }
-}}
+onKeyDown={e => {
+  if (e.key === 'Enter' || e.key === ' ') {
+    e.preventDefault();
+    handleChainSelection(chain, selectedFromChain, setSelectedFromChain, e);
+  }
+}}

Also applies to: 600-613

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 457-467: components/bank/forms/ibcSendForm.tsx#L457-L467
Added lines #L457 - L467 were not covered by tests


[warning] 470-483: components/bank/forms/ibcSendForm.tsx#L470-L483
Added lines #L470 - L483 were not covered by tests

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30cb4a8 and ec9481d.

📒 Files selected for processing (1)
  • components/bank/forms/ibcSendForm.tsx (10 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
components/bank/forms/ibcSendForm.tsx

[warning] 89-89: components/bank/forms/ibcSendForm.tsx#L89
Added line #L89 was not covered by tests


[warning] 92-92: components/bank/forms/ibcSendForm.tsx#L92
Added line #L92 was not covered by tests


[warning] 109-110: components/bank/forms/ibcSendForm.tsx#L109-L110
Added lines #L109 - L110 were not covered by tests


[warning] 121-121: components/bank/forms/ibcSendForm.tsx#L121
Added line #L121 was not covered by tests


[warning] 176-177: components/bank/forms/ibcSendForm.tsx#L176-L177
Added lines #L176 - L177 were not covered by tests


[warning] 179-182: components/bank/forms/ibcSendForm.tsx#L179-L182
Added lines #L179 - L182 were not covered by tests


[warning] 185-185: components/bank/forms/ibcSendForm.tsx#L185
Added line #L185 was not covered by tests


[warning] 206-206: components/bank/forms/ibcSendForm.tsx#L206
Added line #L206 was not covered by tests


[warning] 216-262: components/bank/forms/ibcSendForm.tsx#L216-L262
Added lines #L216 - L262 were not covered by tests


[warning] 265-267: components/bank/forms/ibcSendForm.tsx#L265-L267
Added lines #L265 - L267 were not covered by tests


[warning] 269-293: components/bank/forms/ibcSendForm.tsx#L269-L293
Added lines #L269 - L293 were not covered by tests


[warning] 296-348: components/bank/forms/ibcSendForm.tsx#L296-L348
Added lines #L296 - L348 were not covered by tests


[warning] 381-382: components/bank/forms/ibcSendForm.tsx#L381-L382
Added lines #L381 - L382 were not covered by tests


[warning] 385-387: components/bank/forms/ibcSendForm.tsx#L385-L387
Added lines #L385 - L387 were not covered by tests


[warning] 389-401: components/bank/forms/ibcSendForm.tsx#L389-L401
Added lines #L389 - L401 were not covered by tests


[warning] 457-467: components/bank/forms/ibcSendForm.tsx#L457-L467
Added lines #L457 - L467 were not covered by tests


[warning] 470-483: components/bank/forms/ibcSendForm.tsx#L470-L483
Added lines #L470 - L483 were not covered by tests


[warning] 516-519: components/bank/forms/ibcSendForm.tsx#L516-L519
Added lines #L516 - L519 were not covered by tests


[warning] 587-591: components/bank/forms/ibcSendForm.tsx#L587-L591
Added lines #L587 - L591 were not covered by tests


[warning] 600-613: components/bank/forms/ibcSendForm.tsx#L600-L613
Added lines #L600 - L613 were not covered by tests


[warning] 866-866: components/bank/forms/ibcSendForm.tsx#L866
Added line #L866 was not covered by tests

🔇 Additional comments (2)
components/bank/forms/ibcSendForm.tsx (2)

169-185: Improve fee buffer configuration and documentation.

The fee warning logic uses a hardcoded buffer value and only applies to 'umfx' tokens.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 176-177: components/bank/forms/ibcSendForm.tsx#L176-L177
Added lines #L176 - L177 were not covered by tests


[warning] 179-182: components/bank/forms/ibcSendForm.tsx#L179-L182
Added lines #L179 - L182 were not covered by tests


[warning] 185-185: components/bank/forms/ibcSendForm.tsx#L185
Added line #L185 was not covered by tests


216-293: Add test coverage for Skip protocol integration.

The Skip protocol integration code lacks test coverage. Add unit tests to verify the functionality and error handling.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 216-262: components/bank/forms/ibcSendForm.tsx#L216-L262
Added lines #L216 - L262 were not covered by tests


[warning] 265-267: components/bank/forms/ibcSendForm.tsx#L265-L267
Added lines #L265 - L267 were not covered by tests


[warning] 269-293: components/bank/forms/ibcSendForm.tsx#L269-L293
Added lines #L269 - L293 were not covered by tests

Copy link
Contributor

@fmorency fmorency left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to send tokens over to Osmosis testnet because the SkipGo client has a known issue. This should get resolved soon.

I will merge this PR and we can fix in other, NON OMBIBUS, PRs.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
components/bank/forms/ibcSendForm.tsx (2)

216-262: ⚠️ Potential issue

Add error handling for Skip protocol integration.

The Skip protocol integration lacks proper error handling and validation of the route response.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 216-262: components/bank/forms/ibcSendForm.tsx#L216-L262
Added lines #L216 - L262 were not covered by tests


119-123: ⚠️ Potential issue

Add missing dependencies to useEffect.

The useEffect hook's dependency array is missing ibcChains.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 121-121: components/bank/forms/ibcSendForm.tsx#L121
Added line #L121 was not covered by tests

🧹 Nitpick comments (1)
components/bank/components/tokenList.tsx (1)

20-24: Add default values for optional props.

The new optional props for Osmosis integration should have default values in the destructuring to prevent potential undefined errors.

-  osmosisBalances?: CombinedBalanceInfo[] | undefined;
-  isOsmosisBalancesLoading?: boolean;
-  refetchOsmosisBalances?: () => void;
-  resolveOsmosisRefetch?: () => void;
+  osmosisBalances?: CombinedBalanceInfo[] | undefined = [];
+  isOsmosisBalancesLoading?: boolean = false;
+  refetchOsmosisBalances?: () => void = () => {};
+  resolveOsmosisRefetch?: () => void = () => {};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec9481d and 3387cf8.

⛔ Files ignored due to path filters (1)
  • bun.lockb is excluded by !**/bun.lockb
📒 Files selected for processing (3)
  • components/bank/components/tokenList.tsx (6 hunks)
  • components/bank/forms/ibcSendForm.tsx (8 hunks)
  • components/groups/components/groupControls.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/groups/components/groupControls.tsx
🧰 Additional context used
🪛 GitHub Check: codecov/patch
components/bank/forms/ibcSendForm.tsx

[warning] 87-93: components/bank/forms/ibcSendForm.tsx#L87-L93
Added lines #L87 - L93 were not covered by tests


[warning] 109-110: components/bank/forms/ibcSendForm.tsx#L109-L110
Added lines #L109 - L110 were not covered by tests


[warning] 121-121: components/bank/forms/ibcSendForm.tsx#L121
Added line #L121 was not covered by tests


[warning] 176-177: components/bank/forms/ibcSendForm.tsx#L176-L177
Added lines #L176 - L177 were not covered by tests


[warning] 179-182: components/bank/forms/ibcSendForm.tsx#L179-L182
Added lines #L179 - L182 were not covered by tests


[warning] 185-185: components/bank/forms/ibcSendForm.tsx#L185
Added line #L185 was not covered by tests


[warning] 206-206: components/bank/forms/ibcSendForm.tsx#L206
Added line #L206 was not covered by tests


[warning] 216-262: components/bank/forms/ibcSendForm.tsx#L216-L262
Added lines #L216 - L262 were not covered by tests


[warning] 265-267: components/bank/forms/ibcSendForm.tsx#L265-L267
Added lines #L265 - L267 were not covered by tests


[warning] 269-293: components/bank/forms/ibcSendForm.tsx#L269-L293
Added lines #L269 - L293 were not covered by tests


[warning] 296-348: components/bank/forms/ibcSendForm.tsx#L296-L348
Added lines #L296 - L348 were not covered by tests


[warning] 381-382: components/bank/forms/ibcSendForm.tsx#L381-L382
Added lines #L381 - L382 were not covered by tests


[warning] 385-387: components/bank/forms/ibcSendForm.tsx#L385-L387
Added lines #L385 - L387 were not covered by tests


[warning] 389-401: components/bank/forms/ibcSendForm.tsx#L389-L401
Added lines #L389 - L401 were not covered by tests


[warning] 457-467: components/bank/forms/ibcSendForm.tsx#L457-L467
Added lines #L457 - L467 were not covered by tests


[warning] 470-483: components/bank/forms/ibcSendForm.tsx#L470-L483
Added lines #L470 - L483 were not covered by tests


[warning] 516-519: components/bank/forms/ibcSendForm.tsx#L516-L519
Added lines #L516 - L519 were not covered by tests


[warning] 587-591: components/bank/forms/ibcSendForm.tsx#L587-L591
Added lines #L587 - L591 were not covered by tests


[warning] 600-613: components/bank/forms/ibcSendForm.tsx#L600-L613
Added lines #L600 - L613 were not covered by tests


[warning] 848-848: components/bank/forms/ibcSendForm.tsx#L848
Added line #L848 was not covered by tests

🔇 Additional comments (6)
components/bank/components/tokenList.tsx (2)

114-114: LGTM! Improved modal state management.

The change from using document.getElementById to React state for modal management is a good improvement in line with React best practices.


240-244: LGTM! Proper prop forwarding with defaults.

The SendModal component properly forwards all required props with appropriate default values.

components/bank/forms/ibcSendForm.tsx (4)

87-95: Extract token display name formatting to a shared utility.

The token display name formatting logic is duplicated in multiple places. Extract it to a utility function for reuse.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 87-93: components/bank/forms/ibcSendForm.tsx#L87-L93
Added lines #L87 - L93 were not covered by tests


848-850: Remove unimplemented function.

The useSkip function is not implemented and appears to be unused.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 848-848: components/bank/forms/ibcSendForm.tsx#L848
Added line #L848 was not covered by tests


176-186: Improve fee buffer configuration and documentation.

The fee warning logic uses hardcoded values and only applies to 'umfx' tokens.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 176-177: components/bank/forms/ibcSendForm.tsx#L176-L177
Added lines #L176 - L177 were not covered by tests


[warning] 179-182: components/bank/forms/ibcSendForm.tsx#L179-L182
Added lines #L179 - L182 were not covered by tests


[warning] 185-185: components/bank/forms/ibcSendForm.tsx#L185
Added line #L185 was not covered by tests


87-850: Add test coverage for critical paths.

Several critical code paths lack test coverage, including:

  • Token display name formatting
  • Skip protocol integration
  • Chain selection logic
  • Fee warning logic

Consider adding tests for these scenarios to improve code reliability.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 87-93: components/bank/forms/ibcSendForm.tsx#L87-L93
Added lines #L87 - L93 were not covered by tests


[warning] 109-110: components/bank/forms/ibcSendForm.tsx#L109-L110
Added lines #L109 - L110 were not covered by tests


[warning] 121-121: components/bank/forms/ibcSendForm.tsx#L121
Added line #L121 was not covered by tests


[warning] 176-177: components/bank/forms/ibcSendForm.tsx#L176-L177
Added lines #L176 - L177 were not covered by tests


[warning] 179-182: components/bank/forms/ibcSendForm.tsx#L179-L182
Added lines #L179 - L182 were not covered by tests


[warning] 185-185: components/bank/forms/ibcSendForm.tsx#L185
Added line #L185 was not covered by tests


[warning] 206-206: components/bank/forms/ibcSendForm.tsx#L206
Added line #L206 was not covered by tests


[warning] 216-262: components/bank/forms/ibcSendForm.tsx#L216-L262
Added lines #L216 - L262 were not covered by tests


[warning] 265-267: components/bank/forms/ibcSendForm.tsx#L265-L267
Added lines #L265 - L267 were not covered by tests


[warning] 269-293: components/bank/forms/ibcSendForm.tsx#L269-L293
Added lines #L269 - L293 were not covered by tests


[warning] 296-348: components/bank/forms/ibcSendForm.tsx#L296-L348
Added lines #L296 - L348 were not covered by tests


[warning] 381-382: components/bank/forms/ibcSendForm.tsx#L381-L382
Added lines #L381 - L382 were not covered by tests


[warning] 385-387: components/bank/forms/ibcSendForm.tsx#L385-L387
Added lines #L385 - L387 were not covered by tests


[warning] 389-401: components/bank/forms/ibcSendForm.tsx#L389-L401
Added lines #L389 - L401 were not covered by tests


[warning] 457-467: components/bank/forms/ibcSendForm.tsx#L457-L467
Added lines #L457 - L467 were not covered by tests


[warning] 470-483: components/bank/forms/ibcSendForm.tsx#L470-L483
Added lines #L470 - L483 were not covered by tests


[warning] 516-519: components/bank/forms/ibcSendForm.tsx#L516-L519
Added lines #L516 - L519 were not covered by tests


[warning] 587-591: components/bank/forms/ibcSendForm.tsx#L587-L591
Added lines #L587 - L591 were not covered by tests


[warning] 600-613: components/bank/forms/ibcSendForm.tsx#L600-L613
Added lines #L600 - L613 were not covered by tests


[warning] 848-848: components/bank/forms/ibcSendForm.tsx#L848
Added line #L848 was not covered by tests

@fmorency fmorency merged commit 64be274 into main Feb 6, 2025
7 of 8 checks passed
@fmorency fmorency deleted the chalabi/cross-chain-x branch February 6, 2025 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants