diff --git a/src/commands/config/getSetReset.ts b/src/commands/config/getSetReset.ts index b7499316..9a49e1a1 100644 --- a/src/commands/config/getSetReset.ts +++ b/src/commands/config/getSetReset.ts @@ -44,8 +44,7 @@ export class ConfigActions extends BaseAction { return; } - delete config[key]; - this.writeConfig(key, undefined); + this.removeConfig(key); this.succeedSpinner(`Configuration successfully reset`); } } diff --git a/src/commands/network/setNetwork.ts b/src/commands/network/setNetwork.ts index de771cb8..d6c50a5c 100644 --- a/src/commands/network/setNetwork.ts +++ b/src/commands/network/setNetwork.ts @@ -98,7 +98,7 @@ export class NetworkActions extends BaseAction { async setNetwork(networkName?: string): Promise { const entries = this.getNetworkEntries(); - if (networkName || networkName === "") { + if (networkName) { const selectedNetwork = entries.find(n => n.alias === networkName || (n.type === "built-in" && n.name === networkName), ); diff --git a/src/lib/actions/BaseAction.ts b/src/lib/actions/BaseAction.ts index 92a0d665..943ca49b 100644 --- a/src/lib/actions/BaseAction.ts +++ b/src/lib/actions/BaseAction.ts @@ -8,6 +8,8 @@ import {createClient, createAccount} from "genlayer-js"; import {localnet, studionet, testnetAsimov, testnetBradbury} from "genlayer-js/chains"; import type {GenLayerClient, GenLayerChain, Hash, Address, Account} from "genlayer-js/types"; import { +import { ethers } from "ethers"; +import { writeFileSync, existsSync, readFileSync } from "fs"; applyCustomNetworkProfile, CUSTOM_NETWORKS_CONFIG_KEY, normalizeCustomNetworks, @@ -58,8 +60,6 @@ export function resolveNetwork(stored: string | undefined, customNetworks?: Cust throw new Error(`Unknown network: ${stored}`); } } -import { ethers } from "ethers"; -import { writeFileSync, existsSync, readFileSync } from "fs"; export class BaseAction extends ConfigFileManager { private static readonly DEFAULT_ACCOUNT_NAME = "default"; @@ -90,9 +90,19 @@ export class BaseAction extends ConfigFileManager { const wallet = await ethers.Wallet.fromEncryptedJson(keystoreJson, password); return wallet.privateKey; - } catch (error) { + } catch (error: any) { + // Re-throw non-password errors (corrupted keystore, malformed JSON, etc.) + const isPasswordError = + error?.message?.toLowerCase().includes("password") || + error?.message?.toLowerCase().includes("decrypt") || + error?.code === "INVALID_ARGUMENT"; + if (!isPasswordError) { + throw new Error(`Failed to decrypt keystore: ${error?.message ?? error}`); + } + if (attempt >= BaseAction.MAX_PASSWORD_ATTEMPTS) { this.failSpinner(`Maximum password attempts exceeded (${BaseAction.MAX_PASSWORD_ATTEMPTS}/${BaseAction.MAX_PASSWORD_ATTEMPTS}).`); + return ""; } return await this.decryptKeystore(keystoreJson, attempt + 1); } @@ -149,6 +159,10 @@ export class BaseAction extends ConfigFileManager { if (!existsSync(keystorePath)) { await this.confirmPrompt(`Account '${accountName}' not found. Would you like to create it?`); decryptedPrivateKey = await this.createKeypairByName(accountName, false); + if (!existsSync(keystorePath)) { + this.failSpinner(`Failed to create keystore file for account '${accountName}'. Check disk space and permissions.`); + return; + } } keystoreJson = readFileSync(keystorePath, "utf-8");