Feat/veashi scanner#461
Conversation
✅ Deploy Preview for veascan ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for veashi-scan ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAdds two monorepo packages: Changesveashi-envio-yaho Envio Indexer
veashi-scanner Cross-Chain Message Explorer
Sequence Diagram(s)sequenceDiagram
participant User
participant Home
participant useMessageScanner
participant scannerCache
participant fetchMessagesFromEnvio
participant getMessageDispatchedLogs
User->>Home: set filters and block range
Home->>useMessageScanner: sourceChain, destChain, fromBlock, toBlock
useMessageScanner->>scannerCache: getCachedMessages
useMessageScanner->>fetchMessagesFromEnvio: fetchMessagesFromEnvio
alt Envio unavailable
useMessageScanner->>scannerCache: getUncachedSubranges
useMessageScanner->>getMessageDispatchedLogs: getMessageDispatchedLogs
useMessageScanner->>scannerCache: updateCache
end
useMessageScanner->>Home: messages, isScanning, blockRange, error
Estimated code review effort: 5 (Critical) | ~120 minutesSuggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Comment |
There was a problem hiding this comment.
Actionable comments posted: 19
🧹 Nitpick comments (7)
veashi-scanner/app/globals.css (2)
1-1: Replace CSS@importwithnext/font/googlefor better performance and privacy.The project uses Next.js 14 with App Router, which provides built-in font optimization via
next/font/google. This eliminates external requests to Google's servers, automatically self-hosts fonts at build time, prevents layout shift with optimized fallbacks, and removes the rendering-blocking behavior of CSS@import.Move the DM Sans and JetBrains Mono font declarations from
globals.cssto a dedicated font configuration file (e.g.,app/fonts.ts) usingnext/font/google, then import and use them inlayout.tsx.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/app/globals.css` at line 1, Replace the CSS `@import` statement in globals.css that loads DM Sans and JetBrains Mono fonts from Google Fonts with Next.js font optimization. Create a new font configuration file (such as app/fonts.ts) that uses the localFont or google function from next/font/google to declare the DM Sans and JetBrains Mono font families with their respective weights (400, 500, 600, 700 for DM Sans and 400, 500, 600 for JetBrains Mono). Export these font objects from the configuration file, then import them in app/layout.tsx and apply them using their className property in the appropriate elements (typically DM Sans for body/general content and JetBrains Mono for code). Finally, remove the `@import` url() line from globals.css entirely.
2-3: Use bare import paths instead of relative node_modules paths.The current relative paths (
../node_modules/@kleros/ui-components-library/...) are safe since the repository explicitly usesnodeLinker: node-modulesin.yarnrc.yml. However, bare imports are more idiomatic for Tailwind CSS v4 and would remain compatible if the linker configuration ever changes.Suggested improvement
-@import "../node_modules/@kleros/ui-components-library/dist/assets/theme.css"; -@source "../node_modules/@kleros/ui-components-library"; +@import "`@kleros/ui-components-library/dist/assets/theme.css`"; +@source "`@kleros/ui-components-library`";🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/app/globals.css` around lines 2 - 3, Replace the relative node_modules paths in the import and source statements with bare import paths. Change `../node_modules/@kleros/ui-components-library/dist/assets/theme.css` to `@kleros/ui-components-library/dist/assets/theme.css` in the `@import` statement and change `../node_modules/@kleros/ui-components-library` to `@kleros/ui-components-library` in the `@source` statement to follow the more idiomatic Tailwind CSS v4 convention and ensure compatibility if the node linker configuration changes in the future.veashi-scanner/README.md (1)
1-61: 💤 Low valueConsider adding a "Quick Start" or "How to Use" section explaining the scanner's features.
The README covers installation and configuration, but doesn't document what users will see or do once the app is running (e.g., browsing message list, searching by transaction hash, viewing bridge confirmations, filtering by chain/threshold). Adding a brief "Features" or "Usage" section would improve discoverability and set expectations for first-time users.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/README.md` around lines 1 - 61, Add a new "Features" or "Usage" section to the README after the "Running locally" section that documents what users can do with the Veashi Scanner once it is running. The section should explain key features such as browsing the message list dispatched through Hashi's Yaho contract, searching or filtering messages by transaction hash, viewing bridge confirmation status and progress toward the required threshold, inspecting execution status across multiple bridge providers, and filtering results by source/destination chains. This will help first-time users understand the scanner's capabilities and how to navigate the interface without requiring them to discover features through trial and error.veashi-envio-yaho/test/EventHandlers.test.ts (1)
49-61: ⚡ Quick winAdd an explicit
txHashassertion in the main mapping test.Line 49 onward validates nearly all persisted fields, but
txHashis currently unverified even though the handler depends ontransaction_fields.hash. Adding this catches config/handler/schema drift early.Suggested test addition
expect(entity.messageId).toBe("1"); + expect(entity.txHash).toMatch(/^0x[a-fA-F0-9]{64}$/); expect(entity.sourceChainId).toBe(42161n);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-envio-yaho/test/EventHandlers.test.ts` around lines 49 - 61, The test assertions in EventHandlers.test.ts are missing a verification for the txHash field, even though the handler code depends on transaction_fields.hash. Add an explicit expect statement that asserts the txHash property of the entity to match the expected transaction hash value, placing it among the other field assertions in the sequence that validates the entity's persisted fields.veashi-scanner/components/BridgeStatusCard.tsx (1)
33-35: ⚡ Quick winRemove the duplicated
BridgeStatusCardPropsdeclaration.Line 33 re-declares the same interface already declared at Line 6. This can drift over time due to interface merging and makes the type contract harder to maintain.
Suggested cleanup
-interface BridgeStatusCardProps { - status: BridgeStatus; -}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/components/BridgeStatusCard.tsx` around lines 33 - 35, The BridgeStatusCardProps interface is declared twice in the file, creating a duplicate that can cause type drift and maintenance issues. Remove the duplicate BridgeStatusCardProps interface declaration and retain only the original one to maintain a single source of truth for the interface contract.veashi-scanner/components/tx/cards/DetailsCard.tsx (1)
33-50: ⚡ Quick winExtract execution status mapping to a single derived object.
The nested ternaries duplicate branching for both dot color and label, which is harder to maintain and easy to desync.
Suggested refactor
+ const executionMeta = execLoading + ? { dotClass: "bg-purple-400 animate-pulse", text: "Checking…" } + : execStatus === "executed" + ? { dotClass: "bg-green-400", text: "Executed" } + : execStatus === "failed" + ? { dotClass: "bg-red-400", text: "Failed" } + : { dotClass: "bg-amber-400 animate-pulse", text: "Pending" }; ... <MetaRow label="Execution"> <div className="flex items-center gap-1.5"> - {execLoading ? ( - <span className="w-1.5 h-1.5 rounded-full bg-purple-400 animate-pulse inline-block" /> - ) : execStatus === "executed" ? ( - <span className="w-1.5 h-1.5 rounded-full bg-green-400 inline-block" /> - ) : execStatus === "failed" ? ( - <span className="w-1.5 h-1.5 rounded-full bg-red-400 inline-block" /> - ) : ( - <span className="w-1.5 h-1.5 rounded-full bg-amber-400 animate-pulse inline-block" /> - )} - <span className="text-sm font-mono"> - {execLoading - ? "Checking…" - : execStatus === "executed" - ? "Executed" - : execStatus === "failed" - ? "Failed" - : "Pending"} - </span> + <span className={`w-1.5 h-1.5 rounded-full inline-block ${executionMeta.dotClass}`} /> + <span className="text-sm font-mono">{executionMeta.text}</span> </div> </MetaRow>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/components/tx/cards/DetailsCard.tsx` around lines 33 - 50, The execution status display in the DetailsCard component contains duplicated nested ternaries for both the indicator dot color and status label text, which makes it difficult to maintain and easy to desync. Create a single derived object that maps the execution state (determined by execLoading and execStatus variables) to an object containing both the className for the indicator dot and the label text. Then replace both sets of nested ternaries with references to the properties of this single status mapping object, so the branching logic only exists in one place.Source: Linters/SAST tools
veashi-scanner/hooks/useMessageScanner.ts (1)
125-291: 🏗️ Heavy liftExtract route scanning into smaller units to reduce failure-prone complexity.
This block is heavily nested and already flagged for cognitive complexity/nesting thresholds. Splitting into helpers (
resolveScanRange,scanViaEnvio,scanViaRpcChunks,applyRouteResult) will make cancellation, cache invariants, and error handling safer to maintain.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/hooks/useMessageScanner.ts` around lines 125 - 291, The scan function contains deeply nested logic that makes it difficult to maintain and prone to errors in cancellation handling and cache management. Extract the route scanning logic within the outer loop (where targetDestIds are processed) into smaller helper functions: create resolveScanRange to handle determining startBlock and endBlock based on input parameters and current block number, create scanViaEnvio to handle the Envio indexer fetch and filtering logic, create scanViaRpcChunks to handle the RPC fallback logic with chunked scanning and the nested loops, and create applyRouteResult to handle updating cache and setting messages from results. Each helper should accept necessary parameters (srcId, dstId, chainConfig, publicClient, displayRange, scanRange, signal, etc.) and return results to be processed by the main loop. This refactoring will reduce nesting depth, improve error handling clarity, and make cancellation logic easier to follow.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@veashi-scanner/app/tx/`[...params]/page.tsx:
- Around line 13-15: The chainId derivation from segments[0] can result in NaN
when Number() fails to convert the value, which then gets passed to TxDetail and
useTransaction causing invalid behavior. Add validation to ensure that
Number(segments[0]) produces a valid number before assigning it to chainId; if
the conversion results in NaN, treat chainId as null instead. This validation
should be applied wherever chainId is parsed from the segments array (including
the location at line 50 referenced in the comment).
In `@veashi-scanner/components/BridgeStatusCard.tsx`:
- Around line 40-55: The getTimeAgo function assumes timestamps are in
milliseconds (dividing by 1000), but blockchain event timestamps are in seconds,
causing a ~1000x overstatement of elapsed time when blockchain data is used. Add
JSDoc documentation to the BridgeStatus type clarifying that timestamp should be
in milliseconds, and when populating bridgeStatuses from blockchain data in the
TODO section, ensure you multiply blockchain timestamps (which are in seconds)
by 1000 before assigning to status.timestamp so the getTimeAgo function receives
the correct unit.
In `@veashi-scanner/components/MessagesTable.tsx`:
- Around line 73-76: The table row element (the `<tr>` with the `onClick`
handler and hover-lift class) is only accessible via mouse clicks, preventing
keyboard users from navigating to transaction details. To fix this, add keyboard
accessibility to the row by: adding a tabIndex attribute to make it focusable in
the keyboard navigation order, adding an onKeyDown handler that triggers the
same onClick action when Enter or Space keys are pressed, and adding
role="button" to semantically indicate the row is interactive. Make sure the
keyboard event handler checks for the appropriate key codes and calls the same
onClick callback function.
- Around line 54-57: The key for the MessageRow component in the messages.map
function uses only message.txHash, which creates collisions when different
chains have the same transaction hash, causing React to reuse incorrect row
state. Modify the key prop to include both the chain identifier and the
transaction hash (for example, by combining message.chainId or similar chain
property with message.txHash using a delimiter like a colon or underscore) to
ensure each row has a globally unique key across all chains.
In `@veashi-scanner/components/StatusIndicator.tsx`:
- Around line 29-31: The StatusIndicator function computes the percentage by
dividing current by required without checking if required is zero, which would
result in Infinity or NaN and break the progress display. Add a guard check
before the percentage calculation on line 30 to handle the case when required
equals zero. If required is zero, you should either return a default percentage
value (such as 0) or handle it appropriately for the status computation. This
guard should be placed before the Math.min calculation for the percentage
variable to ensure valid numeric values are used downstream.
In `@veashi-scanner/components/tx/cards/AdaptersCard.tsx`:
- Around line 53-61: The map function iterating over pairedData uses array index
idx as the key, which is unstable and can cause React to render stale UI/state
if the group ordering changes. Replace key={idx} with a stable identifier
derived from the pair object itself, such as a unique id, bridge name, or other
property that uniquely identifies each adapter group independent of its position
in the array.
In `@veashi-scanner/components/tx/cards/BridgeSummaryCard.tsx`:
- Around line 11-23: The `getBridgeName()` function returns lowercase enum
values like "ccip", "lz", "vea", but these are being compared against the
uppercase `Bridge` type literals in the `knownBridges` array ("CCIP",
"LayerZero", "Vea", "DeBridge"), causing all comparisons to fail. Fix this by
normalizing the enum output to match the uppercase format before adding to the
`bridgeNames` Set. Specifically, when processing the results from
`getBridgeName()` calls in both the adapters and reporters loops, transform the
returned values to uppercase or map them to their corresponding `Bridge` type
literal equivalents before calling `bridgeNames.add()`. Additionally, note that
`getBridgeName()` does not currently support DeBridge detection, making the
"DeBridge" entry in the `knownBridges` array unreachable unless that function is
also updated to handle DeBridge cases.
In `@veashi-scanner/components/tx/cards/TxHeaderCard.tsx`:
- Around line 44-47: The messageId display in TxHeaderCard always appends an
ellipsis even when the messageId is shorter than 18 characters, which is
misleading. Modify the rendering logic to conditionally display the ellipsis
only when message.messageId.length is greater than 18 characters. Keep the
slice(0, 18) operation but wrap the ellipsis character in a conditional
expression that checks the actual length of message.messageId before appending
it.
In `@veashi-scanner/hooks/useAdapters.ts`:
- Line 17: The guard clause on line 17 of the useAdapters hook is checking
`message.nonce === undefined` but the actual code usage at line 36 calls
`getHash(domain, id)` which depends on `messageId`. Change the guard condition
to check `message.messageId === undefined` instead of `message.nonce ===
undefined` so that the early return prevents execution when the property that's
actually needed is missing, avoiding errors in the adapter polling logic.
In `@veashi-scanner/hooks/useExecutionStatus.ts`:
- Around line 31-36: In the useExecutionStatus hook's readContract call to the
executed function, the args array currently passes message.messageId as a
string, but the executed function expects a uint256 argument. Cast
message.messageId to BigInt by wrapping it with the BigInt() constructor in the
args property to ensure type compatibility.
In `@veashi-scanner/hooks/useMessageScanner.ts`:
- Around line 199-214: The issue is that when fetchMessagesFromEnvio returns
results with a limit of 10, the code calls updateCache with the full scanRange,
incorrectly marking the entire range as scanned even though only a partial
result was returned. This prevents RPC fallback from discovering older messages.
Fix this by not marking scanRange as covered when only a partial Envio query
result is obtained. Either remove the updateCache call for partial results, or
modify it to only cache the range that was actually covered by the returned
messages. Also ensure the continue statement does not skip RPC fallback for
uncovered portions of scanRange.
- Around line 97-105: In the useMessageScanner hook, the abort logic for
aborting `abortRef.current` and creating a new AbortController is placed after
the early return condition that checks if sourceChain equals destinationChain.
Move the abort logic (the if statement checking abortRef.current and the
AbortController instantiation) to execute before the early return condition, so
that any in-progress scan is properly aborted before returning early when chains
match, preventing stale async results from repopulating after filter changes.
In `@veashi-scanner/hooks/useTransaction.ts`:
- Around line 47-53: The fetchMessageByTxHash call in the useTransaction hook is
not wrapped in error handling, causing the hook to exit prematurely if an error
is thrown, preventing the RPC fallback branch from executing. Wrap the
fetchMessageByTxHash call and the conditional block that checks the result (the
if statement checking envioMsg and !cancelled) in a try-catch block, allowing
any errors to be caught so that execution can continue to the fallback branch
instead of leaving the request in a stuck state.
In `@veashi-scanner/lib/envioClient.ts`:
- Around line 15-21: The TX_HASH_QUERY constant uses the _ilike operator for
filtering by txHash, but _ilike is a pattern-matching operator that supports SQL
wildcards and is inappropriate for exact transaction hash lookups. Replace the
_ilike operator with _eq in the MessageDispatched where clause to ensure
exact-match filtering for the transaction hash, which is semantically correct
and more efficient for this use case.
In `@veashi-scanner/lib/utils.ts`:
- Around line 32-41: Add per-request timeouts to the RPC fetch call in the
eth_getTransactionByHash request to prevent indefinite hangs that can leave
transaction search stuck in loading state. Implement an AbortController with a
timeout (e.g., 5-10 seconds) and pass the abort signal to the fetch options,
ensuring the request is automatically aborted if it exceeds the timeout
duration. This will allow the system to fail fast and move on rather than
waiting indefinitely for unresponsive RPC endpoints.
- Around line 49-50: The hash equality check in the condition comparing
data.result.hash === hash is case-sensitive, but RPC responses are typically
lowercase while the input hash parameter may be mixed-case, causing valid hashes
to fail the equality check. Normalize both the data.result.hash and the hash
variable to lowercase by using the toLowerCase() method before performing the
=== comparison to ensure case-insensitive matching.
In `@veashi-scanner/lib/veashiHelpers.ts`:
- Around line 24-39: The getBridgeName helper function is incomplete and does
not check for DeBridge routes despite DeBridge being defined in the Bridges enum
and scanner types. Add a DeBridge check in the getBridgeName function following
the same pattern as the existing CCIP, LayerZero (LZ), and Vea checks. Insert a
new conditional block that uses isMatch to compare adapterAddress and
reporterAddress against route.debridgeAdapter and route.debridgeReporter, and
return Bridges.DEBRIDGE when matched, placing this check before the final return
null statement to maintain consistency with the other bridge checks.
In `@veashi-scanner/package.json`:
- Around line 15-17: The eslint-config-next dependency version is misaligned
with the next package version. Update the eslint-config-next version to major
version 14 to match next@14. Check the package.json file at line range 15-17
(where next is declared at version 14) and at line range 27-27 (where
eslint-config-next is declared), and ensure eslint-config-next version is set to
14.x to maintain compatibility and prevent linting configuration issues.
In `@veashi-scanner/README.md`:
- Around line 51-59: Remove the table row for the
`NEXT_PUBLIC_HASURA_ADMIN_SECRET` environment variable from the README
environment variables section. This variable is not actually used anywhere in
the codebase, and as noted in the envioClient.ts file, no Hasura admin secret is
required or should ever be sent to the browser. Removing this entry will prevent
misleading users during setup. The NEXT_PUBLIC_ENVIO_URL entry should remain as
it is correctly implemented and documented.
---
Nitpick comments:
In `@veashi-envio-yaho/test/EventHandlers.test.ts`:
- Around line 49-61: The test assertions in EventHandlers.test.ts are missing a
verification for the txHash field, even though the handler code depends on
transaction_fields.hash. Add an explicit expect statement that asserts the
txHash property of the entity to match the expected transaction hash value,
placing it among the other field assertions in the sequence that validates the
entity's persisted fields.
In `@veashi-scanner/app/globals.css`:
- Line 1: Replace the CSS `@import` statement in globals.css that loads DM Sans
and JetBrains Mono fonts from Google Fonts with Next.js font optimization.
Create a new font configuration file (such as app/fonts.ts) that uses the
localFont or google function from next/font/google to declare the DM Sans and
JetBrains Mono font families with their respective weights (400, 500, 600, 700
for DM Sans and 400, 500, 600 for JetBrains Mono). Export these font objects
from the configuration file, then import them in app/layout.tsx and apply them
using their className property in the appropriate elements (typically DM Sans
for body/general content and JetBrains Mono for code). Finally, remove the
`@import` url() line from globals.css entirely.
- Around line 2-3: Replace the relative node_modules paths in the import and
source statements with bare import paths. Change
`../node_modules/@kleros/ui-components-library/dist/assets/theme.css` to
`@kleros/ui-components-library/dist/assets/theme.css` in the `@import` statement
and change `../node_modules/@kleros/ui-components-library` to
`@kleros/ui-components-library` in the `@source` statement to follow the more
idiomatic Tailwind CSS v4 convention and ensure compatibility if the node linker
configuration changes in the future.
In `@veashi-scanner/components/BridgeStatusCard.tsx`:
- Around line 33-35: The BridgeStatusCardProps interface is declared twice in
the file, creating a duplicate that can cause type drift and maintenance issues.
Remove the duplicate BridgeStatusCardProps interface declaration and retain only
the original one to maintain a single source of truth for the interface
contract.
In `@veashi-scanner/components/tx/cards/DetailsCard.tsx`:
- Around line 33-50: The execution status display in the DetailsCard component
contains duplicated nested ternaries for both the indicator dot color and status
label text, which makes it difficult to maintain and easy to desync. Create a
single derived object that maps the execution state (determined by execLoading
and execStatus variables) to an object containing both the className for the
indicator dot and the label text. Then replace both sets of nested ternaries
with references to the properties of this single status mapping object, so the
branching logic only exists in one place.
In `@veashi-scanner/hooks/useMessageScanner.ts`:
- Around line 125-291: The scan function contains deeply nested logic that makes
it difficult to maintain and prone to errors in cancellation handling and cache
management. Extract the route scanning logic within the outer loop (where
targetDestIds are processed) into smaller helper functions: create
resolveScanRange to handle determining startBlock and endBlock based on input
parameters and current block number, create scanViaEnvio to handle the Envio
indexer fetch and filtering logic, create scanViaRpcChunks to handle the RPC
fallback logic with chunked scanning and the nested loops, and create
applyRouteResult to handle updating cache and setting messages from results.
Each helper should accept necessary parameters (srcId, dstId, chainConfig,
publicClient, displayRange, scanRange, signal, etc.) and return results to be
processed by the main loop. This refactoring will reduce nesting depth, improve
error handling clarity, and make cancellation logic easier to follow.
In `@veashi-scanner/README.md`:
- Around line 1-61: Add a new "Features" or "Usage" section to the README after
the "Running locally" section that documents what users can do with the Veashi
Scanner once it is running. The section should explain key features such as
browsing the message list dispatched through Hashi's Yaho contract, searching or
filtering messages by transaction hash, viewing bridge confirmation status and
progress toward the required threshold, inspecting execution status across
multiple bridge providers, and filtering results by source/destination chains.
This will help first-time users understand the scanner's capabilities and how to
navigate the interface without requiring them to discover features through trial
and error.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 04a016ef-de24-484c-9398-1e59984422cf
⛔ Files ignored due to path filters (9)
veashi-scanner/app/favicon.icois excluded by!**/*.icoveashi-scanner/public/file.svgis excluded by!**/*.svgveashi-scanner/public/globe.svgis excluded by!**/*.svgveashi-scanner/public/image.pngis excluded by!**/*.pngveashi-scanner/public/logo.pngis excluded by!**/*.pngveashi-scanner/public/next.svgis excluded by!**/*.svgveashi-scanner/public/vercel.svgis excluded by!**/*.svgveashi-scanner/public/window.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (56)
.gitignorepackage.jsonveashi-envio-yaho/.env.exampleveashi-envio-yaho/README.mdveashi-envio-yaho/abis/Yaho.jsonveashi-envio-yaho/config.yamlveashi-envio-yaho/envio-env.d.tsveashi-envio-yaho/jest.config.tsveashi-envio-yaho/package.jsonveashi-envio-yaho/schema.graphqlveashi-envio-yaho/src/EventHandlers.tsveashi-envio-yaho/test/EventHandlers.test.tsveashi-envio-yaho/tsconfig.jsonveashi-scanner/README.mdveashi-scanner/app/globals.cssveashi-scanner/app/layout.tsxveashi-scanner/app/page.tsxveashi-scanner/app/tx/[...params]/page.tsxveashi-scanner/components/BridgeBadge.tsxveashi-scanner/components/BridgeStatusCard.tsxveashi-scanner/components/ChainBadge.tsxveashi-scanner/components/ChainFilterPanel.tsxveashi-scanner/components/Header.tsxveashi-scanner/components/MessagesTable.tsxveashi-scanner/components/Pagination.tsxveashi-scanner/components/SearchBar.tsxveashi-scanner/components/StatusIndicator.tsxveashi-scanner/components/tx/SectionLabel.tsxveashi-scanner/components/tx/TxDetailContent.tsxveashi-scanner/components/tx/cards/AdaptersCard.tsxveashi-scanner/components/tx/cards/AddressCard.tsxveashi-scanner/components/tx/cards/BridgeSummaryCard.tsxveashi-scanner/components/tx/cards/ChainRouteCard.tsxveashi-scanner/components/tx/cards/DetailsCard.tsxveashi-scanner/components/tx/cards/SectionCard.tsxveashi-scanner/components/tx/cards/ThresholdCard.tsxveashi-scanner/components/tx/cards/TxHeaderCard.tsxveashi-scanner/eslint.config.mjsveashi-scanner/hooks/useAdapters.tsveashi-scanner/hooks/useDebounce.tsveashi-scanner/hooks/useExecutionStatus.tsveashi-scanner/hooks/useMessageScanner.tsveashi-scanner/hooks/useTransaction.tsveashi-scanner/lib/chains.tsveashi-scanner/lib/envioClient.tsveashi-scanner/lib/hashi.tsveashi-scanner/lib/mock-data.tsveashi-scanner/lib/scannerCache.tsveashi-scanner/lib/types.tsveashi-scanner/lib/utils.tsveashi-scanner/lib/veashiHelpers.tsveashi-scanner/next-env.d.tsveashi-scanner/next.config.mjsveashi-scanner/package.jsonveashi-scanner/postcss.config.mjsveashi-scanner/tsconfig.json
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
veashi-scanner/pages/TxPage.tsx (1)
13-15:⚠️ Potential issue | 🟠 Major | ⚡ Quick winValidate parsed
chainIdbefore callingTxDetail.
Number(segments[0])can beNaN. In that casehasChainIdis still true, soTxDetailruns with an invalidchainId, anduseTransactionexits early without clearing loading state (infinite loading UI).Suggested change
- const hasChainId = segments.length >= 2; - const chainId = hasChainId ? Number(segments[0]) : null; + const hasChainId = segments.length >= 2; + const parsedChainId = hasChainId ? Number(segments[0]) : null; + const chainId = + parsedChainId !== null && Number.isInteger(parsedChainId) && parsedChainId > 0 ? parsedChainId : null; const txHash = hasChainId ? segments[1] : segments[0]; @@ - ) : ( - <TxDetail chainId={chainId!} txHash={txHash} /> + ) : chainId === null ? ( + <NoChainIdCard /> + ) : ( + <TxDetail chainId={chainId} txHash={txHash} /> )}Also applies to: 50-50
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/pages/TxPage.tsx` around lines 13 - 15, The chainId parsing in TxPage.tsx has a validation issue where Number(segments[0]) can return NaN, but hasChainId remains true based only on the segments length check. This causes TxDetail to be called with an invalid chainId (NaN), which makes useTransaction exit early without clearing the loading state. Fix this by validating that the parsed chainId is actually a valid number (not NaN) before setting hasChainId to true. The validation should check both that segments.length >= 2 AND that Number(segments[0]) is not NaN. Apply this same fix at the second occurrence around line 50.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@veashi-scanner/globals.css`:
- Line 3: The Tailwind v4 at-rules (`@source`, `@theme`, and `@custom-variant`) used
in globals.css are not recognized by the stylelint-config-standard-scss
configuration, causing linting failures. Configure the stylelint rule for
at-rule-no-unknown by adding an ignoreAtRules array in .stylelintrc.json that
includes the three Tailwind v4 at-rules: `@source`, `@theme`, and `@custom-variant`.
This allows stylelint to skip validation of these vendor-specific at-rules while
maintaining linting for other rules.
- Around line 2-3: Replace the hardcoded ./node_modules/ paths in the `@import`
and `@source` directives with bare package import paths to ensure compatibility
with Yarn workspaces (including PnP linkers) and standard Vite/Node module
resolution. Change the `@import` statement to use the bare path
"`@kleros/ui-components-library/dist/assets/theme.css`" and change the `@source`
directive to use the bare path "`@kleros/ui-components-library`", removing the
./node_modules/ prefix from both lines.
---
Duplicate comments:
In `@veashi-scanner/pages/TxPage.tsx`:
- Around line 13-15: The chainId parsing in TxPage.tsx has a validation issue
where Number(segments[0]) can return NaN, but hasChainId remains true based only
on the segments length check. This causes TxDetail to be called with an invalid
chainId (NaN), which makes useTransaction exit early without clearing the
loading state. Fix this by validating that the parsed chainId is actually a
valid number (not NaN) before setting hasChainId to true. The validation should
check both that segments.length >= 2 AND that Number(segments[0]) is not NaN.
Apply this same fix at the second occurrence around line 50.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f15a5a1e-bebf-4ca5-9987-803f1c082b9e
📒 Files selected for processing (22)
veashi-scanner/Layout.tsxveashi-scanner/README.mdveashi-scanner/components/BridgeStatusCard.tsxveashi-scanner/components/ChainFilterPanel.tsxveashi-scanner/components/Header.tsxveashi-scanner/components/MessagesTable.tsxveashi-scanner/components/Pagination.tsxveashi-scanner/components/SearchBar.tsxveashi-scanner/components/StatusIndicator.tsxveashi-scanner/eslint.config.mjsveashi-scanner/globals.cssveashi-scanner/index.htmlveashi-scanner/lib/envioClient.tsveashi-scanner/main.tsxveashi-scanner/package.jsonveashi-scanner/pages/Home.tsxveashi-scanner/pages/TxPage.tsxveashi-scanner/tsconfig.app.jsonveashi-scanner/tsconfig.jsonveashi-scanner/tsconfig.node.jsonveashi-scanner/vite-env.d.tsveashi-scanner/vite.config.ts
💤 Files with no reviewable changes (5)
- veashi-scanner/pages/Home.tsx
- veashi-scanner/components/StatusIndicator.tsx
- veashi-scanner/components/BridgeStatusCard.tsx
- veashi-scanner/components/Pagination.tsx
- veashi-scanner/components/ChainFilterPanel.tsx
✅ Files skipped from review due to trivial changes (5)
- veashi-scanner/vite-env.d.ts
- veashi-scanner/tsconfig.node.json
- veashi-scanner/tsconfig.app.json
- veashi-scanner/Layout.tsx
- veashi-scanner/eslint.config.mjs
🚧 Files skipped from review as they are similar to previous changes (3)
- veashi-scanner/components/MessagesTable.tsx
- veashi-scanner/components/SearchBar.tsx
- veashi-scanner/lib/envioClient.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
veashi-scanner/lib/veashiHelpers.ts (1)
56-64: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueType assertion is functionally correct but could be more defensive.
The SonarCloud warning is a false positive in this context—the assertion is intentionally widening the type to access runtime properties that the SDK's TypeScript definition omits. However, using
inoperator checks would be more robust against SDK changes and eliminate the static analysis noise:Optional improvement
- // Check DeBridge. The SDK's route type omits these fields even though the - // route data includes them, so we access them through a narrow cast. - const deBridgeRoute = route as typeof route & { deBridgeAdapter?: string; deBridgeReporter?: string }; - if ( - isMatch(adapterAddress, deBridgeRoute.deBridgeAdapter) || - isMatch(reporterAddress, deBridgeRoute.deBridgeReporter) - ) { - return Bridges.DEBRIDGE; - } + // Check DeBridge. The SDK's route type omits these fields even though the + // route data includes them, so we check for their presence at runtime. + const routeRecord = route as Record<string, unknown>; + const deBridgeAdapter = typeof routeRecord.deBridgeAdapter === "string" ? routeRecord.deBridgeAdapter : undefined; + const deBridgeReporter = typeof routeRecord.deBridgeReporter === "string" ? routeRecord.deBridgeReporter : undefined; + if (isMatch(adapterAddress, deBridgeAdapter) || isMatch(reporterAddress, deBridgeReporter)) { + return Bridges.DEBRIDGE; + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@veashi-scanner/lib/veashiHelpers.ts` around lines 56 - 64, The type assertion for deBridgeRoute is functionally correct but can be made more defensive. Instead of using a type assertion to access the deBridgeAdapter and deBridgeReporter properties, use the `in` operator to check if these properties actually exist on the route object before accessing them. This approach will be more robust against SDK changes and will eliminate the static analysis warnings. Replace the type assertion line and modify the conditional checks to use `in` operator checks (e.g., 'deBridgeAdapter' in route and 'deBridgeReporter' in route) before accessing these properties.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@veashi-scanner/lib/utils.ts`:
- Line 57: The hash comparison on line 57 normalizes the input hash but compares
it directly against the potentially unnormalized data.result.hash from the RPC
response. To ensure a proper case-insensitive comparison, normalize
data.result.hash to lowercase before comparing it with normalizedHash.
Additionally, replace the explicit null check with optional chaining syntax
(using the ?. operator) to address the SonarCloud hint and make the code more
concise while maintaining the same null-safety.
---
Nitpick comments:
In `@veashi-scanner/lib/veashiHelpers.ts`:
- Around line 56-64: The type assertion for deBridgeRoute is functionally
correct but can be made more defensive. Instead of using a type assertion to
access the deBridgeAdapter and deBridgeReporter properties, use the `in`
operator to check if these properties actually exist on the route object before
accessing them. This approach will be more robust against SDK changes and will
eliminate the static analysis warnings. Replace the type assertion line and
modify the conditional checks to use `in` operator checks (e.g.,
'deBridgeAdapter' in route and 'deBridgeReporter' in route) before accessing
these properties.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9f567259-0c79-4610-8111-1e0141fa8760
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (11)
package.jsonveashi-scanner/components/BridgeStatusCard.tsxveashi-scanner/components/MessagesTable.tsxveashi-scanner/components/tx/cards/AdaptersCard.tsxveashi-scanner/components/tx/cards/BridgeSummaryCard.tsxveashi-scanner/globals.cssveashi-scanner/hooks/useMessageScanner.tsveashi-scanner/hooks/useTransaction.tsveashi-scanner/lib/envioClient.tsveashi-scanner/lib/utils.tsveashi-scanner/lib/veashiHelpers.ts
✅ Files skipped from review due to trivial changes (1)
- package.json
🚧 Files skipped from review as they are similar to previous changes (5)
- veashi-scanner/components/MessagesTable.tsx
- veashi-scanner/components/tx/cards/AdaptersCard.tsx
- veashi-scanner/components/BridgeStatusCard.tsx
- veashi-scanner/hooks/useTransaction.ts
- veashi-scanner/globals.css
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|




PR-Codex overview
This PR introduces significant updates to the
veashi-scannerandveashi-envio-yahoprojects, including new components, hooks, and TypeScript configurations to enhance functionality and improve user experience in handling cross-chain messages.Detailed summary
Layoutcomponent for application structure.Pagination,AddressesCard,ChainRouteCard, andBridgeSummaryCardcomponents for better UI.useDebounceanduseExecutionStatushooks for improved state management.tsconfig.jsonand related files.MessagesTableandSearchBarfor better transaction searching.MessageDispatchedevents inveashi-envio-yaho.globals.cssand various components.package.jsondependencies for compatibility and new features.Summary by CodeRabbit
MessageDispatcheddata to support message discovery.