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:
+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