Android compatibility
Scope and identity
The Softchat Android application keeps its own event objects, Room storage, outbox, relay protocol owner and UI. Since v0.1 it delegates four things to the SDK: legacy event cryptography, legacy gift-wrap envelopes, one native relay connection, and streaming attachment encryption. This contract covers exactly those operations. The Rust account runtime and its storage are not used by the application and are covered by the other contracts.
Supported behavior
Legacy event objects
android.legacy.event-objects — Signing and validation accept the
application's Int kinds, Long timestamps and raw tag arrays, including empty
arrays and trailing empty fields, and return them unchanged. The portable event
limits are not widened. IDs and BIP-340 signatures are always verified; a
structurally valid event with a wrong ID or signature is rejected.
Legacy envelopes
android.legacy.envelope — Wrapping checks that the rumor's ID and author
match this identity before encryption, keeps the caller's timestamp and alert
policy, and uses fresh wrapper keys and nonces every time. Reading authenticates
the outer event and the seal before any plaintext is returned, accepts only the
legacy two-byte NIP-44 length prefix, and leaves recipient selection to the
caller. A forged rumor cannot hide behind a valid envelope.
Native connection lifecycle
android.native-connection.lifecycle — The Android compatibility factory
completes a send when its bounded queue accepts the frame and then owns that
frame. Input keeps flowing while a write is blocked. A send cancelled while
queued is never written; cancelling an active write discards the connection.
A full receive queue does not block sends or shutdown, and shutdown ends a
stalled TLS handshake. A plain-WS peer reset ends input without inventing a
failure, so the application's heartbeat and retry policy decide what happens.
Secure WebSockets use bounded ten-second output windows instead of a
whole-message deadline.
Platform trust
android.native-connection.platform-trust — Secure connections verify the
certificate chain with Android's hostname-aware trust manager, including the
application's base and domain network-security policy, while Rustls verifies
the hostname and handshake signatures.
Attachment streams
android.attachment.stream — Streaming encryption and decryption keep the
released combined format (nonce, ciphertext, tag), accept an imported key
without exporting it again, support empty files and cancellation, and
authenticate before the caller may publish decrypted output.
Persistence semantics
None. These operations open no database and keep no account state. The Android application owns Room, the outbox, retries and staging files; see the application's incremental Rust client documentation.
Observable behavior
Each operation returns a value or a typed, redacted failure. A successful send is queue acceptance, never relay acceptance; the application waits for its own protocol acknowledgement.
Verification and limits
Rust host tests and the Kotlin facade tests on the JVM run in CI for every change. Platform trust runs only on an Android device through the packed consumer application. The application's own device suites, including real Softrelay exchanges, are recorded in the Android repository. Physical network changes, Doze and production relay delivery are not established by this contract. Implementation entry points are in compat/android/events.rs and transport/connection.rs.
No execution report is bundled with this documentation. Linked test cases describe verification scope; their existence is not a passing result.
| Invariant | Required environments | Execution evidence |
|---|---|---|
android.legacy.event-objectsrust-core | rust-host, android-jvm | missing6 mapped test cases
|
android.legacy.enveloperust-core | rust-host, android-jvm | missing7 mapped test cases
Shared requirements |
android.native-connection.lifecyclerust-core | rust-host, android-jvm | missing11 mapped test cases
|
android.native-connection.platform-trustplatform-adapter | android-device | missing2 mapped test cases
|
android.attachment.streamrust-core | rust-host, android-jvm | missing4 mapped test cases
|