feat(mesh): rich typed Sent records and echo dedup
Adds message_type + typed_payload (JSON) to MeshMessage so the UI can render invoice/alert/coordinate/tx/lightning messages as structured cards in both directions instead of showing raw wire bytes on the Sent side. RPC handlers now route through send_typed_wire / send_channel_typed_wire which transmit the binary envelope directly (no utf8_lossy corruption) and record a rich Sent MeshMessage. Also: store_message deduplicates echo-back doubles (20-msg lookback, 30s window), from_name is plumbed through the federation Incoming path, and peer_dest_prefix / send_raw_payload are factored out of send_message. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
18284e1592
commit
3ed9243c50
@@ -38,8 +38,15 @@ impl RpcHandler {
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("Mesh service not running"))?;
|
||||
|
||||
let wire_str = String::from_utf8_lossy(&wire).to_string();
|
||||
let msg = svc.send_message(contact_id, &wire_str).await?;
|
||||
let display = format!(
|
||||
"Invoice: {} sats{}",
|
||||
amount_sats,
|
||||
memo.as_ref().map(|m| format!(" — {}", m)).unwrap_or_default()
|
||||
);
|
||||
let typed_json = serde_json::to_value(&invoice).ok();
|
||||
let msg = svc
|
||||
.send_typed_wire(contact_id, wire, "invoice", &display, typed_json)
|
||||
.await?;
|
||||
|
||||
info!(contact_id, amount_sats, "Sent invoice over mesh");
|
||||
Ok(serde_json::json!({
|
||||
@@ -77,8 +84,16 @@ impl RpcHandler {
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("Mesh service not running"))?;
|
||||
|
||||
let wire_str = String::from_utf8_lossy(&wire).to_string();
|
||||
let msg = svc.send_message(contact_id, &wire_str).await?;
|
||||
let display = format!(
|
||||
"Location: {:.6}, {:.6}{}",
|
||||
coord.lat_degrees(),
|
||||
coord.lng_degrees(),
|
||||
coord.label.as_ref().map(|l| format!(" ({})", l)).unwrap_or_default()
|
||||
);
|
||||
let typed_json = serde_json::to_value(&coord).ok();
|
||||
let msg = svc
|
||||
.send_typed_wire(contact_id, wire, "coordinate", &display, typed_json)
|
||||
.await?;
|
||||
|
||||
info!(contact_id, "Sent coordinate over mesh");
|
||||
Ok(serde_json::json!({
|
||||
@@ -153,13 +168,23 @@ impl RpcHandler {
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("Mesh service not running"))?;
|
||||
|
||||
let wire_str = String::from_utf8_lossy(&wire).to_string();
|
||||
let display = alert.message.clone();
|
||||
let typed_json = serde_json::to_value(&alert).ok();
|
||||
if broadcast {
|
||||
// Send on channel (all peers)
|
||||
svc.send_message(0, &wire_str).await?;
|
||||
// Send on public channel (all peers) as raw bytes so the binary
|
||||
// envelope is not corrupted by utf8 conversion.
|
||||
svc.send_channel_typed_wire(0, wire, "alert", &display, typed_json.clone())
|
||||
.await?;
|
||||
info!(alert_type = alert_type_str, "Broadcast alert over mesh");
|
||||
} else if let Some(contact_id) = params["contact_id"].as_u64() {
|
||||
svc.send_message(contact_id as u32, &wire_str).await?;
|
||||
svc.send_typed_wire(
|
||||
contact_id as u32,
|
||||
wire,
|
||||
"alert",
|
||||
&display,
|
||||
typed_json,
|
||||
)
|
||||
.await?;
|
||||
info!(contact_id, alert_type = alert_type_str, "Sent alert to peer");
|
||||
} else {
|
||||
anyhow::bail!("Must specify contact_id or broadcast: true");
|
||||
|
||||
Reference in New Issue
Block a user