Skip to content

Nebula: Add Move funds page #7298

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

Merged
merged 1 commit into from
Jun 7, 2025
Merged

Conversation

MananTank
Copy link
Member

@MananTank MananTank commented Jun 6, 2025


PR-Codex overview

This PR enhances the functionality of the dashboard application by adding new components and improving existing ones, particularly around fund movement and wallet connections. It introduces new UI elements and modifies logic for better user experience during transactions.

Detailed summary

  • Updated middleware to preserve search parameters on login redirects.
  • Added placeholder prop to DecimalInput component.
  • Integrated TWAutoConnect in ChatPageLayout.
  • Enhanced TransactionButton to include disableNoFundsPopup prop.
  • Created MoveFundsConnectButton for moving funds functionality.
  • Developed MoveFundsPage with a structured UI for fund transfers.
  • Implemented token selection and transfer logic within MoveFundsPage.
  • Added TokenSelectorPopover for selecting tokens with manual address input.
  • Introduced wallet balance rendering in RenderTokenBalance.
  • Enhanced error handling and user feedback during token transfers.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Introduced a Move Funds page for transferring cryptocurrency between wallets, featuring wallet connection, chain and token selection, and transaction handling.
    • Added a customizable connect button supporting multiple authentication methods and theme adaptation.
    • Added the ability to display placeholder text in decimal input fields.
    • Enhanced button components with an option to disable the "Not Enough Funds" popup.
    • Added a dedicated page layout combining header, theme toggle, support link, and Move Funds functionality.
    • Integrated automatic wallet connection within the chat page layout for seamless user experience.
  • Bug Fixes

    • Updated middleware to allow unauthenticated access to the Move Funds page without redirecting to the login page.

Copy link

changeset-bot bot commented Jun 6, 2025

⚠️ No Changeset found

Latest commit: 044f897

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Jun 6, 2025

Walkthrough

This update introduces a new "Move Funds" feature in the Nebula app, including UI components for connecting wallets, selecting tokens, and transferring funds. It adds new React components, extends button and input props for enhanced control, updates middleware logic to allow unauthenticated access to the move-funds page, and modifies component usage of TWAutoConnect between layout and providers.

Changes

File(s) Change Summary
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx Added MoveFundsPage React component with wallet, chain, token selection, form validation, token fetching, and transaction handling; added multiple internal components and a useWalletTokens hook.
apps/dashboard/src/app/nebula-app/move-funds/page.tsx Added default exported RecoverPage component rendering header, theme toggle, support link, MoveFundsConnectButton, and MoveFundsPage.
apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx Added MoveFundsConnectButton component wrapping thirdweb ConnectButton with multi-auth options and dynamic theming.
apps/dashboard/src/components/buttons/MismatchButton.tsx, apps/dashboard/src/components/buttons/TransactionButton.tsx Added disableNoFundsPopup prop to control "No Funds" popup logic and event tracking; forwarded from TransactionButton to MismatchButton.
apps/dashboard/src/@/components/ui/decimal-input.tsx Extended DecimalInput props with optional placeholder string passed to underlying input.
apps/dashboard/src/middleware.ts Updated middleware to allow unauthenticated access to /move-funds path on the "nebula" subdomain alongside /login.
apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx Added TWAutoConnect component with nebulaAAOptions and nebulaAppThirdwebClient props inside ChatPageLayout.
apps/dashboard/src/app/nebula-app/providers.tsx Removed TWAutoConnect component and related imports from NebulaProviders.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MoveFundsPage
    participant MoveFundsConnectButton
    participant Wallet
    participant SendFunds
    participant TokenAPI
    participant TransactionAPI

    User->>MoveFundsPage: Visit /move-funds
    MoveFundsPage->>MoveFundsConnectButton: Render connect button
    User->>MoveFundsConnectButton: Click connect
    MoveFundsConnectButton->>Wallet: Initiate wallet connection/auth
    Wallet-->>MoveFundsConnectButton: Connection result
    MoveFundsConnectButton-->>MoveFundsPage: Update connection status
    alt Connected
        MoveFundsPage->>SendFunds: Render send funds form
        User->>SendFunds: Select wallet, chain, token, enter details
        SendFunds->>TokenAPI: Fetch available tokens and balances
        TokenAPI-->>SendFunds: Return token list
        User->>SendFunds: Submit form
        SendFunds->>TransactionAPI: Prepare and send transaction
        TransactionAPI-->>SendFunds: Transaction result
        SendFunds-->>User: Show success/error notification
    else Not connected
        MoveFundsPage-->>User: Show connect button
    end
Loading

Suggested labels

Portal

Suggested reviewers

  • MananTank

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 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

vercel bot commented Jun 6, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 7, 2025 0:53am
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) Jun 7, 2025 0:53am
login ⬜️ Skipped (Inspect) Jun 7, 2025 0:53am
thirdweb_playground ⬜️ Skipped (Inspect) Jun 7, 2025 0:53am
wallet-ui ⬜️ Skipped (Inspect) Jun 7, 2025 0:53am

@vercel vercel bot temporarily deployed to Preview – wallet-ui June 6, 2025 19:10 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 6, 2025 19:10 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 6, 2025 19:10 Inactive
@vercel vercel bot temporarily deployed to Preview – login June 6, 2025 19:10 Inactive
@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label Jun 6, 2025
Copy link
Member Author


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link

codecov bot commented Jun 6, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 55.57%. Comparing base (7fa5be5) to head (044f897).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7298   +/-   ##
=======================================
  Coverage   55.57%   55.57%           
=======================================
  Files         909      909           
  Lines       58673    58673           
  Branches     4158     4158           
=======================================
  Hits        32607    32607           
  Misses      25959    25959           
  Partials      107      107           
Flag Coverage Δ
packages 55.57% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

github-actions bot commented Jun 6, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 62.57 KB (0%) 1.3 s (0%) 347 ms (+122.38% 🔺) 1.6 s
thirdweb (cjs) 345.55 KB (0%) 7 s (0%) 1.3 s (+11.59% 🔺) 8.2 s
thirdweb (minimal + tree-shaking) 5.7 KB (0%) 114 ms (0%) 107 ms (+644.07% 🔺) 221 ms
thirdweb/chains (tree-shaking) 531 B (0%) 11 ms (0%) 59 ms (+1617.97% 🔺) 70 ms
thirdweb/react (minimal + tree-shaking) 19.56 KB (0%) 392 ms (0%) 153 ms (+443.13% 🔺) 544 ms

@MananTank MananTank force-pushed the 06-07-nebula_add_move_funds_page branch from c9243c8 to d861fcb Compare June 6, 2025 19:17
@MananTank MananTank marked this pull request as ready for review June 6, 2025 19:17
@MananTank MananTank requested review from a team as code owners June 6, 2025 19:17
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 6, 2025 19:17 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui June 6, 2025 19:17 Inactive
@vercel vercel bot temporarily deployed to Preview – login June 6, 2025 19:17 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 6, 2025 19:17 Inactive
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)
apps/dashboard/src/components/buttons/MismatchButton.tsx (1)

84-91: 🛠️ Refactor suggestion

disableNoFundsPopup should be optional for backward compatibility

Making the prop mandatory forces every existing call-site (outside this PR) to be updated, otherwise TS will break the build.
Declare it optional and default it to false when destructuring:

-type MistmatchButtonProps = React.ComponentProps<typeof Button> & {
+type MistmatchButtonProps = React.ComponentProps<typeof Button> & {
   txChainId: number;
   isLoggedIn: boolean;
   isPending: boolean;
   checkBalance?: boolean;
   client: ThirdwebClient;
-  disableNoFundsPopup: boolean;
+  disableNoFundsPopup?: boolean;
 };
-const {
+const {
   ...
   checkBalance = true,
+  disableNoFundsPopup = false,
   ...buttonProps
 } = props;
🧹 Nitpick comments (5)
apps/dashboard/src/app/nebula-app/move-funds/page.tsx (1)

7-7: Consider renaming for clarity.

The component name RecoverPage might be unclear since it's primarily for moving funds. Consider MoveFundsPage or MoveFundsLayout to better reflect its purpose.

apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1)

38-39: theme === "light" fallback mis-handles "system"

next-themes returns "system" until it resolves the real theme. Treating every non-"light" value as dark causes a flash of the dark SDK theme on a light-system device.

-getSDKTheme(theme === "light" ? "light" : "dark")
+getSDKTheme(theme === "light" ? "light" : theme === "dark" ? "dark" : "light")
apps/dashboard/src/components/buttons/MismatchButton.tsx (1)

202-205: Minor: type can become undefined

When neither showSwitchChainPopover nor showNoFundsPopup is true and the caller hasn’t provided type, buttonProps.type is undefined, yielding an invalid DOM attribute (type="undefined"). The browser will disable form submission.

Safest is to default to "button":

-  type={
-    showSwitchChainPopover || showNoFundsPopup
-      ? "button"
-      : buttonProps.type
-  }
+  type={
+    showSwitchChainPopover || showNoFundsPopup
+      ? "button"
+      : buttonProps.type ?? "button"
+  }
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (2)

439-453: No balance-vs-amount validation

A user can enter an amount greater than their balance and the form will happily attempt the transfer, only to fail async.
A quick client-side check improves UX:

+const balanceQuery = useWalletBalance({
+  address: props.accountAddress,
+  chain: defineChain(form.watch("chainId")),
+  client: dashboardClient,
+  tokenAddress:
+    getAddress(form.watch("token")?.token_address ?? "") ===
+    getAddress(NATIVE_TOKEN_ADDRESS)
+      ? undefined
+      : form.watch("token")?.token_address,
+});
...
-<TransactionButton ... disabled={sendAndConfirmTransaction.isPending}>
+<TransactionButton
+  ... 
+  disabled={
+    sendAndConfirmTransaction.isPending ||
+    (balanceQuery.data &&
+      toWei(form.watch("amount"), balanceQuery.data.decimals) >
+        balanceQuery.data.value)
+  }
+>

665-670: Hard-coded Insight URL duplicates env logic

The base host is re-assembled inline (thirdweb vs thirdweb-dev). Centralise this in a util/env var to avoid drift and make future host changes trivial.

E.g.

const INSIGHT_HOST = process.env.NEXT_PUBLIC_INSIGHT_HOST ?? 
  (isProd ? "https://insight.thirdweb.com" : "https://insight.thirdweb-dev.com");
...
const url = new URL("/v1/tokens", INSIGHT_HOST);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2510c4f and d861fcb.

📒 Files selected for processing (7)
  • apps/dashboard/src/@/components/ui/decimal-input.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx (1 hunks)
  • apps/dashboard/src/components/buttons/MismatchButton.tsx (5 hunks)
  • apps/dashboard/src/components/buttons/TransactionButton.tsx (3 hunks)
  • apps/dashboard/src/middleware.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/dashboard/src/app/nebula-app/move-funds/page.tsx (3)
apps/dashboard/src/app/nebula-app/(app)/icons/NebulaIcon.tsx (1)
  • NebulaIcon (1-24)
apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1)
  • MoveFundsConnectButton (28-49)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1)
  • MoveFundsPage (81-132)
apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1)
apps/dashboard/src/@/constants/thirdweb-client.client.ts (1)
  • getClientThirdwebClient (3-11)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Unit Tests
  • GitHub Check: Lint Packages
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
apps/dashboard/src/@/components/ui/decimal-input.tsx (1)

8-8: LGTM! Clean implementation of placeholder support.

The optional placeholder prop is correctly added to the interface and properly passed to the underlying Input component.

Also applies to: 17-17

apps/dashboard/src/middleware.ts (1)

55-59: LGTM! Proper implementation of unauthenticated access.

The middleware correctly excludes the "move-funds" path from requiring authentication, which aligns with the new wallet connection flow where users need to access the page before logging in.

apps/dashboard/src/app/nebula-app/move-funds/page.tsx (1)

9-35: LGTM! Well-structured page layout.

The component structure is clean and well-organized:

  • Proper header with branding and navigation elements
  • Responsive support link visibility (hidden on mobile)
  • Clean integration of MoveFundsConnectButton and MoveFundsPage components
apps/dashboard/src/components/buttons/TransactionButton.tsx (1)

35-35: LGTM! Proper prop forwarding with explicit default handling.

The disableNoFundsPopup prop is correctly added to the interface and properly forwarded to MismatchButton with explicit default value handling to ensure consistent behavior.

Also applies to: 47-47, 73-75

apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1)

241-260: ⚠️ Potential issue

ERC-20 amount sent without decimal conversion

transfer({ amount: values.amount, … }) expects the wei-denominated quantity (or a formatted string recognised by the SDK).
Passing the human-readable value (“1.5”) for a token with, say, 6 decimals will send 1.5 wei, not 1.5 × 10^6 units.

Convert using the token’s decimals:

-import { transfer } from "thirdweb/extensions/erc20";
+import { transfer } from "thirdweb/extensions/erc20";
+import { toUnits } from "thirdweb";      // new import
...
-  tx = transfer({
-    to: values.receiverAddress,
-    amount: values.amount,
-    contract: erc20Contract,
-  });
+  tx = transfer({
+    to: values.receiverAddress,
+    amount: toUnits(values.amount, values.token.decimals),
+    contract: erc20Contract,
+  });
⛔ Skipped due to learnings
Learnt from: MananTank
PR: thirdweb-dev/js#7081
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create/create-token-page-impl.tsx:110-118
Timestamp: 2025-05-20T18:54:15.781Z
Learning: In the thirdweb dashboard's token asset creation flow, the `transferBatch` function from `thirdweb/extensions/erc20` accepts the raw quantity values from the form without requiring explicit conversion to wei using `toUnits()`. The function appears to handle this conversion internally or is designed to work with the values in the format they're already provided.

@MananTank MananTank force-pushed the 06-07-nebula_add_move_funds_page branch from ea9e08d to 584a9f8 Compare June 6, 2025 21:44
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 7, 2025 00:12 Inactive
@vercel vercel bot temporarily deployed to Preview – login June 7, 2025 00:12 Inactive
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 (1)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1)

197-200: Float parsing precision caveat (re-raised)

Number.parseFloat will silently lose precision for large-decimal ERC-20 amounts.
Consider a big-number parser (toWei, ethers.parseUnits, etc.) inside the refinement so validation matches the value ultimately submitted on-chain.

🧹 Nitpick comments (4)
apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx (1)

2-6: Path looks brittle – prefer absolute aliases

The deep relative import ../../../(app)/components/autoconnect is fragile; a single file move will break it.
If the repo already configures TS path aliases (e.g. @app/components), re-export and import via the alias for resilience and readability.

apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (3)

224-229: Comment / code mismatch

The comment says “filter out all other wallets” but filteredConnectedWallets is currently the unfiltered connectedWallets.
Either reinstate the filter or drop the misleading comment to avoid confusion for future maintainers.


320-327: Minor readability – no need for .values()

for (const { token, amount } of tokens.values()) works, but using the array directly is shorter and avoids the extra iterator:

-for (const { token, amount } of tokens.values()) {
+for (const { token, amount } of tokens) {

339-343: Avoid N× invalidations

queryClient.invalidateQueries({ queryKey: ["walletBalance"] }); is called inside the per-token loop.
When sending many tokens this triggers multiple identical invalidations.

Move it once outside the loop (after the for-of) to cut redundant cache churn:

 for (const { token, amount } of tokens) { ... }
-
-queryClient.invalidateQueries({ queryKey: ["walletBalance"] });
+queryClient.invalidateQueries({ queryKey: ["walletBalance"] });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 130ba90 and 590dab4.

📒 Files selected for processing (9)
  • apps/dashboard/src/@/components/ui/decimal-input.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/providers.tsx (0 hunks)
  • apps/dashboard/src/components/buttons/MismatchButton.tsx (6 hunks)
  • apps/dashboard/src/components/buttons/TransactionButton.tsx (3 hunks)
  • apps/dashboard/src/middleware.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/dashboard/src/app/nebula-app/providers.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/dashboard/src/middleware.ts
  • apps/dashboard/src/components/buttons/TransactionButton.tsx
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx
  • apps/dashboard/src/@/components/ui/decimal-input.tsx
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx
  • apps/dashboard/src/components/buttons/MismatchButton.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (3)
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:255-277
Timestamp: 2025-06-06T23:47:55.100Z
Learning: The `transfer` function from `thirdweb/extensions/erc20` accepts human-readable amounts via the `amount` property and automatically handles conversion to base units (wei) by fetching the token decimals internally. Manual conversion using `toWei()` is not required when using the `amount` property.
Learnt from: MananTank
PR: thirdweb-dev/js#7081
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create/create-token-page-impl.tsx:110-118
Timestamp: 2025-05-20T18:54:15.781Z
Learning: In the thirdweb dashboard's token asset creation flow, the `transferBatch` function from `thirdweb/extensions/erc20` accepts the raw quantity values from the form without requiring explicit conversion to wei using `toUnits()`. The function appears to handle this conversion internally or is designed to work with the values in the format they're already provided.
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:424-424
Timestamp: 2025-06-06T23:46:08.785Z
Learning: The thirdweb project has an ESLint rule that restricts direct usage of `defineChain`. When it's necessary to use `defineChain` directly, it's acceptable to disable the rule with `// eslint-disable-next-line no-restricted-syntax`.
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Build Packages
  • GitHub Check: Unit Tests
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx (1)

33-36: Verify only a single TWAutoConnect instance can ever mount

Moving TWAutoConnect into ChatPageLayout means every page that uses this layout will now mount its own copy.
If another ancestor (or sibling) layout/page happens to include TWAutoConnect as well, you may trigger competing auto-connection side-effects and duplicate listeners.

Please double-check that:

  1. No other rendered tree includes TWAutoConnect.
  2. Route transitions that unmount / remount ChatPageLayout don’t repeatedly fire autoConnect() in quick succession.

If either can occur, consider hoisting the component higher (e.g. the root layout) or guarding the logic with an isMountedRef.

apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1)

249-259: toWei() default assumes 18 decimals – confirm chain accuracy

toWei(amount) converts assuming 18-decimals.
If you ever enable chains whose native asset has a different precision (e.g. Klaytn 18, but others might differ), the transfer value will be off.

Safer:

- value: toWei(amount),
+ value: toWei(amount, chain.nativeCurrency.decimals ?? 18),

(or derive decimals from chain if available).

@MananTank MananTank force-pushed the 06-07-nebula_add_move_funds_page branch from 590dab4 to baf98d0 Compare June 7, 2025 00:37
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 7, 2025 00:37 Inactive
@vercel vercel bot temporarily deployed to Preview – login June 7, 2025 00:37 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui June 7, 2025 00:37 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 7, 2025 00:37 Inactive
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

♻️ Duplicate comments (1)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1)

197-200: parseFloat‐based validation is still lossy for high-precision ERC-20 amounts

We previously raised that Number.parseFloat will silently truncate values with many decimals (e.g. 18-dec USDT). That limitation remains unchanged, so inputs like 0.000000000000000001 will round to 1e-18 and may pass/ fail validation unexpectedly.

🧹 Nitpick comments (2)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (2)

315-323: Use direct array iteration instead of .values() for clarity

for (const { token, amount } of tokens.values()) works but is needlessly indirect.
tokens is already an array of objects; iterating it directly avoids the extra iterator allocation and better signals intent.

-    for (const { token, amount } of tokens.values()) {
+    for (const { token, amount } of tokens) {

671-680: Potential N+1 balance queries

RenderTokenBalance fires a separate useWalletBalance query for every token row. With large portfolios this can trigger dozens of simultaneous requests and throttle the Insight API.

Consider batching balances (e.g. a single getWalletBalance call that returns all token balances) or memoising requests via a shared query key containing the whole token list.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 590dab4 and baf98d0.

📒 Files selected for processing (9)
  • apps/dashboard/src/@/components/ui/decimal-input.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/providers.tsx (0 hunks)
  • apps/dashboard/src/components/buttons/MismatchButton.tsx (6 hunks)
  • apps/dashboard/src/components/buttons/TransactionButton.tsx (3 hunks)
  • apps/dashboard/src/middleware.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/dashboard/src/app/nebula-app/providers.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/dashboard/src/middleware.ts
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx
  • apps/dashboard/src/@/components/ui/decimal-input.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx
  • apps/dashboard/src/components/buttons/TransactionButton.tsx
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx
  • apps/dashboard/src/components/buttons/MismatchButton.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (3)
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:255-277
Timestamp: 2025-06-06T23:47:55.100Z
Learning: The `transfer` function from `thirdweb/extensions/erc20` accepts human-readable amounts via the `amount` property and automatically handles conversion to base units (wei) by fetching the token decimals internally. Manual conversion using `toWei()` is not required when using the `amount` property.
Learnt from: MananTank
PR: thirdweb-dev/js#7081
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create/create-token-page-impl.tsx:110-118
Timestamp: 2025-05-20T18:54:15.781Z
Learning: In the thirdweb dashboard's token asset creation flow, the `transferBatch` function from `thirdweb/extensions/erc20` accepts the raw quantity values from the form without requiring explicit conversion to wei using `toUnits()`. The function appears to handle this conversion internally or is designed to work with the values in the format they're already provided.
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:424-424
Timestamp: 2025-06-06T23:46:08.785Z
Learning: The thirdweb project has an ESLint rule that restricts direct usage of `defineChain`. When it's necessary to use `defineChain` directly, it's acceptable to disable the rule with `// eslint-disable-next-line no-restricted-syntax`.
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)

Copy link
Contributor

graphite-app bot commented Jun 7, 2025

Merge activity

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the user experience in the `Nebula` application by adding new features, improving existing components, and ensuring better handling of user authentication and fund transfers.

### Detailed summary
- Updated redirect logic in `middleware.ts` to preserve search params and prevent redirect from certain paths.
- Added `placeholder` prop to `DecimalInput` in `decimal-input.tsx`.
- Integrated `TWAutoConnect` component in `ChatPageLayout.tsx`.
- Enhanced `TransactionButton` in `TransactionButton.tsx` to manage a new `disableNoFundsPopup` prop.
- Refactored `NebulaProviders` to remove redundant `TWAutoConnect` usage.
- Created a new `RecoverPage` component in `move-funds/page.tsx` for fund recovery.
- Introduced `MoveFundsConnectButton` for connecting wallets in `connect-button.tsx`.
- Implemented a new `MoveFundsPage` for managing fund transfers.
- Updated `MismatchButton` to handle the new `disableNoFundsPopup` prop.
- Enhanced token management and user feedback within the `MoveFundsPage`.
- Added new components and functions for improved token selection and balance rendering.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced a Move Funds page for transferring cryptocurrency between wallets, featuring wallet connection, chain and token selection, and transaction handling.
	- Added a customizable connect button supporting multiple authentication methods and theme adaptation.
	- Added the ability to display placeholder text in decimal input fields.
	- Enhanced button components with an option to disable the "Not Enough Funds" popup.
	- Added a dedicated page layout combining header, theme toggle, support link, and Move Funds functionality.
	- Integrated automatic wallet connection within the chat page layout for seamless user experience.

- **Bug Fixes**
	- Updated middleware to allow unauthenticated access to the Move Funds page without redirecting to the login page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@graphite-app graphite-app bot force-pushed the 06-07-nebula_add_move_funds_page branch from baf98d0 to 044f897 Compare June 7, 2025 00:45
@vercel vercel bot temporarily deployed to Preview – wallet-ui June 7, 2025 00:45 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 7, 2025 00:45 Inactive
@vercel vercel bot temporarily deployed to Preview – login June 7, 2025 00:45 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 7, 2025 00:45 Inactive
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)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (2)

197-200: parseFloat loses precision for large-decimal ERC-20 values

This was raised earlier and left as-is, so just flagging as a reminder.


983-988: Handle non-2xx responses from Insight API

Same issue flagged previously: network / 4xx / 5xx failures propagate as unhandled rejections.

🧹 Nitpick comments (3)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (3)

224-229: Dead code: remove the commented-out filter or implement the intended logic

filteredConnectedWallets currently just aliases connectedWallets; the original filtering for inApp/smart wallets is commented out.
Either restore the filter or drop the alias entirely to avoid future confusion.

-const filteredConnectedWallets = connectedWallets;
-// .filter(
-//   (w) => w.id === "inApp" || w.id === "smart",
-// );;
+// Keep only the affected wallet types (inApp & smart)
+const filteredConnectedWallets = connectedWallets.filter(
+  (w) => w.id === "inApp" || w.id === "smart",
+);

315-323: Unnecessary use of .values() iterator

for…of tokens is clearer and avoids the extra iterator object.

-for (const { token, amount } of tokens.values()) {
+for (const { token, amount } of tokens) {

700-738: Potential request-storm while the user types a custom token address

manualTokenQuery fires on every key-stroke once the input is a valid hex string, which can trigger dozens of RPC calls per second.
Debounce the query key or wrap the state update in a setTimeout/useDebounce hook to avoid rate-limiting issues.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between baf98d0 and 044f897.

📒 Files selected for processing (9)
  • apps/dashboard/src/@/components/ui/decimal-input.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/providers.tsx (0 hunks)
  • apps/dashboard/src/components/buttons/MismatchButton.tsx (6 hunks)
  • apps/dashboard/src/components/buttons/TransactionButton.tsx (3 hunks)
  • apps/dashboard/src/middleware.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/dashboard/src/app/nebula-app/providers.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/dashboard/src/@/components/ui/decimal-input.tsx
  • apps/dashboard/src/middleware.ts
  • apps/dashboard/src/app/nebula-app/move-funds/page.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageLayout.tsx
  • apps/dashboard/src/components/buttons/TransactionButton.tsx
  • apps/dashboard/src/app/nebula-app/move-funds/connect-button.tsx
  • apps/dashboard/src/components/buttons/MismatchButton.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (3)
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:255-277
Timestamp: 2025-06-06T23:47:55.100Z
Learning: The `transfer` function from `thirdweb/extensions/erc20` accepts human-readable amounts via the `amount` property and automatically handles conversion to base units (wei) by fetching the token decimals internally. Manual conversion using `toWei()` is not required when using the `amount` property.
Learnt from: MananTank
PR: thirdweb-dev/js#7081
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create/create-token-page-impl.tsx:110-118
Timestamp: 2025-05-20T18:54:15.781Z
Learning: In the thirdweb dashboard's token asset creation flow, the `transferBatch` function from `thirdweb/extensions/erc20` accepts the raw quantity values from the form without requiring explicit conversion to wei using `toUnits()`. The function appears to handle this conversion internally or is designed to work with the values in the format they're already provided.
Learnt from: MananTank
PR: thirdweb-dev/js#7298
File: apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx:424-424
Timestamp: 2025-06-06T23:46:08.785Z
Learning: The thirdweb project has an ESLint rule that restricts direct usage of `defineChain`. When it's necessary to use `defineChain` directly, it's acceptable to disable the rule with `// eslint-disable-next-line no-restricted-syntax`.
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Unit Tests
  • GitHub Check: Build Packages
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Size
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/dashboard/src/app/nebula-app/move-funds/move-funds.tsx (1)

249-259: toWei() assumes 18 decimals – may under/over-send on chains where the native token uses a different precision

toWei(amount) hard-codes 18 decimals. While most EVM natives are 18, that’s not guaranteed (e.g. Klaytn, Metis).
Consider deriving nativeDecimals via getWalletBalance or chain.nativeCurrency.decimals and using toWei(amount, nativeDecimals) (supported by thirdweb 4.1+) to stay future-proof.

@graphite-app graphite-app bot merged commit 044f897 into main Jun 7, 2025
24 checks passed
@graphite-app graphite-app bot deleted the 06-07-nebula_add_move_funds_page branch June 7, 2025 00:53
@vercel vercel bot temporarily deployed to Production – login June 7, 2025 00:53 Inactive
@vercel vercel bot temporarily deployed to Production – wallet-ui June 7, 2025 00:53 Inactive
@vercel vercel bot temporarily deployed to Production – thirdweb_playground June 7, 2025 00:53 Inactive
@vercel vercel bot temporarily deployed to Production – docs-v2 June 7, 2025 00:53 Inactive
@coderabbitai coderabbitai bot mentioned this pull request Jul 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dashboard Involves changes to the Dashboard.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants