Skip to content

feat: Add rollups-node connection#433

Open
brunomenezes wants to merge 27 commits intofeat/application-summary-pagefrom
feat/add-node-connection
Open

feat: Add rollups-node connection#433
brunomenezes wants to merge 27 commits intofeat/application-summary-pagefrom
feat/add-node-connection

Conversation

@brunomenezes
Copy link
Collaborator

@brunomenezes brunomenezes commented Feb 14, 2026

Summary

The code changes add the possibility to create and persist (in the browser) a configuration to connect to a rollups-node. The connection allows the user to connect to any supported rollups-node.

The following deployment can be used for testing against.
Preview live deployment: https://dave-git-feat-add-node-connection-cartesi.vercel.app/

Test steps:

  • Click the Settings icon in the header.
  • You can see the current selected connection (usually the system mocked setup)
  • Click the Manage button.
  • In the manage view, you can:
    • List available connections
    • Test the status of the connection.
    • Remove a non-selected connection.
    • Connect to a non-selected connection.
  • In the create view, you can:
    • Create a new connection by filling in the fields as requested.

Changes:

  • At the top-right corner, there is a new settings icon button. A user can click to view the selected connection and access the connection management area. The theme toggle is also included in that submenu, allowing you to switch between dark and light modes.
  • Check support node by using semver parser. Range supported at this moment is >=2.0.0-alpha.9 <3.0.0
  • Check against supported chains configured in the application currently: [1, 10, 8453, 13370, 31337, 42161, 84532, 421614, 11155111, 11155420]
  • Allow the user to set a custom chain RPC endpoint for its connection configuration.
    • We only use this different chain RPC for devnets in terms of an upgrade to the Chain configuration. That means that when you connect your wallet (e.g., Metamask) and it doesn't have a network configured for chain ID 31337, it will accept the connection and prompt the user to add the network with the displayed configuration, thereby improving the UX. There are caveats to that, whether or not you add a custom RPC for the chain. For all other testnets and mainnets, the application will only use the custom RPC internally or the default publicly available RPC.
  • We notify the user to be aware of conflicting configurations when multiple connections use the same chain ID but different RPCs, by pointing the user to check their wallet's network to avoid sending transactions to the wrong one.
  • We notify the user when a selected connection is not healthy on startup. Not healthy usually means an unreachable endpoint.
  • On startup, when necessary, we notify and prompt the user to either select a connection or create one.

PS: The development was done using the cartesi-cli 2.0.0-alpha.26 that uses the rollups-node 2.0.0-alpha.9 underneath.
PS²: Just a heads-up: there will eventually be a "hardening" phase with the addition of tests.
PS³: This PR targets PR #431. Once merged, it will also facilitate review on 431.

closes issue #432.

…esign consistent.

* Move the toggle from the header to the settings-menu.
* Replace the default ConnectButton with a ConnectButton.Custom from Rainbowkit. Therefore, we can use Mantine components and keep the design aligned.
* It is pass down to the connection-provider. That way we can check information making a call to the node-rpc-api configured in the system and have accurate information in the system-config e.g (chain-id and node-version).
…rovider properties.

* To define wallet-provider information e.g. chain-id
* To decide if it is a system-mock connection and allow the app to behave accordingly.
…ly do not render connection-view if it is connected.
…s to contextual places.

* Simplify the connection-context state to be more derived driven than set direct objects.
* Add a new type Called DbNodeConnectionConfig that is a Required<T> usually a saved instance improving DX and avoiding casting through the code.
* Refactored the connection hooks to deal with the new structure and also update the components to send the expected parameters correctly.
* Moved functions around. Everything related to connections live under the connections folder.
* In case the wallet has a network to the saved chain-id and the user is using a custom rpc-endpoint an update is necessary in the wallet side. Either by updating the RPC manually or just deleting it and reconnecting the wallet.
* Due to position in the react three this change made unnecessary the need to wrap the form with query-client-provider just to make a simple call.
* Faster check and controlled status responses.
@vercel
Copy link

vercel bot commented Feb 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dave Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-arbitrum-mainnet Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-arbitrum-sepolia Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-base-mainnet Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-base-sepolia Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-mainnet Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-optimism-mainnet Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-optimism-sepolia Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-sepolia Ready Ready Preview, Comment Feb 23, 2026 11:18am
rollups-explorer-workshop Ready Ready Preview, Comment Feb 23, 2026 11:18am

Request Review

@socket-security
Copy link

socket-security bot commented Feb 14, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​types/​semver@​7.7.11001007581100

View full report

…-view.

* Apply refactoring on a couple of hooks that fetch same information. Extracted fetching logic to be a separate simple async function.
… modal.

* It is for either select an existing connection or create the first one.
@brunomenezes
Copy link
Collaborator Author

brunomenezes commented Feb 19, 2026

TBH I didn't like the connection UI very much. I think it could be simpler and more balanced. The style of a single square button with options like "Connection" and "Global" seems weird. The main information about the connection is the URL itself, and not the name or chain or version. Maybe in desktop UI the URL itself should be visible, more like what happens at https://playground.open-rpc.org

I included the UI mockups in the issue from the very beginning. I view it differently: as both the connection and theme toggle are usually settings you set and forget. Making them unnecessary to be visible at all times. However, you can quickly access these in the header and view relevant information about the connection without leaving the page. I think it makes sense to change some of the information displayed, though, i.e. remove [name, version chainid] and add [node-rpc-url, chain-rpc-url].

I will apply these changes, but let me know your thoughts.

PS: The playground.open-rpc-.org is a completely different application.

@brunomenezes
Copy link
Collaborator Author

@tuler, I pushed the changes regarding the read-only information in the settings menu. Also included a story for that reading view piece.

The reviewer needs to be an authenticated user to access.
Link: https://686ef65637ae42e8f97631f9-mhgoxadlzm.chromatic.com/?path=/story/components-settings-connectionsettings--default&globals=backgrounds.grid:!false

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an in-app “rollups-node connection” system that lets users create, persist (IndexedDB), validate, and switch between rollups-node endpoints, with UI entry via a new header settings menu.

Changes:

  • Introduces a connection domain (contexts/provider/hooks, IndexedDB repository, modal UI) to manage rollups-node connections persisted in the browser.
  • Rewires app providers (CartesiProvider/Wagmi/RainbowKit/React Query) to use the selected connection and support devnet chain RPC overrides for better wallet UX.
  • Adds a header settings menu that exposes connection info + “Manage” entrypoint and hosts the theme toggle.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds dexie, semver, and @types/semver dependencies/locks.
apps/dave/package.json Declares new runtime deps (dexie, semver) and types.
apps/dave/src/providers/Providers.tsx Wraps the app with ConnectionProvider and adds a startup loader while building the system connection.
apps/dave/src/providers/DataProvider.tsx Makes Cartesi + React Query depend on the selected connection and moves WalletProvider under it.
apps/dave/src/providers/WalletProvider.tsx Builds Wagmi config from the selected connection and supports devnet chain RPC overrides.
apps/dave/src/lib/supportedRollupsNode.ts Adds semver-based rollups-node version support checking.
apps/dave/src/lib/supportedChains.ts Adds chain-id support checking and devnet detection helper.
apps/dave/src/lib/urlUtils.ts Adds URL parsing/validation helper.
apps/dave/src/lib/transportClient.ts Allows passing viem HTTP transport options.
apps/dave/src/components/connection/* New connection persistence, state, hooks, modal + form + list UI, and node metadata fetch utilities.
apps/dave/src/components/settings/* New settings dropdown UI with connection summary and manage CTA.
apps/dave/src/components/layout/Layout.tsx Replaces header theme toggle with settings menu and uses new wallet connect component.
apps/dave/src/components/ConnectWallet.tsx New custom RainbowKit connect button UI.
apps/dave/src/components/ThemeToggle.tsx Updates toggle labels and accessibility attributes.
apps/dave/src/components/CopyButton.tsx Adds option to disable tooltip.
apps/dave/src/components/layout/PageLoader.tsx Adds full-page loader used during startup system connection build.
apps/dave/src/components/send/SendMenu.tsx Disables send actions when using the system mock connection.
apps/dave/src/components/application/ApplicationCard.tsx Hides send menu when using the system mock connection.
apps/dave/src/components/output/OutputView.tsx Removes debug logging.
apps/dave/src/providers/theme.ts / apps/dave/mantine.d.ts Adds additional icon size tokens to theme typing and values.
.github/workflows/chromatic.yaml Sets env vars for Chromatic runs (node URL + mock enabled).
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +6
import { Button, Group, Stack, Text } from "@mantine/core";
import { isNil } from "ramda";
import { useMemo, type FC } from "react";
import { useNodeConnection } from "../connection/hooks";
import CopyButton from "../CopyButton";

Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

This component uses React hooks (useMemo) and a client-only hook (useNodeConnection), but the file is missing the "use client" directive. In Next.js App Router this can cause a build/runtime error when the module is treated as a Server Component. Add "use client" at the top of the file.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +30
() => [
{
title: "Node RPC",
value: selectedNodeConnection.url,
},
{
title: "Chain RPC",
value: selectedNodeConnection.chain.rpcUrl,
},
],
[selectedNodeConnection],
);

if (isNil(selectedNodeConnection)) return "";
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

selectedNodeConnection can be undefined when no connection is selected yet, but useMemo dereferences selectedNodeConnection.url / .chain.rpcUrl before the nil-check. This will throw at runtime. Guard before building informations (or use optional chaining) and return null instead of an empty string when there is no selected connection.

Suggested change
() => [
{
title: "Node RPC",
value: selectedNodeConnection.url,
},
{
title: "Chain RPC",
value: selectedNodeConnection.chain.rpcUrl,
},
],
[selectedNodeConnection],
);
if (isNil(selectedNodeConnection)) return "";
() => {
if (isNil(selectedNodeConnection)) {
return [];
}
return [
{
title: "Node RPC",
value: selectedNodeConnection.url,
},
{
title: "Chain RPC",
value: selectedNodeConnection.chain.rpcUrl,
},
];
},
[selectedNodeConnection],
);
if (isNil(selectedNodeConnection)) return null;

Copilot uses AI. Check for mistakes.
Comment on lines +355 to +356
const matchChain =
config.chain?.toString() === chainId.toString();
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

matchChain compares config.chain?.toString() against the returned chainId. Since config.chain is an object, this will never match ("[object Object]"), so matchChain will be incorrect. Compare config.chain.id (or config.chain?.id) to chainId instead.

Suggested change
const matchChain =
config.chain?.toString() === chainId.toString();
const matchChain = config.chain?.id === chainId;

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +46
<Menu.Target>
<ActionIcon
size={buttonSize}
onClick={(evt) => {
evt.stopPropagation();
evt.preventDefault();
handlers.toggle();
}}
>
<TbSettings size={theme.other.mdIconSize} />
</ActionIcon>
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The settings ActionIcon has no accessible name, so screen readers will announce it as an unlabeled button. Add an aria-label (e.g. "Settings") to the ActionIcon.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +22
import {
ActionIcon,
Badge,
Button,
Card,
Group,
Stack,
Switch,
Text,
Tooltip,
useMantineTheme,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { pathOr } from "ramda";
import { isNilOrEmpty } from "ramda-adjunct";
import { Activity, type FC } from "react";
import { TbRefresh } from "react-icons/tb";
import { isDevnet } from "../../lib/supportedChains";
import CopyButton from "../CopyButton";
import { useGetNodeInformation, useNodeConnection } from "./hooks";
import type { ConnectionNetworkStatus, DbNodeConnectionConfig } from "./types";

Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

ConnectionView uses client-side hooks (useGetNodeInformation, useNodeConnection) but the file is missing the "use client" directive. In Next.js App Router this can break compilation by treating the module as a Server Component. Add "use client" at the top.

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +98
.catch((reason) => {
if (abortController.signal.aborted) {
console.info(
`Skipping promise catch handling: ${abortController.signal.reason}`,
);
}
setResult({
status: "error",
error: reason,
});
});
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

In useChainRpcHealthCheck, the catch handler logs when the request was aborted but still calls setResult({status: 'error', ...}) anyway. This can overwrite the next request’s state after url/chain changes. Return early in the aborted case (similar to the then branch) so aborted requests don’t update state.

Copilot uses AI. Check for mistakes.
selectedConnection?.type === "system_mock"
? queryClient
: new QueryClient(),
[selectedConnection?.type],
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

QueryClient is only recreated when selectedConnection?.type changes. Switching between two real connections of the same type (e.g. user→user) will keep the same client/cache and can show stale data from the previous node. Include selectedConnection?.id in the memo deps (or otherwise reset/clear the cache) so connection changes always isolate query results.

Suggested change
[selectedConnection?.type],
[selectedConnection?.type, selectedConnection?.id],

Copilot uses AI. Check for mistakes.
if (!isValidVersion) {
return {
status: "not-valid-semantic-versioning",
error: new Error(` ${nodeVersion} is not a valid semantic version`),
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The error message for invalid semver has a leading space (" ${nodeVersion} ..."), which results in awkward formatting in UI/notifications. Remove the leading whitespace in the template string.

Suggested change
error: new Error(` ${nodeVersion} is not a valid semantic version`),
error: new Error(`${nodeVersion} is not a valid semantic version`),

Copilot uses AI. Check for mistakes.
Comment on lines +126 to +140
section: {
height: "100%",
},
}}
pr={hasBalanceToShow ? 0 : ""}
rightSection={
hasBalanceToShow ? (
<Badge radius={0} h="inherit">
<Text fw="bold" size="sm">
{account.displayBalance}
</Text>
</Badge>
) : (
""
)
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

pr is set to an empty string when there’s no balance (pr={hasBalanceToShow ? 0 : ''}). An empty string becomes invalid CSS and can cause inconsistent styling; use undefined/omit the prop instead (or always pass a valid spacing value).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting review

Development

Successfully merging this pull request may close these issues.

Config: Add rollups-node connection

3 participants