Skip to content

YNU-774: Add Native Tokens Support: Contract, SDK, Cerebro Updates#587

Merged
dimast-x merged 3 commits intomainfrom
feat/native-token-support
Feb 25, 2026
Merged

YNU-774: Add Native Tokens Support: Contract, SDK, Cerebro Updates#587
dimast-x merged 3 commits intomainfrom
feat/native-token-support

Conversation

@dimast-x
Copy link
Contributor

@dimast-x dimast-x commented Feb 25, 2026

Summary by CodeRabbit

  • New Features

    • Added token-balance and approve shell commands for querying on-chain balances and initiating approvals.
    • First-class native ETH support for balance, allowance and deposit flows.
    • Improved command autocomplete/suggestions for chain, asset and wallet arguments.
  • User-facing Changes

    • Streamlined approval flow in example apps and dashboard to use a fixed max-approve amount.
    • CLI help/examples updated to document new token commands.
  • Bug Fixes

    • Native-token decimal handling validated to ensure consistent behavior.

@dimast-x dimast-x requested a review from a team as a code owner February 25, 2026 12:58
@dimast-x dimast-x requested a review from nksazonov February 25, 2026 12:59
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8db03d0 and bee2ed1.

📒 Files selected for processing (7)
  • cerebro/operator.go
  • pkg/blockchain/evm/client.go
  • pkg/core/interface.go
  • sdk/go/channel.go
  • sdk/ts/src/blockchain/evm/client.ts
  • sdk/ts/src/client.ts
  • sdk/ts/src/core/interface.ts

📝 Walkthrough

Walkthrough

Adds native-ETH and ERC-20 token operations across CLI, SDKs, blockchain clients, and contracts: new token-balance and approve CLI commands, on-chain balance and approve methods, native-token handling in EVM clients, a native Ether asset entry, and smart-contract decimals validation for native tokens.

Changes

Cohort / File(s) Summary
CLI
cerebro/commands.go, cerebro/operator.go
Added token-balance and approve command handlers, updated help text and completion routing, and wired CLI commands to new operator methods.
Smart Contracts
contracts/src/Utils.sol
Guard added in validateTokenDecimals to treat zero-address (native) token as 18 decimals without ERC‑20 calls.
Go EVM Client
pkg/blockchain/evm/client.go
Exposed GetTokenBalance and Approve; added native-token paths (zero address) for balance, allowance, approvals, and attach value for native deposits; updated call sites to use new APIs.
Go Core & SDK
pkg/core/interface.go, sdk/go/channel.go
Interface extended with GetTokenBalance and Approve; SDK wrappers GetOnChainBalance and ApproveToken added.
TS EVM Client
sdk/ts/src/blockchain/evm/client.ts
Added zeroAddress handling: native token short-circuit for allowance/balance, renamed/adjusted methods (approve/getTokenBalance), and attach native value in create/deposit/checkpoint flows.
TS SDK Client
sdk/ts/src/client.ts, sdk/ts/src/core/interface.ts
Changed approveToken to take asset name and Decimal amount; added/updated interface methods for token balance/approve and several channel/escrow signature/idx changes.
TS Examples
sdk/ts/examples/example-app/src/components/ActionModal.tsx, .../WalletDashboard.tsx
Replaced MAX_UINT256 with a Decimal MAX_APPROVE_AMOUNT; simplified auto-approve flows to call asset-based approve with fixed amount.
Assets Config
clearnode/chart/config/v1-rc/assets.yaml
Added "Ether" asset entry with symbol eth, decimals 18, and native token (zero address) on chain id 11155111.
Manifest
package.json
Updated due to TS example changes (minor manifest update).

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (Operator)
    participant SDK as SDK Client
    participant Core as Go Core Client
    participant EVM as EVM Blockchain Client
    participant Node as Ethereum Node / Contract

    rect rgba(200,200,255,0.5)
    CLI->>SDK: approve(chainId, asset, amount)
    end

    rect rgba(200,255,200,0.5)
    SDK->>Core: ApproveToken(ctx, chainId, asset, amount)
    Core->>EVM: Approve(asset, amount)
    end

    rect rgba(255,230,200,0.5)
    EVM->>Node: if token == zeroAddress ? (no-op / error) : send ERC20 approve tx
    Node-->>EVM: txHash / error
    EVM-->>Core: txHash / error
    Core-->>SDK: txHash / error
    SDK-->>CLI: display result
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • nksazonov
  • philanton
  • alessio

Poem

🐇 I hopped from CLI to chain so bright,
I nudged approvals into the night,
Zero address, decimals true,
ETH and tokens — all anew! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding native tokens support across contract, SDK, and Cerebro components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/native-token-support

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @dimast-x, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the application by adding support for native tokens, alongside existing ERC-20 token functionality. This includes updates to the Cerebro CLI, SDK, and smart contracts to accommodate native token operations such as balance checks, approvals, and deposits. The changes ensure that the system can seamlessly handle both types of tokens, improving user experience and expanding the range of supported assets.

Highlights

  • Native Token Support: This PR introduces support for native tokens (e.g., ETH) in addition to ERC-20 tokens within the application. This includes updates to the contract, SDK, and Cerebro command-line tool.
  • Cerebro Updates: The Cerebro command-line tool is updated with new commands for checking token balance (token-balance) and approving token spending (approve).
  • SDK Enhancements: The SDK is updated to include methods for approving token spending and getting on-chain token balances, handling both ERC-20 tokens and native tokens.
  • Contract Changes: The contract logic is modified to handle native tokens, specifically addressing decimal handling and balance checks.
Changelog
  • cerebro/commands.go
    • Added token-balance and approve commands to Cerebro CLI.
    • Updated examples to include approve command.
  • cerebro/operator.go
    • Added suggestions for token-balance and approve commands.
    • Modified command completion logic to handle chain and asset suggestions for new and existing commands.
  • clearnode/chart/config/v1-rc/assets.yaml
    • Added configuration for Ether (ETH) as a native token.
  • contracts/src/Utils.sol
    • Modified the Utils library to handle native token decimals correctly.
  • pkg/blockchain/evm/client.go
    • Modified getAllowance to handle native tokens, which do not require allowance.
    • Added GetTokenBalance to fetch token balances, including native ETH balances.
    • Added Approve to approve token spending for ERC-20 tokens.
    • Modified Deposit and Checkpoint to handle native token deposits by setting msg.value.
  • pkg/core/interface.go
    • Added GetTokenBalance and Approve methods to the Client interface.
  • sdk/go/channel.go
    • Added ApproveToken and GetOnChainBalance methods to the SDK.
  • sdk/ts/examples/example-app/src/components/ActionModal.tsx
    • Updated autoApprove to use approveToken with the asset name.
  • sdk/ts/examples/example-app/src/components/WalletDashboard.tsx
    • Updated checkpoint logic to use approveToken with the asset name.
  • sdk/ts/src/blockchain/evm/client.ts
    • Modified getAllowance to handle native tokens, which do not require allowance.
    • Modified getTokenBalance to fetch token balances, including native ETH balances.
    • Added approveToken to approve token spending for ERC-20 tokens.
    • Modified depositToChannel and createChannel to handle native token deposits by setting msg.value.
  • sdk/ts/src/client.ts
    • Updated approveToken to use the asset symbol instead of the token address.
Activity
  • dimast-x authored and implemented the changes.
  • The pull request introduces native token support across multiple components.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dimast-x dimast-x force-pushed the feat/native-token-support branch from 0b2ec72 to 8db03d0 Compare February 25, 2026 13:00
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces comprehensive support for native tokens across the smart contracts, Go and TypeScript SDKs, and the Cerebro CLI. The changes are well-structured and effectively implement the required functionality. My review focuses on a couple of areas for improvement. In the Go EVM client, new functions use context.Background() instead of propagating a context from the caller, which I've recommended fixing. Additionally, in the TypeScript example application, the constant used for maximum token approval might be too low for its purpose, and I've suggested a more robust value. Overall, these are solid changes that accomplish the goal of adding native token support.

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 (3)
pkg/core/interface.go (1)

18-19: Align GetTokenBalance parameter naming with asset-based semantics.

Line 18 still uses token, while the new flow is asset-driven. Renaming to asset will reduce caller confusion and API misuse.

♻️ Proposed naming-only diff
-	GetTokenBalance(token string, account string) (decimal.Decimal, error)
+	GetTokenBalance(asset string, account string) (decimal.Decimal, error)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/core/interface.go` around lines 18 - 19, Rename the first parameter of
the GetTokenBalance method from token to asset in the GetTokenBalance(token
string, account string) (decimal.Decimal, error) signature to match the
asset-driven flow; update all implementations of GetTokenBalance, any interface
assertions, callers, tests, and imports that reference the old parameter name so
the code compiles (ensure function/method names remain unchanged and only the
parameter identifier is updated).
sdk/ts/examples/example-app/src/components/ActionModal.tsx (1)

9-9: Centralize MAX_APPROVE_AMOUNT to avoid cross-component drift.

This constant is now duplicated here and in sdk/ts/examples/example-app/src/components/WalletDashboard.tsx. A shared constant module would keep approval behavior consistent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/ts/examples/example-app/src/components/ActionModal.tsx` at line 9,
MAX_APPROVE_AMOUNT is duplicated across components (ActionModal and
WalletDashboard); extract it into a shared exported constant (e.g., export const
MAX_APPROVE_AMOUNT = new Decimal('1e18')) in a new module (suggest name:
constants or shared/constants) and update both ActionModal (function/component
ActionModal) and WalletDashboard (component WalletDashboard) to import that
constant instead of redefining it; ensure the new module also exports any
required Decimal import or that each file still imports Decimal only if needed
for other logic.
sdk/ts/src/blockchain/evm/client.ts (1)

100-103: Prefer explicit native allowance bypass over a magic allowance value.

Line 102 returns a synthetic 1e18 allowance for native assets. It works in practice, but it encodes “not applicable” as a fake number. Consider bypassing allowance checks explicitly for native tokens in deposit-intent paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/ts/src/blockchain/evm/client.ts` around lines 100 - 103, Replace the
synthetic magic allowance value by explicitly signaling “not applicable” for
native tokens: in the function that checks allowance (the branch that currently
uses tokenAddress and zeroAddress), return a clearly typed sentinel (e.g., null
or undefined or a dedicated enum/value) instead of new Decimal('1e18') and
update calling code in deposit/intent flows to treat that sentinel as “bypass
allowance checks” (or add an isNative boolean derived from tokenAddress ===
zeroAddress to skip allowance logic). Reference tokenAddress and zeroAddress to
locate the branch and ensure all callers that expect a Decimal handle the new
sentinel or isNative flag accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/blockchain/evm/client.go`:
- Around line 281-284: The code mutates the shared client field
c.transactOpts.Value (seen in the block and also in Checkpoint and Create) which
risks races; instead make a per-call copy of c.transactOpts (e.g., local :=
*c.transactOpts), set local.Value = amountBig (or nil) as needed, and use that
local copy when invoking contract transactor methods so the client-level
transactOpts is never mutated concurrently; apply the same change to the
Checkpoint and Create call sites to avoid the defer-reset pattern.

In `@sdk/go/channel.go`:
- Around line 991-1001: Update the doc comment for GetOnChainBalance so it no
longer says "ERC20 token balance" — make it clear the function returns on-chain
asset balances for both ERC20 tokens and native chain assets; keep the param
descriptions (ctx, chainID, asset, wallet) but note that asset may refer to
native assets as well, and update the return description to state the balance is
returned as a decimal adjusted for the asset's decimals (ERC20 or native).
Ensure this change is made in the comment block above the GetOnChainBalance
function.

---

Nitpick comments:
In `@pkg/core/interface.go`:
- Around line 18-19: Rename the first parameter of the GetTokenBalance method
from token to asset in the GetTokenBalance(token string, account string)
(decimal.Decimal, error) signature to match the asset-driven flow; update all
implementations of GetTokenBalance, any interface assertions, callers, tests,
and imports that reference the old parameter name so the code compiles (ensure
function/method names remain unchanged and only the parameter identifier is
updated).

In `@sdk/ts/examples/example-app/src/components/ActionModal.tsx`:
- Line 9: MAX_APPROVE_AMOUNT is duplicated across components (ActionModal and
WalletDashboard); extract it into a shared exported constant (e.g., export const
MAX_APPROVE_AMOUNT = new Decimal('1e18')) in a new module (suggest name:
constants or shared/constants) and update both ActionModal (function/component
ActionModal) and WalletDashboard (component WalletDashboard) to import that
constant instead of redefining it; ensure the new module also exports any
required Decimal import or that each file still imports Decimal only if needed
for other logic.

In `@sdk/ts/src/blockchain/evm/client.ts`:
- Around line 100-103: Replace the synthetic magic allowance value by explicitly
signaling “not applicable” for native tokens: in the function that checks
allowance (the branch that currently uses tokenAddress and zeroAddress), return
a clearly typed sentinel (e.g., null or undefined or a dedicated enum/value)
instead of new Decimal('1e18') and update calling code in deposit/intent flows
to treat that sentinel as “bypass allowance checks” (or add an isNative boolean
derived from tokenAddress === zeroAddress to skip allowance logic). Reference
tokenAddress and zeroAddress to locate the branch and ensure all callers that
expect a Decimal handle the new sentinel or isNative flag accordingly.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c17cc7 and 8db03d0.

📒 Files selected for processing (11)
  • cerebro/commands.go
  • cerebro/operator.go
  • clearnode/chart/config/v1-rc/assets.yaml
  • contracts/src/Utils.sol
  • pkg/blockchain/evm/client.go
  • pkg/core/interface.go
  • sdk/go/channel.go
  • sdk/ts/examples/example-app/src/components/ActionModal.tsx
  • sdk/ts/examples/example-app/src/components/WalletDashboard.tsx
  • sdk/ts/src/blockchain/evm/client.ts
  • sdk/ts/src/client.ts

@dimast-x dimast-x force-pushed the feat/native-token-support branch from 04ab272 to bee2ed1 Compare February 25, 2026 13:36
@dimast-x dimast-x merged commit cea67a5 into main Feb 25, 2026
11 of 12 checks passed
@dimast-x dimast-x deleted the feat/native-token-support branch February 25, 2026 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants