feat(chat): wire the two-variant send transport (Phase 5)
Make composed messages actually reach the wire: broadcastChatMemos sends the header + payload as two 0-value memo outputs to the peer's z-address (header first, the lower memo position), on both variants. - chat_outgoing: chatSendOutputs(memos, utf8Prefix) — the pure, testable memo encoder. Full-node memos get a "utf8:" prefix (dragonxd rejects raw JSON and then UTF-8-encodes on-chain, byte-identical to SilentDragonXLite's Memo::from_str); the payload is NOT double-hex. Lite memos are raw UTF-8 (the backend does Memo::from_str directly). Header is always output 0. - App::broadcastChatMemos: full-node builds a two-recipient z_sendmany array (amount 0, from the spendable reply z-address, default fee) via submitZSendMany with markFeeGapRetry=true — deliberately, to suppress the fee-gap auto-retry, which rebuilds a single-recipient tx and would drop the payload output. Lite routes to broadcastChatMemosLite (two 0-value LiteSendRecipients, raw memos; the backend accepts duplicate addresses + 0-value for exactly this pattern). - Encoding + design established by a four-codebase mapping (wallet, daemon, SDXL, lite backend) and an adversarial review of the wiring (0 confirmed findings). - Tests: chatSendOutputs (utf8:-prefix + header-first for full-node, raw for lite) + on-chain round-trip (strip "utf8:" -> the harvest parser re-pairs and decrypts). Remaining as a LIVE test (cannot be proven from source): that dragonxd returns the memo under memoStr verbatim, that recipient-array order maps to note position, that a 0-value memo-only tx relays, and full SDXL<->DragonX interop. Gated by DRAGONX_ENABLE_CHAT (default OFF). 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:
@@ -170,9 +170,8 @@ public:
|
||||
wallet::LiteWalletController* liteWallet() { return lite_wallet_.get(); }
|
||||
// HushChat service (identity + in-memory message store); the Chat tab reads its store.
|
||||
chat::ChatService& chatService() { return chat_service_; }
|
||||
// HushChat composing (Phase 4): construct + locally echo an outgoing message (to a conversation
|
||||
// whose peer key we know) / a new-conversation contact request. Network delivery is wired in a
|
||||
// later phase — see broadcastChatMemos.
|
||||
// HushChat composing: construct, broadcast (broadcastChatMemos), and locally echo an outgoing
|
||||
// message (to a conversation whose peer key we know) / a new-conversation contact request.
|
||||
void sendChatMessage(const std::string& conversationId, const std::string& text);
|
||||
void startChatConversation(const std::string& peerZaddr, const std::string& text);
|
||||
// Reason the lite wallet failed to auto-open this session (empty if none / opened OK).
|
||||
@@ -596,7 +595,8 @@ private:
|
||||
void provisionChatIdentityFromSecret(std::string secret);
|
||||
std::string chatReplyZaddr() const; // a stable wallet z-addr for outgoing headers
|
||||
std::string generateChatLocalId(const char* prefix, int numBytes) const; // unique echo id / cid
|
||||
void broadcastChatMemos(const chat::OutgoingChatMemos& memos); // Phase-5 seam (network delivery)
|
||||
void broadcastChatMemos(const chat::OutgoingChatMemos& memos); // full-node z_sendmany / lite
|
||||
void broadcastChatMemosLite(const chat::OutgoingChatMemos& memos); // lite two-recipient send
|
||||
// Lite first-run welcome prompt: dismissed for the session once the user picks an action.
|
||||
bool lite_firstrun_dismissed_ = false;
|
||||
// Lite send-time unlock: set to show the unlock modal when a spend is attempted while locked.
|
||||
|
||||
Reference in New Issue
Block a user