Skip to content

fix: add 0x prefix to read-only keystore address#283

Merged
MuncleUscles merged 2 commits intomainfrom
fix/readOnly-address-0x-prefix
Mar 18, 2026
Merged

fix: add 0x prefix to read-only keystore address#283
MuncleUscles merged 2 commits intomainfrom
fix/readOnly-address-0x-prefix

Conversation

@MuncleUscles
Copy link
Member

@MuncleUscles MuncleUscles commented Mar 18, 2026

Summary

  • Ethers keystores store addresses without the 0x prefix. getAddress() returned the bare hex, which propagated as a malformed from field in gen_call RPC requests
  • On testnet, this caused the RPC to return an object instead of a hex string, and genlayer-js produced "0x[object Object]" crashing viem's hexToBytes
  • Adds 0x prefix in getAddress() with guard against double-prefixing

Test plan

  • Added regression test: read-only address always has 0x prefix
  • Added regression test: already-prefixed address is not double-prefixed
  • All 437 existing tests pass

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced address handling to ensure all keystore addresses are consistently formatted with the 0x prefix, preventing compatibility issues when addresses are provided without the prefix.
  • Tests

    • Added comprehensive tests to verify proper address formatting behavior, including validation for both prefixed and non-prefixed addresses.
  • Chores

    • Updated genlayer-js dependency to the latest stable patch version.

getEpochInfo now returns validatorMinStakeRaw and validatorMinStake,
fixing the "Cannot mix BigInt and other types" crash in the staking
wizard.
Ethers keystores store addresses without the 0x prefix. When
getAddress() returned the bare address, it propagated as a malformed
`from` field in gen_call RPC requests, causing the testnet RPC to
return an object instead of a hex string. genlayer-js then produced
"0x[object Object]" which crashed viem's hexToBytes.
@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

A patch-level dependency bump for genlayer-js combined with address normalization logic. The getAddress function now ensures all keystore addresses are prefixed with 0x, with corresponding test updates validating the normalization behavior.

Changes

Cohort / File(s) Summary
Dependency Update
package.json
Bumped genlayer-js from ^0.21.0 to ^0.21.2 (patch-level).
Address Normalization
src/lib/actions/BaseAction.ts
Modified getAddress() to prepend 0x prefix to keystore addresses if not already present.
Test Updates
tests/libs/baseAction.test.ts
Added/updated tests to verify 0x prefixing behavior for addresses without prefix and prevent double-prefixing of already-prefixed addresses.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 An address without its 0x is incomplete, my friend,
So now we add the prefix to make it 0x-blend,
No double dressing needed, we're precise,
With normalized addresses—oh, how nice! ✨

🚥 Pre-merge checks | ✅ 3
✅ 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 clearly and accurately summarizes the main change: adding 0x prefix normalization to read-only keystore addresses to fix RPC request malformation issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/readOnly-address-0x-prefix
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Copy link

@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.

🧹 Nitpick comments (2)
tests/libs/baseAction.test.ts (2)

2-2: Use path alias for src imports.

As per coding guidelines, use @/* path alias for ./src/* imports.

Suggested fix
-import {BaseAction} from "../../src/lib/actions/BaseAction";
+import {BaseAction} from "@/lib/actions/BaseAction";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/libs/baseAction.test.ts` at line 2, The test imports BaseAction using a
relative path; update the import to use the project path alias for src (replace
"../../src/lib/actions/BaseAction" with the `@/` path e.g.
"@/lib/actions/BaseAction") so tests follow the coding guideline; ensure the
import in tests/libs/baseAction.test.ts references BaseAction via the alias and,
if needed, confirm tsconfig/paths is configured so the alias resolves in the
test runner.

288-293: Consider consolidating redundant test cases.

This test largely duplicates the test at lines 280-286. Both verify that getAccount(true) returns a 0x-prefixed address when the keystore address lacks the prefix. The regex check on line 291 adds minimal value over the strict equality check on line 292.

Consider merging into the existing test
 test("should return address when called with readOnly=true", async () => {
   const address = await baseAction["getAccount"](true);

+  expect(address).toMatch(/^0x/);
   expect(address).toBe(`0x${mockKeystoreData.address}`);
   expect(existsSync).toHaveBeenCalledWith("/mocked/home/.genlayer/keystores/default.json");
   expect(readFileSync).toHaveBeenCalledWith("/mocked/home/.genlayer/keystores/default.json", "utf-8");
 });
-
-test("should return 0x-prefixed address for readOnly even when keystore has no prefix", async () => {
-  const address = await baseAction["getAccount"](true);
-
-  expect(address).toMatch(/^0x/);
-  expect(address).toBe(`0x${mockKeystoreData.address}`);
-});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/libs/baseAction.test.ts` around lines 288 - 293, The test is redundant
with the earlier case that already asserts getAccount(true) returns a
0x-prefixed address; remove or merge this duplicate by either deleting this test
block or adding the regex assertion to the existing test that calls
baseAction["getAccount"](true) (keep the strict equality assert
expect(address).toBe(`0x${mockKeystoreData.address}`) and, if desired, also
include expect(address).toMatch(/^0x/) in that same test) so only one test
covers both checks for getAccount and mockKeystoreData.address.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/libs/baseAction.test.ts`:
- Line 2: The test imports BaseAction using a relative path; update the import
to use the project path alias for src (replace
"../../src/lib/actions/BaseAction" with the `@/` path e.g.
"@/lib/actions/BaseAction") so tests follow the coding guideline; ensure the
import in tests/libs/baseAction.test.ts references BaseAction via the alias and,
if needed, confirm tsconfig/paths is configured so the alias resolves in the
test runner.
- Around line 288-293: The test is redundant with the earlier case that already
asserts getAccount(true) returns a 0x-prefixed address; remove or merge this
duplicate by either deleting this test block or adding the regex assertion to
the existing test that calls baseAction["getAccount"](true) (keep the strict
equality assert expect(address).toBe(`0x${mockKeystoreData.address}`) and, if
desired, also include expect(address).toMatch(/^0x/) in that same test) so only
one test covers both checks for getAccount and mockKeystoreData.address.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b57152c0-d818-403c-bcea-0cf895a5dc03

📥 Commits

Reviewing files that changed from the base of the PR and between f10c99b and 3b8102d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • package.json
  • src/lib/actions/BaseAction.ts
  • tests/libs/baseAction.test.ts

@MuncleUscles MuncleUscles merged commit fa1c1c5 into main Mar 18, 2026
3 checks passed
@MuncleUscles MuncleUscles deleted the fix/readOnly-address-0x-prefix branch March 18, 2026 13:48
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.

1 participant