diff --git a/silkaj/tui.py b/silkaj/tui.py
index 87463bd2c0fc51888de8dc3ef2d64a41e9b759cd..df76760f69a17663d9f2bb6f544bde78e85c6b16 100644
--- a/silkaj/tui.py
+++ b/silkaj/tui.py
@@ -18,11 +18,17 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
 import sys
 import click
 from datetime import datetime
+from texttable import Texttable
+from collections import OrderedDict
 
 from silkaj import network_tools, constants, wot_tools
 from silkaj import crypto_tools as ct
 
 
+HORIZ_TABLE_CHARS = ["─", "│", "─", "─"]
+VERT_TABLE_CHARS = ["─", "│", "│", "═"]
+
+
 def display_amount(tx, message, amount, ud_value, currency_symbol):
     """
     Displays an amount in unit and relative reference.
@@ -67,3 +73,91 @@ async def send_doc_confirmation(document_name):
         client = network_tools.ClientInstance().client
         await client.close()
         sys.exit(constants.SUCCESS_EXIT_STATUS)
+
+
+def create_table(style="default"):
+    """
+    Creates a table.
+    Applies a style on it, to chose between:
+      * default (table with all boxes drawn, text on the left)
+      * columns (tabls with only columns, text centered)
+    """
+    table = Texttable(max_width=click.get_terminal_size()[0])
+    if style == "columns":
+        table.set_chars(VERT_TABLE_CHARS)
+        return table.set_deco(table.HEADER | table.VLINES | table.BORDER)
+    return table.set_chars(HORIZ_TABLE_CHARS)
+
+
+def fill_table_from_dict_list(table, dict_list: list, type="horiz"):
+    """
+    Given a list of OrderedDictict with same keys,
+    returns a table with keys as header.
+    type can be either "vert" or "horiz"
+    """
+    headers = list(dict_list[0].keys())
+    content = list()
+    for dict in dict_list:
+        assert list(dict.keys()) == headers
+        line = list()
+        for head in headers:
+            line.append(dict[head])
+        content.append(line)
+    if type == "vert":
+        return vert_table(table, content, headers)
+    elif type == "horiz":
+        return horiz_table(table, content, headers)
+
+
+def fill_table_from_dict(table, dict: OrderedDict):
+    """
+    Given an OrderedDict where each value is a list of same length,
+    fill a table where labels are keys and columns are values.
+    """
+    labels = list(dict.keys())
+    content = list()
+    n = 0
+    while True:
+        line = list()
+        err_count = 0
+        for label in labels:
+            try:
+                line.append(dict[label][n])
+            except IndexError:
+                line.append("")
+                err_count += 1
+        if err_count == len(labels):
+            return horiz_table(table, content, labels)
+        content.append(line)
+        n += 1
+
+
+def horiz_table(table, content_list: list, headers=[]):
+    """
+    Fills a table from headers and content list.
+    content_list is a list of lists representing rows.
+    each element of content_list and headers must be of sme length.
+    """
+    if headers:
+        assert len(headers) == len(content_list[0])
+        table.header(headers)
+    for content in content_list:
+        assert len(content) == len(content_list[0])
+        table.add_row(content)
+    return table.draw()
+
+
+def vert_table(table, content_list: list, labels=[]):
+    """
+    Fills a vertical table, where labels are displayed on the first column
+    """
+    if len(labels) > 0:
+        assert len(labels) == len(content_list)
+        for label, line in zip(labels, content_list):
+            assert len(line) == len(content_list[0])
+            table.add_row([label] + line)
+    else:
+        for line in content_list:
+            assert len(line) == len(content_list[0])
+            table.add_row(line)
+    return table.draw()
diff --git a/tests/test_tui.py b/tests/test_tui.py
index 3fd413d132c2cad988246eeb61a170fad52103d7..38a28fbc8daaf768a7a4df833e32ac8be886500e 100644
--- a/tests/test_tui.py
+++ b/tests/test_tui.py
@@ -16,7 +16,13 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
 """
 
 import pytest
-from silkaj.tui import display_pubkey, display_amount, display_pubkey_and_checksum
+from silkaj.tui import (
+    display_pubkey,
+    display_amount,
+    display_pubkey_and_checksum,
+    horiz_table,
+    vert_table,
+)
 from silkaj.constants import G1_SYMBOL, SHORT_PUBKEY_SIZE
 from silkaj import wot_tools
 
@@ -81,3 +87,138 @@ def test_display_pubkey_and_checksum(pubkey, checksum):
     assert pubkey[:14] + "…:" + checksum == display_pubkey_and_checksum(
         pubkey, short=True, length=14
     )
+
+
+# horiz_table
+@pytest.mark.parametrize(
+    "content, headers, expected",
+    [
+        (
+            [
+                ["three", "o'clock"],
+                ["four", "o'clock"],
+                ["rock", "rock around the clock"],
+            ],
+            ["one", "two"],
+            "+-------+-----------------------+\n\
+|  one  |          two          |\n\
++=======+=======================+\n\
+| three | o'clock               |\n\
++-------+-----------------------+\n\
+| four  | o'clock               |\n\
++-------+-----------------------+\n\
+| rock  | rock around the clock |\n\
++-------+-----------------------+",
+        ),
+        (
+            [
+                ["three", "o'clock"],
+                ["four", "o'clock"],
+                ["rock", "rock around the clock"],
+            ],
+            None,
+            "+-------+-----------------------+\n\
+| three | o'clock               |\n\
++-------+-----------------------+\n\
+| four  | o'clock               |\n\
++-------+-----------------------+\n\
+| rock  | rock around the clock |\n\
++-------+-----------------------+",
+        ),
+        (
+            ["one", "two"],
+            [
+                ["three", "o'clock"],
+                ["four", "o'clock"],
+                ["rock"],
+            ],
+            False,
+        ),
+    ],
+)
+def test_horiz_table(content, headers, expected):
+    if expected == False:
+        with pytest.raises(AssertionError) as pytest_error:
+            table = horiz_table(headers, content)
+        assert pytest_error.type == AssertionError  # is it useful ?
+    else:
+        table = horiz_table(content, headers)
+        assert table == expected
+
+
+# vert_table
+@pytest.mark.parametrize(
+    "content, headers, expected",
+    [
+        (
+            [
+                ["o'clock"],
+                ["four"],
+                ["o'clock"],
+            ],
+            ["one", "two", "three"],
+            "+-------+---------+\n\
+| one   | o'clock |\n\
++-------+---------+\n\
+| two   | four    |\n\
++-------+---------+\n\
+| three | o'clock |\n\
++-------+---------+",
+        ),
+        (
+            [
+                ["o'clock"],
+                ["four"],
+                ["o'clock"],
+            ],
+            [],
+            "+---------+\n\
+| o'clock |\n\
++---------+\n\
+| four    |\n\
++---------+\n\
+| o'clock |\n\
++---------+",
+        ),
+        (
+            [
+                ["three", "o'clock"],
+                ["four", "o'clock"],
+            ],
+            ["one", "two"],
+            "+-----+-------+---------+\n\
+| one | three | o'clock |\n\
++-----+-------+---------+\n\
+| two | four  | o'clock |\n\
++-----+-------+---------+",
+        ),
+        (
+            ["one", "two"],
+            [["three", "o'clock"], ["four", "o'clock"], ["rock", "rock"]],
+            False,
+        ),
+        (
+            ["one", "two"],
+            [
+                ["three", "o'clock"],
+                [
+                    "four",
+                ],
+            ],
+            False,
+        ),
+    ],
+)
+def test_vert_table(content, headers, expected):
+    if expected == False:
+        with pytest.raises(AssertionError) as pytest_error:
+            table = vert_table(headers, content)
+        assert pytest_error.type == AssertionError  # is it useful ?
+    else:
+        table = vert_table(content, headers)
+        print(table)
+        assert table == expected
+
+
+# TODO
+# create_table_from_dict_list