feat: BIP-39 master seed for unified key derivation

Replace fragmented random key generation with a single 24-word BIP-39
mnemonic that deterministically derives all node keys: Ed25519 (DID),
secp256k1 (Nostr/Bitcoin), BIP-84 xprv (Bitcoin Core), and LND aezeed
entropy. New onboarding flow: seed generate → word verification → identity
naming. Restore path enabled via 24-word entry. Includes seed RPC handlers,
mock backend support, LND/Bitcoin Core wallet-from-seed integration, and
UI polish across settings and discover views.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-31 01:41:24 +01:00
co-authored by Claude Opus 4.6
parent 5da9e217e6
commit 19dcfd4f31
50 changed files with 2200 additions and 258 deletions
+12 -12
View File
@@ -436,7 +436,7 @@ mod tests {
#[tokio::test]
async fn test_session_create_and_validate() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let token = store.create().await;
assert!(store.validate(&token).await);
@@ -444,13 +444,13 @@ mod tests {
#[tokio::test]
async fn test_session_invalid_token() {
let store = SessionStore::new();
let store = SessionStore::new().await;
assert!(!store.validate("nonexistent_token").await);
}
#[tokio::test]
async fn test_session_remove() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let token = store.create().await;
assert!(store.validate(&token).await);
@@ -460,7 +460,7 @@ mod tests {
#[tokio::test]
async fn test_pending_session_upgrade() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let secret = vec![1, 2, 3, 4];
let token = store.create_pending(secret.clone()).await;
@@ -484,7 +484,7 @@ mod tests {
#[tokio::test]
async fn test_pending_session_max_attempts() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let secret = vec![1, 2, 3];
let token = store.create_pending(secret).await;
@@ -513,7 +513,7 @@ mod tests {
#[tokio::test]
async fn test_session_activity_updates_on_validate() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let token = store.create().await;
// First validation should succeed and touch last_activity
@@ -525,7 +525,7 @@ mod tests {
#[tokio::test]
async fn test_invalidate_all_except() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let token1 = store.create().await;
let token2 = store.create().await;
let token3 = store.create().await;
@@ -540,7 +540,7 @@ mod tests {
#[tokio::test]
async fn test_session_rotate() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let old_token = store.create().await;
assert!(store.validate(&old_token).await);
@@ -555,7 +555,7 @@ mod tests {
#[tokio::test]
async fn test_max_concurrent_sessions() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let mut tokens = Vec::new();
// Create MAX_CONCURRENT_SESSIONS sessions
@@ -583,7 +583,7 @@ mod tests {
#[tokio::test]
async fn test_active_session_count() {
let store = SessionStore::new();
let store = SessionStore::new().await;
assert_eq!(store.active_session_count().await, 0);
let token1 = store.create().await;
@@ -598,7 +598,7 @@ mod tests {
#[tokio::test]
async fn test_cleanup_expired_removes_stale() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let token = store.create().await;
assert!(store.validate(&token).await);
@@ -611,7 +611,7 @@ mod tests {
#[tokio::test]
async fn test_rotate_preserves_session_count() {
let store = SessionStore::new();
let store = SessionStore::new().await;
let token = store.create().await;
assert_eq!(store.active_session_count().await, 1);