Migrating Lint to 1.3.1
This commit is contained in:
@@ -54,7 +54,5 @@ class KeyPair(
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "KeyPair(privateKey=${privKey?.toHexKey()}, publicKey=${pubKey.toHexKey()}"
|
||||
}
|
||||
override fun toString(): String = "KeyPair(privateKey=${privKey?.toHexKey()}, publicKey=${pubKey.toHexKey()}"
|
||||
}
|
||||
|
||||
@@ -42,9 +42,7 @@ class SharedKeyCache {
|
||||
fun get(
|
||||
privateKey: ByteArray,
|
||||
pubKey: ByteArray,
|
||||
): ByteArray? {
|
||||
return sharedKeyCache[combinedHashCode(privateKey, pubKey)]
|
||||
}
|
||||
): ByteArray? = sharedKeyCache[combinedHashCode(privateKey, pubKey)]
|
||||
|
||||
fun add(
|
||||
privateKey: ByteArray,
|
||||
|
||||
@@ -20,24 +20,20 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.crypto.nip06
|
||||
|
||||
class KeyPath(val path: List<Long>) {
|
||||
class KeyPath(
|
||||
val path: List<Long>,
|
||||
) {
|
||||
constructor(path: String) : this(computePath(path))
|
||||
|
||||
val lastChildNumber: Long get() = if (path.isEmpty()) 0L else path.last()
|
||||
|
||||
fun derive(number: Long): KeyPath = KeyPath(path + listOf(number))
|
||||
|
||||
fun append(index: Long): KeyPath {
|
||||
return KeyPath(path + listOf(index))
|
||||
}
|
||||
fun append(index: Long): KeyPath = KeyPath(path + listOf(index))
|
||||
|
||||
fun append(indexes: List<Long>): KeyPath {
|
||||
return KeyPath(path + indexes)
|
||||
}
|
||||
fun append(indexes: List<Long>): KeyPath = KeyPath(path + indexes)
|
||||
|
||||
fun append(that: KeyPath): KeyPath {
|
||||
return KeyPath(path + that.path)
|
||||
}
|
||||
fun append(that: KeyPath): KeyPath = KeyPath(path + that.path)
|
||||
|
||||
override fun toString(): String = asString('\'')
|
||||
|
||||
|
||||
@@ -24,20 +24,23 @@ import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val relay: String?) {
|
||||
data class ATag(
|
||||
val kind: Int,
|
||||
val pubKeyHex: String,
|
||||
val dTag: String,
|
||||
val relay: String?,
|
||||
) {
|
||||
fun toTag() = assembleATag(kind, pubKeyHex, dTag)
|
||||
|
||||
fun toNAddr(): String {
|
||||
return TlvBuilder()
|
||||
fun toNAddr(): String =
|
||||
TlvBuilder()
|
||||
.apply {
|
||||
addString(Nip19Bech32.TlvTypes.SPECIAL, dTag)
|
||||
addStringIfNotNull(Nip19Bech32.TlvTypes.RELAY, relay)
|
||||
addHex(Nip19Bech32.TlvTypes.AUTHOR, pubKeyHex)
|
||||
addInt(Nip19Bech32.TlvTypes.KIND, kind)
|
||||
}
|
||||
.build()
|
||||
}.build()
|
||||
.toNAddress()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun assembleATag(
|
||||
@@ -46,26 +49,23 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela
|
||||
dTag: String,
|
||||
) = "$kind:$pubKeyHex:$dTag"
|
||||
|
||||
fun isATag(key: String): Boolean {
|
||||
return key.startsWith("naddr1") || key.contains(":")
|
||||
}
|
||||
fun isATag(key: String): Boolean = key.startsWith("naddr1") || key.contains(":")
|
||||
|
||||
fun parse(
|
||||
address: String,
|
||||
relay: String?,
|
||||
): ATag? {
|
||||
return if (address.startsWith("naddr") || address.startsWith("nostr:naddr")) {
|
||||
): ATag? =
|
||||
if (address.startsWith("naddr") || address.startsWith("nostr:naddr")) {
|
||||
parseNAddr(address)
|
||||
} else {
|
||||
parseAtag(address, relay)
|
||||
}
|
||||
}
|
||||
|
||||
fun parseAtag(
|
||||
atag: String,
|
||||
relay: String?,
|
||||
): ATag? {
|
||||
return try {
|
||||
): ATag? =
|
||||
try {
|
||||
val parts = atag.split(":")
|
||||
Hex.decode(parts[1])
|
||||
ATag(parts[0].toInt(), parts[1], parts[2], relay)
|
||||
@@ -73,16 +73,14 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela
|
||||
Log.w("ATag", "Error parsing A Tag: $atag: ${t.message}")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun parseAtagUnckecked(atag: String): ATag? {
|
||||
return try {
|
||||
fun parseAtagUnckecked(atag: String): ATag? =
|
||||
try {
|
||||
val parts = atag.split(":")
|
||||
ATag(parts[0].toInt(), parts[1], parts[2], null)
|
||||
} catch (t: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun parseNAddr(naddr: String): ATag? {
|
||||
try {
|
||||
|
||||
@@ -51,7 +51,9 @@ object Bech32 {
|
||||
const val ALPHABET: String = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
|
||||
const val ALPHABET_UPPERCASE: String = "QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L"
|
||||
|
||||
enum class Encoding(val constant: Int) {
|
||||
enum class Encoding(
|
||||
val constant: Int,
|
||||
) {
|
||||
Bech32(1),
|
||||
Bech32m(0x2bc830a3),
|
||||
Beck32WithoutChecksum(0),
|
||||
|
||||
@@ -23,23 +23,18 @@ package com.vitorpamplona.quartz.encoders
|
||||
/** Makes the distinction between String and Hex * */
|
||||
typealias HexKey = String
|
||||
|
||||
fun ByteArray.toHexKey(): HexKey {
|
||||
return Hex.encode(this)
|
||||
}
|
||||
fun ByteArray.toHexKey(): HexKey = Hex.encode(this)
|
||||
|
||||
fun HexKey.hexToByteArray(): ByteArray {
|
||||
return Hex.decode(this)
|
||||
}
|
||||
fun HexKey.hexToByteArray(): ByteArray = Hex.decode(this)
|
||||
|
||||
object HexValidator {
|
||||
private fun isHexChar(c: Char): Boolean {
|
||||
return when (c) {
|
||||
private fun isHexChar(c: Char): Boolean =
|
||||
when (c) {
|
||||
in '0'..'9' -> true
|
||||
in 'a'..'f' -> true
|
||||
in 'A'..'F' -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun isHex(hex: String?): Boolean {
|
||||
if (hex == null) return false
|
||||
|
||||
@@ -205,7 +205,9 @@ object LnInvoiceUtil {
|
||||
return polymod(combined) == 1
|
||||
}
|
||||
|
||||
class AddressFormatException(message: String) : Exception(message)
|
||||
class AddressFormatException(
|
||||
message: String,
|
||||
) : Exception(message)
|
||||
|
||||
fun decodeUnlimitedLength(invoice: String): Boolean {
|
||||
var lower = false
|
||||
@@ -278,19 +280,16 @@ object LnInvoiceUtil {
|
||||
val OneNano = BigDecimal("0.000000001")
|
||||
val OnePico = BigDecimal("0.000000000001")
|
||||
|
||||
fun getAmountInSats(invoice: String): BigDecimal {
|
||||
return getAmount(invoice).multiply(OneHundredK)
|
||||
}
|
||||
fun getAmountInSats(invoice: String): BigDecimal = getAmount(invoice).multiply(OneHundredK)
|
||||
|
||||
private fun multiplier(multiplier: String): BigDecimal {
|
||||
return when (multiplier.lowercase()) {
|
||||
private fun multiplier(multiplier: String): BigDecimal =
|
||||
when (multiplier.lowercase()) {
|
||||
"m" -> OneMili
|
||||
"u" -> OneMicro
|
||||
"n" -> OneNano
|
||||
"p" -> OnePico
|
||||
else -> throw IllegalArgumentException("Invalid multiplier: $multiplier")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds LN invoice in the provided input string and returns it. For example for input = "aaa bbb
|
||||
|
||||
@@ -48,13 +48,12 @@ class Lud06 {
|
||||
}
|
||||
}
|
||||
|
||||
fun toLnUrlp(str: String): String? {
|
||||
return try {
|
||||
fun toLnUrlp(str: String): String? =
|
||||
try {
|
||||
String(Bech32.decodeBytes(str, false).second)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
Log.w("Lud06ToLud16", "Fail to convert LUD06 to LUD16", t)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,9 +47,12 @@ class Nip01Serializer {
|
||||
fun dump()
|
||||
}
|
||||
|
||||
class BufferedDigestWriter(val digest: MessageDigest) : Writer {
|
||||
class BufferedDigestWriter(
|
||||
val digest: MessageDigest,
|
||||
) : Writer {
|
||||
val utf8Encoder =
|
||||
Charsets.UTF_8.newEncoder()
|
||||
Charsets.UTF_8
|
||||
.newEncoder()
|
||||
.onMalformedInput(CodingErrorAction.IGNORE)
|
||||
.onUnmappableCharacter(CodingErrorAction.IGNORE)
|
||||
|
||||
@@ -151,9 +154,7 @@ class Nip01Serializer {
|
||||
stringBuilder.append(value.toInt().toChar())
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
override fun toString(): String = stringBuilder.toString()
|
||||
|
||||
override fun dump() {
|
||||
}
|
||||
|
||||
@@ -48,9 +48,7 @@ class Nip30CustomEmoji {
|
||||
return input.contains(":")
|
||||
}
|
||||
|
||||
fun createEmojiMap(tags: ImmutableListOfLists<String>): Map<String, String> {
|
||||
return tags.lists.filter { it.size > 2 && it[0] == "emoji" }.associate { ":${it[1]}:" to it[2] }
|
||||
}
|
||||
fun createEmojiMap(tags: ImmutableListOfLists<String>): Map<String, String> = tags.lists.filter { it.size > 2 && it[0] == "emoji" }.associate { ":${it[1]}:" to it[2] }
|
||||
|
||||
fun assembleAnnotatedList(
|
||||
input: String,
|
||||
@@ -105,9 +103,13 @@ class Nip30CustomEmoji {
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable open class Renderable()
|
||||
@Immutable open class Renderable
|
||||
|
||||
@Immutable class TextType(val text: String) : Renderable()
|
||||
@Immutable class TextType(
|
||||
val text: String,
|
||||
) : Renderable()
|
||||
|
||||
@Immutable class ImageUrlType(val url: String) : Renderable()
|
||||
@Immutable class ImageUrlType(
|
||||
val url: String,
|
||||
) : Renderable()
|
||||
}
|
||||
|
||||
@@ -52,5 +52,9 @@ class Nip47WalletConnect {
|
||||
}
|
||||
}
|
||||
|
||||
data class Nip47URI(val pubKeyHex: HexKey, val relayUri: String?, val secret: HexKey?)
|
||||
data class Nip47URI(
|
||||
val pubKeyHex: HexKey,
|
||||
val relayUri: String?,
|
||||
val secret: HexKey?,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,17 +40,18 @@ class Nip54InlineMetadata {
|
||||
tags: Array<Array<String>>,
|
||||
): String {
|
||||
val extension =
|
||||
tags.mapNotNull {
|
||||
if (it.isNotEmpty() && it[0] != "url") {
|
||||
if (it.size > 1) {
|
||||
"${it[0]}=${URLEncoder.encode(it[1], "utf-8")}"
|
||||
tags
|
||||
.mapNotNull {
|
||||
if (it.isNotEmpty() && it[0] != "url") {
|
||||
if (it.size > 1) {
|
||||
"${it[0]}=${URLEncoder.encode(it[1], "utf-8")}"
|
||||
} else {
|
||||
"${it[0]}}="
|
||||
}
|
||||
} else {
|
||||
"${it[0]}}="
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.joinToString("&")
|
||||
}.joinToString("&")
|
||||
|
||||
return if (imageUrl.contains("#")) {
|
||||
"$imageUrl&$extension"
|
||||
@@ -59,14 +60,13 @@ class Nip54InlineMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
fun parse(url: String): Map<String, String> {
|
||||
return try {
|
||||
fun parse(url: String): Map<String, String> =
|
||||
try {
|
||||
fragments(URI(url))
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
private fun fragments(uri: URI): Map<String, String> {
|
||||
if (uri.rawFragment == null) return emptyMap()
|
||||
|
||||
@@ -38,8 +38,8 @@ class Nip92MediaAttachments {
|
||||
fun createTag(
|
||||
imageUrl: String,
|
||||
tags: Array<Array<String>>,
|
||||
): Array<String> {
|
||||
return arrayOf(
|
||||
): Array<String> =
|
||||
arrayOf(
|
||||
IMETA,
|
||||
"url $imageUrl",
|
||||
) +
|
||||
@@ -54,23 +54,22 @@ class Nip92MediaAttachments {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun parse(
|
||||
imageUrl: String,
|
||||
tags: Array<Array<String>>,
|
||||
): Map<String, String> {
|
||||
return tags.firstOrNull {
|
||||
it.size > 1 && it[0] == IMETA && it[1] == "url $imageUrl"
|
||||
}?.let { tagList ->
|
||||
tagList.associate { tag ->
|
||||
val parts = tag.split(" ", limit = 2)
|
||||
when (parts.size) {
|
||||
2 -> parts[0] to parts[1]
|
||||
1 -> parts[0] to ""
|
||||
else -> "" to ""
|
||||
): Map<String, String> =
|
||||
tags
|
||||
.firstOrNull {
|
||||
it.size > 1 && it[0] == IMETA && it[1] == "url $imageUrl"
|
||||
}?.let { tagList ->
|
||||
tagList.associate { tag ->
|
||||
val parts = tag.split(" ", limit = 2)
|
||||
when (parts.size) {
|
||||
2 -> parts[0] to parts[1]
|
||||
1 -> parts[0] to ""
|
||||
else -> "" to ""
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: emptyMap()
|
||||
}
|
||||
} ?: emptyMap()
|
||||
}
|
||||
|
||||
@@ -24,9 +24,12 @@ import org.czeal.rfc3986.URIReference
|
||||
|
||||
class RelayUrlFormatter {
|
||||
companion object {
|
||||
fun displayUrl(url: String): String {
|
||||
return url.trim().removePrefix("wss://").removePrefix("ws://").removeSuffix("/")
|
||||
}
|
||||
fun displayUrl(url: String): String =
|
||||
url
|
||||
.trim()
|
||||
.removePrefix("wss://")
|
||||
.removePrefix("ws://")
|
||||
.removeSuffix("/")
|
||||
|
||||
fun normalize(url: String): String {
|
||||
val newUrl =
|
||||
@@ -49,12 +52,11 @@ class RelayUrlFormatter {
|
||||
}
|
||||
}
|
||||
|
||||
fun getHttpsUrl(dirtyUrl: String): String {
|
||||
return if (dirtyUrl.contains("://")) {
|
||||
fun getHttpsUrl(dirtyUrl: String): String =
|
||||
if (dirtyUrl.contains("://")) {
|
||||
dirtyUrl.replace("wss://", "https://").replace("ws://", "http://")
|
||||
} else {
|
||||
"https://$dirtyUrl"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
|
||||
class TlvBuilder() {
|
||||
class TlvBuilder {
|
||||
val outputStream = ByteArrayOutputStream()
|
||||
|
||||
private fun add(
|
||||
@@ -65,9 +65,7 @@ class TlvBuilder() {
|
||||
data: Int?,
|
||||
) = data?.let { addInt(type, it) }
|
||||
|
||||
fun build(): ByteArray {
|
||||
return outputStream.toByteArray()
|
||||
}
|
||||
fun build(): ByteArray = outputStream.toByteArray()
|
||||
}
|
||||
|
||||
fun Int.to32BitByteArray(): ByteArray {
|
||||
@@ -81,7 +79,9 @@ fun ByteArray.toInt32(): Int? {
|
||||
return ByteBuffer.wrap(this, 0, 4).order(ByteOrder.BIG_ENDIAN).int
|
||||
}
|
||||
|
||||
class Tlv(val data: Map<Byte, List<ByteArray>>) {
|
||||
class Tlv(
|
||||
val data: Map<Byte, List<ByteArray>>,
|
||||
) {
|
||||
fun asInt(type: Byte) = data[type]?.mapNotNull { it.toInt32() }
|
||||
|
||||
fun asHex(type: Byte) = data[type]?.map { it.toHexKey().intern() }
|
||||
|
||||
@@ -37,8 +37,8 @@ class AdvertisedRelayListEvent(
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
fun relays(): List<AdvertisedRelayInfo> {
|
||||
return tags.mapNotNull {
|
||||
fun relays(): List<AdvertisedRelayInfo> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "r") {
|
||||
val type =
|
||||
when (it.getOrNull(2)) {
|
||||
@@ -52,24 +52,23 @@ class AdvertisedRelayListEvent(
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun readRelays(): List<String>? {
|
||||
return tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "r") {
|
||||
when (it.getOrNull(2)) {
|
||||
"read" -> it[1]
|
||||
"write" -> null
|
||||
else -> it[1]
|
||||
fun readRelays(): List<String>? =
|
||||
tags
|
||||
.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "r") {
|
||||
when (it.getOrNull(2)) {
|
||||
"read" -> it[1]
|
||||
"write" -> null
|
||||
else -> it[1]
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.ifEmpty { null }
|
||||
}
|
||||
}.ifEmpty { null }
|
||||
|
||||
fun writeRelays(): List<String> {
|
||||
return tags.mapNotNull {
|
||||
fun writeRelays(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "r") {
|
||||
when (it.getOrNull(2)) {
|
||||
"read" -> null
|
||||
@@ -80,20 +79,15 @@ class AdvertisedRelayListEvent(
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KIND = 10002
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Relay list to discover the user's content"
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag {
|
||||
return ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
}
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String {
|
||||
return ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
}
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun updateRelayList(
|
||||
earlierVersion: AdvertisedRelayListEvent,
|
||||
@@ -103,9 +97,11 @@ class AdvertisedRelayListEvent(
|
||||
onReady: (AdvertisedRelayListEvent) -> Unit,
|
||||
) {
|
||||
val tags =
|
||||
earlierVersion.tags.filter { it[0] != "r" }.plus(
|
||||
relays.map(::createRelayTag),
|
||||
).toTypedArray()
|
||||
earlierVersion.tags
|
||||
.filter { it[0] != "r" }
|
||||
.plus(
|
||||
relays.map(::createRelayTag),
|
||||
).toTypedArray()
|
||||
|
||||
signer.sign(createdAt, KIND, tags, earlierVersion.content, onReady)
|
||||
}
|
||||
@@ -119,20 +115,18 @@ class AdvertisedRelayListEvent(
|
||||
create(relays, signer, createdAt, onReady)
|
||||
}
|
||||
|
||||
fun createRelayTag(relay: AdvertisedRelayInfo): Array<String> {
|
||||
return if (relay.type == AdvertisedRelayType.BOTH) {
|
||||
fun createRelayTag(relay: AdvertisedRelayInfo): Array<String> =
|
||||
if (relay.type == AdvertisedRelayType.BOTH) {
|
||||
arrayOf("r", relay.relayUrl)
|
||||
} else {
|
||||
arrayOf("r", relay.relayUrl, relay.type.code)
|
||||
}
|
||||
}
|
||||
|
||||
fun createTagArray(relays: List<AdvertisedRelayInfo>): Array<Array<String>> {
|
||||
return relays
|
||||
fun createTagArray(relays: List<AdvertisedRelayInfo>): Array<Array<String>> =
|
||||
relays
|
||||
.map(::createRelayTag)
|
||||
.plusElement(arrayOf("alt", ALT))
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
fun create(
|
||||
list: List<AdvertisedRelayInfo>,
|
||||
@@ -147,10 +141,15 @@ class AdvertisedRelayListEvent(
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable data class AdvertisedRelayInfo(val relayUrl: String, val type: AdvertisedRelayType)
|
||||
@Immutable data class AdvertisedRelayInfo(
|
||||
val relayUrl: String,
|
||||
val type: AdvertisedRelayType,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
enum class AdvertisedRelayType(val code: String) {
|
||||
enum class AdvertisedRelayType(
|
||||
val code: String,
|
||||
) {
|
||||
BOTH(""),
|
||||
READ("read"),
|
||||
WRITE("write"),
|
||||
|
||||
@@ -58,31 +58,20 @@ class AppMetadata {
|
||||
@Transient
|
||||
var tags: ImmutableListOfLists<String>? = null
|
||||
|
||||
fun anyName(): String? {
|
||||
return displayName ?: name ?: username
|
||||
}
|
||||
fun anyName(): String? = displayName ?: name ?: username
|
||||
|
||||
fun anyNameStartsWith(prefix: String): Boolean {
|
||||
return listOfNotNull(name, username, displayName, nip05, lud06, lud16).any {
|
||||
fun anyNameStartsWith(prefix: String): Boolean =
|
||||
listOfNotNull(name, username, displayName, nip05, lud06, lud16).any {
|
||||
it.contains(prefix, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun lnAddress(): String? {
|
||||
return lud16 ?: lud06
|
||||
}
|
||||
fun lnAddress(): String? = lud16 ?: lud06
|
||||
|
||||
fun bestName(): String? {
|
||||
return displayName ?: name ?: username
|
||||
}
|
||||
fun bestName(): String? = displayName ?: name ?: username
|
||||
|
||||
fun nip05(): String? {
|
||||
return nip05
|
||||
}
|
||||
fun nip05(): String? = nip05
|
||||
|
||||
fun profilePicture(): String? {
|
||||
return picture
|
||||
}
|
||||
fun profilePicture(): String? = picture
|
||||
|
||||
fun cleanBlankNames() {
|
||||
if (picture?.isNotEmpty() == true) picture = picture?.trim()
|
||||
|
||||
@@ -76,8 +76,7 @@ class AudioHeaderEvent(
|
||||
}
|
||||
},
|
||||
arrayOf("alt", ALT),
|
||||
)
|
||||
.toTypedArray()
|
||||
).toTypedArray()
|
||||
|
||||
signer.sign(createdAt, KIND, tags, description, onReady)
|
||||
}
|
||||
|
||||
@@ -73,12 +73,14 @@ class AudioTrackEvent(
|
||||
cover?.let { arrayOf(COVER, it) },
|
||||
subject?.let { arrayOf(SUBJECT, it) },
|
||||
arrayOf("alt", ALT),
|
||||
)
|
||||
.toTypedArray()
|
||||
).toTypedArray()
|
||||
|
||||
signer.sign(createdAt, KIND, tags, "", onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable data class Participant(val key: String, val role: String?)
|
||||
@Immutable data class Participant(
|
||||
val key: String,
|
||||
val role: String?,
|
||||
)
|
||||
|
||||
@@ -42,8 +42,6 @@ class BadgeProfilesEvent(
|
||||
private const val STANDARD_D_TAG = "profile_badges"
|
||||
private const val ALT = "List of accepted badges by the author"
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): ATag {
|
||||
return ATag(KIND, pubKey, STANDARD_D_TAG, null)
|
||||
}
|
||||
fun createAddressTag(pubKey: HexKey): ATag = ATag(KIND, pubKey, STANDARD_D_TAG, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,10 +192,11 @@ open class BaseTextNoteEvent(
|
||||
fun tagsWithoutCitations(): List<String> {
|
||||
val repliesTo = replyTos()
|
||||
val tagAddresses =
|
||||
taggedAddresses().filter {
|
||||
it.kind != CommunityDefinitionEvent.KIND && (kind != WikiNoteEvent.KIND || it.kind != WikiNoteEvent.KIND)
|
||||
// removes forks from itself.
|
||||
}.map { it.toTag() }
|
||||
taggedAddresses()
|
||||
.filter {
|
||||
it.kind != CommunityDefinitionEvent.KIND && (kind != WikiNoteEvent.KIND || it.kind != WikiNoteEvent.KIND)
|
||||
// removes forks from itself.
|
||||
}.map { it.toTag() }
|
||||
if (repliesTo.isEmpty() && tagAddresses.isEmpty()) return emptyList()
|
||||
|
||||
val citations = findCitations()
|
||||
|
||||
@@ -54,18 +54,16 @@ class ChannelCreateEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (ChannelCreateEvent) -> Unit,
|
||||
) {
|
||||
return create(
|
||||
ChannelData(
|
||||
name,
|
||||
about,
|
||||
picture,
|
||||
),
|
||||
signer,
|
||||
createdAt,
|
||||
onReady,
|
||||
)
|
||||
}
|
||||
) = create(
|
||||
ChannelData(
|
||||
name,
|
||||
about,
|
||||
picture,
|
||||
),
|
||||
signer,
|
||||
createdAt,
|
||||
onReady,
|
||||
)
|
||||
|
||||
fun create(
|
||||
channelInfo: ChannelData?,
|
||||
@@ -94,5 +92,9 @@ class ChannelCreateEvent(
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable data class ChannelData(val name: String?, val about: String?, val picture: String?)
|
||||
@Immutable data class ChannelData(
|
||||
val name: String?,
|
||||
val about: String?,
|
||||
val picture: String?,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ class ChannelHideMessageEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig), IsInPublicChatChannel {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
IsInPublicChatChannel {
|
||||
override fun channel() =
|
||||
tags.firstOrNull { it.size > 3 && it[0] == "e" && it[3] == "root" }?.get(1)
|
||||
?: tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
@@ -62,9 +62,7 @@ class ChannelListEvent(
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Public Chat List"
|
||||
|
||||
fun blockListFor(pubKeyHex: HexKey): String {
|
||||
return "$KIND:$pubKeyHex:"
|
||||
}
|
||||
fun blockListFor(pubKeyHex: HexKey): String = "$KIND:$pubKeyHex:"
|
||||
|
||||
fun createListWithTag(
|
||||
key: String,
|
||||
@@ -101,9 +99,7 @@ class ChannelListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (ChannelListEvent) -> Unit,
|
||||
) {
|
||||
return createListWithTag("e", eventId, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = createListWithTag("e", eventId, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addEvents(
|
||||
earlierVersion: ChannelListEvent,
|
||||
@@ -152,9 +148,7 @@ class ChannelListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (ChannelListEvent) -> Unit,
|
||||
) {
|
||||
return addTag(earlierVersion, "e", event, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = addTag(earlierVersion, "e", event, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addTag(
|
||||
earlierVersion: ChannelListEvent,
|
||||
@@ -202,9 +196,7 @@ class ChannelListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (ChannelListEvent) -> Unit,
|
||||
) {
|
||||
return removeTag(earlierVersion, "e", event, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = removeTag(earlierVersion, "e", event, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun removeTag(
|
||||
earlierVersion: ChannelListEvent,
|
||||
|
||||
@@ -34,7 +34,8 @@ class ChannelMessageEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig), IsInPublicChatChannel {
|
||||
) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
IsInPublicChatChannel {
|
||||
override fun channel() =
|
||||
tags.firstOrNull { it.size > 3 && it[0] == "e" && it[3] == "root" }?.get(1)
|
||||
?: tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
@@ -34,7 +34,8 @@ class ChannelMetadataEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig), IsInPublicChatChannel {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
IsInPublicChatChannel {
|
||||
override fun channel() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
fun channelInfo() =
|
||||
|
||||
@@ -33,7 +33,8 @@ class ChannelMuteUserEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig), IsInPublicChatChannel {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
IsInPublicChatChannel {
|
||||
override fun channel() =
|
||||
tags.firstOrNull { it.size > 3 && it[0] == "e" && it[3] == "root" }?.get(1)
|
||||
?: tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
@@ -37,33 +37,29 @@ class ChatMessageRelayListEvent(
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
fun relays(): List<String> {
|
||||
return tags.mapNotNull {
|
||||
fun relays(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "relay") {
|
||||
it[1]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KIND = 10050
|
||||
const val FIXED_D_TAG = ""
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag {
|
||||
return ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
}
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String {
|
||||
return ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
}
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun createTagArray(relays: List<String>): Array<Array<String>> {
|
||||
return relays.map {
|
||||
arrayOf("relay", it)
|
||||
}.plusElement(arrayOf("alt", "Relay list to receive private messages")).toTypedArray()
|
||||
}
|
||||
fun createTagArray(relays: List<String>): Array<Array<String>> =
|
||||
relays
|
||||
.map {
|
||||
arrayOf("relay", it)
|
||||
}.plusElement(arrayOf("alt", "Relay list to receive private messages"))
|
||||
.toTypedArray()
|
||||
|
||||
fun updateRelayList(
|
||||
earlierVersion: ChatMessageRelayListEvent,
|
||||
@@ -73,11 +69,13 @@ class ChatMessageRelayListEvent(
|
||||
onReady: (ChatMessageRelayListEvent) -> Unit,
|
||||
) {
|
||||
val tags =
|
||||
earlierVersion.tags.filter { it[0] != "relay" }.plus(
|
||||
relays.map {
|
||||
arrayOf("relay", it)
|
||||
},
|
||||
).toTypedArray()
|
||||
earlierVersion.tags
|
||||
.filter { it[0] != "relay" }
|
||||
.plus(
|
||||
relays.map {
|
||||
arrayOf("relay", it)
|
||||
},
|
||||
).toTypedArray()
|
||||
|
||||
signer.sign(createdAt, KIND, tags, earlierVersion.content, onReady)
|
||||
}
|
||||
|
||||
@@ -79,7 +79,9 @@ class ClassifiedsEvent(
|
||||
null
|
||||
}
|
||||
|
||||
enum class CONDITION(val value: String) {
|
||||
enum class CONDITION(
|
||||
val value: String,
|
||||
) {
|
||||
NEW("new"),
|
||||
USED_LIKE_NEW("like new"),
|
||||
USED_GOOD("good"),
|
||||
@@ -202,4 +204,8 @@ class ClassifiedsEvent(
|
||||
}
|
||||
}
|
||||
|
||||
data class Price(val amount: String, val currency: String?, val frequency: String?)
|
||||
data class Price(
|
||||
val amount: String,
|
||||
val currency: String?,
|
||||
val frequency: String?,
|
||||
)
|
||||
|
||||
@@ -67,9 +67,7 @@ class CommunityListEvent(
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Community List"
|
||||
|
||||
fun blockListFor(pubKeyHex: HexKey): String {
|
||||
return "$KIND:$pubKeyHex:"
|
||||
}
|
||||
fun blockListFor(pubKeyHex: HexKey): String = "$KIND:$pubKeyHex:"
|
||||
|
||||
fun createListWithTag(
|
||||
key: String,
|
||||
@@ -106,9 +104,7 @@ class CommunityListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (CommunityListEvent) -> Unit,
|
||||
) {
|
||||
return createListWithTag("a", address.toTag(), isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = createListWithTag("a", address.toTag(), isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addEvents(
|
||||
earlierVersion: CommunityListEvent,
|
||||
@@ -157,9 +153,7 @@ class CommunityListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (CommunityListEvent) -> Unit,
|
||||
) {
|
||||
return addTag(earlierVersion, "a", address.toTag(), isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = addTag(earlierVersion, "a", address.toTag(), isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addTag(
|
||||
earlierVersion: CommunityListEvent,
|
||||
@@ -207,9 +201,7 @@ class CommunityListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (CommunityListEvent) -> Unit,
|
||||
) {
|
||||
return removeTag(earlierVersion, "a", address.toTag(), isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = removeTag(earlierVersion, "a", address.toTag(), isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun removeTag(
|
||||
earlierVersion: CommunityListEvent,
|
||||
|
||||
@@ -68,8 +68,7 @@ class CommunityPostApprovalEvent(
|
||||
it[0] == "e" ||
|
||||
(it[0] == "a" && ATag.parse(it[1], null)?.kind != CommunityDefinitionEvent.KIND)
|
||||
)
|
||||
}
|
||||
.map { it[1] }
|
||||
}.map { it[1] }
|
||||
|
||||
companion object {
|
||||
const val KIND = 4550
|
||||
|
||||
@@ -32,7 +32,10 @@ import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@Immutable data class Contact(val pubKeyHex: String, val relayUri: String?)
|
||||
@Immutable data class Contact(
|
||||
val pubKeyHex: String,
|
||||
val relayUri: String?,
|
||||
)
|
||||
|
||||
@Stable
|
||||
class ContactListEvent(
|
||||
@@ -391,7 +394,10 @@ class ContactListEvent(
|
||||
}
|
||||
}
|
||||
|
||||
data class ReadWrite(val read: Boolean, val write: Boolean)
|
||||
data class ReadWrite(
|
||||
val read: Boolean,
|
||||
val write: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
@Stable
|
||||
@@ -420,31 +426,20 @@ class UserMetadata {
|
||||
@Transient
|
||||
var tags: ImmutableListOfLists<String>? = null
|
||||
|
||||
fun anyName(): String? {
|
||||
return displayName ?: name ?: username
|
||||
}
|
||||
fun anyName(): String? = displayName ?: name ?: username
|
||||
|
||||
fun anyNameStartsWith(prefix: String): Boolean {
|
||||
return listOfNotNull(name, username, displayName, nip05, lud06, lud16).any {
|
||||
fun anyNameStartsWith(prefix: String): Boolean =
|
||||
listOfNotNull(name, username, displayName, nip05, lud06, lud16).any {
|
||||
it.contains(prefix, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun lnAddress(): String? {
|
||||
return lud16 ?: lud06
|
||||
}
|
||||
fun lnAddress(): String? = lud16 ?: lud06
|
||||
|
||||
fun bestName(): String? {
|
||||
return displayName ?: name ?: username
|
||||
}
|
||||
fun bestName(): String? = displayName ?: name ?: username
|
||||
|
||||
fun nip05(): String? {
|
||||
return nip05
|
||||
}
|
||||
fun nip05(): String? = nip05
|
||||
|
||||
fun profilePicture(): String? {
|
||||
return picture
|
||||
}
|
||||
fun profilePicture(): String? = picture
|
||||
|
||||
fun cleanBlankNames() {
|
||||
if (picture?.isNotEmpty() == true) picture = picture?.trim()
|
||||
@@ -473,10 +468,10 @@ class UserMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
@Stable class ImmutableListOfLists<T>(val lists: Array<Array<T>>)
|
||||
@Stable class ImmutableListOfLists<T>(
|
||||
val lists: Array<Array<T>>,
|
||||
)
|
||||
|
||||
val EmptyTagList = ImmutableListOfLists<String>(emptyArray())
|
||||
|
||||
fun Array<Array<String>>.toImmutableListOfLists(): ImmutableListOfLists<String> {
|
||||
return ImmutableListOfLists(this)
|
||||
}
|
||||
fun Array<Array<String>>.toImmutableListOfLists(): ImmutableListOfLists<String> = ImmutableListOfLists(this)
|
||||
|
||||
@@ -54,11 +54,12 @@ class DeletionEvent(
|
||||
val tags = mutableListOf<Array<String>>()
|
||||
|
||||
val kinds =
|
||||
deleteEvents.mapTo(HashSet()) {
|
||||
"${it.kind}"
|
||||
}.map {
|
||||
arrayOf("k", it)
|
||||
}
|
||||
deleteEvents
|
||||
.mapTo(HashSet()) {
|
||||
"${it.kind}"
|
||||
}.map {
|
||||
arrayOf("k", it)
|
||||
}
|
||||
|
||||
tags.addAll(deleteEvents.map { arrayOf("e", it.id) })
|
||||
tags.addAll(deleteEvents.mapNotNull { if (it is AddressableEvent) arrayOf("a", it.address().toTag()) else null })
|
||||
@@ -78,11 +79,12 @@ class DeletionEvent(
|
||||
val tags = mutableListOf<Array<String>>()
|
||||
|
||||
val kinds =
|
||||
deleteEvents.mapTo(HashSet()) {
|
||||
"${it.kind}"
|
||||
}.map {
|
||||
arrayOf("k", it)
|
||||
}
|
||||
deleteEvents
|
||||
.mapTo(HashSet()) {
|
||||
"${it.kind}"
|
||||
}.map {
|
||||
arrayOf("k", it)
|
||||
}
|
||||
|
||||
tags.addAll(deleteEvents.map { arrayOf("e", it.id) })
|
||||
tags.addAll(kinds)
|
||||
|
||||
@@ -41,13 +41,9 @@ class DraftEvent(
|
||||
|
||||
fun isDeleted() = content == ""
|
||||
|
||||
fun preCachedDraft(signer: NostrSigner): Event? {
|
||||
return cachedInnerEvent[signer.pubKey]
|
||||
}
|
||||
fun preCachedDraft(signer: NostrSigner): Event? = cachedInnerEvent[signer.pubKey]
|
||||
|
||||
fun preCachedDraft(pubKey: HexKey): Event? {
|
||||
return cachedInnerEvent[pubKey]
|
||||
}
|
||||
fun preCachedDraft(pubKey: HexKey): Event? = cachedInnerEvent[pubKey]
|
||||
|
||||
fun allCache() = cachedInnerEvent.values
|
||||
|
||||
@@ -114,9 +110,7 @@ class DraftEvent(
|
||||
fun createAddressTag(
|
||||
pubKey: HexKey,
|
||||
dTag: String,
|
||||
): String {
|
||||
return ATag.assembleATag(KIND, pubKey, dTag)
|
||||
}
|
||||
): String = ATag.assembleATag(KIND, pubKey, dTag)
|
||||
|
||||
fun create(
|
||||
dTag: String,
|
||||
|
||||
@@ -56,10 +56,11 @@ class EmojiPackEvent(
|
||||
}
|
||||
|
||||
@Immutable
|
||||
data class EmojiUrl(val code: String, val url: String) {
|
||||
fun encode(): String {
|
||||
return ":$code:$url"
|
||||
}
|
||||
data class EmojiUrl(
|
||||
val code: String,
|
||||
val url: String,
|
||||
) {
|
||||
fun encode(): String = ":$code:$url"
|
||||
|
||||
companion object {
|
||||
fun decode(encodedEmojiSetup: String): EmojiUrl? {
|
||||
|
||||
@@ -123,4 +123,7 @@ class FileHeaderEvent(
|
||||
}
|
||||
}
|
||||
|
||||
data class AESGCM(val key: String, val nonce: String)
|
||||
data class AESGCM(
|
||||
val key: String,
|
||||
val nonce: String,
|
||||
)
|
||||
|
||||
@@ -42,14 +42,13 @@ class FileStorageEvent(
|
||||
|
||||
fun decryptKey() = tags.firstOrNull { it.size > 2 && it[0] == DECRYPT }?.let { AESGCM(it[1], it[2]) }
|
||||
|
||||
fun decode(): ByteArray? {
|
||||
return try {
|
||||
fun decode(): ByteArray? =
|
||||
try {
|
||||
Base64.getDecoder().decode(content)
|
||||
} catch (e: Exception) {
|
||||
Log.e("FileStorageEvent", "Unable to decode base 64 ${e.message} $content")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KIND = 1064
|
||||
@@ -58,9 +57,7 @@ class FileStorageEvent(
|
||||
private const val TYPE = "type"
|
||||
private const val DECRYPT = "decrypt"
|
||||
|
||||
fun encode(bytes: ByteArray): String {
|
||||
return Base64.getEncoder().encodeToString(bytes)
|
||||
}
|
||||
fun encode(bytes: ByteArray): String = Base64.getEncoder().encodeToString(bytes)
|
||||
|
||||
fun create(
|
||||
mimeType: String,
|
||||
|
||||
@@ -56,9 +56,7 @@ abstract class GeneralListEvent(
|
||||
|
||||
fun nameOrTitle() = name() ?: title()
|
||||
|
||||
fun cachedPrivateTags(): Array<Array<String>>? {
|
||||
return privateTagsCache
|
||||
}
|
||||
fun cachedPrivateTags(): Array<Array<String>>? = privateTagsCache
|
||||
|
||||
fun filterTagList(
|
||||
key: String,
|
||||
@@ -79,16 +77,14 @@ abstract class GeneralListEvent(
|
||||
isPrivate: Boolean,
|
||||
signer: NostrSigner,
|
||||
onReady: (Boolean) -> Unit,
|
||||
) {
|
||||
return if (isPrivate) {
|
||||
privateTagsOrEmpty(signer = signer) {
|
||||
onReady(
|
||||
it.any { it.size > 1 && it[0] == key && it[1] == tag },
|
||||
)
|
||||
}
|
||||
} else {
|
||||
onReady(isTagged(key, tag))
|
||||
) = if (isPrivate) {
|
||||
privateTagsOrEmpty(signer = signer) {
|
||||
onReady(
|
||||
it.any { it.size > 1 && it[0] == key && it[1] == tag },
|
||||
)
|
||||
}
|
||||
} else {
|
||||
onReady(isTagged(key, tag))
|
||||
}
|
||||
|
||||
fun privateTags(
|
||||
@@ -147,24 +143,16 @@ abstract class GeneralListEvent(
|
||||
onReady: (List<ATag>) -> Unit,
|
||||
) = privateTags(signer) { onReady(filterAddresses(it)) }
|
||||
|
||||
fun filterUsers(tags: Array<Array<String>>): List<String> {
|
||||
return tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
||||
}
|
||||
fun filterUsers(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] }
|
||||
|
||||
fun filterHashtags(tags: Array<Array<String>>): List<String> {
|
||||
return tags.filter { it.size > 1 && it[0] == "t" }.map { it[1] }
|
||||
}
|
||||
fun filterHashtags(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "t" }.map { it[1] }
|
||||
|
||||
fun filterGeohashes(tags: Array<Array<String>>): List<String> {
|
||||
return tags.filter { it.size > 1 && it[0] == "g" }.map { it[1] }
|
||||
}
|
||||
fun filterGeohashes(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "g" }.map { it[1] }
|
||||
|
||||
fun filterEvents(tags: Array<Array<String>>): List<String> {
|
||||
return tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
||||
}
|
||||
fun filterEvents(tags: Array<Array<String>>): List<String> = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] }
|
||||
|
||||
fun filterAddresses(tags: Array<Array<String>>): List<ATag> {
|
||||
return tags
|
||||
fun filterAddresses(tags: Array<Array<String>>): List<ATag> =
|
||||
tags
|
||||
.filter { it.firstOrNull() == "a" }
|
||||
.mapNotNull {
|
||||
val aTagValue = it.getOrNull(1)
|
||||
@@ -172,7 +160,6 @@ abstract class GeneralListEvent(
|
||||
|
||||
if (aTagValue != null) ATag.parse(aTagValue, relay) else null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun createPrivateTags(
|
||||
|
||||
@@ -33,7 +33,8 @@ class LnZapEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : LnZapEventInterface, Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
LnZapEventInterface {
|
||||
// This event is also kept in LocalCache (same object)
|
||||
@Transient val zapRequest: LnZapRequestEvent?
|
||||
|
||||
@@ -55,7 +56,11 @@ class LnZapEvent(
|
||||
|
||||
override fun zappedPollOption(): Int? =
|
||||
try {
|
||||
zapRequest?.tags?.firstOrNull { it.size > 1 && it[0] == POLL_OPTION }?.get(1)?.toInt()
|
||||
zapRequest
|
||||
?.tags
|
||||
?.firstOrNull { it.size > 1 && it[0] == POLL_OPTION }
|
||||
?.get(1)
|
||||
?.toInt()
|
||||
} catch (e: Exception) {
|
||||
Log.e("LnZapEvent", "ZappedPollOption failed to parse", e)
|
||||
null
|
||||
@@ -75,9 +80,7 @@ class LnZapEvent(
|
||||
}
|
||||
}
|
||||
|
||||
override fun content(): String {
|
||||
return content
|
||||
}
|
||||
override fun content(): String = content
|
||||
|
||||
fun lnInvoice() = tags.firstOrNull { it.size > 1 && it[0] == "bolt11" }?.get(1)
|
||||
|
||||
@@ -88,7 +91,7 @@ class LnZapEvent(
|
||||
const val ALT = "Zap event"
|
||||
}
|
||||
|
||||
enum class ZapType() {
|
||||
enum class ZapType {
|
||||
PUBLIC,
|
||||
PRIVATE,
|
||||
ANONYMOUS,
|
||||
|
||||
@@ -44,9 +44,7 @@ class LnZapPaymentRequestEvent(
|
||||
|
||||
fun walletServicePubKey() = tags.firstOrNull { it.size > 1 && it[0] == "p" }?.get(1)
|
||||
|
||||
fun talkingWith(oneSideHex: String): HexKey {
|
||||
return if (pubKey == oneSideHex) walletServicePubKey() ?: pubKey else pubKey
|
||||
}
|
||||
fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) walletServicePubKey() ?: pubKey else pubKey
|
||||
|
||||
fun lnInvoice(
|
||||
signer: NostrSigner,
|
||||
@@ -97,16 +95,20 @@ class LnZapPaymentRequestEvent(
|
||||
|
||||
// REQUEST OBJECTS
|
||||
|
||||
abstract class Request(var method: String? = null)
|
||||
abstract class Request(
|
||||
var method: String? = null,
|
||||
)
|
||||
|
||||
// PayInvoice Call
|
||||
class PayInvoiceParams(var invoice: String? = null)
|
||||
class PayInvoiceParams(
|
||||
var invoice: String? = null,
|
||||
)
|
||||
|
||||
class PayInvoiceMethod(var params: PayInvoiceParams? = null) : Request("pay_invoice") {
|
||||
class PayInvoiceMethod(
|
||||
var params: PayInvoiceParams? = null,
|
||||
) : Request("pay_invoice") {
|
||||
companion object {
|
||||
fun create(bolt11: String): PayInvoiceMethod {
|
||||
return PayInvoiceMethod(PayInvoiceParams(bolt11))
|
||||
}
|
||||
fun create(bolt11: String): PayInvoiceMethod = PayInvoiceMethod(PayInvoiceParams(bolt11))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,7 @@ class LnZapPaymentResponseEvent(
|
||||
|
||||
fun requestId() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
fun talkingWith(oneSideHex: String): HexKey {
|
||||
return if (pubKey == oneSideHex) requestAuthor() ?: pubKey else pubKey
|
||||
}
|
||||
fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) requestAuthor() ?: pubKey else pubKey
|
||||
|
||||
private fun plainContent(
|
||||
signer: NostrSigner,
|
||||
@@ -97,13 +95,21 @@ abstract class Response(
|
||||
|
||||
// PayInvoice Call
|
||||
|
||||
class PayInvoiceSuccessResponse(val result: PayInvoiceResultParams? = null) :
|
||||
Response("pay_invoice") {
|
||||
class PayInvoiceResultParams(val preimage: String)
|
||||
class PayInvoiceSuccessResponse(
|
||||
val result: PayInvoiceResultParams? = null,
|
||||
) : Response("pay_invoice") {
|
||||
class PayInvoiceResultParams(
|
||||
val preimage: String,
|
||||
)
|
||||
}
|
||||
|
||||
class PayInvoiceErrorResponse(val error: PayInvoiceErrorParams? = null) : Response("pay_invoice") {
|
||||
class PayInvoiceErrorParams(val code: ErrorType?, val message: String?)
|
||||
class PayInvoiceErrorResponse(
|
||||
val error: PayInvoiceErrorParams? = null,
|
||||
) : Response("pay_invoice") {
|
||||
class PayInvoiceErrorParams(
|
||||
val code: ErrorType?,
|
||||
val message: String?,
|
||||
)
|
||||
|
||||
enum class ErrorType {
|
||||
@JsonProperty(value = "RATE_LIMITED")
|
||||
|
||||
@@ -75,9 +75,7 @@ class LnZapRequestEvent(
|
||||
return null
|
||||
}
|
||||
|
||||
fun cachedPrivateZap(): LnZapPrivateEvent? {
|
||||
return privateZapEvent
|
||||
}
|
||||
fun cachedPrivateZap(): LnZapPrivateEvent? = privateZapEvent
|
||||
|
||||
fun decryptPrivateZap(
|
||||
signer: NostrSigner,
|
||||
|
||||
@@ -34,7 +34,8 @@ class LongTextNoteEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig), AddressableEvent {
|
||||
) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
AddressableEvent {
|
||||
override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: ""
|
||||
|
||||
override fun address() = ATag(kind, pubKey, dTag(), null)
|
||||
|
||||
@@ -71,9 +71,7 @@ class MuteListEvent(
|
||||
const val FIXED_D_TAG = ""
|
||||
const val ALT = "Mute List"
|
||||
|
||||
fun blockListFor(pubKeyHex: HexKey): String {
|
||||
return "10000:$pubKeyHex:"
|
||||
}
|
||||
fun blockListFor(pubKeyHex: HexKey): String = "10000:$pubKeyHex:"
|
||||
|
||||
fun createListWithTag(
|
||||
key: String,
|
||||
@@ -110,9 +108,7 @@ class MuteListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (MuteListEvent) -> Unit,
|
||||
) {
|
||||
return createListWithTag("p", pubKeyHex, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = createListWithTag("p", pubKeyHex, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun createListWithWord(
|
||||
word: String,
|
||||
@@ -120,9 +116,7 @@ class MuteListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (MuteListEvent) -> Unit,
|
||||
) {
|
||||
return createListWithTag("word", word, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = createListWithTag("word", word, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addUsers(
|
||||
earlierVersion: MuteListEvent,
|
||||
@@ -171,9 +165,7 @@ class MuteListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (MuteListEvent) -> Unit,
|
||||
) {
|
||||
return addTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = addTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addUser(
|
||||
earlierVersion: MuteListEvent,
|
||||
@@ -182,9 +174,7 @@ class MuteListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (MuteListEvent) -> Unit,
|
||||
) {
|
||||
return addTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = addTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun addTag(
|
||||
earlierVersion: MuteListEvent,
|
||||
@@ -232,9 +222,7 @@ class MuteListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (MuteListEvent) -> Unit,
|
||||
) {
|
||||
return removeTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = removeTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun removeUser(
|
||||
earlierVersion: MuteListEvent,
|
||||
@@ -243,9 +231,7 @@ class MuteListEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (MuteListEvent) -> Unit,
|
||||
) {
|
||||
return removeTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
|
||||
}
|
||||
) = removeTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
|
||||
|
||||
fun removeTag(
|
||||
earlierVersion: MuteListEvent,
|
||||
|
||||
@@ -24,7 +24,10 @@ import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||
|
||||
class NIP17Factory {
|
||||
data class Result(val msg: Event, val wraps: List<GiftWrapEvent>)
|
||||
data class Result(
|
||||
val msg: Event,
|
||||
val wraps: List<GiftWrapEvent>,
|
||||
)
|
||||
|
||||
private fun recursiveGiftWrapCreation(
|
||||
event: Event,
|
||||
|
||||
@@ -34,22 +34,27 @@ class NIP90StatusEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
class StatusCode(val code: String, val description: String)
|
||||
class StatusCode(
|
||||
val code: String,
|
||||
val description: String,
|
||||
)
|
||||
|
||||
class AmountInvoice(val amount: Long?, val lnInvoice: String?)
|
||||
class AmountInvoice(
|
||||
val amount: Long?,
|
||||
val lnInvoice: String?,
|
||||
)
|
||||
|
||||
fun status(): StatusCode? {
|
||||
return tags.firstOrNull { it.size > 1 && it[0] == "status" }?.let {
|
||||
fun status(): StatusCode? =
|
||||
tags.firstOrNull { it.size > 1 && it[0] == "status" }?.let {
|
||||
if (it.size > 2 && content == "") {
|
||||
StatusCode(it[1], it[2])
|
||||
} else {
|
||||
StatusCode(it[1], content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun firstAmount(): AmountInvoice? {
|
||||
return tags.firstOrNull { it.size > 1 && it[0] == "amount" }?.let {
|
||||
fun firstAmount(): AmountInvoice? =
|
||||
tags.firstOrNull { it.size > 1 && it[0] == "amount" }?.let {
|
||||
val amount = it[1].toLongOrNull()
|
||||
if (it.size > 2) {
|
||||
if (it[2].isNotBlank()) {
|
||||
@@ -65,7 +70,6 @@ class NIP90StatusEvent(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KIND = 7000
|
||||
|
||||
@@ -54,22 +54,17 @@ class OtsEvent(
|
||||
|
||||
fun digest() = digestEvent()?.hexToByteArray()
|
||||
|
||||
fun otsByteArray(): ByteArray {
|
||||
return Base64.getDecoder().decode(content)
|
||||
}
|
||||
fun otsByteArray(): ByteArray = Base64.getDecoder().decode(content)
|
||||
|
||||
fun cacheVerify(): Long? {
|
||||
return if (verifiedTime != null) {
|
||||
fun cacheVerify(): Long? =
|
||||
if (verifiedTime != null) {
|
||||
verifiedTime
|
||||
} else {
|
||||
verifiedTime = verify()
|
||||
verifiedTime
|
||||
}
|
||||
}
|
||||
|
||||
fun verify(): Long? {
|
||||
return digestEvent()?.let { OtsEvent.verify(otsByteArray(), it) }
|
||||
}
|
||||
fun verify(): Long? = digestEvent()?.let { OtsEvent.verify(otsByteArray(), it) }
|
||||
|
||||
fun info(): String {
|
||||
val detachedOts = DetachedTimestampFile.deserialize(otsByteArray())
|
||||
@@ -111,16 +106,12 @@ class OtsEvent(
|
||||
fun verify(
|
||||
otsFile: String,
|
||||
eventId: HexKey,
|
||||
): Long? {
|
||||
return verify(Base64.getDecoder().decode(otsFile), eventId)
|
||||
}
|
||||
): Long? = verify(Base64.getDecoder().decode(otsFile), eventId)
|
||||
|
||||
fun verify(
|
||||
otsFile: ByteArray,
|
||||
eventId: HexKey,
|
||||
): Long? {
|
||||
return verify(DetachedTimestampFile.deserialize(otsFile), eventId)
|
||||
}
|
||||
): Long? = verify(DetachedTimestampFile.deserialize(otsFile), eventId)
|
||||
|
||||
fun verify(
|
||||
detachedOts: DetachedTimestampFile,
|
||||
|
||||
@@ -37,7 +37,8 @@ class PrivateDmEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig), ChatroomKeyable {
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
ChatroomKeyable {
|
||||
@Transient private var decryptedContent: Map<HexKey, String> = mapOf()
|
||||
|
||||
override fun isContentEncoded() = true
|
||||
@@ -60,13 +61,9 @@ class PrivateDmEvent(
|
||||
}
|
||||
}
|
||||
|
||||
fun talkingWith(oneSideHex: String): HexKey {
|
||||
return if (pubKey == oneSideHex) verifiedRecipientPubKey() ?: pubKey else pubKey
|
||||
}
|
||||
fun talkingWith(oneSideHex: String): HexKey = if (pubKey == oneSideHex) verifiedRecipientPubKey() ?: pubKey else pubKey
|
||||
|
||||
override fun chatroomKey(toRemove: String): ChatroomKey {
|
||||
return ChatroomKey(persistentSetOf(talkingWith(toRemove)))
|
||||
}
|
||||
override fun chatroomKey(toRemove: String): ChatroomKey = ChatroomKey(persistentSetOf(talkingWith(toRemove)))
|
||||
|
||||
/**
|
||||
* To be fully compatible with nip-04, we read e-tags that are in violation to nip-18.
|
||||
@@ -76,13 +73,9 @@ class PrivateDmEvent(
|
||||
*/
|
||||
fun replyTo() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
fun with(pubkeyHex: String): Boolean {
|
||||
return pubkeyHex == pubKey || tags.any { it.size > 1 && it[0] == "p" && it[1] == pubkeyHex }
|
||||
}
|
||||
fun with(pubkeyHex: String): Boolean = pubkeyHex == pubKey || tags.any { it.size > 1 && it[0] == "p" && it[1] == pubkeyHex }
|
||||
|
||||
fun cachedContentFor(signer: NostrSigner): String? {
|
||||
return decryptedContent[signer.pubKey]
|
||||
}
|
||||
fun cachedContentFor(signer: NostrSigner): String? = decryptedContent[signer.pubKey]
|
||||
|
||||
fun plainContent(
|
||||
signer: NostrSigner,
|
||||
@@ -178,11 +171,10 @@ class PrivateDmEvent(
|
||||
}
|
||||
}
|
||||
|
||||
fun geohashMipMap(geohash: String): Array<Array<String>> {
|
||||
return geohash.indices
|
||||
fun geohashMipMap(geohash: String): Array<Array<String>> =
|
||||
geohash.indices
|
||||
.asSequence()
|
||||
.map { arrayOf("g", geohash.substring(0, it + 1)) }
|
||||
.toList()
|
||||
.reversed()
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
@@ -46,18 +46,14 @@ class ReactionEvent(
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (ReactionEvent) -> Unit,
|
||||
) {
|
||||
return create("\u26A0\uFE0F", originalNote, signer, createdAt, onReady)
|
||||
}
|
||||
) = create("\u26A0\uFE0F", originalNote, signer, createdAt, onReady)
|
||||
|
||||
fun createLike(
|
||||
originalNote: EventInterface,
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (ReactionEvent) -> Unit,
|
||||
) {
|
||||
return create("+", originalNote, signer, createdAt, onReady)
|
||||
}
|
||||
) = create("+", originalNote, signer, createdAt, onReady)
|
||||
|
||||
fun create(
|
||||
content: String,
|
||||
|
||||
@@ -37,33 +37,29 @@ class SearchRelayListEvent(
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
override fun dTag() = FIXED_D_TAG
|
||||
|
||||
fun relays(): List<String> {
|
||||
return tags.mapNotNull {
|
||||
fun relays(): List<String> =
|
||||
tags.mapNotNull {
|
||||
if (it.size > 1 && it[0] == "relay") {
|
||||
it[1]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KIND = 10007
|
||||
const val FIXED_D_TAG = ""
|
||||
|
||||
fun createAddressATag(pubKey: HexKey): ATag {
|
||||
return ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
}
|
||||
fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null)
|
||||
|
||||
fun createAddressTag(pubKey: HexKey): String {
|
||||
return ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
}
|
||||
fun createAddressTag(pubKey: HexKey): String = ATag.assembleATag(KIND, pubKey, FIXED_D_TAG)
|
||||
|
||||
fun createTagArray(relays: List<String>): Array<Array<String>> {
|
||||
return relays.map {
|
||||
arrayOf("relay", it)
|
||||
}.plusElement(arrayOf("alt", "Relay list to use for Search")).toTypedArray()
|
||||
}
|
||||
fun createTagArray(relays: List<String>): Array<Array<String>> =
|
||||
relays
|
||||
.map {
|
||||
arrayOf("relay", it)
|
||||
}.plusElement(arrayOf("alt", "Relay list to use for Search"))
|
||||
.toTypedArray()
|
||||
|
||||
fun updateRelayList(
|
||||
earlierVersion: SearchRelayListEvent,
|
||||
@@ -73,11 +69,13 @@ class SearchRelayListEvent(
|
||||
onReady: (SearchRelayListEvent) -> Unit,
|
||||
) {
|
||||
val tags =
|
||||
earlierVersion.tags.filter { it[0] != "relay" }.plus(
|
||||
relays.map {
|
||||
arrayOf("relay", it)
|
||||
},
|
||||
).toTypedArray()
|
||||
earlierVersion.tags
|
||||
.filter { it[0] != "relay" }
|
||||
.plus(
|
||||
relays.map {
|
||||
arrayOf("relay", it)
|
||||
},
|
||||
).toTypedArray()
|
||||
|
||||
signer.sign(createdAt, KIND, tags, earlierVersion.content, onReady)
|
||||
}
|
||||
|
||||
@@ -134,9 +134,7 @@ class TextNoteEvent(
|
||||
}
|
||||
}
|
||||
|
||||
fun findURLs(text: String): List<String> {
|
||||
return UrlDetector(text, UrlDetectorOptions.Default).detect().map { it.originalUrl }
|
||||
}
|
||||
fun findURLs(text: String): List<String> = UrlDetector(text, UrlDetectorOptions.Default).detect().map { it.originalUrl }
|
||||
|
||||
/**
|
||||
* Returns a list of NIP-10 marked tags that are also ordered at best effort to support the
|
||||
@@ -163,13 +161,12 @@ fun List<String>.positionalMarkedTags(
|
||||
o2 == replyingTo -> -1 // reply event being responded to goes last
|
||||
else -> 0 // keep the relative order for any other tag
|
||||
}
|
||||
}
|
||||
.map {
|
||||
when (it) {
|
||||
root -> arrayOf(tagName, it, "", "root")
|
||||
replyingTo -> arrayOf(tagName, it, "", "reply")
|
||||
forkedFrom -> arrayOf(tagName, it, "", "fork")
|
||||
in directMentions -> arrayOf(tagName, it, "", "mention")
|
||||
else -> arrayOf(tagName, it)
|
||||
}
|
||||
}.map {
|
||||
when (it) {
|
||||
root -> arrayOf(tagName, it, "", "root")
|
||||
replyingTo -> arrayOf(tagName, it, "", "reply")
|
||||
forkedFrom -> arrayOf(tagName, it, "", "fork")
|
||||
in directMentions -> arrayOf(tagName, it, "", "mention")
|
||||
else -> arrayOf(tagName, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ class WikiNoteEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig), AddressableEvent {
|
||||
) : BaseTextNoteEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
AddressableEvent {
|
||||
override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: ""
|
||||
|
||||
override fun address() = ATag(kind, pubKey, dTag(), null)
|
||||
|
||||
@@ -27,7 +27,9 @@ import com.vitorpamplona.quartz.events.EventFactory
|
||||
import com.vitorpamplona.quartz.events.LnZapPrivateEvent
|
||||
import com.vitorpamplona.quartz.events.LnZapRequestEvent
|
||||
|
||||
abstract class NostrSigner(val pubKey: HexKey) {
|
||||
abstract class NostrSigner(
|
||||
val pubKey: HexKey,
|
||||
) {
|
||||
abstract fun <T : Event> sign(
|
||||
createdAt: Long,
|
||||
kind: Int,
|
||||
|
||||
@@ -66,8 +66,7 @@ class NostrSignerExternal(
|
||||
localEvent.content,
|
||||
localEvent.sig,
|
||||
) as? T?
|
||||
)
|
||||
?.let { onReady(it) }
|
||||
)?.let { onReady(it) }
|
||||
} else {
|
||||
(
|
||||
EventFactory.create(
|
||||
@@ -79,8 +78,7 @@ class NostrSignerExternal(
|
||||
event.content,
|
||||
signature.split("-")[0],
|
||||
) as? T?
|
||||
)
|
||||
?.let { onReady(it) }
|
||||
)?.let { onReady(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user