-
Notifications
You must be signed in to change notification settings - Fork 18
fix: harden config and keystore handling #409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v0.40-dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -91,8 +91,14 @@ export class BaseAction extends ConfigFileManager { | |
|
|
||
| return wallet.privateKey; | ||
| } catch (error) { | ||
| const message = error instanceof Error ? error.message : String(error); | ||
| const isPasswordError = /password|decrypt/i.test(message); | ||
| if (!isPasswordError) { | ||
| throw error; | ||
| } | ||
| if (attempt >= BaseAction.MAX_PASSWORD_ATTEMPTS) { | ||
| this.failSpinner(`Maximum password attempts exceeded (${BaseAction.MAX_PASSWORD_ATTEMPTS}/${BaseAction.MAX_PASSWORD_ATTEMPTS}).`); | ||
| throw new Error("Maximum password attempts exceeded"); | ||
| } | ||
| return await this.decryptKeystore(keystoreJson, attempt + 1); | ||
| } | ||
|
|
@@ -149,6 +155,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}'.`, undefined, false); | ||
| throw new Error(`Failed to create keystore file for account '${accountName}'.`); | ||
| } | ||
|
Comment on lines
+158
to
+161
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Apply the keystore existence check to the recreation path. This check only covers the initial 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| keystoreJson = readFileSync(keystorePath, "utf-8"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: genlayerlabs/genlayer-cli
Length of output: 451
🏁 Script executed:
Repository: genlayerlabs/genlayer-cli
Length of output: 24893
🌐 Web query:
ethers v6.13.4 Wallet.fromEncryptedJson wrong password error code message source💡 Result:
In ethers v6.13.4, the Wallet.fromEncryptedJson method does not return a specific error code for an incorrect password [1][2]. Instead, it throws an error with the message "incorrect password" [1][3]. This occurs within the decryptKeystoreJson function (which is called by Wallet.fromEncryptedJson) [1][2]. The library uses an internal assertion to verify the keystore's message authentication code (MAC) against the computed one, and if they do not match, it explicitly throws an error: assertArgument(computedMAC === spelunk(data, "crypto.mac:string!").toLowerCase, "incorrect password", "password", "[ REDACTED ]"); [1][3] While ethers v6 utilizes a comprehensive system of error codes for most operational and input-related failures (such as "INVALID_ARGUMENT" or "UNSUPPORTED_OPERATION") [4][5], the "incorrect password" error is an authentication-specific failure that relies on a human-readable message rather than a standardized machine-readable error code [1][4]. Consequently, you should identify this specific failure by checking if the error's message property equals "incorrect password" rather than relying on an error code [1].
Citations:
🏁 Script executed:
Repository: genlayerlabs/genlayer-cli
Length of output: 6905
🏁 Script executed:
Repository: genlayerlabs/genlayer-cli
Length of output: 1539
🏁 Script executed:
Repository: genlayerlabs/genlayer-cli
Length of output: 11885
🏁 Script executed:
Repository: genlayerlabs/genlayer-cli
Length of output: 12983
Match ethers’ wrong-password error fields before retrying.
The lockfile resolves
ethers6.15.0. Retry only errors withcode === "INVALID_ARGUMENT",argument === "password", andshortMessage === "incorrect password". Re-throw all other errors unchanged. Add tests for wrong passwords, malformed JSON, corrupted ciphertext, and prompt failures. A corrupted ciphertext with an unchanged MAC produces the same ethers error as a wrong password and is not distinguishable here.🤖 Prompt for AI Agents