Skip to content

Conversation

@fadeev
Copy link
Member

@fadeev fadeev commented Jul 18, 2025

Contract addresses fresh from the registry 🥬

This also bumps the version of protocol contracts to v14, because the contracts command is using the contract registry.

LIst

yarn -s zetachain query contracts list
✔ Successfully fetched 32 contracts
┌──────────┬───────────────────┬──────────────────────────────────────────────────────────────────────┐
│ Chain ID │ Type              │ Address                                                              │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 97       │ connector         │ 0x0000ecb8cdd25a18F12DAA23f6422e07fBf8B9E1                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 97       │ erc20Custody      │ 0xD80BE3710F08D280F51115e072e5d2a778946cd7                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 97       │ gateway           │ 0x0c487a766110c85d301D96E33579C5B317Fa4995                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 97       │ zetaToken         │ 0x0000c9eC4042283e8139c74F4c64BcD1E0b9B54f                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 103      │ gateway           │ 0xba51550593bA92Ff43376D0A6Cc26a5CA226F9BD                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 901      │ gateway           │ ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis                          │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ connector         │ 0x239e96c8f17C85c30100AC26F635Ea15f23E9c67                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ fungibleModule    │ 0x735b14BB79463307AAcBED86DAf3322B1e6226aB                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ gateway           │ 0x6c533f7fE93fAE114d0954697069Df33C9B74fD7                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ systemContract    │ 0xEdf1c3275d13489aCdC6cD6eD246E72458B8795B                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ uniswapV2Factory  │ 0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ uniswapV2Router02 │ 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 7001     │ zetaToken         │ 0x5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 18332    │ tss               │ tb1qy9pqmk2pd9sv63g27jt8r657wy0d9ueeh0nqur                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 43113    │ erc20Custody      │ 0x1B088fbAfD7ab966022944AD7b90B9f1113DC027                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 43113    │ gateway           │ 0x0dA86Dc3F9B71F84a0E97B0e2291e50B7a5df10f                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 80002    │ connector         │ 0x60E6b70bC2761f878Ff992276612F67FbABC1761                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 80002    │ erc20Custody      │ 0xD80BE3710F08D280F51115e072e5d2a778946cd7                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 80002    │ gateway           │ 0x0c487a766110c85d301D96E33579C5B317Fa4995                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 80002    │ zetaToken         │ 0x1432612E60cad487C857E7D38AFf57134916c902                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 84532    │ connector         │ 0xc0B74d761ef4EC9e9473f65687d36B9F13DB0dCc                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 84532    │ erc20Custody      │ 0xD80BE3710F08D280F51115e072e5d2a778946cd7                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 84532    │ gateway           │ 0x0c487a766110c85d301D96E33579C5B317Fa4995                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 84532    │ zetaToken         │ 0xf4e63991E7475b659bd97Bba85f32a7259239D5d                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 421614   │ erc20Custody      │ 0x1B088fbAfD7ab966022944AD7b90B9f1113DC027                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 421614   │ gateway           │ 0x0dA86Dc3F9B71F84a0E97B0e2291e50B7a5df10f                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 2015141  │ gateway           │ 0x0087115e4a012e747d9bce013ce2244010c6d5e3b0f88ddbc63420519b8619e5a0 │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 11155111 │ tss               │ 0x8531a5aB847ff5B22D855633C25ED1DA3255247e                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 11155111 │ connector         │ 0x3963341dad121c9CD33046089395D66eBF20Fb03                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 11155111 │ erc20Custody      │ 0xD80BE3710F08D280F51115e072e5d2a778946cd7                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 11155111 │ gateway           │ 0x0c487a766110c85d301D96E33579C5B317Fa4995                           │
├──────────┼───────────────────┼──────────────────────────────────────────────────────────────────────┤
│ 11155111 │ zetaToken         │ 0x0000c304D2934c00Db1d51995b9f6996AffD17c0                           │
└──────────┴───────────────────┴──────────────────────────────────────────────────────────────────────┘

Show

yarn -s zetachain query contracts show --chain-id 11155111 --type gateway
0x0c487a766110c85d301D96E33579C5B317Fa4995

How a ninja would use this command:

zetachain q c s -c 11155111 -t gateway

Summary by CodeRabbit

  • New Features

    • Added "contracts" command to query protocol contracts across multiple chains
    • List contracts with JSON or table output options
    • Show contract addresses for specific chains with chain-aware address formatting
  • Chores

    • Updated Node.js version to 22 in CI/CD workflows
    • Enhanced TypeScript configuration support

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 18, 2025

📝 Walkthrough

Walkthrough

A new contract registry CLI command group is introduced with subcommands to list and display protocol contracts across chains. Supporting address formatting utilities and validation schemas are added. GitHub Actions workflows are updated to Node.js 22, TypeScript configuration includes Jest and Node type declarations, and Bitcoin inscription helpers are refactored to use Buffers consistently.

Changes

Cohort / File(s) Summary
Contract Registry Commands
packages/commands/src/query/contracts/index.ts, packages/commands/src/query/contracts/list.ts, packages/commands/src/query/contracts/show.ts, packages/commands/src/query/index.ts
New CLI command group and subcommands added: contractsCommand parent group with listCommand (alias "l") to fetch and display protocol contracts with optional JSON output and column filtering, and showCommand (alias "s") to display a specific contract address by chain ID and type. Integration into query command chain.
Address Utilities
utils/addressResolver.ts
Four new address formatting and parsing functions added: tryParseEvmAddress() for EVM address extraction, formatAddress() for checksummed or ASCII formatting, splitSuiCombinedAddress() for Sui-specific 128-hex-character splitting, and formatAddressForChain() for chain-aware formatting.
Contract Schemas
src/schemas/commands/contracts.ts
Two new Zod validation schemas introduced: contractsListOptionsSchema for list command options (columns, JSON flag, RPC URL) and contractsShowOptionsSchema for show command options (required chainId and type, optional RPC URL).
Registry Address Constant
src/constants/addresses.ts
New constant CONTRACT_REGISTRY_ADDRESS added with value "0x7cce3eb018bf23e1fe2a32692f2c77592d110394".
GitHub Actions Workflows
.github/workflows/build.yaml, .github/workflows/lint.yaml, .github/workflows/publish-npm.yaml, .github/workflows/test.yaml
Node.js runtime version updated from 21 to 22 across all build, lint, publish, and test workflows.
TypeScript Configuration
tsconfig.json
Type declarations for Node.js and Jest added to compiler options via "types": ["node", "jest"].
Bitcoin Utilities
utils/bitcoin.inscription.helpers.ts
Refactored public key and inscription data handling to use Buffer instances consistently; internalKey extracted once and reused throughout Taproot script construction and fee calculations.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as Contracts CLI
    participant RPC as EVM RPC
    participant Registry as Contract Registry
    participant Formatter as Address Formatter
    
    rect rgb(240, 248, 255)
    Note over User,Registry: List Command Flow
    User->>CLI: contracts list [--json] [--columns]
    CLI->>RPC: Connect via RPC URL
    RPC->>Registry: Fetch all contracts
    Registry-->>CLI: Contract data array
    CLI->>CLI: Deduplicate & sort by chainId
    alt JSON output
        CLI-->>User: JSON formatted output
    else Table output
        CLI->>Formatter: Format addresses per chain rules
        Formatter-->>CLI: Formatted addresses
        CLI-->>User: Rendered table
    end
    end
    
    rect rgb(255, 250, 240)
    Note over User,Registry: Show Command Flow
    User->>CLI: contracts show --chainId <id> --type <type>
    CLI->>RPC: Connect via RPC URL
    RPC->>Registry: Fetch all contracts
    Registry-->>CLI: Contract data array
    CLI->>CLI: Find matching chainId & type
    alt Contract found
        CLI->>Formatter: Format address (chain-aware)
        alt Sui chain (103, 105)
            Formatter->>Formatter: Split 128-hex into two 32-byte parts
        else Other chains
            Formatter->>Formatter: Standard EVM checksum formatting
        end
        Formatter-->>CLI: Formatted address
        CLI-->>User: Display address
    else Not found
        CLI-->>User: Error + available contracts list
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: query contracts command" directly summarizes the main change in the changeset, which is the addition of a new CLI command for querying protocol contract addresses from the contract registry. The title is concise, clear, and specific—it uses descriptive terms ("query contracts command") rather than vague language, and a teammate scanning the git history would immediately understand that a new contracts query feature has been added. While the title doesn't enumerate the specific subcommands (list and show) or all implementation details, it appropriately captures the primary change without unnecessary detail.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch contracts-cli

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

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the feat label Jul 18, 2025
@fadeev fadeev marked this pull request as ready for review July 22, 2025 11:53
@fadeev fadeev requested review from a team as code owners July 22, 2025 11:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/commands/src/query/contracts/show.ts (2)

13-17: Consider making the interface more type-safe.

The ContractData interface duplicates what might already be defined elsewhere. Consider importing this from a shared types file to maintain consistency and avoid duplication.

#!/bin/bash
# Description: Check if ContractData interface is defined elsewhere in the codebase
ast-grep --pattern 'interface ContractData {
  $$$
}'

61-63: Improve error handling specificity.

The generic error catch could be more specific. Consider handling different error types (network errors, contract errors, parsing errors) differently to provide more targeted user feedback.

  } catch (error) {
-    console.error(chalk.red("Error details:"), error);
+    if (error instanceof Error) {
+      if (error.message.includes('network')) {
+        console.error(chalk.red("Network error: Please check your RPC URL"));
+      } else if (error.message.includes('contract')) {
+        console.error(chalk.red("Contract error: Unable to fetch contract data"));
+      } else {
+        console.error(chalk.red("Error:"), error.message);
+      }
+    } else {
+      console.error(chalk.red("Unknown error occurred"));
+    }
+    process.exit(1);
  }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 020e499 and 585c62c.

⛔ Files ignored due to path filters (62)
  • typechain-types/@zetachain/protocol-contracts/contracts/Revert.sol/Revertable.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/evm/ZetaConnectorBase.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/evm/ZetaConnectorNative.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/evm/ZetaConnectorNonNative.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/helpers/index.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/IBaseRegistry.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/IBaseRegistryErrors.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/IBaseRegistryEvents.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/index.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/helpers/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/GatewayZEVM.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/index.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/ICoreRegistry.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/IGatewayZEVM.sol/IGatewayZEVM.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/IZRC20.sol/IZRC20.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/IZRC20.sol/IZRC20Metadata.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/UniversalContract.sol/UniversalContract.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/libraries/GatewayZEVMValidations.ts is excluded by !typechain-types/**
  • typechain-types/@zetachain/protocol-contracts/contracts/zevm/libraries/index.ts is excluded by !typechain-types/**
  • typechain-types/contracts/testing/mock/ZRC20Mock.sol/IZRC20Mock.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/Errors.sol/INotSupportedMethods__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/Revert.sol/Revertable__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/evm/ERC20Custody__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/evm/GatewayEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/evm/ZetaConnectorBase__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/evm/ZetaConnectorNative__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/evm/ZetaConnectorNonNative__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/helpers/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/IBaseRegistryErrors__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/IBaseRegistryEvents__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/IBaseRegistry__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/helpers/interfaces/IBaseRegistry.sol/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/helpers/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/GatewayZEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/SystemContract.sol/SystemContract__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/ZRC20.sol/ZRC20__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/ICoreRegistry__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/IGatewayZEVM.sol/IGatewayZEVMErrors__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/IGatewayZEVM.sol/IGatewayZEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/IZRC20.sol/IZRC20Metadata__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/IZRC20.sol/IZRC20__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/UniversalContract.sol/UniversalContract__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/libraries/GatewayZEVMValidations__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@zetachain/protocol-contracts/contracts/zevm/libraries/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/OnlySystem__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/EVMSetup.t.sol/EVMSetup__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/FoundrySetup.t.sol/FoundrySetup__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/TokenSetup.t.sol/TokenSetup__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/ZetaSetup.t.sol/ZetaSetup__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/mock/ZRC20Mock.sol/IZRC20Mock__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/mock/ZRC20Mock.sol/ZRC20Mock__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/mockGateway/NodeLogicMock__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/mockGateway/WrapGatewayEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/testing/mockGateway/WrapGatewayZEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/hardhat.d.ts is excluded by !typechain-types/**
  • typechain-types/index.ts is excluded by !typechain-types/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • package.json (1 hunks)
  • packages/commands/src/query/contracts/index.ts (1 hunks)
  • packages/commands/src/query/contracts/list.ts (1 hunks)
  • packages/commands/src/query/contracts/show.ts (1 hunks)
  • packages/commands/src/query/index.ts (2 hunks)
  • src/constants/addresses.ts (1 hunks)
  • src/schemas/commands/contracts.ts (1 hunks)
  • utils/addressResolver.ts (1 hunks)
🧠 Learnings (5)
📓 Common learnings
Learnt from: hernan-clich
PR: zeta-chain/toolkit#238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.
Learnt from: hernan-clich
PR: zeta-chain/toolkit#332
File: packages/commands/src/bitcoin/inscription/call.ts:66-67
Timestamp: 2025-05-27T16:09:13.029Z
Learning: The ZetaChain toolkit uses comprehensive zod schema validation for command inputs, including hexStringSchema for hex string validation with regex /^(0x)?[0-9a-fA-F]*$/, so manual validation in the command logic is typically unnecessary as validation occurs during option parsing.
Learnt from: hernan-clich
PR: zeta-chain/toolkit#329
File: utils/evm.command.helpers.ts:21-38
Timestamp: 2025-05-16T20:59:05.735Z
Learning: In the ZetaChain toolkit, base schemas like `baseEvmDepositOptionsSchema` are intentionally kept flexible, with mutual exclusivity refinements like name/privateKey validation happening in the specific command implementations that extend the base schema, rather than in the base schema itself.
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/depositAndCall.ts:0-0
Timestamp: 2025-06-13T15:33:54.781Z
Learning: fadeev prefers responses in English.
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/deposit.ts:0-0
Timestamp: 2025-06-13T15:32:09.225Z
Learning: User fadeev prefers that responses be in English; avoid replying in Russian in future interactions.
package.json (3)

Learnt from: s2imonovic
PR: #370
File: contracts/UniswapV3SetupLib.sol:124-128
Timestamp: 2025-06-26T14:06:16.147Z
Learning: In the ZetaChain toolkit codebase, accurate documentation is important - comments should correctly reflect what the code actually does (e.g., fixing comments that incorrectly reference Uniswap V2 when the code deploys V3 contracts).

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

Learnt from: hernan-clich
PR: #291
File: packages/commands/src/accounts/list.ts:0-0
Timestamp: 2025-04-17T15:59:39.612Z
Learning: In the zetachain/toolkit repository, file system operations should use the safe helper functions from fsUtils.ts (like safeReadFile, safeReadDir, safeExists) instead of direct Node.js fs methods to ensure consistent error handling.

packages/commands/src/query/contracts/index.ts (1)

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

src/schemas/commands/contracts.ts (4)

Learnt from: hernan-clich
PR: #329
File: utils/evm.command.helpers.ts:21-38
Timestamp: 2025-05-16T20:59:05.735Z
Learning: In the ZetaChain toolkit, base schemas like baseEvmDepositOptionsSchema are intentionally kept flexible, with mutual exclusivity refinements like name/privateKey validation happening in the specific command implementations that extend the base schema, rather than in the base schema itself.

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

Learnt from: hernan-clich
PR: #332
File: packages/commands/src/bitcoin/inscription/call.ts:66-67
Timestamp: 2025-05-27T16:09:13.029Z
Learning: The ZetaChain toolkit uses comprehensive zod schema validation for command inputs, including hexStringSchema for hex string validation with regex /^(0x)?[0-9a-fA-F]*$/, so manual validation in the command logic is typically unnecessary as validation occurs during option parsing.

Learnt from: hernan-clich
PR: #329
File: utils/evm.command.helpers.ts:21-38
Timestamp: 2025-05-16T20:59:05.735Z
Learning: In the ZetaChain toolkit, mutual exclusivity between 'name' and 'privateKey' is implemented using the 'namePkRefineRule' in the individual command schemas that extend the base schema, rather than in the base schema itself. This design pattern allows the base schema to remain flexible while specific commands can apply constraints as needed.

packages/commands/src/query/contracts/list.ts (1)

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

🧬 Code Graph Analysis (5)
packages/commands/src/query/contracts/index.ts (2)
packages/commands/src/query/contracts/list.ts (1)
  • listCommand (103-118)
packages/commands/src/query/contracts/show.ts (1)
  • showCommand (66-81)
packages/commands/src/query/index.ts (1)
packages/commands/src/query/contracts/index.ts (1)
  • contractsCommand (6-11)
packages/commands/src/query/contracts/show.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsShowOptionsSchema (11-16)
packages/commands/src/query/contracts/list.ts (1)
  • fetchContracts (22-35)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
src/schemas/commands/contracts.ts (1)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
packages/commands/src/query/contracts/list.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsListOptionsSchema (5-9)
src/constants/addresses.ts (1)
  • CONTRACT_REGISTRY_ADDRESS (2-3)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: hernan-clich
PR: zeta-chain/toolkit#238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.
Learnt from: hernan-clich
PR: zeta-chain/toolkit#332
File: packages/commands/src/bitcoin/inscription/call.ts:66-67
Timestamp: 2025-05-27T16:09:13.029Z
Learning: The ZetaChain toolkit uses comprehensive zod schema validation for command inputs, including hexStringSchema for hex string validation with regex /^(0x)?[0-9a-fA-F]*$/, so manual validation in the command logic is typically unnecessary as validation occurs during option parsing.
Learnt from: hernan-clich
PR: zeta-chain/toolkit#329
File: utils/evm.command.helpers.ts:21-38
Timestamp: 2025-05-16T20:59:05.735Z
Learning: In the ZetaChain toolkit, base schemas like `baseEvmDepositOptionsSchema` are intentionally kept flexible, with mutual exclusivity refinements like name/privateKey validation happening in the specific command implementations that extend the base schema, rather than in the base schema itself.
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/depositAndCall.ts:0-0
Timestamp: 2025-06-13T15:33:54.781Z
Learning: fadeev prefers responses in English.
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/deposit.ts:0-0
Timestamp: 2025-06-13T15:32:09.225Z
Learning: User fadeev prefers that responses be in English; avoid replying in Russian in future interactions.
package.json (3)

Learnt from: s2imonovic
PR: #370
File: contracts/UniswapV3SetupLib.sol:124-128
Timestamp: 2025-06-26T14:06:16.147Z
Learning: In the ZetaChain toolkit codebase, accurate documentation is important - comments should correctly reflect what the code actually does (e.g., fixing comments that incorrectly reference Uniswap V2 when the code deploys V3 contracts).

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

Learnt from: hernan-clich
PR: #291
File: packages/commands/src/accounts/list.ts:0-0
Timestamp: 2025-04-17T15:59:39.612Z
Learning: In the zetachain/toolkit repository, file system operations should use the safe helper functions from fsUtils.ts (like safeReadFile, safeReadDir, safeExists) instead of direct Node.js fs methods to ensure consistent error handling.

packages/commands/src/query/contracts/index.ts (1)

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

src/schemas/commands/contracts.ts (4)

Learnt from: hernan-clich
PR: #329
File: utils/evm.command.helpers.ts:21-38
Timestamp: 2025-05-16T20:59:05.735Z
Learning: In the ZetaChain toolkit, base schemas like baseEvmDepositOptionsSchema are intentionally kept flexible, with mutual exclusivity refinements like name/privateKey validation happening in the specific command implementations that extend the base schema, rather than in the base schema itself.

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

Learnt from: hernan-clich
PR: #332
File: packages/commands/src/bitcoin/inscription/call.ts:66-67
Timestamp: 2025-05-27T16:09:13.029Z
Learning: The ZetaChain toolkit uses comprehensive zod schema validation for command inputs, including hexStringSchema for hex string validation with regex /^(0x)?[0-9a-fA-F]*$/, so manual validation in the command logic is typically unnecessary as validation occurs during option parsing.

Learnt from: hernan-clich
PR: #329
File: utils/evm.command.helpers.ts:21-38
Timestamp: 2025-05-16T20:59:05.735Z
Learning: In the ZetaChain toolkit, mutual exclusivity between 'name' and 'privateKey' is implemented using the 'namePkRefineRule' in the individual command schemas that extend the base schema, rather than in the base schema itself. This design pattern allows the base schema to remain flexible while specific commands can apply constraints as needed.

packages/commands/src/query/contracts/list.ts (1)

Learnt from: hernan-clich
PR: #238
File: packages/tasks/src/verify.ts:0-0
Timestamp: 2025-03-18T14:06:01.531Z
Learning: The verify.ts file in the zeta-chain/toolkit repository already implements proper validation for empty contract lists using a condition that checks names.length.

🧬 Code Graph Analysis (5)
packages/commands/src/query/contracts/index.ts (2)
packages/commands/src/query/contracts/list.ts (1)
  • listCommand (103-118)
packages/commands/src/query/contracts/show.ts (1)
  • showCommand (66-81)
packages/commands/src/query/index.ts (1)
packages/commands/src/query/contracts/index.ts (1)
  • contractsCommand (6-11)
packages/commands/src/query/contracts/show.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsShowOptionsSchema (11-16)
packages/commands/src/query/contracts/list.ts (1)
  • fetchContracts (22-35)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
src/schemas/commands/contracts.ts (1)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
packages/commands/src/query/contracts/list.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsListOptionsSchema (5-9)
src/constants/addresses.ts (1)
  • CONTRACT_REGISTRY_ADDRESS (2-3)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
🔇 Additional comments (15)
src/constants/addresses.ts (1)

2-3: Verify mainnet CONTRACT_REGISTRY_ADDRESS

Please confirm that the hard-coded address 0x7cce3eb018bf23e1fe2a32692f2c77592d110394 in your constants file is the official mainnet Registry contract and not a testnet deployment. You can cross-check it on Etherscan or against your deployment records. If you need to support multiple networks, consider making this address network-configurable or adding an inline comment/documentation link.

• File: src/constants/addresses.ts (lines 2–3)
• Usage: imported in packages/commands/src/query/contracts/list.ts

packages/commands/src/query/index.ts (2)

5-5: LGTM!

The import follows the established pattern and maintains alphabetical ordering.


14-14: LGTM!

The command integration follows the existing pattern and maintains alphabetical ordering within the command hierarchy.

packages/commands/src/query/contracts/index.ts (1)

1-11: LGTM!

The command group implementation follows commander.js best practices with appropriate aliasing, clear description, and proper subcommand integration. The structure is consistent with the existing codebase patterns.

packages/commands/src/query/contracts/show.ts (3)

19-33: LGTM!

The findContractByChainId function is well-implemented with proper filtering logic and case-insensitive type matching, which improves user experience.


45-57: Excellent user experience with helpful error messages.

The error handling provides clear feedback with the specific chain ID and type that wasn't found, plus a helpful list of available contracts. This makes debugging much easier for users.


78-80: LGTM!

The command action properly validates options using zod schema before execution, which aligns with the established patterns in the ZetaChain toolkit codebase.

src/schemas/commands/contracts.ts (1)

11-16: Schema definition looks good.

The validation schema correctly defines required fields (chainId, type) and provides appropriate defaults for optional fields (json, rpc).

utils/addressResolver.ts (2)

281-302: Well-implemented address parsing function.

The function correctly handles both direct EVM addresses and left-padded bytes32 values. The use of ethers.isAddress for validation and ethers.getAddress for checksumming follows best practices.


304-322: Robust address formatting with appropriate fallbacks.

The function provides a good fallback strategy: EVM address parsing first, then UTF-8 decoding with null byte cleanup, and finally returning the original hex string if all else fails.

packages/commands/src/query/contracts/list.ts (5)

1-21: Good setup with proper imports and type definitions.

The imports are appropriate and the ContractData interface correctly represents the contract registry structure. Type inference from the schema provides good type safety.


22-35: Clean and correct contract fetching implementation.

The function properly sets up the ethers provider and contract instance, with appropriate error handling delegated to the calling function.


37-57: Correct table formatting with conditional columns.

The function properly builds table headers and rows based on the selected columns. The use of formatAddress for address display ensures consistent formatting.


59-101: Robust main function with comprehensive error handling.

The function handles all scenarios well: spinner management for non-JSON output, proper sorting, multiple output formats, empty results, and comprehensive error handling.


103-118: Well-structured command definition.

The command follows best practices with proper aliases, clear description, and good option definitions. The schema validation ensures type safety. Note: This relates to the earlier flagged inconsistency with the schema's columns default.

@fadeev

This comment was marked as outdated.

Copy link
Member

@hernan-clich hernan-clich left a comment

Choose a reason for hiding this comment

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

Tested ACK

@fadeev fadeev marked this pull request as draft August 22, 2025 01:01
@fadeev fadeev marked this pull request as ready for review October 20, 2025 13:06
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
utils/bitcoin.inscription.helpers.ts (2)

94-94: Optional: Redundant Buffer.from() wrapper.

Since key.publicKey.slice(1, 33) already returns a Buffer, wrapping it in Buffer.from() creates an unnecessary copy. While this defensive copying is harmless for small buffers, it can be simplified.

Apply this diff to remove the redundant wrapper:

-    Buffer.from(key.publicKey.slice(1, 33)),
+    key.publicKey.slice(1, 33),

102-108: Inconsistent buffer handling and suspicious type cast.

Lines 104 wraps chunks in Buffer.from(), but line 107 doesn't wrap the full data and includes a type cast as number | Buffer<ArrayBuffer>. This inconsistency and the type cast suggest unclear typing or a potential issue.

For consistency, either wrap both or neither. Additionally, verify whether the type cast is masking a real type mismatch.

Consider applying this diff for consistency:

   if (inscriptionData.length > MAX_SCRIPT_ELEMENT_SIZE) {
     for (let i = 0; i < inscriptionData.length; i += MAX_SCRIPT_ELEMENT_SIZE) {
       const end = Math.min(i + MAX_SCRIPT_ELEMENT_SIZE, inscriptionData.length);
-      scriptItems.push(Buffer.from(inscriptionData.slice(i, end)));
+      scriptItems.push(inscriptionData.slice(i, end));
     }
   } else {
-    scriptItems.push(inscriptionData as number | Buffer<ArrayBuffer>);
+    scriptItems.push(inscriptionData);
   }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2f214af and 059f7cb.

⛔ Files ignored due to path filters (2)
  • docs/index.md is excluded by !docs/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • package.json (1 hunks)
  • packages/commands/src/query/contracts/index.ts (1 hunks)
  • packages/commands/src/query/contracts/list.ts (1 hunks)
  • packages/commands/src/query/contracts/show.ts (1 hunks)
  • packages/commands/src/query/index.ts (2 hunks)
  • tsconfig.json (1 hunks)
  • utils/bitcoin.inscription.helpers.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/commands/src/query/contracts/show.ts
  • packages/commands/src/query/contracts/index.ts
  • packages/commands/src/query/contracts/list.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/depositAndCall.ts:0-0
Timestamp: 2025-06-13T15:33:54.781Z
Learning: fadeev prefers responses in English.
🧬 Code graph analysis (1)
packages/commands/src/query/index.ts (1)
packages/commands/src/query/contracts/index.ts (1)
  • contractsCommand (6-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (6)
utils/bitcoin.inscription.helpers.ts (3)

114-120: Good refactoring: stored internalKey avoids recomputation.

Storing the internal key in a variable and reusing it (lines 116, 126, 171) is good practice that improves efficiency and maintainability.


123-130: LGTM!

The use of the stored internalKey variable in the calculateRevealFee call is consistent and correct.


169-174: LGTM!

Returning the internalKey in the result object provides a consistent interface and allows callers to reuse the computed key.

packages/commands/src/query/index.ts (1)

6-6: LGTM!

The import and registration of the contractsCommand follow the established pattern and integrate cleanly with the existing query command structure.

Also applies to: 20-20

tsconfig.json (1)

15-19: LGTM!

Adding explicit type definitions for Node.js and Jest is a standard practice that ensures proper TypeScript type checking for the CLI commands and test files.

package.json (1)

167-167: Verify codebase compatibility with @zetachain/protocol-contracts v14.0.0 before merging.

The package version exists on npm (v14.0.0 and v14.0.1 confirmed), has no security advisories, and appears stable. However, v14.0.0 is a major version bump from v13.0.0, yet no public changelog or breaking changes documentation is available to verify compatibility.

  • Confirm all imports and usages of @zetachain/protocol-contracts in the codebase work with v14.x
  • Consider using a fixed version (14.0.1) instead of a caret range (^14.0.0) to avoid unexpected breaking changes from v14.1.0+
  • Test that the contract registry support mentioned in your PR description works as expected with v14.0.0

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
package.json (1)

166-169: Align networks metadata with protocol-contracts v14

protocol-contracts is bumped to 14.1.0 while networks stays on 14.0.0-rc1. This may desync chain IDs/registry addresses and surprise the new CLI.

  • Align to a stable @zetachain/networks matching protocol-contracts v14.x, or document the intentional mismatch.
  • Please confirm the intended versions.

Example change:

-    "@zetachain/networks": "14.0.0-rc1",
+    "@zetachain/networks": "14.1.0",  // or the matching stable you target
packages/commands/src/query/contracts/show.ts (2)

23-40: Deduplicate Sui address formatting logic

splitSuiCombinedAddress and formatAddressForChain duplicate logic in list.ts. Extract once (e.g., utils/addressResolver.ts) to keep behavior consistent between list/show and simplify maintenance.


42-56: Simplify contract lookup to a single pass

filter(...).find(...) can be a single find, clearer and O(n) once.

-const findContractByChainId = (
-  contracts: ContractData[],
-  chainId: string,
-  type: string
-): ContractData | null => {
-  const matchingContracts = contracts.filter(
-    (contract) => contract.chainId.toString() === chainId
-  );
-
-  return (
-    matchingContracts.find(
-      (contract) => contract.contractType.toLowerCase() === type.toLowerCase()
-    ) || null
-  );
-};
+const findContractByChainId = (
+  contracts: ContractData[],
+  chainId: string,
+  type: string
+): ContractData | null =>
+  contracts.find(
+    (c) =>
+      c.chainId.toString() === chainId &&
+      c.contractType.toLowerCase() === type.toLowerCase()
+  ) || null;
packages/commands/src/query/contracts/list.ts (2)

34-43: Share chain-aware address formatting

formatAddressForChain duplicates show.ts. Centralize in a shared util (e.g., utils/addressResolver.ts) and reuse here and in show.ts.


99-107: JSON output: embedded newlines for Sui addresses

For Sui, addresses include \n. Consider emitting structured JSON (e.g., { addressParts: [partA, partB] } or an array) to avoid newline semantics in JSON while keeping CLI table output unchanged.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 059f7cb and 637665e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • package.json (1 hunks)
  • packages/commands/src/query/contracts/list.ts (1 hunks)
  • packages/commands/src/query/contracts/show.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/depositAndCall.ts:0-0
Timestamp: 2025-06-13T15:33:54.781Z
Learning: fadeev prefers responses in English.
🧬 Code graph analysis (2)
packages/commands/src/query/contracts/show.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsShowOptionsSchema (11-15)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
packages/commands/src/query/contracts/list.ts (1)
  • fetchContracts (45-58)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)
packages/commands/src/query/contracts/list.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsListOptionsSchema (5-9)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
src/constants/addresses.ts (1)
  • CONTRACT_REGISTRY_ADDRESS (2-3)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)

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 (2)
packages/commands/src/query/contracts/list.ts (2)

41-44: Comment vs implementation mismatch (comma vs newline)

The function returns newline-separated parts, not comma-separated. Update the comment.

- * representing two concatenated 32-byte values. Split them and display as comma-separated.
+ * representing two concatenated 32-byte values. Split them and display newline-separated.

152-152: Typo in summary: duplicated "contracts"

-  .summary("List protocol contracts contracts on all connected chains")
+  .summary("List protocol contracts on all connected chains")
🧹 Nitpick comments (6)
packages/commands/src/query/contracts/list.ts (6)

27-39: Make dedup robust to contractType casing

If the registry ever varies case (e.g., "Gateway" vs "gateway"), duplicates slip through. Normalize type in the key.

Apply:

 const deduplicateContracts = (contracts: ContractData[]): ContractData[] => {
   const seen = new Set<string>();
   const unique: ContractData[] = [];
   for (const c of contracts) {
-    const key = `${c.chainId.toString()}::${c.contractType}::${normalizeHex(
-      c.addressBytes
-    )}`;
+    const typeKey = (c.contractType || "").toLowerCase();
+    const key = `${c.chainId.toString()}::${typeKey}::${normalizeHex(c.addressBytes)}`;
     if (seen.has(key)) continue;
     seen.add(key);
     unique.push(c);
   }
   return unique;
 };

Please confirm the registry enforces a single-case convention; if yes, feel free to skip.


45-51: Validate 128‑hex input before splitting Sui combined address

Guard against non-hex inputs to avoid producing misleading outputs.

 const splitSuiCombinedAddress = (bytesHex: string): string => {
-  const hex = bytesHex.startsWith("0x") ? bytesHex.slice(2) : bytesHex;
-  if (hex.length !== 128) return formatAddress(bytesHex);
+  const hex = bytesHex.startsWith("0x") ? bytesHex.slice(2) : bytesHex;
+  if (hex.length !== 128 || !/^[0-9a-fA-F]+$/.test(hex)) {
+    return formatAddress(bytesHex);
+  }
   const partA = hex.slice(0, 64);
   const partB = hex.slice(64, 128);
   return `0x${partA}\n0x${partB}`;
 };

53-62: Minor: centralize Sui chain IDs

Small readability win: use a Set.

Within this file:

+const SUI_CHAIN_IDS = new Set(["103", "105"]);
 
 const formatAddressForChain = (
   bytesHex: string,
   chainId: ethers.BigNumberish
 ): string => {
   const id = chainId.toString();
-  if (id === "103" || id === "105") {
+  if (SUI_CHAIN_IDS.has(id)) {
     return splitSuiCombinedAddress(bytesHex);
   }
   return formatAddress(bytesHex);
 };

64-77: Runtime-shape check for registry results

The cast to ContractData[] trusts ABI names. If the struct field names change, later code will break silently. Validate at the boundary with zod.

   const contracts =
-    (await contractRegistry.getAllContracts()) as ContractData[];
+    await contractRegistry.getAllContracts();
+
+  const contractSchema = z.object({
+    addressBytes: z.string(),
+    chainId: z.union([z.bigint(), z.string(), z.number()]),
+    contractType: z.string(),
+  });
+  const contractsParsed = z.array(contractSchema).parse(contracts);
-  return contracts;
+  return contractsParsed as ContractData[];

If the ABI guarantees stable names, this can be deferred; otherwise it’s cheap insurance.


121-129: JSON: expose Sui multi-part addresses structurally (non‑breaking)

Newlines inside JSON strings are awkward to consume. Keep address as-is for BC, and add an addresses array for Sui.

-    if (options.json) {
-      const jsonOutput = sortedContracts.map((c: ContractData) => ({
-        address: formatAddressForChain(c.addressBytes, c.chainId),
-        chainId: c.chainId.toString(),
-        type: c.contractType,
-      }));
+    if (options.json) {
+      const jsonOutput = sortedContracts.map((c: ContractData) => {
+        const id = c.chainId.toString();
+        const address = formatAddressForChain(c.addressBytes, c.chainId);
+        let addresses: string[] | undefined;
+        if (id === "103" || id === "105") {
+          const hex = c.addressBytes.startsWith("0x")
+            ? c.addressBytes.slice(2)
+            : c.addressBytes;
+          if (hex.length === 128 && /^[0-9a-fA-F]+$/.test(hex)) {
+            addresses = [`0x${hex.slice(0, 64)}`, `0x${hex.slice(64, 128)}`];
+          }
+        }
+        return { address, addresses, chainId: id, type: c.contractType };
+      });
       console.log(JSON.stringify(jsonOutput, null, 2));
       return;
     }

Confirm whether downstream consumers would benefit from this field; if not, we can skip.


154-161: Single source of truth for defaults (Commander vs Zod)

Defaults are set in both Commander and zod. Prefer one to avoid drift; zod already provides defaults.

   .addOption(
-    new Option("--rpc <url>", "Custom RPC URL").default(DEFAULT_EVM_RPC_URL)
+    new Option("--rpc <url>", "Custom RPC URL")
   )
   .option("--json", "Output contracts as JSON")
   .addOption(
     new Option("--columns <values...>", "Additional columns to show")
       .choices(["type", "address"])
-      .default(["type", "address"])
   )

If you want defaults surfaced in --help, keep Commander defaults and remove them from the zod schema instead.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 637665e and 5011e27.

📒 Files selected for processing (1)
  • packages/commands/src/query/contracts/list.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/depositAndCall.ts:0-0
Timestamp: 2025-06-13T15:33:54.781Z
Learning: fadeev prefers responses in English.
🧬 Code graph analysis (1)
packages/commands/src/query/contracts/list.ts (4)
src/schemas/commands/contracts.ts (1)
  • contractsListOptionsSchema (5-9)
utils/addressResolver.ts (1)
  • formatAddress (308-322)
src/constants/addresses.ts (1)
  • CONTRACT_REGISTRY_ADDRESS (2-3)
src/constants/api.ts (1)
  • DEFAULT_EVM_RPC_URL (3-4)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
utils/addressResolver.ts (1)

340-349: Consider adding defensive validation for chainId.

While the ethers.BigNumberish type should prevent null/undefined at compile time, adding a runtime check improves robustness:

 export const formatAddressForChain = (
   bytesHex: string,
   chainId: ethers.BigNumberish
 ): string => {
+  if (chainId == null) {
+    return formatAddress(bytesHex);
+  }
   const id = chainId.toString();
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5011e27 and 844ab78.

⛔ Files ignored due to path filters (2)
  • docs/index.md is excluded by !docs/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • packages/commands/src/query/contracts/list.ts (1 hunks)
  • packages/commands/src/query/contracts/show.ts (1 hunks)
  • utils/addressResolver.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/commands/src/query/contracts/show.ts
  • packages/commands/src/query/contracts/list.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: fadeev
PR: zeta-chain/toolkit#346
File: packages/commands/src/ton/depositAndCall.ts:0-0
Timestamp: 2025-06-13T15:33:54.781Z
Learning: fadeev prefers responses in English.
🔇 Additional comments (1)
utils/addressResolver.ts (1)

285-302: No changes required. The length checks in tryParseEvmAddress are correct.

The JSON-RPC API specification mandates that byte arrays and all unformatted data be encoded as hex with a "0x" prefix. When ethers.js reads contract data via JSON-RPC (as it does in the fetchContracts function), all bytes values, including addressBytes, will always include the 0x prefix. Therefore, the length checks (42 for 20-byte addresses, 66 for 32-byte values) correctly assume the prefix is present and will work reliably with data returned from the contract registry.

@hernan-clich hernan-clich merged commit 6745493 into main Oct 24, 2025
13 checks passed
@hernan-clich hernan-clich deleted the contracts-cli branch October 24, 2025 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants