diff --git a/dap-sdk/net/server/notify_server/src/dap_notify_srv.c b/dap-sdk/net/server/notify_server/src/dap_notify_srv.c
index ca8f8e226d6e8975f3dd8b468204a6b4cdf92c58..ee6492daa98365b576f1babccc84cceb6073745e 100644
--- a/dap-sdk/net/server/notify_server/src/dap_notify_srv.c
+++ b/dap-sdk/net/server/notify_server/src/dap_notify_srv.c
@@ -166,7 +166,7 @@ static void s_notify_server_callback_queue(dap_events_socket_t * a_es, void * a_
         size_t l_str_len = a_arg? strlen((char*)a_arg): 0;
         if(l_str_len)
             dap_events_socket_write_inter(a_es->worker->queue_es_io_input[l_worker_id],l_socket_handler->esocket,
-                                      a_arg,l_str_len);
+                                      a_arg,l_str_len+1);
         DAP_DELETE(a_arg);
     }
     pthread_rwlock_unlock(&s_notify_server_clients_mutex);
diff --git a/modules/net/CMakeLists.txt b/modules/net/CMakeLists.txt
index d64767b6181ae6aec139d0dc0c65d1f0ed77b055..97ab46d7e9d559de36db6a1bb18e50d91e47fa4e 100644
--- a/modules/net/CMakeLists.txt
+++ b/modules/net/CMakeLists.txt
@@ -37,16 +37,16 @@ endif()
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS})
 
 if(WIN32)
-  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_wallet dap_chain_net_srv
+  target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_ dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_wallet dap_chain_net_srv
                             dap_chain_mempool dap_chain_global_db dap_chain_net_srv_stake dap_chain_cs_none)
 endif()
 
 if(LINUX)
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto  dap_notify_srv dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain
       dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db dap_chain_net_srv_stake dap_chain_cs_none
       resolv )
 elseif(BSD)
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_notify_srv dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain
       dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db dap_chain_net_srv_stake dap_chain_cs_none )
 endif()
 
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 20b306afc403cbe58d4dd837ac2e9fcf55e9d579..7b36483f49ef737dbe614d631e60fa14b3907045 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -74,6 +74,7 @@
 #include "dap_chain_node_client.h"
 #include "dap_chain_node_cli.h"
 #include "dap_chain_node_cli_cmd.h"
+#include "dap_notify_srv.h"
 #include "dap_chain_ledger.h"
 #include "dap_chain_cs_none.h"
 
@@ -223,6 +224,10 @@ static const dap_chain_node_client_callbacks_t s_node_link_callbacks={
 // State machine switchs here
 static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg);
 
+// Notify about net states
+static void s_net_states_notify(dap_chain_net_t * l_net );
+static void s_net_links_notify(dap_chain_net_t * a_net );
+
 // Prepare link success/error endpoints
 static void s_net_state_link_prepare_success(dap_worker_t * a_worker,dap_chain_node_info_t * a_node_info, void * a_arg);
 static void s_net_state_link_prepare_error(dap_worker_t * a_worker,dap_chain_node_info_t * a_node_info, void * a_arg, int a_errno);
@@ -450,6 +455,7 @@ static void s_node_link_callback_connected(dap_chain_node_client_t * a_node_clie
     pthread_rwlock_wrlock(&l_net_pvt->rwlock);
     l_net_pvt->links = dap_list_append(l_net_pvt->links, a_node_client);
     l_net_pvt->links_connected_count++;
+    s_net_links_notify(l_net);
 
     // If we're fist time here - initiate the GDB sync
     if (! a_node_client->is_reconnecting){
@@ -532,6 +538,15 @@ static void s_node_link_callback_stage(dap_chain_node_client_t * a_node_client,d
     if( s_debug_more)
         log_it(L_INFO,"%s."NODE_ADDR_FP_STR" stage %s",l_net->pub.name,NODE_ADDR_FP_ARGS_S(a_node_client->remote_node_addr),
                                                         dap_client_stage_str(a_stage));
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkStage\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\","
+                            "stage:\"%s\""
+                        "}\n", a_node_client->net->pub.id, a_node_client->info->hdr.cell_id,
+                                NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address),
+                                dap_client_stage_str(a_stage));
 }
 
 /**
@@ -545,6 +560,15 @@ static void s_node_link_callback_error(dap_chain_node_client_t * a_node_client,
     dap_chain_net_t * l_net = (dap_chain_net_t *) a_arg;
     log_it(L_WARNING, "Can't establish link with %s."NODE_ADDR_FP_STR, l_net->pub.name,
            NODE_ADDR_FP_ARGS_S(a_node_client->remote_node_addr));
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkError\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\","
+                            "error:\%d"
+                        "}\n", a_node_client->net->pub.id, a_node_client->info->hdr.cell_id,
+                                NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address),
+                                a_error);
 }
 
 /**
@@ -570,6 +594,14 @@ static void s_node_link_callback_delete(dap_chain_node_client_t * a_node_client,
     }
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
     dap_chain_node_client_close(a_node_client);
+
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkDelete\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\""
+                        "}\n", a_node_client->net->pub.id, a_node_client->info->hdr.cell_id,
+                                NODE_ADDR_FP_ARGS_S(a_node_client->info->hdr.address));
 }
 
 /**
@@ -608,6 +640,14 @@ static void s_net_state_link_prepare_success(dap_worker_t * a_worker,dap_chain_n
         }
     }
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkPrepareSuccess\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\""
+                        "}\n", l_net->pub.id, a_node_info->hdr.cell_id,
+                                NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address));
+
 }
 
 /**
@@ -627,6 +667,15 @@ static void s_net_state_link_prepare_error(dap_worker_t * a_worker,dap_chain_nod
     log_it(L_WARNING,"Link " NODE_ADDR_FP_STR " (%s) prepare error with code %d", NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address),
                                                                                  l_node_addr_str,a_errno );
 
+    dap_notify_server_send_f_mt("{"
+                            "class:\"NetLinkPrepareError\","
+                            "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                            "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                            "address:\""NODE_ADDR_FP_STR"\","
+                            "error: %d"
+                        "}\n", l_net->pub.id, a_node_info->hdr.cell_id,
+                                NODE_ADDR_FP_ARGS_S(a_node_info->hdr.address),a_errno);
+
     pthread_rwlock_wrlock(&l_net_pvt->rwlock);
     if(l_net_pvt->links_dns_requests)
         l_net_pvt->links_dns_requests--;
@@ -644,6 +693,70 @@ static void s_net_state_link_prepare_error(dap_worker_t * a_worker,dap_chain_nod
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
 }
 
+/**
+ * @brief s_net_states_notify
+ * @param l_net
+ */
+static void s_net_states_notify(dap_chain_net_t * l_net )
+{
+    dap_notify_server_send_f_mt("{"
+                                    "class:\"NetStates\","
+                                    "net_id: 0x%016" DAP_UINT64_FORMAT_X ","
+                                    "state: \"%s\","
+                                    "state_target:\"%s\""
+                                "}\n", l_net->pub.id,
+                                       dap_chain_net_state_to_str( PVT(l_net)->state),
+                                       dap_chain_net_state_to_str(PVT(l_net)->state_target));
+
+}
+
+/**
+ * @brief s_net_links_notify
+ * @param l_net
+ */
+static void s_net_links_notify(dap_chain_net_t * a_net )
+{
+    dap_chain_net_pvt_t * l_net_pvt = PVT(a_net);
+    dap_string_t * l_str_reply = dap_string_new("[");
+
+    size_t i =0;
+    for (dap_list_t * l_item = l_net_pvt->links; l_item;  l_item = l_item->next ) {
+        dap_chain_node_client_t * l_node_client = l_item->data;
+
+        if(l_node_client){
+            dap_chain_node_info_t * l_info = l_node_client->info;
+            char l_ext_addr_v4[INET_ADDRSTRLEN]={};
+            char l_ext_addr_v6[INET6_ADDRSTRLEN]={};
+            inet_ntop(AF_INET,&l_info->hdr.ext_addr_v4,l_ext_addr_v4,sizeof (l_info->hdr.ext_addr_v4));
+            inet_ntop(AF_INET6,&l_info->hdr.ext_addr_v6,l_ext_addr_v6,sizeof (l_info->hdr.ext_addr_v6));
+
+            dap_string_append_printf(l_str_reply,"{"
+                                        "id:%u,"
+                                        "address:\""NODE_ADDR_FP_STR"\","
+                                        "alias:\"%s\","
+                                        "cell_id:0x%016"DAP_UINT64_FORMAT_X","
+                                        "ext_ipv4:\"%s\","
+                                        "ext_ipv6:\"%s\","
+                                        "ext_port:%u"
+                                        "state:\"%s\""
+                                    "}", i,NODE_ADDR_FP_ARGS_S(l_info->hdr.address), l_info->hdr.alias, l_info->hdr.cell_id,
+                                     l_ext_addr_v4, l_ext_addr_v6,l_info->hdr.ext_port
+                                     , dap_chain_node_client_state_to_str(l_node_client->state) );
+        }
+        i++;
+    }
+
+
+    dap_notify_server_send_f_mt("{"
+                                    "class:\"NetLinks\","
+                                    "net_id:0x%016" DAP_UINT64_FORMAT_X ","
+                                    "links:%s"
+                                "}\n", a_net->pub.id,
+                                       l_str_reply->str);
+    dap_string_free(l_str_reply,true);
+
+}
+
 /**
  * @brief s_net_states_proc
  * @param l_net
@@ -686,6 +799,7 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
         // Prepare links
         case NET_STATE_LINKS_PREPARE: {
             log_it(L_NOTICE,"%s.state: NET_STATE_LINKS_PREPARE", l_net->pub.name);
+            s_net_states_notify(l_net);
             uint64_t l_own_addr = dap_chain_net_get_cur_addr_int(l_net);
             if (l_net_pvt->node_info) {
                 for (size_t i = 0; i < l_net_pvt->node_info->hdr.links_number; i++) {
@@ -816,6 +930,7 @@ static bool s_net_states_proc(dap_proc_thread_t *a_thread, void *a_arg)
         break;
         default: log_it (L_DEBUG, "Unprocessed state");
     }
+    s_net_states_notify(l_net);
     pthread_rwlock_unlock(&l_net_pvt->rwlock);
 
     return ! l_repeat_after_exit;
@@ -941,6 +1056,8 @@ int dap_chain_net_init()
 {
     dap_chain_node_client_init();
     dap_chain_node_cli_cmd_item_create ("net", s_cli_net, NULL, "Network commands",
+        "net list [chains -n <chain net name>]"
+            "\tList all networks or list all chains in selected network"
         "net -net <chain net name> [-mode update|all] go < online | offline >\n"
             "\tFind and establish links and stay online. \n"
             "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
@@ -1069,24 +1186,54 @@ static int s_cli_net( int argc, char **argv, void *arg_func, char **a_str_reply)
         return -1;
     }
 
-    // command 'net list'
-    if(dap_chain_node_cli_find_option_val(argv, arg_index, argc, "list", NULL) == arg_index) {
-
-        dap_string_t *l_string_ret = dap_string_new("list of nets: ");
-        // show list of nets
-        dap_chain_net_item_t * l_net_item, *l_net_item_tmp;
-        int l_net_i = 0;
-        HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp)
-        {
-            if(l_net_i > 0)
-                dap_string_append(l_string_ret, ", ");
-            dap_string_append_printf(l_string_ret, "%s", l_net_item->name);
-            l_net_i++;
-        }
-        if(!l_net_i)
-            dap_string_append(l_string_ret, "-\n");
-        else
+    // command 'list'
+    const char * l_list_cmd = NULL;
+
+    if(dap_chain_node_cli_find_option_val(argv, arg_index, argc, "list", &l_list_cmd) == arg_index) {
+        dap_string_t *l_string_ret = dap_string_new("");
+        if (dap_strcmp(l_list_cmd,"chains")==0){
+            const char * l_net_str = NULL;
+            dap_chain_net_t* l_net = NULL;
+            dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-net", &l_net_str);
+            dap_chain_node_cli_find_option_val(argv, arg_index, argc, "--net", &l_net_str);
+            dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-n", &l_net_str);
+            l_net = dap_chain_net_by_name(l_net_str);
+
+            if (l_net){
+                dap_string_append(l_string_ret,"Chains:\n ");
+                dap_chain_t * l_chain = l_net->pub.chains;
+                while (l_chain) {
+                    dap_string_append_printf(l_string_ret, "\t%s:\n", l_chain->name );
+                    l_chain = l_chain->next;
+                }
+            }else{
+                dap_chain_net_item_t * l_net_item, *l_net_item_tmp;
+                int l_net_i = 0;
+                dap_string_append(l_string_ret,"Networks:\n ");
+                HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp){
+                    l_net = l_net_item->chain_net;
+                    dap_string_append_printf(l_string_ret, "\t%s:\n", l_net_item->name);
+                    l_net_i++;
+
+                    dap_chain_t * l_chain = l_net->pub.chains;
+                    while (l_chain) {
+                        dap_string_append_printf(l_string_ret, "\t\t%s:\n", l_chain->name );
+                        l_chain = l_chain->next;
+                    }
+                }
+            }
+
+        }else{
+            dap_string_append(l_string_ret,"Networks:\n ");
+            // show list of nets
+            dap_chain_net_item_t * l_net_item, *l_net_item_tmp;
+            int l_net_i = 0;
+            HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp){
+                dap_string_append_printf(l_string_ret, "%s\n", l_net_item->name);
+                l_net_i++;
+            }
             dap_string_append(l_string_ret, "\n");
+        }
 
         dap_chain_node_cli_set_reply_text(a_str_reply, l_string_ret->str);
         dap_string_free(l_string_ret, true);
@@ -1208,16 +1355,52 @@ static int s_cli_net( int argc, char **argv, void *arg_func, char **a_str_reply)
             }
         } else if ( l_links_str ){
             if ( strcmp(l_links_str,"list") == 0 ) {
+                size_t i =0;
+                dap_chain_net_pvt_t * l_net_pvt = PVT(l_net);
+                pthread_rwlock_rdlock(&l_net_pvt->rwlock );
+                size_t l_links_count = dap_list_length(l_net_pvt->links);
+                dap_string_t *l_reply = dap_string_new("");
+                dap_string_append_printf(l_reply,"Links %u:\n", l_links_count);
+                for (dap_list_t * l_item = l_net_pvt->links; l_item;  l_item = l_item->next ) {
+                    dap_chain_node_client_t * l_node_client = l_item->data;
+
+                    if(l_node_client){
+                        dap_chain_node_info_t * l_info = l_node_client->info;
+                        char l_ext_addr_v4[INET_ADDRSTRLEN]={};
+                        char l_ext_addr_v6[INET6_ADDRSTRLEN]={};
+                        inet_ntop(AF_INET,&l_info->hdr.ext_addr_v4,l_ext_addr_v4,sizeof (l_info->hdr.ext_addr_v4));
+                        inet_ntop(AF_INET6,&l_info->hdr.ext_addr_v6,l_ext_addr_v6,sizeof (l_info->hdr.ext_addr_v6));
+
+                        dap_string_append_printf(l_reply,
+                                                    "\t"NODE_ADDR_FP_STR":\n"
+                                                    "\t\talias: %s\n"
+                                                    "\t\tcell_id: 0x%016"DAP_UINT64_FORMAT_X"\n"
+                                                    "\t\text_ipv4: %s\n"
+                                                    "\t\text_ipv6: %s\n"
+                                                    "\t\text_port: %u\n"
+                                                    "\t\tstate: %s\n"
+                                                , NODE_ADDR_FP_ARGS_S(l_info->hdr.address), l_info->hdr.alias, l_info->hdr.cell_id,
+                                                 l_ext_addr_v4, l_ext_addr_v6,l_info->hdr.ext_port
+                                                 , dap_chain_node_client_state_to_str(l_node_client->state) );
+                    }
+                    i++;
+                }
+                pthread_rwlock_unlock(&l_net_pvt->rwlock );
+                dap_chain_node_cli_set_reply_text(a_str_reply,"%s",l_reply->str);
+                dap_string_free(l_reply,true);
 
             } else if ( strcmp(l_links_str,"add") == 0 ) {
-
+                dap_chain_node_cli_set_reply_text(a_str_reply,"Not implemented\n");
             } else if ( strcmp(l_links_str,"del") == 0 ) {
+                dap_chain_node_cli_set_reply_text(a_str_reply,"Not implemented\n");
 
             }  else if ( strcmp(l_links_str,"info") == 0 ) {
+                dap_chain_node_cli_set_reply_text(a_str_reply,"Not implemented\n");
 
             } else if ( strcmp (l_links_str,"disconnect_all") == 0 ){
                 ret = 0;
                 dap_chain_net_stop(l_net);
+                dap_chain_node_cli_set_reply_text(a_str_reply,"Stopped network\n");
             }else {
                 dap_chain_node_cli_set_reply_text(a_str_reply,
                                                   "Subcommand \"link\" requires one of parameter: list\n");