Skip to content

fix: write mnemonic to dead-drop file instead of stderr#22

Draft
jim-counter wants to merge 2 commits intomainfrom
fix/mnemonic-dead-drop
Draft

fix: write mnemonic to dead-drop file instead of stderr#22
jim-counter wants to merge 2 commits intomainfrom
fix/mnemonic-dead-drop

Conversation

@jim-counter
Copy link
Copy Markdown
Member

Summary

  • Replaces stderr mnemonic output in wallet create with a chmod-000 dead-drop file at ~/.openclaw/auto-respawn/.last-mnemonic
  • Agent never sees the recovery phrase — only the file path appears in JSON output
  • Human operator retrieves the phrase manually: chmod 600, cat, back up, rm

Changes

  • lib/wallet.ts — added writeMnemonicDeadDrop() (write with 0600, then chmod 000), refactored path constants
  • auto-respawn.ts — replaced stderr mnemonic block with dead-drop call, added mnemonicPath and security message to JSON output
  • SKILL.md — updated wallet create docs, local storage section, important notes, and usage examples

Test plan

  • npm run typecheck passes
  • npm run lint passes
  • npm test passes (88 tests)
  • Manual: wallet create no longer prints mnemonic to stderr
  • Manual: .last-mnemonic file created with 000 permissions
  • Manual: chmod 600 && cat retrieves the phrase correctly

Closes #16

🤖 Generated with Claude Code

The recovery phrase was printed to stderr, which agent frameworks
capture into the session transcript. Replace with a chmod-000 file
at ~/.openclaw/auto-respawn/.last-mnemonic that only the human
operator can retrieve.

Closes #16

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use .mnemonic-<name> instead of a single .last-mnemonic so multiple
wallets can be created without collision. Check for a stale dead-drop
before creating the wallet keyfile to avoid orphaning a wallet whose
mnemonic was never retrieved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jim-counter jim-counter marked this pull request as draft February 27, 2026 18:21
@jim-counter
Copy link
Copy Markdown
Member Author

bugbot run

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

console.error('')
// Write mnemonic to a dead-drop file (chmod 000) instead of stderr.
// The agent never sees the phrase — only the file path appears in output.
const mnemonicPath = await writeMnemonicDeadDrop(name, result.mnemonic)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wallet persisted before mnemonic, risking irrecoverable phrase loss

High Severity

createWallet persists the encrypted keyfile to disk (via encryptAndSave) before writeMnemonicDeadDrop is called. If the dead-drop write fails (disk full, permission error, etc.), the wallet keyfile already exists but the mnemonic is permanently lost — it only lived in process memory. On retry, createWallet rejects with "wallet already exists" and ensureNoStaleMnemonic finds no dead-drop to warn about, leaving the wallet irrecoverable from its mnemonic. The mnemonic dead-drop write needs to succeed before the wallet keyfile is committed to disk, or createWallet needs to be refactored to separate generation from persistence.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

auto-respawn: mnemonic should not appear on stdout (agent sees it)

1 participant