Rename Utils to Tlv

This commit is contained in:
Chemaclass
2023-03-08 13:26:23 +01:00
parent 49199fe892
commit 26b5061042
6 changed files with 65 additions and 66 deletions

View File

@@ -3,9 +3,7 @@ package com.vitorpamplona.amethyst.service.model
import android.util.Log import android.util.Log
import com.vitorpamplona.amethyst.model.toByteArray import com.vitorpamplona.amethyst.model.toByteArray
import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.model.toHexKey
import com.vitorpamplona.amethyst.service.nip19.TlvTypes import com.vitorpamplona.amethyst.service.nip19.Tlv
import com.vitorpamplona.amethyst.service.nip19.parseTLV
import com.vitorpamplona.amethyst.service.nip19.toInt32
import fr.acinq.secp256k1.Hex import fr.acinq.secp256k1.Hex
import nostr.postr.Bech32 import nostr.postr.Bech32
import nostr.postr.bechToBytes import nostr.postr.bechToBytes
@@ -20,15 +18,15 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela
val dTag = dTag.toByteArray(Charsets.UTF_8) val dTag = dTag.toByteArray(Charsets.UTF_8)
val relay = relay?.toByteArray(Charsets.UTF_8) val relay = relay?.toByteArray(Charsets.UTF_8)
var fullArray = byteArrayOf(TlvTypes.SPECIAL.id, dTag.size.toByte()) + dTag var fullArray = byteArrayOf(Tlv.Type.SPECIAL.id, dTag.size.toByte()) + dTag
if (relay != null) { if (relay != null) {
fullArray = fullArray + byteArrayOf(TlvTypes.RELAY.id, relay.size.toByte()) + relay fullArray = fullArray + byteArrayOf(Tlv.Type.RELAY.id, relay.size.toByte()) + relay
} }
fullArray = fullArray + fullArray = fullArray +
byteArrayOf(TlvTypes.AUTHOR.id, author.size.toByte()) + author + byteArrayOf(Tlv.Type.AUTHOR.id, author.size.toByte()) + author +
byteArrayOf(TlvTypes.KIND.id, kind.size.toByte()) + kind byteArrayOf(Tlv.Type.KIND.id, kind.size.toByte()) + kind
return Bech32.encodeBytes(hrp = "naddr", fullArray, Bech32.Encoding.Bech32) return Bech32.encodeBytes(hrp = "naddr", fullArray, Bech32.Encoding.Bech32)
} }
@@ -62,11 +60,11 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela
val key = naddr.removePrefix("nostr:") val key = naddr.removePrefix("nostr:")
if (key.startsWith("naddr")) { if (key.startsWith("naddr")) {
val tlv = parseTLV(key.bechToBytes()) val tlv = Tlv.parse(key.bechToBytes())
val d = tlv.get(TlvTypes.SPECIAL.id)?.get(0)?.toString(Charsets.UTF_8) ?: "" val d = tlv.get(Tlv.Type.SPECIAL.id)?.get(0)?.toString(Charsets.UTF_8) ?: ""
val relay = tlv.get(TlvTypes.RELAY.id)?.get(0)?.toString(Charsets.UTF_8) val relay = tlv.get(Tlv.Type.RELAY.id)?.get(0)?.toString(Charsets.UTF_8)
val author = tlv.get(TlvTypes.AUTHOR.id)?.get(0)?.toHexKey() val author = tlv.get(Tlv.Type.AUTHOR.id)?.get(0)?.toHexKey()
val kind = tlv.get(TlvTypes.KIND.id)?.get(0)?.let { toInt32(it) } val kind = tlv.get(Tlv.Type.KIND.id)?.get(0)?.let { Tlv.toInt32(it) }
if (kind != null && author != null) { if (kind != null && author != null) {
return ATag(kind, author, d, relay) return ATag(kind, author, d, relay)

View File

@@ -44,13 +44,13 @@ object Nip19 {
} }
private fun nprofile(bytes: ByteArray): Return? { private fun nprofile(bytes: ByteArray): Return? {
val tlv = parseTLV(bytes) val tlv = Tlv.parse(bytes)
val hex = tlv.get(TlvTypes.SPECIAL.id) val hex = tlv.get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toHexKey() ?: return null ?.toHexKey() ?: return null
val relay = tlv.get(TlvTypes.RELAY.id) val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?.toString(Charsets.UTF_8)
@@ -58,13 +58,13 @@ object Nip19 {
} }
private fun nevent(bytes: ByteArray): Return? { private fun nevent(bytes: ByteArray): Return? {
val tlv = parseTLV(bytes) val tlv = Tlv.parse(bytes)
val hex = tlv.get(TlvTypes.SPECIAL.id) val hex = tlv.get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toHexKey() ?: return null ?.toHexKey() ?: return null
val relay = tlv.get(TlvTypes.RELAY.id) val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?.toString(Charsets.UTF_8)
@@ -72,8 +72,8 @@ object Nip19 {
} }
private fun nrelay(bytes: ByteArray): Return? { private fun nrelay(bytes: ByteArray): Return? {
val relayUrl = parseTLV(bytes) val relayUrl = Tlv.parse(bytes)
.get(TlvTypes.SPECIAL.id) .get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?: return null ?.toString(Charsets.UTF_8) ?: return null
@@ -81,23 +81,23 @@ object Nip19 {
} }
private fun naddr(bytes: ByteArray): Return? { private fun naddr(bytes: ByteArray): Return? {
val tlv = parseTLV(bytes) val tlv = Tlv.parse(bytes)
val d = tlv.get(TlvTypes.SPECIAL.id) val d = tlv.get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?: return null ?.toString(Charsets.UTF_8) ?: return null
val relay = tlv.get(TlvTypes.RELAY.id) val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?.toString(Charsets.UTF_8)
val author = tlv.get(TlvTypes.AUTHOR.id) val author = tlv.get(Tlv.Type.AUTHOR.id)
?.get(0) ?.get(0)
?.toHexKey() ?.toHexKey()
val kind = tlv.get(TlvTypes.KIND.id) val kind = tlv.get(Tlv.Type.KIND.id)
?.get(0) ?.get(0)
?.let { toInt32(it) } ?.let { Tlv.toInt32(it) }
return Return(Type.ADDRESS, "$kind:$author:$d", relay) return Return(Type.ADDRESS, "$kind:$author:$d", relay)
} }

View File

@@ -0,0 +1,36 @@
package com.vitorpamplona.amethyst.service.nip19
import java.nio.ByteBuffer
import java.nio.ByteOrder
object Tlv {
enum class Type(val id: Byte) {
SPECIAL(0),
RELAY(1),
AUTHOR(2),
KIND(3);
}
fun toInt32(bytes: ByteArray): Int {
require(bytes.size == 4) { "length must be 4, got: ${bytes.size}" }
return ByteBuffer.wrap(bytes, 0, 4).order(ByteOrder.BIG_ENDIAN).int
}
fun parse(data: ByteArray): Map<Byte, List<ByteArray>> {
val result = mutableMapOf<Byte, MutableList<ByteArray>>()
var rest = data
while (rest.isNotEmpty()) {
val t = rest[0]
val l = rest[1]
val v = rest.sliceArray(IntRange(2, (2 + l) - 1))
rest = rest.sliceArray(IntRange(2 + l, rest.size - 1))
if (v.size < l) continue
if (!result.containsKey(t)) {
result[t] = mutableListOf()
}
result[t]?.add(v)
}
return result
}
}

View File

@@ -1,8 +0,0 @@
package com.vitorpamplona.amethyst.service.nip19
enum class TlvTypes(val id: Byte) {
SPECIAL(0),
RELAY(1),
AUTHOR(2),
KIND(3);
}

View File

@@ -1,27 +0,0 @@
package com.vitorpamplona.amethyst.service.nip19
import java.nio.ByteBuffer
import java.nio.ByteOrder
fun toInt32(bytes: ByteArray): Int {
require(bytes.size == 4) { "length must be 4, got: ${bytes.size}" }
return ByteBuffer.wrap(bytes, 0, 4).order(ByteOrder.BIG_ENDIAN).int
}
fun parseTLV(data: ByteArray): Map<Byte, List<ByteArray>> {
val result = mutableMapOf<Byte, MutableList<ByteArray>>()
var rest = data
while (rest.isNotEmpty()) {
val t = rest[0]
val l = rest[1]
val v = rest.sliceArray(IntRange(2, (2 + l) - 1))
rest = rest.sliceArray(IntRange(2 + l, rest.size - 1))
if (v.size < l) continue
if (!result.containsKey(t)) {
result[t] = mutableListOf()
}
result[t]?.add(v)
}
return result
}

View File

@@ -1,25 +1,25 @@
package com.vitorpamplona.amethyst.service package com.vitorpamplona.amethyst.service
import com.vitorpamplona.amethyst.service.nip19.toInt32 import com.vitorpamplona.amethyst.service.nip19.Tlv
import org.junit.Assert import org.junit.Assert
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
class UtilsTest { class TlvTest {
@Test(expected = IllegalArgumentException::class) @Test(expected = IllegalArgumentException::class)
fun to_int_32_length_smaller_than_4() { fun to_int_32_length_smaller_than_4() {
toInt32(byteArrayOfInts(1, 2, 3)) Tlv.toInt32(byteArrayOfInts(1, 2, 3))
} }
@Test(expected = IllegalArgumentException::class) @Test(expected = IllegalArgumentException::class)
fun to_int_32_length_bigger_than_4() { fun to_int_32_length_bigger_than_4() {
toInt32(byteArrayOfInts(1, 2, 3, 4, 5)) Tlv.toInt32(byteArrayOfInts(1, 2, 3, 4, 5))
} }
@Test() @Test()
fun to_int_32_length_4() { fun to_int_32_length_4() {
val actual = toInt32(byteArrayOfInts(1, 2, 3, 4)) val actual = Tlv.toInt32(byteArrayOfInts(1, 2, 3, 4))
Assert.assertEquals(16909060, actual) Assert.assertEquals(16909060, actual)
} }