diff --git a/silkaj/blockchain_tools.py b/silkaj/blockchain_tools.py
index 376dca0e4a3742d10b65334e8bc2cf55931140f4..67c98710753caa576907c594187e8a66f9d8dddb 100644
--- a/silkaj/blockchain_tools.py
+++ b/silkaj/blockchain_tools.py
@@ -17,18 +17,18 @@ import functools
 
 from duniterpy.api.bma import blockchain
 
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 
 
 @functools.lru_cache(maxsize=1)
 def get_blockchain_parameters():
-    client = ClientInstance().client
+    client = client_instance()
     return client(blockchain.parameters)
 
 
 @functools.lru_cache(maxsize=1)
 def get_head_block():
-    client = ClientInstance().client
+    client = client_instance()
     return client(blockchain.current)
 
 
diff --git a/silkaj/blocks.py b/silkaj/blocks.py
index f8040db6e84d9ff91ea549caa475876fc6e77137..521287e370305dd60f3ad75746a825af67f163dc 100644
--- a/silkaj/blocks.py
+++ b/silkaj/blocks.py
@@ -17,13 +17,12 @@ import logging
 
 from click import INT, argument, command, progressbar
 from duniterpy.api import bma
-from duniterpy.api.client import Client
 from duniterpy.api.errors import DuniterError
 from duniterpy.documents import Block
 from duniterpy.key.verifying_key import VerifyingKey
 
 from silkaj.constants import BMA_MAX_BLOCKS_CHUNK_SIZE
-from silkaj.network_tools import determine_endpoint
+from silkaj.network_tools import client_instance
 from silkaj.tools import message_exit
 
 
@@ -36,7 +35,7 @@ If nothing specified, the whole blockchain gets verified.",
 @argument("from_block", default=0, type=INT)
 @argument("to_block", default=0, type=INT)
 def verify_blocks_signatures(from_block, to_block):
-    client = Client(determine_endpoint())
+    client = client_instance()
     to_block = check_passed_blocks_range(client, from_block, to_block)
     invalid_blocks_signatures = list()
     chunks_from = range(from_block, to_block + 1, BMA_MAX_BLOCKS_CHUNK_SIZE)
diff --git a/silkaj/cert.py b/silkaj/cert.py
index de3a3a4f93c94e319e0bdb009cc9f8ec2f662761..91e596aaf62eda300e693b4414e2bbca7bfe99d8 100644
--- a/silkaj/cert.py
+++ b/silkaj/cert.py
@@ -28,14 +28,14 @@ from silkaj.blockchain_tools import get_blockchain_parameters, get_head_block
 from silkaj.constants import ALL, DATE, SUCCESS_EXIT_STATUS
 from silkaj.crypto_tools import is_pubkey_and_check
 from silkaj.license import license_approval
-from silkaj.network_tools import ClientInstance, send_document
+from silkaj.network_tools import client_instance, send_document
 
 
 @click.command("cert", help="Send certification")
 @click.argument("uid_pubkey_to_certify")
 @click.pass_context
 def send_certification(ctx, uid_pubkey_to_certify):
-    client = ClientInstance().client
+    client = client_instance()
 
     checked_pubkey = is_pubkey_and_check(uid_pubkey_to_certify)
     if checked_pubkey:
@@ -112,7 +112,7 @@ def certification_confirmation(
 ):
     cert = list()
     cert.append(["Cert", "Issuer", "–>", "Recipient: Published: #block-hash date"])
-    client = ClientInstance().client
+    client = client_instance()
     idty_timestamp = idty_to_certify["meta"]["timestamp"]
     block_id_idty = get_block_id(idty_timestamp)
     block = client(bma.blockchain.block, block_id_idty.number)
diff --git a/silkaj/commands.py b/silkaj/commands.py
index 8b1973b588e4c6c7efc65de253d9c16b375b3717..72cad11b207ee6dd7c71d6bb194c1d772ba08f25 100644
--- a/silkaj/commands.py
+++ b/silkaj/commands.py
@@ -26,7 +26,7 @@ from websocket._exceptions import WebSocketConnectionClosedException
 
 from silkaj.blockchain_tools import get_head_block
 from silkaj.constants import ALL, HOUR
-from silkaj.network_tools import ClientInstance, determine_endpoint
+from silkaj.network_tools import client_instance, determine_endpoint
 from silkaj.tools import get_currency_symbol
 from silkaj.wot_tools import identity_of
 
@@ -83,7 +83,7 @@ def power(nbr, pow=0):
     help="Display the current Proof of Work difficulty level to generate the next block",
 )
 def difficulties():
-    client = ClientInstance().client
+    client = client_instance()
     try:
         ws = client(bma.ws.block)
         while True:
@@ -129,7 +129,7 @@ def list_blocks(number, detailed):
     current_nbr = head_block["number"]
     if number == 0:
         number = head_block["issuersFrame"]
-    client = ClientInstance().client
+    client = client_instance()
     blocks = client(bma.blockchain.blocks, number, current_nbr - number + 1)
     issuers = list()
     issuers_dict = dict()
diff --git a/silkaj/idty_tools.py b/silkaj/idty_tools.py
index 137675f94d414e795433687b44ce5c5bce3c178c..00031c89af01240faeb71295e9e37f1cb3908686 100644
--- a/silkaj/idty_tools.py
+++ b/silkaj/idty_tools.py
@@ -26,7 +26,7 @@ from texttable import Texttable
 
 from silkaj import wot_tools as wt
 from silkaj.constants import ALL
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 from silkaj.tui import display_pubkey_and_checksum
 
 
@@ -34,7 +34,7 @@ def display_identity(idty: Identity):
     """
     Creates a table containing the identity infos
     """
-    client = ClientInstance().client
+    client = client_instance()
     id_table = list()
     id_table.append(["Public key", display_pubkey_and_checksum(idty.pubkey)])
     id_table.append(["User ID", idty.uid])
diff --git a/silkaj/membership.py b/silkaj/membership.py
index da36ba96f511c0a10587d9dda25d0cfd548c3e9b..e7ce01fee80a853f90264a08ab7a75b180eeab78 100644
--- a/silkaj/membership.py
+++ b/silkaj/membership.py
@@ -26,7 +26,7 @@ from silkaj import auth, tui, wot
 from silkaj.blockchain_tools import get_blockchain_parameters, get_head_block
 from silkaj.constants import DATE, SUCCESS_EXIT_STATUS
 from silkaj.license import license_approval
-from silkaj.network_tools import ClientInstance, send_document
+from silkaj.network_tools import client_instance, send_document
 
 
 @click.command(
@@ -54,7 +54,7 @@ def send_membership(ctx):
         license_approval(currency)
 
     # Confirmation
-    client = ClientInstance().client
+    client = client_instance()
     display_confirmation_table(identity_uid, key.pubkey, identity_block_id)
     if not dry_run and not ctx.obj["DISPLAY_DOCUMENT"]:
         tui.send_doc_confirmation("membership document for this identity")
@@ -92,7 +92,7 @@ def display_confirmation_table(identity_uid, pubkey, identity_block_id):
     between two renewals is not awaited as for the certification
     """
 
-    client = ClientInstance().client
+    client = client_instance()
 
     identities_requirements = client(bma.wot.requirements, pubkey)
     for identity_requirements in identities_requirements["identities"]:
diff --git a/silkaj/money.py b/silkaj/money.py
index b8316021ce12631e32762e3508ee3cb7d096dd2d..0bb9ca826d418ab1fe821d188a2fe9e18708480f 100644
--- a/silkaj/money.py
+++ b/silkaj/money.py
@@ -29,7 +29,7 @@ from silkaj.crypto_tools import (
     is_pubkey_and_check,
     validate_checksum,
 )
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 from silkaj.tools import get_currency_symbol
 from silkaj.tui import display_amount, display_pubkey_and_checksum
 
@@ -132,7 +132,7 @@ def get_amount_from_pubkey(pubkey):
 
 
 def get_sources(pubkey):
-    client = ClientInstance().client
+    client = client_instance()
     # Sources written into the blockchain
     sources = client(tx.sources, pubkey)
 
@@ -187,7 +187,7 @@ def get_sources(pubkey):
 
 @functools.lru_cache(maxsize=1)
 def get_ud_value():
-    client = ClientInstance().client
+    client = client_instance()
     blockswithud = client(blockchain.ud)
     NBlastUDblock = blockswithud["result"]["blocks"][-1]
     lastUDblock = client(blockchain.block, NBlastUDblock)
diff --git a/silkaj/network_tools.py b/silkaj/network_tools.py
index 78ce9519b4391b0ce78d699146093a334c2a1f84..df951f9a2ba67af4eda735eaeeb6beb691af6f5b 100644
--- a/silkaj/network_tools.py
+++ b/silkaj/network_tools.py
@@ -13,6 +13,7 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
 
+import functools
 import re
 import sys
 import urllib
@@ -24,17 +25,6 @@ from duniterpy.api.client import Client
 from silkaj import constants
 
 
-def singleton(class_):
-    instances = {}
-
-    def getinstance(*args, **kwargs):
-        if class_ not in instances:
-            instances[class_] = class_(*args, **kwargs)
-        return instances[class_]
-
-    return getinstance
-
-
 def determine_endpoint():
     """
     Pass custom endpoint, parse through a regex
@@ -77,14 +67,13 @@ Expected format: {host|ipv4|[ipv6]}:{port}{/path}"
         return ep.endpoint(constants.G1_DEFAULT_ENDPOINT)
 
 
-@singleton
-class ClientInstance:
-    def __init__(self):
-        self.client = Client(determine_endpoint())
+@functools.lru_cache(maxsize=1)
+def client_instance():
+    return Client(determine_endpoint())
 
 
 def send_document(bma_path, document):
-    client = ClientInstance().client
+    client = client_instance()
     doc_name = document.__class__.__name__
     try:
         client(bma_path, document.signed_raw())
diff --git a/silkaj/tx_history.py b/silkaj/tx_history.py
index 5201ba6046ec942cd9f9b294fcf17600be2b1e64..238478bf0430fdefeb879acac4ea2ecb9f86604c 100644
--- a/silkaj/tx_history.py
+++ b/silkaj/tx_history.py
@@ -27,7 +27,7 @@ from silkaj import wot_tools as wt
 from silkaj.constants import ALL, ALL_DIGITAL
 from silkaj.crypto_tools import check_pubkey_format, validate_checksum
 from silkaj.money import amount_in_current_base, get_amount_from_pubkey, get_ud_value
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 from silkaj.tools import get_currency_symbol
 from silkaj.tui import display_pubkey_and_checksum
 
@@ -40,7 +40,7 @@ def transaction_history(pubkey, uids, full_pubkey):
     if check_pubkey_format(pubkey):
         pubkey = validate_checksum(pubkey)
 
-    client = ClientInstance().client
+    client = client_instance()
     ud_value = get_ud_value()
     currency_symbol = get_currency_symbol()
 
diff --git a/silkaj/wot.py b/silkaj/wot.py
index 92377b42e35640100f9a21632fae49a6a7deb6b1..b767619b10141de18af8f7e899bd9785d030fce2 100644
--- a/silkaj/wot.py
+++ b/silkaj/wot.py
@@ -26,7 +26,7 @@ from silkaj import wot_tools as wt
 from silkaj.blockchain_tools import get_blockchain_parameters
 from silkaj.constants import DATE
 from silkaj.crypto_tools import is_pubkey_and_check
-from silkaj.network_tools import ClientInstance, exit_on_http_error
+from silkaj.network_tools import client_instance, exit_on_http_error
 from silkaj.tools import message_exit
 from silkaj.tui import display_pubkey_and_checksum
 
@@ -56,7 +56,7 @@ def received_sent_certifications(uid_pubkey):
     get id of received and sent certifications
     display in a table the result with the numbers
     """
-    client = ClientInstance().client
+    client = client_instance()
     first_block = client(blockchain.block, 1)
     time_first_block = first_block["time"]
 
diff --git a/silkaj/wot_tools.py b/silkaj/wot_tools.py
index dcc527b480a344879271a1237fc99a005f72e6e9..817e3a6f891ba5ded7a540c319e4eea4c3c2be49 100644
--- a/silkaj/wot_tools.py
+++ b/silkaj/wot_tools.py
@@ -17,7 +17,7 @@ import sys
 
 from duniterpy.api.bma import wot
 
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 
 
 def identity_of(pubkey_uid):
@@ -26,7 +26,7 @@ def identity_of(pubkey_uid):
     Not able to get corresponding uid from a non-member identity
     Able to know if an identity is member or not
     """
-    client = ClientInstance().client
+    client = client_instance()
     try:
         return client(wot.identity_of, pubkey_uid)
     except ValueError as e:
@@ -50,7 +50,7 @@ def wot_lookup(identifier):
     Return received and sent certifications lists of matching identities
     if one identity found
     """
-    client = ClientInstance().client
+    client = client_instance()
     return (client(wot.lookup, identifier))["results"]
 
 
diff --git a/tests/test_membership.py b/tests/test_membership.py
index e9f40700cce9f5d00e2e195acb8077c0dd346c7a..d413c00b1f64278de61756eba70fb7bb3e7584b0 100644
--- a/tests/test_membership.py
+++ b/tests/test_membership.py
@@ -39,7 +39,7 @@ from silkaj import auth, blockchain_tools, membership, wot
 from silkaj.blockchain_tools import get_blockchain_parameters
 from silkaj.cli import cli
 from silkaj.constants import DATE, FAILURE_EXIT_STATUS, SUCCESS_EXIT_STATUS
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 from silkaj.tui import display_pubkey_and_checksum
 
 # Values and patches
@@ -135,7 +135,7 @@ def test_display_confirmation_table(patched_wot_requirements, monkeypatch, capsy
     monkeypatch.setattr(bma.blockchain, "parameters", patched_params)
     monkeypatch.setattr(bma.blockchain, "block", patched_block)
 
-    client = ClientInstance().client
+    client = client_instance()
     identities_requirements = client(bma.wot.requirements, pubkey)
     for identity_requirements in identities_requirements["identities"]:
         if identity_requirements["uid"] == identity_uid:
diff --git a/tests/test_revocation.py b/tests/test_revocation.py
index a520a475c55a3e761c0350ccf0c5f21455080506..223bdb05d7e6c4640de67f062aee2115b38101fe 100644
--- a/tests/test_revocation.py
+++ b/tests/test_revocation.py
@@ -24,7 +24,6 @@ import click
 import pytest
 from click.testing import CliRunner
 from duniterpy.api import bma
-from duniterpy.api.client import Client
 from duniterpy.api.errors import DuniterError
 from duniterpy.documents.identity import Identity
 from duniterpy.documents.revocation import Revocation
@@ -35,7 +34,7 @@ from patched.idty_tools import idty1, idty2, idty_block, lookup_one, lookup_two
 from silkaj import auth, blockchain_tools, idty_tools, revocation, wot
 from silkaj.cli import cli
 from silkaj.constants import FAILURE_EXIT_STATUS, SUCCESS_EXIT_STATUS
-from silkaj.network_tools import ClientInstance
+from silkaj.network_tools import client_instance
 from silkaj.tui import display_pubkey_and_checksum
 
 ### useful function ###
@@ -694,7 +693,7 @@ def test_revocation_cli_publish(
         file = revocation.REVOCATION_LOCAL_PATH
 
     # test publication
-    client = ClientInstance().client
+    client = client_instance()
     runner = CliRunner()
     with runner.isolated_filesystem():
         with open(file, "w") as f:
@@ -778,7 +777,7 @@ def test_revocation_cli_publish_send_errors(
         file = revocation.REVOCATION_LOCAL_PATH
 
     # test publication
-    client = ClientInstance().client
+    client = client_instance()
     runner = CliRunner()
     with runner.isolated_filesystem():
         with open(file, "w") as f:
@@ -862,7 +861,7 @@ def test_revocation_cli_revoke(
 
     command = display_dry_options(display, dry_run)
     command.extend(["revocation", "revoke"])
-    client = ClientInstance().client
+    client = client_instance()
 
     result = CliRunner().invoke(cli, args=command, input=user_input)
     for expect in expected:
@@ -912,7 +911,7 @@ def test_revocation_cli_revoke_errors(display, user_input, doc, expected, monkey
 
     command = display_dry_options(display, False)
     command.extend(["revocation", "revoke"])
-    client = ClientInstance().client
+    client = client_instance()
 
     result = CliRunner().invoke(cli, args=command, input=user_input)
     for expect in expected:
diff --git a/tests/test_unit_tx.py b/tests/test_unit_tx.py
index 2d3620e2fc202e2090d0693f6ab5e79e031df745..ced3d49d030301dd7381aad1379ef8cac078c10d 100644
--- a/tests/test_unit_tx.py
+++ b/tests/test_unit_tx.py
@@ -1227,7 +1227,7 @@ def test_generate_and_send_transaction(
 
     # patched functions
     monkeypatch.setattr(blockchain_tools, "get_head_block", patched_get_head_block)
-    #    monkeypatch.setattr(network_tools, "ClientInstance", patched_ClientInstance)
+    #    monkeypatch.setattr(network_tools, "client_instance", patched_client_instance)
 
     tx.generate_and_send_transaction(
         key,
diff --git a/tests/test_verify_blocks.py b/tests/test_verify_blocks.py
index 4fe34a93adcbea5193c1d52f2ff3e8711752c78d..3d75c959c98b13193c0d1619891bf9f417620e89 100644
--- a/tests/test_verify_blocks.py
+++ b/tests/test_verify_blocks.py
@@ -16,7 +16,6 @@
 import pytest
 from click.testing import CliRunner
 from duniterpy.api import bma
-from duniterpy.api.client import Client
 from duniterpy.documents import Block
 
 from silkaj import cli
@@ -32,7 +31,7 @@ from silkaj.constants import (
     FAILURE_EXIT_STATUS,
     SUCCESS_EXIT_STATUS,
 )
-from silkaj.network_tools import determine_endpoint
+from silkaj.network_tools import client_instance
 
 G1_INVALID_BLOCK_SIG = 15144
 HEAD_BLOCK = 48000
@@ -47,7 +46,7 @@ def current(self):
 )
 def test_check_passed_blocks_range(from_block, to_block, capsys, monkeypatch):
     monkeypatch.setattr(bma.blockchain, "current", current)
-    client = Client(determine_endpoint)
+    client = client_instance()
     # https://medium.com/python-pandemonium/testing-sys-exit-with-pytest-10c6e5f7726f
     with pytest.raises(SystemExit) as pytest_wrapped_e:
         check_passed_blocks_range(client, from_block, to_block)
@@ -104,7 +103,7 @@ def test_get_chunk_size(from_block, to_block, chunks_from, chunk_from):
 
 @pytest.mark.parametrize("chunk_size, chunk_from", [(2, 1), (5, 10)])
 def test_get_chunks(chunk_size, chunk_from):
-    client = Client(determine_endpoint())
+    client = client_instance()
     chunk = get_chunk(client, chunk_size, chunk_from)
     assert chunk[0]["number"] + chunk_size - 1 == chunk[-1]["number"]