Merge pull request #2023 from vitorpamplona/claude/refactor-nip90-structure-ugeNj

Refactor NIP90 DVMs: reorganize packages and extract tag classes
This commit is contained in:
Vitor Pamplona
2026-03-29 22:26:02 -04:00
committed by GitHub
24 changed files with 427 additions and 122 deletions
@@ -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<NormalizedRelayUrl>,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): NIP90ContentDiscoveryRequestEvent {
val content = ""
val tags = mutableListOf<Array<String>>()
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<NIP90ContentDiscoveryRequestEvent>.() -> Unit = {},
) = eventTemplate(KIND, "", createdAt) {
alt(ALT)
dvmPubKey(dvmPublicKey)
relays(relays)
param("max_results", "200")
param("user", forUser)
initializer()
}
}
}
@@ -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<NIP90ContentDiscoveryRequestEvent>.dvmPubKey(pubKey: HexKey) = addUnique(arrayOf("p", pubKey))
fun TagArrayBuilder<NIP90ContentDiscoveryRequestEvent>.relays(relays: Set<NormalizedRelayUrl>) = addUnique(RelaysTag.assemble(relays))
fun TagArrayBuilder<NIP90ContentDiscoveryRequestEvent>.param(
key: String,
value: String,
) = add(ParamTag.assemble(key, value))
@@ -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 }
@@ -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<String>) = tag.has(2) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
fun parse(tag: Array<String>): 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<ParamTag>) = params.map { assemble(it) }
}
}
@@ -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<NormalizedRelayUrl>,
) {
companion object {
const val TAG_NAME = "relays"
fun isTag(tag: Array<String>) = tag.has(1) && tag[0] == TAG_NAME
fun parse(tag: Array<String>): 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<NormalizedRelayUrl>) = arrayOf(TAG_NAME) + relays.map { it.url }.toTypedArray()
}
}
@@ -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<NIP90ContentDiscoveryResponseEvent>.() -> Unit = {},
) = eventTemplate(KIND, "", createdAt) {
alt(ALT)
initializer()
}
}
}
@@ -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<NIP90StatusEvent>.() -> Unit = {},
) = eventTemplate(KIND, "", createdAt) {
alt(ALT)
initializer()
}
}
}
@@ -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<NIP90StatusEvent>.status(
code: String,
description: String,
) = addUnique(StatusTag.assemble(code, description))
fun TagArrayBuilder<NIP90StatusEvent>.amount(amount: Long) = addUnique(AmountTag.assemble(amount))
fun TagArrayBuilder<NIP90StatusEvent>.amount(
amount: Long,
lnInvoice: String,
) = addUnique(AmountTag.assemble(amount, lnInvoice))
@@ -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)
@@ -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<String>) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
fun parse(tag: Array<String>): 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)
}
}
@@ -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<String>) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
fun parse(
tag: Array<String>,
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)
}
}
@@ -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<NIP90UserDiscoveryRequestEvent>.() -> Unit = {},
) = eventTemplate(KIND, "", createdAt) {
alt(ALT)
initializer()
}
}
}
@@ -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<NIP90UserDiscoveryResponseEvent>.() -> Unit = {},
) = eventTemplate(KIND, "", createdAt) {
alt(ALT)
initializer()
}
}
}
@@ -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