diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 0d7501a..e5bb7ee 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -10,6 +10,7 @@
+
diff --git a/gradle.properties b/gradle.properties
index 315b4d6..c711405 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=0.1.15
+version=0.2.0
# Kotlin
#kotlin.code.style=official
kotlin.js.compiler=ir
diff --git a/libs.versions.toml b/libs.versions.toml
index 514e5b3..c1c5a6f 100644
--- a/libs.versions.toml
+++ b/libs.versions.toml
@@ -14,6 +14,7 @@ mavenPublish = "0.29.0"
skie = "0.8.2"
# Libraries
+arrow = "1.2.4"
junit5 = "5.11.0"
junitPioneer = "2.2.0"
kermit = "2.0.4"
@@ -25,6 +26,7 @@ okio = "3.9.0"
serialization = "1.7.1"
[libraries]
+arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" }
bouncyCastle = { module = "org.bouncycastle:bcpkix-jdk15to18", version = "1.78.1" }
coreLibraryDesugaring = { module = "com.android.tools:desugar_jdk_libs", version = "2.1.0" }
coroutinesAndroid = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 32097a0..e32bb96 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -26,6 +26,7 @@ dependencyResolutionManagement {
}
include(":solana-kotlin")
+include(":solana-kotlin-arrow-extensions")
include(":tweetnacl-multiplatform")
dependencyResolutionManagement {
diff --git a/solana-kotlin-arrow-extensions/build.gradle.kts b/solana-kotlin-arrow-extensions/build.gradle.kts
new file mode 100644
index 0000000..a6cd7f0
--- /dev/null
+++ b/solana-kotlin-arrow-extensions/build.gradle.kts
@@ -0,0 +1,116 @@
+plugins {
+ alias(libs.plugins.kotlinMultiplatform)
+ alias(libs.plugins.kotlinSerialization)
+ alias(libs.plugins.mavenPublish)
+ alias(libs.plugins.dokka)
+ signing
+}
+
+group = "net.avianlabs.solana"
+version = properties["version"] as String
+
+
+kotlin {
+ applyDefaultHierarchyTemplate()
+ explicitApi()
+
+ jvm {
+ // set the target JVM version
+ compilations.all {
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+ }
+ }
+
+ mingwX64()
+ linuxX64()
+
+ sourceSets {
+ val jvmMain by getting
+
+ val jvmTest by getting
+
+ val commonMain by getting {
+ dependencies {
+ api(project(":solana-kotlin"))
+ implementation(libs.coroutinesCore)
+ implementation(libs.kermit)
+ implementation(libs.arrow.core)
+ }
+ }
+ val commonTest by getting {
+ dependencies {
+ implementation(libs.kotlinTest)
+ implementation(libs.coroutinesTest)
+ }
+ }
+
+ val nativeMain by getting
+
+ val linuxMain by getting
+
+ val mingwMain by getting
+ }
+}
+
+tasks.withType {
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+}
+
+signing {
+ useGpgCmd()
+}
+
+publishing {
+ repositories {
+ mavenLocal()
+ repositories {
+ maven {
+ name = "GitHubPackages"
+ url = uri("https://maven.pkg.github.com/avianlabs/solana-kotlin")
+ credentials {
+ username = System.getenv("GITHUB_ACTOR")
+ password = System.getenv("GITHUB_TOKEN")
+ }
+ }
+ }
+ }
+ publications {
+ withType {
+ pom {
+ name = "Solana Kotlin Arrow Extensions"
+ description = "Arrow extensions for Solana Kotlin"
+ licenses {
+ license {
+ name = "MIT"
+ url = "https://opensource.org/licenses/MIT"
+ }
+ }
+ url = "https://github.com/avianlabs/solana-kotlin"
+ issueManagement {
+ system = "GitHub"
+ url = "https://github.com/avianlabs/solana-kotlin"
+ }
+ scm {
+ connection = "https://github.com/avianlabs/solana-kotlin.git"
+ url = "https://github.com/avianlabs/solana-kotlin"
+ }
+ developers {
+ developer {
+ name = "Avian Labs Engineers"
+ email = "engineering@avianlabs.net"
+ }
+ }
+ }
+ }
+ }
+}
+
+mavenPublishing {
+ if (rootProject.findProperty("signPublications") != "false") {
+ signAllPublications()
+ }
+}
diff --git a/solana-kotlin-arrow-extensions/src/commonMain/kotlin/net/avianlabs/solana/arrow/Either.kt b/solana-kotlin-arrow-extensions/src/commonMain/kotlin/net/avianlabs/solana/arrow/Either.kt
new file mode 100644
index 0000000..2beaa4d
--- /dev/null
+++ b/solana-kotlin-arrow-extensions/src/commonMain/kotlin/net/avianlabs/solana/arrow/Either.kt
@@ -0,0 +1,27 @@
+package net.avianlabs.solana.arrow
+
+import arrow.core.Either
+import arrow.core.left
+import arrow.core.right
+import net.avianlabs.solana.arrow.SolanaKotlinError.RpcError.*
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.RpcError
+
+public fun Response.toEither(): Either =
+ if (error != null) {
+ error!!.toRpcError().left()
+ } else if (result != null) {
+ result!!.right()
+ } else {
+ SolanaKotlinError.MalformedResponse("both error and result are null").left()
+ }
+
+private fun RpcError.toRpcError(): SolanaKotlinError = when (code) {
+ -32700 -> ParseError(message)
+ -32600 -> InvalidRequest(message)
+ -32601 -> MethodNotFound(message)
+ -32602 -> InvalidParams(message)
+ -32603 -> InternalError(message)
+ in -32000 downTo -32099 -> ServerError(message)
+ else -> SolanaKotlinError.UnknownError(message)
+}
diff --git a/solana-kotlin-arrow-extensions/src/commonMain/kotlin/net/avianlabs/solana/arrow/SolanaKotlinError.kt b/solana-kotlin-arrow-extensions/src/commonMain/kotlin/net/avianlabs/solana/arrow/SolanaKotlinError.kt
new file mode 100644
index 0000000..2431fab
--- /dev/null
+++ b/solana-kotlin-arrow-extensions/src/commonMain/kotlin/net/avianlabs/solana/arrow/SolanaKotlinError.kt
@@ -0,0 +1,15 @@
+package net.avianlabs.solana.arrow
+
+public sealed interface SolanaKotlinError {
+ public sealed interface RpcError : SolanaKotlinError {
+ public data class ParseError(val message: String) : RpcError
+ public data class InvalidRequest(val message: String) : RpcError
+ public data class MethodNotFound(val message: String) : RpcError
+ public data class InvalidParams(val message: String) : RpcError
+ public data class InternalError(val message: String) : RpcError
+ public data class ServerError(val message: String) : RpcError
+ }
+
+ public data class MalformedResponse(val message: String) : SolanaKotlinError
+ public data class UnknownError(val message: String) : SolanaKotlinError
+}
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/SolanaClient.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/SolanaClient.kt
index 15bf043..d48323b 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/SolanaClient.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/SolanaClient.kt
@@ -2,9 +2,9 @@ package net.avianlabs.solana
import io.ktor.client.*
import io.ktor.http.*
-import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.client.RpcInvocation
import net.avianlabs.solana.client.RpcKtorClient
import kotlin.coroutines.resume
@@ -35,7 +35,6 @@ public class SolanaClient(
),
)
- @OptIn(ExperimentalSerializationApi::class)
internal val json: Json = Json {
ignoreUnknownKeys = true
isLenient = true
@@ -46,8 +45,8 @@ public class SolanaClient(
internal suspend inline fun invoke(
method: String,
params: JsonArray? = null,
- ): T? {
+ ): Response {
val invocation = RpcInvocation(method, params, headerProviders)
- return client.invoke(invocation).result
+ return client.invoke(invocation)
}
}
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/ExecuteException.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/ExecuteException.kt
deleted file mode 100644
index b9007bc..0000000
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/ExecuteException.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package net.avianlabs.solana.client
-
-public data class ExecuteException(val error: RpcError) : RuntimeException(error.toString())
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcResponse.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/Response.kt
similarity index 75%
rename from solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcResponse.kt
rename to solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/Response.kt
index 62171f9..ea754fe 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcResponse.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/Response.kt
@@ -3,7 +3,7 @@ package net.avianlabs.solana.client
import kotlinx.serialization.Serializable
@Serializable
-public data class RpcResponse(
+public data class Response(
val id: Int,
val jsonrpc: String,
val result: T? = null,
@@ -11,13 +11,13 @@ public data class RpcResponse(
) {
@Serializable
public data class RPC(
- val context: Context?,
- val value: T? = null,
+ val context: Context,
+ val value: T,
) {
@Serializable
public data class Context(
- val slot: Long,
+ val slot: ULong,
val apiVersion: String?,
)
}
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcKtorClient.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcKtorClient.kt
index 8c3c8c0..551e81f 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcKtorClient.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/client/RpcKtorClient.kt
@@ -40,25 +40,20 @@ public class RpcKtorClient(
}
}
- internal suspend inline fun invoke(invocation: RpcInvocation): RpcResponse =
+ internal suspend inline fun invoke(invocation: RpcInvocation): Response =
execute(makeRequest(invocation))
internal inline fun makeRequest(invocation: RpcInvocation): RpcRequest =
RpcRequest(requestIdGenerator.next(), invocation)
- internal suspend inline fun execute(request: RpcRequest): RpcResponse {
- val response = ktorClient.post(url) {
+ internal suspend inline fun execute(request: RpcRequest): Response =
+ ktorClient.post(url) {
contentType(ContentType.Application.Json)
- setBody(request.buildBody())
+ setBody(request.buildBody())
request.invocation.headerProviders.forEach { (header, valueProvider) ->
header(header, valueProvider())
}
- }
- response.body()["error"]?.let {
- throw ExecuteException(Json.decodeFromJsonElement(it))
- }
- return response.body()
- }
+ }.body()
internal inline fun RpcRequest.buildBody(): JsonObject {
val body: MutableMap = mutableMapOf(
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getAccountInfo.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getAccountInfo.kt
index 9349ce2..0ba1445 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getAccountInfo.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getAccountInfo.kt
@@ -7,28 +7,25 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
public suspend fun SolanaClient.getAccountInfo(
publicKey: PublicKey,
commitment: Commitment? = null,
-): AccountInfo? {
- val result = invoke>(
- method = "getAccountInfo",
- params = buildJsonArray {
- add(publicKey.toBase58())
- addJsonObject {
- put("encoding", "base64")
- commitment?.let {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getAccountInfo",
+ params = buildJsonArray {
+ add(publicKey.toBase58())
+ addJsonObject {
+ put("encoding", "base64")
+ commitment?.let {
+ put("commitment", it.value)
}
}
- )
- return result!!.value
-}
+ }
+)
/**
* Account information
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getBalance.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getBalance.kt
index 31e561a..7354630 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getBalance.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getBalance.kt
@@ -5,7 +5,8 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse.RPC
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.Response.RPC
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
@@ -18,17 +19,14 @@ import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
public suspend fun SolanaClient.getBalance(
account: PublicKey,
commitment: Commitment? = null,
-): Long {
- val result = invoke>(
- method = "getBalance",
- params = buildJsonArray {
- add(account.toBase58())
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getBalance",
+ params = buildJsonArray {
+ add(account.toBase58())
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!.value!!
-}
+ }
+)
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getFeeForMessage.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getFeeForMessage.kt
index ddbcfba..023413a 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getFeeForMessage.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getFeeForMessage.kt
@@ -6,7 +6,8 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse.RPC
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.Response.RPC
import net.avianlabs.solana.domain.core.Commitment
/**
@@ -19,17 +20,14 @@ import net.avianlabs.solana.domain.core.Commitment
public suspend fun SolanaClient.getFeeForMessage(
message: ByteArray,
commitment: Commitment? = null
-): Long {
- val result = invoke>(
- method = "getFeeForMessage",
- params = buildJsonArray {
- add(message.encodeBase64())
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getFeeForMessage",
+ params = buildJsonArray {
+ add(message.encodeBase64())
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!.value!!
-}
+ }
+)
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getLatestBlockhash.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getLatestBlockhash.kt
index 83771eb..b09b00c 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getLatestBlockhash.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getLatestBlockhash.kt
@@ -5,7 +5,8 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.Response.RPC
import net.avianlabs.solana.domain.core.Commitment
/**
@@ -15,19 +16,16 @@ import net.avianlabs.solana.domain.core.Commitment
*/
public suspend fun SolanaClient.getLatestBlockhash(
commitment: Commitment? = null,
-): LatestBlockHash {
- val result = invoke>(
- method = "getLatestBlockhash",
- params = buildJsonArray {
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getLatestBlockhash",
+ params = buildJsonArray {
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!.value!!
-}
+ }
+)
@Serializable
public data class LatestBlockHash(
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getMinimumBalanceForRentExemption.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getMinimumBalanceForRentExemption.kt
index 54dc923..86b6536 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getMinimumBalanceForRentExemption.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getMinimumBalanceForRentExemption.kt
@@ -5,6 +5,7 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.domain.core.Commitment
/**
@@ -16,17 +17,14 @@ import net.avianlabs.solana.domain.core.Commitment
public suspend fun SolanaClient.getMinimumBalanceForRentExemption(
dataLength: Long,
commitment: Commitment? = null,
-): Long {
- val result = invoke(
- method = "getMinimumBalanceForRentExemption",
- params = buildJsonArray {
- add(dataLength)
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response = invoke(
+ method = "getMinimumBalanceForRentExemption",
+ params = buildJsonArray {
+ add(dataLength)
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!
-}
+ }
+)
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getNonce.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getNonce.kt
index 6893f9c..25b4f1a 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getNonce.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getNonce.kt
@@ -11,6 +11,8 @@ public suspend fun SolanaClient.getNonce(
publicKey: PublicKey,
commitment: Commitment? = null
): NonceAccount? = getAccountInfo(publicKey, commitment)
+ .result
+ ?.value
?.dataBytes
?.let { data ->
val decoded = NonceAccountData.read(Buffer().write(data))
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getRecentBlockhash.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getRecentBlockhash.kt
index 9918a1e..b264517 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getRecentBlockhash.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getRecentBlockhash.kt
@@ -5,7 +5,8 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.Response.RPC
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.domain.core.FeeCalculator
@@ -23,19 +24,16 @@ import net.avianlabs.solana.domain.core.FeeCalculator
)
public suspend fun SolanaClient.getRecentBlockhash(
commitment: Commitment? = null,
-): RecentBlockHash {
- val result = invoke>(
- method = "getRecentBlockhash",
- params = buildJsonArray {
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getRecentBlockhash",
+ params = buildJsonArray {
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!.value!!
-}
+ }
+)
@Serializable
public data class RecentBlockHash(
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getSignaturesForAddress.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getSignaturesForAddress.kt
index 5277fea..2c8f7ff 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getSignaturesForAddress.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getSignaturesForAddress.kt
@@ -3,6 +3,7 @@ package net.avianlabs.solana.methods
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.*
import net.avianlabs.solana.SolanaClient
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
@@ -18,20 +19,17 @@ import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
public suspend fun SolanaClient.getSignaturesForAddress(
account: PublicKey,
commitment: Commitment? = null,
-): List {
- val result = invoke>(
- method = "getSignaturesForAddress",
- params = buildJsonArray {
- add(account.toBase58())
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getSignaturesForAddress",
+ params = buildJsonArray {
+ add(account.toBase58())
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!
-}
+ }
+)
@Serializable
public data class SignatureInformation(
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTokenAccountBalance.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTokenAccountBalance.kt
index e98635f..2df1664 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTokenAccountBalance.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTokenAccountBalance.kt
@@ -6,7 +6,8 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse.RPC
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.Response.RPC
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
@@ -20,20 +21,17 @@ import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
public suspend fun SolanaClient.getTokenAccountBalance(
tokenAccount: PublicKey,
commitment: Commitment? = null,
-): TokenAmountInfo {
- val result = invoke>(
- method = "getTokenAccountBalance",
- params = buildJsonArray {
- add(tokenAccount.toBase58())
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response> = invoke(
+ method = "getTokenAccountBalance",
+ params = buildJsonArray {
+ add(tokenAccount.toBase58())
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!.value!!
-}
+ }
+)
@Serializable
public data class TokenAmountInfo(
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTransaction.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTransaction.kt
index f0f4a3c..526d907 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTransaction.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/getTransaction.kt
@@ -3,6 +3,7 @@ package net.avianlabs.solana.methods
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.*
import net.avianlabs.solana.SolanaClient
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.domain.core.Commitment
/**
@@ -15,19 +16,17 @@ import net.avianlabs.solana.domain.core.Commitment
public suspend fun SolanaClient.getTransaction(
signature: String,
commitment: Commitment? = null,
-): TransactionResponse? {
- return invoke(
- method = "getTransaction",
- params = buildJsonArray {
- add(signature)
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response = invoke(
+ method = "getTransaction",
+ params = buildJsonArray {
+ add(signature)
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
-}
+ }
+)
@Serializable
public data class TransactionResponse(
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/isBlockHashValid.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/isBlockHashValid.kt
index 15b6e3a..6bb5908 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/isBlockHashValid.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/isBlockHashValid.kt
@@ -5,7 +5,8 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
-import net.avianlabs.solana.client.RpcResponse.RPC
+import net.avianlabs.solana.client.Response
+import net.avianlabs.solana.client.Response.RPC
import net.avianlabs.solana.domain.core.Commitment
/**
@@ -20,18 +21,15 @@ public suspend fun SolanaClient.isBlockHashValid(
blockHash: String,
commitment: Commitment? = null,
minContextSlot: Long? = null,
-): Boolean {
- val result = invoke>(
- method = "isBlockhashValid",
- params = buildJsonArray {
- add(blockHash)
- if (listOfNotNull(commitment, minContextSlot).isNotEmpty()) {
- addJsonObject {
- commitment?.let { put("commitment", it.value) }
- minContextSlot?.let { put("minContextSlot", it) }
- }
+): Response> = invoke(
+ method = "isBlockhashValid",
+ params = buildJsonArray {
+ add(blockHash)
+ if (listOfNotNull(commitment, minContextSlot).isNotEmpty()) {
+ addJsonObject {
+ commitment?.let { put("commitment", it.value) }
+ minContextSlot?.let { put("minContextSlot", it) }
}
}
- )
- return result!!.value!!
-}
+ }
+)
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/requestAirdrop.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/requestAirdrop.kt
index 5df5c69..5121b9b 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/requestAirdrop.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/requestAirdrop.kt
@@ -5,6 +5,7 @@ import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.tweetnacl.ed25519.PublicKey
@@ -19,18 +20,15 @@ public suspend fun SolanaClient.requestAirdrop(
publicKey: PublicKey,
lamports: Long,
commitment: Commitment? = null
-): String {
- val result = invoke(
- method = "requestAirdrop",
- params = buildJsonArray {
- add(publicKey.toBase58())
- add(lamports)
- commitment?.let {
- addJsonObject {
- put("commitment", it.value)
- }
+): Response = invoke(
+ method = "requestAirdrop",
+ params = buildJsonArray {
+ add(publicKey.toBase58())
+ add(lamports)
+ commitment?.let {
+ addJsonObject {
+ put("commitment", it.value)
}
}
- )
- return result!!
-}
+ }
+)
diff --git a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/sendTransaction.kt b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/sendTransaction.kt
index bfe1747..f892a45 100644
--- a/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/sendTransaction.kt
+++ b/solana-kotlin/src/commonMain/kotlin/net/avianlabs/solana/methods/sendTransaction.kt
@@ -6,11 +6,13 @@ import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import net.avianlabs.solana.SolanaClient
+import net.avianlabs.solana.client.Response
import net.avianlabs.solana.domain.core.Commitment
import net.avianlabs.solana.domain.core.Transaction
/**
* Send a signed transaction to the cluster
+ *
* @param transaction The signed transaction to send
* @param skipPreflight If true, skip the preflight check
* @param preflightCommitment The commitment level to use for the preflight check
@@ -24,19 +26,16 @@ public suspend fun SolanaClient.sendTransaction(
preflightCommitment: Commitment = Commitment.Finalized,
maxRetries: Int? = null,
minContextSlot: Long? = null,
-): String {
- val result = invoke(
- method = "sendTransaction",
- params = buildJsonArray {
- add(transaction.serialize().encodeBase64())
- add(buildJsonObject {
- put("encoding", "base64")
- put("skipPreflight", skipPreflight)
- put("preflightCommitment", preflightCommitment.value)
- maxRetries?.let { put("maxRetries", it) }
- minContextSlot?.let { put("minContextSlot", it) }
- })
- }
- )
- return result!!
-}
+): Response = invoke(
+ method = "sendTransaction",
+ params = buildJsonArray {
+ add(transaction.serialize().encodeBase64())
+ add(buildJsonObject {
+ put("encoding", "base64")
+ put("skipPreflight", skipPreflight)
+ put("preflightCommitment", preflightCommitment.value)
+ maxRetries?.let { put("maxRetries", it) }
+ minContextSlot?.let { put("minContextSlot", it) }
+ })
+ }
+)
diff --git a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt
index c81b8b9..41fd5f8 100644
--- a/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt
+++ b/solana-kotlin/src/commonTest/kotlin/net/avianlabs/solana/domain/program/SystemProgramTest.kt
@@ -32,9 +32,10 @@ class SystemProgramTest {
val balance = client.getBalance(keypair.publicKey)
println("Balance: $balance")
- val rentExempt = client.getMinimumBalanceForRentExemption(SystemProgram.NONCE_ACCOUNT_LENGTH)
+ val rentExempt =
+ client.getMinimumBalanceForRentExemption(SystemProgram.NONCE_ACCOUNT_LENGTH).result!!
- val blockhash = client.getLatestBlockhash()
+ val blockhash = client.getLatestBlockhash().result!!.value
val initTransaction = Transaction()
.addInstruction(
@@ -84,12 +85,12 @@ class SystemProgramTest {
.build()
.sign(keypair)
- val testSignature = client.sendTransaction(testTransaction)
+ val testSignature = client.sendTransaction(testTransaction).result!!
println("Advanced nonce account: $testSignature")
delay(15.seconds)
- val testTxInfo = client.getTransaction(testSignature, Commitment.Confirmed)
+ val testTxInfo = client.getTransaction(testSignature, Commitment.Confirmed).result
println("Transaction info: ${testTxInfo?.decode()}")
val newNonce = client.getNonce(nonceAccount.publicKey, Commitment.Processed)