mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 09:13:23 +00:00
Assigning hints to NIPs until NIP-53
Speeding up Bech32 and Hex processing Updating Boosts and Reposts to the new way of declaring tags Renaming the SHA256 hash tag from NIP94 to not confuse with # hashtags
This commit is contained in:
@@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerName
|
||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.utils.sha256
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import junit.framework.TestCase.fail
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
@@ -99,8 +99,8 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.references.references
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactTag
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ReadWrite
|
||||
import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.OtsEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||
import com.vitorpamplona.quartz.nip04Dm.messages.reply
|
||||
@@ -3542,7 +3542,7 @@ class Account(
|
||||
val event = (addressableNote.event as? PeopleListEvent)
|
||||
event != null &&
|
||||
event.pubKey == pubkey &&
|
||||
(event.hasAnyTaggedUser() || event.publicAndPrivateUserCache?.isNotEmpty() == true)
|
||||
(event.hasAnyTaggedUser() || event.cachedPrivateTags()?.isNotEmpty() == true)
|
||||
}
|
||||
|
||||
fun markAsRead(
|
||||
|
||||
@@ -683,11 +683,11 @@ object LocalCache {
|
||||
is BadgeAwardEvent -> event.awardDefinition().map { getOrCreateAddressableNote(it) }
|
||||
is PrivateDmEvent -> event.taggedEvents().mapNotNull { checkGetOrCreateNote(it) }
|
||||
is RepostEvent ->
|
||||
event.boostedPost().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
event.boostedEventIds().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.boostedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
is GenericRepostEvent ->
|
||||
event.boostedPost().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
event.boostedEventIds().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.boostedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
is CommunityPostApprovalEvent ->
|
||||
event.approvedEvents().mapNotNull { checkGetOrCreateNote(it) } +
|
||||
event.approvedAddresses().map { getOrCreateAddressableNote(it) }
|
||||
|
||||
@@ -54,6 +54,7 @@ import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.getGradient
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
|
||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
@@ -94,7 +95,7 @@ fun DisplayPeopleList(
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
accountViewModel.loadUsers(noteEvent.bookmarkedPeopleIds()) {
|
||||
accountViewModel.loadUsers(noteEvent.taggedUserIds()) {
|
||||
members = it
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -42,8 +42,8 @@ import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactTag
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ReadWrite
|
||||
import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.Nip06
|
||||
import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.benchmark
|
||||
|
||||
import androidx.benchmark.junit4.BenchmarkRule
|
||||
import androidx.benchmark.junit4.measureRepeated
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
import junit.framework.TestCase.assertTrue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class EnsureTest {
|
||||
@get:Rule
|
||||
val scope = BenchmarkRule()
|
||||
|
||||
private val testArgs = arrayOf("0", "1f")
|
||||
|
||||
companion object {
|
||||
const val TAG = "0"
|
||||
const val KEY_SIZE = 2
|
||||
|
||||
private val isHexChar =
|
||||
BooleanArray(256).apply {
|
||||
"0123456789abcdefABCDEF".forEach { this[it.code] = true }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun String.isHex() = all { isHexChar[it.code] }
|
||||
}
|
||||
|
||||
fun directCheckElse(args: Array<String>) =
|
||||
if (args[0] != TAG || args[1].length != KEY_SIZE || !args[1].isHex()) {
|
||||
null
|
||||
} else {
|
||||
args[0] + args[1]
|
||||
}
|
||||
|
||||
fun directCheck(args: Array<String>): String? {
|
||||
if (args[0] != TAG || args[1].length != KEY_SIZE || !args[1].isHex()) return null
|
||||
return args[0] + args[1]
|
||||
}
|
||||
|
||||
fun directCheck2(args: Array<String>): String? {
|
||||
if (args[0] == TAG && args[1].length == KEY_SIZE && args[1].isHex()) return args[0] + args[1]
|
||||
return null
|
||||
}
|
||||
|
||||
fun linedCheck(args: Array<String>): String? {
|
||||
if (args[0] != TAG) return null
|
||||
if (args[1].length != KEY_SIZE) return null
|
||||
if (!args[1].isHex()) return null
|
||||
return args[0] + args[1]
|
||||
}
|
||||
|
||||
fun ensureCheck(args: Array<String>): String? {
|
||||
ensure(args[0] == TAG) { return null }
|
||||
ensure(args[1].length == KEY_SIZE) { return null }
|
||||
ensure(args[1].isHex()) { return null }
|
||||
return args[0] + args[1]
|
||||
}
|
||||
|
||||
fun checkCatch(args: Array<String>): String? =
|
||||
runCatching {
|
||||
check(args[0] == TAG)
|
||||
check(args[1].length == KEY_SIZE)
|
||||
check(args[1].isHex())
|
||||
args[0] + args[1]
|
||||
}.getOrNull()
|
||||
|
||||
fun whenCheck(args: Array<String>) =
|
||||
when (false) {
|
||||
(args[0] == TAG),
|
||||
(args[1].length == KEY_SIZE),
|
||||
(args[1].isHex()),
|
||||
-> null
|
||||
else -> args[0] + args[1]
|
||||
}
|
||||
|
||||
fun ensureAll(args: Array<String>): String? {
|
||||
ensureAll {
|
||||
ensure { args[0] == TAG }
|
||||
ensure { args[1].length == KEY_SIZE }
|
||||
ensure { args[1].isHex() }
|
||||
}.ifFail { return null }
|
||||
return args[0] + args[1]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun directCheckElse() = scope.measureRepeated { assertTrue(directCheckElse(testArgs) != null) }
|
||||
|
||||
@Test
|
||||
fun directCheck() = scope.measureRepeated { assertTrue(directCheck(testArgs) != null) }
|
||||
|
||||
@Test
|
||||
fun linedCheck() = scope.measureRepeated { assertTrue(linedCheck(testArgs) != null) }
|
||||
|
||||
@Test
|
||||
fun ensureCheck() = scope.measureRepeated { assertTrue(ensureCheck(testArgs) != null) }
|
||||
|
||||
@Test
|
||||
fun checkCatch() = scope.measureRepeated { assertTrue(checkCatch(testArgs) != null) }
|
||||
|
||||
@Test
|
||||
fun whenCheck() = scope.measureRepeated { assertTrue(whenCheck(testArgs) != null) }
|
||||
|
||||
@Test
|
||||
fun ensureAll() = scope.measureRepeated { assertTrue(ensureAll(testArgs) != null) }
|
||||
}
|
||||
|
||||
class EnsureScope(
|
||||
var passing: Boolean = true,
|
||||
) {
|
||||
inline fun ensure(predicate: () -> Boolean) {
|
||||
if (passing) passing = predicate()
|
||||
}
|
||||
|
||||
inline fun ifFail(ifFail: () -> Unit) {
|
||||
if (!passing) ifFail()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun ensureAll(block: EnsureScope.() -> Unit) = EnsureScope().apply(block)
|
||||
@@ -91,4 +91,19 @@ class HexBenchmark {
|
||||
fun isHex() {
|
||||
r.measureRepeated { Hex.isHex(hex) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun newIsHex() {
|
||||
val isHexChar =
|
||||
BooleanArray(256).apply {
|
||||
"0123456789abcdefABCDEF".forEach { this[it.code] = true }
|
||||
}
|
||||
|
||||
r.measureRepeated {
|
||||
for (c in hex.indices) {
|
||||
if (!isHexChar[hex[c].code]) return@measureRepeated
|
||||
}
|
||||
return@measureRepeated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import com.vitorpamplona.quartz.nip92IMeta.imetasByUrl
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
@@ -79,7 +79,7 @@ class RichTextParser {
|
||||
MediaUrlImage(
|
||||
url = fullUrl,
|
||||
description = description ?: frags[AltTag.TAG_NAME] ?: tags[AltTag.TAG_NAME]?.firstOrNull(),
|
||||
hash = frags[HashTag.TAG_NAME] ?: tags[HashTag.TAG_NAME]?.firstOrNull(),
|
||||
hash = frags[HashSha256Tag.TAG_NAME] ?: tags[HashSha256Tag.TAG_NAME]?.firstOrNull(),
|
||||
blurhash = frags[BlurhashTag.TAG_NAME] ?: tags[BlurhashTag.TAG_NAME]?.firstOrNull(),
|
||||
dim = frags[DimensionTag.TAG_NAME]?.let { DimensionTag.parse(it) } ?: tags[DimensionTag.TAG_NAME]?.firstOrNull()?.let { DimensionTag.parse(it) },
|
||||
contentWarning = frags[ContentWarningTag.TAG_NAME] ?: tags[ContentWarningTag.TAG_NAME]?.firstOrNull(),
|
||||
@@ -90,7 +90,7 @@ class RichTextParser {
|
||||
MediaUrlVideo(
|
||||
url = fullUrl,
|
||||
description = description ?: frags[AltTag.TAG_NAME] ?: tags[AltTag.TAG_NAME]?.firstOrNull(),
|
||||
hash = frags[HashTag.TAG_NAME] ?: tags[HashTag.TAG_NAME]?.firstOrNull(),
|
||||
hash = frags[HashSha256Tag.TAG_NAME] ?: tags[HashSha256Tag.TAG_NAME]?.firstOrNull(),
|
||||
blurhash = frags[BlurhashTag.TAG_NAME] ?: tags[BlurhashTag.TAG_NAME]?.firstOrNull(),
|
||||
dim = frags[DimensionTag.TAG_NAME]?.let { DimensionTag.parse(it) } ?: tags[DimensionTag.TAG_NAME]?.firstOrNull()?.let { DimensionTag.parse(it) },
|
||||
contentWarning = frags[ContentWarningTag.TAG_NAME] ?: tags[ContentWarningTag.TAG_NAME]?.firstOrNull(),
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -62,7 +62,7 @@ class FileStorageHeaderEvent(
|
||||
|
||||
fun mimeType() = tags.firstNotNullOfOrNull(MimeTypeTag::parse)
|
||||
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashTag::parse)
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashSha256Tag::parse)
|
||||
|
||||
fun size() = tags.firstNotNullOfOrNull(SizeTag::parse)
|
||||
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -37,7 +37,7 @@ import com.vitorpamplona.quartz.nip94FileMetadata.tags.TorrentInfoHash
|
||||
|
||||
fun TagArrayBuilder<FileStorageHeaderEvent>.mimeType(mimeType: String) = add(MimeTypeTag.assemble(mimeType))
|
||||
|
||||
fun TagArrayBuilder<FileStorageHeaderEvent>.hash(hash: HexKey) = add(HashTag.assemble(hash))
|
||||
fun TagArrayBuilder<FileStorageHeaderEvent>.hash(hash: HexKey) = add(HashSha256Tag.assemble(hash))
|
||||
|
||||
fun TagArrayBuilder<FileStorageHeaderEvent>.fileSize(size: Int) = add(SizeTag.assemble(size))
|
||||
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@ import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -58,7 +58,7 @@ class ProfileGalleryEntryEvent(
|
||||
|
||||
fun mimeType() = tags.firstNotNullOfOrNull(MimeTypeTag::parse)
|
||||
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashTag::parse)
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashSha256Tag::parse)
|
||||
|
||||
fun size() = tags.firstNotNullOfOrNull(SizeTag::parse)
|
||||
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -42,7 +42,7 @@ fun TagArrayBuilder<ProfileGalleryEntryEvent>.url(url: String) = add(UrlTag.asse
|
||||
|
||||
fun TagArrayBuilder<ProfileGalleryEntryEvent>.mimeType(mimeType: String) = add(MimeTypeTag.assemble(mimeType))
|
||||
|
||||
fun TagArrayBuilder<ProfileGalleryEntryEvent>.hash(hash: HexKey) = add(HashTag.assemble(hash))
|
||||
fun TagArrayBuilder<ProfileGalleryEntryEvent>.hash(hash: HexKey) = add(HashSha256Tag.assemble(hash))
|
||||
|
||||
fun TagArrayBuilder<ProfileGalleryEntryEvent>.fileSize(size: Int) = add(SizeTag.assemble(size))
|
||||
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@ import com.vitorpamplona.quartz.nip01Core.core.tagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip51Lists.Nip51PrivateTags
|
||||
import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@Immutable
|
||||
@@ -77,7 +77,7 @@ class RelationshipStatusEvent(
|
||||
privateInitializer()
|
||||
}
|
||||
|
||||
Nip51PrivateTags.encryptNip44(privateTags, signer) { content ->
|
||||
PrivateTagsInContent.encryptNip44(privateTags, signer) { content ->
|
||||
signer.sign(createdAt, KIND, publicTags, content, onReady)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,3 +28,7 @@ typealias HexKey = String
|
||||
fun ByteArray.toHexKey(): HexKey = Hex.encode(this)
|
||||
|
||||
fun HexKey.hexToByteArray(): ByteArray = Hex.decode(this)
|
||||
|
||||
const val PUBKEY_LENGTH = 64
|
||||
|
||||
const val EVENT_ID_LENGTH = 64
|
||||
|
||||
@@ -22,6 +22,16 @@ package com.vitorpamplona.quartz.nip01Core.core
|
||||
|
||||
typealias Tag = Array<String>
|
||||
|
||||
/**
|
||||
* Returns if the Tag has at least $index elements.
|
||||
*/
|
||||
fun Tag.has(index: Int) = size > index
|
||||
|
||||
/**
|
||||
* Returns if the Tag has less than $index elements.
|
||||
*/
|
||||
fun Tag.lacks(index: Int) = size <= index
|
||||
|
||||
fun Tag.name() = this[0]
|
||||
|
||||
fun Tag.value() = this[1]
|
||||
|
||||
+10
-6
@@ -24,10 +24,14 @@ import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||
|
||||
interface HintProvider {
|
||||
fun eventHints(): EventIdHint
|
||||
|
||||
fun addressIdHints(): AddressHint
|
||||
|
||||
fun pubKeyHints(): PubKeyHint
|
||||
interface EventHintProvider {
|
||||
fun eventHints(): List<EventIdHint>
|
||||
}
|
||||
|
||||
interface AddressHintProvider {
|
||||
fun addressHints(): List<AddressHint>
|
||||
}
|
||||
|
||||
interface PubKeyHintProvider {
|
||||
fun pubKeyHints(): List<PubKeyHint>
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.core.name
|
||||
import com.vitorpamplona.quartz.nip01Core.core.value
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
@@ -128,6 +129,12 @@ data class ATag(
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): AddressHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || !tag[1].contains(':') || tag[2].isEmpty()) return null
|
||||
return AddressHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
aTagId: HexKey,
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.nip01Core.tags.events
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
@@ -58,7 +59,7 @@ data class ETag(
|
||||
const val TAG_SIZE = 2
|
||||
|
||||
@JvmStatic
|
||||
fun isTagged(tag: Array<String>) = tag.size >= TAG_SIZE && tag[0] == TAG_NAME && tag[1].isNotEmpty()
|
||||
fun isTagged(tag: Array<String>) = tag.size >= TAG_SIZE && tag[0] == TAG_NAME && tag[1].length == 64
|
||||
|
||||
@JvmStatic
|
||||
fun isTagged(
|
||||
@@ -68,16 +69,22 @@ data class ETag(
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): ETag? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].length != 64) return null
|
||||
return ETag(tag[1], tag.getOrNull(2), tag.getOrNull(3))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseId(tag: Array<String>): String? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].length != 64) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): EventIdHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return EventIdHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
eventId: HexKey,
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.hashtags
|
||||
|
||||
class HashTag {
|
||||
class HashtagTag {
|
||||
companion object {
|
||||
const val TAG_NAME = "t"
|
||||
const val TAG_SIZE = 2
|
||||
@@ -30,7 +30,7 @@ class HashTag {
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): String? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].isEmpty()) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,6 +23,6 @@ package com.vitorpamplona.quartz.nip01Core.tags.hashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.hashtag(tag: String) = addAll(HashTag.assembleDualCase(tag))
|
||||
fun <T : Event> TagArrayBuilder<T>.hashtag(tag: String) = addAll(HashtagTag.assembleDualCase(tag))
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.hashtags(tag: List<String>) = addAll(HashTag.assemble(tag))
|
||||
fun <T : Event> TagArrayBuilder<T>.hashtags(tag: List<String>) = addAll(HashtagTag.assemble(tag))
|
||||
|
||||
+8
-8
@@ -30,18 +30,18 @@ import com.vitorpamplona.quartz.nip01Core.core.isAnyLowercaseTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
|
||||
fun TagArray.forEachHashTag(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged(HashTag.TAG_NAME, onEach)
|
||||
fun TagArray.forEachHashTag(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged(HashtagTag.TAG_NAME, onEach)
|
||||
|
||||
fun TagArray.anyHashTag(onEach: (str: String) -> Boolean) = this.anyTagged(HashTag.TAG_NAME, onEach)
|
||||
fun TagArray.anyHashTag(onEach: (str: String) -> Boolean) = this.anyTagged(HashtagTag.TAG_NAME, onEach)
|
||||
|
||||
fun TagArray.hasHashtags() = this.hasTagWithContent(HashTag.TAG_NAME)
|
||||
fun TagArray.hasHashtags() = this.hasTagWithContent(HashtagTag.TAG_NAME)
|
||||
|
||||
fun TagArray.hashtags() = this.mapValues(HashTag.TAG_NAME)
|
||||
fun TagArray.hashtags() = this.mapValues(HashtagTag.TAG_NAME)
|
||||
|
||||
fun TagArray.countHashtags() = this.count(HashTag::isTagged)
|
||||
fun TagArray.countHashtags() = this.count(HashtagTag::isTagged)
|
||||
|
||||
fun TagArray.isTaggedHash(hashtag: String) = this.isTagged(HashTag.TAG_NAME, hashtag, true)
|
||||
fun TagArray.isTaggedHash(hashtag: String) = this.isTagged(HashtagTag.TAG_NAME, hashtag, true)
|
||||
|
||||
fun TagArray.isTaggedHashes(hashtags: Set<String>) = this.isAnyLowercaseTagged(HashTag.TAG_NAME, hashtags)
|
||||
fun TagArray.isTaggedHashes(hashtags: Set<String>) = this.isAnyLowercaseTagged(HashtagTag.TAG_NAME, hashtags)
|
||||
|
||||
fun TagArray.firstIsTaggedHashes(hashtags: Set<String>) = this.firstAnyLowercaseTaggedValue(HashTag.TAG_NAME, hashtags)
|
||||
fun TagArray.firstIsTaggedHashes(hashtags: Set<String>) = this.firstAnyLowercaseTaggedValue(HashtagTag.TAG_NAME, hashtags)
|
||||
|
||||
@@ -25,7 +25,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isNotName
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
@@ -59,14 +59,14 @@ data class PTag(
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Tag): PTag? {
|
||||
if (tag.isNotName(TAG_NAME, TAG_SIZE)) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag[1].length != 64) return null
|
||||
return PTag(tag[1], tag.getOrNull(2))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseKey(tag: Array<String>): HexKey? {
|
||||
if (tag.isNotName(TAG_NAME, TAG_SIZE)) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag[1].length != 64) {
|
||||
Log.w("PTag", "Invalid `$TAG_NAME` value ${tag.joinToString(", ")}")
|
||||
return null
|
||||
@@ -74,6 +74,12 @@ data class PTag(
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): PubKeyHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return PubKeyHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
pubkey: HexKey,
|
||||
|
||||
@@ -23,6 +23,8 @@ package com.vitorpamplona.quartz.nip02FollowList
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
@@ -32,8 +34,9 @@ import com.vitorpamplona.quartz.nip01Core.tags.geohash.isTaggedGeoHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.countHashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
|
||||
import com.vitorpamplona.quartz.nip02FollowList.tags.AddressFollowTag
|
||||
import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -45,7 +48,13 @@ class ContactListEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
AddressHintProvider,
|
||||
PubKeyHintProvider {
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
override fun pubKeyHints() = tags.mapNotNull(ContactTag::parseAsHint)
|
||||
|
||||
/**
|
||||
* Returns a list of p-tags that are verified as hex keys.
|
||||
*/
|
||||
@@ -54,9 +63,9 @@ class ContactListEvent(
|
||||
/**
|
||||
* Returns a list of a-tags that are verified as correct.
|
||||
*/
|
||||
fun verifiedFollowAddressSet(): Set<HexKey> = tags.mapNotNullTo(HashSet(), ATag::parseValidAddress)
|
||||
fun verifiedFollowAddressSet(): Set<HexKey> = tags.mapNotNullTo(HashSet(), AddressFollowTag::parseValidAddress)
|
||||
|
||||
fun unverifiedFollowKeySet() = tags.mapNotNull(PTag::parseKey)
|
||||
fun unverifiedFollowKeySet() = tags.mapNotNull(ContactTag::parseKey)
|
||||
|
||||
fun unverifiedFollowTagSet() = tags.hashtags()
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.nip02FollowList.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
|
||||
typealias AddressFollowTag = ATag
|
||||
+17
-4
@@ -18,12 +18,13 @@
|
||||
* 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.nip02FollowList
|
||||
package com.vitorpamplona.quartz.nip02FollowList.tags
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||
import com.vitorpamplona.quartz.nip19Bech32.decodePublicKey
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
@@ -62,13 +63,13 @@ data class ContactTag(
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): ContactTag? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].length != 64) return null
|
||||
return ContactTag(tag[1], tag.getOrNull(2), tag.getOrNull(3))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseValid(tag: Array<String>): ContactTag? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].length != 64) return null
|
||||
return try {
|
||||
ContactTag(decodePublicKey(tag[1]).toHexKey(), tag.getOrNull(2), tag.getOrNull(3))
|
||||
} catch (e: Exception) {
|
||||
@@ -77,9 +78,15 @@ data class ContactTag(
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseKey(tag: Array<String>): String? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].length != 64) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseValidKey(tag: Array<String>): String? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].length != 64) return null
|
||||
return try {
|
||||
decodePublicKey(tag[1]).toHexKey()
|
||||
} catch (e: Exception) {
|
||||
@@ -88,6 +95,12 @@ data class ContactTag(
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): PubKeyHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return PubKeyHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
pubkey: HexKey,
|
||||
@@ -26,10 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.tags.TargetEventTag
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import java.util.Base64
|
||||
@@ -42,10 +41,13 @@ class OtsEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider {
|
||||
override fun eventHints() = tags.mapNotNull(TargetEventTag::parseAsHint)
|
||||
|
||||
override fun isContentEncoded() = true
|
||||
|
||||
fun digestEventId() = tags.firstNotNullOfOrNull(ETag::parseId)
|
||||
fun digestEventId() = tags.firstNotNullOfOrNull(TargetEventTag::parseId)
|
||||
|
||||
fun otsByteArray(): ByteArray = decodeOtsState(content)
|
||||
|
||||
@@ -82,7 +84,7 @@ class OtsEvent(
|
||||
initializer: TagArrayBuilder<OtsEvent>.() -> Unit = {},
|
||||
) = eventTemplate(KIND, encodeOtsState(otsState), createdAt) {
|
||||
alt(ALT)
|
||||
eTag(ETag(eventId))
|
||||
targetEvent(TargetEventTag(eventId))
|
||||
|
||||
initializer()
|
||||
}
|
||||
@@ -95,8 +97,8 @@ class OtsEvent(
|
||||
) = eventTemplate(KIND, encodeOtsState(otsState), createdAt) {
|
||||
alt(ALT)
|
||||
|
||||
eTag(event.toETag())
|
||||
kind(event.event.kind)
|
||||
targetEvent(event.toETag())
|
||||
targetKind(event.event.kind)
|
||||
|
||||
initializer()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.nip03Timestamp
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.tags.TargetEventKindTag
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.tags.TargetEventTag
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.targetEvent(tag: TargetEventTag) = add(tag.toTagArray())
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.targetEvents(tag: List<TargetEventTag>) = addAll(tag.map { it.toTagArray() })
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.targetKind(kind: Int) = add(TargetEventKindTag.assemble(kind))
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.targetKinds(kinds: List<Int>) = addAll(TargetEventKindTag.assemble(kinds))
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.targetKinds(kinds: Set<Int>) = addAll(TargetEventKindTag.assemble(kinds))
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.nip03Timestamp.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag
|
||||
|
||||
typealias TargetEventKindTag = KindTag
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.nip03Timestamp.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
|
||||
typealias TargetEventTag = ETag
|
||||
@@ -25,6 +25,8 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
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.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.aTag
|
||||
@@ -48,7 +50,13 @@ class DeletionEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
fun deleteEvents() = taggedEvents()
|
||||
|
||||
fun deleteEventIds() = taggedEventIds()
|
||||
|
||||
@@ -23,12 +23,18 @@ package com.vitorpamplona.quartz.nip10Notes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findIndexTagsWithEventsOrAddresses
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findIndexTagsWithPeople
|
||||
import com.vitorpamplona.quartz.nip10Notes.content.findNostrUris
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEmbed
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
@@ -48,7 +54,16 @@ open class BaseThreadedEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, kind, tags, content, sig),
|
||||
EventHintProvider,
|
||||
AddressHintProvider,
|
||||
PubKeyHintProvider {
|
||||
override fun eventHints() = tags.mapNotNull(MarkedETag::parseAsHint) + tags.mapNotNull(QTag::parseEventAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint) + tags.mapNotNull(QTag::parseAddressAsHint)
|
||||
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
fun mentions() = taggedUsers()
|
||||
|
||||
fun markedRoot() = tags.firstNotNullOfOrNull(MarkedETag::parseRoot)
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.nip10Notes.tags
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.GenericETag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
@@ -180,6 +181,12 @@ data class MarkedETag(
|
||||
null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): EventIdHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return EventIdHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseRoot(tag: Array<String>): MarkedETag? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.nip17Dm.base
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
@@ -37,7 +38,10 @@ open class BaseDMGroupEvent(
|
||||
sig: HexKey,
|
||||
) : WrappedEvent(id, pubKey, createdAt, kind, tags, content, sig),
|
||||
ChatroomKeyable,
|
||||
NIP17Group {
|
||||
NIP17Group,
|
||||
PubKeyHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
/** Recipients intended to receive this conversation */
|
||||
fun recipients() = tags.mapNotNull(PTag::parse)
|
||||
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.OriginalHashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.SizeTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -57,7 +57,7 @@ class ChatMessageEncryptedFileHeaderEvent(
|
||||
|
||||
fun mimeType() = tags.firstNotNullOfOrNull(FileTypeTag::parse)
|
||||
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashTag::parse)
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashSha256Tag::parse)
|
||||
|
||||
fun size() = tags.firstNotNullOfOrNull(SizeTag::parse)
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.OriginalHashTag
|
||||
@@ -61,7 +61,7 @@ fun TagArrayBuilder<ChatMessageEncryptedFileHeaderEvent>.encryptionNonce(nonce:
|
||||
|
||||
fun TagArrayBuilder<ChatMessageEncryptedFileHeaderEvent>.mimeType(mimeType: String) = add(FileTypeTag.assemble(mimeType))
|
||||
|
||||
fun TagArrayBuilder<ChatMessageEncryptedFileHeaderEvent>.hash(hash: HexKey) = add(HashTag.assemble(hash))
|
||||
fun TagArrayBuilder<ChatMessageEncryptedFileHeaderEvent>.hash(hash: HexKey) = add(HashSha256Tag.assemble(hash))
|
||||
|
||||
fun TagArrayBuilder<ChatMessageEncryptedFileHeaderEvent>.fileSize(size: Int) = add(SizeTag.assemble(size))
|
||||
|
||||
|
||||
@@ -38,6 +38,6 @@ class EncryptionNonce {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(nonce: ByteArray) = arrayOf(EncryptionKey.TAG_NAME, nonce.toHexKey())
|
||||
fun assemble(nonce: ByteArray) = arrayOf(TAG_NAME, nonce.toHexKey())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,12 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
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.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.aTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
||||
@@ -45,10 +49,29 @@ class GenericRepostEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun boostedPost() = tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) }
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
fun originalAuthor() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) }
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
fun boostedEvents() = tags.mapNotNull(ETag::parse)
|
||||
|
||||
fun boostedATags() = tags.mapNotNull(ATag::parse)
|
||||
|
||||
fun boostedAddresses() = tags.mapNotNull(ATag::parseAddress)
|
||||
|
||||
fun originalAuthors() = tags.mapNotNull(PTag::parse)
|
||||
|
||||
fun boostedEventIds() = tags.mapNotNull(ETag::parseId)
|
||||
|
||||
fun boostedAddressIds() = tags.mapNotNull(ATag::parseAddressId)
|
||||
|
||||
fun originalAuthorKeys() = tags.mapNotNull(PTag::parseKey)
|
||||
|
||||
fun containedPost() =
|
||||
try {
|
||||
|
||||
@@ -25,15 +25,17 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
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.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.aTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
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.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -45,10 +47,29 @@ class RepostEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun boostedPost() = taggedEvents()
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
fun originalAuthor() = taggedUsers()
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
fun boostedEvents() = tags.mapNotNull(ETag::parse)
|
||||
|
||||
fun boostedATags() = tags.mapNotNull(ATag::parse)
|
||||
|
||||
fun boostedAddresses() = tags.mapNotNull(ATag::parseAddress)
|
||||
|
||||
fun originalAuthors() = tags.mapNotNull(PTag::parse)
|
||||
|
||||
fun boostedEventIds() = tags.mapNotNull(ETag::parseId)
|
||||
|
||||
fun boostedAddressIds() = tags.mapNotNull(ATag::parseAddressId)
|
||||
|
||||
fun originalAuthorKeys() = tags.mapNotNull(PTag::parseKey)
|
||||
|
||||
fun containedPost() =
|
||||
try {
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip18Reposts.quotes
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
|
||||
interface QTag {
|
||||
fun toTagArray(): Array<String>
|
||||
|
||||
@@ -36,5 +39,17 @@ interface QTag {
|
||||
QAddressableTag.parse(tag)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseEventAsHint(tag: Array<String>): EventIdHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return EventIdHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAddressAsHint(tag: Array<String>): AddressHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length == 64 || !tag[1].contains(':') || tag[2].isEmpty()) return null
|
||||
return AddressHint(tag[1], tag[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,12 @@ object Bech32 {
|
||||
const val ALPHABET: String = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
|
||||
const val ALPHABET_UPPERCASE: String = "QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L"
|
||||
|
||||
private const val GEN0 = 0x3b6a57b2
|
||||
private const val GEN1 = 0x26508e6d
|
||||
private const val GEN2 = 0x1ea119fa
|
||||
private const val GEN3 = 0x3d4233dd
|
||||
private const val GEN4 = 0x2a1462b3
|
||||
|
||||
enum class Encoding(
|
||||
val constant: Int,
|
||||
) {
|
||||
@@ -74,17 +80,17 @@ object Bech32 {
|
||||
fun expand(hrp: String): Array<Int5> {
|
||||
val half = hrp.length + 1
|
||||
val size = half + hrp.length
|
||||
val firstPart = hrp.indices
|
||||
val secondPart = half until size
|
||||
return Array<Int5>(size) {
|
||||
when (it) {
|
||||
in hrp.indices -> hrp[it].code.shr(5).toByte()
|
||||
in half until size -> (hrp[it - half].code and 31).toByte()
|
||||
in firstPart -> hrp[it].code.shr(5).toByte()
|
||||
in secondPart -> (hrp[it - half].code and 31).toByte()
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val GEN = arrayOf(0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3)
|
||||
|
||||
fun polymod(
|
||||
values: Array<Int5>,
|
||||
values1: Array<Int5>,
|
||||
@@ -93,16 +99,20 @@ object Bech32 {
|
||||
values.forEach { v ->
|
||||
val b = chk shr 25
|
||||
chk = ((chk and 0x1ffffff) shl 5) xor v.toInt()
|
||||
for (i in 0..4) {
|
||||
if (((b shr i) and 1) != 0) chk = chk xor GEN[i]
|
||||
}
|
||||
if (((b shr 0) and 1) != 0) chk = chk xor GEN0
|
||||
if (((b shr 1) and 1) != 0) chk = chk xor GEN1
|
||||
if (((b shr 2) and 1) != 0) chk = chk xor GEN2
|
||||
if (((b shr 3) and 1) != 0) chk = chk xor GEN3
|
||||
if (((b shr 4) and 1) != 0) chk = chk xor GEN4
|
||||
}
|
||||
values1.forEach { v ->
|
||||
val b = chk shr 25
|
||||
chk = ((chk and 0x1ffffff) shl 5) xor v.toInt()
|
||||
for (i in 0..4) {
|
||||
if (((b shr i) and 1) != 0) chk = chk xor GEN[i]
|
||||
}
|
||||
if (((b shr 0) and 1) != 0) chk = chk xor GEN0
|
||||
if (((b shr 1) and 1) != 0) chk = chk xor GEN1
|
||||
if (((b shr 2) and 1) != 0) chk = chk xor GEN2
|
||||
if (((b shr 3) and 1) != 0) chk = chk xor GEN3
|
||||
if (((b shr 4) and 1) != 0) chk = chk xor GEN4
|
||||
}
|
||||
return chk
|
||||
}
|
||||
@@ -128,8 +138,7 @@ object Bech32 {
|
||||
else -> addChecksum(hrp, int5s, encoding)
|
||||
}
|
||||
|
||||
val charArray =
|
||||
CharArray(dataWithChecksum.size) { ALPHABET[dataWithChecksum[it].toInt()] }.concatToString()
|
||||
val charArray = CharArray(dataWithChecksum.size) { ALPHABET[dataWithChecksum[it].toInt()] }.concatToString()
|
||||
|
||||
return hrp + "1" + charArray
|
||||
}
|
||||
@@ -231,8 +240,8 @@ object Bech32 {
|
||||
@JvmStatic
|
||||
public fun eight2five(input: ByteArray): ArrayList<Int5> {
|
||||
var buffer = 0L
|
||||
val output =
|
||||
ArrayList<Int5>(input.size * 2) // larger array on purpose. Checksum is added later.
|
||||
// larger array on purpose. Checksum is added later.
|
||||
val output = ArrayList<Int5>(input.size * 2)
|
||||
var count = 0
|
||||
input.forEach { b ->
|
||||
buffer = (buffer shl 8) or (b.toLong() and 0xff)
|
||||
|
||||
@@ -25,7 +25,10 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
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.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
|
||||
@@ -53,7 +56,16 @@ class CommentEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
RootScope {
|
||||
RootScope,
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(RootAuthorTag::parseAsHint) + tags.mapNotNull(ReplyAuthorTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(RootEventTag::parseAsHint) + tags.mapNotNull(ReplyEventTag::parseAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(RootAddressTag::parseAsHint) + tags.mapNotNull(ReplyAddressTag::parseAsHint)
|
||||
|
||||
fun rootAuthor() = tags.firstNotNullOfOrNull(RootAuthorTag::parse)
|
||||
|
||||
fun replyAuthor() = tags.firstNotNullOfOrNull(ReplyAuthorTag::parse)
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.core.valueIfMatches
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
|
||||
@@ -51,6 +52,12 @@ class ReplyAddressTag(
|
||||
@JvmStatic
|
||||
fun parseAddress(tag: Array<String>) = tag.valueIfMatches(TAG_NAME, TAG_SIZE)
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): AddressHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length == 64 || !tag[1].contains(':') || tag[2].isEmpty()) return null
|
||||
return AddressHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
addressId: HexKey,
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PubKeyReferenceTag
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
|
||||
@@ -55,6 +56,12 @@ data class ReplyAuthorTag(
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): PubKeyHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return PubKeyHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
pubkey: HexKey,
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.core.valueIfMatches
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
|
||||
@@ -71,6 +72,12 @@ class ReplyEventTag(
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): EventIdHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return EventIdHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
eventId: HexKey,
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.core.valueIfMatches
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
|
||||
@@ -69,6 +70,12 @@ class RootAddressTag(
|
||||
@JvmStatic
|
||||
fun parseAddress(tag: Array<String>) = tag.valueIfMatches(TAG_NAME, TAG_SIZE)
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): AddressHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length == 64 || !tag[1].contains(':') || tag[2].isEmpty()) return null
|
||||
return AddressHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
addressId: HexKey,
|
||||
|
||||
@@ -22,10 +22,13 @@ package com.vitorpamplona.quartz.nip22Comments.tags
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.PUBKEY_LENGTH
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PubKeyReferenceTag
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@Immutable
|
||||
data class RootAuthorTag(
|
||||
@@ -36,25 +39,45 @@ data class RootAuthorTag(
|
||||
|
||||
companion object {
|
||||
const val TAG_NAME = "P"
|
||||
const val TAG_SIZE = 2
|
||||
|
||||
@JvmStatic
|
||||
fun match(tag: Tag) = tag.match(TAG_NAME, TAG_SIZE)
|
||||
fun match(tag: Tag) = tag.size > 1 && tag[0] == TAG_NAME
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Tag): ReplyAuthorTag? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag[1].length != 64) return null
|
||||
if (tag.size < 2 || tag[0] != TAG_NAME || tag[1].length != PUBKEY_LENGTH) return null
|
||||
return ReplyAuthorTag(tag[1], tag.getOrNull(2))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parse3(tag: Tag): ReplyAuthorTag? {
|
||||
ensure(tag.size >= 2) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == PUBKEY_LENGTH) { return null }
|
||||
return ReplyAuthorTag(tag[1], tag.getOrNull(2))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseKey(tag: Tag): HexKey? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag[1].length != 64) return null
|
||||
if (tag.size < 2 || tag[0] != TAG_NAME || tag[1].length != PUBKEY_LENGTH) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): PubKeyHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != PUBKEY_LENGTH || tag[2].isEmpty()) return null
|
||||
return PubKeyHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun ensure(
|
||||
condition: Boolean,
|
||||
exit: () -> Nothing,
|
||||
) {
|
||||
contract { returns() implies condition }
|
||||
if (!condition) exit()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
pubkey: HexKey,
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.match
|
||||
import com.vitorpamplona.quartz.nip01Core.core.valueIfMatches
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
|
||||
@@ -71,6 +72,12 @@ class RootEventTag(
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): EventIdHint? {
|
||||
if (tag.size < 3 || tag[0] != TAG_NAME || tag[1].length != 64 || tag[2].isEmpty()) return null
|
||||
return EventIdHint(tag[1], tag[2])
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
eventId: HexKey,
|
||||
|
||||
+15
-1
@@ -24,12 +24,17 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.dTags.dTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag
|
||||
import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag
|
||||
import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag
|
||||
@@ -47,7 +52,16 @@ class LongTextNoteEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
AddressableEvent {
|
||||
AddressableEvent,
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(QTag::parseEventAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(QTag::parseAddressAsHint)
|
||||
|
||||
override fun dTag() = tags.dTag()
|
||||
|
||||
override fun aTag(relayHint: String?) = ATag(kind, pubKey, dTag(), relayHint)
|
||||
|
||||
@@ -24,8 +24,12 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
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.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.aTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
||||
@@ -44,7 +48,16 @@ class ReactionEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
fun originalPost() = tags.mapNotNull(ETag::parseId)
|
||||
|
||||
fun originalAuthor() = tags.mapNotNull(PTag::parseKey)
|
||||
|
||||
+6
-1
@@ -24,6 +24,8 @@ 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.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.ChannelData
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
@@ -37,7 +39,10 @@ class ChannelCreateEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider {
|
||||
override fun eventHints() = channelInfo().relays?.map { EventIdHint(id, it) } ?: emptyList()
|
||||
|
||||
fun channelInfo() = ChannelData.parse(content) ?: ChannelData()
|
||||
|
||||
companion object {
|
||||
|
||||
+5
-1
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
||||
@@ -41,7 +42,10 @@ class ChannelHideMessageEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BasePublicChatEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BasePublicChatEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider {
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint)
|
||||
|
||||
fun eventsToHide() = tags.taggedEventIds()
|
||||
|
||||
companion object {
|
||||
|
||||
+6
-1
@@ -24,6 +24,8 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.BasePublicChatEvent
|
||||
@@ -40,7 +42,10 @@ class ChannelMetadataEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BasePublicChatEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BasePublicChatEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider {
|
||||
override fun eventHints() = channelInfo().relays?.map { EventIdHint(id, it) } ?: emptyList()
|
||||
|
||||
fun channelInfo() = ChannelData.parse(content) ?: ChannelData()
|
||||
|
||||
companion object {
|
||||
|
||||
+5
-1
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
||||
@@ -41,7 +42,10 @@ class ChannelMuteUserEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BasePublicChatEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BasePublicChatEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
PubKeyHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
fun usersToMute() = tags.taggedUserIds()
|
||||
|
||||
companion object {
|
||||
|
||||
+6
-1
@@ -24,9 +24,11 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags
|
||||
import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent
|
||||
@@ -41,7 +43,10 @@ class EmojiPackSelectionEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
AddressHintProvider {
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
fun emojiPacks() = taggedATags()
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -23,13 +23,17 @@ package com.vitorpamplona.quartz.nip34Git.issue
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
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.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip14Subject.SubjectTag
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -42,7 +46,16 @@ class GitIssueEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
PubKeyHintProvider,
|
||||
EventHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(QTag::parseEventAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint) + tags.mapNotNull(QTag::parseAddressAsHint)
|
||||
|
||||
fun repositoryHex() = tags.firstNotNullOfOrNull(ATag::parseAddressId)
|
||||
|
||||
fun repositoryAddress() = tags.firstNotNullOfOrNull(ATag::parseAddress)
|
||||
|
||||
@@ -23,9 +23,14 @@ package com.vitorpamplona.quartz.nip34Git.patch
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -37,7 +42,16 @@ class GitPatchEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
PubKeyHintProvider,
|
||||
EventHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(MarkedETag::parseAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint)
|
||||
|
||||
private fun innerRepository() =
|
||||
tags.firstOrNull { it.size > 3 && it[0] == "a" && it[3] == "root" }
|
||||
?: tags.firstOrNull { it.size > 1 && it[0] == "a" }
|
||||
|
||||
@@ -23,13 +23,18 @@ package com.vitorpamplona.quartz.nip34Git.reply
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
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.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.markedETags
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.prepareMarkedETagsAsReplyTo
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag
|
||||
import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -43,7 +48,16 @@ class GitReplyEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
PubKeyHintProvider,
|
||||
EventHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(MarkedETag::parseAsHint) + tags.mapNotNull(QTag::parseEventAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint) + tags.mapNotNull(QTag::parseAddressAsHint)
|
||||
|
||||
fun repositoryHex() = tags.firstNotNullOfOrNull(ATag::parseAddressId)
|
||||
|
||||
fun repository() = tags.firstNotNullOfOrNull(ATag::parse)
|
||||
|
||||
@@ -23,15 +23,20 @@ package com.vitorpamplona.quartz.nip35Torrents
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
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.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
||||
import com.vitorpamplona.quartz.nip10Notes.tags.positionalMarkedTags
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag
|
||||
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -43,7 +48,16 @@ class TorrentCommentEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint) + tags.mapNotNull(QTag::parseEventAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(QTag::parseAddressAsHint)
|
||||
|
||||
fun torrent() = tags.firstNotNullOfOrNull(MarkedETag::parseRoot) ?: tags.firstNotNullOfOrNull(ETag::parse)
|
||||
|
||||
fun torrentIds() = tags.firstNotNullOfOrNull(MarkedETag::parseRootId) ?: tags.firstNotNullOfOrNull(ETag::parseId)
|
||||
|
||||
@@ -23,14 +23,19 @@ package com.vitorpamplona.quartz.nip51Lists
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.tags.NameTag
|
||||
import com.vitorpamplona.quartz.nip51Lists.tags.TitleTag
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
|
||||
@@ -43,20 +48,22 @@ abstract class GeneralListEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : PrivateTagArrayEvent(id, pubKey, createdAt, kind, tags, content, sig) {
|
||||
fun category() = dTag()
|
||||
) : PrivateTagArrayEvent(id, pubKey, createdAt, kind, tags, content, sig),
|
||||
EventHintProvider,
|
||||
AddressHintProvider,
|
||||
PubKeyHintProvider {
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint) + (cachedPrivateTags()?.mapNotNull(ETag::parseAsHint) ?: emptyList())
|
||||
|
||||
fun bookmarkedPosts() = taggedEvents()
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint) + (cachedPrivateTags()?.mapNotNull(ATag::parseAsHint) ?: emptyList())
|
||||
|
||||
fun bookmarkedPeople() = taggedUsers()
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint) + (cachedPrivateTags()?.mapNotNull(PTag::parseAsHint) ?: emptyList())
|
||||
|
||||
fun bookmarkedPeopleIds() = taggedUserIds()
|
||||
fun name() = tags.firstNotNullOfOrNull(NameTag::parse)
|
||||
|
||||
fun name() = tags.firstOrNull { it.size > 1 && it[0] == "name" }?.get(1)
|
||||
@Deprecated("NIP-51 has deprecated Title. Use name instead", ReplaceWith("name()"))
|
||||
fun title() = tags.firstNotNullOfOrNull(TitleTag::parse)
|
||||
|
||||
fun title() = tags.firstOrNull { it.size > 1 && it[0] == "title" }?.get(1)
|
||||
|
||||
fun nameOrTitle() = name()?.ifBlank { null } ?: title()?.ifBlank { null }
|
||||
fun nameOrTitle() = name() ?: title()
|
||||
|
||||
fun filterTagList(
|
||||
key: String,
|
||||
@@ -124,13 +131,13 @@ abstract class GeneralListEvent(
|
||||
onReady: (List<Address>) -> Unit,
|
||||
) = privateTags(signer) { onReady(filterAddresses(it)) }
|
||||
|
||||
fun filterUsers(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
||||
fun filterUsers(tags: Array<Array<String>>): List<String> = tags.mapNotNull(PTag::parseKey)
|
||||
|
||||
fun filterHashtags(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "t" }.map { it[1] }
|
||||
fun filterHashtags(tags: Array<Array<String>>): List<String> = tags.mapNotNull(HashtagTag::parse)
|
||||
|
||||
fun filterGeohashes(tags: Array<Array<String>>): List<String> = tags.geohashes()
|
||||
|
||||
fun filterEvents(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
||||
fun filterEvents(tags: Array<Array<String>>): List<String> = tags.mapNotNull(ETag::parseId)
|
||||
|
||||
fun filterATags(tags: Array<Array<String>>): List<ATag> = tags.mapNotNull(ATag::parse)
|
||||
|
||||
|
||||
@@ -26,9 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
|
||||
@Immutable
|
||||
class MuteListEvent(
|
||||
@@ -39,39 +36,16 @@ class MuteListEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : GeneralListEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
@Transient var publicAndPrivateUserCache: ImmutableSet<HexKey>? = null
|
||||
|
||||
@Transient var publicAndPrivateWordCache: ImmutableSet<String>? = null
|
||||
|
||||
override fun countMemory(): Long =
|
||||
super.countMemory() +
|
||||
pointerSizeInBytes + (publicAndPrivateUserCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0) +
|
||||
pointerSizeInBytes + (publicAndPrivateWordCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0)
|
||||
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
fun publicAndPrivateUsersAndWords(
|
||||
signer: NostrSigner,
|
||||
onReady: (PeopleListEvent.UsersAndWords) -> Unit,
|
||||
) {
|
||||
publicAndPrivateUserCache?.let { userList ->
|
||||
publicAndPrivateWordCache?.let { wordList ->
|
||||
onReady(PeopleListEvent.UsersAndWords(userList, wordList))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
privateTagsOrEmpty(signer) {
|
||||
publicAndPrivateUserCache = filterTagList("p", it)
|
||||
publicAndPrivateWordCache = filterTagList("word", it)
|
||||
|
||||
publicAndPrivateUserCache?.let { userList ->
|
||||
publicAndPrivateWordCache?.let { wordList ->
|
||||
onReady(
|
||||
PeopleListEvent.UsersAndWords(userList, wordList),
|
||||
)
|
||||
}
|
||||
}
|
||||
onReady(
|
||||
PeopleListEvent.UsersAndWords(filterTagList("p", it), filterTagList("word", it)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
|
||||
@Immutable
|
||||
class PeopleListEvent(
|
||||
@@ -39,45 +36,6 @@ class PeopleListEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : GeneralListEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
@Transient var publicAndPrivateUserCache: ImmutableSet<HexKey>? = null
|
||||
|
||||
@Transient var publicAndPrivateWordCache: ImmutableSet<String>? = null
|
||||
|
||||
override fun countMemory(): Long =
|
||||
super.countMemory() +
|
||||
pointerSizeInBytes + (publicAndPrivateUserCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0) +
|
||||
pointerSizeInBytes + (publicAndPrivateWordCache?.sumOf { pointerSizeInBytes + it.bytesUsedInMemory() } ?: 0)
|
||||
|
||||
fun publicAndPrivateWords(
|
||||
signer: NostrSigner,
|
||||
onReady: (ImmutableSet<String>) -> Unit,
|
||||
) {
|
||||
publicAndPrivateWordCache?.let {
|
||||
onReady(it)
|
||||
return
|
||||
}
|
||||
|
||||
privateTagsOrEmpty(signer) {
|
||||
publicAndPrivateWordCache = filterTagList("word", it)
|
||||
publicAndPrivateWordCache?.let { onReady(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun publicAndPrivateUsers(
|
||||
signer: NostrSigner,
|
||||
onReady: (ImmutableSet<String>) -> Unit,
|
||||
) {
|
||||
publicAndPrivateUserCache?.let {
|
||||
onReady(it)
|
||||
return
|
||||
}
|
||||
|
||||
privateTagsOrEmpty(signer) {
|
||||
publicAndPrivateUserCache = filterTagList("p", it)
|
||||
publicAndPrivateUserCache?.let { onReady(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
class UsersAndWords(
|
||||
val users: Set<String> = setOf(),
|
||||
@@ -88,24 +46,13 @@ class PeopleListEvent(
|
||||
signer: NostrSigner,
|
||||
onReady: (UsersAndWords) -> Unit,
|
||||
) {
|
||||
publicAndPrivateUserCache?.let { userList ->
|
||||
publicAndPrivateWordCache?.let { wordList ->
|
||||
onReady(UsersAndWords(userList, wordList))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
privateTagsOrEmpty(signer) {
|
||||
publicAndPrivateUserCache = filterTagList("p", it)
|
||||
publicAndPrivateWordCache = filterTagList("word", it)
|
||||
|
||||
publicAndPrivateUserCache?.let { userList ->
|
||||
publicAndPrivateWordCache?.let { wordList ->
|
||||
onReady(
|
||||
UsersAndWords(userList, wordList),
|
||||
)
|
||||
}
|
||||
}
|
||||
onReady(
|
||||
UsersAndWords(
|
||||
filterTagList("p", it),
|
||||
filterTagList("word", it),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
|
||||
@@ -63,7 +64,7 @@ abstract class PrivateTagArrayEvent(
|
||||
}
|
||||
|
||||
try {
|
||||
Nip51PrivateTags.decrypt(content, signer) {
|
||||
PrivateTagsInContent.decrypt(content, signer) {
|
||||
privateTagsCache = it
|
||||
privateTagsCache?.let { onReady(it) }
|
||||
}
|
||||
@@ -78,7 +79,7 @@ abstract class PrivateTagArrayEvent(
|
||||
onReady: (content: String) -> Unit,
|
||||
) {
|
||||
privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = change(privateTags),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -97,7 +98,7 @@ abstract class PrivateTagArrayEvent(
|
||||
) {
|
||||
if (toPrivate) {
|
||||
current.privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = privateTags.plus(newTag),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -118,7 +119,7 @@ abstract class PrivateTagArrayEvent(
|
||||
) {
|
||||
if (toPrivate) {
|
||||
current.privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = privateTags.plus(newTag),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -168,7 +169,7 @@ abstract class PrivateTagArrayEvent(
|
||||
onReady: (content: String, tags: Array<Array<String>>) -> Unit,
|
||||
) {
|
||||
current.privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = privateTags.replaceAll(oldTagStartsWith, newTag),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -185,7 +186,7 @@ abstract class PrivateTagArrayEvent(
|
||||
onReady: (content: String, tags: Array<Array<String>>) -> Unit,
|
||||
) {
|
||||
current.privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = privateTags.remove(oldTagStartsWith),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -201,7 +202,7 @@ abstract class PrivateTagArrayEvent(
|
||||
onReady: (content: String, tags: Array<Array<String>>) -> Unit,
|
||||
) {
|
||||
current.privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = privateTags.remove(oldTagStartsWith),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -224,7 +225,7 @@ abstract class PrivateTagArrayEvent(
|
||||
onReady: (content: String, tags: Array<Array<String>>) -> Unit,
|
||||
) {
|
||||
current.privateTags(signer) { privateTags ->
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = privateTags.remove(oldTagStartsWith),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
@@ -239,7 +240,7 @@ abstract class PrivateTagArrayEvent(
|
||||
signer: NostrSigner,
|
||||
onReady: (content: String, tags: Array<Array<String>>) -> Unit,
|
||||
) {
|
||||
Nip51PrivateTags.encryptNip04(
|
||||
PrivateTagsInContent.encryptNip04(
|
||||
privateTags = arrayOf(newTag),
|
||||
signer = signer,
|
||||
) { encryptedTags ->
|
||||
|
||||
+2
-2
@@ -18,13 +18,13 @@
|
||||
* 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.nip51Lists
|
||||
package com.vitorpamplona.quartz.nip51Lists.encryption
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
|
||||
class Nip51PrivateTags {
|
||||
class PrivateTagsInContent {
|
||||
companion object {
|
||||
fun decode(content: String) = EventMapper.mapper.readValue<Array<Array<String>>>(content)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.nip51Lists.tags
|
||||
|
||||
class NameTag {
|
||||
companion object {
|
||||
const val TAG_NAME = "name"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): String? {
|
||||
if (tag.size < 2 || tag[0] != TAG_NAME || tag[1].isEmpty()) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(name: String) = arrayOf(TAG_NAME, name)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.nip51Lists.tags
|
||||
|
||||
@Deprecated("Use NameTag Instead")
|
||||
class TitleTag {
|
||||
companion object {
|
||||
const val TAG_NAME = "title"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): String? {
|
||||
if (tag.size < 2 || tag[0] != TAG_NAME || tag[1].isEmpty()) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(name: String) = arrayOf(TAG_NAME, name)
|
||||
}
|
||||
}
|
||||
+16
-1
@@ -23,10 +23,16 @@ package com.vitorpamplona.quartz.nip53LiveActivities.chat
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
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.PubKeyHintProvider
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -38,7 +44,16 @@ class LiveActivitiesChatMessageEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : BaseThreadedEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
EventHintProvider,
|
||||
PubKeyHintProvider,
|
||||
AddressHintProvider {
|
||||
override fun pubKeyHints() = tags.mapNotNull(PTag::parseAsHint)
|
||||
|
||||
override fun eventHints() = tags.mapNotNull(ETag::parseAsHint) + tags.mapNotNull(QTag::parseEventAsHint)
|
||||
|
||||
override fun addressHints() = tags.mapNotNull(ATag::parseAsHint) + tags.mapNotNull(QTag::parseAddressAsHint)
|
||||
|
||||
private fun activityHex() = tags.firstNotNullOfOrNull(ATag::parseAddressId)
|
||||
|
||||
fun activity() = tags.firstNotNullOfOrNull(ATag::parse)
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -48,7 +48,7 @@ fun IMetaTagBuilder.mimeType(mime: String) = add(MimeTypeTag.TAG_NAME, mime)
|
||||
|
||||
fun IMetaTagBuilder.alt(alt: String) = add(AltTag.TAG_NAME, alt)
|
||||
|
||||
fun IMetaTagBuilder.hash(hash: HexKey) = add(HashTag.TAG_NAME, hash)
|
||||
fun IMetaTagBuilder.hash(hash: HexKey) = add(HashSha256Tag.TAG_NAME, hash)
|
||||
|
||||
fun IMetaTagBuilder.size(size: Int) = add(SizeTag.TAG_NAME, size.toString())
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -47,7 +47,7 @@ fun IMetaTag.mimeType() = properties.get(MimeTypeTag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.alt() = properties.get(AltTag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.hash() = properties.get(HashTag.TAG_NAME)
|
||||
fun IMetaTag.hash() = properties.get(HashSha256Tag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.size() = properties.get(SizeTag.TAG_NAME)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip92IMeta.imetas
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -68,7 +68,7 @@ class PictureEvent(
|
||||
|
||||
private fun mimeType() = tags.firstNotNullOfOrNull(MimeTypeTag::parse)
|
||||
|
||||
private fun hash() = tags.firstNotNullOfOrNull(HashTag::parse)
|
||||
private fun hash() = tags.firstNotNullOfOrNull(HashSha256Tag::parse)
|
||||
|
||||
private fun size() = tags.firstNotNullOfOrNull(SizeTag::parse)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag
|
||||
import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
|
||||
fun TagArrayBuilder<PictureEvent>.title(title: String) = addUnique(TitleTag.assemble(title))
|
||||
@@ -43,7 +43,7 @@ fun TagArrayBuilder<PictureEvent>.pictureIMeta(
|
||||
|
||||
fun TagArrayBuilder<PictureEvent>.pictureIMeta(imeta: PictureMeta): TagArrayBuilder<PictureEvent> {
|
||||
add(imeta.toIMetaArray())
|
||||
imeta.hash?.let { add(HashTag.assemble(it)) }
|
||||
imeta.hash?.let { add(HashSha256Tag.assemble(it)) }
|
||||
imeta.mimeType?.let { add(MimeTypeTag.assemble(it)) }
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -47,7 +47,7 @@ fun IMetaTagBuilder.mimeType(mime: String) = add(MimeTypeTag.TAG_NAME, mime)
|
||||
|
||||
fun IMetaTagBuilder.alt(alt: String) = add(AltTag.TAG_NAME, alt)
|
||||
|
||||
fun IMetaTagBuilder.hash(hash: HexKey) = add(HashTag.TAG_NAME, hash)
|
||||
fun IMetaTagBuilder.hash(hash: HexKey) = add(HashSha256Tag.TAG_NAME, hash)
|
||||
|
||||
fun IMetaTagBuilder.size(size: Int) = add(SizeTag.TAG_NAME, size.toString())
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -46,7 +46,7 @@ fun IMetaTag.mimeType() = properties.get(MimeTypeTag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.alt() = properties.get(AltTag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.hash() = properties.get(HashTag.TAG_NAME)
|
||||
fun IMetaTag.hash() = properties.get(HashSha256Tag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.size() = properties.get(SizeTag.TAG_NAME)
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import com.vitorpamplona.quartz.nip92IMeta.imetas
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -65,7 +65,7 @@ abstract class VideoEvent(
|
||||
|
||||
private fun mimeType() = tags.firstNotNullOfOrNull(MimeTypeTag::parse)
|
||||
|
||||
private fun hash() = tags.firstNotNullOfOrNull(HashTag::parse)
|
||||
private fun hash() = tags.firstNotNullOfOrNull(HashSha256Tag::parse)
|
||||
|
||||
private fun size() = tags.firstNotNullOfOrNull(SizeTag::parse)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import com.vitorpamplona.quartz.nip31Alts.alt
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -57,7 +57,7 @@ class FileHeaderEvent(
|
||||
|
||||
fun mimeType() = tags.firstNotNullOfOrNull(MimeTypeTag::parse)
|
||||
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashTag::parse)
|
||||
fun hash() = tags.firstNotNullOfOrNull(HashSha256Tag::parse)
|
||||
|
||||
fun size() = tags.firstNotNullOfOrNull(SizeTag::parse)
|
||||
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -47,7 +47,7 @@ fun IMetaTagBuilder.mimeType(mime: String) = add(MimeTypeTag.TAG_NAME, mime)
|
||||
|
||||
fun IMetaTagBuilder.alt(alt: String) = add(AltTag.TAG_NAME, alt)
|
||||
|
||||
fun IMetaTagBuilder.hash(hash: HexKey) = add(HashTag.TAG_NAME, hash)
|
||||
fun IMetaTagBuilder.hash(hash: HexKey) = add(HashSha256Tag.TAG_NAME, hash)
|
||||
|
||||
fun IMetaTagBuilder.size(size: Int) = add(SizeTag.TAG_NAME, size.toString())
|
||||
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.FallbackTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.ImageTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MagnetTag
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag
|
||||
@@ -41,7 +41,7 @@ fun TagArrayBuilder<FileHeaderEvent>.url(url: String) = add(UrlTag.assemble(url)
|
||||
|
||||
fun TagArrayBuilder<FileHeaderEvent>.mimeType(mimeType: String) = add(MimeTypeTag.assemble(mimeType))
|
||||
|
||||
fun TagArrayBuilder<FileHeaderEvent>.hash(hash: HexKey) = add(HashTag.assemble(hash))
|
||||
fun TagArrayBuilder<FileHeaderEvent>.hash(hash: HexKey) = add(HashSha256Tag.assemble(hash))
|
||||
|
||||
fun TagArrayBuilder<FileHeaderEvent>.fileSize(size: Int) = add(SizeTag.assemble(size))
|
||||
|
||||
|
||||
+2
-2
@@ -20,14 +20,14 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip94FileMetadata.tags
|
||||
|
||||
class HashTag {
|
||||
class HashSha256Tag {
|
||||
companion object {
|
||||
const val TAG_NAME = "x"
|
||||
const val TAG_SIZE = 2
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): String? {
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME) return null
|
||||
if (tag.size < TAG_SIZE || tag[0] != TAG_NAME || tag[1].isEmpty()) return null
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2024 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.utils
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun ensure(
|
||||
condition: Boolean,
|
||||
exit: () -> Nothing,
|
||||
) {
|
||||
contract {
|
||||
returns() implies condition
|
||||
}
|
||||
if (!condition) exit()
|
||||
}
|
||||
@@ -21,24 +21,25 @@
|
||||
package com.vitorpamplona.quartz.utils
|
||||
|
||||
object Hex {
|
||||
private val lowerCaseHex = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
|
||||
private val upperCaseHex = arrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
|
||||
private const val LOWER_CASE_HEX = "0123456789abcdef"
|
||||
private const val UPPER_CASE_HEX = "0123456789ABCDEF"
|
||||
|
||||
private val hexToByte: IntArray =
|
||||
IntArray(256) { -1 }.apply {
|
||||
lowerCaseHex.forEachIndexed { index, char -> this[char.code] = index }
|
||||
upperCaseHex.forEachIndexed { index, char -> this[char.code] = index }
|
||||
LOWER_CASE_HEX.forEachIndexed { index, char -> this[char.code] = index }
|
||||
UPPER_CASE_HEX.forEachIndexed { index, char -> this[char.code] = index }
|
||||
}
|
||||
|
||||
// Encodes both chars in a single Int variable
|
||||
private val byteToHex =
|
||||
IntArray(256) {
|
||||
(lowerCaseHex[(it shr 4)].code shl 8) or lowerCaseHex[(it and 0xF)].code
|
||||
(LOWER_CASE_HEX[(it shr 4)].code shl 8) or LOWER_CASE_HEX[(it and 0xF)].code
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isHex(hex: String?): Boolean {
|
||||
if (hex.isNullOrEmpty() || hex.length and 1 != 0) return false
|
||||
if (hex.isNullOrEmpty()) return false
|
||||
if (hex.length and 1 != 0) return false
|
||||
|
||||
try {
|
||||
for (c in hex.indices) {
|
||||
|
||||
Reference in New Issue
Block a user