Skip to content

Conversation

fadeev
Copy link
Member

@fadeev fadeev commented Oct 3, 2025

Withdraw fee

yarn -s zetachain q fees show --target-chain 11155111
Target Chain     sepolia_testnet (11155111)
Gas Token        ETH.ETHSEP (0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0)
Target Fee       0.000000025200588 ETH.ETHSEP (25200588000 wei)
yarn -s zetachain q fees show --source-chain 84532 --target-chain 11155111

Withdraw fee from a specific source chain

How much would it cost to make a call to Ethereum from Base in Base ETH:

Target Chain     sepolia_testnet (11155111)
Gas Token        ETH.ETHSEP (0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0)
Target Fee       0.000000025200588 ETH.ETHSEP (25200588000 wei)

Source Chain     base_sepolia (84532)
Source Token     ETH.BASESEP (0x236b0DE675cC8F46AE186897fCCeFe3370C9eDeD)
Required Amount  0.000002539453687759 ETH.BASESEP (2539453687759 wei)

With a gas limit

yarn -s zetachain q fees show --source-chain 84532 --target-chain 11155111 --gas-limit 500000
Target Chain     sepolia_testnet (11155111)
Gas Token        ETH.ETHSEP (0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0)
Gas Limit        500000
Target Fee       0.000000600014 ETH.ETHSEP (600014000000 wei)

Source Chain     base_sepolia (84532)
Source Token     ETH.BASESEP (0x236b0DE675cC8F46AE186897fCCeFe3370C9eDeD)
Required Amount  0.0000604813069602 ETH.BASESEP (60481306960200 wei)

JSON output

yarn -s zetachain q fees show --source-chain 84532 --target-chain 11155111 --gas-limit 500000 --json
{
  "target": {
    "chain": {
      "id": "11155111",
      "name": "sepolia_testnet"
    },
    "decimals": 18,
    "fee": "600018500000",
    "symbol": "ETH.ETHSEP",
    "zrc20": "0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0"
  },
  "source": {
    "amount": "60481760701346",
    "chain": {
      "id": "84532",
      "name": "base_sepolia"
    },
    "decimals": 18,
    "equalsGas": false,
    "symbol": "ETH.BASESEP",
    "zrc20": "0x236b0DE675cC8F46AE186897fCCeFe3370C9eDeD"
  }
}

Summary by CodeRabbit

  • New Features
    • Added a top-level "fees" CLI with "list" and new "show" subcommands.
    • "List" now lists withdraw gas fees for all ZRC-20 tokens.
    • "Show" displays withdraw gas fees for a target token and, optionally, the required amount of a source token to cover fees.
    • Supports resolving tokens by chain ID, custom RPC/Router/API, gas limit, and JSON output.

@github-actions github-actions bot added the feat label Oct 3, 2025
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

📝 Walkthrough

Walkthrough

Introduces a new “fees” CLI with list and show subcommands, adds schemas/types to support fee data, and adjusts client contract typings/casts (IZRC20, UniswapV2Router02). Implements data fetching for withdraw gas fees with optional source conversion via Uniswap router, including JSON output and console formatting.

Changes

Cohort / File(s) Summary
Client contract typing updates
packages/client/src/getFees.ts, packages/client/src/getQuote.ts, types/contracts.types.ts
Switches ZRC-20 contract typing to IZRC20 via unknown-cast; adjusts UniswapV2Router02 typing to use generated type and updates a cast path. No runtime logic changes.
Fees CLI feature (commands + schemas)
packages/commands/src/query/fees/index.ts, packages/commands/src/query/fees/list.ts, packages/commands/src/query/fees/show.ts, src/schemas/commands/fees.ts, types/fees.types.ts
Adds fees root command with list/show subcommands. Renames/updates list behavior and spinner handling. Implements show command with data fetching, formatting, and JSON output. Introduces options schema and Zod schemas for fee data.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant CLI as fees show (Commander)
  participant S as fetchShowFeesData
  participant API as Chain/Token API
  participant RPC as EVM Provider
  participant ZRC as IZRC20 (target/gas)
  participant UNI as UniswapV2Router02

  U->>CLI: Run "fees show" with options
  CLI->>S: Validate & call with target/source/rpc/router/api
  S->>API: fetchAllChainData()
  API-->>S: Chains, tokens, labels
  S->>RPC: Create JsonRpcProvider(rpc)
  S->>ZRC: Instantiate target & gas token contracts
  alt gasLimit provided
    S->>ZRC: withdrawGasFee(gasLimit?)
  else no gasLimit
    S->>ZRC: withdrawGasFee()
  end
  ZRC-->>S: fee, gas token address
  opt source provided
    alt source != gas token
      S->>UNI: getAmountsIn(fee, [source, ..., gas])
      UNI-->>S: amountsIn
    else source == gas token
      S-->>S: required = fee
    end
  end
  S-->>CLI: ShowFeesData
  alt --json
    CLI-->>U: JSON ShowFeesData
  else human-readable
    CLI-->>U: Formatted console output
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “feat: fees show command” concisely conveys that this pull request introduces a new CLI subcommand for displaying fees, accurately reflecting the primary feature addition without unnecessary detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ 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 fees-show

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.

@fadeev fadeev marked this pull request as ready for review October 3, 2025 14:25
@fadeev fadeev requested review from a team as code owners October 3, 2025 14:25
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/client/src/getFees.ts (1)

97-103: Incorrect error context string in fetchCCMFees catch

Message references “CCTX By Inbound hash” but this block is fetching CCM fees. Update for clarity.

Apply this diff:

-      context: "Something failed fetching CCTX By Inbound hash",
+      context: "Something went wrong fetching CCM fees",
🧹 Nitpick comments (5)
src/schemas/commands/fees.ts (1)

18-25: Align feesShowOptionsSchema with show command options (avoid drift)

This schema lacks router, sourceChain, and gasLimit, and doesn’t accept number inputs for chain IDs. Align it with the show command and reuse it there.

Apply this diff:

 export const feesShowOptionsSchema = z.object({
   api: z.string().default(DEFAULT_API_URL),
   json: z.boolean().default(false),
   rpc: z.string().default(DEFAULT_EVM_RPC_URL),
-  source: z.string().optional(),
-  target: z.string().optional(),
-  targetChain: z.string().optional(),
+  router: z.string().optional(),                // validated downstream as an address
+  gasLimit: z.union([z.string(), z.number()]).optional(),
+  source: z.string().optional(),
+  sourceChain: z.union([z.string(), z.number()]).optional(),
+  target: z.string().optional(),
+  targetChain: z.union([z.string(), z.number()]).optional(),
 });

Then import and use this schema in the show command to eliminate duplication.

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

26-29: Spinner handling is fine; consider a finally for DRYness

Stopping/clearing the spinner in both try/catch works. You can move it to a finally block to avoid duplication.

Also applies to: 68-69

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

144-156: Avoid duplicating option schemas; reuse central schema

This local zod schema duplicates/extends the one in src/schemas/commands/fees.ts. Prefer importing a unified schema (after adding router/sourceChain/gasLimit there) to prevent drift.

Example:

-const showFeesOptionsSchema = z.object({ ... });
+import { feesShowOptionsSchema as showFeesOptionsSchema } from "../../../../../src/schemas/commands/fees";

267-276: Avoid duplicate API calls for chain metadata

fetchAllChainData is called again only for labels. Pass tokens/labels from fetchShowFeesData or cache locally to reduce I/O.


371-373: Router default: prefer auto-resolving over hardcoding

Hardcoding the router address can drift. Consider defaulting via protocol registry (e.g., getAddress("uniswapV2Router02", "")) with CLI override.

📜 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 78087ef and cededf5.

📒 Files selected for processing (8)
  • packages/client/src/getFees.ts (2 hunks)
  • packages/client/src/getQuote.ts (1 hunks)
  • packages/commands/src/query/fees/index.ts (1 hunks)
  • packages/commands/src/query/fees/list.ts (4 hunks)
  • packages/commands/src/query/fees/show.ts (1 hunks)
  • src/schemas/commands/fees.ts (1 hunks)
  • types/contracts.types.ts (2 hunks)
  • types/fees.types.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 (6)
packages/client/src/getQuote.ts (1)
types/contracts.types.ts (1)
  • UniswapV2Router02Contract (23-23)
types/fees.types.ts (1)
types/shared.schema.ts (1)
  • evmAddressSchema (9-11)
src/schemas/commands/fees.ts (1)
src/constants/api.ts (2)
  • DEFAULT_API_URL (1-2)
  • DEFAULT_EVM_RPC_URL (3-4)
packages/commands/src/query/fees/show.ts (5)
types/fees.types.ts (1)
  • showFeesDataSchema (27-30)
packages/commands/src/query/chains/list.ts (1)
  • fetchAllChainData (36-57)
types/shared.schema.ts (1)
  • evmAddressSchema (9-11)
utils/validateAndParseSchema.ts (1)
  • validateAndParseSchema (28-59)
src/constants/api.ts (2)
  • DEFAULT_EVM_RPC_URL (3-4)
  • DEFAULT_API_URL (1-2)
packages/client/src/getFees.ts (1)
typechain-types/@zetachain/protocol-contracts/contracts/zevm/interfaces/IZRC20.sol/IZRC20.ts (1)
  • IZRC20 (125-301)
packages/commands/src/query/fees/index.ts (2)
packages/commands/src/query/fees/list.ts (1)
  • listCommand (79-95)
packages/commands/src/query/fees/show.ts (1)
  • showCommand (343-379)
🔇 Additional comments (8)
packages/client/src/getFees.ts (1)

21-26: Type cast to IZRC20 looks good

Casting the contract instance to IZRC20 is correct and keeps typings aligned with the ABI.

packages/client/src/getQuote.ts (1)

35-40: LGTM on router typing

Two-step cast to UniswapV2Router02Contract matches the new alias and keeps types precise.

types/contracts.types.ts (1)

1-1: Clean alias for UniswapV2Router02

Type-only import and alias export are correct and simplify usage across the codebase.

Also applies to: 23-23

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

6-10: Good composition of fees command

Root “fees” command correctly aggregates list and show subcommands.

types/fees.types.ts (1)

27-30: Schema shape looks solid

Target required, source optional with proper address validation. Matches the show output.

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

33-39: Contract typing/calls are correct

IZRC20 cast and withdrawGasFee/withdrawGasFeeWithGasLimit usage are correct for ethers v6.


41-47: Gas-limit branching is correct

Cleanly prefers withdrawGasFeeWithGasLimit when provided; falls back otherwise.


107-114: Confirm WETH() returns WZETA on ZEVM

Assumption: router.WETH() yields the wrapped ZETA address (WZETA). If not, the pathing would be wrong.

Would you like me to switch to resolving WZETA via protocol-contracts getAddress for clarity, or add a brief comment stating WETH() == WZETA on ZEVM?

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.

1 participant