Softchat
The public Kotlin/JVM and Android facade for portable Softchat identity, events, private messaging, chat/account projections, relay state, Noise, synchronization, media transforms, request plans, and diagnostics.
Import a local identity once and keep it in a normal val. It is not a closeable block resource. Immutable messages, event drafts, and signed events are Kotlin-owned values; generated UniFFI/JNA types remain internal.
val alice = SoftchatIdentity.import(aliceSecretBytes)
aliceSecretBytes.fill(0)
val bob = SoftchatIdentity.import(bobSecretBytes)
bobSecretBytes.fill(0)
val encrypted = alice.encrypt(bob.publicKey, "hello")
check(bob.decrypt(encrypted) == "hello")
val draft =
NostrEventDraft(
createdAt = 1_700_000_000,
kind = NostrEventKind.SHORT_TEXT_NOTE,
tags = listOf(NostrTag.of("p", bob.publicKey.hex, "", "")),
content = "A signed protocol event",
)
val authored = alice.sign(draft)
val received = SignedNostrEvent.parse(authored.toJson())
check(received == authored)Construction validates values in Rust. Signing always uses the caller's explicit timestamp and preserves exact tag fields and order. Stable failures are represented by the sealed SoftchatException hierarchy.
HTTP execution, files, persistence, Android lifecycle, and background work remain platform-owned.
The complete operation cookbook is generated from the shared five-language source at https://softchat-sdk.jackl.dev/?lang=kotlin. Android developers should select https://softchat-sdk.jackl.dev/?lang=android for dispatcher, Room, WorkManager, file-staging, and device-performance guidance. Dokka is the exact symbol reference; it does not duplicate those lifecycle recipes.