Channel traffic could not flow at all: the Encrypt/Decrypt brokers had no provider registered, so every segment failed with "no provider registered for input signature" and the send surfaced as "one or more segments failed". createReliableChannel documents that providers must be installed first, but library/ never installed any and exposed no way for a caller to, which made the channel API unusable through the FFI. The mechanism is named per channel rather than defaulted, so nothing silently gets pass-through "encryption" on a network built for private messaging -- the caller has to say "noop" and mean it. Only noop exists today; anything else is rejected rather than ignored. Caveat, noted in the code: the brokers dispatch to one provider process-wide, so the per-channel name installs a global provider and channels asking for different mechanisms would fight over it. Naming it at creation is still the right seam for when real providers land. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Logos Messaging API (LMAPI) Library
A C FFI library providing a simplified interface to Logos Messaging functionality.
Overview
This library wraps the high-level API functions from waku/api/api.nim and exposes them via a C FFI interface, making them accessible from C, C++, and other languages that support C FFI.
API Functions
Node Lifecycle
logosdelivery_create_node
Creates a new instance of the node from the given configuration JSON.
void *logosdelivery_create_node(
const char *configJson,
FFICallBack callback,
void *userData
);
Parameters:
configJson: JSON string containing node configurationcallback: Callback function to receive the resultuserData: User data passed to the callback
Returns: Pointer to the context needed by other API functions, or NULL on error.
Example configuration JSON:
{
"mode": "Core",
"preset": "logos.dev",
"messagingOverrides": {
"listen-address": "0.0.0.0",
"tcp-port": 60000,
"discv5-udp-port": 9000
}
}
The configuration object has four optional top-level keys: mode ("Core" or
"Edge", defaults to "Core"), preset, messagingOverrides (per-field node
config overrides), and channelsOverrides (reliable-channel overrides).
Override keys accept the config field name or its CLI switch name (e.g.
"clusterId" or "cluster-id"); unknown keys are rejected.
Use "preset" to select a network preset (e.g., "twn", "logos.dev",
"status.prod") which auto-configures entry nodes, cluster ID, sharding, and
other network-specific settings.
Available presets:
| Preset | Cluster ID | RLN | Sharding | Network |
|---|---|---|---|---|
twn |
1 | on | auto (8 shards) | The Waku Network |
logos.dev |
2 | off | auto (8 shards) | Logos Dev Network |
logos.test |
2 | off | auto (8 shards) | Logos Test Network |
status.prod |
16 | off | auto (1 shard) | Status Production Network |
logosdelivery_start_node
Starts the node.
int logosdelivery_start_node(
void *ctx,
FFICallBack callback,
void *userData
);
logosdelivery_stop_node
Stops the node.
int logosdelivery_stop_node(
void *ctx,
FFICallBack callback,
void *userData
);
logosdelivery_destroy
Destroys a node instance and frees resources.
int logosdelivery_destroy(
void *ctx,
FFICallBack callback,
void *userData
);
Messaging
logosdelivery_subscribe
Subscribe to a content topic to receive messages.
int logosdelivery_subscribe(
void *ctx,
FFICallBack callback,
void *userData,
const char *contentTopic
);
Parameters:
ctx: Context pointer fromlogosdelivery_create_nodecallback: Callback function to receive the resultuserData: User data passed to the callbackcontentTopic: Content topic string (e.g., "/myapp/1/chat/proto")
logosdelivery_unsubscribe
Unsubscribe from a content topic.
int logosdelivery_unsubscribe(
void *ctx,
FFICallBack callback,
void *userData,
const char *contentTopic
);
logosdelivery_send
Send a message.
int logosdelivery_send(
void *ctx,
FFICallBack callback,
void *userData,
const char *messageJson
);
Parameters:
messageJson: JSON string containing the message
Example message JSON:
{
"contentTopic": "/myapp/1/chat/proto",
"payload": "SGVsbG8gV29ybGQ=",
"ephemeral": false
}
Note: The payload field should be base64-encoded.
Returns: Request ID in the callback message that can be used to track message delivery.
Events
logosdelivery_add_event_listener
Registers a callback invoked whenever the named event fires (e.g., message received). Listeners are registered per event name, so register once for each event you want to observe.
uint64_t logosdelivery_add_event_listener(
void *ctx,
const char *eventName,
FFICallBack callback,
void *userData
);
Returns: The listener id (> 0), or 0 if callback is NULL.
Event names: onMessageSent, onMessageError, onMessagePropagated,
onMessageReceived, onConnectionStatusChange, onTopicHealthChange,
onConnectionChange, onChannelMessageReceived, onChannelMessageSent,
onChannelMessageError, onReceivedMessage.
logosdelivery_remove_event_listener
Unregisters a previously added listener.
int logosdelivery_remove_event_listener(
void *ctx,
uint64_t listenerId
);
Returns: RET_OK when a listener was removed, RET_ERR otherwise.
Important: The callback should be fast, non-blocking, and thread-safe.
Building
The library follows the same build system as the main Logos Messaging project.
Build the library
make liblogosdeliveryStatic # Build static library
# or
make liblogosdeliveryDynamic # Build dynamic library
Return Codes
All functions that return int use the following return codes:
RET_OK(0): SuccessRET_ERR(1): ErrorRET_MISSING_CALLBACK(2): Missing callback function
Callback Function
All API functions use the following callback signature:
typedef void (*FFICallBack)(
int callerRet,
const char *msg,
size_t len,
void *userData
);
Parameters:
callerRet: Return code (RET_OK, RET_ERR, etc.)msg: Response message (may be empty for success)len: Length of the messageuserData: User data passed in the original call
Example Usage
#include "liblogosdelivery.h"
#include <stdio.h>
void callback(int ret, const char *msg, size_t len, void *userData) {
if (ret == RET_OK) {
printf("Success: %.*s\n", (int)len, msg);
} else {
printf("Error: %.*s\n", (int)len, msg);
}
}
int main() {
const char *config = "{"
"\"logLevel\": \"INFO\","
"\"mode\": \"Core\","
"\"preset\": \"logos.dev\""
"}";
// Create node
void *ctx = logosdelivery_create_node(config, callback, NULL);
if (ctx == NULL) {
return 1;
}
// Start node
logosdelivery_start_node(ctx, callback, NULL);
// Subscribe to a topic
logosdelivery_subscribe(ctx, callback, NULL, "/myapp/1/chat/proto");
// Send a message
const char *msg = "{"
"\"contentTopic\": \"/myapp/1/chat/proto\","
"\"payload\": \"SGVsbG8gV29ybGQ=\","
"\"ephemeral\": false"
"}";
logosdelivery_send(ctx, callback, NULL, msg);
// Clean up
logosdelivery_stop_node(ctx, callback, NULL);
logosdelivery_destroy(ctx, callback, NULL);
return 0;
}
Architecture
The library is structured as follows:
liblogosdelivery.h: C header file with function declarationsliblogosdelivery.nim: Main library entry pointdeclare_lib.nim: Library declaration and initializationlmapi/node_api.nim: Node lifecycle API implementationlmapi/messaging_api.nim: Subscribe/send API implementation
The library uses the nim-ffi framework for FFI infrastructure, which handles:
- Thread-safe request processing
- Async operation management
- Memory management between C and Nim
- Callback marshaling
See Also
- Main API documentation:
waku/api/api.nim - Original libwaku library:
library/libwaku.nim - nim-ffi framework:
vendor/nim-ffi/