// DragonX Wallet - HushChat service (implementation). #include "chat_service.h" #include "chat_database.h" #include namespace dragonx::chat { ChatService::~ChatService() { clearIdentity(); } void ChatService::setIdentity(const ChatKeyPair& keys) { identity_ = keys; has_identity_ = true; } void ChatService::clearIdentity() { wipeChatKeyPair(identity_); has_identity_ = false; } int ChatService::ingest(const std::vector& metadata, const std::unordered_map& txTimestamps, std::int64_t fallbackTimestamp) { if (!has_identity_) return 0; int added = 0; for (const auto& meta : metadata) { ChatMessage message; message.direction = ChatDirection::Incoming; message.txid = meta.txid; message.conversation_id = meta.conversation_id; message.peer_zaddr = meta.reply_zaddr; message.peer_public_key_hex = meta.sender_public_key_hex; const auto timeIt = txTimestamps.find(meta.txid); message.timestamp = timeIt != txTimestamps.end() ? timeIt->second : fallbackTimestamp; message.payload_position = meta.payload_position; if (meta.type == HushChatHeaderType::ContactRequest) { message.kind = ChatMessageKind::ContactRequest; message.body = meta.payload_memo; // plaintext request text } else { message.kind = ChatMessageKind::Message; std::string plaintext; const ChatCryptoStatus status = decryptIncoming( identity_, meta.sender_public_key_hex, meta.secretstream_header_hex, meta.payload_memo, plaintext); if (status != ChatCryptoStatus::Ok) continue; // drop undecryptable silently message.body = std::move(plaintext); } // In-memory store dedups (txid+position); only persist the genuinely new ones. On the next // session loadFromDatabase() repopulates the store, so re-scanning the chain re-ingests but // the store dedup prevents a duplicate write. if (store_.append(message)) { if (db_) db_->append(message); ++added; } } return added; } void ChatService::loadFromDatabase() { if (!db_) return; for (const auto& message : db_->load()) { store_.append(message); } } } // namespace dragonx::chat