commonMain.fr.acinq.lightning.serialization.v3.bitcoinKSerializers.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lightning-kmp-jvm Show documentation
Show all versions of lightning-kmp-jvm Show documentation
A Kotlin Multiplatform implementation of the Lightning Network
package fr.acinq.lightning.serialization.v3
import fr.acinq.bitcoin.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.CompositeDecoder
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
internal object ByteVectorKSerializer : KSerializer {
@Serializable
private data class ByteVectorSurrogate(val value: ByteArray)
override val descriptor: SerialDescriptor = ByteVectorSurrogate.serializer().descriptor
override fun serialize(encoder: Encoder, value: ByteVector) {
val surrogate = ByteVectorSurrogate(value.toByteArray())
return encoder.encodeSerializableValue(ByteVectorSurrogate.serializer(), surrogate)
}
override fun deserialize(decoder: Decoder): ByteVector {
val surrogate = decoder.decodeSerializableValue(ByteVectorSurrogate.serializer())
return ByteVector(surrogate.value)
}
}
internal object ByteVector32KSerializer : KSerializer {
@Serializable
private data class ByteVector32Surrogate(val value: ByteArray) {
init {
require(value.size == 32)
}
}
override val descriptor: SerialDescriptor = ByteVector32Surrogate.serializer().descriptor
override fun serialize(encoder: Encoder, value: ByteVector32) {
val surrogate = ByteVector32Surrogate(value.toByteArray())
return encoder.encodeSerializableValue(ByteVector32Surrogate.serializer(), surrogate)
}
override fun deserialize(decoder: Decoder): ByteVector32 {
val surrogate = decoder.decodeSerializableValue(ByteVector32Surrogate.serializer())
return ByteVector32(surrogate.value)
}
}
internal object ByteVector64KSerializer : KSerializer {
@Serializable
private data class ByteVector64Surrogate(val value: ByteArray)
override val descriptor: SerialDescriptor = ByteVector64Surrogate.serializer().descriptor
override fun serialize(encoder: Encoder, value: ByteVector64) {
val surrogate = ByteVector64Surrogate(value.toByteArray())
return encoder.encodeSerializableValue(ByteVector64Surrogate.serializer(), surrogate)
}
override fun deserialize(decoder: Decoder): ByteVector64 {
val surrogate = decoder.decodeSerializableValue(ByteVector64Surrogate.serializer())
return ByteVector64(surrogate.value)
}
}
internal object BlockHashKSerializer : KSerializer {
override fun deserialize(decoder: Decoder): BlockHash {
return BlockHash(ByteVector32KSerializer.deserialize(decoder))
}
override val descriptor: SerialDescriptor get() = ByteVector32KSerializer.descriptor
override fun serialize(encoder: Encoder, value: BlockHash) {
ByteVector32KSerializer.serialize(encoder, value.value)
}
}
internal object PrivateKeyKSerializer : KSerializer {
override fun deserialize(decoder: Decoder): PrivateKey {
return PrivateKey(ByteVector32KSerializer.deserialize(decoder))
}
override val descriptor: SerialDescriptor get() = ByteVector32KSerializer.descriptor
override fun serialize(encoder: Encoder, value: PrivateKey) {
ByteVector32KSerializer.serialize(encoder, value.value)
}
}
internal object PublicKeyKSerializer : KSerializer {
override fun deserialize(decoder: Decoder): PublicKey {
return PublicKey(ByteVectorKSerializer.deserialize(decoder))
}
override val descriptor: SerialDescriptor get() = ByteVectorKSerializer.descriptor
override fun serialize(encoder: Encoder, value: PublicKey) {
ByteVectorKSerializer.serialize(encoder, value.value)
}
}
internal object SatoshiKSerializer : KSerializer {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Satoshi", PrimitiveKind.LONG)
override fun serialize(encoder: Encoder, value: Satoshi) {
encoder.encodeLong(value.toLong())
}
override fun deserialize(decoder: Decoder): Satoshi {
return Satoshi(decoder.decodeLong())
}
}
abstract class AbstractBtcSerializableKSerializer>(val name: String, val btcSerializer: BtcSerializer) : KSerializer {
@Serializable
data class Surrogate(val name: String, val bytes: ByteArray)
override val descriptor: SerialDescriptor = Surrogate.serializer().descriptor
override fun serialize(encoder: Encoder, value: T) {
val surrogate = Surrogate(name, btcSerializer.write(value))
return encoder.encodeSerializableValue(Surrogate.serializer(), surrogate)
}
override fun deserialize(decoder: Decoder): T {
val surrogate = decoder.decodeSerializableValue(Surrogate.serializer())
return btcSerializer.read(surrogate.bytes)
}
}
internal object BlockHeaderKSerializer : AbstractBtcSerializableKSerializer("BlockHeader", BlockHeader)
internal object OutPointKSerializer : AbstractBtcSerializableKSerializer("OutPoint", OutPoint)
internal object ScriptWitnessKSerializer : AbstractBtcSerializableKSerializer("ScriptWitness", ScriptWitness)
internal object TxInKSerializer : AbstractBtcSerializableKSerializer("TxIn", TxIn)
internal object TxOutKSerializer : AbstractBtcSerializableKSerializer("TxOut", TxOut)
internal object TransactionKSerializer : AbstractBtcSerializableKSerializer("Transaction", Transaction)
internal object ExtendedPublicKeyKSerializer : KSerializer {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("ExtendedPublicKey") {
element("publickeybytes", ByteVectorKSerializer.descriptor)
element("chaincode", ByteVector32KSerializer.descriptor)
element("depth")
element("path", KeyPathKSerializer.descriptor)
element("parent")
}
override fun serialize(encoder: Encoder, value: DeterministicWallet.ExtendedPublicKey) {
val compositeEncoder = encoder.beginStructure(descriptor)
compositeEncoder.encodeSerializableElement(descriptor, 0, ByteVectorKSerializer, value.publickeybytes)
compositeEncoder.encodeSerializableElement(descriptor, 1, ByteVector32KSerializer, value.chaincode)
compositeEncoder.encodeIntElement(descriptor, 2, value.depth)
compositeEncoder.encodeSerializableElement(descriptor, 3, KeyPathKSerializer, value.path)
compositeEncoder.encodeLongElement(descriptor, 4, value.parent)
compositeEncoder.endStructure(descriptor)
}
override fun deserialize(decoder: Decoder): DeterministicWallet.ExtendedPublicKey {
var publickeybytes: ByteVector? = null
var chaincode: ByteVector32? = null
var depth: Int? = null
var path: KeyPath? = null
var parent: Long? = null
val compositeDecoder = decoder.beginStructure(descriptor)
loop@ while (true) {
when (compositeDecoder.decodeElementIndex(descriptor)) {
CompositeDecoder.DECODE_DONE -> break@loop
0 -> publickeybytes = compositeDecoder.decodeSerializableElement(descriptor, 0, ByteVectorKSerializer)
1 -> chaincode = compositeDecoder.decodeSerializableElement(descriptor, 1, ByteVector32KSerializer)
2 -> depth = compositeDecoder.decodeIntElement(descriptor, 2)
3 -> path = compositeDecoder.decodeSerializableElement(descriptor, 3, KeyPathKSerializer)
4 -> parent = compositeDecoder.decodeLongElement(descriptor, 4)
}
}
compositeDecoder.endStructure(descriptor)
return DeterministicWallet.ExtendedPublicKey(publickeybytes!!, chaincode!!, depth!!, path!!, parent!!)
}
}
internal object KeyPathKSerializer : KSerializer {
private val listSerializer = ListSerializer(Long.serializer())
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("KeyPath") {
element("path", listSerializer.descriptor)
}
override fun serialize(encoder: Encoder, value: KeyPath) {
val compositeEncoder = encoder.beginStructure(ExtendedPublicKeyKSerializer.descriptor)
compositeEncoder.encodeSerializableElement(descriptor, 0, listSerializer, value.path)
compositeEncoder.endStructure(descriptor)
}
override fun deserialize(decoder: Decoder): KeyPath {
val compositeDecoder = decoder.beginStructure(ExtendedPublicKeyKSerializer.descriptor)
require(compositeDecoder.decodeElementIndex(descriptor) == 0)
val path = compositeDecoder.decodeSerializableElement(descriptor, 0, listSerializer)
compositeDecoder.endStructure(descriptor)
return KeyPath(path)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy