feat(chat): provision seed-derived identity + wire the receive sink
Complete the Phase-1 App integration for HushChat, now that the dragonx `hd-transparent-keys` daemon exposes a BIP39 mnemonic (z_exportmnemonic) that is byte-compatible with SilentDragonXLite. Both variants derive the chat identity from the wallet's OWN seed phrase, so it is portable across full-node and lite (same words -> same KDF input -> same identity) and recoverable from the single wallet backup. - App owns a dragonx::chat::ChatService; maybeProvisionChatIdentity() runs each update() tick and, once the wallet seed is reachable and unlocked, derives the identity via deriveChatIdentityFromSecret and sets it on the service. Full-node fetches z_exportmnemonic off the UI thread via the RPC worker; lite reads it synchronously through LiteWalletController::exportSeed. Secrets are wiped on every path. - Wire the previously-dead TransactionRefreshResult.hushChatMetadata sink: both the full and recent transaction-refresh completions now ChatService ::ingest the harvested memos (before the result is moved) so incoming messages are decrypted and threaded. The store dedups across both paths. - Robust provisioning gates: skip + re-arm on relock (isLocked, mirrored for both variants), don't fetch before the encryption state is known, and treat a non-mnemonic wallet (RpcError) as identity-unavailable rather than retrying every tick. rebuildLiteWallet re-arms so a server switch / re-open re-derives from the newly opened wallet. Gated by DRAGONX_ENABLE_CHAT (default OFF) via the constexpr hushChatFeatureEnabledAtBuild() gate, so the wiring folds away in shipping builds. Verified: Linux + Windows(mingw) build with chat ON, ctest 100%, hygiene clean; caches restored to the OFF default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
12
src/app.cpp
12
src/app.cpp
@@ -602,6 +602,13 @@ void App::rebuildLiteWallet(bool force)
|
||||
// controller but never reopen, leaving a permanent "disconnected" state.
|
||||
lite_autoopen_done_ = false;
|
||||
lite_open_error_.clear();
|
||||
|
||||
// A rebuilt controller may back a different wallet (server switch / re-open); drop any chat
|
||||
// identity and re-arm provisioning so it re-derives from the newly opened wallet's seed.
|
||||
chat_service_.clearIdentity();
|
||||
chat_identity_provisioned_ = false;
|
||||
chat_identity_fetch_in_flight_ = false;
|
||||
chat_identity_unavailable_ = false;
|
||||
}
|
||||
|
||||
void App::update()
|
||||
@@ -696,6 +703,11 @@ void App::update()
|
||||
}
|
||||
async_tasks_.reapCompleted();
|
||||
|
||||
// HushChat: once the wallet seed is reachable+unlocked, derive & set the chat identity so the
|
||||
// transaction-refresh harvest can decrypt incoming memos. Cheap early-outs keep it idle until
|
||||
// it can act; compiled away when the feature is off (constexpr gate inside).
|
||||
maybeProvisionChatIdentity();
|
||||
|
||||
// Auto-lock check (only when connected + encrypted + unlocked)
|
||||
if (state_.connected && state_.isUnlocked()) {
|
||||
checkAutoLock();
|
||||
|
||||
Reference in New Issue
Block a user