Kotlin SDK for Privara CoFHE — Fully Homomorphic Encryption (FHE) service powered by Fhenix CoFHE.
- ✅ Type-safe API — Compile-time validation for all FHE types
- ✅ Coroutines support — All methods are
suspendfunctions - ✅ Batch encryption — Encrypt up to 10 values in a single request
- ✅ Error handling — RFC 7807 Problem Details with typed exceptions
- ✅ Health checks — Liveness and readiness probes
- ✅ Pure JVM — Works with any Kotlin/JVM project
GitHub Packages requires authentication. Create a Personal Access Token with read:packages scope and add to ~/.gradle/gradle.properties:
gpr.user=YOUR_GITHUB_USERNAME
gpr.token=ghp_YOUR_TOKENThen add to your build.gradle.kts:
repositories {
maven {
url = uri("https://maven.pkg.github.com/PrivaraXYZ/platform-cofhe-kotlin-sdk")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
password = project.findProperty("gpr.token") as String? ?: System.getenv("GITHUB_TOKEN")
}
}
}
dependencies {
implementation("xyz.privara:cofhe-sdk:0.1.0")
}import xyz.privara.cofhe.sdk.CoFheClient
import xyz.privara.cofhe.sdk.model.BatchItem
import java.math.BigInteger
suspend fun main() {
val client = CoFheClient {
baseUrl = "https://cofhe.privara.xyz"
}
// Encrypt a single value
val encrypted = client.encryptUint64(
value = BigInteger("1000000"),
userAddress = "0x1234567890123456789012345678901234567890"
)
println("Encrypted: ${encrypted.data}")
println("Proof: ${encrypted.inputProof}")
// Batch encryption
val batch = client.encryptBatch(
userAddress = "0x1234567890123456789012345678901234567890",
items = listOf(
BatchItem.uint64(BigInteger("1000000")),
BatchItem.bool(true),
BatchItem.address("0xabcdef0123456789abcdef0123456789abcdef01")
)
)
println("Encrypted ${batch.results.size} values in ${batch.totalEncryptionTimeMs}ms")
client.close()
}// 8-bit unsigned integer (0..255)
client.encryptUint8(value: Int, userAddress: String): EncryptedValue
// 16-bit unsigned integer (0..65535)
client.encryptUint16(value: Int, userAddress: String): EncryptedValue
// 32-bit unsigned integer (0..4294967295)
client.encryptUint32(value: Long, userAddress: String): EncryptedValue
// 64-bit unsigned integer
client.encryptUint64(value: BigInteger, userAddress: String): EncryptedValue
// 128-bit unsigned integer
client.encryptUint128(value: BigInteger, userAddress: String): EncryptedValue
// 256-bit unsigned integer
client.encryptUint256(value: BigInteger, userAddress: String): EncryptedValue
// Ethereum address (0x + 40 hex chars)
client.encryptAddress(value: String, userAddress: String): EncryptedValue
// Boolean
client.encryptBool(value: Boolean, userAddress: String): EncryptedValueclient.encrypt(
type: EncryptionType,
value: Any,
userAddress: String
): EncryptedValueclient.encryptBatch(
userAddress: String,
items: List<BatchItem>
): BatchEncryptResult
// Factory methods for BatchItem
BatchItem.uint8(value: Int)
BatchItem.uint16(value: Int)
BatchItem.uint32(value: Long)
BatchItem.uint64(value: BigInteger)
BatchItem.uint128(value: BigInteger)
BatchItem.uint256(value: BigInteger)
BatchItem.address(value: String)
BatchItem.bool(value: Boolean)// Liveness probe (returns true if service is running)
client.isAlive(): Boolean
// Readiness probe (returns true if FHE SDK is initialized)
client.isReady(): Boolean
// Detailed readiness status
client.healthReady(): HealthStatusval client = CoFheClient {
baseUrl = "https://cofhe.privara.xyz"
requestTimeout = 120.seconds // default: 60s
connectTimeout = 10.seconds // default: 10s
socketTimeout = 60.seconds // default: 60s
enableLogging = true // default: false
engine = mockEngine // for testing (default: OkHttp)
}All errors throw CoFheException sealed class with specific subtypes:
try {
client.encryptUint64(value, userAddress)
} catch (e: CoFheException.Timeout) {
// Retry
} catch (e: CoFheException.NotInitialized) {
// Wait and retry
} catch (e: CoFheException.ValidationFailed) {
// Check invalidParams
e.invalidParams.forEach { println("${it.name}: ${it.reason}") }
} catch (e: CoFheException.NetworkError) {
// Connection failed
} catch (e: CoFheException) {
// HTTP status code available
println("Error: ${e.message} (HTTP ${e.statusCode})")
}Server errors:
ValidationFailed(400) — Request validation error withinvalidParamsInvalidAddress(422) — Invalid Ethereum address formatInvalidValue(422) — Value out of range for typeUnsupportedType(422) — Unknown encryption typeEncryptionFailed(500) — FHE encryption operation failedInternalServerError(500) — Generic server errorNotInitialized(503) — FHE SDK not initialized yetInitializationFailed(503) — FHE SDK initialization failedPoolExhausted(503) — Too many concurrent requestsTimeout(504) — Encryption timeoutUnknownServerError— Unknown URN from server
Client errors:
NetworkError— Connection/DNS/TLS failureSerializationError— JSON parsing failure
data class EncryptedValue(
val type: EncryptionType, // euint64, ebool, etc.
val data: String, // hex ctHash for smart contract
val securityZone: Int, // FHE security zone
val utype: Int, // FHE type identifier
val inputProof: String, // hex ZK proof
val encryptionTimeMs: Long // encryption duration
)The SDK uses Ktor MockEngine for unit testing:
val mockEngine = MockEngine { request ->
respond(
content = """{"type":"euint64","data":"0x123..."}""",
headers = headersOf(HttpHeaders.ContentType, "application/json")
)
}
val client = CoFheClient {
baseUrl = "http://test"
engine = mockEngine
}Integration tests use WireMock to test real HTTP communication without requiring a running service:
@Tag("integration")
class CoFheClientIntegrationTest {
@RegisterExtension
val wireMock = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort())
.build()
@Test
fun test() {
wireMock.stubFor(post("/api/v1/encrypt/uint64")
.willReturn(aResponse().withStatus(200)...))
val client = CoFheClient { baseUrl = wireMock.baseUrl() }
// Test real HTTP communication
}
}End-to-end tests run against a real CoFHE service (manual testing only):
Run tests:
./gradlew :sdk:test # Unit tests (61 tests)
./gradlew :sdk:integrationTest # Integration tests with WireMock (9 tests)
./gradlew :sdk:e2eTest # E2E tests (requires COFHE_BASE_URL env var)
./gradlew :sdk:check # All checks (unit + integration tests)- JVM: Targets JVM 17 bytecode, built with Java 21 toolchain
- Android: Can be converted to AAR if needed (change Gradle plugin)
- iOS: Kotlin Multiplatform support possible in future
# Build
./gradlew :sdk:build
# Run tests
./gradlew :sdk:test
# Publish to GitHub Packages
SDK_VERSION=0.1.0 ./gradlew :sdk:publishMIT