diff --git a/README.md b/README.md index 9d5f0d8..f0df150 100644 --- a/README.md +++ b/README.md @@ -235,8 +235,7 @@ The Local File device stores the wallet seed in a file on your disk, in your user data directory. The encryption is done with your password. LocalFile stores only the seed encrypted [with a random salt using libsodium XSalsa20/Poly1305](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox#algorithm-details), using an encryption key derived from the user chosen password using [Argon2id -(moderate -settings)](https://raw.githubusercontent.com/P-H-C/phc-winner-argon2/master/argon2-specs.pdf). +(moderate settings)](https://raw.githubusercontent.com/P-H-C/phc-winner-argon2/master/argon2-specs.pdf). One can choose to use a default password. To do so, just leave blank the password prompt input when asked the first time at device setting. Without a personalized password, the security of the key is what your hard-drive computer @@ -255,7 +254,7 @@ wallet. The folder where the HDseed file is stored, sits in the user data directory. - Windows : - C:\\Users\\\\AppData\\Local\\BitLogiK\\Uniblow\\keys\\ + C:\\Users\\\\\AppData\\Local\\BitLogiK\\Uniblow\\keys\\ - Linux : \~/.local/share/Uniblow/keys/ @@ -321,6 +320,8 @@ If the card is locked, only half initialized, or in a fancy state, you can use the [CryptnoxPro](https://github.com/Cryptnox-Software/cryptnoxpro) or the [Cryptnox iOS app](https://apps.apple.com/app/id1583011693). Because Uniblow cannot perform advanced operations such as PIN unlock, nor card reset. +For quick demo, the default PIN is setup to "1234". + ### OpenPGP device Works with an OpenPGP v2/v3 device that accepts User Interaction confirmation @@ -406,35 +407,16 @@ Development ### Run it from source -- For the GUI, [install wxPython 4](https://wxpython.org/pages/downloads/) - with your system binaries wheels. - - - **Windows** : Install - [Python3](https://www.python.org/ftp/python/3.9.9/python-3.9.9-amd64.exe), - then run `pip3 install wxPython==4.1.1` - - - **MacOS** : Read the [MacDev document](docs/MacDev.md) for more details. - - - **Linux** : Read the [LinuxDev document](docs/LinuxDev.md) for more - details - -- Install the uniblow package and its dependencies (or use venv) - - - `python3 setup.py install --user` - -- For ETH testnets, put your Infura key in ETHwallet. The binaries have an - Infura key embedded. +- **Windows** : Read the [WinDev document](docs/WinDev.md). -- Run with `python3 uniblow.py -v` +- **MacOS** : Read the [MacDev document](docs/MacDev.md). -The '-v' argument enables the debug logging output for more verbose terminal -output. +- **Linux** : Read the [LinuxDev document](docs/LinuxDev.md) ### Build binaries There are specific instructions and scripts to build uniblow binaries for the -Windows, Debian and MacOS platforms in a dedicated [build -document](docs/Build.md). +Windows, Debian and MacOS platforms in a dedicated [build document](docs/Build.md). License ------- diff --git a/cryptolib/HDwallet.py b/cryptolib/HDwallet.py index 5c5ecbb..d6e6147 100644 --- a/cryptolib/HDwallet.py +++ b/cryptolib/HDwallet.py @@ -116,7 +116,7 @@ def bip39_is_checksum_valid(mnemonic): if words_len not in [12, 15, 18, 21, 24]: return False, True entropy = i >> checksum_length - checksum = i % 2 ** checksum_length + checksum = i % 2**checksum_length entb = entropy.to_bytes(entropy_length >> 3, "big") hashed = int.from_bytes(sha2(entb), "big") computed_checksum = hashed >> (256 - checksum_length) @@ -177,7 +177,7 @@ def generate_mnemonic(nwords): class BIP32node: - HARDENED_LIMIT = 2 ** 31 + HARDENED_LIMIT = 2**31 def __init__(self, i, depth, pvkey, chaincode, curve, parent_fingerprint): # self.vpub_bytes = bytes.fromhex("0488B21E") # testnet 0x043587CF diff --git a/cryptolib/coins/transaction.py b/cryptolib/coins/transaction.py index 7a4355e..dba4554 100644 --- a/cryptolib/coins/transaction.py +++ b/cryptolib/coins/transaction.py @@ -392,7 +392,7 @@ def signature_form(tx, i, script, hashcode=SIGHASH_ALL): elif hashcode == SIGHASH_SINGLE: newtx["outs"] = newtx["outs"][: len(newtx["ins"])] for out in newtx["outs"][: len(newtx["ins"]) - 1]: - out["value"] = 2 ** 64 - 1 + out["value"] = 2**64 - 1 out["script"] = "" elif hashcode == SIGHASH_ANYONECANPAY: newtx["ins"] = [newtx["ins"][i]] diff --git a/devices/BaseDevice.py b/devices/BaseDevice.py index 3c5621e..d0bb7ed 100644 --- a/devices/BaseDevice.py +++ b/devices/BaseDevice.py @@ -77,7 +77,7 @@ def derive_key(self, path, key_type): @abstractmethod def get_public_key(self): - """Provide the publie key in hex X962. + """Provide the public key in hex X962. Compressed format, can be provided uncompressed for EVM wallets. For EdDSA provide the "raw" 32 bytes public key in hex. """ diff --git a/devices/Cryptnox.py b/devices/Cryptnox.py index c64f3a7..d0394a5 100644 --- a/devices/Cryptnox.py +++ b/devices/Cryptnox.py @@ -53,6 +53,10 @@ def __init__(self): self.account = None self.aindex = None + def disconnect(self): + if self.card is not None: + del self.card + def initialize_device(self, settings): self.account = settings["account"] self.aindex = settings["index"] diff --git a/devices/Ledger.py b/devices/Ledger.py index 481d954..fe8329b 100644 --- a/devices/Ledger.py +++ b/devices/Ledger.py @@ -83,6 +83,8 @@ def open_account(self): "Install and open the Ethereum app in the Ledger." ) raise Exception(f"Error {hex(exc.sw)} in Ledger.") + if len(eth_app_info) != 4: + raise Exception(f"Invalid response from the Ledger.") eth_version = f"{eth_app_info[1]}.{eth_app_info[2]}.{eth_app_info[3]}" logger.debug(f"Ledger ETH app version {eth_version}") if int.from_bytes(eth_app_info[1:4], "big") < MINIMUM_APP_VERSION: diff --git a/devices/SeedWatcher.py b/devices/SeedWatcher.py index 5c9057e..e96d9f8 100644 --- a/devices/SeedWatcher.py +++ b/devices/SeedWatcher.py @@ -38,9 +38,11 @@ CURSOR_HAND, BITMAP_TYPE_PNG, TextDataObject, + Font, + FontInfo, ) import gui.swgui -from gui.app import file_path +from gui.app import file_path, scaleSize from cryptolib.HDwallet import ( HD_Wallet, generate_mnemonic, @@ -127,7 +129,7 @@ def __init__(self, parent): Menu.__init__(self) self.parent = parent - men1 = MenuItem(self, 1, "Copy Address") + men1 = MenuItem(self, 1, "Copy address") self.Append(men1) self.Bind(EVT_MENU, self.parent.copy_account, men1) @@ -143,7 +145,9 @@ def __init__(self, parent): class SeedWatcherFrame(gui.swgui.MainFrame): def closesw(self, event): event.Skip() - self.GetParent().Show() + gui_frm = self.GetParent() + gui_frm.swrun = False + gui_frm.Show() class SeedWatcherPanel(gui.swgui.MainPanel): @@ -172,8 +176,8 @@ def gen_new_mnemonic(self, event): self.generate_mnemonic(selnw) def initialize(self, cb_wallet): - self.GOOD_BMP = Bitmap(file_path("gui/good.bmp")) - self.BAD_BMP = Bitmap(file_path("gui/bad.bmp")) + self.GOOD_BMP = Bitmap(file_path("gui/images/good.png")) + self.BAD_BMP = Bitmap(file_path("gui/images/bad.png")) self.m_choice_nwords.Set(WORDSLEN_LIST) self.m_choice_nwords.SetSelection(0) ctab = self.m_dataViewListCtrl1 @@ -348,7 +352,7 @@ def copy_account(self, event): copied_modal = MessageDialog( self, f"Account address {addr}\nwas copied in the clipboard", - "Copied", + "Address copied", STAY_ON_TOP | CENTER, DefaultPosition, ) @@ -392,9 +396,10 @@ def open_wallet(self, evt): def start_seedwatcher(app, cb_wallet): app.frame_sw = SeedWatcherFrame(app.gui_frame) + app.frame_sw.SetSize(scaleSize(app.frame_sw, (650, 700))) + app.gui_frame.swrun = True app.frame_sw.SetIcons(IconBundle(file_path("gui/uniblow.ico"))) HAND_CURSOR = Cursor(CURSOR_HAND) - app.gui_panel.devices_choice.SetSelection(0) app.gui_frame.Hide() app.panel_sw = SeedWatcherPanel(app.frame_sw) app.panel_sw.m_textCtrl_mnemo.SetFocus() @@ -403,18 +408,18 @@ def start_seedwatcher(app, cb_wallet): "Select asset line, then right click on it to open menu" ) - app.panel_sw.m_button_gen.SetBitmap(Bitmap(file_path("gui/GenSeed.png"), BITMAP_TYPE_PNG)) - app.panel_sw.m_button_gen.SetBitmapPressed( - Bitmap(file_path("gui/GenSeeddn.png"), BITMAP_TYPE_PNG) + app.panel_sw.m_button_gen.SetBitmap( + Bitmap(file_path("gui/images/btns/GenSeed.png"), BITMAP_TYPE_PNG) ) - app.panel_sw.m_btnseek.SetBitmap(Bitmap(file_path("gui/SeekAssets.png"), BITMAP_TYPE_PNG)) - app.panel_sw.m_btnseek.SetBitmapPressed( - Bitmap(file_path("gui/SeekAssetsdn.png"), BITMAP_TYPE_PNG) + app.panel_sw.m_btnseek.SetBitmap( + Bitmap(file_path("gui/images/btns/SeekAssets.png"), BITMAP_TYPE_PNG) ) app.panel_sw.m_button_gen.SetCursor(HAND_CURSOR) app.panel_sw.m_choice_nwords.SetCursor(HAND_CURSOR) app.panel_sw.m_typechoice.SetCursor(HAND_CURSOR) app.panel_sw.m_btnseek.SetCursor(HAND_CURSOR) + if sys.platform.startswith("darwin"): + app.panel_sw.m_textCtrl_mnemo.SetFont(Font(FontInfo(18))) app.panel_sw.initialize(cb_wallet) app.frame_sw.Show() diff --git a/devices/cryptnox/__init__.py b/devices/cryptnox/__init__.py index 6aaba36..b0534d7 100644 --- a/devices/cryptnox/__init__.py +++ b/devices/cryptnox/__init__.py @@ -143,7 +143,14 @@ def select(self): def send_apdu(self, APDU): """Send a full APDU command, APDU is a list of integers.""" - logger.debug("--> sending : %i bytes data ", (len(APDU) - 5)) + data_send = len(APDU) - 5 + command = "0x" + hex(APDU[1])[2:].upper() + if data_send > 0: + if data_send >= 2 and APDU[4] != data_send: + data_send -= 2 + logger.debug("--> sending %s with %i bytes data ", command, data_send) + else: + logger.debug("--> sending %s", command) logger.debug(bytes(APDU).hex()) try: data, sw1, sw2 = self.connection.transmit(APDU) @@ -569,7 +576,7 @@ def get_xpub(self): return xpubkey def get_path(self, curvetype="K1", path=b""): - """Read the cuuren tkey path.""" + """Read the current key path.""" curve_code = 0x00 if curvetype[-2:].upper() == "R1": curve_code = 0x10 diff --git a/devices/ledger/ledgerComm.py b/devices/ledger/ledgerComm.py index 63b49ac..61ae0de 100644 --- a/devices/ledger/ledgerComm.py +++ b/devices/ledger/ledgerComm.py @@ -174,11 +174,12 @@ def exchange(self, apdu, timeout=20000): raise LedgerException("Ledger was disconnected.") logger.debug(" Sending => %s", apdu.hex()) response, sw1, sw2 = self.device.transmit(toBytes(apdu.hex())) + resp = bytearray(response) sw = (sw1 << 8) | sw2 - logger.debug(" Receiving <= %s%.2x", response.hex(), sw) + logger.debug(" Receiving <= %s%.2x", resp.hex(), sw) if sw != 0x9000: raise LedgerException("Invalid status %04x" % sw, sw) - return bytearray(response) + return resp def close(self): if self.opened: diff --git a/docs/Build.md b/docs/Build.md index bf32c7a..93da1a4 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -5,7 +5,7 @@ This document provides specific instructions and scripts to build uniblow binari ## Windows 10 -* Install [Python 3.9](https://www.python.org/ftp/python/3.9.9/python-3.9.9-amd64.exe) +* Install [Python 3.9](https://www.python.org/ftp/python/3.9.13/python-3.9.13-amd64.exe) * Install Microsoft Visual C++ 14.x build tools. Required for bootloader installer and pysha3 library compilation. diff --git a/docs/HISTORY.md b/docs/HISTORY.md index 591b7a5..6780932 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -1,6 +1,14 @@ - Uniblow versions history +## 2.0.0 + +* Full redesign of the GUI +* Allow offline mode, display address +* Add fiat prices +* Improve Ledger +* Fix issue preventing start in some Windows +* Eth testnets add Sepolia, remove Rinkeby and Ropsten +* Tezos testnets add Jakarta remove Hangzhou ## 1.6.5 diff --git a/docs/MacDev.md b/docs/MacDev.md index 3d80889..e60df74 100644 --- a/docs/MacDev.md +++ b/docs/MacDev.md @@ -14,11 +14,9 @@ Windows, Debian and MacOS platforms in the [Build document](Build.md). You MacOS system needs : -- [Python 3.9 - pkg](https://www.python.org/ftp/python/3.9.9/python-3.9.9-macos11.pkg) - installed +- [Python 3.9 pkg](https://www.python.org/ftp/python/3.9.9/python-3.9.9-macos11.pkg) installed -- XCode and developer tools +- XCode and developer tools #### Prepare system @@ -30,30 +28,39 @@ cd /Applications/Python\ 3.9/ ``` #### Get the uniblow source + ``` git clone https://github.com/bitlogik/uniblow.git cd uniblow ``` #### Create venv for uniblow + ``` python3 -m venv unibenv source unibenv/bin/activate ``` #### Install uniblow dependencies + ``` python -m pip install pip==21.2.1 +python -m pip install swig python -m pip install wxPython==4.1.1 python -m pip install -e . ``` #### Run uniblow + ``` python uniblow.py ``` +The '-v' argument added enables the debug logging output for more verbose terminal +output. + #### Quit the venv + ``` deactivate ``` @@ -61,6 +68,7 @@ deactivate #### Run uniblow next time Within a terminal, in the uniblow directory + ``` source unibenv/bin/activate python uniblow.py diff --git a/docs/WinDev.md b/docs/WinDev.md new file mode 100644 index 0000000..cabbcbf --- /dev/null +++ b/docs/WinDev.md @@ -0,0 +1,36 @@ +# Uniblow development on Windows + +The following instructions commands are given to run uniblow **from the source** on the Windows system. This can also be used for development purpose. + +When running from the source files, for ETH testnets, you can put your Infura key in +ETHwallet. + +There are specific instructions and scripts to build uniblow binaries for the +Windows, Debian and MacOS platforms in the [Build document](Build.md). + +In Windows, you can easily [run the binaries provided](https://uniblow.org/get). The following instructions here are only to run Uniblow from the Python source code, for development purpose. + +### Install dependencies + +- For the GUI, Install WxPython. + + - Install [Python3.9](https://www.python.org/ftp/python/3.9.13/python-3.9.13-amd64.exe), + + - Then run `python -m pip install wxPython==4.1.1` + +- Download the Uniblow source code + + with git : `git clone https://github.com/bitlogik/uniblow.git` + + Zip without git : [Download here](https://github.com/bitlogik/uniblow/archive/refs/heads/master.zip) + +### Install and run uniblow + +- In the uniblow directory, install the uniblow package and its dependencies (or use venv) + + - `python setup.py install --user` + +- Run with `python uniblow.py -v` + +The '-v' argument enables the debug logging output for more verbose terminal +output. diff --git a/gui/GenSeed.png b/gui/GenSeed.png deleted file mode 100644 index 260574b..0000000 Binary files a/gui/GenSeed.png and /dev/null differ diff --git a/gui/GenSeeddn.png b/gui/GenSeeddn.png deleted file mode 100644 index b4802b1..0000000 Binary files a/gui/GenSeeddn.png and /dev/null differ diff --git a/gui/SeekAssets.png b/gui/SeekAssets.png deleted file mode 100644 index a2db3c8..0000000 Binary files a/gui/SeekAssets.png and /dev/null differ diff --git a/gui/SeekAssetsdn.png b/gui/SeekAssetsdn.png deleted file mode 100644 index d1bec83..0000000 Binary files a/gui/SeekAssetsdn.png and /dev/null differ diff --git a/gui/app.py b/gui/app.py index c3ef7fd..f62261b 100644 --- a/gui/app.py +++ b/gui/app.py @@ -14,32 +14,51 @@ # along with this program. If not, see +from functools import partial +from locale import setlocale, LC_ALL +from logging import getLogger import sys import os.path from os import environ -from webbrowser import open as wopen - -from wx import ( - App, - IconBundle, - TextDataObject, - TheClipboard, - Bitmap, - ID_OK, - ID_CANCEL, - Cursor, - CURSOR_HAND, - BITMAP_TYPE_PNG, - EVT_ACTIVATE_APP, - EVT_CLOSE, -) - -import gui.window + +import wx + +import gui.maingui import gui.infodialog +from gui.utils import file_path, show_history, icon_file +from gui.send_frame import SendModal +from gui.qrframe import QRFrame +from gui.fiat_price import PriceAPI from cryptolib.HDwallet import bip39_is_checksum_valid -ICON_FILE = "gui/uniblow.ico" + +logger = getLogger(__name__) + + +BAD_ADDRESS = "Wrong destination account address checksum or wrong format." +BLANK_ADDR = " " * 65 + + +def attach_tt(elt, txt): + ttc = wx.ToolTip(txt) + ttc.SetDelay(0) + elt.SetToolTip(ttc) + wx.CallLater(1200, lambda: ttc.SetTip("")) + + +def isBitmapButton(elt): + return isinstance(elt, wx.BitmapButton) + + +def scaleSize(frame, sz): + """Scale frame size demending of scaling factor.""" + scal_fact = 1 + if frame.GetDPIScaleFactor() > 1.25: + scal_fact = 1.1 + if frame.GetDPIScaleFactor() > 1.5: + scal_fact = 1.25 + return (int(sz[0] * scal_fact), int(sz[1] * scal_fact)) class InfoBox(gui.infodialog.InfoDialog): @@ -48,21 +67,29 @@ def __init__(self, message, title, style, parent, block_modal=False): self.is_modal = block_modal self.message = message self.SetTitle(title) - self.m_textCtrl.SetBackgroundColour(self.GetBackgroundColour()) - self.m_textCtrl.SetValue(self.message) - self.m_textCtrl.SelectNone() + self.panel = gui.infodialog.InfoPanel(self) + HAND_CURSOR = wx.Cursor(wx.CURSOR_HAND) + self.panel.m_button_cpy.SetCursor(HAND_CURSOR) + self.panel.m_button_ok.SetCursor(HAND_CURSOR) + self.panel.m_button_ok.Bind(wx.EVT_BUTTON, self.close_info) + self.panel.m_button_cpy.Bind(wx.EVT_BUTTON, self.copy_text_dialog) + self.panel.m_textCtrl.SetBackgroundColour(self.GetBackgroundColour()) + self.panel.m_textCtrl.SetValue(self.message) + self.panel.m_textCtrl.SelectNone() if self.is_modal: + self.Layout() self.ShowModal() else: self.Show() + self.Layout() def copy_text_dialog(self, event): event.Skip() - if TheClipboard.Open(): - TheClipboard.Clear() - TheClipboard.SetData(TextDataObject(self.message)) - TheClipboard.Flush() - TheClipboard.Close() + if wx.TheClipboard.Open(): + wx.TheClipboard.Clear() + wx.TheClipboard.SetData(wx.TextDataObject(self.message)) + wx.TheClipboard.Flush() + wx.TheClipboard.Close() # else silent : no Access def close_info(self, event): @@ -71,16 +98,6 @@ def close_info(self, event): self.Destroy() -def file_path(fpath): - if hasattr(sys, "_MEIPASS"): - return os.path.join(sys._MEIPASS, fpath) - return fpath - - -def show_history(history_url): - wopen(history_url, new=1, autoraise=True) - - if sys.platform.startswith("darwin"): # On MacOS, the set_default_verify_paths method of the Python OpenSSL lib, # used in the context method load_default_certs, mostly fails to find any @@ -97,7 +114,17 @@ def show_history(history_url): environ["SSL_CERT_FILE"] = cert_file_path -class HDsetting_panel(gui.window.HDPanel): +class HDsetting_panel(gui.maingui.HDPanel): + def __init__(self, arg): + super().__init__(arg) + HAND_CURSOR = wx.Cursor(wx.CURSOR_HAND) + self.m_butOK.SetCursor(HAND_CURSOR) + self.m_butCancel.SetCursor(HAND_CURSOR) + self.m_butOK.SetBitmap(wx.Bitmap(file_path("gui/images/btns/ok.png"), wx.BITMAP_TYPE_PNG)) + self.m_butCancel.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/cancel.png"), wx.BITMAP_TYPE_PNG) + ) + def hdmnemo_changed(self, evt): evt.Skip() self.m_bitmapHDwl.SetBitmap(self.BAD_BMP) @@ -135,14 +162,29 @@ def hd_ok(self, event): "seed_gen": derivation, } ) - self.GetParent().EndModal(ID_OK) + self.GetParent().EndModal(wx.ID_OK) def hd_cancel(self, event): event.Skip() - self.GetParent().EndModal(ID_CANCEL) + self.GetParent().EndModal(wx.ID_CANCEL) + +class app_option_panel(gui.maingui.OptionPanel): + def __init__(self, arg): + super().__init__(arg) + HAND_CURSOR = wx.Cursor(wx.CURSOR_HAND) + self.known_choice.SetCursor(HAND_CURSOR) + self.m_but_paste.SetCursor(HAND_CURSOR) + self.m_but_paste.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/paste.png"), wx.BITMAP_TYPE_PNG) + ) + self.m_but_ok.SetBitmap(wx.Bitmap(file_path("gui/images/btns/ok.png"), wx.BITMAP_TYPE_PNG)) + self.m_but_cancel.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/cancel.png"), wx.BITMAP_TYPE_PNG) + ) + self.m_but_ok.SetCursor(HAND_CURSOR) + self.m_but_cancel.SetCursor(HAND_CURSOR) -class app_option_panel(gui.window.OptionPanel): def valid_custom(self, event): self.okOption(event) @@ -155,26 +197,53 @@ def okOption(self, event): else: preset_choice = self.known_choice.GetStringSelection() self.option_value = self.preset_values.get(preset_choice, "NotSelected") - self.GetParent().EndModal(ID_OK) + self.GetParent().EndModal(wx.ID_OK) + + def onSearch(self, event): + event.Skip() + search = str(self.search_preset.GetValue()) + if search: + self.search_preset.ShowCancelButton(True) + filt_values = dict( + filter(lambda val: search.lower() in val[0].lower(), self.full_options.items()) + ) + self.known_choice.Clear() + self.known_choice.Append(f"> Select preset filtered with {search}") + self.preset_values = filt_values + for preset_txt in filt_values.keys(): + self.known_choice.Append(preset_txt) + if len(filt_values) == 1: + self.known_choice.SetSelection(1) + elif len(filt_values) == 0: + self.known_choice.Clear() + self.known_choice.Append(f"No preset found for {search}") + self.known_choice.SetSelection(0) + else: + self.known_choice.SetSelection(0) + else: + self.search_preset.ShowCancelButton(False) + self.SetPresetValues(self.full_options) def pasteValue(self, event): """Paste the clipboard value in new_choice input field.""" event.Skip() - text_data = TextDataObject() - if TheClipboard.Open(): - success = TheClipboard.GetData(text_data) - TheClipboard.Close() + text_data = wx.TextDataObject() + if wx.TheClipboard.Open(): + success = wx.TheClipboard.GetData(text_data) + wx.TheClipboard.Close() if success: self.new_choice.SetValue(text_data.GetText()) def cancelOption(self, event): event.Skip() - self.GetParent().EndModal(ID_CANCEL) + self.GetParent().EndModal(wx.ID_CANCEL) def GetValue(self): return self.option_value def HidePreset(self): + self.search_preset.Hide() + self.search_preset.ShowCancelButton(False) self.preset_text.Hide() self.known_choice.Hide() self.m_staticTextor.Hide() @@ -184,6 +253,7 @@ def SetPresetLabel(self, text): self.preset_text.SetLabelText(self.preset_label) def SetPresetValues(self, values): + self.full_options = values self.known_choice.Clear() self.known_choice.Append(f"Select a {self.preset_label}") self.preset_values = values @@ -198,53 +268,206 @@ def SetTitle(self, title): self.GetParent().SetTitle(title) -class UniblowApp(App): - def __init__(self, version): - self.version = version +class UniblowApp(wx.App): + def __init__(self, devices, coinclasses): + self.devices = devices + self.open_devices_sz = None super().__init__(redirect=False) - self.Bind(EVT_ACTIVATE_APP, self.OnActivate) + self.Bind(wx.EVT_ACTIVATE_APP, self.OnActivate) + self.coin_classes = coinclasses + self.dev_selected = None + self.coin_selected = None + self.current_chain = None def OnInit(self): - icon_path = file_path(ICON_FILE) - wicon = IconBundle(icon_path) - HAND_CURSOR = Cursor(CURSOR_HAND) - self.gui_frame = gui.window.TopFrame(None) - self.gui_frame.Bind(EVT_CLOSE, self.OnClose) - if sys.platform.startswith("darwin"): - self.gui_frame.SetSize((996, 418)) - self.gui_panel = gui.window.TopPanel(self.gui_frame) + self.HAND_CURSOR = wx.Cursor(wx.CURSOR_HAND) + wicon = wx.IconBundle(icon_file) + self.gui_frame = gui.maingui.UniblowFrame(None) + self.gui_frame.swrun = False + self.gui_frame.Bind(wx.EVT_CLOSE, self.OnClose) self.gui_frame.SetIcons(wicon) - self.gui_panel.hist_button.SetBitmap(Bitmap(file_path("gui/histo.png"), BITMAP_TYPE_PNG)) - self.gui_panel.hist_button.SetBitmapPressed( - Bitmap(file_path("gui/histodn.png"), BITMAP_TYPE_PNG) + self.open_devices_panel() + self.SetTopWindow(self.gui_frame) + return True + + def InitLocale(self): + if sys.platform.startswith("win") and sys.version_info > (3, 8): + setlocale(LC_ALL, "C") + + def open_devices_panel(self): + self.gui_frame.swrun = False + self.dev_panel = gui.maingui.DevicesPanel(self.gui_frame) + logo = wx.Image(file_path(f"gui/images/logo.png"), wx.BITMAP_TYPE_PNG) + logo.Rescale(64, 64) + self.dev_panel.Layout() + self.dev_panel.bmp_logo.SetBitmap(logo.ConvertToBitmap()) + for dev_idx, device in enumerate(self.devices, start=1): + dbtn = getattr(self.dev_panel, f"d_btn{dev_idx:02d}") + dbtn.SetBitmap( + wx.Bitmap( + file_path(f"gui/images/btns/dev_{device.lower()}.png"), wx.BITMAP_TYPE_PNG + ) + ) + dbtn.Bind(wx.EVT_BUTTON, self.load_device) + dbtn.SetCursor(self.HAND_CURSOR) + if sys.platform.startswith("darwin"): + self.dev_panel.m_staticText1.SetFont(wx.Font(wx.FontInfo(26))) + self.dev_panel.Layout() + self.gui_frame.SetSize(scaleSize(self.gui_frame, (500, 450))) + self.gui_frame.Layout() + + def start_wallet_panel(self): + """Kill devices choice panel and start the wallet panel.""" + self.dev_panel.Destroy() + self.gui_frame.SetSize(scaleSize(self.gui_frame, (820, 460))) + self.gui_frame.Layout() + self.gui_panel = gui.maingui.WalletPanel(self.gui_frame) + self.gui_panel.copy_button.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/copy.png"), wx.BITMAP_TYPE_PNG) ) - self.gui_panel.copy_button.SetBitmap(Bitmap(file_path("gui/copy.png"), BITMAP_TYPE_PNG)) - self.gui_panel.copy_button.SetBitmapPressed( - Bitmap(file_path("gui/copydn.png"), BITMAP_TYPE_PNG) + self.gui_panel.qr_button.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/qr.png"), wx.BITMAP_TYPE_PNG) ) - self.gui_panel.send_button.SetBitmap(Bitmap(file_path("gui/send.png"), BITMAP_TYPE_PNG)) - self.gui_panel.send_button.SetBitmapPressed( - Bitmap(file_path("gui/senddn.png"), BITMAP_TYPE_PNG) + self.gui_panel.hist_button.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/history.png"), wx.BITMAP_TYPE_PNG) ) - self.gui_panel.send_all.SetBitmap(Bitmap(file_path("gui/swipe.png"), BITMAP_TYPE_PNG)) - self.gui_panel.send_all.SetBitmapPressed( - Bitmap(file_path("gui/swipedn.png"), BITMAP_TYPE_PNG) + tt_hist = wx.ToolTip("Open in a block explorer") + tt_hist.SetDelay(400) + self.gui_panel.hist_button.SetToolTip(tt_hist) + self.gui_panel.m_but_changedevice.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/chdev.png"), wx.BITMAP_TYPE_PNG) ) - self.gui_panel.devices_choice.SetCursor(HAND_CURSOR) - self.gui_panel.coins_choice.SetCursor(HAND_CURSOR) - self.gui_panel.network_choice.SetCursor(HAND_CURSOR) - self.gui_panel.wallopt_choice.SetCursor(HAND_CURSOR) - self.gui_panel.hist_button.SetCursor(HAND_CURSOR) - self.gui_panel.copy_button.SetCursor(HAND_CURSOR) - self.gui_panel.send_button.SetCursor(HAND_CURSOR) - self.gui_panel.send_all.SetCursor(HAND_CURSOR) - self.gui_panel.btn_chkaddr.SetCursor(HAND_CURSOR) - self.SetTopWindow(self.gui_frame) - return True + self.gui_panel.hist_button.SetCursor(self.HAND_CURSOR) + self.gui_panel.copy_button.SetCursor(self.HAND_CURSOR) + self.gui_panel.qr_button.SetCursor(self.HAND_CURSOR) + self.gui_panel.m_but_changedevice.SetCursor(self.HAND_CURSOR) + self.gui_panel.hist_button.Bind(wx.EVT_BUTTON, self.disp_history) + self.gui_panel.qr_button.Bind(wx.EVT_BUTTON, self.qr_open) + self.gui_panel.copy_button.Bind(wx.EVT_BUTTON, self.copy_account) + self.gui_panel.m_but_changedevice.Bind(wx.EVT_BUTTON, self.change_device) + self.gui_panel.btn_send.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/send.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.network_choice.SetCursor(self.HAND_CURSOR) + self.gui_panel.wallopt_choice.SetCursor(self.HAND_CURSOR) + self.gui_panel.btn_send.SetCursor(self.HAND_CURSOR) + self.gui_panel.btn_send.Bind(wx.EVT_BUTTON, self.open_send) + self.gui_panel.btn_send.Hide() + self.gui_panel.btn_chkaddr.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/addrchk.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.btn_chkaddr.SetCursor(self.HAND_CURSOR) + self.gui_panel.btn_chkaddr.Bind(wx.EVT_BUTTON, self.check_wallet) + self.gui_panel.wallopt_label.Disable() + self.gui_panel.wallopt_choice.Disable() + self.gui_panel.network_choice.Disable() + if sys.platform.startswith("darwin"): + self.gui_panel.balance_info.SetFont(wx.Font(wx.FontInfo(24))) + self.gui_panel.balance_small.SetFont(wx.Font(wx.FontInfo(15))) + self.gui_panel.balance_unit.SetFont(wx.Font(wx.FontInfo(24))) + self.gui_panel.txt_fiat.SetFont(wx.Font(wx.FontInfo(15))) + self.gui_panel.account_addr.SetFont(wx.Font(wx.FontInfo(18))) + self.gui_panel.account_addr.SetLabel(BLANK_ADDR) + self.gui_frame.Layout() + + def gowallet(self, sdevice): + dev_info = self.dev_selected(sdevice) + if isinstance(dev_info, list): + self.start_wallet_panel() + self.load_coins_list(dev_info) + self.erase_info(True, True) + if sdevice == 2: # Ledger + self.gui_panel.btn_chkaddr.Show() + + def load_device(self, evt): + """Called from the device panel choice click.""" + if evt.GetEventObject() is self.dev_panel.d_btn01: + # SeedWatcher + sel_dev = 0 + elif evt.GetEventObject() is self.dev_panel.d_btn02: + # LocalFiles + sel_dev = 1 + elif evt.GetEventObject() is self.dev_panel.d_btn03: + # Ledger + sel_dev = 2 + elif evt.GetEventObject() is self.dev_panel.d_btn04: + # Cryptnox + sel_dev = 3 + elif evt.GetEventObject() is self.dev_panel.d_btn05: + # OpenPGP + sel_dev = 4 + else: + raise Exception("Bad device button object") + wx.CallAfter(self.gowallet, sel_dev) + + def change_device(self, evt): + if hasattr(self, "balance_timer"): + self.balance_timer.Stop() + if hasattr(self, "device"): + if hasattr(self.device, "disconnect"): + self.device.disconnect() + del self.device + self.gui_panel.Destroy() + self.current_chain = "" + del self.gui_panel + self.open_devices_panel() + + def load_coin(self, evt): + """Called from the chain panel choice click.""" + sel_coinbtn = evt.GetEventObject() + siblings = sel_coinbtn.GetParent().GetChildren() + coinsbtn = list(filter(isBitmapButton, siblings)) + for pos in range(len(coinsbtn)): + if coinsbtn[pos] is sel_coinbtn: + coin_name = self.coins_list[pos] + if coin_name != self.current_chain: + sel_coinbtn.SetBackgroundColour(wx.Colour(113, 110, 234)) + self.gui_panel.scrolled_coins.Disable() + self.current_chain = coin_name + wx.CallAfter(self.coin_selected, coin_name) + else: + coinsbtn[pos].SetBackgroundColour(wx.Colour(248, 250, 252)) + + def deactivate_option_buttons(self): + self.gui_panel.but_evt1.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/blankopt.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.but_evt1.SetCursor(wx.NullCursor) + self.gui_panel.but_evt2.Hide() + self.gui_panel.but_evt1.Unbind(wx.EVT_BUTTON) + self.gui_panel.but_evt2.Unbind(wx.EVT_BUTTON) + self.gui_panel.Layout() + + def activate_option_buttons(self): + self.gui_panel.but_evt1.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/tokens.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.but_evt2.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/wc.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.but_evt2.Show() + self.gui_panel.but_evt1.SetCursor(self.HAND_CURSOR) + self.gui_panel.but_evt2.SetCursor(self.HAND_CURSOR) + self.gui_panel.Layout() + + def disable_send(self, msg=""): + self.gui_panel.btn_send.Hide() + self.gui_panel.alt_text.SetLabel(msg) + self.gui_panel.alt_text.Show() + self.gui_panel.Layout() + + def enable_send(self): + self.gui_panel.alt_text.Hide() + self.gui_panel.alt_text.SetLabel("") + self.gui_panel.btn_send.Show() + self.gui_panel.Layout() def BringWindowToFront(self): try: - self.GetTopWindow().Raise() + if self.gui_frame.swrun: + self.sw_frame.Raise() + else: + self.GetTopWindow().Raise() except Exception: pass @@ -254,6 +477,8 @@ def OnActivate(self, event): event.Skip() def OnClose(self, event): + if hasattr(self, "balance_timer"): + self.balance_timer.Stop() if hasattr(self, "device"): del self.device if hasattr(self, "wallet"): @@ -263,33 +488,208 @@ def OnClose(self, event): def MacReopenApp(self): self.BringWindowToFront() - def load_devices(self, devices_list): - self.gui_panel.devices_choice.Append("Choose your device") - for device in devices_list: - if device == "LocalFile": - device = "Local file wallet" - self.gui_panel.devices_choice.Append(device) - self.gui_panel.devices_choice.SetSelection(0) + def erase_info(self, reset=False, first_time=False): + if hasattr(self, "balance_timer"): + self.balance_timer.Stop() + if hasattr(self, "wallet") and hasattr(self.wallet, "wc_timer"): + self.wallet.wc_client.close() + self.wallet.wc_timer.Stop() + delattr(self.wallet, "wc_timer") + self.gui_panel.hist_button.Disable() + self.gui_panel.copy_button.Disable() + self.disable_send() + self.gui_panel.wallopt_label.Disable() + self.gui_panel.wallopt_choice.Disable() + self.gui_panel.balance_info.SetLabel("") + self.gui_panel.balance_small.SetLabel("") + self.gui_panel.balance_unit.SetLabel("") + self.gui_panel.txt_fiat.SetLabel("$ 0") + self.gui_panel.fiat_panel.Hide() + if hasattr(self.gui_panel, "fiat_price"): + del self.gui_panel.fiat_price + if first_time: + self.gui_panel.img_arrsel.Show() + self.gui_panel.img_arrsel.SetBitmap( + wx.Bitmap(file_path("gui/images/arrsel.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.balance_info.SetLabel("Select a chain") + else: + self.gui_panel.img_arrsel.Hide() + if reset: + self.gui_panel.wallopt_choice.SetSelection(0) + self.gui_panel.qr_button.Disable() + if hasattr(self, "wallet"): + del self.wallet + self.gui_panel.account_addr.SetLabel(BLANK_ADDR) + self.gui_frame.Refresh() + self.gui_frame.Layout() + + def clear_coin_selected(self): + coin_btns = self.gui_panel.scrolled_coins.GetChildren() + for btn in coin_btns: + btn.SetBackgroundColour(wx.Colour(255, 255, 255, 0)) def load_coins_list(self, coins_list): - self.gui_panel.coins_choice.Clear() - self.gui_panel.coins_choice.Append("Select blockchain") + sizer = wx.BoxSizer(wx.VERTICAL) for coin in coins_list: - self.gui_panel.coins_choice.Append(coin) - self.gui_panel.coins_choice.SetSelection(0) + coin_button = wx.BitmapButton( + self.gui_panel.scrolled_coins, + wx.ID_ANY, + wx.NullBitmap, + wx.DefaultPosition, + wx.DefaultSize, + wx.BU_AUTODRAW | wx.BORDER_NONE, + ) + img = wx.Image(file_path(f"gui/images/icons/{coin.lower()}.png"), wx.BITMAP_TYPE_PNG) + img.Rescale(48, 48, wx.IMAGE_QUALITY_BILINEAR) + img.Resize(wx.Size(58, 56), wx.Point(5, 4), red=-1, green=-1, blue=-1) + coin_button.SetBackgroundColour(wx.Colour(248, 250, 252)) + coin_button.SetBitmap(wx.Bitmap(img)) + coin_button.SetCursor(self.HAND_CURSOR) + coin_button.Bind(wx.EVT_BUTTON, self.load_coin) + sizer.Add(coin_button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 3) + self.coins_list = coins_list + self.gui_panel.scrolled_coins.SetSizer(sizer) + self.gui_panel.scrolled_coins.Layout() + self.gui_panel.Layout() + self.gui_frame.Layout() + + def confirm_tx(self, to_addr, amount): + conf_txt = f"Confirm this transaction ?\n{amount} {self.wallet.coin} to {to_addr}" + confirm_tx_modal = wx.MessageDialog( + self.gui_frame, + conf_txt, + "Confirmation", + wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.STAY_ON_TOP | wx.CENTER, + wx.DefaultPosition, + ) + return confirm_tx_modal.ShowModal() + + def callback_send(self, status, address, amount_str, sel_fee=1): + self.gui_panel.Enable() + if status != "OK": + self.send_dialog.Destroy() + return + if not self.gui_panel.btn_send.IsShown(): + self.send_dialog.Destroy() + return + if not hasattr(self, "wallet"): + self.send_dialog.Destroy() + return + self.gui_panel.Disable() + if not self.wallet.check_address(address): + self.warn_modal(BAD_ADDRESS, parent=self.send_dialog) + return + if len(amount_str) <= 0: + self.warn_modal("Input an amount value to transfer.", parent=self.send_dialog) + return + if amount_str[0] == "-": + self.warn_modal("Amount input must be positive or null.", parent=self.send_dialog) + return + try: + if amount_str != "ALL": + if float(amount_str) <= 0: + self.warn_modal("Input a positive amount value.", parent=self.send_dialog) + return + except ValueError: + self.warn_modal("Unvalid amount input", parent=self.send_dialog) + return + self.send_dialog.Disable() + conf = self.confirm_tx(address, amount_str) + if conf == wx.ID_YES: + self.gui_panel.Enable() + self.send_dialog.Destroy() + self.transfer(address, amount_str, sel_fee) + return + self.send_dialog.Enable() + + def open_send(self, evt): + self.send_dialog = SendModal( + self.gui_panel, self.wallet.coin, self.wallet.check_address, self.callback_send + ) + self.send_dialog.SetSize(scaleSize(self.send_dialog, (520, 420))) + self.gui_panel.Disable() + self.send_dialog.Show() + + def qr_open(self, evt): + addr = self.wallet.get_account() + self.gui_panel.qr_button.Disable() + QRFrame(self.gui_frame, self.wallet.coin, addr, self.gui_panel.qr_button) + + def copy_account(self, ev): + if not hasattr(self, "wallet"): + attach_tt(self.gui_panel.copy_button, "No wallet") + return + try: + if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open(): + wx.TheClipboard.Clear() + addr = self.gui_panel.account_addr.GetLabel() + wx.TheClipboard.SetData(wx.TextDataObject(addr)) + wx.TheClipboard.Flush() + wx.TheClipboard.Close() + attach_tt(self.gui_panel.copy_button, "Address copied") + else: + attach_tt(self.gui_panel.copy_button, "No Access") + except Exception: + attach_tt(self.gui_panel.copy_button, "Error") + + def disp_history(self, ev): + hist_url = self.wallet.history() + if hist_url: + show_history(hist_url) + + def warn_modal(self, warning_text, modal=False, parent=None): + if parent is None: + parent = self.gui_frame + InfoBox(warning_text, "Error", wx.OK | wx.ICON_WARNING, parent, block_modal=modal) + + def info_modal(self, title, info_text): + InfoBox(info_text, title, wx.OK | wx.ICON_INFORMATION, self.gui_frame) + + def get_password(self, device_nam, input_message): + pwd_dialog = wx.PasswordEntryDialog( + self.gui_frame, + input_message, + caption=f"{device_nam} wallet PIN/password", + defaultValue="", + pos=wx.DefaultPosition, + ) + if pwd_dialog.ShowModal() == wx.ID_OK: + passval = pwd_dialog.GetValue() + return passval + + def get_option(self, network_id, input_value, preset_values): + option_dialog = gui.maingui.OptionDialog(self.gui_frame) + option_dialog.SetSize(scaleSize(option_dialog, (455, 380))) + option_panel = app_option_panel(option_dialog) + option_panel.SetTitle(f"Wallet settings : {input_value} selection") + option_panel.SetPresetLabel(f"preset {input_value}") + option_panel.SetCustomLabel(f"Input a {input_value}") + if preset_values: + option_panel.SetPresetValues(preset_values[network_id]) + else: + option_panel.HidePreset() + if option_dialog.ShowModal() == wx.ID_OK: + optval = option_panel.GetValue() + return optval + + def add_wallet_types(self, wallets_types): + self.gui_panel.wallopt_choice.Clear() + for wtype in wallets_types: + if wtype not in ["ERC20", "WalletConnect"]: + self.gui_panel.wallopt_choice.Append(wtype) def hd_setup(self, proposal): """Call the HD device option window.""" - self.gui_hdframe = gui.window.HDDialog(self.gui_frame) + self.gui_hdframe = gui.maingui.HDDialog(self.gui_frame) self.gui_hdpanel = HDsetting_panel(self.gui_hdframe) - HAND_CURSOR = Cursor(CURSOR_HAND) if proposal: # LocalFile wallet init setup - self.gui_hdpanel.GOOD_BMP = Bitmap(file_path("gui/good.bmp")) - self.gui_hdpanel.BAD_BMP = Bitmap(file_path("gui/bad.bmp")) + self.gui_hdpanel.GOOD_BMP = wx.Bitmap(file_path("gui/images/good.png")) + self.gui_hdpanel.BAD_BMP = wx.Bitmap(file_path("gui/images/bad.png")) self.gui_hdpanel.m_bitmapHDwl.SetBitmap(self.gui_hdpanel.BAD_BMP) self.gui_hdpanel.m_bitmapHDcs.SetBitmap(self.gui_hdpanel.BAD_BMP) - self.gui_hdpanel.m_checkBox_secboost.SetCursor(HAND_CURSOR) + self.gui_hdpanel.m_checkBox_secboost.SetCursor(self.HAND_CURSOR) self.gui_hdpanel.m_textCtrl_mnemo.SetValue(proposal) self.gui_hdpanel.m_usertxt.SetLabel( "Validate this first proposal,\n" @@ -307,11 +707,11 @@ def hd_setup(self, proposal): self.gui_hdpanel.m_textCtrl_pwd.Destroy() self.gui_hdpanel.m_checkBox_secboost.Destroy() self.gui_hdpanel.m_usertxt.SetLabel("Choose account and index for the key to use.") - self.gui_hdframe.SetSize(480, 320) - self.gui_hdpanel.m_butOK.SetCursor(HAND_CURSOR) - self.gui_hdpanel.m_butcancel.SetCursor(HAND_CURSOR) + self.gui_hdframe.SetSize(scaleSize(self.gui_hdframe, (580, 360))) + self.gui_hdpanel.m_butOK.SetCursor(self.HAND_CURSOR) + self.gui_hdpanel.m_butCancel.SetCursor(self.HAND_CURSOR) ret = self.gui_hdframe.ShowModal() - if ret == ID_OK: + if ret == wx.ID_OK: wallet_settings = self.gui_hdpanel.hd_wallet_settings # Removal of stored settings self.gui_hdframe.DestroyChildren() @@ -320,3 +720,171 @@ def hd_setup(self, proposal): return wallet_settings else: return None + + def end_checkwallet(self, modal, result): + wx.MilliSleep(200) + modal.Update(100, "done") + wx.MilliSleep(200) + if not result: + self.warn_modal("The address verification was rejected on the Ledger.") + + def check_device_address(self, pm): + try: + self.device.get_public_key(partial(self.end_checkwallet, pm)) + except Exception as exc: + pm.Update(100, "failure") + wx.MilliSleep(200) + wx.CallAfter(self.device_error, exc) + + def check_wallet(self, evt): + evt.Skip() + if not hasattr(self, "wallet"): + return + progress_modal = wx.ProgressDialog( + "", + "", + style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE | wx.PD_SMOOTH, + parent=self.gui_frame, + ) + wx.MilliSleep(250) + wait_msg = "Verify the address on the Ledger screen.\n" + wait_msg += self.wallet.get_account() + progress_modal.Update(50, wait_msg) + wx.MilliSleep(250) + wx.CallAfter(self.check_device_address, progress_modal) + + def display_fiat(self, chain, net, balance, fiat_price): + if not self.check_coin_consistency(chain, net): + # User changed the coin or network the time of the get price + return + self.gui_panel.fiat_price = fiat_price + self.gui_panel.fiat_panel.Show() + self.gui_panel.txt_fiat.SetLabel(f"$ {balance * fiat_price:.2f}") + self.gui_panel.Layout() + + def display_balance(self): + logger.debug("Checking for wallet balance") + if not hasattr(self, "wallet"): + self.erase_info() + return + coinw = type(self.wallet) + wall_net = self.gui_panel.network_choice.GetSelection() + try: + balance = self.wallet.get_balance() + except Exception as exc: + if hasattr(self, "balance_timer"): + self.balance_timer.Stop() + if hasattr(self, "wallet") and hasattr(self.wallet, "wc_timer"): + self.wallet.wc_client.close() + self.wallet.wc_timer.Stop() + delattr(self.wallet, "wc_timer") + self.gui_panel.hist_button.Disable() + self.disable_send() + self.deactivate_option_buttons() + self.gui_panel.wallopt_label.Disable() + self.gui_panel.wallopt_choice.Disable() + self.gui_panel.balance_info.SetLabel(" - offline -") + self.gui_panel.balance_small.SetLabel("") + self.gui_panel.balance_unit.SetLabel("") + self.gui_panel.txt_fiat.SetLabel("$ 0") + self.gui_panel.fiat_panel.Hide() + if hasattr(self.gui_panel, "fiat_price"): + del self.gui_panel.fiat_price + self.gui_frame.Refresh() + self.gui_frame.Layout() + err_msg = ( + f"Error when getting account balance.\nCheck your Internet connection.\n{str(exc)}" + ) + logger.error("Error in display_balance : %s", err_msg, exc_info=exc, stack_info=True) + self.warn_modal(err_msg) + return + if not self.check_coin_consistency(coinw, wall_net): + # User changed the coin or network the time of the get balance + return + if not hasattr(self, "wallet"): + return + balance_num, balance_coin = balance.split(" ")[:2] + if "." in balance_num: + balance_int, balance_float = balance_num.split(".") + balance_int += "." + else: + balance_int = balance_num + balance_float = "" + self.gui_panel.balance_info.SetLabel(f"{balance_int}{balance_float[:2]}") + self.gui_panel.balance_small.SetLabel(f"{balance_float[2:]}") + self.gui_panel.balance_unit.SetLabel(balance_coin) + if ( + # No fund in the wallet + balance_num not in ("0", "0.0") + # EOS when register pubkey mode : disable sending + and balance_num != "Register" + # WalletConnect : disable sending + and not hasattr(self.wallet, "wc_timer") + ): + self.enable_send() + cb_fiat = partial(self.display_fiat, coinw, wall_net, float(balance_num)) + # Read the coin price + # if not testnet + if self.gui_panel.network_choice.GetSelection() == 0 or self.current_chain == "GLMR": + if hasattr(self.wallet, "eth") and self.wallet.eth.ERC20: + PriceAPI(cb_fiat, self.wallet.eth.ERC20, self.current_chain) + else: + PriceAPI(cb_fiat, self.wallet.coin) + else: + self.disable_send() + if hasattr(self, "wallet") and hasattr(self.wallet, "wc_timer"): + # WalletConnect active + self.disable_send("Use the connected dapp to transact") + self.gui_panel.Refresh() + self.gui_panel.Update() + self.gui_panel.Layout() + + def device_error(self, exc): + self.current_chain = "" + if hasattr(self, "device"): + del self.device + if hasattr(self, "gui_panel"): + # Back to device panel + self.gui_panel.Destroy() + del self.gui_panel + self.open_devices_panel() + logger.error("Error with device : %s", str(exc), exc_info=exc, stack_info=True) + self.warn_modal(str(exc)) + return + + def check_coin_consistency(self, current_wallet=None, network_num=None): + """Check if selected coin is the same as the current wallet class used.""" + # Designed to fix a race condition when the async data of a wallet + # are displayed : address and balance. + # Changing the coin selected could mix crypto info. So this terminates some + # process path that are no longer valid. + if hasattr(self, "wallet") and self.current_chain is not None: + if current_wallet is None: + current_wallet = type(self.wallet) + coin_class = self.coin_classes(self.current_chain) + if coin_class is not current_wallet: + return False + if network_num is not None: + if self.gui_panel.network_choice.IsEmpty(): + return + net_sel = self.gui_panel.network_choice.GetSelection() + if net_sel < 0: + return False + return net_sel == network_num + return True + + def token_started(self): + self.gui_panel.but_evt1.Unbind(wx.EVT_BUTTON) + self.gui_panel.but_evt1.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/quit.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.but_evt2.Disable() + return self.gui_panel.but_evt1 + + def wc_started(self): + self.gui_panel.but_evt2.Unbind(wx.EVT_BUTTON) + self.gui_panel.but_evt2.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/endwc.png"), wx.BITMAP_TYPE_PNG) + ) + self.gui_panel.but_evt1.Disable() + return self.gui_panel.but_evt2 diff --git a/gui/bad.bmp b/gui/bad.bmp deleted file mode 100644 index 8acfad6..0000000 Binary files a/gui/bad.bmp and /dev/null differ diff --git a/gui/copy.png b/gui/copy.png deleted file mode 100644 index 76b1bda..0000000 Binary files a/gui/copy.png and /dev/null differ diff --git a/gui/copydn.png b/gui/copydn.png deleted file mode 100644 index 6ab111a..0000000 Binary files a/gui/copydn.png and /dev/null differ diff --git a/gui/fiat_price.py b/gui/fiat_price.py new file mode 100644 index 0000000..ce1b469 --- /dev/null +++ b/gui/fiat_price.py @@ -0,0 +1,74 @@ +from json import load +from urllib.request import urlopen + +from wx import CallAfter + + +chain_names = { + "GMLR": "moonbeam", + "EOS": "eos", + "XTZ": "tezos", + "ARB": "arbitrum-one", + "BSC": "binance-smart-chain", + "SOL": "solana", + "FTM": "fantom", + "CELO": "celo", + "MATIC": "polygon-pos", + "MOVR": "moonriver", + "CRO": "cronos", + "BOBA": "boba", + "ONE": "harmony-shard-0", + "AVAX": "avalanche", + "METIS": "metis-andromeda", + "ETH": "ethereum", + "OP": "optimistic-ethereum", +} + +native_tokens = { + "GMLR": "moonbeam", + "EOS": "eos", + "XTZ": "tezos", + "ARB": "ethereum", + "BSC": "binancecoin", + "SOL": "solana", + "FTM": "fantom", + "CELO": "celo", + "MATIC": "matic-network", + "MOVR": "moonriver", + "CRO": "cronos", + "BOBA": "boba-network", + "ONE": "harmony", + "AVAX": "avalanche-2", + "METIS": "metis-token", + "ETH": "ethereum", + "OP": "optimism", +} + + +class PriceAPI: + + BASE_URL = "https://api.coingecko.com/api/v3/" + + def __init__(self, cb, token, chain=""): + """Async query""" + CallAfter(self.get_price, token, chain, cb) + + def get_price(self, token_id, chainid, cb): + """Read token price in USD from CoinGecko""" + call_url = "" + if chainid: + call_url = ( + f"{PriceAPI.BASE_URL}simple/token_price/" + f"{chain_names.get(chainid)}?" + f"contract_addresses={token_id.lower()}" + "&vs_currencies=usd" + ) + else: + token_id = native_tokens.get(token_id) + if token_id is not None: + call_url = f"{PriceAPI.BASE_URL}simple/price?ids={token_id}" "&vs_currencies=usd" + if call_url: + rsp = urlopen(call_url) + value_json = load(rsp) + value = value_json[token_id.lower()]["usd"] + cb(value) diff --git a/gui/good.bmp b/gui/good.bmp deleted file mode 100644 index 52a448e..0000000 Binary files a/gui/good.bmp and /dev/null differ diff --git a/gui/gui-sw.fbp b/gui/gui-sw.fbp index 755ae65..163ccf6 100644 --- a/gui/gui-sw.fbp +++ b/gui/gui-sw.fbp @@ -59,7 +59,7 @@ 0 wxAUI_MGR_DEFAULT - + 248,250,252 1 1 @@ -84,7 +84,7 @@ wxVERTICAL none - 15 + 8 wxBOTTOM 0 @@ -102,79 +102,6 @@ bSizer31 wxHORIZONTAL none - - 10 - wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - Load From File; - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - MyButton - - 0 - - 0 - - - 0 - - 1 - m_button_gen - 1 - - - protected - 1 - - - - Resizable - 1 - - wxBORDER_NONE - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - gen_new_mnemonic - - 5 wxEXPAND @@ -210,7 +137,7 @@ 0 Left 1 - + 0,0,0 1 ,90,90,9,70,0 0 @@ -259,7 +186,7 @@ - + wxSYS_COLOUR_WINDOW 1 0 @@ -311,10 +238,83 @@ + + 10 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From File; + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_button_gen + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + gen_new_mnemonic + + - 8 + 12 wxTOP 0 @@ -358,7 +358,7 @@ 0 Left 1 - + 0,0,0 1 ,90,90,12,70,0 0 @@ -419,7 +419,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -509,7 +509,7 @@ - + wxBORDER_NONE @@ -548,7 +548,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -638,7 +638,7 @@ - + wxBORDER_NONE @@ -657,7 +657,7 @@ - + wxSYS_COLOUR_WINDOW 1 0 @@ -669,7 +669,7 @@ 0 Left 1 - + wxSYS_COLOUR_WINDOWTEXT 1 ,90,90,12,70,0 0 @@ -754,7 +754,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -803,7 +803,7 @@ - + 255,255,255 1 0 @@ -815,7 +815,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -940,7 +940,7 @@ - + wxSYS_COLOUR_WINDOW 1 0 @@ -1038,7 +1038,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -1087,7 +1087,7 @@ - + 255,255,255 1 0 @@ -1099,7 +1099,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -1163,7 +1163,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -1227,7 +1227,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -1276,7 +1276,7 @@ - + 255,255,255 1 0 @@ -1288,7 +1288,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -1396,7 +1396,7 @@ - + wxBORDER_NONE seek_assets @@ -1426,7 +1426,7 @@ 0 Left 0 - + 0,0,0 1 ,90,90,10,70,0 0 diff --git a/gui/gui_uniblow.fbp b/gui/gui2.fbp similarity index 56% rename from gui/gui_uniblow.fbp rename to gui/gui2.fbp index bd79def..868b60c 100644 --- a/gui/gui_uniblow.fbp +++ b/gui/gui2.fbp @@ -11,12 +11,12 @@ res UTF-8 connect - window + maingui 1000 none 1 0 - Uniblow + uniblow_newgui . @@ -43,33 +43,33 @@ wxID_ANY - TopFrame + UniblowFrame - 950,425 - wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU + 500,450 + wxCAPTION|wxCLOSE_BOX|wxMINIMIZE|wxMINIMIZE_BOX|wxSYSTEM_MENU ; ; forward_declare - Uniblow + - wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL + wxTAB_TRAVERSAL 1 0 wxAUI_MGR_DEFAULT - + 248,250,252 1 1 impl_virtual - ,90,90,-1,70,0 + 0 wxID_ANY - TopPanel + WalletPanel -1,-1 ; ; forward_declare @@ -84,153 +84,21 @@ none 5 - wxALIGN_CENTER_VERTICAL|wxLEFT - 0 - - 0 - protected - 0 - - - - 5 - wxALIGN_CENTER_VERTICAL + wxEXPAND 0 - - - bSizer2 + + wxID_ANY + chains + -1,-1 + sbSizer5 wxVERTICAL + 1 none - - 5 - wxALIGN_CENTER_HORIZONTAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,11,70,0 - 0 - 0 - wxID_ANY - Device - 0 - - 0 - - - 0 - - 1 - device_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - + 5 - wxTOP|wxALIGN_CENTER_HORIZONTAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,12,70,0 - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - devices_choice - 1 - - - protected - 1 - - Resizable - 0 - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 20 - wxALIGN_CENTER_HORIZONTAL|wxTOP + 0 - + 1 1 1 @@ -240,7 +108,7 @@ - + 248,250,252 1 0 @@ -252,71 +120,9 @@ 0 Left 1 - - 1 - ,90,90,11,70,0 - 0 - 0 - wxID_ANY - Blockchain - 0 - - 0 - - - 0 - - 1 - coins_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 0 - + 0,0,0 1 - ,90,90,12,70,0 + 0 0 wxID_ANY @@ -327,7 +133,7 @@ 0 1 - coins_choice + scrolled_coins 1 @@ -335,377 +141,976 @@ 1 Resizable - 0 + 5 + 5 1 - - + 85,378 ; ; forward_declare 0 - - wxFILTER_NONE - wxDefaultValidator - - - - - - 20 - wxALIGN_CENTER_HORIZONTAL|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - ,90,90,10,70,0 - 0 - 0 - wxID_ANY - Network - 0 - - 0 - - - 0 - - 1 - network_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_HORIZONTAL|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - ,90,90,12,70,0 - 0 - 0 - wxID_ANY - - 0 - -1,-1 - - 0 - - 1 - network_choice - 1 - - - protected - 1 - - Resizable - 0 - 1 - 150,-1 - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 20 - wxALIGN_CENTER_HORIZONTAL|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - ,90,90,10,70,0 - 0 - 0 - wxID_ANY - Account Type - 0 - - 0 - - - 0 - - 1 - wallopt_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_HORIZONTAL|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - ,90,90,12,70,0 - 0 - 0 - wxID_ANY - - 0 - -1,-1 - - 0 - - 1 - wallopt_choice - 1 - - - protected - 1 - - Resizable - 0 - 1 - 185,-1 - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxEXPAND - 1 - - 32 - protected - 220 + wxBORDER_NONE|wxVSCROLL 5 - + wxEXPAND | wxALL 1 - + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 - bSizer3 - wxVERTICAL - none - - 16 - wxEXPAND|wxLEFT|wxTOP - 0 - - - bSizer5 - wxVERTICAL - none - - 5 - - 0 - - - bSizer201 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,14,70,0 - 0 - 0 - wxID_ANY - Account - 0 - - 0 - - - 0 - - 1 - account_label - 1 - - + 1 + m_panel1 + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer6 + wxVERTICAL + none + + 16 + wxEXPAND + 0 + + + bSizer4 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bSizer29 + wxVERTICAL + none + + 12 + wxTOP + 0 + + + bSizer28 + wxHORIZONTAL + none + + 20 + wxALIGN_BOTTOM|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + img_arrsel + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + + + + + 24 + wxRIGHT + 0 + + 0 + protected + 0 + + + + 8 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_BOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,16,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + -1,-1 + 1 + balance_info + 1 + + + protected + 1 + + Resizable + 1 + -1,-1 + + ; ; forward_declare + 0 + + + + wxFULL_REPAINT_ON_RESIZE + -1 + + + + 2 + wxLEFT + 0 + + 0 + protected + 0 + + + + 10 + wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_BOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,10,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + balance_small + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 8 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,16,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + balance_unit + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 18 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + 100,116,139 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 1 + wxID_ANY + + 0 + + + 0 + + 1 + fiat_panel + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxBORDER_SUNKEN|wxTAB_TRAVERSAL + + + bSizer31 + wxHORIZONTAL + none + + 8 + wxLEFT + 0 + + 0 + protected + 0 + + + + 3 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 248,248,248 + 1 + ,90,90,10,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + txt_fiat + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 8 + wxLEFT + 0 + + 0 + protected + 0 + + + + + + + + + + + 5 + + 1 + + 0 + protected + 0 + + + + 24 + + 0 + + + bSizer5 + wxVERTICAL + none + + 12 + wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_but_changedevice + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + Network + 0 + + 0 + + + 0 + + 1 + m_staticText26 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 12 + wxALIGN_CENTER_HORIZONTAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + wxSYS_COLOUR_WINDOW + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,12,70,0 + 0 + 0 + wxID_ANY + + 0 + + + 0 + 120,-1 + 1 + network_choice + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + 16 + wxBOTTOM + 0 + + + optevt_sizer + wxHORIZONTAL + none + + 45 + wxEXPAND|wxLEFT + 1 + + 0 + protected + 0 + + + + 12 + wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + 248,250,252 + + + 1 + 0 + 1 + + 0 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + but_evt1 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 36 + wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + 248,250,252 + + + 1 + 0 + 1 + + 0 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + but_evt2 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + + + 6 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + 240,240,240 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panel4 + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer32 + wxVERTICAL + none + + 16 + wxTOP + 0 + + 0 protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 + 0 - 80 - wxALIGN_CENTER_VERTICAL|wxLEFT|wxRESERVE_SPACE_EVEN_IF_HIDDEN + 36 + wxLEFT 0 - + 1 1 1 @@ -715,32 +1120,24 @@ - - + 255,255,255 1 0 1 1 - - 0 0 - Dock 0 Left 1 1 - - ,90,90,10,70,0 + 0 0 wxID_ANY - Check on Ledger screen - - 0 0 @@ -748,131 +1145,249 @@ 0 1 - btn_chkaddr + m_panel5 1 protected 1 - - Resizable 1 - ; ; forward_declare 0 - - wxFILTER_NONE - wxDefaultValidator - - + wxTAB_TRAVERSAL + + + bSizer36 + wxHORIZONTAL + none + + 12 + wxTOP|wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + qr_button + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 16 + wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 113,110,234 + 1 + ,90,90,12,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + 525,-1 + + 0 + -1,-1 + 1 + account_addr + 1 + + + protected + 1 + + Resizable + 1 + -1,-1 + wxST_ELLIPSIZE_MIDDLE + ; ; forward_declare + 0 + + + + + -1 + + + + 12 + wxTOP|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + copy_button + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + - - - - 16 - wxTOP|wxBOTTOM|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,13,70,0 - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - account_addr - 1 - - - protected - 1 - - Resizable - 1 - 585,-1 - wxTE_READONLY - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - wxBORDER_NONE - - - - - - 8 - wxALIGN_CENTER_HORIZONTAL - 0 - - - bSizer6 - wxHORIZONTAL - none - - 5 - - 1 - - - bSizer18 - wxVERTICAL - none - 5 - + 16 + wxTOP|wxBOTTOM|wxEXPAND 0 - bSizer19 + bSizer34 wxHORIZONTAL none - - 25 - wxLEFT + + 36 + wxALIGN_CENTER_VERTICAL|wxLEFT 0 - + 1 1 1 @@ -883,7 +1398,7 @@ - Load From File; + 1 0 @@ -897,7 +1412,7 @@ Dock 0 Left - 0 + 1 1 @@ -937,14 +1452,14 @@ - + wxBORDER_NONE - - 75 + + 12 wxLEFT 0 - + 1 1 1 @@ -955,7 +1470,7 @@ - Load From File; + 1 0 @@ -969,13 +1484,13 @@ Dock 0 Left - 0 + 1 1 0 - 0 + 1 wxID_ANY MyButton @@ -985,9 +1500,9 @@ 0 - + -1,-1 1 - copy_button + btn_chkaddr 1 @@ -998,8 +1513,8 @@ Resizable 1 - - wxBORDER_NONE + -1,-1 + ; ; forward_declare 0 @@ -1009,95 +1524,13 @@ - - - - - - - 20 - wxTOP - 0 - - 0 - protected - 0 - - - - 16 - wxTOP - 0 - - - bSizer16 - wxHORIZONTAL - none - - 24 - - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,15,70,0 - 0 - 0 - wxID_ANY - Balance - 0 - - 0 - - - 0 - - 1 - balance_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 + wxBORDER_NONE - 12 - wxLEFT|wxALIGN_BOTTOM - 0 + 8 + wxRIGHT|wxLEFT|wxEXPAND + 1 0 protected @@ -1105,815 +1538,824 @@ - 20 - + 5 + wxRIGHT 0 - - 1 - 1 - 1 - 1 - - - - - 250,-1 - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,15,70,0 - 0 - 0 - wxID_ANY - - 0 - - 0 - - 250,-1 - 0 + - 0 - balance_info - 1 - - -1,-1 + bSizer37 + wxHORIZONTAL + none + + 8 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,11,70,0 + 0 + 0 + wxID_ANY + Wallet type + 0 + + 0 + + + 0 + + 1 + wallopt_label + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 24 + wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + wxSYS_COLOUR_WINDOW + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,11,70,0 + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + wallopt_choice + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + 32 + wxEXPAND + 1 + + 0 protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 + 0 - - 10 - wxTOP|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - - 0 - - 1 - copy_status - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 148 - wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Right - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - qrimg - 1 - - - protected - 1 - - Fixed - 1 - 140,140 - ; ; forward_declare - 0 - - - - - + + + 12 + wxTOP + 0 + + 0 + protected + 0 - - - 8 - wxTOP|wxEXPAND - 0 - - - bSizer4 - wxHORIZONTAL - none - - 8 - wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,14,70,0 - 0 - 0 - wxID_ANY - To : - 0 - - 0 - - - 0 - - 1 - dest_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - + + 72 + wxRIGHT|wxALIGN_RIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + + + 0 + + 0 + + + 0 + + 1 + btn_send + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE - - 3 - wxALIGN_BOTTOM - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - addr_panel - 1 - - - protected - 1 - - Resizable - 1 - - ; ; forward_declare - 0 - - - - wxTAB_TRAVERSAL - - - bSizer20 - wxVERTICAL - none - - 3 - wxALIGN_CENTER_HORIZONTAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - ,90,90,14,70,0 - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - dest_addr - 1 - - - protected - 1 - - Resizable - 1 - 581,-1 - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,11,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + alt_text + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + 120 - - 12 - wxTOP - 0 - + + + + + + 0 + wxAUI_MGR_DEFAULT + 248,250,252 + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + DevicesPanel + + -1,-1 + ; ; forward_declare + + + + wxTAB_TRAVERSAL + + + bSizer3 + wxVERTICAL + none + + 32 + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + bmp_logo + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxBORDER_NONE + + + + 18 + wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 113,110,234 + 1 + ,90,90,16,70,0 + 0 + 0 + wxID_ANY + Select Device + 0 + + 0 + + + 0 + + 1 + m_staticText1 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + wxFULL_REPAINT_ON_RESIZE + -1 + + + + 8 + wxALIGN_CENTER_HORIZONTAL|wxTOP + 0 + + 2 + wxBOTH + + + 36 + + fgSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 18 + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + SeedWatcher + + 0 + + 0 + + + 0 - bSizer7 - wxHORIZONTAL - none - - 8 - wxLEFT|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,14,70,0 - 0 - 0 - wxID_ANY - Amount : - 0 - - 0 - - - 0 - - 1 - amount_label - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - ,90,90,14,70,0 - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - amount - 1 - - - protected - 1 - - Resizable - 1 - - wxTE_PROCESS_ENTER - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - 0 - - 0 - - - bSizer9 - wxVERTICAL - none - - 6 - wxLEFT|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - 2 - - 0 - - 0 - - 0 - - 1 - fee_slider - 1 - - - protected - 1 - - Resizable - 1 - - wxSL_HORIZONTAL - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - 1 - - - - - - - 6 - wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,10,70,0 - 0 - 0 - wxID_ANY - - 0 - - 0 - - - 0 - - 1 - fee_setting - 1 - - - protected - 1 - - Resizable - 1 - - wxALIGN_CENTER_HORIZONTAL - ; ; forward_declare - 0 - - - - - -1 - - - - - - 8 - wxTOP|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - Load From File; - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 0 - - 1 - - - 0 - 0 - wxID_ANY - MyButton - - 0 - - 0 - - - 0 - - 1 - send_button - 1 - - - protected - 1 - - - - Resizable - 1 - - wxBORDER_NONE - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 8 - wxLEFT - 1 - - 0 - protected - 0 - - - - 8 - wxLEFT|wxTOP - 0 - - 1 - 1 - 1 - 1 - - - - - - - Load From File; - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 0 - - 1 - - - 0 - 0 - wxID_ANY - MyButton - - 0 - - 0 - - - 0 - - 1 - send_all - 1 - - - protected - 1 - - - - Resizable - 1 - - wxBORDER_NONE - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - + 1 + d_btn01 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + LocalFiles + + 0 + + 0 + + + 0 + + 1 + d_btn02 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Ledger + + 0 + + 0 + + + 0 + + 1 + d_btn03 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Cryptnox + + 0 + + 0 + + + 0 + + 1 + d_btn04 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + OpenPGP + + 0 + + 0 + + + 0 + + 1 + d_btn05 + 1 + + + protected + 1 + + + + Resizable + 1 + + wxBORDER_NONE + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE @@ -1941,7 +2383,7 @@ 600,480 wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP|wxSYSTEM_MENU ; ; forward_declare - Local File wallet setup + Wallet setup @@ -1950,7 +2392,7 @@ 0 wxAUI_MGR_DEFAULT - + 248,250,252 1 1 @@ -2009,13 +2451,13 @@ 0 Left 1 - + 0,0,0 1 ,90,90,14,70,0 0 0 wxID_ANY - Local wallet mnemonic setup + Wallet mnemonic setup 0 0 @@ -2080,7 +2522,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -2116,8 +2558,8 @@ - 5 - wxALIGN_BOTTOM|wxBOTTOM + 6 + wxBOTTOM|wxALIGN_BOTTOM 0 1 @@ -2170,7 +2612,7 @@ - + wxBORDER_NONE @@ -2199,7 +2641,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -2235,7 +2677,7 @@ - 5 + 6 wxALIGN_BOTTOM|wxBOTTOM 0 @@ -2289,7 +2731,7 @@ - + wxBORDER_NONE @@ -2318,7 +2760,7 @@ - + wxSYS_COLOUR_WINDOW 1 0 @@ -2330,7 +2772,7 @@ 0 Left 1 - + wxSYS_COLOUR_WINDOWTEXT 1 ,90,90,12,70,0 0 @@ -2414,7 +2856,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -2442,18 +2884,157 @@ ; ; forward_declare 0 - + + + + + -1 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + 255,255,255 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textCtrl_pwd + 1 + + + protected + 1 + + Resizable + 1 + 170,-1 + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 22 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + SecuBoost + + 0 + + + 0 + + 1 + m_checkBox_secboost + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Extra security boost for mnemonic. Not compatible with BIP39. Requires >1GB RAM free + + wxFILTER_NONE + wxDefaultValidator + - -1 + + + + 16 + wxALIGN_CENTER_HORIZONTAL|wxTOP + 1 + + + bSizer14 + wxHORIZONTAL + none 5 - wxALL + wxALIGN_CENTER_VERTICAL 0 - + 1 1 1 @@ -2475,21 +3056,22 @@ 0 Left 1 - + 0,0,0 1 0 0 wxID_ANY + Account # + 0 0 - 0 1 - m_textCtrl_pwd + m_accounttxt 1 @@ -2498,26 +3080,22 @@ Resizable 1 - 170,-1 + ; ; forward_declare 0 - - wxFILTER_NONE - wxDefaultValidator - - + -1 - 22 - wxALIGN_CENTER_VERTICAL|wxLEFT + 5 + wxALL|wxALIGN_CENTER_VERTICAL 0 - + 1 1 1 @@ -2527,11 +3105,10 @@ - + 255,255,255 1 0 - 0 1 1 @@ -2540,21 +3117,23 @@ 0 Left 1 - + 0,0,0 1 0 0 wxID_ANY - SecuBoost + 0 + 2147483647 0 + 0 0 1 - m_checkBox_secboost + m_spinCtrl_account 1 @@ -2563,34 +3142,20 @@ Resizable 1 - - + 75,-1 + wxSP_ARROW_KEYS ; ; forward_declare 0 - Extra security boost for mnemonic. Not compatible with BIP39. Requires >1GB RAM free - - wxFILTER_NONE - wxDefaultValidator - + + - - - - 16 - wxALIGN_CENTER_HORIZONTAL|wxTOP - 1 - - - bSizer14 - wxHORIZONTAL - none - 5 - wxALIGN_CENTER_VERTICAL + 24 + wxLEFT|wxALIGN_CENTER_VERTICAL 0 1 @@ -2614,13 +3179,13 @@ 0 Left 1 - + 0,0,0 1 0 0 wxID_ANY - Account # + index 0 0 @@ -2629,7 +3194,7 @@ 0 1 - m_accounttxt + m_indextxt 1 @@ -2663,7 +3228,7 @@ - + 255,255,255 1 0 @@ -2675,7 +3240,7 @@ 0 Left 1 - + 0,0,0 1 0 @@ -2691,7 +3256,7 @@ 0 1 - m_spinCtrl_account + m_spinCtrl_index 1 @@ -2711,11 +3276,157 @@ + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + Alt. derivation path (Not BIP44, for ETH / EVM) + + 0 + + + 0 + + 1 + m_altderiv + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 20 + wxTOP + 0 + + 0 + protected + 0 + + + + 24 + wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,10,70,0 + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + m_usertxt + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 18 + wxALIGN_CENTER_HORIZONTAL|wxALL + 0 + + + bSizer12 + wxHORIZONTAL + none - 24 - wxLEFT|wxALIGN_CENTER_VERTICAL + 5 + wxALL 0 - + 1 1 1 @@ -2726,24 +3437,30 @@ + Load From File; 1 0 1 1 + + 0 0 + Dock 0 Left 1 1 + 0 0 wxID_ANY - index + OK + 0 0 @@ -2752,13 +3469,15 @@ 0 1 - m_indextxt + m_butOK 1 protected 1 + + Resizable 1 @@ -2766,17 +3485,31 @@ ; ; forward_declare 0 + + wxFILTER_NONE + wxDefaultValidator + - - -1 + wxBORDER_NONE + hd_ok + + + + 25 + wxRIGHT + 1 + + 0 + protected + 0 5 - wxALL|wxALIGN_CENTER_VERTICAL + wxALL 0 - + 1 1 1 @@ -2787,355 +3520,1294 @@ + Load From File; 1 0 1 1 + + 0 0 + Dock 0 Left 1 1 + 0 0 wxID_ANY - 0 - 2147483647 + Cancel + + 0 0 - 0 0 1 - m_spinCtrl_index + m_butCancel 1 protected 1 + + Resizable 1 - 75,-1 - wxSP_ARROW_KEYS + + ; ; forward_declare 0 - + + wxFILTER_NONE + wxDefaultValidator + - + wxBORDER_NONE + hd_cancel + + + + + + + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + SendDialog + + 520,420 + wxDEFAULT_DIALOG_STYLE + ; ; forward_declare + Sending + + + + + + + 0 + wxAUI_MGR_DEFAULT + 248,250,252 + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + SendPanel + + -1,-1 + ; ; forward_declare + + + + wxTAB_TRAVERSAL + + + bSizer13 + wxHORIZONTAL + none + + 16 + wxRIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 1 + + + bSizer23 + wxVERTICAL + none + + 24 + wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + + 0 + + + bSizer201 + wxHORIZONTAL + none + + 5 + wxTOP|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + Destination Address + 0 + + 0 + + + 0 + + 1 + m_staticText7 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 20 + wxLEFT + 0 + + 0 + protected + 0 + + + + 8 + wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Paste + + 0 + + 0 + + + 0 + + 1 + paste_btn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + + + 5 + wxEXPAND + 0 + + + bSizer14 + wxHORIZONTAL + none + + 5 + wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + 255,255,255 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + text_dest + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 6 + wxRIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + bmp_chk + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxBORDER_NONE + + + + + + 16 + wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer15 + wxHORIZONTAL + none + + 5 + + 0 + + wxID_ANY + Amount + -1,175 + sbSizer3 + wxVERTICAL + 1 + none + + 8 + wxLEFT + 0 + + + bSizer18 + wxVERTICAL + none + + 5 + wxRIGHT|wxLEFT|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + Available : + 0 + + 0 + + + 0 + + 1 + m_staticTextAvailLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + text_avail + 1 + + + protected + 1 + + Resizable + 1 + -1,-1 + + ; ; forward_declare + 0 + + + + + -1 + + + + + + 5 + + 0 + + + bSizer20 + wxHORIZONTAL + none + + 8 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + 255,255,255 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + 150,-1 + 1 + text_amount + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxTOP|wxBOTTOM|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + text_coin + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + 32 + wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + Send all + + 0 + + + 0 + + 1 + check_sendall + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 8 + wxTOP + 0 + + 0 + protected + 0 + + + + 5 + + 0 + + + bSizer191 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,9,70,0 + 0 + 0 + wxID_ANY + value ~ + 0 + + 0 + + + 0 + + 1 + fiat_label + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,9,70,0 + 0 + 0 + wxID_ANY + $ 0 + 0 + + 0 + + + 0 + + 1 + fiat_value + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + + + 24 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + wxID_ANY + Fees + -1,175 + sbSizer2 + wxVERTICAL + 1 + none + + 24 + wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 2 + + 0 + + 0 + + 0 + + 1 + fee_slider + 1 + + + protected + 1 + + Resizable + 1 + + wxSL_HORIZONTAL + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 1 + + + + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + ,90,90,9,70,0 + 0 + 0 + wxID_ANY + Normal fee + 0 + + 0 + + + 0 + + 1 + text_fees + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + - - - - 5 - wxALL|wxALIGN_CENTER_HORIZONTAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Alt. derivation path (Not BIP44, for ETH / EVM) - - 0 - - - 0 - - 1 - m_altderiv - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 20 - wxTOP - 0 - - 0 - protected - 0 - - - - 24 - wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - ,90,90,10,70,0 - 0 - 0 - wxID_ANY - - 0 - - 0 - - - 0 - - 1 - m_usertxt - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 18 - wxALIGN_CENTER_HORIZONTAL|wxALL - 0 - - - bSizer12 - wxHORIZONTAL - none - 5 - wxALL + 24 + wxALIGN_CENTER_HORIZONTAL|wxTOP 0 - - 1 - 1 - 1 - 1 - - - - - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - OK - - 0 - - 0 - - - 0 + - 1 - m_butOK - 1 - - - protected - 1 - - - - Resizable - 1 - -1,36 - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - hd_ok + bSizer19 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From File; + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + OK + + 0 + + 0 + + + 0 + + 1 + ok_btn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + + + 32 + wxRIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From File; + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Cancel + + 0 + + 0 + + + 0 + + 1 + cancel_btn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxBORDER_NONE + + - 25 - wxRIGHT - 1 + 16 + wxTOP + 0 0 protected 0 - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - wxID_ANY - Cancel - - 0 - - 0 - - - 0 - - 1 - m_butcancel - 1 - - - protected - 1 - - - - Resizable - 1 - -1,36 - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - hd_cancel - - + + + + 24 + wxRIGHT + 0 + + 0 + protected + 0 @@ -3158,7 +4830,7 @@ OptionDialog - 455,375 + 455,380 wxDEFAULT_DIALOG_STYLE ; ; forward_declare @@ -3170,7 +4842,7 @@ 0 wxAUI_MGR_DEFAULT - + 248,250,252 1 1 @@ -3183,7 +4855,7 @@ OptionPanel - -1,-1 + 396,400 ; ; forward_declare @@ -3230,7 +4902,7 @@ 0 Left 1 - + 0,0,0 1 ,90,90,11,70,0 0 @@ -3265,6 +4937,86 @@ -1 + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer31 + wxHORIZONTAL + none + + 5 + wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + 255,255,255 + 0 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 0,0,0 + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + 180,-1 + 1 + search_preset + 1 + + + protected + 1 + + Resizable + 1 + 1 + + wxTE_PROCESS_ENTER + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + onEraseSearch + onSearch + onSearch + onSearch + + + + 5 wxALL|wxALIGN_CENTER_HORIZONTAL @@ -3279,7 +5031,7 @@ - + wxSYS_COLOUR_WINDOW 1 0 @@ -3315,7 +5067,7 @@ Resizable 0 1 - 360,-1 + 320,-1 ; ; forward_declare 0 @@ -3355,9 +5107,9 @@ 0 Left 1 - + 0,0,0 1 - ,90,90,11,70,0 + ,90,90,11,70,1 0 0 wxID_ANY @@ -3416,7 +5168,7 @@ 0 Left 1 - + 0,0,0 1 ,90,90,11,70,0 0 @@ -3453,9 +5205,9 @@ 5 - wxALL|wxALIGN_CENTER_HORIZONTAL + wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -3498,7 +5250,7 @@ 0 1 - m_butpaste + m_but_paste 1 @@ -3520,7 +5272,7 @@ - + wxBORDER_NONE pasteValue @@ -3538,7 +5290,7 @@ - + 255,255,255 1 0 @@ -3550,7 +5302,7 @@ 0 Left 1 - + 0,0,0 1 ,90,90,11,70,0 0 @@ -3573,7 +5325,7 @@ Resizable 1 - 375,-1 + 320,-1 wxTE_PROCESS_ENTER ; ; forward_declare 0 @@ -3590,7 +5342,7 @@ - 28 + 20 wxALIGN_CENTER_HORIZONTAL|wxTOP 0 @@ -3600,9 +5352,9 @@ none 5 - wxALL + wxBOTTOM|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -3613,7 +5365,7 @@ - + Load From File; 1 0 @@ -3631,11 +5383,11 @@ 1 - ,90,90,11,70,0 + 0 0 wxID_ANY - Cancel + OK 0 @@ -3645,7 +5397,7 @@ 0 1 - m_button4 + m_but_ok 1 @@ -3656,7 +5408,7 @@ Resizable 1 - -1,40 + ; ; forward_declare 0 @@ -3667,8 +5419,8 @@ - - cancelOption + wxBORDER_NONE + okOption @@ -3683,9 +5435,9 @@ 5 - wxALL + wxBOTTOM|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -3696,7 +5448,7 @@ - + Load From File; 1 0 @@ -3714,11 +5466,11 @@ 1 - ,90,90,11,70,0 + 0 0 wxID_ANY - OK + Cancel 0 @@ -3728,7 +5480,7 @@ 0 1 - m_button3 + m_but_cancel 1 @@ -3739,7 +5491,7 @@ Resizable 1 - -1,40 + ; ; forward_declare 0 @@ -3750,8 +5502,8 @@ - - okOption + wxBORDER_NONE + cancelOption diff --git a/gui/histo.png b/gui/histo.png deleted file mode 100644 index 33dc161..0000000 Binary files a/gui/histo.png and /dev/null differ diff --git a/gui/histodn.png b/gui/histodn.png deleted file mode 100644 index 6204719..0000000 Binary files a/gui/histodn.png and /dev/null differ diff --git a/gui/images/arrsel.png b/gui/images/arrsel.png new file mode 100644 index 0000000..c3c7e70 Binary files /dev/null and b/gui/images/arrsel.png differ diff --git a/gui/images/bad.png b/gui/images/bad.png new file mode 100644 index 0000000..a2c9944 Binary files /dev/null and b/gui/images/bad.png differ diff --git a/gui/images/btns/GenSeed.png b/gui/images/btns/GenSeed.png new file mode 100644 index 0000000..6824c6e Binary files /dev/null and b/gui/images/btns/GenSeed.png differ diff --git a/gui/images/btns/SeekAssets.png b/gui/images/btns/SeekAssets.png new file mode 100644 index 0000000..2daf73b Binary files /dev/null and b/gui/images/btns/SeekAssets.png differ diff --git a/gui/images/btns/addrchk.png b/gui/images/btns/addrchk.png new file mode 100644 index 0000000..ef600a8 Binary files /dev/null and b/gui/images/btns/addrchk.png differ diff --git a/gui/images/btns/blankopt.png b/gui/images/btns/blankopt.png new file mode 100644 index 0000000..9bfa991 Binary files /dev/null and b/gui/images/btns/blankopt.png differ diff --git a/gui/images/btns/cancel.png b/gui/images/btns/cancel.png new file mode 100644 index 0000000..cc5baff Binary files /dev/null and b/gui/images/btns/cancel.png differ diff --git a/gui/images/btns/chdev.png b/gui/images/btns/chdev.png new file mode 100644 index 0000000..7477f21 Binary files /dev/null and b/gui/images/btns/chdev.png differ diff --git a/gui/images/btns/close.png b/gui/images/btns/close.png new file mode 100644 index 0000000..8f57098 Binary files /dev/null and b/gui/images/btns/close.png differ diff --git a/gui/images/btns/copy.png b/gui/images/btns/copy.png new file mode 100644 index 0000000..ea28401 Binary files /dev/null and b/gui/images/btns/copy.png differ diff --git a/gui/images/btns/dev_cryptnox.png b/gui/images/btns/dev_cryptnox.png new file mode 100644 index 0000000..0486686 Binary files /dev/null and b/gui/images/btns/dev_cryptnox.png differ diff --git a/gui/images/btns/dev_ledger.png b/gui/images/btns/dev_ledger.png new file mode 100644 index 0000000..fefe468 Binary files /dev/null and b/gui/images/btns/dev_ledger.png differ diff --git a/gui/images/btns/dev_localfile.png b/gui/images/btns/dev_localfile.png new file mode 100644 index 0000000..093b9d3 Binary files /dev/null and b/gui/images/btns/dev_localfile.png differ diff --git a/gui/images/btns/dev_openpgp.png b/gui/images/btns/dev_openpgp.png new file mode 100644 index 0000000..4839a3d Binary files /dev/null and b/gui/images/btns/dev_openpgp.png differ diff --git a/gui/images/btns/dev_seedwatcher.png b/gui/images/btns/dev_seedwatcher.png new file mode 100644 index 0000000..6cdf58b Binary files /dev/null and b/gui/images/btns/dev_seedwatcher.png differ diff --git a/gui/images/btns/endwc.png b/gui/images/btns/endwc.png new file mode 100644 index 0000000..44f9f04 Binary files /dev/null and b/gui/images/btns/endwc.png differ diff --git a/gui/images/btns/history.png b/gui/images/btns/history.png new file mode 100644 index 0000000..7ad6ae7 Binary files /dev/null and b/gui/images/btns/history.png differ diff --git a/gui/images/btns/ok.png b/gui/images/btns/ok.png new file mode 100644 index 0000000..a5ee6a4 Binary files /dev/null and b/gui/images/btns/ok.png differ diff --git a/gui/images/btns/paste.png b/gui/images/btns/paste.png new file mode 100644 index 0000000..2fe15e0 Binary files /dev/null and b/gui/images/btns/paste.png differ diff --git a/gui/images/btns/proceed.png b/gui/images/btns/proceed.png new file mode 100644 index 0000000..2abbf85 Binary files /dev/null and b/gui/images/btns/proceed.png differ diff --git a/gui/images/btns/qr.png b/gui/images/btns/qr.png new file mode 100644 index 0000000..72d6c3f Binary files /dev/null and b/gui/images/btns/qr.png differ diff --git a/gui/images/btns/quit.png b/gui/images/btns/quit.png new file mode 100644 index 0000000..0f33c76 Binary files /dev/null and b/gui/images/btns/quit.png differ diff --git a/gui/images/btns/send.png b/gui/images/btns/send.png new file mode 100644 index 0000000..d0c8f24 Binary files /dev/null and b/gui/images/btns/send.png differ diff --git a/gui/images/btns/tokens.png b/gui/images/btns/tokens.png new file mode 100644 index 0000000..91e858b Binary files /dev/null and b/gui/images/btns/tokens.png differ diff --git a/gui/images/btns/wc.png b/gui/images/btns/wc.png new file mode 100644 index 0000000..8cd8a3a Binary files /dev/null and b/gui/images/btns/wc.png differ diff --git a/gui/images/good.png b/gui/images/good.png new file mode 100644 index 0000000..90bc02d Binary files /dev/null and b/gui/images/good.png differ diff --git a/gui/images/icons/arb.png b/gui/images/icons/arb.png new file mode 100644 index 0000000..284e789 Binary files /dev/null and b/gui/images/icons/arb.png differ diff --git a/gui/images/icons/avax.png b/gui/images/icons/avax.png new file mode 100644 index 0000000..99dc6ff Binary files /dev/null and b/gui/images/icons/avax.png differ diff --git a/gui/images/icons/bsc.png b/gui/images/icons/bsc.png new file mode 100644 index 0000000..89caff4 Binary files /dev/null and b/gui/images/icons/bsc.png differ diff --git a/gui/images/icons/btc.png b/gui/images/icons/btc.png new file mode 100644 index 0000000..335d6b7 Binary files /dev/null and b/gui/images/icons/btc.png differ diff --git a/gui/images/icons/celo.png b/gui/images/icons/celo.png new file mode 100644 index 0000000..4668398 Binary files /dev/null and b/gui/images/icons/celo.png differ diff --git a/gui/images/icons/doge.png b/gui/images/icons/doge.png new file mode 100644 index 0000000..99a7272 Binary files /dev/null and b/gui/images/icons/doge.png differ diff --git a/gui/images/icons/eos.png b/gui/images/icons/eos.png new file mode 100644 index 0000000..a60252a Binary files /dev/null and b/gui/images/icons/eos.png differ diff --git a/gui/images/icons/eth.png b/gui/images/icons/eth.png new file mode 100644 index 0000000..f2f5292 Binary files /dev/null and b/gui/images/icons/eth.png differ diff --git a/gui/images/icons/ftm.png b/gui/images/icons/ftm.png new file mode 100644 index 0000000..651333a Binary files /dev/null and b/gui/images/icons/ftm.png differ diff --git a/gui/images/icons/glmr.png b/gui/images/icons/glmr.png new file mode 100644 index 0000000..48dd6c1 Binary files /dev/null and b/gui/images/icons/glmr.png differ diff --git a/gui/images/icons/ltc.png b/gui/images/icons/ltc.png new file mode 100644 index 0000000..43b784e Binary files /dev/null and b/gui/images/icons/ltc.png differ diff --git a/gui/images/icons/matic.png b/gui/images/icons/matic.png new file mode 100644 index 0000000..6d3c0e9 Binary files /dev/null and b/gui/images/icons/matic.png differ diff --git a/gui/images/icons/metis.png b/gui/images/icons/metis.png new file mode 100644 index 0000000..7193b52 Binary files /dev/null and b/gui/images/icons/metis.png differ diff --git a/gui/images/icons/op.png b/gui/images/icons/op.png new file mode 100644 index 0000000..ee9d1e6 Binary files /dev/null and b/gui/images/icons/op.png differ diff --git a/gui/images/icons/sol.png b/gui/images/icons/sol.png new file mode 100644 index 0000000..baa6abb Binary files /dev/null and b/gui/images/icons/sol.png differ diff --git a/gui/images/icons/xtz.png b/gui/images/icons/xtz.png new file mode 100644 index 0000000..a3d1ea9 Binary files /dev/null and b/gui/images/icons/xtz.png differ diff --git a/gui/images/logo.png b/gui/images/logo.png new file mode 100644 index 0000000..7a691e1 Binary files /dev/null and b/gui/images/logo.png differ diff --git a/gui/infodialog.fbp b/gui/infodialog.fbp index 0f693fe..3b69f5c 100644 --- a/gui/infodialog.fbp +++ b/gui/infodialog.fbp @@ -53,6 +53,29 @@ + + + 0 + wxAUI_MGR_DEFAULT + wxSYS_COLOUR_WINDOW + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + InfoPanel + + -1,-1 + ; ; forward_declare + + + + wxTAB_TRAVERSAL bSizer1 @@ -72,21 +95,21 @@ - wxSYS_COLOUR_WINDOW + 1 0 1 - 1 + 0 0 Dock 0 Left 1 - + wxSYS_COLOUR_WINDOWTEXT 1 - + ,90,90,10,70,0 0 0 wxID_ANY @@ -146,7 +169,7 @@ - + Load From Resource; 1 0 @@ -164,11 +187,11 @@ 1 - + ,90,92,-1,70,0 0 0 wxID_ANY - Copy Text + OK 0 @@ -178,7 +201,7 @@ 0 1 - m_button_cpy + m_button_ok 1 @@ -201,7 +224,6 @@ - copy_text_dialog @@ -251,7 +273,7 @@ 0 0 wxID_ANY - OK + Copy text 0 @@ -261,7 +283,7 @@ 0 1 - m_button_ok + m_button_cpy 1 @@ -284,7 +306,6 @@ - close_info diff --git a/gui/infodialog.py b/gui/infodialog.py index 7a8a86d..297933b 100644 --- a/gui/infodialog.py +++ b/gui/infodialog.py @@ -21,23 +21,46 @@ def __init__( self, parent ): self.SetSizeHints( wx.Size( 500,250 ), wx.DefaultSize ) + + self.Centre( wx.BOTH ) + + def __del__( self ): + pass + + +########################################################################### +## Class InfoPanel +########################################################################### + +class InfoPanel ( wx.Panel ): + + def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): + wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + + self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + bSizer1 = wx.BoxSizer( wx.VERTICAL ) self.m_textCtrl = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_WORDWRAP|wx.BORDER_NONE ) - self.m_textCtrl.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + self.m_textCtrl.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_textCtrl.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT ) ) bSizer1.Add( self.m_textCtrl, 1, wx.ALL|wx.EXPAND, 24 ) bSizer2 = wx.BoxSizer( wx.HORIZONTAL ) - self.m_button_cpy = wx.Button( self, wx.ID_ANY, u"Copy Text", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer2.Add( self.m_button_cpy, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + self.m_button_ok = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 ) + + self.m_button_ok.SetBitmap( wx.NullBitmap ) + self.m_button_ok.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, wx.EmptyString ) ) + + bSizer2.Add( self.m_button_ok, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) bSizer2.Add( ( 20, 0), 1, wx.EXPAND, 5 ) - self.m_button_ok = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer2.Add( self.m_button_ok, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + self.m_button_cpy = wx.Button( self, wx.ID_ANY, u"Copy text", wx.DefaultPosition, wx.DefaultSize, 0 ) + bSizer2.Add( self.m_button_cpy, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) bSizer1.Add( bSizer2, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) @@ -48,22 +71,9 @@ def __init__( self, parent ): self.SetSizer( bSizer1 ) self.Layout() - - self.Centre( wx.BOTH ) - - # Connect Events - self.m_button_cpy.Bind( wx.EVT_BUTTON, self.copy_text_dialog ) - self.m_button_ok.Bind( wx.EVT_BUTTON, self.close_info ) + bSizer1.Fit( self ) def __del__( self ): pass - # Virtual event handlers, overide them in your derived class - def copy_text_dialog( self, event ): - event.Skip() - - def close_info( self, event ): - event.Skip() - - diff --git a/gui/maingui.py b/gui/maingui.py new file mode 100644 index 0000000..f3ba801 --- /dev/null +++ b/gui/maingui.py @@ -0,0 +1,892 @@ +# -*- coding: utf-8 -*- + +########################################################################### +## Python code generated with wxFormBuilder (version Oct 26 2018) +## http://www.wxformbuilder.org/ +## +## PLEASE DO *NOT* EDIT THIS FILE! +########################################################################### + +import wx +import wx.xrc + +########################################################################### +## Class UniblowFrame +########################################################################### + +class UniblowFrame ( wx.Frame ): + + def __init__( self, parent ): + wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,450 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.TAB_TRAVERSAL ) + + self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) + + + self.Centre( wx.BOTH ) + + def __del__( self ): + pass + + +########################################################################### +## Class WalletPanel +########################################################################### + +class WalletPanel ( wx.Panel ): + + def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): + wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + + self.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + bSizer1 = wx.BoxSizer( wx.HORIZONTAL ) + + sbSizer5 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"chains" ), wx.VERTICAL ) + + self.scrolled_coins = wx.ScrolledWindow( sbSizer5.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.Size( 85,378 ), wx.BORDER_NONE|wx.VSCROLL ) + self.scrolled_coins.SetScrollRate( 5, 5 ) + self.scrolled_coins.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.scrolled_coins.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + sbSizer5.Add( self.scrolled_coins, 0, 0, 5 ) + + + bSizer1.Add( sbSizer5, 0, wx.EXPAND, 5 ) + + self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + bSizer6 = wx.BoxSizer( wx.VERTICAL ) + + bSizer4 = wx.BoxSizer( wx.HORIZONTAL ) + + bSizer29 = wx.BoxSizer( wx.VERTICAL ) + + bSizer28 = wx.BoxSizer( wx.HORIZONTAL ) + + self.img_arrsel = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + bSizer28.Add( self.img_arrsel, 0, wx.ALIGN_BOTTOM|wx.BOTTOM|wx.RIGHT|wx.LEFT, 20 ) + + + bSizer28.Add( ( 0, 0), 0, wx.RIGHT, 24 ) + + self.balance_info = wx.StaticText( self.m_panel1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( -1,-1 ), 0|wx.FULL_REPAINT_ON_RESIZE ) + self.balance_info.Wrap( -1 ) + + self.balance_info.SetFont( wx.Font( 16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.balance_info.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer28.Add( self.balance_info, 0, wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_BOTTOM, 8 ) + + + bSizer28.Add( ( 0, 0), 0, wx.LEFT, 2 ) + + self.balance_small = wx.StaticText( self.m_panel1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.balance_small.Wrap( -1 ) + + self.balance_small.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.balance_small.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer28.Add( self.balance_small, 0, wx.TOP|wx.BOTTOM|wx.RIGHT|wx.ALIGN_BOTTOM, 10 ) + + self.balance_unit = wx.StaticText( self.m_panel1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.balance_unit.Wrap( -1 ) + + self.balance_unit.SetFont( wx.Font( 16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.balance_unit.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer28.Add( self.balance_unit, 0, wx.ALIGN_BOTTOM|wx.TOP|wx.BOTTOM|wx.RIGHT, 8 ) + + self.fiat_panel = wx.Panel( self.m_panel1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_SUNKEN|wx.TAB_TRAVERSAL ) + self.fiat_panel.SetBackgroundColour( wx.Colour( 100, 116, 139 ) ) + self.fiat_panel.Hide() + + bSizer31 = wx.BoxSizer( wx.HORIZONTAL ) + + + bSizer31.Add( ( 0, 0), 0, wx.LEFT, 8 ) + + self.txt_fiat = wx.StaticText( self.fiat_panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.txt_fiat.Wrap( -1 ) + + self.txt_fiat.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.txt_fiat.SetForegroundColour( wx.Colour( 248, 248, 248 ) ) + + bSizer31.Add( self.txt_fiat, 0, wx.ALL, 3 ) + + + bSizer31.Add( ( 0, 0), 0, wx.LEFT, 8 ) + + + self.fiat_panel.SetSizer( bSizer31 ) + self.fiat_panel.Layout() + bSizer31.Fit( self.fiat_panel ) + bSizer28.Add( self.fiat_panel, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 18 ) + + + bSizer29.Add( bSizer28, 0, wx.TOP, 12 ) + + + bSizer4.Add( bSizer29, 0, wx.ALIGN_CENTER_VERTICAL, 5 ) + + + bSizer4.Add( ( 0, 0), 1, 0, 5 ) + + bSizer5 = wx.BoxSizer( wx.VERTICAL ) + + self.m_but_changedevice = wx.BitmapButton( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + bSizer5.Add( self.m_but_changedevice, 0, wx.BOTTOM|wx.LEFT, 12 ) + + self.m_staticText26 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"Network", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText26.Wrap( -1 ) + + self.m_staticText26.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer5.Add( self.m_staticText26, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP|wx.BOTTOM|wx.RIGHT, 5 ) + + network_choiceChoices = [] + self.network_choice = wx.Choice( self.m_panel1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, network_choiceChoices, 0 ) + self.network_choice.SetSelection( 0 ) + self.network_choice.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.network_choice.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + self.network_choice.SetMinSize( wx.Size( 120,-1 ) ) + + bSizer5.Add( self.network_choice, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.RIGHT, 12 ) + + + bSizer4.Add( bSizer5, 0, 0, 24 ) + + + bSizer6.Add( bSizer4, 0, wx.EXPAND, 16 ) + + optevt_sizer = wx.BoxSizer( wx.HORIZONTAL ) + + + optevt_sizer.Add( ( 0, 0), 1, wx.EXPAND|wx.LEFT, 45 ) + + self.but_evt1 = wx.BitmapButton( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + self.but_evt1.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + optevt_sizer.Add( self.but_evt1, 0, wx.ALIGN_CENTER_VERTICAL, 12 ) + + self.but_evt2 = wx.BitmapButton( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + self.but_evt2.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + optevt_sizer.Add( self.but_evt2, 0, wx.RIGHT|wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 36 ) + + + bSizer6.Add( optevt_sizer, 0, wx.BOTTOM, 16 ) + + self.m_panel4 = wx.Panel( self.m_panel1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + self.m_panel4.SetBackgroundColour( wx.Colour( 240, 240, 240 ) ) + + bSizer32 = wx.BoxSizer( wx.VERTICAL ) + + + bSizer32.Add( ( 0, 0), 0, wx.TOP, 16 ) + + self.m_panel5 = wx.Panel( self.m_panel4, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + self.m_panel5.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + + bSizer36 = wx.BoxSizer( wx.HORIZONTAL ) + + self.qr_button = wx.BitmapButton( self.m_panel5, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + bSizer36.Add( self.qr_button, 0, wx.TOP|wx.BOTTOM|wx.LEFT, 12 ) + + self.account_addr = wx.StaticText( self.m_panel5, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( -1,-1 ), wx.ST_ELLIPSIZE_MIDDLE ) + self.account_addr.Wrap( -1 ) + + self.account_addr.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.account_addr.SetForegroundColour( wx.Colour( 113, 110, 234 ) ) + self.account_addr.SetMaxSize( wx.Size( 525,-1 ) ) + + bSizer36.Add( self.account_addr, 0, wx.RIGHT|wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 16 ) + + self.copy_button = wx.BitmapButton( self.m_panel5, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + bSizer36.Add( self.copy_button, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 12 ) + + + self.m_panel5.SetSizer( bSizer36 ) + self.m_panel5.Layout() + bSizer36.Fit( self.m_panel5 ) + bSizer32.Add( self.m_panel5, 0, wx.LEFT, 36 ) + + bSizer34 = wx.BoxSizer( wx.HORIZONTAL ) + + self.hist_button = wx.BitmapButton( self.m_panel4, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + bSizer34.Add( self.hist_button, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 36 ) + + self.btn_chkaddr = wx.BitmapButton( self.m_panel4, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.Size( -1,-1 ), wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + self.btn_chkaddr.Hide() + + bSizer34.Add( self.btn_chkaddr, 0, wx.LEFT, 12 ) + + + bSizer34.Add( ( 0, 0), 1, wx.RIGHT|wx.LEFT|wx.EXPAND, 8 ) + + bSizer37 = wx.BoxSizer( wx.HORIZONTAL ) + + self.wallopt_label = wx.StaticText( self.m_panel4, wx.ID_ANY, u"Wallet type", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.wallopt_label.Wrap( -1 ) + + self.wallopt_label.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.wallopt_label.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer37.Add( self.wallopt_label, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT, 8 ) + + wallopt_choiceChoices = [] + self.wallopt_choice = wx.Choice( self.m_panel4, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wallopt_choiceChoices, 0 ) + self.wallopt_choice.SetSelection( 0 ) + self.wallopt_choice.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.wallopt_choice.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + + bSizer37.Add( self.wallopt_choice, 0, wx.ALIGN_CENTER_VERTICAL, 24 ) + + + bSizer34.Add( bSizer37, 0, wx.RIGHT, 5 ) + + + bSizer34.Add( ( 0, 0), 1, wx.EXPAND, 32 ) + + + bSizer32.Add( bSizer34, 0, wx.TOP|wx.BOTTOM|wx.EXPAND, 16 ) + + + self.m_panel4.SetSizer( bSizer32 ) + self.m_panel4.Layout() + bSizer32.Fit( self.m_panel4 ) + bSizer6.Add( self.m_panel4, 0, wx.EXPAND|wx.BOTTOM|wx.RIGHT|wx.LEFT, 6 ) + + + bSizer6.Add( ( 0, 0), 0, wx.TOP, 12 ) + + self.btn_send = wx.BitmapButton( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + bSizer6.Add( self.btn_send, 0, wx.RIGHT|wx.ALIGN_RIGHT, 72 ) + + self.alt_text = wx.StaticText( self.m_panel1, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.alt_text.Wrap( 120 ) + + self.alt_text.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + + bSizer6.Add( self.alt_text, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + + self.m_panel1.SetSizer( bSizer6 ) + self.m_panel1.Layout() + bSizer6.Fit( self.m_panel1 ) + bSizer1.Add( self.m_panel1, 1, wx.EXPAND |wx.ALL, 5 ) + + + self.SetSizer( bSizer1 ) + self.Layout() + bSizer1.Fit( self ) + + def __del__( self ): + pass + + +########################################################################### +## Class DevicesPanel +########################################################################### + +class DevicesPanel ( wx.Panel ): + + def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): + wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + + self.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + bSizer3 = wx.BoxSizer( wx.VERTICAL ) + + self.bmp_logo = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_NONE ) + bSizer3.Add( self.bmp_logo, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP|wx.BOTTOM, 32 ) + + self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"Select Device", wx.DefaultPosition, wx.DefaultSize, 0|wx.FULL_REPAINT_ON_RESIZE ) + self.m_staticText1.Wrap( -1 ) + + self.m_staticText1.SetFont( wx.Font( 16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_staticText1.SetForegroundColour( wx.Colour( 113, 110, 234 ) ) + + bSizer3.Add( self.m_staticText1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.BOTTOM|wx.RIGHT|wx.LEFT, 18 ) + + fgSizer1 = wx.FlexGridSizer( 0, 2, 18, 36 ) + fgSizer1.SetFlexibleDirection( wx.BOTH ) + fgSizer1.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED ) + + self.d_btn01 = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + fgSizer1.Add( self.d_btn01, 0, wx.ALL, 5 ) + + self.d_btn02 = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + fgSizer1.Add( self.d_btn02, 0, wx.ALL, 5 ) + + self.d_btn03 = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + fgSizer1.Add( self.d_btn03, 0, wx.ALL, 5 ) + + self.d_btn04 = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + fgSizer1.Add( self.d_btn04, 0, wx.ALL, 5 ) + + self.d_btn05 = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + fgSizer1.Add( self.d_btn05, 0, wx.ALL, 5 ) + + + bSizer3.Add( fgSizer1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 8 ) + + + self.SetSizer( bSizer3 ) + self.Layout() + bSizer3.Fit( self ) + + def __del__( self ): + pass + + +########################################################################### +## Class HDDialog +########################################################################### + +class HDDialog ( wx.Dialog ): + + def __init__( self, parent ): + wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Wallet setup", pos = wx.DefaultPosition, size = wx.Size( 600,480 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.DEFAULT_DIALOG_STYLE|wx.STAY_ON_TOP|wx.SYSTEM_MENU ) + + self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) + + + self.Centre( wx.BOTH ) + + def __del__( self ): + pass + + +########################################################################### +## Class HDPanel +########################################################################### + +class HDPanel ( wx.Panel ): + + def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): + wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + + self.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + bSizer11 = wx.BoxSizer( wx.VERTICAL ) + + bSizer15 = wx.BoxSizer( wx.HORIZONTAL ) + + self.title_text = wx.StaticText( self, wx.ID_ANY, u"Wallet mnemonic setup", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.title_text.Wrap( -1 ) + + self.title_text.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.title_text.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer15.Add( self.title_text, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 32 ) + + + bSizer15.Add( ( 24, 0), 0, 0, 15 ) + + self.m_textwl = wx.StaticText( self, wx.ID_ANY, u"Words in list", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_textwl.Wrap( -1 ) + + self.m_textwl.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer15.Add( self.m_textwl, 0, wx.ALIGN_BOTTOM|wx.ALL, 5 ) + + self.m_bitmapHDwl = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_NONE ) + bSizer15.Add( self.m_bitmapHDwl, 0, wx.BOTTOM|wx.ALIGN_BOTTOM, 6 ) + + self.m_textcs = wx.StaticText( self, wx.ID_ANY, u"Checksum", wx.DefaultPosition, wx.DefaultSize, wx.ST_NO_AUTORESIZE ) + self.m_textcs.Wrap( -1 ) + + self.m_textcs.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer15.Add( self.m_textcs, 0, wx.ALL|wx.ALIGN_BOTTOM, 5 ) + + self.m_bitmapHDcs = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_NONE ) + bSizer15.Add( self.m_bitmapHDcs, 0, wx.ALIGN_BOTTOM|wx.BOTTOM, 6 ) + + + bSizer15.Add( ( 0, 0), 1, wx.EXPAND|wx.RIGHT, 16 ) + + + bSizer11.Add( bSizer15, 1, wx.EXPAND, 5 ) + + self.m_textCtrl_mnemo = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE ) + self.m_textCtrl_mnemo.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_textCtrl_mnemo.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT ) ) + self.m_textCtrl_mnemo.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + + bSizer11.Add( self.m_textCtrl_mnemo, 1, wx.LEFT|wx.RIGHT|wx.EXPAND, 16 ) + + bSizer13 = wx.BoxSizer( wx.HORIZONTAL ) + + + bSizer13.Add( ( 0, 0), 0, wx.RIGHT, 18 ) + + self.m_bwptxt = wx.StaticText( self, wx.ID_ANY, u"Deriv. password (opt.)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_bwptxt.Wrap( -1 ) + + self.m_bwptxt.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer13.Add( self.m_bwptxt, 0, wx.ALIGN_CENTER_VERTICAL, 4 ) + + self.m_textCtrl_pwd = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 170,-1 ), 0 ) + self.m_textCtrl_pwd.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_textCtrl_pwd.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + + bSizer13.Add( self.m_textCtrl_pwd, 0, wx.ALL, 5 ) + + self.m_checkBox_secboost = wx.CheckBox( self, wx.ID_ANY, u"SecuBoost", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_checkBox_secboost.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_checkBox_secboost.SetToolTip( u"Extra security boost for mnemonic.\nNot compatible with BIP39.\nRequires >1GB RAM free" ) + + bSizer13.Add( self.m_checkBox_secboost, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 22 ) + + + bSizer11.Add( bSizer13, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + bSizer14 = wx.BoxSizer( wx.HORIZONTAL ) + + self.m_accounttxt = wx.StaticText( self, wx.ID_ANY, u"Account #", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_accounttxt.Wrap( -1 ) + + self.m_accounttxt.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer14.Add( self.m_accounttxt, 0, wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_spinCtrl_account = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 75,-1 ), wx.SP_ARROW_KEYS, 0, 2147483647, 0 ) + self.m_spinCtrl_account.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_spinCtrl_account.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + + bSizer14.Add( self.m_spinCtrl_account, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_indextxt = wx.StaticText( self, wx.ID_ANY, u"index", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_indextxt.Wrap( -1 ) + + self.m_indextxt.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer14.Add( self.m_indextxt, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 24 ) + + self.m_spinCtrl_index = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 75,-1 ), wx.SP_ARROW_KEYS, 0, 2147483647, 0 ) + self.m_spinCtrl_index.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_spinCtrl_index.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + + bSizer14.Add( self.m_spinCtrl_index, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + + bSizer11.Add( bSizer14, 1, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 16 ) + + self.m_altderiv = wx.CheckBox( self, wx.ID_ANY, u"Alt. derivation path (Not BIP44, for ETH / EVM)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_altderiv.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer11.Add( self.m_altderiv, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + + bSizer11.Add( ( 0, 0), 0, wx.TOP, 20 ) + + self.m_usertxt = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_usertxt.Wrap( -1 ) + + self.m_usertxt.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_usertxt.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer11.Add( self.m_usertxt, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.RIGHT, 24 ) + + bSizer12 = wx.BoxSizer( wx.HORIZONTAL ) + + self.m_butOK = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + + self.m_butOK.SetBitmap( wx.NullBitmap ) + bSizer12.Add( self.m_butOK, 0, wx.ALL, 5 ) + + + bSizer12.Add( ( 0, 0), 1, wx.RIGHT, 25 ) + + self.m_butCancel = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + + self.m_butCancel.SetBitmap( wx.NullBitmap ) + bSizer12.Add( self.m_butCancel, 0, wx.ALL, 5 ) + + + bSizer11.Add( bSizer12, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 18 ) + + + self.SetSizer( bSizer11 ) + self.Layout() + bSizer11.Fit( self ) + + # Connect Events + self.m_textCtrl_mnemo.Bind( wx.EVT_TEXT, self.hdmnemo_changed ) + self.m_butOK.Bind( wx.EVT_BUTTON, self.hd_ok ) + self.m_butCancel.Bind( wx.EVT_BUTTON, self.hd_cancel ) + + def __del__( self ): + pass + + + # Virtual event handlers, overide them in your derived class + def hdmnemo_changed( self, event ): + event.Skip() + + def hd_ok( self, event ): + event.Skip() + + def hd_cancel( self, event ): + event.Skip() + + +########################################################################### +## Class SendDialog +########################################################################### + +class SendDialog ( wx.Dialog ): + + def __init__( self, parent ): + wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Sending", pos = wx.DefaultPosition, size = wx.Size( 520,420 ), style = wx.DEFAULT_DIALOG_STYLE ) + + self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) + + + self.Centre( wx.BOTH ) + + def __del__( self ): + pass + + +########################################################################### +## Class SendPanel +########################################################################### + +class SendPanel ( wx.Panel ): + + def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): + wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + + self.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + bSizer13 = wx.BoxSizer( wx.HORIZONTAL ) + + + bSizer13.Add( ( 0, 0), 0, wx.RIGHT, 16 ) + + bSizer23 = wx.BoxSizer( wx.VERTICAL ) + + + bSizer23.Add( ( 0, 0), 0, wx.BOTTOM, 24 ) + + bSizer201 = wx.BoxSizer( wx.HORIZONTAL ) + + self.m_staticText7 = wx.StaticText( self, wx.ID_ANY, u"Destination Address", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText7.Wrap( -1 ) + + self.m_staticText7.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer201.Add( self.m_staticText7, 0, wx.TOP|wx.LEFT, 5 ) + + + bSizer201.Add( ( 0, 0), 0, wx.LEFT, 20 ) + + self.paste_btn = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + bSizer201.Add( self.paste_btn, 0, wx.BOTTOM, 8 ) + + + bSizer23.Add( bSizer201, 0, 0, 5 ) + + bSizer14 = wx.BoxSizer( wx.HORIZONTAL ) + + self.text_dest = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.text_dest.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.text_dest.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + + bSizer14.Add( self.text_dest, 1, wx.RIGHT|wx.LEFT, 5 ) + + + bSizer14.Add( ( 0, 0), 0, wx.RIGHT, 6 ) + + self.bmp_chk = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_NONE ) + bSizer14.Add( self.bmp_chk, 0, wx.ALIGN_CENTER_VERTICAL, 5 ) + + + bSizer23.Add( bSizer14, 0, wx.EXPAND, 5 ) + + + bSizer23.Add( ( 0, 0), 0, wx.TOP, 16 ) + + bSizer15 = wx.BoxSizer( wx.HORIZONTAL ) + + sbSizer3 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Amount" ), wx.VERTICAL ) + + sbSizer3.SetMinSize( wx.Size( -1,175 ) ) + bSizer18 = wx.BoxSizer( wx.VERTICAL ) + + self.m_staticTextAvailLabel = wx.StaticText( sbSizer3.GetStaticBox(), wx.ID_ANY, u"Available : ", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticTextAvailLabel.Wrap( -1 ) + + self.m_staticTextAvailLabel.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer18.Add( self.m_staticTextAvailLabel, 0, wx.RIGHT|wx.LEFT|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.text_avail = wx.StaticText( sbSizer3.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( -1,-1 ), 0 ) + self.text_avail.Wrap( -1 ) + + bSizer18.Add( self.text_avail, 0, wx.BOTTOM|wx.RIGHT|wx.LEFT, 5 ) + + + sbSizer3.Add( bSizer18, 0, wx.LEFT, 8 ) + + bSizer20 = wx.BoxSizer( wx.HORIZONTAL ) + + self.text_amount = wx.TextCtrl( sbSizer3.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.text_amount.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.text_amount.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + self.text_amount.SetMinSize( wx.Size( 150,-1 ) ) + + bSizer20.Add( self.text_amount, 0, wx.BOTTOM|wx.RIGHT|wx.LEFT, 8 ) + + self.text_coin = wx.StaticText( sbSizer3.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.text_coin.Wrap( -1 ) + + bSizer20.Add( self.text_coin, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5 ) + + + sbSizer3.Add( bSizer20, 0, 0, 5 ) + + self.check_sendall = wx.CheckBox( sbSizer3.GetStaticBox(), wx.ID_ANY, u"Send all", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.check_sendall.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + sbSizer3.Add( self.check_sendall, 0, wx.LEFT, 32 ) + + + sbSizer3.Add( ( 0, 0), 0, wx.TOP, 8 ) + + bSizer191 = wx.BoxSizer( wx.HORIZONTAL ) + + self.fiat_label = wx.StaticText( sbSizer3.GetStaticBox(), wx.ID_ANY, u"value ~", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.fiat_label.Wrap( -1 ) + + self.fiat_label.SetFont( wx.Font( 9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.fiat_label.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer191.Add( self.fiat_label, 0, wx.ALL, 5 ) + + self.fiat_value = wx.StaticText( sbSizer3.GetStaticBox(), wx.ID_ANY, u"$ 0", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.fiat_value.Wrap( -1 ) + + self.fiat_value.SetFont( wx.Font( 9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.fiat_value.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer191.Add( self.fiat_value, 0, wx.ALL, 5 ) + + + sbSizer3.Add( bSizer191, 0, 0, 5 ) + + + bSizer15.Add( sbSizer3, 0, 0, 5 ) + + sbSizer2 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Fees" ), wx.VERTICAL ) + + sbSizer2.SetMinSize( wx.Size( -1,175 ) ) + + sbSizer2.Add( ( 0, 0), 0, wx.TOP, 24 ) + + self.fee_slider = wx.Slider( sbSizer2.GetStaticBox(), wx.ID_ANY, 1, 0, 2, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL ) + sbSizer2.Add( self.fee_slider, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.text_fees = wx.StaticText( sbSizer2.GetStaticBox(), wx.ID_ANY, u"Normal fee", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.text_fees.Wrap( -1 ) + + self.text_fees.SetFont( wx.Font( 9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.text_fees.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + sbSizer2.Add( self.text_fees, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + + bSizer15.Add( sbSizer2, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 24 ) + + + bSizer23.Add( bSizer15, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + bSizer19 = wx.BoxSizer( wx.HORIZONTAL ) + + self.ok_btn = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + + self.ok_btn.SetBitmap( wx.NullBitmap ) + bSizer19.Add( self.ok_btn, 0, wx.ALL, 5 ) + + + bSizer19.Add( ( 0, 0), 0, wx.RIGHT, 32 ) + + self.cancel_btn = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + + self.cancel_btn.SetBitmap( wx.NullBitmap ) + bSizer19.Add( self.cancel_btn, 0, wx.ALL, 5 ) + + + bSizer23.Add( bSizer19, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 24 ) + + + bSizer23.Add( ( 0, 0), 0, wx.TOP, 16 ) + + + bSizer13.Add( bSizer23, 1, wx.EXPAND, 5 ) + + + bSizer13.Add( ( 0, 0), 0, wx.RIGHT, 24 ) + + + self.SetSizer( bSizer13 ) + self.Layout() + bSizer13.Fit( self ) + + def __del__( self ): + pass + + +########################################################################### +## Class OptionDialog +########################################################################### + +class OptionDialog ( wx.Dialog ): + + def __init__( self, parent ): + wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 455,380 ), style = wx.DEFAULT_DIALOG_STYLE ) + + self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) + + + self.Centre( wx.BOTH ) + + def __del__( self ): + pass + + +########################################################################### +## Class OptionPanel +########################################################################### + +class OptionPanel ( wx.Panel ): + + def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 396,400 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): + wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + + self.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + + bSizer18 = wx.BoxSizer( wx.VERTICAL ) + + + bSizer18.Add( ( 0, 0), 1, wx.TOP, 16 ) + + self.preset_text = wx.StaticText( self, wx.ID_ANY, u"Known Preset", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.preset_text.Wrap( -1 ) + + self.preset_text.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.preset_text.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer18.Add( self.preset_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + bSizer31 = wx.BoxSizer( wx.HORIZONTAL ) + + self.search_preset = wx.SearchCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PROCESS_ENTER ) + self.search_preset.ShowSearchButton( True ) + self.search_preset.ShowCancelButton( False ) + self.search_preset.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.search_preset.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + self.search_preset.SetMinSize( wx.Size( 180,-1 ) ) + + bSizer31.Add( self.search_preset, 0, wx.TOP, 5 ) + + + bSizer18.Add( bSizer31, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + known_choiceChoices = [] + self.known_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( 320,-1 ), known_choiceChoices, 0 ) + self.known_choice.SetSelection( 0 ) + self.known_choice.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.known_choice.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + + bSizer18.Add( self.known_choice, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.m_staticTextor = wx.StaticText( self, wx.ID_ANY, u"OR", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticTextor.Wrap( -1 ) + + self.m_staticTextor.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, True, wx.EmptyString ) ) + self.m_staticTextor.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer18.Add( self.m_staticTextor, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.custom_text = wx.StaticText( self, wx.ID_ANY, u"other custom", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.custom_text.Wrap( -1 ) + + self.custom_text.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.custom_text.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + + bSizer18.Add( self.custom_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + self.m_but_paste = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + bSizer18.Add( self.m_but_paste, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP|wx.RIGHT|wx.LEFT, 5 ) + + self.new_choice = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 320,-1 ), wx.TE_PROCESS_ENTER ) + self.new_choice.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.new_choice.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.new_choice.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + + bSizer18.Add( self.new_choice, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + bSizer19 = wx.BoxSizer( wx.HORIZONTAL ) + + self.m_but_ok = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + + self.m_but_ok.SetBitmap( wx.NullBitmap ) + bSizer19.Add( self.m_but_ok, 0, wx.BOTTOM|wx.RIGHT|wx.LEFT, 5 ) + + + bSizer19.Add( ( 0, 0), 1, wx.LEFT, 16 ) + + self.m_but_cancel = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|0|wx.BORDER_NONE ) + + self.m_but_cancel.SetBitmap( wx.NullBitmap ) + bSizer19.Add( self.m_but_cancel, 0, wx.BOTTOM|wx.RIGHT|wx.LEFT, 5 ) + + + bSizer18.Add( bSizer19, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 20 ) + + + bSizer18.Add( ( 0, 0), 1, wx.EXPAND, 5 ) + + + self.SetSizer( bSizer18 ) + self.Layout() + + # Connect Events + self.search_preset.Bind( wx.EVT_SEARCHCTRL_CANCEL_BTN, self.onEraseSearch ) + self.search_preset.Bind( wx.EVT_SEARCHCTRL_SEARCH_BTN, self.onSearch ) + self.search_preset.Bind( wx.EVT_TEXT, self.onSearch ) + self.search_preset.Bind( wx.EVT_TEXT_ENTER, self.onSearch ) + self.m_but_paste.Bind( wx.EVT_BUTTON, self.pasteValue ) + self.new_choice.Bind( wx.EVT_TEXT_ENTER, self.valid_custom ) + self.m_but_ok.Bind( wx.EVT_BUTTON, self.okOption ) + self.m_but_cancel.Bind( wx.EVT_BUTTON, self.cancelOption ) + + def __del__( self ): + pass + + + # Virtual event handlers, overide them in your derived class + def onEraseSearch( self, event ): + event.Skip() + + def onSearch( self, event ): + event.Skip() + + + + def pasteValue( self, event ): + event.Skip() + + def valid_custom( self, event ): + event.Skip() + + def okOption( self, event ): + event.Skip() + + def cancelOption( self, event ): + event.Skip() + + diff --git a/gui/qrframe.py b/gui/qrframe.py new file mode 100644 index 0000000..ae3f65d --- /dev/null +++ b/gui/qrframe.py @@ -0,0 +1,83 @@ +from io import BytesIO +import qrcode +import wx + +from gui.utils import icon_file, file_path + + +class QRFrame(wx.Frame): + def __init__(self, parent, coin, address, btn): + + super().__init__( + parent, + id=wx.ID_ANY, + title=f" Receive {coin}", + size=wx.Size(360, 328), + style=wx.FRAME_FLOAT_ON_PARENT | wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, + ) + self.btn = btn + self.SetIcons(wx.IconBundle(icon_file)) + + self.SetSizeHints(wx.DefaultSize, wx.DefaultSize) + self.Centre(wx.BOTH) + qrpanel = wx.Panel( + self, + id=wx.ID_ANY, + size=(-1, -1), + style=wx.TAB_TRAVERSAL, + name=wx.EmptyString, + ) + qrpanel.SetBackgroundColour(wx.Colour(248, 250, 252)) + + imgqr = qrcode.make( + address, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=4, + border=3, + ) + imgbuf = BytesIO() + imgqr.save(imgbuf, "BMP") + imgbuf.seek(0) + wxi = wx.Image(imgbuf, type=wx.BITMAP_TYPE_BMP).ConvertToBitmap() + + siz1 = wx.BoxSizer(wx.VERTICAL) + qrpanel.bmpqr = wx.StaticBitmap( + qrpanel, wx.ID_ANY, wxi, wx.DefaultPosition, wx.DefaultSize, 0 + ) + siz1.Add(qrpanel.bmpqr, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 32) + qrpanel.stxt = wx.StaticText( + qrpanel, + wx.ID_ANY, + f"Scan to send {coin} to this wallet.", + wx.DefaultPosition, + wx.DefaultSize, + 0, + ) + qrpanel.stxt.Wrap(-1) + qrpanel.stxt.SetForegroundColour(wx.Colour(0, 0, 0)) + siz1.Add(qrpanel.stxt, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5) + + qrpanel.close_btn = wx.BitmapButton( + qrpanel, + wx.ID_ANY, + wx.NullBitmap, + wx.DefaultPosition, + wx.DefaultSize, + wx.BU_AUTODRAW | 0 | wx.BORDER_NONE, + ) + qrpanel.close_btn.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/close.png"), wx.BITMAP_TYPE_PNG) + ) + + siz1.Add(qrpanel.close_btn, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 16) + qrpanel.close_btn.Bind(wx.EVT_BUTTON, self.closing) + self.Bind(wx.EVT_CLOSE, self.closing) + qrpanel.close_btn.SetCursor(wx.Cursor(wx.CURSOR_HAND)) + qrpanel.SetSizer(siz1) + qrpanel.Layout() + self.Show() + + def closing(self, event): + self.btn.Enable() + event.Skip() + self.Destroy() diff --git a/gui/send.png b/gui/send.png deleted file mode 100644 index 1538cc8..0000000 Binary files a/gui/send.png and /dev/null differ diff --git a/gui/send_frame.py b/gui/send_frame.py new file mode 100644 index 0000000..39f6e3e --- /dev/null +++ b/gui/send_frame.py @@ -0,0 +1,115 @@ +import wx + +from sys import platform + +from gui.utils import file_path +from gui.maingui import SendDialog, SendPanel + + +FEES_PRORITY_TEXT = [ + "Economic fee", + "Normal fee", + "Faster fee", +] + + +class SendModal(SendDialog): + def __init__(self, parent, coin, check, callback): + bal_txt = parent.balance_info.GetLabel() + bal_txt += parent.balance_small.GetLabel() + super().__init__(parent) + self.panel = SendPanel(self) + self.panel.text_coin.SetLabel(coin) + self.check_addr_method = check + self.cb = callback + handcurs = wx.Cursor(wx.CURSOR_HAND) + self.GOOD_BMP = wx.Bitmap(file_path("gui/images/good.png")) + self.BAD_BMP = wx.Bitmap(file_path("gui/images/bad.png")) + self.panel.fiat_label.Hide() + self.panel.fiat_value.Hide() + self.panel.text_avail.SetLabel(bal_txt) + self.Bind(wx.EVT_CLOSE, self.close) + self.panel.text_dest.Bind(wx.EVT_TEXT, self.check_addr) + self.panel.text_amount.Bind(wx.EVT_TEXT, self.compute_value) + self.panel.check_sendall.Bind(wx.EVT_CHECKBOX, self.check_all) + self.panel.cancel_btn.SetCursor(handcurs) + self.panel.ok_btn.SetCursor(handcurs) + self.panel.paste_btn.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/paste.png"), wx.BITMAP_TYPE_PNG) + ) + self.panel.ok_btn.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/ok.png"), wx.BITMAP_TYPE_PNG) + ) + self.panel.cancel_btn.SetBitmap( + wx.Bitmap(file_path("gui/images/btns/cancel.png"), wx.BITMAP_TYPE_PNG) + ) + self.panel.paste_btn.SetCursor(handcurs) + self.panel.fee_slider.Bind(wx.EVT_SCROLL, self.fee_changed) + self.panel.cancel_btn.Bind(wx.EVT_BUTTON, self.click_cancel) + self.panel.ok_btn.Bind(wx.EVT_BUTTON, self.click_ok) + self.panel.paste_btn.Bind(wx.EVT_BUTTON, self.paste_addr) + self.panel.bmp_chk.SetBitmap(self.BAD_BMP) + if platform.startswith("darwin"): + self.panel.fiat_label.SetFont(wx.Font(wx.FontInfo(14))) + self.panel.fiat_value.SetFont(wx.Font(wx.FontInfo(14))) + self.panel.text_fees.SetFont(wx.Font(wx.FontInfo(14))) + + def close(self, evt): + self.cb("CLOSE", "", "0") + + def check_all(self, evt): + if evt.IsChecked(): + self.panel.text_amount.SetValue("ALL") + self.panel.text_amount.Disable() + else: + self.panel.text_amount.SetValue("") + self.panel.text_amount.Enable() + + def fee_changed(self, nfeesel): + self.panel.text_fees.SetLabel(FEES_PRORITY_TEXT[nfeesel.GetSelection()]) + + def paste_addr(self, evt): + evt.Skip() + text_data = wx.TextDataObject() + if wx.TheClipboard.Open(): + success = wx.TheClipboard.GetData(text_data) + wx.TheClipboard.Close() + if success: + self.panel.text_dest.SetValue(text_data.GetText()) + + def check_addr(self, evt): + if self.check_addr_method(evt.GetString()): + self.panel.bmp_chk.SetBitmap(self.GOOD_BMP) + else: + self.panel.bmp_chk.SetBitmap(self.BAD_BMP) + + def compute_value(self, evt): + # Update total balance + bal_txt = self.GetParent().balance_info.GetLabel() + bal_txt += self.GetParent().balance_small.GetLabel() + self.panel.text_avail.SetLabel(bal_txt) + app_panel = self.GetParent() + if hasattr(app_panel, "fiat_price"): + try: + amnt_str = evt.GetString() + if amnt_str == "ALL": + amnt = float(bal_txt) + else: + amnt = float(evt.GetString()) + rate = self.GetParent().fiat_price + self.panel.fiat_label.Show() + self.panel.fiat_value.Show() + self.panel.fiat_value.SetLabel(f"$ {amnt * rate:.2f}") + self.panel.Layout() + except ValueError: + self.panel.fiat_label.Hide() + self.panel.fiat_value.Hide() + + def click_cancel(self, event): + self.cb("CANCEL", "", "0") + + def click_ok(self, event): + amount = self.panel.text_amount.GetValue() + dest = self.panel.text_dest.GetValue() + fee_level = self.panel.fee_slider.GetValue() + self.cb("OK", dest, amount, fee_level) diff --git a/gui/senddn.png b/gui/senddn.png deleted file mode 100644 index 8ff4a90..0000000 Binary files a/gui/senddn.png and /dev/null differ diff --git a/gui/swgui.py b/gui/swgui.py index 9d4ac1b..341ceb0 100644 --- a/gui/swgui.py +++ b/gui/swgui.py @@ -46,25 +46,23 @@ class MainPanel ( wx.Panel ): def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) + self.SetBackgroundColour( wx.Colour( 248, 250, 252 ) ) + bSizer11 = wx.BoxSizer( wx.VERTICAL ) - bSizer11.Add( ( 0, 0), 0, wx.BOTTOM, 15 ) + bSizer11.Add( ( 0, 0), 0, wx.BOTTOM, 8 ) bSizer31 = wx.BoxSizer( wx.HORIZONTAL ) bSizer31.SetMinSize( wx.Size( -1,40 ) ) - self.m_button_gen = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE ) - - self.m_button_gen.SetBitmap( wx.NullBitmap ) - bSizer31.Add( self.m_button_gen, 0, wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.RIGHT|wx.LEFT, 10 ) - bSizer6 = wx.BoxSizer( wx.VERTICAL ) self.m_staticText9 = wx.StaticText( self, wx.ID_ANY, u"Generation option", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText9.Wrap( -1 ) self.m_staticText9.SetFont( wx.Font( 9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_staticText9.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) bSizer6.Add( self.m_staticText9, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP|wx.RIGHT|wx.LEFT, 5 ) @@ -72,17 +70,23 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_choice_nwords = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice_nwordsChoices, 0 ) self.m_choice_nwords.SetSelection( 0 ) self.m_choice_nwords.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_choice_nwords.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) bSizer6.Add( self.m_choice_nwords, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.RIGHT|wx.LEFT, 10 ) bSizer31.Add( bSizer6, 1, wx.EXPAND, 5 ) + self.m_button_gen = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) + + self.m_button_gen.SetBitmap( wx.NullBitmap ) + bSizer31.Add( self.m_button_gen, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.BOTTOM|wx.LEFT, 10 ) + bSizer11.Add( bSizer31, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) - bSizer11.Add( ( 0, 0), 0, wx.TOP, 8 ) + bSizer11.Add( ( 0, 0), 0, wx.TOP, 12 ) bSizer3 = wx.BoxSizer( wx.HORIZONTAL ) @@ -90,15 +94,18 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_staticText12.Wrap( -1 ) self.m_staticText12.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_staticText12.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) bSizer3.Add( self.m_staticText12, 1, wx.ALIGN_BOTTOM|wx.RIGHT, 40 ) self.m_staticText5 = wx.StaticText( self, wx.ID_ANY, u" Words in list", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText5.Wrap( -1 ) + self.m_staticText5.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + bSizer3.Add( self.m_staticText5, 0, wx.ALL, 5 ) - self.m_bitmap_wl = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_bitmap_wl = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_NONE ) bSizer3.Add( self.m_bitmap_wl, 0, wx.ALIGN_CENTER, 7 ) @@ -107,9 +114,11 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_staticText6 = wx.StaticText( self, wx.ID_ANY, u" Checksum", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText6.Wrap( -1 ) + self.m_staticText6.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + bSizer3.Add( self.m_staticText6, 0, wx.ALL, 5 ) - self.m_bitmap_cs = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_bitmap_cs = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BORDER_NONE ) bSizer3.Add( self.m_bitmap_cs, 0, wx.ALIGN_CENTER_VERTICAL, 7 ) @@ -117,6 +126,8 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_textCtrl_mnemo = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( -1,100 ), wx.TE_MULTILINE|wx.TE_PROCESS_ENTER|wx.BORDER_SIMPLE ) self.m_textCtrl_mnemo.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_textCtrl_mnemo.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOWTEXT ) ) + self.m_textCtrl_mnemo.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) bSizer11.Add( self.m_textCtrl_mnemo, 0, wx.ALL|wx.EXPAND, 5 ) @@ -128,9 +139,14 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_staticText51 = wx.StaticText( self, wx.ID_ANY, u"Der. password (optional)", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText51.Wrap( -1 ) + self.m_staticText51.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + bSizer4.Add( self.m_staticText51, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.BOTTOM|wx.RIGHT, 5 ) self.m_textpwd = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 190,-1 ), wx.TE_PROCESS_ENTER ) + self.m_textpwd.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_textpwd.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + bSizer4.Add( self.m_textpwd, 0, wx.TOP|wx.BOTTOM, 5 ) @@ -144,6 +160,8 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. m_typechoiceChoices = [ u"BIP39", u"Electrum", u"Electrum old", u"SecuBoost" ] self.m_typechoice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_typechoiceChoices, 0 ) self.m_typechoice.SetSelection( 0 ) + self.m_typechoice.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) ) + bSizer4.Add( self.m_typechoice, 0, wx.LEFT|wx.RIGHT|wx.TOP, 4 ) @@ -157,26 +175,38 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_staticTextAcct = wx.StaticText( self, wx.ID_ANY, u"Account #", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticTextAcct.Wrap( -1 ) + self.m_staticTextAcct.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + bSizer5.Add( self.m_staticTextAcct, 0, wx.ALIGN_CENTER_VERTICAL, 5 ) self.m_account = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 112,-1 ), wx.SP_ARROW_KEYS, 0, 2147483647, 0 ) + self.m_account.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_account.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + bSizer5.Add( self.m_account, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) self.is_change = wx.CheckBox( self, wx.ID_ANY, u"internal", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) + self.is_change.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + bSizer5.Add( self.is_change, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 22 ) self.m_staticTextIdx = wx.StaticText( self, wx.ID_ANY, u"Index", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticTextIdx.Wrap( -1 ) + self.m_staticTextIdx.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + bSizer5.Add( self.m_staticTextIdx, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 25 ) self.m_index = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 112,-1 ), wx.SP_ARROW_KEYS, 0, 2147483647, 0 ) + self.m_index.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) + self.m_index.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) + bSizer5.Add( self.m_index, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.BOTTOM|wx.LEFT, 5 ) bSizer11.Add( bSizer5, 0, wx.ALIGN_CENTER, 5 ) - self.m_btnseek = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE ) + self.m_btnseek = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE|wx.BORDER_NONE ) self.m_btnseek.SetBitmap( wx.NullBitmap ) bSizer11.Add( self.m_btnseek, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 14 ) @@ -185,6 +215,7 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx. self.m_staticTextcopy.Wrap( -1 ) self.m_staticTextcopy.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + self.m_staticTextcopy.SetForegroundColour( wx.Colour( 0, 0, 0 ) ) self.m_staticTextcopy.Enable( False ) bSizer11.Add( self.m_staticTextcopy, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP|wx.RIGHT|wx.LEFT, 5 ) diff --git a/gui/swipe.png b/gui/swipe.png deleted file mode 100644 index d3fc8ce..0000000 Binary files a/gui/swipe.png and /dev/null differ diff --git a/gui/swipedn.png b/gui/swipedn.png deleted file mode 100644 index 53282c4..0000000 Binary files a/gui/swipedn.png and /dev/null differ diff --git a/gui/utils.py b/gui/utils.py new file mode 100644 index 0000000..90c97f8 --- /dev/null +++ b/gui/utils.py @@ -0,0 +1,18 @@ +import sys +import os.path +from webbrowser import open as wopen +from wx import IconBundle + + +def file_path(fpath): + if hasattr(sys, "_MEIPASS"): + return os.path.join(sys._MEIPASS, fpath) + return fpath + + +def show_history(history_url): + wopen(history_url, new=1, autoraise=True) + + +ICON_FILE_PATH = "gui/uniblow.ico" +icon_file = file_path(ICON_FILE_PATH) diff --git a/gui/window.py b/gui/window.py deleted file mode 100644 index 8213b90..0000000 --- a/gui/window.py +++ /dev/null @@ -1,575 +0,0 @@ -# -*- coding: utf-8 -*- - -########################################################################### -## Python code generated with wxFormBuilder (version Oct 26 2018) -## http://www.wxformbuilder.org/ -## -## PLEASE DO *NOT* EDIT THIS FILE! -########################################################################### - -import wx -import wx.xrc - -########################################################################### -## Class TopFrame -########################################################################### - -class TopFrame ( wx.Frame ): - - def __init__( self, parent ): - wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Uniblow", pos = wx.DefaultPosition, size = wx.Size( 950,425 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.FULL_REPAINT_ON_RESIZE|wx.TAB_TRAVERSAL ) - - self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) - - - self.Centre( wx.BOTH ) - - def __del__( self ): - pass - - -########################################################################### -## Class TopPanel -########################################################################### - -class TopPanel ( wx.Panel ): - - def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): - wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) - - self.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer1 = wx.BoxSizer( wx.HORIZONTAL ) - - - bSizer1.Add( ( 0, 0), 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5 ) - - bSizer2 = wx.BoxSizer( wx.VERTICAL ) - - self.device_label = wx.StaticText( self, wx.ID_ANY, u"Device", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.device_label.Wrap( -1 ) - - self.device_label.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer2.Add( self.device_label, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - devices_choiceChoices = [] - self.devices_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, devices_choiceChoices, 0 ) - self.devices_choice.SetSelection( 0 ) - self.devices_choice.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer2.Add( self.devices_choice, 0, wx.TOP|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.coins_label = wx.StaticText( self, wx.ID_ANY, u"Blockchain", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.coins_label.Wrap( -1 ) - - self.coins_label.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer2.Add( self.coins_label, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 20 ) - - coins_choiceChoices = [] - self.coins_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, coins_choiceChoices, 0 ) - self.coins_choice.SetSelection( 0 ) - self.coins_choice.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.coins_choice.Enable( False ) - - bSizer2.Add( self.coins_choice, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 5 ) - - self.network_label = wx.StaticText( self, wx.ID_ANY, u"Network", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.network_label.Wrap( -1 ) - - self.network_label.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.network_label.Enable( False ) - - bSizer2.Add( self.network_label, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 20 ) - - network_choiceChoices = [] - self.network_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( 150,-1 ), network_choiceChoices, 0 ) - self.network_choice.SetSelection( 0 ) - self.network_choice.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.network_choice.Enable( False ) - - bSizer2.Add( self.network_choice, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 5 ) - - self.wallopt_label = wx.StaticText( self, wx.ID_ANY, u"Account Type", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.wallopt_label.Wrap( -1 ) - - self.wallopt_label.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.wallopt_label.Enable( False ) - - bSizer2.Add( self.wallopt_label, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 20 ) - - wallopt_choiceChoices = [] - self.wallopt_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( 185,-1 ), wallopt_choiceChoices, 0 ) - self.wallopt_choice.SetSelection( 0 ) - self.wallopt_choice.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.wallopt_choice.Enable( False ) - - bSizer2.Add( self.wallopt_choice, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 5 ) - - - bSizer2.Add( ( 220, 32), 1, wx.EXPAND, 5 ) - - - bSizer1.Add( bSizer2, 0, wx.ALIGN_CENTER_VERTICAL, 5 ) - - bSizer3 = wx.BoxSizer( wx.VERTICAL ) - - bSizer5 = wx.BoxSizer( wx.VERTICAL ) - - bSizer201 = wx.BoxSizer( wx.HORIZONTAL ) - - self.account_label = wx.StaticText( self, wx.ID_ANY, u"Account", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.account_label.Wrap( -1 ) - - self.account_label.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer201.Add( self.account_label, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT, 5 ) - - self.btn_chkaddr = wx.Button( self, wx.ID_ANY, u"Check on Ledger screen", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.btn_chkaddr.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer201.Add( self.btn_chkaddr, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RESERVE_SPACE_EVEN_IF_HIDDEN, 80 ) - - - bSizer5.Add( bSizer201, 0, 0, 5 ) - - self.account_addr = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 585,-1 ), wx.TE_READONLY|wx.BORDER_NONE ) - self.account_addr.SetFont( wx.Font( 13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer5.Add( self.account_addr, 0, wx.TOP|wx.BOTTOM|wx.EXPAND, 16 ) - - - bSizer3.Add( bSizer5, 0, wx.EXPAND|wx.LEFT|wx.TOP, 16 ) - - bSizer6 = wx.BoxSizer( wx.HORIZONTAL ) - - bSizer18 = wx.BoxSizer( wx.VERTICAL ) - - bSizer19 = wx.BoxSizer( wx.HORIZONTAL ) - - self.hist_button = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE ) - - self.hist_button.SetBitmap( wx.NullBitmap ) - self.hist_button.Enable( False ) - - bSizer19.Add( self.hist_button, 0, wx.LEFT, 25 ) - - self.copy_button = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE ) - - self.copy_button.SetBitmap( wx.NullBitmap ) - self.copy_button.Enable( False ) - - bSizer19.Add( self.copy_button, 0, wx.LEFT, 75 ) - - - bSizer18.Add( bSizer19, 0, 0, 5 ) - - - bSizer18.Add( ( 0, 0), 0, wx.TOP, 20 ) - - bSizer16 = wx.BoxSizer( wx.HORIZONTAL ) - - self.balance_label = wx.StaticText( self, wx.ID_ANY, u"Balance", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.balance_label.Wrap( -1 ) - - self.balance_label.SetFont( wx.Font( 15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer16.Add( self.balance_label, 0, 0, 24 ) - - - bSizer16.Add( ( 0, 0), 0, wx.LEFT|wx.ALIGN_BOTTOM, 12 ) - - self.balance_info = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) - self.balance_info.Wrap( -1 ) - - self.balance_info.SetFont( wx.Font( 15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer16.Add( self.balance_info, 0, 0, 20 ) - - - bSizer18.Add( bSizer16, 0, wx.TOP, 16 ) - - - bSizer6.Add( bSizer18, 1, 0, 5 ) - - self.copy_status = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) - self.copy_status.Wrap( -1 ) - - bSizer6.Add( self.copy_status, 0, wx.TOP|wx.LEFT, 10 ) - - self.qrimg = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.Size( 140,140 ), 0 ) - bSizer6.Add( self.qrimg, 0, wx.LEFT, 148 ) - - - bSizer3.Add( bSizer6, 0, wx.ALIGN_CENTER_HORIZONTAL, 8 ) - - bSizer4 = wx.BoxSizer( wx.HORIZONTAL ) - - self.dest_label = wx.StaticText( self, wx.ID_ANY, u"To :", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.dest_label.Wrap( -1 ) - - self.dest_label.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer4.Add( self.dest_label, 0, wx.ALIGN_BOTTOM|wx.TOP|wx.BOTTOM|wx.LEFT, 8 ) - - self.addr_panel = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) - bSizer20 = wx.BoxSizer( wx.VERTICAL ) - - self.dest_addr = wx.TextCtrl( self.addr_panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 581,-1 ), 0 ) - self.dest_addr.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.dest_addr.Enable( False ) - - bSizer20.Add( self.dest_addr, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 3 ) - - - self.addr_panel.SetSizer( bSizer20 ) - self.addr_panel.Layout() - bSizer20.Fit( self.addr_panel ) - bSizer4.Add( self.addr_panel, 0, wx.ALIGN_BOTTOM, 3 ) - - - bSizer3.Add( bSizer4, 0, wx.TOP|wx.EXPAND, 8 ) - - bSizer7 = wx.BoxSizer( wx.HORIZONTAL ) - - self.amount_label = wx.StaticText( self, wx.ID_ANY, u"Amount :", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.amount_label.Wrap( -1 ) - - self.amount_label.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer7.Add( self.amount_label, 0, wx.LEFT|wx.TOP, 8 ) - - self.amount = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PROCESS_ENTER ) - self.amount.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - self.amount.Enable( False ) - - bSizer7.Add( self.amount, 0, wx.ALL, 5 ) - - bSizer9 = wx.BoxSizer( wx.VERTICAL ) - - self.fee_slider = wx.Slider( self, wx.ID_ANY, 1, 0, 2, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL ) - bSizer9.Add( self.fee_slider, 0, wx.LEFT|wx.TOP, 6 ) - - self.fee_setting = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTER_HORIZONTAL ) - self.fee_setting.Wrap( -1 ) - - self.fee_setting.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer9.Add( self.fee_setting, 0, wx.LEFT, 6 ) - - - bSizer7.Add( bSizer9, 0, 0, 0 ) - - self.send_button = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE ) - - self.send_button.SetBitmap( wx.NullBitmap ) - self.send_button.Enable( False ) - - bSizer7.Add( self.send_button, 0, wx.TOP|wx.LEFT, 8 ) - - - bSizer7.Add( ( 0, 0), 1, wx.LEFT, 8 ) - - self.send_all = wx.BitmapButton( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, wx.BU_AUTODRAW|wx.BORDER_NONE ) - - self.send_all.SetBitmap( wx.NullBitmap ) - self.send_all.Enable( False ) - - bSizer7.Add( self.send_all, 0, wx.LEFT|wx.TOP, 8 ) - - - bSizer3.Add( bSizer7, 0, wx.TOP, 12 ) - - - bSizer1.Add( bSizer3, 1, 0, 5 ) - - - self.SetSizer( bSizer1 ) - self.Layout() - bSizer1.Fit( self ) - - def __del__( self ): - pass - - -########################################################################### -## Class HDDialog -########################################################################### - -class HDDialog ( wx.Dialog ): - - def __init__( self, parent ): - wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Local File wallet setup", pos = wx.DefaultPosition, size = wx.Size( 600,480 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.DEFAULT_DIALOG_STYLE|wx.STAY_ON_TOP|wx.SYSTEM_MENU ) - - self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) - - - self.Centre( wx.BOTH ) - - def __del__( self ): - pass - - -########################################################################### -## Class HDPanel -########################################################################### - -class HDPanel ( wx.Panel ): - - def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): - wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) - - bSizer11 = wx.BoxSizer( wx.VERTICAL ) - - bSizer15 = wx.BoxSizer( wx.HORIZONTAL ) - - self.title_text = wx.StaticText( self, wx.ID_ANY, u"Local wallet mnemonic setup", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.title_text.Wrap( -1 ) - - self.title_text.SetFont( wx.Font( 14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer15.Add( self.title_text, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 32 ) - - - bSizer15.Add( ( 24, 0), 0, 0, 15 ) - - self.m_textwl = wx.StaticText( self, wx.ID_ANY, u"Words in list", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_textwl.Wrap( -1 ) - - bSizer15.Add( self.m_textwl, 0, wx.ALIGN_BOTTOM|wx.ALL, 5 ) - - self.m_bitmapHDwl = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer15.Add( self.m_bitmapHDwl, 0, wx.ALIGN_BOTTOM|wx.BOTTOM, 5 ) - - self.m_textcs = wx.StaticText( self, wx.ID_ANY, u"Checksum", wx.DefaultPosition, wx.DefaultSize, wx.ST_NO_AUTORESIZE ) - self.m_textcs.Wrap( -1 ) - - bSizer15.Add( self.m_textcs, 0, wx.ALL|wx.ALIGN_BOTTOM, 5 ) - - self.m_bitmapHDcs = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer15.Add( self.m_bitmapHDcs, 0, wx.ALIGN_BOTTOM|wx.BOTTOM, 5 ) - - - bSizer15.Add( ( 0, 0), 1, wx.EXPAND|wx.RIGHT, 16 ) - - - bSizer11.Add( bSizer15, 1, wx.EXPAND, 5 ) - - self.m_textCtrl_mnemo = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE ) - self.m_textCtrl_mnemo.SetFont( wx.Font( 12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer11.Add( self.m_textCtrl_mnemo, 1, wx.LEFT|wx.RIGHT|wx.EXPAND, 16 ) - - bSizer13 = wx.BoxSizer( wx.HORIZONTAL ) - - - bSizer13.Add( ( 0, 0), 0, wx.RIGHT, 18 ) - - self.m_bwptxt = wx.StaticText( self, wx.ID_ANY, u"Deriv. password (opt.)", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_bwptxt.Wrap( -1 ) - - bSizer13.Add( self.m_bwptxt, 0, wx.ALIGN_CENTER_VERTICAL, 4 ) - - self.m_textCtrl_pwd = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 170,-1 ), 0 ) - bSizer13.Add( self.m_textCtrl_pwd, 0, wx.ALL, 5 ) - - self.m_checkBox_secboost = wx.CheckBox( self, wx.ID_ANY, u"SecuBoost", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_checkBox_secboost.SetToolTip( u"Extra security boost for mnemonic.\nNot compatible with BIP39.\nRequires >1GB RAM free" ) - - bSizer13.Add( self.m_checkBox_secboost, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 22 ) - - - bSizer11.Add( bSizer13, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - bSizer14 = wx.BoxSizer( wx.HORIZONTAL ) - - self.m_accounttxt = wx.StaticText( self, wx.ID_ANY, u"Account #", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_accounttxt.Wrap( -1 ) - - bSizer14.Add( self.m_accounttxt, 0, wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.m_spinCtrl_account = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 75,-1 ), wx.SP_ARROW_KEYS, 0, 2147483647, 0 ) - bSizer14.Add( self.m_spinCtrl_account, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.m_indextxt = wx.StaticText( self, wx.ID_ANY, u"index", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_indextxt.Wrap( -1 ) - - bSizer14.Add( self.m_indextxt, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 24 ) - - self.m_spinCtrl_index = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 75,-1 ), wx.SP_ARROW_KEYS, 0, 2147483647, 0 ) - bSizer14.Add( self.m_spinCtrl_index, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) - - - bSizer11.Add( bSizer14, 1, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 16 ) - - self.m_altderiv = wx.CheckBox( self, wx.ID_ANY, u"Alt. derivation path (Not BIP44, for ETH / EVM)", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer11.Add( self.m_altderiv, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - - bSizer11.Add( ( 0, 0), 0, wx.TOP, 20 ) - - self.m_usertxt = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_usertxt.Wrap( -1 ) - - self.m_usertxt.SetFont( wx.Font( 10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer11.Add( self.m_usertxt, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.RIGHT, 24 ) - - bSizer12 = wx.BoxSizer( wx.HORIZONTAL ) - - self.m_butOK = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.Size( -1,36 ), 0 ) - bSizer12.Add( self.m_butOK, 0, wx.ALL, 5 ) - - - bSizer12.Add( ( 0, 0), 1, wx.RIGHT, 25 ) - - self.m_butcancel = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.Size( -1,36 ), 0 ) - bSizer12.Add( self.m_butcancel, 0, wx.ALL, 5 ) - - - bSizer11.Add( bSizer12, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 18 ) - - - self.SetSizer( bSizer11 ) - self.Layout() - bSizer11.Fit( self ) - - # Connect Events - self.m_textCtrl_mnemo.Bind( wx.EVT_TEXT, self.hdmnemo_changed ) - self.m_butOK.Bind( wx.EVT_BUTTON, self.hd_ok ) - self.m_butcancel.Bind( wx.EVT_BUTTON, self.hd_cancel ) - - def __del__( self ): - pass - - - # Virtual event handlers, overide them in your derived class - def hdmnemo_changed( self, event ): - event.Skip() - - def hd_ok( self, event ): - event.Skip() - - def hd_cancel( self, event ): - event.Skip() - - -########################################################################### -## Class OptionDialog -########################################################################### - -class OptionDialog ( wx.Dialog ): - - def __init__( self, parent ): - wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 455,375 ), style = wx.DEFAULT_DIALOG_STYLE ) - - self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) - - - self.Centre( wx.BOTH ) - - def __del__( self ): - pass - - -########################################################################### -## Class OptionPanel -########################################################################### - -class OptionPanel ( wx.Panel ): - - def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ): - wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name ) - - bSizer18 = wx.BoxSizer( wx.VERTICAL ) - - - bSizer18.Add( ( 0, 0), 1, wx.TOP, 16 ) - - self.preset_text = wx.StaticText( self, wx.ID_ANY, u"Known Preset", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.preset_text.Wrap( -1 ) - - self.preset_text.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer18.Add( self.preset_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - known_choiceChoices = [] - self.known_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.Size( 360,-1 ), known_choiceChoices, 0 ) - self.known_choice.SetSelection( 0 ) - self.known_choice.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer18.Add( self.known_choice, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.m_staticTextor = wx.StaticText( self, wx.ID_ANY, u"OR", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.m_staticTextor.Wrap( -1 ) - - self.m_staticTextor.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer18.Add( self.m_staticTextor, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.custom_text = wx.StaticText( self, wx.ID_ANY, u"other custom", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.custom_text.Wrap( -1 ) - - self.custom_text.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer18.Add( self.custom_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.m_butpaste = wx.Button( self, wx.ID_ANY, u"Paste", wx.DefaultPosition, wx.DefaultSize, 0 ) - bSizer18.Add( self.m_butpaste, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.new_choice = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 375,-1 ), wx.TE_PROCESS_ENTER ) - self.new_choice.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer18.Add( self.new_choice, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - bSizer19 = wx.BoxSizer( wx.HORIZONTAL ) - - self.m_button4 = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.Size( -1,40 ), 0 ) - self.m_button4.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer19.Add( self.m_button4, 0, wx.ALL, 5 ) - - - bSizer19.Add( ( 0, 0), 1, wx.LEFT, 16 ) - - self.m_button3 = wx.Button( self, wx.ID_ANY, u"OK", wx.DefaultPosition, wx.Size( -1,40 ), 0 ) - self.m_button3.SetFont( wx.Font( 11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) - - bSizer19.Add( self.m_button3, 0, wx.ALL, 5 ) - - - bSizer18.Add( bSizer19, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.TOP, 28 ) - - - bSizer18.Add( ( 0, 0), 1, wx.EXPAND, 5 ) - - - self.SetSizer( bSizer18 ) - self.Layout() - bSizer18.Fit( self ) - - # Connect Events - self.m_butpaste.Bind( wx.EVT_BUTTON, self.pasteValue ) - self.new_choice.Bind( wx.EVT_TEXT_ENTER, self.valid_custom ) - self.m_button4.Bind( wx.EVT_BUTTON, self.cancelOption ) - self.m_button3.Bind( wx.EVT_BUTTON, self.okOption ) - - def __del__( self ): - pass - - - # Virtual event handlers, overide them in your derived class - def pasteValue( self, event ): - event.Skip() - - def valid_custom( self, event ): - event.Skip() - - def cancelOption( self, event ): - event.Skip() - - def okOption( self, event ): - event.Skip() - - diff --git a/package/build_win_verinfo.py b/package/build_win_verinfo.py index c1a08f9..6a62785 100644 --- a/package/build_win_verinfo.py +++ b/package/build_win_verinfo.py @@ -31,7 +31,8 @@ def now_time_filetime(): def ver_str_to_comma(verstr): - return ", ".join(verstr.split(".")) + verstr_norm = verstr.split("-", 1)[0] + return ", ".join(verstr_norm.split(".")) def fill_version_info(file_name, version_str, file_desc, comment): diff --git a/package/uniblow.spec b/package/uniblow.spec index 411bd7a..2dfd632 100644 --- a/package/uniblow.spec +++ b/package/uniblow.spec @@ -46,28 +46,46 @@ pkgs_remove = [ "libdbus", ] +datai = [ + (ICON, "gui/"), + ("../cryptolib/wordslist/english.txt", "cryptolib/wordslist/"), + ("../gui/images/logo.png", "gui/images/"), + ("../gui/images/good.png", "gui/images/"), + ("../gui/images/bad.png", "gui/images/"), + ("../gui/images/arrsel.png", "gui/images/"), + ("../gui/images/btns/GenSeed.png", "gui/images/btns/"), + ("../gui/images/btns/blankopt.png", "gui/images/btns/"), + ("../gui/images/btns/cancel.png", "gui/images/btns/"), + ("../gui/images/btns/chdev.png", "gui/images/btns/"), + ("../gui/images/btns/close.png", "gui/images/btns/"), + ("../gui/images/btns/proceed.png", "gui/images/btns/"), + ("../gui/images/btns/paste.png", "gui/images/btns/"), + ("../gui/images/btns/ok.png", "gui/images/btns/"), + ("../gui/images/btns/quit.png", "gui/images/btns/"), + ("../gui/images/btns/qr.png", "gui/images/btns/"), + ("../gui/images/btns/copy.png", "gui/images/btns/"), + ("../gui/images/btns/history.png", "gui/images/btns/"), + ("../gui/images/btns/SeekAssets.png", "gui/images/btns/"), + ("../gui/images/btns/send.png", "gui/images/btns/"), + ("../gui/images/btns/dev_seedwatcher.png", "gui/images/btns/"), + ("../gui/images/btns/dev_localfile.png", "gui/images/btns/"), + ("../gui/images/btns/dev_ledger.png", "gui/images/btns/"), + ("../gui/images/btns/dev_cryptnox.png", "gui/images/btns/"), + ("../gui/images/btns/dev_openpgp.png", "gui/images/btns/"), + ("../gui/images/btns/addrchk.png", "gui/images/btns/"), + ("../gui/images/btns/tokens.png", "gui/images/btns/"), + ("../gui/images/btns/wc.png", "gui/images/btns/"), + ("../gui/images/btns/endwc.png", "gui/images/btns/"), +] +datai += [ + (f"../gui/images/icons/{coin.lower()}.png", "gui/images/icons/") for coin in SUPPORTED_COINS +] + a = Analysis( ["../uniblow.py"], pathex=[current_path], binaries=[], - datas=[ - (ICON, "gui/"), - ("../cryptolib/wordslist/english.txt", "cryptolib/wordslist/"), - ("../gui/good.bmp", "gui/"), - ("../gui/bad.bmp", "gui/"), - ("../gui/GenSeed.png", "gui/"), - ("../gui/GenSeeddn.png", "gui/"), - ("../gui/copy.png", "gui/"), - ("../gui/copydn.png", "gui/"), - ("../gui/histo.png", "gui/"), - ("../gui/histodn.png", "gui/"), - ("../gui/SeekAssets.png", "gui/"), - ("../gui/SeekAssetsdn.png", "gui/"), - ("../gui/send.png", "gui/"), - ("../gui/senddn.png", "gui/"), - ("../gui/swipe.png", "gui/"), - ("../gui/swipedn.png", "gui/"), - ], + datas=datai, hiddenimports=additional_imports, hookspath=[], runtime_hooks=[], @@ -158,6 +176,6 @@ if os_platform == "mac": "LANG": "en_US.UTF-8", "LC_CTYPE": "en_US.UTF-8", }, - "NSHumanReadableCopyright": "Copyright (C) 2021 BitLogiK", + "NSHumanReadableCopyright": "Copyright (C) 2021-2022 BitLogiK", }, ) diff --git a/screenshot.png b/screenshot.png index 8a001c3..ce08873 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/setup.cfg b/setup.cfg index 065ffad..6286307 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,4 +9,4 @@ disable = missing-module-docstring,missing-class-docstring,missing-function-docs generated-members = wx.* # [black] -# --line-length=100 --target-version=py39 --include "\.(py[iw]?|spec)$" --exclude "unibenv|gui/(window|infodialog|swgui).py|cryptolib/ElectrumLegacy.py" . +# --line-length=100 --target-version=py39 --include "\.(py[iw]?|spec)$" --exclude "unibenv|gui/(infodialog|swgui|maingui).py|cryptolib/ElectrumLegacy.py" . diff --git a/setup.py b/setup.py index d3f2907..ff4fe10 100644 --- a/setup.py +++ b/setup.py @@ -35,25 +35,6 @@ "hidapi==0.11.0.post2", "pyWalletConnect==1.2.2", ], - package_data={ - "gui": [ - "uniblow.ico", - "good.bmp", - "bad.bmp", - "GenSeed.png", - "GenSeeddn.png", - "copy.png", - "copydn.png", - "histo.png", - "histodn.png", - "SeekAssets.png", - "SeekAssetsdn.png", - "send.png", - "senddn.png", - "swipe.png", - "swipedn.png", - ] - }, include_package_data=False, classifiers=[ "Programming Language :: Python :: 3 :: Only", diff --git a/uniblow.py b/uniblow.py index 8ef6986..7df5d09 100644 --- a/uniblow.py +++ b/uniblow.py @@ -17,23 +17,21 @@ try: from ctypes import windll + + windll.shcore.SetProcessDpiAwareness(1) except ImportError: # Not Windows, anyway pass -if "windll" in globals(): - windll.shcore.SetProcessDpiAwareness(2) from copy import copy as ccopy -from functools import partial from importlib import import_module from logging import basicConfig, DEBUG, getLogger -from io import BytesIO from sys import argv import wx -import qrcode import gui.app +from gui.utils import file_path from devices.SeedWatcher import start_seedwatcher from devices.SingleKey import SKdevice from wallets.wallets_utils import InvalidOption, NotEnoughTokens @@ -61,25 +59,13 @@ DEVICES_LIST = [ "SeedWatcher", "LocalFile", - "OpenPGP", "Ledger", "Cryptnox", -] - -FEES_PRORITY_TEXT = [ - "Economic fee", - "Normal fee", - "Faster fee", + "OpenPGP", ] DEFAULT_PASSWORD = "NoPasswd" -GREEN_COLOR = wx.Colour(73, 172, 73) -RED_COLOR = wx.Colour(198, 60, 60) - - -BAD_ADDRESS = "Wrong destination account address checksum or wrong format." - logger = getLogger(__name__) @@ -111,180 +97,12 @@ def get_device_class(device_str): return device_class -def check_coin_consistency(current_wallet=None, network_num=None): - """Check if selected coin is the same as the current wallet class used.""" - # Designed to fix a race condition when the async data of a wallet - # are displayed : address and balance. - # Changing the coin selector could mix crypto info. So this terminates some - # process path that are no longer valid. - if not app.gui_panel.coins_choice.IsEnabled(): - # Can be seedwatcher - return True - coin_sel = app.gui_panel.coins_choice.GetSelection() - if coin_sel <= 0: - return False - coin_name = app.gui_panel.coins_choice.GetString(coin_sel) - coin_class = get_coin_class(coin_name) - if current_wallet is None: - current_wallet = type(app.wallet) - if coin_class is not current_wallet: - return False - if network_num is not None: - net_sel = app.gui_panel.network_choice.GetSelection() - if net_sel < 0: - return False - return net_sel == network_num - return True - - -def display_balance(): - logger.debug("Checking for wallet balance") - if not hasattr(app, "wallet"): - erase_info() - return - if not check_coin_consistency(): - return - try: - balance = app.wallet.get_balance() - except Exception as exc: - erase_info() - err_msg = ( - f"Error when getting account balance.\nCheck your Internet connection.\n{str(exc)}" - ) - logger.error("Error in display_balance : %s", err_msg, exc_info=exc, stack_info=True) - warn_modal(err_msg) - return - app.gui_panel.balance_info.SetLabel(balance) - app.gui_panel.hist_button.Enable() - app.gui_panel.copy_button.Enable() - app.gui_panel.account_label.Enable() - app.gui_panel.balance_label.Enable() - bal_str = balance.split(" ")[0] - if ( - # No fund in the wallet - bal_str not in ("0", "0.0") - # EOS when register pubkey mode : disable sending - and not bal_str.startswith("Register") - # WalletConnect : disable sending - and not hasattr(app.wallet, "wc_timer") - ): - app.gui_panel.dest_addr.Enable() - app.gui_panel.amount.Enable() - app.gui_panel.dest_label.Enable() - app.gui_panel.amount_label.Enable() - app.gui_panel.fee_slider.Enable() - app.gui_panel.fee_setting.Enable() - app.gui_panel.send_button.Enable() - app.gui_panel.send_all.Enable() - else: - app.gui_panel.dest_addr.Clear() - app.gui_panel.amount.Clear() - app.gui_panel.dest_label.Disable() - app.gui_panel.amount_label.Disable() - app.gui_panel.fee_slider.Disable() - app.gui_panel.fee_setting.Disable() - app.gui_panel.dest_addr.Disable() - app.gui_panel.amount.Disable() - app.gui_panel.send_button.Disable() - app.gui_panel.send_all.Disable() - if hasattr(app.wallet, "wc_timer"): - # WalletConnect active - app.gui_panel.dest_addr.ChangeValue(" Use the connected dapp to transact") - - -def erase_info(reset=False): - if hasattr(app, "balance_timer"): - app.balance_timer.Stop() - if hasattr(app, "wallet") and hasattr(app.wallet, "wc_timer"): - app.wallet.wc_client.close() - app.wallet.wc_timer.Stop() - delattr(app.wallet, "wc_timer") - paint_toaddr(wx.NullColour) - app.gui_panel.hist_button.Disable() - app.gui_panel.copy_button.Disable() - app.gui_panel.dest_addr.Clear() - app.gui_panel.dest_addr.Disable() - app.gui_panel.amount.Clear() - app.gui_panel.amount.Disable() - app.gui_panel.send_all.Disable() - app.gui_panel.send_button.Disable() - app.gui_panel.wallopt_label.Disable() - app.gui_panel.wallopt_choice.Disable() - app.gui_panel.account_label.Disable() - app.gui_panel.balance_label.Disable() - app.gui_panel.dest_label.Disable() - app.gui_panel.amount_label.Disable() - app.gui_panel.fee_slider.Disable() - app.gui_panel.fee_setting.Disable() - app.gui_panel.btn_chkaddr.Hide() - if reset: - app.gui_panel.network_choice.SetSelection(0) - app.gui_panel.wallopt_choice.SetSelection(0) - app.gui_panel.fee_setting.SetLabel("") - app.gui_panel.qrimg.SetBitmap(wx.Bitmap()) - if hasattr(app, "wallet"): - del app.wallet - app.gui_panel.balance_info.SetLabel("") - app.gui_panel.account_addr.SetLabel("") - app.gui_frame.Refresh() - - class DisplayTimer(wx.Timer): def __init__(self): wx.Timer.__init__(self) def Notify(self): - display_balance() - - -def warn_modal(warning_text, modal=False): - gui.app.InfoBox( - warning_text, "Error", wx.OK | wx.ICON_WARNING, app.gui_frame, block_modal=modal - ) - - -def info_modal(title, info_text): - gui.app.InfoBox(info_text, title, wx.OK | wx.ICON_INFORMATION, app.gui_frame) - - -def get_password(device_nam, input_message): - pwd_dialog = wx.PasswordEntryDialog( - app.gui_frame, - input_message, - caption=f"{device_nam} wallet PIN/password", - defaultValue="", - pos=wx.DefaultPosition, - ) - if pwd_dialog.ShowModal() == wx.ID_OK: - passval = pwd_dialog.GetValue() - return passval - - -def get_option(network_id, input_value, preset_values): - option_dialog = gui.window.OptionDialog(app.gui_frame) - option_panel = gui.app.app_option_panel(option_dialog) - option_panel.SetTitle(f"Wallet settings : {input_value} selection") - option_panel.SetPresetLabel(f"preset {input_value}") - option_panel.SetCustomLabel(f"input a {input_value}") - if preset_values: - option_panel.SetPresetValues(preset_values[network_id]) - else: - option_panel.HidePreset() - if option_dialog.ShowModal() == wx.ID_OK: - optval = option_panel.GetValue() - return optval - - -def confirm_tx(to_addr, amount): - conf_txt = f"Confirm this transaction ?\n{amount} {app.wallet.coin} to {to_addr}" - confirm_tx_modal = wx.MessageDialog( - app.gui_frame, - conf_txt, - "Confirmation", - wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.STAY_ON_TOP | wx.CENTER, - wx.DefaultPosition, - ) - return confirm_tx_modal.ShowModal() + wx.CallAfter(app.display_balance) def confirm_request(request_ui_message): @@ -304,37 +122,7 @@ def confirm_request(request_ui_message): def tx_success(message): - info_modal("Transaction sent", message) - - -def copy_result(restxt): - app.gui_panel.copy_status.SetLabel(restxt) - if restxt != "": - wx.CallLater(1800, copy_result, "") - - -def copy_account(ev): - if not hasattr(app, "wallet"): - copy_result("No wallet") - return - try: - if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open(): - wx.TheClipboard.Clear() - addr = app.gui_panel.account_addr.GetValue() - wx.TheClipboard.SetData(wx.TextDataObject(addr)) - wx.TheClipboard.Flush() - wx.TheClipboard.Close() - copy_result("Copied") - else: - copy_result("No Access") - except Exception: - copy_result("Error") - - -def disp_history(ev): - hist_url = app.wallet.history() - if hist_url: - gui.app.show_history(hist_url) + app.info_modal("Transaction sent", message) def watch_messages(): @@ -344,10 +132,10 @@ def watch_messages(): try: app.wallet.get_messages() except NotEnoughTokens as exc: - warn_modal(str(exc)) + app.warn_modal(str(exc)) except Exception as exc: if str(exc).startswith("You rejected the"): - warn_modal(str(exc)) + app.warn_modal(str(exc)) return wallet_error(exc, "fromwatch") @@ -368,16 +156,10 @@ def cb_open_wallet(wallet_obj, pkey, waltype, sw_frame, pubkey_cpr): # Special case for Bitcoin Electrum old app.wallet = wallet_obj(key_device, pubkey_cpr) sw_frame.Close() + app.start_wallet_panel() app.gui_panel.btn_chkaddr.Hide() - app.gui_panel.devices_choice.SetSelection(1) - app.gui_panel.coins_choice.Clear() - app.gui_panel.coins_choice.Append(app.wallet.coin) - app.gui_panel.coins_choice.SetSelection(0) - app.gui_panel.coins_choice.Disable() app.gui_panel.network_choice.Clear() - app.gui_panel.wallopt_choice.Clear() app.gui_panel.network_choice.Enable() - app.gui_panel.network_label.Enable() if app.wallet.coin not in ["BTC", "XTZ"]: app.gui_panel.wallopt_choice.Enable() app.gui_panel.wallopt_label.Enable() @@ -385,24 +167,61 @@ def cb_open_wallet(wallet_obj, pkey, waltype, sw_frame, pubkey_cpr): acc_types = app.wallet.get_account_types() for netw in networks: app.gui_panel.network_choice.Append(netw) - for wtype in acc_types: - app.gui_panel.wallopt_choice.Append(wtype) + app.add_wallet_types(acc_types) app.gui_panel.network_choice.SetSelection(0) app.gui_panel.wallopt_choice.SetSelection(waltype) + app.deactivate_option_buttons() + app.current_chain = app.wallet.coin + if app.wallet.coin in [ + "ETH", + "BSC", + "MATIC", + "FTM", + "OP", + "METIS", + "CELO", + "GLMR", + "ARB", + "AVAX", + ]: + app.activate_option_buttons() + app.gui_panel.but_evt1.Bind( + wx.EVT_BUTTON, lambda x: process_coin_select(app.wallet.coin, 0, 1) + ) + app.gui_panel.but_evt2.Bind( + wx.EVT_BUTTON, lambda x: process_coin_select(app.wallet.coin, 0, 2) + ) + app.gui_panel.network_choice.Bind( + wx.EVT_CHOICE, lambda x: net_selected(app.wallet.coin, x.GetInt()) + ) + app.gui_panel.wallopt_choice.Bind(wx.EVT_CHOICE, lambda x: wtype_selected(app.wallet.coin, x)) + + coin_button = wx.BitmapButton( + app.gui_panel.scrolled_coins, + wx.ID_ANY, + wx.NullBitmap, + wx.DefaultPosition, + wx.DefaultSize, + wx.BU_AUTODRAW | wx.BORDER_NONE, + ) + img = wx.Image(file_path(f"gui/images/icons/{app.wallet.coin.lower()}.png"), wx.BITMAP_TYPE_PNG) + img.Rescale(48, 48, wx.IMAGE_QUALITY_BILINEAR) + img.Resize(wx.Size(58, 56), wx.Point(5, 4), red=-1, green=-1, blue=-1) + bmp = wx.Bitmap(img) + coin_button.SetBackgroundColour(wx.Colour(248, 250, 252)) + coin_button.SetBitmap(bmp) + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(coin_button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 6) + app.gui_panel.scrolled_coins.SetSizer(sizer) + app.gui_panel.scrolled_coins.Layout() + app.gui_panel.Layout() + app.gui_frame.Layout() display_coin(app.wallet.get_account()) -def device_selected(device): +def device_selected(sel_device): close_device() - app.gui_panel.btn_chkaddr.Hide() - app.gui_panel.coins_choice.Disable() - app.gui_panel.coins_choice.SetSelection(0) - app.gui_panel.network_choice.Clear() - app.gui_panel.network_choice.Disable() - app.gui_panel.wallopt_choice.Clear() - erase_info(True) - sel_device = device.GetInt() - device_sel_name = DEVICES_LIST[sel_device - 1] + device_sel_name = DEVICES_LIST[sel_device] coins_list = ccopy(SUPPORTED_COINS) if device_sel_name == "Ledger": coins_list = [ @@ -421,21 +240,20 @@ def device_selected(device): coins_list.remove("SOL") if device_sel_name == "Cryptnox": coins_list.remove("SOL") - app.load_coins_list(coins_list) - if sel_device == 1: + if sel_device == 0: # Seed Watcher start_seedwatcher(app, cb_open_wallet) - if sel_device > 1: + if sel_device > 0: # Real keys device the_device = get_device_class(device_sel_name) try: device_loaded = the_device() except Exception as exc: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) logger.error( "Error during device loading : %s", str(exc), exc_info=exc, stack_info=True ) - warn_modal(str(exc)) + app.warn_modal(str(exc)) return pin_left = -1 password_default = device_loaded.default_password @@ -453,7 +271,7 @@ def device_selected(device): if the_device.is_HD: HDwallet_settings = app.hd_setup("") if HDwallet_settings is None: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) return raise pwdException # Can raise notinit @@ -470,7 +288,7 @@ def device_selected(device): # Get settings from the user HDwallet_settings = app.hd_setup(mnemonic) if HDwallet_settings is None: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) return if the_device.has_admin_password: set_admin_message = ( @@ -490,9 +308,9 @@ def device_selected(device): f"The chosen {the_device.admin_pass_name} must be\n{lenmsg} chars long." ) while True: - admin_password = get_password(device_sel_name, set_admin_message) + admin_password = app.get_password(device_sel_name, set_admin_message) if admin_password is None: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) return if admin_password == "": admin_password = device_loaded.default_admin_password @@ -501,7 +319,7 @@ def device_selected(device): and len(admin_password) <= device_loaded.admin_pwd_maxlen ): break - warn_modal( + app.warn_modal( f"{the_device.admin_pass_name} shall be {lenmsg} chars long.", True, ) @@ -519,9 +337,9 @@ def device_selected(device): pintype = "digits" inp_message += f"The chosen {pwd_pin} must be\n{lenmsg} {pintype} long." while True: - password = get_password(device_sel_name, inp_message) + password = app.get_password(device_sel_name, inp_message) if password is None: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) return if password == "": password = device_loaded.default_password @@ -534,7 +352,7 @@ def device_selected(device): wmsg = f"Device {pwd_pin} shall be {lenmsg} {pintype} long." if device_loaded.is_pin_numeric: wmsg += f"\n\nThe {pwd_pin} must be {pintype} (0-9) only." - warn_modal( + app.warn_modal( wmsg, True, ) @@ -551,31 +369,31 @@ def device_selected(device): device_loaded.initialize_device() break except Exception as exc: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) logger.error( "Error during device initialization : %s", {str(exc)}, exc_info=exc, stack_info=True, ) - warn_modal(str(exc)) + app.warn_modal(str(exc)) return except pwdException as excp: if not device_loaded.password_retries_inf: try: pin_left = device_loaded.get_pw_left() except Exception as exc: - device_error(exc) + app.device_error(exc) return if pin_left == 0: - warn_modal(f"Device {pwd_pin} is locked.") + app.warn_modal(f"Device {pwd_pin} is locked.") return if ( the_device.password_softlock > 0 and pin_left == the_device.password_softlock and str(excp) == "0" ): - warn_modal(f"Device {pwd_pin} is soft locked. Restart it to try again.") + app.warn_modal(f"Device {pwd_pin} is soft locked. Restart it to try again.") return while True: inp_message = f"Input your {device_sel_name} wallet {pwd_pin}.\n" @@ -593,9 +411,9 @@ def device_selected(device): if device_loaded.is_pin_numeric: pintype = "digits" inp_message += f"\nThe {pwd_pin} to provide\nis {lenmsg} {pintype} long." - password_default = get_password(device_sel_name, inp_message) + password_default = app.get_password(device_sel_name, inp_message) if password_default is None: - app.gui_panel.devices_choice.SetSelection(0) + # app.gui_panel.devices_choice.SetSelection(0) return if ( len(password_default) >= device_loaded.password_min_len @@ -606,90 +424,58 @@ def device_selected(device): wmsg = f"Device {pwd_pin} shall be {lenmsg} {pintype} long." if device_loaded.is_pin_numeric: wmsg += f"\n\nThe {pwd_pin} must be {pintype} (0-9) only." - warn_modal( + app.warn_modal( wmsg, True, ) except Exception as exc: - return device_error(exc) + return app.device_error(exc) wx.MilliSleep(100) if the_device.has_password and the_device.is_HD and not the_device.password_retries_inf: # Kind of special for Cryptnox for now device_loaded.set_path(HDwallet_settings) app.device = device_loaded if app.device.created: - info_modal( + app.info_modal( "Device created", f"A new {device_sel_name} device was successfully created.", ) - app.gui_panel.coins_choice.Enable() - app.gui_panel.coins_choice.Hide() - app.gui_panel.coins_choice.ShowWithEffect(wx.SHOW_EFFECT_ROLL_TO_RIGHT, 750) - app.gui_panel.coins_choice.SetFocus() - else: - erase_info(True) + return coins_list def wallet_fallback(): """Called when a user option failed""" # Reset the wallet to the first type wallet_type_fallback = 0 - # If Tezos, which have 2 different key types, must stick on the previous keytype - if app.gui_panel.coins_choice.GetStringSelection() == "XTZ" and hasattr( - app.device, "get_key_type" - ): - device_key_type = app.device.get_key_type() - if device_key_type: - # Inverse of XTZ get_key_type to set back the type selector - if device_key_type == "ED": - # tz1 first choice - wallet_type_fallback = 0 - elif device_key_type == "K1": - # tz2 second choice - wallet_type_fallback = 1 app.gui_panel.wallopt_choice.SetSelection(wallet_type_fallback) - # Act like the user selected back the first wallet type - coin_sel = app.gui_panel.coins_choice.GetStringSelection() - net_sel = app.gui_panel.network_choice.GetSelection() - wx.CallLater(180, process_coin_select, coin_sel, net_sel, wallet_type_fallback) - - -def device_error(exc): - app.gui_panel.coins_choice.Disable() - app.gui_panel.coins_choice.SetSelection(0) - app.gui_panel.network_choice.Clear() - app.gui_panel.network_choice.Disable() - app.gui_panel.wallopt_choice.Clear() - app.gui_panel.wallopt_choice.Disable() - app.gui_panel.devices_choice.SetSelection(0) - app.gui_panel.btn_chkaddr.Hide() - erase_info(True) - logger.error("Error with device : %s", str(exc), exc_info=exc, stack_info=True) - warn_modal(str(exc)) - return + app.gui_panel.scrolled_coins.Enable() def wallet_error(exc, level="hard"): """Process wallet exception""" if level == "hard": app.gui_panel.network_choice.Clear() - app.gui_panel.coins_choice.SetSelection(0) + app.clear_coin_selected() + app.deactivate_option_buttons() app.gui_panel.wallopt_choice.Clear() app.gui_panel.wallopt_choice.Disable() + app.gui_panel.btn_chkaddr.Disable() if hasattr(app, "wallet"): erase_option = app.wallet.coin != "BTC" else: + app.clear_coin_selected() + app.current_chain = "" erase_option = False - erase_info(erase_option) + app.erase_info(erase_option) logger.error("Error in the wallet : %s", str(exc), exc_info=exc, stack_info=True) if level == "fromwatch": exc = str(exc) + "\nYou can reconnect by selecting the network option." - warn_modal(str(exc)) + app.deactivate_option_buttons() + app.gui_panel.scrolled_coins.Enable() + app.warn_modal(str(exc)) def set_coin(coin, network, wallet_type): - fee_opt_sel = app.gui_panel.fee_slider.GetValue() - app.gui_panel.fee_setting.SetLabel(FEES_PRORITY_TEXT[fee_opt_sel]) try: option_info = None option_arg = {} @@ -701,12 +487,12 @@ def set_coin(coin, network, wallet_type): opt_idx = coin_class.user_options.index(wallet_type) option_info = coin_class.options_data[opt_idx] option_preset = option_info.get("preset") - option_value = get_option(network, option_info["prompt"], option_preset) + option_value = app.get_option(network, option_info["prompt"], option_preset) if option_value is None: wx.CallAfter(wallet_fallback) return key_type = get_coin_class(coin).get_key_type(wallet_type) - if not check_coin_consistency(get_coin_class(coin), network): + if not app.check_coin_consistency(get_coin_class(coin), network): return if app.device.is_HD: current_path = ( @@ -723,258 +509,202 @@ def set_coin(coin, network, wallet_type): "confirm_callback": confirm_request, } app.wallet = get_coin_class(coin)(network, wallet_type, app.device, **option_arg) - if not check_coin_consistency(network_num=network): + if not app.check_coin_consistency(network_num=network): return account_id = app.wallet.get_account() - if not check_coin_consistency(network_num=network): + if not app.check_coin_consistency(network_num=network): return + app.gui_panel.btn_chkaddr.Enable() if option_info is not None and option_info.get("use_get_messages", False): app.wallet.wc_timer = wx.Timer() app.wallet.wc_timer.Notify = watch_messages except InvalidOption as exc: - warn_modal(str(exc)) + app.warn_modal(str(exc)) wx.CallAfter(wallet_fallback) return except Exception as exc: if str(exc).endswith("disconnected."): - device_error(exc) + app.device_error(exc) else: wallet_error(exc) return - if not check_coin_consistency(network_num=network): + if not app.check_coin_consistency(network_num=network): return - if app.device.has_screen: - app.gui_panel.btn_chkaddr.Show() + if app.gui_panel.network_choice.GetSelection() > 0 and app.current_chain != "GLMR": + # Testnet + app.wallet.coin = "t" + app.wallet.coin + app.gui_panel.scrolled_coins.Enable() + app.gui_panel.txt_fiat.SetLabel("$ 0") + + app.gui_panel.but_evt1.Enable() + app.gui_panel.but_evt2.Enable() + + # Detect is token or wallet connect + if coin in [ + "ETH", + "BSC", + "MATIC", + "FTM", + "OP", + "METIS", + "CELO", + "GLMR", + "ARB", + "AVAX", + ]: + if wallet_type == 1: + btn = app.token_started() + btn.Bind(wx.EVT_BUTTON, lambda x: process_coin_select(coin, network, 0)) + if wallet_type == 2: + btn = app.wc_started() + btn.Bind(wx.EVT_BUTTON, lambda x: process_coin_select(coin, network, 0)) + + app.gui_panel.fiat_panel.Hide() + if hasattr(app.gui_panel, "fiat_price"): + del app.gui_panel.fiat_price display_coin(account_id) def display_coin(account_addr): - imgbuf = BytesIO() - imgqr = qrcode.make( - account_addr, - error_correction=qrcode.constants.ERROR_CORRECT_L, - box_size=4, - border=3, - ) - imgqr.save(imgbuf, "PNG") - if not check_coin_consistency(): + if not app.check_coin_consistency(): return - app.gui_panel.account_addr.SetValue(account_addr) - imgbuf.seek(0) - wxi = wx.Image(imgbuf, type=wx.BITMAP_TYPE_PNG) - app.gui_panel.qrimg.SetScaleMode(wx.StaticBitmap.ScaleMode.Scale_None) # or Scale_AspectFit - app.gui_panel.qrimg.SetBitmap(wx.Bitmap(wxi)) + app.gui_panel.account_addr.SetLabel(account_addr) + app.gui_panel.qr_button.Enable() + app.gui_panel.copy_button.Enable() + app.gui_panel.hist_button.Enable() + app.gui_panel.balance_info.SetLabel(f" ... ") + app.gui_panel.account_addr.Layout() + if hasattr(app, "balance_timer"): + app.balance_timer.Stop() app.balance_timer = DisplayTimer() - wx.CallLater(50, display_balance) - app.balance_timer.Start(10000) + app.balance_timer.Start(12000) if hasattr(app.wallet, "wc_timer"): app.wallet.wc_timer.Start(2500, oneShot=wx.TIMER_CONTINUOUS) app.gui_frame.Refresh() app.gui_frame.Update() + app.gui_frame.Layout() + wx.CallAfter(app.display_balance) def process_coin_select(coin, sel_network, sel_wallettype): app.gui_panel.network_choice.Enable() - app.gui_panel.network_label.Enable() - if ( - app.gui_panel.coins_choice.IsEnabled() - or app.gui_panel.coins_choice.GetStringSelection() != "BTC" - ): + if len(app.gui_panel.scrolled_coins.GetChildren()) > 1 or app.current_chain != "BTC": # Because BTC wallet types are different path/wallet from SeedWatcher app.gui_panel.wallopt_choice.Enable() app.gui_panel.wallopt_label.Enable() + app.deactivate_option_buttons() + app.gui_panel.btn_chkaddr.Disable() + if coin in [ + "ETH", + "BSC", + "MATIC", + "FTM", + "OP", + "METIS", + "CELO", + "GLMR", + "ARB", + "AVAX", + ]: + app.activate_option_buttons() + app.gui_panel.but_evt1.Bind( + wx.EVT_BUTTON, lambda x: process_coin_select(coin, sel_network, 1) + ) + app.gui_panel.but_evt2.Bind( + wx.EVT_BUTTON, lambda x: process_coin_select(coin, sel_network, 2) + ) + app.gui_panel.wallopt_choice.Disable() + app.gui_panel.network_choice.Bind(wx.EVT_CHOICE, lambda x: net_selected(coin, x.GetInt())) + app.gui_panel.wallopt_choice.Bind(wx.EVT_CHOICE, lambda x: wtype_selected(coin, x)) set_coin(coin, sel_network, sel_wallettype) -def coin_selected(coin_sel): +def coin_selected(coin_name): app.gui_panel.network_choice.Clear() - app.gui_panel.wallopt_choice.Clear() - erase_info(True) - if coin_sel.GetInt() > 0: - coin_name = coin_sel.GetString() - networks = get_coin_class(coin_name).get_networks() - acc_types = get_coin_class(coin_name).get_account_types() - for netw in networks: - app.gui_panel.network_choice.Append(netw) - for wtype in acc_types: - app.gui_panel.wallopt_choice.Append(wtype) - sele_network = 0 - sele_wttype = 0 - app.gui_panel.network_choice.SetSelection(sele_network) - app.gui_panel.wallopt_choice.SetSelection(sele_wttype) - wx.CallLater(180, process_coin_select, coin_name, sele_network, sele_wttype) - - -def net_selected(net_sel): - erase_info() - coin_sel = app.gui_panel.coins_choice.GetStringSelection() + app.erase_info(True) + networks = get_coin_class(coin_name).get_networks() + acc_types = get_coin_class(coin_name).get_account_types() + for netw in networks: + app.gui_panel.network_choice.Append(netw) + app.add_wallet_types(acc_types) + sele_network = 0 + sele_wttype = 0 + app.gui_panel.network_choice.SetSelection(sele_network) + app.gui_panel.wallopt_choice.SetSelection(sele_wttype) + app.gui_panel.btn_chkaddr.Disable() + wx.CallLater(180, process_coin_select, coin_name, sele_network, sele_wttype) + + +def net_selected(coin_sel, net_sel): + app.erase_info() + app.gui_panel.btn_chkaddr.Disable() wtype_sel = app.gui_panel.wallopt_choice.GetSelection() - wx.CallLater(180, process_coin_select, coin_sel, net_sel.GetInt(), wtype_sel) + wx.CallLater(180, process_coin_select, coin_sel, net_sel, wtype_sel) -def wtype_selected(wtype_sel): - erase_info() - coin_sel = app.gui_panel.coins_choice.GetStringSelection() +def wtype_selected(coin_sel, wtype_sel): + app.erase_info() + app.gui_panel.btn_chkaddr.Disable() net_sel = app.gui_panel.network_choice.GetSelection() wx.CallLater(180, process_coin_select, coin_sel, net_sel, wtype_sel.GetInt()) -def fee_changed(feesel): - app.gui_panel.fee_setting.SetLabel(FEES_PRORITY_TEXT[feesel.GetSelection()]) - - -def paint_toaddr(color): - app.gui_panel.addr_panel.SetBackgroundColour(color) - - -def check_addr(ev): - ev.Skip() - paint_toaddr(wx.NullColour) - if not hasattr(app, "wallet"): - return - addr = ev.GetString() - if len(addr) < 7: - app.gui_frame.Refresh() - return - if app.wallet.check_address(addr): - paint_toaddr(GREEN_COLOR) - else: - paint_toaddr(RED_COLOR) - app.gui_frame.Refresh() - - -def transfer(to, amount): - conf = confirm_tx(to, amount) - if conf == wx.ID_YES: - fee_opt = app.gui_panel.fee_slider.GetValue() - try: - progress_modal = wx.ProgressDialog( - "Processing transaction", - "", - style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE | wx.PD_SMOOTH, - ) - wx.MilliSleep(50) - wait_msg = "Buiding and signing the transaction" - if app.wallet.current_device.has_hardware_button: - wait_msg += "\nPress the button on the physical device to confirm." - progress_modal.Update(50, wait_msg) - wx.MilliSleep(250) - if amount == "ALL": - tx_info = app.wallet.transfer_all(to, fee_opt) - else: - tx_info = app.wallet.transfer(amount, to, fee_opt) - progress_modal.Update(100, "done") - wx.MilliSleep(250) - tx_success(tx_info) - except Exception as exc: - progress_modal.Update(100) - wx.MilliSleep(100) - progress_modal.Destroy() - wx.MilliSleep(100) - logger.error( - "Error during the transaction processing : %s", - str(exc), - exc_info=exc, - stack_info=True, - ) - if str(exc).endswith("disconnected."): - device_error(exc) - elif str(exc) == "Error status : 0x6600": - warn_modal("User button on PGP device timeout") - else: - warn_modal(str(exc)) - wx.MilliSleep(250) - return - - -def send(ev): - ev.Skip() - if not app.gui_panel.send_button.IsEnabled(): - return - if not hasattr(app, "wallet"): - return - to = app.gui_panel.dest_addr.GetValue() - if not app.wallet.check_address(to): - warn_modal(BAD_ADDRESS) - return - sending_value_str = app.gui_panel.amount.GetValue() - if len(sending_value_str) <= 0: - warn_modal("Input an amount value to transfer.") - return - if sending_value_str[0] == "-": - warn_modal("Amount input must be positive or null.") - return +def perform_transfer(to, amnt, fees, status_modal): try: - float(sending_value_str) - except ValueError: - warn_modal("Unvalid amount input") - return - transfer(to, sending_value_str) - - -def send_all(ev): - ev.Skip() - if not hasattr(app, "wallet"): - return - to = app.gui_panel.dest_addr.GetValue() - if not app.wallet.check_address(to): - warn_modal(BAD_ADDRESS) - return - transfer(to, "ALL") - - -def end_checkwallet(modal, result): - wx.MilliSleep(200) - modal.Update(100, "done") - wx.MilliSleep(200) - if not result: - warn_modal("The address verification was rejected on the Ledger.") + if amnt == "ALL": + tx_info = app.wallet.transfer_all(to, fees) + else: + tx_info = app.wallet.transfer(amnt, to, fees) + status_modal.Update(100, "done") + status_modal.Fit() + tx_success(tx_info) + except Exception as exc: + status_modal.Update(100) + wx.MilliSleep(100) + status_modal.Destroy() + wx.MilliSleep(100) + logger.error( + "Error during the transaction processing : %s", + str(exc), + exc_info=exc, + stack_info=True, + ) + if str(exc).endswith("disconnected."): + app.device_error(exc) + elif str(exc) == "Error status : 0x6600": + app.warn_modal("User button on PGP device timeout") + else: + app.warn_modal(str(exc)) + wx.MilliSleep(250) -def check_wallet(evt): +def transfer(to, amount, fee_opt=1): progress_modal = wx.ProgressDialog( - "", + "Processing transaction", "", style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE | wx.PD_SMOOTH, + parent=app.gui_frame, ) - wx.MilliSleep(200) - wait_msg = "Verify the address on the Ledger screen." + wait_msg = "Buiding and signing the transaction" + if app.wallet.current_device.has_hardware_button: + wait_msg += "\nPress the button on the physical device to confirm." progress_modal.Update(50, wait_msg) - wx.MilliSleep(250) - try: - app.device.get_public_key(partial(end_checkwallet, progress_modal)) - except Exception as exc: - progress_modal.Update(100, "failure") - wx.MilliSleep(200) - wx.CallAfter(device_error, exc) + progress_modal.Fit() + wx.CallLater(250, perform_transfer, to, amount, fee_opt, progress_modal) def start_main_app(): - app.load_devices(DEVICES_LIST) - app.load_coins_list(SUPPORTED_COINS) - app.gui_panel.devices_choice.Bind(wx.EVT_CHOICE, device_selected) - app.gui_panel.coins_choice.Bind(wx.EVT_CHOICE, coin_selected) - app.gui_panel.network_choice.Bind(wx.EVT_CHOICE, net_selected) - app.gui_panel.wallopt_choice.Bind(wx.EVT_CHOICE, wtype_selected) - app.gui_panel.send_button.Bind(wx.EVT_BUTTON, send) - app.gui_panel.send_all.Bind(wx.EVT_BUTTON, send_all) - app.gui_panel.dest_addr.Bind(wx.EVT_TEXT, check_addr) - app.gui_panel.amount.Bind(wx.EVT_TEXT_ENTER, send) - app.gui_panel.hist_button.Bind(wx.EVT_BUTTON, disp_history) - app.gui_panel.copy_button.Bind(wx.EVT_BUTTON, copy_account) - app.gui_panel.fee_slider.Bind(wx.EVT_SCROLL_CHANGED, fee_changed) - app.gui_panel.btn_chkaddr.Bind(wx.EVT_BUTTON, check_wallet) - app.gui_panel.btn_chkaddr.Hide() - erase_info(True) - app.gui_frame.SetLabel(f"Uniblow - {VERSION}") + app.gui_frame.SetLabel(f" Uniblow - {VERSION}") app.gui_frame.Show() -app = gui.app.UniblowApp(VERSION) - - if __name__ == "__main__": + app = gui.app.UniblowApp(DEVICES_LIST, get_coin_class) + app.dev_selected = device_selected + app.coin_selected = coin_selected + app.transfer = transfer + if "-v" in argv[1:]: basicConfig(level=DEBUG) diff --git a/version.py b/version.py index 04857f6..dff03f4 100644 --- a/version.py +++ b/version.py @@ -1 +1,3 @@ -VERSION = "1.6.5" +# Shall be x.y.z, with optional dash trailing "-textstr" + +VERSION = "2.0.0-rc1" diff --git a/wallets/DOGEwallet.py b/wallets/DOGEwallet.py index e52dfe8..bbab576 100644 --- a/wallets/DOGEwallet.py +++ b/wallets/DOGEwallet.py @@ -99,7 +99,7 @@ def getKey(self, keychar): return out def get_fee(self, priority): - return int(10 ** DOGE_units) + return int(10**DOGE_units) def testaddr(doge_addr, is_testnet): diff --git a/wallets/EOSwallet.py b/wallets/EOSwallet.py index a5161e6..d50283c 100644 --- a/wallets/EOSwallet.py +++ b/wallets/EOSwallet.py @@ -345,7 +345,7 @@ def get_account(self): def get_balance(self): # Get balance in base integer unit if not self.eos.account: - return "Register this publickey\nin an account, and refresh." + return "Register publickey" bal_list = self.eos.getbalance() return bal_list[0] if len(bal_list) > 0 else f"0 {self.coin}" diff --git a/wallets/ETHwallet.py b/wallets/ETHwallet.py index 90624d3..ebff49b 100644 --- a/wallets/ETHwallet.py +++ b/wallets/ETHwallet.py @@ -165,14 +165,14 @@ def prepare(self, toaddr, paymentvalue, gprice, glimit, data=bytearray(b"")): maxspendable = self.getbalance(False) balance_eth = self.getbalance() if balance_eth < (gprice * glimit): - raise NotEnoughTokens("Not enough native ETH funding for the tx fee") + raise NotEnoughTokens("Not enough native gas for the tx fee") else: maxspendable = self.getbalance() - (gprice * glimit) if paymentvalue > maxspendable or paymentvalue < 0: if self.ERC20: sym = self.token_symbol else: - sym = "native ETH" + sym = "native gas" raise NotEnoughTokens(f"Not enough {sym} tokens for the tx") self.nonce = int2bytearray(self.getnonce()) self.gasprice = int2bytearray(gprice) @@ -288,10 +288,9 @@ class ETH_wallet: networks = [ "Mainnet", - "Rinkeby", - "Ropsten", "Kovan", "Goerli", + "Sepolia", ] wtypes = ["Standard", "ERC20", "WalletConnect"] @@ -341,22 +340,23 @@ def __init__( self.network = self.networks[network].lower() if self.network == "mainnet": self.chainID = 1 - if self.network == "ropsten": - self.chainID = 3 - if self.network == "rinkeby": - self.chainID = 4 if self.network == "goerli": self.chainID = 5 if self.network == "kovan": self.chainID = 42 + if self.network == "sepolia": + self.chainID = 11155111 INFURA_KEY = "xxx" # Put your Infura key here - if INFURA_KEY == "xxx" and self.network != "mainnet": + if INFURA_KEY == "xxx" and self.network != "mainnet" and self.network != "sepolia": raise Exception( - "To use Uniblow from source with an Ethereum testnet, bring your own Infura key." + "To use Uniblow from source with Goerli or Kovan, bring your own Infura key." ) if self.network == "mainnet": rpc_endpoint = "https://rpc.ankr.com/eth/" self.explorer = "https://etherscan.io/address/0x" + elif self.network == "sepolia": + rpc_endpoint = "https://rpc.sepolia.org" + self.explorer = "https://sepolia.etherscan.io/address/0x" else: rpc_endpoint = f"https://{self.network}.infura.io/v3/{INFURA_KEY}" self.explorer = f"https://{self.network}.etherscan.io/address/0x" diff --git a/wallets/XTZwallet.py b/wallets/XTZwallet.py index 8a1129e..8a9f1f7 100644 --- a/wallets/XTZwallet.py +++ b/wallets/XTZwallet.py @@ -283,8 +283,8 @@ class XTZ_wallet: networks = [ "Mainnet", - "HangzhouNet", "IthacaNet", + "JakartaNet", ] wtypes = [ @@ -350,7 +350,7 @@ def history(self): # Get history page if self.network == "mainnet": XTZ_EXPLORER_URL = f"https://tzstats.com/{self.xtz.address}#transfers" - else: # Granada[Net] and Hangzhou[Net] + else: XTZ_EXPLORER_URL = ( f"https://{self.network[:-3]}.tzstats.com/{self.xtz.address}#transfers" ) diff --git a/wallets/typed_data_hash.py b/wallets/typed_data_hash.py index 21a8686..fe15a0a 100644 --- a/wallets/typed_data_hash.py +++ b/wallets/typed_data_hash.py @@ -108,7 +108,7 @@ def encode_value(vtype, value, go): if value >= 0: intval_bin = uint256(value) else: - intval_bin = uint256(2 ** 256 + value) + intval_bin = uint256(2**256 + value) return intval_bin if vtype in bytes_types: if not isinstance(value, str):