mirror of
https://github.com/jwinterm/lightWallet.git
synced 2026-10-17 05:11:25 +02:00
561 lines
24 KiB
Python
561 lines
24 KiB
Python
# !/usr/bin/python
|
|
from platform import system
|
|
from kivy.app import App
|
|
from kivy.config import Config
|
|
from kivy.uix.accordion import Accordion
|
|
from kivy.uix.button import Button
|
|
from kivy.uix.label import Label
|
|
from kivy.properties import ObjectProperty
|
|
from kivy.core.clipboard import Clipboard
|
|
from kivy.clock import Clock
|
|
from kivy.uix.popup import Popup
|
|
from kivy.storage.jsonstore import JsonStore
|
|
from kivy.uix.textinput import TextInput
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import time
|
|
from subprocess import PIPE, Popen, STDOUT
|
|
from threading import Thread
|
|
from Queue import Queue, Empty
|
|
import shutil
|
|
|
|
from lib.checklastblock import CheckLastBlock
|
|
from lib.savewallet import storeWallet
|
|
from lib.transferfunds import transferfundsrpccall
|
|
|
|
|
|
# Set POSIX argument for linux for something...
|
|
ON_POSIX = 'posix' in sys.builtin_module_names
|
|
|
|
|
|
# parser gets command line args
|
|
parser = argparse.ArgumentParser()
|
|
parser.parse_args()
|
|
|
|
|
|
# define functions to read output streams
|
|
def enqueue_output(out, queue):
|
|
for line in iter(out.readline, b''):
|
|
queue.put(line)
|
|
out.close()
|
|
|
|
|
|
def read_output(process, stdout, queue):
|
|
while True:
|
|
out = stdout.readline()
|
|
#print("Process is: "+process.poll())
|
|
if out == '' and process.poll() != None:
|
|
break
|
|
if out != '':
|
|
line = out.rstrip()
|
|
queue.put_nowait(line)
|
|
sys.stdout.flush()
|
|
|
|
|
|
# Function to split tx output lines
|
|
def txSplit(line):
|
|
split_line = line.split(': ')
|
|
try:
|
|
amount = float(split_line[1].split(',')[0])
|
|
tx = split_line[2].strip('<>')
|
|
date = split_line[0].split('.')[0]
|
|
return amount, tx, date
|
|
except ValueError:
|
|
return "Error", "Error", "Error"
|
|
except IndexError:
|
|
return "Error", "Error", "Error"
|
|
|
|
|
|
class MarkupLabel(Label):
|
|
""" Label class with markup on by default """
|
|
pass
|
|
|
|
|
|
class TabTextInput(TextInput):
|
|
""" Tab or enter to next TextInput class """
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.next = kwargs.pop('next', None)
|
|
super(TabTextInput, self).__init__(*args, **kwargs)
|
|
|
|
def set_next(self, next):
|
|
self.next = next
|
|
|
|
def _keyboard_on_key_down(self, window, keycode, text, modifiers):
|
|
key, key_str = keycode
|
|
if key in (9, 13) and self.next is not None:
|
|
self.next.focus = True
|
|
self.next.select_all()
|
|
else:
|
|
super(TabTextInput, self)._keyboard_on_key_down(window, keycode, text, modifiers)
|
|
|
|
|
|
class InitialPopup(Popup):
|
|
""" Initial popup widget """
|
|
|
|
def loadWalletPopup(self):
|
|
self.dismiss()
|
|
lwp = LoadWalletPopup()
|
|
lwp.open()
|
|
|
|
def createWalletPopup(self):
|
|
self.dismiss()
|
|
cwp = CreateWalletPopup()
|
|
cwp.open()
|
|
|
|
def quit(self):
|
|
sys.exit(0)
|
|
|
|
|
|
class CreateWalletPopup(Popup):
|
|
""" Wallet creation screen popup """
|
|
wallet_name = ObjectProperty()
|
|
wallet_pw = ObjectProperty()
|
|
repeat_wallet_pw = ObjectProperty()
|
|
|
|
def createWallet(self):
|
|
electrum_coming = False
|
|
wallet_name = self.wallet_name.text
|
|
wallet_pw = self.wallet_pw.text
|
|
if self.wallet_pw.text == self.repeat_wallet_pw.text:
|
|
p = Popen(["simplewallet", "--generate-new-wallet",
|
|
"./" + wallet_name.replace('.', '') + "_walletData/" + wallet_name,
|
|
"--password", wallet_pw],
|
|
stdout=PIPE,
|
|
stdin=PIPE,
|
|
bufsize=1,
|
|
close_fds=ON_POSIX)
|
|
if not os.path.exists('./{0}_walletData'.format(wallet_name.replace('.', ''))):
|
|
os.mkdir('./{0}_walletData'.format(wallet_name.replace('.', '')))
|
|
else:
|
|
sys.exit(7777)
|
|
q = Queue()
|
|
t = Thread(target=enqueue_output, args=(p.stdout, q))
|
|
t.daemon = True # thread dies with the program
|
|
t.start()
|
|
t_start = time.time()
|
|
while time.time() - t_start < 2:
|
|
try:
|
|
line = q.get_nowait() # or q.get(timeout=.1)
|
|
if "new wallet:" in line:
|
|
address = line.rstrip().split(': ')[1]
|
|
if "view key:" in line:
|
|
view_key = line.rstrip().split(': ')[1]
|
|
if 130 < len(line.rstrip()) < 350:
|
|
electrum = line.rstrip()
|
|
if "PLEASE NOTE:" in line:
|
|
electrum_coming = line.rstrip()
|
|
print("simplewallet output:", line.rstrip())
|
|
except Empty:
|
|
# print('no output yet')
|
|
pass
|
|
else: # got line
|
|
# print(line)
|
|
pass
|
|
# time.sleep(0.1)
|
|
p.kill()
|
|
# os.system("taskkill /im simplewallet.exe /f")
|
|
# print(p.pid)
|
|
with open('./{0}_walletData/info.txt'.format(wallet_name.replace('.', '')), 'w') as f:
|
|
f.write("Name:\n{0}\n\nAddress:\n{1}\n\nView key:\n{2}\n\nElectrum seed:\n{3}".format(
|
|
wallet_name, address, view_key, electrum))
|
|
with open("./CONFIG.file", 'w') as f:
|
|
f.write(wallet_name)
|
|
self.dismiss()
|
|
content = Button(
|
|
text="Your wallet has been created in the local directory {0}_walletData\nThe info.txt document in that folder contains your wallet recovery seed.\nPlease keep this seed safe, you can restore a corrupted/lost wallet with it.\nSomeone else can also bypass your password and steal your XMR with it.\nI suggest deleting or encrypting this file.".format(
|
|
wallet_name))
|
|
walletCreatedPopup = Popup(title="Wallet created window",
|
|
content=content)
|
|
content.bind(on_press=walletCreatedPopup.dismiss)
|
|
walletCreatedPopup.open()
|
|
App.get_running_app().root.launchWallet(wallet_name, wallet_pw)
|
|
else:
|
|
content = Button(text="Check passwords!!!\nClick to dismiss")
|
|
pwErrorPopup = Popup(title="Password match error window",
|
|
content=content)
|
|
content.bind(on_press=pwErrorPopup.dismiss)
|
|
pwErrorPopup.open()
|
|
|
|
|
|
class LoadWalletPopup(Popup):
|
|
""" Wallet loading screen popup """
|
|
wallet_path = ObjectProperty()
|
|
wallet_pw = ObjectProperty()
|
|
repeat_wallet_pw = ObjectProperty()
|
|
|
|
def loadWallet(self):
|
|
split_name = os.path.split(self.wallet_path.text)[1].split('.')
|
|
wallet_name = '.'.join(tuple(split_name[0:len(split_name) - 1]))
|
|
print(split_name, wallet_name)
|
|
wallet_pw = self.wallet_pw.text
|
|
wallet_error = False
|
|
if self.wallet_pw.text == self.repeat_wallet_pw.text:
|
|
p = Popen(["simplewallet", "--wallet-file",
|
|
self.wallet_path.text,
|
|
"--password", wallet_pw],
|
|
stdout=PIPE,
|
|
stdin=PIPE,
|
|
bufsize=1,
|
|
close_fds=ON_POSIX)
|
|
q = Queue()
|
|
t = Thread(target=enqueue_output, args=(p.stdout, q))
|
|
t.daemon = True # thread dies with the program
|
|
t.start()
|
|
t_start = time.time()
|
|
while time.time() - t_start < 2:
|
|
try:
|
|
line = q.get_nowait() # or q.get(timeout=.1)
|
|
print("simplewallet output:", line.rstrip())
|
|
if "Opened wallet: " in line.rstrip():
|
|
address = line.rstrip().split(": ")[1]
|
|
if "Error: failed" in line.rstrip():
|
|
wallet_error = True
|
|
except Empty:
|
|
# print('no output yet')
|
|
pass
|
|
else: # got line
|
|
pass
|
|
p.kill()
|
|
if not wallet_error:
|
|
if not os.path.exists("./{0}_walletData".format(wallet_name.replace('.', ''))):
|
|
os.mkdir("./{0}_walletData".format(wallet_name.replace('.', '')))
|
|
with open("./CONFIG.file", 'w') as f:
|
|
f.write(wallet_name)
|
|
with open("./{0}_walletData/{1}.address.txt".format(wallet_name.replace('.', ''), wallet_name), 'w') as f:
|
|
f.write(address)
|
|
shutil.copyfile(self.wallet_path.text,
|
|
"./{0}_walletData/{1}.keys".format(wallet_name.replace('.', ''), wallet_name))
|
|
self.dismiss()
|
|
content = Button(
|
|
text="Your wallet keys file has been copied to the local directory {0}_walletData\nThe original has not been disturbed.".format(
|
|
wallet_name))
|
|
walletCopiedPopup = Popup(title="Wallet keys copied window",
|
|
content=content)
|
|
content.bind(on_press=walletCopiedPopup.dismiss)
|
|
walletCopiedPopup.open()
|
|
App.get_running_app().root.launchWallet(wallet_name, wallet_pw)
|
|
else:
|
|
content = Button(text="Wallet import error!\nClick to start over")
|
|
pwErrorPopup = Popup(title="Wallet import error window",
|
|
content=content)
|
|
content.bind(on_press=pwErrorPopup.dismiss)
|
|
ip = InitialPopup()
|
|
content.bind(on_press=ip.open)
|
|
pwErrorPopup.open()
|
|
|
|
|
|
class PasswordPopup(Popup):
|
|
""" Popup class to get pw on launch with CONFIG.file """
|
|
wallet_pw = ObjectProperty()
|
|
walletname_label = ObjectProperty()
|
|
|
|
def __init__(self, wallet_name):
|
|
super(PasswordPopup, self).__init__()
|
|
self.wallet_name = wallet_name
|
|
if not App.get_running_app().root.wallet_error:
|
|
self.walletname_label.text = "Please enter your password for {0} account:".format(self.wallet_name)
|
|
if App.get_running_app().root.wallet_error:
|
|
self.walletname_label.text = "There seems to be a problem with binary file,\nPlease enter your password to attempt rebuild of {0} account:".format(
|
|
self.wallet_name)
|
|
|
|
def launchWallet(self):
|
|
wallet_pw = self.wallet_pw.text
|
|
App.get_running_app().root.launchWallet(self.wallet_name, wallet_pw)
|
|
self.dismiss()
|
|
|
|
|
|
class TransferPopup(Popup):
|
|
""" Popup class to initiate XMR transfer """
|
|
transfer_popup_label = ObjectProperty()
|
|
|
|
def __init__(self, amount, address, mixin, paymentid):
|
|
super(TransferPopup, self).__init__()
|
|
self.amount = amount
|
|
self.address = address
|
|
self.mixin = mixin
|
|
self.paymentid = paymentid
|
|
self.popuptext = "Are you sure you want to send {0:0.9f} XMR\n to [size=8]{1}[/size]\n with mixin count {2} and payment id [size=8]{3}[/size]".format(
|
|
float(amount), address, mixin, paymentid)
|
|
self.transfer_popup_label.text = self.popuptext
|
|
|
|
def transfer(self):
|
|
txid = transferfundsrpccall(self.amount, self.address, self.mixin, self.paymentid)
|
|
txid_popup = TxIDPopup(txid)
|
|
txid_popup.open()
|
|
|
|
|
|
class TxIDPopup(Popup):
|
|
txid_label = ObjectProperty()
|
|
def __init__(self, txid):
|
|
super(TxIDPopup, self).__init__()
|
|
self.txid = txid
|
|
self.txid_label.text = "TxID: [ref=txid]{0}[/ref]\n(Click TxID to copy to clipboard)".format(txid)
|
|
|
|
def selecttxid(self):
|
|
Clipboard.put(self.txid)
|
|
|
|
|
|
class RootWidget(Accordion):
|
|
"""Root Kivy accordion widget class"""
|
|
wallet_error = None
|
|
# Transfer XMR id items
|
|
address_input_textinput = ObjectProperty()
|
|
amount_input_textinput = ObjectProperty()
|
|
mixin_input_textinput = ObjectProperty()
|
|
paymentid_input_textinput = ObjectProperty()
|
|
# Wallet account id items
|
|
wallet_account_label = ObjectProperty()
|
|
wallet_address_label = ObjectProperty()
|
|
unlocked_balance_label = ObjectProperty()
|
|
total_balance_label = ObjectProperty()
|
|
calculated_balance_label = ObjectProperty()
|
|
# Daemon id items
|
|
daemon_server_textinput = ObjectProperty()
|
|
blockheight_label = ObjectProperty()
|
|
last_reward_label = ObjectProperty()
|
|
last_block_time_label = ObjectProperty()
|
|
time_since_last_label = ObjectProperty()
|
|
wallet_block_label = ObjectProperty()
|
|
blockheight = 0
|
|
# Process, queue, and thread variables
|
|
daemon_queue = Queue()
|
|
daemon_thread = None
|
|
wallet_process = None
|
|
wallet_queue = Queue()
|
|
wallet_thread = None
|
|
# Other variables
|
|
calculated_balance = 0.0
|
|
total_balance = 0.0
|
|
unlocked_balance = 0.0
|
|
temp_tx_amount = 0.0
|
|
temp_tx_hash = ""
|
|
temp_tx_paymentid = ""
|
|
wallet_save_time = None
|
|
|
|
def __init__(self, **kwargs):
|
|
super(RootWidget, self).__init__(**kwargs)
|
|
self.daemon_thread = Thread(target=self.checkDaemonStatus,
|
|
args=(self.daemon_queue, self.daemon_server_textinput.text))
|
|
self.daemon_thread.daemon = True
|
|
self.daemon_thread.start()
|
|
if os.path.isfile('./CONFIG.file'):
|
|
with open('./CONFIG.file', 'r') as f:
|
|
self.wallet_name = f.read().rstrip()
|
|
print(self.wallet_name)
|
|
Clock.schedule_once(self.initialPassword, 0.5)
|
|
else:
|
|
Clock.schedule_once(self.initialConfig, 0.5)
|
|
Clock.schedule_interval(self.checkDaemon, 5)
|
|
|
|
|
|
def initialConfig(self, dt):
|
|
ip = InitialPopup()
|
|
ip.open()
|
|
|
|
def initialPassword(self, dt):
|
|
gp = PasswordPopup(self.wallet_name)
|
|
gp.open()
|
|
|
|
def checkDaemonStatus(self, daemon_queue, server):
|
|
"""Class to be threaded for checking bitmonerod status"""
|
|
# print(server)
|
|
height, reward, timesince, localtime = CheckLastBlock(server + "/json_rpc")
|
|
daemon_queue.put((height, reward, timesince, localtime))
|
|
# print("sleeping")
|
|
time.sleep(1)
|
|
self.checkDaemonStatus(daemon_queue, self.daemon_server_textinput.text)
|
|
|
|
def checkDaemon(self, dt):
|
|
try:
|
|
height, reward, timesince, localtime = self.daemon_queue.get_nowait()
|
|
self.blockheight = int(height)
|
|
self.blockheight_label.text = "[b][color=00ffff]{0}[/b][/color]".format(height)
|
|
self.last_reward_label.text = "[b][color=00ffff]{0:.2f}[/b][/color] XMR".format(reward * 1e-12)
|
|
self.last_block_time_label.text = "[b][color=00ffff]{0}[/b][/color]".format(localtime)
|
|
self.time_since_last_label.text = "[b][color=00ffff]{0:.0f}[/b][/color] seconds".format(timesince)
|
|
except:
|
|
pass
|
|
|
|
def launchWallet(self, wallet_name, wallet_pw):
|
|
with open("./{0}_walletData/{1}.address.txt".format(wallet_name.replace('.', ''), wallet_name), 'r') as f:
|
|
self.address = f.read().rstrip()
|
|
self.wallet_account_label.text = "[b][color=00ffff]{0}[/b][/color]".format(wallet_name)
|
|
self.wallet_address_label.text = "[b][color=00ffff][ref=Address]{0}[/ref][/b][/color]".format(self.address)
|
|
if not os.path.isfile("./{0}_walletData/{1}".format(wallet_name.replace('.', ''), wallet_name)):
|
|
self.wallet_process = Popen(["simplewallet.exe", "--wallet-file", "./{0}_walletData/{1}".format(
|
|
wallet_name.replace('.', ''), wallet_name), "--password", wallet_pw],
|
|
stdin=PIPE,
|
|
stdout=PIPE,
|
|
stderr=STDOUT,
|
|
bufsize=1)
|
|
self.wallet_process.communicate(input="exit\r\n")
|
|
self.wallet_process.kill()
|
|
# try:
|
|
# system("taskkill /im simplewallet.exe /f")
|
|
# except:
|
|
# print("Simplewallet.exe not running")
|
|
if os.path.isfile("./{0}_walletData/tx.txt".format(wallet_name.replace('.', ''))):
|
|
with open("./{0}_walletData/tx.txt".format(wallet_name.replace('.', ''), 'r')) as previous_txs:
|
|
txs = previous_txs.read().split('\n')
|
|
for idx, line in enumerate(txs):
|
|
this_amount, this_tx, this_date = txSplit(line)
|
|
if idx < len(txs) - 1:
|
|
next_amount, next_tx, date = txSplit(txs[idx+1])
|
|
else:
|
|
next_amount, next_tx, date = "Done", "Done", "Done"
|
|
if this_tx != next_tx and self.temp_tx_amount == 0.0:
|
|
if "Received" in line:
|
|
l = Label(text="Received {0:0.3f} XMR on {1} in tx: {2}".format(this_amount, this_date, this_tx),
|
|
size_hint_y=None, height=15, font_size=9)
|
|
self.ids.tx_list.add_widget(l)
|
|
self.calculated_balance += this_amount
|
|
elif "Spent" in line:
|
|
l = Label(text="Spent {0:0.3f} XMR on {1} in tx: {2}".format(this_amount, this_date, this_tx),
|
|
size_hint_y=None, height=15, font_size=9)
|
|
self.ids.tx_list.add_widget(l)
|
|
self.calculated_balance -= this_amount
|
|
elif this_tx == next_tx and self.temp_tx_amount == 0.0:
|
|
self.temp_tx_amount += this_amount + next_amount
|
|
elif this_tx == next_tx and self.temp_tx_amount != 0.0:
|
|
self.temp_tx_amount += next_amount
|
|
elif this_tx != next_tx and self.temp_tx_amount != 0.0:
|
|
if "Received" in line:
|
|
l = Label(text="Received {0:0.3f} XMR on {1} in tx: {2}".format(this_amount, this_date, this_tx),
|
|
size_hint_y=None, height=15, font_size=9)
|
|
self.ids.tx_list.add_widget(l)
|
|
self.calculated_balance += self.temp_tx_amount
|
|
elif "Spent" in line:
|
|
l = Label(text="Spent {0:0.3f} XMR on {1} in tx: {2}".format(this_amount, this_date, this_tx),
|
|
size_hint_y=None, height=15, font_size=9)
|
|
self.ids.tx_list.add_widget(l)
|
|
self.calculated_balance -= self.temp_tx_amount
|
|
self.temp_tx_amount = 0.0
|
|
self.temp_tx_amount = 0.0
|
|
self.calculated_balance_label.text = "[b][color=00ffff]{0:.3f}[/b][/color]".format(self.calculated_balance)
|
|
self.wallet_process = Popen(["simplewallet", "--wallet-file", "./{0}_walletData/{1}.keys".format(
|
|
wallet_name.replace('.', ''), wallet_name), "--password", wallet_pw,
|
|
"--daemon-address", self.daemon_server_textinput.text, "--rpc-bind-port", "19091"],
|
|
stdin=PIPE,
|
|
stdout=PIPE,
|
|
stderr=STDOUT,
|
|
bufsize=1)
|
|
self.wallet_thread = Thread(target=read_output,
|
|
args=(self.wallet_process, self.wallet_process.stdout, self.wallet_queue))
|
|
# self.wallet_thread = Thread(target=enqueue_output,
|
|
# args=(self.wallet_process.stdout, self.wallet_queue))
|
|
self.wallet_thread.daemon = True # thread dies with the program
|
|
self.wallet_thread.start()
|
|
Clock.schedule_interval(self.readWalletQueue, .01)
|
|
# Clock.schedule_interval(self.saveWallet, 60)
|
|
|
|
def readWalletQueue(self, dt):
|
|
print(self.wallet_thread.is_alive)
|
|
try:
|
|
print("trying")
|
|
newLine = self.wallet_queue.get_nowait()
|
|
# with open("rpcwallet.log", 'a') as logfile:
|
|
# logfile.write(newLine+'\n')
|
|
print newLine
|
|
if "Wallet initialize failed: failed to read file" in newLine:
|
|
self.wallet_thread.join()
|
|
self.wallet_error = True
|
|
os.remove("./{0}_walletData/{1}".format(self.wallet_name.replace('.', ''), self.wallet_name))
|
|
Clock.schedule_once(self.initialPassword, 0.5)
|
|
if "height:" in newLine:
|
|
height = newLine.split(", ")[1].split(": ")[1]
|
|
self.wallet_block_label.text = "[b][color=00ffff]{0}[/b][/color] of [b][color=00ffff]{1}[/b][/color]".format(
|
|
height, self.blockheight)
|
|
elif "height " in newLine:
|
|
height = newLine.split(", ")[1].split(" ")[1]
|
|
self.wallet_block_label.text = "[b][color=00ffff]{0}[/b][/color] of [b][color=00ffff]{1}[/b][/color]".format(
|
|
height, self.blockheight)
|
|
elif "Refresh done," in newLine:
|
|
print("refresh done")
|
|
split_line = newLine.split(',')
|
|
self.total_balance = float(split_line[2].split(': ')[1])
|
|
self.unlocked_balance = float(split_line[3].split(': ')[1])
|
|
self.total_balance_label.text = "[b][color=00ffff]{0:.3f}[/b][/color]".format(self.total_balance)
|
|
self.unlocked_balance_label.text = "[b][color=00ffff]{0:.3f}[/b][/color]".format(self.unlocked_balance)
|
|
if not self.wallet_save_time:
|
|
print("First save launching!")
|
|
Clock.schedule_once(self.saveWallet, 0.1)
|
|
self.wallet_save_time = time.time()
|
|
print("Wallet saved at: {0}".format(self.wallet_save_time))
|
|
if self.wallet_save_time:
|
|
if time.time() - self.wallet_save_time > 1800:
|
|
Clock.schedule_once(self.saveWallet, 0.1)
|
|
print(time.time(), self.wallet_save_time, "saving")
|
|
self.wallet_save_time = time.time()
|
|
elif "Received money" in newLine and "with tx" in newLine:
|
|
with open("./{0}_walletData/tx.txt".format(self.wallet_name), 'a') as tx_file:
|
|
this_amount, this_tx, this_date = txSplit(newLine)
|
|
tx_file.write(newLine + '\n')
|
|
self.calculated_balance += this_amount
|
|
self.calculated_balance_label.text = "[b][color=00ffff]{0:.3f}[/b][/color]".format(
|
|
self.calculated_balance)
|
|
l = Label(text="Received {0:0.3f} XMR on {1} in tx: {2}".format(this_amount, this_date, this_tx),
|
|
size_hint_y=None, height=15, font_size=9)
|
|
self.ids.tx_list.add_widget(l)
|
|
elif "Spent money" in newLine and "with tx" in newLine:
|
|
with open("./{0}_walletData/tx.txt".format(self.wallet_name), 'a') as tx_file:
|
|
this_amount, this_tx, this_date = txSplit(newLine)
|
|
tx_file.write(newLine + '\n')
|
|
self.calculated_balance -= this_amount
|
|
l = Label(text="Spent {0:0.3f} XMR on {1} in tx: {2}".format(this_amount, this_date, this_tx),
|
|
size_hint_y=None, height=15, font_size=9)
|
|
self.ids.tx_list.add_widget(l)
|
|
# elif "Payment found" in newLine:
|
|
# with open("./{0}_walletData/tx.txt".format(self.wallet_name), 'a') as tx_file:
|
|
# tx_file.write(newLine + '\n')
|
|
except Empty:
|
|
pass
|
|
# if not self.wallet_thread.is_alive():
|
|
# print("dead")
|
|
# self.wallet_thread.start()
|
|
# Clock.schedule_interval(self.readWalletQueue, 0.01)
|
|
|
|
def saveWallet(self, dt):
|
|
print("Launching save thread")
|
|
save_thread = Thread(target=storeWallet)
|
|
save_thread.daemon = True
|
|
save_thread.start()
|
|
save_thread.join()
|
|
print("Finished save thread")
|
|
|
|
def selectAddress(self):
|
|
"""copy address to clipboard when user clicks"""
|
|
print('User clicked on ', self.address)
|
|
self.daemon_server_textinput.copy(self.address)
|
|
|
|
def transferfunds(self):
|
|
"""initiate transfer of funds to new address"""
|
|
try:
|
|
float(self.amount_input_textinput.text)
|
|
tp = TransferPopup(self.amount_input_textinput.text, self.address_input_textinput.text,
|
|
self.mixin_input_textinput.text, self.paymentid_input_textinput.text)
|
|
tp.open()
|
|
except ValueError:
|
|
print("no,no")
|
|
|
|
|
|
class KVNewApp(App):
|
|
def build(self):
|
|
return RootWidget()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
Config.set('kivy', 'exit_on_escape', 0)
|
|
Config.set('kivy', 'window_icon', "./lilicon.ico")
|
|
KVNewApp().run()
|
|
try:
|
|
App.get_running_app().root.wallet_process.kill()
|
|
except:
|
|
print("Wallet process not running")
|
|
# try:
|
|
# system("taskkill /im simplewallet.exe /f")
|
|
# except:
|
|
# print("Simplewallet.exe not running")
|