Files
purple-electrumwallet/electrum/gui/stdio.py
T

263 lines
8.6 KiB
Python
Raw Normal View History

2013-09-26 05:23:14 +02:00
from decimal import Decimal
2018-09-25 18:15:28 +02:00
import getpass
import datetime
import logging
from typing import Optional
2018-09-25 18:15:28 +02:00
from electrum.gui import BaseElectrumGui
2020-04-14 16:12:47 +02:00
from electrum import util
from electrum import constants
2017-03-06 08:33:35 +01:00
from electrum import WalletStorage, Wallet
from electrum.wallet import Abstract_Wallet
from electrum.wallet_db import WalletDB
from electrum.util import format_satoshis, EventListener, event_listener
2019-10-23 17:09:41 +02:00
from electrum.bitcoin import is_address, COIN
from electrum.transaction import PartialTxOutput
2019-01-18 19:59:12 +01:00
from electrum.network import TxBroadcastError, BestEffortRequestFailed
from electrum.fee_policy import FixedFeePolicy
2018-09-25 18:15:28 +02:00
_ = lambda x:x # i18n
2013-09-26 05:23:14 +02:00
# minimal fdisk like gui for console usage
# written by rofl0r, with some bits stolen from the text gui (ncurses)
2018-09-25 18:15:28 +02:00
class ElectrumGui(BaseElectrumGui, EventListener):
2013-09-26 05:23:14 +02:00
def __init__(self, *, config, daemon, plugins):
BaseElectrumGui.__init__(self, config=config, daemon=daemon, plugins=plugins)
self.network = daemon.network
storage = WalletStorage(config.get_wallet_path())
password = None
2022-06-22 00:38:41 +02:00
if not storage.file_exists():
2017-02-16 10:54:24 +01:00
print("Wallet not found. try 'electrum create'")
2013-09-26 05:23:14 +02:00
exit()
2017-03-06 08:33:35 +01:00
if storage.is_encrypted():
password = getpass.getpass('Password:', stream=None)
storage.decrypt(password)
del storage
self.wallet = self.daemon.load_wallet(config.get_wallet_path(), password)
self.contacts = self.wallet.contacts
2014-09-05 17:34:50 +02:00
self.done = 0
2013-09-26 05:23:14 +02:00
self.last_balance = ""
self.str_recipient = ""
self.str_description = ""
self.str_amount = ""
self.str_fee = ""
self.register_callbacks()
2013-09-26 05:23:14 +02:00
self.commands = [_("[h] - displays this help text"), \
_("[i] - display transaction history"), \
_("[o] - enter payment order"), \
_("[p] - print stored payment order"), \
_("[s] - send stored payment order"), \
_("[r] - show own receipt addresses"), \
_("[c] - display contacts"), \
_("[b] - print server banner"), \
2021-03-21 00:34:25 -04:00
_("[q] - quit")]
2013-09-26 05:23:14 +02:00
self.num_commands = len(self.commands)
@event_listener
def on_event_wallet_updated(self, wallet):
self.updated()
@event_listener
def on_event_network_updated(self):
self.updated()
@event_listener
2023-02-08 12:51:24 +01:00
def on_event_banner(self, *args):
self.print_banner()
2015-11-13 22:42:21 +09:00
2013-09-26 05:23:14 +02:00
def main_command(self):
self.print_balance()
2017-02-16 10:54:24 +01:00
c = input("enter command: ")
if c == "h" : self.print_commands()
2013-09-26 05:23:14 +02:00
elif c == "i" : self.print_history()
elif c == "o" : self.enter_order()
elif c == "p" : self.print_order()
elif c == "s" : self.send_order()
elif c == "r" : self.print_addresses()
elif c == "c" : self.print_contacts()
elif c == "b" : self.print_banner()
elif c == "n" : self.network_dialog()
elif c == "e" : self.settings_dialog()
elif c == "q" : self.done = 1
else: self.print_commands()
def updated(self):
s = self.get_balance()
if s != self.last_balance:
print(s)
self.last_balance = s
return True
def print_commands(self):
self.print_list(self.commands, "Available commands")
def print_history(self):
width = [20, 40, 14, 14]
delta = (80 - sum(width) - 4)/3
format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \
+ "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s"
messages = []
2022-06-17 10:04:28 +02:00
domain = self.wallet.get_addresses()
for hist_item in reversed(self.wallet.adb.get_history(domain)):
if hist_item.tx_mined_status.conf:
timestamp = hist_item.tx_mined_status.timestamp
2013-09-26 05:23:14 +02:00
try:
2015-04-02 15:19:00 +02:00
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
2013-11-10 12:30:57 -08:00
except Exception:
2013-09-26 05:23:14 +02:00
time_str = "unknown"
else:
2016-02-15 19:50:44 +01:00
time_str = 'unconfirmed'
2013-09-26 05:23:14 +02:00
label = self.wallet.get_label_for_txid(hist_item.txid)
messages.append(format_str % (
time_str, label,
format_satoshis(hist_item.delta, whitespaces=True),
format_satoshis(hist_item.balance, whitespaces=True)))
2013-09-26 05:23:14 +02:00
2021-03-21 00:34:25 -04:00
self.print_list(messages[::-1], format_str%(_("Date"), _("Description"), _("Amount"), _("Balance")))
2013-09-26 05:23:14 +02:00
def print_balance(self):
print(self.get_balance())
def get_balance(self):
network = self.wallet.network
if network and network.is_connected():
if not self.wallet.is_up_to_date():
2021-03-21 00:34:25 -04:00
msg = _("Synchronizing...")
2015-09-03 12:02:03 +09:00
else:
c, u, x = self.wallet.get_balance()
2025-06-29 22:02:09 +00:00
msg = _("Balance")+": {} ".format(Decimal(c) / COIN)
if u:
2025-06-29 22:02:09 +00:00
msg += " [{} unconfirmed]".format(Decimal(u) / COIN)
if x:
2025-06-29 22:02:09 +00:00
msg += " [{} unmatured]".format(Decimal(x) / COIN)
2013-09-26 05:23:14 +02:00
else:
2021-03-21 00:34:25 -04:00
msg = _("Not connected")
2015-09-03 12:02:03 +09:00
2022-10-31 16:13:22 +00:00
return msg
2013-09-26 05:23:14 +02:00
def print_contacts(self):
2015-04-23 12:46:52 +02:00
messages = map(lambda x: "%20s %45s "%(x[0], x[1][1]), self.contacts.items())
self.print_list(messages, "%19s %25s "%("Key", "Value"))
2013-09-26 05:23:14 +02:00
def print_addresses(self):
messages = map(lambda addr: "%30s %30s "%(addr, self.wallet.get_label_for_address(addr)), self.wallet.get_addresses())
2013-09-26 05:23:14 +02:00
self.print_list(messages, "%19s %25s "%("Address", "Label"))
def print_order(self):
print("send order to " + self.str_recipient + ", amount: " + self.str_amount \
+ "\nfee: " + self.str_fee + ", desc: " + self.str_description)
def enter_order(self):
2017-02-16 10:54:24 +01:00
self.str_recipient = input("Pay to: ")
self.str_description = input("Description : ")
self.str_amount = input("Amount: ")
self.str_fee = input("Fee: ")
2013-09-26 05:23:14 +02:00
def send_order(self):
self.do_send()
def print_banner(self):
2021-03-21 00:34:25 -04:00
for i, x in enumerate(self.wallet.network.banner.split('\n')):
print(x)
2013-09-26 05:23:14 +02:00
2018-01-12 15:05:27 +01:00
def print_list(self, lst, firstline):
lst = list(lst)
self.maxpos = len(lst)
2013-09-26 05:23:14 +02:00
if not self.maxpos: return
print(firstline)
for i in range(self.maxpos):
2018-01-12 15:05:27 +01:00
msg = lst[i] if i < len(lst) else ""
2013-09-26 05:23:14 +02:00
print(msg)
2015-09-03 12:02:03 +09:00
2015-08-26 17:44:19 +02:00
def main(self):
self.daemon.start_network()
while self.done == 0:
self.main_command()
2013-09-26 05:23:14 +02:00
def do_send(self):
2017-08-31 10:06:13 +02:00
if not is_address(self.str_recipient):
print(_(f'Invalid {constants.net.COIN_NAME} address'))
2013-09-26 05:23:14 +02:00
return
try:
2015-06-01 11:26:22 +09:00
amount = int(Decimal(self.str_amount) * COIN)
2013-11-10 12:30:57 -08:00
except Exception:
2013-09-26 05:23:14 +02:00
print(_('Invalid Amount'))
return
try:
2015-06-01 11:26:22 +09:00
fee = int(Decimal(self.str_fee) * COIN)
2013-11-10 12:30:57 -08:00
except Exception:
2013-09-26 05:23:14 +02:00
print(_('Invalid Fee'))
return
2018-01-12 15:05:27 +01:00
if self.wallet.has_password():
2013-09-26 05:23:14 +02:00
password = self.password_dialog()
if not password:
return
else:
password = None
c = ""
while c != "y":
2017-02-16 10:54:24 +01:00
c = input("ok to send (y/n)?")
2013-09-26 05:23:14 +02:00
if c == "n": return
try:
2025-03-14 17:19:41 +00:00
tx = self.wallet.make_unsigned_transaction(
2023-10-10 17:45:26 +00:00
outputs=[PartialTxOutput.from_address_and_value(self.str_recipient, amount)],
fee_policy=FixedFeePolicy(fee),
2023-10-10 17:45:26 +00:00
)
self.wallet.sign_transaction(tx, password)
2013-11-09 20:21:02 -08:00
except Exception as e:
print(repr(e))
2013-09-26 05:23:14 +02:00
return
2015-09-03 12:02:03 +09:00
if self.str_description:
self.wallet.set_label(tx.txid(), self.str_description)
2013-09-26 05:23:14 +02:00
print(_("Please wait..."))
2018-10-10 15:56:41 +02:00
try:
self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
2019-01-18 19:59:12 +01:00
except TxBroadcastError as e:
msg = e.get_message_for_gui()
print(msg)
except BestEffortRequestFailed as e:
msg = repr(e)
print(msg)
2018-10-10 15:56:41 +02:00
else:
2013-09-26 05:23:14 +02:00
print(_('Payment sent.'))
#self.do_clear()
#self.update_contacts_tab()
def network_dialog(self):
print("use 'electrum setconfig server/proxy' to change your network settings")
return True
def settings_dialog(self):
print("use 'electrum setconfig' to change your settings")
return True
def password_dialog(self):
return getpass.getpass()
2015-09-03 12:02:03 +09:00
2013-09-26 05:23:14 +02:00
# XXX unused
def run_receive_tab(self, c):
#if c == 10:
# out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"])
return
2015-09-03 12:02:03 +09:00
2013-09-26 05:23:14 +02:00
def run_contacts_tab(self, c):
pass