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 com.vitorpamplona.amethyst.model.toByteArray
import com.vitorpamplona.amethyst.model.toHexKey
import com.vitorpamplona.amethyst.service.nip19.TlvTypes
import com.vitorpamplona.amethyst.service.nip19.parseTLV
import com.vitorpamplona.amethyst.service.nip19.toInt32
import com.vitorpamplona.amethyst.service.nip19.Tlv
import fr.acinq.secp256k1.Hex
import nostr.postr.Bech32
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 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) {
fullArray = fullArray + byteArrayOf(TlvTypes.RELAY.id, relay.size.toByte()) + relay
fullArray = fullArray + byteArrayOf(Tlv.Type.RELAY.id, relay.size.toByte()) + relay
}
fullArray = fullArray +
byteArrayOf(TlvTypes.AUTHOR.id, author.size.toByte()) + author +
byteArrayOf(TlvTypes.KIND.id, kind.size.toByte()) + kind
byteArrayOf(Tlv.Type.AUTHOR.id, author.size.toByte()) + author +
byteArrayOf(Tlv.Type.KIND.id, kind.size.toByte()) + kind
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:")
if (key.startsWith("naddr")) {
val tlv = parseTLV(key.bechToBytes())
val d = tlv.get(TlvTypes.SPECIAL.id)?.get(0)?.toString(Charsets.UTF_8) ?: ""
val relay = tlv.get(TlvTypes.RELAY.id)?.get(0)?.toString(Charsets.UTF_8)
val author = tlv.get(TlvTypes.AUTHOR.id)?.get(0)?.toHexKey()
val kind = tlv.get(TlvTypes.KIND.id)?.get(0)?.let { toInt32(it) }
val tlv = Tlv.parse(key.bechToBytes())
val d = tlv.get(Tlv.Type.SPECIAL.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(Tlv.Type.AUTHOR.id)?.get(0)?.toHexKey()
val kind = tlv.get(Tlv.Type.KIND.id)?.get(0)?.let { Tlv.toInt32(it) }
if (kind != null && author != null) {
return ATag(kind, author, d, relay)

View File

@@ -44,13 +44,13 @@ object Nip19 {
}
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)
?.toHexKey() ?: return null
val relay = tlv.get(TlvTypes.RELAY.id)
val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0)
?.toString(Charsets.UTF_8)
@@ -58,13 +58,13 @@ object Nip19 {
}
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)
?.toHexKey() ?: return null
val relay = tlv.get(TlvTypes.RELAY.id)
val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0)
?.toString(Charsets.UTF_8)
@@ -72,8 +72,8 @@ object Nip19 {
}
private fun nrelay(bytes: ByteArray): Return? {
val relayUrl = parseTLV(bytes)
.get(TlvTypes.SPECIAL.id)
val relayUrl = Tlv.parse(bytes)
.get(Tlv.Type.SPECIAL.id)
?.get(0)
?.toString(Charsets.UTF_8) ?: return null
@@ -81,23 +81,23 @@ object Nip19 {
}
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)
?.toString(Charsets.UTF_8) ?: return null
val relay = tlv.get(TlvTypes.RELAY.id)
val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0)
?.toString(Charsets.UTF_8)
val author = tlv.get(TlvTypes.AUTHOR.id)
val author = tlv.get(Tlv.Type.AUTHOR.id)
?.get(0)
?.toHexKey()
val kind = tlv.get(TlvTypes.KIND.id)
val kind = tlv.get(Tlv.Type.KIND.id)
?.get(0)
?.let { toInt32(it) }
?.let { Tlv.toInt32(it) }
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
import com.vitorpamplona.amethyst.service.nip19.toInt32
import com.vitorpamplona.amethyst.service.nip19.Tlv
import org.junit.Assert
import org.junit.Ignore
import org.junit.Test
class UtilsTest {
class TlvTest {
@Test(expected = IllegalArgumentException::class)
fun to_int_32_length_smaller_than_4() {
toInt32(byteArrayOfInts(1, 2, 3))
Tlv.toInt32(byteArrayOfInts(1, 2, 3))
}
@Test(expected = IllegalArgumentException::class)
fun to_int_32_length_bigger_than_4() {
toInt32(byteArrayOfInts(1, 2, 3, 4, 5))
Tlv.toInt32(byteArrayOfInts(1, 2, 3, 4, 5))
}
@Test()
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)
}