Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.

feat: start setting up UI for 1Click#557

Merged
defuse-es merged 4 commits intodefuse-protocol:betafrom
defuse-es:1Click
Jul 25, 2025
Merged

feat: start setting up UI for 1Click#557
defuse-es merged 4 commits intodefuse-protocol:betafrom
defuse-es:1Click

Conversation

@defuse-es
Copy link
Contributor

@defuse-es defuse-es commented Jul 24, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive 1-click token swap widget with a user-friendly interface, including token selection, swap form, price impact, and rate information.
    • Added a modal for selecting tokens with search and filtering capabilities.
    • Implemented context providers and state machines for robust swap UI logic and state management.
    • Provided support for Nix-based reproducible development environments.
  • Enhancements

    • Asset lists can now optionally display blockchain chain icons and names.
    • Improved positioning of icons and selection indicators in asset lists.
  • Bug Fixes

    • None noted.
  • Chores

    • Updated development environment configuration files and centralized blockchain icon management.

@coderabbitai
Copy link

coderabbitai bot commented Jul 24, 2025

Walkthrough

This update introduces a comprehensive 1-click swap feature, adding new components, state machines, hooks, and types to support a robust token swap UI. It also includes Nix-based development environment configuration, updates to asset and modal components, and centralizes blockchain icon management. Minor style and ignore file adjustments are also present.

Changes

File(s) Change Summary
.gitignore, example.envrc, flake.nix Added Nix flake configuration, example environment file, and updated .gitignore for Nix support.
src/components/Asset/AssetList.tsx, src/components/Asset/AssetComboIcon/index.tsx Enhanced asset list to support optional chain icon/name display; adjusted icon positioning.
src/constants/blockchains.tsx Centralized blockchain icon paths in a new chainIcons constant and refactored icon usage.
src/components/Modal/ModalContainer.tsx, src/stores/modalStore.ts Added new modal type for token selection and updated modal container to handle it.
src/components/Modal/ModalSelectToken.tsx Introduced a new modal component for selecting tokens, with search, filtering, and selection logic.
src/features/machines/swapUIMachine1Click.ts Added a new XState state machine to manage the swap UI logic, handling form state, quoting, submission, and side effects.
src/features/1Click/components/SwapForm.tsx, src/features/1Click/components/SwapFormProvider.tsx Added swap form and provider components, integrating form management and swap logic with state machine.
src/features/1Click/components/SwapPriceImpact.tsx, src/features/1Click/components/SwapRateInfo.tsx Introduced components for displaying swap price impact and rate/slippage information.
src/features/1Click/components/SwapSubmitter.tsx, src/features/1Click/components/SwapSubmitter.tsx Added context and provider for handling swap submission logic.
src/features/1Click/components/SwapUIMachineFormSyncProvider.tsx, src/features/1Click/components/SwapUIMachineProvider.tsx Added providers to synchronize form state with the swap UI state machine and initialize machine context.
src/features/1Click/components/SwapWidget.tsx Introduced the main swap widget component, composing all swap-related providers and UI.
src/features/1Click/hooks/useSwapRateData.ts Added a hook to extract swap rate and slippage data from the swap UI state machine.
src/types/swap.ts Added a type alias for 1-click swap widget props.
src/index.ts Exported the new swap widget under the alias SwapWidget1Click.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SwapWidget
    participant SwapForm
    participant ModalSelectToken
    participant SwapUIMachine
    participant SwapSubmitter

    User->>SwapWidget: Opens SwapWidget
    SwapWidget->>SwapForm: Renders swap form
    User->>SwapForm: Enters amount/selects tokens
    SwapForm->>ModalSelectToken: Opens token selection modal
    User->>ModalSelectToken: Searches/selects token
    ModalSelectToken->>SwapForm: Returns selected token
    SwapForm->>SwapUIMachine: Updates form state, requests quote
    SwapUIMachine->>SwapForm: Returns quote, price impact, rate info
    User->>SwapForm: Clicks submit
    SwapForm->>SwapSubmitter: Calls onSubmit
    SwapSubmitter->>SwapUIMachine: Submits swap intent
    SwapUIMachine-->>SwapForm: Updates UI with intent status/result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Suggested reviewers

  • cawabunga-bytes
  • jobotics

Poem

A swap so quick, with just one click,
The Widget hops—no code to fix!
Chains and tokens, icons bright,
Nix and Flakes set up just right.
Modal magic, state machine,
Rabbits swap with code so clean!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @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.

Copy link

@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: 15

🧹 Nitpick comments (10)
flake.nix (1)

11-19: Nice dev-shell – consider pinning Yarn version & adding a cacheable NODE_PATH

The shell is functional, but two small improvements can make it more predictable:

  1. Pin Yarn to a specific version (yarn-1_22 or yarn-berry) instead of the default output, which drifts with nixpkgs-unstable.
  2. Export NODE_PATH with shellHook so editors pick up node-modules without extra config.
11         devShells.default = pkgs.mkShell {
12           buildInputs = [
13             pkgs.nodejs_20
14-            (pkgs.yarn.override { nodejs = pkgs.nodejs_20; })
+            (pkgs.yarn-1_22.override { nodejs = pkgs.nodejs_20; })
...
18           ];
19+          shellHook = ''
+            export NODE_PATH=$PWD/node_modules
+          '';
20         };
src/constants/blockchains.tsx (1)

70-259: Inconsistent chainName casing – minor UX polish

NetworkIcon treats chainName === "near" specially (black bg). Passing "XRP Ledger", "Polygon", "TON", etc. creates inconsistent alt texts/casing and may break future casing-based logic. Stick to one convention (all lowercase snake-case recommended) or extend the component to normalise the value.

No functional bug, but a quick find-replace keeps things tidy.

src/types/swap.ts (1)

58-58: Alias is harmless but may be redundant

SwapWidget1ClickProps is a direct alias of SwapWidgetProps. Unless you envision the prop shapes diverging, exporting the original type under two names can confuse IDE auto-import and docs. Consider re-export instead:

export { SwapWidgetProps as SwapWidget1ClickProps }
src/features/swap/components-1Click/SwapRateInfo.tsx (2)

34-34: Move useToggle hook or add proper import.

The useToggle hook is used here but defined later in the file. Consider moving the hook definition above the component or extracting it to a separate utility file for better code organization.


36-36: Address the TODO comment about rate readiness handling.

The TODO suggests uncertainty about where the rate readiness logic should be handled. Consider moving this logic to the useSwapRateData hook or the parent component for better separation of concerns.

Do you want me to suggest a refactor that moves the rate readiness logic to a more appropriate location?

src/components/Asset/AssetList.tsx (1)

76-81: Consider improving readability and adding explanation for the ignore comment.

The biome-ignore comment lacks an explanation. Also, the string concatenation could be cleaner.

-                  {/* biome-ignore lint/nursery/useConsistentCurlyBraces: <explanation> */}
-                  {token.symbol}{" "}
-                  {showChain && isBaseToken(token)
-                    ? token.chainName.toUpperCase()
-                    : ""}
+                  {/* biome-ignore lint/nursery/useConsistentCurlyBraces: Space needed between symbol and chain name */}
+                  {showChain && isBaseToken(token)
+                    ? `${token.symbol} ${token.chainName.toUpperCase()}`
+                    : token.symbol}
src/features/swap/components-1Click/SwapForm.tsx (2)

292-370: Consider refactoring the error message mapping for better maintainability.

The switch statement is quite long and could be simplified by extracting error messages to a constant object.

const ERROR_MESSAGES: Record<string, string | null> = {
  ERR_USER_DIDNT_SIGN: "It seems the message wasn't signed in your wallet. Please try again.",
  ERR_CANNOT_VERIFY_SIGNATURE: "We couldn't verify your signature, please try again with another wallet.",
  ERR_SIGNED_DIFFERENT_ACCOUNT: "The message was signed with a different wallet. Please try again.",
  ERR_PUBKEY_ADDING_DECLINED: null,
  ERR_PUBKEY_CHECK_FAILED: "We couldn't verify your key, possibly due to a connection issue.",
  ERR_PUBKEY_ADDING_FAILED: "Transaction for adding public key is failed. Please try again.",
  ERR_PUBKEY_EXCEPTION: "An error occurred while adding public key. Please try again.",
  ERR_QUOTE_EXPIRED_RETURN_IS_LOWER: "The quote has expired or the return is lower than expected. Please try again.",
  ERR_CANNOT_PUBLISH_INTENT: "We couldn't send your request, possibly due to a network issue or server downtime. Please check your connection or try again later.",
  ERR_WALLET_POPUP_BLOCKED: "Please allow popups and try again.",
  ERR_WALLET_CANCEL_ACTION: null,
}

// Then in the function:
const content = ERROR_MESSAGES[status] ?? `An error occurred. Please try again. ${status}`

1-370: Consider breaking down this large component for better maintainability.

This component is quite large (370+ lines) and handles many responsibilities. Consider extracting some logic into custom hooks or smaller components:

  • Token selection modal logic could be a custom hook
  • Error message rendering could be a separate component
  • Balance checking logic could be extracted to a custom hook

This would improve testability, reusability, and make the main component more focused on its primary responsibility of rendering the swap form.

src/features/machines/swapUIMachine1Click.ts (2)

142-162: Consider logging parse errors for debugging.

The parseFormValues action correctly handles parsing errors by returning null, but consider adding debug logging in the catch block to help troubleshoot parsing issues during development.

         } catch {
+          logger.debug("Failed to parse amount input", { amountIn: context.formValues.amountIn })
           return {
             tokenOut,
             amountIn: null,
           }
         }

301-301: Consider making default slippage configurable.

The hardcoded 1% slippage (10,000 basis points) might be too high for stable pairs or too low for volatile tokens. Consider making this configurable through input parameters.

     referral: input.referral,
-    slippageBasisPoints: 10_000, // 1%
+    slippageBasisPoints: input.slippageBasisPoints ?? 10_000, // Default 1%
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a20d8a5 and 7963062.

⛔ Files ignored due to path filters (1)
  • flake.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • .gitignore (1 hunks)
  • example.envrc (1 hunks)
  • flake.nix (1 hunks)
  • src/components/Asset/AssetComboIcon/index.tsx (1 hunks)
  • src/components/Asset/AssetList.tsx (3 hunks)
  • src/components/Modal/ModalContainer.tsx (1 hunks)
  • src/components/Modal/ModalSelectToken.tsx (1 hunks)
  • src/constants/blockchains.tsx (5 hunks)
  • src/features/machines/swapUIMachine1Click.ts (1 hunks)
  • src/features/swap/components-1Click/SwapForm.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapFormProvider.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapPriceImpact.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapRateInfo.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapSubmitter.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapUIMachineFormSyncProvider.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapUIMachineProvider.tsx (1 hunks)
  • src/features/swap/components-1Click/SwapWidget.tsx (1 hunks)
  • src/features/swap/hooks-1Click/useSwapRateData.ts (1 hunks)
  • src/index.ts (1 hunks)
  • src/stores/modalStore.ts (1 hunks)
  • src/types/swap.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (9)
src/components/Modal/ModalContainer.tsx (2)
src/providers/ModalStoreProvider.tsx (1)
  • useModalStore (31-39)
src/components/Modal/ModalSelectToken.tsx (1)
  • ModalSelectToken (48-192)
src/features/swap/components-1Click/SwapFormProvider.tsx (2)
src/features/swap/components-1Click/SwapForm.tsx (2)
  • SwapFormProps (47-50)
  • SwapFormValues (42-45)
src/features/swap/components/SwapFormProvider.tsx (1)
  • SwapFormProvider (7-18)
src/constants/blockchains.tsx (2)
src/types/base.ts (1)
  • SupportedChainName (1-23)
src/components/Network/NetworkIcon.tsx (1)
  • NetworkIcon (3-20)
src/features/swap/components-1Click/SwapUIMachineProvider.tsx (7)
src/features/machines/swapUIMachine1Click.ts (1)
  • swapUIMachine (75-496)
src/types/swap.ts (1)
  • SwappableToken (13-13)
src/types/walletMessage.ts (2)
  • WalletMessage (101-107)
  • WalletSignatureResult (109-114)
src/features/swap/components-1Click/SwapForm.tsx (1)
  • SwapFormValues (42-45)
src/utils/assert.ts (1)
  • assert (5-9)
src/utils/tokenUtils.ts (1)
  • computeTotalDeltaDifferentDecimals (131-146)
src/features/machines/swapIntentMachine.ts (1)
  • swapIntentMachine (151-666)
src/features/swap/components-1Click/SwapRateInfo.tsx (8)
src/types/swap.ts (1)
  • SwappableToken (13-13)
src/features/swap/hooks-1Click/useSwapRateData.ts (1)
  • useSwapRateData (9-11)
src/hooks/useTokensUsdPrices.ts (2)
  • useTokensUsdPrices (19-24)
  • TokenUsdPriceData (6-9)
src/components/Popover.tsx (3)
  • Popover (80-80)
  • PopoverTrigger (80-80)
  • PopoverContent (80-80)
src/utils/format.ts (2)
  • formatTokenValue (1-40)
  • formatUsdAmount (60-75)
src/utils/tokenUtils.ts (1)
  • BASIS_POINTS_DENOMINATOR (283-283)
src/types/base.ts (1)
  • TokenValue (77-80)
src/features/swap/components/SwapRateInfo.tsx (1)
  • SwapRateInfo (26-126)
src/features/swap/components-1Click/SwapUIMachineFormSyncProvider.tsx (5)
src/types/swap.ts (1)
  • SwapWidgetProps (15-56)
src/features/swap/components-1Click/SwapForm.tsx (1)
  • SwapFormValues (42-45)
src/features/swap/components-1Click/SwapUIMachineProvider.tsx (1)
  • SwapUIMachineContext (49-50)
src/features/swap/hooks/usePublicKeyModalOpener.ts (1)
  • usePublicKeyModalOpener (12-50)
src/features/swap/components/SwapUIMachineFormSyncProvider.tsx (1)
  • SwapUIMachineFormSyncProvider (17-91)
src/features/swap/components-1Click/SwapSubmitter.tsx (3)
src/features/swap/components-1Click/SwapUIMachineProvider.tsx (1)
  • SwapUIMachineContext (49-50)
src/logger.ts (1)
  • logger (36-36)
src/features/swap/components/SwapSubmitter.tsx (1)
  • SwapSubmitterProvider (13-45)
src/features/machines/swapUIMachine1Click.ts (11)
src/services/quoteService.ts (1)
  • QuoteResult (35-51)
src/types/swap.ts (1)
  • SwappableToken (13-13)
src/types/base.ts (1)
  • TokenValue (77-80)
src/features/machines/intentStatusMachine.ts (1)
  • intentStatusMachine (41-254)
src/features/machines/depositedBalanceMachine.ts (2)
  • BalanceMapping (33-33)
  • depositedBalanceMachine (60-276)
src/features/machines/backgroundQuoterMachine.ts (1)
  • backgroundQuoterMachine (57-96)
src/features/machines/swapIntentMachine.ts (1)
  • swapIntentMachine (151-666)
src/utils/tokenUtils.ts (3)
  • getAnyBaseTokenInfo (152-158)
  • getTokenMaxDecimals (193-198)
  • getUnderlyingBaseTokenInfos (160-171)
src/utils/parse.ts (1)
  • parseUnits (3-9)
src/utils/assert.ts (1)
  • assert (5-9)
src/utils/authIdentity.ts (1)
  • authHandleToIntentsUserId (40-82)
src/components/Asset/AssetList.tsx (3)
src/utils/token.ts (1)
  • isBaseToken (8-12)
src/constants/blockchains.tsx (1)
  • chainIcons (34-62)
src/components/Asset/AssetComboIcon/index.tsx (1)
  • AssetComboIcon (13-50)
🔇 Additional comments (22)
src/stores/modalStore.ts (1)

3-8: Enum extension looks good – remember to wire-up consumers

The new MODAL_SELECT_TOKEN value fits the existing pattern. Please make sure every place that switches on ModalType (e.g. modal container, state machines) has a corresponding branch, otherwise the modal may silently fail to render.

example.envrc (1)

1-1: 👍 Straightforward direnv config

use flake is the correct one-liner for nix-direnv. Nothing else to add.

.gitignore (1)

34-37: LGTM! Clean .gitignore organization.

The addition of the .direnv ignore rule under a dedicated "# nix" section is appropriate for the Nix development environment setup. The newline separation also improves readability.

src/components/Asset/AssetComboIcon/index.tsx (1)

36-36: LGTM! Visual positioning improvement.

The adjustment from bottom-0 to -bottom-[7px] properly positions the chain icon for better visual alignment in the asset list display.

src/index.ts (1)

4-4: LGTM! Clean export addition for the new feature.

The export alias SwapWidget1Click clearly distinguishes the new one-click swap widget from the existing SwapWidget while maintaining a consistent naming pattern.

src/components/Modal/ModalContainer.tsx (2)

7-7: LGTM! Clean import addition.

The import follows the established pattern for modal components.


13-14: LGTM! Consistent modal integration.

The new switch case for MODAL_SELECT_TOKEN follows the same pattern as existing modal cases and properly integrates the token selection functionality into the modal system.

src/features/swap/components-1Click/SwapFormProvider.tsx (1)

7-18: Clean React Hook Form implementation.

The form provider setup is correct with appropriate configuration for swap form handling. The "onSubmit" mode with "onChange" revalidation provides good user experience.

src/features/swap/hooks-1Click/useSwapRateData.ts (1)

9-11: Clean hook implementation using selector pattern.

The hook correctly delegates to the context selector, providing a clean API for consuming swap rate data.

src/features/swap/components-1Click/SwapRateInfo.tsx (2)

42-125: Well-structured UI with proper accessibility.

The accordion and popover implementation uses Radix UI components correctly, providing good accessibility. The conditional rendering logic and slippage percentage formatting are implemented properly.


128-170: Clean utility function implementations.

The useToggle hook, renderExchangeRate, and renderTokenUsdPrice functions are well-implemented with proper null handling and formatting.

src/features/swap/components-1Click/SwapWidget.tsx (1)

12-63: Well-organized provider composition architecture.

The nested provider structure follows a logical hierarchy from general to specific concerns. Props are appropriately distributed to relevant providers, and the composition enables clean separation of concerns across the swap feature.

src/components/Asset/AssetList.tsx (2)

38-40: LGTM! Type-safe chain icon retrieval.

The implementation correctly uses the isBaseToken type guard to safely access the chainName property before retrieving the icon.


62-64: Good UI adjustment for the checkmark position.

Moving the checkmark to top-right prevents overlap with the chain icon that's now displayed at bottom-right.

src/components/Modal/ModalSelectToken.tsx (1)

107-132: Well-structured token list construction.

The code properly handles both unified tokens (with grouped tokens) and base tokens, correctly managing the disabled/selected state based on the current selection.

src/features/swap/components-1Click/SwapUIMachineProvider.tsx (1)

85-106: Well-implemented quote state handling.

The updateUIAmountOut action properly handles all quote states: clearing the field for null quotes, showing "–" for errors, and calculating formatted amounts for valid quotes. Good UX considerations.

src/features/swap/components-1Click/SwapForm.tsx (1)

167-173: Correct implementation of balance validation.

The balance checking logic properly handles null cases and uses the appropriate comparison utility to determine if the user has sufficient balance.

src/features/machines/swapUIMachine1Click.ts (5)

1-43: Well-organized imports with proper type annotations.

The imports are cleanly structured with appropriate use of type imports and clear separation between external dependencies and internal modules.


44-74: Comprehensive and well-structured type definitions.

The Context type properly models all necessary UI state, and the event types are clearly defined for machine communication.


166-178: Quote update logic preserves successful quotes appropriately.

The implementation prevents UI flickering by maintaining successful quotes when new errors occur, which provides a better user experience.


267-281: Guards implementation is clean and appropriate.

The validation guards correctly check for valid quotes and form input, ensuring the state machine only proceeds when preconditions are met.


306-335: Global event handlers properly coordinate child actors.

The event handling ensures proper state synchronization across child actors, particularly for authentication and balance updates.

Copy link

@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

🧹 Nitpick comments (5)
src/features/1Click/hooks/useSwapRateData.ts (1)

13-66: Consider extracting shared logic to avoid code duplication.

This selector function appears to duplicate logic from src/features/swap/hooks/useSwapRateData.ts. Consider extracting the common calculation logic into a shared utility function to improve maintainability.

src/features/1Click/components/SwapSubmitter.tsx (1)

24-38: Improve warning message for better debugging.

The current warning message doesn't specify which required field is missing. Consider making it more specific to aid in debugging.

  const onSubmit = () => {
    if (userAddress == null || userChainType == null) {
-     logger.warn("No user address provided")
+     logger.warn("Cannot submit swap: missing user credentials", {
+       hasUserAddress: userAddress != null,
+       hasUserChainType: userChainType != null
+     })
      return
    }
src/features/1Click/components/SwapUIMachineFormSyncProvider.tsx (1)

63-64: Address the TODO: Remove hardcoded zero amounts

The hardcoded 0n values for amountIn and amountOut should be replaced with actual values or the fields should be removed as mentioned in the TODO comment. This could cause issues if the onSuccessSwap callback expects accurate amount values.

Would you like me to help implement a solution that either retrieves the actual amounts from the event data or refactors the callback interface to remove these fields?

src/features/1Click/components/SwapRateInfo.tsx (1)

36-40: Consider handling rate readiness at a higher level

The TODO comment suggests that the rate readiness check might be better handled outside of this component. This would make the component more focused and potentially prevent unnecessary renders.

Consider moving this check to the parent component and only rendering SwapRateInfo when rates are available. This would simplify the component and improve separation of concerns.

src/features/1Click/components/SwapUIMachineProvider.tsx (1)

4-4: Use consistent import paths

The import uses an absolute path while other imports in the file use relative paths. Consider maintaining consistency.

-import { assert } from "src/utils/assert"
+import { assert } from "../../../utils/assert"
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7963062 and 15bfa1c.

📒 Files selected for processing (10)
  • src/features/1Click/components/SwapForm.tsx (1 hunks)
  • src/features/1Click/components/SwapFormProvider.tsx (1 hunks)
  • src/features/1Click/components/SwapPriceImpact.tsx (1 hunks)
  • src/features/1Click/components/SwapRateInfo.tsx (1 hunks)
  • src/features/1Click/components/SwapSubmitter.tsx (1 hunks)
  • src/features/1Click/components/SwapUIMachineFormSyncProvider.tsx (1 hunks)
  • src/features/1Click/components/SwapUIMachineProvider.tsx (1 hunks)
  • src/features/1Click/components/SwapWidget.tsx (1 hunks)
  • src/features/1Click/hooks/useSwapRateData.ts (1 hunks)
  • src/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/features/1Click/components/SwapFormProvider.tsx (1)
src/features/1Click/components/SwapForm.tsx (2)
  • SwapFormProps (47-50)
  • SwapFormValues (42-45)
src/features/1Click/hooks/useSwapRateData.ts (3)
src/features/1Click/components/SwapUIMachineProvider.tsx (1)
  • SwapUIMachineContext (49-50)
src/utils/tokenUtils.ts (2)
  • computeTotalDeltaDifferentDecimals (131-146)
  • accountSlippageExactIn (344-355)
src/features/swap/hooks/useSwapRateData.ts (1)
  • swapRateDataSelector (13-66)
src/features/1Click/components/SwapSubmitter.tsx (2)
src/features/1Click/components/SwapUIMachineProvider.tsx (1)
  • SwapUIMachineContext (49-50)
src/logger.ts (1)
  • logger (36-36)
src/features/1Click/components/SwapUIMachineFormSyncProvider.tsx (5)
src/types/swap.ts (1)
  • SwapWidgetProps (15-56)
src/features/1Click/components/SwapForm.tsx (1)
  • SwapFormValues (42-45)
src/features/1Click/components/SwapUIMachineProvider.tsx (1)
  • SwapUIMachineContext (49-50)
src/features/swap/hooks/usePublicKeyModalOpener.ts (1)
  • usePublicKeyModalOpener (12-50)
src/features/swap/components/SwapUIMachineFormSyncProvider.tsx (1)
  • SwapUIMachineFormSyncProvider (17-91)
src/features/1Click/components/SwapForm.tsx (21)
src/types/hostAppLink.ts (1)
  • RenderHostAppLink (12-16)
src/features/1Click/components/SwapUIMachineProvider.tsx (1)
  • SwapUIMachineContext (49-50)
src/hooks/useTokensUsdPrices.ts (1)
  • useTokensUsdPrices (19-24)
src/providers/ModalStoreProvider.tsx (1)
  • useModalStore (31-39)
src/components/Modal/ModalSelectToken.tsx (1)
  • ModalSelectTokenPayload (28-37)
src/constants/swap.tsx (1)
  • SWAP_TOKEN_FLAGS (1-4)
src/features/1Click/components/SwapSubmitter.tsx (1)
  • SwapSubmitterContext (7-11)
src/features/machines/depositedBalanceMachine.ts (2)
  • balanceSelector (278-285)
  • transitBalanceSelector (347-364)
src/utils/tokenUtils.ts (1)
  • compareAmounts (200-219)
src/components/Island.tsx (1)
  • Island (4-13)
src/components/TradeNavigationLinks.tsx (1)
  • TradeNavigationLinks (9-46)
src/components/Form/index.tsx (1)
  • Form (28-58)
src/components/Form/FieldComboInput.tsx (1)
  • FieldComboInput (46-201)
src/utils/format.ts (1)
  • formatUsdAmount (60-75)
src/components/Button/ButtonSwitch.tsx (1)
  • ButtonSwitch (12-26)
src/components/AuthGate.tsx (1)
  • AuthGate (12-31)
src/components/Button/ButtonCustom.tsx (1)
  • ButtonCustom (17-82)
src/features/1Click/components/SwapPriceImpact.tsx (1)
  • SwapPriceImpact (9-48)
src/features/1Click/components/SwapRateInfo.tsx (1)
  • SwapRateInfo (26-126)
src/features/machines/intentStatusMachine.ts (1)
  • intentStatusMachine (41-254)
src/components/IntentCard/SwapIntentCard.tsx (1)
  • SwapIntentCard (17-135)
src/features/1Click/components/SwapUIMachineProvider.tsx (6)
src/types/swap.ts (1)
  • SwappableToken (13-13)
src/types/walletMessage.ts (2)
  • WalletMessage (101-107)
  • WalletSignatureResult (109-114)
src/features/1Click/components/SwapForm.tsx (1)
  • SwapFormValues (42-45)
src/utils/assert.ts (1)
  • assert (5-9)
src/utils/tokenUtils.ts (1)
  • computeTotalDeltaDifferentDecimals (131-146)
src/features/machines/swapIntentMachine.ts (1)
  • swapIntentMachine (151-666)
🔇 Additional comments (6)
src/features/1Click/components/SwapFormProvider.tsx (1)

7-18: LGTM! Clean form provider implementation.

The component correctly implements the FormProvider pattern with appropriate form configuration. The validation modes and default values are well-chosen for a swap form.

src/features/1Click/components/SwapSubmitter.tsx (1)

13-45: Clean submission context implementation.

The component properly implements the context provider pattern with appropriate error handling and logging. The defensive checks prevent invalid submissions.

src/features/1Click/components/SwapPriceImpact.tsx (1)

9-48: Solid price impact calculation and display logic.

The component correctly handles edge cases with early returns, implements proper price impact calculation, and provides appropriate visual feedback with conditional styling. The logic for showing impacts only when significant (>1% or beneficial) is user-friendly.

src/features/1Click/components/SwapWidget.tsx (1)

12-63: Well-structured widget composition with proper provider nesting.

The component effectively composes multiple context providers in a logical order, ensuring each provider has access to the dependencies it needs. The prop threading is clean and the isLoggedIn derivation is straightforward.

src/features/1Click/components/SwapUIMachineProvider.tsx (1)

69-71: Good defensive programming with token validation

The assertion ensures that tokens are always defined, preventing potential runtime errors. The fallback to first tokens in the list provides sensible defaults.

src/features/1Click/components/SwapForm.tsx (1)

292-370: Excellent error handling with user-friendly messages

The renderIntentCreationResult function provides comprehensive error handling with clear, actionable messages for users. The decision to return null for certain errors (user cancellation, popup blocked) shows good UX consideration.

@cawabunga-bytes cawabunga-bytes self-requested a review July 24, 2025 19:17
@defuse-es defuse-es merged commit e4c15c4 into defuse-protocol:beta Jul 25, 2025
3 checks passed
amdefuse pushed a commit that referenced this pull request Jul 25, 2025
## [1.0.0-beta.206](v1.0.0-beta.205...v1.0.0-beta.206) (2025-07-25)

### Features

* start setting up UI for 1Click ([#557](#557)) ([e4c15c4](e4c15c4))
@amdefuse
Copy link
Contributor

🎉 This PR is included in version 1.0.0-beta.206 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants