diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index aabc4be72..7fa36f404 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -200,7 +200,7 @@ import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprov import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.NIP90ContentDiscoveryRequestEvent import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.nip92IMeta.imetas import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent @@ -1881,7 +1881,7 @@ class Account( onReady: (event: NIP90ContentDiscoveryRequestEvent) -> Unit, ) { val relays = nip65RelayList.inboxFlow.value.toSet() - val request = NIP90ContentDiscoveryRequestEvent.create(dvmPublicKey.pubkeyHex, signer.pubKey, relays, signer) + val request = signer.sign(NIP90ContentDiscoveryRequestEvent.build(dvmPublicKey.pubkeyHex, signer.pubKey, relays)) val relayList = dvmPublicKey.inboxRelays()?.toSet()?.ifEmpty { null } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 97c9e4234..c138c431f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -203,11 +203,11 @@ import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryRequestEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.userDiscoveryRequest.NIP90UserDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.userDiscoveryResponse.NIP90UserDiscoveryResponseEvent import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import com.vitorpamplona.quartz.nip96FileStorage.config.FileServersEvent import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/watchers/FilterRepliesAndReactionsToNotes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/watchers/FilterRepliesAndReactionsToNotes.kt index 57faeb9f0..0160962bb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/watchers/FilterRepliesAndReactionsToNotes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/watchers/FilterRepliesAndReactionsToNotes.kt @@ -41,8 +41,8 @@ import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent import com.vitorpamplona.quartz.nip56Reports.ReportEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent import com.vitorpamplona.quartz.utils.mapOfSet val RepliesAndReactionsKinds = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index aa1518e82..928c8ebb5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -282,8 +282,8 @@ import com.vitorpamplona.quartz.nip87Ecash.fedimint.FedimintEvent import com.vitorpamplona.quartz.nip87Ecash.recommendation.MintRecommendationEvent import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import com.vitorpamplona.quartz.nipA0VoiceMessages.BaseVoiceEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt index 894dfacab..5f73c4c0c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90ContentDiscoveryResponse.kt @@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent @Composable fun RenderNIP90ContentDiscoveryResponse( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt index 16e1e66c2..c039390d3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/NIP90Status.kt @@ -25,7 +25,7 @@ import androidx.compose.runtime.Composable import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent @Composable fun RenderNIP90Status( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index dddd78535..bca58da33 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -141,7 +141,7 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag import com.vitorpamplona.quartz.utils.Hex import com.vitorpamplona.quartz.utils.Log diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt index b7268d473..0d81a4cc8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt @@ -79,8 +79,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PayInvoiceErrorResponse import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppMetadata -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent @Composable fun DvmContentDiscoveryScreen( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt index 8a1ac91e3..ec880e6a4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt @@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.FilterByListParams import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent open class NIP90ContentDiscoveryResponseFilter( val account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt index 81ac4d826..2b00709cd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt @@ -266,11 +266,11 @@ import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryRequestEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.userDiscoveryRequest.NIP90UserDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.userDiscoveryResponse.NIP90UserDiscoveryResponseEvent import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import com.vitorpamplona.quartz.nip96FileStorage.config.FileServersEvent import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt similarity index 73% rename from quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryRequestEvent.kt rename to quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt index 3751f33e4..00ca00088 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt @@ -18,15 +18,16 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.nip90Dvms +package com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable 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.relay.normalizer.NormalizedRelayUrl -import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag +import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Stable @@ -43,21 +44,19 @@ class NIP90ContentDiscoveryRequestEvent( const val KIND = 5300 const val ALT = "NIP90 Content Discovery request" - suspend fun create( + fun build( dvmPublicKey: HexKey, forUser: HexKey, relays: Set, - signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): NIP90ContentDiscoveryRequestEvent { - val content = "" - val tags = mutableListOf>() - tags.add(arrayOf("p", dvmPublicKey)) - tags.add(AltTag.assemble(ALT)) - tags.add(arrayOf("relays") + relays.map { it.url }.toTypedArray()) - tags.add(arrayOf("param", "max_results", "200")) - tags.add(arrayOf("param", "user", forUser)) - return signer.sign(createdAt, KIND, tags.toTypedArray(), content) + initializer: TagArrayBuilder.() -> Unit = {}, + ) = eventTemplate(KIND, "", createdAt) { + alt(ALT) + dvmPubKey(dvmPublicKey) + relays(relays) + param("max_results", "200") + param("user", forUser) + initializer() } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/TagArrayBuilderExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/TagArrayBuilderExt.kt new file mode 100644 index 000000000..b9ca5e65d --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/TagArrayBuilderExt.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest + +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.tags.ParamTag +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.tags.RelaysTag + +fun TagArrayBuilder.dvmPubKey(pubKey: HexKey) = addUnique(arrayOf("p", pubKey)) + +fun TagArrayBuilder.relays(relays: Set) = addUnique(RelaysTag.assemble(relays)) + +fun TagArrayBuilder.param( + key: String, + value: String, +) = add(ParamTag.assemble(key, value)) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/TagArrayExt.kt new file mode 100644 index 000000000..09ee9c4a8 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/TagArrayExt.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest + +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.tags.ParamTag +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.tags.RelaysTag + +fun TagArray.relays() = firstNotNullOfOrNull(RelaysTag::parse) + +fun TagArray.params() = mapNotNull(ParamTag::parse) + +fun TagArray.param(key: String) = params().firstOrNull { it.key == key } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/tags/ParamTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/tags/ParamTag.kt new file mode 100644 index 000000000..d323f840c --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/tags/ParamTag.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.tags + +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +@Stable +class ParamTag( + val key: String, + val value: String, +) { + companion object { + const val TAG_NAME = "param" + + fun isTag(tag: Array) = tag.has(2) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse(tag: Array): ParamTag? { + ensure(tag.has(2)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + return ParamTag(tag[1], tag[2]) + } + + fun assemble( + key: String, + value: String, + ) = arrayOf(TAG_NAME, key, value) + + fun assemble(param: ParamTag) = assemble(param.key, param.value) + + fun assemble(params: List) = params.map { assemble(it) } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/tags/RelaysTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/tags/RelaysTag.kt new file mode 100644 index 000000000..3bca17fa3 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/tags/RelaysTag.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer +import com.vitorpamplona.quartz.utils.ensure + +class RelaysTag( + val relays: List, +) { + companion object { + const val TAG_NAME = "relays" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME + + fun parse(tag: Array): RelaysTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + val relays = tag.drop(1).mapNotNull { RelayUrlNormalizer.normalizeOrNull(it) } + ensure(relays.isNotEmpty()) { return null } + return RelaysTag(relays) + } + + fun assemble(relays: Set) = arrayOf(TAG_NAME) + relays.map { it.url }.toTypedArray() + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt similarity index 85% rename from quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryResponseEvent.kt rename to quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt index 8d97e0f00..9333bfc1f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90ContentDiscoveryResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt @@ -18,14 +18,15 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.nip90Dvms +package com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper -import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -71,15 +72,12 @@ class NIP90ContentDiscoveryResponseEvent( const val KIND = 6300 const val ALT = "NIP90 Content Discovery reply" - suspend fun create( - signer: NostrSigner, + fun build( createdAt: Long = TimeUtils.now(), - ): NIP90ContentDiscoveryResponseEvent { - val tags = - arrayOf( - AltTag.assemble(ALT), - ) - return signer.sign(createdAt, KIND, tags, "") + initializer: TagArrayBuilder.() -> Unit = {}, + ) = eventTemplate(KIND, "", createdAt) { + alt(ALT) + initializer() } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90StatusEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt similarity index 54% rename from quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90StatusEvent.kt rename to quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt index 7191bb667..0b157e3fc 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90StatusEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.nip90Dvms +package com.vitorpamplona.quartz.nip90Dvms.status import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -36,56 +37,20 @@ class NIP90StatusEvent( content: String, sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { - class StatusCode( - val code: String, - val description: String, - ) + fun status() = tags.status(content) - class AmountInvoice( - val amount: Long?, - val lnInvoice: String?, - ) - - fun status(): StatusCode? = - tags.firstOrNull { it.size > 1 && it[0] == "status" }?.let { - if (it.size > 2 && content == "") { - StatusCode(it[1], it[2]) - } else { - StatusCode(it[1], content) - } - } - - fun firstAmount(): AmountInvoice? = - tags.firstOrNull { it.size > 1 && it[0] == "amount" }?.let { - val amount = it[1].toLongOrNull() - if (it.size > 2) { - if (it[2].isNotBlank()) { - AmountInvoice(amount, it[2]) - } else { - null - } - } else { - if (amount != null) { - AmountInvoice(amount, null) - } else { - null - } - } - } + fun firstAmount() = tags.firstAmount() companion object { const val KIND = 7000 const val ALT = "NIP90 Status update" - suspend fun create( - signer: NostrSigner, + fun build( createdAt: Long = TimeUtils.now(), - ): NIP90StatusEvent { - val tags = - arrayOf( - AltTag.assemble(ALT), - ) - return signer.sign(createdAt, KIND, tags, "") + initializer: TagArrayBuilder.() -> Unit = {}, + ) = eventTemplate(KIND, "", createdAt) { + alt(ALT) + initializer() } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/TagArrayBuilderExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/TagArrayBuilderExt.kt new file mode 100644 index 000000000..ff12777c7 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/TagArrayBuilderExt.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.status + +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip90Dvms.status.tags.AmountTag +import com.vitorpamplona.quartz.nip90Dvms.status.tags.StatusTag + +fun TagArrayBuilder.status( + code: String, + description: String, +) = addUnique(StatusTag.assemble(code, description)) + +fun TagArrayBuilder.amount(amount: Long) = addUnique(AmountTag.assemble(amount)) + +fun TagArrayBuilder.amount( + amount: Long, + lnInvoice: String, +) = addUnique(AmountTag.assemble(amount, lnInvoice)) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/TagArrayExt.kt new file mode 100644 index 000000000..1c5847f2c --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/TagArrayExt.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.status + +import com.vitorpamplona.quartz.nip01Core.core.TagArray +import com.vitorpamplona.quartz.nip90Dvms.status.tags.AmountTag +import com.vitorpamplona.quartz.nip90Dvms.status.tags.StatusTag + +fun TagArray.status(content: String) = firstNotNullOfOrNull { StatusTag.parse(it, content) } + +fun TagArray.firstAmount() = firstNotNullOfOrNull(AmountTag::parse) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/tags/AmountTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/tags/AmountTag.kt new file mode 100644 index 000000000..7ce290028 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/tags/AmountTag.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.status.tags + +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +@Stable +class AmountTag( + val amount: Long?, + val lnInvoice: String?, +) { + companion object { + const val TAG_NAME = "amount" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse(tag: Array): AmountTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + val amount = tag[1].toLongOrNull() + return if (tag.has(2) && tag[2].isNotBlank()) { + AmountTag(amount, tag[2]) + } else if (amount != null) { + AmountTag(amount, null) + } else { + null + } + } + + fun assemble(amount: Long) = arrayOf(TAG_NAME, amount.toString()) + + fun assemble( + amount: Long, + lnInvoice: String, + ) = arrayOf(TAG_NAME, amount.toString(), lnInvoice) + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/tags/StatusTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/tags/StatusTag.kt new file mode 100644 index 000000000..17dadac6b --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/tags/StatusTag.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.status.tags + +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +@Stable +class StatusTag( + val code: String, + val description: String, +) { + companion object { + const val TAG_NAME = "status" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse( + tag: Array, + content: String, + ): StatusTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + return if (tag.has(2) && content.isEmpty()) { + StatusTag(tag[1], tag[2]) + } else { + StatusTag(tag[1], content) + } + } + + fun assemble( + code: String, + description: String, + ) = arrayOf(TAG_NAME, code, description) + + fun assemble(status: StatusTag) = assemble(status.code, status.description) + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt similarity index 77% rename from quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryRequestEvent.kt rename to quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt index 7ca2ea6fa..0acdb60cf 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.nip90Dvms +package com.vitorpamplona.quartz.nip90Dvms.userDiscoveryRequest import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -38,17 +39,14 @@ class NIP90UserDiscoveryRequestEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 5301 - const val ALT = "NIP90 Content Discovery request" + const val ALT = "NIP90 User Discovery request" - suspend fun create( - signer: NostrSigner, + fun build( createdAt: Long = TimeUtils.now(), - ): NIP90UserDiscoveryRequestEvent { - val tags = - arrayOf( - AltTag.assemble(ALT), - ) - return signer.sign(createdAt, KIND, tags, "") + initializer: TagArrayBuilder.() -> Unit = {}, + ) = eventTemplate(KIND, "", createdAt) { + alt(ALT) + initializer() } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt similarity index 77% rename from quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryResponseEvent.kt rename to quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt index bc26106dd..4c078a7a9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/NIP90UserDiscoveryResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt @@ -18,13 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.quartz.nip90Dvms +package com.vitorpamplona.quartz.nip90Dvms.userDiscoveryResponse import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate +import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -38,17 +39,14 @@ class NIP90UserDiscoveryResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6301 - const val ALT = "NIP90 Content Discovery reply" + const val ALT = "NIP90 User Discovery reply" - suspend fun create( - signer: NostrSigner, + fun build( createdAt: Long = TimeUtils.now(), - ): NIP90UserDiscoveryResponseEvent { - val tags = - arrayOf( - AltTag.assemble(ALT), - ) - return signer.sign(createdAt, KIND, tags, "") + initializer: TagArrayBuilder.() -> Unit = {}, + ) = eventTemplate(KIND, "", createdAt) { + alt(ALT) + initializer() } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt index b12d62f90..c897002ec 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt @@ -190,11 +190,11 @@ import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.AppRecommendationEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryRequestEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90ContentDiscoveryResponseEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90StatusEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryRequestEvent -import com.vitorpamplona.quartz.nip90Dvms.NIP90UserDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryRequest.NIP90ContentDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent +import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent +import com.vitorpamplona.quartz.nip90Dvms.userDiscoveryRequest.NIP90UserDiscoveryRequestEvent +import com.vitorpamplona.quartz.nip90Dvms.userDiscoveryResponse.NIP90UserDiscoveryResponseEvent import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import com.vitorpamplona.quartz.nip96FileStorage.config.FileServersEvent import com.vitorpamplona.quartz.nip98HttpAuth.HTTPAuthorizationEvent