diff --git a/silkaj/money.py b/silkaj/money.py index 4a291f762663d528e5a8c95d934f17476333a85e..880984b7d25c1c6821620f25007929e9a8aa62eb 100644 --- a/silkaj/money.py +++ b/silkaj/money.py @@ -13,12 +13,14 @@ # 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 sys + from click import argument, command, echo, pass_context from duniterpy.api.bma import blockchain, tx from duniterpy.documents.transaction import InputSource from tabulate import tabulate -from silkaj import wot_tools as wt +from silkaj import constants from silkaj.auth import auth_method, has_auth_method from silkaj.blockchain_tools import HeadBlock from silkaj.crypto_tools import ( @@ -26,8 +28,8 @@ from silkaj.crypto_tools import ( is_pubkey_and_check, validate_checksum, ) -from silkaj.network_tools import ClientInstance -from silkaj.tools import CurrencySymbol, coroutine, message_exit +from silkaj.network_tools import ClientInstance, gva_query +from silkaj.tools import coroutine, message_exit from silkaj.tui import display_amount, display_pubkey_and_checksum @@ -36,9 +38,19 @@ from silkaj.tui import display_amount, display_pubkey_and_checksum @pass_context @coroutine async def cmd_amount(ctx, pubkeys): - client = ClientInstance().client - if not has_auth_method(): - + def gen_query(pubkeys_list): + pubkeys_str = " ".join(f'"{pubkey}"' for pubkey in pubkeys_list) + return f'query {{\ +balances(scripts: [{pubkeys_str}]){{amount}}\ +currentBlock{{monetaryMass membersCount}}\ +currentUd{{amount}}\ +idty(pubkey: "{pubkeys_list[0]}"){{username}}\ +node {{peer {{currency}} }}\ +}}' + + if has_auth_method(): + pubkeys_list = auth_method().pubkey + else: # check input pubkeys if not pubkeys: message_exit("You should specify one or many pubkeys") @@ -57,69 +69,65 @@ async def cmd_amount(ctx, pubkeys): if wrong_pubkeys: message_exit("Please check the pubkeys format.") - total = [0, 0] - for pubkey in pubkeys_list: - inputs_balance = await get_amount_from_pubkey(pubkey) - await show_amount_from_pubkey(pubkey, inputs_balance) - total[0] += inputs_balance[0] - total[1] += inputs_balance[1] - if len(pubkeys_list) > 1: - await show_amount_from_pubkey("Total", total) - else: - key = auth_method() - pubkey = key.pubkey - await show_amount_from_pubkey(pubkey, await get_amount_from_pubkey(pubkey)) - await client.close() - - -async def show_amount_from_pubkey(label, inputs_balance): + response = await gva_query(gen_query(pubkeys_list)) + if not response: + pubkey_checksum = display_pubkey_and_checksum(pubkeys_list) + sys.exit(f"{pubkey_checksum} public key without money activity.") + + currency = response["node"]["peer"]["currency"] + if currency == "g1": + currency_symbol = constants.G1_SYMBOL + elif currency == "g1-test": + currency_symbol = constants.GTEST_SYMBOL + + current_block = response["currentBlock"] + average = current_block["monetaryMass"] / current_block["membersCount"] + current_ud = response["currentUd"]["amount"] + uid = response["idty"]["username"] if response["idty"] else None + + table = [] + balances_sum = {"amount": 0} + for pubkey, balance in zip(pubkeys_list, response["balances"]): + gen_table(table, pubkey, balance, current_ud, average, currency_symbol, uid) + if balance: + balances_sum["amount"] += balance["amount"] + if len(pubkeys_list) > 1: + gen_table(table, "Total", balances_sum, current_ud, average, currency_symbol) + echo(tabulate(table, tablefmt="fancy_grid")) + + +def gen_table(table, label, balance, current_ud, average, currency_symbol, uid=None): """ Shows the balance of a pubkey. `label` can be either a pubkey or "Total". + if `pubkey` is a pubkey, get pubkey:checksum """ - totalAmountInput = inputs_balance[0] - balance = inputs_balance[1] - currency_symbol = await CurrencySymbol().symbol - ud_value = await UDValue().ud_value - average, monetary_mass = await get_average() - member = False - - # if `pubkey` is a pubkey, get pubkey:checksum and uid if label != "Total": - member = await wt.is_member(label) label = display_pubkey_and_checksum(label) - # display balance table - display = list() - display.append(["Balance of pubkey", label]) - - if member: - display.append(["User identifier", member["uid"]]) - - if totalAmountInput - balance != 0: - display_amount(display, "Blockchain", balance, ud_value, currency_symbol) + table.append(["Balance of pubkey", label]) + if uid: + table.append(["User identifier", uid]) + if balance: + """ + TODO: handle pendings? + if totalAmountInput - balance != 0: + display_amount(table, "Blockchain balance", balance, current_ud, currency_symbol) + display_amount( + table, + "Pendings balance", + totalAmountInput - balance, + current_ud, + currency_symbol, + ) + """ display_amount( - display, - "Pending transaction", - (totalAmountInput - balance), - ud_value, - currency_symbol, + table, "Total balance", balance["amount"], current_ud, currency_symbol ) - display_amount(display, "Total amount", totalAmountInput, ud_value, currency_symbol) - display.append( - [ - "Total relative to M/N", - "{0} x M/N".format(round(totalAmountInput / average, 2)), - ] - ) - echo(tabulate(display, tablefmt="fancy_grid")) - - -async def get_average(): - head = await HeadBlock().head_block - monetary_mass = head["monetaryMass"] - members_count = head["membersCount"] - average = monetary_mass / members_count - return average, monetary_mass + relative = round(balance["amount"] / average, 2) + line = ["Total relative to M/N", f"{relative} × M/N"] + table.append(line) + else: + table.append(["Public key", "Without money activity"]) async def get_amount_from_pubkey(pubkey): diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index b9d86013df100bec325298a758e7377bd124af99..ad0c69bf48902c2c58accb94fed893a666631f49 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -50,9 +50,9 @@ def test_balance(): silkaj + ["--gtest", "balance", "3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj"] ).decode() assert ( - "│ Balance of pubkey │ 3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:EyF │" + "│ Balance of pubkey │ 3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:EyF │" in output ) - assert "│ Total amount (unit|relative) │" in output + assert "│ Total balance (unit|relative) │" in output assert "UD ĞTest" in output assert "Total relative to M/N" in output