Skip to content

Conversation

@katspaugh
Copy link
Member

@katspaugh katspaugh commented Oct 28, 2025

Summary

Implements the ability to create new wallets with cryptographically secure randomly generated private keys, complementing the existing import and Ledger functionality.

Features

  • Secure key generation using Node.js crypto.randomBytes() (CSPRNG)
  • Multi-step security flow with explicit user warnings and risk acknowledgment
  • Private key display with one-time visibility and clear backup instructions
  • Backup verification requiring last 8 characters re-entry to confirm
  • Encrypted storage using existing AES-256-GCM + PBKDF2 infrastructure
  • Comprehensive testing - 27 unit tests covering security aspects
  • Integration tests for CLI command execution
  • Full documentation in README with examples and security best practices

Usage

safe wallet create

User Flow

  1. Display security warnings → require confirmation
  2. Set up password for encryption
  3. Enter wallet name
  4. Generate cryptographically secure private key
  5. Display private key once with warnings
  6. Verify user backed up key (enter last 8 chars)
  7. Encrypt and store wallet

Files Changed

New Files

  • src/utils/key-generation.ts - Core key generation utilities
  • src/commands/wallet/create.ts - Wallet creation command
  • src/tests/unit/utils/key-generation.test.ts - 27 comprehensive unit tests

Modified Files

  • src/cli.ts - Register create command
  • src/tests/integration/e2e-wallet-commands.test.ts - Add create command tests
  • src/ui/screens/WalletListScreen.tsx - Show "Never" for unused wallets
  • README.md - Comprehensive documentation update

Testing

All tests passing:

  • ✅ 27 unit tests for key generation
  • ✅ Integration tests for CLI command
  • ✅ Type checking passes
  • ✅ Linting passes
npm test -- key-generation
# Test Files  1 passed (1)
# Tests  27 passed (27)

Security

  • Uses Node.js `crypto.randomBytes(32)` for CSPRNG
  • Validates keys are within secp256k1 curve order
  • Multiple user warnings before generation
  • Private key shown only once during creation
  • Backup verification required before storage
  • Encrypted with AES-256-GCM using existing secure infrastructure

Documentation

Updated README with:

  • Quick start guide showing wallet create as primary option
  • Detailed "Wallet Management" section with security flow
  • Example output and step-by-step walkthrough
  • Security best practices for key backup
  • Updated command reference table

🤖 Generated with Claude Code

Implements the ability to create new wallets with cryptographically
secure randomly generated private keys, complementing the existing
import and Ledger functionality.

Features:
- Secure key generation using Node.js crypto.randomBytes() (CSPRNG)
- Multi-step security flow with explicit user warnings
- Private key display with one-time visibility
- Backup verification requiring last 8 characters re-entry
- Encrypted storage using existing AES-256-GCM infrastructure
- 27 comprehensive unit tests covering security aspects
- Integration tests for CLI command
- Full documentation in README

Command: safe wallet create

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings October 28, 2025 20:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds the ability to create new wallets with randomly generated private keys, eliminating the need for users to provide their own keys. The implementation includes secure key generation using Node.js crypto, comprehensive backup verification flow, and extensive documentation.

  • Introduces generatePrivateKey(), deriveWalletFromPrivateKey(), and generateWalletId() utility functions using cryptographically secure random number generation
  • Implements safe wallet create command with security warnings, password setup, key display, and backup verification
  • Updates documentation with detailed wallet creation guide and security best practices

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/utils/key-generation.ts New utility module for secure private key generation, wallet derivation, and ID generation
src/commands/wallet/create.ts New command implementation for interactive wallet creation workflow with security checks
src/cli.ts Registers the new wallet create command
src/ui/screens/WalletListScreen.tsx Improves UI to always show "Last used" field with "Never" fallback
src/tests/unit/utils/key-generation.test.ts Comprehensive unit tests covering key generation, validation, entropy, and security
src/tests/integration/e2e-wallet-commands.test.ts E2E test verifying the create command is available
README.md Extensive documentation on wallet creation workflow, security practices, and usage examples

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +61 to +62
export function generateWalletId(): string {
return randomBytes(16).toString('hex')
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

The generateWalletId() function duplicates the wallet ID generation logic already present in wallet-store.ts line 121. Consider importing and using this function in WalletStorageService.importWallet() instead of using inline randomBytes(16).toString('hex') to maintain a single source of truth for ID generation.

Copilot uses AI. Check for mistakes.
spinner.start('Storing wallet...')

try {
const wallet = await walletStorage.importWallet(name as string, privateKey, password as string)
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

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

The type assertions name as string and password as string are unnecessary since the control flow guarantees these variables are strings (early returns prevent null/undefined). Remove the type assertions for cleaner code.

Suggested change
const wallet = await walletStorage.importWallet(name as string, privateKey, password as string)
const wallet = await walletStorage.importWallet(name, privateKey, password)

Copilot uses AI. Check for mistakes.
Replaces inline randomBytes(16).toString('hex') calls in wallet-store.ts
with the centralized generateWalletId() utility function to eliminate
code duplication and maintain consistency.

Changes:
- Import generateWalletId from key-generation.ts
- Replace wallet ID generation in importWallet() (line 122)
- Replace wallet ID generation in importLedgerWallet() (line 165)

This ensures all wallet IDs are generated using the same method
across the codebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@katspaugh
Copy link
Member Author

Refactoring Update

Added a follow-up commit to eliminate code duplication:

Changes

  • Replaced inline randomBytes(16).toString('hex') calls in wallet-store.ts with the centralized generateWalletId() function
  • Now there's a single source of truth for wallet ID generation across the codebase
  • Affects both importWallet() and importLedgerWallet() methods

Testing

✅ All tests pass
✅ Type checking passes
✅ Build succeeds

This ensures consistency and makes the ID generation logic easier to maintain and test.

@katspaugh katspaugh merged commit 69e0802 into main Oct 28, 2025
4 checks passed
@katspaugh katspaugh deleted the feat/wallet-create branch October 28, 2025 20:34
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.

2 participants