From f8a02cf8223b66bdbf987ee0d9b63d5132592248 Mon Sep 17 00:00:00 2001 From: Edgars Date: Tue, 17 Mar 2026 16:31:26 +0200 Subject: [PATCH 1/2] fix: bump genlayer-js to 0.21.2 for staking wizard min stake fix getEpochInfo now returns validatorMinStakeRaw and validatorMinStake, fixing the "Cannot mix BigInt and other types" crash in the staking wizard. --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index faf8db8..e13739b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "dotenv": "^17.0.0", "ethers": "^6.13.4", "fs-extra": "^11.3.0", - "genlayer-js": "^0.21.0", + "genlayer-js": "^0.21.2", "inquirer": "^12.0.0", "keytar": "^7.9.0", "node-fetch": "^3.0.0", @@ -5581,9 +5581,9 @@ } }, "node_modules/genlayer-js": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/genlayer-js/-/genlayer-js-0.21.0.tgz", - "integrity": "sha512-zUlz74nZPwNcpPiiGk5Njfn0YLbRhmPsIQECMYHivDBp5DI5lrUQt5H3wd4Q+p7af3lk0uzg0jbo31iVaAyTiA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/genlayer-js/-/genlayer-js-0.21.2.tgz", + "integrity": "sha512-2QFfcgcMAdNDIYGw7c5v3BUn6pazVcYvSNCzXKarRY6rf15BHbZGRu3AK1pfXjer+rM7XLgCXUmP48qvcp+i1w==", "license": "MIT", "dependencies": { "eslint-plugin-import": "^2.30.0", diff --git a/package.json b/package.json index a1d74fa..ab63e32 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "dotenv": "^17.0.0", "ethers": "^6.13.4", "fs-extra": "^11.3.0", - "genlayer-js": "^0.21.0", + "genlayer-js": "^0.21.2", "inquirer": "^12.0.0", "keytar": "^7.9.0", "node-fetch": "^3.0.0", From 3b8102d527c14541627a72e87c98d5df8c6254bc Mon Sep 17 00:00:00 2001 From: Edgars Date: Wed, 18 Mar 2026 15:42:47 +0200 Subject: [PATCH 2/2] fix: add 0x prefix to read-only keystore address 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. --- src/lib/actions/BaseAction.ts | 3 ++- tests/libs/baseAction.test.ts | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/lib/actions/BaseAction.ts b/src/lib/actions/BaseAction.ts index 086b6ad..d555a6d 100644 --- a/src/lib/actions/BaseAction.ts +++ b/src/lib/actions/BaseAction.ts @@ -169,7 +169,8 @@ export class BaseAction extends ConfigFileManager { } private getAddress(keystoreData: any): Address { - return keystoreData.address as Address; + const addr = keystoreData.address; + return (addr.startsWith('0x') ? addr : `0x${addr}`) as Address; } protected async createKeypairByName(accountName: string, overwrite: boolean, passwordInput?: string): Promise { diff --git a/tests/libs/baseAction.test.ts b/tests/libs/baseAction.test.ts index 278530b..91ad3f9 100644 --- a/tests/libs/baseAction.test.ts +++ b/tests/libs/baseAction.test.ts @@ -280,11 +280,30 @@ describe("BaseAction", () => { test("should return address when called with readOnly=true", async () => { const address = await baseAction["getAccount"](true); - expect(address).toBe(mockKeystoreData.address); + 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}`); + }); + + test("should not double-prefix address that already has 0x", async () => { + const prefixedKeystoreData = { + ...mockKeystoreData, + address: "0x1234567890123456789012345678901234567890", + }; + vi.mocked(readFileSync).mockReturnValue(JSON.stringify(prefixedKeystoreData)); + + const address = await baseAction["getAccount"](true); + + expect(address).toBe("0x1234567890123456789012345678901234567890"); + }); + test("should create new keypair when keystore file does not exist", async () => { vi.mocked(existsSync).mockReturnValue(false); vi.mocked(inquirer.prompt)