From efd1fd6102582af8a0e03732eac1539064096ca9 Mon Sep 17 00:00:00 2001 From: xilanma Date: Thu, 20 Nov 2014 05:58:54 +0800 Subject: [PATCH] initial commit --- .gitignore | 15 + .travis.yml | 5 + AUTHORS | 11 + Info.plist | 22 + LICENCE | 674 ++++++ MANIFEST.in | 16 + README | 46 + RELEASE-NOTES | 257 ++ app.fil | 17 + contrib/build-wine/README | 13 + contrib/build-wine/archive.patch | 12 + contrib/build-wine/build-electrum-git.sh | 69 + contrib/build-wine/build-electrum.sh | 50 + contrib/build-wine/deterministic.spec | 65 + contrib/build-wine/electrum.nsi | 104 + contrib/build-wine/prepare-wine.sh | 68 + contrib/make_download | 43 + data/README | 12 + data/cleanlook/name.cfg | 1 + data/cleanlook/style.css | 62 + data/dark/name.cfg | 1 + data/dark/style.css | 35 + data/noface.svg | 162 ++ data/sahara/name.cfg | 1 + data/sahara/style.css | 102 + data/wordlist/english.txt | 2048 ++++++++++++++++ data/wordlist/japanese.txt | 2048 ++++++++++++++++ data/wordlist/portuguese.txt | 1654 +++++++++++++ data/wordlist/spanish.txt | 2048 ++++++++++++++++ docs/android.html | 60 + docs/cold_storage | 31 + docs/console.html | 71 + electrum | 473 ++++ electrum-ixc | 476 ++++ electrum-ixc.conf.sample | 18 + electrum-ixc.desktop | 17 + electrum-ixc.png | Bin 0 -> 9322 bytes electrum.conf.sample | 18 + electrum.desktop | 17 + electrum.icns | Bin 0 -> 673689 bytes electrum.png | Bin 0 -> 9322 bytes gui/__init__.py | 5 + gui/android.py | 1028 ++++++++ gui/gtk.py | 1368 +++++++++++ gui/qt/__init__.py | 226 ++ gui/qt/amountedit.py | 98 + gui/qt/console.py | 319 +++ gui/qt/history_widget.py | 25 + gui/qt/installwizard.py | 540 +++++ gui/qt/lite_window.py | 874 +++++++ gui/qt/main_window.py | 2822 ++++++++++++++++++++++ gui/qt/network_dialog.py | 249 ++ gui/qt/password_dialog.py | 175 ++ gui/qt/paytoedit.py | 242 ++ gui/qt/qrcodewidget.py | 134 + gui/qt/qrtextedit.py | 69 + gui/qt/qrwindow.py | 86 + gui/qt/receiving_widget.py | 77 + gui/qt/seed_dialog.py | 117 + gui/qt/transaction_dialog.py | 228 ++ gui/qt/util.py | 244 ++ gui/qt/version_getter.py | 121 + gui/stdio.py | 252 ++ gui/text.py | 482 ++++ icons.qrc | 33 + icons/clock1.png | Bin 0 -> 946 bytes icons/clock2.png | Bin 0 -> 944 bytes icons/clock3.png | Bin 0 -> 946 bytes icons/clock4.png | Bin 0 -> 962 bytes icons/clock5.png | Bin 0 -> 956 bytes icons/cold_seed.png | Bin 0 -> 9883 bytes icons/confirmed.png | Bin 0 -> 1267 bytes icons/copy.png | Bin 0 -> 2111 bytes icons/dark_background.png | Bin 0 -> 28057 bytes icons/electrum-ixc.png | Bin 0 -> 12642 bytes icons/electrum.ico | Bin 0 -> 17790 bytes icons/electrum.png | Bin 0 -> 9322 bytes icons/electrum_dark_icon.png | Bin 0 -> 3872 bytes icons/electrum_light_icon.png | Bin 0 -> 3869 bytes icons/expired.png | Bin 0 -> 27679 bytes icons/hot_seed.png | Bin 0 -> 9993 bytes icons/key.png | Bin 0 -> 5428 bytes icons/lock.png | Bin 0 -> 1994 bytes icons/lock.svg | 276 +++ icons/network.png | Bin 0 -> 3031 bytes icons/preferences.png | Bin 0 -> 1691 bytes icons/qrcode.png | Bin 0 -> 314 bytes icons/seed.png | Bin 0 -> 10322 bytes icons/status_connected.png | Bin 0 -> 1044 bytes icons/status_disconnected.png | Bin 0 -> 952 bytes icons/status_disconnected.svg | 292 +++ icons/status_lagging.png | Bin 0 -> 1036 bytes icons/status_waiting.png | Bin 0 -> 1501 bytes icons/status_waiting.svg | 397 +++ icons/switchgui.png | Bin 0 -> 1649 bytes icons/trustedcoin.png | Bin 0 -> 3727 bytes icons/unconfirmed.png | Bin 0 -> 1574 bytes icons/unconfirmed.svg | 562 +++++ icons/unlock.png | Bin 0 -> 2166 bytes icons/unlock.svg | 508 ++++ icons/unpaid.png | Bin 0 -> 28522 bytes lib/__init__.py | 16 + lib/account.py | 419 ++++ lib/auxpow.py | 224 ++ lib/bitcoin.py | 793 ++++++ lib/blockchain.py | 599 +++++ lib/bmp.py | 221 ++ lib/commands.py | 401 +++ lib/daemon.py | 228 ++ lib/i18n.py | 63 + lib/interface.py | 497 ++++ lib/mnemonic.py | 169 ++ lib/msqr.py | 94 + lib/network.py | 473 ++++ lib/network_proxy.py | 232 ++ lib/old_mnemonic.py | 1691 +++++++++++++ lib/paymentrequest.proto | 46 + lib/paymentrequest.py | 354 +++ lib/paymentrequest_pb2.py | 337 +++ lib/plugins.py | 111 + lib/qrscanner.py | 45 + lib/ripemd.py | 399 +++ lib/simple_config.py | 176 ++ lib/synchronizer.py | 196 ++ lib/tests/__init__.py | 0 lib/tests/test_bitcoin.py | 163 ++ lib/tests/test_simple_config.py | 241 ++ lib/tests/test_util.py | 65 + lib/tests/test_wallet.py | 164 ++ lib/transaction.py | 876 +++++++ lib/util.py | 356 +++ lib/verifier.py | 173 ++ lib/version.py | 9 + lib/wallet.py | 1747 ++++++++++++++ lib/x509.py | 228 ++ make_packages | 57 + mki18n.py | 63 + plugins/__init__.py | 1 + plugins/btchipwallet.py | 503 ++++ plugins/coinbase_buyback.py | 321 +++ plugins/cosigner_pool.py | 199 ++ plugins/exchange_rate.py | 679 ++++++ plugins/greenaddress_instant.py | 111 + plugins/labels.py | 247 ++ plugins/plot.py | 159 ++ plugins/trezor.py | 503 ++++ plugins/virtualkeyboard.py | 71 + pubkeys/Animazing.asc | 38 + pubkeys/ThomasV.asc | 87 + pubkeys/wozz.asc | 199 ++ scripts/block_headers | 29 + scripts/get_history | 16 + scripts/merchant/merchant.conf.template | 16 + scripts/merchant/merchant.py | 301 +++ scripts/merchant/merchant.readme | 36 + scripts/peers | 42 + scripts/servers | 28 + scripts/txradar | 20 + scripts/util.py | 71 + scripts/watch_address | 34 + setup-release.py | 93 + setup.py | 145 ++ 162 files changed, 38566 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 AUTHORS create mode 100644 Info.plist create mode 100644 LICENCE create mode 100644 MANIFEST.in create mode 100644 README create mode 100644 RELEASE-NOTES create mode 100644 app.fil create mode 100644 contrib/build-wine/README create mode 100644 contrib/build-wine/archive.patch create mode 100755 contrib/build-wine/build-electrum-git.sh create mode 100755 contrib/build-wine/build-electrum.sh create mode 100644 contrib/build-wine/deterministic.spec create mode 100644 contrib/build-wine/electrum.nsi create mode 100755 contrib/build-wine/prepare-wine.sh create mode 100755 contrib/make_download create mode 100644 data/README create mode 100644 data/cleanlook/name.cfg create mode 100644 data/cleanlook/style.css create mode 100644 data/dark/name.cfg create mode 100644 data/dark/style.css create mode 100644 data/noface.svg create mode 100644 data/sahara/name.cfg create mode 100644 data/sahara/style.css create mode 100644 data/wordlist/english.txt create mode 100644 data/wordlist/japanese.txt create mode 100644 data/wordlist/portuguese.txt create mode 100644 data/wordlist/spanish.txt create mode 100644 docs/android.html create mode 100644 docs/cold_storage create mode 100644 docs/console.html create mode 100755 electrum create mode 100755 electrum-ixc create mode 100644 electrum-ixc.conf.sample create mode 100644 electrum-ixc.desktop create mode 100644 electrum-ixc.png create mode 100644 electrum.conf.sample create mode 100644 electrum.desktop create mode 100644 electrum.icns create mode 100644 electrum.png create mode 100644 gui/__init__.py create mode 100644 gui/android.py create mode 100644 gui/gtk.py create mode 100644 gui/qt/__init__.py create mode 100644 gui/qt/amountedit.py create mode 100644 gui/qt/console.py create mode 100644 gui/qt/history_widget.py create mode 100644 gui/qt/installwizard.py create mode 100644 gui/qt/lite_window.py create mode 100644 gui/qt/main_window.py create mode 100644 gui/qt/network_dialog.py create mode 100644 gui/qt/password_dialog.py create mode 100644 gui/qt/paytoedit.py create mode 100644 gui/qt/qrcodewidget.py create mode 100644 gui/qt/qrtextedit.py create mode 100644 gui/qt/qrwindow.py create mode 100644 gui/qt/receiving_widget.py create mode 100644 gui/qt/seed_dialog.py create mode 100644 gui/qt/transaction_dialog.py create mode 100644 gui/qt/util.py create mode 100644 gui/qt/version_getter.py create mode 100644 gui/stdio.py create mode 100644 gui/text.py create mode 100644 icons.qrc create mode 100644 icons/clock1.png create mode 100644 icons/clock2.png create mode 100644 icons/clock3.png create mode 100644 icons/clock4.png create mode 100644 icons/clock5.png create mode 100644 icons/cold_seed.png create mode 100644 icons/confirmed.png create mode 100644 icons/copy.png create mode 100644 icons/dark_background.png create mode 100644 icons/electrum-ixc.png create mode 100644 icons/electrum.ico create mode 100644 icons/electrum.png create mode 100644 icons/electrum_dark_icon.png create mode 100644 icons/electrum_light_icon.png create mode 100644 icons/expired.png create mode 100644 icons/hot_seed.png create mode 100644 icons/key.png create mode 100644 icons/lock.png create mode 100644 icons/lock.svg create mode 100644 icons/network.png create mode 100644 icons/preferences.png create mode 100644 icons/qrcode.png create mode 100644 icons/seed.png create mode 100644 icons/status_connected.png create mode 100644 icons/status_disconnected.png create mode 100644 icons/status_disconnected.svg create mode 100644 icons/status_lagging.png create mode 100644 icons/status_waiting.png create mode 100644 icons/status_waiting.svg create mode 100644 icons/switchgui.png create mode 100644 icons/trustedcoin.png create mode 100644 icons/unconfirmed.png create mode 100644 icons/unconfirmed.svg create mode 100644 icons/unlock.png create mode 100644 icons/unlock.svg create mode 100644 icons/unpaid.png create mode 100644 lib/__init__.py create mode 100644 lib/account.py create mode 100644 lib/auxpow.py create mode 100644 lib/bitcoin.py create mode 100644 lib/blockchain.py create mode 100644 lib/bmp.py create mode 100644 lib/commands.py create mode 100644 lib/daemon.py create mode 100644 lib/i18n.py create mode 100644 lib/interface.py create mode 100644 lib/mnemonic.py create mode 100644 lib/msqr.py create mode 100644 lib/network.py create mode 100644 lib/network_proxy.py create mode 100644 lib/old_mnemonic.py create mode 100644 lib/paymentrequest.proto create mode 100644 lib/paymentrequest.py create mode 100644 lib/paymentrequest_pb2.py create mode 100644 lib/plugins.py create mode 100644 lib/qrscanner.py create mode 100644 lib/ripemd.py create mode 100644 lib/simple_config.py create mode 100644 lib/synchronizer.py create mode 100644 lib/tests/__init__.py create mode 100644 lib/tests/test_bitcoin.py create mode 100644 lib/tests/test_simple_config.py create mode 100644 lib/tests/test_util.py create mode 100644 lib/tests/test_wallet.py create mode 100644 lib/transaction.py create mode 100644 lib/util.py create mode 100644 lib/verifier.py create mode 100644 lib/version.py create mode 100644 lib/wallet.py create mode 100644 lib/x509.py create mode 100755 make_packages create mode 100755 mki18n.py create mode 100644 plugins/__init__.py create mode 100644 plugins/btchipwallet.py create mode 100644 plugins/coinbase_buyback.py create mode 100644 plugins/cosigner_pool.py create mode 100644 plugins/exchange_rate.py create mode 100644 plugins/greenaddress_instant.py create mode 100644 plugins/labels.py create mode 100644 plugins/plot.py create mode 100644 plugins/trezor.py create mode 100644 plugins/virtualkeyboard.py create mode 100644 pubkeys/Animazing.asc create mode 100644 pubkeys/ThomasV.asc create mode 100644 pubkeys/wozz.asc create mode 100755 scripts/block_headers create mode 100755 scripts/get_history create mode 100644 scripts/merchant/merchant.conf.template create mode 100644 scripts/merchant/merchant.py create mode 100644 scripts/merchant/merchant.readme create mode 100755 scripts/peers create mode 100755 scripts/servers create mode 100755 scripts/txradar create mode 100644 scripts/util.py create mode 100755 scripts/watch_address create mode 100644 setup-release.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..87d61407 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +####-*.patch +gui/icons_rc.py +lib/icons_rc.py +*.pyc +*.swp +build/ +dist/ +*.egg/ +/electrum.py +contrib/pyinstaller/ +Electrum.egg-info/ +gui/qt/icons_rc.py +locale/ +.devlocaltmp/ +*_trial_temp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e40b20bf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: python +python: + - "2.7" +install: "pip install slowaes==0.1a1 ecdsa>=0.9 pbkdf2 requests pyasn1 pyasn1-modules tlslite>=0.4.5 qrcode SocksiPy-branch" +script: nosetests -e gui diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..29c23f6a --- /dev/null +++ b/AUTHORS @@ -0,0 +1,11 @@ +ThomasV - Creator and maintainer. +Animazing / Tachikoma - Styled the new GUI. Mac version. +Azelphur - GUI stuff. +Coblee - Alternate coin support and py2app support. +Deafboy - Ubuntu packages. +EagleTM - Bugfixes. +ErebusBat - Mac distribution. +Genjix - Porting pro-mode functionality to lite-gui and worked on server +Slush - Work on the server. Designed the original Stratum spec. +Julian Toash (Tuxavant) - Various fixes to the client. +rdymac - Website and translations. diff --git a/Info.plist b/Info.plist new file mode 100644 index 00000000..90583adf --- /dev/null +++ b/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleURLTypes + + + CFBundleURLName + ixcoin + CFBundleURLSchemes + + ixcoin + + + + LSArchitecturePriority + + i386 + x86_64 + + + diff --git a/LICENCE b/LICENCE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/LICENCE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..cffa5763 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,16 @@ +include README LICENCE RELEASE-NOTES AUTHORS +include electrum-ixc.conf.sample +include electrum-ixc.desktop +include *.py +include electrum-ixc +recursive-include lib *.py +recursive-include gui *.py +recursive-include plugins *.py +recursive-include packages *.py +include app.fil +include icons.qrc +recursive-include icons * +recursive-include scripts * +recursive-include data * +recursive-include locale *.mo +recursive-include docs * diff --git a/README b/README new file mode 100644 index 00000000..0261ad14 --- /dev/null +++ b/README @@ -0,0 +1,46 @@ +** base58-encoded Ixcoin addresses. +Public-key-hash-addresses have version 138 (or 111 testnet). + +Licence: GNU GPL v3 +Author: Thomas Voegtlin +Language: Python +Homepage: https://ixco.in/electrum + + +1. GETTING STARTED +------------------ + +To run Electrum from this directory, just do: + + ./electrum-ixc + +If you install Electrum on your system, you can run it from any +directory: + + sudo python setup.py install + electrum-ixc + + +To start Electrum from your web browser, see +http://electrum.org/bitcoin_URIs.html + + + +2. HOW OFFICIAL PACKAGES ARE CREATED +------------------------------------ + +python mki18n.py +pyrcc4 icons.qrc -o gui/qt/icons_rc.py +python setup.py sdist --format=zip,gztar + +On Mac OS X: + + # On port based installs + sudo python setup-release.py py2app + + # On brew installs + ARCHFLAGS="-arch i386 -arch x86_64" sudo python setup-release.py py2app --includes sip + + sudo hdiutil create -fs HFS+ -volname "Electrum-IXC" -srcfolder dist/Electrum-IXC.app dist/electrum-ixc-VERSION-macosx.dmg + + diff --git a/RELEASE-NOTES b/RELEASE-NOTES new file mode 100644 index 00000000..ce7338f0 --- /dev/null +++ b/RELEASE-NOTES @@ -0,0 +1,257 @@ +# Release 2.0 + + * New address derivation (BIP39 + BIP32 + BIP44). + + * 8 bits of the seed phrase are used to store a version number. The + current version number (0x01) refers to the current wallet + structure (BIP44). The version number also serves as a checksum for + the seed, and it will prevent the import of seeds from incompatible + wallets. + + * New serialization format for unsigned or partially signed + transactions, that includes the master public key and derivation + needed to sign inputs. This new format is compact enough to + send transactions to cold storage using QR codes + + * Deterministic Multisig wallets using parallel BIP32 derivations and + P2SH addresses (2 of 2, 2 of 3). + + * New plugins: + - Trezor: support for the Trezor hardware wallet by SatoshiLabs + - Cosigner Pool: shared memory pool for partially signed transactions + + * BIP70: verification of signed payment requests + - Verification is pure python, using tlslite. + - In the GUI, payment requests are in the 'Invoices' tab. + + * New 'Receive' tab: + - create and manage payment requests, with QR Codes + - the former Receive tab was renamed to 'Addresses' + - the former Point of Sale plugin is replaced by a resizeable + window that pops up if you click on the QR code + + * The 'Send' tab in the Qt GUI supports transactions with multiple + outputs, and with OP_RETURN "message" + + * The GUI can use the daemon: "electrum -d". The daemon can serve + several clients. It times out if no client uses if for more than 5 + minutes. + + * Wallet files are saved as JSON instead of Python. + + * Documentation is now hosted on a wiki: http://electrum.orain.org + + + +# Release 1.9.8 + +* Electrum servers were upgraded to version 0.9. The new server stores + a Patrica tree of all UTXOs, an idea proposed by Alan Reiner in the + bitcointalk forum. This property allows the client to directly + request the balance of any address. The new commands are: + 1. getaddressbalance
+ 2. getaddressunspent
+ 3. getutxoaddress + +* Command-line commands that require a connection to the network spawn + a daemon, that remains connected and handles subsequent + commands. The daemon terminates itself if it remains unused for more + than one minute. The purpose of this is to make scripting more + efficient. For example, a bash script using many electrum commands + will open only one connection. + +# Release 1.9.7 +* Fix for offline signing +* Various bugfixes +* GUI usability improvements +* Coinbase Buyback plugin + +# Release 1.9.6 +* During wallet creation, do not write seed to disk until it is encrypted. +* Confirmation dialog if the transaction fee is higher than 1mBTC. +* bugfixes + +# Release 1.9.5 + +* Coin control: select addresses to send from +* Put addresses that have been used in a minimized section (Qt GUI) +* Allow non ascii chars in passwords + + +# Release 1.9.4 +bugfixes: offline transactions + +# Release 1.9.3 +bugfixes: connection problems, transactions staying unverified + +# Release 1.9.2 +* fix a syntax error + +# Release 1.9.1 +* fix regression with --offline mode +* fix regression with --portable mode: use a dedicated directory + +# Release 1.9 + +* The client connects to multiple servers in order to retrieve block headers and find the longest chain +* SSL certificate validation (to prevent MITM) +* Deterministic signatures (RFC 6979) +* Menu to create/restore/open wallets +* Create transactions with multiple outputs from CSV (comma separated values) +* New text gui: stdio +* Plugins are no longer tied to the qt GUI, they can reach all GUIs +* Proxy bugs have been fixed + + +# Release 1.8.1 + +* Notification option when receiving new tranactions +* Confirm dialogue before sending large amounts +* Alternative datafile location for non-windows systems +* Fix offline wallet creation +* Remove enforced tx fee +* Tray icon improvements +* Various bugfixes + + +# Release 1.8 + +* Menubar in classic gui +* Updated the QR Code plugin to enable offline/online wallets to transmit unsigned/signed transactions via QR code. +* Fixed bug where never-confirmed transactions prevented further spending + + +# Release 1.7.4 + +* Increase default fee +* fix create and restore in command line +* fix verify message in the gui + + +# Release 1.7.3: + +* Classic GUI can display amounts in mBTC +* Account selector in the classic GUI +* Changed the way the portable flag uses without supplying a -w argument +* Classic GUI asks users to enter their seed on wallet creation + + +# Release 1.7.2: + +* Transactions that are in the same block are displayed in chronological order in the history. +* The client computes transaction priority and rejects zero-fee transactions that need a fee. +* The default fee was lowered to 200 uBTC per kb. +* Due to an internal format change, your history may be pruned when + you open your wallet for the first time after upgrading to 1.7.2. If + this is the case, please visit a full server to restore your full + history. You will only need to do that once. + + +# Release 1.7.1: bugfixes. + + +# Release 1.7 + +* The Classic GUI can be extended with plugins. Developers who want to +add new features or third-party services to Electrum are invited to +write plugins. Some previously existing and non-essential features of +Electrum (point-of-sale mode, qrcode scanner) were removed from the +core and are now available as plugins. + +* The wallet waits for 2 confirmations before creating new +addresses. This makes recovery from seed more robust. Note that it +might create unwanted gaps if you use Electrum 1.7 together with older +versions of Electrum. + +* An interactive Python console replaces the 'Wall' tab. The provided +python environment gives users access to the wallet and gui. Most +electrum commands are available as python function in the +console. Custom scripts an be loaded with a "run(filename)" +command. Tab-completions are available. + +* The location of the Electrum folder in Windows changed from +LOCALAPPDATA to APPDATA. Discussion on this topic can be found here: +https://bitcointalk.org/index.php?topic=144575.0 + +* Private keys can be exported from within the classic GUI: + For a single address, use the address menu (right-click). + To export the keys of your entire wallet, use the settings dialog (import/export tab). + +* It is possible to create, sign and redeem multisig transaction using the +command line interface. This is made possible by the following new commands: + dumpprivkey, listunspent, createmultisig, createrawtransaction, decoderawtransaction, signrawtransaction +The syntax of these commands is similar to their bitcoind counterpart. +For an example, see Gavin's tutorial: https://gist.github.com/gavinandresen/3966071 + +* Offline wallets now work in a way similar to Armory: + 1. user creates an unsigned transaction using the online (watching-only) wallet. + 2. unsigned transaction is copied to the offline computer, and signed by the offline wallet. + 3. signed transaction is copied to the online computer, broadcasted by the online client. + 4. All these steps can be done via the command line interface or the classic GUI. + +* Many command line commands have been renamed in order to make the syntax consistent with bitcoind. + +# Release 1.6.2 + +== Classic GUI +* Added new version notification + +# Release 1.6.1 (11-01-2013) + +== Core +* It is now possible to restore a wallet from MPK (this will create a watching-only wallet) +* A switch button allows to easily switch between Lite and Classic GUI. + +== Classic GUI +* Seed and MPK help dialogs were rewritten +* Point of Sale: requested amounts can be expressed in other currencies and are converted to bitcoin. + +== Lite GUI +* The receiving button was removed in favor of a menu item to keep it consistent with the history toggle. + +# Release 1.6.0 (07-01-2013) + +== Core +* (Feature) Add support for importing, signing and verifiying compressed keys +* (Feature) Auto reconnect to random server on disconnect +* (Feature) Ultimate fallback to HTTP port 80 if TCP doesn't work on any server +* (Bug) Under rare circumstances changing password with incorrect password could damage wallet + +== Lite GUI +* (Chore) Use blockchain.info for exchange rate data +* (Feature) added currency conversion for BRL, CNY, RUB +* (Feature) Saraha theme +* (Feature) csv import/export for transactions including labels + +== Classic GUI +* (Chore) pruning servers now called "p", full servers "f" to avoid confusion with terms +* (Feature) Debits in history shown in red +* (Feature) csv import/export for transactions including labels + +# Release 1.5.8 (02-01-2013) + +== Core +* (Bug) Fix pending address balance on received coins for pruning servers +* (Bug) Fix history command line option to show output again (regression by SPV) +* (Chore) Add timeout to blockchain headers file download by HTTP +* (Feature) new option: -L, --language: default language used in GUI. + +== Lite GUI +* (Bug) Sending to auto-completed contacts works again +* (Chore) Added version number to title bar + +== Classic GUI +* (Feature) Language selector in options. + +# Release 1.5.7 (18-12-2012) + +== Core +* The blockchain headers file is no longer included in the packages, it is downloaded on startup. +* New command line option: -P or --portable, for portable wallets. With this flag, all preferences are saved to the wallet file, and the blockchain headers file is in the same directory as the wallet + +== Lite GUI +* (Feature) Added the ability to export your transactions to a CSV file. +* (Feature) Added a label dialog after sending a transaction. +* (Feature) Reworked receiving addresses; instead of a random selection from one of your receiving addresses a new widget will show listing unused addresses. +* (Chore) Removed server selection. With all the new server options a simple menu item does not suffice anymore. + diff --git a/app.fil b/app.fil new file mode 100644 index 00000000..1b392ff3 --- /dev/null +++ b/app.fil @@ -0,0 +1,17 @@ +gui/gtk.py +gui/qt/main_window.py +gui/qt/lite_window.py +gui/qt/history_widget.py +gui/qt/installwizard.py +gui/qt/network_dialog.py +gui/qt/password_dialog.py +gui/qt/util.py +gui/qt/receiving_widget.py +gui/qt/seed_dialog.py +gui/qt/transaction_dialog.py +gui/qt/version_getter.py +plugins/aliases.py +plugins/pointofsale.py +plugins/labels.py +plugins/qrscanner.py +plugins/virtualkeyboard.py diff --git a/contrib/build-wine/README b/contrib/build-wine/README new file mode 100644 index 00000000..73b58845 --- /dev/null +++ b/contrib/build-wine/README @@ -0,0 +1,13 @@ +These scripts can be used for cross-compilation of Windows Electrum executables from Linux/Wine. + +Usage: +1. Copy content of this directory to /build-wine. +2. Install Wine (version 1.4 or 1.5+ works fine, 1.4.1 has bug). +3. Run "./prepare-wine.sh", it will download all dependencies. When you'll be asked, always leave default settings and press "Next >". +4. By running "./build-electrum.sh", sources will be packed into three separate versions to dist/ directory: + * Standalone compressed executable is "dist/electrum.exe" + * Uncompressed binaries are in "dist/electrum". They're useful for comparsion with other builds. + * NSIS-based installer of Electrum is "electrum-setup.exe" +7. Everytime you want to rebuild new version of Electrum just change the path to ZIP file in "build-electrum.sh" and re-run the script. + +For more information contact: slush diff --git a/contrib/build-wine/archive.patch b/contrib/build-wine/archive.patch new file mode 100644 index 00000000..e9513527 --- /dev/null +++ b/contrib/build-wine/archive.patch @@ -0,0 +1,12 @@ +252a253,255 +> class NoZlib: +> def decompress(self, data): +> return data +253a257,259 +> def compress(self, data, lvl): +> return data +> +316c322 +< zlib = DummyZlib() +--- +> zlib = NoZlib() diff --git a/contrib/build-wine/build-electrum-git.sh b/contrib/build-wine/build-electrum-git.sh new file mode 100755 index 00000000..279b364d --- /dev/null +++ b/contrib/build-wine/build-electrum-git.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# You probably need to update only this link +ELECTRUM_GIT_URL=git://github.com/spesmilo/electrum.git +BRANCH=master +NAME_ROOT=electrum + +# These settings probably don't need any change +export WINEPREFIX=/opt/wine-electrum +PYHOME=c:/python26 +PYTHON="wine $PYHOME/python.exe -OO -B" + +# Let's begin! +cd `dirname $0` +set -e + +cd tmp + +if [ -d "electrum-git" ]; then + # GIT repository found, update it + echo "Pull" + + cd electrum-git + git pull + cd .. + +else + # GIT repository not found, clone it + echo "Clone" + + git clone -b $BRANCH $ELECTRUM_GIT_URL electrum-git +fi + +cd electrum-git +COMMIT_HASH=`git rev-parse HEAD | awk '{ print substr($1, 0, 11) }'` +echo "Last commit: $COMMIT_HASH" +cd .. + + +rm -rf $WINEPREFIX/drive_c/electrum +cp -r electrum-git $WINEPREFIX/drive_c/electrum +cp electrum-git/LICENCE . + +# Build Qt resources +wine $WINEPREFIX/drive_c/Python26/Lib/site-packages/PyQt4/pyrcc4.exe C:/electrum/icons.qrc -o C:/electrum/lib/icons_rc.py + +# Copy ZBar libraries to electrum +#cp "$WINEPREFIX/drive_c/Program Files (x86)/ZBar/bin/"*.dll "$WINEPREFIX/drive_c/electrum/" + +cd .. + +rm -rf dist/ + +# For building standalone compressed EXE, run: +$PYTHON "C:/pyinstaller/pyinstaller.py" --noconfirm --ascii -w --onefile "C:/electrum/electrum" + +# For building uncompressed directory of dependencies, run: +$PYTHON "C:/pyinstaller/pyinstaller.py" --noconfirm --ascii -w deterministic.spec + +# For building NSIS installer, run: +wine "$WINEPREFIX/drive_c/Program Files (x86)/NSIS/makensis.exe" electrum.nsi +#wine $WINEPREFIX/drive_c/Program\ Files\ \(x86\)/NSIS/makensis.exe electrum.nsis + +DATE=`date +"%Y%m%d"` +cd dist +mv electrum.exe $NAME_ROOT-$DATE-$COMMIT_HASH.exe +mv electrum $NAME_ROOT-$DATE-$COMMIT_HASH +mv electrum-setup.exe $NAME_ROOT-$DATE-$COMMIT_HASH-setup.exe +zip -r $NAME_ROOT-$DATE-$COMMIT_HASH.zip $NAME_ROOT-$DATE-$COMMIT_HASH diff --git a/contrib/build-wine/build-electrum.sh b/contrib/build-wine/build-electrum.sh new file mode 100755 index 00000000..99272cdf --- /dev/null +++ b/contrib/build-wine/build-electrum.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# You probably need to update only this link +ELECTRUM_URL=http://electrum.bitcoin.cz/download/Electrum-1.6.1.tar.gz +NAME_ROOT=electrum-1.6.1 + +# These settings probably don't need any change +export WINEPREFIX=/opt/wine-electrum +PYHOME=c:/python26 +PYTHON="wine $PYHOME/python.exe -OO -B" + +# Let's begin! +cd `dirname $0` +set -e + +cd tmp + +# Download and unpack Electrum +wget -O electrum.tgz "$ELECTRUM_URL" +tar xf electrum.tgz +mv Electrum-* electrum +rm -rf $WINEPREFIX/drive_c/electrum +cp electrum/LICENCE . +mv electrum $WINEPREFIX/drive_c + +# Copy ZBar libraries to electrum +#cp "$WINEPREFIX/drive_c/Program Files (x86)/ZBar/bin/"*.dll "$WINEPREFIX/drive_c/electrum/" + +cd .. + +rm -rf dist/$NAME_ROOT +rm -f dist/$NAME_ROOT.zip +rm -f dist/$NAME_ROOT.exe +rm -f dist/$NAME_ROOT-setup.exe + +# For building standalone compressed EXE, run: +$PYTHON "C:/pyinstaller/pyinstaller.py" --noconfirm --ascii -w --onefile "C:/electrum/electrum" + +# For building uncompressed directory of dependencies, run: +$PYTHON "C:/pyinstaller/pyinstaller.py" --noconfirm --ascii -w deterministic.spec + +# For building NSIS installer, run: +wine "$WINEPREFIX/drive_c/Program Files (x86)/NSIS/makensis.exe" electrum.nsi +#wine $WINEPREFIX/drive_c/Program\ Files\ \(x86\)/NSIS/makensis.exe electrum.nsis + +cd dist +mv electrum.exe $NAME_ROOT.exe +mv electrum $NAME_ROOT +mv electrum-setup.exe $NAME_ROOT-setup.exe +zip -r $NAME_ROOT.zip $NAME_ROOT diff --git a/contrib/build-wine/deterministic.spec b/contrib/build-wine/deterministic.spec new file mode 100644 index 00000000..50f2d028 --- /dev/null +++ b/contrib/build-wine/deterministic.spec @@ -0,0 +1,65 @@ +# -*- mode: python -*- + +# We don't put these files in to actually include them in the script but to make the Analysis method scan them for imports +a = Analysis(['electrum-ixc', 'gui/qt/main_window.py', 'gui/qt/lite_window.py', 'gui/text.py', + 'lib/util.py', 'lib/wallet.py', 'lib/simple_config.py', + 'lib/bitcoin.py', 'lib/blockchain.py' + ], + hiddenimports=["lib","gui"], + pathex=['lib:gui:plugins'], + hookspath=None) + +##### include mydir in distribution ####### +def extra_datas(mydir): + def rec_glob(p, files): + import os + import glob + for d in glob.glob(p): + if os.path.isfile(d): + files.append(d) + rec_glob("%s/*" % d, files) + files = [] + rec_glob("%s/*" % mydir, files) + extra_datas = [] + for f in files: + extra_datas.append((f, f, 'DATA')) + + return extra_datas +########################################### + +# append dirs + +# Theme data +a.datas += extra_datas('data') + +# Localization +a.datas += extra_datas('locale') + +# Py folders that are needed because of the magic import finding +a.datas += extra_datas('gui') +a.datas += extra_datas('lib') +a.datas += extra_datas('plugins') + +pyz = PYZ(a.pure) +exe = EXE(pyz, + a.scripts, + a.binaries, + a.datas, + name=os.path.join('build\\pyi.win32\\electrum-ixc', 'electrum-ixc.exe'), + debug=False, + strip=None, + upx=False, + icon='icons/electrum.ico', + console=False) + # The console True makes an annoying black box pop up, but it does make Electrum output command line commands, with this turned off no output will be given but commands can still be used + +coll = COLLECT(exe, + a.binaries, + a.zipfiles, + a.datas, + strip=None, + upx=True, + debug=False, + icon='icons/electrum.ico', + console=False, + name=os.path.join('dist', 'electrum')) diff --git a/contrib/build-wine/electrum.nsi b/contrib/build-wine/electrum.nsi new file mode 100644 index 00000000..33a1d4c9 --- /dev/null +++ b/contrib/build-wine/electrum.nsi @@ -0,0 +1,104 @@ +;-------------------------------- +;Include Modern UI + + !include "MUI2.nsh" + +;-------------------------------- +;General + + ;Name and file + Name "Electrum-IXC" + OutFile "dist/electrum-ixc-setup.exe" + + ;Default installation folder + InstallDir "$PROGRAMFILES\Electrum-IXC" + + ;Get installation folder from registry if available + InstallDirRegKey HKCU "Software\Electrum-IXC" "" + + ;Request application privileges for Windows Vista + RequestExecutionLevel admin + +;-------------------------------- +;Variables + +;-------------------------------- +;Interface Settings + + !define MUI_ABORTWARNING + +;-------------------------------- +;Pages + + ;!insertmacro MUI_PAGE_LICENSE "tmp/LICENCE" + ;!insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + + ;Start Menu Folder Page Configuration + !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" + !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Electrum-IXC" + !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" + + ;!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder + + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Installer Sections + +Section + + SetOutPath "$INSTDIR" + + ;ADD YOUR OWN FILES HERE... + file /r dist\electrum-ixc\*.* + + ;Store installation folder + WriteRegStr HKCU "Software\Electrum-IXC" "" $INSTDIR + + ;Create uninstaller + WriteUninstaller "$INSTDIR\Uninstall.exe" + + + CreateShortCut "$DESKTOP\Electrum-IXC.lnk" "$INSTDIR\electrum-ixc.exe" "" + + ;create start-menu items + CreateDirectory "$SMPROGRAMS\Electrum-IXC" + CreateShortCut "$SMPROGRAMS\Electrum-IXC\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\Electrum-IXC\Electrum-IXC.lnk" "$INSTDIR\electrum-ixc.exe" "" "$INSTDIR\electrum-ixc.exe" 0 + +SectionEnd + +;-------------------------------- +;Descriptions + + ;Assign language strings to sections + ;!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + ; !insertmacro MUI_DESCRIPTION_TEXT ${SecDummy} $(DESC_SecDummy) + ;!insertmacro MUI_FUNCTION_DESCRIPTION_END + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + + ;ADD YOUR OWN FILES HERE... + RMDir /r "$INSTDIR\*.*" + + RMDir "$INSTDIR" + + Delete "$DESKTOP\Electrum-IXC.lnk" + Delete "$SMPROGRAMS\Electrum-IXC\*.*" + RmDir "$SMPROGRAMS\Electrum-IXC" + + DeleteRegKey /ifempty HKCU "Software\Electrum-IXC" + +SectionEnd diff --git a/contrib/build-wine/prepare-wine.sh b/contrib/build-wine/prepare-wine.sh new file mode 100755 index 00000000..6764ae7b --- /dev/null +++ b/contrib/build-wine/prepare-wine.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Please update these links carefully, some versions won't work under Wine +PYTHON_URL=http://www.python.org/ftp/python/2.6.6/python-2.6.6.msi +PYQT4_URL=http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.9.5/PyQt-Py2.6-x86-gpl-4.9.5-1.exe +PYWIN32_URL=http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win32-py2.6.exe/download +PYINSTALLER_URL=http://downloads.sourceforge.net/project/pyinstaller/2.0/pyinstaller-2.0.zip +NSIS_URL=http://prdownloads.sourceforge.net/nsis/nsis-2.46-setup.exe?download +#ZBAR_URL=http://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10-setup.exe/download + +# These settings probably don't need change +export WINEPREFIX=/opt/wine-electrum +PYHOME=c:/python26 +PYTHON="wine $PYHOME/python.exe -OO -B" + +# Let's begin! +cd `dirname $0` +set -e + +# Clean up Wine environment +echo "Cleaning $WINEPREFIX" +rm -rf $WINEPREFIX/* +echo "done" + +echo "Cleaning tmp" +rm -rf tmp +mkdir -p tmp +echo "done" + +cd tmp + +# Install Python +wget -O python.msi "$PYTHON_URL" +msiexec /q /i python.msi + +# Install PyWin32 +wget -O pywin32.exe "$PYWIN32_URL" +wine pywin32.exe + +# Install PyQt4 +wget -O PyQt.exe "$PYQT4_URL" +wine PyQt.exe + +#cp -r /electrum-wine/pyinstaller $WINEPREFIX/drive_c/ +# Install pyinstaller +wget -O pyinstaller.zip "$PYINSTALLER_URL" +unzip pyinstaller.zip +mv pyinstaller-2.0 $WINEPREFIX/drive_c/pyinstaller + +# Patch pyinstaller's DummyZlib +patch $WINEPREFIX/drive_c/pyinstaller/PyInstaller/loader/archive.py < ../archive.patch + +# Install ZBar +#wget -q -O zbar.exe "http://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10-setup.exe/download" +#wine zbar.exe + +# Install dependencies +wget -q -O - "http://python-distribute.org/distribute_setup.py" | $PYTHON +wine "$PYHOME\\Scripts\\easy_install.exe" ecdsa slowaes #zbar + +# Install NSIS installer +wget -q -O nsis.exe "http://prdownloads.sourceforge.net/nsis/nsis-2.46-setup.exe?download" +wine nsis.exe + +# Install UPX +#wget -O upx.zip "http://upx.sourceforge.net/download/upx308w.zip" +#unzip -o upx.zip +#cp upx*/upx.exe . diff --git a/contrib/make_download b/contrib/make_download new file mode 100755 index 00000000..8d0d2f30 --- /dev/null +++ b/contrib/make_download @@ -0,0 +1,43 @@ +#!/usr/bin/python +import sys +import hashlib +import os + +from versions import version, version_win, version_mac, template_path, dl_path + +with open(template_path) as f: + string = f.read() + +_tgz = "Electrum-%s.tar.gz" % version +_zip = "Electrum-%s.zip" % version + +_mac = "electrum-%s.dmg" % version_mac +_win = "electrum-%s.exe" % version_win +_win_setup = "electrum-%s-setup.exe" % version_win +_win_portable = "electrum-%s-portable.exe" % version_win + +md5_tgz = hashlib.md5(file('dist/'+_tgz, 'r').read()).digest().encode('hex') +md5_zip = hashlib.md5(file('dist/'+_zip, 'r').read()).digest().encode('hex') + +for n in [_win, _win_portable, _win_setup, _mac]: + if not os.path.exists("binaries/%s" % n): + os.system("wget http://download.electrum.org/download/%s -O binaries/%s" % (n, n)) + +md5_mac = hashlib.md5(file('binaries/'+_mac, 'r').read()).digest().encode('hex') +md5_win = hashlib.md5(file('binaries/'+_win, 'r').read()).digest().encode('hex') +md5_win_setup = hashlib.md5(file('binaries/'+_win_setup, 'r').read()).digest().encode('hex') +md5_win_portable = hashlib.md5(file('binaries/'+_win_portable, 'r').read()).digest().encode('hex') + +string = string.replace("##VERSION##", version) +string = string.replace("##VERSION_WIN##", version_win) +string = string.replace("##VERSION_MAC##", version_mac) +string = string.replace("##md5_tgz##", md5_tgz) +string = string.replace("##md5_zip##", md5_zip) +string = string.replace("##md5_mac##", md5_mac) +string = string.replace("##md5_win##", md5_win) +string = string.replace("##md5_win_setup##", md5_win_setup) +string = string.replace("##md5_win_portable##", md5_win_portable) + +with open(dl_path,'w') as f: + f.write(string) + diff --git a/data/README b/data/README new file mode 100644 index 00000000..03254ac6 --- /dev/null +++ b/data/README @@ -0,0 +1,12 @@ +To add a new theme, simply create a new directory in the electrum data directory (either ./data or your system wide local data). + +Inside your directory create a file called name.cfg with the name of that theme. + +Create another file called style.css - this will be your CSS for the theme (see other themes for reference). + +Documentation on Qt's stylesheets (used by Electrum): + +Overview: http://qt-project.org/doc/qt-4.8/stylesheet.html +Examples: http://qt-project.org/doc/qt-4.8/stylesheet-examples.html +Reference manual: http://doc.qt.nokia.com/4.7-snapshot/stylesheet-reference.html + diff --git a/data/cleanlook/name.cfg b/data/cleanlook/name.cfg new file mode 100644 index 00000000..475ba47b --- /dev/null +++ b/data/cleanlook/name.cfg @@ -0,0 +1 @@ +Cleanlook diff --git a/data/cleanlook/style.css b/data/cleanlook/style.css new file mode 100644 index 00000000..888cbcf9 --- /dev/null +++ b/data/cleanlook/style.css @@ -0,0 +1,62 @@ +#main_window +{ + background: qlineargradient(x1: 0, y1: 0, x2:0,y2:1, stop: 0 white , stop: 1 #E8E8E8); +} + +MiniWindow QPushButton { + color: #777; + border: 1px solid #CCC; + border-radius: 0px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 white, stop: 1 #E6E6E6); + min-height: 30px; + min-width: 30px; +} + +#send_button{ + color: #FFF; + border: 1px solid #3786E6; + border-radius: 4px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #72B2F8, stop: 1 #3484E6); + padding: 2px; + width: 20px; +} + +#send_button:disabled{ + color: #D3E8FE; + border: 1px solid #6DAEF7; + border-radius: 4px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #A5CFFA, stop: 1 #72B2F8); +} +#address_input, #amount_input, #label_input +{ + color: #000; + padding: 5px; + border-radius: 5px; + min-height: 23px; + border: 1px solid #AAA9A9; + width: 200px; +} + +#address_input[isValid=true] +{ + color: #4D9948; +} + +#address_input[isValid=false] +{ + color: #CE4141; +} + +#balance_label +{ + color: #333; +} + +#history +{ + color: #888; +} + diff --git a/data/dark/name.cfg b/data/dark/name.cfg new file mode 100644 index 00000000..4030549b --- /dev/null +++ b/data/dark/name.cfg @@ -0,0 +1 @@ +Dark diff --git a/data/dark/style.css b/data/dark/style.css new file mode 100644 index 00000000..c4554e63 --- /dev/null +++ b/data/dark/style.css @@ -0,0 +1,35 @@ +#main_window +{ + background-image: url(:/icons/dark_background.png); +} + +#address_input[readOnly=true], #amount_input[readOnly=true] +{ + font: italic; + color: gray; +} +#address_input[readOnly=false], #amount_input[readOnly=false] +{ + font: normal; + color: black; +} + +#valid_address::indicator +{ + width: 24px; + height: 24px; +} +#valid_address::indicator:checked +{ + image: url(confirmed.png); +} +#valid_address::indicator:unchecked +{ + image: url(unconfirmed.png); +} + +#balance_label +{ + color: white; +} + diff --git a/data/noface.svg b/data/noface.svg new file mode 100644 index 00000000..dc24f111 --- /dev/null +++ b/data/noface.svg @@ -0,0 +1,162 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/data/sahara/name.cfg b/data/sahara/name.cfg new file mode 100644 index 00000000..da4844db --- /dev/null +++ b/data/sahara/name.cfg @@ -0,0 +1 @@ +Sahara diff --git a/data/sahara/style.css b/data/sahara/style.css new file mode 100644 index 00000000..cd8d7272 --- /dev/null +++ b/data/sahara/style.css @@ -0,0 +1,102 @@ +#main_window +{ + background: qlineargradient(x1: 0, y1: 0, x2:0,y2:1, stop: 0 white , stop: 1 #F2E3BE); +} + +MiniWindow QPushButton { + color: #C1A76D; + border: 1px solid #A7811C; + border-radius: 0px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 white, stop: 1 #F2E3BE); + min-height: 25px; + min-width: 30px; +} + +#send_button{ + color: #FEEBA7; + border: 1px solid #AD8B35; + border-radius: 4px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #E0A035, stop: 1 #AD8B35); + min-width: 80px; + min-height: 23px; + padding: 2px; +} + +#send_button:disabled{ + color: #FEEDD3; + border: 1px solid #F7D46D; + border-radius: 4px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #FAEEA5, stop: 1 #DBC050); + min-width: 80px; + min-height: 23px; + padding: 2px; +} + +#receive_button +{ + color: #FEEBA7; + border: 1px solid #AD8B35; + border-radius: 4px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #E0A035, stop: 1 #AD8B35); + min-height: 25px; + min-width: 30px; +} +#receive_button[isActive=true] +{ + color: #FEEBA7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #E0A035, stop: 1 #987620); +} + +#address_input, #amount_input +{ + color: #000; + padding: 5px; + border-radius: 4px; + border: 1px solid #CBAE69; + width: 225px; +} + +#address_input[isValid=true] +{ + color: #4D9948; + padding: 5px; + border-radius: 4px; + border: 1px solid #CBAE69; + width: 225px; + margin-top: 4px; +} + +#address_input[isValid=false] +{ + color: #CE4141; + padding: 5px; + border-radius: 4px; + border: 1px solid #CBAE69; + width: 225px; + margin-top: 4px; +} + +#address_input[isValid=placeholder] +{ + color: #DEC58D; + padding: 5px; + border-radius: 4px; + border: 1px solid #CBAE69; + width: 225px; + margin-top: 4px; +} +#balance_label +{ + color: #7E5907; +} + +#history +{ + color: #8B6914; +} + diff --git a/data/wordlist/english.txt b/data/wordlist/english.txt new file mode 100644 index 00000000..942040ed --- /dev/null +++ b/data/wordlist/english.txt @@ -0,0 +1,2048 @@ +abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo diff --git a/data/wordlist/japanese.txt b/data/wordlist/japanese.txt new file mode 100644 index 00000000..c4c9dca4 --- /dev/null +++ b/data/wordlist/japanese.txt @@ -0,0 +1,2048 @@ +あいこくしん +あいさつ +あいだ +あおぞら +あかちゃん +あきる +あけがた +あける +あこがれる +あさい +あさひ +あしあと +あじわう +あずかる +あずき +あそぶ +あたえる +あたためる +あたりまえ +あたる +あつい +あつかう +あっしゅく +あつまり +あつめる +あてな +あてはまる +あひる +あぶら +あぶる +あふれる +あまい +あまど +あまやかす +あまり +あみもの +あめりか +あやまる +あゆむ +あらいぐま +あらし +あらすじ +あらためる +あらゆる +あらわす +ありがとう +あわせる +あわてる +あんい +あんがい +あんこ +あんぜん +あんてい +あんない +あんまり +いいだす +いおん +いがい +いがく +いきおい +いきなり +いきもの +いきる +いくじ +いくぶん +いけばな +いけん +いこう +いこく +いこつ +いさましい +いさん +いしき +いじゅう +いじょう +いじわる +いずみ +いずれ +いせい +いせえび +いせかい +いせき +いぜん +いそうろう +いそがしい +いだい +いだく +いたずら +いたみ +いたりあ +いちおう +いちじ +いちど +いちば +いちぶ +いちりゅう +いつか +いっしゅん +いっせい +いっそう +いったん +いっち +いってい +いっぽう +いてざ +いてん +いどう +いとこ +いない +いなか +いねむり +いのち +いのる +いはつ +いばる +いはん +いびき +いひん +いふく +いへん +いほう +いみん +いもうと +いもたれ +いもり +いやがる +いやす +いよかん +いよく +いらい +いらすと +いりぐち +いりょう +いれい +いれもの +いれる +いろえんぴつ +いわい +いわう +いわかん +いわば +いわゆる +いんげんまめ +いんさつ +いんしょう +いんよう +うえき +うえる +うおざ +うがい +うかぶ +うかべる +うきわ +うくらいな +うくれれ +うけたまわる +うけつけ +うけとる +うけもつ +うける +うごかす +うごく +うこん +うさぎ +うしなう +うしろがみ +うすい +うすぎ +うすぐらい +うすめる +うせつ +うちあわせ +うちがわ +うちき +うちゅう +うっかり +うつくしい +うったえる +うつる +うどん +うなぎ +うなじ +うなずく +うなる +うねる +うのう +うぶげ +うぶごえ +うまれる +うめる +うもう +うやまう +うよく +うらがえす +うらぐち +うらない +うりあげ +うりきれ +うるさい +うれしい +うれゆき +うれる +うろこ +うわき +うわさ +うんこう +うんちん +うんてん +うんどう +えいえん +えいが +えいきょう +えいご +えいせい +えいぶん +えいよう +えいわ +えおり +えがお +えがく +えきたい +えくせる +えしゃく +えすて +えつらん +えのぐ +えほうまき +えほん +えまき +えもじ +えもの +えらい +えらぶ +えりあ +えんえん +えんかい +えんぎ +えんげき +えんしゅう +えんぜつ +えんそく +えんちょう +えんとつ +おいかける +おいこす +おいしい +おいつく +おうえん +おうさま +おうじ +おうせつ +おうたい +おうふく +おうべい +おうよう +おえる +おおい +おおう +おおどおり +おおや +おおよそ +おかえり +おかず +おがむ +おかわり +おぎなう +おきる +おくさま +おくじょう +おくりがな +おくる +おくれる +おこす +おこなう +おこる +おさえる +おさない +おさめる +おしいれ +おしえる +おじぎ +おじさん +おしゃれ +おそらく +おそわる +おたがい +おたく +おだやか +おちつく +おっと +おつり +おでかけ +おとしもの +おとなしい +おどり +おどろかす +おばさん +おまいり +おめでとう +おもいで +おもう +おもたい +おもちゃ +おやつ +おやゆび +およぼす +おらんだ +おろす +おんがく +おんけい +おんしゃ +おんせん +おんだん +おんちゅう +おんどけい +かあつ +かいが +がいき +がいけん +がいこう +かいさつ +かいしゃ +かいすいよく +かいぜん +かいぞうど +かいつう +かいてん +かいとう +かいふく +がいへき +かいほう +かいよう +がいらい +かいわ +かえる +かおり +かかえる +かがく +かがし +かがみ +かくご +かくとく +かざる +がぞう +かたい +かたち +がちょう +がっきゅう +がっこう +がっさん +がっしょう +かなざわし +かのう +がはく +かぶか +かほう +かほご +かまう +かまぼこ +かめれおん +かゆい +かようび +からい +かるい +かろう +かわく +かわら +がんか +かんけい +かんこう +かんしゃ +かんそう +かんたん +かんち +がんばる +きあい +きあつ +きいろ +ぎいん +きうい +きうん +きえる +きおう +きおく +きおち +きおん +きかい +きかく +きかんしゃ +ききて +きくばり +きくらげ +きけんせい +きこう +きこえる +きこく +きさい +きさく +きさま +きさらぎ +ぎじかがく +ぎしき +ぎじたいけん +ぎじにってい +ぎじゅつしゃ +きすう +きせい +きせき +きせつ +きそう +きぞく +きぞん +きたえる +きちょう +きつえん +ぎっちり +きつつき +きつね +きてい +きどう +きどく +きない +きなが +きなこ +きぬごし +きねん +きのう +きのした +きはく +きびしい +きひん +きふく +きぶん +きぼう +きほん +きまる +きみつ +きむずかしい +きめる +きもだめし +きもち +きもの +きゃく +きやく +ぎゅうにく +きよう +きょうりゅう +きらい +きらく +きりん +きれい +きれつ +きろく +ぎろん +きわめる +ぎんいろ +きんかくじ +きんじょ +きんようび +ぐあい +くいず +くうかん +くうき +くうぐん +くうこう +ぐうせい +くうそう +ぐうたら +くうふく +くうぼ +くかん +くきょう +くげん +ぐこう +くさい +くさき +くさばな +くさる +くしゃみ +くしょう +くすのき +くすりゆび +くせげ +くせん +ぐたいてき +くださる +くたびれる +くちこみ +くちさき +くつした +ぐっすり +くつろぐ +くとうてん +くどく +くなん +くねくね +くのう +くふう +くみあわせ +くみたてる +くめる +くやくしょ +くらす +くらべる +くるま +くれる +くろう +くわしい +ぐんかん +ぐんしょく +ぐんたい +ぐんて +けあな +けいかく +けいけん +けいこ +けいさつ +げいじゅつ +けいたい +げいのうじん +けいれき +けいろ +けおとす +けおりもの +げきか +げきげん +げきだん +げきちん +げきとつ +げきは +げきやく +げこう +げこくじょう +げざい +けさき +げざん +けしき +けしごむ +けしょう +げすと +けたば +けちゃっぷ +けちらす +けつあつ +けつい +けつえき +けっこん +けつじょ +けっせき +けってい +けつまつ +げつようび +げつれい +けつろん +げどく +けとばす +けとる +けなげ +けなす +けなみ +けぬき +げねつ +けねん +けはい +げひん +けぶかい +げぼく +けまり +けみかる +けむし +けむり +けもの +けらい +けろけろ +けわしい +けんい +けんえつ +けんお +けんか +げんき +けんげん +けんこう +けんさく +けんしゅう +けんすう +げんそう +けんちく +けんてい +けんとう +けんない +けんにん +げんぶつ +けんま +けんみん +けんめい +けんらん +けんり +こあくま +こいぬ +こいびと +ごうい +こうえん +こうおん +こうかん +ごうきゅう +ごうけい +こうこう +こうさい +こうじ +こうすい +ごうせい +こうそく +こうたい +こうちゃ +こうつう +こうてい +こうどう +こうない +こうはい +ごうほう +ごうまん +こうもく +こうりつ +こえる +こおり +ごかい +ごがつ +ごかん +こくご +こくさい +こくとう +こくない +こくはく +こぐま +こけい +こける +ここのか +こころ +こさめ +こしつ +こすう +こせい +こせき +こぜん +こそだて +こたい +こたえる +こたつ +こちょう +こっか +こつこつ +こつばん +こつぶ +こてい +こてん +ことがら +ことし +ことば +ことり +こなごな +こねこね +このまま +このみ +このよ +ごはん +こひつじ +こふう +こふん +こぼれる +ごまあぶら +こまかい +ごますり +こまつな +こまる +こむぎこ +こもじ +こもち +こもの +こもん +こやく +こやま +こゆう +こゆび +こよい +こよう +こりる +これくしょん +ころっけ +こわもて +こわれる +こんいん +こんかい +こんき +こんしゅう +こんすい +こんだて +こんとん +こんなん +こんびに +こんぽん +こんまけ +こんや +こんれい +こんわく +ざいえき +さいかい +さいきん +ざいげん +ざいこ +さいしょ +さいせい +ざいたく +ざいちゅう +さいてき +ざいりょう +さうな +さかいし +さがす +さかな +さかみち +さがる +さぎょう +さくし +さくひん +さくら +さこく +さこつ +さずかる +ざせき +さたん +さつえい +ざつおん +ざっか +ざつがく +さっきょく +ざっし +さつじん +ざっそう +さつたば +さつまいも +さてい +さといも +さとう +さとおや +さとし +さとる +さのう +さばく +さびしい +さべつ +さほう +さほど +さます +さみしい +さみだれ +さむけ +さめる +さやえんどう +さゆう +さよう +さよく +さらだ +ざるそば +さわやか +さわる +さんいん +さんか +さんきゃく +さんこう +さんさい +ざんしょ +さんすう +さんせい +さんそ +さんち +さんま +さんみ +さんらん +しあい +しあげ +しあさって +しあわせ +しいく +しいん +しうち +しえい +しおけ +しかい +しかく +じかん +しごと +しすう +じだい +したうけ +したぎ +したて +したみ +しちょう +しちりん +しっかり +しつじ +しつもん +してい +してき +してつ +じてん +じどう +しなぎれ +しなもの +しなん +しねま +しねん +しのぐ +しのぶ +しはい +しばかり +しはつ +しはらい +しはん +しひょう +しふく +じぶん +しへい +しほう +しほん +しまう +しまる +しみん +しむける +じむしょ +しめい +しめる +しもん +しゃいん +しゃうん +しゃおん +じゃがいも +しやくしょ +しゃくほう +しゃけん +しゃこ +しゃざい +しゃしん +しゃせん +しゃそう +しゃたい +しゃちょう +しゃっきん +じゃま +しゃりん +しゃれい +じゆう +じゅうしょ +しゅくはく +じゅしん +しゅっせき +しゅみ +しゅらば +じゅんばん +しょうかい +しょくたく +しょっけん +しょどう +しょもつ +しらせる +しらべる +しんか +しんこう +じんじゃ +しんせいじ +しんちく +しんりん +すあげ +すあし +すあな +ずあん +すいえい +すいか +すいとう +ずいぶん +すいようび +すうがく +すうじつ +すうせん +すおどり +すきま +すくう +すくない +すける +すごい +すこし +ずさん +すずしい +すすむ +すすめる +すっかり +ずっしり +ずっと +すてき +すてる +すねる +すのこ +すはだ +すばらしい +ずひょう +ずぶぬれ +すぶり +すふれ +すべて +すべる +ずほう +すぼん +すまい +すめし +すもう +すやき +すらすら +するめ +すれちがう +すろっと +すわる +すんぜん +すんぽう +せあぶら +せいかつ +せいげん +せいじ +せいよう +せおう +せかいかん +せきにん +せきむ +せきゆ +せきらんうん +せけん +せこう +せすじ +せたい +せたけ +せっかく +せっきゃく +ぜっく +せっけん +せっこつ +せっさたくま +せつぞく +せつだん +せつでん +せっぱん +せつび +せつぶん +せつめい +せつりつ +せなか +せのび +せはば +せびろ +せぼね +せまい +せまる +せめる +せもたれ +せりふ +ぜんあく +せんい +せんえい +せんか +せんきょ +せんく +せんげん +ぜんご +せんさい +せんしゅ +せんすい +せんせい +せんぞ +せんたく +せんちょう +せんてい +せんとう +せんぬき +せんねん +せんぱい +ぜんぶ +ぜんぽう +せんむ +せんめんじょ +せんもん +せんやく +せんゆう +せんよう +ぜんら +ぜんりゃく +せんれい +せんろ +そあく +そいとげる +そいね +そうがんきょう +そうき +そうご +そうしん +そうだん +そうなん +そうび +そうめん +そうり +そえもの +そえん +そがい +そげき +そこう +そこそこ +そざい +そしな +そせい +そせん +そそぐ +そだてる +そつう +そつえん +そっかん +そつぎょう +そっけつ +そっこう +そっせん +そっと +そとがわ +そとづら +そなえる +そなた +そふぼ +そぼく +そぼろ +そまつ +そまる +そむく +そむりえ +そめる +そもそも +そよかぜ +そらまめ +そろう +そんかい +そんけい +そんざい +そんしつ +そんぞく +そんちょう +ぞんび +ぞんぶん +そんみん +たあい +たいいん +たいうん +たいえき +たいおう +だいがく +たいき +たいぐう +たいけん +たいこ +たいざい +だいじょうぶ +だいすき +たいせつ +たいそう +だいたい +たいちょう +たいてい +だいどころ +たいない +たいねつ +たいのう +たいはん +だいひょう +たいふう +たいへん +たいほ +たいまつばな +たいみんぐ +たいむ +たいめん +たいやき +たいよう +たいら +たいりょく +たいる +たいわん +たうえ +たえる +たおす +たおる +たおれる +たかい +たかね +たきび +たくさん +たこく +たこやき +たさい +たしざん +だじゃれ +たすける +たずさわる +たそがれ +たたかう +たたく +ただしい +たたみ +たちばな +だっかい +だっきゃく +だっこ +だっしゅつ +だったい +たてる +たとえる +たなばた +たにん +たぬき +たのしみ +たはつ +たぶん +たべる +たぼう +たまご +たまる +だむる +ためいき +ためす +ためる +たもつ +たやすい +たよる +たらす +たりきほんがん +たりょう +たりる +たると +たれる +たれんと +たろっと +たわむれる +だんあつ +たんい +たんおん +たんか +たんき +たんけん +たんご +たんさん +たんじょうび +だんせい +たんそく +たんたい +だんち +たんてい +たんとう +だんな +たんにん +だんねつ +たんのう +たんぴん +だんぼう +たんまつ +たんめい +だんれつ +だんろ +だんわ +ちあい +ちあん +ちいき +ちいさい +ちえん +ちかい +ちから +ちきゅう +ちきん +ちけいず +ちけん +ちこく +ちさい +ちしき +ちしりょう +ちせい +ちそう +ちたい +ちたん +ちちおや +ちつじょ +ちてき +ちてん +ちぬき +ちぬり +ちのう +ちひょう +ちへいせん +ちほう +ちまた +ちみつ +ちみどろ +ちめいど +ちゃんこなべ +ちゅうい +ちゆりょく +ちょうし +ちょさくけん +ちらし +ちらみ +ちりがみ +ちりょう +ちるど +ちわわ +ちんたい +ちんもく +ついか +ついたち +つうか +つうじょう +つうはん +つうわ +つかう +つかれる +つくね +つくる +つけね +つける +つごう +つたえる +つづく +つつじ +つつむ +つとめる +つながる +つなみ +つねづね +つのる +つぶす +つまらない +つまる +つみき +つめたい +つもり +つもる +つよい +つるぼ +つるみく +つわもの +つわり +てあし +てあて +てあみ +ていおん +ていか +ていき +ていけい +ていこく +ていさつ +ていし +ていせい +ていたい +ていど +ていねい +ていひょう +ていへん +ていぼう +てうち +ておくれ +てきとう +てくび +でこぼこ +てさぎょう +てさげ +てすり +てそう +てちがい +てちょう +てつがく +てつづき +でっぱ +てつぼう +てつや +でぬかえ +てぬき +てぬぐい +てのひら +てはい +てぶくろ +てふだ +てほどき +てほん +てまえ +てまきずし +てみじか +てみやげ +てらす +てれび +てわけ +てわたし +でんあつ +てんいん +てんかい +てんき +てんぐ +てんけん +てんごく +てんさい +てんし +てんすう +でんち +てんてき +てんとう +てんない +てんぷら +てんぼうだい +てんめつ +てんらんかい +でんりょく +でんわ +どあい +といれ +どうかん +とうきゅう +どうぐ +とうし +とうむぎ +とおい +とおか +とおく +とおす +とおる +とかい +とかす +ときおり +ときどき +とくい +とくしゅう +とくてん +とくに +とくべつ +とけい +とける +とこや +とさか +としょかん +とそう +とたん +とちゅう +とっきゅう +とっくん +とつぜん +とつにゅう +とどける +ととのえる +とない +となえる +となり +とのさま +とばす +どぶがわ +とほう +とまる +とめる +ともだち +ともる +どようび +とらえる +とんかつ +どんぶり +ないかく +ないこう +ないしょ +ないす +ないせん +ないそう +なおす +ながい +なくす +なげる +なこうど +なさけ +なたでここ +なっとう +なつやすみ +ななおし +なにごと +なにもの +なにわ +なのか +なふだ +なまいき +なまえ +なまみ +なみだ +なめらか +なめる +なやむ +ならう +ならび +ならぶ +なれる +なわとび +なわばり +にあう +にいがた +にうけ +におい +にかい +にがて +にきび +にくしみ +にくまん +にげる +にさんかたんそ +にしき +にせもの +にちじょう +にちようび +にっか +にっき +にっけい +にっこう +にっさん +にっしょく +にっすう +にっせき +にってい +になう +にほん +にまめ +にもつ +にやり +にゅういん +にりんしゃ +にわとり +にんい +にんか +にんき +にんげん +にんしき +にんずう +にんそう +にんたい +にんち +にんてい +にんにく +にんぷ +にんまり +にんむ +にんめい +にんよう +ぬいくぎ +ぬかす +ぬぐいとる +ぬぐう +ぬくもり +ぬすむ +ぬまえび +ぬめり +ぬらす +ぬんちゃく +ねあげ +ねいき +ねいる +ねいろ +ねぐせ +ねくたい +ねくら +ねこぜ +ねこむ +ねさげ +ねすごす +ねそべる +ねだん +ねつい +ねっしん +ねつぞう +ねったいぎょ +ねぶそく +ねふだ +ねぼう +ねほりはほり +ねまき +ねまわし +ねみみ +ねむい +ねむたい +ねもと +ねらう +ねわざ +ねんいり +ねんおし +ねんかん +ねんきん +ねんぐ +ねんざ +ねんし +ねんちゃく +ねんど +ねんぴ +ねんぶつ +ねんまつ +ねんりょう +ねんれい +のいず +のおづま +のがす +のきなみ +のこぎり +のこす +のこる +のせる +のぞく +のぞむ +のたまう +のちほど +のっく +のばす +のはら +のべる +のぼる +のみもの +のやま +のらいぬ +のらねこ +のりもの +のりゆき +のれん +のんき +ばあい +はあく +ばあさん +ばいか +ばいく +はいけん +はいご +はいしん +はいすい +はいせん +はいそう +はいち +ばいばい +はいれつ +はえる +はおる +はかい +ばかり +はかる +はくしゅ +はけん +はこぶ +はさみ +はさん +はしご +ばしょ +はしる +はせる +ぱそこん +はそん +はたん +はちみつ +はつおん +はっかく +はづき +はっきり +はっくつ +はっけん +はっこう +はっさん +はっしん +はったつ +はっちゅう +はってん +はっぴょう +はっぽう +はなす +はなび +はにかむ +はぶらし +はみがき +はむかう +はめつ +はやい +はやし +はらう +はろうぃん +はわい +はんい +はんえい +はんおん +はんかく +はんきょう +ばんぐみ +はんこ +はんしゃ +はんすう +はんだん +ぱんち +ぱんつ +はんてい +はんとし +はんのう +はんぱ +はんぶん +はんぺん +はんぼうき +はんめい +はんらん +はんろん +ひいき +ひうん +ひえる +ひかく +ひかり +ひかる +ひかん +ひくい +ひけつ +ひこうき +ひこく +ひさい +ひさしぶり +ひさん +びじゅつかん +ひしょ +ひそか +ひそむ +ひたむき +ひだり +ひたる +ひつぎ +ひっこし +ひっし +ひつじゅひん +ひっす +ひつぜん +ぴったり +ぴっちり +ひつよう +ひてい +ひとごみ +ひなまつり +ひなん +ひねる +ひはん +ひびく +ひひょう +ひほう +ひまわり +ひまん +ひみつ +ひめい +ひめじし +ひやけ +ひやす +ひよう +びょうき +ひらがな +ひらく +ひりつ +ひりょう +ひるま +ひるやすみ +ひれい +ひろい +ひろう +ひろき +ひろゆき +ひんかく +ひんけつ +ひんこん +ひんしゅ +ひんそう +ぴんち +ひんぱん +びんぼう +ふあん +ふいうち +ふうけい +ふうせん +ぷうたろう +ふうとう +ふうふ +ふえる +ふおん +ふかい +ふきん +ふくざつ +ふくぶくろ +ふこう +ふさい +ふしぎ +ふじみ +ふすま +ふせい +ふせぐ +ふそく +ぶたにく +ふたん +ふちょう +ふつう +ふつか +ふっかつ +ふっき +ふっこく +ぶどう +ふとる +ふとん +ふのう +ふはい +ふひょう +ふへん +ふまん +ふみん +ふめつ +ふめん +ふよう +ふりこ +ふりる +ふるい +ふんいき +ぶんがく +ぶんぐ +ふんしつ +ぶんせき +ふんそう +ぶんぽう +へいあん +へいおん +へいがい +へいき +へいげん +へいこう +へいさ +へいしゃ +へいせつ +へいそ +へいたく +へいてん +へいねつ +へいわ +へきが +へこむ +べにいろ +べにしょうが +へらす +へんかん +べんきょう +べんごし +へんさい +へんたい +べんり +ほあん +ほいく +ぼうぎょ +ほうこく +ほうそう +ほうほう +ほうもん +ほうりつ +ほえる +ほおん +ほかん +ほきょう +ぼきん +ほくろ +ほけつ +ほけん +ほこう +ほこる +ほしい +ほしつ +ほしゅ +ほしょう +ほせい +ほそい +ほそく +ほたて +ほたる +ぽちぶくろ +ほっきょく +ほっさ +ほったん +ほとんど +ほめる +ほんい +ほんき +ほんけ +ほんしつ +ほんやく +まいにち +まかい +まかせる +まがる +まける +まこと +まさつ +まじめ +ますく +まぜる +まつり +まとめ +まなぶ +まぬけ +まねく +まほう +まもる +まゆげ +まよう +まろやか +まわす +まわり +まわる +まんが +まんきつ +まんぞく +まんなか +みいら +みうち +みえる +みがく +みかた +みかん +みけん +みこん +みじかい +みすい +みすえる +みせる +みっか +みつかる +みつける +みてい +みとめる +みなと +みなみかさい +みねらる +みのう +みのがす +みほん +みもと +みやげ +みらい +みりょく +みわく +みんか +みんぞく +むいか +むえき +むえん +むかい +むかう +むかえ +むかし +むぎちゃ +むける +むげん +むさぼる +むしあつい +むしば +むじゅん +むしろ +むすう +むすこ +むすぶ +むすめ +むせる +むせん +むちゅう +むなしい +むのう +むやみ +むよう +むらさき +むりょう +むろん +めいあん +めいうん +めいえん +めいかく +めいきょく +めいさい +めいし +めいそう +めいぶつ +めいれい +めいわく +めぐまれる +めざす +めした +めずらしい +めだつ +めまい +めやす +めんきょ +めんせき +めんどう +もうしあげる +もうどうけん +もえる +もくし +もくてき +もくようび +もちろん +もどる +もらう +もんく +もんだい +やおや +やける +やさい +やさしい +やすい +やすたろう +やすみ +やせる +やそう +やたい +やちん +やっと +やっぱり +やぶる +やめる +ややこしい +やよい +やわらかい +ゆうき +ゆうびんきょく +ゆうべ +ゆうめい +ゆけつ +ゆしゅつ +ゆせん +ゆそう +ゆたか +ゆちゃく +ゆでる +ゆにゅう +ゆびわ +ゆらい +ゆれる +ようい +ようか +ようきゅう +ようじ +ようす +ようちえん +よかぜ +よかん +よきん +よくせい +よくぼう +よけい +よごれる +よさん +よしゅう +よそう +よそく +よっか +よてい +よどがわく +よねつ +よやく +よゆう +よろこぶ +よろしい +らいう +らくがき +らくご +らくさつ +らくだ +らしんばん +らせん +らぞく +らたい +らっか +られつ +りえき +りかい +りきさく +りきせつ +りくぐん +りくつ +りけん +りこう +りせい +りそう +りそく +りてん +りねん +りゆう +りゅうがく +りよう +りょうり +りょかん +りょくちゃ +りょこう +りりく +りれき +りろん +りんご +るいけい +るいさい +るいじ +るいせき +るすばん +るりがわら +れいかん +れいぎ +れいせい +れいぞうこ +れいとう +れいぼう +れきし +れきだい +れんあい +れんけい +れんこん +れんさい +れんしゅう +れんぞく +れんらく +ろうか +ろうご +ろうじん +ろうそく +ろくが +ろこつ +ろじうら +ろしゅつ +ろせん +ろてん +ろめん +ろれつ +ろんぎ +ろんぱ +ろんぶん +ろんり +わかす +わかめ +わかやま +わかれる +わしつ +わじまし +わすれもの +わらう +われる diff --git a/data/wordlist/portuguese.txt b/data/wordlist/portuguese.txt new file mode 100644 index 00000000..394c88da --- /dev/null +++ b/data/wordlist/portuguese.txt @@ -0,0 +1,1654 @@ +# Copyright (c) 2014, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +abaular +abdominal +abeto +abissinio +abjeto +ablucao +abnegar +abotoar +abrutalhar +absurdo +abutre +acautelar +accessorios +acetona +achocolatado +acirrar +acne +acovardar +acrostico +actinomicete +acustico +adaptavel +adeus +adivinho +adjunto +admoestar +adnominal +adotivo +adquirir +adriatico +adsorcao +adutora +advogar +aerossol +afazeres +afetuoso +afixo +afluir +afortunar +afrouxar +aftosa +afunilar +agentes +agito +aglutinar +aiatola +aimore +aino +aipo +airoso +ajeitar +ajoelhar +ajudante +ajuste +alazao +albumina +alcunha +alegria +alexandre +alforriar +alguns +alhures +alivio +almoxarife +alotropico +alpiste +alquimista +alsaciano +altura +aluviao +alvura +amazonico +ambulatorio +ametodico +amizades +amniotico +amovivel +amurada +anatomico +ancorar +anexo +anfora +aniversario +anjo +anotar +ansioso +anturio +anuviar +anverso +anzol +aonde +apaziguar +apito +aplicavel +apoteotico +aprimorar +aprumo +apto +apuros +aquoso +arauto +arbusto +arduo +aresta +arfar +arguto +aritmetico +arlequim +armisticio +aromatizar +arpoar +arquivo +arrumar +arsenio +arturiano +aruaque +arvores +asbesto +ascorbico +aspirina +asqueroso +assustar +astuto +atazanar +ativo +atletismo +atmosferico +atormentar +atroz +aturdir +audivel +auferir +augusto +aula +aumento +aurora +autuar +avatar +avexar +avizinhar +avolumar +avulso +axiomatico +azerbaijano +azimute +azoto +azulejo +bacteriologista +badulaque +baforada +baixote +bajular +balzaquiana +bambuzal +banzo +baoba +baqueta +barulho +bastonete +batuta +bauxita +bavaro +bazuca +bcrepuscular +beato +beduino +begonia +behaviorista +beisebol +belzebu +bemol +benzido +beocio +bequer +berro +besuntar +betume +bexiga +bezerro +biatlon +biboca +bicuspide +bidirecional +bienio +bifurcar +bigorna +bijuteria +bimotor +binormal +bioxido +bipolarizacao +biquini +birutice +bisturi +bituca +biunivoco +bivalve +bizarro +blasfemo +blenorreia +blindar +bloqueio +blusao +boazuda +bofete +bojudo +bolso +bombordo +bonzo +botina +boquiaberto +bostoniano +botulismo +bourbon +bovino +boximane +bravura +brevidade +britar +broxar +bruno +bruxuleio +bubonico +bucolico +buda +budista +bueiro +buffer +bugre +bujao +bumerangue +burundines +busto +butique +buzios +caatinga +cabuqui +cacunda +cafuzo +cajueiro +camurca +canudo +caquizeiro +carvoeiro +casulo +catuaba +cauterizar +cebolinha +cedula +ceifeiro +celulose +cerzir +cesto +cetro +ceus +cevar +chavena +cheroqui +chita +chovido +chuvoso +ciatico +cibernetico +cicuta +cidreira +cientistas +cifrar +cigarro +cilio +cimo +cinzento +cioso +cipriota +cirurgico +cisto +citrico +ciumento +civismo +clavicula +clero +clitoris +cluster +coaxial +cobrir +cocota +codorniz +coexistir +cogumelo +coito +colusao +compaixao +comutativo +contentamento +convulsivo +coordenativa +coquetel +correto +corvo +costureiro +cotovia +covil +cozinheiro +cretino +cristo +crivo +crotalo +cruzes +cubo +cucuia +cueiro +cuidar +cujo +cultural +cunilingua +cupula +curvo +custoso +cutucar +czarismo +dablio +dacota +dados +daguerreotipo +daiquiri +daltonismo +damista +dantesco +daquilo +darwinista +dasein +dativo +deao +debutantes +decurso +deduzir +defunto +degustar +dejeto +deltoide +demover +denunciar +deputado +deque +dervixe +desvirtuar +deturpar +deuteronomio +devoto +dextrose +dezoito +diatribe +dicotomico +didatico +dietista +difuso +digressao +diluvio +diminuto +dinheiro +dinossauro +dioxido +diplomatico +dique +dirimivel +disturbio +diurno +divulgar +dizivel +doar +dobro +docura +dodoi +doer +dogue +doloso +domo +donzela +doping +dorsal +dossie +dote +doutro +doze +dravidico +dreno +driver +dropes +druso +dubnio +ducto +dueto +dulija +dundum +duodeno +duquesa +durou +duvidoso +duzia +ebano +ebrio +eburneo +echarpe +eclusa +ecossistema +ectoplasma +ecumenismo +eczema +eden +editorial +edredom +edulcorar +efetuar +efigie +efluvio +egiptologo +egresso +egua +einsteiniano +eira +eivar +eixos +ejetar +elastomero +eldorado +elixir +elmo +eloquente +elucidativo +emaranhar +embutir +emerito +emfa +emitir +emotivo +empuxo +emulsao +enamorar +encurvar +enduro +enevoar +enfurnar +enguico +enho +enigmista +enlutar +enormidade +enpreendimento +enquanto +enriquecer +enrugar +entusiastico +enunciar +envolvimento +enxuto +enzimatico +eolico +epiteto +epoxi +epura +equivoco +erario +erbio +ereto +erguido +erisipela +ermo +erotizar +erros +erupcao +ervilha +esburacar +escutar +esfuziante +esguio +esloveno +esmurrar +esoterismo +esperanca +espirito +espurio +essencialmente +esturricar +esvoacar +etario +eterno +etiquetar +etnologo +etos +etrusco +euclidiano +euforico +eugenico +eunuco +europio +eustaquio +eutanasia +evasivo +eventualidade +evitavel +evoluir +exaustor +excursionista +exercito +exfoliado +exito +exotico +expurgo +exsudar +extrusora +exumar +fabuloso +facultativo +fado +fagulha +faixas +fajuto +faltoso +famoso +fanzine +fapesp +faquir +fartura +fastio +faturista +fausto +favorito +faxineira +fazer +fealdade +febril +fecundo +fedorento +feerico +feixe +felicidade +felipe +feltro +femur +fenotipo +fervura +festivo +feto +feudo +fevereiro +fezinha +fiasco +fibra +ficticio +fiduciario +fiesp +fifa +figurino +fijiano +filtro +finura +fiorde +fiquei +firula +fissurar +fitoteca +fivela +fixo +flavio +flexor +flibusteiro +flotilha +fluxograma +fobos +foco +fofura +foguista +foie +foliculo +fominha +fonte +forum +fosso +fotossintese +foxtrote +fraudulento +frevo +frivolo +frouxo +frutose +fuba +fucsia +fugitivo +fuinha +fujao +fulustreco +fumo +funileiro +furunculo +fustigar +futurologo +fuxico +fuzue +gabriel +gado +gaelico +gafieira +gaguejo +gaivota +gajo +galvanoplastico +gamo +ganso +garrucha +gastronomo +gatuno +gaussiano +gaviao +gaxeta +gazeteiro +gear +geiser +geminiano +generoso +genuino +geossinclinal +gerundio +gestual +getulista +gibi +gigolo +gilete +ginseng +giroscopio +glaucio +glacial +gleba +glifo +glote +glutonia +gnostico +goela +gogo +goitaca +golpista +gomo +gonzo +gorro +gostou +goticula +gourmet +governo +gozo +graxo +grevista +grito +grotesco +gruta +guaxinim +gude +gueto +guizo +guloso +gume +guru +gustativo +gustavo +gutural +habitue +haitiano +halterofilista +hamburguer +hanseniase +happening +harpista +hastear +haveres +hebreu +hectometro +hedonista +hegira +helena +helminto +hemorroidas +henrique +heptassilabo +hertziano +hesitar +heterossexual +heuristico +hexagono +hiato +hibrido +hidrostatico +hieroglifo +hifenizar +higienizar +hilario +himen +hino +hippie +hirsuto +historiografia +hitlerista +hodometro +hoje +holograma +homus +honroso +hoquei +horto +hostilizar +hotentote +huguenote +humilde +huno +hurra +hutu +iaia +ialorixa +iambico +iansa +iaque +iara +iatista +iberico +ibis +icar +iceberg +icosagono +idade +ideologo +idiotice +idoso +iemenita +iene +igarape +iglu +ignorar +igreja +iguaria +iidiche +ilativo +iletrado +ilharga +ilimitado +ilogismo +ilustrissimo +imaturo +imbuzeiro +imerso +imitavel +imovel +imputar +imutavel +inaveriguavel +incutir +induzir +inextricavel +infusao +ingua +inhame +iniquo +injusto +inning +inoxidavel +inquisitorial +insustentavel +intumescimento +inutilizavel +invulneravel +inzoneiro +iodo +iogurte +ioio +ionosfera +ioruba +iota +ipsilon +irascivel +iris +irlandes +irmaos +iroques +irrupcao +isca +isento +islandes +isotopo +isqueiro +israelita +isso +isto +iterbio +itinerario +itrio +iuane +iugoslavo +jabuticabeira +jacutinga +jade +jagunco +jainista +jaleco +jambo +jantarada +japones +jaqueta +jarro +jasmim +jato +jaula +javel +jazz +jegue +jeitoso +jejum +jenipapo +jeova +jequitiba +jersei +jesus +jetom +jiboia +jihad +jilo +jingle +jipe +jocoso +joelho +joguete +joio +jojoba +jorro +jota +joule +joviano +jubiloso +judoca +jugular +juizo +jujuba +juliano +jumento +junto +jururu +justo +juta +juventude +labutar +laguna +laico +lajota +lanterninha +lapso +laquear +lastro +lauto +lavrar +laxativo +lazer +leasing +lebre +lecionar +ledo +leguminoso +leitura +lele +lemure +lento +leonardo +leopardo +lepton +leque +leste +letreiro +leucocito +levitico +lexicologo +lhama +lhufas +liame +licoroso +lidocaina +liliputiano +limusine +linotipo +lipoproteina +liquidos +lirismo +lisura +liturgico +livros +lixo +lobulo +locutor +lodo +logro +lojista +lombriga +lontra +loop +loquaz +lorota +losango +lotus +louvor +luar +lubrificavel +lucros +lugubre +luis +luminoso +luneta +lustroso +luto +luvas +luxuriante +luzeiro +maduro +maestro +mafioso +magro +maiuscula +majoritario +malvisto +mamute +manutencao +mapoteca +maquinista +marzipa +masturbar +matuto +mausoleu +mavioso +maxixe +mazurca +meandro +mecha +medusa +mefistofelico +megera +meirinho +melro +memorizar +menu +mequetrefe +mertiolate +mestria +metroviario +mexilhao +mezanino +miau +microssegundo +midia +migratorio +mimosa +minuto +miosotis +mirtilo +misturar +mitzvah +miudos +mixuruca +mnemonico +moagem +mobilizar +modulo +moer +mofo +mogno +moita +molusco +monumento +moqueca +morubixaba +mostruario +motriz +mouse +movivel +mozarela +muarra +muculmano +mudo +mugir +muitos +mumunha +munir +muon +muquira +murros +musselina +nacoes +nado +naftalina +nago +naipe +naja +nalgum +namoro +nanquim +napolitano +naquilo +nascimento +nautilo +navios +nazista +nebuloso +nectarina +nefrologo +negus +nelore +nenufar +nepotismo +nervura +neste +netuno +neutron +nevoeiro +newtoniano +nexo +nhenhenhem +nhoque +nigeriano +niilista +ninho +niobio +niponico +niquelar +nirvana +nisto +nitroglicerina +nivoso +nobreza +nocivo +noel +nogueira +noivo +nojo +nominativo +nonuplo +noruegues +nostalgico +noturno +nouveau +nuanca +nublar +nucleotideo +nudista +nulo +numismatico +nunquinha +nupcias +nutritivo +nuvens +oasis +obcecar +obeso +obituario +objetos +oblongo +obnoxio +obrigatorio +obstruir +obtuso +obus +obvio +ocaso +occipital +oceanografo +ocioso +oclusivo +ocorrer +ocre +octogono +odalisca +odisseia +odorifico +oersted +oeste +ofertar +ofidio +oftalmologo +ogiva +ogum +oigale +oitavo +oitocentos +ojeriza +olaria +oleoso +olfato +olhos +oliveira +olmo +olor +olvidavel +ombudsman +omeleteira +omitir +omoplata +onanismo +ondular +oneroso +onomatopeico +ontologico +onus +onze +opalescente +opcional +operistico +opio +oposto +oprobrio +optometrista +opusculo +oratorio +orbital +orcar +orfao +orixa +orla +ornitologo +orquidea +ortorrombico +orvalho +osculo +osmotico +ossudo +ostrogodo +otario +otite +ouro +ousar +outubro +ouvir +ovario +overnight +oviparo +ovni +ovoviviparo +ovulo +oxala +oxente +oxiuro +oxossi +ozonizar +paciente +pactuar +padronizar +paete +pagodeiro +paixao +pajem +paludismo +pampas +panturrilha +papudo +paquistanes +pastoso +patua +paulo +pauzinhos +pavoroso +paxa +pazes +peao +pecuniario +pedunculo +pegaso +peixinho +pejorativo +pelvis +penuria +pequno +petunia +pezada +piauiense +pictorico +pierro +pigmeu +pijama +pilulas +pimpolho +pintura +piorar +pipocar +piqueteiro +pirulito +pistoleiro +pituitaria +pivotar +pixote +pizzaria +plistoceno +plotar +pluviometrico +pneumonico +poco +podridao +poetisa +pogrom +pois +polvorosa +pomposo +ponderado +pontudo +populoso +poquer +porvir +posudo +potro +pouso +povoar +prazo +prezar +privilegios +proximo +prussiano +pseudopode +psoriase +pterossauros +ptialina +ptolemaico +pudor +pueril +pufe +pugilista +puir +pujante +pulverizar +pumba +punk +purulento +pustula +putsch +puxe +quatrocentos +quetzal +quixotesco +quotizavel +rabujice +racista +radonio +rafia +ragu +rajado +ralo +rampeiro +ranzinza +raptor +raquitismo +raro +rasurar +ratoeira +ravioli +razoavel +reavivar +rebuscar +recusavel +reduzivel +reexposicao +refutavel +regurgitar +reivindicavel +rejuvenescimento +relva +remuneravel +renunciar +reorientar +repuxo +requisito +resumo +returno +reutilizar +revolvido +rezonear +riacho +ribossomo +ricota +ridiculo +rifle +rigoroso +rijo +rimel +rins +rios +riqueza +riquixa +rissole +ritualistico +rivalizar +rixa +robusto +rococo +rodoviario +roer +rogo +rojao +rolo +rompimento +ronronar +roqueiro +rorqual +rosto +rotundo +rouxinol +roxo +royal +ruas +rucula +rudimentos +ruela +rufo +rugoso +ruivo +rule +rumoroso +runico +ruptura +rural +rustico +rutilar +saariano +sabujo +sacudir +sadomasoquista +safra +sagui +sais +samurai +santuario +sapo +saquear +sartriano +saturno +saude +sauva +saveiro +saxofonista +sazonal +scherzo +script +seara +seborreia +secura +seduzir +sefardim +seguro +seja +selvas +sempre +senzala +sepultura +sequoia +sestercio +setuplo +seus +seviciar +sezonismo +shalom +siames +sibilante +sicrano +sidra +sifilitico +signos +silvo +simultaneo +sinusite +sionista +sirio +sisudo +situar +sivan +slide +slogan +soar +sobrio +socratico +sodomizar +soerguer +software +sogro +soja +solver +somente +sonso +sopro +soquete +sorveteiro +sossego +soturno +sousafone +sovinice +sozinho +suavizar +subverter +sucursal +sudoriparo +sufragio +sugestoes +suite +sujo +sultao +sumula +suntuoso +suor +supurar +suruba +susto +suturar +suvenir +tabuleta +taco +tadjique +tafeta +tagarelice +taitiano +talvez +tampouco +tanzaniano +taoista +tapume +taquion +tarugo +tascar +tatuar +tautologico +tavola +taxionomista +tchecoslovaco +teatrologo +tectonismo +tedioso +teflon +tegumento +teixo +telurio +temporas +tenue +teosofico +tepido +tequila +terrorista +testosterona +tetrico +teutonico +teve +texugo +tiara +tibia +tiete +tifoide +tigresa +tijolo +tilintar +timpano +tintureiro +tiquete +tiroteio +tisico +titulos +tive +toar +toboga +tofu +togoles +toicinho +tolueno +tomografo +tontura +toponimo +toquio +torvelinho +tostar +toto +touro +toxina +trazer +trezentos +trivialidade +trovoar +truta +tuaregue +tubular +tucano +tudo +tufo +tuiste +tulipa +tumultuoso +tunisino +tupiniquim +turvo +tutu +ucraniano +udenista +ufanista +ufologo +ugaritico +uiste +uivo +ulceroso +ulema +ultravioleta +umbilical +umero +umido +umlaut +unanimidade +unesco +ungulado +unheiro +univoco +untuoso +urano +urbano +urdir +uretra +urgente +urinol +urna +urologo +urro +ursulina +urtiga +urupe +usavel +usbeque +usei +usineiro +usurpar +utero +utilizar +utopico +uvular +uxoricidio +vacuo +vadio +vaguear +vaivem +valvula +vampiro +vantajoso +vaporoso +vaquinha +varziano +vasto +vaticinio +vaudeville +vazio +veado +vedico +veemente +vegetativo +veio +veja +veludo +venusiano +verdade +verve +vestuario +vetusto +vexatorio +vezes +viavel +vibratorio +victor +vicunha +vidros +vietnamita +vigoroso +vilipendiar +vime +vintem +violoncelo +viquingue +virus +visualizar +vituperio +viuvo +vivo +vizir +voar +vociferar +vodu +vogar +voile +volver +vomito +vontade +vortice +vosso +voto +vovozinha +voyeuse +vozes +vulva +vupt +western +xadrez +xale +xampu +xango +xarope +xaual +xavante +xaxim +xenonio +xepa +xerox +xicara +xifopago +xiita +xilogravura +xinxim +xistoso +xixi +xodo +xogum +xucro +zabumba +zagueiro +zambiano +zanzar +zarpar +zebu +zefiro +zeloso +zenite +zumbi diff --git a/data/wordlist/spanish.txt b/data/wordlist/spanish.txt new file mode 100644 index 00000000..d0900c2c --- /dev/null +++ b/data/wordlist/spanish.txt @@ -0,0 +1,2048 @@ +ábaco +abdomen +abeja +abierto +abogado +abono +aborto +abrazo +abrir +abuelo +abuso +acabar +academia +acceso +acción +aceite +acelga +acento +aceptar +ácido +aclarar +acné +acoger +acoso +activo +acto +actriz +actuar +acudir +acuerdo +acusar +adicto +admitir +adoptar +adorno +aduana +adulto +aéreo +afectar +afición +afinar +afirmar +ágil +agitar +agonía +agosto +agotar +agregar +agrio +agua +agudo +águila +aguja +ahogo +ahorro +aire +aislar +ajedrez +ajeno +ajuste +alacrán +alambre +alarma +alba +álbum +alcalde +aldea +alegre +alejar +alerta +aleta +alfiler +alga +algodón +aliado +aliento +alivio +alma +almeja +almíbar +altar +alteza +altivo +alto +altura +alumno +alzar +amable +amante +amapola +amargo +amasar +ámbar +ámbito +ameno +amigo +amistad +amor +amparo +amplio +ancho +anciano +ancla +andar +andén +anemia +ángulo +anillo +ánimo +anís +anotar +antena +antiguo +antojo +anual +anular +anuncio +añadir +añejo +año +apagar +aparato +apetito +apio +aplicar +apodo +aporte +apoyo +aprender +aprobar +apuesta +apuro +arado +araña +arar +árbitro +árbol +arbusto +archivo +arco +arder +ardilla +arduo +área +árido +aries +armonía +arnés +aroma +arpa +arpón +arreglo +arroz +arruga +arte +artista +asa +asado +asalto +ascenso +asegurar +aseo +asesor +asiento +asilo +asistir +asno +asombro +áspero +astilla +astro +astuto +asumir +asunto +atajo +ataque +atar +atento +ateo +ático +atleta +átomo +atraer +atroz +atún +audaz +audio +auge +aula +aumento +ausente +autor +aval +avance +avaro +ave +avellana +avena +avestruz +avión +aviso +ayer +ayuda +ayuno +azafrán +azar +azote +azúcar +azufre +azul +baba +babor +bache +bahía +baile +bajar +balanza +balcón +balde +bambú +banco +banda +baño +barba +barco +barniz +barro +báscula +bastón +basura +batalla +batería +batir +batuta +baúl +bazar +bebé +bebida +bello +besar +beso +bestia +bicho +bien +bingo +blanco +bloque +blusa +boa +bobina +bobo +boca +bocina +boda +bodega +boina +bola +bolero +bolsa +bomba +bondad +bonito +bono +bonsái +borde +borrar +bosque +bote +botín +bóveda +bozal +bravo +brazo +brecha +breve +brillo +brinco +brisa +broca +broma +bronce +brote +bruja +brusco +bruto +buceo +bucle +bueno +buey +bufanda +bufón +búho +buitre +bulto +burbuja +burla +burro +buscar +butaca +buzón +caballo +cabeza +cabina +cabra +cacao +cadáver +cadena +caer +café +caída +caimán +caja +cajón +cal +calamar +calcio +caldo +calidad +calle +calma +calor +calvo +cama +cambio +camello +camino +campo +cáncer +candil +canela +canguro +canica +canto +caña +cañón +caoba +caos +capaz +capitán +capote +captar +capucha +cara +carbón +cárcel +careta +carga +cariño +carne +carpeta +carro +carta +casa +casco +casero +caspa +castor +catorce +catre +caudal +causa +cazo +cebolla +ceder +cedro +celda +célebre +celoso +célula +cemento +ceniza +centro +cerca +cerdo +cereza +cero +cerrar +certeza +césped +cetro +chacal +chaleco +champú +chancla +chapa +charla +chico +chiste +chivo +choque +choza +chuleta +chupar +ciclón +ciego +cielo +cien +cierto +cifra +cigarro +cima +cinco +cine +cinta +ciprés +circo +ciruela +cisne +cita +ciudad +clamor +clan +claro +clase +clave +cliente +clima +clínica +cobre +cocción +cochino +cocina +coco +código +codo +cofre +coger +cohete +cojín +cojo +cola +colcha +colegio +colgar +colina +collar +colmo +columna +combate +comer +comida +cómodo +compra +conde +conejo +conga +conocer +consejo +contar +copa +copia +corazón +corbata +corcho +cordón +corona +correr +coser +cosmos +costa +cráneo +cráter +crear +crecer +creído +crema +cría +crimen +cripta +crisis +cromo +crónica +croqueta +crudo +cruz +cuadro +cuarto +cuatro +cubo +cubrir +cuchara +cuello +cuento +cuerda +cuesta +cueva +cuidar +culebra +culpa +culto +cumbre +cumplir +cuna +cuneta +cuota +cupón +cúpula +curar +curioso +curso +curva +cutis +dama +danza +dar +dardo +dátil +deber +débil +década +decir +dedo +defensa +definir +dejar +delfín +delgado +delito +demora +denso +dental +deporte +derecho +derrota +desayuno +deseo +desfile +desnudo +destino +desvío +detalle +detener +deuda +día +diablo +diadema +diamante +diana +diario +dibujo +dictar +diente +dieta +diez +difícil +digno +dilema +diluir +dinero +directo +dirigir +disco +diseño +disfraz +diva +divino +doble +doce +dolor +domingo +don +donar +dorado +dormir +dorso +dos +dosis +dragón +droga +ducha +duda +duelo +dueño +dulce +dúo +duque +durar +dureza +duro +ébano +ebrio +echar +eco +ecuador +edad +edición +edificio +editor +educar +efecto +eficaz +eje +ejemplo +elefante +elegir +elemento +elevar +elipse +élite +elixir +elogio +eludir +embudo +emitir +emoción +empate +empeño +empleo +empresa +enano +encargo +enchufe +encía +enemigo +enero +enfado +enfermo +engaño +enigma +enlace +enorme +enredo +ensayo +enseñar +entero +entrar +envase +envío +época +equipo +erizo +escala +escena +escolar +escribir +escudo +esencia +esfera +esfuerzo +espada +espejo +espía +esposa +espuma +esquí +estar +este +estilo +estufa +etapa +eterno +ética +etnia +evadir +evaluar +evento +evitar +exacto +examen +exceso +excusa +exento +exigir +exilio +existir +éxito +experto +explicar +exponer +extremo +fábrica +fábula +fachada +fácil +factor +faena +faja +falda +fallo +falso +faltar +fama +familia +famoso +faraón +farmacia +farol +farsa +fase +fatiga +fauna +favor +fax +febrero +fecha +feliz +feo +feria +feroz +fértil +fervor +festín +fiable +fianza +fiar +fibra +ficción +ficha +fideo +fiebre +fiel +fiera +fiesta +figura +fijar +fijo +fila +filete +filial +filtro +fin +finca +fingir +finito +firma +flaco +flauta +flecha +flor +flota +fluir +flujo +flúor +fobia +foca +fogata +fogón +folio +folleto +fondo +forma +forro +fortuna +forzar +fosa +foto +fracaso +frágil +franja +frase +fraude +freír +freno +fresa +frío +frito +fruta +fuego +fuente +fuerza +fuga +fumar +función +funda +furgón +furia +fusil +fútbol +futuro +gacela +gafas +gaita +gajo +gala +galería +gallo +gamba +ganar +gancho +ganga +ganso +garaje +garza +gasolina +gastar +gato +gavilán +gemelo +gemir +gen +género +genio +gente +geranio +gerente +germen +gesto +gigante +gimnasio +girar +giro +glaciar +globo +gloria +gol +golfo +goloso +golpe +goma +gordo +gorila +gorra +gota +goteo +gozar +grada +gráfico +grano +grasa +gratis +grave +grieta +grillo +gripe +gris +grito +grosor +grúa +grueso +grumo +grupo +guante +guapo +guardia +guerra +guía +guiño +guion +guiso +guitarra +gusano +gustar +haber +hábil +hablar +hacer +hacha +hada +hallar +hamaca +harina +haz +hazaña +hebilla +hebra +hecho +helado +helio +hembra +herir +hermano +héroe +hervir +hielo +hierro +hígado +higiene +hijo +himno +historia +hocico +hogar +hoguera +hoja +hombre +hongo +honor +honra +hora +hormiga +horno +hostil +hoyo +hueco +huelga +huerta +hueso +huevo +huida +huir +humano +húmedo +humilde +humo +hundir +huracán +hurto +icono +ideal +idioma +ídolo +iglesia +iglú +igual +ilegal +ilusión +imagen +imán +imitar +impar +imperio +imponer +impulso +incapaz +índice +inerte +infiel +informe +ingenio +inicio +inmenso +inmune +innato +insecto +instante +interés +íntimo +intuir +inútil +invierno +ira +iris +ironía +isla +islote +jabalí +jabón +jamón +jarabe +jardín +jarra +jaula +jazmín +jefe +jeringa +jinete +jornada +joroba +joven +joya +juerga +jueves +juez +jugador +jugo +juguete +juicio +junco +jungla +junio +juntar +júpiter +jurar +justo +juvenil +juzgar +kilo +koala +labio +lacio +lacra +lado +ladrón +lagarto +lágrima +laguna +laico +lamer +lámina +lámpara +lana +lancha +langosta +lanza +lápiz +largo +larva +lástima +lata +látex +latir +laurel +lavar +lazo +leal +lección +leche +lector +leer +legión +legumbre +lejano +lengua +lento +leña +león +leopardo +lesión +letal +letra +leve +leyenda +libertad +libro +licor +líder +lidiar +lienzo +liga +ligero +lima +límite +limón +limpio +lince +lindo +línea +lingote +lino +linterna +líquido +liso +lista +litera +litio +litro +llaga +llama +llanto +llave +llegar +llenar +llevar +llorar +llover +lluvia +lobo +loción +loco +locura +lógica +logro +lombriz +lomo +lonja +lote +lucha +lucir +lugar +lujo +luna +lunes +lupa +lustro +luto +luz +maceta +macho +madera +madre +maduro +maestro +mafia +magia +mago +maíz +maldad +maleta +malla +malo +mamá +mambo +mamut +manco +mando +manejar +manga +maniquí +manjar +mano +manso +manta +mañana +mapa +máquina +mar +marco +marea +marfil +margen +marido +mármol +marrón +martes +marzo +masa +máscara +masivo +matar +materia +matiz +matriz +máximo +mayor +mazorca +mecha +medalla +medio +médula +mejilla +mejor +melena +melón +memoria +menor +mensaje +mente +menú +mercado +merengue +mérito +mes +mesón +meta +meter +método +metro +mezcla +miedo +miel +miembro +miga +mil +milagro +militar +millón +mimo +mina +minero +mínimo +minuto +miope +mirar +misa +miseria +misil +mismo +mitad +mito +mochila +moción +moda +modelo +moho +mojar +molde +moler +molino +momento +momia +monarca +moneda +monja +monto +moño +morada +morder +moreno +morir +morro +morsa +mortal +mosca +mostrar +motivo +mover +móvil +mozo +mucho +mudar +mueble +muela +muerte +muestra +mugre +mujer +mula +muleta +multa +mundo +muñeca +mural +muro +músculo +museo +musgo +música +muslo +nácar +nación +nadar +naipe +naranja +nariz +narrar +nasal +natal +nativo +natural +náusea +naval +nave +navidad +necio +néctar +negar +negocio +negro +neón +nervio +neto +neutro +nevar +nevera +nicho +nido +niebla +nieto +niñez +niño +nítido +nivel +nobleza +noche +nómina +noria +norma +norte +nota +noticia +novato +novela +novio +nube +nuca +núcleo +nudillo +nudo +nuera +nueve +nuez +nulo +número +nutria +oasis +obeso +obispo +objeto +obra +obrero +observar +obtener +obvio +oca +ocaso +océano +ochenta +ocho +ocio +ocre +octavo +octubre +oculto +ocupar +ocurrir +odiar +odio +odisea +oeste +ofensa +oferta +oficio +ofrecer +ogro +oído +oír +ojo +ola +oleada +olfato +olivo +olla +olmo +olor +olvido +ombligo +onda +onza +opaco +opción +ópera +opinar +oponer +optar +óptica +opuesto +oración +orador +oral +órbita +orca +orden +oreja +órgano +orgía +orgullo +oriente +origen +orilla +oro +orquesta +oruga +osadía +oscuro +osezno +oso +ostra +otoño +otro +oveja +óvulo +óxido +oxígeno +oyente +ozono +pacto +padre +paella +página +pago +país +pájaro +palabra +palco +paleta +pálido +palma +paloma +palpar +pan +panal +pánico +pantera +pañuelo +papá +papel +papilla +paquete +parar +parcela +pared +parir +paro +párpado +parque +párrafo +parte +pasar +paseo +pasión +paso +pasta +pata +patio +patria +pausa +pauta +pavo +payaso +peatón +pecado +pecera +pecho +pedal +pedir +pegar +peine +pelar +peldaño +pelea +peligro +pellejo +pelo +peluca +pena +pensar +peñón +peón +peor +pepino +pequeño +pera +percha +perder +pereza +perfil +perico +perla +permiso +perro +persona +pesa +pesca +pésimo +pestaña +pétalo +petróleo +pez +pezuña +picar +pichón +pie +piedra +pierna +pieza +pijama +pilar +piloto +pimienta +pino +pintor +pinza +piña +piojo +pipa +pirata +pisar +piscina +piso +pista +pitón +pizca +placa +plan +plata +playa +plaza +pleito +pleno +plomo +pluma +plural +pobre +poco +poder +podio +poema +poesía +poeta +polen +policía +pollo +polvo +pomada +pomelo +pomo +pompa +poner +porción +portal +posada +poseer +posible +poste +potencia +potro +pozo +prado +precoz +pregunta +premio +prensa +preso +previo +primo +príncipe +prisión +privar +proa +probar +proceso +producto +proeza +profesor +programa +prole +promesa +pronto +propio +próximo +prueba +público +puchero +pudor +pueblo +puerta +puesto +pulga +pulir +pulmón +pulpo +pulso +puma +punto +puñal +puño +pupa +pupila +puré +quedar +queja +quemar +querer +queso +quieto +química +quince +quitar +rábano +rabia +rabo +ración +radical +raíz +rama +rampa +rancho +rango +rapaz +rápido +rapto +rasgo +raspa +rato +rayo +raza +razón +reacción +realidad +rebaño +rebote +recaer +receta +rechazo +recoger +recreo +recto +recurso +red +redondo +reducir +reflejo +reforma +refrán +refugio +regalo +regir +regla +regreso +rehén +reino +reír +reja +relato +relevo +relieve +relleno +reloj +remar +remedio +remo +rencor +rendir +renta +reparto +repetir +reposo +reptil +res +rescate +resina +respeto +resto +resumen +retiro +retorno +retrato +reunir +revés +revista +rey +rezar +rico +riego +rienda +riesgo +rifa +rígido +rigor +rincón +riñón +río +riqueza +risa +ritmo +rito +rizo +roble +roce +rociar +rodar +rodeo +rodilla +roer +rojizo +rojo +romero +romper +ron +ronco +ronda +ropa +ropero +rosa +rosca +rostro +rotar +rubí +rubor +rudo +rueda +rugir +ruido +ruina +ruleta +rulo +rumbo +rumor +ruptura +ruta +rutina +sábado +saber +sabio +sable +sacar +sagaz +sagrado +sala +saldo +salero +salir +salmón +salón +salsa +salto +salud +salvar +samba +sanción +sandía +sanear +sangre +sanidad +sano +santo +sapo +saque +sardina +sartén +sastre +satán +sauna +saxofón +sección +seco +secreto +secta +sed +seguir +seis +sello +selva +semana +semilla +senda +sensor +señal +señor +separar +sepia +sequía +ser +serie +sermón +servir +sesenta +sesión +seta +setenta +severo +sexo +sexto +sidra +siesta +siete +siglo +signo +sílaba +silbar +silencio +silla +símbolo +simio +sirena +sistema +sitio +situar +sobre +socio +sodio +sol +solapa +soldado +soledad +sólido +soltar +solución +sombra +sondeo +sonido +sonoro +sonrisa +sopa +soplar +soporte +sordo +sorpresa +sorteo +sostén +sótano +suave +subir +suceso +sudor +suegra +suelo +sueño +suerte +sufrir +sujeto +sultán +sumar +superar +suplir +suponer +supremo +sur +surco +sureño +surgir +susto +sutil +tabaco +tabique +tabla +tabú +taco +tacto +tajo +talar +talco +talento +talla +talón +tamaño +tambor +tango +tanque +tapa +tapete +tapia +tapón +taquilla +tarde +tarea +tarifa +tarjeta +tarot +tarro +tarta +tatuaje +tauro +taza +tazón +teatro +techo +tecla +técnica +tejado +tejer +tejido +tela +teléfono +tema +temor +templo +tenaz +tender +tener +tenis +tenso +teoría +terapia +terco +término +ternura +terror +tesis +tesoro +testigo +tetera +texto +tez +tibio +tiburón +tiempo +tienda +tierra +tieso +tigre +tijera +tilde +timbre +tímido +timo +tinta +tío +típico +tipo +tira +tirón +titán +títere +título +tiza +toalla +tobillo +tocar +tocino +todo +toga +toldo +tomar +tono +tonto +topar +tope +toque +tórax +torero +tormenta +torneo +toro +torpedo +torre +torso +tortuga +tos +tosco +toser +tóxico +trabajo +tractor +traer +tráfico +trago +traje +tramo +trance +trato +trauma +trazar +trébol +tregua +treinta +tren +trepar +tres +tribu +trigo +tripa +triste +triunfo +trofeo +trompa +tronco +tropa +trote +trozo +truco +trueno +trufa +tubería +tubo +tuerto +tumba +tumor +túnel +túnica +turbina +turismo +turno +tutor +ubicar +úlcera +umbral +unidad +unir +universo +uno +untar +uña +urbano +urbe +urgente +urna +usar +usuario +útil +utopía +uva +vaca +vacío +vacuna +vagar +vago +vaina +vajilla +vale +válido +valle +valor +válvula +vampiro +vara +variar +varón +vaso +vecino +vector +vehículo +veinte +vejez +vela +velero +veloz +vena +vencer +venda +veneno +vengar +venir +venta +venus +ver +verano +verbo +verde +vereda +verja +verso +verter +vía +viaje +vibrar +vicio +víctima +vida +vídeo +vidrio +viejo +viernes +vigor +vil +villa +vinagre +vino +viñedo +violín +viral +virgo +virtud +visor +víspera +vista +vitamina +viudo +vivaz +vivero +vivir +vivo +volcán +volumen +volver +voraz +votar +voto +voz +vuelo +vulgar +yacer +yate +yegua +yema +yerno +yeso +yodo +yoga +yogur +zafiro +zanja +zapato +zarza +zona +zorro +zumo +zurdo diff --git a/docs/android.html b/docs/android.html new file mode 100644 index 00000000..1aed1a47 --- /dev/null +++ b/docs/android.html @@ -0,0 +1,60 @@ + + +
+

Electrum for Android

+ +This page explains how to install Electrum on Android devices.

+ +Please note that Electrum is not distributed as a binary package, but +as python source code; this gives users the possibility to see what +the code is doing, and to check that it does not contain malware. The +downside is that installation is slightly more complicated than +downloading an app on the Android market, but it remains very +simple.

+ +It is possible to print this page on paper and to install everything from +QR codes. If you encounter problems, you may find help at + +this link. + + +

1. Download and install Google Scripting Layer for Android

+ +You can get +it here, +or by scanning the following qr code:
+ + + +

2. Download and install Python for Android

+ +You can get +it here, +or by scanning the following qr code:
+ +
+Once you have installed the apk, launch the Python for Android application and click 'install' + +

3. Download the Electrum install script

+ +Download e4a_install.py and install it in your sl4a/scripts directory. +You can do it manually, or from QR code, as follows: +
+1. Launch SL4A.
+2. Press the Menu button.
+3. Tap Add.
+4. Tap Scan Barcode.
+5. Scan the following QRcode:
+
+ +
This will install a script named e4a_install.py
+ +

4. Download and install Electrum

+
+1. Tap e4a_install.py: it will download and install a directory named "Electrum-0.43d"
+2. To launch Electrum, visit the "Electrum-0.43d" directory and tap 'electrum4a.py'
+
+ + diff --git a/docs/cold_storage b/docs/cold_storage new file mode 100644 index 00000000..f94a524e --- /dev/null +++ b/docs/cold_storage @@ -0,0 +1,31 @@ +Here is how to sign a transaction with an offline Electrum wallet. + +1. With your online (seedless) wallet, create the transaction using 'mktx': + +./electrum -w seedless_wallet mktx 1Cpf9zb5Rm5Z5qmmGezn6ERxFWvwuZ6UCx 0.1 +{ + "complete": false, + "hex": "01000000015a92850cc5dc7bb7c1a711c1ce0c1658596c085d49c17fce68c641cce0bdd188010000004801ff45fe197f1a7a7779f58690c3100364d7ce596bf47bb52e88e617e22940bf54a8f139194652584b0d357eb95defb8b4911b0a53118b8afecb96aedb1334e772df350901002800ffffffff02b1f0f65d000000001976a9147ea19cc36d846e2ce81762def3cb9299bed0847188ac80969800000000001976a91451e814c0f7637ba9a59bc11628337a2df6559a5088ac00000000" +} + +Electrum returns an unsigned transaction. Note that the serialization +format contains the master public key needed and key derivation, used +by the offline wallet to sign the transaction. + + +2. Sign the transaction with your offline wallet, using 'signrawtransaction': + +./electrum -w wallet_with_seed signrawtransaction 01000000015a92850cc5dc7bb7c1a711c1ce0c1658596c085d49c17fce68c641cce0bdd188010000004801ff45fe197f1a7a7779f58690c3100364d7ce596bf47bb52e88e617e22940bf54a8f139194652584b0d357eb95defb8b4911b0a53118b8afecb96aedb1334e772df350901002800ffffffff02b1f0f65d000000001976a9147ea19cc36d846e2ce81762def3cb9299bed0847188ac80969800000000001976a91451e814c0f7637ba9a59bc11628337a2df6559a5088ac00000000 +Password: +{ + "complete": true, + "hex": "01000000015a92850cc5dc7bb7c1a711c1ce0c1658596c085d49c17fce68c641cce0bdd188010000008b483045022100c65dd8899d4e1d12b1ebaa0ea15835f9a158343733fbe990cdfebde2164d89c802201a5a8fe737b07daf700aeecf3b6a4111c563ebc181da75b1f264883060c273da0141040beb415f075a532982fe982d01736453d4e3413566c79a39d16679474c7ab94022269b9f726edc152a89dfcf18cd3dd2a38fc5e442f24d22a51545ca42beb7b5ffffffff02b1f0f65d000000001976a9147ea19cc36d846e2ce81762def3cb9299bed0847188ac80969800000000001976a91451e814c0f7637ba9a59bc11628337a2df6559a5088ac00000000" +} + +The result is a fully signed transaction, as indicated by the "complete" field. + + +3. Broadcast the transaction to the Bitcoin network, using 'sendrawtransaction': + + ./electrum sendrawtransaction 01000000015a92850cc5dc7bb7c1a711c1ce0c1658596c085d49c17fce68c641cce0bdd188010000008b483045022100c65dd8899d4e1d12b1ebaa0ea15835f9a158343733fbe990cdfebde2164d89c802201a5a8fe737b07daf700aeecf3b6a4111c563ebc181da75b1f264883060c273da0141040beb415f075a532982fe982d01736453d4e3413566c79a39d16679474c7ab94022269b9f726edc152a89dfcf18cd3dd2a38fc5e442f24d22a51545ca42beb7b5ffffffff02b1f0f65d000000001976a9147ea19cc36d846e2ce81762def3cb9299bed0847188ac80969800000000001976a91451e814c0f7637ba9a59bc11628337a2df6559a5088ac00000000 +"ef6b561232f3c507219ab7d2a79f8849e14ed7e926e77546c2d9e751905b825b" diff --git a/docs/console.html b/docs/console.html new file mode 100644 index 00000000..e8430f02 --- /dev/null +++ b/docs/console.html @@ -0,0 +1,71 @@ + + +This is the documentation for the Electrum Console.
+ + +
+
+Most Electrum command-line commands are also available in the console.
+The results are Python objects, even though they are +sometimes rendered as JSON for clarity.
+
+Let us call listunspent(), to see the list of unspent outputs in the wallet: +
+>> listunspent()
+[
+    {
+        "address": "12cmY5RHRgx8KkUKASDcDYRotget9FNso3", 
+        "index": 0, 
+        "raw_output_script": "76a91411bbdc6e3a27c44644d83f783ca7df3bdc2778e688ac", 
+        "tx_hash": "e7029df9ac8735b04e8e957d0ce73987b5c9c5e920ec4a445130cdeca654f096", 
+        "value": 0.01
+    }, 
+    {
+        "address": "1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF", 
+        "index": 0, 
+        "raw_output_script": "76a914aaf437e25805f288141bfcdc27887ee5492bd13188ac", 
+        "tx_hash": "b30edf57ca2a31560b5b6e8dfe567734eb9f7d3259bb334653276efe520735df", 
+        "value": 9.04735316
+    }
+]
+
+Note that the result is rendered as JSON.
+However, if we save it to a Python variable, it is rendered as a Python object: +
+>> u = listunspent()
+>> u
+[{'tx_hash': u'e7029df9ac8735b04e8e957d0ce73987b5c9c5e920ec4a445130cdeca654f096', 'index': 0, 'raw_output_script': '76a91411bbdc6e3a27c44644d83f783ca7df3bdc2778e688ac', 'value': 0.01, 'address': '12cmY5RHRgx8KkUKASDcDYRotget9FNso3'}, {'tx_hash': u'b30edf57ca2a31560b5b6e8dfe567734eb9f7d3259bb334653276efe520735df', 'index': 0, 'raw_output_script': '76a914aaf437e25805f288141bfcdc27887ee5492bd13188ac', 'value': 9.04735316, 'address': '1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF'}]
+
+
+This makes it possible to combine Electrum commands with Python.
+For example, let us pick only the addresses in the previous result: +
+>> map(lambda x:x.get('address'), listunspent())
+[
+    "12cmY5RHRgx8KkUKASDcDYRotget9FNso3", 
+    "1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF"
+]
+
+Here we combine two commands, listunspent +and dumpprivkeys, in order to dump the private keys of all adresses that have unspent outputs: +
+>> dumpprivkeys( map(lambda x:x.get('address'), listunspent()) )
+{
+    "12cmY5RHRgx8KkUKASDcDYRotget9FNso3": "***************************************************", 
+    "1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF": "***************************************************"
+}
+
+Note that dumpprivkey will ask for your password if your +wallet is encrypted. +
+The GUI methods can be accessed through the gui variable. +For example, you can display a QR code from a string using +gui.show_qrcode. +Example: +
+gui.show_qrcode(dumpprivkey(listunspent()[0]['address']))
+
+ +
+ + diff --git a/electrum b/electrum new file mode 100755 index 00000000..63314597 --- /dev/null +++ b/electrum @@ -0,0 +1,473 @@ +#!/usr/bin/env python2 +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from decimal import Decimal +import json +import optparse +import os +import re +import ast +import sys +import time +import traceback + + +is_local = os.path.dirname(os.path.realpath(__file__)) == os.getcwd() +is_android = 'ANDROID_DATA' in os.environ + +if is_local: + sys.path.append('packages') + +import __builtin__ +__builtin__.use_local_modules = is_local or is_android + +# load local module as electrum +if __builtin__.use_local_modules: + import imp + imp.load_module('electrum', *imp.find_module('lib')) + imp.load_module('electrum_gui', *imp.find_module('gui')) + + +from electrum import util +from electrum import SimpleConfig, Network, Wallet, WalletStorage, NetworkProxy, Commands, known_commands, pick_random_server +from electrum.util import print_msg, print_stderr, print_json, set_verbosity +from electrum.daemon import get_daemon +from electrum.plugins import init_plugins + + + +# get password routine +def prompt_password(prompt, confirm=True): + import getpass + if sys.stdin.isatty(): + password = getpass.getpass(prompt) + if password and confirm: + password2 = getpass.getpass("Confirm: ") + if password != password2: + sys.exit("Error: Passwords do not match.") + else: + password = raw_input(prompt) + if not password: + password = None + return password + + +def arg_parser(): + usage = "%prog [options] command" + parser = optparse.OptionParser(usage=usage, add_help_option=False) + parser.add_option("-h", "--help", action="callback", callback=print_help_cb, help="show this help text") + parser.add_option("-g", "--gui", dest="gui", help="User interface: qt, lite, gtk, text or stdio") + parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum.dat)") + parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline") + parser.add_option("-d", "--daemon", action="store_true", dest="daemon", default=False, help="use daemon") + parser.add_option("-C", "--concealed", action="store_true", dest="concealed", default=False, help="don't echo seed to console when restoring") + parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses") + parser.add_option("-l", "--labels", action="store_true", dest="show_labels", default=False, help="show the labels of listed addresses") + parser.add_option("-f", "--fee", dest="tx_fee", default=None, help="set tx fee") + parser.add_option("-F", "--fromaddr", dest="from_addr", default=None, help="set source address for payto/mktx. if it isn't in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It's not saved in the wallet.") + parser.add_option("-c", "--changeaddr", dest="change_addr", default=None, help="set the change address for payto/mktx. default is a spare address, or the source address if it's not in the wallet") + parser.add_option("-s", "--server", dest="server", default=None, help="set server host:port:protocol, where protocol is either t (tcp), h (http), s (tcp+ssl), or g (https)") + parser.add_option("-p", "--proxy", dest="proxy", default=None, help="set proxy [type:]host[:port], where type is socks4,socks5 or http") + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="show debugging information") + parser.add_option("-P", "--portable", action="store_true", dest="portable", default=False, help="portable wallet") + parser.add_option("-L", "--lang", dest="language", default=None, help="defaut language used in GUI") + parser.add_option("-G", "--gap", dest="gap_limit", default=None, help="gap limit") + parser.add_option("-W", "--password", dest="password", default=None, help="set password for usage with commands (currently only implemented for create command, do not use it for longrunning gui session since the password is visible in /proc)") + parser.add_option("-1", "--oneserver", action="store_true", dest="oneserver", default=False, help="connect to one server only") + parser.add_option("--mpk", dest="mpk", default=False, help="restore from master public key") + parser.add_option("-m", action="store_true", dest="hide_gui", default=False, help="hide GUI on startup") + parser.add_option("--nbits", dest="nbits", default="128", help="number of bits for make_seed") + parser.add_option("--entropy", dest="entropy", default="1", help="custom entropy for make_seed") + return parser + + +def print_help(parser): + parser.print_help() + print_msg("Type 'electrum help ' to see the help for a specific command") + print_msg("Type 'electrum --help' to see the list of options") + run_command(known_commands['help']) + + +def print_help_cb(self, opt, value, parser): + print_help(parser) + sys.exit(1) + + +def run_command(cmd, password=None, args=None): + if args is None: + args = [] # Do not use mutables as default values! + if cmd.requires_network and not options.offline: + s = get_daemon(config, True) + network = NetworkProxy(s, config) + network.start() + while network.is_connecting(): + time.sleep(0.1) + if not network.is_connected(): + print_msg("daemon is not connected") + sys.exit(1) + if wallet: + wallet.start_threads(network) + wallet.update() + else: + network = None + + cmd_runner = Commands(wallet, network) + func = getattr(cmd_runner, cmd.name) + cmd_runner.password = password + try: + result = func(*args[1:]) + except Exception: + traceback.print_exc(file=sys.stdout) + sys.exit(1) + + + if cmd.requires_network and not options.offline: + if wallet: + wallet.stop_threads() + network.stop() + + + if type(result) == str: + print_msg(result) + elif result is not None: + print_json(result) + + + +if __name__ == '__main__': + + wallet = None + parser = arg_parser() + options, args = parser.parse_args() + if options.portable and options.wallet_path is None: + options.electrum_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electrum_data') + + # config is an object passed to the various constructors (wallet, interface, gui) + if is_android: + config_options = { + 'portable': True, + 'verbose': True, + 'gui': 'android', + 'auto_cycle': True, + } + else: + config_options = eval(str(options)) + for k, v in config_options.items(): + if v is None: + config_options.pop(k) + + set_verbosity(config_options.get('verbose')) + + config = SimpleConfig(config_options) + + if len(args) == 0: + url = None + cmd = 'gui' + elif len(args) == 1 and re.match('^bitcoin:', args[0]): + url = args[0] + cmd = 'gui' + else: + cmd = args[0] + + if cmd == 'gui': + init_plugins(config) + gui_name = config.get('gui', 'classic') + if gui_name in ['lite', 'classic']: + gui_name = 'qt' + try: + gui = __import__('electrum_gui.' + gui_name, fromlist=['electrum_gui']) + except ImportError: + traceback.print_exc(file=sys.stdout) + sys.exit() + #sys.exit("Error: Unknown GUI: " + gui_name ) + + # network interface + if not options.offline: + s = get_daemon(config, start_daemon=options.daemon) + network = NetworkProxy(s, config) + network.start() + else: + network = None + + gui = gui.ElectrumGui(config, network) + gui.main(url) + + if network: + network.stop() + + # we use daemon threads, their termination is enforced. + # this sleep command gives them time to terminate cleanly. + time.sleep(0.3) + sys.exit(0) + + if cmd == 'daemon': + arg = args[1] if len(args)>1 else None + if arg not in ['start', 'stop', 'status']: + print_msg("syntax: electrum daemon ") + sys.exit(1) + s = get_daemon(config, False) + if arg == 'start': + if s: + print_msg("Daemon already running") + sys.exit(1) + get_daemon(config, True) + sys.exit(0) + elif arg in ['status','stop']: + if not s: + print_msg("Daemon not running") + sys.exit(1) + network = NetworkProxy(s, config) + network.start() + if arg == 'status': + print_json({ + 'server': network.get_parameters()[0], + 'blockchain_height': network.get_local_height(), + 'server_height': network.get_server_height(), + 'nodes': network.get_interfaces(), + 'connected': network.is_connected() + }) + elif arg == 'stop': + network.stop_daemon() + print_msg("Daemon stopped") + network.stop() + else: + print "unknown command \"%s\""% arg + sys.exit(0) + + + if cmd not in known_commands: + cmd = 'help' + + cmd = known_commands[cmd] + + # instanciate wallet for command-line + storage = WalletStorage(config) + + if cmd.name in ['create', 'restore']: + if storage.file_exists: + sys.exit("Error: Remove the existing wallet first!") + if options.password is not None: + password = options.password + elif cmd.name == 'restore' and options.mpk: + password = None + else: + password = prompt_password("Password (hit return if you do not wish to encrypt your wallet):") + + # if config.server is set, the user either passed the server on command line + # or chose it previously already. if he didn't pass a server on the command line, + # we just pick up a random one. + if not config.get('server'): + config.set_key('server', pick_random_server()) + + #fee = options.tx_fee if options.tx_fee else raw_input("fee (default:%s):" % (str(Decimal(wallet.fee)/100000000))) + #gap = options.gap_limit if options.gap_limit else raw_input("gap limit (default 5):") + #if fee: + # wallet.set_fee(float(fee)*100000000) + #if gap: + # wallet.change_gap_limit(int(gap)) + + if cmd.name == 'restore': + if options.mpk: + if Wallet.is_old_mpk(options.mpk): + wallet = Wallet.from_old_mpk(options.mpk, storage) + if Wallet.is_xpub(options.mpk): + wallet = Wallet.from_xpub(options.mpk, storage) + else: + import getpass + seed = getpass.getpass(prompt="seed:", stream=None) if options.concealed else raw_input("seed:") + if not Wallet.is_seed(seed): + sys.exit("Error: Invalid seed") + wallet = Wallet.from_seed(seed, storage) + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + + if not options.offline: + s = get_daemon(config, True) + network = NetworkProxy(s,config) + network.start() + wallet.start_threads(network) + print_msg("Recovering wallet...") + wallet.restore(lambda x: x) + if wallet.is_found(): + print_msg("Recovery successful") + else: + print_msg("Warning: Found no history for this wallet") + else: + wallet.synchronize() + print_msg("Warning: This wallet was restored offline. It may contain more addresses than displayed.") + + else: + wallet = Wallet(storage) + seed = wallet.make_seed() + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + wallet.synchronize() + print_msg("Your wallet generation seed is:\n\"%s\"" % seed) + print_msg("Please keep it in a safe place; if you lose it, you will not be able to restore your wallet.") + + + print_msg("Wallet saved in '%s'" % wallet.storage.path) + + # terminate + sys.exit(0) + + + if cmd.name not in ['create', 'restore'] and cmd.requires_wallet and not storage.file_exists: + print_msg("Error: Wallet file not found.") + print_msg("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option") + sys.exit(0) + + + if cmd.requires_wallet: + wallet = Wallet(storage) + else: + wallet = None + + + # important warning + if cmd.name in ['dumpprivkey', 'dumpprivkeys']: + print_stderr("WARNING: ALL your private keys are secret.") + print_stderr("Exposing a single private key can compromise your entire wallet!") + print_stderr("In particular, DO NOT use 'redeem private key' services proposed by third parties.") + + # commands needing password + if cmd.requires_password: + if wallet.seed == '': + seed = '' + password = None + elif wallet.use_encryption: + password = prompt_password('Password:', False) + if not password: + print_msg("Error: Password required") + sys.exit(1) + # check password + try: + seed = wallet.get_seed(password) + except Exception: + print_msg("Error: This password does not decode this wallet.") + sys.exit(1) + else: + password = None + seed = wallet.get_seed(None) + else: + password = None + + # add missing arguments, do type conversions + if (cmd.name == 'importprivkey' and len(args)==1)\ + or (cmd.name == 'signtxwithkey' and len(args)==2): + # See if they specificed a key on the cmd line, if not prompt + args.append(prompt_password('Enter PrivateKey (will not echo):', False)) + + elif cmd.name == 'createmultisig': + args = [cmd, int(args[1]), json.loads(args[2])] + + elif cmd.name == 'createrawtransaction': + args = [cmd, json.loads(args[1]), json.loads(args[2])] + + elif cmd.name == 'listaddresses': + args = [cmd, options.show_all, options.show_labels] + + elif cmd.name == 'make_seed': + args = [cmd, int(options.nbits), long(options.entropy), options.language] + + elif cmd.name in ['payto', 'mktx']: + domain = [options.from_addr] if options.from_addr else None + args = ['mktx', args[1], Decimal(args[2]), Decimal(options.tx_fee) if options.tx_fee else None, options.change_addr, domain] + + elif cmd.name in ['paytomany', 'mksendmanytx']: + domain = [options.from_addr] if options.from_addr else None + outputs = [] + for i in range(1, len(args), 2): + if len(args) < i+2: + print_msg("Error: Mismatched arguments.") + sys.exit(1) + outputs.append((args[i], Decimal(args[i+1]))) + args = ['mksendmanytx', outputs, Decimal(options.tx_fee) if options.tx_fee else None, options.change_addr, domain] + + elif cmd.name == 'help': + if len(args) < 2: + print_help(parser) + sys.exit(1) + + # check the number of arguments + if len(args) - 1 < cmd.min_args: + print_msg("Not enough arguments") + print_msg("Syntax:", cmd.syntax) + sys.exit(1) + + if cmd.max_args >= 0 and len(args) - 1 > cmd.max_args: + print_msg("too many arguments", args) + print_msg("Syntax:", cmd.syntax) + sys.exit(1) + + if cmd.max_args < 0: + if len(args) > cmd.min_args + 1: + message = ' '.join(args[cmd.min_args:]) + print_msg("Warning: Final argument was reconstructed from several arguments:", repr(message)) + args = args[0:cmd.min_args] + [message] + + if cmd.name == 'check_seed': + args.append(long(options.entropy)) + args.append(options.language) + + + # run the command + if cmd.name == 'deseed': + if not wallet.seed: + print_msg("Error: This wallet has no seed") + else: + ns = wallet.storage.path + '.seedless' + print_msg("Warning: you are going to create a seedless wallet'\nIt will be saved in '%s'" % ns) + if raw_input("Are you sure you want to continue? (y/n) ") in ['y', 'Y', 'yes']: + wallet.storage.path = ns + wallet.seed = '' + wallet.storage.put('seed', '', True) + wallet.use_encryption = False + wallet.storage.put('use_encryption', wallet.use_encryption, True) + for k in wallet.imported_keys.keys(): + wallet.imported_keys[k] = '' + wallet.storage.put('imported_keys', wallet.imported_keys, True) + print_msg("Done.") + else: + print_msg("Action canceled.") + + elif cmd.name == 'getconfig': + key = args[1] + out = config.get(key) + print_msg(out) + + elif cmd.name == 'setconfig': + key, value = args[1:3] + try: + value = ast.literal_eval(value) + except: + pass + config.set_key(key, value, True) + print_msg(True) + + elif cmd.name == 'password': + new_password = prompt_password('New password:') + wallet.update_password(password, new_password) + + else: + run_command(cmd, password, args) + + time.sleep(0.1) + sys.exit(0) diff --git a/electrum-ixc b/electrum-ixc new file mode 100755 index 00000000..7c11c587 --- /dev/null +++ b/electrum-ixc @@ -0,0 +1,476 @@ +#!/usr/bin/env python2 +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from decimal import Decimal +import json +import optparse +import os +import re +import ast +import sys +import time +import traceback + + +is_local = os.path.dirname(os.path.realpath(__file__)) == os.getcwd() +is_android = 'ANDROID_DATA' in os.environ + +if is_local: + sys.path.append('packages') + +import __builtin__ +__builtin__.use_local_modules = is_local or is_android + +# load local module as electrum +if __builtin__.use_local_modules: + import imp + imp.load_module('electrum_ixc', *imp.find_module('lib')) + imp.load_module('electrum_ixc_gui', *imp.find_module('gui')) + + +from electrum_ixc import util +from electrum_ixc import SimpleConfig, Network, Wallet, WalletStorage, NetworkProxy, Commands, known_commands, pick_random_server +from electrum_ixc.util import print_msg, print_stderr, print_json, set_verbosity +from electrum_ixc.daemon import get_daemon +from electrum_ixc.plugins import init_plugins + + + +# get password routine +def prompt_password(prompt, confirm=True): + import getpass + if sys.stdin.isatty(): + password = getpass.getpass(prompt) + if password and confirm: + password2 = getpass.getpass("Confirm: ") + if password != password2: + sys.exit("Error: Passwords do not match.") + else: + password = raw_input(prompt) + if not password: + password = None + return password + + +def arg_parser(): + usage = "%prog [options] command" + parser = optparse.OptionParser(usage=usage, add_help_option=False) + parser.add_option("-h", "--help", action="callback", callback=print_help_cb, help="show this help text") + parser.add_option("-g", "--gui", dest="gui", help="User interface: qt, lite, gtk, text or stdio") + parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum-ixc.dat)") + parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline") + parser.add_option("-d", "--daemon", action="store_true", dest="daemon", default=False, help="use daemon") + parser.add_option("-C", "--concealed", action="store_true", dest="concealed", default=False, help="don't echo seed to console when restoring") + parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses") + parser.add_option("-l", "--labels", action="store_true", dest="show_labels", default=False, help="show the labels of listed addresses") + parser.add_option("-f", "--fee", dest="tx_fee", default=None, help="set tx fee") + parser.add_option("-F", "--fromaddr", dest="from_addr", default=None, help="set source address for payto/mktx. if it isn't in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It's not saved in the wallet.") + parser.add_option("-c", "--changeaddr", dest="change_addr", default=None, help="set the change address for payto/mktx. default is a spare address, or the source address if it's not in the wallet") + parser.add_option("-s", "--server", dest="server", default=None, help="set server host:port:protocol, where protocol is either t (tcp), h (http), s (tcp+ssl), or g (https)") + parser.add_option("-p", "--proxy", dest="proxy", default=None, help="set proxy [type:]host[:port], where type is socks4,socks5 or http") + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="show debugging information") + parser.add_option("-P", "--portable", action="store_true", dest="portable", default=False, help="portable wallet") + parser.add_option("-L", "--lang", dest="language", default=None, help="defaut language used in GUI") + parser.add_option("-G", "--gap", dest="gap_limit", default=None, help="gap limit") + parser.add_option("-W", "--password", dest="password", default=None, help="set password for usage with commands (currently only implemented for create command, do not use it for longrunning gui session since the password is visible in /proc)") + parser.add_option("-1", "--oneserver", action="store_true", dest="oneserver", default=False, help="connect to one server only") + parser.add_option("--mpk", dest="mpk", default=False, help="restore from master public key") + parser.add_option("-m", action="store_true", dest="hide_gui", default=False, help="hide GUI on startup") + parser.add_option("--nbits", dest="nbits", default="128", help="number of bits for make_seed") + parser.add_option("--entropy", dest="entropy", default="1", help="custom entropy for make_seed") + return parser + + +def print_help(parser): + parser.print_help() + print_msg("Type 'electrum-ixc help ' to see the help for a specific command") + print_msg("Type 'electrum-ixc --help' to see the list of options") + run_command(known_commands['help']) + + +def print_help_cb(self, opt, value, parser): + print_help(parser) + sys.exit(1) + + +def run_command(cmd, password=None, args=None): + if args is None: + args = [] # Do not use mutables as default values! + if cmd.requires_network and not options.offline: + s = get_daemon(config, True) + network = NetworkProxy(s, config) + network.start() + while network.is_connecting(): + time.sleep(0.1) + if not network.is_connected(): + print_msg("daemon is not connected") + sys.exit(1) + if wallet: + wallet.start_threads(network) + wallet.update() + else: + network = None + + cmd_runner = Commands(wallet, network) + func = getattr(cmd_runner, cmd.name) + cmd_runner.password = password + try: + result = func(*args[1:]) + except Exception: + traceback.print_exc(file=sys.stdout) + sys.exit(1) + + + if cmd.requires_network and not options.offline: + if wallet: + wallet.stop_threads() + network.stop() + + + if type(result) == str: + print_msg(result) + elif result is not None: + print_json(result) + + + +if __name__ == '__main__': + + wallet = None + parser = arg_parser() + options, args = parser.parse_args() + if options.portable and options.wallet_path is None: + options.electrum_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electrum_data') + + # config is an object passed to the various constructors (wallet, interface, gui) + if is_android: + config_options = { + 'portable': True, + 'verbose': True, + 'gui': 'android', + 'auto_cycle': True, + } + else: + config_options = eval(str(options)) + for k, v in config_options.items(): + if v is None: + config_options.pop(k) + + set_verbosity(config_options.get('verbose')) + + config = SimpleConfig(config_options) + + if len(args) == 0: + url = None + cmd = 'gui' + elif len(args) == 1 and re.match('^bitcoin:', args[0]): + url = args[0] + cmd = 'gui' + else: + cmd = args[0] + + if cmd == 'gui': + init_plugins(config) + gui_name = config.get('gui', 'classic') + if gui_name in ['lite', 'classic']: + gui_name = 'qt' + try: + gui = __import__('electrum_ixc_gui.' + gui_name, fromlist=['electrum_ixc_gui']) + except ImportError: + traceback.print_exc(file=sys.stdout) + sys.exit() + #sys.exit("Error: Unknown GUI: " + gui_name ) + + # network interface + if not options.offline: + s = get_daemon(config, start_daemon=options.daemon) + network = NetworkProxy(s, config) + network.start() + else: + network = None + + gui = gui.ElectrumGui(config, network) + gui.main(url) + + if network: + network.stop() + + # we use daemon threads, their termination is enforced. + # this sleep command gives them time to terminate cleanly. + time.sleep(0.3) + sys.exit(0) + + if cmd == 'daemon': + arg = args[1] if len(args)>1 else None + if arg not in ['start', 'stop', 'status']: + print_msg("syntax: electrum daemon ") + sys.exit(1) + s = get_daemon(config, False) + if arg == 'start': + if s: + print_msg("Daemon already running") + sys.exit(1) + get_daemon(config, True) + sys.exit(0) + elif arg in ['status','stop']: + if not s: + print_msg("Daemon not running") + sys.exit(1) + network = NetworkProxy(s, config) + network.start() + if arg == 'status': + print_json({ + 'server': network.get_parameters()[0], + 'blockchain_height': network.get_local_height(), + 'server_height': network.get_server_height(), + 'nodes': network.get_interfaces(), + 'connected': network.is_connected() + }) + elif arg == 'stop': + network.stop_daemon() + print_msg("Daemon stopped") + network.stop() + else: + print "unknown command \"%s\""% arg + sys.exit(0) + + + if cmd not in known_commands: + cmd = 'help' + + cmd = known_commands[cmd] + + # instanciate wallet for command-line + storage = WalletStorage(config) + + if cmd.name in ['create', 'restore']: + if storage.file_exists: + sys.exit("Error: Remove the existing wallet first!") + if options.password is not None: + password = options.password + elif cmd.name == 'restore' and options.mpk: + password = None + else: + password = prompt_password("Password (hit return if you do not wish to encrypt your wallet):") + + # if config.server is set, the user either passed the server on command line + # or chose it previously already. if he didn't pass a server on the command line, + # we just pick up a random one. + if not config.get('server'): + config.set_key('server', pick_random_server()) + + #fee = options.tx_fee if options.tx_fee else raw_input("fee (default:%s):" % (str(Decimal(wallet.fee)/100000000))) + #gap = options.gap_limit if options.gap_limit else raw_input("gap limit (default 5):") + #if fee: + # wallet.set_fee(float(fee)*100000000) + #if gap: + # wallet.change_gap_limit(int(gap)) + + if cmd.name == 'restore': + if options.mpk: + if Wallet.is_old_mpk(options.mpk): + wallet = Wallet.from_old_mpk(options.mpk, storage) + if Wallet.is_xpub(options.mpk): + wallet = Wallet.from_xpub(options.mpk, storage) + else: + import getpass + seed = getpass.getpass(prompt="seed:", stream=None) if options.concealed else raw_input("seed:") + if not Wallet.is_seed(seed): + sys.exit("Error: Invalid seed") + wallet = Wallet.from_seed(seed, storage) + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + + if not options.offline: + s = get_daemon(config, True) + network = NetworkProxy(s,config) + network.start() + wallet.start_threads(network) + print_msg("Recovering wallet...") + wallet.restore(lambda x: x) + if wallet.is_found(): + print_msg("Recovery successful") + else: + print_msg("Warning: Found no history for this wallet") + else: + wallet.synchronize() + print_msg("Warning: This wallet was restored offline. It may contain more addresses than displayed.") + + else: + wallet = Wallet(storage) + seed = wallet.make_seed() + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + wallet.synchronize() + print_msg("Your wallet generation seed is:\n\"%s\"" % seed) + print_msg("Please keep it in a safe place; if you lose it, you will not be able to restore your wallet.") + + + print_msg("Wallet saved in '%s'" % wallet.storage.path) + + # terminate + sys.exit(0) + + + if cmd.name not in ['create', 'restore'] and cmd.requires_wallet and not storage.file_exists: + print_msg("Error: Wallet file not found.") + print_msg("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option") + sys.exit(0) + + + if cmd.requires_wallet: + wallet = Wallet(storage) + else: + wallet = None + + + # important warning + if cmd.name in ['dumpprivkey', 'dumpprivkeys']: + print_stderr("WARNING: ALL your private keys are secret.") + print_stderr("Exposing a single private key can compromise your entire wallet!") + print_stderr("In particular, DO NOT use 'redeem private key' services proposed by third parties.") + + # commands needing password + if cmd.requires_password: + if wallet.seed == '': + seed = '' + password = None + elif wallet.use_encryption: + password = prompt_password('Password:', False) + if not password: + print_msg("Error: Password required") + sys.exit(1) + # check password + try: + seed = wallet.get_seed(password) + except Exception: + print_msg("Error: This password does not decode this wallet.") + sys.exit(1) + else: + password = None + seed = wallet.get_seed(None) + else: + password = None + + # add missing arguments, do type conversions + if cmd.name == 'importprivkey': + # See if they specificed a key on the cmd line, if not prompt + if len(args) == 1: + args.append(prompt_password('Enter PrivateKey (will not echo):', False)) + + elif cmd.name == 'signrawtransaction': + args = [cmd, args[1], json.loads(args[2]) if len(args) > 2 else [] ] + + elif cmd.name == 'createmultisig': + args = [cmd, int(args[1]), json.loads(args[2])] + + elif cmd.name == 'createrawtransaction': + args = [cmd, json.loads(args[1]), json.loads(args[2])] + + elif cmd.name == 'listaddresses': + args = [cmd, options.show_all, options.show_labels] + + elif cmd.name == 'make_seed': + args = [cmd, int(options.nbits), long(options.entropy), options.language] + + elif cmd.name in ['payto', 'mktx']: + domain = [options.from_addr] if options.from_addr else None + args = ['mktx', args[1], Decimal(args[2]), Decimal(options.tx_fee) if options.tx_fee else None, options.change_addr, domain] + + elif cmd.name in ['paytomany', 'mksendmanytx']: + domain = [options.from_addr] if options.from_addr else None + outputs = [] + for i in range(1, len(args), 2): + if len(args) < i+2: + print_msg("Error: Mismatched arguments.") + sys.exit(1) + outputs.append((args[i], Decimal(args[i+1]))) + args = ['mksendmanytx', outputs, Decimal(options.tx_fee) if options.tx_fee else None, options.change_addr, domain] + + elif cmd.name == 'help': + if len(args) < 2: + print_help(parser) + sys.exit(1) + + # check the number of arguments + if len(args) - 1 < cmd.min_args: + print_msg("Not enough arguments") + print_msg("Syntax:", cmd.syntax) + sys.exit(1) + + if cmd.max_args >= 0 and len(args) - 1 > cmd.max_args: + print_msg("too many arguments", args) + print_msg("Syntax:", cmd.syntax) + sys.exit(1) + + if cmd.max_args < 0: + if len(args) > cmd.min_args + 1: + message = ' '.join(args[cmd.min_args:]) + print_msg("Warning: Final argument was reconstructed from several arguments:", repr(message)) + args = args[0:cmd.min_args] + [message] + + if cmd.name == 'check_seed': + args.append(long(options.entropy)) + args.append(options.language) + + + # run the command + if cmd.name == 'deseed': + if not wallet.seed: + print_msg("Error: This wallet has no seed") + else: + ns = wallet.storage.path + '.seedless' + print_msg("Warning: you are going to create a seedless wallet'\nIt will be saved in '%s'" % ns) + if raw_input("Are you sure you want to continue? (y/n) ") in ['y', 'Y', 'yes']: + wallet.storage.path = ns + wallet.seed = '' + wallet.storage.put('seed', '', True) + wallet.use_encryption = False + wallet.storage.put('use_encryption', wallet.use_encryption, True) + for k in wallet.imported_keys.keys(): + wallet.imported_keys[k] = '' + wallet.storage.put('imported_keys', wallet.imported_keys, True) + print_msg("Done.") + else: + print_msg("Action canceled.") + + elif cmd.name == 'getconfig': + key = args[1] + out = config.get(key) + print_msg(out) + + elif cmd.name == 'setconfig': + key, value = args[1:3] + try: + value = ast.literal_eval(value) + except: + pass + config.set_key(key, value, True) + print_msg(True) + + elif cmd.name == 'password': + new_password = prompt_password('New password:') + wallet.update_password(password, new_password) + + else: + run_command(cmd, password, args) + + time.sleep(0.1) + sys.exit(0) diff --git a/electrum-ixc.conf.sample b/electrum-ixc.conf.sample new file mode 100644 index 00000000..3485108b --- /dev/null +++ b/electrum-ixc.conf.sample @@ -0,0 +1,18 @@ +# Configuration file for the electrum client +# Settings defined here are shared across wallets +# +# copy this file to /etc/electrum-ixc.conf if you want read-only settings +# copy it into your ~/.electrum-ixc/ directory if you want global settings +# that can be rewritten by the client + +[client] +server = 192.168.0.115:50001:t +proxy = None +gap_limit = 5 +# booleans use python syntax +use_change = True +gui = qt +num_zeros = 2 +# default transaction fee is in Satoshis +fee = 10000 #@todo ixcoin fee? +winpos-qt = [799, 226, 877, 435] diff --git a/electrum-ixc.desktop b/electrum-ixc.desktop new file mode 100644 index 00000000..c29bbcf2 --- /dev/null +++ b/electrum-ixc.desktop @@ -0,0 +1,17 @@ +# If you want electrum to appear in a linux app launcher ("start menu"), install this by doing: +# sudo desktop-file-install electrum-ixc.desktop + +[Desktop Entry] +Comment=Lightweight Ixcoin Client +Exec=electrum-ixc %u +GenericName[en_US]=Electrum-IXC +GenericName=Electrum-IXC +Icon=/usr/share/app-install/icons/electrum-ixc.png +Name[en_US]=Electrum Ixcoin Wallet +Name=Electrum Ixcoin Wallet +Categories=Network; +StartupNotify=false +Terminal=false +Type=Application +MimeType=x-scheme-handler/ixcoin + diff --git a/electrum-ixc.png b/electrum-ixc.png new file mode 100644 index 0000000000000000000000000000000000000000..e07a7dc07fc1e4af61e1aed5f2256fbbc4906258 GIT binary patch literal 9322 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 VNPDbT9$gm%c&G3lTrOu3_8*h*D|!F` literal 0 HcmV?d00001 diff --git a/electrum.conf.sample b/electrum.conf.sample new file mode 100644 index 00000000..eb84db01 --- /dev/null +++ b/electrum.conf.sample @@ -0,0 +1,18 @@ +# Configuration file for the electrum client +# Settings defined here are shared across wallets +# +# copy this file to /etc/electrum.conf if you want read-only settings +# copy it into your ~/.electrum/ directory if you want global settings +# that can be rewritten by the client + +[client] +server = electrum.novit.ro:50001:t +proxy = None +gap_limit = 5 +# booleans use python syntax +use_change = True +gui = qt +num_zeros = 2 +# default transaction fee is in Satoshis +fee = 10000 +winpos-qt = [799, 226, 877, 435] diff --git a/electrum.desktop b/electrum.desktop new file mode 100644 index 00000000..1b0c5ab3 --- /dev/null +++ b/electrum.desktop @@ -0,0 +1,17 @@ +# If you want electrum to appear in a linux app launcher ("start menu"), install this by doing: +# sudo desktop-file-install electrum.desktop + +[Desktop Entry] +Comment=Lightweight Bitcoin Client +Exec=electrum %u +GenericName[en_US]=Electrum +GenericName=Electrum +Icon=/usr/share/app-install/icons/electrum.png +Name[en_US]=Electrum Bitcoin Wallet +Name=Electrum Bitcoin Wallet +Categories=Network; +StartupNotify=false +Terminal=false +Type=Application +MimeType=x-scheme-handler/bitcoin + diff --git a/electrum.icns b/electrum.icns new file mode 100644 index 0000000000000000000000000000000000000000..29853f150ce5734238ee35dbe3cc2533ed69de7a GIT binary patch literal 673689 zcmeFa2Y3_L);2mLTe1OZMk8q?tJrcca__x@u>oUx@0eyVr=1@ZWDTnfr5K0J%?z=}e7K9|{ z*`~N?_QO=yyr%~D>+VfaRR7|KV`C^va^m5nSu-e#b}ybuzIXY2ruf~}y|{#YAK0}- z{GR1rTojc=Q9Et;olHpr7ZevoM^Um*7PRA7?QVb51%`wK=>Aq_@3uqh=M!MD1p4@D zcL?^l9eQtrx5;2Mc^l389d^6QOK0-()ag9UUOF$8eX+r)G3YcZl}2aK7z~S9EwAEK zR<%LJaT+bdsW_!lrDE_;spQlgt6~|>#)Ps;hFq!`hEp&s!zz>v`J&{Mtb$Q08GLXY z)0JU094jye18>6aV+*M3ByM3#IRoPfqM#U<&3U-&R-B_iS zaZ$3}wwBrHIbE#`-F1%Des5DlBEu|}&?pOO>e3zh;E2G`$jGq3h!96pqrJV%(a}C; zbF8DO38s*wp1G+OQ@q$z@BFNEi@#q;Mn-QRwAIfN93HCAPEiM2!Yl!tGKf|7R&#@U z_^1Y}*#H&m&#-+wm>!`a{75C^r(_I1M!y10LbRr*zn8a(>6*@HB0};abh_Yz;AmcK zu0O-~3Jvb9gDgXu>x1q~&qPo8Ioizo=>nspf^@!G(&}zoyJ^f?hS7NOzuoNY;+_^u z_u`&y&CXhsTvWDnYVyPRj%F_i^a@zL_! zCVx_Hzh&MvR`cHq3dal}%?^C=(U(R>M)coYx+zp__B^HKx!F@UhI8{A%`Vn3npJCb zjB<{n*_MYQ#w{u-ikKGD*6iSdK=esL_}$HJHxL*NWfpdwII&AGlWQ1F*$un+bHhfH zuWvcNk-gQ@kKg7v zZ(KK1Hs|j)==)~JjW@*x*xE#{i|s*^%uByGe*BB2Vtd;iM3uc8r8b&<0s?%@Mm4qC z?rJpnS|Z9KT_Y^M2IF$O3#Ie5*h1;BP+OQwsIQKyw!0gRLH-7v-sEQuarg7|@G$rV z8I6^8ozf$~S7-3@)NA#Aeg>`H%WTkk2bh%QcD>Q)>+7NO_4V`h*7I5qFF#+Dz;~U| zW|vVqv$vTy+RQFSo;TRMWu6*OZ?lfF+GQG(r>9{q@bnTqr5e4br%5B& zX`_c=qCM1B6Q1f!CY?raHPLFFV3O*L@Jo8Zpw_AlT8&Cge2r42QE9Y#H7^)k^=doC zTXl>EPD!a&!zrm$oLX(=D7955(NL_wyTgTXxTjH<@va&T3JEGoE%04f+yo*ZZE6X} zviMXfIjc&BB1%rB5jc)js?~JP+3<(Xe>fm1PyI zh5@o#Ns91RrW>n;yiz4s!iic{-QX)(1xK7K4{$e@S2NInC6xiyU7=L4xTA$Q)y>Lu zQSm&dki#o0tc;snDOa$(R*k~lC>tYVb!uL%R0?bt1}#wH3&E67b`CQ z(gkjacwmLyPC=Z7W;AK6M8TmjO`cJdV5i6z9X_NAjsycVQA1QwSnU+#C~X-aIF+J| zp>#yTW|vZEky>SATsRB_%5!Rzr^@YAR{`x%D=}iE=?FGTl@@*6wGvS1M~ouDcVTfs zB&zK+rC5cF<>X=+)PqIPRJRJ!*ed%UH5N-`Y)rTX#$pMJj*GI~F_xf&Xp1E(E+Qx} zJT^Mi5}6RvVJy+H#8?8N;u2y5h_OV)I~j{lb|8$!KP5E?#^RUb?=TiAF&4k>HcvO- zl+d8$K+#q*f}L%}zc*~foET;@1*Q4GR&qj|ZN;yz!6za!r|-0RCB^--bE16pxt0!F zQTq)aFky6Vc3NUgbV6!&≥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�ngR7GZ}~j{%G1E6 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Ü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

_#+QN`VlQt;@pYxT2refb?h`8Wh6(o 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

n372}hy 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

Br{IM8ZOIYDiK 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 literal 0 HcmV?d00001 diff --git a/electrum.png b/electrum.png new file mode 100644 index 0000000000000000000000000000000000000000..e07a7dc07fc1e4af61e1aed5f2256fbbc4906258 GIT binary patch literal 9322 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 VNPDbT9$gm%c&G3lTrOu3_8*h*D|!F` literal 0 HcmV?d00001 diff --git a/gui/__init__.py b/gui/__init__.py new file mode 100644 index 00000000..6a94fb5c --- /dev/null +++ b/gui/__init__.py @@ -0,0 +1,5 @@ +# To create a new GUI, please add its code to this directory. +# Two objects must be passed to the ElectrumGui: config and network +# The Wallet object is instanciated by the GUI + +# Notifications about network events are sent to the GUI by using network.register_callback() diff --git a/gui/android.py b/gui/android.py new file mode 100644 index 00000000..ae2d2af7 --- /dev/null +++ b/gui/android.py @@ -0,0 +1,1028 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + + + +from __future__ import absolute_import +import android + +from electrum_ixc import SimpleConfig, Wallet, WalletStorage, format_satoshis, mnemonic_encode, mnemonic_decode +from electrum_ixc.bitcoin import is_valid +from electrum_ixc import util +from decimal import Decimal +import datetime, re + + + +def modal_dialog(title, msg = None): + droid.dialogCreateAlert(title,msg) + droid.dialogSetPositiveButtonText('OK') + droid.dialogShow() + droid.dialogGetResponse() + droid.dialogDismiss() + +def modal_input(title, msg, value = None, etype=None): + droid.dialogCreateInput(title, msg, value, etype) + droid.dialogSetPositiveButtonText('OK') + droid.dialogSetNegativeButtonText('Cancel') + droid.dialogShow() + response = droid.dialogGetResponse() + result = response.result + droid.dialogDismiss() + + if result is None: + print "modal input: result is none" + return modal_input(title, msg, value, etype) + + if result.get('which') == 'positive': + return result.get('value') + +def modal_question(q, msg, pos_text = 'OK', neg_text = 'Cancel'): + droid.dialogCreateAlert(q, msg) + droid.dialogSetPositiveButtonText(pos_text) + droid.dialogSetNegativeButtonText(neg_text) + droid.dialogShow() + response = droid.dialogGetResponse() + result = response.result + droid.dialogDismiss() + + if result is None: + print "modal question: result is none" + return modal_question(q,msg, pos_text, neg_text) + + return result.get('which') == 'positive' + +def edit_label(addr): + v = modal_input('Edit label',None,wallet.labels.get(addr)) + if v is not None: + if v: + wallet.labels[addr] = v + else: + if addr in wallet.labels.keys(): + wallet.labels.pop(addr) + wallet.update_tx_history() + wallet.save() + droid.fullSetProperty("labelTextView", "text", v) + +def select_from_contacts(): + title = 'Contacts:' + droid.dialogCreateAlert(title) + l = [] + for i in range(len(wallet.addressbook)): + addr = wallet.addressbook[i] + label = wallet.labels.get(addr,addr) + l.append( label ) + droid.dialogSetItems(l) + droid.dialogSetPositiveButtonText('New contact') + droid.dialogShow() + response = droid.dialogGetResponse().result + droid.dialogDismiss() + + if response.get('which') == 'positive': + return 'newcontact' + + result = response.get('item') + print result + if result is not None: + addr = wallet.addressbook[result] + return addr + + +def select_from_addresses(): + droid.dialogCreateAlert("Addresses:") + l = [] + addresses = wallet.addresses() + for i in range(len(addresses)): + addr = addresses[i] + label = wallet.labels.get(addr,addr) + l.append( label ) + droid.dialogSetItems(l) + droid.dialogShow() + response = droid.dialogGetResponse() + result = response.result.get('item') + droid.dialogDismiss() + if result is not None: + addr = addresses[result] + return addr + + +def protocol_name(p): + if p == 't': return 'TCP' + if p == 'h': return 'HTTP' + if p == 's': return 'SSL' + if p == 'g': return 'HTTPS' + + +def protocol_dialog(host, protocol, z): + droid.dialogCreateAlert('Protocol',host) + if z: + protocols = z.keys() + else: + protocols = 'thsg' + l = [] + current = protocols.index(protocol) + for p in protocols: + l.append(protocol_name(p)) + droid.dialogSetSingleChoiceItems(l, current) + droid.dialogSetPositiveButtonText('OK') + droid.dialogSetNegativeButtonText('Cancel') + droid.dialogShow() + response = droid.dialogGetResponse().result + selected_item = droid.dialogGetSelectedItems().result + droid.dialogDismiss() + + if not response: return + if not selected_item: return + if response.get('which') == 'positive': + return protocols[selected_item[0]] + + + + +def make_layout(s, scrollable = False): + content = """ + + + + + + + %s """%s + + if scrollable: + content = """ + + + + + %s + + + + """%content + + + return """ + + + %s + """%content + + + + +def main_layout(): + return make_layout(""" + + + + + + + %s """%get_history_layout(15),True) + + + +def qr_layout(addr): + return make_layout(""" + + + + + + + + + + """%(addr,wallet.labels.get(addr,'')), True) + +payto_layout = make_layout(""" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """,False) + + + +settings_layout = make_layout(""" """) + + + +def get_history_values(n): + values = [] + h = wallet.get_tx_history() + length = min(n, len(h)) + for i in range(length): + tx_hash, conf, is_mine, value, fee, balance, timestamp = h[-i-1] + try: + dt = datetime.datetime.fromtimestamp( timestamp ) + if dt.date() == dt.today().date(): + time_str = str( dt.time() ) + else: + time_str = str( dt.date() ) + except Exception: + time_str = 'pending' + + conf_str = 'v' if conf else 'o' + label, is_default_label = wallet.get_label(tx_hash) + values.append((conf_str, ' ' + time_str, ' ' + format_satoshis(value,True), ' ' + label )) + + return values + + +def get_history_layout(n): + rows = "" + i = 0 + values = get_history_values(n) + for v in values: + a,b,c,d = v + color = "#ff00ff00" if a == 'v' else "#ffff0000" + rows += """ + + + + + + """%(i,a,color,i,b,i,c,i,d) + i += 1 + + output = """ + + %s +"""% rows + return output + + +def set_history_layout(n): + values = get_history_values(n) + i = 0 + for v in values: + a,b,c,d = v + droid.fullSetProperty("hl_%d_col1"%i,"text", a) + + if a == 'v': + droid.fullSetProperty("hl_%d_col1"%i, "textColor","#ff00ff00") + else: + droid.fullSetProperty("hl_%d_col1"%i, "textColor","#ffff0000") + + droid.fullSetProperty("hl_%d_col2"%i,"text", b) + droid.fullSetProperty("hl_%d_col3"%i,"text", c) + droid.fullSetProperty("hl_%d_col4"%i,"text", d) + i += 1 + + + + +status_text = '' +def update_layout(): + global status_text + if not network.is_connected(): + text = "Not connected..." + elif not wallet.up_to_date: + text = "Synchronizing..." + else: + c, u = wallet.get_balance() + text = "Balance:"+format_satoshis(c) + if u : text += ' [' + format_satoshis(u,True).strip() + ']' + + + # vibrate if status changed + if text != status_text: + if status_text and network.is_connected() and wallet.up_to_date: + droid.vibrate() + status_text = text + + droid.fullSetProperty("balanceTextView", "text", status_text) + + if wallet.up_to_date: + set_history_layout(15) + + + + +def pay_to(recipient, amount, fee, label): + + if wallet.use_encryption: + password = droid.dialogGetPassword('Password').result + if not password: return + else: + password = None + + droid.dialogCreateSpinnerProgress("Electrum-IXC", "signing transaction...") + droid.dialogShow() + + try: + tx = wallet.mktx( [(recipient, amount)], password, fee) + except Exception as e: + modal_dialog('error', e.message) + droid.dialogDismiss() + return + + if label: + wallet.labels[tx.hash()] = label + + droid.dialogDismiss() + + r, h = wallet.sendtx( tx ) + if r: + modal_dialog('Payment sent', h) + return True + else: + modal_dialog('Error', h) + + + + + + + +def make_new_contact(): + code = droid.scanBarcode() + r = code.result + if r: + data = r['extras']['SCAN_RESULT'] + if data: + if re.match('^ixcoin:', data): + address, _, _, _, _ = util.parse_URI(data) + elif is_valid(data): + address = data + else: + address = None + if address: + if modal_question('Add to contacts?', address): + wallet.add_contact(address) + else: + modal_dialog('Invalid address', data) + + +do_refresh = False + +def update_callback(): + global do_refresh + print "gui callback", network.is_connected() + do_refresh = True + droid.eventPost("refresh",'z') + +def main_loop(): + global do_refresh + + update_layout() + out = None + quitting = False + while out is None: + + event = droid.eventWait(1000).result + if event is None: + if do_refresh: + update_layout() + do_refresh = False + continue + + print "got event in main loop", repr(event) + if event == 'OK': continue + if event is None: continue + if not event.get("name"): continue + + # request 2 taps before we exit + if event["name"]=="key": + if event["data"]["key"] == '4': + if quitting: + out = 'quit' + else: + quitting = True + else: quitting = False + + if event["name"]=="click": + id=event["data"]["id"] + + elif event["name"]=="settings": + out = 'settings' + + elif event["name"] in menu_commands: + out = event["name"] + + if out == 'contacts': + global contact_addr + contact_addr = select_from_contacts() + if contact_addr == 'newcontact': + make_new_contact() + contact_addr = None + if not contact_addr: + out = None + + elif out == "receive": + global receive_addr + receive_addr = select_from_addresses() + if receive_addr: + amount = modal_input('Amount', 'Amount you want receive. ', '', "numberDecimal") + if amount: + receive_addr = 'ixcoin:%s?amount=%s'%(receive_addr, amount) + + if not receive_addr: + out = None + + + return out + + +def payto_loop(): + global recipient + if recipient: + droid.fullSetProperty("recipient","text",recipient) + recipient = None + + out = None + while out is None: + event = droid.eventWait().result + if not event: continue + print "got event in payto loop", event + if event == 'OK': continue + if not event.get("name"): continue + + if event["name"] == "click": + id = event["data"]["id"] + + if id=="buttonPay": + + droid.fullQuery() + recipient = droid.fullQueryDetail("recipient").result.get('text') + label = droid.fullQueryDetail("label").result.get('text') + amount = droid.fullQueryDetail('amount').result.get('text') + + if not is_valid(recipient): + modal_dialog('Error','Invalid Ixcoin address') + continue + + try: + amount = int( 100000000 * Decimal(amount) ) + except Exception: + modal_dialog('Error','Invalid amount') + continue + + result = pay_to(recipient, amount, wallet.fee, label) + if result: + out = 'main' + + elif id=="buttonContacts": + addr = select_from_contacts() + droid.fullSetProperty("recipient","text",addr) + + elif id=="buttonQR": + code = droid.scanBarcode() + r = code.result + if r: + data = r['extras']['SCAN_RESULT'] + if data: + if re.match('^bitcoin:', data): + payto, amount, label, _, _ = util.parse_URI(data) + droid.fullSetProperty("recipient", "text",payto) + droid.fullSetProperty("amount", "text", amount) + droid.fullSetProperty("label", "text", label) + else: + droid.fullSetProperty("recipient", "text", data) + + + elif event["name"] in menu_commands: + out = event["name"] + + elif event["name"]=="key": + if event["data"]["key"] == '4': + out = 'main' + + #elif event["name"]=="screen": + # if event["data"]=="destroy": + # out = 'main' + + return out + + +receive_addr = '' +contact_addr = '' +recipient = '' + +def receive_loop(): + out = None + while out is None: + event = droid.eventWait().result + print "got event", event + if event["name"]=="key": + if event["data"]["key"] == '4': + out = 'main' + + elif event["name"]=="clipboard": + droid.setClipboard(receive_addr) + modal_dialog('Address copied to clipboard',receive_addr) + + elif event["name"]=="edit": + edit_label(receive_addr) + + return out + +def contacts_loop(): + global recipient + out = None + while out is None: + event = droid.eventWait().result + print "got event", event + if event["name"]=="key": + if event["data"]["key"] == '4': + out = 'main' + + elif event["name"]=="clipboard": + droid.setClipboard(contact_addr) + modal_dialog('Address copied to clipboard',contact_addr) + + elif event["name"]=="edit": + edit_label(contact_addr) + + elif event["name"]=="paytocontact": + recipient = contact_addr + out = 'send' + + elif event["name"]=="deletecontact": + if modal_question('delete contact', contact_addr): + out = 'main' + + return out + + +def server_dialog(servers): + droid.dialogCreateAlert("Public servers") + droid.dialogSetItems( servers.keys() ) + droid.dialogSetPositiveButtonText('Private server') + droid.dialogShow() + response = droid.dialogGetResponse().result + droid.dialogDismiss() + if not response: return + + if response.get('which') == 'positive': + return modal_input('Private server', None) + + i = response.get('item') + if i is not None: + response = servers.keys()[i] + return response + + +def show_seed(): + if wallet.use_encryption: + password = droid.dialogGetPassword('Seed').result + if not password: return + else: + password = None + + try: + seed = wallet.get_seed(password) + except Exception: + modal_dialog('error','incorrect password') + return + + modal_dialog('Your seed is',seed) + modal_dialog('Mnemonic code:', ' '.join(mnemonic_encode(seed)) ) + +def change_password_dialog(): + if wallet.use_encryption: + password = droid.dialogGetPassword('Your wallet is encrypted').result + if password is None: return + else: + password = None + + try: + wallet.get_seed(password) + except Exception: + modal_dialog('error','incorrect password') + return + + new_password = droid.dialogGetPassword('Choose a password').result + if new_password == None: + return + + if new_password != '': + password2 = droid.dialogGetPassword('Confirm new password').result + if new_password != password2: + modal_dialog('error','passwords do not match') + return + + wallet.update_password(password, new_password) + if new_password: + modal_dialog('Password updated','your wallet is encrypted') + else: + modal_dialog('No password','your wallet is not encrypted') + return True + + +def settings_loop(): + + + def set_listview(): + host, port, p = network.default_server.split(':') + fee = str( Decimal( wallet.fee)/100000000 ) + is_encrypted = 'yes' if wallet.use_encryption else 'no' + protocol = protocol_name(p) + droid.fullShow(settings_layout) + droid.fullSetList("myListView",['Server: ' + host, 'Protocol: '+ protocol, 'Port: '+port, 'Transaction fee: '+fee, 'Password: '+is_encrypted, 'Seed']) + + set_listview() + + out = None + while out is None: + event = droid.eventWait() + event = event.result + print "got event", event + if event == 'OK': continue + if not event: continue + + servers = network.get_servers() + name = event.get("name") + if not name: continue + + if name == "itemclick": + pos = event["data"]["position"] + host, port, protocol = network.default_server.split(':') + network_changed = False + + if pos == "0": #server + host = server_dialog(servers) + if host: + p = servers[host] + port = p[protocol] + network_changed = True + + elif pos == "1": #protocol + if host in servers: + protocol = protocol_dialog(host, protocol, servers[host]) + z = servers[host] + port = z[protocol] + network_changed = True + + elif pos == "2": #port + a_port = modal_input('Port number', 'If you use a public server, this field is set automatically when you set the protocol', port, "number") + if a_port != port: + port = a_port + network_changed = True + + elif pos == "3": #fee + fee = modal_input('Transaction fee', 'The fee will be this amount multiplied by the number of inputs in your transaction. ', str( Decimal( wallet.fee)/100000000 ), "numberDecimal") + if fee: + try: + fee = int( 100000000 * Decimal(fee) ) + except Exception: + modal_dialog('error','invalid fee value') + wallet.set_fee(fee) + set_listview() + + elif pos == "4": + if change_password_dialog(): + set_listview() + + elif pos == "5": + show_seed() + + if network_changed: + proxy = None + auto_connect = False + try: + network.set_parameters(host, port, protocol, proxy, auto_connect) + except Exception: + modal_dialog('error','invalid server') + set_listview() + + elif name in menu_commands: + out = event["name"] + + elif name == 'cancel': + out = 'main' + + elif name == "key": + if event["data"]["key"] == '4': + out = 'main' + + return out + +def add_menu(s): + droid.clearOptionsMenu() + if s == 'main': + droid.addOptionsMenuItem("Send","send",None,"") + droid.addOptionsMenuItem("Receive","receive",None,"") + droid.addOptionsMenuItem("Contacts","contacts",None,"") + droid.addOptionsMenuItem("Settings","settings",None,"") + elif s == 'receive': + droid.addOptionsMenuItem("Copy","clipboard",None,"") + droid.addOptionsMenuItem("Label","edit",None,"") + elif s == 'contacts': + droid.addOptionsMenuItem("Copy","clipboard",None,"") + droid.addOptionsMenuItem("Label","edit",None,"") + droid.addOptionsMenuItem("Pay to","paytocontact",None,"") + #droid.addOptionsMenuItem("Delete","deletecontact",None,"") + + +def make_bitmap(addr): + # fixme: this is highly inefficient + droid.dialogCreateSpinnerProgress("please wait") + droid.dialogShow() + try: + import pyqrnative, bmp + qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.L) + qr.addData(addr) + qr.make() + k = qr.getModuleCount() + assert k == 33 + bmp.save_qrcode(qr,"/sdcard/sl4a/qrcode.bmp") + finally: + droid.dialogDismiss() + + + + +droid = android.Android() +menu_commands = ["send", "receive", "settings", "contacts", "main"] +wallet = None +network = None + +class ElectrumGui: + + def __init__(self, config, _network): + global wallet, network + network = _network + network.register_callback('updated', update_callback) + network.register_callback('connected', update_callback) + network.register_callback('disconnected', update_callback) + network.register_callback('disconnecting', update_callback) + + storage = WalletStorage(config) + if not storage.file_exists: + action = self.restore_or_create() + if not action: exit() + + wallet = Wallet(storage) + if action == 'create': + wallet.init_seed(None) + self.show_seed() + wallet.save_seed(None) + wallet.synchronize() # generate first addresses offline + + elif action == 'restore': + seed = self.seed_dialog() + if not seed: + exit() + wallet.init_seed(str(seed)) + wallet.save_seed(None) + else: + exit() + + wallet.start_threads(network) + + if action == 'restore': + if not self.restore_wallet(): + exit() + + self.password_dialog() + + else: + wallet = Wallet(storage) + wallet.start_threads(network) + + + def main(self, url): + s = 'main' + while True: + add_menu(s) + if s == 'main': + droid.fullShow(main_layout()) + s = main_loop() + + elif s == 'send': + droid.fullShow(payto_layout) + s = payto_loop() + + elif s == 'receive': + make_bitmap(receive_addr) + droid.fullShow(qr_layout(receive_addr)) + s = receive_loop() + + elif s == 'contacts': + make_bitmap(contact_addr) + droid.fullShow(qr_layout(contact_addr)) + s = contacts_loop() + + elif s == 'settings': + s = settings_loop() + + else: + break + + droid.makeToast("Bye!") + + + def restore_or_create(self): + droid.dialogCreateAlert("Wallet not found","Do you want to create a new wallet, or restore an existing one?") + droid.dialogSetPositiveButtonText('Create') + droid.dialogSetNeutralButtonText('Restore') + droid.dialogSetNegativeButtonText('Cancel') + droid.dialogShow() + response = droid.dialogGetResponse().result + droid.dialogDismiss() + if not response: return + if response.get('which') == 'negative': + return + + return 'restore' if response.get('which') == 'neutral' else 'create' + + + def seed_dialog(self): + if modal_question("Enter your seed","Input method",'QR Code', 'mnemonic'): + code = droid.scanBarcode() + r = code.result + if r: + seed = r['extras']['SCAN_RESULT'] + else: + return + else: + m = modal_input('Mnemonic','please enter your code') + try: + seed = mnemonic_decode(m.split(' ')) + except Exception: + modal_dialog('error: could not decode this seed') + return + + return str(seed) + + + def network_dialog(self): + return True + + + def show_seed(self): + modal_dialog('Your seed is:', wallet.seed) + modal_dialog('Mnemonic code:', ' '.join(mnemonic_encode(wallet.seed)) ) + + + def password_dialog(self): + change_password_dialog() + + + def restore_wallet(self): + + msg = "recovering wallet..." + droid.dialogCreateSpinnerProgress("Electrum-IXC", msg) + droid.dialogShow() + + wallet.restore(lambda x: None) + + droid.dialogDismiss() + droid.vibrate() + + if wallet.is_found(): + wallet.fill_addressbook() + modal_dialog("recovery successful") + else: + if not modal_question("no transactions found for this seed","do you want to keep this wallet?"): + return False + + return True + diff --git a/gui/gtk.py b/gui/gtk.py new file mode 100644 index 00000000..c8fdc65f --- /dev/null +++ b/gui/gtk.py @@ -0,0 +1,1368 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import datetime +import thread, time, ast, sys, re +import socket, traceback +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk, Gdk, GObject, cairo +from decimal import Decimal +from electrum_ixc.util import print_error +from electrum_ixc.bitcoin import is_valid +from electrum_ixc import WalletStorage, Wallet + +Gdk.threads_init() +APP_NAME = "Electrum-IXC" +import platform +MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace' + +from electrum_ixc.util import format_satoshis, parse_URI +from electrum_ixc.network import DEFAULT_SERVERS +from electrum_ixc.bitcoin import MIN_RELAY_TX_FEE + +def numbify(entry, is_int = False): + text = entry.get_text().strip() + chars = '0123456789' + if not is_int: chars +='.' + s = ''.join([i for i in text if i in chars]) + if not is_int: + if '.' in s: + p = s.find('.') + s = s.replace('.','') + s = s[:p] + '.' + s[p:p+8] + try: + amount = int( Decimal(s) * 100000000 ) + except Exception: + amount = None + else: + try: + amount = int( s ) + except Exception: + amount = None + entry.set_text(s) + return amount + + + + +def show_seed_dialog(seed, parent): + if not seed: + show_message("No seed") + return + + dialog = Gtk.MessageDialog( + parent = parent, + flags = Gtk.DialogFlags.MODAL, + buttons = Gtk.ButtonsType.OK, + message_format = "Your wallet generation seed is:\n\n" + '"' + seed + '"'\ + + "\n\nPlease keep it in a safe place; if you lose it, you will not be able to restore your wallet.\n\n" ) + dialog.set_title("Seed") + dialog.show() + dialog.run() + dialog.destroy() + +def restore_create_dialog(): + + # ask if the user wants to create a new wallet, or recover from a seed. + # if he wants to recover, and nothing is found, do not create wallet + dialog = Gtk.Dialog("electrum-ixc", parent=None, + flags=Gtk.DialogFlags.MODAL, + buttons= ("create", 0, "restore",1, "cancel",2) ) + + label = Gtk.Label("Wallet file not found.\nDo you want to create a new wallet,\n or to restore an existing one?" ) + label.show() + dialog.vbox.pack_start(label, True, True, 0) + dialog.show() + r = dialog.run() + dialog.destroy() + + if r==2: return False + return 'restore' if r==1 else 'create' + + + +def run_recovery_dialog(): + message = "Please enter your wallet seed or the corresponding mnemonic list of words, and the gap limit of your wallet." + dialog = Gtk.MessageDialog( + parent = None, + flags = Gtk.DialogFlags.MODAL, + buttons = Gtk.ButtonsType.OK_CANCEL, + message_format = message) + + vbox = dialog.vbox + dialog.set_default_response(Gtk.ResponseType.OK) + + # ask seed, server and gap in the same dialog + seed_box = Gtk.HBox() + seed_label = Gtk.Label(label='Seed or mnemonic:') + seed_label.set_size_request(150,-1) + seed_box.pack_start(seed_label, False, False, 10) + seed_label.show() + seed_entry = Gtk.Entry() + seed_entry.show() + seed_entry.set_size_request(450,-1) + seed_box.pack_start(seed_entry, False, False, 10) + add_help_button(seed_box, '.') + seed_box.show() + vbox.pack_start(seed_box, False, False, 5) + + dialog.show() + r = dialog.run() + seed = seed_entry.get_text() + dialog.destroy() + + if r==Gtk.ResponseType.CANCEL: + return False + + if Wallet.is_seed(seed): + return seed + + show_message("no seed") + return False + + + +def run_settings_dialog(self): + + message = "Here are the settings of your wallet. For more explanations, click on the question mark buttons next to each input field." + + dialog = Gtk.MessageDialog( + parent = self.window, + flags = Gtk.DialogFlags.MODAL, + buttons = Gtk.ButtonsType.OK_CANCEL, + message_format = message) + + image = Gtk.Image() + image.set_from_stock(Gtk.STOCK_PREFERENCES, Gtk.IconSize.DIALOG) + image.show() + dialog.set_image(image) + dialog.set_title("Settings") + + vbox = dialog.vbox + dialog.set_default_response(Gtk.ResponseType.OK) + + fee = Gtk.HBox() + fee_entry = Gtk.Entry() + fee_label = Gtk.Label(label='Transaction fee:') + fee_label.set_size_request(150,10) + fee_label.show() + fee.pack_start(fee_label,False, False, 10) + fee_entry.set_text( str( Decimal(self.wallet.fee_per_kb) /100000000 ) ) + fee_entry.connect('changed', numbify, False) + fee_entry.show() + fee.pack_start(fee_entry,False,False, 10) + add_help_button(fee, 'Fee per kilobyte of transaction. Recommended value:0.0001') + fee.show() + vbox.pack_start(fee, False,False, 5) + + nz = Gtk.HBox() + nz_entry = Gtk.Entry() + nz_label = Gtk.Label(label='Display zeros:') + nz_label.set_size_request(150,10) + nz_label.show() + nz.pack_start(nz_label,False, False, 10) + nz_entry.set_text( str( self.num_zeros )) + nz_entry.connect('changed', numbify, True) + nz_entry.show() + nz.pack_start(nz_entry,False,False, 10) + add_help_button(nz, "Number of zeros displayed after the decimal point.\nFor example, if this number is 2, then '5.' is displayed as '5.00'") + nz.show() + vbox.pack_start(nz, False,False, 5) + + dialog.show() + r = dialog.run() + fee = fee_entry.get_text() + nz = nz_entry.get_text() + + dialog.destroy() + if r==Gtk.ResponseType.CANCEL: + return + + try: + fee = int( 100000000 * Decimal(fee) ) + except Exception: + show_message("error") + return + self.wallet.set_fee(fee) + + try: + nz = int( nz ) + if nz>8: nz = 8 + except Exception: + show_message("error") + return + + if self.num_zeros != nz: + self.num_zeros = nz + self.config.set_key('num_zeros',nz,True) + self.update_history_tab() + + + + +def run_network_dialog( network, parent ): + image = Gtk.Image() + image.set_from_stock(Gtk.STOCK_NETWORK, Gtk.IconSize.DIALOG) + host, port, protocol, proxy_config, auto_connect = network.get_parameters() + server = "%s:%s:%s"%(host, port, protocol) + if parent: + if network.is_connected(): + status = "Connected to %s\n%d blocks"%(host, network.get_local_height()) + else: + status = "Not connected" + else: + import random + status = "Please choose a server.\nSelect cancel if you are offline." + + servers = network.get_servers() + + dialog = Gtk.MessageDialog( parent, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, status) + dialog.set_title("Server") + dialog.set_image(image) + image.show() + + vbox = dialog.vbox + host_box = Gtk.HBox() + host_label = Gtk.Label(label='Connect to:') + host_label.set_size_request(100,-1) + host_label.show() + host_box.pack_start(host_label, False, False, 10) + host_entry = Gtk.Entry() + host_entry.set_size_request(200,-1) + if network.is_connected(): + host_entry.set_text(server) + else: + host_entry.set_text("Not Connected") + host_entry.show() + host_box.pack_start(host_entry, False, False, 10) + add_help_button(host_box, 'The name, port number and protocol of your Electrum-IXC server, separated by a colon. Example: "ecdsa.org:50002:s". Some servers allow you to connect through http (port 80) or https (port 443)') + host_box.show() + + p_box = Gtk.HBox(False, 10) + p_box.show() + + p_label = Gtk.Label(label='Protocol:') + p_label.set_size_request(100,-1) + p_label.show() + p_box.pack_start(p_label, False, False, 10) + + combobox = Gtk.ComboBoxText() + combobox.show() + combobox.append_text("TCP") + combobox.append_text("SSL") + combobox.append_text("HTTP") + combobox.append_text("HTTPS") + + p_box.pack_start(combobox, True, True, 0) + + def current_line(): + return unicode(host_entry.get_text()).split(':') + + def set_combobox(protocol): + combobox.set_active('tshg'.index(protocol)) + + def set_protocol(protocol): + host = current_line()[0] + pp = servers[host] + if protocol not in pp.keys(): + protocol = pp.keys()[0] + set_combobox(protocol) + port = pp[protocol] + host_entry.set_text( host + ':' + port + ':' + protocol) + + combobox.connect("changed", lambda x:set_protocol('tshg'[combobox.get_active()])) + if network.is_connected(): + set_combobox(protocol) + + server_list = Gtk.ListStore(str) + for host in servers.keys(): + server_list.append([host]) + + treeview = Gtk.TreeView(model=server_list) + treeview.show() + + label = 'Active Servers' if network.is_connected() else 'Default Servers' + tvcolumn = Gtk.TreeViewColumn(label) + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + tvcolumn.pack_start(cell, False) + tvcolumn.add_attribute(cell, 'text', 0) + + vbox.pack_start(host_box, False,False, 5) + vbox.pack_start(p_box, True, True, 0) + + #scroll = Gtk.ScrolledWindow() + #scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + #scroll.add_with_viewport(treeview) + #scroll.show() + #vbox.pack_start(scroll, True) + vbox.pack_start(treeview, True, True, 0) + + def my_treeview_cb(treeview): + path, view_column = treeview.get_cursor() + host = server_list.get_value( server_list.get_iter(path), 0) + + pp = servers[host] + if 't' in pp.keys(): + protocol = 't' + else: + protocol = pp.keys()[0] + port = pp[protocol] + host_entry.set_text( host + ':' + port + ':' + protocol) + set_combobox(protocol) + + treeview.connect('cursor-changed', my_treeview_cb) + + dialog.show_all() + r = dialog.run() + server = host_entry.get_text() + dialog.destroy() + + if r==Gtk.ResponseType.CANCEL: + return False + + try: + host, port, protocol = server.split(':') + except Exception: + show_message("error:" + server) + return False + + network.set_parameters(host, port, protocol, proxy_config, auto_connect) + + + + + +def show_message(message, parent=None): + dialog = Gtk.MessageDialog( + parent = parent, + flags = Gtk.DialogFlags.MODAL, + buttons = Gtk.ButtonsType.CLOSE, + message_format = message ) + dialog.show() + dialog.run() + dialog.destroy() + +def password_line(label): + password = Gtk.HBox() + password_label = Gtk.Label(label=label) + password_label.set_size_request(120,10) + password_label.show() + password.pack_start(password_label,False, False, 10) + password_entry = Gtk.Entry() + password_entry.set_size_request(300,-1) + password_entry.set_visibility(False) + password_entry.show() + password.pack_start(password_entry,False,False, 10) + password.show() + return password, password_entry + +def password_dialog(parent): + dialog = Gtk.MessageDialog( parent, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, "Please enter your password.") + dialog.get_image().set_visible(False) + current_pw, current_pw_entry = password_line('Password:') + current_pw_entry.connect("activate", lambda entry, dialog, response: dialog.response(response), dialog, Gtk.ResponseType.OK) + dialog.vbox.pack_start(current_pw, False, True, 0) + dialog.show() + result = dialog.run() + pw = current_pw_entry.get_text() + dialog.destroy() + if result != Gtk.ResponseType.CANCEL: return pw + + +def change_password_dialog(is_encrypted, parent): + + if parent: + msg = 'Your wallet is encrypted. Use this dialog to change the password. To disable wallet encryption, enter an empty new password.' if is_encrypted else 'Your wallet keys are not encrypted' + else: + msg = "Please choose a password to encrypt your wallet keys" + + dialog = Gtk.MessageDialog( parent, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, msg) + dialog.set_title("Change password") + image = Gtk.Image() + image.set_from_stock(Gtk.STOCK_DIALOG_AUTHENTICATION, Gtk.IconSize.DIALOG) + image.show() + dialog.set_image(image) + + if is_encrypted: + current_pw, current_pw_entry = password_line('Current password:') + dialog.vbox.pack_start(current_pw, False, True, 0) + + password, password_entry = password_line('New password:') + dialog.vbox.pack_start(password, False, True, 5) + password2, password2_entry = password_line('Confirm password:') + dialog.vbox.pack_start(password2, False, True, 5) + + dialog.show() + result = dialog.run() + password = current_pw_entry.get_text() if is_encrypted else None + new_password = password_entry.get_text() + new_password2 = password2_entry.get_text() + dialog.destroy() + if result == Gtk.ResponseType.CANCEL: + return + + if new_password != new_password2: + show_message("passwords do not match") + return change_password_dialog(is_encrypted, parent) + + if not new_password: + new_password = None + + return True, password, new_password + + + +def add_help_button(hbox, message): + button = Gtk.Button('?') + button.connect("clicked", lambda x: show_message(message)) + button.show() + hbox.pack_start(button,False, False, 0) + + +class ElectrumWindow: + + def show_message(self, msg): + show_message(msg, self.window) + + def on_key(self, w, event): + if Gdk.ModifierType.CONTROL_MASK & event.state and event.keyval in [113,119]: + Gtk.main_quit() + return True + + def __init__(self, wallet, config, network): + self.config = config + self.wallet = wallet + self.network = network + self.funds_error = False # True if not enough funds + self.num_zeros = int(self.config.get('num_zeros',0)) + self.window = Gtk.Window(Gtk.WindowType.TOPLEVEL) + self.window.connect('key-press-event', self.on_key) + title = 'Electrum-IXC ' + self.wallet.electrum_version + ' - ' + self.config.path + if not self.wallet.seed: title += ' [seedless]' + self.window.set_title(title) + self.window.connect("destroy", Gtk.main_quit) + self.window.set_border_width(0) + #self.window.connect('mykeypress', Gtk.main_quit) + self.window.set_default_size(720, 350) + self.wallet_updated = False + + vbox = Gtk.VBox() + + self.notebook = Gtk.Notebook() + self.create_history_tab() + if self.wallet.seed: + self.create_send_tab() + self.create_recv_tab() + self.create_book_tab() + self.create_about_tab() + self.notebook.show() + vbox.pack_start(self.notebook, True, True, 2) + + self.status_bar = Gtk.Statusbar() + vbox.pack_start(self.status_bar, False, False, 0) + + self.status_image = Gtk.Image() + self.status_image.set_from_stock(Gtk.STOCK_NO, Gtk.IconSize.MENU) + self.status_image.set_alignment(True, 0.5 ) + self.status_image.show() + + self.network_button = Gtk.Button() + self.network_button.connect("clicked", lambda x: run_network_dialog(self.network, self.window) ) + self.network_button.add(self.status_image) + self.network_button.set_relief(Gtk.ReliefStyle.NONE) + self.network_button.show() + self.status_bar.pack_end(self.network_button, False, False, 0) + + if self.wallet.seed: + def seedb(w, wallet): + if wallet.use_encryption: + password = password_dialog(self.window) + if not password: return + else: password = None + seed = wallet.get_mnemonic(password) + show_seed_dialog(seed, self.window) + button = Gtk.Button('S') + button.connect("clicked", seedb, self.wallet ) + button.set_relief(Gtk.ReliefStyle.NONE) + button.show() + self.status_bar.pack_end(button,False, False, 0) + + settings_icon = Gtk.Image() + settings_icon.set_from_stock(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) + settings_icon.set_alignment(0.5, 0.5) + settings_icon.set_size_request(16,16 ) + settings_icon.show() + + prefs_button = Gtk.Button() + prefs_button.connect("clicked", lambda x: run_settings_dialog(self) ) + prefs_button.add(settings_icon) + prefs_button.set_tooltip_text("Settings") + prefs_button.set_relief(Gtk.ReliefStyle.NONE) + prefs_button.show() + self.status_bar.pack_end(prefs_button,False,False, 0) + + self.pw_icon = Gtk.Image() + self.pw_icon.set_from_stock(Gtk.STOCK_DIALOG_AUTHENTICATION, Gtk.IconSize.MENU) + self.pw_icon.set_alignment(0.5, 0.5) + self.pw_icon.set_size_request(16,16 ) + self.pw_icon.show() + + if self.wallet.seed: + + if self.wallet.use_encryption: + self.pw_icon.set_tooltip_text('Wallet is encrypted') + else: + self.pw_icon.set_tooltip_text('Wallet is unencrypted') + + password_button = Gtk.Button() + password_button.connect("clicked", self.do_update_password, self.wallet) + password_button.add(self.pw_icon) + password_button.set_relief(Gtk.ReliefStyle.NONE) + password_button.show() + self.status_bar.pack_end(password_button,False,False, 0) + + self.window.add(vbox) + self.window.show_all() + #self.fee_box.hide() + + self.context_id = self.status_bar.get_context_id("statusbar") + self.update_status_bar() + + self.network.register_callback('updated', self.update_callback) + + + def update_status_bar_thread(): + while True: + GObject.idle_add( self.update_status_bar ) + time.sleep(0.5) + + + def check_recipient_thread(): + old_r = '' + while True: + time.sleep(0.5) + if self.payto_entry.is_focus(): + continue + r = self.payto_entry.get_text() + if r != old_r: + old_r = r + r = r.strip() + if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', r): + try: + to_address = self.wallet.get_alias(r, interactive=False) + except Exception: + continue + if to_address: + s = r + ' <' + to_address + '>' + GObject.idle_add( lambda: self.payto_entry.set_text(s) ) + + + thread.start_new_thread(update_status_bar_thread, ()) + if self.wallet.seed: + thread.start_new_thread(check_recipient_thread, ()) + self.notebook.set_current_page(0) + + def update_callback(self): + self.wallet_updated = True + + def do_update_password(self, button, wallet): + if not wallet.seed: + show_message("No seed") + return + + res = change_password_dialog(wallet.use_encryption, self.window) + if res: + _, password, new_password = res + + try: + wallet.get_seed(password) + except Exception: + show_message("Incorrect password") + return + + wallet.update_password(password, new_password) + + if wallet.use_encryption: + self.pw_icon.set_tooltip_text('Wallet is encrypted') + else: + self.pw_icon.set_tooltip_text('Wallet is unencrypted') + + + def add_tab(self, page, name): + tab_label = Gtk.Label(label=name) + tab_label.show() + self.notebook.append_page(page, tab_label) + + + def create_send_tab(self): + + page = vbox = Gtk.VBox() + page.show() + + payto = Gtk.HBox() + payto_label = Gtk.Label(label='Pay to:') + payto_label.set_size_request(100,-1) + payto.pack_start(payto_label, False, False, 0) + payto_entry = Gtk.Entry() + payto_entry.set_size_request(450, 26) + payto.pack_start(payto_entry, False, False, 0) + vbox.pack_start(payto, False, False, 5) + + message = Gtk.HBox() + message_label = Gtk.Label(label='Description:') + message_label.set_size_request(100,-1) + message.pack_start(message_label, False, False, 0) + message_entry = Gtk.Entry() + message_entry.set_size_request(450, 26) + message.pack_start(message_entry, False, False, 0) + vbox.pack_start(message, False, False, 5) + + amount_box = Gtk.HBox() + amount_label = Gtk.Label(label='Amount:') + amount_label.set_size_request(100,-1) + amount_box.pack_start(amount_label, False, False, 0) + amount_entry = Gtk.Entry() + amount_entry.set_size_request(120, -1) + amount_box.pack_start(amount_entry, False, False, 0) + vbox.pack_start(amount_box, False, False, 5) + + self.fee_box = fee_box = Gtk.HBox() + fee_label = Gtk.Label(label='Fee:') + fee_label.set_size_request(100,-1) + fee_box.pack_start(fee_label, False, False, 0) + fee_entry = Gtk.Entry() + fee_entry.set_size_request(60, 26) + fee_box.pack_start(fee_entry, False, False, 0) + vbox.pack_start(fee_box, False, False, 5) + + end_box = Gtk.HBox() + empty_label = Gtk.Label(label='') + empty_label.set_size_request(100,-1) + end_box.pack_start(empty_label, False, False, 0) + send_button = Gtk.Button("Send") + send_button.show() + end_box.pack_start(send_button, False, False, 0) + clear_button = Gtk.Button("Clear") + clear_button.show() + end_box.pack_start(clear_button, False, False, 15) + send_button.connect("clicked", self.do_send, (payto_entry, message_entry, amount_entry, fee_entry)) + clear_button.connect("clicked", self.do_clear, (payto_entry, message_entry, amount_entry, fee_entry)) + + vbox.pack_start(end_box, False, False, 5) + + # display this line only if there is a signature + payto_sig = Gtk.HBox() + payto_sig_id = Gtk.Label(label='') + payto_sig.pack_start(payto_sig_id, False, False, 0) + vbox.pack_start(payto_sig, True, True, 5) + + + self.user_fee = False + + def entry_changed( entry, is_fee ): + self.funds_error = False + amount = numbify(amount_entry) + fee = numbify(fee_entry) + if not is_fee: fee = None + if amount is None: + return + tx = self.wallet.make_unsigned_transaction([('op_return', 'dummy_tx', amount)], fee) + if not is_fee: + if tx: + fee = tx.get_fee() + fee_entry.set_text( str( Decimal( fee ) / 100000000 ) ) + self.fee_box.show() + if tx: + amount_entry.modify_text(Gtk.StateType.NORMAL, Gdk.color_parse("#000000")) + fee_entry.modify_text(Gtk.StateType.NORMAL, Gdk.color_parse("#000000")) + send_button.set_sensitive(True) + else: + send_button.set_sensitive(False) + amount_entry.modify_text(Gtk.StateType.NORMAL, Gdk.color_parse("#cc0000")) + fee_entry.modify_text(Gtk.StateType.NORMAL, Gdk.color_parse("#cc0000")) + self.funds_error = True + + amount_entry.connect('changed', entry_changed, False) + fee_entry.connect('changed', entry_changed, True) + + self.payto_entry = payto_entry + self.payto_fee_entry = fee_entry + self.payto_sig_id = payto_sig_id + self.payto_sig = payto_sig + self.amount_entry = amount_entry + self.message_entry = message_entry + self.add_tab(page, 'Send') + + def set_frozen(self,entry,frozen): + if frozen: + entry.set_editable(False) + entry.set_has_frame(False) + entry.modify_base(Gtk.StateType.NORMAL, Gdk.color_parse("#eeeeee")) + else: + entry.set_editable(True) + entry.set_has_frame(True) + entry.modify_base(Gtk.StateType.NORMAL, Gdk.color_parse("#ffffff")) + + def set_url(self, url): + payto, amount, label, message, payment_request = parse_URI(url) + self.notebook.set_current_page(1) + self.payto_entry.set_text(payto) + self.message_entry.set_text(message) + self.amount_entry.set_text(amount) + self.payto_sig.set_visible(False) + + def create_about_tab(self): + from gi.repository import Pango + page = Gtk.VBox() + page.show() + tv = Gtk.TextView() + tv.set_editable(False) + tv.set_cursor_visible(False) + tv.modify_font(Pango.FontDescription(MONOSPACE_FONT)) + scroll = Gtk.ScrolledWindow() + scroll.add(tv) + page.pack_start(scroll, True, True, 0) + self.info = tv.get_buffer() + self.add_tab(page, 'Wall') + + def do_clear(self, w, data): + self.payto_sig.set_visible(False) + self.payto_fee_entry.set_text('') + for entry in [self.payto_entry,self.amount_entry,self.message_entry]: + self.set_frozen(entry,False) + entry.set_text('') + + def question(self,msg): + dialog = Gtk.MessageDialog( self.window, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, msg) + dialog.show() + result = dialog.run() + dialog.destroy() + return result == Gtk.ResponseType.OK + + def do_send(self, w, data): + payto_entry, label_entry, amount_entry, fee_entry = data + label = label_entry.get_text() + r = payto_entry.get_text() + r = r.strip() + + m1 = re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', r) + m2 = re.match('(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+) \<([1-9A-HJ-NP-Za-km-z]{26,})\>', r) + + if m1: + to_address = self.wallet.get_alias(r, True, self.show_message, self.question) + if not to_address: + return + else: + self.update_sending_tab() + + elif m2: + to_address = m2.group(5) + else: + to_address = r + + if not is_valid(to_address): + self.show_message( "invalid ixcoin address:\n"+to_address) + return + + try: + amount = int( Decimal(amount_entry.get_text()) * 100000000 ) + except Exception: + self.show_message( "invalid amount") + return + try: + fee = int( Decimal(fee_entry.get_text()) * 100000000 ) + except Exception: + self.show_message( "invalid fee") + return + + if self.wallet.use_encryption: + password = password_dialog(self.window) + if not password: + return + else: + password = None + + try: + tx = self.wallet.mktx( [(to_address, amount)], password, fee ) + except Exception as e: + self.show_message(str(e)) + return + + #@todo ixcoin electrum-ltc modifies this... + if tx.requires_fee(self.wallet.verifier) and fee < MIN_RELAY_TX_FEE: + self.show_message( "This transaction requires a higher fee, or it will not be propagated by the network." ) + return + + + if label: + self.wallet.labels[tx.hash()] = label + + status, msg = self.wallet.sendtx( tx ) + if status: + self.show_message( "payment sent.\n" + msg ) + payto_entry.set_text("") + label_entry.set_text("") + amount_entry.set_text("") + fee_entry.set_text("") + #self.fee_box.hide() + self.update_sending_tab() + else: + self.show_message( msg ) + + + def treeview_button_press(self, treeview, event): + if event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS: + c = treeview.get_cursor()[0] + if treeview == self.history_treeview: + tx_details = self.history_list.get_value( self.history_list.get_iter(c), 8) + self.show_message(tx_details) + elif treeview == self.contacts_treeview: + m = self.addressbook_list.get_value( self.addressbook_list.get_iter(c), 0) + #a = self.wallet.aliases.get(m) + #if a: + # if a[0] in self.wallet.authorities.keys(): + # s = self.wallet.authorities.get(a[0]) + # else: + # s = "self-signed" + # msg = 'Alias: '+ m + '\nTarget address: '+ a[1] + '\n\nSigned by: ' + s + '\nSigning address:' + a[0] + # self.show_message(msg) + + + def treeview_key_press(self, treeview, event): + c = treeview.get_cursor()[0] + if event.keyval == Gdk.KEY_Up: + if c and c[0] == 0: + treeview.parent.grab_focus() + treeview.set_cursor((0,)) + elif event.keyval == Gdk.KEY_Return: + if treeview == self.history_treeview: + tx_details = self.history_list.get_value( self.history_list.get_iter(c), 8) + self.show_message(tx_details) + elif treeview == self.contacts_treeview: + m = self.addressbook_list.get_value( self.addressbook_list.get_iter(c), 0) + #a = self.wallet.aliases.get(m) + #if a: + # if a[0] in self.wallet.authorities.keys(): + # s = self.wallet.authorities.get(a[0]) + # else: + # s = "self" + # msg = 'Alias:'+ m + '\n\nTarget: '+ a[1] + '\nSigned by: ' + s + '\nSigning address:' + a[0] + # self.show_message(msg) + + return False + + def create_history_tab(self): + + self.history_list = Gtk.ListStore(str, str, str, str, 'gboolean', str, str, str, str) + treeview = Gtk.TreeView(model=self.history_list) + self.history_treeview = treeview + treeview.set_tooltip_column(7) + treeview.show() + treeview.connect('key-press-event', self.treeview_key_press) + treeview.connect('button-press-event', self.treeview_button_press) + + tvcolumn = Gtk.TreeViewColumn('') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererPixbuf() + tvcolumn.pack_start(cell, False) + tvcolumn.set_attributes(cell, stock_id=1) + + tvcolumn = Gtk.TreeViewColumn('Date') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + tvcolumn.pack_start(cell, False) + tvcolumn.add_attribute(cell, 'text', 2) + + tvcolumn = Gtk.TreeViewColumn('Description') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + cell.set_property('foreground', 'grey') + cell.set_property('family', MONOSPACE_FONT) + cell.set_property('editable', True) + def edited_cb(cell, path, new_text, h_list): + tx = h_list.get_value( h_list.get_iter(path), 0) + self.wallet.set_label(tx,new_text) + self.update_history_tab() + cell.connect('edited', edited_cb, self.history_list) + def editing_started(cell, entry, path, h_list): + tx = h_list.get_value( h_list.get_iter(path), 0) + if not self.wallet.labels.get(tx): entry.set_text('') + cell.connect('editing-started', editing_started, self.history_list) + tvcolumn.set_expand(True) + tvcolumn.pack_start(cell, True) + tvcolumn.set_attributes(cell, text=3, foreground_set = 4) + + tvcolumn = Gtk.TreeViewColumn('Amount') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + cell.set_alignment(1, 0.5) + cell.set_property('family', MONOSPACE_FONT) + tvcolumn.pack_start(cell, False) + tvcolumn.add_attribute(cell, 'text', 5) + + tvcolumn = Gtk.TreeViewColumn('Balance') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + cell.set_alignment(1, 0.5) + cell.set_property('family', MONOSPACE_FONT) + tvcolumn.pack_start(cell, False) + tvcolumn.add_attribute(cell, 'text', 6) + + tvcolumn = Gtk.TreeViewColumn('Tooltip') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + tvcolumn.pack_start(cell, False) + tvcolumn.add_attribute(cell, 'text', 7) + tvcolumn.set_visible(False) + + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.add(treeview) + + self.add_tab(scroll, 'History') + self.update_history_tab() + + + def create_recv_tab(self): + self.recv_list = Gtk.ListStore(str, str, str, str, str) + self.add_tab( self.make_address_list(True), 'Receive') + self.update_receiving_tab() + + def create_book_tab(self): + self.addressbook_list = Gtk.ListStore(str, str, str) + self.add_tab( self.make_address_list(False), 'Contacts') + self.update_sending_tab() + + def make_address_list(self, is_recv): + liststore = self.recv_list if is_recv else self.addressbook_list + treeview = Gtk.TreeView(model= liststore) + treeview.connect('key-press-event', self.treeview_key_press) + treeview.connect('button-press-event', self.treeview_button_press) + treeview.show() + if not is_recv: + self.contacts_treeview = treeview + + tvcolumn = Gtk.TreeViewColumn('Address') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + cell.set_property('family', MONOSPACE_FONT) + tvcolumn.pack_start(cell, True) + tvcolumn.add_attribute(cell, 'text', 0) + + tvcolumn = Gtk.TreeViewColumn('Label') + tvcolumn.set_expand(True) + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + cell.set_property('editable', True) + def edited_cb2(cell, path, new_text, liststore): + address = liststore.get_value( liststore.get_iter(path), 0) + self.wallet.set_label(address, new_text) + self.update_receiving_tab() + self.update_sending_tab() + self.update_history_tab() + cell.connect('edited', edited_cb2, liststore) + tvcolumn.pack_start(cell, True) + tvcolumn.add_attribute(cell, 'text', 1) + + tvcolumn = Gtk.TreeViewColumn('Tx') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + tvcolumn.pack_start(cell, True) + tvcolumn.add_attribute(cell, 'text', 2) + + if is_recv: + tvcolumn = Gtk.TreeViewColumn('Balance') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + tvcolumn.pack_start(cell, True) + tvcolumn.add_attribute(cell, 'text', 3) + tvcolumn = Gtk.TreeViewColumn('Type') + treeview.append_column(tvcolumn) + cell = Gtk.CellRendererText() + tvcolumn.pack_start(cell, True) + tvcolumn.add_attribute(cell, 'text', 4) + + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + scroll.add(treeview) + + hbox = Gtk.HBox() + if not is_recv: + button = Gtk.Button("New") + button.connect("clicked", self.newaddress_dialog) + button.show() + hbox.pack_start(button,False, False, 0) + + def showqrcode(w, treeview, liststore): + import qrcode + path, col = treeview.get_cursor() + if not path: return + address = liststore.get_value(liststore.get_iter(path), 0) + qr = qrcode.QRCode() + qr.add_data(address) + boxsize = 7 + matrix = qr.get_matrix() + boxcount_row = len(matrix) + size = (boxcount_row + 4) * boxsize + def area_expose_cb(area, cr): + style = area.get_style() + Gdk.cairo_set_source_color(cr, style.white) + cr.rectangle(0, 0, size, size) + cr.fill() + Gdk.cairo_set_source_color(cr, style.black) + for r in range(boxcount_row): + for c in range(boxcount_row): + if matrix[r][c]: + cr.rectangle((c + 2) * boxsize, (r + 2) * boxsize, boxsize, boxsize) + cr.fill() + area = Gtk.DrawingArea() + area.set_size_request(size, size) + area.connect("draw", area_expose_cb) + area.show() + dialog = Gtk.Dialog(address, parent=self.window, flags=Gtk.DialogFlags.MODAL, buttons = ("ok",1)) + dialog.vbox.add(area) + dialog.run() + dialog.destroy() + + button = Gtk.Button("QR") + button.connect("clicked", showqrcode, treeview, liststore) + button.show() + hbox.pack_start(button,False, False, 0) + + button = Gtk.Button("Copy to clipboard") + def copy2clipboard(w, treeview, liststore): + import platform + path, col = treeview.get_cursor() + if path: + address = liststore.get_value( liststore.get_iter(path), 0) + if platform.system() == 'Windows': + from Tkinter import Tk + r = Tk() + r.withdraw() + r.clipboard_clear() + r.clipboard_append( address ) + r.destroy() + else: + atom = Gdk.atom_intern('CLIPBOARD', True) + c = Gtk.Clipboard.get(atom) + c.set_text( address, len(address) ) + button.connect("clicked", copy2clipboard, treeview, liststore) + button.show() + hbox.pack_start(button,False, False, 0) + + if is_recv: + button = Gtk.Button("Freeze") + def freeze_address(w, treeview, liststore, wallet): + path, col = treeview.get_cursor() + if path: + address = liststore.get_value( liststore.get_iter(path), 0) + if address in wallet.frozen_addresses: + wallet.unfreeze(address) + else: + wallet.freeze(address) + self.update_receiving_tab() + button.connect("clicked", freeze_address, treeview, liststore, self.wallet) + button.show() + hbox.pack_start(button,False, False, 0) + + if not is_recv: + button = Gtk.Button("Pay to") + def payto(w, treeview, liststore): + path, col = treeview.get_cursor() + if path: + address = liststore.get_value( liststore.get_iter(path), 0) + self.payto_entry.set_text( address ) + self.notebook.set_current_page(1) + self.amount_entry.grab_focus() + + button.connect("clicked", payto, treeview, liststore) + button.show() + hbox.pack_start(button,False, False, 0) + + vbox = Gtk.VBox() + vbox.pack_start(scroll,True, True, 0) + vbox.pack_start(hbox, False, False, 0) + return vbox + + def update_status_bar(self): + + if self.funds_error: + text = "Not enough funds" + elif self.network.is_connected(): + host, port, _,_,_ = self.network.get_parameters() + port = int(port) + height = self.network.get_local_height() + self.network_button.set_tooltip_text("Connected to %s:%d.\n%d blocks"%(host, port, height)) + if not self.wallet.up_to_date: + self.status_image.set_from_stock(Gtk.STOCK_REFRESH, Gtk.IconSize.MENU) + text = "Synchronizing..." + else: + self.status_image.set_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU) + c, u = self.wallet.get_balance() + text = "Balance: %s "%( format_satoshis(c,False,self.num_zeros) ) + if u: text += "[%s unconfirmed]"%( format_satoshis(u,True,self.num_zeros).strip() ) + else: + self.status_image.set_from_stock(Gtk.STOCK_NO, Gtk.IconSize.MENU) + self.network_button.set_tooltip_text("Not connected.") + text = "Not connected" + + self.status_bar.pop(self.context_id) + self.status_bar.push(self.context_id, text) + + if self.wallet.up_to_date and self.wallet_updated: + self.update_history_tab() + self.update_receiving_tab() + # addressbook too... + self.info.set_text( self.network.banner ) + self.wallet_updated = False + + def update_receiving_tab(self): + self.recv_list.clear() + for address in self.wallet.addresses(True): + Type = "R" + c = u = 0 + if self.wallet.is_change(address): Type = "C" + if address in self.wallet.imported_keys.keys(): + Type = "I" + c, u = self.wallet.get_addr_balance(address) + if address in self.wallet.frozen_addresses: Type = Type + "F" + label = self.wallet.labels.get(address) + h = self.wallet.history.get(address,[]) + n = len(h) + tx = "0" if n==0 else "%d"%n + self.recv_list.append((address, label, tx, format_satoshis(c,False,self.num_zeros), Type )) + + def update_sending_tab(self): + # detect addresses that are not mine in history, add them here... + self.addressbook_list.clear() + #for alias, v in self.wallet.aliases.items(): + # s, target = v + # label = self.wallet.labels.get(alias) + # self.addressbook_list.append((alias, label, '-')) + + for address in self.wallet.addressbook: + label = self.wallet.labels.get(address) + n = self.wallet.get_num_tx(address) + self.addressbook_list.append((address, label, "%d"%n)) + + def update_history_tab(self): + cursor = self.history_treeview.get_cursor()[0] + self.history_list.clear() + + for item in self.wallet.get_tx_history(): + tx_hash, conf, is_mine, value, fee, balance, timestamp = item + if conf > 0: + try: + time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] + except Exception: + time_str = "------" + conf_icon = Gtk.STOCK_APPLY + elif conf == -1: + time_str = 'unverified' + conf_icon = None + else: + time_str = 'pending' + conf_icon = Gtk.STOCK_EXECUTE + + label, is_default_label = self.wallet.get_label(tx_hash) + tooltip = tx_hash + "\n%d confirmations"%conf if tx_hash else '' + details = self.get_tx_details(tx_hash) + + self.history_list.prepend( [tx_hash, conf_icon, time_str, label, is_default_label, + format_satoshis(value,True,self.num_zeros, whitespaces=True), + format_satoshis(balance,False,self.num_zeros, whitespaces=True), tooltip, details] ) + if cursor: self.history_treeview.set_cursor( cursor ) + + + def get_tx_details(self, tx_hash): + import datetime + if not tx_hash: return '' + tx = self.wallet.transactions.get(tx_hash) + is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx) + conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash) + + if timestamp: + time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] + else: + time_str = 'pending' + + inputs = map(lambda x: x.get('address'), tx.inputs) + outputs = map(lambda x: x[0], tx.get_outputs()) + tx_details = "Transaction Details" +"\n\n" \ + + "Transaction ID:\n" + tx_hash + "\n\n" \ + + "Status: %d confirmations\n"%conf + if is_mine: + if fee: + tx_details += "Amount sent: %s\n"% format_satoshis(v-fee, False) \ + + "Transaction fee: %s\n"% format_satoshis(fee, False) + else: + tx_details += "Amount sent: %s\n"% format_satoshis(v, False) \ + + "Transaction fee: unknown\n" + else: + tx_details += "Amount received: %s\n"% format_satoshis(v, False) \ + + tx_details += "Date: %s\n\n"%time_str \ + + "Inputs:\n-"+ '\n-'.join(inputs) + "\n\n" \ + + "Outputs:\n-"+ '\n-'.join(outputs) + + return tx_details + + + + def newaddress_dialog(self, w): + + title = "New Contact" + dialog = Gtk.Dialog(title, parent=self.window, + flags=Gtk.DialogFlags.MODAL, + buttons= ("cancel", 0, "ok",1) ) + dialog.show() + + label = Gtk.HBox() + label_label = Gtk.Label(label='Label:') + label_label.set_size_request(120,10) + label_label.show() + label.pack_start(label_label, True, True, 0) + label_entry = Gtk.Entry() + label_entry.show() + label.pack_start(label_entry, True, True, 0) + label.show() + dialog.vbox.pack_start(label, False, True, 5) + + address = Gtk.HBox() + address_label = Gtk.Label(label='Address:') + address_label.set_size_request(120,10) + address_label.show() + address.pack_start(address_label, True, True, 0) + address_entry = Gtk.Entry() + address_entry.show() + address.pack_start(address_entry, True, True, 0) + address.show() + dialog.vbox.pack_start(address, False, True, 5) + + result = dialog.run() + address = address_entry.get_text() + label = label_entry.get_text() + dialog.destroy() + + if result == 1: + if is_valid(address): + self.wallet.add_contact(address,label) + self.update_sending_tab() + else: + errorDialog = Gtk.MessageDialog( + parent=self.window, + flags=Gtk.DialogFlags.MODAL, + buttons= Gtk.ButtonsType.CLOSE, + message_format = "Invalid address") + errorDialog.show() + errorDialog.run() + errorDialog.destroy() + + + +class ElectrumGui(): + + def __init__(self, config, network): + self.network = network + self.config = config + + + def main(self, url=None): + + storage = WalletStorage(self.config) + if not storage.file_exists: + action = self.restore_or_create() + if not action: + exit() + self.wallet = wallet = Wallet(storage) + gap = self.config.get('gap_limit', 5) + if gap != 5: + wallet.gap_limit = gap + wallet.storage.put('gap_limit', gap, True) + + if action == 'create': + seed = wallet.make_seed() + show_seed_dialog(seed, None) + r = change_password_dialog(False, None) + password = r[2] if r else None + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + wallet.synchronize() # generate first addresses offline + + elif action == 'restore': + seed = self.seed_dialog() + if not seed: + exit() + r = change_password_dialog(False, None) + password = r[2] if r else None + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + + else: + exit() + else: + self.wallet = Wallet(storage) + action = None + + self.wallet.start_threads(self.network) + + if action == 'restore': + self.restore_wallet(wallet) + + w = ElectrumWindow(self.wallet, self.config, self.network) + if url: w.set_url(url) + Gtk.main() + + def restore_or_create(self): + return restore_create_dialog() + + def seed_dialog(self): + return run_recovery_dialog() + + def network_dialog(self): + return run_network_dialog( self.network, parent=None ) + + + def restore_wallet(self, wallet): + + dialog = Gtk.MessageDialog( + parent = None, + flags = Gtk.DialogFlags.MODAL, + buttons = Gtk.ButtonsType.CANCEL, + message_format = "Please wait..." ) + dialog.show() + + def recover_thread( wallet, dialog ): + wallet.restore(lambda x:x) + GObject.idle_add( dialog.destroy ) + + thread.start_new_thread( recover_thread, ( wallet, dialog ) ) + r = dialog.run() + dialog.destroy() + if r==Gtk.ResponseType.CANCEL: return False + if not wallet.is_found(): + show_message("No transactions found for this seed") + + return True diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py new file mode 100644 index 00000000..da6c1ac7 --- /dev/null +++ b/gui/qt/__init__.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys +import time +import datetime +import re +import threading +import os.path, json, ast, traceback +import shutil +import signal + +try: + import PyQt4 +except Exception: + sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'") + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore + +from electrum_ixc.i18n import _, set_language +from electrum_ixc.util import print_error, print_msg +from electrum_ixc.plugins import run_hook +from electrum_ixc import WalletStorage, Wallet +from electrum_ixc.bitcoin import MIN_RELAY_TX_FEE + +from util import * + +try: + import icons_rc +except Exception: + sys.exit("Error: Could not import icons_rc.py, please generate it with: 'pyrcc4 icons.qrc -o gui/qt/icons_rc.py'") + +from util import * +from main_window import ElectrumWindow + + +class OpenFileEventFilter(QObject): + def __init__(self, windows): + self.windows = windows + super(OpenFileEventFilter, self).__init__() + + def eventFilter(self, obj, event): + if event.type() == QtCore.QEvent.FileOpen: + if len(self.windows) >= 1: + self.windows[0].set_url(event.url().toEncoded()) + return True + return False + + +class ElectrumGui: + + def __init__(self, config, network, app=None): + set_language(config.get('language')) + self.network = network + self.config = config + self.windows = [] + self.efilter = OpenFileEventFilter(self.windows) + if app is None: + self.app = QApplication(sys.argv) + self.app.installEventFilter(self.efilter) + + + def build_tray_menu(self): + m = QMenu() + m.addAction(_("Show/Hide"), self.show_or_hide) + m.addAction(_("Dark/Light"), self.toggle_tray_icon) + m.addSeparator() + m.addAction(_("Exit Electrum-IXC"), self.close) + self.tray.setContextMenu(m) + + def toggle_tray_icon(self): + self.dark_icon = not self.dark_icon + self.config.set_key("dark_icon", self.dark_icon, True) + icon = QIcon(":icons/electrum_dark_icon.png") if self.dark_icon else QIcon(':icons/electrum_light_icon.png') + self.tray.setIcon(icon) + + def show_or_hide(self): + self.tray_activated(QSystemTrayIcon.DoubleClick) + + def tray_activated(self, reason): + if reason == QSystemTrayIcon.DoubleClick: + if self.current_window.isMinimized() or self.current_window.isHidden(): + self.current_window.show() + self.current_window.raise_() + else: + self.current_window.hide() + + def close(self): + self.current_window.close() + + + + def go_full(self): + self.config.set_key('lite_mode', False, True) + self.lite_window.hide() + self.main_window.show() + self.main_window.raise_() + self.current_window = self.main_window + + def go_lite(self): + self.config.set_key('lite_mode', True, True) + self.main_window.hide() + self.lite_window.show() + self.lite_window.raise_() + self.current_window = self.lite_window + + + def init_lite(self): + import lite_window + if not self.check_qt_version(): + if self.config.get('lite_mode') is True: + msg = "Electrum-IXC was unable to load the 'Lite GUI' because it needs Qt version >= 4.7.\nChanging your config to use the 'Classic' GUI" + QMessageBox.warning(None, "Could not start Lite GUI.", msg) + self.config.set_key('lite_mode', False, True) + sys.exit(0) + self.lite_window = None + return + + actuator = lite_window.MiniActuator(self.main_window) + actuator.load_theme() + self.lite_window = lite_window.MiniWindow(actuator, self.go_full, self.config) + driver = lite_window.MiniDriver(self.main_window, self.lite_window) + + + + def check_qt_version(self): + qtVersion = qVersion() + return int(qtVersion[0]) >= 4 and int(qtVersion[2]) >= 7 + + + def set_url(self, uri): + self.current_window.pay_from_URI(uri) + + + def main(self, url): + + storage = WalletStorage(self.config) + if storage.file_exists: + try: + wallet = Wallet(storage) + except BaseException as e: + QMessageBox.warning(None, _('Warning'), str(e), _('OK')) + return + action = wallet.get_action() + else: + action = 'new' + + if action is not None: + import installwizard + wizard = installwizard.InstallWizard(self.config, self.network, storage) + wallet = wizard.run(action) + if not wallet: + return + else: + wallet.start_threads(self.network) + + # init tray + self.dark_icon = self.config.get("dark_icon", False) + icon = QIcon(":icons/electrum_dark_icon.png") if self.dark_icon else QIcon(':icons/electrum_light_icon.png') + self.tray = QSystemTrayIcon(icon, None) + self.tray.setToolTip('Electrum-IXC') + self.tray.activated.connect(self.tray_activated) + self.build_tray_menu() + self.tray.show() + + # main window + self.main_window = w = ElectrumWindow(self.config, self.network, self) + self.current_window = self.main_window + + #lite window + self.init_lite() + + # initial configuration + if self.config.get('hide_gui') is True and self.tray.isVisible(): + self.main_window.hide() + self.lite_window.hide() + else: + if self.config.get('lite_mode') is True: + self.go_lite() + else: + self.go_full() + + # plugins that need to change the GUI do it here + run_hook('init_qt', self) + + w.load_wallet(wallet) + + s = Timer() + s.start() + + self.windows.append(w) + if url: + self.set_url(url) + + w.app = self.app + w.connect_slots(s) + w.update_wallet() + + signal.signal(signal.SIGINT, lambda *args: self.app.quit()) + self.app.exec_() + if self.tray: + self.tray.hide() + + # clipboard persistence + # see http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg17328.html + event = QtCore.QEvent(QtCore.QEvent.Clipboard) + self.app.sendEvent(self.app.clipboard(), event) + + w.close_wallet() diff --git a/gui/qt/amountedit.py b/gui/qt/amountedit.py new file mode 100644 index 00000000..394e888b --- /dev/null +++ b/gui/qt/amountedit.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from decimal import Decimal + +class MyLineEdit(QLineEdit): + frozen = pyqtSignal() + + def setFrozen(self, b): + self.setReadOnly(b) + self.setFrame(not b) + self.frozen.emit() + +class AmountEdit(MyLineEdit): + shortcut = pyqtSignal() + + def __init__(self, base_unit, is_int = False, parent=None): + QLineEdit.__init__(self, parent) + self.base_unit = base_unit + self.textChanged.connect(self.numbify) + self.is_int = is_int + self.is_shortcut = False + self.help_palette = QPalette() + + def decimal_point(self): + return 8 + + def numbify(self): + text = unicode(self.text()).strip() + if text == '!': + self.shortcut.emit() + return + pos = self.cursorPosition() + chars = '0123456789' + if not self.is_int: chars +='.' + s = ''.join([i for i in text if i in chars]) + if not self.is_int: + if '.' in s: + p = s.find('.') + s = s.replace('.','') + s = s[:p] + '.' + s[p:p+self.decimal_point()] + self.setText(s) + self.setCursorPosition(pos) + + def paintEvent(self, event): + QLineEdit.paintEvent(self, event) + if self.base_unit: + panel = QStyleOptionFrameV2() + self.initStyleOption(panel) + textRect = self.style().subElementRect(QStyle.SE_LineEditContents, panel, self) + textRect.adjust(2, 0, -10, 0) + painter = QPainter(self) + painter.setPen(self.help_palette.brush(QPalette.Disabled, QPalette.Text).color()) + painter.drawText(textRect, Qt.AlignRight | Qt.AlignVCenter, self.base_unit()) + + def get_amount(self): + try: + x = int(str(self.text())) + except: + return None + return x + + +class BTCAmountEdit(AmountEdit): + + def __init__(self, decimal_point, is_int = False, parent=None): + AmountEdit.__init__(self, self._base_unit, is_int, parent) + self.decimal_point = decimal_point + + def _base_unit(self): + p = self.decimal_point() + assert p in [2, 5, 8] + if p == 8: + return 'IXC' + if p == 5: + return 'mIXC' + if p == 2: + return 'ibits' + raise Exception('Unknown base unit') + + def get_amount(self): + try: + x = Decimal(str(self.text())) + except: + return None + p = pow(10, self.decimal_point()) + return int( p * x ) + + def setAmount(self, amount): + if amount is None: + self.setText("") + return + + p = pow(10, self.decimal_point()) + x = amount / Decimal(p) + self.setText(str(x)) diff --git a/gui/qt/console.py b/gui/qt/console.py new file mode 100644 index 00000000..bba56aef --- /dev/null +++ b/gui/qt/console.py @@ -0,0 +1,319 @@ +# source: http://stackoverflow.com/questions/2758159/how-to-embed-a-python-interpreter-in-a-pyqt-widget + +import sys, os, re +import traceback, platform +from PyQt4 import QtCore +from PyQt4 import QtGui +from electrum_ixc import util + + +if platform.system() == 'Windows': + MONOSPACE_FONT = 'Lucida Console' +elif platform.system() == 'Darwin': + MONOSPACE_FONT = 'Monaco' +else: + MONOSPACE_FONT = 'monospace' + + +class Console(QtGui.QPlainTextEdit): + def __init__(self, prompt='>> ', startup_message='', parent=None): + QtGui.QPlainTextEdit.__init__(self, parent) + + self.prompt = prompt + self.history = [] + self.namespace = {} + self.construct = [] + + self.setGeometry(50, 75, 600, 400) + self.setWordWrapMode(QtGui.QTextOption.WrapAnywhere) + self.setUndoRedoEnabled(False) + self.document().setDefaultFont(QtGui.QFont(MONOSPACE_FONT, 10, QtGui.QFont.Normal)) + self.showMessage(startup_message) + + self.updateNamespace({'run':self.run_script}) + self.set_json(False) + + def set_json(self, b): + self.is_json = b + + def run_script(self, filename): + with open(filename) as f: + script = f.read() + + # eval is generally considered bad practice. use it wisely! + result = eval(script, self.namespace, self.namespace) + + + + def updateNamespace(self, namespace): + self.namespace.update(namespace) + + def showMessage(self, message): + self.appendPlainText(message) + self.newPrompt() + + def clear(self): + self.setPlainText('') + self.newPrompt() + + def newPrompt(self): + if self.construct: + prompt = '.' * len(self.prompt) + else: + prompt = self.prompt + + self.completions_pos = self.textCursor().position() + self.completions_visible = False + + self.appendPlainText(prompt) + self.moveCursor(QtGui.QTextCursor.End) + + def getCommand(self): + doc = self.document() + curr_line = unicode(doc.findBlockByLineNumber(doc.lineCount() - 1).text()) + curr_line = curr_line.rstrip() + curr_line = curr_line[len(self.prompt):] + return curr_line + + def setCommand(self, command): + if self.getCommand() == command: + return + + doc = self.document() + curr_line = unicode(doc.findBlockByLineNumber(doc.lineCount() - 1).text()) + self.moveCursor(QtGui.QTextCursor.End) + for i in range(len(curr_line) - len(self.prompt)): + self.moveCursor(QtGui.QTextCursor.Left, QtGui.QTextCursor.KeepAnchor) + + self.textCursor().removeSelectedText() + self.textCursor().insertText(command) + self.moveCursor(QtGui.QTextCursor.End) + + + def show_completions(self, completions): + if self.completions_visible: + self.hide_completions() + + c = self.textCursor() + c.setPosition(self.completions_pos) + + completions = map(lambda x: x.split('.')[-1], completions) + t = '\n' + ' '.join(completions) + if len(t) > 500: + t = t[:500] + '...' + c.insertText(t) + self.completions_end = c.position() + + self.moveCursor(QtGui.QTextCursor.End) + self.completions_visible = True + + + def hide_completions(self): + if not self.completions_visible: + return + c = self.textCursor() + c.setPosition(self.completions_pos) + l = self.completions_end - self.completions_pos + for x in range(l): c.deleteChar() + + self.moveCursor(QtGui.QTextCursor.End) + self.completions_visible = False + + + def getConstruct(self, command): + if self.construct: + prev_command = self.construct[-1] + self.construct.append(command) + if not prev_command and not command: + ret_val = '\n'.join(self.construct) + self.construct = [] + return ret_val + else: + return '' + else: + if command and command[-1] == (':'): + self.construct.append(command) + return '' + else: + return command + + def getHistory(self): + return self.history + + def setHisory(self, history): + self.history = history + + def addToHistory(self, command): + if command.find("importprivkey") > -1: + return + + if command and (not self.history or self.history[-1] != command): + self.history.append(command) + self.history_index = len(self.history) + + def getPrevHistoryEntry(self): + if self.history: + self.history_index = max(0, self.history_index - 1) + return self.history[self.history_index] + return '' + + def getNextHistoryEntry(self): + if self.history: + hist_len = len(self.history) + self.history_index = min(hist_len, self.history_index + 1) + if self.history_index < hist_len: + return self.history[self.history_index] + return '' + + def getCursorPosition(self): + c = self.textCursor() + return c.position() - c.block().position() - len(self.prompt) + + def setCursorPosition(self, position): + self.moveCursor(QtGui.QTextCursor.StartOfLine) + for i in range(len(self.prompt) + position): + self.moveCursor(QtGui.QTextCursor.Right) + + def register_command(self, c, func): + methods = { c: func} + self.updateNamespace(methods) + + + def runCommand(self): + command = self.getCommand() + self.addToHistory(command) + + command = self.getConstruct(command) + + if command: + tmp_stdout = sys.stdout + + class stdoutProxy(): + def __init__(self, write_func): + self.write_func = write_func + self.skip = False + + def flush(self): + pass + + def write(self, text): + if not self.skip: + stripped_text = text.rstrip('\n') + self.write_func(stripped_text) + QtCore.QCoreApplication.processEvents() + self.skip = not self.skip + + if type(self.namespace.get(command)) == type(lambda:None): + self.appendPlainText("'%s' is a function. Type '%s()' to use it in the Python console."%(command, command)) + self.newPrompt() + return + + sys.stdout = stdoutProxy(self.appendPlainText) + try: + try: + # eval is generally considered bad practice. use it wisely! + result = eval(command, self.namespace, self.namespace) + if result != None: + if self.is_json: + util.print_json(result) + else: + self.appendPlainText(repr(result)) + except SyntaxError: + # exec is generally considered bad practice. use it wisely! + exec command in self.namespace + except SystemExit: + self.close() + except Exception: + traceback_lines = traceback.format_exc().split('\n') + # Remove traceback mentioning this file, and a linebreak + for i in (3,2,1,-1): + traceback_lines.pop(i) + self.appendPlainText('\n'.join(traceback_lines)) + sys.stdout = tmp_stdout + self.newPrompt() + self.set_json(False) + + + def keyPressEvent(self, event): + if event.key() == QtCore.Qt.Key_Tab: + self.completions() + return + + self.hide_completions() + + if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return): + self.runCommand() + return + if event.key() == QtCore.Qt.Key_Home: + self.setCursorPosition(0) + return + if event.key() == QtCore.Qt.Key_PageUp: + return + elif event.key() in (QtCore.Qt.Key_Left, QtCore.Qt.Key_Backspace): + if self.getCursorPosition() == 0: + return + elif event.key() == QtCore.Qt.Key_Up: + self.setCommand(self.getPrevHistoryEntry()) + return + elif event.key() == QtCore.Qt.Key_Down: + self.setCommand(self.getNextHistoryEntry()) + return + elif event.key() == QtCore.Qt.Key_L and event.modifiers() == QtCore.Qt.ControlModifier: + self.clear() + + super(Console, self).keyPressEvent(event) + + + + def completions(self): + cmd = self.getCommand() + lastword = re.split(' |\(|\)',cmd)[-1] + beginning = cmd[0:-len(lastword)] + + path = lastword.split('.') + ns = self.namespace.keys() + + if len(path) == 1: + ns = ns + prefix = '' + else: + obj = self.namespace.get(path[0]) + prefix = path[0] + '.' + ns = dir(obj) + + + completions = [] + for x in ns: + if x[0] == '_':continue + xx = prefix + x + if xx.startswith(lastword): + completions.append(xx) + completions.sort() + + if not completions: + self.hide_completions() + elif len(completions) == 1: + self.hide_completions() + self.setCommand(beginning + completions[0]) + else: + # find common prefix + p = os.path.commonprefix(completions) + if len(p)>len(lastword): + self.hide_completions() + self.setCommand(beginning + p) + else: + self.show_completions(completions) + + +welcome_message = ''' + --------------------------------------------------------------- + Welcome to a primitive Python interpreter. + --------------------------------------------------------------- +''' + +if __name__ == '__main__': + app = QtGui.QApplication(sys.argv) + console = Console(startup_message=welcome_message) + console.updateNamespace({'myVar1' : app, 'myVar2' : 1234}) + console.show(); + sys.exit(app.exec_()) diff --git a/gui/qt/history_widget.py b/gui/qt/history_widget.py new file mode 100644 index 00000000..9f01013b --- /dev/null +++ b/gui/qt/history_widget.py @@ -0,0 +1,25 @@ +from PyQt4.QtGui import * +from electrum_ixc.i18n import _ + +class HistoryWidget(QTreeWidget): + + def __init__(self, parent=None): + QTreeWidget.__init__(self, parent) + self.setColumnCount(2) + self.setHeaderLabels([_("Amount"), _("To / From"), _("When")]) + self.setIndentation(0) + + def empty(self): + self.clear() + + def append(self, address, amount, date): + if address is None: + address = _("Unknown") + if amount is None: + amount = _("Unknown") + if date is None: + date = _("Unknown") + item = QTreeWidgetItem([amount, address, date]) + if float(amount) < 0: + item.setForeground(0, QBrush(QColor("#BC1E1E"))) + self.insertTopLevelItem(0, item) diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py new file mode 100644 index 00000000..92124483 --- /dev/null +++ b/gui/qt/installwizard.py @@ -0,0 +1,540 @@ +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore + +import electrum_ixc as electrum +from electrum_ixc.i18n import _ +from electrum_ixc import Wallet, Wallet_2of2, Wallet_2of3 +from electrum_ixc import bitcoin +from electrum_ixc import util + +import seed_dialog +from network_dialog import NetworkDialog +from util import * +from amountedit import AmountEdit + +import sys +import threading +from electrum_ixc.plugins import run_hook +from electrum_ixc.mnemonic import prepare_seed + +MSG_ENTER_ANYTHING = _("Please enter a wallet seed, a master public key, a list of Ixcoin addresses, or a list of private keys") +MSG_SHOW_MPK = _("This is your master public key") +MSG_ENTER_MPK = _("Please enter your master public key") +MSG_ENTER_COLD_MPK = _("Please enter the master public key of your cosigner wallet") +MSG_ENTER_SEED_OR_MPK = _("Please enter a wallet seed, or master public key") +MSG_VERIFY_SEED = _("Your seed is important!") + "\n" + _("To make sure that you have properly saved your seed, please retype it here.") + + +class InstallWizard(QDialog): + + def __init__(self, config, network, storage): + QDialog.__init__(self) + self.config = config + self.network = network + self.storage = storage + self.setMinimumSize(575, 400) + self.setMaximumSize(575, 400) + self.setWindowTitle('Electrum-IXC') + self.connect(self, QtCore.SIGNAL('accept'), self.accept) + self.stack = QStackedLayout() + self.setLayout(self.stack) + + def set_layout(self, layout): + w = QWidget() + w.setLayout(layout) + self.stack.addWidget(w) + self.stack.setCurrentWidget(w) + + def restore_or_create(self): + vbox = QVBoxLayout() + main_label = QLabel(_("Electrum-IXC could not find an existing wallet.")) + vbox.addWidget(main_label) + grid = QGridLayout() + grid.setSpacing(5) + gb1 = QGroupBox(_("What do you want to do?")) + vbox.addWidget(gb1) + b1 = QRadioButton(gb1) + b1.setText(_("Create new wallet")) + b1.setChecked(True) + b2 = QRadioButton(gb1) + b2.setText(_("Restore an existing wallet")) + group1 = QButtonGroup() + group1.addButton(b1) + group1.addButton(b2) + vbox.addWidget(b1) + vbox.addWidget(b2) + + gb2 = QGroupBox(_("Wallet type:")) + vbox.addWidget(gb2) + group2 = QButtonGroup() + + self.wallet_types = [ + ('standard', _("Standard wallet")), + ('twofactor', _("Wallet with two-factor authentication")), + ('multisig', _("Multi-signature wallet")), + ('hardware', _("Hardware wallet")), + ] + + for i, (wtype,name) in enumerate(self.wallet_types): + if not filter(lambda x:x[0]==wtype, electrum.wallet.wallet_types): + continue + button = QRadioButton(gb2) + button.setText(name) + vbox.addWidget(button) + group2.addButton(button) + group2.setId(button, i) + if i==0: + button.setChecked(True) + + vbox.addStretch(1) + hbox, button = ok_cancel_buttons2(self, _('Next')) + vbox.addLayout(hbox) + self.set_layout(vbox) + self.show() + self.raise_() + button.setDefault(True) + + if not self.exec_(): + return None, None + + action = 'create' if b1.isChecked() else 'restore' + wallet_type = self.wallet_types[group2.checkedId()][0] + return action, wallet_type + + + def verify_seed(self, seed, sid, func=None): + r = self.enter_seed_dialog(MSG_VERIFY_SEED, sid, func) + if not r: + return + if prepare_seed(r) != prepare_seed(seed): + QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK')) + return False + else: + return True + + + def get_seed_text(self, seed_e): + text = unicode(seed_e.toPlainText()).strip() + text = ' '.join(text.split()) + return text + + def is_any(self, text): + return Wallet.is_seed(text) or Wallet.is_old_mpk(text) or Wallet.is_xpub(text) or Wallet.is_xprv(text) or Wallet.is_address(text) or Wallet.is_private_key(text) + + def is_mpk(self, text): + return Wallet.is_xpub(text) or Wallet.is_old_mpk(text) + + def enter_seed_dialog(self, msg, sid, func=None): + if func is None: + func = self.is_any + vbox, seed_e = seed_dialog.enter_seed_box(msg, self, sid) + vbox.addStretch(1) + hbox, button = ok_cancel_buttons2(self, _('Next')) + vbox.addLayout(hbox) + button.setEnabled(False) + seed_e.textChanged.connect(lambda: button.setEnabled(func(self.get_seed_text(seed_e)))) + self.set_layout(vbox) + if not self.exec_(): + return + return self.get_seed_text(seed_e) + + + def multi_mpk_dialog(self, xpub_hot, n): + vbox = QVBoxLayout() + vbox0, seed_e0 = seed_dialog.enter_seed_box(MSG_SHOW_MPK, self, 'hot') + vbox.addLayout(vbox0) + seed_e0.setText(xpub_hot) + seed_e0.setReadOnly(True) + entries = [] + for i in range(n): + vbox2, seed_e2 = seed_dialog.enter_seed_box(MSG_ENTER_COLD_MPK, self, 'cold') + vbox.addLayout(vbox2) + entries.append(seed_e2) + vbox.addStretch(1) + hbox, button = ok_cancel_buttons2(self, _('Next')) + vbox.addLayout(hbox) + button.setEnabled(False) + f = lambda: button.setEnabled( map(lambda e: Wallet.is_xpub(self.get_seed_text(e)), entries) == [True]*len(entries)) + for e in entries: + e.textChanged.connect(f) + self.set_layout(vbox) + if not self.exec_(): + return + return map(lambda e: self.get_seed_text(e), entries) + + + def multi_seed_dialog(self, n): + vbox = QVBoxLayout() + vbox1, seed_e1 = seed_dialog.enter_seed_box(MSG_ENTER_SEED_OR_MPK, self, 'hot') + vbox.addLayout(vbox1) + entries = [seed_e1] + for i in range(n): + vbox2, seed_e2 = seed_dialog.enter_seed_box(MSG_ENTER_SEED_OR_MPK, self, 'cold') + vbox.addLayout(vbox2) + entries.append(seed_e2) + vbox.addStretch(1) + hbox, button = ok_cancel_buttons2(self, _('Next')) + vbox.addLayout(hbox) + button.setEnabled(False) + + f = lambda: button.setEnabled( map(lambda e: self.is_any(self.get_seed_text(e)), entries) == [True]*len(entries)) + for e in entries: + e.textChanged.connect(f) + + self.set_layout(vbox) + if not self.exec_(): + return + return map(lambda e: self.get_seed_text(e), entries) + + + + + + def waiting_dialog(self, task, msg= _("Electrum-IXC is generating your addresses, please wait.")): + def target(): + task() + self.emit(QtCore.SIGNAL('accept')) + + vbox = QVBoxLayout() + self.waiting_label = QLabel(msg) + vbox.addWidget(self.waiting_label) + self.set_layout(vbox) + t = threading.Thread(target = target) + t.start() + self.exec_() + + + + + def network_dialog(self): + # skip this if config already exists + if self.config.get('server') is not None: + return + + grid = QGridLayout() + grid.setSpacing(5) + + label = QLabel(_("Electrum-IXC communicates with remote servers to get information about your transactions and addresses. The servers all fulfil the same purpose only differing in hardware. In most cases you simply want to let Electrum-IXC pick one at random if you have a preference though feel free to select a server manually.") + "\n\n" \ + + _("How do you want to connect to a server:")+" ") + label.setWordWrap(True) + grid.addWidget(label, 0, 0) + + gb = QGroupBox() + + b1 = QRadioButton(gb) + b1.setText(_("Auto connect")) + b1.setChecked(True) + + b2 = QRadioButton(gb) + b2.setText(_("Select server manually")) + + #b3 = QRadioButton(gb) + #b3.setText(_("Stay offline")) + + grid.addWidget(b1,1,0) + grid.addWidget(b2,2,0) + #grid.addWidget(b3,3,0) + + vbox = QVBoxLayout() + vbox.addLayout(grid) + + vbox.addStretch(1) + vbox.addLayout(ok_cancel_buttons(self, _('Next'))) + + self.set_layout(vbox) + if not self.exec_(): + return + + if b2.isChecked(): + return NetworkDialog(self.network, self.config, None).do_exec() + else: + self.config.set_key('auto_cycle', True, True) + return + + + def show_message(self, msg, icon=None): + vbox = QVBoxLayout() + self.set_layout(vbox) + if icon: + logo = QLabel() + logo.setPixmap(icon) + vbox.addWidget(logo) + vbox.addWidget(QLabel(msg)) + vbox.addStretch(1) + vbox.addLayout(close_button(self, _('Next'))) + if not self.exec_(): + return None + + + def choice(self, title, msg, choices): + vbox = QVBoxLayout() + self.set_layout(vbox) + vbox.addWidget(QLabel(title)) + gb2 = QGroupBox(msg) + vbox.addWidget(gb2) + group2 = QButtonGroup() + for i,c in enumerate(choices): + button = QRadioButton(gb2) + button.setText(c[1]) + vbox.addWidget(button) + group2.addButton(button) + group2.setId(button, i) + if i==0: + button.setChecked(True) + vbox.addStretch(1) + vbox.addLayout(ok_cancel_buttons(self, _("Next"))) + if not self.exec_(): + return + wallet_type = choices[group2.checkedId()][0] + return wallet_type + + + def question(self, msg, yes_label=_('OK'), no_label=_('Cancel'), icon=None): + vbox = QVBoxLayout() + self.set_layout(vbox) + if icon: + logo = QLabel() + logo.setPixmap(icon) + vbox.addWidget(logo) + label = QLabel(msg) + label.setWordWrap(True) + vbox.addWidget(label) + vbox.addStretch(1) + vbox.addLayout(ok_cancel_buttons(self, yes_label, no_label)) + if not self.exec_(): + return None + return True + + + def show_seed(self, seed, sid): + vbox = seed_dialog.show_seed_box(seed, sid) + vbox.addLayout(ok_cancel_buttons(self, _("Next"))) + self.set_layout(vbox) + return self.exec_() + + + def password_dialog(self): + msg = _("Please choose a password to encrypt your wallet keys.")+'\n'\ + +_("Leave these fields empty if you want to disable encryption.") + from password_dialog import make_password_dialog, run_password_dialog + self.set_layout( make_password_dialog(self, None, msg) ) + return run_password_dialog(self, None, self)[2] + + + + + + def run(self, action): + + if action == 'new': + action, wallet_type = self.restore_or_create() + if wallet_type == 'multisig': + wallet_type = self.choice(_("Multi Signature Wallet"), 'Select wallet type', [('2of2', _("2 of 2")),('2of3',_("2 of 3"))]) + if not wallet_type: + return + elif wallet_type == 'hardware': + hardware_wallets = map(lambda x:(x[1],x[2]), filter(lambda x:x[0]=='hardware', electrum.wallet.wallet_types)) + wallet_type = self.choice(_("Hardware Wallet"), 'Select your hardware wallet', hardware_wallets) + if not wallet_type: + return + elif wallet_type == 'twofactor': + wallet_type = '2fa' + + if action == 'create': + self.storage.put('wallet_type', wallet_type, False) + + if action is None: + return + + if action == 'restore': + wallet = self.restore(wallet_type) + if not wallet: + return + action = None + else: + wallet = Wallet(self.storage) + action = wallet.get_action() + # fixme: password is only needed for multiple accounts + password = None + + while action is not None: + util.print_error("installwizard:", wallet, action) + + if action == 'create_seed': + seed = wallet.make_seed() + if not self.show_seed(seed, None): + return + if not self.verify_seed(seed, None): + return + password = self.password_dialog() + wallet.add_seed(seed, password) + wallet.create_master_keys(password) + + elif action == 'add_cosigner': + xpub1 = wallet.master_public_keys.get("x1/") + r = self.multi_mpk_dialog(xpub1, 1) + if not r: + return + xpub2 = r[0] + wallet.add_master_public_key("x2/", xpub2) + + elif action == 'add_two_cosigners': + xpub1 = wallet.master_public_keys.get("x1/") + r = self.multi_mpk_dialog(xpub1, 2) + if not r: + return + xpub2, xpub3 = r + wallet.add_master_public_key("x2/", xpub2) + wallet.add_master_public_key("x3/", xpub3) + + elif action == 'create_accounts': + try: + wallet.create_main_account(password) + except BaseException as e: + import traceback + traceback.print_exc(file=sys.stdout) + QMessageBox.information(None, _('Error'), str(e), _('OK')) + return + self.waiting_dialog(wallet.synchronize) + + else: + f = run_hook('get_wizard_action', self, wallet, action) + if not f: + raise BaseException('unknown wizard action', action) + r = f(wallet, self) + if not r: + return + + # next action + action = wallet.get_action() + + + if self.network: + if self.network.interfaces: + self.network_dialog() + else: + QMessageBox.information(None, _('Warning'), _('You are offline'), _('OK')) + self.network.stop() + self.network = None + + # start wallet threads + wallet.start_threads(self.network) + + if action == 'restore': + self.waiting_dialog(lambda: wallet.restore(self.waiting_label.setText)) + if self.network: + msg = _("Recovery successful") if wallet.is_found() else _("No transactions found for this seed") + else: + msg = _("This wallet was restored offline. It may contain more addresses than displayed.") + QMessageBox.information(None, _('Information'), msg, _('OK')) + + return wallet + + + + def restore(self, t): + + if t == 'standard': + text = self.enter_seed_dialog(MSG_ENTER_ANYTHING, None) + if not text: + return + if Wallet.is_xprv(text): + password = self.password_dialog() + wallet = Wallet.from_xprv(text, password, self.storage) + elif Wallet.is_old_mpk(text): + wallet = Wallet.from_old_mpk(text, self.storage) + elif Wallet.is_xpub(text): + wallet = Wallet.from_xpub(text, self.storage) + elif Wallet.is_address(text): + wallet = Wallet.from_address(text, self.storage) + elif Wallet.is_private_key(text): + wallet = Wallet.from_private_key(text, self.storage) + elif Wallet.is_seed(text): + password = self.password_dialog() + wallet = Wallet.from_seed(text, self.storage) + wallet.add_seed(text, password) + wallet.create_master_keys(password) + wallet.create_main_account(password) + else: + raise BaseException('unknown wallet type') + + elif t in ['2of2']: + r = self.multi_seed_dialog(1) + if not r: + return + text1, text2 = r + wallet = Wallet_2of2(self.storage) + if Wallet.is_seed(text1) or Wallet.is_seed(text2): + password = self.password_dialog() + else: + password = None + + if Wallet.is_seed(text2) and Wallet.is_xpub(text1): + c = text1 + text1 = text2 + text2 = c + + if Wallet.is_seed(text1): + wallet.add_seed(text1, password) + wallet.create_master_keys(password) + else: + wallet.add_master_public_key("x1/", text1) + + if Wallet.is_seed(text2): + wallet.add_cosigner_seed(text2, "x2/", password) + elif Wallet.is_xpub(text2): + wallet.add_master_public_key("x2/", text2) + + wallet.create_main_account(password) + + + elif t in ['2of3']: + r = self.multi_seed_dialog(2) + if not r: + return + text1, text2, text3 = r + wallet = Wallet_2of3(self.storage) + if Wallet.is_seed(text1) or Wallet.is_seed(text2) or Wallet.is_seed(text3): + password = self.password_dialog() + else: + password = None + + if Wallet.is_xpub(text1) and Wallet.is_seed(text2): + temp = text1 + text1 = text2 + text2 = temp + + if Wallet.is_xpub(text1) and Wallet.is_seed(text3): + temp = text1 + text1 = text3 + text3 = temp + + if Wallet.is_seed(text1): + wallet.add_seed(text1, password) + wallet.create_master_keys(password) + else: + wallet.add_master_public_key("x1/", text1) + + if Wallet.is_seed(text2): + wallet.add_cosigner_seed(text2, "x2/", password) + elif Wallet.is_xpub(text2): + wallet.add_master_public_key("x2/", text2) + + if Wallet.is_seed(text3): + wallet.add_cosigner_seed(text3, "x3/", password) + elif Wallet.is_xpub(text3): + wallet.add_master_public_key("x3/", text3) + + wallet.create_main_account(password) + + else: + self.storage.put('wallet_type', t) + wallet = run_hook('installwizard_restore', self, self.storage) + if not wallet: + return + + # create first keys offline + self.waiting_dialog(wallet.synchronize) + + return wallet diff --git a/gui/qt/lite_window.py b/gui/qt/lite_window.py new file mode 100644 index 00000000..0cd42add --- /dev/null +++ b/gui/qt/lite_window.py @@ -0,0 +1,874 @@ +import sys + +# Let's do some dep checking and handle missing ones gracefully +try: + from PyQt4.QtCore import * + from PyQt4.QtGui import * + from PyQt4.Qt import Qt + import PyQt4.QtCore as QtCore + +except ImportError: + print "You need to have PyQT installed to run Electrum-IXC in graphical mode." + print "If you have pip installed try 'sudo pip install pyqt' if you are on Debian/Ubuntu try 'sudo apt-get install python-qt4'." + sys.exit(0) + +from decimal import Decimal as D +from electrum_ixc.util import get_resource_path as rsrc +from electrum_ixc.bitcoin import is_valid +from electrum_ixc.i18n import _ +import decimal +import json +import os.path +import random +import re +import time +from electrum_ixc.wallet import Wallet, WalletStorage +import webbrowser +import history_widget +import receiving_widget +from electrum_ixc import util +import datetime + +from electrum_ixc.version import ELECTRUM_VERSION as electrum_version +from electrum_ixc.util import format_satoshis, age + +from main_window import ElectrumWindow +import shutil + +from util import * + +bitcoin = lambda v: v * 100000000 + +def IconButton(filename, parent=None): + pixmap = QPixmap(filename) + icon = QIcon(pixmap) + return QPushButton(icon, "", parent) + + +def resize_line_edit_width(line_edit, text_input): + metrics = QFontMetrics(qApp.font()) + # Create an extra character to add some space on the end + text_input += "A" + line_edit.setMinimumWidth(metrics.width(text_input)) + +def load_theme_name(theme_path): + try: + with open(os.path.join(theme_path, "name.cfg")) as name_cfg_file: + return name_cfg_file.read().rstrip("\n").strip() + except IOError: + return None + + +def theme_dirs_from_prefix(prefix): + if not os.path.exists(prefix): + return [] + theme_paths = {} + for potential_theme in os.listdir(prefix): + theme_full_path = os.path.join(prefix, potential_theme) + theme_css = os.path.join(theme_full_path, "style.css") + if not os.path.exists(theme_css): + continue + theme_name = load_theme_name(theme_full_path) + if theme_name is None: + continue + theme_paths[theme_name] = prefix, potential_theme + return theme_paths + +def load_theme_paths(): + theme_paths = {} + theme_paths.update(theme_dirs_from_prefix(util.data_dir())) + return theme_paths + + + + +class TransactionWindow(QDialog): + + def set_label(self): + label = unicode(self.label_edit.text()) + self.parent.wallet.labels[self.tx_id] = label + + super(TransactionWindow, self).accept() + + def __init__(self, transaction_id, parent): + super(TransactionWindow, self).__init__() + + self.tx_id = str(transaction_id) + self.parent = parent + + self.setModal(True) + self.resize(200,100) + self.setWindowTitle(_("Transaction successfully sent")) + + self.layout = QGridLayout(self) + history_label = "%s\n%s" % (_("Your transaction has been sent."), _("Please enter a label for this transaction for future reference.")) + self.layout.addWidget(QLabel(history_label)) + + self.label_edit = QLineEdit() + self.label_edit.setPlaceholderText(_("Transaction label")) + self.label_edit.setObjectName("label_input") + self.label_edit.setAttribute(Qt.WA_MacShowFocusRect, 0) + self.label_edit.setFocusPolicy(Qt.ClickFocus) + self.layout.addWidget(self.label_edit) + + self.save_button = QPushButton(_("Save")) + self.layout.addWidget(self.save_button) + self.save_button.clicked.connect(self.set_label) + + self.exec_() + +class MiniWindow(QDialog): + + def __init__(self, actuator, expand_callback, config): + super(MiniWindow, self).__init__() + + self.actuator = actuator + self.config = config + self.btc_balance = None + self.use_exchanges = ["Blockchain", "CoinDesk"] + self.quote_currencies = ["BRL", "CNY", "EUR", "GBP", "RUB", "USD"] + self.actuator.set_configured_currency(self.set_quote_currency) + self.actuator.set_configured_exchange(self.set_exchange) + + # Needed because price discovery is done in a different thread + # which needs to be sent back to this main one to update the GUI + self.connect(self, SIGNAL("refresh_balance()"), self.refresh_balance) + + self.balance_label = BalanceLabel(self.change_quote_currency, self) + self.balance_label.setObjectName("balance_label") + + + # Bitcoin address code + self.address_input = QLineEdit() + self.address_input.setPlaceholderText(_("Enter a Ixcoin address or contact")) + self.address_input.setObjectName("address_input") + + self.address_input.setFocusPolicy(Qt.ClickFocus) + + self.address_input.textChanged.connect(self.address_field_changed) + resize_line_edit_width(self.address_input, + "1BtaFUr3qVvAmwrsuDuu5zk6e4s2rxd2Gy") + + self.address_completions = QStringListModel() + address_completer = QCompleter(self.address_input) + address_completer.setCaseSensitivity(False) + address_completer.setModel(self.address_completions) + self.address_input.setCompleter(address_completer) + + address_layout = QHBoxLayout() + address_layout.addWidget(self.address_input) + + self.amount_input = QLineEdit() + self.amount_input.setPlaceholderText(_("... and amount") + " (%s)"%self.actuator.g.base_unit()) + self.amount_input.setObjectName("amount_input") + + self.amount_input.setFocusPolicy(Qt.ClickFocus) + # This is changed according to the user's displayed balance + self.amount_validator = QDoubleValidator(self.amount_input) + self.amount_validator.setNotation(QDoubleValidator.StandardNotation) + self.amount_validator.setDecimals(8) + self.amount_input.setValidator(self.amount_validator) + + # This removes the very ugly OSX highlighting, please leave this in :D + self.address_input.setAttribute(Qt.WA_MacShowFocusRect, 0) + self.amount_input.setAttribute(Qt.WA_MacShowFocusRect, 0) + self.amount_input.textChanged.connect(self.amount_input_changed) + + #if self.actuator.g.wallet.seed: + self.send_button = QPushButton(_("&Send")) + #else: + # self.send_button = QPushButton(_("&Create")) + + self.send_button.setObjectName("send_button") + self.send_button.setDisabled(True); + self.send_button.clicked.connect(self.send) + + # Creating the receive button + self.switch_button = QPushButton( QIcon(":icons/switchgui.png"),'' ) + self.switch_button.setMaximumWidth(25) + self.switch_button.setFlat(True) + self.switch_button.clicked.connect(expand_callback) + + main_layout = QGridLayout(self) + + main_layout.addWidget(self.balance_label, 0, 0, 1, 3) + main_layout.addWidget(self.switch_button, 0, 3) + + main_layout.addWidget(self.address_input, 1, 0, 1, 4) + main_layout.addWidget(self.amount_input, 2, 0, 1, 2) + main_layout.addWidget(self.send_button, 2, 2, 1, 2) + + self.send_button.setMaximumWidth(125) + + self.history_list = history_widget.HistoryWidget() + self.history_list.setObjectName("history") + self.history_list.hide() + self.history_list.setAlternatingRowColors(True) + + main_layout.addWidget(self.history_list, 3, 0, 1, 4) + + self.receiving = receiving_widget.ReceivingWidget(self) + self.receiving.setObjectName("receiving") + + # Add to the right side + self.receiving_box = QGroupBox(_("Select a receiving address")) + extra_layout = QGridLayout() + + # Checkbox to filter used addresses + hide_used = QCheckBox(_('Hide used addresses')) + hide_used.setChecked(True) + hide_used.stateChanged.connect(self.receiving.toggle_used) + + # Events for receiving addresses + self.receiving.clicked.connect(self.receiving.copy_address) + self.receiving.itemDoubleClicked.connect(self.receiving.edit_label) + self.receiving.itemChanged.connect(self.receiving.update_label) + + + # Label + extra_layout.addWidget( QLabel(_('Selecting an address will copy it to the clipboard.') + '\n' + _('Double clicking the label will allow you to edit it.') ),0,0) + + extra_layout.addWidget(self.receiving, 1,0) + extra_layout.addWidget(hide_used, 2,0) + extra_layout.setColumnMinimumWidth(0,200) + + self.receiving_box.setLayout(extra_layout) + main_layout.addWidget(self.receiving_box,0,4,-1,3) + self.receiving_box.hide() + + self.main_layout = main_layout + + quit_shortcut = QShortcut(QKeySequence("Ctrl+Q"), self) + quit_shortcut.activated.connect(self.close) + close_shortcut = QShortcut(QKeySequence("Ctrl+W"), self) + close_shortcut.activated.connect(self.close) + + g = self.config.get("winpos-lite",[4, 25, 351, 149]) + self.setGeometry(g[0], g[1], g[2], g[3]) + + show_hist = self.config.get("gui_show_history",False) + self.show_history(show_hist) + show_hist = self.config.get("gui_show_receiving",False) + self.toggle_receiving_layout(show_hist) + + self.setWindowIcon(QIcon(":icons/electrum-ixc.png")) + self.setWindowTitle("Electrum-IXC") + self.setWindowFlags(Qt.Window|Qt.MSWindowsFixedSizeDialogHint) + self.layout().setSizeConstraint(QLayout.SetFixedSize) + self.setObjectName("main_window") + + + def context_menu(self): + view_menu = QMenu() + themes_menu = view_menu.addMenu(_("&Themes")) + selected_theme = self.actuator.selected_theme() + theme_group = QActionGroup(self) + for theme_name in self.actuator.theme_names(): + theme_action = themes_menu.addAction(theme_name) + theme_action.setCheckable(True) + if selected_theme == theme_name: + theme_action.setChecked(True) + class SelectThemeFunctor: + def __init__(self, theme_name, toggle_theme): + self.theme_name = theme_name + self.toggle_theme = toggle_theme + def __call__(self, checked): + if checked: + self.toggle_theme(self.theme_name) + delegate = SelectThemeFunctor(theme_name, self.toggle_theme) + theme_action.toggled.connect(delegate) + theme_group.addAction(theme_action) + view_menu.addSeparator() + + show_receiving = view_menu.addAction(_("Show Receiving addresses")) + show_receiving.setCheckable(True) + show_receiving.toggled.connect(self.toggle_receiving_layout) + show_receiving.setChecked(self.config.get("gui_show_receiving",False)) + + show_history = view_menu.addAction(_("Show History")) + show_history.setCheckable(True) + show_history.toggled.connect(self.show_history) + show_history.setChecked(self.config.get("gui_show_history",False)) + + return view_menu + + + + def toggle_theme(self, theme_name): + self.actuator.change_theme(theme_name) + # Recompute style globally + qApp.style().unpolish(self) + qApp.style().polish(self) + + def closeEvent(self, event): + g = self.geometry() + self.config.set_key("winpos-lite", [g.left(),g.top(),g.width(),g.height()],True) + self.actuator.g.closeEvent(event) + qApp.quit() + + def pay_from_URI(self, URI): + try: + dest_address, amount, label, message, request_url = util.parse_URI(URI) + except: + return + self.address_input.setText(dest_address) + self.address_field_changed(dest_address) + self.amount_input.setText(str(amount)) + + def activate(self): + pass + + def deactivate(self): + pass + + def set_exchange(self, use_exchange): + if use_exchange not in self.use_exchanges: + return + self.use_exchanges.remove(use_exchange) + self.use_exchanges.insert(0, use_exchange) + self.refresh_balance() + + def set_quote_currency(self, currency): + """Set and display the fiat currency country.""" + if currency not in self.quote_currencies: + return + self.quote_currencies.remove(currency) + self.quote_currencies.insert(0, currency) + self.refresh_balance() + + def change_quote_currency(self, forward=True): + if forward: + self.quote_currencies = \ + self.quote_currencies[1:] + self.quote_currencies[0:1] + else: + self.quote_currencies = \ + self.quote_currencies[-1:] + self.quote_currencies[0:-1] + self.actuator.set_config_currency(self.quote_currencies[0]) + self.refresh_balance() + + def refresh_balance(self): + if self.btc_balance is None: + # Price has been discovered before wallet has been loaded + # and server connect... so bail. + return + self.set_balances(self.btc_balance) + self.amount_input_changed(self.amount_input.text()) + + def set_balances(self, btc_balance): + """Set the ixcoin balance and update the amount label accordingly.""" + self.btc_balance = btc_balance + quote_text = self.create_quote_text(btc_balance) + if quote_text: + quote_text = "(%s)" % quote_text + + amount = self.actuator.g.format_amount(btc_balance) + unit = self.actuator.g.base_unit() + + self.balance_label.set_balance_text(amount, unit, quote_text) + self.setWindowTitle("Electrum-IXC %s - %s %s" % (electrum_version, amount, unit)) + + def amount_input_changed(self, amount_text): + """Update the number of ixcoins displayed.""" + self.check_button_status() + + try: + amount = D(str(amount_text)) * (10**self.actuator.g.decimal_point) + except decimal.InvalidOperation: + self.balance_label.show_balance() + else: + quote_text = self.create_quote_text(amount) + if quote_text: + self.balance_label.set_amount_text(quote_text) + self.balance_label.show_amount() + else: + self.balance_label.show_balance() + + def create_quote_text(self, btc_balance): + """Return a string copy of the amount fiat currency the + user has in ixcoins.""" + from electrum_ixc.plugins import run_hook + r = {} + run_hook('get_fiat_balance_text', btc_balance, r) + return r.get(0,'') + + def send(self): + if self.actuator.send(self.address_input.text(), + self.amount_input.text(), self): + self.address_input.setText("") + self.amount_input.setText("") + + def check_button_status(self): + """Check that the ixcoin address is valid and that something + is entered in the amount before making the send button clickable.""" + try: + value = D(str(self.amount_input.text())) * (10**self.actuator.g.decimal_point) + except decimal.InvalidOperation: + value = None + # self.address_input.property(...) returns a qVariant, not a bool. + # The == is needed to properly invoke a comparison. + if (self.address_input.property("isValid") == True and + value is not None and 0 < value <= self.btc_balance): + self.send_button.setDisabled(False) + else: + self.send_button.setDisabled(True) + + def address_field_changed(self, address): + # label or alias, with address in brackets + match2 = re.match("(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>", + address) + if match2: + address = match2.group(2) + self.address_input.setText(address) + + if is_valid(address): + self.check_button_status() + self.address_input.setProperty("isValid", True) + self.recompute_style(self.address_input) + else: + self.send_button.setDisabled(True) + self.address_input.setProperty("isValid", False) + self.recompute_style(self.address_input) + + if len(address) == 0: + self.address_input.setProperty("isValid", None) + self.recompute_style(self.address_input) + + def recompute_style(self, element): + self.style().unpolish(element) + self.style().polish(element) + + def copy_address(self): + receive_popup = ReceivePopup(self.receive_button) + self.actuator.copy_address(receive_popup) + + def update_completions(self, completions): + self.address_completions.setStringList(completions) + + + def update_history(self, tx_history): + + self.history_list.empty() + + for item in tx_history[-10:]: + tx_hash, conf, is_mine, value, fee, balance, timestamp = item + label = self.actuator.g.wallet.get_label(tx_hash)[0] + v_str = self.actuator.g.format_amount(value, True) + self.history_list.append(label, v_str, age(timestamp)) + + + def the_website(self): + webbrowser.open("http://electrumalt.org") + + + def toggle_receiving_layout(self, toggle_state): + if toggle_state: + self.receiving_box.show() + else: + self.receiving_box.hide() + self.config.set_key("gui_show_receiving", toggle_state) + + def show_history(self, toggle_state): + if toggle_state: + self.main_layout.setRowMinimumHeight(3,200) + self.history_list.show() + else: + self.main_layout.setRowMinimumHeight(3,0) + self.history_list.hide() + self.config.set_key("gui_show_history", toggle_state) + +class BalanceLabel(QLabel): + + SHOW_CONNECTING = 1 + SHOW_BALANCE = 2 + SHOW_AMOUNT = 3 + + def __init__(self, change_quote_currency, parent=None): + super(QLabel, self).__init__(_("Connecting..."), parent) + self.change_quote_currency = change_quote_currency + self.state = self.SHOW_CONNECTING + self.balance_text = "" + self.amount_text = "" + self.parent = parent + + def mousePressEvent(self, event): + """Change the fiat currency selection if window background is clicked.""" + if self.state != self.SHOW_CONNECTING: + if event.button() == Qt.LeftButton: + self.change_quote_currency() + else: + position = event.globalPos() + menu = self.parent.context_menu() + menu.exec_(position) + + + def set_balance_text(self, amount, unit, quote_text): + """Set the amount of ixcoins in the gui.""" + if self.state == self.SHOW_CONNECTING: + self.state = self.SHOW_BALANCE + + self.balance_text = "%s"%amount\ + + " %s" % unit \ + + " %s" % quote_text + + if self.state == self.SHOW_BALANCE: + self.setText(self.balance_text) + + def set_amount_text(self, quote_text): + self.amount_text = "%s" % quote_text + if self.state == self.SHOW_AMOUNT: + self.setText(self.amount_text) + + def show_balance(self): + if self.state == self.SHOW_AMOUNT: + self.state = self.SHOW_BALANCE + self.setText(self.balance_text) + + def show_amount(self): + if self.state == self.SHOW_BALANCE: + self.state = self.SHOW_AMOUNT + self.setText(self.amount_text) + +def ok_cancel_buttons(dialog): + row_layout = QHBoxLayout() + row_layout.addStretch(1) + ok_button = QPushButton(_("OK")) + row_layout.addWidget(ok_button) + ok_button.clicked.connect(dialog.accept) + cancel_button = QPushButton(_("Cancel")) + row_layout.addWidget(cancel_button) + cancel_button.clicked.connect(dialog.reject) + return row_layout + +class PasswordDialog(QDialog): + + def __init__(self, parent): + super(QDialog, self).__init__(parent) + + self.setModal(True) + + self.password_input = QLineEdit() + self.password_input.setEchoMode(QLineEdit.Password) + + main_layout = QVBoxLayout(self) + message = _('Please enter your password') + main_layout.addWidget(QLabel(message)) + + grid = QGridLayout() + grid.setSpacing(8) + grid.addWidget(QLabel(_('Password')), 1, 0) + grid.addWidget(self.password_input, 1, 1) + main_layout.addLayout(grid) + + main_layout.addLayout(ok_cancel_buttons(self)) + self.setLayout(main_layout) + + def run(self): + if not self.exec_(): + return + return unicode(self.password_input.text()) + +class ReceivePopup(QDialog): + + def leaveEvent(self, event): + self.close() + + def setup(self, address): + label = QLabel(_("Copied your Ixcoin address to the clipboard!")) + address_display = QLineEdit(address) + address_display.setReadOnly(True) + resize_line_edit_width(address_display, address) + + main_layout = QVBoxLayout(self) + main_layout.addWidget(label) + main_layout.addWidget(address_display) + + self.setMouseTracking(True) + self.setWindowTitle("Electrum-IXC - " + _("Receive Ixcoin payment")) + self.setWindowFlags(Qt.Window|Qt.FramelessWindowHint| + Qt.MSWindowsFixedSizeDialogHint) + self.layout().setSizeConstraint(QLayout.SetFixedSize) + #self.setFrameStyle(QFrame.WinPanel|QFrame.Raised) + #self.setAlignment(Qt.AlignCenter) + + def popup(self): + parent = self.parent() + top_left_pos = parent.mapToGlobal(parent.rect().bottomLeft()) + self.move(top_left_pos) + center_mouse_pos = self.mapToGlobal(self.rect().center()) + QCursor.setPos(center_mouse_pos) + self.show() + +class MiniActuator: + """Initialize the definitions relating to themes and + sending/receiving ixcoins.""" + + + def __init__(self, main_window): + """Retrieve the gui theme used in previous session.""" + self.g = main_window + self.theme_name = self.g.config.get('litegui_theme','Cleanlook') + self.themes = load_theme_paths() + self.load_theme() + + def load_theme(self): + """Load theme retrieved from wallet file.""" + try: + theme_prefix, theme_path = self.themes[self.theme_name] + except KeyError: + util.print_error("Theme not found!", self.theme_name) + return + full_theme_path = "%s/%s/style.css" % (theme_prefix, theme_path) + with open(full_theme_path) as style_file: + qApp.setStyleSheet(style_file.read()) + + def theme_names(self): + """Sort themes.""" + return sorted(self.themes.keys()) + + def selected_theme(self): + """Select theme.""" + return self.theme_name + + def change_theme(self, theme_name): + """Change theme.""" + self.theme_name = theme_name + self.g.config.set_key('litegui_theme',theme_name) + self.load_theme() + + def set_configured_exchange(self, set_exchange): + use_exchange = self.g.config.get('use_exchange') + if use_exchange is not None: + set_exchange(use_exchange) + + def set_configured_currency(self, set_quote_currency): + """Set the inital fiat currency conversion country (USD/EUR/GBP) in + the GUI to what it was set to in the wallet.""" + currency = self.g.config.get('currency') + # currency can be none when Electrum is used for the first + # time and no setting has been created yet. + if currency is not None: + set_quote_currency(currency) + + def set_config_exchange(self, conversion_exchange): + self.g.config.set_key('exchange',conversion_exchange,True) + self.g.update_status() + + def set_config_currency(self, conversion_currency): + """Change the wallet fiat currency country.""" + self.g.config.set_key('currency',conversion_currency,True) + self.g.update_status() + + def copy_address(self, receive_popup): + """Copy the wallet addresses into the client.""" + addrs = [addr for addr in self.g.wallet.addresses(True) + if not self.g.wallet.is_change(addr)] + # Select most recent addresses from gap limit + addrs = addrs[-self.g.wallet.gap_limit:] + copied_address = random.choice(addrs) + qApp.clipboard().setText(copied_address) + receive_popup.setup(copied_address) + receive_popup.popup() + + def waiting_dialog(self, f): + s = Timer() + s.start() + w = QDialog() + w.resize(200, 70) + w.setWindowTitle('Electrum-IXC') + l = QLabel(_('Sending transaction, please wait.')) + vbox = QVBoxLayout() + vbox.addWidget(l) + w.setLayout(vbox) + w.show() + def ff(): + s = f() + if s: l.setText(s) + else: w.close() + w.connect(s, QtCore.SIGNAL('timersignal'), ff) + w.exec_() + w.destroy() + + + def send(self, address, amount, parent_window): + """Send ixcoins to the target address.""" + dest_address = self.fetch_destination(address) + + if dest_address is None or not is_valid(dest_address): + QMessageBox.warning(parent_window, _('Error'), + _('Invalid Ixcoin Address') + ':\n' + address, _('OK')) + return False + + amount = D(unicode(amount)) * (10*self.g.decimal_point) + print "amount", amount + return + + if self.g.wallet.use_encryption: + password_dialog = PasswordDialog(parent_window) + password = password_dialog.run() + if not password: + return + else: + password = None + + fee = 0 + # 0.1 BTC = 10000000 + if amount < bitcoin(1) / 10: + # 0.001 BTC + fee = bitcoin(1) / 1000 + + try: + tx = self.g.wallet.mktx([(dest_address, amount)], password, fee) + except Exception as error: + QMessageBox.warning(parent_window, _('Error'), str(error), _('OK')) + return False + + if tx.is_complete(): + h = self.g.wallet.send_tx(tx) + + self.waiting_dialog(lambda: False if self.g.wallet.tx_event.isSet() else _("Sending transaction, please wait...")) + + status, message = self.g.wallet.receive_tx(h, tx) + + if not status: + import tempfile + dumpf = tempfile.NamedTemporaryFile(delete=False) + dumpf.write(tx) + dumpf.close() + print "Dumped error tx to", dumpf.name + QMessageBox.warning(parent_window, _('Error'), message, _('OK')) + return False + + TransactionWindow(message, self) + else: + filename = 'unsigned_tx_%s' % (time.mktime(time.gmtime())) + try: + fileName = QFileDialog.getSaveFileName(QWidget(), _("Select a transaction filename"), os.path.expanduser('~/%s' % (filename))) + with open(fileName,'w') as f: + f.write(json.dumps(tx.as_dict(),indent=4) + '\n') + QMessageBox.information(QWidget(), _('Unsigned transaction created'), _("Unsigned transaction was saved to file:") + " " +fileName, _('OK')) + except Exception as e: + QMessageBox.warning(QWidget(), _('Error'), _('Could not write transaction to file: %s' % e), _('OK')) + return True + + def fetch_destination(self, address): + recipient = unicode(address).strip() + + # alias + match1 = re.match("^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$", + recipient) + + # label or alias, with address in brackets + match2 = re.match("(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>", + recipient) + + if match1: + dest_address = \ + self.g.wallet.get_alias(recipient, True, + self.show_message, self.question) + return dest_address + elif match2: + return match2.group(2) + else: + return recipient + + + + + +class MiniDriver(QObject): + + INITIALIZING = 0 + CONNECTING = 1 + SYNCHRONIZING = 2 + READY = 3 + + def __init__(self, main_window, mini_window): + super(QObject, self).__init__() + + self.g = main_window + self.network = main_window.network + self.window = mini_window + + if self.network: + self.network.register_callback('updated',self.update_callback) + self.network.register_callback('status', self.update_callback) + + self.state = None + + self.initializing() + self.connect(self, SIGNAL("updatesignal()"), self.update) + self.update_callback() + + # This is a hack to workaround that Qt does not like changing the + # window properties from this other thread before the runloop has + # been called from. + def update_callback(self): + self.emit(SIGNAL("updatesignal()")) + + def update(self): + if not self.network: + self.initializing() + #elif not self.network.interface: + # self.initializing() + elif not self.network.is_connected(): + self.connecting() + + if self.g.wallet is None: + self.ready() + elif not self.g.wallet.up_to_date: + self.synchronizing() + else: + self.ready() + self.update_balance() + self.update_completions() + self.update_history() + self.window.receiving.update_list() + + + def initializing(self): + if self.state == self.INITIALIZING: + return + self.state = self.INITIALIZING + self.window.deactivate() + + def connecting(self): + if self.state == self.CONNECTING: + return + self.state = self.CONNECTING + self.window.deactivate() + + def synchronizing(self): + if self.state == self.SYNCHRONIZING: + return + self.state = self.SYNCHRONIZING + self.window.deactivate() + + def ready(self): + if self.state == self.READY: + return + self.state = self.READY + self.window.activate() + + def update_balance(self): + conf_balance, unconf_balance = self.g.wallet.get_balance() + balance = D(conf_balance + unconf_balance) + self.window.set_balances(balance) + + def update_completions(self): + completions = [] + for addr, label in self.g.wallet.labels.items(): + if addr in self.g.wallet.addressbook: + completions.append("%s <%s>" % (label, addr)) + self.window.update_completions(completions) + + def update_history(self): + tx_history = self.g.wallet.get_tx_history() + self.window.update_history(tx_history) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + with open(rsrc("style.css")) as style_file: + app.setStyleSheet(style_file.read()) + mini = MiniWindow() + sys.exit(app.exec_()) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py new file mode 100644 index 00000000..0e263618 --- /dev/null +++ b/gui/qt/main_window.py @@ -0,0 +1,2822 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, time, datetime, re, threading +from electrum_ixc.i18n import _, set_language +from electrum_ixc.util import print_error, print_msg +import os.path, json, ast, traceback +import webbrowser +import shutil +import StringIO + + +import PyQt4 +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore + +from electrum_ixc.bitcoin import MIN_RELAY_TX_FEE, is_valid +from electrum_ixc.plugins import run_hook + +import icons_rc + +from electrum_ixc.util import format_satoshis +from electrum_ixc import Transaction +from electrum_ixc import mnemonic +from electrum_ixc import util, bitcoin, commands, Interface, Wallet +from electrum_ixc import SimpleConfig, Wallet, WalletStorage +from electrum_ixc import Imported_Wallet + +from amountedit import AmountEdit, BTCAmountEdit, MyLineEdit +from network_dialog import NetworkDialog +from qrcodewidget import QRCodeWidget, QRDialog +from qrtextedit import ScanQRTextEdit, ShowQRTextEdit + +from decimal import Decimal + +import httplib +import socket +import webbrowser +import csv + + + + + +from electrum_ixc import ELECTRUM_VERSION +import re + +from util import MyTreeWidget, HelpButton, EnterButton, line_dialog, text_dialog, ok_cancel_buttons, close_button, WaitingDialog +from util import filename_field, ok_cancel_buttons2, address_field +from util import MONOSPACE_FONT + + + +class StatusBarButton(QPushButton): + def __init__(self, icon, tooltip, func): + QPushButton.__init__(self, icon, '') + self.setToolTip(tooltip) + self.setFlat(True) + self.setMaximumWidth(25) + self.clicked.connect(func) + self.func = func + self.setIconSize(QSize(25,25)) + + def keyPressEvent(self, e): + if e.key() == QtCore.Qt.Key_Return: + apply(self.func,()) + + + +default_column_widths = { + "history":[40,140,350,140], + "contacts":[350,330], + "receive": [370,200,130] +} + +# status of payment requests +PR_UNPAID = 0 +PR_EXPIRED = 1 +PR_SENT = 2 # sent but not propagated +PR_PAID = 3 # send and propagated +PR_ERROR = 4 # could not parse + +pr_icons = { + PR_UNPAID:":icons/unpaid.png", + PR_PAID:":icons/confirmed.png", + PR_EXPIRED:":icons/expired.png" +} +pr_tooltips = { + PR_UNPAID:_('Unpaid'), + PR_PAID:_('Paid'), + PR_EXPIRED:_('Expired') +} + + + +class ElectrumWindow(QMainWindow): + labelsChanged = pyqtSignal() + + def __init__(self, config, network, gui_object): + QMainWindow.__init__(self) + + self.config = config + self.network = network + self.gui_object = gui_object + self.tray = gui_object.tray + self.go_lite = gui_object.go_lite + self.lite = None + + self.create_status_bar() + self.need_update = threading.Event() + + self.decimal_point = config.get('decimal_point', 8) + self.num_zeros = int(config.get('num_zeros',0)) + self.invoices = {} + + self.completions = QStringListModel() + + self.tabs = tabs = QTabWidget(self) + self.column_widths = self.config.get("column_widths_2", default_column_widths ) + tabs.addTab(self.create_history_tab(), _('History') ) + tabs.addTab(self.create_send_tab(), _('Send') ) + tabs.addTab(self.create_receive_tab(), _('Receive') ) + tabs.addTab(self.create_addresses_tab(), _('Addresses') ) + tabs.addTab(self.create_contacts_tab(), _('Contacts') ) + tabs.addTab(self.create_invoices_tab(), _('Invoices') ) + tabs.addTab(self.create_console_tab(), _('Console') ) + tabs.setMinimumSize(600, 400) + tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + self.setCentralWidget(tabs) + + g = self.config.get("winpos-qt",[100, 100, 840, 400]) + self.setGeometry(g[0], g[1], g[2], g[3]) + if self.config.get("is_maximized"): + self.showMaximized() + + self.setWindowIcon(QIcon(":icons/electrum-ixc.png")) + self.init_menubar() + + QShortcut(QKeySequence("Ctrl+W"), self, self.close) + QShortcut(QKeySequence("Ctrl+Q"), self, self.close) + QShortcut(QKeySequence("Ctrl+R"), self, self.update_wallet) + QShortcut(QKeySequence("Ctrl+PgUp"), self, lambda: tabs.setCurrentIndex( (tabs.currentIndex() - 1 )%tabs.count() )) + QShortcut(QKeySequence("Ctrl+PgDown"), self, lambda: tabs.setCurrentIndex( (tabs.currentIndex() + 1 )%tabs.count() )) + + for i in range(tabs.count()): + QShortcut(QKeySequence("Alt+" + str(i + 1)), self, lambda i=i: tabs.setCurrentIndex(i)) + + self.connect(self, QtCore.SIGNAL('update_status'), self.update_status) + self.connect(self, QtCore.SIGNAL('banner_signal'), lambda: self.console.showMessage(self.network.banner) ) + self.connect(self, QtCore.SIGNAL('transaction_signal'), lambda: self.notify_transactions() ) + self.connect(self, QtCore.SIGNAL('payment_request_ok'), self.payment_request_ok) + self.connect(self, QtCore.SIGNAL('payment_request_error'), self.payment_request_error) + self.labelsChanged.connect(self.update_tabs) + + self.history_list.setFocus(True) + + # network callbacks + if self.network: + self.network.register_callback('updated', lambda: self.need_update.set()) + self.network.register_callback('banner', lambda: self.emit(QtCore.SIGNAL('banner_signal'))) + self.network.register_callback('status', lambda: self.emit(QtCore.SIGNAL('update_status'))) + self.network.register_callback('new_transaction', lambda: self.emit(QtCore.SIGNAL('transaction_signal'))) + self.network.register_callback('stop', self.close) + + # set initial message + self.console.showMessage(self.network.banner) + + self.wallet = None + self.payment_request = None + self.qr_window = None + self.not_enough_funds = False + self.pluginsdialog = None + + def update_account_selector(self): + # account selector + accounts = self.wallet.get_account_names() + self.account_selector.clear() + if len(accounts) > 1: + self.account_selector.addItems([_("All accounts")] + accounts.values()) + self.account_selector.setCurrentIndex(0) + self.account_selector.show() + else: + self.account_selector.hide() + + def close_wallet(self): + self.wallet.stop_threads() + run_hook('close_wallet') + + def load_wallet(self, wallet): + import electrum_ixc as electrum + self.wallet = wallet + self.update_wallet_format() + # address used to create a dummy transaction and estimate transaction fee + self.dummy_address = self.wallet.addresses(False)[0] + self.invoices = self.wallet.storage.get('invoices', {}) + self.accounts_expanded = self.wallet.storage.get('accounts_expanded',{}) + self.current_account = self.wallet.storage.get("current_account", None) + title = 'Electrum-IXC ' + self.wallet.electrum_version + ' - ' + os.path.basename(self.wallet.storage.path) + if self.wallet.is_watching_only(): title += ' [%s]' % (_('watching only')) + self.setWindowTitle( title ) + self.update_wallet() + # Once GUI has been initialized check if we want to announce something since the callback has been called before the GUI was initialized + self.notify_transactions() + self.update_account_selector() + # update menus + self.new_account_menu.setEnabled(self.wallet.can_create_accounts()) + self.private_keys_menu.setEnabled(not self.wallet.is_watching_only()) + self.password_menu.setEnabled(self.wallet.can_change_password()) + self.seed_menu.setEnabled(self.wallet.has_seed()) + self.mpk_menu.setEnabled(self.wallet.is_deterministic()) + self.import_menu.setEnabled(self.wallet.can_import()) + self.export_menu.setEnabled(self.wallet.can_export()) + + self.update_lock_icon() + self.update_buttons_on_seed() + self.update_console() + + self.clear_receive_tab() + self.update_receive_tab() + run_hook('load_wallet', wallet) + + + def update_wallet_format(self): + # convert old-format imported keys + if self.wallet.imported_keys: + password = self.password_dialog(_("Please enter your password in order to update imported keys")) + try: + self.wallet.convert_imported_keys(password) + except: + self.show_message("error") + + + def open_wallet(self): + wallet_folder = self.wallet.storage.path + filename = unicode( QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder) ) + if not filename: + return + + storage = WalletStorage({'wallet_path': filename}) + if not storage.file_exists: + self.show_message("file not found "+ filename) + return + + # close current wallet + self.close_wallet() + # load new wallet + wallet = Wallet(storage) + wallet.start_threads(self.network) + self.load_wallet(wallet) + + + + def backup_wallet(self): + import shutil + path = self.wallet.storage.path + wallet_folder = os.path.dirname(path) + filename = unicode( QFileDialog.getSaveFileName(self, _('Enter a filename for the copy of your wallet'), wallet_folder) ) + if not filename: + return + + new_path = os.path.join(wallet_folder, filename) + if new_path != path: + try: + shutil.copy2(path, new_path) + QMessageBox.information(None,"Wallet backup created", _("A copy of your wallet file was created in")+" '%s'" % str(new_path)) + except (IOError, os.error), reason: + QMessageBox.critical(None,"Unable to create backup", _("Electrum-IXC was unable to copy your wallet file to the specified location.")+"\n" + str(reason)) + + + def new_wallet(self): + import installwizard + + wallet_folder = os.path.dirname(self.wallet.storage.path) + i = 1 + while True: + filename = "wallet_%d"%i + if filename in os.listdir(wallet_folder): + i += 1 + else: + break + + filename = line_dialog(self, _('New Wallet'), _('Enter file name') + ':', _('OK'), filename) + if not filename: + return + + full_path = os.path.join(wallet_folder, filename) + storage = WalletStorage({'wallet_path': full_path}) + if storage.file_exists: + QMessageBox.critical(None, "Error", _("File exists")) + return + + wizard = installwizard.InstallWizard(self.config, self.network, storage) + wallet = wizard.run('new') + if wallet: + self.load_wallet(wallet) + + + + def init_menubar(self): + menubar = QMenuBar() + + file_menu = menubar.addMenu(_("&File")) + file_menu.addAction(_("&Open"), self.open_wallet).setShortcut(QKeySequence.Open) + file_menu.addAction(_("&New/Restore"), self.new_wallet).setShortcut(QKeySequence.New) + file_menu.addAction(_("&Save Copy"), self.backup_wallet).setShortcut(QKeySequence.SaveAs) + file_menu.addAction(_("&Quit"), self.close) + + wallet_menu = menubar.addMenu(_("&Wallet")) + wallet_menu.addAction(_("&New contact"), self.new_contact_dialog) + self.new_account_menu = wallet_menu.addAction(_("&New account"), self.new_account_dialog) + + wallet_menu.addSeparator() + + self.password_menu = wallet_menu.addAction(_("&Password"), self.change_password_dialog) + self.seed_menu = wallet_menu.addAction(_("&Seed"), self.show_seed_dialog) + self.mpk_menu = wallet_menu.addAction(_("&Master Public Keys"), self.show_master_public_keys) + + wallet_menu.addSeparator() + labels_menu = wallet_menu.addMenu(_("&Labels")) + labels_menu.addAction(_("&Import"), self.do_import_labels) + labels_menu.addAction(_("&Export"), self.do_export_labels) + + self.private_keys_menu = wallet_menu.addMenu(_("&Private keys")) + self.private_keys_menu.addAction(_("&Sweep"), self.sweep_key_dialog) + self.import_menu = self.private_keys_menu.addAction(_("&Import"), self.do_import_privkey) + self.export_menu = self.private_keys_menu.addAction(_("&Export"), self.export_privkeys_dialog) + wallet_menu.addAction(_("&Export History"), self.export_history_dialog) + + tools_menu = menubar.addMenu(_("&Tools")) + + # Settings / Preferences are all reserved keywords in OSX using this as work around + tools_menu.addAction(_("Electrum-IXC preferences") if sys.platform == 'darwin' else _("Preferences"), self.settings_dialog) + tools_menu.addAction(_("&Network"), self.run_network_dialog) + tools_menu.addAction(_("&Plugins"), self.plugins_dialog) + tools_menu.addSeparator() + tools_menu.addAction(_("&Sign/verify message"), self.sign_verify_message) + tools_menu.addAction(_("&Encrypt/decrypt message"), self.encrypt_message) + tools_menu.addSeparator() + + csv_transaction_menu = tools_menu.addMenu(_("&Create transaction")) + csv_transaction_menu.addAction(_("&From CSV file"), self.do_process_from_csv_file) + csv_transaction_menu.addAction(_("&From CSV text"), self.do_process_from_csv_text) + + raw_transaction_menu = tools_menu.addMenu(_("&Load transaction")) + raw_transaction_menu.addAction(_("&From file"), self.do_process_from_file) + raw_transaction_menu.addAction(_("&From text"), self.do_process_from_text) + raw_transaction_menu.addAction(_("&From the blockchain"), self.do_process_from_txid) + raw_transaction_menu.addAction(_("&From QR code"), self.read_tx_from_qrcode) + self.raw_transaction_menu = raw_transaction_menu + + help_menu = menubar.addMenu(_("&Help")) + help_menu.addAction(_("&About"), self.show_about) + help_menu.addAction(_("&Official website"), lambda: webbrowser.open("http://electrumalt.org")) + help_menu.addSeparator() + help_menu.addAction(_("&Documentation"), lambda: webbrowser.open("http://electrum.org/documentation.html")).setShortcut(QKeySequence.HelpContents) + help_menu.addAction(_("&Report Bug"), self.show_report_bug) + + self.setMenuBar(menubar) + + def show_about(self): + QMessageBox.about(self, "Electrum-IXC", + _("Version")+" %s" % (self.wallet.electrum_version) + "\n\n" + _("Electrum-IXC's focus is speed, with low resource usage and simplifying Ixcoin. You do not need to perform regular backups, because your wallet can be recovered from a secret phrase that you can memorize or write on paper. Startup times are instant because it operates in conjunction with high-performance servers that handle the most complicated parts of the Ixcoin system.")) + + def show_report_bug(self): + QMessageBox.information(self, "Electrum-IXC - " + _("Reporting Bugs"), + _("Please report any bugs as issues on github:")+" https://github.com/spesmilo/electrum/issues") + + + def notify_transactions(self): + if not self.network or not self.network.is_connected(): + return + + print_error("Notifying GUI") + if len(self.network.pending_transactions_for_notifications) > 0: + # Combine the transactions if there are more then three + tx_amount = len(self.network.pending_transactions_for_notifications) + if(tx_amount >= 3): + total_amount = 0 + for tx in self.network.pending_transactions_for_notifications: + is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx) + if(v > 0): + total_amount += v + + self.notify(_("%(txs)s new transactions received. Total amount received in the new transactions %(amount)s %(unit)s") \ + % { 'txs' : tx_amount, 'amount' : self.format_amount(total_amount), 'unit' : self.base_unit()}) + + self.network.pending_transactions_for_notifications = [] + else: + for tx in self.network.pending_transactions_for_notifications: + if tx: + self.network.pending_transactions_for_notifications.remove(tx) + is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx) + if(v > 0): + self.notify(_("New transaction received. %(amount)s %(unit)s") % { 'amount' : self.format_amount(v), 'unit' : self.base_unit()}) + + def notify(self, message): + if self.tray: + self.tray.showMessage("Electrum-IXC", message, QSystemTrayIcon.Information, 20000) + + + + # custom wrappers for getOpenFileName and getSaveFileName, that remember the path selected by the user + def getOpenFileName(self, title, filter = ""): + directory = self.config.get('io_dir', unicode(os.path.expanduser('~'))) + fileName = unicode( QFileDialog.getOpenFileName(self, title, directory, filter) ) + if fileName and directory != os.path.dirname(fileName): + self.config.set_key('io_dir', os.path.dirname(fileName), True) + return fileName + + def getSaveFileName(self, title, filename, filter = ""): + directory = self.config.get('io_dir', unicode(os.path.expanduser('~'))) + path = os.path.join( directory, filename ) + fileName = unicode( QFileDialog.getSaveFileName(self, title, path, filter) ) + if fileName and directory != os.path.dirname(fileName): + self.config.set_key('io_dir', os.path.dirname(fileName), True) + return fileName + + def close(self): + if self.qr_window: + self.qr_window.close() + QMainWindow.close(self) + run_hook('close_main_window') + + def connect_slots(self, sender): + self.connect(sender, QtCore.SIGNAL('timersignal'), self.timer_actions) + self.previous_payto_e='' + + def timer_actions(self): + if self.need_update.is_set(): + self.update_wallet() + self.need_update.clear() + + run_hook('timer_actions') + + def format_amount(self, x, is_diff=False, whitespaces=False): + return format_satoshis(x, is_diff, self.num_zeros, self.decimal_point, whitespaces) + + + def get_decimal_point(self): + return self.decimal_point + + + def base_unit(self): + assert self.decimal_point in [2, 5, 8] + if self.decimal_point == 2: + return 'ibits' + if self.decimal_point == 5: + return 'mIXC' + if self.decimal_point == 8: + return 'IXC' + raise Exception('Unknown base unit') + + def update_status(self): + if not self.wallet: + return + + if self.network is None or not self.network.is_running(): + text = _("Offline") + icon = QIcon(":icons/status_disconnected.png") + + elif self.network.is_connected(): + server_lag = self.network.get_local_height() - self.network.get_server_height() + if not self.wallet.up_to_date: + text = _("Synchronizing...") + icon = QIcon(":icons/status_waiting.png") + elif server_lag > 1: + text = _("Server is lagging (%d blocks)"%server_lag) + icon = QIcon(":icons/status_lagging.png") + else: + c, u = self.wallet.get_account_balance(self.current_account) + text = _( "Balance" ) + ": %s "%( self.format_amount(c) ) + self.base_unit() + if u: text += " [%s unconfirmed]"%( self.format_amount(u,True).strip() ) + + # append fiat balance and price from exchange rate plugin + r = {} + run_hook('get_fiat_status_text', c+u, r) + quote = r.get(0) + if quote: + text += "%s"%quote + + if self.tray: + self.tray.setToolTip(text) + icon = QIcon(":icons/status_connected.png") + else: + text = _("Not connected") + icon = QIcon(":icons/status_disconnected.png") + + self.balance_label.setText(text) + self.status_button.setIcon( icon ) + + + def update_wallet(self): + self.update_status() + if self.wallet.up_to_date or not self.network or not self.network.is_connected(): + self.update_tabs() + + def update_tabs(self): + self.update_history_tab() + self.update_receive_tab() + self.update_address_tab() + self.update_contacts_tab() + self.update_completions() + self.update_invoices_tab() + + + def create_history_tab(self): + self.history_list = l = MyTreeWidget(self) + l.setColumnCount(5) + for i,width in enumerate(self.column_widths['history']): + l.setColumnWidth(i, width) + l.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance')] ) + l.itemDoubleClicked.connect(self.tx_label_clicked) + l.itemChanged.connect(self.tx_label_changed) + l.customContextMenuRequested.connect(self.create_history_menu) + return l + + + def create_history_menu(self, position): + self.history_list.selectedIndexes() + item = self.history_list.currentItem() + be = self.config.get('block_explorer', 'Blockchain.info') + if be == 'Blockchain.info': + block_explorer = 'https://blockchain.info/tx/' + elif be == 'Blockr.io': + block_explorer = 'https://blockr.io/tx/info/' + elif be == 'Insight.is': + block_explorer = 'http://live.insight.is/tx/' + elif be == "Blocktrail.com": + block_explorer = 'https://www.blocktrail.com/tx/' + + if not item: return + tx_hash = str(item.data(0, Qt.UserRole).toString()) + if not tx_hash: return + menu = QMenu() + menu.addAction(_("Copy ID to Clipboard"), lambda: self.app.clipboard().setText(tx_hash)) + menu.addAction(_("Details"), lambda: self.show_transaction(self.wallet.transactions.get(tx_hash))) + menu.addAction(_("Edit description"), lambda: self.tx_label_clicked(item,2)) + menu.addAction(_("View on block explorer"), lambda: webbrowser.open(block_explorer + tx_hash)) + menu.exec_(self.contacts_list.viewport().mapToGlobal(position)) + + + def show_transaction(self, tx): + import transaction_dialog + d = transaction_dialog.TxDialog(tx, self) + d.exec_() + + def tx_label_clicked(self, item, column): + if column==2 and item.isSelected(): + self.is_edit=True + item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + self.history_list.editItem( item, column ) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + self.is_edit=False + + def tx_label_changed(self, item, column): + if self.is_edit: + return + self.is_edit=True + tx_hash = str(item.data(0, Qt.UserRole).toString()) + tx = self.wallet.transactions.get(tx_hash) + text = unicode( item.text(2) ) + self.wallet.set_label(tx_hash, text) + if text: + item.setForeground(2, QBrush(QColor('black'))) + else: + text = self.wallet.get_default_label(tx_hash) + item.setText(2, text) + item.setForeground(2, QBrush(QColor('gray'))) + self.is_edit=False + + + def edit_label(self, is_recv): + l = self.address_list if is_recv else self.contacts_list + item = l.currentItem() + item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + l.editItem( item, 1 ) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + + + + def address_label_clicked(self, item, column, l, column_addr, column_label): + if column == column_label and item.isSelected(): + is_editable = item.data(0, 32).toBool() + if not is_editable: + return + addr = unicode( item.text(column_addr) ) + label = unicode( item.text(column_label) ) + item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + l.editItem( item, column ) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + + + def address_label_changed(self, item, column, l, column_addr, column_label): + if column == column_label: + addr = unicode( item.text(column_addr) ) + text = unicode( item.text(column_label) ) + is_editable = item.data(0, 32).toBool() + if not is_editable: + return + + changed = self.wallet.set_label(addr, text) + if changed: + self.update_history_tab() + self.update_completions() + + self.current_item_changed(item) + + run_hook('item_changed', item, column) + + + def current_item_changed(self, a): + run_hook('current_item_changed', a) + + + + def update_history_tab(self): + + self.history_list.clear() + for item in self.wallet.get_tx_history(self.current_account): + tx_hash, conf, is_mine, value, fee, balance, timestamp = item + time_str = _("unknown") + if conf > 0: + try: + time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] + except Exception: + time_str = _("error") + + if conf == -1: + time_str = 'unverified' + icon = QIcon(":icons/unconfirmed.png") + elif conf == 0: + time_str = 'pending' + icon = QIcon(":icons/unconfirmed.png") + elif conf < 6: + icon = QIcon(":icons/clock%d.png"%conf) + else: + icon = QIcon(":icons/confirmed.png") + + if value is not None: + v_str = self.format_amount(value, True, whitespaces=True) + else: + v_str = '--' + + balance_str = self.format_amount(balance, whitespaces=True) + + if tx_hash: + label, is_default_label = self.wallet.get_label(tx_hash) + else: + label = _('Pruned transaction outputs') + is_default_label = False + + item = QTreeWidgetItem( [ '', time_str, label, v_str, balance_str] ) + item.setFont(2, QFont(MONOSPACE_FONT)) + item.setFont(3, QFont(MONOSPACE_FONT)) + item.setFont(4, QFont(MONOSPACE_FONT)) + if value < 0: + item.setForeground(3, QBrush(QColor("#BC1E1E"))) + if tx_hash: + item.setData(0, Qt.UserRole, tx_hash) + item.setToolTip(0, "%d %s\nTxId:%s" % (conf, _('Confirmations'), tx_hash) ) + if is_default_label: + item.setForeground(2, QBrush(QColor('grey'))) + + item.setIcon(0, icon) + self.history_list.insertTopLevelItem(0,item) + + + self.history_list.setCurrentItem(self.history_list.topLevelItem(0)) + run_hook('history_tab_update') + + + def create_receive_tab(self): + w = QWidget() + grid = QGridLayout(w) + grid.setColumnMinimumWidth(3, 300) + grid.setColumnStretch(5, 1) + + self.receive_address_e = QLineEdit() + self.receive_address_e.setReadOnly(True) + grid.addWidget(QLabel(_('Receiving address')), 0, 0) + grid.addWidget(self.receive_address_e, 0, 1, 1, 3) + self.receive_address_e.textChanged.connect(self.update_receive_qr) + + self.copy_button = QPushButton() + self.copy_button.setIcon(QIcon(":icons/copy.png")) + self.copy_button.clicked.connect(lambda: self.app.clipboard().setText(self.receive_address_e.text())) + grid.addWidget(self.copy_button, 0, 4) + + self.receive_message_e = QLineEdit() + grid.addWidget(QLabel(_('Message')), 1, 0) + grid.addWidget(self.receive_message_e, 1, 1, 1, 3) + self.receive_message_e.textChanged.connect(self.update_receive_qr) + + self.receive_amount_e = BTCAmountEdit(self.get_decimal_point) + grid.addWidget(QLabel(_('Requested amount')), 2, 0) + grid.addWidget(self.receive_amount_e, 2, 1, 1, 2) + self.receive_amount_e.textChanged.connect(self.update_receive_qr) + + self.save_request_button = QPushButton(_('Save')) + self.save_request_button.clicked.connect(self.save_payment_request) + grid.addWidget(self.save_request_button, 3, 1) + clear_button = QPushButton(_('New')) + clear_button.clicked.connect(self.new_receive_address) + grid.addWidget(clear_button, 3, 2) + grid.setRowStretch(4, 1) + + self.receive_qr = QRCodeWidget(fixedSize=200) + grid.addWidget(self.receive_qr, 0, 5, 5, 2) + self.receive_qr.mousePressEvent = lambda x: self.toggle_qr_window() + + grid.setRowStretch(5, 1) + + self.receive_requests_label = QLabel(_('Saved Requests')) + self.receive_list = MyTreeWidget(self) + self.receive_list.customContextMenuRequested.connect(self.receive_list_menu) + self.receive_list.currentItemChanged.connect(self.receive_item_changed) + self.receive_list.itemClicked.connect(self.receive_item_changed) + self.receive_list.setHeaderLabels( [_('Address'), _('Message'), _('Amount')] ) + self.receive_list.setColumnWidth(0, 340) + h = self.receive_list.header() + h.setStretchLastSection(False) + h.setResizeMode(1, QHeaderView.Stretch) + + grid.addWidget(self.receive_requests_label, 6, 0) + grid.addWidget(self.receive_list, 7, 0, 1, 6) + return w + + def receive_item_changed(self, item): + if item is None: + return + addr = str(item.text(0)) + amount, message = self.receive_requests[addr] + self.receive_address_e.setText(addr) + self.receive_message_e.setText(message) + self.receive_amount_e.setAmount(amount) + + + def receive_list_delete(self, item): + addr = str(item.text(0)) + self.receive_requests.pop(addr) + self.wallet.storage.put('receive_requests', self.receive_requests) + self.update_receive_tab() + self.clear_receive_tab() + + def receive_list_menu(self, position): + item = self.receive_list.itemAt(position) + menu = QMenu() + menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(str(item.text(0)))) + menu.addAction(_("Delete"), lambda: self.receive_list_delete(item)) + menu.exec_(self.receive_list.viewport().mapToGlobal(position)) + + def save_payment_request(self): + addr = str(self.receive_address_e.text()) + amount = self.receive_amount_e.get_amount() + message = unicode(self.receive_message_e.text()) + if not message and not amount: + QMessageBox.warning(self, _('Error'), _('No message or amount'), _('OK')) + return + self.receive_requests = self.wallet.storage.get('receive_requests',{}) + self.receive_requests[addr] = (amount, message) + self.wallet.storage.put('receive_requests', self.receive_requests) + self.update_receive_tab() + + def new_receive_address(self): + domain = self.wallet.get_account_addresses(self.current_account, include_change=False) + for addr in domain: + if not self.wallet.history.get(addr) and addr not in self.receive_requests.keys(): + break + else: + if isinstance(self.wallet, Imported_Wallet): + self.show_message(_('No more addresses in your wallet.')) + return + if not self.question(_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?")): + return + addr = self.wallet.create_new_address(self.current_account, False) + self.receive_address_e.setText(addr) + self.receive_message_e.setText('') + self.receive_amount_e.setAmount(None) + + def clear_receive_tab(self): + self.receive_requests = self.wallet.storage.get('receive_requests',{}) + domain = self.wallet.get_account_addresses(self.current_account, include_change=False) + for addr in domain: + if not self.wallet.history.get(addr) and addr not in self.receive_requests.keys(): + break + else: + addr = '' + self.receive_address_e.setText(addr) + self.receive_message_e.setText('') + self.receive_amount_e.setAmount(None) + + def toggle_qr_window(self): + import qrwindow + if not self.qr_window: + self.qr_window = qrwindow.QR_Window(self) + self.qr_window.setVisible(True) + self.qr_window_geometry = self.qr_window.geometry() + else: + if not self.qr_window.isVisible(): + self.qr_window.setVisible(True) + self.qr_window.setGeometry(self.qr_window_geometry) + else: + self.qr_window_geometry = self.qr_window.geometry() + self.qr_window.setVisible(False) + self.update_receive_qr() + + + def receive_at(self, addr): + if not bitcoin.is_address(addr): + return + self.tabs.setCurrentIndex(2) + self.receive_address_e.setText(addr) + + def update_receive_tab(self): + self.receive_requests = self.wallet.storage.get('receive_requests',{}) + b = len(self.receive_requests) > 0 + self.receive_list.setVisible(b) + self.receive_requests_label.setVisible(b) + + self.receive_list.clear() + for address, v in self.receive_requests.items(): + amount, message = v + item = QTreeWidgetItem( [ address, message, self.format_amount(amount) if amount else ""] ) + item.setFont(0, QFont(MONOSPACE_FONT)) + self.receive_list.addTopLevelItem(item) + + + def update_receive_qr(self): + import urlparse, urllib + addr = str(self.receive_address_e.text()) + amount = self.receive_amount_e.get_amount() + message = unicode(self.receive_message_e.text()).encode('utf8') + self.save_request_button.setEnabled((amount is not None) or (message != "")) + if addr: + query = [] + if amount: + query.append('amount=%s'%format_satoshis(amount)) + if message: + query.append('message=%s'%urllib.quote(message)) + p = urlparse.ParseResult(scheme='ixcoin', netloc='', path=addr, params='', query='&'.join(query), fragment='') + url = urlparse.urlunparse(p) + else: + url = "" + self.receive_qr.setData(url) + if self.qr_window: + self.qr_window.set_content(addr, amount, message, url) + + + def create_send_tab(self): + w = QWidget() + + self.send_grid = grid = QGridLayout(w) + grid.setSpacing(8) + grid.setColumnMinimumWidth(3,300) + grid.setColumnStretch(5,1) + grid.setRowStretch(8, 1) + + from paytoedit import PayToEdit + self.amount_e = BTCAmountEdit(self.get_decimal_point) + self.payto_e = PayToEdit(self) + self.payto_help = HelpButton(_('Recipient of the funds.') + '\n\n' + _('You may enter a Ixcoin address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Ixcoin address)')) + grid.addWidget(QLabel(_('Pay to')), 1, 0) + grid.addWidget(self.payto_e, 1, 1, 1, 3) + grid.addWidget(self.payto_help, 1, 4) + + completer = QCompleter() + completer.setCaseSensitivity(False) + self.payto_e.setCompleter(completer) + completer.setModel(self.completions) + + self.message_e = MyLineEdit() + self.message_help = HelpButton(_('Description of the transaction (not mandatory).') + '\n\n' + _('The description is not sent to the recipient of the funds. It is stored in your wallet file, and displayed in the \'History\' tab.')) + grid.addWidget(QLabel(_('Description')), 2, 0) + grid.addWidget(self.message_e, 2, 1, 1, 3) + grid.addWidget(self.message_help, 2, 4) + + self.from_label = QLabel(_('From')) + grid.addWidget(self.from_label, 3, 0) + self.from_list = MyTreeWidget(self) + self.from_list.setColumnCount(2) + self.from_list.setColumnWidth(0, 350) + self.from_list.setColumnWidth(1, 50) + self.from_list.setHeaderHidden(True) + self.from_list.setMaximumHeight(80) + self.from_list.setContextMenuPolicy(Qt.CustomContextMenu) + self.from_list.customContextMenuRequested.connect(self.from_list_menu) + grid.addWidget(self.from_list, 3, 1, 1, 3) + self.set_pay_from([]) + + self.amount_help = HelpButton(_('Amount to be sent.') + '\n\n' \ + + _('The amount will be displayed in red if you do not have enough funds in your wallet. Note that if you have frozen some of your addresses, the available funds will be lower than your total balance.') \ + + '\n\n' + _('Keyboard shortcut: type "!" to send all your coins.')) + grid.addWidget(QLabel(_('Amount')), 4, 0) + grid.addWidget(self.amount_e, 4, 1, 1, 2) + grid.addWidget(self.amount_help, 4, 3) + + self.fee_e_label = QLabel(_('Fee')) + self.fee_e = BTCAmountEdit(self.get_decimal_point) + grid.addWidget(self.fee_e_label, 5, 0) + grid.addWidget(self.fee_e, 5, 1, 1, 2) + msg = _('Ixcoin transactions are in general not free. A transaction fee is paid by the sender of the funds.') + '\n\n'\ + + _('The amount of fee can be decided freely by the sender. However, transactions with low fees take more time to be processed.') + '\n\n'\ + + _('A suggested fee is automatically added to this field. You may override it. The suggested fee increases with the size of the transaction.') + self.fee_e_help = HelpButton(msg) + grid.addWidget(self.fee_e_help, 5, 3) + self.update_fee_edit() + self.send_button = EnterButton(_("Send"), self.do_send) + grid.addWidget(self.send_button, 6, 1) + b = EnterButton(_("Clear"), self.do_clear) + grid.addWidget(b, 6, 2) + self.payto_sig = QLabel('') + grid.addWidget(self.payto_sig, 7, 0, 1, 4) + w.setLayout(grid) + + def on_shortcut(): + sendable = self.get_sendable_balance() + inputs = self.get_coins() + for i in inputs: self.wallet.add_input_info(i) + addr = self.payto_e.payto_address if self.payto_e.payto_address else self.dummy_address + output = ('address', addr, sendable) + dummy_tx = Transaction(inputs, [output]) + fee = self.wallet.estimated_fee(dummy_tx) + self.amount_e.setAmount(max(0,sendable-fee)) + self.amount_e.textEdited.emit("") + self.fee_e.setAmount(fee) + + self.amount_e.shortcut.connect(on_shortcut) + + def text_edited(is_fee): + outputs = self.payto_e.get_outputs() + amount = self.amount_e.get_amount() + fee = self.fee_e.get_amount() if is_fee else None + if amount is None: + self.fee_e.setAmount(None) + self.not_enough_funds = False + else: + if not outputs: + addr = self.payto_e.payto_address if self.payto_e.payto_address else self.dummy_address + outputs = [('address', addr, amount)] + tx = self.wallet.make_unsigned_transaction(outputs, fee, coins = self.get_coins()) + self.not_enough_funds = (tx is None) + if not is_fee: + fee = self.wallet.get_tx_fee(tx) if tx else None + self.fee_e.setAmount(fee) + + self.payto_e.textChanged.connect(lambda:text_edited(False)) + self.amount_e.textEdited.connect(lambda:text_edited(False)) + self.fee_e.textEdited.connect(lambda:text_edited(True)) + + def entry_changed(): + if not self.not_enough_funds: + palette = QPalette() + palette.setColor(self.amount_e.foregroundRole(), QColor('black')) + text = "" + else: + palette = QPalette() + palette.setColor(self.amount_e.foregroundRole(), QColor('red')) + text = _( "Not enough funds" ) + c, u = self.wallet.get_frozen_balance() + if c+u: text += ' (' + self.format_amount(c+u).strip() + ' ' + self.base_unit() + ' ' +_("are frozen") + ')' + self.statusBar().showMessage(text) + self.amount_e.setPalette(palette) + self.fee_e.setPalette(palette) + + self.amount_e.textChanged.connect(entry_changed) + self.fee_e.textChanged.connect(entry_changed) + + run_hook('create_send_tab', grid) + return w + + def update_fee_edit(self): + b = self.config.get('can_edit_fees', False) + self.fee_e.setVisible(b) + self.fee_e_label.setVisible(b) + self.fee_e_help.setVisible(b) + + def from_list_delete(self, item): + i = self.from_list.indexOfTopLevelItem(item) + self.pay_from.pop(i) + self.redraw_from_list() + + def from_list_menu(self, position): + item = self.from_list.itemAt(position) + menu = QMenu() + menu.addAction(_("Remove"), lambda: self.from_list_delete(item)) + menu.exec_(self.from_list.viewport().mapToGlobal(position)) + + def set_pay_from(self, domain = None): + self.pay_from = [] if domain == [] else self.wallet.get_unspent_coins(domain) + self.redraw_from_list() + + def redraw_from_list(self): + self.from_list.clear() + self.from_label.setHidden(len(self.pay_from) == 0) + self.from_list.setHidden(len(self.pay_from) == 0) + + def format(x): + h = x.get('prevout_hash') + return h[0:8] + '...' + h[-8:] + ":%d"%x.get('prevout_n') + u'\t' + "%s"%x.get('address') + + for item in self.pay_from: + self.from_list.addTopLevelItem(QTreeWidgetItem( [format(item), self.format_amount(item['value']) ])) + + def update_completions(self): + l = [] + for addr,label in self.wallet.labels.items(): + if addr in self.wallet.addressbook: + l.append( label + ' <' + addr + '>') + + run_hook('update_completions', l) + self.completions.setStringList(l) + + + def protected(func): + return lambda s, *args: s.do_protect(func, args) + + + def read_send_tab(self): + + if self.payment_request and self.payment_request.has_expired(): + QMessageBox.warning(self, _('Error'), _('Payment request has expired'), _('OK')) + return + + label = unicode( self.message_e.text() ) + + if self.payment_request: + outputs = self.payment_request.get_outputs() + else: + errors = self.payto_e.get_errors() + if errors: + self.show_warning(_("Invalid Lines found:") + "\n\n" + '\n'.join([ _("Line #") + str(x[0]+1) + ": " + x[1] for x in errors])) + return + outputs = self.payto_e.get_outputs() + + if not outputs: + QMessageBox.warning(self, _('Error'), _('No outputs'), _('OK')) + return + + for type, addr, amount in outputs: + if addr is None: + QMessageBox.warning(self, _('Error'), _('Ixcoin Address is None'), _('OK')) + return + if type == 'op_return': + continue + if type == 'address' and not bitcoin.is_address(addr): + QMessageBox.warning(self, _('Error'), _('Invalid Ixcoin Address'), _('OK')) + return + if amount is None: + QMessageBox.warning(self, _('Error'), _('Invalid Amount'), _('OK')) + return + + fee = self.fee_e.get_amount() + if fee is None: + QMessageBox.warning(self, _('Error'), _('Invalid Fee'), _('OK')) + return + + amount = sum(map(lambda x:x[2], outputs)) + confirm_amount = self.config.get('confirm_amount', 100000000) + if amount >= confirm_amount: + o = '\n'.join(map(lambda x:x[1], outputs)) + if not self.question(_("send %(amount)s to %(address)s?")%{ 'amount' : self.format_amount(amount) + ' '+ self.base_unit(), 'address' : o}): + return + + coins = self.get_coins() + return outputs, fee, label, coins + + + def do_send(self): + if run_hook('before_send'): + return + r = self.read_send_tab() + if not r: + return + outputs, fee, label, coins = r + try: + tx = self.wallet.make_unsigned_transaction(outputs, fee, None, coins = coins) + if not tx: + raise BaseException(_("Insufficient funds")) + except Exception as e: + traceback.print_exc(file=sys.stdout) + self.show_message(str(e)) + return + + if tx.get_fee() < MIN_RELAY_TX_FEE and tx.requires_fee(self.wallet.verifier): + QMessageBox.warning(self, _('Error'), _("This transaction requires a higher fee, or it will not be propagated by the network."), _('OK')) + return + + if not self.config.get('can_edit_fees', False): + if not self.question(_("A fee of %(fee)s will be added to this transaction.\nProceed?")%{ 'fee' : self.format_amount(fee) + ' '+ self.base_unit()}): + return + else: + confirm_fee = self.config.get('confirm_fee', 100000) + if fee >= confirm_fee: + if not self.question(_("The fee for this transaction seems unusually high.\nAre you really sure you want to pay %(fee)s in fees?")%{ 'fee' : self.format_amount(fee) + ' '+ self.base_unit()}): + return + + self.send_tx(tx, label) + + + @protected + def send_tx(self, tx, label, password): + self.send_button.setDisabled(True) + + # call hook to see if plugin needs gui interaction + run_hook('send_tx', tx) + + # sign the tx + def sign_thread(): + if self.wallet.is_watching_only(): + return tx + self.wallet.sign_transaction(tx, password) + return tx + + def sign_done(tx): + if label: + self.wallet.set_label(tx.hash(), label) + if not tx.is_complete() or self.config.get('show_before_broadcast'): + self.show_transaction(tx) + self.do_clear() + return + self.broadcast_transaction(tx) + + # keep a reference to WaitingDialog or the gui might crash + self.waiting_dialog = WaitingDialog(self, 'Signing..', sign_thread, sign_done, lambda: self.send_button.setDisabled(False)) + self.waiting_dialog.start() + + + + def broadcast_transaction(self, tx): + + def broadcast_thread(): + # non-GUI thread + pr = self.payment_request + if pr is None: + return self.wallet.sendtx(tx) + if pr.has_expired(): + self.payment_request = None + return False, _("Payment request has expired") + status, msg = self.wallet.sendtx(tx) + if not status: + return False, msg + self.invoices[pr.get_id()] = (pr.get_domain(), pr.get_memo(), pr.get_amount(), pr.get_expiration_date(), PR_PAID, tx.hash()) + self.wallet.storage.put('invoices', self.invoices) + self.payment_request = None + refund_address = self.wallet.addresses()[0] + ack_status, ack_msg = pr.send_ack(str(tx), refund_address) + if ack_status: + msg = ack_msg + return status, msg + + def broadcast_done(status, msg): + # GUI thread + if status: + QMessageBox.information(self, '', _('Payment sent.') + '\n' + msg, _('OK')) + self.update_invoices_tab() + self.do_clear() + else: + QMessageBox.warning(self, _('Error'), msg, _('OK')) + self.send_button.setDisabled(False) + + self.waiting_dialog = WaitingDialog(self, 'Broadcasting..', broadcast_thread, broadcast_done) + self.waiting_dialog.start() + + + + def prepare_for_payment_request(self): + self.tabs.setCurrentIndex(1) + self.payto_e.is_pr = True + for e in [self.payto_e, self.amount_e, self.message_e]: + e.setFrozen(True) + for h in [self.payto_help, self.amount_help, self.message_help]: + h.hide() + self.payto_e.setText(_("please wait...")) + return True + + def payment_request_ok(self): + pr = self.payment_request + pr_id = pr.get_id() + if pr_id not in self.invoices: + self.invoices[pr_id] = (pr.get_domain(), pr.get_memo(), pr.get_amount(), pr.get_expiration_date(), PR_UNPAID, None) + self.wallet.storage.put('invoices', self.invoices) + self.update_invoices_tab() + else: + print_error('invoice already in list') + + status = self.invoices[pr_id][4] + if status == PR_PAID: + self.do_clear() + self.show_message("invoice already paid") + self.payment_request = None + return + + self.payto_help.show() + self.payto_help.set_alt(lambda: self.show_pr_details(pr)) + + if not pr.has_expired(): + self.payto_e.setGreen() + else: + self.payto_e.setExpired() + + self.payto_e.setText(pr.domain) + self.amount_e.setText(self.format_amount(pr.get_amount())) + self.message_e.setText(pr.get_memo()) + # signal to set fee + self.amount_e.textEdited.emit("") + + def payment_request_error(self): + self.do_clear() + self.show_message(self.payment_request.error) + self.payment_request = None + + def pay_from_URI(self,URI): + if not URI: + return + address, amount, label, message, request_url = util.parse_URI(URI) + try: + address, amount, label, message, request_url = util.parse_URI(URI) + except Exception as e: + QMessageBox.warning(self, _('Error'), _('Invalid ixcoin URI:') + '\n' + str(e), _('OK')) + return + + self.tabs.setCurrentIndex(1) + + if not request_url: + if label: + if self.wallet.labels.get(address) != label: + if self.question(_('Save label "%s" for address %s ?'%(label,address))): + if address not in self.wallet.addressbook and not self.wallet.is_mine(address): + self.wallet.addressbook.append(address) + self.wallet.set_label(address, label) + else: + label = self.wallet.labels.get(address) + if address: + self.payto_e.setText(label + ' <'+ address +'>' if label else address) + if message: + self.message_e.setText(message) + if amount: + self.amount_e.setAmount(amount) + self.amount_e.textEdited.emit("") + return + + from electrum_ixc import paymentrequest + def payment_request(): + self.payment_request = paymentrequest.PaymentRequest(self.config) + self.payment_request.read(request_url) + if self.payment_request.verify(): + self.emit(SIGNAL('payment_request_ok')) + else: + self.emit(SIGNAL('payment_request_error')) + + self.pr_thread = threading.Thread(target=payment_request).start() + self.prepare_for_payment_request() + + + + def do_clear(self): + self.not_enough_funds = False + self.payto_e.is_pr = False + self.payto_sig.setVisible(False) + for e in [self.payto_e, self.message_e, self.amount_e, self.fee_e]: + e.setText('') + e.setFrozen(False) + + for h in [self.payto_help, self.amount_help, self.message_help]: + h.show() + + self.payto_help.set_alt(None) + self.set_pay_from([]) + self.update_status() + run_hook('do_clear') + + + def set_addrs_frozen(self,addrs,freeze): + for addr in addrs: + if not addr: continue + if addr in self.wallet.frozen_addresses and not freeze: + self.wallet.unfreeze(addr) + elif addr not in self.wallet.frozen_addresses and freeze: + self.wallet.freeze(addr) + self.update_address_tab() + + + + def create_list_tab(self, headers): + "generic tab creation method" + l = MyTreeWidget(self) + l.setColumnCount( len(headers) ) + l.setHeaderLabels( headers ) + + w = QWidget() + vbox = QVBoxLayout() + w.setLayout(vbox) + + vbox.setMargin(0) + vbox.setSpacing(0) + vbox.addWidget(l) + buttons = QWidget() + vbox.addWidget(buttons) + + return l, w + + + def create_addresses_tab(self): + l, w = self.create_list_tab([ _('Address'), _('Label'), _('Balance'), _('Tx')]) + for i,width in enumerate(self.column_widths['receive']): + l.setColumnWidth(i, width) + l.setContextMenuPolicy(Qt.CustomContextMenu) + l.customContextMenuRequested.connect(self.create_receive_menu) + l.setSelectionMode(QAbstractItemView.ExtendedSelection) + l.itemDoubleClicked.connect(lambda a, b: self.address_label_clicked(a,b,l,0,1)) + l.itemChanged.connect(lambda a,b: self.address_label_changed(a,b,l,0,1)) + l.currentItemChanged.connect(lambda a,b: self.current_item_changed(a)) + self.address_list = l + return w + + + + + def save_column_widths(self): + self.column_widths["receive"] = [] + for i in range(self.address_list.columnCount() -1): + self.column_widths["receive"].append(self.address_list.columnWidth(i)) + + self.column_widths["history"] = [] + for i in range(self.history_list.columnCount() - 1): + self.column_widths["history"].append(self.history_list.columnWidth(i)) + + self.column_widths["contacts"] = [] + for i in range(self.contacts_list.columnCount() - 1): + self.column_widths["contacts"].append(self.contacts_list.columnWidth(i)) + + self.config.set_key("column_widths_2", self.column_widths, True) + + + def create_contacts_tab(self): + l, w = self.create_list_tab([_('Address'), _('Label'), _('Tx')]) + l.setContextMenuPolicy(Qt.CustomContextMenu) + l.customContextMenuRequested.connect(self.create_contact_menu) + for i,width in enumerate(self.column_widths['contacts']): + l.setColumnWidth(i, width) + l.itemDoubleClicked.connect(lambda a, b: self.address_label_clicked(a,b,l,0,1)) + l.itemChanged.connect(lambda a,b: self.address_label_changed(a,b,l,0,1)) + self.contacts_list = l + return w + + + def create_invoices_tab(self): + l, w = self.create_list_tab([_('Date'), _('Requestor'), _('Memo'), _('Amount'), _('Status')]) + l.setColumnWidth(0, 150) + l.setColumnWidth(1, 150) + l.setColumnWidth(3, 150) + l.setColumnWidth(4, 40) + h = l.header() + h.setStretchLastSection(False) + h.setResizeMode(2, QHeaderView.Stretch) + l.setContextMenuPolicy(Qt.CustomContextMenu) + l.customContextMenuRequested.connect(self.create_invoice_menu) + self.invoices_list = l + return w + + def update_invoices_tab(self): + invoices = self.wallet.storage.get('invoices', {}) + l = self.invoices_list + l.clear() + for key, value in sorted(invoices.items(), key=lambda x: -x[1][3]): + domain, memo, amount, expiration_date, status, tx_hash = value + if status == PR_UNPAID and expiration_date and expiration_date < time.time(): + status = PR_EXPIRED + date_str = datetime.datetime.fromtimestamp(expiration_date).isoformat(' ')[:-3] + item = QTreeWidgetItem( [ date_str, domain, memo, self.format_amount(amount, whitespaces=True), ''] ) + icon = QIcon(pr_icons.get(status)) + item.setIcon(4, icon) + item.setToolTip(4, pr_tooltips.get(status,'')) + item.setData(0, 32, key) + item.setFont(1, QFont(MONOSPACE_FONT)) + item.setFont(2, QFont(MONOSPACE_FONT)) + l.addTopLevelItem(item) + l.setCurrentItem(l.topLevelItem(0)) + + def delete_imported_key(self, addr): + if self.question(_("Do you want to remove")+" %s "%addr +_("from your wallet?")): + self.wallet.delete_imported_key(addr) + self.update_address_tab() + self.update_history_tab() + + def edit_account_label(self, k): + text, ok = QInputDialog.getText(self, _('Rename account'), _('Name') + ':', text = self.wallet.labels.get(k,'')) + if ok: + label = unicode(text) + self.wallet.set_label(k,label) + self.update_address_tab() + + def account_set_expanded(self, item, k, b): + item.setExpanded(b) + self.accounts_expanded[k] = b + + def create_account_menu(self, position, k, item): + menu = QMenu() + exp = item.isExpanded() + menu.addAction(_("Minimize") if exp else _("Maximize"), lambda: self.account_set_expanded(item, k, not exp)) + menu.addAction(_("Rename"), lambda: self.edit_account_label(k)) + if self.wallet.seed_version > 4: + menu.addAction(_("View details"), lambda: self.show_account_details(k)) + if self.wallet.account_is_pending(k): + menu.addAction(_("Delete"), lambda: self.delete_pending_account(k)) + menu.exec_(self.address_list.viewport().mapToGlobal(position)) + + def delete_pending_account(self, k): + self.wallet.delete_pending_account(k) + self.update_address_tab() + self.update_account_selector() + + def create_receive_menu(self, position): + # fixme: this function apparently has a side effect. + # if it is not called the menu pops up several times + #self.address_list.selectedIndexes() + + selected = self.address_list.selectedItems() + multi_select = len(selected) > 1 + addrs = [unicode(item.text(0)) for item in selected] + if not multi_select: + item = self.address_list.itemAt(position) + if not item: return + + addr = addrs[0] + if not is_valid(addr): + k = str(item.data(0,32).toString()) + if k: + self.create_account_menu(position, k, item) + else: + item.setExpanded(not item.isExpanded()) + return + + menu = QMenu() + if not multi_select: + menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr)) + menu.addAction(_("Request payment"), lambda: self.receive_at(addr)) + menu.addAction(_("Edit label"), lambda: self.edit_label(True)) + menu.addAction(_("Public keys"), lambda: self.show_public_keys(addr)) + if self.wallet.can_export(): + menu.addAction(_("Private key"), lambda: self.show_private_key(addr)) + if not self.wallet.is_watching_only(): + menu.addAction(_("Sign/verify message"), lambda: self.sign_verify_message(addr)) + menu.addAction(_("Encrypt/decrypt message"), lambda: self.encrypt_message(addr)) + if self.wallet.is_imported(addr): + menu.addAction(_("Remove from wallet"), lambda: self.delete_imported_key(addr)) + + if any(addr not in self.wallet.frozen_addresses for addr in addrs): + menu.addAction(_("Freeze"), lambda: self.set_addrs_frozen(addrs, True)) + if any(addr in self.wallet.frozen_addresses for addr in addrs): + menu.addAction(_("Unfreeze"), lambda: self.set_addrs_frozen(addrs, False)) + + def can_send(addr): + return addr not in self.wallet.frozen_addresses and self.wallet.get_addr_balance(addr) != (0, 0) + if any(can_send(addr) for addr in addrs): + menu.addAction(_("Send From"), lambda: self.send_from_addresses(addrs)) + + run_hook('receive_menu', menu, addrs) + menu.exec_(self.address_list.viewport().mapToGlobal(position)) + + + def get_sendable_balance(self): + return sum(map(lambda x:x['value'], self.get_coins())) + + + def get_coins(self): + if self.pay_from: + return self.pay_from + else: + domain = self.wallet.get_account_addresses(self.current_account) + for i in self.wallet.frozen_addresses: + if i in domain: domain.remove(i) + return self.wallet.get_unspent_coins(domain) + + + def send_from_addresses(self, addrs): + self.set_pay_from( addrs ) + self.tabs.setCurrentIndex(1) + + + def payto(self, addr): + if not addr: return + label = self.wallet.labels.get(addr) + m_addr = label + ' <' + addr + '>' if label else addr + self.tabs.setCurrentIndex(1) + self.payto_e.setText(m_addr) + self.amount_e.setFocus() + + + def delete_contact(self, x): + if self.question(_("Do you want to remove")+" %s "%x +_("from your list of contacts?")): + self.wallet.delete_contact(x) + self.wallet.set_label(x, None) + self.update_history_tab() + self.update_contacts_tab() + self.update_completions() + + + def create_contact_menu(self, position): + item = self.contacts_list.itemAt(position) + menu = QMenu() + if not item: + menu.addAction(_("New contact"), lambda: self.new_contact_dialog()) + else: + addr = unicode(item.text(0)) + label = unicode(item.text(1)) + is_editable = item.data(0,32).toBool() + payto_addr = item.data(0,33).toString() + menu.addAction(_("Copy to Clipboard"), lambda: self.app.clipboard().setText(addr)) + menu.addAction(_("Pay to"), lambda: self.payto(payto_addr)) + menu.addAction(_("QR code"), lambda: self.show_qrcode("ixcoin:" + addr, _("Address"))) + if is_editable: + menu.addAction(_("Edit label"), lambda: self.edit_label(False)) + menu.addAction(_("Delete"), lambda: self.delete_contact(addr)) + + run_hook('create_contact_menu', menu, item) + menu.exec_(self.contacts_list.viewport().mapToGlobal(position)) + + def delete_invoice(self, key): + self.invoices.pop(key) + self.wallet.storage.put('invoices', self.invoices) + self.update_invoices_tab() + + def show_invoice(self, key): + from electrum_ixc.paymentrequest import PaymentRequest + domain, memo, value, expiration, status, tx_hash = self.invoices[key] + pr = PaymentRequest(self.config) + pr.read_file(key) + pr.domain = domain + pr.verify() + self.show_pr_details(pr, tx_hash) + + def show_pr_details(self, pr, tx_hash=None): + msg = 'Domain: ' + pr.domain + msg += '\nStatus: ' + pr.get_status() + msg += '\nMemo: ' + pr.get_memo() + msg += '\nPayment URL: ' + pr.payment_url + msg += '\n\nOutputs:\n' + '\n'.join(map(lambda x: x[1] + ' ' + self.format_amount(x[2])+ self.base_unit(), pr.get_outputs())) + if tx_hash: + msg += '\n\nTransaction ID: ' + tx_hash + QMessageBox.information(self, 'Invoice', msg , 'OK') + + def do_pay_invoice(self, key): + from electrum_ixc.paymentrequest import PaymentRequest + domain, memo, value, expiration, status, tx_hash = self.invoices[key] + pr = PaymentRequest(self.config) + pr.read_file(key) + pr.domain = domain + self.payment_request = pr + self.prepare_for_payment_request() + if pr.verify(): + self.payment_request_ok() + else: + self.payment_request_error() + + + def create_invoice_menu(self, position): + item = self.invoices_list.itemAt(position) + if not item: + return + key = str(item.data(0, 32).toString()) + domain, memo, value, expiration, status, tx_hash = self.invoices[key] + menu = QMenu() + menu.addAction(_("Details"), lambda: self.show_invoice(key)) + if status == PR_UNPAID: + menu.addAction(_("Pay Now"), lambda: self.do_pay_invoice(key)) + menu.addAction(_("Delete"), lambda: self.delete_invoice(key)) + menu.exec_(self.invoices_list.viewport().mapToGlobal(position)) + + + + def update_address_tab(self): + l = self.address_list + # extend the syntax for consistency + l.addChild = l.addTopLevelItem + l.insertChild = l.insertTopLevelItem + + l.clear() + + accounts = self.wallet.get_accounts() + if self.current_account is None: + account_items = sorted(accounts.items()) + else: + account_items = [(self.current_account, accounts.get(self.current_account))] + + + for k, account in account_items: + + if len(accounts) > 1: + name = self.wallet.get_account_name(k) + c,u = self.wallet.get_account_balance(k) + account_item = QTreeWidgetItem( [ name, '', self.format_amount(c+u), ''] ) + l.addTopLevelItem(account_item) + account_item.setExpanded(self.accounts_expanded.get(k, True)) + account_item.setData(0, 32, k) + else: + account_item = l + + sequences = [0,1] if account.has_change() else [0] + for is_change in sequences: + if len(sequences) > 1: + name = _("Receiving") if not is_change else _("Change") + seq_item = QTreeWidgetItem( [ name, '', '', '', ''] ) + account_item.addChild(seq_item) + if not is_change: + seq_item.setExpanded(True) + else: + seq_item = account_item + + used_item = QTreeWidgetItem( [ _("Used"), '', '', '', ''] ) + used_flag = False + + addr_list = account.get_addresses(is_change) + for address in addr_list: + num, is_used = self.wallet.is_used(address) + label = self.wallet.labels.get(address,'') + c, u = self.wallet.get_addr_balance(address) + balance = self.format_amount(c + u) + item = QTreeWidgetItem( [ address, label, balance, "%d"%num] ) + item.setFont(0, QFont(MONOSPACE_FONT)) + item.setData(0, 32, True) # label can be edited + if address in self.wallet.frozen_addresses: + item.setBackgroundColor(0, QColor('lightblue')) + if self.wallet.is_beyond_limit(address, account, is_change): + item.setBackgroundColor(0, QColor('red')) + if is_used: + if not used_flag: + seq_item.insertChild(0, used_item) + used_flag = True + used_item.addChild(item) + else: + seq_item.addChild(item) + + # we use column 1 because column 0 may be hidden + l.setCurrentItem(l.topLevelItem(0),1) + + + def update_contacts_tab(self): + l = self.contacts_list + l.clear() + + for address in self.wallet.addressbook: + label = self.wallet.labels.get(address,'') + n = self.wallet.get_num_tx(address) + item = QTreeWidgetItem( [ address, label, "%d"%n] ) + item.setFont(0, QFont(MONOSPACE_FONT)) + # 32 = label can be edited (bool) + item.setData(0,32, True) + # 33 = payto string + item.setData(0,33, address) + l.addTopLevelItem(item) + + run_hook('update_contacts_tab', l) + l.setCurrentItem(l.topLevelItem(0)) + + + def create_console_tab(self): + from console import Console + self.console = console = Console() + return console + + + def update_console(self): + console = self.console + console.history = self.config.get("console-history",[]) + console.history_index = len(console.history) + + console.updateNamespace({'wallet' : self.wallet, 'network' : self.network, 'gui':self}) + console.updateNamespace({'util' : util, 'bitcoin':bitcoin}) + + c = commands.Commands(self.wallet, self.network, lambda: self.console.set_json(True)) + methods = {} + def mkfunc(f, method): + return lambda *args: apply( f, (method, args, self.password_dialog )) + for m in dir(c): + if m[0]=='_' or m in ['network','wallet']: continue + methods[m] = mkfunc(c._run, m) + + console.updateNamespace(methods) + + + def change_account(self,s): + if s == _("All accounts"): + self.current_account = None + else: + accounts = self.wallet.get_account_names() + for k, v in accounts.items(): + if v == s: + self.current_account = k + self.update_history_tab() + self.update_status() + self.update_address_tab() + self.update_receive_tab() + + def create_status_bar(self): + + sb = QStatusBar() + sb.setFixedHeight(35) + qtVersion = qVersion() + + self.balance_label = QLabel("") + sb.addWidget(self.balance_label) + + from version_getter import UpdateLabel + self.updatelabel = UpdateLabel(self.config, sb) + + self.account_selector = QComboBox() + self.account_selector.setSizeAdjustPolicy(QComboBox.AdjustToContents) + self.connect(self.account_selector,SIGNAL("activated(QString)"),self.change_account) + sb.addPermanentWidget(self.account_selector) + + if (int(qtVersion[0]) >= 4 and int(qtVersion[2]) >= 7): + sb.addPermanentWidget( StatusBarButton( QIcon(":icons/switchgui.png"), _("Switch to Lite Mode"), self.go_lite ) ) + + self.lock_icon = QIcon() + self.password_button = StatusBarButton( self.lock_icon, _("Password"), self.change_password_dialog ) + sb.addPermanentWidget( self.password_button ) + + sb.addPermanentWidget( StatusBarButton( QIcon(":icons/preferences.png"), _("Preferences"), self.settings_dialog ) ) + self.seed_button = StatusBarButton( QIcon(":icons/seed.png"), _("Seed"), self.show_seed_dialog ) + sb.addPermanentWidget( self.seed_button ) + self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), _("Network"), self.run_network_dialog ) + sb.addPermanentWidget( self.status_button ) + + run_hook('create_status_bar', sb) + + self.setStatusBar(sb) + + + def update_lock_icon(self): + icon = QIcon(":icons/lock.png") if self.wallet.use_encryption else QIcon(":icons/unlock.png") + self.password_button.setIcon( icon ) + + + def update_buttons_on_seed(self): + self.seed_button.setVisible(self.wallet.has_seed()) + self.password_button.setVisible(self.wallet.can_change_password()) + self.send_button.setText(_("Create unsigned transaction") if self.wallet.is_watching_only() else _("Send")) + + + def change_password_dialog(self): + from password_dialog import PasswordDialog + d = PasswordDialog(self.wallet, self) + d.run() + self.update_lock_icon() + + + def new_contact_dialog(self): + + d = QDialog(self) + d.setWindowTitle(_("New Contact")) + vbox = QVBoxLayout(d) + vbox.addWidget(QLabel(_('New Contact')+':')) + + grid = QGridLayout() + line1 = QLineEdit() + line2 = QLineEdit() + grid.addWidget(QLabel(_("Address")), 1, 0) + grid.addWidget(line1, 1, 1) + grid.addWidget(QLabel(_("Name")), 2, 0) + grid.addWidget(line2, 2, 1) + + vbox.addLayout(grid) + vbox.addLayout(ok_cancel_buttons(d)) + + if not d.exec_(): + return + + address = str(line1.text()) + label = unicode(line2.text()) + + if not is_valid(address): + QMessageBox.warning(self, _('Error'), _('Invalid Address'), _('OK')) + return + + self.wallet.add_contact(address) + if label: + self.wallet.set_label(address, label) + + self.update_contacts_tab() + self.update_history_tab() + self.update_completions() + self.tabs.setCurrentIndex(3) + + + @protected + def new_account_dialog(self, password): + + dialog = QDialog(self) + dialog.setModal(1) + dialog.setWindowTitle(_("New Account")) + + vbox = QVBoxLayout() + vbox.addWidget(QLabel(_('Account name')+':')) + e = QLineEdit() + vbox.addWidget(e) + msg = _("Note: Newly created accounts are 'pending' until they receive ixcoins.") + " " \ + + _("You will need to wait for 2 confirmations until the correct balance is displayed and more addresses are created for that account.") + l = QLabel(msg) + l.setWordWrap(True) + vbox.addWidget(l) + + vbox.addLayout(ok_cancel_buttons(dialog)) + dialog.setLayout(vbox) + r = dialog.exec_() + if not r: return + + name = str(e.text()) + + self.wallet.create_pending_account(name, password) + self.update_address_tab() + self.update_account_selector() + self.tabs.setCurrentIndex(3) + + + + + def show_master_public_keys(self): + + dialog = QDialog(self) + dialog.setModal(1) + dialog.setWindowTitle(_("Master Public Keys")) + + main_layout = QGridLayout() + mpk_dict = self.wallet.get_master_public_keys() + # filter out the empty keys (PendingAccount) + mpk_dict = {acc:mpk for acc,mpk in mpk_dict.items() if mpk} + + # only show the combobox in case multiple accounts are available + if len(mpk_dict) > 1: + combobox = QComboBox() + for name in mpk_dict: + combobox.addItem(name) + combobox.setCurrentIndex(0) + main_layout.addWidget(combobox, 1, 0) + + account = unicode(combobox.currentText()) + mpk_text = ShowQRTextEdit(text=mpk_dict[account]) + mpk_text.setMaximumHeight(170) + mpk_text.selectAll() # for easy copying + main_layout.addWidget(mpk_text, 2, 0) + + def show_mpk(account): + mpk = mpk_dict.get(unicode(account), "") + mpk_text.setText(mpk) + + combobox.currentIndexChanged[str].connect(lambda acc: show_mpk(acc)) + elif len(mpk_dict) == 1: + mpk = mpk_dict.values()[0] + mpk_text = ShowQRTextEdit(text=mpk) + mpk_text.setMaximumHeight(170) + mpk_text.selectAll() # for easy copying + main_layout.addWidget(mpk_text, 2, 0) + + vbox = QVBoxLayout() + vbox.addLayout(main_layout) + vbox.addLayout(close_button(dialog)) + + dialog.setLayout(vbox) + dialog.exec_() + + @protected + def show_seed_dialog(self, password): + if not self.wallet.has_seed(): + QMessageBox.information(self, _('Message'), _('This wallet has no seed'), _('OK')) + return + + try: + mnemonic = self.wallet.get_mnemonic(password) + except Exception: + QMessageBox.warning(self, _('Error'), _('Incorrect Password'), _('OK')) + return + from seed_dialog import SeedDialog + d = SeedDialog(self, mnemonic, self.wallet.has_imported_keys()) + d.exec_() + + + + def show_qrcode(self, data, title = _("QR code")): + if not data: + return + d = QRDialog(data, self, title) + d.exec_() + + + def do_protect(self, func, args): + if self.wallet.use_encryption: + password = self.password_dialog() + if not password: + return + else: + password = None + + if args != (False,): + args = (self,) + args + (password,) + else: + args = (self,password) + apply( func, args) + + + def show_public_keys(self, address): + if not address: return + try: + pubkey_list = self.wallet.get_public_keys(address) + except Exception as e: + traceback.print_exc(file=sys.stdout) + self.show_message(str(e)) + return + + d = QDialog(self) + d.setMinimumSize(600, 200) + d.setModal(1) + d.setWindowTitle(_("Public key")) + vbox = QVBoxLayout() + vbox.addWidget( QLabel(_("Address") + ': ' + address)) + vbox.addWidget( QLabel(_("Public key") + ':')) + keys = ShowQRTextEdit(text='\n'.join(pubkey_list)) + vbox.addWidget(keys) + vbox.addLayout(close_button(d)) + d.setLayout(vbox) + d.exec_() + + @protected + def show_private_key(self, address, password): + if not address: return + try: + pk_list = self.wallet.get_private_key(address, password) + except Exception as e: + traceback.print_exc(file=sys.stdout) + self.show_message(str(e)) + return + + d = QDialog(self) + d.setMinimumSize(600, 200) + d.setModal(1) + d.setWindowTitle(_("Private key")) + vbox = QVBoxLayout() + vbox.addWidget( QLabel(_("Address") + ': ' + address)) + vbox.addWidget( QLabel(_("Private key") + ':')) + keys = ShowQRTextEdit(text='\n'.join(pk_list)) + vbox.addWidget(keys) + vbox.addLayout(close_button(d)) + d.setLayout(vbox) + d.exec_() + + + @protected + def do_sign(self, address, message, signature, password): + message = unicode(message.toPlainText()) + message = message.encode('utf-8') + try: + sig = self.wallet.sign_message(str(address.text()), message, password) + signature.setText(sig) + except Exception as e: + self.show_message(str(e)) + + def do_verify(self, address, message, signature): + message = unicode(message.toPlainText()) + message = message.encode('utf-8') + if bitcoin.verify_message(address.text(), str(signature.toPlainText()), message): + self.show_message(_("Signature verified")) + else: + self.show_message(_("Error: wrong signature")) + + + def sign_verify_message(self, address=''): + d = QDialog(self) + d.setModal(1) + d.setWindowTitle(_('Sign/verify Message')) + d.setMinimumSize(410, 290) + + layout = QGridLayout(d) + + message_e = QTextEdit() + layout.addWidget(QLabel(_('Message')), 1, 0) + layout.addWidget(message_e, 1, 1) + layout.setRowStretch(2,3) + + address_e = QLineEdit() + address_e.setText(address) + layout.addWidget(QLabel(_('Address')), 2, 0) + layout.addWidget(address_e, 2, 1) + + signature_e = QTextEdit() + layout.addWidget(QLabel(_('Signature')), 3, 0) + layout.addWidget(signature_e, 3, 1) + layout.setRowStretch(3,1) + + hbox = QHBoxLayout() + + b = QPushButton(_("Sign")) + b.clicked.connect(lambda: self.do_sign(address_e, message_e, signature_e)) + hbox.addWidget(b) + + b = QPushButton(_("Verify")) + b.clicked.connect(lambda: self.do_verify(address_e, message_e, signature_e)) + hbox.addWidget(b) + + b = QPushButton(_("Close")) + b.clicked.connect(d.accept) + hbox.addWidget(b) + layout.addLayout(hbox, 4, 1) + d.exec_() + + + @protected + def do_decrypt(self, message_e, pubkey_e, encrypted_e, password): + try: + decrypted = self.wallet.decrypt_message(str(pubkey_e.text()), str(encrypted_e.toPlainText()), password) + message_e.setText(decrypted) + except BaseException as e: + traceback.print_exc(file=sys.stdout) + self.show_warning(str(e)) + + + def do_encrypt(self, message_e, pubkey_e, encrypted_e): + message = unicode(message_e.toPlainText()) + message = message.encode('utf-8') + try: + encrypted = bitcoin.encrypt_message(message, str(pubkey_e.text())) + encrypted_e.setText(encrypted) + except BaseException as e: + traceback.print_exc(file=sys.stdout) + self.show_warning(str(e)) + + + def encrypt_message(self, address = ''): + d = QDialog(self) + d.setModal(1) + d.setWindowTitle(_('Encrypt/decrypt Message')) + d.setMinimumSize(610, 490) + + layout = QGridLayout(d) + + message_e = QTextEdit() + layout.addWidget(QLabel(_('Message')), 1, 0) + layout.addWidget(message_e, 1, 1) + layout.setRowStretch(2,3) + + pubkey_e = QLineEdit() + if address: + pubkey = self.wallet.get_public_keys(address)[0] + pubkey_e.setText(pubkey) + layout.addWidget(QLabel(_('Public key')), 2, 0) + layout.addWidget(pubkey_e, 2, 1) + + encrypted_e = QTextEdit() + layout.addWidget(QLabel(_('Encrypted')), 3, 0) + layout.addWidget(encrypted_e, 3, 1) + layout.setRowStretch(3,1) + + hbox = QHBoxLayout() + b = QPushButton(_("Encrypt")) + b.clicked.connect(lambda: self.do_encrypt(message_e, pubkey_e, encrypted_e)) + hbox.addWidget(b) + + b = QPushButton(_("Decrypt")) + b.clicked.connect(lambda: self.do_decrypt(message_e, pubkey_e, encrypted_e)) + hbox.addWidget(b) + + b = QPushButton(_("Close")) + b.clicked.connect(d.accept) + hbox.addWidget(b) + + layout.addLayout(hbox, 4, 1) + d.exec_() + + + def question(self, msg): + return QMessageBox.question(self, _('Message'), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes + + def show_message(self, msg): + QMessageBox.information(self, _('Message'), msg, _('OK')) + + def show_warning(self, msg): + QMessageBox.warning(self, _('Warning'), msg, _('OK')) + + def password_dialog(self, msg=None): + d = QDialog(self) + d.setModal(1) + d.setWindowTitle(_("Enter Password")) + + pw = QLineEdit() + pw.setEchoMode(2) + + vbox = QVBoxLayout() + if not msg: + msg = _('Please enter your password') + vbox.addWidget(QLabel(msg)) + + grid = QGridLayout() + grid.setSpacing(8) + grid.addWidget(QLabel(_('Password')), 1, 0) + grid.addWidget(pw, 1, 1) + vbox.addLayout(grid) + + vbox.addLayout(ok_cancel_buttons(d)) + d.setLayout(vbox) + + run_hook('password_dialog', pw, grid, 1) + if not d.exec_(): return + return unicode(pw.text()) + + + + + + + + + def tx_from_text(self, txt): + "json or raw hexadecimal" + try: + txt.decode('hex') + is_hex = True + except: + is_hex = False + + if is_hex: + try: + return Transaction.deserialize(txt) + except: + traceback.print_exc(file=sys.stdout) + QMessageBox.critical(None, _("Unable to parse transaction"), _("Electrum-IXC was unable to parse your transaction")) + return + + try: + tx_dict = json.loads(str(txt)) + assert "hex" in tx_dict.keys() + tx = Transaction.deserialize(tx_dict["hex"]) + #if tx_dict.has_key("input_info"): + # input_info = json.loads(tx_dict['input_info']) + # tx.add_input_info(input_info) + return tx + except Exception: + traceback.print_exc(file=sys.stdout) + QMessageBox.critical(None, _("Unable to parse transaction"), _("Electrum-IXC was unable to parse your transaction")) + + + def read_tx_from_qrcode(self): + from electrum_ixc import qrscanner + try: + data = qrscanner.scan_qr(self.config) + except BaseException, e: + QMessageBox.warning(self, _('Error'), _(e), _('OK')) + return + if not data: + return + # if the user scanned a bitcoin URI + if data.startswith("ixcoin:"): + self.pay_from_URI(data) + return + # else if the user scanned an offline signed tx + # transactions are binary, but qrcode seems to return utf8... + z = data.decode('utf8') + data = ''.join(chr(ord(b)) for b in z).encode('hex') + tx = self.tx_from_text(data) + if not tx: + return + self.show_transaction(tx) + + + def read_tx_from_file(self): + fileName = self.getOpenFileName(_("Select your transaction file"), "*.txn") + if not fileName: + return + try: + with open(fileName, "r") as f: + file_content = f.read() + except (ValueError, IOError, os.error), reason: + QMessageBox.critical(None, _("Unable to read file or no transaction found"), _("Electrum-IXC was unable to open your transaction file") + "\n" + str(reason)) + + return self.tx_from_text(file_content) + + + @protected + def sign_raw_transaction(self, tx, password): + try: + self.wallet.sign_transaction(tx, password) + except Exception as e: + traceback.print_exc(file=sys.stdout) + QMessageBox.warning(self, _("Error"), str(e)) + + def do_process_from_text(self): + text = text_dialog(self, _('Input raw transaction'), _("Transaction:"), _("Load transaction")) + if not text: + return + tx = self.tx_from_text(text) + if tx: + self.show_transaction(tx) + + def do_process_from_file(self): + tx = self.read_tx_from_file() + if tx: + self.show_transaction(tx) + + def do_process_from_txid(self): + from electrum_ixc import transaction + txid, ok = QInputDialog.getText(self, _('Lookup transaction'), _('Transaction ID') + ':') + if ok and txid: + r = self.network.synchronous_get([ ('blockchain.transaction.get',[str(txid)]) ])[0] + if r: + tx = transaction.Transaction.deserialize(r) + if tx: + self.show_transaction(tx) + else: + self.show_message("unknown transaction") + + def do_process_from_csvReader(self, csvReader): + outputs = [] + errors = [] + errtext = "" + try: + for position, row in enumerate(csvReader): + address = row[0] + if not bitcoin.is_address(address): + errors.append((position, address)) + continue + amount = Decimal(row[1]) + amount = int(100000000*amount) + outputs.append(('address', address, amount)) + except (ValueError, IOError, os.error), reason: + QMessageBox.critical(None, _("Unable to read file or no transaction found"), _("Electrum-IXC was unable to open your transaction file") + "\n" + str(reason)) + return + if errors != []: + for x in errors: + errtext += "CSV Row " + str(x[0]+1) + ": " + x[1] + "\n" + QMessageBox.critical(None, _("Invalid Addresses"), _("ABORTING! Invalid Addresses found:") + "\n\n" + errtext) + return + + try: + tx = self.wallet.make_unsigned_transaction(outputs, None, None) + except Exception as e: + self.show_message(str(e)) + return + + self.show_transaction(tx) + + def do_process_from_csv_file(self): + fileName = self.getOpenFileName(_("Select your transaction CSV"), "*.csv") + if not fileName: + return + try: + with open(fileName, "r") as f: + csvReader = csv.reader(f) + self.do_process_from_csvReader(csvReader) + except (ValueError, IOError, os.error), reason: + QMessageBox.critical(None, _("Unable to read file or no transaction found"), _("Electrum-IXC was unable to open your transaction file") + "\n" + str(reason)) + return + + def do_process_from_csv_text(self): + text = text_dialog(self, _('Input CSV'), _("Please enter a list of outputs.") + '\n' \ + + _("Format: address, amount. One output per line"), _("Load CSV")) + if not text: + return + f = StringIO.StringIO(text) + csvReader = csv.reader(f) + self.do_process_from_csvReader(csvReader) + + + + @protected + def export_privkeys_dialog(self, password): + if self.wallet.is_watching_only(): + self.show_message(_("This is a watching-only wallet")) + return + + d = QDialog(self) + d.setWindowTitle(_('Private keys')) + d.setMinimumSize(850, 300) + vbox = QVBoxLayout(d) + + msg = "%s\n%s\n%s" % (_("WARNING: ALL your private keys are secret."), + _("Exposing a single private key can compromise your entire wallet!"), + _("In particular, DO NOT use 'redeem private key' services proposed by third parties.")) + vbox.addWidget(QLabel(msg)) + + e = QTextEdit() + e.setReadOnly(True) + vbox.addWidget(e) + + defaultname = 'electrum-ixc-private-keys.csv' + select_msg = _('Select file to export your private keys to') + hbox, filename_e, csv_button = filename_field(self, self.config, defaultname, select_msg) + vbox.addLayout(hbox) + + h, b = ok_cancel_buttons2(d, _('Export')) + b.setEnabled(False) + vbox.addLayout(h) + + private_keys = {} + addresses = self.wallet.addresses(True) + done = False + def privkeys_thread(): + for addr in addresses: + time.sleep(0.1) + if done: + break + private_keys[addr] = "\n".join(self.wallet.get_private_key(addr, password)) + d.emit(SIGNAL('computing_privkeys')) + d.emit(SIGNAL('show_privkeys')) + + def show_privkeys(): + s = "\n".join( map( lambda x: x[0] + "\t"+ x[1], private_keys.items())) + e.setText(s) + b.setEnabled(True) + + d.connect(d, QtCore.SIGNAL('computing_privkeys'), lambda: e.setText("Please wait... %d/%d"%(len(private_keys),len(addresses)))) + d.connect(d, QtCore.SIGNAL('show_privkeys'), show_privkeys) + threading.Thread(target=privkeys_thread).start() + + if not d.exec_(): + done = True + return + + filename = filename_e.text() + if not filename: + return + + try: + self.do_export_privkeys(filename, private_keys, csv_button.isChecked()) + except (IOError, os.error), reason: + export_error_label = _("Electrum-IXC was unable to produce a private key-export.") + QMessageBox.critical(None, _("Unable to create csv"), export_error_label + "\n" + str(reason)) + + except Exception as e: + self.show_message(str(e)) + return + + self.show_message(_("Private keys exported.")) + + + def do_export_privkeys(self, fileName, pklist, is_csv): + with open(fileName, "w+") as f: + if is_csv: + transaction = csv.writer(f) + transaction.writerow(["address", "private_key"]) + for addr, pk in pklist.items(): + transaction.writerow(["%34s"%addr,pk]) + else: + import json + f.write(json.dumps(pklist, indent = 4)) + + + def do_import_labels(self): + labelsFile = self.getOpenFileName(_("Open labels file"), "*.dat") + if not labelsFile: return + try: + f = open(labelsFile, 'r') + data = f.read() + f.close() + for key, value in json.loads(data).items(): + self.wallet.set_label(key, value) + QMessageBox.information(None, _("Labels imported"), _("Your labels were imported from")+" '%s'" % str(labelsFile)) + except (IOError, os.error), reason: + QMessageBox.critical(None, _("Unable to import labels"), _("Electrum-IXC was unable to import your labels.")+"\n" + str(reason)) + + + def do_export_labels(self): + labels = self.wallet.labels + try: + fileName = self.getSaveFileName(_("Select file to save your labels"), 'electrum_ixc_labels.dat', "*.dat") + if fileName: + with open(fileName, 'w+') as f: + json.dump(labels, f) + QMessageBox.information(None, _("Labels exported"), _("Your labels where exported to")+" '%s'" % str(fileName)) + except (IOError, os.error), reason: + QMessageBox.critical(None, _("Unable to export labels"), _("Electrum-IXC was unable to export your labels.")+"\n" + str(reason)) + + + def export_history_dialog(self): + + d = QDialog(self) + d.setWindowTitle(_('Export History')) + d.setMinimumSize(400, 200) + vbox = QVBoxLayout(d) + + defaultname = os.path.expanduser('~/electrum-ixc-history.csv') + select_msg = _('Select file to export your wallet transactions to') + + hbox, filename_e, csv_button = filename_field(self, self.config, defaultname, select_msg) + vbox.addLayout(hbox) + + vbox.addStretch(1) + + h, b = ok_cancel_buttons2(d, _('Export')) + vbox.addLayout(h) + + run_hook('export_history_dialog', self,hbox) + self.update() + + if not d.exec_(): + return + + filename = filename_e.text() + if not filename: + return + + try: + self.do_export_history(self.wallet, filename, csv_button.isChecked()) + except (IOError, os.error), reason: + export_error_label = _("Electrum-IXC was unable to produce a transaction export.") + QMessageBox.critical(self, _("Unable to export history"), export_error_label + "\n" + str(reason)) + return + + QMessageBox.information(self,_("History exported"), _("Your wallet history has been successfully exported.")) + + + def do_export_history(self, wallet, fileName, is_csv): + history = wallet.get_tx_history() + lines = [] + for item in history: + tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item + if confirmations: + if timestamp is not None: + try: + time_string = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] + except [RuntimeError, TypeError, NameError] as reason: + time_string = "unknown" + pass + else: + time_string = "unknown" + else: + time_string = "pending" + + if value is not None: + value_string = format_satoshis(value, True) + else: + value_string = '--' + + if fee is not None: + fee_string = format_satoshis(fee, True) + else: + fee_string = '0' + + if tx_hash: + label, is_default_label = wallet.get_label(tx_hash) + label = label.encode('utf-8') + else: + label = "" + + balance_string = format_satoshis(balance, False) + if is_csv: + lines.append([tx_hash, label, confirmations, value_string, fee_string, balance_string, time_string]) + else: + lines.append({'txid':tx_hash, 'date':"%16s"%time_string, 'label':label, 'value':value_string}) + + with open(fileName, "w+") as f: + if is_csv: + transaction = csv.writer(f) + transaction.writerow(["transaction_hash","label", "confirmations", "value", "fee", "balance", "timestamp"]) + for line in lines: + transaction.writerow(line) + else: + import json + f.write(json.dumps(lines, indent = 4)) + + + def sweep_key_dialog(self): + d = QDialog(self) + d.setWindowTitle(_('Sweep private keys')) + d.setMinimumSize(600, 300) + + vbox = QVBoxLayout(d) + vbox.addWidget(QLabel(_("Enter private keys"))) + + keys_e = QTextEdit() + keys_e.setTabChangesFocus(True) + vbox.addWidget(keys_e) + + h, address_e = address_field(self.wallet.addresses(False)) + vbox.addLayout(h) + + vbox.addStretch(1) + hbox, button = ok_cancel_buttons2(d, _('Sweep')) + vbox.addLayout(hbox) + button.setEnabled(False) + + def get_address(): + addr = str(address_e.text()) + if bitcoin.is_address(addr): + return addr + + def get_pk(): + pk = str(keys_e.toPlainText()).strip() + if Wallet.is_private_key(pk): + return pk.split() + + f = lambda: button.setEnabled(get_address() is not None and get_pk() is not None) + keys_e.textChanged.connect(f) + address_e.textChanged.connect(f) + if not d.exec_(): + return + + fee = self.wallet.fee_per_kb + tx = Transaction.sweep(get_pk(), self.network, get_address(), fee) + self.show_transaction(tx) + + + @protected + def do_import_privkey(self, password): + if not self.wallet.has_imported_keys(): + r = QMessageBox.question(None, _('Warning'), ''+_('Warning') +':\n
'+ _('Imported keys are not recoverable from seed.') + ' ' \ + + _('If you ever need to restore your wallet from its seed, these keys will be lost.') + '

' \ + + _('Are you sure you understand what you are doing?'), 3, 4) + if r == 4: return + + text = text_dialog(self, _('Import private keys'), _("Enter private keys")+':', _("Import")) + if not text: return + + text = str(text).split() + badkeys = [] + addrlist = [] + for key in text: + try: + addr = self.wallet.import_key(key, password) + except Exception as e: + badkeys.append(key) + continue + if not addr: + badkeys.append(key) + else: + addrlist.append(addr) + if addrlist: + QMessageBox.information(self, _('Information'), _("The following addresses were added") + ':\n' + '\n'.join(addrlist)) + if badkeys: + QMessageBox.critical(self, _('Error'), _("The following inputs could not be imported") + ':\n'+ '\n'.join(badkeys)) + self.update_address_tab() + self.update_history_tab() + + + def settings_dialog(self): + self.need_restart = False + d = QDialog(self) + d.setWindowTitle(_('Electrum-IXC Settings')) + d.setModal(1) + vbox = QVBoxLayout() + grid = QGridLayout() + grid.setColumnStretch(0,1) + widgets = [] + + lang_label = QLabel(_('Language') + ':') + lang_help = HelpButton(_('Select which language is used in the GUI (after restart).')) + lang_combo = QComboBox() + from electrum_ixc.i18n import languages + lang_combo.addItems(languages.values()) + try: + index = languages.keys().index(self.config.get("language",'')) + except Exception: + index = 0 + lang_combo.setCurrentIndex(index) + if not self.config.is_modifiable('language'): + for w in [lang_combo, lang_label]: w.setEnabled(False) + def on_lang(x): + lang_request = languages.keys()[lang_combo.currentIndex()] + if lang_request != self.config.get('language'): + self.config.set_key("language", lang_request, True) + self.need_restart = True + lang_combo.currentIndexChanged.connect(on_lang) + widgets.append((lang_label, lang_combo, lang_help)) + + nz_label = QLabel(_('Zeros after decimal point') + ':') + nz_help = HelpButton(_('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')) + nz = QSpinBox() + nz.setMinimum(0) + nz.setMaximum(self.decimal_point) + nz.setValue(self.num_zeros) + if not self.config.is_modifiable('num_zeros'): + for w in [nz, nz_label]: w.setEnabled(False) + def on_nz(): + value = nz.value() + if self.num_zeros != value: + self.num_zeros = value + self.config.set_key('num_zeros', value, True) + self.update_history_tab() + self.update_address_tab() + nz.valueChanged.connect(on_nz) + widgets.append((nz_label, nz, nz_help)) + + fee_label = QLabel(_('Transaction fee per kb') + ':') + fee_help = HelpButton(_('Fee per kilobyte of transaction.') + '\n' \ + + _('Recommended value') + ': ' + self.format_amount(bitcoin.RECOMMENDED_FEE) + ' ' + self.base_unit()) + fee_e = BTCAmountEdit(self.get_decimal_point) + fee_e.setAmount(self.wallet.fee_per_kb) + if not self.config.is_modifiable('fee_per_kb'): + for w in [fee_e, fee_label]: w.setEnabled(False) + def on_fee(): + fee = fee_e.get_amount() + self.wallet.set_fee(fee) + fee_e.editingFinished.connect(on_fee) + widgets.append((fee_label, fee_e, fee_help)) + + units = ['IXC', 'mIXC', 'ibits'] + unit_label = QLabel(_('Base unit') + ':') + unit_combo = QComboBox() + unit_combo.addItems(units) + unit_combo.setCurrentIndex(units.index(self.base_unit())) + msg = _('Base unit of your wallet.')\ + + '\n1IXC=1000mIXC.\n' \ + + _(' These settings affects the fields in the Send tab')+' ' + unit_help = HelpButton(msg) + def on_unit(x): + unit_result = units[unit_combo.currentIndex()] + if self.base_unit() == unit_result: + return + if unit_result == 'IXC': + self.decimal_point = 8 + elif unit_result == 'mIXC': + self.decimal_point = 5 + elif unit_result == 'ibits': + self.decimal_point = 2 + else: + raise Exception('Unknown base unit') + self.config.set_key('decimal_point', self.decimal_point, True) + self.update_history_tab() + self.update_receive_tab() + self.update_address_tab() + self.update_invoices_tab() + fee_e.setAmount(self.wallet.fee_per_kb) + self.update_status() + unit_combo.currentIndexChanged.connect(on_unit) + widgets.append((unit_label, unit_combo, unit_help)) + + block_explorers = ['Blockchain.info', 'Blockr.io', 'Insight.is', "Blocktrail.com"] + block_ex_label = QLabel(_('Online Block Explorer') + ':') + block_ex_combo = QComboBox() + block_ex_combo.addItems(block_explorers) + block_ex_combo.setCurrentIndex(block_explorers.index(self.config.get('block_explorer', 'Blockchain.info'))) + block_ex_help = HelpButton(_('Choose which online block explorer to use for functions that open a web browser')) + def on_be(x): + be_result = block_explorers[block_ex_combo.currentIndex()] + self.config.set_key('block_explorer', be_result, True) + block_ex_combo.currentIndexChanged.connect(on_be) + widgets.append((block_ex_label, block_ex_combo, block_ex_help)) + + from electrum_ixc import qrscanner + system_cameras = qrscanner._find_system_cameras() + qr_combo = QComboBox() + qr_combo.addItem("Default","default") + for camera, device in system_cameras.items(): + qr_combo.addItem(camera, device) + #combo.addItem("Manually specify a device", config.get("video_device")) + index = qr_combo.findData(self.config.get("video_device")) + qr_combo.setCurrentIndex(index) + qr_label = QLabel(_('Video Device') + ':') + qr_combo.setEnabled(qrscanner.zbar is not None) + qr_help = HelpButton(_("Install the zbar package to enable this.\nOn linux, type: 'apt-get install python-zbar'")) + on_video_device = lambda x: self.config.set_key("video_device", str(qr_combo.itemData(x).toString()), True) + qr_combo.currentIndexChanged.connect(on_video_device) + widgets.append((qr_label, qr_combo, qr_help)) + + usechange_cb = QCheckBox(_('Use change addresses')) + usechange_cb.setChecked(self.wallet.use_change) + usechange_help = HelpButton(_('Using change addresses makes it more difficult for other people to track your transactions.')) + if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False) + def on_usechange(x): + usechange_result = x == Qt.Checked + if self.wallet.use_change != usechange_result: + self.wallet.use_change = usechange_result + self.wallet.storage.put('use_change', self.wallet.use_change) + usechange_cb.stateChanged.connect(on_usechange) + widgets.append((usechange_cb, None, usechange_help)) + + showtx_cb = QCheckBox(_('Show transaction before broadcast')) + showtx_cb.setChecked(self.config.get('show_before_broadcast', False)) + showtx_cb.stateChanged.connect(lambda x: self.config.set_key('show_before_broadcast', showtx_cb.isChecked())) + showtx_help = HelpButton(_('Display the details of your transactions before broadcasting it.')) + widgets.append((showtx_cb, None, showtx_help)) + + can_edit_fees_cb = QCheckBox(_('Set transaction fees manually')) + can_edit_fees_cb.setChecked(self.config.get('can_edit_fees', False)) + def on_editfees(x): + self.config.set_key('can_edit_fees', x == Qt.Checked) + self.update_fee_edit() + can_edit_fees_cb.stateChanged.connect(on_editfees) + can_edit_fees_help = HelpButton(_('This option lets you edit fees in the send tab.')) + widgets.append((can_edit_fees_cb, None, can_edit_fees_help)) + + for a,b,c in widgets: + i = grid.rowCount() + if b: + grid.addWidget(a, i, 0) + grid.addWidget(b, i, 1) + else: + grid.addWidget(a, i, 0, 1, 2) + grid.addWidget(c, i, 2) + + vbox.addLayout(grid) + vbox.addStretch(1) + vbox.addLayout(close_button(d)) + d.setLayout(vbox) + + # run the dialog + d.exec_() + + run_hook('close_settings_dialog') + if self.need_restart: + QMessageBox.warning(self, _('Success'), _('Please restart Electrum-IXC to activate the new GUI settings'), _('OK')) + + + + def run_network_dialog(self): + if not self.network: + QMessageBox.warning(self, _('Offline'), _('You are using Electrum-IXC in offline mode.\nRestart Electrum-IXC if you want to get connected.'), _('OK')) + return + NetworkDialog(self.wallet.network, self.config, self).do_exec() + + def closeEvent(self, event): + self.config.set_key("is_maximized", self.isMaximized()) + if not self.isMaximized(): + g = self.geometry() + self.config.set_key("winpos-qt", [g.left(),g.top(),g.width(),g.height()]) + self.save_column_widths() + self.config.set_key("console-history", self.console.history[-50:], True) + self.wallet.storage.put('accounts_expanded', self.accounts_expanded) + event.accept() + + + def plugins_dialog(self): + from electrum_ixc.plugins import plugins + + d = QDialog(self) + d.setWindowTitle(_('Electrum-IXC Plugins')) + d.setModal(1) + + vbox = QVBoxLayout(d) + + # plugins + scroll = QScrollArea() + scroll.setEnabled(True) + scroll.setWidgetResizable(True) + scroll.setMinimumSize(400,250) + vbox.addWidget(scroll) + + w = QWidget() + scroll.setWidget(w) + w.setMinimumHeight(len(plugins)*35) + + grid = QGridLayout() + grid.setColumnStretch(0,1) + w.setLayout(grid) + + def do_toggle(cb, p, w): + if p.is_enabled(): + if p.disable(): + p.close() + else: + if p.enable(): + p.load_wallet(self.wallet) + p.init_qt(self.gui_object) + r = p.is_enabled() + cb.setChecked(r) + if w: w.setEnabled(r) + + def mk_toggle(cb, p, w): + return lambda: do_toggle(cb,p,w) + + for i, p in enumerate(plugins): + try: + cb = QCheckBox(p.fullname()) + cb.setDisabled(not p.is_available()) + cb.setChecked(p.is_enabled()) + grid.addWidget(cb, i, 0) + if p.requires_settings(): + w = p.settings_widget(self) + w.setEnabled( p.is_enabled() ) + grid.addWidget(w, i, 1) + else: + w = None + cb.clicked.connect(mk_toggle(cb,p,w)) + grid.addWidget(HelpButton(p.description()), i, 2) + except Exception: + print_msg("Error: cannot display plugin", p) + traceback.print_exc(file=sys.stdout) + grid.setRowStretch(i+1,1) + vbox.addLayout(close_button(d)) + d.exec_() + + def show_account_details(self, k): + account = self.wallet.accounts[k] + + d = QDialog(self) + d.setWindowTitle(_('Account Details')) + d.setModal(1) + + vbox = QVBoxLayout(d) + name = self.wallet.get_account_name(k) + label = QLabel('Name: ' + name) + vbox.addWidget(label) + + vbox.addWidget(QLabel(_('Address type') + ': ' + account.get_type())) + + vbox.addWidget(QLabel(_('Derivation') + ': ' + k)) + + vbox.addWidget(QLabel(_('Master Public Key:'))) + + text = QTextEdit() + text.setReadOnly(True) + text.setMaximumHeight(170) + vbox.addWidget(text) + + mpk_text = '\n'.join( account.get_master_pubkeys() ) + text.setText(mpk_text) + + vbox.addLayout(close_button(d)) + d.exec_() diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py new file mode 100644 index 00000000..1b63297b --- /dev/null +++ b/gui/qt/network_dialog.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, time, datetime, re, threading +from electrum_ixc.i18n import _ +from electrum_ixc.util import print_error, print_msg +import os.path, json, ast, traceback + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from electrum_ixc import DEFAULT_SERVERS, DEFAULT_PORTS + +from util import * + +#protocol_names = ['TCP', 'HTTP', 'SSL', 'HTTPS'] +#protocol_letters = 'thsg' +protocol_names = ['TCP', 'SSL'] +protocol_letters = 'ts' + +class NetworkDialog(QDialog): + def __init__(self, network, config, parent): + + QDialog.__init__(self,parent) + self.setModal(1) + self.setWindowTitle(_('Network')) + self.setMinimumSize(375, 20) + + self.network = network + self.config = config + self.protocol = None + + self.servers = network.get_servers() + host, port, protocol, proxy_config, auto_connect = network.get_parameters() + if not proxy_config: + proxy_config = { "mode":"none", "host":"localhost", "port":"8080"} + + if parent: + n = len(network.get_interfaces()) + if n: + status = _("Blockchain") + ": " + "%d "%(network.get_local_height()) + _("blocks") + ".\n" + _("Getting block headers from %d nodes.")%n + else: + status = _("Not connected") + if network.is_connected(): + status += "\n" + _("Server") + ": %s"%(host) + else: + status += "\n" + _("Disconnected from server") + else: + status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.") + + vbox = QVBoxLayout() + vbox.setSpacing(30) + hbox = QHBoxLayout() + l = QLabel() + l.setPixmap(QPixmap(":icons/network.png")) + hbox.addStretch(10) + hbox.addWidget(l) + hbox.addWidget(QLabel(status)) + hbox.addStretch(50) + msg = _("Electrum-IXC sends your wallet addresses to a single server, in order to receive your transaction history.") + "\n\n" \ + + _("In addition, Electrum-IXC connects to several nodes in order to download block headers and find out the longest blockchain.") + " " \ + + _("This blockchain is used to verify the transactions sent by the address server.") + hbox.addWidget(HelpButton(msg)) + vbox.addLayout(hbox) + + # grid layout + grid = QGridLayout() + grid.setSpacing(8) + vbox.addLayout(grid) + + # protocol + self.server_protocol = QComboBox() + self.server_host = QLineEdit() + self.server_host.setFixedWidth(200) + self.server_port = QLineEdit() + self.server_port.setFixedWidth(60) + self.server_protocol.addItems(protocol_names) + self.server_protocol.connect(self.server_protocol, SIGNAL('currentIndexChanged(int)'), self.change_protocol) + + grid.addWidget(QLabel(_('Protocol') + ':'), 3, 0) + grid.addWidget(self.server_protocol, 3, 1) + + # server + grid.addWidget(QLabel(_('Server') + ':'), 0, 0) + + # auto connect + self.autocycle_cb = QCheckBox(_('Auto-connect')) + self.autocycle_cb.setChecked(auto_connect) + grid.addWidget(self.autocycle_cb, 0, 1) + if not self.config.is_modifiable('auto_cycle'): self.autocycle_cb.setEnabled(False) + msg = _("If auto-connect is enabled, Electrum-IXC will always use a server that is on the longest blockchain.") + " " \ + + _("If it is disabled, Electrum-IXC will warn you if your server is lagging.") + grid.addWidget(HelpButton(msg), 0, 4) + grid.addWidget(self.server_host, 0, 2, 1, 2) + grid.addWidget(self.server_port, 0, 3) + + label = _('Active Servers') if network.is_connected() else _('Default Servers') + self.servers_list_widget = QTreeWidget(parent) + self.servers_list_widget.setHeaderLabels( [ label, _('Limit') ] ) + self.servers_list_widget.setMaximumHeight(150) + self.servers_list_widget.setColumnWidth(0, 240) + + self.change_server(host, protocol) + self.set_protocol(protocol) + + self.servers_list_widget.connect(self.servers_list_widget, + SIGNAL('currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)'), + lambda x,y: self.server_changed(x)) + grid.addWidget(self.servers_list_widget, 1, 1, 1, 3) + + if not config.is_modifiable('server'): + for w in [self.server_host, self.server_port, self.server_protocol, self.servers_list_widget]: w.setEnabled(False) + + def enable_set_server(): + enabled = not self.autocycle_cb.isChecked() + self.server_host.setEnabled(enabled) + self.server_port.setEnabled(enabled) + self.servers_list_widget.setEnabled(enabled) + + self.autocycle_cb.clicked.connect(enable_set_server) + enable_set_server() + + # proxy setting + self.proxy_mode = QComboBox() + self.proxy_host = QLineEdit() + self.proxy_host.setFixedWidth(200) + self.proxy_port = QLineEdit() + self.proxy_port.setFixedWidth(60) + self.proxy_mode.addItems(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP']) + + def check_for_disable(index = False): + if self.proxy_mode.currentText() != 'NONE': + self.proxy_host.setEnabled(True) + self.proxy_port.setEnabled(True) + else: + self.proxy_host.setEnabled(False) + self.proxy_port.setEnabled(False) + + check_for_disable() + self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), check_for_disable) + + if not self.config.is_modifiable('proxy'): + for w in [self.proxy_host, self.proxy_port, self.proxy_mode]: w.setEnabled(False) + + self.proxy_mode.setCurrentIndex(self.proxy_mode.findText(str(proxy_config.get("mode").upper()))) + self.proxy_host.setText(proxy_config.get("host")) + self.proxy_port.setText(proxy_config.get("port")) + + grid.addWidget(QLabel(_('Proxy') + ':'), 4, 0) + grid.addWidget(self.proxy_mode, 4, 1) + grid.addWidget(self.proxy_host, 4, 2) + grid.addWidget(self.proxy_port, 4, 3) + + # buttons + vbox.addLayout(ok_cancel_buttons(self)) + self.setLayout(vbox) + + + def init_servers_list(self): + self.servers_list_widget.clear() + for _host, d in self.servers.items(): + if d.get(self.protocol): + pruning_level = d.get('pruning','') + self.servers_list_widget.addTopLevelItem(QTreeWidgetItem( [ _host, pruning_level ] )) + + + def set_protocol(self, protocol): + if protocol != self.protocol: + self.protocol = protocol + self.init_servers_list() + + def change_protocol(self, index): + p = protocol_letters[index] + host = unicode(self.server_host.text()) + pp = self.servers.get(host, DEFAULT_PORTS) + if p not in pp.keys(): + p = pp.keys()[0] + port = pp[p] + self.server_host.setText( host ) + self.server_port.setText( port ) + self.set_protocol(p) + + def server_changed(self, x): + if x: + self.change_server(str(x.text(0)), self.protocol) + + def change_server(self, host, protocol): + + pp = self.servers.get(host, DEFAULT_PORTS) + if protocol: + port = pp.get(protocol) + if not port: protocol = None + + if not protocol: + if 's' in pp.keys(): + protocol = 's' + port = pp.get(protocol) + else: + protocol = pp.keys()[0] + port = pp.get(protocol) + + self.server_host.setText( host ) + self.server_port.setText( port ) + self.server_protocol.setCurrentIndex(protocol_letters.index(protocol)) + + if not self.servers: return + for p in protocol_letters: + i = protocol_letters.index(p) + j = self.server_protocol.model().index(i,0) + #if p not in pp.keys(): # and self.interface.is_connected: + # self.server_protocol.model().setData(j, QVariant(0), Qt.UserRole-1) + #else: + # self.server_protocol.model().setData(j, QVariant(33), Qt.UserRole-1) + + + def do_exec(self): + + if not self.exec_(): + return + + host = str( self.server_host.text() ) + port = str( self.server_port.text() ) + protocol = protocol_letters[self.server_protocol.currentIndex()] + + if self.proxy_mode.currentText() != 'NONE': + proxy = { 'mode':str(self.proxy_mode.currentText()).lower(), + 'host':str(self.proxy_host.text()), + 'port':str(self.proxy_port.text()) } + else: + proxy = None + + auto_connect = self.autocycle_cb.isChecked() + + self.network.set_parameters(host, port, protocol, proxy, auto_connect) + return True diff --git a/gui/qt/password_dialog.py b/gui/qt/password_dialog.py new file mode 100644 index 00000000..7164b5ab --- /dev/null +++ b/gui/qt/password_dialog.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2013 ecdsa@github +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from electrum_ixc.i18n import _ +from util import * +import re +import math + + + +def make_password_dialog(self, wallet, msg, new_pass=True): + + self.pw = QLineEdit() + self.pw.setEchoMode(2) + self.new_pw = QLineEdit() + self.new_pw.setEchoMode(2) + self.conf_pw = QLineEdit() + self.conf_pw.setEchoMode(2) + + vbox = QVBoxLayout() + label = QLabel(msg) + label.setWordWrap(True) + + grid = QGridLayout() + grid.setSpacing(8) + grid.setColumnMinimumWidth(0, 70) + grid.setColumnStretch(1,1) + + logo = QLabel() + lockfile = ":icons/lock.png" if wallet and wallet.use_encryption else ":icons/unlock.png" + logo.setPixmap(QPixmap(lockfile).scaledToWidth(36)) + logo.setAlignment(Qt.AlignCenter) + + grid.addWidget(logo, 0, 0) + grid.addWidget(label, 0, 1, 1, 2) + vbox.addLayout(grid) + + grid = QGridLayout() + grid.setSpacing(8) + grid.setColumnMinimumWidth(0, 250) + grid.setColumnStretch(1,1) + + if wallet and wallet.use_encryption: + grid.addWidget(QLabel(_('Password')), 0, 0) + grid.addWidget(self.pw, 0, 1) + + grid.addWidget(QLabel(_('New Password') if new_pass else _('Password')), 1, 0) + grid.addWidget(self.new_pw, 1, 1) + + grid.addWidget(QLabel(_('Confirm Password')), 2, 0) + grid.addWidget(self.conf_pw, 2, 1) + vbox.addLayout(grid) + + #Password Strength Label + self.pw_strength = QLabel() + grid.addWidget(self.pw_strength, 3, 0, 1, 2) + self.new_pw.textChanged.connect(lambda: update_password_strength(self.pw_strength, self.new_pw.text())) + + vbox.addStretch(1) + vbox.addLayout(ok_cancel_buttons(self)) + return vbox + + +def run_password_dialog(self, wallet, parent): + + if wallet and wallet.is_watching_only(): + QMessageBox.information(parent, _('Error'), _('This is a watching-only wallet'), _('OK')) + return False, None, None + + if not self.exec_(): + return False, None, None + + password = unicode(self.pw.text()) if wallet and wallet.use_encryption else None + new_password = unicode(self.new_pw.text()) + new_password2 = unicode(self.conf_pw.text()) + + if new_password != new_password2: + QMessageBox.warning(parent, _('Error'), _('Passwords do not match'), _('OK')) + # Retry + return run_password_dialog(self, wallet, parent) + + if not new_password: + new_password = None + + return True, password, new_password + +def check_password_strength(password): + + ''' + Check the strength of the password entered by the user and return back the same + :param password: password entered by user in New Password + :return: password strength Weak or Medium or Strong + ''' + password = unicode(password) + n = math.log(len(set(password))) + num = re.search("[0-9]", password) is not None and re.match("^[0-9]*$", password) is None + caps = password != password.upper() and password != password.lower() + extra = re.match("^[a-zA-Z0-9]*$", password) is None + score = len(password)*( n + caps + num + extra)/20 + password_strength = {0:"Weak",1:"Medium",2:"Strong",3:"Very Strong"} + return password_strength[min(3, int(score))] + + +def update_password_strength(pw_strength_label,password): + + ''' + call the function check_password_strength and update the label pw_strength interactively as the user is typing the password + :param pw_strength_label: the label pw_strength + :param password: password entered in New Password text box + :return: None + ''' + if password: + colors = {"Weak":"Red","Medium":"Blue","Strong":"Green", "Very Strong":"Green"} + strength = check_password_strength(password) + label = _("Password Strength")+ ": "+"" + strength + "" + else: + label = "" + pw_strength_label.setText(label) + + + +class PasswordDialog(QDialog): + + def __init__(self, wallet, parent): + QDialog.__init__(self, parent) + self.setModal(1) + self.wallet = wallet + self.parent = parent + self.setWindowTitle(_("Set Password")) + msg = (_('Your wallet is encrypted. Use this dialog to change your password.') + ' '\ + +_('To disable wallet encryption, enter an empty new password.')) \ + if wallet.use_encryption else _('Your wallet keys are not encrypted') + self.setLayout(make_password_dialog(self, wallet, msg)) + + + def run(self): + ok, password, new_password = run_password_dialog(self, self.wallet, self.parent) + if not ok: + return + + try: + self.wallet.check_password(password) + except Exception: + QMessageBox.warning(self.parent, _('Error'), _('Incorrect Password'), _('OK')) + return False, None, None + + try: + self.wallet.update_password(password, new_password) + except: + import traceback, sys + traceback.print_exc(file=sys.stdout) + QMessageBox.warning(self.parent, _('Error'), _('Failed to update password'), _('OK')) + return + + if new_password: + QMessageBox.information(self.parent, _('Success'), _('Password was updated successfully'), _('OK')) + else: + QMessageBox.information(self.parent, _('Success'), _('This wallet is not encrypted'), _('OK')) diff --git a/gui/qt/paytoedit.py b/gui/qt/paytoedit.py new file mode 100644 index 00000000..d0e0fc41 --- /dev/null +++ b/gui/qt/paytoedit.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from qrtextedit import ScanQRTextEdit + +import re +from decimal import Decimal +from electrum_ixc import bitcoin + +RE_ADDRESS = '[1-9A-HJ-NP-Za-km-z]{26,}' +RE_ALIAS = '(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>' + +frozen_style = "QWidget { background-color:none; border:none;}" +normal_style = "QPlainTextEdit { }" + +class PayToEdit(ScanQRTextEdit): + def __init__(self, win): + super(PayToEdit,self).__init__(win=win) + self.amount_edit = win.amount_e + self.document().contentsChanged.connect(self.update_size) + self.heightMin = 0 + self.heightMax = 150 + self.c = None + self.textChanged.connect(self.check_text) + self.outputs = [] + self.errors = [] + self.is_pr = False + self.scan_f = self.win.pay_from_URI + self.update_size() + self.payto_address = None + + def lock_amount(self): + self.amount_edit.setFrozen(True) + + def unlock_amount(self): + self.amount_edit.setFrozen(False) + + def setFrozen(self, b): + self.setReadOnly(b) + self.setStyleSheet(frozen_style if b else normal_style) + self.button.setHidden(b) + + def setGreen(self): + self.is_pr = True + self.setStyleSheet("QWidget { background-color:#80ff80;}") + + def setExpired(self): + self.is_pr = True + self.setStyleSheet("QWidget { background-color:#ffcccc;}") + + def parse_address_and_amount(self, line): + m = re.match('^OP_RETURN\s+"(.+)"$', line.strip()) + if m: + type = 'op_return' + address = m.group(1) + amount = 0 + else: + x, y = line.split(',') + type = 'address' + address = self.parse_address(x) + amount = self.parse_amount(y) + return type, address, amount + + + def parse_amount(self, x): + p = pow(10, self.amount_edit.decimal_point()) + return int( p * Decimal(x.strip())) + + + def parse_address(self, line): + r = line.strip() + m = re.match('^'+RE_ALIAS+'$', r) + address = m.group(2) if m else r + assert bitcoin.is_address(address) + return address + + + def check_text(self): + self.errors = [] + if self.is_pr: + return + + # filter out empty lines + lines = filter( lambda x: x, self.lines()) + outputs = [] + total = 0 + + self.payto_address = None + + if len(lines) == 1: + try: + self.payto_address = self.parse_address(lines[0]) + except: + pass + + if self.payto_address: + self.unlock_amount() + return + + for i, line in enumerate(lines): + try: + type, to_address, amount = self.parse_address_and_amount(line) + except: + self.errors.append((i, line.strip())) + continue + + outputs.append((type, to_address, amount)) + total += amount + + self.outputs = outputs + self.payto_address = None + + if outputs: + self.amount_edit.setAmount(total) + else: + self.amount_edit.setText("") + + self.amount_edit.textEdited.emit("") + + if total or len(lines)>1: + self.lock_amount() + else: + self.unlock_amount() + + + def get_errors(self): + return self.errors + + def get_outputs(self): + if self.payto_address: + try: + amount = self.amount_edit.get_amount() + except: + amount = None + self.outputs = [('address', self.payto_address, amount)] + + return self.outputs[:] + + + def lines(self): + return str(self.toPlainText()).split('\n') + + + def is_multiline(self): + return len(self.lines()) > 1 + + + def update_size(self): + docHeight = self.document().size().height() + h = docHeight*17 + 11 + if self.heightMin <= h <= self.heightMax: + self.setMinimumHeight(h) + self.setMaximumHeight(h) + self.verticalScrollBar().hide() + + + def setCompleter(self, completer): + self.c = completer + self.c.setWidget(self) + self.c.setCompletionMode(QCompleter.PopupCompletion) + self.c.activated.connect(self.insertCompletion) + + + def insertCompletion(self, completion): + if self.c.widget() != self: + return + tc = self.textCursor() + extra = completion.length() - self.c.completionPrefix().length() + tc.movePosition(QTextCursor.Left) + tc.movePosition(QTextCursor.EndOfWord) + tc.insertText(completion.right(extra)) + self.setTextCursor(tc) + + + def textUnderCursor(self): + tc = self.textCursor() + tc.select(QTextCursor.WordUnderCursor) + return tc.selectedText() + + + def keyPressEvent(self, e): + if self.isReadOnly(): + return + + if self.c.popup().isVisible(): + if e.key() in [Qt.Key_Enter, Qt.Key_Return]: + e.ignore() + return + + if e.key() in [Qt.Key_Tab]: + e.ignore() + return + + if e.key() in [Qt.Key_Down, Qt.Key_Up] and not self.is_multiline(): + e.ignore() + return + + QPlainTextEdit.keyPressEvent(self, e) + + ctrlOrShift = e.modifiers() and (Qt.ControlModifier or Qt.ShiftModifier) + if self.c is None or (ctrlOrShift and e.text().isEmpty()): + return + + eow = QString("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=") + hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift; + completionPrefix = self.textUnderCursor() + + if hasModifier or e.text().isEmpty() or completionPrefix.length() < 1 or eow.contains(e.text().right(1)): + self.c.popup().hide() + return + + if completionPrefix != self.c.completionPrefix(): + self.c.setCompletionPrefix(completionPrefix); + self.c.popup().setCurrentIndex(self.c.completionModel().index(0, 0)) + + cr = self.cursorRect() + cr.setWidth(self.c.popup().sizeHintForColumn(0) + self.c.popup().verticalScrollBar().sizeHint().width()) + self.c.complete(cr) + + + def qr_input(self): + data = super(PayToEdit,self).qr_input() + if data.startswith("ixcoin:"): + self.scan_f(data) + # TODO: update fee diff --git a/gui/qt/qrcodewidget.py b/gui/qt/qrcodewidget.py new file mode 100644 index 00000000..84573e31 --- /dev/null +++ b/gui/qt/qrcodewidget.py @@ -0,0 +1,134 @@ +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore +import PyQt4.QtGui as QtGui + +import os +import qrcode + +import electrum_ixc +from electrum_ixc import bmp +from electrum_ixc.i18n import _ + + +class QRCodeWidget(QWidget): + + def __init__(self, data = None, fixedSize=False): + QWidget.__init__(self) + self.data = None + self.qr = None + self.fixedSize=fixedSize + if fixedSize: + self.setFixedSize(fixedSize, fixedSize) + self.setData(data) + + + def setData(self, data): + if self.data != data: + self.data = data + if self.data: + self.qr = qrcode.QRCode() + self.qr.add_data(self.data) + if not self.fixedSize: + k = len(self.qr.get_matrix()) + self.setMinimumSize(k*5,k*5) + else: + self.qr = None + + self.update() + + + def paintEvent(self, e): + if not self.data: + return + + black = QColor(0, 0, 0, 255) + white = QColor(255, 255, 255, 255) + + if not self.qr: + qp = QtGui.QPainter() + qp.begin(self) + qp.setBrush(white) + qp.setPen(white) + r = qp.viewport() + qp.drawRect(0, 0, r.width(), r.height()) + qp.end() + return + + matrix = self.qr.get_matrix() + k = len(matrix) + qp = QtGui.QPainter() + qp.begin(self) + r = qp.viewport() + + margin = 10 + framesize = min(r.width(), r.height()) + boxsize = int( (framesize - 2*margin)/k ) + size = k*boxsize + left = (r.width() - size)/2 + top = (r.height() - size)/2 + + # Make a white margin around the QR in case of dark theme use + qp.setBrush(white) + qp.setPen(white) + qp.drawRect(left-margin, top-margin, size+(margin*2), size+(margin*2)) + + for r in range(k): + for c in range(k): + if matrix[r][c]: + qp.setBrush(black) + qp.setPen(black) + else: + qp.setBrush(white) + qp.setPen(white) + qp.drawRect(left+c*boxsize, top+r*boxsize, boxsize, boxsize) + qp.end() + + + +class QRDialog(QDialog): + + def __init__(self, data, parent=None, title = "", show_text=False): + QDialog.__init__(self, parent) + + d = self + d.setWindowTitle(title) + vbox = QVBoxLayout() + qrw = QRCodeWidget(data) + vbox.addWidget(qrw, 1) + if show_text: + text = QTextEdit() + text.setText(data) + text.setReadOnly(True) + vbox.addWidget(text) + hbox = QHBoxLayout() + hbox.addStretch(1) + + config = electrum.get_config() + if config: + filename = os.path.join(config.path, "qrcode.bmp") + + def print_qr(): + bmp.save_qrcode(qrw.qr, filename) + QMessageBox.information(None, _('Message'), _("QR code saved to file") + " " + filename, _('OK')) + + def copy_to_clipboard(): + bmp.save_qrcode(qrw.qr, filename) + QApplication.clipboard().setImage(QImage(filename)) + QMessageBox.information(None, _('Message'), _("QR code saved to clipboard"), _('OK')) + + b = QPushButton(_("Copy")) + hbox.addWidget(b) + b.clicked.connect(copy_to_clipboard) + + b = QPushButton(_("Save")) + hbox.addWidget(b) + b.clicked.connect(print_qr) + + b = QPushButton(_("Close")) + hbox.addWidget(b) + b.clicked.connect(d.accept) + b.setDefault(True) + + vbox.addLayout(hbox) + d.setLayout(vbox) diff --git a/gui/qt/qrtextedit.py b/gui/qt/qrtextedit.py new file mode 100644 index 00000000..48155253 --- /dev/null +++ b/gui/qt/qrtextedit.py @@ -0,0 +1,69 @@ +from electrum_ixc.i18n import _ +from PyQt4.QtGui import * +from PyQt4.QtCore import * + +class QRTextEdit(QPlainTextEdit): + """Abstract class for QR-code related TextEdits. Do not use directly.""" + def __init__(self, text=None): + super(QRTextEdit, self).__init__(text) + self.button = QToolButton(self) + self.button.setIcon(QIcon(":icons/qrcode.png")) + self.button.setStyleSheet("QToolButton { border: none; padding: 0px; }") + self.button.setVisible(True) + self.setText = self.setPlainText + + def resizeEvent(self, e): + o = QPlainTextEdit.resizeEvent(self, e) + sz = self.button.sizeHint() + frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth) + self.button.move(self.rect().right() - frameWidth - sz.width(), + (self.rect().bottom() - frameWidth - sz.height())) + return o + +class ShowQRTextEdit(QRTextEdit): + def __init__(self, text=None): + super(ShowQRTextEdit, self).__init__(text) + self.setReadOnly(1) + self.button.clicked.connect(self.qr_show) + + def qr_show(self): + from qrcodewidget import QRDialog + try: + s = str(self.toPlainText()) + except: + s = unicode(self.toPlainText()) + QRDialog(s).exec_() + + def contextMenuEvent(self, e): + m = self.createStandardContextMenu() + m.addAction(_("Show as QR code"), self.qr_show) + m.exec_(e.globalPos()) + + +class ScanQRTextEdit(QRTextEdit): + def __init__(self, win, text=""): + super(ScanQRTextEdit,self).__init__(text) + self.setReadOnly(0) + self.win = win + assert win, "You must pass a window with access to the config to ScanQRTextEdit constructor." + if win: + assert hasattr(win,"config"), "You must pass a window with access to the config to ScanQRTextEdit constructor." + self.button.clicked.connect(self.qr_input) + + + def qr_input(self): + from electrum_ixc import qrscanner + try: + data = qrscanner.scan_qr(self.win.config) + except BaseException, e: + QMessageBox.warning(self, _('Error'), _(e), _('OK')) + return "" + if type(data) != str: + return + self.setText(data) + return data + + def contextMenuEvent(self, e): + m = self.createStandardContextMenu() + m.addAction(_("Read QR code"), self.qr_input) + m.exec_(e.globalPos()) diff --git a/gui/qt/qrwindow.py b/gui/qt/qrwindow.py new file mode 100644 index 00000000..dffe2611 --- /dev/null +++ b/gui/qt/qrwindow.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2014 Thomas Voegtlin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import re +import platform +from decimal import Decimal +from urllib import quote + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore +import PyQt4.QtGui as QtGui + +from electrum_ixc_gui.qt.qrcodewidget import QRCodeWidget +from electrum_ixc.i18n import _ + +if platform.system() == 'Windows': + MONOSPACE_FONT = 'Lucida Console' +elif platform.system() == 'Darwin': + MONOSPACE_FONT = 'Monaco' +else: + MONOSPACE_FONT = 'monospace' + +column_index = 4 + +class QR_Window(QWidget): + + def __init__(self, win): + QWidget.__init__(self) + self.win = win + self.setWindowTitle('Electrum-IXC - '+_('Invoice')) + self.setMinimumSize(800, 250) + self.address = '' + self.label = '' + self.amount = 0 + self.setFocusPolicy(QtCore.Qt.NoFocus) + + main_box = QHBoxLayout() + + self.qrw = QRCodeWidget() + main_box.addWidget(self.qrw, 1) + + vbox = QVBoxLayout() + main_box.addLayout(vbox) + + self.address_label = QLabel("") + #self.address_label.setFont(QFont(MONOSPACE_FONT)) + vbox.addWidget(self.address_label) + + self.label_label = QLabel("") + vbox.addWidget(self.label_label) + + self.amount_label = QLabel("") + vbox.addWidget(self.amount_label) + + vbox.addStretch(1) + self.setLayout(main_box) + + + def set_content(self, address, amount, message, url): + address_text = "%s" % address if address else "" + self.address_label.setText(address_text) + if amount: + amount = self.win.format_amount(amount) + amount_text = "%s %s " % (amount, self.win.base_unit()) + else: + amount_text = '' + self.amount_label.setText(amount_text) + label_text = "%s" % message if message else "" + self.label_label.setText(label_text) + self.qrw.setData(url) diff --git a/gui/qt/receiving_widget.py b/gui/qt/receiving_widget.py new file mode 100644 index 00000000..60334431 --- /dev/null +++ b/gui/qt/receiving_widget.py @@ -0,0 +1,77 @@ +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from electrum_ixc.i18n import _ + +class ReceivingWidget(QTreeWidget): + + def toggle_used(self): + if self.hide_used: + self.hide_used = False + self.setColumnHidden(2, False) + else: + self.hide_used = True + self.setColumnHidden(2, True) + self.update_list() + + def edit_label(self, item, column): + if column == 1 and item.isSelected(): + self.editing = True + item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + self.editItem(item, column) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled) + self.editing = False + + def update_label(self, item, column): + if self.editing: + return + else: + address = str(item.text(0)) + label = unicode( item.text(1) ) + self.owner.actuator.g.wallet.set_label(address, label) + + def copy_address(self): + address = self.currentItem().text(0) + qApp.clipboard().setText(address) + + + def update_list(self): + return + self.clear() + addresses = self.owner.actuator.g.wallet.addresses(False) + for address in addresses: + history = self.owner.actuator.g.wallet.history.get(address,[]) + + used = "No" + # It appears that at this moment history can either be an array with tx and block height + # Or just a tx that's why this ugly code duplication is in, will fix + if len(history) == 1: + # This means pruned data. If that's the case the address has to been used at one point + if history[0] == "*": + used = "Yes" + else: + for tx_hash in history: + tx = self.owner.actuator.g.wallet.transactions.get(tx_hash) + if tx: + used = "Yes" + else: + for tx_hash, height in history: + tx = self.owner.actuator.g.wallet.transactions.get(tx_hash) + if tx: + used = "Yes" + + if(self.hide_used == True and used == "No") or self.hide_used == False: + label = self.owner.actuator.g.wallet.labels.get(address,'') + item = QTreeWidgetItem([address, label, used]) + self.insertTopLevelItem(0, item) + + def __init__(self, owner=None): + self.owner = owner + self.editing = False + + QTreeWidget.__init__(self, owner) + self.setColumnCount(3) + self.setHeaderLabels([_("Address"), _("Label"), _("Used")]) + self.setIndentation(0) + + self.hide_used = True + self.setColumnHidden(2, True) diff --git a/gui/qt/seed_dialog.py b/gui/qt/seed_dialog.py new file mode 100644 index 00000000..0f1ea26d --- /dev/null +++ b/gui/qt/seed_dialog.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2013 ecdsa@github +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore +from electrum_ixc.i18n import _ +from electrum_ixc import mnemonic +from qrcodewidget import QRCodeWidget, QRDialog +from util import close_button +from qrtextedit import ShowQRTextEdit, ScanQRTextEdit + +class SeedDialog(QDialog): + def __init__(self, parent, seed, imported_keys): + QDialog.__init__(self, parent) + self.setModal(1) + self.setMinimumWidth(400) + self.setWindowTitle('Electrum-IXC' + ' - ' + _('Seed')) + vbox = show_seed_box(seed) + if imported_keys: + vbox.addWidget(QLabel(""+_("WARNING")+": " + _("Your wallet contains imported keys. These keys cannot be recovered from seed.") + "

")) + vbox.addLayout(close_button(self)) + self.setLayout(vbox) + + +def icon_filename(sid): + if sid == 'cold': + return ":icons/cold_seed.png" + elif sid == 'hot': + return ":icons/hot_seed.png" + else: + return ":icons/seed.png" + + + + +def show_seed_box(seed, sid=None): + + save_msg = _("Please save these %d words on paper (order is important).")%len(seed.split()) + " " + qr_msg = _("Your seed is also displayed as QR code, in case you want to transfer it to a mobile phone.") + "

" + warning_msg = ""+_("WARNING")+": " + _("Never disclose your seed. Never type it on a website.") + "

" + + if sid is None: + msg = _("Your wallet generation seed is") + msg2 = save_msg + " " \ + + _("This seed will allow you to recover your wallet in case of computer failure.") + "
" \ + + warning_msg + + elif sid == 'cold': + msg = _("Your cold storage seed is") + msg2 = save_msg + " " \ + + _("This seed will be permanently deleted from your wallet file. Make sure you have saved it before you press 'next'") + " " \ + + elif sid == 'hot': + msg = _("Your hot seed is") + msg2 = save_msg + " " \ + + _("If you ever need to recover your wallet from seed, you will need both this seed and your cold seed.") + " " \ + + label1 = QLabel(msg+ ":") + seed_text = ShowQRTextEdit(text=seed) + seed_text.setMaximumHeight(130) + + label2 = QLabel(msg2) + label2.setWordWrap(True) + + logo = QLabel() + logo.setPixmap(QPixmap(icon_filename(sid)).scaledToWidth(56)) + logo.setMaximumWidth(60) + + grid = QGridLayout() + grid.addWidget(logo, 0, 0) + grid.addWidget(label1, 0, 1) + grid.addWidget(seed_text, 1, 0, 1, 2) + vbox = QVBoxLayout() + vbox.addLayout(grid) + vbox.addWidget(label2) + vbox.addStretch(1) + + return vbox + + +def enter_seed_box(msg, window, sid=None): + vbox = QVBoxLayout() + logo = QLabel() + logo.setPixmap(QPixmap(icon_filename(sid)).scaledToWidth(56)) + logo.setMaximumWidth(60) + + label = QLabel(msg) + label.setWordWrap(True) + + seed_e = ScanQRTextEdit(win=window) + seed_e.setMaximumHeight(100) + seed_e.setTabChangesFocus(True) + + vbox.addWidget(label) + + grid = QGridLayout() + grid.addWidget(logo, 0, 0) + grid.addWidget(seed_e, 0, 1) + + vbox.addLayout(grid) + return vbox, seed_e diff --git a/gui/qt/transaction_dialog.py b/gui/qt/transaction_dialog.py new file mode 100644 index 00000000..4a0e3bbf --- /dev/null +++ b/gui/qt/transaction_dialog.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, time, datetime, re, threading +from electrum_ixc.i18n import _, set_language +from electrum_ixc.util import print_error, print_msg +import os.path, json, ast, traceback +import shutil +import StringIO + + +try: + import PyQt4 +except Exception: + sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'") + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore + +from electrum_ixc import transaction +from electrum_ixc.plugins import run_hook + +from util import MyTreeWidget +from util import MONOSPACE_FONT + +class TxDialog(QDialog): + + def __init__(self, tx, parent): + self.tx = tx + tx_dict = tx.as_dict() + self.parent = parent + self.wallet = parent.wallet + + QDialog.__init__(self) + self.setMinimumWidth(600) + self.setWindowTitle(_("Transaction")) + self.setModal(1) + + vbox = QVBoxLayout() + self.setLayout(vbox) + + vbox.addWidget(QLabel(_("Transaction ID:"))) + self.tx_hash_e = QLineEdit() + self.tx_hash_e.setReadOnly(True) + vbox.addWidget(self.tx_hash_e) + self.status_label = QLabel() + vbox.addWidget(self.status_label) + + self.date_label = QLabel() + vbox.addWidget(self.date_label) + self.amount_label = QLabel() + vbox.addWidget(self.amount_label) + self.fee_label = QLabel() + vbox.addWidget(self.fee_label) + + self.add_io(vbox) + + vbox.addStretch(1) + + self.buttons = buttons = QHBoxLayout() + vbox.addLayout( buttons ) + + buttons.addStretch(1) + + self.sign_button = b = QPushButton(_("Sign")) + b.clicked.connect(self.sign) + buttons.addWidget(b) + + self.broadcast_button = b = QPushButton(_("Broadcast")) + b.clicked.connect(lambda: self.parent.broadcast_transaction(self.tx)) + + b.hide() + buttons.addWidget(b) + + self.save_button = b = QPushButton(_("Save")) + b.clicked.connect(self.save) + buttons.addWidget(b) + + cancelButton = QPushButton(_("Close")) + cancelButton.clicked.connect(lambda: self.done(0)) + buttons.addWidget(cancelButton) + cancelButton.setDefault(True) + + b = QPushButton() + b.setIcon(QIcon(":icons/qrcode.png")) + b.clicked.connect(self.show_qr) + buttons.insertWidget(1,b) + + run_hook('transaction_dialog', self) + + self.update() + + + def show_qr(self): + text = self.tx.raw.decode('hex') + try: + self.parent.show_qrcode(text, 'Transaction') + except Exception as e: + self.show_message(str(e)) + + + def sign(self): + self.parent.sign_raw_transaction(self.tx) + self.update() + + + def save(self): + name = 'signed_%s.txn' % (self.tx.hash()[0:8]) if self.tx.is_complete() else 'unsigned.txn' + fileName = self.parent.getSaveFileName(_("Select where to save your signed transaction"), name, "*.txn") + if fileName: + with open(fileName, "w+") as f: + f.write(json.dumps(self.tx.as_dict(),indent=4) + '\n') + self.show_message(_("Transaction saved successfully")) + + + + def update(self): + + is_relevant, is_mine, v, fee = self.wallet.get_tx_value(self.tx) + if self.wallet.can_sign(self.tx): + self.sign_button.show() + else: + self.sign_button.hide() + + if self.tx.is_complete(): + status = _("Signed") + tx_hash = self.tx.hash() + + if tx_hash in self.wallet.transactions.keys(): + conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash) + if timestamp: + time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] + else: + time_str = 'pending' + status = _("%d confirmations")%conf + self.broadcast_button.hide() + else: + time_str = None + conf = 0 + self.broadcast_button.show() + else: + s, r = self.tx.signature_count() + status = _("Unsigned") if s == 0 else _('Partially signed (%d/%d)'%(s,r)) + time_str = None + self.broadcast_button.hide() + tx_hash = 'unknown' + + self.tx_hash_e.setText(tx_hash) + self.status_label.setText(_('Status:') + ' ' + status) + + if time_str is not None: + self.date_label.setText(_("Date: %s")%time_str) + self.date_label.show() + else: + self.date_label.hide() + + # if we are not synchronized, we cannot tell + if self.parent.network is None or not self.parent.network.is_running() or not self.parent.network.is_connected(): + return + if not self.wallet.up_to_date: + return + + if is_relevant: + if is_mine: + if fee is not None: + self.amount_label.setText(_("Amount sent:")+' %s'% self.parent.format_amount(v-fee) + ' ' + self.parent.base_unit()) + self.fee_label.setText(_("Transaction fee")+': %s'% self.parent.format_amount(fee) + ' ' + self.parent.base_unit()) + else: + self.amount_label.setText(_("Amount sent:")+' %s'% self.parent.format_amount(v) + ' ' + self.parent.base_unit()) + self.fee_label.setText(_("Transaction fee")+': '+ _("unknown")) + else: + self.amount_label.setText(_("Amount received:")+' %s'% self.parent.format_amount(v) + ' ' + self.parent.base_unit()) + else: + self.amount_label.setText(_("Transaction unrelated to your wallet")) + + run_hook('transaction_dialog_update', self) + + + + def add_io(self, vbox): + + if self.tx.locktime > 0: + vbox.addWidget(QLabel("LockTime: %d\n" % self.tx.locktime)) + + vbox.addWidget(QLabel(_("Inputs"))) + def format_input(x): + if x.get('is_coinbase'): + return 'coinbase' + else: + _hash = x.get('prevout_hash') + return _hash[0:8] + '...' + _hash[-8:] + ":%d"%x.get('prevout_n') + u'\t' + "%s"%x.get('address') + lines = map(format_input, self.tx.inputs ) + i_text = QTextEdit() + i_text.setFont(QFont(MONOSPACE_FONT)) + i_text.setText('\n'.join(lines)) + i_text.setReadOnly(True) + i_text.setMaximumHeight(100) + vbox.addWidget(i_text) + + vbox.addWidget(QLabel(_("Outputs"))) + lines = map(lambda x: x[0] + u'\t\t' + self.parent.format_amount(x[1]) if x[1] else x[0], self.tx.get_outputs()) + o_text = QTextEdit() + o_text.setFont(QFont(MONOSPACE_FONT)) + o_text.setText('\n'.join(lines)) + o_text.setReadOnly(True) + o_text.setMaximumHeight(100) + vbox.addWidget(o_text) + + + + def show_message(self, msg): + QMessageBox.information(self, _('Message'), msg, _('OK')) diff --git a/gui/qt/util.py b/gui/qt/util.py new file mode 100644 index 00000000..cb4e2b8e --- /dev/null +++ b/gui/qt/util.py @@ -0,0 +1,244 @@ +from electrum_ixc.i18n import _ +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import os.path +import time +import traceback +import sys +import threading +import platform + +if platform.system() == 'Windows': + MONOSPACE_FONT = 'Lucida Console' +elif platform.system() == 'Darwin': + MONOSPACE_FONT = 'Monaco' +else: + MONOSPACE_FONT = 'monospace' + + +class WaitingDialog(QThread): + def __init__(self, parent, message, run_task, on_success=None, on_complete=None): + QThread.__init__(self) + self.parent = parent + self.d = QDialog(parent) + self.d.setWindowTitle('Please wait') + l = QLabel(message) + vbox = QVBoxLayout(self.d) + vbox.addWidget(l) + self.run_task = run_task + self.on_success = on_success + self.on_complete = on_complete + self.d.connect(self.d, SIGNAL('done'), self.close) + self.d.show() + + def run(self): + self.error = None + try: + self.result = self.run_task() + except BaseException as e: + traceback.print_exc(file=sys.stdout) + self.error = str(e) + self.d.emit(SIGNAL('done')) + + def close(self): + self.d.accept() + if self.error: + QMessageBox.warning(self.parent, _('Error'), self.error, _('OK')) + else: + if self.on_success: + if type(self.result) is not tuple: + self.result = (self.result,) + self.on_success(*self.result) + + if self.on_complete: + self.on_complete() + + +class Timer(QThread): + def run(self): + while True: + self.emit(SIGNAL('timersignal')) + time.sleep(0.5) + + +class EnterButton(QPushButton): + def __init__(self, text, func): + QPushButton.__init__(self, text) + self.func = func + self.clicked.connect(func) + + def keyPressEvent(self, e): + if e.key() == Qt.Key_Return: + apply(self.func,()) + + + + + +class HelpButton(QPushButton): + def __init__(self, text): + QPushButton.__init__(self, '?') + self.help_text = text + self.setFocusPolicy(Qt.NoFocus) + self.setFixedWidth(20) + self.alt = None + self.clicked.connect(self.onclick) + + def set_alt(self, func): + self.alt = func + + def onclick(self): + if self.alt: + apply(self.alt) + else: + QMessageBox.information(self, 'Help', self.help_text, 'OK') + + + +def close_button(dialog, label=None): + hbox = QHBoxLayout() + hbox.addStretch(1) + b = QPushButton(label or _("Close")) + hbox.addWidget(b) + b.clicked.connect(dialog.close) + b.setDefault(True) + return hbox + +def ok_cancel_buttons2(dialog, ok_label=None, cancel_label=None): + hbox = QHBoxLayout() + hbox.addStretch(1) + b = QPushButton(cancel_label or _('Cancel')) + hbox.addWidget(b) + b.clicked.connect(dialog.reject) + b = QPushButton(ok_label or _("OK")) + hbox.addWidget(b) + b.clicked.connect(dialog.accept) + b.setDefault(True) + return hbox, b + +def ok_cancel_buttons(dialog, ok_label=None, cancel_label=None): + hbox, b = ok_cancel_buttons2(dialog, ok_label, cancel_label) + return hbox + +def line_dialog(parent, title, label, ok_label, default=None): + dialog = QDialog(parent) + dialog.setMinimumWidth(500) + dialog.setWindowTitle(title) + dialog.setModal(1) + l = QVBoxLayout() + dialog.setLayout(l) + l.addWidget(QLabel(label)) + txt = QLineEdit() + if default: + txt.setText(default) + l.addWidget(txt) + l.addLayout(ok_cancel_buttons(dialog, ok_label)) + if dialog.exec_(): + return unicode(txt.text()) + +def text_dialog(parent, title, label, ok_label, default=None): + from qrtextedit import ScanQRTextEdit + dialog = QDialog(parent) + dialog.setMinimumWidth(500) + dialog.setWindowTitle(title) + dialog.setModal(1) + l = QVBoxLayout() + dialog.setLayout(l) + l.addWidget(QLabel(label)) + txt = ScanQRTextEdit(parent) + if default: + txt.setText(default) + l.addWidget(txt) + l.addLayout(ok_cancel_buttons(dialog, ok_label)) + if dialog.exec_(): + return unicode(txt.toPlainText()) + + + +def address_field(addresses): + hbox = QHBoxLayout() + address_e = QLineEdit() + if addresses: + address_e.setText(addresses[0]) + def func(): + i = addresses.index(str(address_e.text())) + 1 + i = i % len(addresses) + address_e.setText(addresses[i]) + button = QPushButton(_('Address')) + button.clicked.connect(func) + hbox.addWidget(button) + hbox.addWidget(address_e) + return hbox, address_e + + +def filename_field(parent, config, defaultname, select_msg): + + vbox = QVBoxLayout() + vbox.addWidget(QLabel(_("Format"))) + gb = QGroupBox("format", parent) + b1 = QRadioButton(gb) + b1.setText(_("CSV")) + b1.setChecked(True) + b2 = QRadioButton(gb) + b2.setText(_("json")) + vbox.addWidget(b1) + vbox.addWidget(b2) + + hbox = QHBoxLayout() + + directory = config.get('io_dir', unicode(os.path.expanduser('~'))) + path = os.path.join( directory, defaultname ) + filename_e = QLineEdit() + filename_e.setText(path) + + def func(): + text = unicode(filename_e.text()) + _filter = "*.csv" if text.endswith(".csv") else "*.json" if text.endswith(".json") else None + p = unicode( QFileDialog.getSaveFileName(None, select_msg, text, _filter)) + if p: + filename_e.setText(p) + + button = QPushButton(_('File')) + button.clicked.connect(func) + hbox.addWidget(button) + hbox.addWidget(filename_e) + vbox.addLayout(hbox) + + def set_csv(v): + text = unicode(filename_e.text()) + text = text.replace(".json",".csv") if v else text.replace(".csv",".json") + filename_e.setText(text) + + b1.clicked.connect(lambda: set_csv(True)) + b2.clicked.connect(lambda: set_csv(False)) + + return vbox, filename_e, b1 + + + +class MyTreeWidget(QTreeWidget): + def __init__(self, parent): + QTreeWidget.__init__(self, parent) + self.setContextMenuPolicy(Qt.CustomContextMenu) + self.itemActivated.connect(self.on_activated) + + def on_activated(self, item): + if not item: return + for i in range(0,self.viewport().height()/5): + if self.itemAt(QPoint(0,i*5)) == item: + break + else: + return + for j in range(0,30): + if self.itemAt(QPoint(0,i*5 + j)) != item: + break + self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), QPoint(50, i*5 + j - 1)) + + + + +if __name__ == "__main__": + app = QApplication([]) + t = WaitingDialog(None, 'testing ...', lambda: [time.sleep(1)], lambda x: QMessageBox.information(None, 'done', "done", _('OK'))) + t.start() + app.exec_() diff --git a/gui/qt/version_getter.py b/gui/qt/version_getter.py new file mode 100644 index 00000000..3e741a1d --- /dev/null +++ b/gui/qt/version_getter.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import threading, httplib, re, socket +import webbrowser +from PyQt4.QtGui import * +from PyQt4.QtCore import * +import PyQt4.QtCore as QtCore + +from electrum_ixc.i18n import _ +from electrum_ixc import ELECTRUM_VERSION, print_error + +class VersionGetter(threading.Thread): + + def __init__(self, label): + threading.Thread.__init__(self) + self.label = label + + def run(self): + try: + con = httplib.HTTPConnection('electrum.org', 80, timeout=5) + con.request("GET", "/version") + res = con.getresponse() + except socket.error as msg: + print_error("Could not retrieve version information") + return + + if res.status == 200: + latest_version = res.read() + latest_version = latest_version.replace("\n","") + if(re.match('^\d+(\.\d+)*$', latest_version)): + self.label.callback(latest_version) + +class UpdateLabel(QLabel): + def __init__(self, config, sb): + QLabel.__init__(self) + self.new_version = False + self.sb = sb + self.config = config + self.current_version = ELECTRUM_VERSION + self.connect(self, QtCore.SIGNAL('new_electrum_version'), self.new_electrum_version) + # prevent HTTP leaks if a proxy is set + if self.config.get('proxy'): + return + VersionGetter(self).start() + + def callback(self, version): + self.latest_version = version + if(self.compare_versions(self.latest_version, self.current_version) == 1): + latest_seen = self.config.get("last_seen_version",ELECTRUM_VERSION) + if(self.compare_versions(self.latest_version, latest_seen) == 1): + self.new_version = True + self.emit(QtCore.SIGNAL('new_electrum_version')) + + def new_electrum_version(self): + if self.new_version: + self.setText(_("New version available") + ": " + self.latest_version) + self.sb.insertPermanentWidget(1, self) + + def compare_versions(self, version1, version2): + def normalize(v): + return [int(x) for x in re.sub(r'(\.0+)*$','', v).split(".")] + return cmp(normalize(version1), normalize(version2)) + + def ignore_this_version(self): + self.setText("") + self.config.set_key("last_seen_version", self.latest_version, True) + QMessageBox.information(self, _("Preference saved"), _("Notifications about this update will not be shown again.")) + self.dialog.done(0) + + def ignore_all_version(self): + self.setText("") + self.config.set_key("last_seen_version", "9.9.9", True) + QMessageBox.information(self, _("Preference saved"), _("No more notifications about version updates will be shown.")) + self.dialog.done(0) + + def open_website(self): + webbrowser.open("http://electrumalt.org/download.html") + self.dialog.done(0) + + def mouseReleaseEvent(self, event): + dialog = QDialog(self) + dialog.setWindowTitle(_('Electrum update')) + dialog.setModal(1) + + main_layout = QGridLayout() + main_layout.addWidget(QLabel(_("A new version of Electrum is available:")+" " + self.latest_version), 0,0,1,3) + + ignore_version = QPushButton(_("Ignore this version")) + ignore_version.clicked.connect(self.ignore_this_version) + + ignore_all_versions = QPushButton(_("Ignore all versions")) + ignore_all_versions.clicked.connect(self.ignore_all_version) + + open_website = QPushButton(_("Goto download page")) + open_website.clicked.connect(self.open_website) + + main_layout.addWidget(ignore_version, 1, 0) + main_layout.addWidget(ignore_all_versions, 1, 1) + main_layout.addWidget(open_website, 1, 2) + + dialog.setLayout(main_layout) + + self.dialog = dialog + + if not dialog.exec_(): return diff --git a/gui/stdio.py b/gui/stdio.py new file mode 100644 index 00000000..7289447a --- /dev/null +++ b/gui/stdio.py @@ -0,0 +1,252 @@ +from decimal import Decimal +_ = lambda x:x +#from i18n import _ +from electrum_ixc.wallet import WalletStorage, Wallet +from electrum_ixc.util import format_satoshis, set_verbosity +from electrum_ixc.bitcoin import is_valid +from electrum_ixc.network import filter_protocol +import sys, getpass, datetime + +# minimal fdisk like gui for console usage +# written by rofl0r, with some bits stolen from the text gui (ncurses) + +class ElectrumGui: + + def __init__(self, config, network): + self.network = network + self.config = config + storage = WalletStorage(config) + if not storage.file_exists: + print "Wallet not found. try 'electrum-ixc create'" + exit() + + self.done = 0 + self.last_balance = "" + + set_verbosity(False) + + self.str_recipient = "" + self.str_description = "" + self.str_amount = "" + self.str_fee = "" + + self.wallet = Wallet(storage) + self.wallet.start_threads(network) + + self.wallet.network.register_callback('updated', self.updated) + self.wallet.network.register_callback('connected', self.connected) + self.wallet.network.register_callback('disconnected', self.disconnected) + self.wallet.network.register_callback('disconnecting', self.disconnecting) + self.wallet.network.register_callback('peers', self.peers) + self.wallet.network.register_callback('banner', self.print_banner) + self.commands = [_("[h] - displays this help text"), \ + _("[i] - display transaction history"), \ + _("[o] - enter payment order"), \ + _("[p] - print stored payment order"), \ + _("[s] - send stored payment order"), \ + _("[r] - show own receipt addresses"), \ + _("[c] - display contacts"), \ + _("[b] - print server banner"), \ + _("[q] - quit") ] + self.num_commands = len(self.commands) + + def main_command(self): + self.print_balance() + c = raw_input("enter command: ") + if c == "h" : self.print_commands() + elif c == "i" : self.print_history() + elif c == "o" : self.enter_order() + elif c == "p" : self.print_order() + elif c == "s" : self.send_order() + elif c == "r" : self.print_addresses() + elif c == "c" : self.print_contacts() + elif c == "b" : self.print_banner() + elif c == "n" : self.network_dialog() + elif c == "e" : self.settings_dialog() + elif c == "q" : self.done = 1 + else: self.print_commands() + + def peers(self): + print("got peers list:") + l = filter_protocol(self.wallet.network.get_servers(), 's') + for s in l: + print (s) + + def connected(self): + print ("connected") + + def disconnected(self): + print ("disconnected") + + def disconnecting(self): + print ("disconnecting") + + def updated(self): + s = self.get_balance() + if s != self.last_balance: + print(s) + self.last_balance = s + return True + + def print_commands(self): + self.print_list(self.commands, "Available commands") + + def print_history(self): + width = [20, 40, 14, 14] + delta = (80 - sum(width) - 4)/3 + format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \ + + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" + b = 0 + messages = [] + + for item in self.wallet.get_tx_history(): + tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item + if confirmations: + try: + time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] + except Exception: + time_str = "unknown" + else: + time_str = 'pending' + + label, is_default_label = self.wallet.get_label(tx_hash) + messages.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) ) + + self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance"))) + + + def print_balance(self): + print(self.get_balance()) + + def get_balance(self): + if self.wallet.network.interface and self.wallet.network.interface.is_connected: + if not self.wallet.up_to_date: + msg = _( "Synchronizing..." ) + else: + c, u = self.wallet.get_balance() + msg = _("Balance")+": %f "%(Decimal( c ) / 100000000) + if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000) + else: + msg = _( "Not connected" ) + + return(msg) + + + def print_contacts(self): + messages = map(lambda addr: "%30s %30s "%(addr, self.wallet.labels.get(addr,"")), self.wallet.addressbook) + self.print_list(messages, "%19s %25s "%("Address", "Label")) + + def print_addresses(self): + messages = map(lambda addr: "%30s %30s "%(addr, self.wallet.labels.get(addr,"")), self.wallet.addresses()) + self.print_list(messages, "%19s %25s "%("Address", "Label")) + + def print_order(self): + print("send order to " + self.str_recipient + ", amount: " + self.str_amount \ + + "\nfee: " + self.str_fee + ", desc: " + self.str_description) + + def enter_order(self): + self.str_recipient = raw_input("Pay to: ") + self.str_description = raw_input("Description : ") + self.str_amount = raw_input("Amount: ") + self.str_fee = raw_input("Fee: ") + + def send_order(self): + self.do_send() + + def print_banner(self): + for i, x in enumerate( self.wallet.network.banner.split('\n') ): + print( x ) + + def print_list(self, list, firstline): + self.maxpos = len(list) + if not self.maxpos: return + print(firstline) + for i in range(self.maxpos): + msg = list[i] if i < len(list) else "" + print(msg) + + + def main(self,url): + while self.done == 0: self.main_command() + + def do_send(self): + if not is_valid(self.str_recipient): + print(_('Invalid Bitcoin address')) + return + try: + amount = int( Decimal( self.str_amount) * 100000000 ) + except Exception: + print(_('Invalid Amount')) + return + try: + fee = int( Decimal( self.str_fee) * 100000000 ) + except Exception: + print(_('Invalid Fee')) + return + + if self.wallet.use_encryption: + password = self.password_dialog() + if not password: + return + else: + password = None + + c = "" + while c != "y": + c = raw_input("ok to send (y/n)?") + if c == "n": return + + try: + tx = self.wallet.mktx( [(self.str_recipient, amount)], password, fee) + except Exception as e: + print(str(e)) + return + + if self.str_description: + self.wallet.labels[tx.hash()] = self.str_description + + h = self.wallet.send_tx(tx) + print(_("Please wait...")) + self.wallet.tx_event.wait() + status, msg = self.wallet.receive_tx( h, tx ) + + if status: + print(_('Payment sent.')) + #self.do_clear() + #self.update_contacts_tab() + else: + print(_('Error')) + + def network_dialog(self): + print("use 'electrum-ixc setconfig server/proxy' to change your network settings") + return True + + + def settings_dialog(self): + print("use 'electrum-ixc setconfig' to change your settings") + return True + + def password_dialog(self): + return getpass.getpass() + + +# XXX unused + + def run_receive_tab(self, c): + #if c == 10: + # out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"]) + return + + def run_contacts_tab(self, c): + pass +# if c == 10 and self.wallet.addressbook: +# out = self.run_popup('Adress', ["Copy", "Pay to", "Edit label", "Delete"]).get('button') +# address = self.wallet.addressbook[self.pos%len(self.wallet.addressbook)] +# if out == "Pay to": +# self.tab = 1 +# self.str_recipient = address +# self.pos = 2 +# elif out == "Edit label": +# s = self.get_string(6 + self.pos, 18) +# if s: +# self.wallet.labels[address] = s diff --git a/gui/text.py b/gui/text.py new file mode 100644 index 00000000..b792198c --- /dev/null +++ b/gui/text.py @@ -0,0 +1,482 @@ +import curses, datetime, locale +from decimal import Decimal +_ = lambda x:x +#from i18n import _ +from electrum_ixc.util import format_satoshis, set_verbosity +from electrum_ixc.bitcoin import is_valid + +from electrum_ixc import Wallet, WalletStorage + +import tty, sys + + +class ElectrumGui: + + def __init__(self, config, network): + + self.config = config + self.network = network + storage = WalletStorage(config) + if not storage.file_exists: + print "Wallet not found. try 'electrum-ixc create'" + exit() + + self.wallet = Wallet(storage) + self.wallet.start_threads(self.network) + + locale.setlocale(locale.LC_ALL, '') + self.encoding = locale.getpreferredencoding() + + self.stdscr = curses.initscr() + curses.noecho() + curses.cbreak() + curses.start_color() + curses.use_default_colors() + curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE) + curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_CYAN) + self.stdscr.keypad(1) + self.stdscr.border(0) + self.maxy, self.maxx = self.stdscr.getmaxyx() + self.set_cursor(0) + self.w = curses.newwin(10, 50, 5, 5) + + set_verbosity(False) + self.tab = 0 + self.pos = 0 + self.popup_pos = 0 + + self.str_recipient = "" + self.str_description = "" + self.str_amount = "" + self.str_fee = "" + self.history = None + + if self.network: + self.network.register_callback('updated', self.update) + self.network.register_callback('connected', self.refresh) + self.network.register_callback('disconnected', self.refresh) + self.network.register_callback('disconnecting', self.refresh) + + self.tab_names = [_("History"), _("Send"), _("Receive"), _("Contacts"), _("Wall")] + self.num_tabs = len(self.tab_names) + + + def set_cursor(self, x): + try: + curses.curs_set(x) + except Exception: + pass + + def restore_or_create(self): + pass + + def verify_seed(self): + pass + + def get_string(self, y, x): + self.set_cursor(1) + curses.echo() + self.stdscr.addstr( y, x, " "*20, curses.A_REVERSE) + s = self.stdscr.getstr(y,x) + curses.noecho() + self.set_cursor(0) + return s + + def update(self): + self.update_history() + if self.tab == 0: + self.print_history() + self.refresh() + + def print_history(self): + + width = [20, 40, 14, 14] + delta = (self.maxx - sum(width) - 4)/3 + format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" + + if self.history is None: + self.update_history() + + self.print_list(self.history[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance"))) + + def update_history(self): + width = [20, 40, 14, 14] + delta = (self.maxx - sum(width) - 4)/3 + format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" + + b = 0 + self.history = [] + + for item in self.wallet.get_tx_history(): + tx_hash, conf, is_mine, value, fee, balance, timestamp = item + if conf: + try: + time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] + except Exception: + time_str = "------" + else: + time_str = 'pending' + + label, is_default_label = self.wallet.get_label(tx_hash) + self.history.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) ) + + + def print_balance(self): + if not self.network: + msg = _("Offline") + elif self.network.is_connected(): + if not self.wallet.up_to_date: + msg = _("Synchronizing...") + else: + c, u = self.wallet.get_balance() + msg = _("Balance")+": %f "%(Decimal( c ) / 100000000) + if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000) + else: + msg = _("Not connected") + + self.stdscr.addstr( self.maxy -1, 3, msg) + + for i in range(self.num_tabs): + self.stdscr.addstr( 0, 2 + 2*i + len(''.join(self.tab_names[0:i])), ' '+self.tab_names[i]+' ', curses.A_BOLD if self.tab == i else 0) + + self.stdscr.addstr( self.maxy -1, self.maxx-30, ' '.join([_("Settings"), _("Network"), _("Quit")])) + + + def print_contacts(self): + messages = map(lambda addr: "%30s %30s "%(addr, self.wallet.labels.get(addr,"")), self.wallet.addressbook) + self.print_list(messages, "%19s %25s "%("Address", "Label")) + + def print_receive(self): + fmt = "%-35s %-30s" + messages = map(lambda addr: fmt % (addr, self.wallet.labels.get(addr,"")), self.wallet.addresses()) + self.print_list(messages, fmt % ("Address", "Label")) + + def print_edit_line(self, y, label, text, index, size): + text += " "*(size - len(text) ) + self.stdscr.addstr( y, 2, label) + self.stdscr.addstr( y, 15, text, curses.A_REVERSE if self.pos%6==index else curses.color_pair(1)) + + def print_send_tab(self): + self.stdscr.clear() + self.print_edit_line(3, _("Pay to"), self.str_recipient, 0, 40) + self.print_edit_line(5, _("Description"), self.str_description, 1, 40) + self.print_edit_line(7, _("Amount"), self.str_amount, 2, 15) + self.print_edit_line(9, _("Fee"), self.str_fee, 3, 15) + self.stdscr.addstr( 12, 15, _("[Send]"), curses.A_REVERSE if self.pos%6==4 else curses.color_pair(2)) + self.stdscr.addstr( 12, 25, _("[Clear]"), curses.A_REVERSE if self.pos%6==5 else curses.color_pair(2)) + + def print_banner(self): + if self.network: + self.print_list( self.network.banner.split('\n')) + + def print_list(self, list, firstline = None): + self.maxpos = len(list) + if not self.maxpos: return + if firstline: + firstline += " "*(self.maxx -2 - len(firstline)) + self.stdscr.addstr( 1, 1, firstline ) + for i in range(self.maxy-4): + msg = list[i] if i < len(list) else "" + msg += " "*(self.maxx - 2 - len(msg)) + m = msg[0:self.maxx - 2] + m = m.encode(self.encoding) + self.stdscr.addstr( i+2, 1, m, curses.A_REVERSE if i == (self.pos % self.maxpos) else 0) + + def refresh(self): + if self.tab == -1: return + self.stdscr.border(0) + self.print_balance() + self.stdscr.refresh() + + def main_command(self): + c = self.stdscr.getch() + print c + if c == curses.KEY_RIGHT: self.tab = (self.tab + 1)%self.num_tabs + elif c == curses.KEY_LEFT: self.tab = (self.tab - 1)%self.num_tabs + elif c == curses.KEY_DOWN: self.pos +=1 + elif c == curses.KEY_UP: self.pos -= 1 + elif c == 9: self.pos +=1 # tab + elif curses.unctrl(c) in ['^W', '^C', '^X', '^Q']: self.tab = -1 + elif curses.unctrl(c) in ['^N']: self.network_dialog() + elif curses.unctrl(c) == '^S': self.settings_dialog() + else: return c + if self.pos<0: self.pos=0 + if self.pos>=self.maxpos: self.pos=self.maxpos - 1 + + def run_tab(self, i, print_func, exec_func): + while self.tab == i: + self.stdscr.clear() + print_func() + self.refresh() + c = self.main_command() + if c: exec_func(c) + + + def run_history_tab(self, c): + if c == 10: + out = self.run_popup('',["blah","foo"]) + + + def edit_str(self, target, c, is_num=False): + # detect backspace + if c in [8, 127, 263] and target: + target = target[:-1] + elif not is_num or curses.unctrl(c) in '0123456789.': + target += curses.unctrl(c) + return target + + + def run_send_tab(self, c): + if self.pos%6 == 0: + self.str_recipient = self.edit_str(self.str_recipient, c) + if self.pos%6 == 1: + self.str_description = self.edit_str(self.str_description, c) + if self.pos%6 == 2: + self.str_amount = self.edit_str(self.str_amount, c, True) + elif self.pos%6 == 3: + self.str_fee = self.edit_str(self.str_fee, c, True) + elif self.pos%6==4: + if c == 10: self.do_send() + elif self.pos%6==5: + if c == 10: self.do_clear() + + + def run_receive_tab(self, c): + if c == 10: + out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"]) + + def run_contacts_tab(self, c): + if c == 10 and self.wallet.addressbook: + out = self.run_popup('Adress', ["Copy", "Pay to", "Edit label", "Delete"]).get('button') + address = self.wallet.addressbook[self.pos%len(self.wallet.addressbook)] + if out == "Pay to": + self.tab = 1 + self.str_recipient = address + self.pos = 2 + elif out == "Edit label": + s = self.get_string(6 + self.pos, 18) + if s: + self.wallet.labels[address] = s + + def run_banner_tab(self, c): + self.show_message(repr(c)) + pass + + def main(self,url): + + tty.setraw(sys.stdin) + while self.tab != -1: + self.run_tab(0, self.print_history, self.run_history_tab) + self.run_tab(1, self.print_send_tab, self.run_send_tab) + self.run_tab(2, self.print_receive, self.run_receive_tab) + self.run_tab(3, self.print_contacts, self.run_contacts_tab) + self.run_tab(4, self.print_banner, self.run_banner_tab) + + tty.setcbreak(sys.stdin) + curses.nocbreak() + self.stdscr.keypad(0) + curses.echo() + curses.endwin() + + + def do_clear(self): + self.str_amount = '' + self.str_recipient = '' + self.str_fee = '' + self.str_description = '' + + def do_send(self): + if not is_valid(self.str_recipient): + self.show_message(_('Invalid Ixcoin address')) + return + try: + amount = int( Decimal( self.str_amount) * 100000000 ) + except Exception: + self.show_message(_('Invalid Amount')) + return + try: + fee = int( Decimal( self.str_fee) * 100000000 ) + except Exception: + self.show_message(_('Invalid Fee')) + return + + if self.wallet.use_encryption: + password = self.password_dialog() + if not password: + return + else: + password = None + + try: + tx = self.wallet.mktx( [(self.str_recipient, amount)], password, fee) + except Exception as e: + self.show_message(str(e)) + return + + if self.str_description: + self.wallet.labels[tx.hash()] = self.str_description + + h = self.wallet.send_tx(tx) + self.show_message(_("Please wait..."), getchar=False) + self.wallet.tx_event.wait() + status, msg = self.wallet.receive_tx( h, tx ) + + if status: + self.show_message(_('Payment sent.')) + self.do_clear() + #self.update_contacts_tab() + else: + self.show_message(_('Error')) + + + def show_message(self, message, getchar = True): + w = self.w + w.clear() + w.border(0) + for i, line in enumerate(message.split('\n')): + w.addstr(2+i,2,line) + w.refresh() + if getchar: c = self.stdscr.getch() + + + def run_popup(self, title, items): + return self.run_dialog(title, map(lambda x: {'type':'button','label':x}, items), interval=1, y_pos = self.pos+3) + + + def network_dialog(self): + if not self.network: return + auto_connect = self.network.config.get('auto_cycle') + host, port, protocol = self.network.default_server.split(':') + srv = 'auto-connect' if auto_connect else self.network.default_server + + out = self.run_dialog('Network', [ + {'label':'server', 'type':'str', 'value':srv}, + {'label':'proxy', 'type':'str', 'value':self.config.get('proxy', '')}, + ], buttons = 1) + if out: + if out.get('server'): + server = out.get('server') + auto_connect = server == 'auto-connect' + if not auto_connect: + try: + host, port, protocol = server.split(':') + except Exception: + self.show_message("Error:" + server + "\nIn doubt, type \"auto-connect\"") + return False + + if out.get('proxy'): + proxy = self.parse_proxy_options(out.get('proxy')) + else: + proxy = None + + self.network.set_parameters(host, port, protocol, proxy, auto_connect) + + + + def settings_dialog(self): + out = self.run_dialog('Settings', [ + {'label':'Default GUI', 'type':'list', 'choices':['classic','lite','gtk','text'], 'value':self.config.get('gui')}, + {'label':'Default fee', 'type':'satoshis', 'value': format_satoshis(self.wallet.fee).strip() } + ], buttons = 1) + if out: + if out.get('Default GUI'): + self.config.set_key('gui', out['Default GUI'], True) + if out.get('Default fee'): + fee = int ( Decimal( out['Default fee']) *10000000 ) + self.config.set_key('fee_per_kb', fee, True) + + + def password_dialog(self): + out = self.run_dialog('Password', [ + {'label':'Password', 'type':'password', 'value':''} + ], buttons = 1) + return out.get('Password') + + + def run_dialog(self, title, items, interval=2, buttons=None, y_pos=3): + self.popup_pos = 0 + + self.w = curses.newwin( 5 + len(items)*interval + (2 if buttons else 0), 50, y_pos, 5) + w = self.w + out = {} + while True: + w.clear() + w.border(0) + w.addstr( 0, 2, title) + + num = len(items) + + numpos = num + if buttons: numpos += 2 + + for i in range(num): + item = items[i] + label = item.get('label') + if item.get('type') == 'list': + value = item.get('value','') + elif item.get('type') == 'satoshis': + value = item.get('value','') + elif item.get('type') == 'str': + value = item.get('value','') + elif item.get('type') == 'password': + value = '*'*len(item.get('value','')) + else: + value = '' + + if len(value)<20: value += ' '*(20-len(value)) + + if item.has_key('value'): + w.addstr( 2+interval*i, 2, label) + w.addstr( 2+interval*i, 15, value, curses.A_REVERSE if self.popup_pos%numpos==i else curses.color_pair(1) ) + else: + w.addstr( 2+interval*i, 2, label, curses.A_REVERSE if self.popup_pos%numpos==i else 0) + + if buttons: + w.addstr( 5+interval*i, 10, "[ ok ]", curses.A_REVERSE if self.popup_pos%numpos==(numpos-2) else curses.color_pair(2)) + w.addstr( 5+interval*i, 25, "[cancel]", curses.A_REVERSE if self.popup_pos%numpos==(numpos-1) else curses.color_pair(2)) + + w.refresh() + + c = self.stdscr.getch() + if c in [ord('q'), 27]: break + elif c in [curses.KEY_LEFT, curses.KEY_UP]: self.popup_pos -= 1 + elif c in [curses.KEY_RIGHT, curses.KEY_DOWN]: self.popup_pos +=1 + else: + i = self.popup_pos%numpos + if buttons and c==10: + if i == numpos-2: + return out + elif i == numpos -1: + return {} + + item = items[i] + _type = item.get('type') + + if _type == 'str': + item['value'] = self.edit_str(item['value'], c) + out[item.get('label')] = item.get('value') + + elif _type == 'password': + item['value'] = self.edit_str(item['value'], c) + out[item.get('label')] = item ['value'] + + elif _type == 'satoshis': + item['value'] = self.edit_str(item['value'], c, True) + out[item.get('label')] = item.get('value') + + elif _type == 'list': + choices = item.get('choices') + try: + j = choices.index(item.get('value')) + except Exception: + j = 0 + new_choice = choices[(j + 1)% len(choices)] + item['value'] = new_choice + out[item.get('label')] = item.get('value') + + elif _type == 'button': + out['button'] = item.get('label') + break + + return out + diff --git a/icons.qrc b/icons.qrc new file mode 100644 index 00000000..94fd43e3 --- /dev/null +++ b/icons.qrc @@ -0,0 +1,33 @@ + + + icons/electrum.png + icons/clock1.png + icons/clock2.png + icons/clock3.png + icons/clock4.png + icons/clock5.png + icons/confirmed.png + icons/copy.png + icons/expired.png + icons/key.png + icons/lock.png + icons/unlock.png + icons/preferences.png + icons/seed.png + icons/hot_seed.png + icons/cold_seed.png + icons/status_connected.png + icons/status_disconnected.png + icons/status_waiting.png + icons/status_lagging.png + icons/switchgui.png + icons/electrum_light_icon.png + icons/electrum_dark_icon.png + icons/unconfirmed.png + icons/unpaid.png + icons/network.png + icons/dark_background.png + icons/qrcode.png + icons/trustedcoin.png + + diff --git a/icons/clock1.png b/icons/clock1.png new file mode 100644 index 0000000000000000000000000000000000000000..448e47f947d3da4e023f69279e7f8a830ed5ca75 GIT binary patch literal 946 zcmV;j15NyiP)Ip-$*fn9H5H_r6~) zqzOIA*`4R?9$~HJXy)hVy-X%^Hjd*nj@HvsO4>@T#BsbDhT*TJQYkvR7cUQl5TaZz zpYBrX%Im!YZ>4+tN#}B$cv_`dt+KWK)cz12{86*^Lb+UiU=KlItwjhSipAoEH+!-R zg|2=ts~r+uX@WRrKr1?f7CVg>^!@#a?}O)ZG2wo>u(0s8wbpt7<#PG-gqQecz|DDb zXOA7FDfIWV@n{`fhfyyo56wa!wll{&`My)G>&|#esVUi$!`Y9?F%OnG=95HG;|ETxpBsErJPo-M`#ox=@A=!SjF=fyOh@+@_FSh-`>1ItTp?= z0Y6^5N+1;-N= zVjR%M;72X|R=~vM8^n&~_RrU!g<-hpluD&&tKI%Y{<)@y$H(xp-Q4+om9?!+B2VyF ztx8*19{*e8r&~7&UC?*$n1{aqX{A!}9e`r7_~2%}{)M`~s+F+xo){)GG(aE>*DJTF zw|tIGoZ_Q%A7fXR&3EV!udS@CH0=@SKhXx{ U3^ThEGXMYp07*qoM6N<$g34vUH2?qr literal 0 HcmV?d00001 diff --git a/icons/clock2.png b/icons/clock2.png new file mode 100644 index 0000000000000000000000000000000000000000..c1a6e99f7f28d66f4dd6901f4c09a2e4325ac3b7 GIT binary patch literal 944 zcmV;h15f;kP)Z$OUJg1324BT5lxs2GsJ|8 zhaDFZHJA{RCA%9hCR{x1qSx9(JrNEb)RP`GM$`nzB9zh05p{96Wei$2V6hhqM zk=e+S@HOq`BiczvkjOFI8s^{CRmgh07D%?AwHfjSAEa$U2hA^@pFh6{Ec!wSIg&|VJ)Fvo$}mRyKGK(1 zYuH#{C#Rc?B)W{aCPH=i<)P+mU&~vH5c^=#VpAW`bwqzVA;*FySD+hH4*&gw}dV?(FQ8mx=#*eLQy}_B?blfs#H>JFK-> zPhhN|6-Tr>A^Eo^u)^@;t!uR?YW(aKi^X`e5q=nL-7};4F=RHw&AZF2Y~Cl9l6%!E zp%AQXZSm8M>qNd!yiu_$kJ}f@<#NjdC=?3I*H*Vb()X7wo@3zX5rRV_v<3WDzQuN@ z&EXSy&b@yQHWux7ceg%WSXj8>oO3UoX?Aw@^k^Wzo_KZSxJ_r+^#Y7Fq@y~nvBk|l z*J>+Io?mz&+n3(B$IQ%3Z#tcx)>==dggs-7_Uj#0)><#^?(SZ#R4PrkPx=ps^~c_I S7%Wc!0000+gKKBb;;WWpZ*-`M!TtYdxf-J08ceYs99kwVscn=*ra8RJ?aDb`OLQ zqEspkv}Mz;p6bmXY0c$n&KBqk)(LlRvAVh8zWY7;dwt8DDwRrC-2+kW%Ee;w)L?Js z>;YNG_}Y^3EcMz3^~B=KJe{QC?dO-D{`Q~xm3U&}Eg{4w&N-(5N~O}k;A737b!w%O z`WAPLVSh&lH~+m3Jst-;7609-)8ScOIh15f-1w+AHZ}{)dO`?wpwRq7UrW&A=@_Lv zl;>fsWo3DZ_H0O3py_H25w5|{Wy6Vqs+_-_IZ^ub{5cr}!SEBk!B7&0+*)5JF$N1H z#t>FQ;@UkhRj_r^q(MG+pLP*5`pnLt=XoQ_7&9zwhE!_&d^^U0uqjwez0pAH7*YW) zLCJ_`4@Xp^n8SsXG;JA@N}A(QqKJ$|WSY>aMH`DwEn7QxDP34#;=MUO{9*xI#NArN zJD)db^XfD!Gpww0P1;IU*ER@Rvh2?XU>#V;3nxc-uInO6qDhSg5z*cj^TBHdztv!j z@l>^@FR4u9rJl$85k{kp0VlwLl^!aS(v&e^QxKY)w<8dmdrnflZ|4*+m*@({E3mS- zL}6bWel816;E-4hQp6w=Kr_1-VO>O_Yahm#d9}U0J@eNMbG^U6Fc1rg@tV+5;he!b zi^_uApK9Xs^1<^|Dj^GN zlCLiXtBafN^aI&GRO2qAqoXakTyDe|GnCEPV_L^Dtf#ZanE6Vj@>9874&5Hk07*qoM6N<$g2J7>Bme*a literal 0 HcmV?d00001 diff --git a/icons/clock4.png b/icons/clock4.png new file mode 100644 index 0000000000000000000000000000000000000000..ba036f47d33e7ac9a3db80ccdec293e0ee3be034 GIT binary patch literal 962 zcmV;z13mnSP)D(iwsmO+s?$ftr*sTFZ0xRGYjMF_~`(Ig8SE6t;MA*OkKU%t$p zd;jof4%Nvl9&cX7ZnT1xwRQgeruuVzjr)QinB|9{e*g~;5BIgV zC%?}p>ivvok&p)Q-Wt?~L$)dlEv*>%XtC?JTk&|M^5K9G;%jDR9{_?NXlrfrzdIp) z-^3f(2no5|aooH6H=LDdI_YEMpBVKyhYN3*gr@SBdwcIq0GNW!xGey!=Y!&E84876d!CPy4B=XYKwDR#w+w zh~OMx3?U3dsLBo?BCv>IT^X5U`^eT*aQ>aG4k_h1pNM*FrB+B0B3*k7YxP*xpt6^lBN^sTj#5_4w9W--5BUypGJ#D&*=ifMZBWxKe0FeLe|eG{|YNr;yE6 z@W~LNCQBe9>Bq4xS;6l%Hnl)F4Q&av=@4z5Ge{=)01*5X0kB}9v9PG%JdGXl5Jhg% z2QUe_2I2-REzINTXLiu_!aM*1v-#hJ0fYeyjj7uTRw!g2s|68F`WX@QEBwQ}eKExG zCc=#ygwaugOAy8<6s$D3J*)89&>mdE;QFCbzd zbPctC2whzTtgf!$S@n0e6eAe4u>1p||IOHY@N4kabokYEFPqJlil=I)dG}pxY;Hhn zf^~pageZ#8l)KP~q0xl2Ed;rJWO5QOkM0clzJHDrQ7O~C&v-UQp#*qA1Ljc?b}xly zvjw3f6k{;ZFkGPLRe>m$C>%F1COOQVuU|{%6u4Ld?3ZxaJQP2?J zMF9!0Goa_Jxm|@8{Nq5VyT@xhxxx+}IztI&}Y8LdP+}>~+HL zKN2J(-1|j9I*t2Pfty$NprBEi$(s5@cBxXS#LPJd#u%HJnE0UgjooWQ7wUX#MIzND zk<1gO#~V2Rxrf~I22vO-%w){+jb}cYot^v4IcJ|b)A;!KnPivxa^Rhvq3l46bniYa z6n54b9^dnD_v`HX_5*imZf@>p=bU}&jR%a5jwTa{#5p1wW`QmdX}=ZQMIu^iG#cMm etJTOIlKurBK+b`Ue8F7+0000#d!H05Ze6WU7Oc_gLB1Hl4E zSBDG*b3pL1gNLi%)k+}9tQ#yW3_R?I7CvfL%@{2=w2PN|$LlNY>(xHHcv%#sKQm)w zbaAun^w6%HQW)L`gGgrltAa>?P&ch6Ur8VbFVpV#tAJvF4~V>xP==GGGo1w)o4HEM z_NiB%HMfYX6YhV*3Uu4X$uof*Q2^LTkVKQ@YvIyUeb4%S90>4|@cR0U!#-~jlexPg|Xv^oh;H=~C6vRK~F zCjqrOmvy;Y7n`{8A1AMkxEC2@8YFYGmEar&SbEq1UG8t@*_-9PEQ8fkd_iT=<3DqM zHFR(g2xBj!Ow+gALUO@Dr)^uwiQjE^LL+ivVTRu&;w)IoCM`=ce4oXxeDtRg_XSB% zBF({FHoHJkj5G*^{>m+JZ0fHE;#C3(b}QrO1|tK>*D6y4lr1>2++A=bxC(Vk<#2Q8 zyXD7YAU=CJwl4A_f<6@klx;d(4j<{0yf>fP-c`zjNcND`Y<)d0TR?vLR}m8I40mE_ z+=n_|9|5$ifU9sv8;xl(EmgS^u^@Xt7@fi=pW9Os-)JCLp_=p(j%&8!Yo^3N&(`^0SAs_c#{=tReb6lHcm*~|0TXH ze(Xo`!rXxJ&uiqG8wLPE8q>C(89@7d{+;|-jk2jH00`6JaQ;ed?qPCs1*>!V#1Etq z`V`9B#=eR#&i6Uj5`C>bmX4=X?{ow5De~)jD54L#B{zFaUdIUm5+1ot>CZ;Rr#S1K zJa7)SzxE1Twt-D;a()f;TAkCyKV9+l+N%2tj)BCO;HV*5{s6&`j|RhYy5UZ9vo~Hn zbrhPT`o@)9uE;v*tn&PVA>CIys=(txH|^_%^NtV(O2cgCs=N1Zzs0we70P-1?4sG< zByXA?dS3Xf^PyVw{e@K_%#j8qi1`fzCS@*`NEP|Yp_7= z@4v3KYhY3vZc^Qa*``izQrc$OF(tQ+hxM z5Td4s)|X^Iv_?A7es0V(K@TuY>$?2M8E7f+&&|9LOB z4U+fAs?hqFs$3_J&2t!4VuAptmr8wPOvI)pb5TPdFz5J|-^lrHJlep`8&wpCLNp zL8hqQ*0*^lGI1GBCC!jdsU}s6GbUb$6RRUJ0dlT`+Hm9MR4cFo7-fx{_pn96@IW8{ z2#w;c{5p^(%f%zHdjYCW2oejqD0~E_Z>hP|1UZahHDKOz6 zI>-0x1?VuoLRGqX4CST!eG24|SeDm<-tQ;@g0+L8`R&8+;EnI*(;4H}W5Fwgp%7V|)r@hLNIQ9RB(!8@U;e37+r+TYL zeXQOq=#)#gQSv}-^@dsN?@w+5#}y!tLu&LYR!JOPJJCufkNr{$KrRus9N@ORJv{l^ zA{ob_uz-flDWk|-2>&&-`Y@byHC3l`KLj1-Bc}c*v9srS4L-#E=~fw12|4-$!izAL zs}XZ8SJQ>-147Q$>f^|J&xye+Q%Vp6El61u1gzH>Dde9Y4y^}Z+IJ5)sJ692;?=4M zR<5HVh%Y+(z0+SqBHhX4A2n;aW(?rWCKRqR*pPm-X0h!m?@KEe`Hk2m z&ZfmQziuW!Th>nRY{=cfC5AgF@`A{YQf`ppG^`WXn|Qlcxas6l)7 z;r*8OJC$CKM@u3gSX}UKD`}c@)U`7@Dx0n2duWRq^tfEQqr>jk!76SE|ATExYK71F z92i7-9&x|bcRP&&6apct5!w|dY`s<|UTfry@z0H{2e{deXE7W7d@#ESFpAdM!F|?CqYkRQLo*v4WcUg0!{>c_wR)Sq~#U z$Dfg?EZ>g-knAFI>wkvfsr%zmZjN5^VYLUMX*nu{g|CcX*N*j0`Clv2M8o7bvk|g@ z*$^N>^mUN6ah62`uc@E@s^bPzh2DwSTvvFi>)qh1jU2&2gPL(2kLfe!J5< z-{Q{OD*dVd$a8>yh4WWlp_RGiBpNB*gm%Zb1u1;FdP=JTPy7#+ddBAhVd*SvnCHq~ zE(CVQ15l(Cs7eK@zI;ayh)@0t^s?F}^YVGd@?C~)Hz??|Ykgm4u!%-~fVP7^)ps@v z?f!ID4`X-p2Ra~AbQx`}$tSpt_g0b7Bm-7EZ}q&TiDX`&U*SA*6?DX_M{n`7y~-Y} zS-LKlA8dUuBqnR5t5e`a{$nau^2(mXg@o@5XdlrObV|SRw9_(o`?nOf=tPR9k2e@u zs7EU;T*@qEhCiW3g-M{LK12SFqc7rxy*abJhwA)=&Y!4=foO=S!rawH&cB5uH~hwhU|4b5lx(WS!WEr~)PpL#%$Y}M%> zQVm?_u6xJ3^M)!GR-qM|;Tp7l``#WcM!D7e^SXur-t_M$`efp5oaz12yz^yM>(sw0AXqjn zMA69|A2G`_f^Lae>)64-Gs#qlrt0B>m0IF-l_W>(Klkg5~MPaXZ_j zgt{VVl`)VLOS*@gWv|=2(QUqilE_eYI_C}_ZP=v(cy9zkJMM4|U|#kg)9hkxNdZ8j zxxCOnV-(8Yno}%H;c*dF*?6#H_YFR|eBbWxME>et5%5E$MXvtFi2RlRw);C>SRMGK z=Goqur(C1(UYiX`pMVzRkp+KNJCLb_UrlPA^f_$}-_S~q@PA_y3E(U?ET5c&;~;ql z4KHR70_xg{9Xg70xUzFT1oxPIT_PJ$?{`;G`zy=vGPs=Y7$J5?YZ8C757OgWiddYp z0hw+B$m+MvRjZz-caGNE&nE`Y|F|2AM}7(NgEzVq+ja&l<7mnD$^3q9>C(f(nmRzd zE4~{0^RGAbOIMzDVo_6Cq_iS{wkc~u>;405tUKGHaKr(0hK{HSE%Vt#p#S&^5T*zf zGQMy?pHhklZsiM<@y3dXd-`2z;Bc6P#z&!B0ot%OQo6HQw@?;D38+=;eH*$M89;xv z@fk8!iUvGFJjRc&u_;p0x`dtI=?9h86|6$(lC4hOJ-^wR9zGQxUJtlFG+t2J!YQK$ zg7MIraFg4G_rKki`HiLBcYWE;v8HxXM`CF6I$Mh4z1fx^;!|*`4Ew63#+dn3PDIeY z!JB^3ZT0Dp|=$qyQ6k#f){r8gLYEdM-C zvhM@sKetwJx}9gp;KtECa+Xk>-&b<7G8?$Wk6OV$Pey=ycBkp{b9lp^KHQZyuAyh2 z35oV1oe*j_0&%D==R-T33!k3#0y-gVg)1UC`GGX#ua%F_KKG`xL|fqk%D71HOw{CL zf#;VSUK5YwoKxSdhT?pO4l+WhQAp_zn>|F{x9o~6TAIn&ksVhdX~iKi9gaT#E?XO_vHmI=>Wo}$A51+ZdFihVp_hOQS;U{?YSV_(~`T03^JObII zp{pik!WqjZ)u|~giElcFNtygajjqq7i)GK$QlC4E2u75Df`D{n#L*mfrv-V)CynKZioOp$IVHzw2_R7D*vp0^za+s22 zaDhlD(%Vr36o`qO4WUkkyi7L!A&QnR^9rl#8v$(3_8R@Yx7g7oWRNJRcltfcmr!i& zA3-@@ENQ_q*Muh_&LkT$yjAOQ38763eY0OBWjU}KZ4h-JC}i{D&QJ4`@fHfbYyB{Q zrGCWrRG*ThFOW%ioR6S|i@%NMyAuBM=itz-vNix}B+DlFS<3@UR#-S8F=|=Z__9CR zfsVsF{u3Fng&Ek>NMV@7xEs;b65>uCF16@^xkn6n1x=n4;I;Bk*UP@N}Guq9ABK+Sg5~Y$7`@@|krii9H3LQ(Ai8R@I04`3*vS^N&Gn7Qm{F>VB z66GQf!6R?E?6gWF3q+$u8$<6p4fxP3-Ix0q(~t}W^*U0S8Z!^b^3sLF{E6iw(R#25uLy;H)~#iM&N2dX zy{hZ$x^PofXr;s&$WxaFeTj!vA9A0)h|=f9%|l1_VM_2;N-Sms)Dg7b6V^BqD`z!n zBQ9^=_D}WH96BaB2U=vJSRM%`MDZ?S9UNx!ry4YU6SzlD5Uz$~d>T*18Pq!_B1#nOznfn9gU# z^y1v9EjTPeP=tUUtI31?u%|5G&Yg44Q{Jj?QIFzvnizjw@)&Nv{A&W6(L*7gW^?)Qu zjw{)718^M)LmCm!zBU9rje+3BI%Q8y_}E{UbPr=3qR+&5GDRKUlFI$frj8RZ0Q8LW zC|TG7SP76>{D)&cD~uivWvdcsfKWfbb!5xLP-e=s#g6v{*=JQIjU=KDnE!RQc-U~P z;`9l{7cwAen+^oe)V!7^vWcvE3NTVvQy@5ykuwaSOb|B zH4D_JuPZjJ=4>I7aB2LD(bz%HPH%#n+w3xJ=gyt_FCn(j#|!CmNq8DMuWIAJK)k10 z`@2wY#(8T@;PWi}g<|(TxXS!@r&)b;^BU>{MW}WU-4VT4Fu$w*68kR_4?}-+z;tJj zCClG=?B5`Fl@D(DPhL_&j;BC*{YaiV+i?hIHh#!Q?#se8HN!S6i5Z2{zFa?%pRF(wy=-)CLN*kTD1*rz zfuD`wpt?x{3_%BpuK3D(^;nguHKG9_O@(*kf5DCJAm8^3zm73`WL8%V1K#P~`?Y|O zgpEETTJ-l(U1xYs`1Rm=qX?>VK9>L+J{$%ZnqsY~EsdW)5U{p{B9?R+e9m)(g$%-Y#WNf{77-5XD1pJBy@tzqSU zvj(gk@yrh}FpPZNmhn_Z7%gR~j zh+oy;%;c;(bYOg|0UyBPAL2dZ!)D;&BZ&Uy@nT?Rr`YD*ux044KUg|r4Z@&M)c6c( zs8bJ~?xMNrd_r3`7eFVv;&EXB%e~wcG^wZNFk|&L@J1$B8WA4zORB`rJ6B8g7V#+v z6K~dr_iCx;j4AQ5yywXPaYtC8!^yCIRvm;2wjA^5l{o&8qZFeCBoOJZXmUSXP#cUc zL1-1tT$2lS`s$FmGnV&zY4A8?CAf-4!`ZYc!oL5zV8Ra~mk`_We2|m%(?XX9v0i-c zHCN#$M_1@>{%aL_atB-Ln1Dv?J@tbi$%&_f@l?o&5&v7-xkXHejvs>7!ZaDx1%9X(6-RfqZyiC+B zTMEhHjHFwj38mPX$3QJNVyJx(ou9!6B3xzL+Z#Kc`i1tTiExT1m9&vvQB5S)F5RX> zC1$rAEn?W2=#!rfx)Aa9vASh9HG4!;5lct_8G&FUYI?Z!?Xtn2UWrE^cV?gYxAno> zn2<|sZ&;NMw6SL+s^5f{pUfl~OM(>_oKCu($)d_Bm=V80Qu~^S3HrG&Ti#OnqcpNu zlA!v%w#Y)yk!PkmeYs)(8!ikTR}LgS!oGv(4wmCC5my3G6UhD zH**&@4K6_KI`xI|z-d%vdzPctPs?zg81{S(nGcc%9Xuy>`I65_WLkYFERMkno9p9l z=n?vzUiReIT$B(-zLwCvGobSXhXjRq8 zbp6#m$x~W7*~`G7Fxpm~JdrV2m~_sorY^o%6+C*~h%VQ|meOcbd?0^;z^3jDY4edH zu*ibAd_V8a0^LV`G-M%l)>BNuN=!wKswZ!9bNhP$LVD);A8qvR%@ z2lJl;0u=9%dV&(P=S4AMwc!wDxT7?sLyg zP1a#?0amMIn?9G|1a3W=95byvqMCT3BAtHoxmT+r9EMpJ&Y-SI5|yvHiAGvw%CZ(F zIwz=CgcZjLwAM&^HTr+xRCN7Ip*L&IA5B*QrTqiRex22T!j2D?WIuA+=?e8Uwh9ka z!B8s#A}sBZEO0lx79BK2B9sD7DTazN>A^Ibq|gp{8~Se!Sks5CJrj!*tvw7{e!tKK zhss3Bs1xqsfL=->E!0L;#i%vyTTWbls0?rZLLg8qR2=V@JIDDpCf^KN6OEHn=5sDY zPlpHKR~29)pxks`=W^-b45FqZJ2XHwW}p9MW~O$0WG)4{7Q+uS%w9nEPCRo+ z$}M6oCG9QiW;qsdPc>>!PhF=GztaU5jO5+{^)^h1D5KDk!~%CKeitSuVymQ4ko1KM z<~Z9-Hop5YB0zRlPcbJZY+xOuX9gybu>%=6Ui&~(o;Oh;=3pUjTEY1HqMMRpr)nMe zKXF%ltI6U2PWB3nRH-cVO4Oz^60$ADP>8FQMM8?+00!H7JWx8KgD~;07_eC^Bx}j} z!U$SmXAkKiZM`ty%C=LZZw}&9IE-jt;h!N+!-p~(53nVtWzUk$9VMFSk>rb=#04YZ zSd&&~&m_B_N32nzZ8F_tTff6ifZ}<5=wv-XvFMbq1D28Cj85MAj)TgJ%T~3fPJ_U# zLSymDf|Fwq7+^`06UhvH)QDTCtoOp(kYdLLB?tsBkBFz&{oQ^7WUr#DK`U)p1DuX1 zS&}-0D2_P2Vnw3ewE5Wi%l$SYJKJlvX2W{uNpPR1pa`*>0t#(oAlSx;?rlq8%A9&h z>_S;*SaK2vI^%3!S^&;K-7+h9$k$g??52xg=g&Z0LP#dVMbVe4Oan9Jz9cGWI zns8?sQ3gb_AzgSghpeF62G0~6j~c%VPx6TCHY8NDZOaeJSNJN-UA$gC^U}hITk4mo^tCQHom&}>hilYQ+Imi&wpB9s z($^gUOpUja9&}iB+X7}z;ue5$e~^-X3>4flLb^qaU1g21KOL*)04KTTK3k-tQ?$`< zR>Lme&ulQ<-zLQe(%g-9T*n%khh+`b(kcZVn6Lqe?emoD+lj)zm=3lDT=DoI_GKJ8 zccbSNR$S}?TRE?+<52r_AjMcj%s|t1PZw}9dF$90k$l8YI%FOR=J+#?g|y36)|Cky z?TWio)iIBqq$B4Tc-ezMX#R#d=9aRhfuajcRuioDJ2h(PW_da5`ao(70GS)jFoT#n z_|6Q~M2vDTi5lMw<@jBiTQoScF@D{Jz;#VfGPfE1iT7L)!#w)0Y()`j9<5W6qO_2D zRwcsYa*hs(EOI8@Ytbn(NSWzy(X<;x%eA3W$#g_L72&H`LSVr(w92LV%RGvs7CiWs zagf@}&y*U@9GEfPE-PH)OSbMG;$FXCM}D5(p+o&K$Mw!M=?cbHebY5JA<;Eq^F`ws z`tT(75)5wfD7O^#%>>l@hyp4VhL?3(EbR?aP*&}-)!76hm;>4%Pk5{hV{E$ZZH6=wD{MyE1N3^_?Mube z7SIk)#5{#%T;PwVsp}6_pYaLcI`8>HclB_T_9xnG_F0!|(V{FUN;8(9MjKEj7p^E6 zP4Q{4k($Mj{jw(RP{~vB0a%hFSlasI)Sty8=F78k-m;hU7+)6VNRJk!`Kg%(00gia zP|T<@3mGr30xc}CL3^3?35cBr*bQ&{=<*@5h-li787euE61^wLyRIc`d=%Qc7CNvk z52py2-NRI!!qe%74G@F>p$FjJAmc!n_SBYMmPA*V6G7EfisZ*4H&{&oJTkO@LNuC9 z=>tRNNI)(HRwcj^fgw9FGn-bKv!o&>SOUwP4>|CPFqe3v!Vei1$-tAO57Tp1j)zqD z6C9P#gfcOK{JLB))m4~dXs&-bnI4F0b+fWPG1&#+Ae*$;OZ+@Mb`?Th*q(5l$F5eq zxYajpHtek*CWkcpit#0Tc3U^{GgF-`61j%ob?~KgJvuPwJz21Fb#1)pl8!WvC?`mm zHRPX)4@QYJrYV0+k^}I+BLO5>dCvs(*kT@w2w?x$0;GozU3QbFF+Izx@rnf23T3>| z#g}qvX}&k3XgW0PgjHP;)g;$}osAu3Z=I)~)&_YgRLX6H_p$tz3Zj@sFn z6|~N9yq9;wMSj`|C-KL6E@mIh{;&vy&uGY5xO|ES|7-#~tpJ8!+mqHx(j^##gXXWo zLJuZRh3pRAEpx!*4aA^!6`t40`HcUK>i z!J(wGtmx9S8Z3Kr{(K=p>y*6?dpxWl`QM$0$<7{iSZ{XLOL!%$`KC$W_*6*IU?g+& zvE~A=B&Q@U;qtgWC@kG;Ps{SR#bECMYVXhcKmf2r|Fm7ss9T%RoT`PC=i~oeLr>i<%0y_?k`{&nSI~%W)lH?c1e_Y3k zrB`o+%YPzRKc4LsdH>dVBQytSusvLv&<@FC_?;9LWp!*hBpVr?;f;IbVhEP863Xf` znXgPsym>bL8h@9v)8Jfcyy6yFYj-zd>G~;nONUPQrCCZSM)DMToK=}5JvD|$TQ$MZ z?(y-zH`&)ukYDkT`z0s06*~ADXV^dtQMCWR{%MtyBUkQ2$D=h(lAu<5oia~=F0pDt z;(K9?YC%o{=|&{_AXTYs78O#32{XFv!(cLOKSB@%9DI> z%!{+$_8RiL*>1kSXlwhsl?P}ArB-id(#^cS22sP^srmLKy2>YZk8 zXZI?9#AkeUdos0a{p!pi{Xl)O+@#i>wC*vFrHl3av-nq6=$|wA!$2m`>rFT;$Pxic z)4GMyK9yzJF&gi3yW9~9mG9sDMegSz9<_Y)KK-($C9#Tw`FE8Lpe2C<2F-4NF%Ka3 zfTh$?%f7l5KCdMcrXM_og-q~j57nuQ0VWGCcP}d5H}d$Z;&&IT(vl*URhPjIhos4i z-%SpH;%f}R^2Pm8c0Y2@?asG}B*JC&+_jN!WH;Lh2BVS^B0*Xtp})vX=^C_w9`BZ< zPU!lb5y~B2eR25x{Gg**BxKAmD&9?GpIW8+PuF@t&jk6r^G(Hy#&*bJV^;W;()Xu& z-%5XP6WpT(S^w*yJ(40>PKhdlyKrEzW|t7Q6U`|u29MrE4OLTr1 zRTaEkz^J$~ps=Ot+`T=;NapN&eBN4x@@=SPJDlndLp&kQNuWqsE(*H-q!R z{?gbqoB#(67KI*lOWRRqO|$RK7n6<5fD!99TShDPPo<^iv$)@0yr2x?D4@3<@GP7B z=jVRgZcXr2iL%4Be9ogWYO)zm`__O&e?P+GNC@kWV z{zxpM_Vdt?P+VS>SmsNYhjoQ^muj_C_GxNayG|hW&NqF)a54h$b$p_lTau#eCitf9OKz02RvMzuww=n?x?gygTF){fM zmNETxu8Q$vR=w(}mJnLx!WLer>XFjSsG`a44-oJ`JCubGluAwVeuOkYQC3Z+Qpz;& EKZIOnr~m)} literal 0 HcmV?d00001 diff --git a/icons/confirmed.png b/icons/confirmed.png new file mode 100644 index 0000000000000000000000000000000000000000..901be189a6fca7d9d3f7efb2c5a494a5ec0b93ea GIT binary patch literal 1267 zcmV(G);P$p;kx>XP_3jgx;v64^oz(P$HEdhO+fyVb;Y=l74C{pt9#P8qQwek6QMfeLMqOrjB0$Q+a&4L{Z z=RFkkU|?98OxT=6^U06h)`N*X$pkkF0Pu~cqPZ)ITN>WjG;c~?G3pyuS7jB8w{IJH zjHWMoV%DA|RZDW1On79#69!lqaFD{`_D}f7-RJi8p5}D`AVP7P|4425cl9s5Q0g0} z!h?ZH6AQ$ejWu=QLRvW*JdjKI^Qwy*m#?VKV_}W}V`zQ6Yab5o__L|!1Zs!R$XXB^ zO6TWJ60!#u1^^ErMnzeLzo)kQy+D*&2YdO9no0WH$75eUy=G~VkQ^{P5HWaYf9u7A zXx`p-sOuN3U}kTaK=gOu*#mpOZoic71d{<4=8!e;Xw9O$vdX-@M3h~&Wc)X4>z7WK z6$VQNAelqfKT04|t3TsGVB+4du?ZC`O!{{`;3T~mw@5Ro=xDIHm`UMkn* zaZqI+6iJ030tr9}fXRgi6E3IWk%iwr_u5bIM@?@BcZ}82BQKem%~)w>-Nob7TvnA6 z4Qny@l`P0Y1qlM+!9fZsFM*_U0lyx&a=zmbuj=iv#st5C006q$QYRm%p16DVeEpSZ z_GBrdPKG80Kty2JNPB(w+W|U$xRU5Smbw0D(~;A-p3E_)7LA%{lt?7}>2zA(`q9e9 zWt%6IN3;THA_yXa2MgEGi$6}DzuMO1-?p&)sU`qsAP}$ufq%K?A*FZ1%8O?{`5 z{!}WZIgTSFDZ`cJh^5G~G3XB3p-{*ZLa-!BEQA0Nu_Q@Q6vZAG7%%}iH>U^y(9+T( z0g#i)q}t!#ucXsy)v_#wnH3_EBuTPWRkdVUwu8Z-ttg5e3?C)f_oWgjW+<%+gu+&a)B!EN99X@jJt=qGH8S7`< z|Kyp2=a==pxpTx@S&hKkOad^L0=u?4CR+A`J8zl3yZXMzz8^lh@XBi^Ir~;uY9($G z2>|ZyBw0R7`RecM#cPo@bMFQ<)-t1|gIEa3hp7hd_t(U`Tw;Q#B--ar(f z5Z=2tIsDyX5e@(cpIA8f>WP?z3kFdVDMISSRbG?KsCX1vg9sO1JrT3_Jh5;P0PK!O zPq%{T96g<>)^p(pYh{oGfa&+%q~5I4Cay$P}@mB5-8GSpvWp->WWwG8;6RT%nDV1 zZ^G|+XB!XQzKgegcnjy>WX`YXubXo%SQ1FUB>@6V21zhk4=y9GDZ< z#81Dm6N}4)aaDiaoNK`l5E9Z*?tvnK2f{#NX^>Z+0C4@mHvogT5<{98RE`ypIJ}iw zxpD`9v9@7z+niFlgVxTu7Ay!1AY}-GAk|j{<=I`g?PJS?d+MN>0gzLbu>yuF45PM!~;Bu-@kPa&Rxiw6B+`k z+ye+f4b7sWIXp-~RPVRh0HOpp14GU8tFi#C?u^wZaIq?cBJ?h?3N^i#Olici`DGq>@HM>omOSz1Y7&I+oJ#rFcdo$Hc-o_*44DSIoFvkS zyo|!?V<>{PeB@dX40z4hhhLgUH;9?7N#ppE78X1B)gMmds~_FftDi*VWqgqGO|ZfDVNmQ9n+_0@DbB z`3h=7DAc@>334hZ+KNnR#NM54{{Dek)amTQ#d9zWL&3=H9vmk)f=C(6Z;Tp3NF1_B zQBdAW55A%R2=0!;rdr&~>$O2t?-fGNOMxKLjD(ZWs+)UV9L)zBfC$3N9N6e86hV*b zHB`keD;E&KJbD^>q4GYdHiRfQ6LT;0y8q~@C4TnazhUu0=04=W5|qzOxA^ouS7OUV zt49aO)%&deDg=2%u>iLrm8PfywGk#EM0ih*=JfODj-%VnuxmPP)Lqj2xh@`iaSq@7 z|LT2)aK$=CM?ZmJ@WlWAaCdYchq$oZ4W>QC& zQiWE+l>}5D-ja}o2!*W1i7}APR{Z2fHdt5DnuCyWpwnP}x$O3E;TH8%=PYwWZ3KTN{@cd|iOa2p+nZeAQB%`5>8sL#du~88K z;gx3-uJRlN9Po3CT|e}vIheUuzv^0W9nZ}Cm%n=h6Kx-AOGJh=vaG}Wu8ab_ybZ0x zRbG|9b#sbu{rJzmv>d~{w-&GF*nrJriBCYr!LrbAuM%gh6O0=l=c(+xx!I8f)nqhZQGv0WyR7ah2C3 zGb$c&9L%zyojtGnjy>~<7glz!9Up)8@ZKH%zSS+M=vI1gmDeOQDjsc|0XR0#zn*&T z##x|m``v#1Gq3F4?z1f~!b$%pA!K>jbP1cA=i&M1ZyNkpgOav=?5TS#3H z@B25lVQ8iv9~+Q$i8G6a<&5_&Jb&|DO|mOAbHmeVmhpgq>(UgLTk-EUZ`Z$2lpjil pr7Xh{172*W{_u(4ern*t^gp1ELkYHEdl~=$002ovPDHLkV1j153{e08 literal 0 HcmV?d00001 diff --git a/icons/dark_background.png b/icons/dark_background.png new file mode 100644 index 0000000000000000000000000000000000000000..d106c09627b146ea464bbe955ac6d11a4e394152 GIT binary patch literal 28057 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 JDiOng{{dmy*_QwS literal 0 HcmV?d00001 diff --git a/icons/electrum-ixc.png b/icons/electrum-ixc.png new file mode 100644 index 0000000000000000000000000000000000000000..3c4876a1e4caef082476e17357b24bda3552ae46 GIT binary patch literal 12642 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 literal 0 HcmV?d00001 diff --git a/icons/electrum.ico b/icons/electrum.ico new file mode 100644 index 0000000000000000000000000000000000000000..3b4d53a0a700058758c5f52b61560d41f367f0d7 GIT binary patch literal 17790 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 literal 0 HcmV?d00001 diff --git a/icons/electrum.png b/icons/electrum.png new file mode 100644 index 0000000000000000000000000000000000000000..e07a7dc07fc1e4af61e1aed5f2256fbbc4906258 GIT binary patch literal 9322 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 VNPDbT9$gm%c&G3lTrOu3_8*h*D|!F` literal 0 HcmV?d00001 diff --git a/icons/electrum_dark_icon.png b/icons/electrum_dark_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e836a2fdb9fa46f08d2d4710682938a0eabdfee5 GIT binary patch literal 3872 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 literal 0 HcmV?d00001 diff --git a/icons/hot_seed.png b/icons/hot_seed.png new file mode 100644 index 0000000000000000000000000000000000000000..fa11e68796d791f3c19f4181a00c9887556cc330 GIT binary patch literal 9993 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 TUIRcf00000NkvXXu0mjf!nSu@ literal 0 HcmV?d00001 diff --git a/icons/key.png b/icons/key.png new file mode 100644 index 0000000000000000000000000000000000000000..4470abfe84fd7abd8d20072cd340ba1e434a5a17 GIT binary patch literal 5428 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/network.png b/icons/network.png new file mode 100644 index 0000000000000000000000000000000000000000..6a5bcba970804a39a01ba4cae4bd6992a2330e38 GIT binary patch literal 3031 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 Z@qe8?M#M5n{0jg8002ovPDHLkV1kvE;jsV! literal 0 HcmV?d00001 diff --git a/icons/preferences.png b/icons/preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..2596f3cc5eb500a4b866146ef4f2b1706b72aae4 GIT binary patch literal 1691 zcmV;M24wk(P)=DcaWxi`ep6rD=zgT=e~d=}J9qD}F$_7s`q|YEizS5|`skn}iemkqnuhA>Od1<& z=YcQ>WkT0iZmPWbV2+uh-byL8_=oQjLC}*;zuzomWMsVd>efH}ZYuNorrL6oIjMW? znu z41xgw9vKz^GrPEWi7*-oA~F_6Vv?E3$;q+mz&20RaP^I~Jj=4(E1oXTk|YW3U$pnJ zEE6yq41(EYg4vV=_Z_#UD9W)1&8y$8PBgK?^E{tGDL_O?L@*FSzq?RW!s;astnJYp^X-R2bN=hP949J?SuC07++xh!lQcAI>;f(^8WiLFv;wb~mvXidCk?Dl0sMz=BzGyTWS(lmN z=wx|xl$Mm{XU~|ywYZwaKp@bqC`yY)nH!a_R=Or#h5B6QY_Kecru~g$Nr{QRvSnp69NF1iOKYb?m#;8nq}$Qn-i9ZhSOAB^0axn@F&GSeX*O6^ zO=ms{FkNilv2`=Ya@F?COvB&_R#VE_lM+e_OwEcSlKYZ!b45N-c>PSl{TvcRe z{`~1Bl+PKFjOy^M;gOM9&#hf0*fMOeB&On%BZtM}qGDZURu)4w4euOyC)(fN-*o7M zzf?^LDBO7V7aWUsE0(4kiwn}on55v&&^_$`;G~*BrJN^c4!+3qeD&IjH9}gN6=}&< zgu+3H(ik*N1IH#{Z^K?O5{VQX{`g4${Ta;L*pd9>SI!-`S`yyf_Tp?)QGOZ;kIDFM zD1wWZZ>vNZJ9_o#7XO?3-hN9I#RF&0oD*X)2_D}7Mk8SagCX1t-Giczqj*UXuhZ%N z1OOZW8)S zHh%sO($Ui1C12>dbbX-fy?OvbTzXknxWf5`1%W^yb>_?*)?hGV?wmZ{JLFjdptZB3 z`BBL0xKoPgn2XR~~QeV6I-fA>O^#_A6y9AjWHGTx#F7>!&lb zGM!hiT(ghM5=*H@`}+DuJs!`YyFPyifE))<5+5297YiW4GG|$CY@jzFia`Q^kBf~9 z6QG|iU6Pw$khewCXwJ92msfm!p~nMY9Dp*>0il$F5Q6wACm_rNh7+2|PXH(Y4S<^E l$YMN$9w~0B#@8tT`frm{0s2>vdAk4r002ovPDHLkV1m?gC#wJe literal 0 HcmV?d00001 diff --git a/icons/qrcode.png b/icons/qrcode.png new file mode 100644 index 0000000000000000000000000000000000000000..41a84aa1d424088bc50edb767a4037d3c30f8c29 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X?s&R5hE&{2`t$$4J+o?qAcsSVvOxCYldTLNrF3#6c5of} zsvzu8Av?wG`TE03ZHLmEX0a_cU+{6}hK_|FF7k35ICOk<8|$e=wnu9t4sobF>-Fc= z5h!ew4YG(TCGEosZ`os>VCTH>XuYUWgE zsAmcAT_rRUhk!^Z5wub0iOibUJ_pb>_o-*|&H5-TV1=U2)pNiULj})fW3Ycs^U{C* zj-xG(stmLWpuJW^Jc+=2hA^;>4%)_3{h=BFff2s^9(fW@)jNAZGWUY=nYys+EIbdt zMkx^XOQ=L(tYMcDl=p^r2}p!z?UPO{=}I+SayU@$m!uBy8z7{0eNddt=zY~UG{)gbV0xidjs~XoM#m3`AFx<;$hAetLcGbUVL{X?AmMgK6 z8-DcZ>~CDTyqMoH%kq0*Ue`|2~py^0e`aTihSdu2LIZmNwW^`%BLxh5h)K{-&3wru0PJ) z`@oMNd_csmo_`9p>JuU@Ktoj@zOcqz9#P=eDJUEr%$m%#$>N5{M46iHDqjhG z9B<-6+i!9Y2ts}T0pM+q)Lr`A7>mCzr&iHK4S~ z;vWc97>eRSzoqN-e^!B#h9ZWcxbyc5f^|X=883RybwAo>>@Fzn2L40f(-qhepccdmz*Fc_LR$&ArZ)$YKHZ;QLxXcY&<3nN3{l&2#J? zAIMhuM~Dc5h19ry#}UraOO)!z0uue;j}3*X6(95Le(R znS5AdDq!x8Tys9EMx}T0>s8cQ@SMz-0g@ay#E_qlWJ2yaqqD4X_X+dY4kG?O7rS+o zYqp{>qt_By$-jE;%KB6eob7|wAHi8Hv_4nfQkh_w{c0nz)_3MTt@U)*(*#Q?%hgvN2;Aovj#NWj2A~#

ERd2S{ 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + + + Record + + + record + media + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/status_lagging.png b/icons/status_lagging.png new file mode 100644 index 0000000000000000000000000000000000000000..5aec99f58a12a8fc92e65f93010704b76d63d475 GIT binary patch literal 1036 zcmV+n1oQieP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2i*z- z4-gmlJi@gA00WFkL_t(I%dM1MYn(+C$A4#Lo|kOW?XIRRl}KBxtP!;oD+a_638GN_ z79kg98p#N&*ffpFn2+w5i{#VXL6PE09JG^8r3R_DL^MH?>!&b=!i7;C?I^R2fF@0>dy z37%-Qgct*W_nv;cfr{n#-jD2ASPbrqlWNp`pC?bi4AcAeht zHp$L5d77}Z@sMKZsZ=V3ESD=oju{#d7sf75R?bG%l|@__k?z&WJ9YAI1K(}pyG`zeMVvv?Hb+aZGOX2u!Zw;> zonXY^tl*4b%@8O9ppq-(Ua`4iMDZ5T^vO=KMwVKw*7S)uhNMU69)}(Ry;pLtWS#@% z8ji5lYGREn9k`r%yz$!-xVy=nR21I3t8nOuf0AW?ru! z)}i`^`~TE4T!eE0&dNS?02>*=!a*`;1ZN-!L$Dz$|JF0qFB|}`F6zy!-@Eqf@_G`E zmJq-g!CJvtAqotU+fQPRUk-a0Br4~ ztTp?7c|FM+oqXwshx%o8k4HcaSbG9EfEIyqp#1&>A08VsQ!f`d=M1L-(wx=Wp5EDP z>#f^s{0y{!DzK@l*>eZ%0BnJg$07m*$be)J9iXRA0saHuQ_+O{e`8Pp0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2iyY^ z3n2yMIGw!!00mu1L_t(Y$F){lY*bYgUFUIMGtIl%wC$bJ8Y!?gUg5poG1N4XS4ifBpFZfR%;yZ75RdD*+c zzrNnm1pxeB0hKFuJk1SbEpMh%tTJD|Zg8JQ82}LzuG77sd|%t`So}gd6W{gsv27QJ z?k!y&4hSLI0q7$tsCqc;V-tdhg28c%90^Mi0!k?uV_=MeQ3}pEay%OR9u00L+1uLQ z+0-8C-Pu_GN_}YYc7IK6@eh^d<4fLpX-V*|3KU@zb{{P*D_I;%+8|IcGy+Z2U}zjl z5x5E<1W4NwhOXfE`|}>1R4`xJnHfJ9?%!_YD@gs-8`4YkFZ~;n)o`t4gcXKaD;*!BK;r%r8IQ2JV?}_$}&(F{Q*q>`P<$AoAq?FfOsE*M_@$Bat zKWI49yy4u1fBHD1pp+nGOQdW8N~j!Gfj0^_>2Zwe%F+e~JxRHnvZ?8?o3KYCsD9$T z;`tAT_RN}5k(;(%2&s^=1yZ&I$Xya$Xb8tc%ieiE$8Vm0b5*572vPSlQfTpZ|D0K6 z$5%c!yCRVh$hA09wt~hPyrzaoijfgcu3oe2L&MM*B@`M57@_?FN+4s~f!B3OygG#| z6##+HzB+xrt3CGpK`Zti7hk4C^WK1NDW9#1<{y89B;?41xVE|Q_2BqY9>$0 z8xyGWc|O|E)zi24a&6zI2#4k1`9+UB5RD}Ycl+VkH_RSvK*8OU1O(JMXNo5V5w<%#^|QUtGMowLXnJ}if59EF6pGMB|5JixPEHS2>|IK$P75y$e+HV zFmnD#41kfn?uLQ`pq!hUSx`NWTVrz=)r1r8i1fAo)(XJRA~OVO0P5~bpJyx5vtOQ- zaX`v}c$tL&;AY`u6T1M^e|uHjS#(JJz-Bcx(P-;m+SqXb@Dz@x00000NkvXXu0mjf Dz+SxI literal 0 HcmV?d00001 diff --git a/icons/status_waiting.svg b/icons/status_waiting.svg new file mode 100644 index 00000000..fb51a42b --- /dev/null +++ b/icons/status_waiting.svg @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + View Refresh + + + reload + refresh + view + + + + + Ricardo 'Rick' González + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/switchgui.png b/icons/switchgui.png new file mode 100644 index 0000000000000000000000000000000000000000..ec18650d7a60d131d2be098860734acb72fcbd1d GIT binary patch literal 1649 zcmV-%29EiOP)6z``>}FTkf}wlft5@&; ze^swuy%|`M6q zB~rzELz6b|6;&hhxv@SsHqpUH(79_D>+XJm^FO>dCxLr5Mick#{h6LQTo~X2N6-og z!+@aW2wRRY2nYf}BzB_{B?uuvkv3q47zhStfI;%W9GIXMAO@xeYN&ykVG8C!oFF0? z!t}PC{PgY@>p5S<>Z%C*ar7^)M3xu;aSkVf3k2tqPbdT}hXmk)crsjn(s*3LP6R~y zI_Y;}Jw(7I{eY3Yi=Y<2uWlKW>o*Kwtt8N!HN?5ha0VjXH3?8A3?xX%dekU}BhnB{ozQ z5y4>@Xaq!4vPO<^97Y0YqKhEF<*xG0@ynPA58u9qFmODz{{-(myNOOudHLWe0_Xa6 z>Ue-W_yQ@z05!u5RO4sbj`gvc#Uw0eAYBYZ(42h}Dd@FB$Hk7aacv7H>B>~%ul9f? zMpI81DX4hEsWU_saY>9SII+?MmU$~h_u7v2+`D-)(|Bm#pKMvz=I|?90Jzxks0n*_ z-oTziXXr(6;JF)l>EJ1Z)C+Y9n4%UBQ;0K)8DffP9PgrniI95OnP9}(C$=L6o3DO$ z4t%^MW)R}o@%9Ncb%%j-!k$BC5P|Ww>xE=lA{i~NPE4gtLi56F;-Mv3>HUawaKO{rFr2IaJRo7X0u ztH`U8ZnxXdGz=;1Xt)P7t*7S!y2+|XQ8Zv@0DRWo>i2rRflWGU)dxaI>JmtXErh5lQ50pshk>8V8;!D1?19n1=34bAiVBBO zlaMJB&9YE!4~#gvM~U|yRn3{Hcb%M*NYis**oG+sQ`HRcun?Kg{kZxZfCihmn6lD5 zU0&Vtq>FK>FYbXxS;!GZ5s@zfTu5Mb^a~!Sd!eB`c(GQs2KXE(u)#a!$aA2|*g~)L zFr5KCanQLi4om<&zz_F8I0jV5_^`?68zyzYOPYmR6Wf6Mft!IzK*}CS2$?aaa`FO9 zjwO>62=yZ^eos$VOFY;2I%bL0q_5ykOO@gUEBqwi?|bv>F32hf!aIORlFmy&uS`II zkl#Q0gsqS7y7P^*eU$lnBr7%2k1O>{^2bQ7p9AUIXHo5P?DOxL zK6?r{51a$0fZnL%whTuq+80|a_sO@d$cikK{0Aekn@j!H(EtDd03~!qSaf7zbY(hY za%Ew3WdJfTF)%GKGA%JMR539+F*G_gHZ3qVIxsNVl~St!001R)MObuXVRU6WZEs|0 vW_bWIFfceRFf=VNGE^}&IyE#pG&n6VH99ab>0%Da00000NkvXXu0mjfvqI^8 literal 0 HcmV?d00001 diff --git a/icons/trustedcoin.png b/icons/trustedcoin.png new file mode 100644 index 0000000000000000000000000000000000000000..2153866a66b0600350f245d89e762a6c4f0de607 GIT binary patch literal 3727 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 Y1#Gf$Vc%2N4FCWD07*qoM6N<$f|hXf0{{R3 literal 0 HcmV?d00001 diff --git a/icons/unconfirmed.svg b/icons/unconfirmed.svg new file mode 100644 index 00000000..36560ca4 --- /dev/null +++ b/icons/unconfirmed.svg @@ -0,0 +1,562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + System Run + + + + run + launch + exec + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/unlock.png b/icons/unlock.png new file mode 100644 index 0000000000000000000000000000000000000000..10787e539f937b28c71b02c038a1f83a6780e7ff GIT binary patch literal 2166 zcmV-+2#NQJP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2i*e^ z0TC)h(Qk?X00;I-L_t(o!|j=Ej9o<;$A8b9Ip?1Hvb(o?yOb_(Dj^k0F`BgHB}jQ*G=29laIkQj+3CK|1hX!->uDxYeVFKTE5)bdsdw9qascem~C z-j{RFIWvzR&fTSph39ufBTtTPiYTjJbSr@)9Q3 zPg1Y1!CJeluc|UPcZQR1p5)lEW341jerCyjxP5!`&HoDEojZ3<7^{B(wybTeW%HJ; zG{zg0N-5?Gd>9O7 zn9gyUVHsDW@l%~(sXGN#t7r%Yq;X_ z%h|f+h9E43dv@)5@XBE@*p+sC=%MD?%<-LSwZipVZz#52grwJFW@d(e9y-YJLGp=-$11Pp_(lMff5LS6ucHM2gctJ3GsvLkE4Q)43<T+1wC?eEqBZvq|lHk4P z)Tx=hJHGqU%wvp^0^Cf=o)bxV{L$lpz3kX z(NDA1N(N7DzxUTDhu@ff1Lxd;-vPDi2x8=_3j$cgU;|rtLuF~=l~GDmjs7FgbFwrm z+Kd5#QmM4|LI9Q^Fd#BuhzZo*tUVPT;|r_%;?RLT(}wJK{ytJKG8|KVHDl^cvzLRy`iZnrlG9*QxBaw%A% zieRXWt)n)!hW6a)8&|?%8(0HDNNse2BuPo>5&8}$6*N^0N?5K?s*O+@9i_Zx47Cx8+~A=PSy`q=2=%Zo#Ho^s2&kI_#v7CL>hJmt2VHxotS(ps~Am${iE z!@D&xhW6>#>CT_PhGoJqrXCAE%u)3qIVMl(oSIwG7h>!=A*(vx3T}$3!+1~R9rLX> z@ajIQv^wUx4QqqdN%KDlS+#G2z>~tuj~C^cV*bmtvm zSfW&^62(<)sX`D{Fg6A;xI884bphs909YUI^?G+b{+r!gGCKHM3%T%Q^S_H=BPtaV}i{26?mBKmSu>Z2$lO07*qoM6N<$f_Z` + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/unpaid.png b/icons/unpaid.png new file mode 100644 index 0000000000000000000000000000000000000000..6400b8ba62b7c51ab9a7639d4239ae49475607a4 GIT binary patch literal 28522 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 N<~?22GG)uq{{tA31VI1* literal 0 HcmV?d00001 diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 00000000..053dd4d2 --- /dev/null +++ b/lib/__init__.py @@ -0,0 +1,16 @@ +from version import ELECTRUM_VERSION +from util import format_satoshis, print_msg, print_json, print_error, set_verbosity +from wallet import WalletSynchronizer, WalletStorage +from wallet import Wallet, Wallet_2of2, Wallet_2of3, Imported_Wallet +from verifier import TxVerifier +from network import Network, DEFAULT_SERVERS, DEFAULT_PORTS, pick_random_server +from interface import Interface +from simple_config import SimpleConfig, get_config, set_config +import bitcoin +import account +import transaction +from transaction import Transaction +from plugins import BasePlugin +from commands import Commands, known_commands +from daemon import NetworkServer +from network_proxy import NetworkProxy diff --git a/lib/account.py b/lib/account.py new file mode 100644 index 00000000..8ad36057 --- /dev/null +++ b/lib/account.py @@ -0,0 +1,419 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2013 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import bitcoin +from bitcoin import * +from i18n import _ +from transaction import Transaction, is_extended_pubkey +from util import print_msg + + +class Account(object): + def __init__(self, v): + self.receiving_pubkeys = v.get('receiving', []) + self.change_pubkeys = v.get('change', []) + # addresses will not be stored on disk + self.receiving_addresses = map(self.pubkeys_to_address, self.receiving_pubkeys) + self.change_addresses = map(self.pubkeys_to_address, self.change_pubkeys) + + def dump(self): + return {'receiving':self.receiving_pubkeys, 'change':self.change_pubkeys} + + def get_pubkey(self, for_change, n): + pubkeys_list = self.change_pubkeys if for_change else self.receiving_pubkeys + return pubkeys_list[n] + + def get_address(self, for_change, n): + addr_list = self.change_addresses if for_change else self.receiving_addresses + return addr_list[n] + + def get_pubkeys(self, for_change, n): + return [ self.get_pubkey(for_change, n)] + + def get_addresses(self, for_change): + addr_list = self.change_addresses if for_change else self.receiving_addresses + return addr_list[:] + + def derive_pubkeys(self, for_change, n): + pass + + def create_new_address(self, for_change): + pubkeys_list = self.change_pubkeys if for_change else self.receiving_pubkeys + addr_list = self.change_addresses if for_change else self.receiving_addresses + n = len(pubkeys_list) + pubkeys = self.derive_pubkeys(for_change, n) + address = self.pubkeys_to_address(pubkeys) + pubkeys_list.append(pubkeys) + addr_list.append(address) + print_msg(address) + return address + + def pubkeys_to_address(self, pubkey): + return public_key_to_bc_address(pubkey.decode('hex')) + + def has_change(self): + return True + + def get_name(self, k): + return _('Main account') + + def redeem_script(self, for_change, n): + return None + + def synchronize_sequence(self, wallet, for_change): + limit = self.gap_limit_for_change if for_change else self.gap_limit + while True: + addresses = self.get_addresses(for_change) + if len(addresses) < limit: + address = self.create_new_address(for_change) + wallet.add_address(address) + continue + if map( lambda a: wallet.address_is_old(a), addresses[-limit:] ) == limit*[False]: + break + else: + address = self.create_new_address(for_change) + wallet.add_address(address) + + def synchronize(self, wallet): + self.synchronize_sequence(wallet, False) + self.synchronize_sequence(wallet, True) + + +class PendingAccount(Account): + def __init__(self, v): + self.pending_address = v['pending'] + + def synchronize(self, wallet): + return + + def get_addresses(self, is_change): + return [] if is_change else [self.pending_address] + + def has_change(self): + return False + + def dump(self): + return {'pending':self.pending_address } + + def get_name(self, k): + return _('Pending account') + + def get_master_pubkeys(self): + return [] + + def get_type(self): + return _('pending') + +class ImportedAccount(Account): + def __init__(self, d): + self.keypairs = d['imported'] + + def synchronize(self, wallet): + return + + def get_addresses(self, for_change): + return [] if for_change else sorted(self.keypairs.keys()) + + def get_pubkey(self, *sequence): + for_change, i = sequence + assert for_change == 0 + addr = self.get_addresses(0)[i] + return self.keypairs[addr][0] + + def get_xpubkeys(self, for_change, n): + return self.get_pubkeys(for_change, n) + + def get_private_key(self, sequence, wallet, password): + from wallet import pw_decode + for_change, i = sequence + assert for_change == 0 + address = self.get_addresses(0)[i] + pk = pw_decode(self.keypairs[address][1], password) + # this checks the password + assert address == address_from_private_key(pk) + return [pk] + + def has_change(self): + return False + + def add(self, address, pubkey, privkey, password): + from wallet import pw_encode + self.keypairs[address] = (pubkey, pw_encode(privkey, password )) + + def remove(self, address): + self.keypairs.pop(address) + + def dump(self): + return {'imported':self.keypairs} + + def get_name(self, k): + return _('Imported keys') + + def update_password(self, old_password, new_password): + for k, v in self.keypairs.items(): + pubkey, a = v + b = pw_decode(a, old_password) + c = pw_encode(b, new_password) + self.keypairs[k] = (pubkey, c) + + +class OldAccount(Account): + """ Privatekey(type,n) = Master_private_key + H(n|S|type) """ + gap_limit = 5 + gap_limit_for_change = 3 + + def __init__(self, v): + Account.__init__(self, v) + self.mpk = v['mpk'].decode('hex') + + + @classmethod + def mpk_from_seed(klass, seed): + curve = SECP256k1 + secexp = klass.stretch_key(seed) + master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 ) + master_public_key = master_private_key.get_verifying_key().to_string().encode('hex') + return master_public_key + + @classmethod + def stretch_key(self,seed): + oldseed = seed + for i in range(100000): + seed = hashlib.sha256(seed + oldseed).digest() + return string_to_number( seed ) + + @classmethod + def get_sequence(self, mpk, for_change, n): + return string_to_number( Hash( "%d:%d:"%(n,for_change) + mpk ) ) + + def get_address(self, for_change, n): + pubkey = self.get_pubkey(for_change, n) + address = public_key_to_bc_address( pubkey.decode('hex') ) + return address + + @classmethod + def get_pubkey_from_mpk(self, mpk, for_change, n): + curve = SECP256k1 + z = self.get_sequence(mpk, for_change, n) + master_public_key = ecdsa.VerifyingKey.from_string( mpk, curve = SECP256k1 ) + pubkey_point = master_public_key.pubkey.point + z*curve.generator + public_key2 = ecdsa.VerifyingKey.from_public_point( pubkey_point, curve = SECP256k1 ) + return '04' + public_key2.to_string().encode('hex') + + def derive_pubkeys(self, for_change, n): + return self.get_pubkey_from_mpk(self.mpk, for_change, n) + + def get_private_key_from_stretched_exponent(self, for_change, n, secexp): + order = generator_secp256k1.order() + secexp = ( secexp + self.get_sequence(self.mpk, for_change, n) ) % order + pk = number_to_string( secexp, generator_secp256k1.order() ) + compressed = False + return SecretToASecret( pk, compressed ) + + + def get_private_key(self, sequence, wallet, password): + seed = wallet.get_seed(password) + self.check_seed(seed) + for_change, n = sequence + secexp = self.stretch_key(seed) + pk = self.get_private_key_from_stretched_exponent(for_change, n, secexp) + return [pk] + + + def check_seed(self, seed): + curve = SECP256k1 + secexp = self.stretch_key(seed) + master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 ) + master_public_key = master_private_key.get_verifying_key().to_string() + if master_public_key != self.mpk: + print_error('invalid password (mpk)', self.mpk.encode('hex'), master_public_key.encode('hex')) + raise Exception('Invalid password') + return True + + def get_master_pubkeys(self): + return [self.mpk.encode('hex')] + + def get_type(self): + return _('Old Electrum format') + + def get_xpubkeys(self, for_change, n): + s = ''.join(map(lambda x: bitcoin.int_to_hex(x,2), (for_change, n))) + mpk = self.mpk.encode('hex') + x_pubkey = 'fe' + mpk + s + return [ x_pubkey ] + + @classmethod + def parse_xpubkey(self, x_pubkey): + assert is_extended_pubkey(x_pubkey) + pk = x_pubkey[2:] + mpk = pk[0:128] + dd = pk[128:] + s = [] + while dd: + n = int(bitcoin.rev_hex(dd[0:4]), 16) + dd = dd[4:] + s.append(n) + assert len(s) == 2 + return mpk, s + + +class BIP32_Account(Account): + gap_limit = 20 + gap_limit_for_change = 3 + + def __init__(self, v): + Account.__init__(self, v) + self.xpub = v['xpub'] + self.xpub_receive = None + self.xpub_change = None + + def dump(self): + d = Account.dump(self) + d['xpub'] = self.xpub + return d + + def first_address(self): + pubkeys = self.derive_pubkeys(0, 0) + address = self.pubkeys_to_address(pubkeys) + return address + + def get_master_pubkeys(self): + return [self.xpub] + + @classmethod + def derive_pubkey_from_xpub(self, xpub, for_change, n): + _, _, _, c, cK = deserialize_xkey(xpub) + for i in [for_change, n]: + cK, c = CKD_pub(cK, c, i) + return cK.encode('hex') + + def get_pubkey_from_xpub(self, xpub, for_change, n): + xpubs = self.get_master_pubkeys() + i = xpubs.index(xpub) + pubkeys = self.get_pubkeys(sequence, n) + return pubkeys[i] + + def derive_pubkeys(self, for_change, n): + xpub = self.xpub_change if for_change else self.xpub_receive + if xpub is None: + xpub = bip32_public_derivation(self.xpub, "", "/%d"%for_change) + if for_change: + self.xpub_change = xpub + else: + self.xpub_receive = xpub + _, _, _, c, cK = deserialize_xkey(xpub) + cK, c = CKD_pub(cK, c, n) + result = cK.encode('hex') + return result + + + def get_private_key(self, sequence, wallet, password): + out = [] + xpubs = self.get_master_pubkeys() + roots = [k for k, v in wallet.master_public_keys.iteritems() if v in xpubs] + for root in roots: + xpriv = wallet.get_master_private_key(root, password) + if not xpriv: + continue + _, _, _, c, k = deserialize_xkey(xpriv) + pk = bip32_private_key( sequence, k, c ) + out.append(pk) + return out + + def get_type(self): + return _('Standard 1 of 1') + + def get_xpubkeys(self, for_change, n): + # unsorted + s = ''.join(map(lambda x: bitcoin.int_to_hex(x,2), (for_change,n))) + xpubs = self.get_master_pubkeys() + return map(lambda xpub: 'ff' + bitcoin.DecodeBase58Check(xpub).encode('hex') + s, xpubs) + + @classmethod + def parse_xpubkey(self, pubkey): + assert is_extended_pubkey(pubkey) + pk = pubkey.decode('hex') + pk = pk[1:] + xkey = bitcoin.EncodeBase58Check(pk[0:78]) + dd = pk[78:] + s = [] + while dd: + n = int( bitcoin.rev_hex(dd[0:2].encode('hex')), 16) + dd = dd[2:] + s.append(n) + assert len(s) == 2 + return xkey, s + + def get_name(self, k): + return "Main account" if k == '0' else "Account " + k + + + + +class BIP32_Account_2of2(BIP32_Account): + + def __init__(self, v): + BIP32_Account.__init__(self, v) + self.xpub2 = v['xpub2'] + + def dump(self): + d = BIP32_Account.dump(self) + d['xpub2'] = self.xpub2 + return d + + def get_pubkeys(self, for_change, n): + return self.get_pubkey(for_change, n) + + def derive_pubkeys(self, for_change, n): + return map(lambda x: self.derive_pubkey_from_xpub(x, for_change, n), self.get_master_pubkeys()) + + def redeem_script(self, for_change, n): + pubkeys = self.get_pubkeys(for_change, n) + return Transaction.multisig_script(sorted(pubkeys), 2) + + def pubkeys_to_address(self, pubkeys): + redeem_script = Transaction.multisig_script(sorted(pubkeys), 2) + address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5) + return address + + def get_address(self, for_change, n): + return self.pubkeys_to_address(self.get_pubkeys(for_change, n)) + + def get_master_pubkeys(self): + return [self.xpub, self.xpub2] + + def get_type(self): + return _('Multisig 2 of 2') + + +class BIP32_Account_2of3(BIP32_Account_2of2): + + def __init__(self, v): + BIP32_Account_2of2.__init__(self, v) + self.xpub3 = v['xpub3'] + + def dump(self): + d = BIP32_Account_2of2.dump(self) + d['xpub3'] = self.xpub3 + return d + + def get_master_pubkeys(self): + return [self.xpub, self.xpub2, self.xpub3] + + def get_type(self): + return _('Multisig 2 of 3') diff --git a/lib/auxpow.py b/lib/auxpow.py new file mode 100644 index 00000000..8a8ed98e --- /dev/null +++ b/lib/auxpow.py @@ -0,0 +1,224 @@ +# https://github.com/kR105/i0coin/compare/bitcoin:master...master#diff-d3b948fe89a5d012a7eaeea8f25d7c42R1 +import string +import btcutils + +BLOCK_VERSION_CHAIN_START = (1 << 16) + +def get_our_chain_id(): + return 0x0003 #ixcoin + +def get_chain_id(header): + return header['version'] / BLOCK_VERSION_CHAIN_START + +def check_merkle_branch(hash, merkle_branch, index): + return btcutils.check_merkle_branch(hash, merkle_branch, index) + +# https://github.com/kR105/i0coin/compare/bitcoin:master...master#diff-610df86e65fce009eb271c2a4f7394ccR262 +def calc_merkle_index(chain_id, nonce, merkle_size): + rand = nonce + rand = (rand * 1103515245 + 12345) & 0xffffffff + rand += chain_id + rand = (rand * 1103515245 + 12345) & 0xffffffff + return rand % merkle_size + +def verify(auxhash, chain_id, auxpow): + parent_block = auxpow['parent_block'] + coinbase = auxpow['coinbasetx'] + coinbase_hash = coinbase['txid'] + + chain_merkle_branch = auxpow['chainMerkleBranch'] + chain_index = auxpow['chainIndex'] + + coinbase_merkle_branch = auxpow['coinbaseMerkleBranch'] + coinbase_index = auxpow['coinbaseIndex'] + + #if (get_chain_id(parent_block) == chain_id) + # return error("Aux POW parent has our chain ID"); + + if (get_chain_id(parent_block) == chain_id): + print 'Aux POW parent has our chain ID' + return False + + #// Check that the chain merkle root is in the coinbase + #uint256 nRootHash = CBlock::CheckMerkleBranch(hashAuxBlock, vChainMerkleBranch, nChainIndex); + #vector vchRootHash(nRootHash.begin(), nRootHash.end()); + #std::reverse(vchRootHash.begin(), vchRootHash.end()); // correct endian + + # Check that the chain merkle root is in the coinbase + root_hash = check_merkle_branch(auxhash, chain_merkle_branch, chain_index) + + # Check that we are in the parent block merkle tree + # if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != parentBlock.hashMerkleRoot) + # return error("Aux POW merkle root incorrect"); + if (check_merkle_branch(coinbase_hash, coinbase_merkle_branch, coinbase_index) != parent_block['merkle_root']): + print 'Aux POW merkle root incorrect' + return False + + #// Check that the same work is not submitted twice to our chain. + #// + + #CScript::const_iterator pcHead = + #std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)); + + #CScript::const_iterator pc = + #std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end()); + + #if (pc == script.end()) + #return error("Aux POW missing chain merkle root in parent coinbase"); + + script = coinbase['vin'][0]['coinbase'] + pos = string.find(script, root_hash) + + # todo: if pos == -1 ?? + if pos == -1: + print 'Aux POW missing chain merkle root in parent coinbase' + return False + + #todo: make sure only submitted once + #if (pcHead != script.end()) + #{ + #// Enforce only one chain merkle root by checking that a single instance of the merged + #// mining header exists just before. + #if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader))) + #return error("Multiple merged mining headers in coinbase"); + #if (pcHead + sizeof(pchMergedMiningHeader) != pc) + #return error("Merged mining header is not just before chain merkle root"); + #} + #else + #{ + #// For backward compatibility. + #// Enforce only one chain merkle root by checking that it starts early in the coinbase. + #// 8-12 bytes are enough to encode extraNonce and nBits. + #if (pc - script.begin() > 20) + #return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase"); + #} + + + #// Ensure we are at a deterministic point in the merkle leaves by hashing + #// a nonce and our chain ID and comparing to the index. + #pc += vchRootHash.size(); + #if (script.end() - pc < 8) + #return error("Aux POW missing chain merkle tree size and nonce in parent coinbase"); + + pos = pos + len(root_hash) + if (len(script) - pos < 8): + print 'Aux POW missing chain merkle tree size and nonce in parent coinbase' + return false + + #int nSize; + #memcpy(&nSize, &pc[0], 4); + #if (nSize != (1 << vChainMerkleBranch.size())) + #return error("Aux POW merkle branch size does not match parent coinbase"); + + def hex_to_int(s): + s = s.decode('hex')[::-1].encode('hex') + return int(s, 16) + + size = hex_to_int(script[pos:pos+8]) + nonce = hex_to_int(script[pos+8:pos+16]) + + #print 'size',size + #print 'nonce',nonce + #print '(1 << len(chain_merkle_branch)))', (1 << len(chain_merkle_branch)) + #size = hex_to_int(script[pos:pos+4]) + #nonce = hex_to_int(script[pos+4:pos+8]) + + if (size != (1 << len(chain_merkle_branch))): + print 'Aux POW merkle branch size does not match parent coinbase' + return False + + #int nNonce; + #memcpy(&nNonce, &pc[4], 4); + #// Choose a pseudo-random slot in the chain merkle tree + #// but have it be fixed for a size/nonce/chain combination. + #// + #// This prevents the same work from being used twice for the + #// same chain while reducing the chance that two chains clash + #// for the same slot. + #unsigned int rand = nNonce; + #rand = rand * 1103515245 + 12345; + #rand += nChainID; + #rand = rand * 1103515245 + 12345; + + #if (nChainIndex != (rand % nSize)) + #return error("Aux POW wrong index"); + + index = calc_merkle_index(chain_id, nonce, size) + #print 'index', index + + if (chain_index != index): + print 'Aux POW wrong index' + return False + + return True + + +if __name__ == "__main__": + #testing + #auxpow= { + #'parent_block':{ + #'merkle_root':'11feeb10dd38c4c7f5069113fdc9d98509e431abbd4b4746951c7b5ca8872d86', + #'nonce':220414812, + #'previousblockhash':'0000000000000191065f88ab70f4103ff11f060ba916f1e0c0354451e4709824', + #'hash':'00000000002a20a2839a0802830a7fe3e2def157f5df7edfa8771cf5e8c0a9cc', + #'version':1, + #'time':1325305711, + #'bits':'1a0e76ba' + #}, + #'chainMerkleBranch':[ + #'1d18e96bcbb4632d89c85145b1f65c4da5c099215edaeb882773a28ea2efdca4', + #'66000ba5cecf913ef18854823312921ad97869dd37de07a36d563cbe97a9d879' + #], + #'coinbaseMerkleBranch':[ + #'37758df045b2fc1548c052153adbe67768cef6a733d0b6d2063cc1e3ff21b5c3', + #'3d65957eaa177b49ba38de1e48fa1a972d189fc2d0d86781d052ece71b2943cd', + #'090e0e458d262d4fa5a56ddd44677aef742d58d26fa431475ae3b87732dcee6a', + #'74aecba6f266ab3fddd6846745802d12d85534fb7b06d5fa0bc927e9ce5267b0', + #'eda7e0398b46616358bb15b892f35007e7329b7e5752c252f49c43928883ee34', + #'0a4c49d9319698e89638b69d68b514ef70314d26cb4fdda6fe951b429be100b3' + #], + #'coinbaseIndex':0, + #'chainIndex':1, + #'coinbasetx':{ + #'locktime':0, + #'version':1, + #'vin':[ + #{ + #'coinbase':'04ba760e1a0155522cfabe6d6dc52d147bbf91815a4b534506729896920e6f39980d8e8d4ef78fa4429b1516c80400000000000000', + #'sequence':4294967295 + #} + #], + #'vout':[ + #{ + #'n':0, + #'value':50.02165, + #'scriptPubKey':{ + #'reqSigs':1, + #'hex':'4104bb8a2a4d2351687274e3daed6b3f7303c7115e593bce6b908a096f0ac071067fb820b0a7b12f0cdeac9bcf1ad1f19b4ecce90cf6a953d05dabed19b42557cadfac', + #'addresses':[ + #'xd3k7hgQHHD6rdeGToCm2G8Z26LK1LjK9S' + #], + #'asm':'04bb8a2a4d2351687274e3daed6b3f7303c7115e593bce6b908a096f0ac071067fb820b0a7b12f0cdeac9bcf1ad1f19b4ecce90cf6a953d05dabed19b42557cadf OP_CHECKSIG', + #'type':'pubkey' + #} + #} + #], + #'txid':'87c04be9d0522cc17fbb35828f4eb583328cf0e5b4616f2415fc018e6ef94196' + #}, + #'size':558 + #} + auxpow = {'parent_block': {'nonce': 220414812, 'prev_block_hash': '0000000000000191065f88ab70f4103ff11f060ba916f1e0c0354451e4709824', 'timestamp': 1325305711, 'merkle_root': '11feeb10dd38c4c7f5069113fdc9d98509e431abbd4b4746951c7b5ca8872d86', 'version': 1, 'bits': 437155514}, 'chainMerkleBranch': ['1d18e96bcbb4632d89c85145b1f65c4da5c099215edaeb882773a28ea2efdca4', '66000ba5cecf913ef18854823312921ad97869dd37de07a36d563cbe97a9d879'], 'coinbaseMerkleBranch': ['37758df045b2fc1548c052153adbe67768cef6a733d0b6d2063cc1e3ff21b5c3', '3d65957eaa177b49ba38de1e48fa1a972d189fc2d0d86781d052ece71b2943cd', '090e0e458d262d4fa5a56ddd44677aef742d58d26fa431475ae3b87732dcee6a', '74aecba6f266ab3fddd6846745802d12d85534fb7b06d5fa0bc927e9ce5267b0', 'eda7e0398b46616358bb15b892f35007e7329b7e5752c252f49c43928883ee34', '0a4c49d9319698e89638b69d68b514ef70314d26cb4fdda6fe951b429be100b3'], 'coinbaseIndex': 0, 'coinbasetx': {'lockTime': 0, 'version': 1, 'vin': [{'coinbase': '04ba760e1a0155522cfabe6d6dc52d147bbf91815a4b534506729896920e6f39980d8e8d4ef78fa4429b1516c80400000000000000', 'sequence': 4294967295}], 'vout': [{'value': 5002165000, 'scriptPubKey': '4104bb8a2a4d2351687274e3daed6b3f7303c7115e593bce6b908a096f0ac071067fb820b0a7b12f0cdeac9bcf1ad1f19b4ecce90cf6a953d05dabed19b42557cadfac'}]}, 'chainIndex': 1} + + header = {'auxpow_length': 1700, + 'auxpow_offset': 0, + 'bits': 461017156, + 'merkle_root': '6ea3984bd09238c0a3b05282d7971c4f1ccc1df9361ba7e61be43d4228771715', + 'nonce': 0, + 'prev_block_hash': '00000000006bc8bf1468fbb495bad554d8d16740f8b88e67003f0052c90a6aa7', + 'timestamp': 1325305695, + 'version': 196865} + + #print get_chain_id(header) + #print get_chain_id(auxpow['parent_block']) + + print verify('6aa64d34307e3a3c062be612af6ce8a262b05c0f4aa9b41f23db9c0bd3c935f1', 3, auxpow) diff --git a/lib/bitcoin.py b/lib/bitcoin.py new file mode 100644 index 00000000..5e0ddf64 --- /dev/null +++ b/lib/bitcoin.py @@ -0,0 +1,793 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import hashlib +import base64 +import re +import sys +import hmac + +import version +from util import print_error + +try: + import ecdsa +except ImportError: + sys.exit("Error: python-ecdsa does not seem to be installed. Try 'sudo pip install ecdsa'") + +try: + import aes +except ImportError: + sys.exit("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'") + +################################## transactions + +DUST_THRESHOLD = 5430 +MIN_RELAY_TX_FEE = 1000 +RECOMMENDED_FEE = 50000 +COINBASE_MATURITY = 100 + +# AES encryption +EncodeAES = lambda secret, s: base64.b64encode(aes.encryptData(secret,s)) +DecodeAES = lambda secret, e: aes.decryptData(secret, base64.b64decode(e)) + +def strip_PKCS7_padding(s): + """return s stripped of PKCS7 padding""" + if len(s)%16 or not s: + raise ValueError("String of len %d can't be PCKS7-padded" % len(s)) + numpads = ord(s[-1]) + if numpads > 16: + raise ValueError("String ending with %r can't be PCKS7-padded" % s[-1]) + if s[-numpads:] != numpads*chr(numpads): + raise ValueError("Invalid PKCS7 padding") + return s[:-numpads] + + +def aes_encrypt_with_iv(key, iv, data): + mode = aes.AESModeOfOperation.modeOfOperation["CBC"] + key = map(ord, key) + iv = map(ord, iv) + data = aes.append_PKCS7_padding(data) + keysize = len(key) + assert keysize in aes.AES.keySize.values(), 'invalid key size: %s' % keysize + moo = aes.AESModeOfOperation() + (mode, length, ciph) = moo.encrypt(data, mode, key, keysize, iv) + return ''.join(map(chr, ciph)) + +def aes_decrypt_with_iv(key, iv, data): + mode = aes.AESModeOfOperation.modeOfOperation["CBC"] + key = map(ord, key) + iv = map(ord, iv) + keysize = len(key) + assert keysize in aes.AES.keySize.values(), 'invalid key size: %s' % keysize + data = map(ord, data) + moo = aes.AESModeOfOperation() + decr = moo.decrypt(data, None, mode, key, keysize, iv) + decr = strip_PKCS7_padding(decr) + return decr + + + +def pw_encode(s, password): + if password: + secret = Hash(password) + return EncodeAES(secret, s.encode("utf8")) + else: + return s + + +def pw_decode(s, password): + if password is not None: + secret = Hash(password) + try: + d = DecodeAES(secret, s).decode("utf8") + except Exception: + raise Exception('Invalid password') + return d + else: + return s + + +def rev_hex(s): + return s.decode('hex')[::-1].encode('hex') + + +def int_to_hex(i, length=1): + s = hex(i)[2:].rstrip('L') + s = "0"*(2*length - len(s)) + s + return rev_hex(s) + + +def var_int(i): + # https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer + if i<0xfd: + return int_to_hex(i) + elif i<=0xffff: + return "fd"+int_to_hex(i,2) + elif i<=0xffffffff: + return "fe"+int_to_hex(i,4) + else: + return "ff"+int_to_hex(i,8) + + +def op_push(i): + if i<0x4c: + return int_to_hex(i) + elif i<0xff: + return '4c' + int_to_hex(i) + elif i<0xffff: + return '4d' + int_to_hex(i,2) + else: + return '4e' + int_to_hex(i,4) + + +def sha256(x): + return hashlib.sha256(x).digest() + + +def Hash(x): + if type(x) is unicode: x=x.encode('utf-8') + return sha256(sha256(x)) + + +hash_encode = lambda x: x[::-1].encode('hex') +hash_decode = lambda x: x.decode('hex')[::-1] +hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest() + +def is_new_seed(x, prefix=version.SEED_BIP44): + import mnemonic + x = mnemonic.prepare_seed(x) + s = hmac_sha_512("Seed version", x.encode('utf8')).encode('hex') + return s.startswith(prefix) + + +def is_old_seed(seed): + import old_mnemonic + words = seed.strip().split() + try: + old_mnemonic.mn_decode(words) + uses_electrum_words = True + except Exception: + uses_electrum_words = False + + try: + seed.decode('hex') + is_hex = (len(seed) == 32) + except Exception: + is_hex = False + + return is_hex or (uses_electrum_words and len(words) == 12) + + +# pywallet openssl private key implementation + +def i2d_ECPrivateKey(pkey, compressed=False): + if compressed: + key = '3081d30201010420' + \ + '%064x' % pkey.secret + \ + 'a081a53081a2020101302c06072a8648ce3d0101022100' + \ + '%064x' % _p + \ + '3006040100040107042102' + \ + '%064x' % _Gx + \ + '022100' + \ + '%064x' % _r + \ + '020101a124032200' + else: + key = '308201130201010420' + \ + '%064x' % pkey.secret + \ + 'a081a53081a2020101302c06072a8648ce3d0101022100' + \ + '%064x' % _p + \ + '3006040100040107044104' + \ + '%064x' % _Gx + \ + '%064x' % _Gy + \ + '022100' + \ + '%064x' % _r + \ + '020101a144034200' + + return key.decode('hex') + i2o_ECPublicKey(pkey.pubkey, compressed) + +def i2o_ECPublicKey(pubkey, compressed=False): + # public keys are 65 bytes long (520 bits) + # 0x04 + 32-byte X-coordinate + 32-byte Y-coordinate + # 0x00 = point at infinity, 0x02 and 0x03 = compressed, 0x04 = uncompressed + # compressed keys: where is 0x02 if y is even and 0x03 if y is odd + if compressed: + if pubkey.point.y() & 1: + key = '03' + '%064x' % pubkey.point.x() + else: + key = '02' + '%064x' % pubkey.point.x() + else: + key = '04' + \ + '%064x' % pubkey.point.x() + \ + '%064x' % pubkey.point.y() + + return key.decode('hex') + +# end pywallet openssl private key implementation + + + +############ functions from pywallet ##################### + +def hash_160(public_key): + try: + md = hashlib.new('ripemd160') + md.update(sha256(public_key)) + return md.digest() + except Exception: + import ripemd + md = ripemd.new(sha256(public_key)) + return md.digest() + + +def public_key_to_bc_address(public_key): + h160 = hash_160(public_key) + return hash_160_to_bc_address(h160) + +def hash_160_to_bc_address(h160, addrtype = 138): + vh160 = chr(addrtype) + h160 + h = Hash(vh160) + addr = vh160 + h[0:4] + return b58encode(addr) + +def bc_address_to_hash_160(addr): + bytes = b58decode(addr, 25) + return ord(bytes[0]), bytes[1:21] + + +__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +__b58base = len(__b58chars) + + +def b58encode(v): + """ encode v, which is a string of bytes, to base58.""" + + long_value = 0L + for (i, c) in enumerate(v[::-1]): + long_value += (256**i) * ord(c) + + result = '' + while long_value >= __b58base: + div, mod = divmod(long_value, __b58base) + result = __b58chars[mod] + result + long_value = div + result = __b58chars[long_value] + result + + # Bitcoin does a little leading-zero-compression: + # leading 0-bytes in the input become leading-1s + nPad = 0 + for c in v: + if c == '\0': nPad += 1 + else: break + + return (__b58chars[0]*nPad) + result + + +def b58decode(v, length): + """ decode v into a string of len bytes.""" + long_value = 0L + for (i, c) in enumerate(v[::-1]): + long_value += __b58chars.find(c) * (__b58base**i) + + result = '' + while long_value >= 256: + div, mod = divmod(long_value, 256) + result = chr(mod) + result + long_value = div + result = chr(long_value) + result + + nPad = 0 + for c in v: + if c == __b58chars[0]: nPad += 1 + else: break + + result = chr(0)*nPad + result + if length is not None and len(result) != length: + return None + + return result + + +def EncodeBase58Check(vchIn): + hash = Hash(vchIn) + return b58encode(vchIn + hash[0:4]) + + +def DecodeBase58Check(psz): + vchRet = b58decode(psz, None) + key = vchRet[0:-4] + csum = vchRet[-4:] + hash = Hash(key) + cs32 = hash[0:4] + if cs32 != csum: + return None + else: + return key + + +def PrivKeyToSecret(privkey): + return privkey[9:9+32] + + +def SecretToASecret(secret, compressed=False, addrtype=138): + vchIn = chr((addrtype+128)&255) + secret + if compressed: vchIn += '\01' + return EncodeBase58Check(vchIn) + +def ASecretToSecret(key, addrtype=138): + vch = DecodeBase58Check(key) + if vch and vch[0] == chr((addrtype+128)&255): + return vch[1:] + else: + return False + +def regenerate_key(sec): + b = ASecretToSecret(sec) + if not b: + return False + b = b[0:32] + return EC_KEY(b) + + +def GetPubKey(pubkey, compressed=False): + return i2o_ECPublicKey(pubkey, compressed) + + +def GetPrivKey(pkey, compressed=False): + return i2d_ECPrivateKey(pkey, compressed) + + +def GetSecret(pkey): + return ('%064x' % pkey.secret).decode('hex') + + +def is_compressed(sec): + b = ASecretToSecret(sec) + return len(b) == 33 + + +def public_key_from_private_key(sec): + # rebuild public key from private key, compressed or uncompressed + pkey = regenerate_key(sec) + assert pkey + compressed = is_compressed(sec) + public_key = GetPubKey(pkey.pubkey, compressed) + return public_key.encode('hex') + + +def address_from_private_key(sec): + public_key = public_key_from_private_key(sec) + address = public_key_to_bc_address(public_key.decode('hex')) + return address + + +def is_valid(addr): + return is_address(addr) + + +def is_address(addr): + ADDRESS_RE = re.compile('[1-9A-HJ-NP-Za-km-z]{26,}\\Z') + if not ADDRESS_RE.match(addr): return False + try: + addrtype, h = bc_address_to_hash_160(addr) + except Exception: + return False + return addr == hash_160_to_bc_address(h, addrtype) + + +def is_private_key(key): + try: + k = ASecretToSecret(key) + return k is not False + except: + return False + + +########### end pywallet functions ####################### + +try: + from ecdsa.ecdsa import curve_secp256k1, generator_secp256k1 +except Exception: + print "cannot import ecdsa.curve_secp256k1. You probably need to upgrade ecdsa.\nTry: sudo pip install --upgrade ecdsa" + exit() + +from ecdsa.curves import SECP256k1 +from ecdsa.ellipticcurve import Point +from ecdsa.util import string_to_number, number_to_string + +def msg_magic(message): + varint = var_int(len(message)) + encoded_varint = "".join([chr(int(varint[i:i+2], 16)) for i in xrange(0, len(varint), 2)]) + return "\x18Ixcoin Signed Message:\n" + encoded_varint + message + + +def verify_message(address, signature, message): + try: + EC_KEY.verify_message(address, signature, message) + return True + except Exception as e: + print_error("Verification error: {0}".format(e)) + return False + + +def encrypt_message(message, pubkey): + return EC_KEY.encrypt_message(message, pubkey.decode('hex')) + + +def chunks(l, n): + return [l[i:i+n] for i in xrange(0, len(l), n)] + + +def ECC_YfromX(x,curved=curve_secp256k1, odd=True): + _p = curved.p() + _a = curved.a() + _b = curved.b() + for offset in range(128): + Mx = x + offset + My2 = pow(Mx, 3, _p) + _a * pow(Mx, 2, _p) + _b % _p + My = pow(My2, (_p+1)/4, _p ) + + if curved.contains_point(Mx,My): + if odd == bool(My&1): + return [My,offset] + return [_p-My,offset] + raise Exception('ECC_YfromX: No Y found') + + +def negative_point(P): + return Point( P.curve(), P.x(), -P.y(), P.order() ) + + +def point_to_ser(P, comp=True ): + if comp: + return ( ('%02x'%(2+(P.y()&1)))+('%064x'%P.x()) ).decode('hex') + return ( '04'+('%064x'%P.x())+('%064x'%P.y()) ).decode('hex') + + +def ser_to_point(Aser): + curve = curve_secp256k1 + generator = generator_secp256k1 + _r = generator.order() + assert Aser[0] in ['\x02','\x03','\x04'] + if Aser[0] == '\x04': + return Point( curve, string_to_number(Aser[1:33]), string_to_number(Aser[33:]), _r ) + Mx = string_to_number(Aser[1:]) + return Point( curve, Mx, ECC_YfromX(Mx, curve, Aser[0]=='\x03')[0], _r ) + + + +class MyVerifyingKey(ecdsa.VerifyingKey): + @classmethod + def from_signature(klass, sig, recid, h, curve): + """ See http://www.secg.org/download/aid-780/sec1-v2.pdf, chapter 4.1.6 """ + from ecdsa import util, numbertheory + import msqr + curveFp = curve.curve + G = curve.generator + order = G.order() + # extract r,s from signature + r, s = util.sigdecode_string(sig, order) + # 1.1 + x = r + (recid/2) * order + # 1.3 + alpha = ( x * x * x + curveFp.a() * x + curveFp.b() ) % curveFp.p() + beta = msqr.modular_sqrt(alpha, curveFp.p()) + y = beta if (beta - recid) % 2 == 0 else curveFp.p() - beta + # 1.4 the constructor checks that nR is at infinity + R = Point(curveFp, x, y, order) + # 1.5 compute e from message: + e = string_to_number(h) + minus_e = -e % order + # 1.6 compute Q = r^-1 (sR - eG) + inv_r = numbertheory.inverse_mod(r,order) + Q = inv_r * ( s * R + minus_e * G ) + return klass.from_public_point( Q, curve ) + + +class EC_KEY(object): + def __init__( self, k ): + secret = string_to_number(k) + self.pubkey = ecdsa.ecdsa.Public_key( generator_secp256k1, generator_secp256k1 * secret ) + self.privkey = ecdsa.ecdsa.Private_key( self.pubkey, secret ) + self.secret = secret + + def get_public_key(self, compressed=True): + return point_to_ser(self.pubkey.point, compressed).encode('hex') + + def sign_message(self, message, compressed, address): + private_key = ecdsa.SigningKey.from_secret_exponent( self.secret, curve = SECP256k1 ) + public_key = private_key.get_verifying_key() + signature = private_key.sign_digest_deterministic( Hash( msg_magic(message) ), hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_string ) + assert public_key.verify_digest( signature, Hash( msg_magic(message) ), sigdecode = ecdsa.util.sigdecode_string) + for i in range(4): + sig = base64.b64encode( chr(27 + i + (4 if compressed else 0)) + signature ) + try: + self.verify_message( address, sig, message) + return sig + except Exception: + continue + else: + raise Exception("error: cannot sign message") + + + @classmethod + def verify_message(self, address, signature, message): + sig = base64.b64decode(signature) + if len(sig) != 65: raise Exception("Wrong encoding") + + nV = ord(sig[0]) + if nV < 27 or nV >= 35: + raise Exception("Bad encoding") + if nV >= 31: + compressed = True + nV -= 4 + else: + compressed = False + + recid = nV - 27 + h = Hash( msg_magic(message) ) + public_key = MyVerifyingKey.from_signature( sig[1:], recid, h, curve = SECP256k1 ) + + # check public key + public_key.verify_digest( sig[1:], h, sigdecode = ecdsa.util.sigdecode_string) + + # check that we get the original signing address + addr = public_key_to_bc_address( point_to_ser(public_key.pubkey.point, compressed) ) + if address != addr: + raise Exception("Bad signature") + + + # ECIES encryption/decryption methods; AES-128-CBC with PKCS7 is used as the cipher; hmac-sha256 is used as the mac + + @classmethod + def encrypt_message(self, message, pubkey): + + pk = ser_to_point(pubkey) + if not ecdsa.ecdsa.point_is_valid(generator_secp256k1, pk.x(), pk.y()): + raise Exception('invalid pubkey') + + ephemeral_exponent = number_to_string(ecdsa.util.randrange(pow(2,256)), generator_secp256k1.order()) + ephemeral = EC_KEY(ephemeral_exponent) + ecdh_key = point_to_ser(pk * ephemeral.privkey.secret_multiplier) + key = hashlib.sha512(ecdh_key).digest() + iv, key_e, key_m = key[0:16], key[16:32], key[32:] + ciphertext = aes_encrypt_with_iv(key_e, iv, message) + ephemeral_pubkey = ephemeral.get_public_key(compressed=True).decode('hex') + encrypted = 'BIE1' + ephemeral_pubkey + ciphertext + mac = hmac.new(key_m, encrypted, hashlib.sha256).digest() + + return base64.b64encode(encrypted + mac) + + + def decrypt_message(self, encrypted): + + encrypted = base64.b64decode(encrypted) + + if len(encrypted) < 85: + raise Exception('invalid ciphertext: length') + + magic = encrypted[:4] + ephemeral_pubkey = encrypted[4:37] + ciphertext = encrypted[37:-32] + mac = encrypted[-32:] + + if magic != 'BIE1': + raise Exception('invalid ciphertext: invalid magic bytes') + + try: + ephemeral_pubkey = ser_to_point(ephemeral_pubkey) + except AssertionError, e: + raise Exception('invalid ciphertext: invalid ephemeral pubkey') + + if not ecdsa.ecdsa.point_is_valid(generator_secp256k1, ephemeral_pubkey.x(), ephemeral_pubkey.y()): + raise Exception('invalid ciphertext: invalid ephemeral pubkey') + + ecdh_key = point_to_ser(ephemeral_pubkey * self.privkey.secret_multiplier) + key = hashlib.sha512(ecdh_key).digest() + iv, key_e, key_m = key[0:16], key[16:32], key[32:] + if mac != hmac.new(key_m, encrypted[:-32], hashlib.sha256).digest(): + raise Exception('invalid ciphertext: invalid mac') + + return aes_decrypt_with_iv(key_e, iv, ciphertext) + + +###################################### BIP32 ############################## + +random_seed = lambda n: "%032x"%ecdsa.util.randrange( pow(2,n) ) +BIP32_PRIME = 0x80000000 + + +def get_pubkeys_from_secret(secret): + # public key + private_key = ecdsa.SigningKey.from_string( secret, curve = SECP256k1 ) + public_key = private_key.get_verifying_key() + K = public_key.to_string() + K_compressed = GetPubKey(public_key.pubkey,True) + return K, K_compressed + + +# Child private key derivation function (from master private key) +# k = master private key (32 bytes) +# c = master chain code (extra entropy for key derivation) (32 bytes) +# n = the index of the key we want to derive. (only 32 bits will be used) +# If n is negative (i.e. the 32nd bit is set), the resulting private key's +# corresponding public key can NOT be determined without the master private key. +# However, if n is positive, the resulting private key's corresponding +# public key can be determined without the master private key. +def CKD_priv(k, c, n): + is_prime = n & BIP32_PRIME + return _CKD_priv(k, c, rev_hex(int_to_hex(n,4)).decode('hex'), is_prime) + +def _CKD_priv(k, c, s, is_prime): + import hmac + from ecdsa.util import string_to_number, number_to_string + order = generator_secp256k1.order() + keypair = EC_KEY(k) + cK = GetPubKey(keypair.pubkey,True) + data = chr(0) + k + s if is_prime else cK + s + I = hmac.new(c, data, hashlib.sha512).digest() + k_n = number_to_string( (string_to_number(I[0:32]) + string_to_number(k)) % order , order ) + c_n = I[32:] + return k_n, c_n + +# Child public key derivation function (from public key only) +# K = master public key +# c = master chain code +# n = index of key we want to derive +# This function allows us to find the nth public key, as long as n is +# non-negative. If n is negative, we need the master private key to find it. +def CKD_pub(cK, c, n): + if n & BIP32_PRIME: raise + return _CKD_pub(cK, c, rev_hex(int_to_hex(n,4)).decode('hex')) + +# helper function, callable with arbitrary string +def _CKD_pub(cK, c, s): + import hmac + from ecdsa.util import string_to_number, number_to_string + order = generator_secp256k1.order() + I = hmac.new(c, cK + s, hashlib.sha512).digest() + curve = SECP256k1 + pubkey_point = string_to_number(I[0:32])*curve.generator + ser_to_point(cK) + public_key = ecdsa.VerifyingKey.from_public_point( pubkey_point, curve = SECP256k1 ) + c_n = I[32:] + cK_n = GetPubKey(public_key.pubkey,True) + return cK_n, c_n + + +BITCOIN_HEADER_PRIV = "0488ade4" +BITCOIN_HEADER_PUB = "0488b21e" + +TESTNET_HEADER_PRIV = "04358394" +TESTNET_HEADER_PUB = "043587cf" + +BITCOIN_HEADERS = (BITCOIN_HEADER_PUB, BITCOIN_HEADER_PRIV) +TESTNET_HEADERS = (TESTNET_HEADER_PUB, TESTNET_HEADER_PRIV) + +def _get_headers(testnet): + """Returns the correct headers for either testnet or bitcoin, in the form + of a 2-tuple, like (public, private).""" + if testnet: + return TESTNET_HEADERS + else: + return BITCOIN_HEADERS + + +def deserialize_xkey(xkey): + + xkey = DecodeBase58Check(xkey) + assert len(xkey) == 78 + + xkey_header = xkey[0:4].encode('hex') + # Determine if the key is a bitcoin key or a testnet key. + if xkey_header in TESTNET_HEADERS: + head = TESTNET_HEADER_PRIV + elif xkey_header in BITCOIN_HEADERS: + head = BITCOIN_HEADER_PRIV + else: + raise Exception("Unknown xkey header: '%s'" % xkey_header) + + depth = ord(xkey[4]) + fingerprint = xkey[5:9] + child_number = xkey[9:13] + c = xkey[13:13+32] + if xkey[0:4].encode('hex') == head: + K_or_k = xkey[13+33:] + else: + K_or_k = xkey[13+32:] + return depth, fingerprint, child_number, c, K_or_k + + +def get_xkey_name(xkey, testnet=False): + depth, fingerprint, child_number, c, K = deserialize_xkey(xkey) + n = int(child_number.encode('hex'), 16) + if n & BIP32_PRIME: + child_id = "%d'"%(n - BIP32_PRIME) + else: + child_id = "%d"%n + if depth == 0: + return '' + elif depth == 1: + return child_id + else: + raise BaseException("xpub depth error") + + +def xpub_from_xprv(xprv, testnet=False): + depth, fingerprint, child_number, c, k = deserialize_xkey(xprv) + K, cK = get_pubkeys_from_secret(k) + header_pub, _ = _get_headers(testnet) + xpub = header_pub.decode('hex') + chr(depth) + fingerprint + child_number + c + cK + return EncodeBase58Check(xpub) + + +def bip32_root(seed, testnet=False): + import hmac + header_pub, header_priv = _get_headers(testnet) + I = hmac.new("Bitcoin seed", seed, hashlib.sha512).digest() + master_k = I[0:32] + master_c = I[32:] + K, cK = get_pubkeys_from_secret(master_k) + xprv = (header_priv + "00" + "00000000" + "00000000").decode("hex") + master_c + chr(0) + master_k + xpub = (header_pub + "00" + "00000000" + "00000000").decode("hex") + master_c + cK + return EncodeBase58Check(xprv), EncodeBase58Check(xpub) + + +def bip32_private_derivation(xprv, branch, sequence, testnet=False): + header_pub, header_priv = _get_headers(testnet) + depth, fingerprint, child_number, c, k = deserialize_xkey(xprv) + assert sequence.startswith(branch) + sequence = sequence[len(branch):] + for n in sequence.split('/'): + if n == '': continue + i = int(n[:-1]) + BIP32_PRIME if n[-1] == "'" else int(n) + parent_k = k + k, c = CKD_priv(k, c, i) + depth += 1 + + _, parent_cK = get_pubkeys_from_secret(parent_k) + fingerprint = hash_160(parent_cK)[0:4] + child_number = ("%08X"%i).decode('hex') + K, cK = get_pubkeys_from_secret(k) + xprv = header_priv.decode('hex') + chr(depth) + fingerprint + child_number + c + chr(0) + k + xpub = header_pub.decode('hex') + chr(depth) + fingerprint + child_number + c + cK + return EncodeBase58Check(xprv), EncodeBase58Check(xpub) + + +def bip32_public_derivation(xpub, branch, sequence, testnet=False): + header_pub, _ = _get_headers(testnet) + depth, fingerprint, child_number, c, cK = deserialize_xkey(xpub) + assert sequence.startswith(branch) + sequence = sequence[len(branch):] + for n in sequence.split('/'): + if n == '': continue + i = int(n) + parent_cK = cK + cK, c = CKD_pub(cK, c, i) + depth += 1 + + fingerprint = hash_160(parent_cK)[0:4] + child_number = ("%08X"%i).decode('hex') + xpub = header_pub.decode('hex') + chr(depth) + fingerprint + child_number + c + cK + return EncodeBase58Check(xpub) + + +def bip32_private_key(sequence, k, chain): + for i in sequence: + k, chain = CKD_priv(k, chain, i) + return SecretToASecret(k, True) diff --git a/lib/blockchain.py b/lib/blockchain.py new file mode 100644 index 00000000..1b0eda17 --- /dev/null +++ b/lib/blockchain.py @@ -0,0 +1,599 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@ecdsa.org +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +import threading, time, Queue, os, sys, shutil, traceback, json, auxpow +import zlib +from util import user_dir, appdata_dir, print_error +from bitcoin import * + +from transaction import BCDataStream + +import pprint +pp = pprint.PrettyPrinter(indent=4) + +max_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 + +class Blockchain(threading.Thread): + + def __init__(self, config, network): + threading.Thread.__init__(self) + self.daemon = True + self.config = config + self.network = network + self.lock = threading.Lock() + self.local_height = 0 + self.running = False + self.headers_url = '' + self.set_local_height() + self.queue = Queue.Queue() + + + def height(self): + return self.local_height + + + def stop(self): + with self.lock: self.running = False + + + def is_running(self): + with self.lock: return self.running + + + def run(self): + self.init_headers_file() + self.set_local_height() + print_error( "blocks:", self.local_height ) + + with self.lock: + self.running = True + + while self.is_running(): + + try: + result = self.queue.get() + except Queue.Empty: + continue + + if not result: continue + + i, header = result + if not header: continue + + height = header.get('block_height') + + if height <= self.local_height: + continue + + if height > self.local_height + 50: + if not self.get_and_verify_chunks(i, header, height): + continue + + if height > self.local_height: + # get missing parts from interface (until it connects to my chain) + chain = self.get_chain( i, header ) + + # skip that server if the result is not consistent + if not chain: + print_error('e') + continue + + # verify the chain + if self.verify_chain( chain ): + print_error("height:", height, i.server) + for header in chain: + self.save_header(header) + else: + print_error("error", i.server) + # todo: dismiss that server + continue + + + self.network.new_blockchain_height(height, i) + + + + + def verify_chain(self, chain): + + first_header = chain[0] + prev_header = self.read_header(first_header.get('block_height') -1) + + for header in chain: + + height = header.get('block_height') + + prev_hash = self.hash_header(prev_header) + bits, target = self.get_target(height, chain) + _hash = self.hash_header(header) + pow_hash = _hash + + try: + if height >= 45000 and header['version'] == 196865: + assert auxpow.verify(_hash, auxpow.get_our_chain_id(), header['auxpow']) + pow_hash = self.hash_header(header['auxpow']['parent_block']) + assert prev_hash == header.get('prev_block_hash') + assert bits == header.get('bits') + assert int('0x'+pow_hash,16) < target + except Exception: + print traceback.format_exc() + print 'error validating chain at height ', height + print 'block ', height, '(',_hash,') failed validation' + pprint.pprint(header) + return False + + prev_header = header + + return True + + + + def verify_chunk(self, index, hexdata): + hex_to_int = lambda s: int('0x' + s[::-1].encode('hex'), 16) + + data = hexdata.decode('hex') + disk_data = '' + height = index * 2016 + num = hex_to_int(data[0:4]) + data = data[4:] + + auxpowdata = data[num*88:] + auxpowbaseoffset = 0 + + if index == 0: + previous_hash = ("0"*64) + else: + prev_header = self.read_header(index*2016-1) + if prev_header is None: raise + previous_hash = self.hash_header(prev_header) + + + bits, target = self.get_target(height) + + chain = [] + for i in range(num): + height = index * 2016 + i + + raw_header = data[i*88:(i+1)*88] + disk_data += raw_header[0:80] # strip auxpow data + + header = self.header_from_string(raw_header) + _hash = self.hash_header(header) + _prev_hash = _hash + header['block_height'] = height + + if (i == 0): + auxpowbaseoffset = header['auxpow_offset'] + + start = header['auxpow_offset'] - auxpowbaseoffset + end = start + header['auxpow_length'] + + if (end > start): + header['auxpow'] = self.auxpow_from_string(auxpowdata[start:end].decode('hex')) + #print header['auxpow'] + + if height >= 20160 and (height % 144) == 0: + #print height , '%', 144 , '=', height % 144 + bits, target = self.get_target(height, chain) + + + if height >= 45000 and header['version'] == 196865: #TODO getAuxPowVersion() + #todo: check that auxpow.get_chain_id(header) == auxpow.get_our_chain_id? + #print header['auxpow'] + try: + assert auxpow.verify(_hash, auxpow.get_our_chain_id(), header['auxpow']) + except Exception as e: + print traceback.format_exc() + print 'block ', height, '(',_hash,') failed validation' + print 'auxpow failed verification' + pp.pprint(header['auxpow']) + raise e + #pp.pprint(header) + #pp.pprint(parent_header) + _hash = self.hash_header(header['auxpow']['parent_block']) + #print _hash + # todo: verify auxpow data + #_hash = '' # auxpow.getHash() + + try: + assert previous_hash == header.get('prev_block_hash') + assert bits == header.get('bits') + assert int('0x'+_hash,16) < target + except Exception as e: + print 'block ', height, ' failed validation' + raise e + + if height % 144 == 0: + print 'block ', height, ' validated' + + chain.append(header) + previous_header = header + previous_hash = _prev_hash + + self.save_chunk(index, disk_data) + print_error("validated chunk %d"%height) + + #def parent_block_to_header(self, parent_block): + #h = {} + #h['version'] = parent_block['version'] + #h['prev_block_hash'] = parent_block['previousblockhash'] + #h['merkle_root'] = parent_block['merkleroot'] + #h['timestamp'] = parent_block['time'] + #h['bits'] = int(parent_block['bits'], 16) #not sure + #h['nonce'] = parent_block['nonce'] + #return h + + def header_to_string(self, res): + s = int_to_hex(res.get('version'),4) \ + + rev_hex(res.get('prev_block_hash')) \ + + rev_hex(res.get('merkle_root')) \ + + int_to_hex(int(res.get('timestamp')),4) \ + + int_to_hex(int(res.get('bits')),4) \ + + int_to_hex(int(res.get('nonce')),4) + return s + + def auxpow_from_string(self, s): + res = {} + res['coinbasetx'], s = tx_from_string(s) + res['coinbaseMerkleBranch'], res['coinbaseIndex'], s = merkle_branch_from_string(s) + res['chainMerkleBranch'], res['chainIndex'], s = merkle_branch_from_string(s) + res['parent_block'] = header_from_string(s) + return res + + + def header_from_string(self, s): + # hmmm why specify 0x at beginning if 16 is already specified?? + hex_to_int = lambda s: int('0x' + s[::-1].encode('hex'), 16) + h = {} + h['version'] = hex_to_int(s[0:4]) + h['prev_block_hash'] = hash_encode(s[4:36]) + h['merkle_root'] = hash_encode(s[36:68]) + h['timestamp'] = hex_to_int(s[68:72]) + h['bits'] = hex_to_int(s[72:76]) + h['nonce'] = hex_to_int(s[76:80]) + if (len(s) > 80): + h['auxpow_offset'] = hex_to_int(s[80:84]) + h['auxpow_length'] = hex_to_int(s[84:88]) + return h + + def hash_header(self, header): + return rev_hex(Hash(self.header_to_string(header).decode('hex')).encode('hex')) + + def path(self): + return os.path.join( self.config.path, 'blockchain_headers') + + def init_headers_file(self): + filename = self.path() + if os.path.exists(filename): + return + + try: + import urllib, socket + socket.setdefaulttimeout(30) + print_error("downloading ", self.headers_url ) + urllib.urlretrieve(self.headers_url, filename) + print_error("done.") + except Exception: + print_error( "download failed. creating file", filename ) + open(filename,'wb+').close() + + def save_chunk(self, index, chunk): + filename = self.path() + f = open(filename,'rb+') + f.seek(index*2016*80) + h = f.write(chunk) + f.close() + self.set_local_height() + + def save_header(self, header): + data = self.header_to_string(header).decode('hex') + assert len(data) == 80 + height = header.get('block_height') + filename = self.path() + f = open(filename,'rb+') + f.seek(height*80) + h = f.write(data) + f.close() + self.set_local_height() + + + def set_local_height(self): + name = self.path() + if os.path.exists(name): + h = os.path.getsize(name)/80 - 1 + if self.local_height != h: + self.local_height = h + + + def read_header(self, block_height): + name = self.path() + if os.path.exists(name): + f = open(name,'rb') + f.seek(block_height*80) + h = f.read(80) + f.close() + if len(h) == 80: + h = self.header_from_string(h) + return h + + def get_ixcoin_target(self, height, chain=None): + if chain is None: + chain = [] # Do not use mutables as default values! + + nTargetTimespan = 24 * 60 * 60 #ixcoin: 144 blocks ever 24 hours + nInterval = 144 + blockstogoback = nInterval + + if (height >= 43000): + blockstogoback = nInterval + 1 + + last_height = (height / 144) * 144 - 1 + first_height = (height / 144) * 144 - blockstogoback + + #print 'new target at... ' , height + #print 'first height: ' + #print first_height + #print 'last height: ' + #print last_height + + first = self.read_header(first_height) + last = self.read_header(last_height) + + if first is None: + for h in chain: + if h.get('block_height') == first_height: + first = h + + if last is None: + for h in chain: + if h.get('block_height') == last_height: + last = h + + nActualTimespan = last.get('timestamp') - first.get('timestamp') + + # https://github.com/FrictionlessCoin/iXcoin/blob/master/src/main.cpp#L1240 + nTwoPercent = nTargetTimespan / 50 + if nActualTimespan < nTargetTimespan: + #print 'smaller actual timespan' + if nActualTimespan < (nTwoPercent * 16): + #print 'a' + nActualTimespan = nTwoPercent * 45 + elif nActualTimespan < (nTwoPercent * 32): + #print 'b' + nActualTimespan = nTwoPercent * 47 + else: + #print 'c' + nActualTimespan = nTwoPercent * 49 + elif nActualTimespan > (nTargetTimespan * 4): + #print 'd' + nActualTimespan = nTargetTimespan * 4 + + return self.get_target_from_timespans(last.get('bits'), nActualTimespan, nTargetTimespan) + + def get_target_from_timespans(self, bits, nActualTimespan, nTargetTimespan): + + # convert to bignum + MM = 256*256*256 + a = bits%MM + if a < 0x8000: + a *= 256 + target = (a) * pow(2, 8 * (bits/MM - 3)) + + # new target + new_target = min( max_target, (target * nActualTimespan)/nTargetTimespan ) + + # convert it to bits + c = ("%064X"%new_target)[2:] + i = 31 + while c[0:2]=="00": + c = c[2:] + i -= 1 + + c = int('0x'+c[0:6],16) + if c >= 0x800000: + c /= 256 + i += 1 + + new_bits = c + MM * i + + #print 'new bits: ', hex(new_bits) + #print 'new target: ', hex(new_target) + return new_bits, new_target + + + def get_target(self, height, chain=None): + if chain is None: + chain = [] # Do not use mutables as default values! + + # Ixcoin: target changes every 144 blocks after block 20160 + # https://github.com/FrictionlessCoin/iXcoin/blob/master/src/main.cpp#L1196 + if height >= 20160: + #print height , '%', 144 , '=', height % 144 + return self.get_ixcoin_target(height, chain) + + index = height / 2016 + + if index == 0: return 0x1d00ffff, max_target + + first = self.read_header((index-1)*2016) + last = self.read_header(index*2016-1) + if last is None: + for h in chain: + if h.get('block_height') == index*2016-1: + last = h + + nActualTimespan = last.get('timestamp') - first.get('timestamp') + nTargetTimespan = 14*24*60*60 + nActualTimespan = max(nActualTimespan, nTargetTimespan/4) + nActualTimespan = min(nActualTimespan, nTargetTimespan*4) + + return self.get_target_from_timespans(last.get('bits'), nActualTimespan, nTargetTimespan) + + + def request_header(self, i, h, queue): + print_error("requesting header %d from %s"%(h, i.server)) + i.send_request({'method':'blockchain.block.get_header', 'params':[h]}, queue) + + def retrieve_request(self, queue): + while True: + try: + ir = queue.get(timeout=1) + except Queue.Empty: + print_error('blockchain: request timeout') + continue + i, r = ir + result = r['result'] + return result + + def get_chain(self, interface, final_header): + + header = final_header + chain = [ final_header ] + requested_header = False + queue = Queue.Queue() + + while self.is_running(): + + if requested_header: + header = self.retrieve_request(queue) + if not header: return + chain = [ header ] + chain + requested_header = False + + height = header.get('block_height') + previous_header = self.read_header(height -1) + if not previous_header: + self.request_header(interface, height - 1, queue) + requested_header = True + continue + + # verify that it connects to my chain + prev_hash = self.hash_header(previous_header) + if prev_hash != header.get('prev_block_hash'): + print_error("reorg") + self.request_header(interface, height - 1, queue) + requested_header = True + continue + + else: + # the chain is complete + return chain + + + def get_and_verify_chunks(self, i, header, height): + + queue = Queue.Queue() + min_index = (self.local_height + 1)/2016 + max_index = (height + 1)/2016 + n = min_index + while n < max_index + 1: + print_error( "Requesting chunk:", n ) + # todo: ixcoin get_auxblock_chunk after block 45000...? + # todo: call blockchain.block.get_auxblock from verify_chunk instead? + i.send_request({'method':'blockchain.block.get_chunk', 'params':[n]}, queue) + r = self.retrieve_request(queue) + + print 'chunk compressed length : ', len(r) + r = zlib.decompress(r.decode('hex')) + print 'chunk uncompressed length : ', len(r) + + try: + self.verify_chunk(n, r) + n = n + 1 + except Exception: + print traceback.format_exc() + print_error('Verify chunk failed!') + n = n - 1 + if n < 0: + return False + + return True + +# START electrum-ixc-server +# the following code was copied from the server's utils.py file +def tx_from_string(s): + vds = BCDataStream() + vds.write(s) + #vds.write(raw.decode('hex')) + d = {} + d['version'] = vds.read_int32() + n_vin = vds.read_compact_size() + d['vin'] = [] + for i in xrange(n_vin): + txin = {} + # dirty hack: add outpoint structure to get correct txid later + outpoint_pos = vds.read_cursor + txin['coinbase'] = vds.read_bytes(vds.read_compact_size()).encode('hex') + txin['sequence'] = vds.read_uint32() + d['vin'].append(txin) + n_vout = vds.read_compact_size() + d['vout'] = [] + for i in xrange(n_vout): + txout = {} + txout['value'] = vds.read_int64() + txout['scriptPubKey'] = vds.read_bytes(vds.read_compact_size()).encode('hex') + d['vout'].append(txout) + d['lockTime'] = vds.read_uint32() + + # compute txid + # dirty hack to insert coinbase outpoint structure before hashing + raw = s[0:outpoint_pos] + COINBASE_OP = '0' * 64 + 'F' * 8 + raw += (COINBASE_OP).decode('hex') + raw += s[outpoint_pos:vds.read_cursor] + + d['txid'] = Hash(raw)[::-1].encode('hex') + + return d, s[vds.read_cursor:] # +1? + +def merkle_branch_from_string(s): + vds = BCDataStream() + vds.write(s) + #vds.write(raw.decode('hex')) + hashes = [] + n_hashes = vds.read_compact_size() + for i in xrange(n_hashes): + _hash = vds.read_bytes(32) + hashes.append(hash_encode(_hash)) + index = vds.read_int32() + return hashes, index, s[vds.read_cursor:] + +def hex_to_int(s): + return int('0x' + s[::-1].encode('hex'), 16) + + +def header_from_string(s): + #OK ixcoin todo: include auxpow position in auxpow file (offset(s)) + res = { + 'version': hex_to_int(s[0:4]), + 'prev_block_hash': hash_encode(s[4:36]), + 'merkle_root': hash_encode(s[36:68]), + 'timestamp': hex_to_int(s[68:72]), + 'bits': hex_to_int(s[72:76]), + 'nonce': hex_to_int(s[76:80]), + } + + if (len(s) > 80): + res['auxpow_offset'] = hex_to_int(s[80:84]) + res['auxpow_length'] = hex_to_int(s[84:88]) + + return res +# END electrum-ixc-server + + diff --git a/lib/bmp.py b/lib/bmp.py new file mode 100644 index 00000000..e8302ec0 --- /dev/null +++ b/lib/bmp.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8 -*- +""" +bmp.py - module for constructing simple BMP graphics files + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +__version__ = "0.3" +__about = "bmp module, version %s, written by Paul McGuire, October, 2003, updated by Margus Laak, September, 2009" % __version__ + +from math import ceil, hypot + + +def shortToString(i): + hi = (i & 0xff00) >> 8 + lo = i & 0x00ff + return chr(lo) + chr(hi) + +def longToString(i): + hi = (long(i) & 0x7fff0000) >> 16 + lo = long(i) & 0x0000ffff + return shortToString(lo) + shortToString(hi) + +def long24ToString(i): + return chr(i & 0xff) + chr(i >> 8 & 0xff) + chr(i >> 16 & 0xff) + +def stringToLong(input_string, offset): + return ord(input_string[offset+3]) << 24 | ord(input_string[offset+2]) << 16 | ord(input_string[offset+1]) << 8 | ord(input_string[offset]) + +def stringToLong24(input_string, offset): + return ord(input_string[offset+2]) << 16 | ord(input_string[offset+1]) << 8 | ord(input_string[offset]) + +class Color(object): + """class for specifying colors while drawing BitMap elements""" + __slots__ = [ 'red', 'grn', 'blu' ] + __shade = 32 + + def __init__( self, r=0, g=0, b=0 ): + self.red = r + self.grn = g + self.blu = b + + def __setattr__(self, name, value): + if hasattr(self, name): + raise AttributeError, "Color is immutable" + else: + object.__setattr__(self, name, value) + + def __str__( self ): + return "R:%d G:%d B:%d" % (self.red, self.grn, self.blu ) + + def __hash__( self ): + return ( ( long(self.blu) ) + + ( long(self.grn) << 8 ) + + ( long(self.red) << 16 ) ) + + def __eq__( self, other ): + return (self is other) or (self.toLong == other.toLong) + + def lighten( self ): + return Color( + min( self.red + Color.__shade, 255), + min( self.grn + Color.__shade, 255), + min( self.blu + Color.__shade, 255) + ) + + def darken( self ): + return Color( + max( self.red - Color.__shade, 0), + max( self.grn - Color.__shade, 0), + max( self.blu - Color.__shade, 0) + ) + + def toLong( self ): + return self.__hash__() + + def fromLong( l ): + b = l & 0xff + l = l >> 8 + g = l & 0xff + l = l >> 8 + r = l & 0xff + return Color( r, g, b ) + fromLong = staticmethod(fromLong) + +# define class constants for common colors +Color.BLACK = Color( 0, 0, 0 ) +Color.RED = Color( 255, 0, 0 ) +Color.GREEN = Color( 0, 255, 0 ) +Color.BLUE = Color( 0, 0, 255 ) +Color.CYAN = Color( 0, 255, 255 ) +Color.MAGENTA = Color( 255, 0, 255 ) +Color.YELLOW = Color( 255, 255, 0 ) +Color.WHITE = Color( 255, 255, 255 ) +Color.DKRED = Color( 128, 0, 0 ) +Color.DKGREEN = Color( 0, 128, 0 ) +Color.DKBLUE = Color( 0, 0, 128 ) +Color.TEAL = Color( 0, 128, 128 ) +Color.PURPLE = Color( 128, 0, 128 ) +Color.BROWN = Color( 128, 128, 0 ) +Color.GRAY = Color( 128, 128, 128 ) + + +class BitMap(object): + """class for drawing and saving simple Windows bitmap files""" + + LINE_SOLID = 0 + LINE_DASHED = 1 + LINE_DOTTED = 2 + LINE_DOT_DASH=3 + _DASH_LEN = 12.0 + _DOT_LEN = 6.0 + _DOT_DASH_LEN = _DOT_LEN + _DASH_LEN + + def __init__( self, width, height, + bkgd = Color.WHITE, frgd = Color.BLACK ): + self.wd = int( ceil(width) ) + self.ht = int( ceil(height) ) + self.bgcolor = 0 + self.fgcolor = 1 + self.palette = [] + self.palette.append( bkgd.toLong() ) + self.palette.append( frgd.toLong() ) + self.currentPen = self.fgcolor + + tmparray = [ self.bgcolor ] * self.wd + self.bitarray = [ tmparray[:] for i in range( self.ht ) ] + self.currentPen = 1 + + + def plotPoint( self, x, y ): + if ( 0 <= x < self.wd and 0 <= y < self.ht ): + x = int(x) + y = int(y) + self.bitarray[y][x] = self.currentPen + + + def _saveBitMapNoCompression( self ): + line_padding = (4 - (self.wd % 4)) % 4 + + # write bitmap header + _bitmap = "BM" + _bitmap += longToString( 54 + self.ht*(self.wd*3 + line_padding) ) # DWORD size in bytes of the file + _bitmap += longToString( 0 ) # DWORD 0 + _bitmap += longToString( 54 ) + _bitmap += longToString( 40 ) # DWORD header size = 40 + _bitmap += longToString( self.wd ) # DWORD image width + _bitmap += longToString( self.ht ) # DWORD image height + _bitmap += shortToString( 1 ) # WORD planes = 1 + _bitmap += shortToString( 24 ) # WORD bits per pixel = 8 + _bitmap += longToString( 0 ) # DWORD compression = 0 + _bitmap += longToString( self.ht * (self.wd * 3 + line_padding) ) # DWORD sizeimage = size in bytes of the bitmap = width * height + _bitmap += longToString( 0 ) # DWORD horiz pixels per meter (?) + _bitmap += longToString( 0 ) # DWORD ver pixels per meter (?) + _bitmap += longToString( 0 ) # DWORD number of colors used = 256 + _bitmap += longToString( 0 ) # DWORD number of "import colors = len( self.palette ) + + # write pixels + self.bitarray.reverse() + for row in self.bitarray: + for pixel in row: + c = self.palette[pixel] + _bitmap += long24ToString(c) + for i in range(line_padding): + _bitmap += chr( 0 ) + + return _bitmap + + + + def saveFile( self, filename): + _b = self._saveBitMapNoCompression( ) + + f = file(filename, 'wb') + f.write(_b) + f.close() + + +def save_qrcode(qr, filename): + matrix = qr.get_matrix() + k = len(matrix) + bitmap = BitMap( (k+2)*8, (k+2)*8 ) + bitmap.bitarray = [] + for r in range(k+2): + tmparray = [ 0 ] * (k+2)*8 + + if 0 < r < k+1: + for c in range(k): + if matrix[r-1][c]: + tmparray[ (1+c)*8:(2+c)*8] = [1]*8 + + for i in range(8): + bitmap.bitarray.append( tmparray[:] ) + + bitmap.saveFile( filename ) + + + +if __name__ == "__main__": + + bmp = BitMap( 10, 10 ) + bmp.plotPoint( 5, 5 ) + bmp.plotPoint( 0, 0 ) + bmp.saveFile( "test.bmp" ) diff --git a/lib/commands.py b/lib/commands.py new file mode 100644 index 00000000..ddbadbf0 --- /dev/null +++ b/lib/commands.py @@ -0,0 +1,401 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import datetime +import time +import copy +from util import print_msg, format_satoshis, print_stderr +from bitcoin import is_valid, hash_160_to_bc_address, hash_160 +from decimal import Decimal +import bitcoin +from transaction import Transaction + + +class Command: + def __init__(self, name, min_args, max_args, requires_network, requires_wallet, requires_password, description, syntax = '', options_syntax = ''): + self.name = name + self.min_args=min_args + self.max_args = max_args + self.requires_network = requires_network + self.requires_wallet = requires_wallet + self.requires_password = requires_password + self.description = description + self.syntax = syntax + self.options = options_syntax + + +known_commands = {} + + +def register_command(*args): + global known_commands + name = args[0] + known_commands[name] = Command(*args) + + + +payto_options = ' --fee, -f: set transaction fee\n --fromaddr, -F: send from address -\n --changeaddr, -c: send change to address' +listaddr_options = " -a: show all addresses, including change addresses\n -l: include labels in results" +restore_options = " accepts a seed or master public key." +mksendmany_syntax = 'mksendmanytx [ ...]' +payto_syntax = "payto [label]\n can be a ixcoin address or a label" +paytomany_syntax = "paytomany [ ...]\n can be a ixcion address or a label" +signmessage_syntax = 'signmessage

\nIf you want to lead or end a message with spaces, or want double spaces inside the message make sure you quote the string. I.e. " Hello This is a weird String "' +verifymessage_syntax = 'verifymessage
\nIf you want to lead or end a message with spaces, or want double spaces inside the message make sure you quote the string. I.e. " Hello This is a weird String "' + +# command +# requires_network +# requires_wallet +# requires_password +register_command('contacts', 0, 0, False, True, False, 'Show your list of contacts') +register_command('create', 0, 0, False, True, False, 'Create a new wallet') +register_command('createmultisig', 2, 2, False, True, False, 'similar to ixcoind\'s command') +register_command('createrawtransaction', 2, 2, False, True, False, 'similar to ixcoind\'s command') +register_command('deseed', 0, 0, False, True, False, 'Remove seed from wallet, creating a seedless, watching-only wallet.') +register_command('decoderawtransaction', 1, 1, False, False, False, 'similar to ixcoind\'s command') +register_command('getprivatekeys', 1, 1, False, True, True, 'Get the private keys of a given address', 'getprivatekeys ') +register_command('dumpprivkeys', 0, 0, False, True, True, 'Dump all private keys in your wallet') +register_command('freeze', 1, 1, False, True, True, 'Freeze the funds at one of your wallet\'s addresses', 'freeze
') +register_command('getbalance', 0, 1, True, True, False, 'Return the balance of your wallet, or of one account in your wallet', 'getbalance []') +register_command('getservers', 0, 0, True, False, False, 'Return the list of available servers') +register_command('getversion', 0, 0, False, False, False, 'Return the version of your client', 'getversion') +register_command('getaddressbalance', 1, 1, True, False, False, 'Return the balance of an address', 'getaddressbalance
') +register_command('getaddresshistory', 1, 1, True, False, False, 'Return the transaction history of a wallet address', 'getaddresshistory
') +register_command('getconfig', 1, 1, False, False, False, 'Return a configuration variable', 'getconfig ') +register_command('getpubkeys', 1, 1, False, True, False, 'Return the public keys for a wallet address', 'getpubkeys ') +register_command('getrawtransaction', 1, 1, True, False, False, 'Retrieve a transaction', 'getrawtransaction ') +register_command('getseed', 0, 0, False, True, True, 'Print the generation seed of your wallet.') +register_command('getmpk', 0, 0, False, True, False, 'Return your wallet\'s master public key', 'getmpk') +register_command('help', 0, 1, False, False, False, 'Prints this help') +register_command('history', 0, 0, True, True, False, 'Returns the transaction history of your wallet') +register_command('importprivkey', 1, 1, False, True, True, 'Import a private key', 'importprivkey ') +register_command('listaddresses', 2, 2, False, True, False, 'Returns your list of addresses.', '', listaddr_options) +register_command('listunspent', 0, 0, True, True, False, 'Returns the list of unspent inputs in your wallet.') +register_command('getaddressunspent', 1, 1, True, False, False, 'Returns the list of unspent inputs for an address.') +register_command('mktx', 5, 5, False, True, True, 'Create a signed transaction', 'mktx [label]', payto_options) +register_command('mksendmanytx', 4, 4, False, True, True, 'Create a signed transaction', mksendmany_syntax, payto_options) +register_command('payto', 5, 5, True, True, True, 'Create and broadcast a transaction.', payto_syntax, payto_options) +register_command('paytomany', 4, 4, True, True, True, 'Create and broadcast a transaction.', paytomany_syntax, payto_options) +register_command('password', 0, 0, False, True, True, 'Change your password') +register_command('restore', 0, 0, True, True, False, 'Restore a wallet', '', restore_options) +register_command('searchcontacts', 1, 1, False, True, False, 'Search through contacts, return matching entries', 'searchcontacts ') +register_command('setconfig', 2, 2, False, False, False, 'Set a configuration variable', 'setconfig ') +register_command('setlabel', 2,-1, False, True, False, 'Assign a label to an item', 'setlabel