- Finishes the transition to EventHint objects for building events.

- Removes the "a-tag" dependency on Addressable interface because the `a` can have different names in different objects.
This commit is contained in:
Vitor Pamplona
2026-02-18 09:53:03 -05:00
parent 46b17628ac
commit 2c3ca7f906
23 changed files with 114 additions and 159 deletions
@@ -529,13 +529,12 @@ class Account(
if (!signer.isWriteable()) return null if (!signer.isWriteable()) return null
if (note.hasReacted(userProfile(), reaction)) return null if (note.hasReacted(userProfile(), reaction)) return null
val noteEvent = note.event ?: return null val eventHint = note.toEventHint<Event>() ?: return null
// For NIP-17 private groups, we don't support tracked mode (too complex) // For NIP-17 private groups, we don't support tracked mode (too complex)
if (noteEvent is NIP17Group) return null if (eventHint.event is NIP17Group) return null
val relayHint = note.relays.firstOrNull()?.url val event = ReactionAction.reactTo(eventHint, reaction, signer)
val event = ReactionAction.reactTo(noteEvent, reaction, signer, relayHint)
val relays = computeRelayListToBroadcast(event) val relays = computeRelayListToBroadcast(event)
return event to relays return event to relays
@@ -1360,19 +1359,15 @@ class Account(
} }
suspend fun createInteractiveStoryReadingState( suspend fun createInteractiveStoryReadingState(
root: InteractiveStoryBaseEvent, root: EventHintBundle<InteractiveStoryBaseEvent>,
rootRelay: NormalizedRelayUrl?, readingScene: EventHintBundle<InteractiveStoryBaseEvent>,
readingScene: InteractiveStoryBaseEvent,
readingSceneRelay: NormalizedRelayUrl?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
val template = val template =
InteractiveStoryReadingStateEvent.build( InteractiveStoryReadingStateEvent.build(
root = root, root = root,
rootRelay = rootRelay,
currentScene = readingScene, currentScene = readingScene,
currentSceneRelay = readingSceneRelay,
) )
val event = signer.sign(template) val event = signer.sign(template)
@@ -1391,8 +1386,7 @@ class Account(
suspend fun updateInteractiveStoryReadingState( suspend fun updateInteractiveStoryReadingState(
readingState: InteractiveStoryReadingStateEvent, readingState: InteractiveStoryReadingStateEvent,
readingScene: InteractiveStoryBaseEvent, readingScene: EventHintBundle<InteractiveStoryBaseEvent>,
readingSceneRelay: NormalizedRelayUrl?,
) { ) {
if (!isWriteable()) return if (!isWriteable()) return
@@ -1400,7 +1394,6 @@ class Account(
InteractiveStoryReadingStateEvent.update( InteractiveStoryReadingStateEvent.update(
base = readingState, base = readingState,
currentScene = readingScene, currentScene = readingScene,
currentSceneRelay = readingSceneRelay,
) )
val event = signer.sign(template) val event = signer.sign(template)
@@ -61,7 +61,6 @@ import com.vitorpamplona.quartz.experimental.trustedAssertions.list.TrustProvide
import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent
import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.isAddressable import com.vitorpamplona.quartz.nip01Core.core.isAddressable
@@ -420,18 +419,18 @@ object LocalCache : ILocalCache, ICacheProvider {
return null return null
} }
override fun checkGetOrCreateNote(key: String): Note? { override fun checkGetOrCreateNote(hexKey: String): Note? {
if (ATag.isATag(key)) { if (ATag.isATag(hexKey)) {
return checkGetOrCreateAddressableNote(key) return checkGetOrCreateAddressableNote(hexKey)
} }
if (isValidHex(key)) { if (isValidHex(hexKey)) {
val note = getOrCreateNote(key) val note = getOrCreateNote(hexKey)
val noteEvent = note.event val noteEvent = note.event
return if (noteEvent is AddressableEvent) { return if (noteEvent is AddressableEvent) {
// upgrade to the latest // upgrade to the latest
val newNote = checkGetOrCreateAddressableNote(noteEvent.aTag().toTag()) val newNote = getOrCreateAddressableNote(noteEvent.address())
if (newNote != null && newNote.event == null) { if (newNote.event == null) {
val author = note.author ?: getOrCreateUser(noteEvent.pubKey) val author = note.author ?: getOrCreateUser(noteEvent.pubKey)
newNote.loadEvent(noteEvent as Event, author, emptyList()) newNote.loadEvent(noteEvent as Event, author, emptyList())
note.moveAllReferencesTo(newNote) note.moveAllReferencesTo(newNote)
@@ -1407,10 +1406,13 @@ object LocalCache : ILocalCache, ICacheProvider {
) = consumeBaseReplaceable(event, relay, wasVerified) ) = consumeBaseReplaceable(event, relay, wasVerified)
private fun consumeBaseReplaceable( private fun consumeBaseReplaceable(
event: BaseAddressableEvent, event: Event,
relay: NormalizedRelayUrl?, relay: NormalizedRelayUrl?,
wasVerified: Boolean, wasVerified: Boolean,
): Boolean { ): Boolean {
// TODO: Redo the Event sctructure in Quartz to avoid this check
check(event is AddressableEvent) { "Event must be addressable: ${event.kind}" }
val version = getOrCreateNote(event.id) val version = getOrCreateNote(event.id)
val replaceableNote = getOrCreateAddressableNote(event.address()) val replaceableNote = getOrCreateAddressableNote(event.address())
val author = getOrCreateUser(event.pubKey) val author = getOrCreateUser(event.pubKey)
@@ -2767,7 +2769,7 @@ object LocalCache : ILocalCache, ICacheProvider {
note?.event?.let { noteEvent -> note?.event?.let { noteEvent ->
if (noteEvent is AddressableEvent) { if (noteEvent is AddressableEvent) {
getAddressableNoteIfExists(noteEvent.aTag().toTag())?.addRelay(relay) getAddressableNoteIfExists(noteEvent.address())?.addRelay(relay)
} }
} }
@@ -143,7 +143,7 @@ fun routeForInner(
} }
is AddressableEvent -> { is AddressableEvent -> {
Route.Note(noteEvent.aTag().toTag()) Route.Note(noteEvent.addressTag())
} }
else -> { else -> {
@@ -61,12 +61,13 @@ fun RenderInteractiveStory(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: INav, nav: INav,
) { ) {
val baseRootEvent = baseNote.event as? InteractiveStoryBaseEvent ?: return val baseRootEvent = baseNote.toEventHint<InteractiveStoryBaseEvent>() ?: return
val address = baseNote.address() ?: return val address = baseNote.address() ?: return
// keep updating the root event with new versions // keep updating the root event with new versions
val note = observeNote(baseNote, accountViewModel) val note = observeNote(baseNote, accountViewModel)
val rootEvent = note.value?.note?.event as? InteractiveStoryBaseEvent ?: return val rootHint = note.value.note.toEventHint<InteractiveStoryBaseEvent>() ?: return
val rootEvent = rootHint.event
// keep updating the reading state event with new versions // keep updating the reading state event with new versions
val readingStateNote = accountViewModel.getInteractiveStoryReadingState(address.toValue()) val readingStateNote = accountViewModel.getInteractiveStoryReadingState(address.toValue())
@@ -83,11 +84,11 @@ fun RenderInteractiveStory(
RenderInteractiveStory( RenderInteractiveStory(
section = it, section = it,
onSelect = { onSelect = {
val event = it.event as? InteractiveStoryBaseEvent ?: return@RenderInteractiveStory val eventHint = it.toEventHint<InteractiveStoryBaseEvent>() ?: return@RenderInteractiveStory
accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, event) accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, eventHint)
}, },
onRestart = { onRestart = {
accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, rootEvent) accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, rootHint)
}, },
makeItShort = makeItShort, makeItShort = makeItShort,
canPreview = canPreview, canPreview = canPreview,
@@ -103,11 +104,11 @@ fun RenderInteractiveStory(
RenderInteractiveStory( RenderInteractiveStory(
section = rootEvent, section = rootEvent,
onSelect = { onSelect = {
val event = it.event as? InteractiveStoryBaseEvent ?: return@RenderInteractiveStory val eventHint = it.toEventHint<InteractiveStoryBaseEvent>() ?: return@RenderInteractiveStory
accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, event) accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, eventHint)
}, },
onRestart = { onRestart = {
accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, rootEvent) accountViewModel.updateInteractiveStoryReadingState(baseRootEvent, rootHint)
}, },
makeItShort = makeItShort, makeItShort = makeItShort,
canPreview = canPreview, canPreview = canPreview,
@@ -91,6 +91,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.relay.client.EmptyNostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.EmptyNostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.EmptyIAuthStatus import com.vitorpamplona.quartz.nip01Core.relay.client.auth.EmptyIAuthStatus
@@ -1480,21 +1481,17 @@ class AccountViewModel(
fun getInteractiveStoryReadingState(dATag: String): AddressableNote = LocalCache.getOrCreateAddressableNote(InteractiveStoryReadingStateEvent.createAddress(account.signer.pubKey, dATag)) fun getInteractiveStoryReadingState(dATag: String): AddressableNote = LocalCache.getOrCreateAddressableNote(InteractiveStoryReadingStateEvent.createAddress(account.signer.pubKey, dATag))
fun updateInteractiveStoryReadingState( fun updateInteractiveStoryReadingState(
root: InteractiveStoryBaseEvent, rootHint: EventHintBundle<InteractiveStoryBaseEvent>,
readingScene: InteractiveStoryBaseEvent, readingSceneHint: EventHintBundle<InteractiveStoryBaseEvent>,
) { ) {
launchSigner { launchSigner {
val sceneNoteRelayHint = LocalCache.getOrCreateAddressableNote(readingScene.address()).relayHintUrl() val readingState = getInteractiveStoryReadingState(rootHint.event.addressTag())
val readingState = getInteractiveStoryReadingState(root.addressTag())
val readingStateEvent = readingState.event as? InteractiveStoryReadingStateEvent val readingStateEvent = readingState.event as? InteractiveStoryReadingStateEvent
if (readingStateEvent != null) { if (readingStateEvent != null) {
account.updateInteractiveStoryReadingState(readingStateEvent, readingScene, sceneNoteRelayHint) account.updateInteractiveStoryReadingState(readingStateEvent, readingSceneHint)
} else { } else {
val rootNoteRelayHint = LocalCache.getOrCreateAddressableNote(root.address()).relayHintUrl() account.createInteractiveStoryReadingState(rootHint, readingSceneHint)
account.createInteractiveStoryReadingState(root, rootNoteRelayHint, readingScene, sceneNoteRelayHint)
} }
} }
} }
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.commons.model.nip18Reposts
import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.Note
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
@@ -35,34 +35,26 @@ object RepostAction {
/** /**
* Creates a signed repost event. * Creates a signed repost event.
* *
* @param event The event to repost * @param eventHint The event to repost
* @param signer The NostrSigner to sign the event * @param signer The NostrSigner to sign the event
* @param noteHint Optional relay hint where the note was seen
* @param authorHint Optional relay hint for the author's outbox
* @return Signed repost event ready to broadcast * @return Signed repost event ready to broadcast
* @throws IllegalStateException if signer is not writeable * @throws IllegalStateException if signer is not writeable
*/ */
suspend fun repost( suspend fun repost(
event: Event, eventHint: EventHintBundle<Event>,
signer: NostrSigner, signer: NostrSigner,
noteHint: String? = null,
authorHint: String? = null,
): Event { ): Event {
if (!signer.isWriteable()) { if (!signer.isWriteable()) {
throw IllegalStateException("Cannot repost: signer is not writeable") throw IllegalStateException("Cannot repost: signer is not writeable")
} }
// Normalize relay hints
val normalizedNoteHint = noteHint?.let { RelayUrlNormalizer.normalizeOrNull(it) }
val normalizedAuthorHint = authorHint?.let { RelayUrlNormalizer.normalizeOrNull(it) }
// Use NIP-18 RepostEvent (kind 6) for text notes (kind 1) // Use NIP-18 RepostEvent (kind 6) for text notes (kind 1)
// Use GenericRepostEvent (kind 16) for all other kinds // Use GenericRepostEvent (kind 16) for all other kinds
val template = val template =
if (event.kind == 1) { if (eventHint.event.kind == 1) {
RepostEvent.build(event, normalizedNoteHint, normalizedAuthorHint) RepostEvent.build(eventHint)
} else { } else {
GenericRepostEvent.build(event, normalizedNoteHint, normalizedAuthorHint) GenericRepostEvent.build(eventHint)
} }
return signer.sign(template) return signer.sign(template)
@@ -86,10 +78,8 @@ object RepostAction {
if (!signer.isWriteable()) return null if (!signer.isWriteable()) return null
if (note.hasBoostedInTheLast5Minutes(signer.pubKey)) return null if (note.hasBoostedInTheLast5Minutes(signer.pubKey)) return null
val noteEvent = note.event ?: return null val hint = note.toEventHint<Event>() ?: return null
val noteHint = note.relayHintUrl()?.url
val authorHint = note.author?.bestRelayHint()?.url
return repost(noteEvent, signer, noteHint, authorHint) return repost(hint, signer)
} }
} }
@@ -24,7 +24,6 @@ import com.vitorpamplona.amethyst.commons.model.Note
import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.User
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip17Dm.NIP17Factory import com.vitorpamplona.quartz.nip17Dm.NIP17Factory
import com.vitorpamplona.quartz.nip17Dm.base.NIP17Group import com.vitorpamplona.quartz.nip17Dm.base.NIP17Group
@@ -49,18 +48,14 @@ object ReactionAction {
* @throws IllegalStateException if signer is not writeable * @throws IllegalStateException if signer is not writeable
*/ */
suspend fun reactTo( suspend fun reactTo(
event: Event, eventHint: EventHintBundle<Event>,
reaction: String, reaction: String,
signer: NostrSigner, signer: NostrSigner,
relayHint: String? = null,
): ReactionEvent { ): ReactionEvent {
if (!signer.isWriteable()) { if (!signer.isWriteable()) {
throw IllegalStateException("Cannot react: signer is not writeable") throw IllegalStateException("Cannot react: signer is not writeable")
} }
val normalizedRelayHint = relayHint?.let { RelayUrlNormalizer.normalizeOrNull(it) }
val eventHint = EventHintBundle(event, normalizedRelayHint)
// Handle custom emoji reactions (format: ":emoji_name:") // Handle custom emoji reactions (format: ":emoji_name:")
val template = val template =
if (reaction.startsWith(":")) { if (reaction.startsWith(":")) {
@@ -82,10 +77,9 @@ object ReactionAction {
* Creates a "like" reaction ("+"). * Creates a "like" reaction ("+").
*/ */
suspend fun like( suspend fun like(
event: Event, event: EventHintBundle<Event>,
signer: NostrSigner, signer: NostrSigner,
relayHint: String? = null, ): ReactionEvent = reactTo(event, "+", signer)
): ReactionEvent = reactTo(event, "+", signer, relayHint)
/** /**
* Advanced: React to an event with support for NIP-17 private groups. * Advanced: React to an event with support for NIP-17 private groups.
@@ -102,7 +96,6 @@ object ReactionAction {
* @param onPrivate Callback for private group reactions (returns NIP17Factory.Result) * @param onPrivate Callback for private group reactions (returns NIP17Factory.Result)
*/ */
suspend fun reactToWithGroupSupport( suspend fun reactToWithGroupSupport(
event: Event,
eventHint: EventHintBundle<Event>, eventHint: EventHintBundle<Event>,
reaction: String, reaction: String,
signer: NostrSigner, signer: NostrSigner,
@@ -113,6 +106,8 @@ object ReactionAction {
throw IllegalStateException("Cannot react: signer is not writeable") throw IllegalStateException("Cannot react: signer is not writeable")
} }
val event = eventHint.event
// Check if this is a NIP-17 private group event // Check if this is a NIP-17 private group event
if (event is NIP17Group) { if (event is NIP17Group) {
val users = event.groupMembers().toList() val users = event.groupMembers().toList()
@@ -185,9 +180,8 @@ object ReactionAction {
if (!signer.isWriteable()) return if (!signer.isWriteable()) return
if (note.hasReacted(by, reaction)) return if (note.hasReacted(by, reaction)) return
val noteEvent = note.event ?: return
val eventHint = note.toEventHint<Event>() ?: return val eventHint = note.toEventHint<Event>() ?: return
reactToWithGroupSupport(noteEvent, eventHint, reaction, signer, onPublic, onPrivate) reactToWithGroupSupport(eventHint, reaction, signer, onPublic, onPrivate)
} }
} }
@@ -70,6 +70,7 @@ import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache
import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager
import com.vitorpamplona.amethyst.desktop.nwc.NwcPaymentHandler import com.vitorpamplona.amethyst.desktop.nwc.NwcPaymentHandler
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
@@ -538,7 +539,8 @@ fun NoteActionsRow(
if (!isLiked) { if (!isLiked) {
scope.launch { scope.launch {
reactToNote( reactToNote(
event = event, // TODO: Bring a hint to where the event came from
event = EventHintBundle(event, null),
reaction = "+", reaction = "+",
account = account, account = account,
relayManager = relayManager, relayManager = relayManager,
@@ -578,7 +580,8 @@ fun NoteActionsRow(
if (!isReposted) { if (!isReposted) {
scope.launch { scope.launch {
repostNote( repostNote(
event = event, // TODO: Bring a hint to where the event came from
event = EventHintBundle(event, null),
account = account, account = account,
relayManager = relayManager, relayManager = relayManager,
) )
@@ -808,7 +811,7 @@ fun NoteActionsRow(
* Creates a reaction event and broadcasts to relays. * Creates a reaction event and broadcasts to relays.
*/ */
private suspend fun reactToNote( private suspend fun reactToNote(
event: Event, event: EventHintBundle<Event>,
reaction: String, reaction: String,
account: AccountState.LoggedIn, account: AccountState.LoggedIn,
relayManager: DesktopRelayConnectionManager, relayManager: DesktopRelayConnectionManager,
@@ -893,7 +896,7 @@ private suspend fun removeBookmark(
* Creates a repost event and broadcasts to relays. * Creates a repost event and broadcasts to relays.
*/ */
private suspend fun repostNote( private suspend fun repostNote(
event: Event, event: EventHintBundle<Event>,
account: AccountState.LoggedIn, account: AccountState.LoggedIn,
relayManager: DesktopRelayConnectionManager, relayManager: DesktopRelayConnectionManager,
) { ) {
@@ -28,7 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.core.builder import com.vitorpamplona.quartz.nip01Core.core.builder
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
@@ -83,17 +83,16 @@ class InteractiveStoryReadingStateEvent(
fun update( fun update(
base: InteractiveStoryReadingStateEvent, base: InteractiveStoryReadingStateEvent,
currentScene: InteractiveStoryBaseEvent, currentScene: EventHintBundle<InteractiveStoryBaseEvent>,
currentSceneRelay: NormalizedRelayUrl?,
createdAt: Long = TimeUtils.now(), createdAt: Long = TimeUtils.now(),
): EventTemplate<InteractiveStoryReadingStateEvent> { ): EventTemplate<InteractiveStoryReadingStateEvent> {
val rootTag = base.dTag() val rootTag = base.dTag()
val sceneTag = currentScene.aTag(currentSceneRelay) val sceneTag = ATag(currentScene.event.address(), currentScene.relay)
val status = val status =
if (rootTag == sceneTag.toTag()) { if (rootTag == sceneTag.toTag()) {
ReadStatusTag.STATUS.NEW ReadStatusTag.STATUS.NEW
} else if (currentScene.options().isEmpty()) { } else if (currentScene.event.options().isEmpty()) {
ReadStatusTag.STATUS.DONE ReadStatusTag.STATUS.DONE
} else { } else {
ReadStatusTag.STATUS.READING ReadStatusTag.STATUS.READING
@@ -109,34 +108,32 @@ class InteractiveStoryReadingStateEvent(
} }
fun build( fun build(
root: InteractiveStoryBaseEvent, root: EventHintBundle<InteractiveStoryBaseEvent>,
rootRelay: NormalizedRelayUrl?, currentScene: EventHintBundle<InteractiveStoryBaseEvent>,
currentScene: InteractiveStoryBaseEvent,
currentSceneRelay: NormalizedRelayUrl?,
createdAt: Long = TimeUtils.now(), createdAt: Long = TimeUtils.now(),
initializer: TagArrayBuilder<InteractiveStoryReadingStateEvent>.() -> Unit = {}, initializer: TagArrayBuilder<InteractiveStoryReadingStateEvent>.() -> Unit = {},
) = eventTemplate(KIND, "", createdAt) { ) = eventTemplate(KIND, "", createdAt) {
val rootTag = root.aTag(rootRelay) val rootTag = ATag(root.event.address(), root.relay)
val sceneTag = currentScene.aTag(currentSceneRelay) val sceneTag = ATag(currentScene.event.address(), currentScene.relay)
val status = val status =
if (rootTag == sceneTag) { if (rootTag == sceneTag) {
ReadStatusTag.STATUS.NEW ReadStatusTag.STATUS.NEW
} else if (currentScene.options().isEmpty()) { } else if (currentScene.event.options().isEmpty()) {
ReadStatusTag.STATUS.DONE ReadStatusTag.STATUS.DONE
} else { } else {
ReadStatusTag.STATUS.READING ReadStatusTag.STATUS.READING
} }
dTag(rootTag.toTag()) dTag(rootTag.toTag())
alt(root.title()?.let { ALT2 + it } ?: ALT1) alt(root.event.title()?.let { ALT2 + it } ?: ALT1)
rootScene(rootTag) rootScene(rootTag)
currentScene(sceneTag) currentScene(sceneTag)
status(status) status(status)
root.title()?.let { storyTitle(it) } root.event.title()?.let { storyTitle(it) }
root.summary()?.let { storyImage(it) } root.event.summary()?.let { storyImage(it) }
root.image()?.let { storySummary(it) } root.event.image()?.let { storySummary(it) }
initializer() initializer()
} }
@@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag
@@ -71,8 +70,6 @@ class NipTextEvent(
override fun dTag() = tags.dTag() override fun dTag() = tags.dTag()
override fun aTag(relayHint: NormalizedRelayUrl?) = ATag(kind, pubKey, dTag(), relayHint)
override fun address() = Address(kind, pubKey, dTag()) override fun address() = Address(kind, pubKey, dTag())
override fun addressTag() = Address.assemble(kind, pubKey, dTag()) override fun addressTag() = Address.assemble(kind, pubKey, dTag())
@@ -21,15 +21,11 @@
package com.vitorpamplona.quartz.nip01Core.core package com.vitorpamplona.quartz.nip01Core.core
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
@Immutable @Immutable
interface AddressableEvent : IEvent { interface AddressableEvent : IEvent {
fun dTag(): String fun dTag(): String
fun aTag(relayHint: NormalizedRelayUrl? = null): ATag
fun address(): Address fun address(): Address
fun addressTag(): String fun addressTag(): String
@@ -21,8 +21,6 @@
package com.vitorpamplona.quartz.nip01Core.core package com.vitorpamplona.quartz.nip01Core.core
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag
@Immutable @Immutable
@@ -38,8 +36,6 @@ open class BaseAddressableEvent(
AddressableEvent { AddressableEvent {
override fun dTag() = tags.dTag() override fun dTag() = tags.dTag()
override fun aTag(relayHint: NormalizedRelayUrl?) = ATag(kind, pubKey, dTag(), relayHint)
override fun address() = Address(kind, pubKey, dTag()) override fun address() = Address(kind, pubKey, dTag())
/** /**
@@ -21,8 +21,6 @@
package com.vitorpamplona.quartz.nip01Core.core package com.vitorpamplona.quartz.nip01Core.core
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
@Immutable @Immutable
open class BaseReplaceableEvent( open class BaseReplaceableEvent(
@@ -33,11 +31,10 @@ open class BaseReplaceableEvent(
tags: TagArray, tags: TagArray,
content: String, content: String,
sig: HexKey, sig: HexKey,
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) { ) : Event(id, pubKey, createdAt, kind, tags, content, sig),
AddressableEvent {
override fun dTag() = FIXED_D_TAG override fun dTag() = FIXED_D_TAG
override fun aTag(relayHint: NormalizedRelayUrl?) = ATag(kind, pubKey, FIXED_D_TAG, relayHint)
override fun address(): Address = Address(kind, pubKey, dTag()) override fun address(): Address = Address(kind, pubKey, dTag())
/** /**
@@ -20,11 +20,20 @@
*/ */
package com.vitorpamplona.quartz.nip01Core.tags.aTag package com.vitorpamplona.quartz.nip01Core.tags.aTag
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
fun <T : Event> TagArrayBuilder<T>.aTag(tag: ATag) = add(tag.toATagArray()) fun <T : Event> TagArrayBuilder<T>.aTag(tag: ATag) = add(tag.toATagArray())
fun <T : Event> TagArrayBuilder<T>.aTag(
address: Address,
relayHint: NormalizedRelayUrl? = null,
) = add(ATag.assemble(address, relayHint))
fun <T : Event> TagArrayBuilder<T>.aTags(tag: List<ATag>) = addAll(tag.map { it.toATagArray() }) fun <T : Event> TagArrayBuilder<T>.aTags(tag: List<ATag>) = addAll(tag.map { it.toATagArray() })
fun <T : Event> TagArrayBuilder<T>.removeATag(tag: ATag) = this.removeIf(ATag::isSameAddress, tag.toATagArray()) fun <T : Event> TagArrayBuilder<T>.removeATag(tag: ATag) = this.removeIf(ATag::isSameAddress, tag.toATagArray())
fun <T : Event> TagArrayBuilder<T>.removeAddress(address: Address) = this.removeIf(ATag::isSameAddress, ATag.assemble(address, null))
@@ -89,7 +89,7 @@ class DeletionEvent(
deleteEvents.forEach { deleteEvents.forEach {
eTag(ETag(it.id)) eTag(ETag(it.id))
if (it is AddressableEvent) { if (it is AddressableEvent) {
aTag(it.aTag()) aTag(it.address())
} }
} }
@@ -108,7 +108,7 @@ class DeletionEvent(
deleteEvents.forEach { deleteEvents.forEach {
if (it is AddressableEvent) { if (it is AddressableEvent) {
aTag(it.aTag()) aTag(it.address())
} }
} }
@@ -26,9 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
@@ -38,7 +38,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
import com.vitorpamplona.quartz.nip31Alts.AltTag
import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip31Alts.alt
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.lastNotNullOfOrNull import com.vitorpamplona.quartz.utils.lastNotNullOfOrNull
@@ -93,45 +92,28 @@ class GenericRepostEvent(
const val ALT = "Generic repost" const val ALT = "Generic repost"
fun build( fun build(
boostedPost: Event, eventHint: EventHintBundle<Event>,
eventSourceRelay: NormalizedRelayUrl?,
authorHomeRelay: NormalizedRelayUrl?,
createdAt: Long = TimeUtils.now(), createdAt: Long = TimeUtils.now(),
initializer: TagArrayBuilder<GenericRepostEvent>.() -> Unit = {}, initializer: TagArrayBuilder<GenericRepostEvent>.() -> Unit = {},
) = eventTemplate(KIND, boostedPost.toJson(), createdAt) { ) = eventTemplate(KIND, eventHint.event.toJson(), createdAt) {
val boostedPost = eventHint.event
alt(ALT) alt(ALT)
kind(boostedPost.kind) kind(boostedPost.kind)
pTag(PTag(boostedPost.pubKey, authorHomeRelay)) pTag(PTag(boostedPost.pubKey, eventHint.authorHomeRelay))
eTag(ETag(boostedPost.id, eventSourceRelay, boostedPost.pubKey)) eTag(ETag(boostedPost.id, eventHint.relay, boostedPost.pubKey))
if (boostedPost is AddressableEvent) { if (boostedPost is AddressableEvent) {
aTag(boostedPost.aTag(eventSourceRelay)) aTag(boostedPost.address(), eventHint.relay)
} }
initializer() initializer()
} }
suspend fun create( suspend fun create(
boostedPost: Event, eventHint: EventHintBundle<Event>,
signer: NostrSigner, signer: NostrSigner,
createdAt: Long = TimeUtils.now(), createdAt: Long = TimeUtils.now(),
): GenericRepostEvent { ): GenericRepostEvent = signer.sign(build(eventHint, createdAt))
val content = boostedPost.toJson()
val tags =
mutableListOf(
arrayOf("e", boostedPost.id),
arrayOf("p", boostedPost.pubKey),
)
if (boostedPost is AddressableEvent) {
tags.add(arrayOf("a", boostedPost.aTag().toTag()))
}
tags.add(arrayOf("k", "${boostedPost.kind}"))
tags.add(AltTag.assemble(ALT))
return signer.sign(createdAt, KIND, tags.toTypedArray(), content)
}
} }
} }
@@ -26,9 +26,10 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTag import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTag
@@ -82,7 +83,7 @@ class RepostEvent(
fun containedPost() = fun containedPost() =
try { try {
fromJson(content) fromJson(content)
} catch (e: Exception) { } catch (_: Exception) {
null null
} }
@@ -91,22 +92,28 @@ class RepostEvent(
const val ALT = "Repost event" const val ALT = "Repost event"
fun build( fun build(
boostedPost: Event, eventHint: EventHintBundle<Event>,
eventSourceRelay: NormalizedRelayUrl?,
authorHomeRelay: NormalizedRelayUrl?,
createdAt: Long = TimeUtils.now(), createdAt: Long = TimeUtils.now(),
initializer: TagArrayBuilder<RepostEvent>.() -> Unit = {}, initializer: TagArrayBuilder<RepostEvent>.() -> Unit = {},
) = eventTemplate(KIND, boostedPost.toJson(), createdAt) { ) = eventTemplate(KIND, eventHint.event.toJson(), createdAt) {
val boostedPost = eventHint.event
alt(ALT) alt(ALT)
pTag(PTag(boostedPost.pubKey, authorHomeRelay)) pTag(PTag(boostedPost.pubKey, eventHint.authorHomeRelay))
eTag(ETag(boostedPost.id, eventSourceRelay, boostedPost.pubKey)) eTag(ETag(boostedPost.id, eventHint.relay, boostedPost.pubKey))
if (boostedPost is AddressableEvent) { if (boostedPost is AddressableEvent) {
aTag(boostedPost.aTag(eventSourceRelay)) aTag(boostedPost.address(), eventHint.relay)
} }
kind(boostedPost.kind) kind(boostedPost.kind)
initializer() initializer()
} }
suspend fun create(
eventHint: EventHintBundle<Event>,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): RepostEvent = signer.sign(build(eventHint, createdAt))
} }
} }
@@ -31,9 +31,7 @@ import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
@@ -119,8 +117,6 @@ class LongTextNoteEvent(
override fun dTag() = tags.dTag() override fun dTag() = tags.dTag()
override fun aTag(relayHint: NormalizedRelayUrl?) = ATag(kind, pubKey, dTag(), relayHint)
override fun address() = Address(kind, pubKey, dTag()) override fun address() = Address(kind, pubKey, dTag())
override fun addressTag() = Address.assemble(kind, pubKey, dTag()) override fun addressTag() = Address.assemble(kind, pubKey, dTag())
@@ -91,7 +91,7 @@ class ReactionEvent(
) = eventTemplate<ReactionEvent>(KIND, reaction, createdAt) { ) = eventTemplate<ReactionEvent>(KIND, reaction, createdAt) {
eTag(reactedTo.toETag()) eTag(reactedTo.toETag())
if (reactedTo.event is AddressableEvent) { if (reactedTo.event is AddressableEvent) {
aTag(reactedTo.event.aTag(reactedTo.relay)) aTag(reactedTo.event.address(), reactedTo.relay)
} }
pTag(reactedTo.event.pubKey, reactedTo.relay) pTag(reactedTo.event.pubKey, reactedTo.relay)
kind(reactedTo.event.kind) kind(reactedTo.event.kind)
@@ -104,7 +104,7 @@ class ReactionEvent(
) = eventTemplate<ReactionEvent>(KIND, reaction.toContentEncode(), createdAt) { ) = eventTemplate<ReactionEvent>(KIND, reaction.toContentEncode(), createdAt) {
eTag(reactedTo.toETag()) eTag(reactedTo.toETag())
if (reactedTo.event is AddressableEvent) { if (reactedTo.event is AddressableEvent) {
aTag(reactedTo.event.aTag(reactedTo.relay)) aTag(reactedTo.event.address(), reactedTo.relay)
} }
pTag(reactedTo.event.pubKey, reactedTo.relay) pTag(reactedTo.event.pubKey, reactedTo.relay)
kind(reactedTo.event.kind) kind(reactedTo.event.kind)
@@ -78,7 +78,7 @@ class EmojiPackSelectionEvent(
createdAt: Long = TimeUtils.now(), createdAt: Long = TimeUtils.now(),
updater: TagArrayBuilder<EmojiPackSelectionEvent>.() -> Unit = {}, updater: TagArrayBuilder<EmojiPackSelectionEvent>.() -> Unit = {},
) = eventUpdate(currentSelection, createdAt) { ) = eventUpdate(currentSelection, createdAt) {
removePack(packToRemove.aTag(null)) removePack(packToRemove.address())
updater() updater()
} }
@@ -20,14 +20,15 @@
*/ */
package com.vitorpamplona.quartz.nip30CustomEmoji.selection package com.vitorpamplona.quartz.nip30CustomEmoji.selection
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTag import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTag
import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTags import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTags
import com.vitorpamplona.quartz.nip01Core.tags.aTag.removeATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.removeAddress
fun TagArrayBuilder<EmojiPackSelectionEvent>.pack(tag: ATag) = aTag(tag) fun TagArrayBuilder<EmojiPackSelectionEvent>.pack(tag: ATag) = aTag(tag)
fun TagArrayBuilder<EmojiPackSelectionEvent>.packs(tags: List<ATag>) = aTags(tags) fun TagArrayBuilder<EmojiPackSelectionEvent>.packs(tags: List<ATag>) = aTags(tags)
fun TagArrayBuilder<EmojiPackSelectionEvent>.removePack(tag: ATag) = removeATag(tag) fun TagArrayBuilder<EmojiPackSelectionEvent>.removePack(address: Address) = removeAddress(address)
@@ -34,7 +34,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
@@ -129,8 +128,6 @@ class WikiNoteEvent(
override fun dTag() = tags.dTag() override fun dTag() = tags.dTag()
override fun aTag(relayHint: NormalizedRelayUrl?) = ATag(kind, pubKey, dTag(), relayHint)
override fun address() = Address(kind, pubKey, dTag()) override fun address() = Address(kind, pubKey, dTag())
override fun addressTag() = Address.assemble(kind, pubKey, dTag()) override fun addressTag() = Address.assemble(kind, pubKey, dTag())
@@ -104,7 +104,7 @@ class LnZapRequestEvent(
AltTag.assemble(ALT), AltTag.assemble(ALT),
) )
if (zappedEvent is AddressableEvent) { if (zappedEvent is AddressableEvent) {
tags = tags + listOf(arrayOf("a", zappedEvent.aTag().toTag())) tags = tags + listOf(ATag.assemble(zappedEvent.address(), null))
} }
if (pollOption != null && pollOption >= 0) { if (pollOption != null && pollOption >= 0) {
tags = tags + listOf(arrayOf(PollOptionTag.TAG_NAME, pollOption.toString())) tags = tags + listOf(arrayOf(PollOptionTag.TAG_NAME, pollOption.toString()))