From 897435977ee3cafed11af7a9a55675c3456848e3 Mon Sep 17 00:00:00 2001
From: funkatronics <funkatronicsmail@gmail.com>
Date: Mon, 8 Jan 2024 11:19:22 -0700
Subject: [PATCH] handle empty sigs

---
 .../serialization/ByteStringSerializer.kt     |  2 ++
 .../com/funkatronics/transaction/Message.kt   | 35 ++++++++++++-------
 .../funkatronics/transaction/Transaction.kt   |  2 ++
 3 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/core/src/commonMain/kotlin/com/funkatronics/serialization/ByteStringSerializer.kt b/core/src/commonMain/kotlin/com/funkatronics/serialization/ByteStringSerializer.kt
index 951ac07..213d4a6 100644
--- a/core/src/commonMain/kotlin/com/funkatronics/serialization/ByteStringSerializer.kt
+++ b/core/src/commonMain/kotlin/com/funkatronics/serialization/ByteStringSerializer.kt
@@ -15,6 +15,8 @@ open class ByteStringSerializer(val length: Int) : KSerializer<ByteArray> {
         }
 
     override fun serialize(encoder: Encoder, value: ByteArray) {
+        if (value.isEmpty()) ByteArray(length).forEach { encoder.encodeByte(it) }
+        check(value.size == length) { "Cannot serialize, provided byte array has incorrect size { ${value.size} }" }
         value.forEach { encoder.encodeByte(it) }
     }
 }
\ No newline at end of file
diff --git a/solana/src/commonMain/kotlin/com/funkatronics/transaction/Message.kt b/solana/src/commonMain/kotlin/com/funkatronics/transaction/Message.kt
index 681b26e..66947f0 100644
--- a/solana/src/commonMain/kotlin/com/funkatronics/transaction/Message.kt
+++ b/solana/src/commonMain/kotlin/com/funkatronics/transaction/Message.kt
@@ -17,6 +17,13 @@ val Blockhash.blockhash get() = this.bytes
 
 sealed class Message {
 
+    abstract val signatureCount: UByte
+    abstract val readOnlyAccounts: UByte
+    abstract val readOnlyNonSigners: UByte
+    abstract val accounts: List<SolanaPublicKey>
+    abstract val blockhash: Blockhash
+    abstract val instructions: List<Instruction>
+
     companion object {
         fun from(bytes: ByteArray) = TransactionFormat.decodeFromByteArray(MessageSerializer, bytes)
     }
@@ -82,23 +89,23 @@ sealed class Message {
 
 @Serializable
 data class LegacyMessage(
-    val signatureCount: UByte,
-    val readOnlyAccounts: UByte,
-    val readOnlyNonSigners: UByte,
-    val accounts: List<SolanaPublicKey>,
-    val blockhash: Blockhash,
-    val instructions: List<Instruction>
+    override val signatureCount: UByte,
+    override val readOnlyAccounts: UByte,
+    override val readOnlyNonSigners: UByte,
+    override val accounts: List<SolanaPublicKey>,
+    override val blockhash: Blockhash,
+    override val instructions: List<Instruction>
 ) : Message()
 
 @Serializable
 data class VersionedMessage(
     @Transient val version: Byte = 0,
-    val signatureCount: UByte,
-    val readOnlyAccounts: UByte,
-    val readOnlyNonSigners: UByte,
-    val accounts: List<SolanaPublicKey>,
-    val blockhash: Blockhash,
-    val instructions: List<Instruction>,
+    override val signatureCount: UByte,
+    override val readOnlyAccounts: UByte,
+    override val readOnlyNonSigners: UByte,
+    override val accounts: List<SolanaPublicKey>,
+    override val blockhash: Blockhash,
+    override val instructions: List<Instruction>,
     val addressTableLookups: List<AddressTableLookup>
 ) : Message()
 
@@ -143,4 +150,6 @@ object MessageSerializer : KSerializer<Message> {
             is VersionedMessage -> encoder.encodeSerializableValue(VersionedMessage.serializer(), value)
         }
     }
-}
\ No newline at end of file
+}
+
+fun Message.toUnsignedTransaction(): Transaction = Transaction(this)
\ No newline at end of file
diff --git a/solana/src/commonMain/kotlin/com/funkatronics/transaction/Transaction.kt b/solana/src/commonMain/kotlin/com/funkatronics/transaction/Transaction.kt
index 3529032..5dd643c 100644
--- a/solana/src/commonMain/kotlin/com/funkatronics/transaction/Transaction.kt
+++ b/solana/src/commonMain/kotlin/com/funkatronics/transaction/Transaction.kt
@@ -12,6 +12,8 @@ data class Transaction(
     @Serializable(with = MessageSerializer::class) val message: Message
 ) {
 
+    constructor(message: Message): this(buildList(message.signatureCount.toInt()) { ByteArray(size) }, message)
+
     companion object {
         fun from(bytes: ByteArray) = TransactionFormat.decodeFromByteArray(serializer(), bytes)
     }