Improves the feedback to messages from relays.

This commit is contained in:
Vitor Pamplona
2023-10-16 11:54:14 -04:00
parent 202af650de
commit 4286b64b41
4 changed files with 137 additions and 77 deletions
@@ -406,7 +406,7 @@ class Account(
) )
} }
broadcastPrivately(giftWraps) broadcastPrivately(NIP24Factory.Result(senderReaction, giftWraps))
} else { } else {
val giftWraps = NIP24Factory().createReactionWithinGroup( val giftWraps = NIP24Factory().createReactionWithinGroup(
emojiUrl = emojiUrl, emojiUrl = emojiUrl,
@@ -459,7 +459,7 @@ class Account(
recipientPubKey = it recipientPubKey = it
) )
broadcastPrivately(listOf(giftWraps)) broadcastPrivately(NIP24Factory.Result(senderReaction, listOf(giftWraps)))
} }
} else { } else {
val giftWraps = NIP24Factory().createReactionWithinGroup( val giftWraps = NIP24Factory().createReactionWithinGroup(
@@ -1662,7 +1662,7 @@ class Account(
event = sealedEvent, event = sealedEvent,
recipientPubKey = it recipientPubKey = it
) )
broadcastPrivately(listOf(giftWraps)) broadcastPrivately(NIP24Factory.Result(chatMessageEvent, listOf(giftWraps)))
} }
} }
} else { } else {
@@ -1683,42 +1683,53 @@ class Account(
} }
} }
fun broadcastPrivately(signedEvents: List<GiftWrapEvent>) { fun broadcastPrivately(signedEvents: NIP24Factory.Result) {
signedEvents.forEach { val mine = signedEvents.wraps.filter {
Client.send(it) (it.recipientPubKey() == keyPair.pubKey.toHexKey())
}
mine.forEach {
// Only keep in cache the GiftWrap for the account. // Only keep in cache the GiftWrap for the account.
if (it.recipientPubKey() == keyPair.pubKey.toHexKey()) { if (loginWithExternalSigner) {
if (loginWithExternalSigner) { ExternalSignerUtils.decrypt(it.content, it.pubKey, it.id, SignerType.NIP44_DECRYPT)
ExternalSignerUtils.decrypt(it.content, it.pubKey, it.id, SignerType.NIP44_DECRYPT) val decryptedContent = ExternalSignerUtils.cachedDecryptedContent[it.id] ?: ""
val decryptedContent = ExternalSignerUtils.cachedDecryptedContent[it.id] ?: "" if (decryptedContent.isEmpty()) return
if (decryptedContent.isEmpty()) return it.cachedGift(keyPair.pubKey, decryptedContent)?.let { cached ->
it.cachedGift(keyPair.pubKey, decryptedContent)?.let { cached -> if (cached is SealedGossipEvent) {
if (cached is SealedGossipEvent) { ExternalSignerUtils.decrypt(cached.content, cached.pubKey, cached.id, SignerType.NIP44_DECRYPT)
ExternalSignerUtils.decrypt(cached.content, cached.pubKey, cached.id, SignerType.NIP44_DECRYPT) val localDecryptedContent = ExternalSignerUtils.cachedDecryptedContent[cached.id] ?: ""
val localDecryptedContent = ExternalSignerUtils.cachedDecryptedContent[cached.id] ?: "" if (localDecryptedContent.isEmpty()) return
if (localDecryptedContent.isEmpty()) return cached.cachedGossip(keyPair.pubKey, localDecryptedContent)?.let { gossip ->
cached.cachedGossip(keyPair.pubKey, localDecryptedContent)?.let { gossip -> LocalCache.justConsume(gossip, null)
LocalCache.justConsume(gossip, null)
}
} else {
LocalCache.justConsume(it, null)
}
}
} else {
it.cachedGift(keyPair.privKey!!)?.let {
if (it is SealedGossipEvent) {
it.cachedGossip(keyPair.privKey!!)?.let {
LocalCache.justConsume(it, null)
}
} else {
LocalCache.justConsume(it, null)
} }
} else {
LocalCache.justConsume(it, null)
}
}
} else {
it.cachedGift(keyPair.privKey!!)?.let {
if (it is SealedGossipEvent) {
it.cachedGossip(keyPair.privKey!!)?.let {
LocalCache.justConsume(it, null)
}
} else {
LocalCache.justConsume(it, null)
} }
} }
LocalCache.consume(it, null)
} }
LocalCache.consume(it, null)
}
val mineNote = LocalCache.getNoteIfExists(mine.first().id)
signedEvents.wraps.forEach {
// Creates an alias
if (mineNote != null && it.recipientPubKey() != keyPair.pubKey.toHexKey()) {
LocalCache.getOrAddAliasNote(it.id, mineNote)
}
Client.send(it)
} }
} }
@@ -166,6 +166,18 @@ object LocalCache {
return null return null
} }
fun getOrAddAliasNote(idHex: String, note: Note): Note {
checkNotInMainThread()
return notes.get(idHex) ?: run {
require(isValidHex(idHex)) {
"$idHex is not a valid hex"
}
notes.putIfAbsent(idHex, note) ?: note
}
}
fun getOrCreateNote(idHex: String): Note { fun getOrCreateNote(idHex: String): Note {
checkNotInMainThread() checkNotInMainThread()
@@ -17,6 +17,7 @@ import com.vitorpamplona.quartz.events.ChannelMessageEvent
import com.vitorpamplona.quartz.events.ContactListEvent import com.vitorpamplona.quartz.events.ContactListEvent
import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent import com.vitorpamplona.quartz.events.EmojiPackSelectionEvent
import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.EventInterface
import com.vitorpamplona.quartz.events.GenericRepostEvent import com.vitorpamplona.quartz.events.GenericRepostEvent
import com.vitorpamplona.quartz.events.GiftWrapEvent import com.vitorpamplona.quartz.events.GiftWrapEvent
import com.vitorpamplona.quartz.events.LnZapEvent import com.vitorpamplona.quartz.events.LnZapEvent
@@ -208,6 +209,28 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
} }
} }
override fun markAsSeenOnRelay(eventId: String, relay: Relay) {
super.markAsSeenOnRelay(eventId, relay)
val note = LocalCache.getNoteIfExists(eventId) ?: return
val privKey = account.keyPair.privKey ?: return
val noteEvent = note.event ?: return
markInnerAsSeenOnRelay(noteEvent, privKey, relay)
}
private fun markInnerAsSeenOnRelay(noteEvent: EventInterface, privKey: ByteArray, relay: Relay) {
LocalCache.getNoteIfExists(noteEvent.id())?.addRelay(relay)
if (noteEvent is GiftWrapEvent) {
val gift = noteEvent.cachedGift(privKey) ?: return
markInnerAsSeenOnRelay(gift, privKey, relay)
} else if (noteEvent is SealedGossipEvent) {
val rumor = noteEvent.cachedGossip(privKey) ?: return
markInnerAsSeenOnRelay(rumor, privKey, relay)
}
}
override fun updateChannelFilters() { override fun updateChannelFilters() {
return if (hasLoadedTheBasics[account.userProfile()] != null) { return if (hasLoadedTheBasics[account.userProfile()] != null) {
// gets everthing about the user logged in // gets everthing about the user logged in
@@ -7,6 +7,8 @@ import com.vitorpamplona.quartz.encoders.ATag
import com.vitorpamplona.quartz.encoders.HexKey import com.vitorpamplona.quartz.encoders.HexKey
class NIP24Factory { class NIP24Factory {
data class Result(val msg: Event, val wraps: List<GiftWrapEvent>)
fun createMsgNIP24( fun createMsgNIP24(
msg: String, msg: String,
to: List<HexKey>, to: List<HexKey>,
@@ -18,7 +20,7 @@ class NIP24Factory {
markAsSensitive: Boolean = false, markAsSensitive: Boolean = false,
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null geohash: String? = null
): List<GiftWrapEvent> { ): Result {
val senderPublicKey = keyPair.pubKey.toHexKey() val senderPublicKey = keyPair.pubKey.toHexKey()
val senderMessage = ChatMessageEvent.create( val senderMessage = ChatMessageEvent.create(
@@ -34,19 +36,22 @@ class NIP24Factory {
geohash = geohash geohash = geohash
) )
return to.plus(senderPublicKey).map { return Result(
GiftWrapEvent.create( msg = senderMessage,
event = SealedGossipEvent.create( wraps = to.plus(senderPublicKey).map {
event = senderMessage, GiftWrapEvent.create(
encryptTo = it, event = SealedGossipEvent.create(
privateKey = keyPair.privKey!! event = senderMessage,
), encryptTo = it,
recipientPubKey = it privateKey = keyPair.privKey!!
) ),
} recipientPubKey = it
)
}
)
} }
fun createReactionWithinGroup(content: String, originalNote: EventInterface, to: List<HexKey>, from: KeyPair): List<GiftWrapEvent> { fun createReactionWithinGroup(content: String, originalNote: EventInterface, to: List<HexKey>, from: KeyPair): Result {
val senderPublicKey = from.pubKey.toHexKey() val senderPublicKey = from.pubKey.toHexKey()
val senderReaction = ReactionEvent.create( val senderReaction = ReactionEvent.create(
@@ -55,19 +60,22 @@ class NIP24Factory {
from from
) )
return to.plus(senderPublicKey).map { return Result(
GiftWrapEvent.create( msg = senderReaction,
event = SealedGossipEvent.create( wraps = to.plus(senderPublicKey).map {
event = senderReaction, GiftWrapEvent.create(
encryptTo = it, event = SealedGossipEvent.create(
privateKey = from.privKey!! event = senderReaction,
), encryptTo = it,
recipientPubKey = it privateKey = from.privKey!!
) ),
} recipientPubKey = it
)
}
)
} }
fun createReactionWithinGroup(emojiUrl: EmojiUrl, originalNote: EventInterface, to: List<HexKey>, from: KeyPair): List<GiftWrapEvent> { fun createReactionWithinGroup(emojiUrl: EmojiUrl, originalNote: EventInterface, to: List<HexKey>, from: KeyPair): Result {
val senderPublicKey = from.pubKey.toHexKey() val senderPublicKey = from.pubKey.toHexKey()
val senderReaction = ReactionEvent.create( val senderReaction = ReactionEvent.create(
@@ -76,16 +84,19 @@ class NIP24Factory {
from from
) )
return to.plus(senderPublicKey).map { return Result(
GiftWrapEvent.create( msg = senderReaction,
event = SealedGossipEvent.create( wraps = to.plus(senderPublicKey).map {
event = senderReaction, GiftWrapEvent.create(
encryptTo = it, event = SealedGossipEvent.create(
privateKey = from.privKey!! event = senderReaction,
), encryptTo = it,
recipientPubKey = it privateKey = from.privKey!!
) ),
} recipientPubKey = it
)
}
)
} }
fun createTextNoteNIP24( fun createTextNoteNIP24(
@@ -103,7 +114,7 @@ class NIP24Factory {
directMentions: Set<HexKey>, directMentions: Set<HexKey>,
zapRaiserAmount: Long? = null, zapRaiserAmount: Long? = null,
geohash: String? = null geohash: String? = null
): List<GiftWrapEvent> { ): Result {
val senderPublicKey = keyPair.pubKey.toHexKey() val senderPublicKey = keyPair.pubKey.toHexKey()
val senderMessage = TextNoteEvent.create( val senderMessage = TextNoteEvent.create(
@@ -122,15 +133,18 @@ class NIP24Factory {
geohash = geohash geohash = geohash
) )
return to.plus(senderPublicKey).map { return Result(
GiftWrapEvent.create( msg = senderMessage,
event = SealedGossipEvent.create( wraps = to.plus(senderPublicKey).map {
event = senderMessage, GiftWrapEvent.create(
encryptTo = it, event = SealedGossipEvent.create(
privateKey = keyPair.privKey!! event = senderMessage,
), encryptTo = it,
recipientPubKey = it privateKey = keyPair.privKey!!
) ),
} recipientPubKey = it
)
}
)
} }
} }