From f5fbfa5c322f7a1c1fba7f2f8993174c8593a915 Mon Sep 17 00:00:00 2001
From: Moul <moul@moul.re>
Date: Fri, 14 Oct 2022 18:37:03 +0200
Subject: [PATCH] Move gen_pubkey_checksum from tui to public_key (#330)

In order to avoid as much as possible circural import

Also fits better with other pubkey tools
---
 silkaj/auth.py            |  2 +-
 silkaj/cert.py            |  6 +++---
 silkaj/checksum.py        |  2 +-
 silkaj/idty_tools.py      |  2 +-
 silkaj/membership.py      |  3 ++-
 silkaj/money/balance.py   |  6 +++---
 silkaj/money/history.py   |  8 ++++++--
 silkaj/money/transfer.py  |  9 +++++----
 silkaj/public_key.py      | 16 +++++++++++++++-
 silkaj/revocation.py      |  7 ++++---
 silkaj/tui.py             | 19 +++----------------
 silkaj/wot.py             |  4 ++--
 tests/money/test_tools.py |  2 +-
 tests/test_idty_tools.py  |  2 +-
 tests/test_membership.py  |  3 ++-
 tests/test_public_key.py  | 19 +++++++++++++++++++
 tests/test_revocation.py  |  2 +-
 tests/test_tui.py         | 22 +++-------------------
 18 files changed, 73 insertions(+), 61 deletions(-)

diff --git a/silkaj/auth.py b/silkaj/auth.py
index 2be8c9ec..f038f067 100644
--- a/silkaj/auth.py
+++ b/silkaj/auth.py
@@ -23,7 +23,7 @@ from duniterpy.key import SigningKey
 from duniterpy.key.scrypt_params import ScryptParams
 
 from silkaj.constants import PUBKEY_PATTERN
-from silkaj.tui import gen_pubkey_checksum
+from silkaj.public_key import gen_pubkey_checksum
 
 SEED_HEX_PATTERN = "^[0-9a-fA-F]{64}$"
 PUBSEC_PUBKEY_PATTERN = f"pub: ({PUBKEY_PATTERN})"
diff --git a/silkaj/cert.py b/silkaj/cert.py
index 4ab28c47..869e0765 100644
--- a/silkaj/cert.py
+++ b/silkaj/cert.py
@@ -30,7 +30,7 @@ from silkaj.blockchain import tools as bc_tools
 from silkaj.constants import ALL, DATE
 from silkaj.g1_monetary_license import license_approval
 from silkaj.network import client_instance, send_document
-from silkaj.public_key import is_pubkey_and_check
+from silkaj.public_key import gen_pubkey_checksum, is_pubkey_and_check
 
 
 @click.command("cert", help="Send certification")
@@ -129,9 +129,9 @@ def certification_confirmation(
     cert.append(
         [
             "Pubkey",
-            tui.gen_pubkey_checksum(issuer_pubkey),
+            gen_pubkey_checksum(issuer_pubkey),
             "–>",
-            tui.gen_pubkey_checksum(pubkey_to_certify),
+            gen_pubkey_checksum(pubkey_to_certify),
         ]
     )
     params = bc_tools.get_blockchain_parameters()
diff --git a/silkaj/checksum.py b/silkaj/checksum.py
index 8737a87e..b5de0d47 100644
--- a/silkaj/checksum.py
+++ b/silkaj/checksum.py
@@ -23,8 +23,8 @@ from silkaj.public_key import (
     PUBKEY_CHECKSUM_PATTERN,
     PUBKEY_DELIMITED_PATTERN,
     gen_checksum,
+    gen_pubkey_checksum,
 )
-from silkaj.tui import gen_pubkey_checksum
 
 MESSAGE = "You should specify a pubkey or an authentication method"
 
diff --git a/silkaj/idty_tools.py b/silkaj/idty_tools.py
index 5c65e289..1d1f265b 100644
--- a/silkaj/idty_tools.py
+++ b/silkaj/idty_tools.py
@@ -27,7 +27,7 @@ from texttable import Texttable
 from silkaj import wot_tools as wt
 from silkaj.constants import ALL
 from silkaj.network import client_instance
-from silkaj.tui import gen_pubkey_checksum
+from silkaj.public_key import gen_pubkey_checksum
 
 
 def display_identity(idty: Identity) -> Texttable:
diff --git a/silkaj/membership.py b/silkaj/membership.py
index d65ce49c..ef280e8e 100644
--- a/silkaj/membership.py
+++ b/silkaj/membership.py
@@ -27,6 +27,7 @@ from silkaj.blockchain import tools as bc_tools
 from silkaj.constants import DATE, SUCCESS_EXIT_STATUS
 from silkaj.g1_monetary_license import license_approval
 from silkaj.network import client_instance, send_document
+from silkaj.public_key import gen_pubkey_checksum
 
 
 @click.command(
@@ -124,7 +125,7 @@ def display_confirmation_table(
         )
 
     table.append(["User Identifier (UID)", identity_uid])
-    table.append(["Public Key", tui.gen_pubkey_checksum(pubkey)])
+    table.append(["Public Key", gen_pubkey_checksum(pubkey)])
 
     table.append(["Block Identity", str(identity_block_id)[:45] + "…"])
 
diff --git a/silkaj/money/balance.py b/silkaj/money/balance.py
index 3309cb2a..520b9a8f 100644
--- a/silkaj/money/balance.py
+++ b/silkaj/money/balance.py
@@ -23,7 +23,7 @@ from silkaj import wot_tools as wt
 from silkaj.auth import auth_method, has_auth_method
 from silkaj.blockchain.tools import get_head_block
 from silkaj.money import tools as m_tools
-from silkaj.public_key import is_pubkey_and_check
+from silkaj.public_key import gen_pubkey_checksum, is_pubkey_and_check
 from silkaj.tools import get_currency_symbol
 
 
@@ -48,7 +48,7 @@ def cmd_amount(ctx: Context, pubkeys: str) -> None:
                 print(f"ERROR: pubkey {pubkey} has a wrong format")
             if pubkey in pubkeys_list:
                 sys.exit(
-                    f"ERROR: pubkey {tui.gen_pubkey_checksum(pubkey)} was specified many times"
+                    f"ERROR: pubkey {gen_pubkey_checksum(pubkey)} was specified many times"
                 )
             pubkeys_list.append(pubkey)
         if wrong_pubkeys:
@@ -83,7 +83,7 @@ def show_amount_from_pubkey(label: str, inputs_balance: List[int]) -> None:
     # if `pubkey` is a pubkey, get pubkey:checksum and uid
     if label != "Total":
         member = wt.is_member(label)
-        label = tui.gen_pubkey_checksum(label)
+        label = gen_pubkey_checksum(label)
     # display balance table
     display = []
     display.append(["Balance of pubkey", label])
diff --git a/silkaj/money/history.py b/silkaj/money/history.py
index edd456a9..98a8f892 100644
--- a/silkaj/money/history.py
+++ b/silkaj/money/history.py
@@ -32,9 +32,13 @@ from silkaj.money.tools import (
     get_ud_value,
 )
 from silkaj.network import client_instance
-from silkaj.public_key import check_pubkey_format, validate_checksum
+from silkaj.public_key import (
+    check_pubkey_format,
+    gen_pubkey_checksum,
+    validate_checksum,
+)
 from silkaj.tools import get_currency_symbol
-from silkaj.tui import Table, gen_pubkey_checksum
+from silkaj.tui import Table
 
 
 @command("history", help="Display transaction history")
diff --git a/silkaj/money/transfer.py b/silkaj/money/transfer.py
index 8447b313..bc5d2a0d 100644
--- a/silkaj/money/transfer.py
+++ b/silkaj/money/transfer.py
@@ -39,6 +39,7 @@ from silkaj.constants import (
     MINIMAL_RELATIVE_TX_AMOUNT,
 )
 from silkaj.money import tools as m_tools
+from silkaj.public_key import gen_pubkey_checksum
 
 MAX_COMMENT_LENGTH = 255
 
@@ -147,7 +148,7 @@ def send_transaction(
     if allsources:
         if pubkey_amount[0] <= 0:
             tools.message_exit(
-                f"Error: Issuer pubkey {tui.gen_pubkey_checksum(issuer_pubkey)} is empty. \
+                f"Error: Issuer pubkey {gen_pubkey_checksum(issuer_pubkey)} is empty. \
 No transaction sent."
             )
 
@@ -307,7 +308,7 @@ def check_transaction_values(
         if public_key.check_pubkey_format(outputBackChange):
             outputBackChange = public_key.validate_checksum(outputBackChange)
     if enough_source:
-        pubkey = tui.gen_pubkey_checksum(issuer_pubkey)
+        pubkey = gen_pubkey_checksum(issuer_pubkey)
         tools.message_exit(
             f"{pubkey} pubkey doesn’t have enough money for this transaction."
         )
@@ -465,7 +466,7 @@ def generate_and_send_transaction(
         print("Generate Change Transaction")
     else:
         print("Generate Transaction:")
-    print("   - From:    " + tui.gen_pubkey_checksum(issuers))
+    print("   - From:    " + gen_pubkey_checksum(issuers))
     for tx_amount, outputAddress in zip(tx_amounts, outputAddresses):
         display_sent_tx(outputAddress, tx_amount)
     print("   - Total:   " + str(sum(tx_amounts) / 100))
@@ -485,7 +486,7 @@ def generate_and_send_transaction(
 def display_sent_tx(outputAddress: str, amount: int) -> None:
     print(
         "   - To:     ",
-        tui.gen_pubkey_checksum(outputAddress),
+        gen_pubkey_checksum(outputAddress),
         "\n   - Amount: ",
         amount / 100,
     )
diff --git a/silkaj/public_key.py b/silkaj/public_key.py
index 5e39c2f3..d6095f36 100644
--- a/silkaj/public_key.py
+++ b/silkaj/public_key.py
@@ -19,7 +19,7 @@ from typing import Any, Optional, Union
 
 import base58
 
-from silkaj.constants import PUBKEY_PATTERN
+from silkaj.constants import PUBKEY_PATTERN, SHORT_PUBKEY_SIZE
 from silkaj.tools import message_exit
 
 PUBKEY_DELIMITED_PATTERN = f"^{PUBKEY_PATTERN}$"
@@ -79,3 +79,17 @@ def gen_checksum(pubkey: str) -> str:
     pubkey_byte = base58.b58decode(pubkey)
     _hash = hashlib.sha256(hashlib.sha256(pubkey_byte).digest()).digest()
     return str(base58.b58encode(_hash)[:3].decode("utf-8"))
+
+
+def gen_pubkey_checksum(
+    pubkey: str,
+    short: Optional[bool] = False,
+    length: Optional[int] = SHORT_PUBKEY_SIZE,
+) -> str:
+    """
+    Returns "<pubkey>:<checksum>" in full form.
+    returns `length` first chars of pubkey and checksum in short form.
+    `length` defaults to SHORT_PUBKEY_SIZE.
+    """
+    short_pubkey = f"{pubkey[:length]}…" if short else pubkey
+    return f"{short_pubkey}:{gen_checksum(pubkey)}"
diff --git a/silkaj/revocation.py b/silkaj/revocation.py
index 4c677f9f..837cd9e4 100644
--- a/silkaj/revocation.py
+++ b/silkaj/revocation.py
@@ -29,6 +29,7 @@ from duniterpy.key.verifying_key import VerifyingKey
 from silkaj import auth, idty_tools, network, tui, wot
 from silkaj.blockchain.tools import get_currency
 from silkaj.constants import FAILURE_EXIT_STATUS, SUCCESS_EXIT_STATUS
+from silkaj.public_key import gen_pubkey_checksum
 
 REVOCATION_LOCAL_PATH = "revocation.txt"
 
@@ -46,7 +47,7 @@ def save(ctx: click.Context, file: str) -> None:
     currency = get_currency()
 
     key = auth.auth_method()
-    tui.gen_pubkey_checksum(key.pubkey)
+    gen_pubkey_checksum(key.pubkey)
     _id = (wot.choose_identity(key.pubkey))[0]
     rev_doc = create_revocation_doc(_id, key.pubkey, currency)
     rev_doc.sign(key)
@@ -78,7 +79,7 @@ def revoke_now(ctx: click.Context) -> None:
     warn_before_dry_run_or_display(ctx)
 
     key = auth.auth_method()
-    tui.gen_pubkey_checksum(key.pubkey)
+    gen_pubkey_checksum(key.pubkey)
     _id = (wot.choose_identity(key.pubkey))[0]
     rev_doc = create_revocation_doc(_id, key.pubkey, currency)
     rev_doc.sign(key)
@@ -183,7 +184,7 @@ def create_revocation_doc(_id: Dict, pubkey: str, currency: str) -> Revocation:
 
 
 def save_doc(path: str, content: str, pubkey: str) -> None:
-    pubkey_cksum = tui.gen_pubkey_checksum(pubkey)
+    pubkey_cksum = gen_pubkey_checksum(pubkey)
     rev_path = Path(path)
     # Ask confirmation if the file exists
     if rev_path.is_file():
diff --git a/silkaj/tui.py b/silkaj/tui.py
index 4813b81e..ed9543b8 100644
--- a/silkaj/tui.py
+++ b/silkaj/tui.py
@@ -16,12 +16,13 @@
 import shutil
 import sys
 from collections import OrderedDict
-from typing import Dict, List, Optional, Union
+from typing import Dict, List, Union
 
 import click
 from texttable import Texttable
 
-from silkaj import constants, public_key, wot_tools
+from silkaj import constants, wot_tools
+from silkaj.public_key import gen_pubkey_checksum
 
 VERT_TABLE_CHARS = ["─", "│", "│", "═"]
 
@@ -52,20 +53,6 @@ def display_pubkey(tx: List, message: str, pubkey: str) -> None:
         tx.append([f"{message} (id)", idty["uid"]])
 
 
-def gen_pubkey_checksum(
-    pubkey: str,
-    short: Optional[bool] = False,
-    length: Optional[int] = constants.SHORT_PUBKEY_SIZE,
-) -> str:
-    """
-    Returns "<pubkey>:<checksum>" in full form.
-    returns `length` first chars of pubkey and checksum in short form.
-    `length` defaults to SHORT_PUBKEY_SIZE.
-    """
-    short_pubkey = f"{pubkey[:length]}…" if short else pubkey
-    return f"{short_pubkey}:{public_key.gen_checksum(pubkey)}"
-
-
 def send_doc_confirmation(document_name: str) -> None:
     if not click.confirm(f"Do you confirm sending this {document_name}?"):
         sys.exit(constants.SUCCESS_EXIT_STATUS)
diff --git a/silkaj/wot.py b/silkaj/wot.py
index f0dc7d68..9e14c70c 100644
--- a/silkaj/wot.py
+++ b/silkaj/wot.py
@@ -25,8 +25,8 @@ from silkaj import wot_tools as wt
 from silkaj.blockchain.tools import get_blockchain_parameters
 from silkaj.constants import DATE
 from silkaj.network import client_instance, exit_on_http_error
-from silkaj.public_key import is_pubkey_and_check
-from silkaj.tui import Table, gen_pubkey_checksum
+from silkaj.public_key import gen_pubkey_checksum, is_pubkey_and_check
+from silkaj.tui import Table
 
 
 def get_sent_certifications(
diff --git a/tests/money/test_tools.py b/tests/money/test_tools.py
index 69b2eec4..d3e43920 100644
--- a/tests/money/test_tools.py
+++ b/tests/money/test_tools.py
@@ -19,7 +19,7 @@ from click.testing import CliRunner
 from silkaj.cli import cli
 from silkaj.constants import FAILURE_EXIT_STATUS
 from silkaj.money.tools import get_sources
-from silkaj.tui import gen_pubkey_checksum
+from silkaj.public_key import gen_pubkey_checksum
 
 
 def test_get_sources(monkeypatch):
diff --git a/tests/test_idty_tools.py b/tests/test_idty_tools.py
index e8961cb2..082523f6 100644
--- a/tests/test_idty_tools.py
+++ b/tests/test_idty_tools.py
@@ -24,7 +24,7 @@ from duniterpy.documents.identity import Identity
 
 from silkaj import idty_tools
 from silkaj.constants import ALL, PUBKEY_PATTERN
-from silkaj.tui import gen_pubkey_checksum
+from silkaj.public_key import gen_pubkey_checksum
 from tests.patched.idty_tools import (
     idty1,
     idty2,
diff --git a/tests/test_membership.py b/tests/test_membership.py
index 66e6e177..77a5cd7c 100644
--- a/tests/test_membership.py
+++ b/tests/test_membership.py
@@ -27,6 +27,7 @@ from silkaj.blockchain import tools as bc_tools
 from silkaj.cli import cli
 from silkaj.constants import DATE
 from silkaj.network import client_instance
+from silkaj.public_key import gen_pubkey_checksum
 from tests.patched.blockchain_tools import (
     currency,
     fake_block_id,
@@ -165,7 +166,7 @@ def test_display_confirmation_table(patched_wot_requirements, monkeypatch, capsy
         )
 
     table.append(["User Identifier (UID)", identity_uid])
-    table.append(["Public Key", tui.gen_pubkey_checksum(PUBKEY)])
+    table.append(["Public Key", gen_pubkey_checksum(PUBKEY)])
 
     table.append(["Block Identity", str(identity_block_id)[:45] + "…"])
 
diff --git a/tests/test_public_key.py b/tests/test_public_key.py
index 3849ebe3..a0830a2c 100644
--- a/tests/test_public_key.py
+++ b/tests/test_public_key.py
@@ -16,6 +16,7 @@
 import pytest
 
 from silkaj import public_key
+from silkaj.constants import SHORT_PUBKEY_SIZE
 
 
 # test gen_checksum
@@ -113,3 +114,21 @@ def test_is_pubkey_and_check_errors(uid_pubkey, expected, capsys):
         public_key.is_pubkey_and_check(uid_pubkey)
         assert capsys.readouterr() == expected
     assert pytest_exit.type == SystemExit
+
+
+# gen_pubkey_checksum
+@pytest.mark.parametrize(
+    "pubkey, checksum",
+    [
+        ("J4c8CARmP9vAFNGtHRuzx14zvxojyRWHW2darguVqjtX", "KAv"),
+    ],
+)
+def test_gen_pubkey_checksum(pubkey, checksum):
+    assert f"{pubkey}:{checksum}" == public_key.gen_pubkey_checksum(pubkey)
+    assert (
+        f"{pubkey[:SHORT_PUBKEY_SIZE]}…:{checksum}"
+        == public_key.gen_pubkey_checksum(pubkey, short=True)
+    )
+    assert f"{pubkey[:14]}…:{checksum}" == public_key.gen_pubkey_checksum(
+        pubkey, short=True, length=14
+    )
diff --git a/tests/test_revocation.py b/tests/test_revocation.py
index 4e282242..3ed44f96 100644
--- a/tests/test_revocation.py
+++ b/tests/test_revocation.py
@@ -29,7 +29,7 @@ from silkaj.blockchain import tools as bc_tools
 from silkaj.cli import cli
 from silkaj.constants import FAILURE_EXIT_STATUS, SUCCESS_EXIT_STATUS
 from silkaj.network import client_instance
-from silkaj.tui import gen_pubkey_checksum
+from silkaj.public_key import gen_pubkey_checksum
 from tests.patched.auth import patched_auth_method
 from tests.patched.blockchain_tools import patched_get_head_block_gtest
 from tests.patched.idty_tools import idty1, idty2, idty_block, lookup_one, lookup_two
diff --git a/tests/test_tui.py b/tests/test_tui.py
index 460337ab..90563800 100644
--- a/tests/test_tui.py
+++ b/tests/test_tui.py
@@ -20,7 +20,8 @@ import pytest
 from texttable import Texttable
 
 from silkaj import tui, wot_tools
-from silkaj.constants import G1_SYMBOL, SHORT_PUBKEY_SIZE
+from silkaj.constants import G1_SYMBOL
+from silkaj.public_key import gen_pubkey_checksum
 from tests.patched.test_constants import mock_ud_value
 from tests.patched.wot import patched_is_member
 
@@ -53,7 +54,7 @@ def test_display_amount(message, amount, currency_symbol):
 def test_display_pubkey(message, pubkey, uid, monkeypatch):
     monkeypatch.setattr(wot_tools, "is_member", patched_is_member)
 
-    expected = [[f"{message} (pubkey:checksum)", tui.gen_pubkey_checksum(pubkey)]]
+    expected = [[f"{message} (pubkey:checksum)", gen_pubkey_checksum(pubkey)]]
     if uid:
         expected.append([f"{message} (id)", uid])
     tx = []
@@ -61,23 +62,6 @@ def test_display_pubkey(message, pubkey, uid, monkeypatch):
     assert tx == expected
 
 
-# gen_pubkey_checksum
-@pytest.mark.parametrize(
-    "pubkey, checksum",
-    [
-        ("J4c8CARmP9vAFNGtHRuzx14zvxojyRWHW2darguVqjtX", "KAv"),
-    ],
-)
-def test_gen_pubkey_checksum(pubkey, checksum):
-    assert f"{pubkey}:{checksum}" == tui.gen_pubkey_checksum(pubkey)
-    assert f"{pubkey[:SHORT_PUBKEY_SIZE]}…:{checksum}" == tui.gen_pubkey_checksum(
-        pubkey, short=True
-    )
-    assert f"{pubkey[:14]}…:{checksum}" == tui.gen_pubkey_checksum(
-        pubkey, short=True, length=14
-    )
-
-
 def test_create_table():
     expected = Texttable(max_width=shutil.get_terminal_size().columns)
     expected.add_rows([["one", "two"], ["three", "four"]])
-- 
GitLab