diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 0f718239a..65efa4cab 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -77,7 +77,7 @@ object LocalCache { } fun checkGetOrCreateNote(key: String): Note? { - if (key.startsWith("naddr1")) { + if (key.startsWith("naddr1") || key.contains(":")) { return checkGetOrCreateAddressableNote(key) } return try { @@ -120,7 +120,7 @@ object LocalCache { fun checkGetOrCreateAddressableNote(key: String): AddressableNote? { return try { - val addr = ATag.parse(key) + val addr = ATag.parse(key, null) // relay doesn't matter for the index. if (addr != null) getOrCreateAddressableNote(addr) else @@ -133,10 +133,12 @@ object LocalCache { @Synchronized fun getOrCreateAddressableNote(key: ATag): AddressableNote { - return addressables[key.toNAddr()] ?: run { + // we can't use naddr here because naddr might include relay info and + // the preferred relay should not be part of the index. + return addressables[key.toTag()] ?: run { val answer = AddressableNote(key) answer.author = checkGetOrCreateUser(key.pubKeyHex) - addressables.put(key.toNAddr(), answer) + addressables.put(key.toTag(), answer) answer } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 2544afd17..9e9a58dfc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -24,7 +24,7 @@ import kotlinx.coroutines.withContext val tagSearch = Pattern.compile("(?:\\s|\\A)\\#\\[([0-9]+)\\]") -class AddressableNote(val address: ATag): Note(address.toNAddr()) { +class AddressableNote(val address: ATag): Note(address.toTag()) { override fun idNote() = address.toNAddr() override fun idDisplayNote() = idNote().toShortenHex() override fun address() = address diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt index 46f905070..6c3bde56c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/ThreadAssembler.kt @@ -35,8 +35,8 @@ class ThreadAssembler { @OptIn(ExperimentalTime::class) fun findThreadFor(noteId: String): Set { val (result, elapsed) = measureTimedValue { - val note = if (noteId.startsWith("naddr")) { - val aTag = ATag.parse(noteId) + val note = if (noteId.contains(":")) { + val aTag = ATag.parse(noteId, null) if (aTag != null) LocalCache.getOrCreateAddressableNote(aTag) else diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/Nip19.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/Nip19.kt index 54d765940..00db14164 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/Nip19.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/Nip19.kt @@ -11,7 +11,7 @@ class Nip19 { USER, NOTE, RELAY, ADDRESS } - data class Return(val type: Type, val hex: String) + data class Return(val type: Type, val hex: String, val relay: String?) fun uriToRoute(uri: String?): Return? { try { @@ -39,29 +39,39 @@ class Nip19 { } private fun npub(bytes: ByteArray): Return { - return Return(Type.USER, bytes.toHexKey()) + return Return(Type.USER, bytes.toHexKey(), null) } private fun note(bytes: ByteArray): Return { - return Return(Type.NOTE, bytes.toHexKey()); + return Return(Type.NOTE, bytes.toHexKey(), null); } private fun nprofile(bytes: ByteArray): Return? { - val hex = parseTLV(bytes) - .get(NIP19TLVTypes.SPECIAL.id) + val tlv = parseTLV(bytes) + + val hex = tlv.get(NIP19TLVTypes.SPECIAL.id) ?.get(0) ?.toHexKey() ?: return null - return Return(Type.USER, hex) + val relay = tlv.get(NIP19TLVTypes.RELAY.id) + ?.get(0) + ?.toString(Charsets.UTF_8) + + return Return(Type.USER, hex, relay) } private fun nevent(bytes: ByteArray): Return? { - val hex = parseTLV(bytes) - .get(NIP19TLVTypes.SPECIAL.id) + val tlv = parseTLV(bytes) + + val hex = tlv.get(NIP19TLVTypes.SPECIAL.id) ?.get(0) ?.toHexKey() ?: return null - return Return(Type.USER, hex) + val relay = tlv.get(NIP19TLVTypes.RELAY.id) + ?.get(0) + ?.toString(Charsets.UTF_8) + + return Return(Type.USER, hex, relay) } private fun nrelay(bytes: ByteArray): Return? { @@ -70,7 +80,7 @@ class Nip19 { ?.get(0) ?.toString(Charsets.UTF_8) ?: return null - return Return(Type.RELAY, relayUrl) + return Return(Type.RELAY, relayUrl, null) } private fun naddr(bytes: ByteArray): Return? { @@ -92,7 +102,7 @@ class Nip19 { ?.get(0) ?.let { toInt32(it) } - return Return(Type.ADDRESS, "$kind:$author:$d") + return Return(Type.ADDRESS, "$kind:$author:$d", relay) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt index 26684b34f..cace13279 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt @@ -84,7 +84,7 @@ object NostrUserProfileDataSource: NostrDataSource("UserProfileFeed") { types = FeedType.values().toSet(), filter = JsonFilter( kinds = listOf(BadgeProfilesEvent.kind), - tags = mapOf("p" to listOf(it.pubkeyHex)), + authors = listOf(it.pubkeyHex), limit = 1 ) ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt index 4a8ae0374..7e7b30608 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ATag.kt @@ -11,35 +11,41 @@ import nostr.postr.Bech32 import nostr.postr.bechToBytes import nostr.postr.toByteArray -data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String) { +data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val relay: String?) { fun toTag() = "$kind:$pubKeyHex:$dTag" fun toNAddr(): String { val kind = kind.toByteArray() - val addr = pubKeyHex.toByteArray() + val author = pubKeyHex.toByteArray() val dTag = dTag.toByteArray(Charsets.UTF_8) + val relay = relay?.toByteArray(Charsets.UTF_8) - val fullArray = - byteArrayOf(NIP19TLVTypes.SPECIAL.id, dTag.size.toByte()) + dTag + - byteArrayOf(NIP19TLVTypes.AUTHOR.id, addr.size.toByte()) + addr + + var fullArray = + byteArrayOf(NIP19TLVTypes.SPECIAL.id, dTag.size.toByte()) + dTag + + if (relay != null) + fullArray = fullArray + byteArrayOf(NIP19TLVTypes.RELAY.id, relay.size.toByte()) + relay + + fullArray = fullArray + + byteArrayOf(NIP19TLVTypes.AUTHOR.id, author.size.toByte()) + author + byteArrayOf(NIP19TLVTypes.KIND.id, kind.size.toByte()) + kind return Bech32.encodeBytes(hrp = "naddr", fullArray, Bech32.Encoding.Bech32) } companion object { - fun parse(address: String): ATag? { + fun parse(address: String, relay: String?): ATag? { return if (address.startsWith("naddr") || address.startsWith("nostr:naddr")) parseNAddr(address) else - parseAtag(address) + parseAtag(address, relay) } - fun parseAtag(atag: String): ATag? { + fun parseAtag(atag: String, relay: String?): ATag? { return try { val parts = atag.split(":") Hex.decode(parts[1]) - ATag(parts[0].toInt(), parts[1], parts[2]) + ATag(parts[0].toInt(), parts[1], parts[2], relay) } catch (t: Throwable) { Log.w("ATag", "Error parsing A Tag: ${atag}: ${t.message}") null @@ -58,7 +64,7 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String) { val kind = tlv.get(NIP19TLVTypes.KIND.id)?.get(0)?.let { toInt32(it) } if (kind != null && author != null) - return ATag(kind, author, d) + return ATag(kind, author, d, relay) } } catch (e: Throwable) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt index b0a3693a7..c27b6b0b2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeAwardEvent.kt @@ -14,7 +14,12 @@ class BadgeAwardEvent( sig: HexKey ): Event(id, pubKey, createdAt, kind, tags, content, sig) { fun awardees() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } - fun awardDefinition() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun awardDefinition() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } companion object { const val kind = 8 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt index d3572d84d..e084f1c58 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeDefinitionEvent.kt @@ -14,7 +14,7 @@ class BadgeDefinitionEvent( sig: HexKey ): Event(id, pubKey, createdAt, kind, tags, content, sig) { fun dTag() = tags.filter { it.firstOrNull() == "d" }.mapNotNull { it.getOrNull(1) }.firstOrNull() ?: "" - fun address() = ATag(kind, pubKey, dTag()) + fun address() = ATag(kind, pubKey, dTag(), null) fun name() = tags.filter { it.firstOrNull() == "name" }.mapNotNull { it.getOrNull(1) }.firstOrNull() fun thumb() = tags.filter { it.firstOrNull() == "thumb" }.mapNotNull { it.getOrNull(1) }.firstOrNull() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt index 9a6ce84a9..d13925222 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/BadgeProfilesEvent.kt @@ -11,10 +11,15 @@ class BadgeProfilesEvent( sig: HexKey ): Event(id, pubKey, createdAt, kind, tags, content, sig) { fun badgeAwardEvents() = tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) } - fun badgeAwardDefinitions() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun badgeAwardDefinitions() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } fun dTag() = tags.filter { it.firstOrNull() == "d" }.mapNotNull { it.getOrNull(1) }.firstOrNull() ?: "" - fun address() = ATag(kind, pubKey, dTag()) + fun address() = ATag(kind, pubKey, dTag(), null) companion object { const val kind = 30008 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt index 823b112e5..20448a433 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapEvent.kt @@ -24,8 +24,12 @@ class LnZapEvent( override fun taggedAddresses(): List = tags .filter { it.firstOrNull() == "a" } - .mapNotNull { it.getOrNull(1) } - .mapNotNull { ATag.parse(it) } + .mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } override fun amount(): BigDecimal? { return lnInvoice()?.let { LnInvoiceUtil.getAmountInSats(it) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt index 4f6fa852c..4d7f3f911 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/LnZapRequestEvent.kt @@ -16,7 +16,12 @@ class LnZapRequestEvent ( ): Event(id, pubKey, createdAt, kind, tags, content, sig) { fun zappedPost() = tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) } fun zappedAuthor() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } - fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } companion object { const val kind = 9734 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt index 14fd66d47..1824995e8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/LongTextNoteEvent.kt @@ -17,7 +17,7 @@ class LongTextNoteEvent( fun mentions() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } fun dTag() = tags.filter { it.firstOrNull() == "d" }.mapNotNull { it.getOrNull(1) }.firstOrNull() ?: "" - fun address() = ATag(kind, pubKey, dTag()) + fun address() = ATag(kind, pubKey, dTag(), null) fun topics() = tags.filter { it.firstOrNull() == "t" }.mapNotNull { it.getOrNull(1) } fun title() = tags.filter { it.firstOrNull() == "title" }.mapNotNull { it.getOrNull(1) }.firstOrNull() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt index 4676bee1e..5525ff7f5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReactionEvent.kt @@ -17,7 +17,12 @@ class ReactionEvent ( fun originalPost() = tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) } fun originalAuthor() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } - fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } companion object { const val kind = 7 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt index 765f98abd..8ca58d7d8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/ReportEvent.kt @@ -48,7 +48,12 @@ class ReportEvent ( ) } - fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } companion object { const val kind = 1984 diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt index 5e7b5f4b5..aec19a407 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/RepostEvent.kt @@ -18,7 +18,12 @@ class RepostEvent ( fun boostedPost() = tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) } fun originalAuthor() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } - fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } fun containedPost() = try { fromJson(content, Client.lenient) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt index 63839802b..ed5460f34 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/TextNoteEvent.kt @@ -14,7 +14,13 @@ class TextNoteEvent( sig: HexKey ): Event(id, pubKey, createdAt, kind, tags, content, sig) { fun mentions() = tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) } - fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { it.getOrNull(1) }.mapNotNull { ATag.parse(it) } + fun taggedAddresses() = tags.filter { it.firstOrNull() == "a" }.mapNotNull { + val aTagValue = it.getOrNull(1) + val relay = it.getOrNull(2) + + if (aTagValue != null) ATag.parse(aTagValue, relay) else null + } + fun replyTos() = tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) } companion object { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt index 6ef3abb29..cbd22d9e7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt @@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.components import androidx.compose.foundation.text.ClickableText import androidx.compose.material.LocalTextStyle import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -31,7 +32,24 @@ fun ClickableRoute( onClick = { navController.navigate(route) }, style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary) ) - } else { + } else if (nip19.type == Nip19.Type.ADDRESS) { + val noteBase = LocalCache.checkGetOrCreateAddressableNote(nip19.hex) + + if (noteBase == null) { + Text( + "@${nip19.hex} " + ) + } else { + val noteState by noteBase.live().metadata.observeAsState() + val note = noteState?.note ?: return + + ClickableText( + text = AnnotatedString("@${note.idDisplayNote()} "), + onClick = { navController.navigate("Note/${nip19.hex}") }, + style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary) + ) + } + } else if (nip19.type == Nip19.Type.NOTE) { val noteBase = LocalCache.getOrCreateNote(nip19.hex) val noteState by noteBase.live().metadata.observeAsState() val note = noteState?.note ?: return @@ -55,5 +73,9 @@ fun ClickableRoute( style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary) ) } + } else { + Text( + "@${nip19.hex} " + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index 79706fe34..109a353e9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -200,11 +200,13 @@ private fun isArabic(text: String): Boolean { fun isBechLink(word: String): Boolean { return word.startsWith("nostr:", true) || word.startsWith("npub1", true) + || word.startsWith("naddr1", true) || word.startsWith("note1", true) || word.startsWith("nprofile1", true) || word.startsWith("nevent1", true) || word.startsWith("@npub1", true) || word.startsWith("@note1", true) + || word.startsWith("@addr1", true) || word.startsWith("@nprofile1", true) || word.startsWith("@nevent1", true) } diff --git a/app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt b/app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt index 77d6a96c0..2cba993cb 100644 --- a/app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt +++ b/app/src/test/java/com/vitorpamplona/amethyst/NIP19ParserTest.kt @@ -18,15 +18,39 @@ class NIP19ParserTest { assertEquals("30023:d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c:guide-wireguard", result?.hex) } + @Test + fun nAddrParse3() { + val result = Nip19().uriToRoute("naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38") + assertEquals(Nip19.Type.ADDRESS, result?.type) + assertEquals("30023:d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193:89de7920", result?.hex) + assertEquals("wss://relay.damus.io", result?.relay) + } + + @Test + fun nAddrATagParse3() { + val address = ATag.parse("30023:d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193:89de7920", "wss://relay.damus.io") + assertEquals(30023, address?.kind) + assertEquals("d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193", address?.pubKeyHex) + assertEquals("89de7920", address?.dTag) + assertEquals("wss://relay.damus.io" , address?.relay) + assertEquals("naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38", address?.toNAddr()) + } + @Test fun nAddrFormatter() { - val address = ATag(30023, "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", "" ) + val address = ATag(30023, "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", "", null) assertEquals("naddr1qqqqygzxpsj7dqha57pjk5k37gkn6g4nzakewtmqmnwryyhd3jfwlpgxtspsgqqqw4rs3xyxus", address.toNAddr()) } @Test fun nAddrFormatter2() { - val address = ATag(30023, "d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c", "guide-wireguard" ) + val address = ATag(30023, "d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c", "guide-wireguard", null) assertEquals("naddr1qq8kwatfv3jj6amfwfjkwatpwfjqygxsm6lelvfda7qlg0tud9pfhduysy4vrexj65azqtdk4tr75j6xdspsgqqqw4rsg32ag8", address.toNAddr()) } + + @Test + fun nAddrFormatter3() { + val address = ATag(30023, "d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193", "89de7920", "wss://relay.damus.io") + assertEquals("naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38", address.toNAddr()) + } } \ No newline at end of file