ProtocolEngine with typed configuration, storage providers, events, telemetry and transport callbacks. Every engine method has a typed wrapper generated from the SDK’s interface definition, so a new method or configuration field reaches C# when the binding is regenerated.
Install
The binding ships as source inbindings/csharp and is not on NuGet. Check out the release and add a project reference:
The SDK loads the library from the directory in
OFFLINE_PROTOCOL_LIBRARY_DIR when it is set, and otherwise from the application directory and the system paths. Take the source and the library from the same release.
Quick start
engine.Services and engine.Data, for example service subscriptions:
Storage
InitializeMlsWithFileStoresAsync uses the built-in file stores, sealed under a 32-byte store key, given in base64, that you keep out of the source. For your own backend, implement IProtocolStorage, wrap it in a NativeStorageProvider and pass two providers to InitializeMlsAsync. Prove a backend first with ProtocolEngine.RunStorageConformanceAsync. A provider is single use: to probe a backend and then use it, wrap the same IProtocolStorage in a new provider. MemoryProtocolStorage is an in-memory backend for tests.
Threads, events and callbacks
- One engine thread. Every call for an engine runs on its own .NET thread behind a bounded queue (512 calls by default). Await each call; a slow call such as
StartAsyncdelays every call queued behind it. Cancelling a call ends your wait, not a call already queued. - Events off the engine thread.
SetEventCallbackAsyncdelivers each event as JSON on a dedicated delivery thread. A handler that throws is counted inEventHandlerFailureCountand never ends the process.PollEventAsyncreads the same events without a callback. Keep handlers short and never call the same engine synchronously from one. - Transport callbacks.
SetBleTransportCallbackAsync,SetWifiDirectTransportCallbackAsync,SetReticulumTransportCallbackAsyncandSetNostrTransportCallbackAsyncsignal that a carrier has outbound frames. Drain them with the generated methods, such asBleGetNextFragmentAsync, until the queue answersnull. Install them beforeStartAsync. - Dispose before exit. WinUI, WPF and MAUI hosts call
DisposeAsyncbefore the application shuts down, so telemetry flushes and transports stop cleanly.
What your host provides
- Transports. The radios and sockets, through the transport callbacks and the generated transport methods.
- Storage. The built-in file stores or two providers, as above.
- Telemetry lifecycle. If you enable telemetry with
EnableTelemetryAsync, the library fillsosand the binding fillsos_major. CallNotifyAppStateAsyncwhen a desktop app leaves and returns to the foreground.
Reference
- C# binding README: building, testing and the consumer check.
- C# binding contract: the engine thread, events, storage providers, telemetry, typed configuration and transport callbacks.
- C binding: the C API the binding calls.

