Skip to content

Password - #10

Closed
dkackman wants to merge 63 commits into
mainfrom
password
Closed

dkackman wants to merge 63 commits into
mainfrom
password

Conversation

@dkackman

Copy link
Copy Markdown
Owner

No description provided.

dkackman and others added 30 commits March 15, 2026 13:21
Design for issue xch-dev#206: opt-in per-operation password protection
for wallet secret access, transaction signing, and hardened key
generation. Includes biometric convenience layer design.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10-task plan covering keychain core changes, API layer modifications,
backend endpoint threading, integration tests, and Tauri/frontend
skeleton. Includes bincode backward compatibility handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add password_protected bool field to the Secret variant of KeyData,
with LegacyKeyData enum and backward-compatible bincode deserialization
in from_bytes(). Update all construction sites to set the flag based on
whether a non-empty password was provided. Add is_password_protected()
accessor to Keychain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add change_password() method to Keychain that decrypts with the old
password and re-encrypts with a new one, updating the password_protected
flag. Add KeyNotFound and NoSecretKey error variants. Include tests for
password changing, wrong password rejection, public key rejection,
flag-on-import behavior, serialization roundtrip, and legacy format
backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add password parameter to sign(), transact(), and transact_with() and
thread it from every endpoint request struct through to the keychain.
Add change_password endpoint and populate has_password on KeyInfo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace two-step promptIfEnabled + requestPassword auth with unified
requestPassword returning string | null | undefined, where undefined
means cancelled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…bels

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Biometric authentication is a global setting (not per-wallet), so it
belongs in the Preferences section of GlobalSettings rather than the
per-wallet Security section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Biometric unlock now works across multiple operations. The skip flag
   is cleared at the start of requestPassword when the previous keychain
   password was accepted (i.e., we're called again without a manual
   dialog entry in between).

2. Delete confirmation dialog now closes when the password prompt is
   cancelled, matching the Details dialog behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These unauthorized errors were silently swallowed because they don't
contain "decrypt" in the reason string. They indicate wallet-level
issues (missing key, watch-only wallet) that the user should see,
unlike NotLoggedIn/NoSigningKey which are expected during transitions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The biometric toggle is a global setting (not per-wallet), so it
belongs in GlobalSettings Preferences, not the per-wallet Security
section. Updated spec to match implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dkackman and others added 29 commits March 16, 2026 13:04
When the backend rejects a keychain-retrieved password (decrypt error),
ErrorContext calls notifyDecryptError() which marks the fingerprint as
stale in PasswordContext. The next requestPassword call skips keychain
and shows the dialog directly. When the user types the correct password
via the dialog, handleSubmit clears the stale flag and updates keychain.

This gives the user a recoverable path without needing to know they
should cancel the biometric prompt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all keychain password storage — password wallets always use the
dialog, biometric is a standalone gate for no-password wallets only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dkackman dkackman closed this Aug 22, 2026
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.

1 participant