Skip to content

Commit

Permalink
add json serialization support for SolanaPublicKey
Browse files Browse the repository at this point in the history
  • Loading branch information
Funkatronics committed Jun 13, 2024
1 parent 0934d1d commit 9349209
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.solana.publickey

import com.funkatronics.encoders.Base58
import com.funkatronics.kborsh.BorshDecoder
import com.funkatronics.kborsh.BorshEncoder
import com.solana.serialization.ByteStringSerializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

Expand Down Expand Up @@ -35,13 +39,16 @@ open class SolanaPublicKey(final override val bytes: ByteArray) : PublicKey {
}

object SolanaPublicKeySerializer : KSerializer<SolanaPublicKey> {
private val delegate = ByteStringSerializer(SolanaPublicKey.PUBLIC_KEY_LENGTH)
override val descriptor: SerialDescriptor = delegate.descriptor
private val borshDelegate = ByteStringSerializer(SolanaPublicKey.PUBLIC_KEY_LENGTH)
private val jsonDelegate = String.serializer()
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("SolanaPublicKey")

override fun deserialize(decoder: Decoder): SolanaPublicKey =
SolanaPublicKey(decoder.decodeSerializableValue(delegate))
if (decoder is BorshDecoder) SolanaPublicKey(decoder.decodeSerializableValue(borshDelegate))
else SolanaPublicKey.from(decoder.decodeSerializableValue(jsonDelegate))

override fun serialize(encoder: Encoder, value: SolanaPublicKey) {
encoder.encodeSerializableValue(delegate, value.bytes)
if (encoder is BorshEncoder) encoder.encodeSerializableValue(borshDelegate, value.bytes)
else encoder.encodeSerializableValue(jsonDelegate, value.base58())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.solana.serialization

import com.funkatronics.kborsh.Borsh
import com.solana.publickey.SolanaPublicKey
import com.solana.publickey.SolanaPublicKeySerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class SolanaPublicKeySerializerTests {

@Test
fun `Json serializes as base58 string`() {
// given
val publicKeyBase58 = "11111111111111111111111111111111"
val publicKey = SolanaPublicKey.from(publicKeyBase58)

// when
val serialized = Json.encodeToString(SolanaPublicKeySerializer, publicKey)

// then
assertEquals("\"$publicKeyBase58\"", serialized)
}

@Test
fun `Json deserializes from base58 string`() {
// given
@Serializable
data class TestStruct(val owner: SolanaPublicKey)

val publicKeyBase58 = "11111111111111111111111111111111"
val publicKey = SolanaPublicKey.from(publicKeyBase58)
val json = """
{
"owner": "$publicKeyBase58"
}
""".trimIndent()

// when
val deserialzed = Json.decodeFromString<TestStruct>(json)

// then
assertEquals(publicKey, deserialzed.owner)
}

@Test
fun `Borsh serializes as base58 string`() {
// given
val publicKeyBase58 = "11111111111111111111111111111111"
val publicKey = SolanaPublicKey.from(publicKeyBase58)

// when
val serialized = Borsh.encodeToByteArray(SolanaPublicKeySerializer, publicKey)

// then
assertContentEquals(publicKey.bytes, serialized)
}

@Test
fun `Borsh deserializes from base58 string`() {
// given
val publicKeyBase58 = "11111111111111111111111111111111"
val publicKey = SolanaPublicKey.from(publicKeyBase58)

// when
val deserialzed = Borsh.decodeFromByteArray(SolanaPublicKeySerializer, publicKey.bytes)

// then
assertEquals(publicKey, deserialzed)
}
}

0 comments on commit 9349209

Please sign in to comment.