URI: 
       tstdio.py - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
       tstdio.py (8385B)
       ---
            1 from decimal import Decimal
            2 import getpass
            3 import datetime
            4 import logging
            5 
            6 from electrum import util
            7 from electrum import WalletStorage, Wallet
            8 from electrum.wallet_db import WalletDB
            9 from electrum.util import format_satoshis
           10 from electrum.bitcoin import is_address, COIN
           11 from electrum.transaction import PartialTxOutput
           12 from electrum.network import TxBroadcastError, BestEffortRequestFailed
           13 from electrum.logging import console_stderr_handler
           14 
           15 _ = lambda x:x  # i18n
           16 
           17 # minimal fdisk like gui for console usage
           18 # written by rofl0r, with some bits stolen from the text gui (ncurses)
           19 
           20 
           21 class ElectrumGui:
           22 
           23     def __init__(self, config, daemon, plugins):
           24         self.config = config
           25         self.network = daemon.network
           26         storage = WalletStorage(config.get_wallet_path())
           27         if not storage.file_exists:
           28             print("Wallet not found. try 'electrum create'")
           29             exit()
           30         if storage.is_encrypted():
           31             password = getpass.getpass('Password:', stream=None)
           32             storage.decrypt(password)
           33 
           34         db = WalletDB(storage.read(), manual_upgrades=False)
           35 
           36         self.done = 0
           37         self.last_balance = ""
           38 
           39         console_stderr_handler.setLevel(logging.CRITICAL)
           40 
           41         self.str_recipient = ""
           42         self.str_description = ""
           43         self.str_amount = ""
           44         self.str_fee = ""
           45 
           46         self.wallet = Wallet(db, storage, config=config)
           47         self.wallet.start_network(self.network)
           48         self.contacts = self.wallet.contacts
           49 
           50         util.register_callback(self.on_network, ['wallet_updated', 'network_updated', 'banner'])
           51         self.commands = [_("[h] - displays this help text"), \
           52                          _("[i] - display transaction history"), \
           53                          _("[o] - enter payment order"), \
           54                          _("[p] - print stored payment order"), \
           55                          _("[s] - send stored payment order"), \
           56                          _("[r] - show own receipt addresses"), \
           57                          _("[c] - display contacts"), \
           58                          _("[b] - print server banner"), \
           59                          _("[q] - quit") ]
           60         self.num_commands = len(self.commands)
           61 
           62     def on_network(self, event, *args):
           63         if event in ['wallet_updated', 'network_updated']:
           64             self.updated()
           65         elif event == 'banner':
           66             self.print_banner()
           67 
           68     def main_command(self):
           69         self.print_balance()
           70         c = input("enter command: ")
           71         if c == "h" : self.print_commands()
           72         elif c == "i" : self.print_history()
           73         elif c == "o" : self.enter_order()
           74         elif c == "p" : self.print_order()
           75         elif c == "s" : self.send_order()
           76         elif c == "r" : self.print_addresses()
           77         elif c == "c" : self.print_contacts()
           78         elif c == "b" : self.print_banner()
           79         elif c == "n" : self.network_dialog()
           80         elif c == "e" : self.settings_dialog()
           81         elif c == "q" : self.done = 1
           82         else: self.print_commands()
           83 
           84     def updated(self):
           85         s = self.get_balance()
           86         if s != self.last_balance:
           87             print(s)
           88         self.last_balance = s
           89         return True
           90 
           91     def print_commands(self):
           92         self.print_list(self.commands, "Available commands")
           93 
           94     def print_history(self):
           95         width = [20, 40, 14, 14]
           96         delta = (80 - sum(width) - 4)/3
           97         format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \
           98         + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s"
           99         messages = []
          100 
          101         for hist_item in reversed(self.wallet.get_history()):
          102             if hist_item.tx_mined_status.conf:
          103                 timestamp = hist_item.tx_mined_status.timestamp
          104                 try:
          105                     time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
          106                 except Exception:
          107                     time_str = "unknown"
          108             else:
          109                 time_str = 'unconfirmed'
          110 
          111             label = self.wallet.get_label_for_txid(hist_item.txid)
          112             messages.append(format_str % (time_str, label, format_satoshis(delta, whitespaces=True),
          113                                           format_satoshis(hist_item.balance, whitespaces=True)))
          114 
          115         self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
          116 
          117 
          118     def print_balance(self):
          119         print(self.get_balance())
          120 
          121     def get_balance(self):
          122         if self.wallet.network.is_connected():
          123             if not self.wallet.up_to_date:
          124                 msg = _( "Synchronizing..." )
          125             else:
          126                 c, u, x =  self.wallet.get_balance()
          127                 msg = _("Balance")+": %f  "%(Decimal(c) / COIN)
          128                 if u:
          129                     msg += "  [%f unconfirmed]"%(Decimal(u) / COIN)
          130                 if x:
          131                     msg += "  [%f unmatured]"%(Decimal(x) / COIN)
          132         else:
          133                 msg = _( "Not connected" )
          134 
          135         return(msg)
          136 
          137 
          138     def print_contacts(self):
          139         messages = map(lambda x: "%20s   %45s "%(x[0], x[1][1]), self.contacts.items())
          140         self.print_list(messages, "%19s  %25s "%("Key", "Value"))
          141 
          142     def print_addresses(self):
          143         messages = map(lambda addr: "%30s    %30s       "%(addr, self.wallet.get_label(addr)), self.wallet.get_addresses())
          144         self.print_list(messages, "%19s  %25s "%("Address", "Label"))
          145 
          146     def print_order(self):
          147         print("send order to " + self.str_recipient + ", amount: " + self.str_amount \
          148               + "\nfee: " + self.str_fee + ", desc: " + self.str_description)
          149 
          150     def enter_order(self):
          151         self.str_recipient = input("Pay to: ")
          152         self.str_description = input("Description : ")
          153         self.str_amount = input("Amount: ")
          154         self.str_fee = input("Fee: ")
          155 
          156     def send_order(self):
          157         self.do_send()
          158 
          159     def print_banner(self):
          160         for i, x in enumerate( self.wallet.network.banner.split('\n') ):
          161             print( x )
          162 
          163     def print_list(self, lst, firstline):
          164         lst = list(lst)
          165         self.maxpos = len(lst)
          166         if not self.maxpos: return
          167         print(firstline)
          168         for i in range(self.maxpos):
          169             msg = lst[i] if i < len(lst) else ""
          170             print(msg)
          171 
          172 
          173     def main(self):
          174         while self.done == 0: self.main_command()
          175 
          176     def do_send(self):
          177         if not is_address(self.str_recipient):
          178             print(_('Invalid Bitcoin address'))
          179             return
          180         try:
          181             amount = int(Decimal(self.str_amount) * COIN)
          182         except Exception:
          183             print(_('Invalid Amount'))
          184             return
          185         try:
          186             fee = int(Decimal(self.str_fee) * COIN)
          187         except Exception:
          188             print(_('Invalid Fee'))
          189             return
          190 
          191         if self.wallet.has_password():
          192             password = self.password_dialog()
          193             if not password:
          194                 return
          195         else:
          196             password = None
          197 
          198         c = ""
          199         while c != "y":
          200             c = input("ok to send (y/n)?")
          201             if c == "n": return
          202 
          203         try:
          204             tx = self.wallet.mktx(outputs=[PartialTxOutput.from_address_and_value(self.str_recipient, amount)],
          205                                   password=password,
          206                                   fee=fee)
          207         except Exception as e:
          208             print(repr(e))
          209             return
          210 
          211         if self.str_description:
          212             self.wallet.set_label(tx.txid(), self.str_description)
          213 
          214         print(_("Please wait..."))
          215         try:
          216             self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
          217         except TxBroadcastError as e:
          218             msg = e.get_message_for_gui()
          219             print(msg)
          220         except BestEffortRequestFailed as e:
          221             msg = repr(e)
          222             print(msg)
          223         else:
          224             print(_('Payment sent.'))
          225             #self.do_clear()
          226             #self.update_contacts_tab()
          227 
          228     def network_dialog(self):
          229         print("use 'electrum setconfig server/proxy' to change your network settings")
          230         return True
          231 
          232 
          233     def settings_dialog(self):
          234         print("use 'electrum setconfig' to change your settings")
          235         return True
          236 
          237     def password_dialog(self):
          238         return getpass.getpass()
          239 
          240 
          241 #   XXX unused
          242 
          243     def run_receive_tab(self, c):
          244         #if c == 10:
          245         #    out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"])
          246         return
          247 
          248     def run_contacts_tab(self, c):
          249         pass