diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c
index f17c9383dc548ffe85f1d936adcf68c3b3051d9c..f5ea1f68963a05ff40881edb488cda640f341583 100644
--- a/dap_chain_node_cli_cmd.c
+++ b/dap_chain_node_cli_cmd.c
@@ -124,7 +124,7 @@ static bool del_alias(const char *alias)
  *
  * return addr, NULL if not found
  */
-static dap_chain_node_addr_t* get_name_by_alias(const char *alias)
+dap_chain_node_addr_t* get_name_by_alias(const char *alias)
 {
     dap_chain_node_addr_t *addr = NULL;
     if(!alias)
@@ -733,7 +733,7 @@ int com_node(int argc, const char ** argv, char **str_reply)
         if(!node_info) {
             return -1;
         }
-        int timeout_ms = 100000; //100 sec.
+        int timeout_ms = 10000; //10 sec.
         // start handshake
         chain_node_client_t *client = chain_node_client_connect(node_info);
         if(!client) {
@@ -753,8 +753,18 @@ int com_node(int argc, const char ** argv, char **str_reply)
         DAP_DELETE(node_info);
 
         //Add new established connection in the list
-        chain_node_client_list_add(client);
-
+        int ret = chain_node_client_list_add(&address, client);
+        switch (ret)
+        {
+        case -1:
+            chain_node_client_close(client);
+            set_reply_text(str_reply, "connection established, but not saved");
+            return -1;
+        case -2:
+            chain_node_client_close(client);
+            set_reply_text(str_reply, "connection already present");
+            return -1;
+        }
         set_reply_text(str_reply, "connection established");
         break;
     }
diff --git a/dap_chain_node_cli_cmd.h b/dap_chain_node_cli_cmd.h
index c27e7ec822ac0cfbc3a6af0ef9f727196720f735..3303207c5fd2bd58c214b132307fc5b4ab5482c9 100644
--- a/dap_chain_node_cli_cmd.h
+++ b/dap_chain_node_cli_cmd.h
@@ -21,8 +21,16 @@
 
 #pragma once
 
+#include "dap_chain_node.h"
 #include "dap_chain_node_cli.h"
 
+/**
+ * Find in base addr by alias
+ *
+ * return addr, NULL if not found
+ */
+dap_chain_node_addr_t* get_name_by_alias(const char *alias);
+
 /**
  *  Look up NAME as the name of a command, and return a pointer to that
  *  command.  Return a NULL pointer if NAME isn't a command name.
diff --git a/dap_chain_node_remote.c b/dap_chain_node_remote.c
index 914a847221d0a14ae9b7cc78e7fcaea4bf2ffca9..dcb72890a6895bf30d18deabe5706c1a1667673f 100644
--- a/dap_chain_node_remote.c
+++ b/dap_chain_node_remote.c
@@ -22,69 +22,116 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
-#include <glib.h>
 #include <pthread.h>
 
+#include "uthash.h"
 #include "dap_chain_node_remote.h"
 
+typedef struct dap_chain_item {
+    dap_chain_node_addr_t address;
+    chain_node_client_t *client;
+    UT_hash_handle hh;
+} list_linked_item_t;
 
 // List of connections
-static GList *connect_list = NULL;
+static list_linked_item_t *conn_list = NULL;
 
 // for separate access to connect_list
 static pthread_mutex_t connect_list_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /**
- * Add new established connection in the list
+ * Add new established connection to the list
+ *
+ * return 0 OK, -1 error, -2 already present
  */
-bool chain_node_client_list_add(chain_node_client_t *client)
+int chain_node_client_list_add(dap_chain_node_addr_t *address, chain_node_client_t *client)
 {
-    if(!client)
-        return false;
+    int ret = 0;
+    if(!address || !client)
+        return -1;
+    list_linked_item_t *item_tmp;
     pthread_mutex_lock(&connect_list_mutex);
-    connect_list = g_list_append(connect_list, client);
+    HASH_FIND(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); // address already in the hash?
+    if(item_tmp == NULL) {
+        item_tmp = DAP_NEW(list_linked_item_t);
+        item_tmp->address.uint64 = address->uint64;
+        item_tmp->client = client;
+        HASH_ADD(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); // address: name of key field
+        ret = 0;
+    }
+    // connection already present
+    else
+        ret = -2;
+    //connect_list = g_list_append(connect_list, client);
     pthread_mutex_unlock(&connect_list_mutex);
-    return true;
+    return ret;
 }
 
 /**
  * Delete established connection from the list
+ *
+ * return 0 OK, -1 error, -2 address not found
  */
-bool chain_node_client_list_del(chain_node_client_t *client)
+int chain_node_client_list_del(dap_chain_node_addr_t *address)
 {
+    int ret = -1;
+    if(!address)
+        return -1;
+    list_linked_item_t *item_tmp;
     pthread_mutex_lock(&connect_list_mutex);
-    GList *list = g_list_find(connect_list, client);
-    // found
-    if(list)
-        connect_list = g_list_remove(connect_list, client);
+    HASH_FIND(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp);
+    if(item_tmp != NULL) {
+        HASH_DEL(conn_list, item_tmp);
+        ret = 0;
+    }
+    else
+        // address not found in the hash
+        ret = -2;
     pthread_mutex_unlock(&connect_list_mutex);
-    if(list)
-        return true;
-    return false;
+    if(!ret) {
+        // close connection
+        chain_node_client_close(item_tmp->client);
+        // del struct for hash
+        DAP_DELETE(item_tmp);
+    }
+    return ret;
 }
 
 /**
- * Get one established connection
- *
- * n - the position of the established connection, counting from 0
- *
- * return client, or NULL if the position is off the end of the list
+ * Delete all established connection from the list
  */
-chain_node_client_t* chain_node_client_list_get_item(int n)
+void chain_node_client_list_del_all(void)
 {
+    int ret = -1;
+    list_linked_item_t *iter_current, *item_tmp;
     pthread_mutex_lock(&connect_list_mutex);
-    chain_node_client_t *client = g_list_nth_data(connect_list, (guint) n);
+    HASH_ITER(hh, conn_list , iter_current, item_tmp) {
+        // close connection
+        chain_node_client_close(iter_current->client);
+        // del struct for hash
+        HASH_DEL(conn_list, iter_current);
+    }
     pthread_mutex_unlock(&connect_list_mutex);
-    return client;
 }
+
 /**
- * Get the number of established connections
+ * Get present established connection
+ *
+ * return client, or NULL if the position is off the end of the list
  */
-int chain_node_client_list_count(void)
+const chain_node_client_t* chain_node_client_find(dap_chain_node_addr_t *address)
 {
+    int ret = 0;
+    if(!address)
+        return NULL;
+    chain_node_client_t *client_ret = NULL;
+    list_linked_item_t *item_tmp;
     pthread_mutex_lock(&connect_list_mutex);
-    int len = g_list_length(connect_list);
+    HASH_FIND(hh, conn_list, address, sizeof(dap_chain_node_addr_t), item_tmp); // address already in the hash?
+    if(item_tmp != NULL) {
+        client_ret = item_tmp->client;
+    }
     pthread_mutex_unlock(&connect_list_mutex);
-    return len;
+    return client_ret;
 }
 
diff --git a/dap_chain_node_remote.h b/dap_chain_node_remote.h
index ef7f4c5ef5452c2d5f5a1fdcfb046c67e03391a2..f0ff4d92cb6d7e3d07d6658855ec00e568f644ae 100644
--- a/dap_chain_node_remote.h
+++ b/dap_chain_node_remote.h
@@ -23,28 +23,31 @@
 
 #include <stdbool.h>
 
+#include "dap_chain_node.h"
 #include "dap_chain_node_cli_connect.h"
 
 /**
- * Add new established connection in the list
+ * Add new established connection to the list
+ *
+ * return 0 OK, -1 error, -2 already present
  */
-bool chain_node_client_list_add(chain_node_client_t *client);
+int chain_node_client_list_add(dap_chain_node_addr_t *address, chain_node_client_t *client);
 
 /**
  * Delete established connection from the list
+ *
+ * return 0 OK, -1 error, -2 address not found
  */
-bool chain_node_client_list_del(chain_node_client_t *client);
+int chain_node_client_list_del(dap_chain_node_addr_t *address);
 
 /**
- * Get one established connection
- *
- * n - the position of the established connection, counting from 0
- *
- * return client, or NULL if the position is off the end of the list
+ * Delete all established connection from the list
  */
-chain_node_client_t* chain_node_client_list_get_item(int n);
+void chain_node_client_list_del_all(void);
 
 /**
- * Get the number of established connections
+ * Get present established connection
+ *
+ * return client, or NULL if the position is off the end of the list
  */
-int chain_node_client_list_count(void);
+const chain_node_client_t* chain_node_client_find(dap_chain_node_addr_t *address);