Skip to content

Latest commit

 

History

History
84 lines (71 loc) · 3.39 KB

README.md

File metadata and controls

84 lines (71 loc) · 3.39 KB

Java example

Two devices, Alice and Bob, in one JVM: they pair, establish an end-to-end encrypted session, use conversation signals, transfer a file, and create an MLS group, using the Java binding.

alice off1q89jrev...
bob   off1q9jxmhy...
  ok: bob and alice are paired
  ok: bob sees alice online
  ok: bob sees alice typing
  ok: bob received "hello bob" (encrypted end to end)
  ok: alice received a read receipt
  ok: alice received a threaded reply
  ok: bob received the original file bytes
  ok: bob joined the MLS group
  ok: bob received the group message
alice transport [Internet]
group members [off1..., off1...]
done

What it shows

  • Creating an engine from a ProtocolConfig (every field spelled out: the generated Java record has no defaults, see J2).
  • The engine's own encrypted file stores (initializeMlsWithFileStores), so no storage provider is needed.
  • Pairing from events: the app reads pollEvent(), and answers connection_request_received and connection_accepted with the key package exchange.
  • Presence and typing indicators, followed by a normal encrypted message, a read receipt tied to its message ID, and a high-priority rich reply threaded to the original message.
  • sendFile with byte-for-byte verification of the reassembled file_received event. That event contains base64-encoded data for the host to save or use.
  • Creating an MLS group, inviting the paired peer, and sending a group message.
  • Reading active transports and group membership back from the SDK.
  • A transport's job, in a dozen lines: take what an engine wants to send (internetGetNextMessage) and hand it to the engine it is addressed to (internetMessageReceived), then acknowledge the successful carrier write (internetConfirmSent). A real app does this over a radio or a socket. Everything else here, the pairing, the MLS session and the encryption, is the engine's own.

The in-process carrier delivers frames directly between the two engines. It does not act as an internet relay or record transport metrics; the event checks show that the SDK processed each feature end to end.

Run it

You need JDK 22 or later and the native library.

cargo build -p offline-protocol-uniffi      # from the repository root
cd examples/java-app
gradle run                                   # Gradle 9; -PnativeLibrary=<file> for another library

settings.gradle.kts includes bindings/java as a composite build and substitutes it for the published coordinate, so the example runs against the source in this checkout. In your own project, drop that block and depend on a release from Maven Central:

dependencies {
    implementation("com.offlineprotocol:offline-protocol-java:<version>")
}

Run on JDK 22 or later with --enable-native-access=ALL-UNNAMED and the library's path in -Duniffi.component.offline_protocol.libraryOverride=<file> (or on java.library.path); build.gradle.kts does both for gradle run.

Where to go next

  • Callbacks (EventCallback, transports, storage providers) run on the engine's thread and must not call back in: J4.
  • The host fills the telemetry platform: J3.