diff --git a/src/sakia/gui/sub/transfer/controller.py b/src/sakia/gui/sub/transfer/controller.py
index 1528e3cf362be1440a7cad4c71e7d303122c5061..3388cc2915c8756cce7c7a8c8a0a650f85293b5d 100644
--- a/src/sakia/gui/sub/transfer/controller.py
+++ b/src/sakia/gui/sub/transfer/controller.py
@@ -2,7 +2,7 @@ import re
 import logging
 
 from PyQt5.QtCore import Qt, QObject, pyqtSignal, QCoreApplication
-from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout
+from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout, QMessageBox
 
 from duniterpy.constants import PUBKEY_REGEX
 from duniterpy.documents import CRCPubkey
@@ -34,7 +34,7 @@ class TransferController(QObject):
         """
         super().__init__()
         self.view = view
-        self.model = model
+        self.model = model  # type: TransferModel
         self.search_user = search_user
         self.user_information = user_information
         self.password_input = password_input
@@ -49,6 +49,7 @@ class TransferController(QObject):
         )
         self.view.spinbox_amount.valueChanged.connect(self.handle_amount_change)
         self.view.spinbox_relative.valueChanged.connect(self.handle_relative_change)
+        self.view.button_source_check.clicked.connect(self.check_source)
 
     @classmethod
     def create(cls, parent, app):
@@ -324,3 +325,8 @@ class TransferController(QObject):
         self.model.set_connection(index)
         self.password_input.set_connection(self.model.connection)
         self.refresh()
+
+    def check_source(self):
+        qmessagebox = QMessageBox(self.view)
+        qmessagebox.setText("The source has been checked.")
+        qmessagebox.exec()
diff --git a/src/sakia/services/documents.py b/src/sakia/services/documents.py
index afab7abe64e071e0944b1095811fa0c45fa295ad..e85985b79aad9da073751832b36741b984d20b82 100644
--- a/src/sakia/services/documents.py
+++ b/src/sakia/services/documents.py
@@ -1,5 +1,3 @@
-from hashlib import sha256
-
 import jsonschema
 import attr
 import logging
@@ -15,12 +13,10 @@ from duniterpy.documents import (
     SIGParameter,
     Unlock,
     block_uid,
-    BlockUID,
 )
-from duniterpy.documents import Identity as IdentityDoc
 from duniterpy.documents import Transaction as TransactionDoc
 from duniterpy.documents.transaction import reduce_base
-from duniterpy.grammars.output import Condition, Operator, SIG, CSV, CLTV, XHX
+from duniterpy.grammars.output import Condition, Operator, SIG, CSV
 from duniterpy.api import bma
 from sakia.data.entities import Identity, Transaction, Source
 from sakia.data.processors import (
@@ -335,7 +331,7 @@ class DocumentsService:
                 for s in [src for src in available_sources if src.base == current_base]:
                     condition = pypeg2.parse(s.conditions, Condition)
                     # evaluate the condition
-                    if not self.evaluate_condition(
+                    if not self._sources_services.evaluate_condition(
                         currency, condition, [key], [], s.identifier
                     ):
                         continue
@@ -644,97 +640,3 @@ class DocumentsService:
             return result
         except NotEnoughChangeError as e:
             return (False, str(e)), tx_entities
-
-    def evaluate_condition(
-        self,
-        currency,
-        condition: Condition,
-        keys: list,
-        passwords,
-        identifier: str,
-        result: bool = True,
-    ) -> bool:
-        """
-        Evaluate a source lock condition
-        Support multiple signatures and passwords
-
-        :param passwords:
-        :param str currency: Name of currency
-        :param Condition condition: Condition instance
-        :param [SigningKey] keys: Keys to unlock condition (first key is the source owner key)
-        :param str identifier: Source transaction identifier
-        :param bool result: result accumulator
-        :return:
-        """
-        left = False
-        right = False
-        # if left param is a condition...
-        if isinstance(condition.left, Condition):
-            # evaluate condition
-            left = self.evaluate_condition(
-                currency, condition.left, keys, passwords, identifier, result
-            )
-        # if right param is a condition...
-        if isinstance(condition.right, Condition):
-            # evaluate condition
-            right = self.evaluate_condition(
-                currency, condition.right, keys, passwords, identifier, result
-            )
-        # if left param is a SIG...
-        if isinstance(condition.left, SIG) and condition.left.pubkey in (
-            key.pubkey for key in keys
-        ):
-            left = True
-        # if left param is a CSV value...
-        if isinstance(condition.left, CSV):
-            # capture transaction of the source
-            tx = self._transactions_processor.find_by_hash(keys[0].pubkey, identifier)
-            if tx:
-                # capture current blockchain time
-                median_time = self._blockchain_processor.time(currency)
-                # param is true if tx time + CSV delay <= blockchain time
-                left = tx.timestamp + int(condition.left.time) <= median_time
-        # if left param is a CLTV value...
-        if isinstance(condition.left, CLTV):
-            # capture current blockchain time
-            median_time = self._blockchain_processor.time(currency)
-            # param is true if CL:TV value <= blockchain time
-            left = int(condition.left.timestamp) <= median_time
-        # if left param is a XHX value...
-        if isinstance(condition.left, XHX):
-            left = condition.left.sha_hash in [
-                sha256(password).hexdigest().upper() for password in passwords
-            ]
-        # if no op then stop evaluation...
-        if not condition.op:
-            return left
-        # if right param is a SIG...
-        if isinstance(condition.right, SIG) and condition.right.pubkey in (
-            key.pubkey for key in keys
-        ):
-            right = True
-        # if right param is a CSV value...
-        if isinstance(condition.right, CSV):
-            # capture transaction of the source
-            tx = self._transactions_processor.find_by_hash(keys[0].pubkey, identifier)
-            if tx:
-                # capture current blockchain time
-                median_time = self._blockchain_processor.time(currency)
-                # param is true if tx time + CSV delay <= blockchain time
-                right = tx.timestamp + int(condition.right.time) <= median_time
-        # if right param is a CLTV value...
-        if isinstance(condition.right, CLTV):
-            # capture current blockchain time
-            median_time = self._blockchain_processor.time(currency)
-            # param is true if CLTV value <= blockchain time
-            right = int(condition.right.timestamp) <= median_time
-        # if right param is a XHX value...
-        if isinstance(condition.right, XHX):
-            right = condition.right.sha_hash in [
-                sha256(password).upper() for password in passwords
-            ]
-        # if operator AND...
-        if condition.op == "&&":
-            return left & right
-        # operator OR
-        return left | right
diff --git a/src/sakia/services/sources.py b/src/sakia/services/sources.py
index be5ce7a36ff22529c52918f6d7ef0c5db883ac28..a5c2aa18ab8356673e88c3b89fe9acdc960c0633 100644
--- a/src/sakia/services/sources.py
+++ b/src/sakia/services/sources.py
@@ -1,7 +1,9 @@
+from hashlib import sha256
+
 from PyQt5.QtCore import QObject
 from duniterpy.api import bma, errors
 from duniterpy.documents import Transaction as TransactionDoc
-from duniterpy.grammars.output import Condition, SIG
+from duniterpy.grammars.output import Condition, SIG, CSV, CLTV, XHX
 from duniterpy.documents import BlockUID
 import logging
 import pypeg2
@@ -263,3 +265,97 @@ class SourcesServices(QObject):
             self._sources_processor.insert(entity)
         except AttributeError as e:
             self._logger.error(str(e))
+
+    def evaluate_condition(
+        self,
+        currency,
+        condition: Condition,
+        keys: list,
+        passwords,
+        identifier: str,
+        result: bool = True,
+    ) -> bool:
+        """
+        Evaluate a source lock condition
+        Support multiple signatures and passwords
+
+        :param passwords:
+        :param str currency: Name of currency
+        :param Condition condition: Condition instance
+        :param [SigningKey] keys: Keys to unlock condition (first key is the source owner key)
+        :param str identifier: Source transaction identifier
+        :param bool result: result accumulator
+        :return:
+        """
+        left = False
+        right = False
+        # if left param is a condition...
+        if isinstance(condition.left, Condition):
+            # evaluate condition
+            left = self.evaluate_condition(
+                currency, condition.left, keys, passwords, identifier, result
+            )
+        # if right param is a condition...
+        if isinstance(condition.right, Condition):
+            # evaluate condition
+            right = self.evaluate_condition(
+                currency, condition.right, keys, passwords, identifier, result
+            )
+        # if left param is a SIG...
+        if isinstance(condition.left, SIG) and condition.left.pubkey in (
+            key.pubkey for key in keys
+        ):
+            left = True
+        # if left param is a CSV value...
+        if isinstance(condition.left, CSV):
+            # capture transaction of the source
+            tx = self._transactions_processor.find_by_hash(keys[0].pubkey, identifier)
+            if tx:
+                # capture current blockchain time
+                median_time = self._blockchain_processor.time(currency)
+                # param is true if tx time + CSV delay <= blockchain time
+                left = tx.timestamp + int(condition.left.time) <= median_time
+        # if left param is a CLTV value...
+        if isinstance(condition.left, CLTV):
+            # capture current blockchain time
+            median_time = self._blockchain_processor.time(currency)
+            # param is true if CL:TV value <= blockchain time
+            left = int(condition.left.timestamp) <= median_time
+        # if left param is a XHX value...
+        if isinstance(condition.left, XHX):
+            left = condition.left.sha_hash in [
+                sha256(password).hexdigest().upper() for password in passwords
+            ]
+        # if no op then stop evaluation...
+        if not condition.op:
+            return left
+        # if right param is a SIG...
+        if isinstance(condition.right, SIG) and condition.right.pubkey in (
+            key.pubkey for key in keys
+        ):
+            right = True
+        # if right param is a CSV value...
+        if isinstance(condition.right, CSV):
+            # capture transaction of the source
+            tx = self._transactions_processor.find_by_hash(keys[0].pubkey, identifier)
+            if tx:
+                # capture current blockchain time
+                median_time = self._blockchain_processor.time(currency)
+                # param is true if tx time + CSV delay <= blockchain time
+                right = tx.timestamp + int(condition.right.time) <= median_time
+        # if right param is a CLTV value...
+        if isinstance(condition.right, CLTV):
+            # capture current blockchain time
+            median_time = self._blockchain_processor.time(currency)
+            # param is true if CLTV value <= blockchain time
+            right = int(condition.right.timestamp) <= median_time
+        # if right param is a XHX value...
+        if isinstance(condition.right, XHX):
+            right = condition.right.sha_hash in [
+                sha256(password).hexdigest().upper() for password in passwords
+            ]
+        # if operator AND...
+        if condition.op == "&&":
+            return left & right
+        # operator OR
+        return left | right
diff --git a/tests/technical/test_documents_service.py b/tests/technical/test_documents_service.py
index 9ec0a14a12ea2cdd22ab9576e5287e6d816a1eb8..99e94e3e5f47f34cffedb1306e9986df09feb2aa 100644
--- a/tests/technical/test_documents_service.py
+++ b/tests/technical/test_documents_service.py
@@ -44,6 +44,7 @@ async def test_send_more_than_40_sources(
         0,
         "Test comment",
         0,
+        None,
     )
     assert transactions[0].comment == "[CHAINED]"
     assert transactions[1].comment == "Test comment"
diff --git a/tests/technical/test_sources_service.py b/tests/technical/test_sources_service.py
index 9cb1d21c642f6b0c2088e9ac8ceb77db107fc365..553741bf3b74d9416fd40f12037db025a6ebff3a 100644
--- a/tests/technical/test_sources_service.py
+++ b/tests/technical/test_sources_service.py
@@ -83,7 +83,7 @@ async def test_send_tx_then_cancel(
     )
     fake_server_with_blockchain.reject_next_post = True
     await application_with_one_connection.documents_service.send_money(
-        bob_connection, bob.salt, bob.password, alice.key.pubkey, 10, 0, None, 0
+        bob_connection, bob.salt, bob.password, alice.key.pubkey, 10, 0, None, 0, None
     )
     tx_after_send = application_with_one_connection.transactions_service.transfers(
         bob.key.pubkey
diff --git a/tests/unit/services/test_documents.py b/tests/unit/services/test_documents.py
index 4374dca2d48041ecf1398ea2a248008fbdd976ba..dbb5fc19e6982e25e2901724a40cad2e185efbff 100644
--- a/tests/unit/services/test_documents.py
+++ b/tests/unit/services/test_documents.py
@@ -1,12 +1,10 @@
 from hashlib import sha256
 
-import pypeg2
 import pytest
 from duniterpy.grammars import output
-from duniterpy.grammars.output import Condition
 
-from sakia.data.entities import Transaction, Source
-from sakia.data.repositories import TransactionsRepo, SourcesRepo
+from sakia.data.entities import Transaction
+from sakia.data.repositories import TransactionsRepo
 
 
 @pytest.mark.asyncio
@@ -34,7 +32,7 @@ async def test_lock_mode_0(application_with_one_connection, fake_server, bob, al
         _,
         sakia_tx_list,
     ) = await application_with_one_connection.documents_service.send_money(
-        bob_connection, bob.salt, bob.password, alice.key.pubkey, 100, 0, None, 0
+        bob_connection, bob.salt, bob.password, alice.key.pubkey, 100, 0, None, 0, None
     )
 
     assert len(sakia_tx_list) == 1
@@ -69,7 +67,7 @@ async def test_lock_mode_1(application_with_one_connection, fake_server, bob, al
         _,
         sakia_tx_list,
     ) = await application_with_one_connection.documents_service.send_money(
-        bob_connection, bob.salt, bob.password, alice.key.pubkey, 100, 0, None, 1
+        bob_connection, bob.salt, bob.password, alice.key.pubkey, 100, 0, None, 1, None
     )
 
     assert len(sakia_tx_list) == 1
@@ -132,14 +130,14 @@ def test_evaluate_condition_source_lock_mode_0(
     condition = output.Condition.token(output.SIG.token(bob.key.pubkey),)
     # bob can spend this source
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency, condition, [bob.key], [], tx_hash
         )
         is True
     )
     # alice can not
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             condition,
             [alice.key],
@@ -212,14 +210,14 @@ def test_evaluate_condition_source_lock_mode_1(
     )
     # bob try to spend his source
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency, condition, [bob.key], [], tx_hash
         )
         is True
     )
     # alice try to get back this source before the CSV delay
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             condition,
             [alice.key],
@@ -271,14 +269,14 @@ def test_evaluate_condition_source_lock_mode_1(
 
     # bob try to spend his source
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency, condition, [bob.key], [], tx_hash
         )
         is True
     )
     # alice can get back this source after the CSV delay
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             condition,
             [alice.key],
@@ -347,14 +345,14 @@ def test_evaluate_condition_source_multisig(
     )
     # bob can not spend this source alone
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency, condition, [bob.key], [], tx_hash
         )
         is False
     )
     # alice can not spend this source alone
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             condition,
             [alice.key],
@@ -365,7 +363,7 @@ def test_evaluate_condition_source_multisig(
     )
     # alice && bob together only can spend this source
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             condition,
             [alice.key, bob.key],
@@ -519,7 +517,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # alice spend the source from tx2 with the password
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx2_condition,
             [alice.key],
@@ -532,7 +530,7 @@ def test_evaluate_condition_source_atomic_swap(
     # the password is revealed in the unlock of the tx3 spending tx2
     # bob can now spend tx1 using the password
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx1_condition,
             [bob.key],
@@ -544,7 +542,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # alice and bob can sign together to spend tx1
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx1_condition,
             [bob.key, alice.key],
@@ -556,7 +554,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # alice and bob can sign together to spend tx2
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx2_condition,
             [bob.key, alice.key],
@@ -568,7 +566,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # alice can not spend the source from tx2 without the password
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx2_condition,
             [alice.key],
@@ -580,7 +578,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # bob can not spend tx1 without the password
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx1_condition,
             [bob.key],
@@ -672,7 +670,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # alice can get back the source from tx1 without the password after 48h
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx1_condition,
             [alice.key],
@@ -684,7 +682,7 @@ def test_evaluate_condition_source_atomic_swap(
 
     # bob can spend tx2 without the password after 24h
     assert (
-        application_with_one_connection.documents_service.evaluate_condition(
+        application_with_one_connection.sources_service.evaluate_condition(
             application_with_one_connection.currency,
             tx2_condition,
             [bob.key],