mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 08:04:45 +00:00
fix: drill relay attribution into Marmot kind-445 inner notes
Audit follow-up to the gift-wrap relay-icon fix: Marmot group chat rows render the decrypted inner note (kind 9/7) via the standard chat feed with RelayBadgesHorizontal, but nothing ever populated that note's relay list — OK acceptances and relay deliveries all landed on the kind-445 envelope, which has no link to its inner event. - GroupEvent now implements HasInnerEvent (same @Transient @Volatile innerEventId pattern as GiftWrapEvent/SealedRumorEvent), so LocalCache.addRelayToNoteAndInners drills 445 -> inner for both OK confirmations and duplicate EVENT deliveries. RouteMaker is unaffected: it gates on the concrete wrap types before casting to HasInnerEvent. - GroupEventHandler sets innerEventId at decrypt time and copies the envelope's accumulated relays down to the inner note (looked up by event.id, not the eventNote/publicNote params, which belong to the triggering event when replayed from retryPendingFor). - sendMarmotGroupMessage sets innerEventId on the freshly built envelope before consuming/publishing, so acceptances for sent group messages reach the rendered note as soon as the inner note is indexed. Also audited the remaining chat-rendered types: NIP-04 PrivateDmEvent, ChatMessageEvent rumors, NIP-C7 ChatEvent, ChannelMessage/Ephemeral/ LiveActivities messages all route through consumeRegularEvent (duplicates covered by the shared helper), and NIP-37 drafts render the wrap note itself with markAsSeen covering the version/addressable pair. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YEiq1NMK3q12KGQ2yYhPEp
This commit is contained in:
@@ -2632,6 +2632,10 @@ class Account(
|
||||
Log.d("MarmotDbg") {
|
||||
"sendMarmotGroupMessage: built outer kind:${outbound.signedEvent.kind} id=${outbound.signedEvent.id.take(8)}…"
|
||||
}
|
||||
// Link the envelope to the inner message we just encrypted so relay
|
||||
// OK acceptances drill down to the note the chat renders (see
|
||||
// LocalCache.addRelayToNoteAndInners).
|
||||
outbound.signedEvent.innerEventId = innerEvent.id
|
||||
cache.justConsumeMyOwnEvent(outbound.signedEvent)
|
||||
// Sending a message moves the group out of "New Requests" into
|
||||
// "Known" — do this eagerly before relay round-trip so the UI
|
||||
|
||||
+12
@@ -617,6 +617,18 @@ class GroupEventHandler(
|
||||
}
|
||||
}
|
||||
|
||||
// Link the envelope to its inner note and copy over the
|
||||
// relays that delivered/accepted the kind-445 so far, so
|
||||
// the chat row shows relay icons. Later acceptances drill
|
||||
// down on their own via LocalCache.addRelayToNoteAndInners
|
||||
// once innerEventId is set. The outer note is looked up by
|
||||
// event.id — NOT eventNote/publicNote, which belong to the
|
||||
// *triggering* event when this runs from retryPendingFor.
|
||||
event.innerEventId = innerEvent.id
|
||||
cache.getNoteIfExists(event.id)?.let { outerNote ->
|
||||
cache.copyRelaysFromTo(outerNote, innerEvent.id)
|
||||
}
|
||||
|
||||
// Track the message in the Marmot group chatroom
|
||||
account.marmotGroupList.addMessage(result.groupId, innerNote)
|
||||
|
||||
|
||||
+15
-1
@@ -25,7 +25,9 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.HasInnerEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlin.concurrent.Volatile
|
||||
|
||||
/**
|
||||
* Marmot Group Event (MIP-03) — kind 445.
|
||||
@@ -59,7 +61,19 @@ class GroupEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
HasInnerEvent {
|
||||
// Set when the app layer learns the envelope ↔ inner mapping: on decrypt
|
||||
// for inbound events, at build time for outbound ones. Lets relay
|
||||
// attribution (OK acceptances, duplicate deliveries) drill from the
|
||||
// kind-445 envelope down to the inner note the chat UI renders.
|
||||
// `@Volatile`: written by the decrypt coroutine, read by relay socket
|
||||
// threads.
|
||||
@kotlinx.serialization.Transient
|
||||
@kotlin.jvm.Transient
|
||||
@Volatile
|
||||
override var innerEventId: HexKey? = null
|
||||
|
||||
/**
|
||||
* Base64-encoded encrypted content: nonce(12 bytes) || ciphertext.
|
||||
* Decrypt with ChaCha20-Poly1305 using the MLS exporter-derived key.
|
||||
|
||||
Reference in New Issue
Block a user