From dc466680ef6668d3efee94a48e478d11716a2879 Mon Sep 17 00:00:00 2001 From: funkatronics Date: Tue, 25 Nov 2025 16:22:36 -0700 Subject: [PATCH 1/5] add getTransaction method + tests --- .../kotlin/com/solana/rpc/JsonParsed.kt | 84 ++++++++++++ .../kotlin/com/solana/rpc/SolanaRpcClient.kt | 9 ++ .../kotlin/com/solana/rpc/SolanaRpcRequest.kt | 16 +++ .../com/solana/rpc/SolanaRpcResponse.kt | 10 ++ .../com/solana/rpc/GetTransactionTest.kt | 120 ++++++++++++++++++ .../kotlin/com/solana/rpc/RpcClientTests.kt | 1 - 6 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 solanaclient/src/commonMain/kotlin/com/solana/rpc/JsonParsed.kt create mode 100644 solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/JsonParsed.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/JsonParsed.kt new file mode 100644 index 0000000..7089dd4 --- /dev/null +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/JsonParsed.kt @@ -0,0 +1,84 @@ +package com.solana.rpc + +import com.funkatronics.encoders.Base58 +import com.solana.publickey.SolanaPublicKey +import com.solana.transaction.Blockhash +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject + +@Serializable +data class TransactionMetadata( + val err: Map? = null, + val fee: ULong, + val computeUnitsConsumed: ULong, + val preBalances: List, + val postBalances: List, + val innerInstructions: List, + val preTokenBalances: List, + val postTokenBalances: List, + val logMessages: List, + val rewards: List, +) + +@Serializable +data class Instruction( + val index: Int, + val instructions: List +) + +@Serializable +data class InnerInstruction( + val programIdIndex: Int, + val accounts: List, + @SerialName("data") val base58EncodedData: String +) { + val rawData = Base58.decode(base58EncodedData) +} + +@Serializable +data class TokenBalance( + val accountIndex: Int, + val mint: SolanaPublicKey, + val owner: SolanaPublicKey? = null, + val programId: SolanaPublicKey? = null, + val uiTokenAmount: UiTokenAmount +) + +@Serializable +data class UiTokenAmount( + val amount: ULong, + val decimals: Byte, + @SerialName("uiAmountString") val uiAmount: String +) + +@Serializable +data class JsonParsedTransaction( + val message: JsonParsedMessage, + val signatures: List +) + +@Serializable +data class JsonParsedMessage( + val accountKeys: List, + val instructions: List, + val recentBlockhash: Blockhash +) + +@Serializable +data class JsonParsedInstruction( + val program: String? = null, + val programId: SolanaPublicKey, + val stackHeight: ULong? = null, + val parsed: JsonElement? = null, +) + +@Serializable +data class JsonParsedAccountMeta( + @SerialName("pubkey") val publicKey: SolanaPublicKey, + val source: String, + @SerialName("signer") val isSigner: Boolean, + @SerialName("writable") val isWritable: Boolean, +) \ No newline at end of file diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt index 4db9d2a..9fb41d1 100644 --- a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt @@ -146,6 +146,15 @@ class SolanaRpcClient( return@withTimeout Result.success(isActive) } + suspend fun getTransaction( + transactionSignature: String, + commitment: Commitment = Commitment.FINALIZED, + maxSupportedTransactionVersion: Long = 0 + ) = makeRequest( + GetTransactionRequest(transactionSignature, commitment, maxSupportedTransactionVersion), + TransactionDetails.serializer().nullable + ) + internal suspend inline fun makeRequest(request: RpcRequest, serializer: DeserializationStrategy) = rpcDriver.makeRequest(request, serializer) diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt index 3870fc7..83c6e4b 100644 --- a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt @@ -228,4 +228,20 @@ class RentExemptBalanceRequest( params = { add(size) }, configuration = { put("commitment", commitment?.serialName()) }, requestId +) + +class GetTransactionRequest( + signature: String, + commitment: Commitment = Commitment.FINALIZED, + maxSupportedTransactionVersion: Long = 0, + requestId: String? = null +) : SolanaRpcRequest( + method = "getTransaction", + params = { add(signature) }, + configuration = { + put("commitment", commitment.serialName()) + put("maxSupportedTransactionVersion", maxSupportedTransactionVersion) + put("encoding", "jsonParsed") + }, + requestId ) \ No newline at end of file diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcResponse.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcResponse.kt index 54d0e59..f47b755 100644 --- a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcResponse.kt +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcResponse.kt @@ -1,6 +1,7 @@ package com.solana.rpc import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject @Serializable @@ -21,4 +22,13 @@ data class SignatureStatus( val confirmations: Long?, var err: JsonObject?, var confirmationStatus: Commitment? +) + +@Serializable +data class TransactionDetails( + val blockTime: Long, + val meta: TransactionMetadata, + val slot: ULong, + val transaction: JsonParsedTransaction, + val version: JsonElement? = null ) \ No newline at end of file diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt new file mode 100644 index 0000000..32f23c7 --- /dev/null +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt @@ -0,0 +1,120 @@ +package com.solana.rpc + +import com.solana.config.TestConfig +import com.solana.networking.KtorNetworkDriver +import com.solana.publickey.SolanaPublicKey +import com.solana.transaction.AccountMeta +import com.solana.transaction.Message +import com.solana.transaction.Transaction +import com.solana.transaction.TransactionInstruction +import diglol.crypto.Ed25519 +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withContext +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class GetTransactionTest { + + @Test + fun `GetTransaction returns transaction details`() = runTest { + // given + val keyPair = Ed25519.generateKeyPair() + val pubkey = SolanaPublicKey(keyPair.publicKey) + val programId = SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr") + val rpc = SolanaRpcClient(TestConfig.RPC_URL, KtorNetworkDriver()) + val expectedParsedInstruction = JsonParsedInstruction( + program="spl-memo", + programId = programId, + stackHeight = 1u, + parsed = JsonPrimitive("hello world") + ) + + // when + rpc.requestAirdrop(pubkey, 0.1f) + val blockhashResponse = rpc.getLatestBlockhash() + val transaction = Message.Builder() + .setRecentBlockhash(blockhashResponse.result!!.blockhash) + .addInstruction(TransactionInstruction( + SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), + listOf(AccountMeta(pubkey, true, true)), + "hello world".encodeToByteArray() + )) + .build().run { + val sig = Ed25519.sign(keyPair, serialize()) + Transaction(listOf(sig), this) + } + + val txResponse = withContext(Dispatchers.Default.limitedParallelism(1)) { + rpc.sendAndConfirmTransaction(transaction, TransactionOptions( + commitment = Commitment.CONFIRMED, + skipPreflight = true + )) + } + val response = rpc.getTransaction(txResponse.result!!, Commitment.CONFIRMED) + + println(response.result) + + // then + assertNull(response.error) + assertNotNull(response.result) + assertNotNull(response.result!!.meta) + assertNull(response.result!!.meta.err) + assertEquals(expectedParsedInstruction, response.result!!.transaction.message.instructions.first()) + } + + @Test + fun `GetTransaction returns transaction error`() = runTest { + // given + val keyPair = Ed25519.generateKeyPair() + val pubkey = SolanaPublicKey(keyPair.publicKey) + val programId = SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr") + val rpc = SolanaRpcClient(TestConfig.RPC_URL, KtorNetworkDriver()) + val expectedParsedInstruction = JsonParsedInstruction( + program="spl-memo", + programId = programId, + stackHeight = 1u, + parsed = JsonPrimitive("hello world") + ) + + // when + rpc.requestAirdrop(pubkey, 0.1f) + val blockhashResponse = rpc.getLatestBlockhash() + val transaction = Message.Builder() + .setRecentBlockhash(blockhashResponse.result!!.blockhash) + .addInstruction(TransactionInstruction( + SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), + listOf( + AccountMeta(pubkey, true, true), + AccountMeta(programId, false, false) + ), + "hello world".encodeToByteArray() + )) + .build().run { + val sig = Ed25519.sign(keyPair, serialize()) + Transaction(listOf(sig), this) + } + + val txResponse = withContext(Dispatchers.Default.limitedParallelism(1)) { + rpc.sendAndConfirmTransaction(transaction, TransactionOptions( + commitment = Commitment.CONFIRMED, + skipPreflight = true + )) + } + val response = rpc.getTransaction(txResponse.result!!, Commitment.CONFIRMED) + + println(response.result) + + // then + assertNull(response.error) + assertNotNull(response.result) + assertNotNull(response.result!!.meta) + assertNotNull(response.result!!.meta.err) + assertEquals(expectedParsedInstruction, response.result!!.transaction.message.instructions.first()) + } +} \ No newline at end of file diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt index b20a270..c19d41e 100644 --- a/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt @@ -5,7 +5,6 @@ import com.funkatronics.kborsh.Borsh import com.solana.config.TestConfig import com.solana.networking.KtorNetworkDriver import com.solana.publickey.SolanaPublicKey -import com.solana.rpccore.Rpc20Response import com.solana.serialization.ByteStringSerializer import com.solana.transaction.AccountMeta import com.solana.transaction.Message From 924e46c0b2d1bb480bbccd66598e93d4798a1997 Mon Sep 17 00:00:00 2001 From: funkatronics Date: Tue, 25 Nov 2025 16:23:00 -0700 Subject: [PATCH 2/5] add getAnchorAccountInfo extension --- .../kotlin/com/solana/rpc/SolanaRpcClient.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt index 9fb41d1..094e96c 100644 --- a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt @@ -4,6 +4,7 @@ import com.solana.networking.HttpNetworkDriver import com.solana.networking.Rpc20Driver import com.solana.publickey.SolanaPublicKey import com.solana.rpccore.RpcRequest +import com.solana.serialization.AnchorDiscriminatorSerializer import com.solana.serializers.SolanaResponseDeserializer import com.solana.transaction.Transaction import kotlinx.coroutines.delay @@ -182,6 +183,26 @@ suspend inline fun SolanaRpcClient.getAccountInfo( requestId: String? = null ) = getAccountInfo(serializer(), publicKey, commitment, minContextSlot, dataSlice, requestId) +suspend inline fun SolanaRpcClient.getAnchorAccountInfo( + accountName: String, + publicKey: SolanaPublicKey, + commitment: Commitment? = null, + minContextSlot: Long? = null, + dataSlice: AccountRequest.DataSlice? = null, + requestId: String? = null +) = getAccountInfo( + AnchorDiscriminatorSerializer( + "account", + accountName, + serializer() + ), + publicKey, + commitment, + minContextSlot, + dataSlice, + requestId +) + suspend fun SolanaRpcClient.getMultipleAccounts( deserializer: KSerializer, publicKeys: List, From a99c6c6496960fb1b01c22512fd57775c6750eb0 Mon Sep 17 00:00:00 2001 From: funkatronics Date: Mon, 1 Dec 2025 11:31:07 -0700 Subject: [PATCH 3/5] fix tests for different validator behavior --- .../kotlin/com/solana/rpc/GetTransactionTest.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt index 32f23c7..e09ec8a 100644 --- a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt @@ -65,7 +65,12 @@ class GetTransactionTest { assertNotNull(response.result) assertNotNull(response.result!!.meta) assertNull(response.result!!.meta.err) - assertEquals(expectedParsedInstruction, response.result!!.transaction.message.instructions.first()) + response.result!!.transaction.message.instructions.first().apply { + assertEquals(expectedParsedInstruction.program, this.program) + assertEquals(expectedParsedInstruction.programId, this.programId) + assertEquals(expectedParsedInstruction.parsed, this.parsed) + assertEquals(expectedParsedInstruction.stackHeight, this.stackHeight ?: 1u) + } } @Test @@ -115,6 +120,11 @@ class GetTransactionTest { assertNotNull(response.result) assertNotNull(response.result!!.meta) assertNotNull(response.result!!.meta.err) - assertEquals(expectedParsedInstruction, response.result!!.transaction.message.instructions.first()) + response.result!!.transaction.message.instructions.first().apply { + assertEquals(expectedParsedInstruction.program, this.program) + assertEquals(expectedParsedInstruction.programId, this.programId) + assertEquals(expectedParsedInstruction.parsed, this.parsed) + assertEquals(expectedParsedInstruction.stackHeight, this.stackHeight ?: 1u) + } } } \ No newline at end of file From a36a3062a4c1a9bd27cb64717bedd224a2e00ddc Mon Sep 17 00:00:00 2001 From: funkatronics Date: Fri, 9 Jan 2026 12:46:22 -0700 Subject: [PATCH 4/5] add getFee request --- .../kotlin/com/solana/rpc/SolanaRpcClient.kt | 10 +++++ .../kotlin/com/solana/rpc/SolanaRpcRequest.kt | 16 +++++++ .../com/solana/rpc/GetFeeForMessageTests.kt | 42 +++++++++++++++++++ .../com/solana/rpc/GetTransactionTest.kt | 19 +-------- .../kotlin/com/solana/rpc/RpcClientTests.kt | 6 --- .../solana/rpc/SimulateTransactionTests.kt | 7 ---- .../commonTest/kotlin/com/solana/rpc/Util.kt | 11 +++++ 7 files changed, 81 insertions(+), 30 deletions(-) create mode 100644 solanaclient/src/commonTest/kotlin/com/solana/rpc/GetFeeForMessageTests.kt create mode 100644 solanaclient/src/commonTest/kotlin/com/solana/rpc/Util.kt diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt index 3410fb6..d919062 100644 --- a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcClient.kt @@ -6,6 +6,7 @@ import com.solana.publickey.SolanaPublicKey import com.solana.rpccore.RpcRequest import com.solana.serialization.AnchorDiscriminatorSerializer import com.solana.serializers.SolanaResponseDeserializer +import com.solana.transaction.Message import com.solana.transaction.Transaction import kotlinx.coroutines.delay import kotlinx.coroutines.isActive @@ -117,6 +118,15 @@ class SolanaRpcClient( SolanaResponseDeserializer(SimulationResult.serializer()) ) + suspend fun getFeeForMessage( + message: Message, + commitment: Commitment = Commitment.PROCESSED, + minContextSlot: Long? = null, + ) = makeRequest( + GetFeeForMessageRequest(message, commitment, minContextSlot), + SolanaResponseDeserializer(ULong.serializer()) + ) + suspend fun sendTransaction( transaction: Transaction, options: TransactionOptions = defaultTransactionOptions, diff --git a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt index 59213b8..9881848 100644 --- a/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt +++ b/solanaclient/src/commonMain/kotlin/com/solana/rpc/SolanaRpcRequest.kt @@ -5,6 +5,7 @@ import com.funkatronics.encoders.Base64 import com.funkatronics.hash.Sha256 import com.solana.publickey.SolanaPublicKey import com.solana.rpccore.JsonRpc20Request +import com.solana.transaction.Message import com.solana.transaction.Transaction import kotlinx.serialization.Serializable import kotlinx.serialization.json.* @@ -248,6 +249,21 @@ class GetTransactionRequest( requestId ) +class GetFeeForMessageRequest( + message: Message, + commitment: Commitment = Commitment.PROCESSED, + minContextSlot: Long? = null, + requestId: String? = null +) : SolanaRpcRequest( + method = "getFeeForMessage", + params = { add(message.serialize().run { Base64.encodeToString(this) }) }, + configuration = { + put("commitment", commitment.serialName()) + put("minContextSlot", minContextSlot) + }, + requestId +) + class SimulateTransactionRequest( transaction: Transaction, commitment: Commitment? = null, diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetFeeForMessageTests.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetFeeForMessageTests.kt new file mode 100644 index 0000000..18f3055 --- /dev/null +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetFeeForMessageTests.kt @@ -0,0 +1,42 @@ +package com.solana.rpc + +import com.solana.config.TestConfig +import com.solana.networking.KtorNetworkDriver +import com.solana.publickey.SolanaPublicKey +import com.solana.transaction.Message +import diglol.crypto.Ed25519 +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertNotNull +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class GetFeeForMessageTests { + + @Test + fun `getFeeForMessage with basic options returns non-zero value`() = runTest { + // given + val keyPair = Ed25519.generateKeyPair() + val pubkey = SolanaPublicKey(keyPair.publicKey) + val rpc = SolanaRpcClient(TestConfig.RPC_URL, KtorNetworkDriver()) + + // when + val blockhashResponse = rpc.getLatestBlockhash() + + val message = Message.Builder() + .setRecentBlockhash(blockhashResponse.result!!.blockhash) + .addInstruction(buildMemoTransaction(pubkey, "hello solana!")) + .build() + + val response = rpc.getFeeForMessage( + message, + commitment = Commitment.CONFIRMED, + minContextSlot = null, + ) + + // then + assertNull(response.error) + assertNotNull(response.result) + assertTrue { response.result!! > 0u } + } +} \ No newline at end of file diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt index e09ec8a..cf84cd5 100644 --- a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt @@ -3,21 +3,17 @@ package com.solana.rpc import com.solana.config.TestConfig import com.solana.networking.KtorNetworkDriver import com.solana.publickey.SolanaPublicKey -import com.solana.transaction.AccountMeta import com.solana.transaction.Message import com.solana.transaction.Transaction -import com.solana.transaction.TransactionInstruction import diglol.crypto.Ed25519 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.test.runTest import kotlinx.coroutines.withContext -import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertNull -import kotlin.test.assertTrue class GetTransactionTest { @@ -40,11 +36,7 @@ class GetTransactionTest { val blockhashResponse = rpc.getLatestBlockhash() val transaction = Message.Builder() .setRecentBlockhash(blockhashResponse.result!!.blockhash) - .addInstruction(TransactionInstruction( - SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), - listOf(AccountMeta(pubkey, true, true)), - "hello world".encodeToByteArray() - )) + .addInstruction(buildMemoTransaction(pubkey, "hello world")) .build().run { val sig = Ed25519.sign(keyPair, serialize()) Transaction(listOf(sig), this) @@ -92,14 +84,7 @@ class GetTransactionTest { val blockhashResponse = rpc.getLatestBlockhash() val transaction = Message.Builder() .setRecentBlockhash(blockhashResponse.result!!.blockhash) - .addInstruction(TransactionInstruction( - SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), - listOf( - AccountMeta(pubkey, true, true), - AccountMeta(programId, false, false) - ), - "hello world".encodeToByteArray() - )) + .addInstruction(buildMemoTransaction(pubkey, "hello world")) .build().run { val sig = Ed25519.sign(keyPair, serialize()) Transaction(listOf(sig), this) diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt index c19d41e..cc1b251 100644 --- a/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/RpcClientTests.kt @@ -437,10 +437,4 @@ class RpcClientTests { assertNotNull(response.result) assertTrue { response.result!!.isNotEmpty() } } - - private fun buildMemoTransaction(address: SolanaPublicKey, memo: String) = - TransactionInstruction(SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), - listOf(AccountMeta(address, true, true)), - memo.encodeToByteArray() - ) } \ No newline at end of file diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/SimulateTransactionTests.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/SimulateTransactionTests.kt index 4d7bddf..59fa08c 100644 --- a/solanaclient/src/commonTest/kotlin/com/solana/rpc/SimulateTransactionTests.kt +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/SimulateTransactionTests.kt @@ -10,7 +10,6 @@ import com.solana.transaction.TransactionInstruction import com.solana.transaction.toUnsignedTransaction import diglol.crypto.Ed25519 import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlinx.coroutines.withContext import kotlin.test.Test @@ -191,10 +190,4 @@ class SimulateTransactionTests { assertNotNull(response.result!!.logs) assertNull(response.result!!.err) } - - private fun buildMemoTransaction(address: SolanaPublicKey, memo: String) = - TransactionInstruction(SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), - listOf(AccountMeta(address, true, true)), - memo.encodeToByteArray() - ) } \ No newline at end of file diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/Util.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/Util.kt new file mode 100644 index 0000000..884bec0 --- /dev/null +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/Util.kt @@ -0,0 +1,11 @@ +package com.solana.rpc + +import com.solana.publickey.SolanaPublicKey +import com.solana.transaction.AccountMeta +import com.solana.transaction.TransactionInstruction + +fun buildMemoTransaction(address: SolanaPublicKey, memo: String) = + TransactionInstruction(SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), + listOf(AccountMeta(address, true, true)), + memo.encodeToByteArray() + ) \ No newline at end of file From 36631e8655d4e0e54bc66f3271834422935eaeff Mon Sep 17 00:00:00 2001 From: funkatronics Date: Fri, 9 Jan 2026 12:51:40 -0700 Subject: [PATCH 5/5] fix bad merge: fix test --- .../kotlin/com/solana/rpc/GetTransactionTest.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt index cf84cd5..8af7c2c 100644 --- a/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt +++ b/solanaclient/src/commonTest/kotlin/com/solana/rpc/GetTransactionTest.kt @@ -3,8 +3,10 @@ package com.solana.rpc import com.solana.config.TestConfig import com.solana.networking.KtorNetworkDriver import com.solana.publickey.SolanaPublicKey +import com.solana.transaction.AccountMeta import com.solana.transaction.Message import com.solana.transaction.Transaction +import com.solana.transaction.TransactionInstruction import diglol.crypto.Ed25519 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.test.runTest @@ -84,7 +86,15 @@ class GetTransactionTest { val blockhashResponse = rpc.getLatestBlockhash() val transaction = Message.Builder() .setRecentBlockhash(blockhashResponse.result!!.blockhash) - .addInstruction(buildMemoTransaction(pubkey, "hello world")) + .addInstruction(TransactionInstruction( + SolanaPublicKey.from("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), + listOf( + AccountMeta(pubkey, true, true), + AccountMeta(programId, false, false) + ), + "hello world".encodeToByteArray() + ) + ) .build().run { val sig = Ed25519.sign(keyPair, serialize()) Transaction(listOf(sig), this)