- Migrates Zap splits, zapraisers, subject, alts and content warning to their own packages.

- Adds protected event tags
This commit is contained in:
Vitor Pamplona
2025-01-14 19:35:16 -05:00
parent 502d39c893
commit d19ae56afa
138 changed files with 760 additions and 310 deletions
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -60,7 +61,7 @@ class BlossomServersEvent(
servers
.map {
arrayOf("server", it)
}.plusElement(arrayOf("alt", ALT))
}.plusElement(AltTagSerializer.toTagArray(ALT))
.toTypedArray()
fun updateRelayList(
@@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -72,12 +74,12 @@ class AudioHeaderEvent(
wavefront?.let { arrayOf(WAVEFORM, it) },
sensitiveContent?.let {
if (it) {
arrayOf("content-warning", "")
ContentWarningSerializer.toTagArray()
} else {
null
}
},
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
).toTypedArray()
signer.sign(createdAt, KIND, tags, description, onReady)
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -73,7 +74,7 @@ class AudioTrackEvent(
price?.let { arrayOf(PRICE, it) },
cover?.let { arrayOf(COVER, it) },
subject?.let { arrayOf(SUBJECT, it) },
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
).toTypedArray()
signer.sign(createdAt, KIND, tags, "", onReady)
@@ -29,6 +29,7 @@ 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.nip21UriScheme.toNostrUri
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -101,7 +102,7 @@ class PrivateOutboxRelayListEvent(
companion object {
const val KIND = 10013
const val FIXED_D_TAG = ""
val TAGS = arrayOf(arrayOf("alt", "Relay list to store private content from this author"))
val TAGS = arrayOf(AltTagSerializer.toTagArray("Relay list to store private content from this author"))
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -63,7 +64,7 @@ class TextNoteModificationEvent(
tags.add(arrayOf("summary", it))
}
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -31,7 +31,11 @@ import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
@@ -69,14 +73,13 @@ open class InteractiveStoryBaseEvent(
tags.addAll(buildHashtagTags(findHashtags(content)))
tags.addAll(buildUrlRefs(findURLs(content)))
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
@@ -99,7 +102,7 @@ open class InteractiveStoryBaseEvent(
arrayOf("title", title),
summary?.let { arrayOf("summary", it) },
image?.let { arrayOf("image", it) },
arrayOf("alt", alt),
AltTagSerializer.toTagArray(alt),
) +
options.map {
val relayUrl = it.address.relay
@@ -24,7 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip22Comments.RootScope
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.removeTrailingNullsAndEmptyOthers
@@ -120,7 +121,7 @@ class InteractiveStoryReadingStateEvent(
val tags =
listOfNotNull(
arrayOf("d", rootTag),
arrayOf("alt", root.title()?.let { ALT2 + it } ?: ALT1),
AltTagSerializer.toTagArray(root.title()?.let { ALT2 + it } ?: ALT1),
root.title()?.let { arrayOf("title", it) },
root.summary()?.let { arrayOf("summary", it) },
root.image()?.let { arrayOf("image", it) },
@@ -24,7 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip22Comments.RootScope
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -25,6 +25,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import java.util.Base64
@@ -68,7 +69,7 @@ class FileStorageEvent(
val tags =
listOfNotNull(
arrayOf(TYPE, mimeType),
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
val content = encode(data)
@@ -24,6 +24,8 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -91,7 +93,7 @@ class FileStorageHeaderEvent(
arrayOf("e", storageEvent.id),
mimeType?.let { arrayOf(MIME_TYPE, mimeType) },
hash?.let { arrayOf(HASH, it) },
alt?.let { arrayOf(ALT, it) } ?: arrayOf("alt", ALT_DESCRIPTION),
alt?.let { arrayOf(ALT, it) } ?: AltTagSerializer.toTagArray(ALT_DESCRIPTION),
size?.let { arrayOf(FILE_SIZE, it) },
dimensions?.let { arrayOf(DIMENSION, it.toString()) },
blurhash?.let { arrayOf(BLUR_HASH, it) },
@@ -99,7 +101,7 @@ class FileStorageHeaderEvent(
torrentInfoHash?.let { arrayOf(TORRENT_INFOHASH, it) },
sensitiveContent?.let {
if (it) {
arrayOf("content-warning", "")
ContentWarningSerializer.toTagArray()
} else {
null
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -50,7 +51,7 @@ class NNSEvent(
createdAt: Long = TimeUtils.now(),
onReady: (NNSEvent) -> Unit,
) {
val tags = arrayOf(arrayOf("alt", ALT))
val tags = arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, "", onReady)
}
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -141,7 +142,7 @@ class GalleryListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -24,6 +24,8 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -108,7 +110,7 @@ class ProfileGalleryEntryEvent(
eventid?.let { etag },
magnetUri?.let { arrayOf(MAGNET_URI, it) },
mimeType?.let { arrayOf(MIME_TYPE, it) },
alt?.ifBlank { null }?.let { arrayOf(ALT, it) } ?: arrayOf("alt", ALT_DESCRIPTION),
alt?.ifBlank { null }?.let { arrayOf(ALT, it) } ?: AltTagSerializer.toTagArray(ALT_DESCRIPTION),
hash?.let { arrayOf(HASH, it) },
size?.let { arrayOf(FILE_SIZE, it) },
dimensions?.let { arrayOf(DIMENSION, it.toString()) },
@@ -118,7 +120,7 @@ class ProfileGalleryEntryEvent(
torrentInfoHash?.let { arrayOf(TORRENT_INFOHASH, it) },
sensitiveContent?.let {
if (it) {
arrayOf("content-warning", "")
ContentWarningSerializer.toTagArray()
} else {
null
}
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.experimental.relationshipStatus
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -53,7 +54,7 @@ class RelationshipStatusEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -69,7 +70,7 @@ class RelationshipStatusEvent(
) {
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("d", targetUser))
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
val privateTags = mutableListOf<Array<String>>()
petname?.let { privateTags.add(arrayOf(PETNAME, it)) }
@@ -27,7 +27,11 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -102,19 +106,18 @@ class PollNoteEvent(
tags.add(arrayOf(CONSENSUS_THRESHOLD, consensusThreshold.toString()))
}
closedAt?.let { tags.add(arrayOf(CLOSED_AT, closedAt.toString())) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
}
emojis?.forEach { tags.add(it.toTagArray()) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
if (isDraft) {
signer.assembleRumor(createdAt, KIND, tags.toTypedArray(), msg, onReady)
@@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip39ExtIdentities.updateClaims
import com.vitorpamplona.quartz.utils.TimeUtils
import java.io.ByteArrayInputStream
@@ -68,7 +69,7 @@ class MetadataEvent(
val tags = mutableListOf<Array<String>>()
tags.add(
arrayOf("alt", "User profile for ${name ?: currentJson.get("name").asText() ?: ""}"),
AltTagSerializer.toTagArray("User profile for ${name ?: currentJson.get("name").asText() ?: ""}"),
)
return signer.sign(createdAt, KIND, tags.toTypedArray(), writer.buffer.toString())
@@ -118,7 +119,7 @@ class MetadataEvent(
ObjectMapper().writeValue(writer, currentJson)
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("alt", "User profile for ${name ?: currentJson.get("name").asText() ?: ""}"))
tags.add(AltTagSerializer.toTagArray("User profile for ${name ?: currentJson.get("name").asText() ?: ""}"))
latest?.updateClaims(twitter, github, mastodon)?.forEach {
tags.add(it)
@@ -39,6 +39,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser
import com.vitorpamplona.quartz.nip01Core.toHexKey
import com.vitorpamplona.quartz.nip19Bech32.decodePublicKey
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable data class Contact(
@@ -143,7 +144,7 @@ class ContactListEvent(
}
val tags =
listOf(arrayOf("alt", ALT)) +
listOf(AltTagSerializer.toTagArray(ALT)) +
followUsers.map {
listOfNotNull("p", it.pubKeyHex, it.relayUri).toTypedArray()
} +
@@ -413,7 +414,7 @@ class ContactListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -34,6 +34,7 @@ import com.vitorpamplona.quartz.nip03Timestamp.ots.OpenTimestamps
import com.vitorpamplona.quartz.nip03Timestamp.ots.VerifyResult
import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.UrlException
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
import kotlinx.coroutines.CancellationException
@@ -178,7 +179,7 @@ class OtsEvent(
val tags =
arrayOf(
arrayOf("e", eventId),
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
signer.sign(createdAt, KIND, tags, otsFileBase64, onReady)
}
@@ -1,11 +1,11 @@
package com.vitorpamplona.quartz.nip03Timestamp.ots;
import com.vitorpamplona.quartz.utils.Hex;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpCrypto;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpKECCAK256;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpRIPEMD160;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA1;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256;
import com.vitorpamplona.quartz.utils.Hex;
import java.io.File;
import java.io.IOException;
@@ -2,7 +2,6 @@ package com.vitorpamplona.quartz.nip03Timestamp.ots;
import android.util.Log;
import com.vitorpamplona.quartz.utils.Hex;
import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.BitcoinBlockHeaderAttestation;
import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.EthereumBlockHeaderAttestation;
import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.LitecoinBlockHeaderAttestation;
@@ -12,6 +11,7 @@ import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.VerificationExcept
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpAppend;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpCrypto;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpSHA256;
import com.vitorpamplona.quartz.utils.Hex;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -1,11 +1,11 @@
package com.vitorpamplona.quartz.nip03Timestamp.ots;
import com.vitorpamplona.quartz.utils.Hex;
import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.BitcoinBlockHeaderAttestation;
import com.vitorpamplona.quartz.nip03Timestamp.ots.attestation.TimeAttestation;
import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.Op;
import com.vitorpamplona.quartz.nip03Timestamp.ots.op.OpBinary;
import com.vitorpamplona.quartz.utils.Hex;
import java.util.ArrayList;
import java.util.Arrays;
@@ -2,11 +2,11 @@ package com.vitorpamplona.quartz.nip03Timestamp.ots.op;
import android.util.Log;
import com.vitorpamplona.quartz.utils.Hex;
import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamDeserializationContext;
import com.vitorpamplona.quartz.nip03Timestamp.ots.StreamSerializationContext;
import com.vitorpamplona.quartz.nip03Timestamp.ots.Utils;
import com.vitorpamplona.quartz.nip03Timestamp.ots.exceptions.DeserializationException;
import com.vitorpamplona.quartz.utils.Hex;
import java.util.Arrays;
@@ -28,7 +28,11 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
import com.vitorpamplona.quartz.nip17Dm.ChatroomKey
import com.vitorpamplona.quartz.nip17Dm.ChatroomKeyable
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.utils.Hex
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -149,13 +153,13 @@ class PrivateDmEvent(
publishedRecipientPubKey?.let { tags.add(arrayOf("p", publishedRecipientPubKey)) }
replyTos?.forEach { tags.add(arrayOf("e", it, "", "reply")) }
mentions?.forEach { tags.add(arrayOf("p", it)) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
/* Privacy issue: DO NOT ADD THESE TO THE TAGS.
imetas?.forEach {
@@ -163,7 +167,7 @@ class PrivateDmEvent(
}
*/
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.nip04Encrypt(message, recipientPubKey) { content ->
if (isDraft) {
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -68,7 +69,7 @@ class DeletionEvent(
tags.addAll(deleteEvents.map { arrayOf("e", it.id) })
tags.addAll(deleteEvents.mapNotNull { if (it is AddressableEvent) arrayOf("a", it.address().toTag()) else null })
tags.addAll(kinds)
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -92,7 +93,7 @@ class DeletionEvent(
tags.addAll(deleteEvents.map { arrayOf("e", it.id) })
tags.addAll(kinds)
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -49,4 +49,11 @@ data class PTag(
fun toNPub(): String = pubKeyHex.hexToByteArray().toNpub()
fun toPTagArray() = removeTrailingNullsAndEmptyOthers("p", pubKeyHex, relay)
companion object {
fun parse(tags: Array<String>): PTag {
require(tags[0] == "p")
return PTag(tags[1], tags.getOrNull(2))
}
}
}
@@ -32,7 +32,11 @@ import com.vitorpamplona.quartz.nip10Notes.content.buildUrlRefs
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -50,6 +54,12 @@ class TextNoteEvent(
companion object {
const val KIND = 1
const val ALT = "A short note: "
fun shortedMessageForAlt(msg: String): String {
if (msg.length < 50) return ALT + msg
return ALT + msg.take(50) + "..."
}
fun create(
msg: String,
@@ -73,6 +83,7 @@ class TextNoteEvent(
onReady: (TextNoteEvent) -> Unit,
) {
val tags = mutableListOf<Array<String>>()
tags.add(AltTagSerializer.toTagArray(shortedMessageForAlt(msg)))
replyTos?.let {
tags.addAll(
it.positionalMarkedTags(
@@ -116,13 +127,13 @@ class TextNoteEvent(
}
tags.addAll(buildHashtagTags(findHashtags(msg) + (extraTags ?: emptyList())))
tags.addAll(buildUrlRefs(findURLs(msg)))
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach { tags.add(Nip92MediaAttachments.createTag(it)) }
emojis?.forEach { tags.add(it.toTagArray()) }
@@ -23,4 +23,6 @@ package com.vitorpamplona.quartz.nip14Subject
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
fun Event.subject() = tags.firstTagValue("subject")
val SUBJECT_TAG = "subject"
fun Event.subject() = tags.firstTagValue(SUBJECT_TAG)
@@ -0,0 +1,28 @@
/**
* 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.nip14Subject
class SubjectTagSerializer {
companion object {
@JvmStatic
fun toTagArray(subject: String = "") = arrayOf(SUBJECT_TAG, subject)
}
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.hexToByteArray
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.toHexKey
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -150,7 +151,7 @@ class ChatMessageEncryptedFileHeaderEvent(
blurhash?.let { arrayOf(BLUR_HASH, it) },
sensitiveContent?.let {
if (it) {
arrayOf("content-warning", "")
ContentWarningSerializer.toTagArray()
} else {
null
}
@@ -24,8 +24,12 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
import com.vitorpamplona.quartz.nip14Subject.SubjectTagSerializer
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
@@ -95,20 +99,19 @@ class ChatMessageEvent(
to?.forEach { tags.add(arrayOf("p", it)) }
replyTos?.forEach { tags.add(arrayOf("e", it, "", "reply")) }
mentions?.forEach { tags.add(arrayOf("p", it, "", "mention")) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
subject?.let { tags.add(arrayOf("subject", it)) }
subject?.let { tags.add(SubjectTagSerializer.toTagArray(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
}
emojis?.forEach { tags.add(it.toTagArray()) }
// tags.add(arrayOf("alt", alt))
// tags.add(AltTagSerializer.toTagArray(ALT))
if (isDraft) {
signer.assembleRumor(createdAt, KIND, tags.toTypedArray(), msg, onReady)
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -60,7 +61,7 @@ class ChatMessageRelayListEvent(
relays
.map {
arrayOf("relay", it)
}.plusElement(arrayOf("alt", "Relay list to receive private messages"))
}.plusElement(AltTagSerializer.toTagArray("Relay list to receive private messages"))
.toTypedArray()
fun updateRelayList(
@@ -25,7 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip59Giftwrap.GiftWrapEvent
import com.vitorpamplona.quartz.nip59Giftwrap.SealedGossipEvent
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -70,7 +71,7 @@ class GenericRepostEvent(
}
tags.add(arrayOf("k", "${boostedPost.kind}"))
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEvents
import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUsers
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -70,7 +71,7 @@ class RepostEvent(
tags += listOf(arrayOf("a", boostedPost.address().toTag()))
}
tags += listOf(arrayOf("alt", ALT))
tags += listOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, content, onReady)
}
@@ -72,7 +72,7 @@ object Nip19Parser {
val type = matcher.group(2) // npub1
val key = matcher.group(3) // bech32
return type + key
return type!! + key
} catch (e: Throwable) {
Log.e("NIP19 Parser", "Issue trying to Decode NIP19 $uri: ${e.message}", e)
}
@@ -37,7 +37,10 @@ import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip19Bech32.parseAtag
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -212,13 +215,12 @@ class CommentEvent(
emojis?.forEach { tags.add(it.toTagArray()) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
@@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip01Core.tags.addressables.dTag
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -77,7 +78,7 @@ class LongTextNoteEvent(
replyTos?.forEach { tags.add(arrayOf("e", it)) }
mentions?.forEach { tags.add(arrayOf("p", it)) }
title?.let { tags.add(arrayOf("title", it)) }
tags.add(arrayOf("alt", "Blog post: $title"))
tags.add(AltTagSerializer.toTagArray("Blog post: $title"))
signer.sign(createdAt, KIND, tags.toTypedArray(), msg, onReady)
}
}
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -87,7 +88,7 @@ class ChannelCreateEvent(
val tags =
arrayOf(
arrayOf("alt", "Public chat creation event ${channelInfo?.name?.let { "about $it" }}"),
AltTagSerializer.toTagArray("Public chat creation event ${channelInfo?.name?.let { "about $it" }}"),
)
signer.sign(createdAt, KIND, tags, content, onReady)
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -57,7 +58,7 @@ class ChannelHideMessageEvent(
(
messagesToHide?.map { arrayOf("e", it) }?.toTypedArray()
?: emptyArray()
) + arrayOf(arrayOf("alt", ALT))
) + arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, reason, onReady)
}
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip28PublicChat
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
@@ -264,7 +265,7 @@ class ChannelListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -26,7 +26,11 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -82,20 +86,19 @@ class ChannelMessageEvent(
tags.add(arrayOf("e", it))
}
}
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
}
emojis?.forEach { tags.add(it.toTagArray()) }
tags.add(
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
if (isDraft) {
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -91,7 +92,7 @@ class ChannelMetadataEvent(
val tags =
listOf(
arrayOf("e", originalChannelIdHex, "", "root"),
arrayOf("alt", "Public chat update to ${newChannelInfo?.name}"),
AltTagSerializer.toTagArray("Public chat update to ${newChannelInfo?.name}"),
)
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -58,7 +59,7 @@ class ChannelMuteUserEvent(
(
usersToMute?.map { arrayOf("p", it) }?.toTypedArray()
?: emptyArray()
) + arrayOf(arrayOf("alt", ALT))
) + arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, content, onReady)
}
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip30CustomEmoji
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -49,7 +50,7 @@ class EmojiPackEvent(
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("d", name))
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -70,7 +71,7 @@ class EmojiPackSelectionEvent(
listOfEmojiPacks?.forEach { tags.add(arrayOf("a", it.toTag())) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), msg, onReady)
}
@@ -0,0 +1,28 @@
/**
* 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.nip31Alts
class AltTagSerializer {
companion object {
@JvmStatic
fun toTagArray(altDescriptor: String = "") = arrayOf(ALT_TAG, altDescriptor)
}
}
@@ -0,0 +1,28 @@
/**
* 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.nip31Alts
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
val ALT_TAG = "alt"
fun Event.alt() = tags.firstTagValue(ALT_TAG)
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -73,7 +74,7 @@ class GitIssueEvent(
arrayOf<String>(),
)
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -89,7 +90,7 @@ class GitPatchEvent(
arrayOf<String>(),
)
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -35,7 +35,11 @@ import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip10Notes.positionalMarkedTags
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -85,7 +89,7 @@ class GitReplyEvent(
arrayOf<String>(),
)
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
}
@@ -149,19 +153,17 @@ class GitReplyEvent(
}
tags.addAll(buildHashtagTags(findHashtags(msg)))
tags.addAll(buildUrlRefs(findURLs(msg)))
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
}
emojis?.forEach { tags.add(it.toTagArray()) }
tags.add(arrayOf("alt", "a git issue reply"))
tags.add(AltTagSerializer.toTagArray("a git issue reply"))
if (isDraft) {
signer.assembleRumor(createdAt, KIND, tags.toTypedArray(), msg, onReady)
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -53,7 +54,7 @@ class GitRepositoryEvent(
onReady: (GitRepositoryEvent) -> Unit,
) {
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), "", onReady)
}
}
@@ -34,7 +34,11 @@ import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip10Notes.positionalMarkedTags
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -120,20 +124,18 @@ class TorrentCommentEvent(
tags.addAll(buildHashtagTags(findHashtags(message)))
tags.addAll(buildUrlRefs(findURLs(message)))
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
}
emojis?.forEach { tags.add(it.toTagArray()) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
if (isDraft) {
signer.assembleRumor(createdAt, KIND, tags.toTypedArray(), content, onReady)
@@ -27,6 +27,8 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
import com.vitorpamplona.quartz.nip01Core.core.mapValues
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -96,10 +98,10 @@ class TorrentEvent(
arrayOf("title", title),
arrayOf("btih", btih),
x?.let { arrayOf("x", it) },
alt?.let { arrayOf("alt", it) } ?: arrayOf("alt", ALT_DESCRIPTION),
alt?.let { arrayOf("alt", it) } ?: AltTagSerializer.toTagArray(ALT_DESCRIPTION),
sensitiveContent?.let {
if (it) {
arrayOf("content-warning", "")
ContentWarningSerializer.toTagArray()
} else {
null
}
@@ -0,0 +1,27 @@
/**
* 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.nip36SensitiveContent
class ContentWarningSerializer {
companion object {
fun toTagArray(reason: String = "") = arrayOf(CONTENT_WARNING, reason)
}
}
@@ -22,10 +22,12 @@ package com.vitorpamplona.quartz.nip36SensitiveContent
import com.vitorpamplona.quartz.nip01Core.core.Event
fun Event.isSensitive() = tags.any { (it.size > 0 && it[0] == "content-warning") }
const val CONTENT_WARNING = "content-warning"
fun Event.isSensitive() = tags.any { (it.size > 0 && it[0] == CONTENT_WARNING) }
fun Event.isSensitiveOrNSFW() =
tags.any {
(it.size > 0 && it[0] == "content-warning") ||
(it.size > 0 && it[0] == CONTENT_WARNING) ||
(it.size > 1 && it[0] == "t" && (it[1].equals("nsfw", true) || it[1].equals("nude", true)))
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.Hex
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -37,16 +38,8 @@ class NostrConnectEvent(
tags: Array<Array<String>>,
content: String,
sig: HexKey,
) : Event(
id,
pubKey,
createdAt,
com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.KIND,
tags,
content,
sig,
) {
@Transient private var decryptedContent: Map<HexKey, com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage> = mapOf()
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
@Transient private var decryptedContent: Map<HexKey, BunkerMessage> = mapOf()
override fun countMemory(): Long =
super.countMemory() +
@@ -71,7 +64,7 @@ class NostrConnectEvent(
fun plainContent(
signer: NostrSigner,
onReady: (com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage) -> Unit,
onReady: (BunkerMessage) -> Unit,
) {
decryptedContent[signer.pubKey]?.let {
onReady(it)
@@ -80,7 +73,7 @@ class NostrConnectEvent(
// decrypts using NIP-04 or NIP-44
signer.decrypt(content, talkingWith(signer.pubKey)) { retVal ->
val content = EventMapper.mapper.readValue(retVal, com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage::class.java)
val content = EventMapper.mapper.readValue(retVal, BunkerMessage::class.java)
decryptedContent = decryptedContent + Pair(signer.pubKey, content)
@@ -93,35 +86,22 @@ class NostrConnectEvent(
const val ALT = "Nostr Connect Event"
fun create(
message: com.vitorpamplona.quartz.nip46RemoteSigner.BunkerMessage,
message: BunkerMessage,
remoteKey: HexKey,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent) -> Unit,
onReady: (NostrConnectEvent) -> Unit,
) {
val tags =
arrayOf(
arrayOf("alt", com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.ALT),
AltTagSerializer.toTagArray(ALT),
arrayOf("p", remoteKey),
)
signer.sign(
createdAt,
com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.KIND,
tags,
"",
onReady,
)
val encrypted = EventMapper.mapper.writeValueAsString(message)
signer.nip44Encrypt(encrypted, remoteKey) { content ->
signer.sign(
createdAt,
com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent.Companion.KIND,
tags,
content,
onReady,
)
signer.sign(createdAt, KIND, tags, content, onReady)
}
}
}
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -85,7 +86,7 @@ class LnZapPaymentRequestEvent(
) {
val serializedRequest = EventMapper.mapper.writeValueAsString(PayInvoiceMethod.create(lnInvoice))
val tags = arrayOf(arrayOf("p", walletServicePubkey), arrayOf("alt", ALT))
val tags = arrayOf(arrayOf("p", walletServicePubkey), AltTagSerializer.toTagArray(ALT))
signer.nip04Encrypt(
serializedRequest,
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -60,7 +61,7 @@ class SearchRelayListEvent(
relays
.map {
arrayOf("relay", it)
}.plusElement(arrayOf("alt", "Relay list to use for Search"))
}.plusElement(AltTagSerializer.toTagArray("Relay list to use for Search"))
.toTypedArray()
fun updateRelayList(
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -199,7 +200,7 @@ class BookmarkListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -223,7 +224,7 @@ class BookmarkListEvent(
events?.forEach { tags.add(arrayOf("e", it)) }
users?.forEach { tags.add(arrayOf("p", it)) }
addresses?.forEach { tags.add(arrayOf("a", it.toTag())) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
createPrivateTags(privEvents, privUsers, privAddresses, signer) { content ->
signer.sign(createdAt, KIND, tags.toTypedArray(), content, onReady)
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip51Lists
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -299,7 +300,7 @@ class MuteListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip51Lists
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -350,7 +351,7 @@ class PeopleListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -49,7 +50,7 @@ class PinListEvent(
) {
val tags = mutableListOf<Array<String>>()
pins.forEach { tags.add(arrayOf("pin", it)) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), "", onReady)
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -51,7 +52,7 @@ class RelaySetEvent(
) {
val tags = mutableListOf<Array<String>>()
relays.forEach { tags.add(arrayOf("r", it)) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), "", onReady)
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -54,7 +55,7 @@ class CalendarDateSlotEvent(
createdAt: Long = TimeUtils.now(),
onReady: (CalendarDateSlotEvent) -> Unit,
) {
val tags = arrayOf(arrayOf("alt", ALT))
val tags = arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, "", onReady)
}
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -44,7 +45,7 @@ class CalendarEvent(
createdAt: Long = TimeUtils.now(),
onReady: (CalendarEvent) -> Unit,
) {
val tags = arrayOf(arrayOf("alt", ALT))
val tags = arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, "", onReady)
}
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -56,7 +57,7 @@ class CalendarRSVPEvent(
createdAt: Long = TimeUtils.now(),
onReady: (CalendarRSVPEvent) -> Unit,
) {
val tags = arrayOf(arrayOf("alt", ALT))
val tags = arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, "", onReady)
}
}
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
import com.vitorpamplona.quartz.nip01Core.core.firstTagValueAsLong
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -61,7 +62,7 @@ class CalendarTimeSlotEvent(
createdAt: Long = TimeUtils.now(),
onReady: (CalendarTimeSlotEvent) -> Unit,
) {
val tags = arrayOf(arrayOf("alt", ALT))
val tags = arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, "", onReady)
}
}
@@ -28,7 +28,11 @@ import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashMipMap
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrl
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -88,19 +92,17 @@ class LiveActivitiesChatMessageEvent(
)
replyTos?.forEach { tags.add(arrayOf("e", it)) }
mentions?.forEach { tags.add(arrayOf("p", it)) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
imetas?.forEach {
tags.add(Nip92MediaAttachments.createTag(it))
}
emojis?.forEach { tags.add(it.toTagArray()) }
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
if (isDraft) {
signer.assembleRumor(createdAt, KIND, tags.toTypedArray(), content, onReady)
@@ -25,6 +25,8 @@ import com.vitorpamplona.quartz.experimental.audio.Participant
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip10Notes.PTag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -60,7 +62,7 @@ class LiveActivitiesEvent(
fun host() = tags.firstOrNull { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }?.get(1)
fun hosts() = tags.filter { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }.map { it[1] }
fun hosts() = tags.filter { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }.map { PTag(it[1], it.getOrNull(2)) }
fun checkStatus(eventStatus: String?): String? =
if (eventStatus == STATUS_LIVE && createdAt < TimeUtils.eightHoursAgo()) {
@@ -84,7 +86,7 @@ class LiveActivitiesEvent(
createdAt: Long = TimeUtils.now(),
onReady: (LiveActivitiesEvent) -> Unit,
) {
val tags = arrayOf(arrayOf("alt", ALT))
val tags = arrayOf(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags, "", onReady)
}
}
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -76,7 +77,7 @@ class WikiNoteEvent(
replyTos?.forEach { tags.add(arrayOf("e", it)) }
mentions?.forEach { tags.add(arrayOf("p", it)) }
title?.let { tags.add(arrayOf("title", it)) }
tags.add(arrayOf("alt", "Wiki Post: $title"))
tags.add(AltTagSerializer.toTagArray("Wiki Post: $title"))
signer.sign(createdAt, KIND, tags.toTypedArray(), msg, onReady)
}
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable data class ReportedKey(
@@ -102,7 +103,7 @@ class ReportEvent(
tags += listOf(arrayOf("a", reportedPost.address().toTag()))
}
tags += listOf(arrayOf("alt", "Report for ${type.name}"))
tags += listOf(AltTagSerializer.toTagArray("Report for ${type.name}"))
signer.sign(createdAt, KIND, tags, content, onReady)
}
@@ -117,7 +118,7 @@ class ReportEvent(
val content = ""
val reportAuthorTag = arrayOf("p", reportedUser, type.name.lowercase())
val alt = arrayOf("alt", "Report for ${type.name}")
val alt = AltTagSerializer.toTagArray("Report for ${type.name}")
val tags: Array<Array<String>> = arrayOf(reportAuthorTag, alt)
signer.sign(createdAt, KIND, tags, content, onReady)
@@ -30,6 +30,7 @@ import com.vitorpamplona.quartz.nip01Core.core.mapValues
import com.vitorpamplona.quartz.nip01Core.hexToByteArray
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -114,7 +115,7 @@ class LnZapRequestEvent(
arrayOf("e", originalNote.id),
arrayOf("p", toUserPubHex ?: originalNote.pubKey),
arrayOf("relays") + relays,
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
if (originalNote is AddressableEvent) {
tags = tags + listOf(arrayOf("a", originalNote.address().toTag()))
@@ -0,0 +1,27 @@
/**
* 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.nip57Zaps.splits
sealed interface BaseZapSplitSetup {
val weight: Double
fun mainId(): String
}
@@ -18,30 +18,12 @@
* 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.nip57Zaps
package com.vitorpamplona.quartz.nip57Zaps.splits
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.firstTagValueAsLong
import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent
import com.vitorpamplona.quartz.nip01Core.core.mapTagged
fun Event.hasZapSplitSetup() = tags.hasTagWithContent("zap")
fun Event.zapSplitSetup(): List<ZapSplitSetup> =
tags.mapTagged("zap") {
val isLnAddress = it[0].contains("@") || it[0].startsWith("LNURL", true)
val weight = if (isLnAddress) 1.0 else (it.getOrNull(3)?.toDoubleOrNull() ?: 0.0)
if (weight > 0) {
ZapSplitSetup(
it[1],
it.getOrNull(2),
weight,
isLnAddress,
)
} else {
null
}
}
fun Event.zapraiserAmount() = tags.firstTagValueAsLong("zapraiser")
fun Event.zapSplitSetup(): List<BaseZapSplitSetup> = tags.mapTagged("zap") { ZapSplitSetupParser.parse(it) }
@@ -18,11 +18,14 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.nip57Zaps
package com.vitorpamplona.quartz.nip57Zaps.splits
import com.vitorpamplona.quartz.nip01Core.HexKey
data class ZapSplitSetup(
val lnAddressOrPubKeyHex: String,
val pubKeyHex: HexKey,
val relay: String?,
val weight: Double,
val isLnAddress: Boolean,
)
override val weight: Double,
) : BaseZapSplitSetup {
override fun mainId() = pubKeyHex
}
@@ -0,0 +1,31 @@
/**
* 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.nip57Zaps.splits
/**
* This is an old version on how to do zap splits
*/
data class ZapSplitSetupLnAddress(
val lnAddress: String,
override val weight: Double,
) : BaseZapSplitSetup {
override fun mainId() = lnAddress
}
@@ -0,0 +1,47 @@
/**
* 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.nip57Zaps.splits
class ZapSplitSetupParser {
companion object {
@JvmStatic
fun parse(tags: Array<String>): BaseZapSplitSetup? {
require(tags[0] == "zap")
val isLnAddress = tags[1].contains("@") || tags[1].startsWith("LNURL", true)
val weight = if (isLnAddress) 1.0 else (tags.getOrNull(3)?.toDoubleOrNull() ?: 0.0)
return if (weight > 0) {
if (isLnAddress) {
ZapSplitSetupLnAddress(tags[1], 1.0)
} else {
ZapSplitSetup(
tags[1],
tags.getOrNull(2),
weight,
)
}
} else {
null
}
}
}
}
@@ -0,0 +1,32 @@
/**
* 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.nip57Zaps.splits
class ZapSplitSetupSerializer {
companion object {
@JvmStatic
fun toTagArray(zapSplit: BaseZapSplitSetup): Array<String> =
when (zapSplit) {
is ZapSplitSetupLnAddress -> arrayOf("zap", zapSplit.lnAddress)
is ZapSplitSetup -> arrayOf("zap", zapSplit.pubKeyHex, zapSplit.relay ?: "", zapSplit.weight.toString())
}
}
}
@@ -0,0 +1,26 @@
/**
* 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.nip57Zaps.zapraiser
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.firstTagValueAsLong
fun Event.zapraiserAmount() = tags.firstTagValueAsLong("zapraiser")
@@ -0,0 +1,28 @@
/**
* 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.nip57Zaps.zapraiser
class ZapRaiserSerializer {
companion object {
@JvmStatic
fun toTagArray(zapRaiserAmount: Long): Array<String> = arrayOf("zapraiser", zapRaiserAmount.toString())
}
}
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -127,7 +128,7 @@ class AdvertisedRelayListEvent(
fun createTagArray(relays: List<AdvertisedRelayInfo>): Array<Array<String>> =
relays
.map(Companion::createRelayTag)
.plusElement(arrayOf("alt", ALT))
.plusElement(AltTagSerializer.toTagArray(ALT))
.toTypedArray()
fun create(
@@ -33,7 +33,11 @@ import com.vitorpamplona.quartz.nip10Notes.content.buildUrlRefs
import com.vitorpamplona.quartz.nip10Notes.content.findHashtags
import com.vitorpamplona.quartz.nip10Notes.content.findURLs
import com.vitorpamplona.quartz.nip22Comments.RootScope
import com.vitorpamplona.quartz.nip57Zaps.ZapSplitSetup
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetupSerializer
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.ZapRaiserSerializer
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments.Companion.IMETA
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -159,7 +163,7 @@ class PictureEvent(
createdAt: Long = TimeUtils.now(),
onReady: (PictureEvent) -> Unit,
) {
val tags = mutableListOf(arrayOf<String>("alt", ALT_DESCRIPTION))
val tags = mutableListOf(AltTagSerializer.toTagArray(ALT_DESCRIPTION))
images.forEach {
tags.add(it.toIMetaArray())
@@ -187,14 +191,13 @@ class PictureEvent(
tags.addAll(buildHashtagTags(findHashtags(msg)))
tags.addAll(buildUrlRefs(findURLs(msg)))
}
zapReceiver?.forEach { tags.add(ZapSplitSetupSerializer.toTagArray(it)) }
zapRaiserAmount?.let { tags.add(ZapRaiserSerializer.toTagArray(it)) }
zapReceiver?.forEach {
tags.add(arrayOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString()))
}
if (markAsSensitive) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
zapRaiserAmount?.let { tags.add(arrayOf("zapraiser", "$it")) }
geohash?.let { tags.addAll(geohashMipMap(it)) }
signer.sign(createdAt, KIND, tags.toTypedArray(), msg ?: "", onReady)
@@ -0,0 +1,27 @@
/**
* 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.nip70ProtectedEvts
import com.vitorpamplona.quartz.nip01Core.core.Event
const val PROTECTED_TAG = "-"
fun Event.isProtected() = tags.any { (it.size > 0 && it[0] == PROTECTED_TAG) }
@@ -0,0 +1,27 @@
/**
* 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.nip70ProtectedEvts
class ProtectedTagSerializer {
companion object {
fun toTagArray(reason: String = "") = arrayOf("-", reason)
}
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip22Comments.RootScope
import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningSerializer
import com.vitorpamplona.quartz.nip92IMeta.Nip92MediaAttachments.Companion.IMETA
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
@@ -150,7 +151,7 @@ abstract class VideoEvent(
tags.add(arrayOf("d", dTag))
tags.add(arrayOf(ALT, altDescription))
if (sensitiveContent == true) {
tags.add(arrayOf("content-warning", ""))
tags.add(ContentWarningSerializer.toTagArray())
}
duration?.let { tags.add(arrayOf(DURATION, "duration")) }
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.experimental.audio.Participant
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -54,7 +55,7 @@ class CommunityDefinitionEvent(
onReady: (CommunityDefinitionEvent) -> Unit,
) {
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
signer.sign(createdAt, KIND, tags.toTypedArray(), "", onReady)
}
}
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip19Bech32.parseAtag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
@@ -269,7 +270,7 @@ class CommunityListEvent(
if (tags.any { it.size > 1 && it[0] == "alt" }) {
tags
} else {
tags + arrayOf("alt", ALT)
tags + AltTagSerializer.toTagArray(ALT)
}
signer.sign(createdAt, KIND, newTags, content, onReady)
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -89,7 +90,7 @@ class CommunityPostApprovalEvent(
val replyToPost = arrayOf("e", approvedPost.id)
val replyToAuthor = arrayOf("p", approvedPost.pubKey)
val innerKind = arrayOf("k", "${approvedPost.kind}")
val alt = arrayOf("alt", ALT)
val alt = AltTagSerializer.toTagArray(ALT)
val tags: Array<Array<String>> =
arrayOf(communities, replyToPost, replyToAuthor, innerKind, alt)
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -63,7 +64,7 @@ class GoalEvent(
mutableListOf(
arrayOf(AMOUNT, amount.toString()),
arrayOf("relays") + relays,
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
if (linkedEvent is AddressableEvent) {
@@ -24,6 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
class AppSpecificDataEvent(
@@ -60,7 +61,7 @@ class AppSpecificDataEvent(
val newTags =
if (withD.none { it.size > 0 && it[0] == "alt" }) {
withD + arrayOf("alt", ALT)
withD + AltTagSerializer.toTagArray(ALT)
} else {
withD
}
@@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.tags.addressables.firstTaggedAddress
import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent
import com.vitorpamplona.quartz.nip01Core.tags.people.firstTaggedUser
import com.vitorpamplona.quartz.nip10Notes.BaseTextNoteEvent
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -62,7 +63,7 @@ class HighlightEvent(
createdAt: Long = TimeUtils.now(),
onReady: (HighlightEvent) -> Unit,
) {
signer.sign(createdAt, KIND, arrayOf(arrayOf("alt", ALT)), msg, onReady)
signer.sign(createdAt, KIND, arrayOf(AltTagSerializer.toTagArray(ALT)), msg, onReady)
}
}
}
@@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
import java.io.ByteArrayInputStream
@@ -85,7 +86,7 @@ class AppDefinitionEvent(
) {
val tags =
arrayOf(
arrayOf("alt", "App definition event for ${details.name}"),
AltTagSerializer.toTagArray("App definition event for ${details.name}"),
)
signer.sign(createdAt, KIND, tags, "", onReady)
}
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
import com.vitorpamplona.quartz.nip19Bech32.parse
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
@@ -50,7 +51,7 @@ class AppRecommendationEvent(
) {
val tags =
arrayOf(
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
signer.sign(createdAt, KIND, tags, "", onReady)
}
@@ -25,6 +25,7 @@ import androidx.compose.runtime.Stable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.utils.TimeUtils
@Stable
@@ -52,7 +53,7 @@ class NIP90ContentDiscoveryRequestEvent(
val content = ""
val tags = mutableListOf<Array<String>>()
tags.add(arrayOf("p", dvmPublicKey))
tags.add(arrayOf("alt", ALT))
tags.add(AltTagSerializer.toTagArray(ALT))
tags.add(arrayOf("relays") + relays.toTypedArray())
tags.add(arrayOf("param", "max_results", "200"))
tags.add(arrayOf("param", "user", forUser))
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
@@ -83,7 +84,7 @@ class NIP90ContentDiscoveryResponseEvent(
) {
val tags =
arrayOf(
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
signer.sign(createdAt, KIND, tags, "", onReady)
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -84,7 +85,7 @@ class NIP90StatusEvent(
) {
val tags =
arrayOf(
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
signer.sign(createdAt, KIND, tags, "", onReady)
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -47,7 +48,7 @@ class NIP90UserDiscoveryRequestEvent(
) {
val tags =
arrayOf(
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
signer.sign(createdAt, KIND, tags, "", onReady)
}
@@ -24,6 +24,7 @@ import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip31Alts.AltTagSerializer
import com.vitorpamplona.quartz.nip89AppHandlers.AppRecommendationEvent
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -47,7 +48,7 @@ class NIP90UserDiscoveryResponseEvent(
) {
val tags =
arrayOf(
arrayOf("alt", ALT),
AltTagSerializer.toTagArray(ALT),
)
signer.sign(createdAt, KIND, tags, "", onReady)
}
@@ -21,6 +21,7 @@
package com.vitorpamplona.quartz.nip92IMeta
import com.vitorpamplona.quartz.nip01Core.HexKey
import com.vitorpamplona.quartz.nip36SensitiveContent.CONTENT_WARNING
import com.vitorpamplona.quartz.nip94FileMetadata.Dimension
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.ALT
import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent.Companion.BLUR_HASH
@@ -63,7 +64,7 @@ class IMetaTagBuilder(
fun torrent(uri: String) = add(TORRENT_INFOHASH, uri)
fun sensitiveContent(reason: String) = add("content-warning", reason)
fun sensitiveContent(reason: String) = add(CONTENT_WARNING, reason)
fun build() = IMetaTag(url, properties)
}

Some files were not shown because too many files have changed in this diff Show More