Coverage for silkaj/money/balance.py: 86%

72 statements  

« prev     ^ index     » next       coverage.py v7.6.3, created at 2024-10-18 04:28 +0000

1# Copyright 2016-2024 Maël Azimi <m.a@moul.re> 

2# 

3# Silkaj is free software: you can redistribute it and/or modify 

4# it under the terms of the GNU Affero General Public License as published by 

5# the Free Software Foundation, either version 3 of the License, or 

6# (at your option) any later version. 

7# 

8# Silkaj is distributed in the hope that it will be useful, 

9# but WITHOUT ANY WARRANTY; without even the implied warranty of 

10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

11# GNU Affero General Public License for more details. 

12# 

13# You should have received a copy of the GNU Affero General Public License 

14# along with Silkaj. If not, see <https://www.gnu.org/licenses/>. 

15 

16import sys 

17from typing import Optional 

18 

19import rich_click as click 

20 

21from silkaj import tui 

22from silkaj.auth import auth_method, has_auth_method 

23from silkaj.blockchain.tools import get_head_block 

24from silkaj.money import tools as m_tools 

25from silkaj.public_key import gen_pubkey_checksum, is_pubkey_and_check 

26from silkaj.tools import get_currency_symbol 

27from silkaj.wot import tools as wt 

28 

29 

30@click.command("balance", help="Get wallet balance") 

31@click.argument("pubkeys", nargs=-1) 

32@click.pass_context 

33def balance_cmd(ctx: click.Context, pubkeys: str) -> None: 

34 if not has_auth_method(): 

35 # check input pubkeys 

36 if not pubkeys: 

37 sys.exit("You should specify one or many pubkeys") 

38 pubkeys_list = [] 

39 wrong_pubkeys = False 

40 for input_pubkey in pubkeys: 

41 checked_pubkey = is_pubkey_and_check(input_pubkey) 

42 if checked_pubkey: 

43 pubkey = str(checked_pubkey) 

44 else: 

45 pubkey = input_pubkey 

46 wrong_pubkeys = True 

47 print(f"ERROR: pubkey {pubkey} has a wrong format") 

48 if pubkey in pubkeys_list: 

49 sys.exit( 

50 f"ERROR: pubkey {gen_pubkey_checksum(pubkey)} was specified many times", 

51 ) 

52 pubkeys_list.append(pubkey) 

53 if wrong_pubkeys: 

54 sys.exit("Please check the pubkeys format.") 

55 

56 total = [0, 0] 

57 for pubkey in pubkeys_list: 

58 inputs_balance = m_tools.get_amount_from_pubkey(pubkey) 

59 show_amount_from_pubkey(pubkey, inputs_balance) 

60 total[0] += inputs_balance[0] 

61 total[1] += inputs_balance[1] 

62 if len(pubkeys_list) > 1: 

63 show_amount_from_pubkey("Total", total) 

64 else: 

65 key = auth_method() 

66 pubkey = key.pubkey 

67 show_amount_from_pubkey(pubkey, m_tools.get_amount_from_pubkey(pubkey)) 

68 

69 

70def show_amount_from_pubkey(label: str, inputs_balance: list[int]) -> None: 

71 """ 

72 Shows the balance of a pubkey. 

73 `label` can be either a pubkey or "Total". 

74 """ 

75 totalAmountInput = inputs_balance[0] 

76 balance = inputs_balance[1] 

77 currency_symbol = get_currency_symbol() 

78 ud_value = m_tools.get_ud_value() 

79 average = get_average() 

80 member = None 

81 

82 # if `pubkey` is a pubkey, get pubkey:checksum and uid 

83 if label != "Total": 

84 member = wt.is_member(label) 

85 label = gen_pubkey_checksum(label) 

86 # display balance table 

87 display = [] 

88 display.append(["Balance of pubkey", label]) 

89 

90 if member: 

91 display.append(["User identifier", member["uid"]]) 

92 

93 if totalAmountInput - balance != 0: 

94 m_tools.display_amount( 

95 display, 

96 "Blockchain", 

97 balance, 

98 ud_value, 

99 currency_symbol, 

100 ) 

101 m_tools.display_amount( 

102 display, 

103 "Pending transaction", 

104 (totalAmountInput - balance), 

105 ud_value, 

106 currency_symbol, 

107 ) 

108 m_tools.display_amount( 

109 display, 

110 "Total balance", 

111 totalAmountInput, 

112 ud_value, 

113 currency_symbol, 

114 ) 

115 if average: 

116 display.append( 

117 [ 

118 "Total relative to M/N", 

119 f"{round(totalAmountInput / average, 2)} x M/N", 

120 ], 

121 ) 

122 

123 table = tui.Table() 

124 table.fill_rows(display) 

125 click.echo(table.draw()) 

126 

127 

128def get_average() -> Optional[int]: 

129 head = get_head_block() 

130 try: 

131 return head["monetaryMass"] / head["membersCount"] 

132 except ZeroDivisionError: 

133 print("The currency reached zero members") 

134 return None