diff --git a/examples/cbindings/Makefile b/examples/cbindings/Makefile index aa26a01..ed2d923 100644 --- a/examples/cbindings/Makefile +++ b/examples/cbindings/Makefile @@ -2,7 +2,7 @@ CC = gcc CFLAGS = -Wall -Wextra -I../../library -pthread -LDFLAGS = -L../../build -lchat -lncurses -Wl,-rpath,../../build +LDFLAGS = -L../../build -llogoschat -lncurses -Wl,-rpath,../../build BUILD_DIR = ../../build TARGET = $(BUILD_DIR)/cbindings_chat_tui diff --git a/examples/cbindings/cbindings_chat_tui.c b/examples/cbindings/cbindings_chat_tui.c index 16c4a9e..5bc3faf 100644 --- a/examples/cbindings/cbindings_chat_tui.c +++ b/examples/cbindings/cbindings_chat_tui.c @@ -30,9 +30,7 @@ static const size_t MAX_INPUT_LEN = 2048; // Application state structures typedef struct { char current_convo[128]; - char inbox_id[128]; char my_name[64]; - char my_address[128]; void *ctx; } ChatState; @@ -442,23 +440,13 @@ static void bundle_callback(int ret, const char *msg, size_t len, void *userData static void identity_callback(int ret, const char *msg, size_t len, void *userData) { (void)userData; (void)len; if (ret == RET_OK) { - const char *keys[] = {"name", "address"}; - char *values[] = {g_app.chat.my_name, g_app.chat.my_address}; - size_t sizes[] = {sizeof(g_app.chat.my_name), sizeof(g_app.chat.my_address)}; - json_extract(msg, keys, values, sizes, 2); - - char buf[256]; - snprintf(buf, sizeof(buf), "Identity: %s (%.24s...)", g_app.chat.my_name, g_app.chat.my_address); - add_log(buf); - } -} + const char *keys[] = {"name"}; + char *values[] = {g_app.chat.my_name}; + size_t sizes[] = {sizeof(g_app.chat.my_name)}; + json_extract(msg, keys, values, sizes, 1); -static void inbox_callback(int ret, const char *msg, size_t len, void *userData) { - (void)userData; - if (ret == RET_OK && len > 0) { - snprintf(g_app.chat.inbox_id, sizeof(g_app.chat.inbox_id), "%.*s", (int)len, msg); char buf[256]; - snprintf(buf, sizeof(buf), "Inbox: %.24s...", g_app.chat.inbox_id); + snprintf(buf, sizeof(buf), "Identity: %s", g_app.chat.my_name); add_log(buf); } } @@ -713,7 +701,6 @@ int main(int argc, char *argv[]) { add_log("Starting client..."); chat_start(g_app.chat.ctx, general_callback, NULL); chat_get_identity(g_app.chat.ctx, identity_callback, NULL); - chat_get_default_inbox_id(g_app.chat.ctx, inbox_callback, NULL); add_message("Welcome to Chat TUI!"); add_message("Type /help for commands, /quit to exit"); diff --git a/library/api/client_api.nim b/library/api/client_api.nim index 0edb798..10c8d76 100644 --- a/library/api/client_api.nim +++ b/library/api/client_api.nim @@ -7,7 +7,6 @@ import chronos import ffi import src/chat -import src/chat/proto_types import src/chat/delivery/waku_client import src/chat/identity import library/utils @@ -119,15 +118,6 @@ proc chat_get_id( let clientId = ctx.myLib[].getId() return ok(clientId) -proc chat_get_default_inbox_id( - ctx: ptr FFIContext[ChatClient], - callback: FFICallBack, - userData: pointer -) {.ffi.} = - ## Get the default inbox conversation ID - let inboxId = ctx.myLib[].defaultInboxConversationId() - return ok(inboxId) - ################################################# # Conversation List Operations ################################################# diff --git a/library/api/conversation_api.nim b/library/api/conversation_api.nim index 97d7919..faab6fd 100644 --- a/library/api/conversation_api.nim +++ b/library/api/conversation_api.nim @@ -1,14 +1,13 @@ ## Conversation API - FFI bindings for conversation operations ## Uses the {.ffi.} pragma for async request handling -import std/[json, options] +import std/options import chronicles import chronos import ffi import stew/byteutils import src/chat -import src/chat/proto_types import library/utils logScope: @@ -22,32 +21,24 @@ proc chat_new_private_conversation( ctx: ptr FFIContext[ChatClient], callback: FFICallBack, userData: pointer, - introBundleJson: cstring, + introBundleStr: cstring, contentHex: cstring ) {.ffi.} = ## Create a new private conversation with the given IntroBundle - ## introBundleJson: JSON string with {"ident": "hex...", "ephemeral": "hex..."} + ## introBundleStr: Intro bundle ASCII string as returned by chat_create_intro_bundle ## contentHex: Initial message content as hex-encoded string try: - let bundleJson = parseJson($introBundleJson) - - # Parse IntroBundle from JSON - let identBytes = hexToSeqByte(bundleJson["ident"].getStr()) - let ephemeralBytes = hexToSeqByte(bundleJson["ephemeral"].getStr()) - - let introBundle = IntroBundle( - ident: identBytes, - ephemeral: ephemeralBytes - ) - + # Convert bundle string to seq[byte] + let bundle = toBytes($introBundleStr) + # Convert hex content to bytes let content = hexToSeqByte($contentHex) - + # Create the conversation - let errOpt = await ctx.myLib[].newPrivateConversation(introBundle, content) + let errOpt = await ctx.myLib[].newPrivateConversation(bundle, content) if errOpt.isSome(): return err("failed to create conversation: " & $errOpt.get()) - + return ok("") except CatchableError as e: error "chat_new_private_conversation failed", error = e.msg diff --git a/library/api/identity_api.nim b/library/api/identity_api.nim index 2503242..439a72a 100644 --- a/library/api/identity_api.nim +++ b/library/api/identity_api.nim @@ -8,8 +8,6 @@ import ffi import stew/byteutils import src/chat -import src/chat/crypto -import src/chat/proto_types import library/utils logScope: @@ -25,12 +23,9 @@ proc chat_get_identity( userData: pointer ) {.ffi.} = ## Get the client identity - ## Returns JSON string: {"name": "...", "address": "...", "pubkey": "hex..."} - let ident = ctx.myLib[].identity() + ## Returns JSON string: {"name": "..."} let identJson = %*{ - "name": ident.getName(), - "address": ident.getAddr(), - "pubkey": ident.getPubkey().toHex() + "name": ctx.myLib[].getId() } return ok($identJson) @@ -44,11 +39,7 @@ proc chat_create_intro_bundle( userData: pointer ) {.ffi.} = ## Create an IntroBundle for initiating private conversations - ## Returns JSON string: {"ident": "hex...", "ephemeral": "hex..."} + ## Returns the intro bundle as an ASCII string (format: logos_chatintro__) let bundle = ctx.myLib[].createIntroBundle() - let bundleJson = %*{ - "ident": bundle.ident.toHex(), - "ephemeral": bundle.ephemeral.toHex() - } - return ok($bundleJson) + return ok(string.fromBytes(bundle)) diff --git a/library/liblogoschat.h b/library/liblogoschat.h index d0aac93..487a903 100644 --- a/library/liblogoschat.h +++ b/library/liblogoschat.h @@ -58,9 +58,6 @@ void set_event_callback(void *ctx, FFICallBack callback, void *userData); // Get the client's identifier int chat_get_id(void *ctx, FFICallBack callback, void *userData); -// Get the default inbox conversation ID -int chat_get_default_inbox_id(void *ctx, FFICallBack callback, void *userData); - ////////////////////////////////////////////////////////////////////////////// // Conversation Operations ////////////////////////////////////////////////////////////////////////////// @@ -75,10 +72,10 @@ int chat_get_conversation(void *ctx, FFICallBack callback, void *userData, const char *convoId); // Create a new private conversation with the given IntroBundle -// introBundleJson: JSON string with {"ident": "hex...", "ephemeral": "hex..."} +// introBundleStr: Intro bundle ASCII string as returned by chat_create_intro_bundle // contentHex: Initial message content as hex-encoded string int chat_new_private_conversation(void *ctx, FFICallBack callback, - void *userData, const char *introBundleJson, + void *userData, const char *introBundleStr, const char *contentHex); // Send a message to a conversation @@ -93,11 +90,11 @@ int chat_send_message(void *ctx, FFICallBack callback, void *userData, ////////////////////////////////////////////////////////////////////////////// // Get the client identity -// Returns JSON: {"name": "...", "address": "...", "pubkey": "hex..."} +// Returns JSON: {"name": "..."} int chat_get_identity(void *ctx, FFICallBack callback, void *userData); // Create an IntroBundle for initiating private conversations -// Returns JSON: {"ident": "hex...", "ephemeral": "hex..."} +// Returns the intro bundle as an ASCII string (format: logos_chatintro__) int chat_create_intro_bundle(void *ctx, FFICallBack callback, void *userData); #ifdef __cplusplus diff --git a/library/liblogoschat.nim b/library/liblogoschat.nim index f0f87f3..87f8de0 100644 --- a/library/liblogoschat.nim +++ b/library/liblogoschat.nim @@ -10,10 +10,8 @@ import stew/byteutils import src/chat/client, - src/chat/conversations, src/chat/identity, src/chat/delivery/waku_client, - src/chat/proto_types, library/declare_lib, library/utils diff --git a/src/chat/client.nim b/src/chat/client.nim index 0545930..3717311 100644 --- a/src/chat/client.nim +++ b/src/chat/client.nim @@ -139,7 +139,7 @@ proc notifyDeliveryAck(client: ChatClient, convo: Conversation, # Functional ################################################# -proc createIntroBundle*(self: var ChatClient): seq[byte] = +proc createIntroBundle*(self: ChatClient): seq[byte] = ## Generates an IntroBundle for the client, which includes ## the required information to send a message. result = self.libchatCtx.createIntroductionBundle().valueOr: @@ -198,6 +198,10 @@ proc parseMessage(client: ChatClient, msg: ChatPayload) {.raises: [ValueError].} if opt_content.isSome(): let content = opt_content.get() let convo = client.getConversation(content.conversationId) + + if content.isNewConvo: + client.notifyNewConversation(convo) + # TODO: (P1) Add sender information from LibChat. let msg = ReceivedMessage(timestamp:getCurrentTimestamp(),content: content.data ) client.notifyNewMessage(convo, msg) diff --git a/vendor/libchat b/vendor/libchat index d903eac..a9ca4ff 160000 --- a/vendor/libchat +++ b/vendor/libchat @@ -1 +1 @@ -Subproject commit d903eac011f31b9db83c0860235341d4340cf5f0 +Subproject commit a9ca4ffb7de90ea4cd269350c189c19fb78a2589