├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .gitmodules ├── .travis.yml ├── AUTHORS ├── LICENCE ├── MANIFEST.in ├── README.rst ├── RELEASE-NOTES ├── SECURITY.md ├── contrib ├── android │ ├── Dockerfile │ ├── Makefile │ ├── Readme.md │ ├── bitcoin_intent.xml │ ├── blacklist.txt │ ├── buildozer.spec │ └── make_apk ├── build-linux │ ├── appimage │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── apprun.sh │ │ ├── build.sh │ │ └── patches │ │ │ └── python-3.7-reproducible-buildinfo.diff │ └── sdist │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── build.sh │ │ └── make_tgz ├── build-wine │ ├── .dockerignore │ ├── Dockerfile │ ├── README.md │ ├── apt.preferences │ ├── apt.sources.list │ ├── build-electrum-git.sh │ ├── build.sh │ ├── deterministic.spec │ ├── electrum.nsi │ ├── gpg_keys │ │ └── 7ED10B6531D7C8E1BC296021FC624643487034E5.asc │ ├── make_win.sh │ ├── prepare-wine.sh │ ├── sign.sh │ └── unsign.sh ├── build_tools_util.sh ├── deterministic-build │ ├── check_submodules.sh │ ├── find_restricted_dependencies.py │ ├── requirements-binaries-mac.txt │ ├── requirements-binaries.txt │ ├── requirements-build-appimage.txt │ ├── requirements-build-base.txt │ ├── requirements-build-mac.txt │ ├── requirements-build-sdist.txt │ ├── requirements-build-wine.txt │ ├── requirements-eth.txt │ ├── requirements-hw.txt │ ├── requirements-qt.txt │ └── requirements.txt ├── freeze_packages.sh ├── make_download ├── make_libsecp256k1.sh ├── make_libusb.sh ├── make_locale ├── make_packages ├── make_zbar.sh ├── osx │ ├── README.md │ ├── cdrkit-deterministic.patch │ ├── entitlements.plist │ ├── make_osx │ ├── notarize_app.sh │ ├── osx.spec │ └── package.sh ├── pull_locale ├── push_locale ├── requirements │ ├── requirements-binaries-mac.txt │ ├── requirements-binaries.txt │ ├── requirements-build-appimage.txt │ ├── requirements-build-mac.txt │ ├── requirements-build-sdist.txt │ ├── requirements-build-wine.txt │ ├── requirements-eth.txt │ ├── requirements-hw.txt │ ├── requirements-travis.txt │ └── requirements.txt ├── sign_packages ├── sign_version ├── udev │ ├── 20-hw1.rules │ ├── 51-coinkite.rules │ ├── 51-hid-digitalbitbox.rules │ ├── 51-safe-t.rules │ ├── 51-trezor.rules │ ├── 51-usb-keepkey.rules │ ├── 52-hid-digitalbitbox.rules │ ├── 53-hid-bitbox02.rules │ ├── 54-hid-bitbox02.rules │ └── README.md └── upload ├── electrum-env ├── electrum.desktop ├── electrum ├── __init__.py ├── address_synchronizer.py ├── base_crash_reporter.py ├── base_wizard.py ├── bip32.py ├── bip39_recovery.py ├── bip39_wallet_formats.json ├── bitcoin.py ├── blockchain.py ├── channel_db.py ├── checkpoints.json ├── checkpoints_testnet.json ├── coinchooser.py ├── commands.py ├── constants.py ├── contacts.py ├── crypto.py ├── currencies.json ├── daemon.py ├── descriptor.py ├── dns_hacks.py ├── dnssec.py ├── ecc.py ├── ecc_fast.py ├── electrum ├── exchange_rate.py ├── gui │ ├── __init__.py │ ├── icons │ │ ├── bitbox02.png │ │ ├── bitbox02_unpaired.png │ │ ├── bitcoin.png │ │ ├── camera_dark.png │ │ ├── camera_white.png │ │ ├── clock1.png │ │ ├── clock2.png │ │ ├── clock3.png │ │ ├── clock4.png │ │ ├── clock5.pdn │ │ ├── clock5.png │ │ ├── coldcard.png │ │ ├── coldcard_unpaired.png │ │ ├── confirmed.png │ │ ├── confirmed.svg │ │ ├── copy.png │ │ ├── digitalbitbox.png │ │ ├── digitalbitbox_unpaired.png │ │ ├── electrum.icns │ │ ├── electrum.ico │ │ ├── electrum.png │ │ ├── electrum_dark_icon.png │ │ ├── electrum_launcher.png │ │ ├── electrum_light_icon.png │ │ ├── electrum_presplash.png │ │ ├── electrumb.png │ │ ├── expired.png │ │ ├── eye1.png │ │ ├── file.png │ │ ├── info.png │ │ ├── keepkey.png │ │ ├── keepkey_unpaired.png │ │ ├── key.png │ │ ├── ledger.png │ │ ├── ledger_unpaired.png │ │ ├── lightning.png │ │ ├── lightning_disconnected.png │ │ ├── lock.png │ │ ├── lock.svg │ │ ├── microphone.png │ │ ├── network.png │ │ ├── offline_tx.png │ │ ├── preferences.png │ │ ├── preferences.svg │ │ ├── qrcode.png │ │ ├── qrcode_white.png │ │ ├── qtum.png │ │ ├── revealer.png │ │ ├── revealer_c.png │ │ ├── safe-t.png │ │ ├── safe-t_unpaired.png │ │ ├── seal.png │ │ ├── seed.png │ │ ├── speaker.png │ │ ├── status_connected.png │ │ ├── status_connected.svg │ │ ├── status_connected_fork.png │ │ ├── status_connected_proxy.png │ │ ├── status_connected_proxy.svg │ │ ├── status_connected_proxy_fork.png │ │ ├── status_disconnected.png │ │ ├── status_disconnected.svg │ │ ├── status_lagging.png │ │ ├── status_lagging.svg │ │ ├── status_lagging_fork.png │ │ ├── status_waiting.png │ │ ├── status_waiting.svg │ │ ├── tab_addresses.png │ │ ├── tab_coins.png │ │ ├── tab_console.png │ │ ├── tab_contacts.png │ │ ├── tab_history.png │ │ ├── tab_receive.png │ │ ├── tab_send.png │ │ ├── tor_logo.png │ │ ├── trezor.png │ │ ├── trezor_unpaired.png │ │ ├── trustedcoin-status.png │ │ ├── trustedcoin-wizard.png │ │ ├── unconfirmed.png │ │ ├── unlock.png │ │ ├── unlock.svg │ │ ├── unpaid.png │ │ ├── update.png │ │ ├── warning.png │ │ └── zoom.png │ ├── kivy │ │ ├── __init__.py │ │ ├── data │ │ │ ├── background.png │ │ │ ├── fonts │ │ │ │ ├── Roboto-Bold.ttf │ │ │ │ ├── Roboto-Condensed.ttf │ │ │ │ ├── Roboto-Medium.ttf │ │ │ │ ├── Roboto.ttf │ │ │ │ └── tron │ │ │ │ │ ├── License.txt │ │ │ │ │ ├── Readme.txt │ │ │ │ │ └── Tr2n.ttf │ │ │ ├── glsl │ │ │ │ ├── default.fs │ │ │ │ ├── default.png │ │ │ │ ├── default.vs │ │ │ │ ├── header.fs │ │ │ │ └── header.vs │ │ │ ├── images │ │ │ │ ├── defaulttheme-0.png │ │ │ │ └── defaulttheme.atlas │ │ │ ├── java-classes │ │ │ │ └── org │ │ │ │ │ └── electrum │ │ │ │ │ └── qr │ │ │ │ │ └── SimpleScannerActivity.java │ │ │ ├── logo │ │ │ │ └── kivy-icon-32.png │ │ │ └── style.kv │ │ ├── i18n.py │ │ ├── main.kv │ │ ├── main_window.py │ │ ├── nfc_scanner │ │ │ ├── __init__.py │ │ │ ├── scanner_android.py │ │ │ └── scanner_dummy.py │ │ ├── theming │ │ │ └── light │ │ │ │ ├── action_bar.png │ │ │ │ ├── action_button_group.png │ │ │ │ ├── action_group_dark.png │ │ │ │ ├── action_group_light.png │ │ │ │ ├── add_contact.png │ │ │ │ ├── arrow_back.png │ │ │ │ ├── bit_logo.png │ │ │ │ ├── blue_bg_round_rb.png │ │ │ │ ├── btn_create_account.png │ │ │ │ ├── btn_create_act_disabled.png │ │ │ │ ├── btn_nfc.png │ │ │ │ ├── btn_send_address.png │ │ │ │ ├── btn_send_nfc.png │ │ │ │ ├── calculator.png │ │ │ │ ├── camera.png │ │ │ │ ├── card.png │ │ │ │ ├── card_bottom.png │ │ │ │ ├── card_btn.png │ │ │ │ ├── card_top.png │ │ │ │ ├── carousel_deselected.png │ │ │ │ ├── carousel_selected.png │ │ │ │ ├── clock1.png │ │ │ │ ├── clock2.png │ │ │ │ ├── clock3.png │ │ │ │ ├── clock4.png │ │ │ │ ├── clock5.png │ │ │ │ ├── close.png │ │ │ │ ├── closebutton.png │ │ │ │ ├── confirmed.png │ │ │ │ ├── contact.png │ │ │ │ ├── contact_overlay.png │ │ │ │ ├── copy.png │ │ │ │ ├── create_act_text.png │ │ │ │ ├── create_act_text_active.png │ │ │ │ ├── delete.png │ │ │ │ ├── dialog.png │ │ │ │ ├── dropdown_background.png │ │ │ │ ├── electrum_icon640.png │ │ │ │ ├── error.png │ │ │ │ ├── eye1.png │ │ │ │ ├── gear.png │ │ │ │ ├── globe.png │ │ │ │ ├── icon_border.png │ │ │ │ ├── important.png │ │ │ │ ├── info.png │ │ │ │ ├── lightblue_bg_round_lb.png │ │ │ │ ├── lightning.png │ │ │ │ ├── lightning.svg │ │ │ │ ├── list.png │ │ │ │ ├── logo.png │ │ │ │ ├── logo_atom_dull.png │ │ │ │ ├── mail_icon.png │ │ │ │ ├── manualentry.png │ │ │ │ ├── network.png │ │ │ │ ├── network.svg │ │ │ │ ├── nfc.png │ │ │ │ ├── nfc_clock.png │ │ │ │ ├── nfc_phone.png │ │ │ │ ├── nfc_stage_one.png │ │ │ │ ├── overflow_background.png │ │ │ │ ├── overflow_btn_dn.png │ │ │ │ ├── paste_icon.png │ │ │ │ ├── pen.png │ │ │ │ ├── qrcode.png │ │ │ │ ├── save.png │ │ │ │ ├── settings.png │ │ │ │ ├── shadow.png │ │ │ │ ├── shadow_right.png │ │ │ │ ├── share.png │ │ │ │ ├── star_big_inactive.png │ │ │ │ ├── stepper_full.png │ │ │ │ ├── stepper_left.png │ │ │ │ ├── stepper_restore_password.png │ │ │ │ ├── stepper_restore_seed.png │ │ │ │ ├── tab.png │ │ │ │ ├── tab_btn.png │ │ │ │ ├── tab_btn_disabled.png │ │ │ │ ├── tab_btn_pressed.png │ │ │ │ ├── tab_disabled.png │ │ │ │ ├── tab_strip.png │ │ │ │ ├── textinput_active.png │ │ │ │ ├── unconfirmed.png │ │ │ │ ├── wallet.png │ │ │ │ ├── wallets.png │ │ │ │ └── white_bg_round_top.png │ │ ├── uix │ │ │ ├── __init__.py │ │ │ ├── combobox.py │ │ │ ├── dialogs │ │ │ │ ├── __init__.py │ │ │ │ ├── addresses.py │ │ │ │ ├── amount_dialog.py │ │ │ │ ├── bump_fee_dialog.py │ │ │ │ ├── checkbox_dialog.py │ │ │ │ ├── choice_dialog.py │ │ │ │ ├── crash_reporter.py │ │ │ │ ├── dscancel_dialog.py │ │ │ │ ├── fee_dialog.py │ │ │ │ ├── fx_dialog.py │ │ │ │ ├── installwizard.py │ │ │ │ ├── invoice_dialog.py │ │ │ │ ├── label_dialog.py │ │ │ │ ├── lightning_channels.py │ │ │ │ ├── lightning_open_channel.py │ │ │ │ ├── lightning_tx_dialog.py │ │ │ │ ├── nfc_transaction.py │ │ │ │ ├── password_dialog.py │ │ │ │ ├── qr_dialog.py │ │ │ │ ├── qr_scanner.py │ │ │ │ ├── question.py │ │ │ │ ├── request_dialog.py │ │ │ │ ├── seed_options.py │ │ │ │ ├── settings.py │ │ │ │ ├── tx_dialog.py │ │ │ │ └── wallets.py │ │ │ ├── drawer.py │ │ │ ├── gridview.py │ │ │ ├── qrcodewidget.py │ │ │ ├── screens.py │ │ │ └── ui_screens │ │ │ │ ├── about.kv │ │ │ │ ├── history.kv │ │ │ │ ├── lightning.kv │ │ │ │ ├── network.kv │ │ │ │ ├── proxy.kv │ │ │ │ ├── receive.kv │ │ │ │ ├── send.kv │ │ │ │ ├── server.kv │ │ │ │ └── status.kv │ │ └── util.py │ ├── qt │ │ ├── __init__.py │ │ ├── address_dialog.py │ │ ├── address_list.py │ │ ├── amountedit.py │ │ ├── bip39_recovery_dialog.py │ │ ├── channel_details.py │ │ ├── channels_list.py │ │ ├── completion_text_edit.py │ │ ├── confirm_tx_dialog.py │ │ ├── console.py │ │ ├── contact_list.py │ │ ├── custom_model.py │ │ ├── delegation_dialog.py │ │ ├── delegation_list.py │ │ ├── exception_window.py │ │ ├── fee_slider.py │ │ ├── history_list.py │ │ ├── installwizard.py │ │ ├── invoice_list.py │ │ ├── lightning_dialog.py │ │ ├── lightning_tx_dialog.py │ │ ├── locktimeedit.py │ │ ├── main_window.py │ │ ├── network_dialog.py │ │ ├── password_dialog.py │ │ ├── paytoedit.py │ │ ├── qrcodewidget.py │ │ ├── qrreader │ │ │ ├── __init__.py │ │ │ └── qtmultimedia │ │ │ │ ├── __init__.py │ │ │ │ ├── camera_dialog.py │ │ │ │ ├── crop_blur_effect.py │ │ │ │ ├── validator.py │ │ │ │ ├── video_overlay.py │ │ │ │ ├── video_surface.py │ │ │ │ └── video_widget.py │ │ ├── qrtextedit.py │ │ ├── qrwindow.py │ │ ├── request_list.py │ │ ├── seed_dialog.py │ │ ├── settings_dialog.py │ │ ├── smart_contract_dialog.py │ │ ├── smart_contract_list.py │ │ ├── stylesheet_patcher.py │ │ ├── swap_dialog.py │ │ ├── token_dialog.py │ │ ├── token_list.py │ │ ├── transaction_dialog.py │ │ ├── update_checker.py │ │ ├── util.py │ │ ├── utxo_list.py │ │ └── watchtower_dialog.py │ ├── stdio.py │ └── text.py ├── i18n.py ├── interface.py ├── invoices.py ├── json_db.py ├── keystore.py ├── lnaddr.py ├── lnchannel.py ├── lnhtlc.py ├── lnmsg.py ├── lnonion.py ├── lnpeer.py ├── lnrater.py ├── lnrouter.py ├── lnsweep.py ├── lntransport.py ├── lnutil.py ├── lnverifier.py ├── lnwatcher.py ├── lnwire │ ├── README.md │ ├── onion_wire.csv │ └── peer_wire.csv ├── lnworker.py ├── locale │ ├── ar_SA │ │ └── electrum.po │ ├── be_BY │ │ └── electrum.po │ ├── bg_BG │ │ └── electrum.po │ ├── cs_CZ │ │ └── electrum.po │ ├── da_DK │ │ └── electrum.po │ ├── de_DE │ │ └── electrum.po │ ├── el_GR │ │ └── electrum.po │ ├── eo_UY │ │ └── electrum.po │ ├── es_ES │ │ └── electrum.po │ ├── fa_IR │ │ └── electrum.po │ ├── fr_FR │ │ └── electrum.po │ ├── hu_HU │ │ └── electrum.po │ ├── hy_AM │ │ └── electrum.po │ ├── id_ID │ │ └── electrum.po │ ├── it_IT │ │ └── electrum.po │ ├── ja_JP │ │ └── electrum.po │ ├── ko_KR │ │ └── electrum.po │ ├── ky_KG │ │ └── electrum.po │ ├── lv_LV │ │ └── electrum.po │ ├── nb_NO │ │ └── electrum.po │ ├── nl_NL │ │ └── electrum.po │ ├── pl_PL │ │ └── electrum.po │ ├── pt_BR │ │ └── electrum.po │ ├── pt_PT │ │ └── electrum.po │ ├── ro_RO │ │ └── electrum.po │ ├── ru_RU │ │ └── electrum.po │ ├── sk_SK │ │ └── electrum.po │ ├── sl_SI │ │ └── electrum.po │ ├── sv_SE │ │ └── electrum.po │ ├── ta_IN │ │ └── electrum.po │ ├── th_TH │ │ └── electrum.po │ ├── tr_TR │ │ └── electrum.po │ ├── uk_UA │ │ └── electrum.po │ ├── vi_VN │ │ └── electrum.po │ ├── zh_CN │ │ └── electrum.po │ └── zh_TW │ │ └── electrum.po ├── logging.py ├── mnemonic.py ├── network.py ├── old_mnemonic.py ├── paymentrequest.proto ├── paymentrequest.py ├── paymentrequest_pb2.py ├── pem.py ├── plot.py ├── plugin.py ├── plugins │ ├── README │ ├── __init__.py │ ├── audio_modem │ │ ├── __init__.py │ │ └── qt.py │ ├── bitbox02 │ │ ├── __init__.py │ │ ├── bitbox02.py │ │ └── qt.py │ ├── coldcard │ │ ├── README.md │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── coldcard.py │ │ └── qt.py │ ├── cosigner_pool │ │ ├── __init__.py │ │ └── qt.py │ ├── digitalbitbox │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── digitalbitbox.py │ │ └── qt.py │ ├── email_requests │ │ ├── __init__.py │ │ └── qt.py │ ├── hw_wallet │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── plugin.py │ │ └── qt.py │ ├── keepkey │ │ ├── __init__.py │ │ ├── client.py │ │ ├── clientbase.py │ │ ├── cmdline.py │ │ ├── keepkey.py │ │ └── qt.py │ ├── labels │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── kivy.py │ │ ├── labels.py │ │ └── qt.py │ ├── ledger │ │ ├── __init__.py │ │ ├── auth2fa.py │ │ ├── cmdline.py │ │ ├── ledger.py │ │ └── qt.py │ ├── revealer │ │ ├── DejaVuSansMono-Bold.ttf │ │ ├── LICENSE_DEJAVU.txt │ │ ├── SIL Open Font License.txt │ │ ├── SourceSansPro-Bold.otf │ │ ├── __init__.py │ │ ├── hmac_drbg.py │ │ ├── qt.py │ │ └── revealer.py │ ├── safe_t │ │ ├── __init__.py │ │ ├── client.py │ │ ├── clientbase.py │ │ ├── cmdline.py │ │ ├── qt.py │ │ ├── safe_t.py │ │ └── transport.py │ ├── trezor │ │ ├── __init__.py │ │ ├── clientbase.py │ │ ├── cmdline.py │ │ ├── qt.py │ │ └── trezor.py │ ├── trustedcoin │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── kivy.py │ │ ├── qt.py │ │ └── trustedcoin.py │ └── virtualkeyboard │ │ ├── __init__.py │ │ └── qt.py ├── qrreader │ ├── __init__.py │ ├── abstract_base.py │ └── zbar.py ├── qrscanner.py ├── ripemd.py ├── rsakey.py ├── scripts │ ├── bip39_recovery.py │ ├── bip70.py │ ├── block_headers.py │ ├── bruteforce_pw.py │ ├── estimate_fee.py │ ├── get_history.py │ ├── peers.py │ ├── quick_start.py │ ├── servers.py │ ├── txradar.py │ └── watch_address.py ├── segwit_addr.py ├── servers.json ├── servers_regtest.json ├── servers_testnet.json ├── simple_config.py ├── sql_db.py ├── storage.py ├── submarine_swaps.py ├── synchronizer.py ├── tests │ ├── __init__.py │ ├── regtest.py │ ├── regtest │ │ ├── regtest.sh │ │ ├── start_bitcoind.sh │ │ └── start_electrumx.sh │ ├── test_bitcoin.py │ ├── test_blockchain.py │ ├── test_bolt11.py │ ├── test_coinchooser.py │ ├── test_commands.py │ ├── test_dnssec.py │ ├── test_lnchannel.py │ ├── test_lnhtlc.py │ ├── test_lnmsg.py │ ├── test_lnpeer.py │ ├── test_lnrouter.py │ ├── test_lntransport.py │ ├── test_lnutil.py │ ├── test_mnemonic.py │ ├── test_network.py │ ├── test_psbt.py │ ├── test_revealer.py │ ├── test_simple_config.py │ ├── test_storage_upgrade.py │ ├── test_transaction.py │ ├── test_util.py │ ├── test_verifier.py │ ├── test_wallet.py │ ├── test_wallet_vertical.py │ └── test_x509.py ├── transaction.py ├── util.py ├── verifier.py ├── version.py ├── wallet.py ├── wallet_db.py ├── wordlist │ ├── chinese_simplified.txt │ ├── english.txt │ ├── japanese.txt │ ├── portuguese.txt │ └── spanish.txt └── x509.py ├── pubkeys ├── Animazing.asc ├── ThomasV.asc ├── bauerj.asc ├── kyuupichan.asc ├── sombernight.asc └── wozz.asc ├── run_electrum ├── screenshot ├── history.png └── tokens.png ├── setup.py └── tox.ini /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ####-*.patch 2 | *.pyc 3 | *.swp 4 | build/ 5 | dist/ 6 | *.egg/ 7 | Electrum.egg-info/ 8 | .devlocaltmp/ 9 | *_trial_temp 10 | packages 11 | env/ 12 | .buildozer/ 13 | bin/ 14 | /app.fil 15 | .idea 16 | .mypy_cache 17 | .vscode 18 | electrum_data 19 | 20 | # icons 21 | electrum/gui/kivy/theming/light-0.png 22 | electrum/gui/kivy/theming/light-1.png 23 | electrum/gui/kivy/theming/light.atlas 24 | 25 | # tests/tox 26 | .tox/ 27 | .cache/ 28 | .coverage 29 | .pytest_cache 30 | 31 | # build workspaces 32 | contrib/build-wine/tmp/ 33 | contrib/build-wine/fresh_clone/ 34 | contrib/build-linux/appimage/build/ 35 | contrib/build-linux/appimage/.cache/ 36 | contrib/android_debug.keystore 37 | 38 | # shared objects 39 | electrum/*.so 40 | electrum/*.so.0 41 | electrum/*.dll 42 | electrum/*.dylib 43 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/.gitmodules -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | ThomasV - Creator and maintainer. 2 | Animazing / Tachikoma - Styled the new GUI. Mac version. 3 | Azelphur - GUI stuff. 4 | Coblee - Alternate coin support and py2app support. 5 | Deafboy - Ubuntu packages. 6 | EagleTM - Bugfixes. 7 | ErebusBat - Mac distribution. 8 | Genjix - Porting pro-mode functionality to lite-gui and worked on server 9 | Slush - Work on the server. Designed the original Stratum spec. 10 | Julian Toash (Tuxavant) - Various fixes to the client. 11 | rdymac - Website and translations. 12 | kyuupichan - Miscellaneous. -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENCE RELEASE-NOTES AUTHORS 2 | include README.rst 3 | include electrum.desktop 4 | include *.py 5 | include run_electrum 6 | recursive-include packages *.py 7 | recursive-include packages cacert.pem 8 | 9 | include contrib/requirements/requirements*.txt 10 | include contrib/deterministic-build/requirements*.txt 11 | include contrib/make_libsecp256k1.sh 12 | include contrib/build_tools_util.sh 13 | 14 | graft electrum 15 | prune electrum/tests 16 | graft contrib/udev 17 | 18 | exclude electrum/*.so 19 | exclude electrum/*.so.0 20 | 21 | global-exclude __pycache__ 22 | global-exclude *.py[co~] 23 | global-exclude *.py.orig 24 | global-exclude *.py.rej 25 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report security issues send an email to electrumdev@gmail.com. 6 | 7 | The following keys may be used to communicate sensitive information to developers: 8 | 9 | | Name | Fingerprint | 10 | |------|-------------| 11 | | ThomasV | 6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6 | 12 | | SomberNight | 4AD6 4339 DFA0 5E20 B3F6 AD51 E7B7 48CD AF5E 5ED9 | 13 | 14 | You can import a key by running the following command with that 15 | individual’s fingerprint: `gpg --recv-keys ""` 16 | Ensure that you put quotes around fingerprints containing spaces. 17 | 18 | These public keys can also be found in the Electrum git repository, 19 | in the top-level `pubkeys` folder. 20 | -------------------------------------------------------------------------------- /contrib/android/Makefile: -------------------------------------------------------------------------------- 1 | PYTHON = python3 2 | 3 | # needs kivy installed or in PYTHONPATH 4 | 5 | .PHONY: theming apk clean 6 | 7 | theming: 8 | #bash -c 'for i in network lightning; do convert -background none theming/light/$i.{svg,png}; done' 9 | $(PYTHON) -m kivy.atlas ../../electrum/gui/kivy/theming/light 1024 ../../electrum/gui/kivy/theming/light/*.png 10 | prepare: 11 | # running pre build setup 12 | @cp buildozer.spec ../../buildozer.spec 13 | # copy electrum to main.py 14 | @cp ../../run_electrum ../../main.py 15 | @-if [ ! -d "../../.buildozer" ];then \ 16 | cd ../..; buildozer android debug;\ 17 | cp -f blacklist.txt .buildozer/android/platform/python-for-android/src/blacklist.txt;\ 18 | rm -rf ./.buildozer/android/platform/python-for-android/dist;\ 19 | fi 20 | apk: 21 | @make prepare 22 | @-cd ../..; buildozer android debug deploy run 23 | @make clean 24 | release: 25 | @make prepare 26 | @-cd ../..; buildozer android release 27 | @make clean 28 | clean: 29 | # Cleaning up 30 | # rename main.py to electrum 31 | @-rm ../../main.py 32 | # remove buildozer.spec 33 | @-rm ../../buildozer.spec 34 | -------------------------------------------------------------------------------- /contrib/android/bitcoin_intent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /contrib/android/blacklist.txt: -------------------------------------------------------------------------------- 1 | # eggs 2 | *.egg-info 3 | 4 | # unit test 5 | unittest/* 6 | 7 | # python config 8 | config/makesetup 9 | 10 | # unused pygame files 11 | pygame/_camera_* 12 | pygame/camera.pyo 13 | pygame/*.html 14 | pygame/*.bmp 15 | pygame/*.svg 16 | pygame/cdrom.so 17 | pygame/pygame_icon.icns 18 | pygame/LGPL 19 | pygame/threads/Py25Queue.pyo 20 | pygame/*.ttf 21 | pygame/mac* 22 | pygame/_numpy* 23 | pygame/sndarray.pyo 24 | pygame/surfarray.pyo 25 | pygame/_arraysurfarray.pyo 26 | 27 | # unused kivy files (platform specific) 28 | kivy/input/providers/wm_* 29 | kivy/input/providers/mactouch* 30 | kivy/input/providers/probesysfs* 31 | kivy/input/providers/mtdev* 32 | kivy/input/providers/hidinput* 33 | kivy/core/camera/camera_videocapture* 34 | kivy/core/spelling/*osx* 35 | kivy/core/video/video_pyglet* 36 | 37 | kivy/adapters 38 | kivy/modules 39 | kivy/uix/sandbox 40 | kivy/uix/pagelayout 41 | kivy/uix/video 42 | kivy/uix/vkeyboard 43 | kivy/uix/videoplayer 44 | 45 | # unused encodings 46 | lib-dynload/*codec* 47 | encodings/cp*.pyo 48 | encodings/tis* 49 | encodings/shift* 50 | encodings/bz2* 51 | encodings/iso* 52 | encodings/undefined* 53 | encodings/johab* 54 | encodings/p* 55 | encodings/m* 56 | encodings/euc* 57 | encodings/k* 58 | encodings/unicode_internal* 59 | encodings/quo* 60 | encodings/gb* 61 | encodings/big5* 62 | encodings/hp* 63 | encodings/hz* 64 | 65 | # unused python modules 66 | bsddb/* 67 | wsgiref/* 68 | hotshot/* 69 | pydoc_data/* 70 | tty.pyo 71 | #anydbm.pyo 72 | nturl2path.pyo 73 | LICENCE.txt 74 | macurl2path.pyo 75 | dummy_threading.pyo 76 | audiodev.pyo 77 | antigravity.pyo 78 | #dumbdbm.pyo 79 | sndhdr.pyo 80 | __phello__.foo.pyo 81 | sunaudio.pyo 82 | os2emxpath.pyo 83 | multiprocessing/dummy* 84 | 85 | # unused binaries python modules 86 | lib-dynload/termios.so 87 | lib-dynload/_lsprof.so 88 | lib-dynload/*audioop.so 89 | #lib-dynload/mmap.so 90 | lib-dynload/_hotshot.so 91 | #lib-dynload/_csv.so 92 | lib-dynload/future_builtins.so 93 | lib-dynload/_heapq.so 94 | lib-dynload/_json.so 95 | lib-dynload/grp.so 96 | lib-dynload/resource.so 97 | lib-dynload/pyexpat.so 98 | 99 | # odd files 100 | plat-linux3/regen 101 | 102 | #>sqlite3 103 | # conditionnal include depending if some recipes are included or not. 104 | #sqlite3/* 105 | #lib-dynload/_sqlite3.so 106 | # /dev/null 2>&1; then 21 | echo "Please install gettext" 22 | exit 1 23 | fi 24 | for i in ./*; do 25 | dir="$ROOT_FOLDER"/electrum/locale/$i/LC_MESSAGES 26 | mkdir -p $dir 27 | msgfmt --output-file=$dir/electrum.mo $i/electrum.po || true 28 | done 29 | ) 30 | 31 | ( 32 | cd "$ROOT_FOLDER" 33 | 34 | echo "'git clean -fd' would delete the following files: >>>" 35 | git clean -fd --dry-run 36 | echo "<<<" 37 | 38 | # we could build the kivy atlas potentially? 39 | #(cd electrum/gui/kivy/; make theming) || echo "building kivy atlas failed! skipping." 40 | 41 | find -exec touch -h -d '2000-11-11T11:11:11+00:00' {} + 42 | 43 | # note: .zip sdists would not be reproducible due to https://bugs.python.org/issue40963 44 | TZ=UTC faketime -f '2000-11-11 11:11:11' python3 setup.py --quiet sdist --format=gztar 45 | ) 46 | -------------------------------------------------------------------------------- /contrib/build-wine/.dockerignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | build/ 3 | .cache/ 4 | dist/ 5 | signed/ 6 | -------------------------------------------------------------------------------- /contrib/build-wine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye@sha256:43ef0c6c3585d5b406caa7a0f232ff5a19c1402aeb415f68bcd1cf9d10180af8 2 | 3 | # need ca-certificates before using snapshot packages 4 | RUN apt update -qq > /dev/null && apt install -qq --yes --no-install-recommends \ 5 | ca-certificates 6 | 7 | # pin the distro packages. 8 | COPY apt.sources.list /etc/apt/sources.list 9 | COPY apt.preferences /etc/apt/preferences.d/snapshot 10 | 11 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 12 | ENV DEBIAN_FRONTEND=noninteractive 13 | 14 | RUN dpkg --add-architecture i386 && \ 15 | apt-get update -q && \ 16 | apt-get install -qy --allow-downgrades \ 17 | wget \ 18 | gnupg2 \ 19 | dirmngr \ 20 | python3-software-properties \ 21 | software-properties-common \ 22 | git \ 23 | p7zip-full \ 24 | make \ 25 | mingw-w64 \ 26 | mingw-w64-tools \ 27 | autotools-dev \ 28 | autoconf \ 29 | autopoint \ 30 | libtool \ 31 | gettext \ 32 | sudo \ 33 | nsis \ 34 | && \ 35 | rm -rf /var/lib/apt/lists/* && \ 36 | apt-get autoremove -y && \ 37 | apt-get clean 38 | 39 | RUN wget -nc https://dl.winehq.org/wine-builds/Release.key && \ 40 | echo "c51bcb8cc4a12abfbd7c7660eaf90f49674d15e222c262f27e6c96429111b822 Release.key" | sha256sum -c - && \ 41 | apt-key add Release.key && \ 42 | rm Release.key && \ 43 | wget -nc https://dl.winehq.org/wine-builds/winehq.key && \ 44 | echo "78b185fabdb323971d13bd329fefc8038e08559aa51c4996de18db0639a51df6 winehq.key" | sha256sum -c - && \ 45 | apt-key add winehq.key && \ 46 | rm winehq.key && \ 47 | apt-add-repository https://dl.winehq.org/wine-builds/debian/ && \ 48 | apt-get update -q && \ 49 | apt-get install -qy --allow-downgrades \ 50 | wine-stable-amd64:amd64=8.0.1~bullseye-1 \ 51 | wine-stable-i386:i386=8.0.1~bullseye-1 \ 52 | wine-stable:amd64=8.0.1~bullseye-1 \ 53 | winehq-stable:amd64=8.0.1~bullseye-1 \ 54 | libvkd3d1:amd64=1.3~bullseye-1 \ 55 | libvkd3d1:i386=1.3~bullseye-1 \ 56 | && \ 57 | rm -rf /var/lib/apt/lists/* && \ 58 | apt-get autoremove -y && \ 59 | apt-get clean 60 | 61 | RUN mkdir --parents "/opt/wine64/drive_c/electrum" 62 | -------------------------------------------------------------------------------- /contrib/build-wine/apt.preferences: -------------------------------------------------------------------------------- 1 | Package: * 2 | Pin: origin "snapshot.debian.org" 3 | Pin-Priority: 1001 4 | -------------------------------------------------------------------------------- /contrib/build-wine/apt.sources.list: -------------------------------------------------------------------------------- 1 | deb https://snapshot.debian.org/archive/debian/20230317T205011Z/ bullseye main 2 | deb-src https://snapshot.debian.org/archive/debian/20230317T205011Z/ bullseye main -------------------------------------------------------------------------------- /contrib/build-wine/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # env vars: 4 | # - ELECBUILD_NOCACHE: if set, forces rebuild of docker image 5 | # - ELECBUILD_COMMIT: if set, do a fresh clone and git checkout 6 | 7 | set -e 8 | 9 | PROJECT_ROOT="$(dirname "$(readlink -e "$0")")/../.." 10 | PROJECT_ROOT_OR_FRESHCLONE_ROOT="$PROJECT_ROOT" 11 | CONTRIB="$PROJECT_ROOT/contrib" 12 | CONTRIB_WINE="$CONTRIB/build-wine" 13 | 14 | . "$CONTRIB"/build_tools_util.sh 15 | 16 | 17 | DOCKER_BUILD_FLAGS="" 18 | if [ ! -z "$ELECBUILD_NOCACHE" ] ; then 19 | info "ELECBUILD_NOCACHE is set. forcing rebuild of docker image." 20 | DOCKER_BUILD_FLAGS="--pull --no-cache" 21 | fi 22 | 23 | info "building docker image." 24 | docker build \ 25 | $DOCKER_BUILD_FLAGS \ 26 | -t qtum-electrum-wine-builder-img \ 27 | "$CONTRIB_WINE" 28 | 29 | info "building binary..." 30 | docker run -it \ 31 | --privileged \ 32 | --name qtum-electrum-wine-builder-cont \ 33 | -v "$PROJECT_ROOT_OR_FRESHCLONE_ROOT":/opt/wine64/drive_c/electrum \ 34 | --rm \ 35 | --workdir /opt/wine64/drive_c/electrum/contrib/build-wine \ 36 | qtum-electrum-wine-builder-img \ 37 | ./make_win.sh 38 | -------------------------------------------------------------------------------- /contrib/build-wine/sign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | here=$(dirname "$0") 4 | test -n "$here" -a -d "$here" || exit 5 | cd $here 6 | 7 | CERT_FILE=${CERT_FILE:-~/codesigning/cert.pem} 8 | KEY_FILE=${KEY_FILE:-~/codesigning/key.pem} 9 | if [[ ! -f "$CERT_FILE" ]]; then 10 | ls $CERT_FILE 11 | echo "Make sure that $CERT_FILE and $KEY_FILE exist" 12 | fi 13 | 14 | if ! which osslsigncode > /dev/null 2>&1; then 15 | echo "Please install osslsigncode" 16 | fi 17 | 18 | rm -rf signed 19 | mkdir -p signed >/dev/null 2>&1 20 | 21 | cd dist 22 | echo "Found $(ls *.exe | wc -w) files to sign." 23 | for f in $(ls *.exe); do 24 | echo "Signing $f..." 25 | osslsigncode sign \ 26 | -h sha256 \ 27 | -certs "$CERT_FILE" \ 28 | -key "$KEY_FILE" \ 29 | -n "Electrum" \ 30 | -i "https://electrum.org/" \ 31 | -t "http://timestamp.digicert.com/" \ 32 | -in "$f" \ 33 | -out "../signed/$f" 34 | ls ../signed/$f -lah 35 | done 36 | -------------------------------------------------------------------------------- /contrib/build-wine/unsign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | here=$(dirname "$0") 3 | test -n "$here" -a -d "$here" || exit 4 | cd $here 5 | 6 | if ! which osslsigncode > /dev/null 2>&1; then 7 | echo "Please install osslsigncode" 8 | exit 9 | fi 10 | 11 | # exit if command fails 12 | set -e 13 | 14 | mkdir -p signed >/dev/null 2>&1 15 | mkdir -p signed/stripped >/dev/null 2>&1 16 | 17 | version=`python3 -c "import electrum; print(electrum.version.ELECTRUM_VERSION)"` 18 | 19 | echo "Found $(ls dist/*.exe | wc -w) files to verify." 20 | 21 | for mine in $(ls dist/*.exe); do 22 | echo "---------------" 23 | f=$(basename $mine) 24 | echo "Downloading https://download.electrum.org/$version/$f" 25 | wget -q https://download.electrum.org/$version/$f -O signed/$f 26 | out="signed/stripped/$f" 27 | # Remove PE signature from signed binary 28 | osslsigncode remove-signature -in signed/$f -out $out > /dev/null 2>&1 29 | chmod +x $out 30 | if cmp -s $out $mine; then 31 | echo "Success: $f" 32 | gpg --sign --armor --detach signed/$f 33 | else 34 | echo "Failure: $f" 35 | fi 36 | done 37 | -------------------------------------------------------------------------------- /contrib/deterministic-build/check_submodules.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | here=$(dirname "$0") 4 | test -n "$here" -a -d "$here" || exit 5 | 6 | cd ${here}/../.. 7 | 8 | git submodule init 9 | git submodule update 10 | 11 | function get_git_mtime { 12 | if [ $# -eq 1 ]; then 13 | git log --pretty=%at -n1 -- $1 14 | else 15 | git log --pretty=%ar -n1 -- $2 16 | fi 17 | } 18 | 19 | fail=0 20 | 21 | 22 | #if [ $(date +%s -d "2 weeks ago") -gt $(get_git_mtime "contrib/deterministic-build/electrum-locale/") ]; then 23 | # echo "Last update from electrum-locale is older than 2 weeks."\ 24 | # "Please update it to incorporate the latest translations from crowdin." 25 | # fail=1 26 | #fi 27 | 28 | exit ${fail} -------------------------------------------------------------------------------- /contrib/deterministic-build/find_restricted_dependencies.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | 4 | try: 5 | import requests 6 | except ImportError as e: 7 | sys.exit(f"Error: {str(e)}. Try 'sudo python3 -m pip install '") 8 | 9 | 10 | def check_restriction(p, r): 11 | # See: https://www.python.org/dev/peps/pep-0496/ 12 | # Hopefully we don't need to parse the whole microlanguage 13 | if "extra" in r and "[" not in p: 14 | return False 15 | for marker in ["os_name", "platform_release", "sys_platform", "platform_system"]: 16 | if marker in r: 17 | return True 18 | 19 | 20 | for p in sys.stdin.read().split(): 21 | p = p.strip() 22 | if not p: 23 | continue 24 | assert "==" in p, "This script expects a list of packages with pinned version, e.g. package==1.2.3, not {}".format(p) 25 | p, v = p.rsplit("==", 1) 26 | try: 27 | data = requests.get("https://pypi.org/pypi/{}/{}/json".format(p, v)).json()["info"] 28 | except ValueError: 29 | raise Exception("Package could not be found: {}=={}".format(p, v)) 30 | try: 31 | for r in data["requires_dist"]: 32 | if ";" not in r: 33 | continue 34 | d, restricted = r.split(";", 1) 35 | if check_restriction(d, restricted): 36 | print(d, sep=" ") 37 | print("Installing {} from {} although it is only needed for {}".format(d, p, restricted), file=sys.stderr) 38 | except TypeError: 39 | # Has no dependencies at all 40 | continue 41 | 42 | -------------------------------------------------------------------------------- /contrib/deterministic-build/requirements-build-appimage.txt: -------------------------------------------------------------------------------- 1 | Cython==0.29.32 \ 2 | --hash=sha256:8733cf4758b79304f2a4e39ebfac5e92341bce47bcceb26c1254398b2f8c1af7 \ 3 | --hash=sha256:eeb475eb6f0ccf6c039035eb4f0f928eb53ead88777e0a760eccb140ad90930b 4 | pip==22.3.1 \ 5 | --hash=sha256:65fd48317359f3af8e593943e6ae1506b66325085ea64b706a998c6e83eeaf38 \ 6 | --hash=sha256:908c78e6bc29b676ede1c4d57981d490cb892eb45cd8c214ab6298125119e077 7 | setuptools==67.8.0 \ 8 | --hash=sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102 \ 9 | --hash=sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f 10 | wheel==0.38.4 \ 11 | --hash=sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac \ 12 | --hash=sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8 13 | -------------------------------------------------------------------------------- /contrib/deterministic-build/requirements-build-base.txt: -------------------------------------------------------------------------------- 1 | flit-core==3.8.0 \ 2 | --hash=sha256:64a29ec845164a6abe1136bf4bc5ae012bdfe758ed42fc7571a9059a7c80bd83 \ 3 | --hash=sha256:b305b30c99526df5e63d6022dd2310a0a941a187bd3884f4c8ef0418df6c39f3 4 | packaging==21.3 \ 5 | --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \ 6 | --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 7 | pip==22.3.1 \ 8 | --hash=sha256:65fd48317359f3af8e593943e6ae1506b66325085ea64b706a998c6e83eeaf38 \ 9 | --hash=sha256:908c78e6bc29b676ede1c4d57981d490cb892eb45cd8c214ab6298125119e077 10 | poetry-core==1.3.2 \ 11 | --hash=sha256:0ab006a40cb38d6a38b97264f6835da2f08a96912f2728ce668e9ac6a34f686f \ 12 | --hash=sha256:ea0f5a90b339cde132b4e43cff78a1b440cd928db864bb67cfc97fdfcefe7218 13 | pyparsing==3.0.9 \ 14 | --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \ 15 | --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc 16 | setuptools==67.8.0 \ 17 | --hash=sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102 \ 18 | --hash=sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f 19 | setuptools-scm==7.0.5 \ 20 | --hash=sha256:031e13af771d6f892b941adb6ea04545bbf91ebc5ce68c78aaf3fff6e1fb4844 \ 21 | --hash=sha256:7930f720905e03ccd1e1d821db521bff7ec2ac9cf0ceb6552dd73d24a45d3b02 22 | tomli==2.0.1 \ 23 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ 24 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f 25 | typing-extensions==4.4.0 \ 26 | --hash=sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa \ 27 | --hash=sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e 28 | wheel==0.38.4 \ 29 | --hash=sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac \ 30 | --hash=sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8 31 | -------------------------------------------------------------------------------- /contrib/deterministic-build/requirements-build-mac.txt: -------------------------------------------------------------------------------- 1 | altgraph==0.17.4 \ 2 | --hash=sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff \ 3 | --hash=sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406 4 | Cython==0.29.32 \ 5 | --hash=sha256:8733cf4758b79304f2a4e39ebfac5e92341bce47bcceb26c1254398b2f8c1af7 \ 6 | --hash=sha256:eeb475eb6f0ccf6c039035eb4f0f928eb53ead88777e0a760eccb140ad90930b 7 | macholib==1.16.2 \ 8 | --hash=sha256:557bbfa1bb255c20e9abafe7ed6cd8046b48d9525db2f9b77d3122a63a2a8bf8 9 | pip==22.3.1 \ 10 | --hash=sha256:65fd48317359f3af8e593943e6ae1506b66325085ea64b706a998c6e83eeaf38 \ 11 | --hash=sha256:908c78e6bc29b676ede1c4d57981d490cb892eb45cd8c214ab6298125119e077 12 | pyinstaller-hooks-contrib==2022.13 \ 13 | --hash=sha256:e06d0881e599d94dc39c6ed1917f0ad9b1858a2478b9892faac18bd48bcdc2de 14 | setuptools==67.8.0 \ 15 | --hash=sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102 \ 16 | --hash=sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f 17 | wheel==0.38.4 \ 18 | --hash=sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac \ 19 | --hash=sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8 20 | -------------------------------------------------------------------------------- /contrib/deterministic-build/requirements-build-sdist.txt: -------------------------------------------------------------------------------- 1 | pip==22.3.1 \ 2 | --hash=sha256:65fd48317359f3af8e593943e6ae1506b66325085ea64b706a998c6e83eeaf38 \ 3 | --hash=sha256:908c78e6bc29b676ede1c4d57981d490cb892eb45cd8c214ab6298125119e077 4 | setuptools==67.8.0 \ 5 | --hash=sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102 \ 6 | --hash=sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f 7 | wheel==0.38.4 \ 8 | --hash=sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac \ 9 | --hash=sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8 10 | -------------------------------------------------------------------------------- /contrib/deterministic-build/requirements-build-wine.txt: -------------------------------------------------------------------------------- 1 | altgraph==0.17.4 \ 2 | --hash=sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff \ 3 | --hash=sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406 4 | future==0.18.3 \ 5 | --hash=sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307 6 | pefile==2022.5.30 \ 7 | --hash=sha256:a5488a3dd1fd021ce33f969780b88fe0f7eebb76eb20996d7318f307612a045b 8 | pip==22.3.1 \ 9 | --hash=sha256:65fd48317359f3af8e593943e6ae1506b66325085ea64b706a998c6e83eeaf38 \ 10 | --hash=sha256:908c78e6bc29b676ede1c4d57981d490cb892eb45cd8c214ab6298125119e077 11 | pyinstaller-hooks-contrib==2022.13 \ 12 | --hash=sha256:e06d0881e599d94dc39c6ed1917f0ad9b1858a2478b9892faac18bd48bcdc2de \ 13 | --hash=sha256:91ecb30db757a8db8b6661d91d5df99e0998245f05f5cfaade0550922c7030a3 14 | pywin32-ctypes==0.2.0 \ 15 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ 16 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 17 | setuptools==67.8.0 \ 18 | --hash=sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102 \ 19 | --hash=sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f 20 | wheel==0.38.4 \ 21 | --hash=sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac \ 22 | --hash=sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8 23 | -------------------------------------------------------------------------------- /contrib/deterministic-build/requirements-eth.txt: -------------------------------------------------------------------------------- 1 | pycryptodomex==3.10.4 \ 2 | --hash=sha256:acd3498a8ccf8ad20ce7daa5f7f5e6521465eeceb026f28a6adb0228dd9fcc6e \ 3 | --hash=sha256:82ee08933c2b682cf55a229851c7d69767d307f33f05b1f05a09f207cbb25308 \ 4 | --hash=sha256:c1888507549eccedd0fff20dfa70c95b3848bf5b4fe2da1c971ee3ee646675d9 \ 5 | --hash=sha256:99f925b9a1c6a62f03385e0c14f8fd55d2366bb47fd8c3ccd82764c4f39aa5b5 \ 6 | --hash=sha256:ea3e634623ff41a9471517a9a3735821d91cfc97b8b803522e9fd96c1a094568 \ 7 | --hash=sha256:22838f744833bd5befb6b9b55c50e255b39fa3cb2c7d28c2d9e903f222f8cc4c \ 8 | --hash=sha256:c07f8cad7b2597357291f144a07c0120399bc0a1ee5ca0c6b2af52691ad2a22a \ 9 | --hash=sha256:9e628383788eac3f661798c01121029a60722a0922b3e903ea88be3065231256 \ 10 | --hash=sha256:a68871322ece62fea85ba63c16c5d0fb150be723e71cb879b6fd011c38afc502 \ 11 | --hash=sha256:784b39e5c4d6331f559036b0efc8593d3336a6e6a0db86997fe2679bc84a3a82 \ 12 | --hash=sha256:041cbde579b3e044ea1b24ff16e4a2d84eacdfd925a96bca21707df0953d1f94 \ 13 | --hash=sha256:6cd44aca92f997c049050a6d2048a3009068dfe34830f76964019679c727fe40 \ 14 | --hash=sha256:1ad37bae59782e864317725da11cd9f9bc4e6def1e68f673054e0e855ceef9ac \ 15 | --hash=sha256:c905625a65f2b05c9d1c4be8c182f34ee274d704441c3cc57f440097ccc63dc3 \ 16 | --hash=sha256:0e1b6dfe40e98a4f0368fa4df4c6f61ef8ed1d505efc8c1d5936e0091a127da6 \ 17 | --hash=sha256:9dae6c26803e04cac1aa4144d0f3ec4f9984c10449208eed430c98c63776d0d0 \ 18 | --hash=sha256:cb585c23505bc6a6c51d91830ea15bb28369ecab6301ab3e8f0474b5c651c064 \ 19 | --hash=sha256:e767c7a84d7eff2294ea488dfd1b9583b886f95cd521c59495f0266c7d967e1f 20 | toolz==0.10.0 \ 21 | --hash=sha256:08fdd5ef7c96480ad11c12d472de21acd32359996f69a5259299b540feba4560 22 | https://github.com/icodeface/eth-hash/archive/master.zip \ 23 | --hash=sha256:e1d310018e2b327272611ebe06b1a101c5fa817f9d890bdbd7adfdbc862cdfaf 24 | https://github.com/icodeface/eth-utils/archive/master.zip \ 25 | --hash=sha256:c2b0b5232ec9fa06c9fe8b4074812d015eb33310c0386e857ae04f1d0682f56a 26 | https://github.com/icodeface/eth-abi/archive/master.zip \ 27 | --hash=sha256:1cf87ce883f746381ee94f2c6e179b23556b5e0bfa3ba0cf756b3799ee4aa6e2 28 | -------------------------------------------------------------------------------- /contrib/freeze_packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Run this after a new release to update dependencies 3 | 4 | set -e 5 | 6 | venv_dir=~/.electrum-venv 7 | contrib=$(dirname "$0") 8 | 9 | # note: we should not use a higher version of python than what the binaries bundle 10 | if [[ ! "$SYSTEM_PYTHON" ]] ; then 11 | SYSTEM_PYTHON=$(which python3.6) || printf "" 12 | else 13 | SYSTEM_PYTHON=$(which $SYSTEM_PYTHON) || printf "" 14 | fi 15 | if [[ ! "$SYSTEM_PYTHON" ]] ; then 16 | echo "Please specify which python to use in \$SYSTEM_PYTHON" && exit 1; 17 | fi 18 | 19 | which virtualenv > /dev/null 2>&1 || { echo "Please install virtualenv" && exit 1; } 20 | 21 | ${SYSTEM_PYTHON} -m hashin -h > /dev/null 2>&1 || { ${SYSTEM_PYTHON} -m pip install hashin; } 22 | 23 | for i in '' '-hw' '-binaries' '-binaries-mac' '-build-wine' '-build-mac' '-build-sdist' '-build-appimage'; do 24 | rm -rf "$venv_dir" 25 | virtualenv -p ${SYSTEM_PYTHON} $venv_dir 26 | 27 | source $venv_dir/bin/activate 28 | 29 | echo "Installing dependencies... (requirements${i}.txt)" 30 | 31 | python -m pip install -r "$contrib/requirements/requirements${i}.txt" --upgrade 32 | 33 | echo "OK." 34 | 35 | requirements=$(pip freeze --all) 36 | restricted=$(echo $requirements | ${SYSTEM_PYTHON} $contrib/deterministic-build/find_restricted_dependencies.py) 37 | requirements="$requirements $restricted" 38 | 39 | echo "Generating package hashes... (requirements${i}.txt)" 40 | rm "$contrib/deterministic-build/requirements${i}.txt" 41 | touch "$contrib/deterministic-build/requirements${i}.txt" 42 | 43 | for requirement in $requirements; do 44 | echo -e "\r Hashing $requirement..." 45 | ${SYSTEM_PYTHON} -m hashin -r "$contrib/deterministic-build/requirements${i}.txt" "${requirement}" 46 | done 47 | 48 | echo "OK." 49 | done 50 | 51 | echo "Done. Updated requirements" 52 | -------------------------------------------------------------------------------- /contrib/make_libusb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | LIBUSB_VERSION="4239bc3a50014b8e6a5a2a59df1fff3b7469543b" 4 | # ^ tag v1.0.26 5 | 6 | set -e 7 | 8 | . $(dirname "$0")/build_tools_util.sh || (echo "Could not source build_tools_util.sh" && exit 1) 9 | 10 | here="$(dirname "$(realpath "$0" 2> /dev/null || grealpath "$0")")" 11 | CONTRIB="$here" 12 | PROJECT_ROOT="$CONTRIB/.." 13 | 14 | pkgname="libusb" 15 | info "Building $pkgname..." 16 | 17 | ( 18 | cd "$CONTRIB" 19 | if [ ! -d libusb ]; then 20 | git clone https://github.com/libusb/libusb.git 21 | fi 22 | cd libusb 23 | if ! $(git cat-file -e ${LIBUSB_VERSION}) ; then 24 | info "Could not find requested version $LIBUSB_VERSION in local clone; fetching..." 25 | git fetch --all 26 | fi 27 | git reset --hard 28 | git clean -dfxq 29 | git checkout "${LIBUSB_VERSION}^{commit}" 30 | 31 | if [ "$BUILD_TYPE" = "wine" ] ; then 32 | echo "libusb_1_0_la_LDFLAGS += -Wc,-static" >> libusb/Makefile.am 33 | fi 34 | ./bootstrap.sh || fail "Could not bootstrap libusb" 35 | if ! [ -r config.status ] ; then 36 | if [ "$BUILD_TYPE" = "wine" ] ; then 37 | # windows target 38 | LDFLAGS="-Wl,--no-insert-timestamp" 39 | elif [ $(uname) == "Darwin" ]; then 40 | # macos target 41 | LDFLAGS="-Wl -lm" 42 | else 43 | # linux target 44 | LDFLAGS="" 45 | fi 46 | LDFLAGS="$LDFLAGS" ./configure \ 47 | $AUTOCONF_FLAGS \ 48 | || fail "Could not configure $pkgname. Please make sure you have a C compiler installed and try again." 49 | fi 50 | make "-j$CPU_COUNT" || fail "Could not build $pkgname" 51 | make install || warn "Could not install $pkgname" 52 | . "$here/$pkgname/libusb/.libs/libusb-1.0.la" 53 | host_strip "$here/$pkgname/libusb/.libs/$dlname" 54 | TARGET_NAME="$dlname" 55 | if [ $(uname) == "Darwin" ]; then # on mac, dlname is "libusb-1.0.0.dylib" 56 | TARGET_NAME="libusb-1.0.dylib" 57 | fi 58 | cp -fpv "$here/$pkgname/libusb/.libs/$dlname" "$PROJECT_ROOT/electrum/$TARGET_NAME" || fail "Could not copy the $pkgname binary to its destination" 59 | info "$TARGET_NAME has been placed in the inner 'electrum' folder." 60 | if [ -n "$DLL_TARGET_DIR" ] ; then 61 | cp -fpv "$here/$pkgname/libusb/.libs/$dlname" "$DLL_TARGET_DIR/$TARGET_NAME" || fail "Could not copy the $pkgname binary to DLL_TARGET_DIR" 62 | fi 63 | ) 64 | -------------------------------------------------------------------------------- /contrib/make_locale: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | 4 | os.chdir(os.path.dirname(os.path.realpath(__file__))) 5 | os.chdir('../electrum') 6 | 7 | # Convert .po to .mo 8 | print('Installing') 9 | for lang in os.listdir('locale'): 10 | if lang.startswith('messages'): 11 | continue 12 | # Check LC_MESSAGES folder 13 | mo_dir = 'locale/%s/LC_MESSAGES' % lang 14 | if not os.path.exists(mo_dir): 15 | os.mkdir(mo_dir) 16 | cmd = 'msgfmt --output-file="%s/electrum.mo" "locale/%s/electrum.po"' % (mo_dir, lang) 17 | print('Installing', lang) 18 | os.system(cmd) -------------------------------------------------------------------------------- /contrib/make_packages: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CONTRIB="$(dirname "$0")" 4 | test -n "$CONTRIB" -a -d "$CONTRIB" || exit 5 | 6 | rm "$CONTRIB"/../packages/ -r 7 | 8 | #Install pure python modules in electrum directory 9 | python3 -m pip install --no-dependencies --no-binary :all: \ 10 | -r "$CONTRIB"/deterministic-build/requirements.txt -t "$CONTRIB"/../packages 11 | 12 | -------------------------------------------------------------------------------- /contrib/osx/cdrkit-deterministic.patch: -------------------------------------------------------------------------------- 1 | --- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400 2 | +++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500 3 | @@ -1139,8 +1139,9 @@ 4 | scan_directory_tree(struct directory *this_dir, char *path, 5 | struct directory_entry *de) 6 | { 7 | - DIR *current_dir; 8 | + int current_file; 9 | char whole_path[PATH_MAX]; 10 | + struct dirent **d_list; 11 | struct dirent *d_entry; 12 | struct directory *parent; 13 | int dflag; 14 | @@ -1164,7 +1165,8 @@ 15 | this_dir->dir_flags |= DIR_WAS_SCANNED; 16 | 17 | errno = 0; /* Paranoia */ 18 | - current_dir = opendir(path); 19 | + //current_dir = opendir(path); 20 | + current_file = scandir(path, &d_list, NULL, alphasort); 21 | d_entry = NULL; 22 | 23 | /* 24 | @@ -1173,12 +1175,12 @@ 25 | */ 26 | old_path = path; 27 | 28 | - if (current_dir) { 29 | + if (current_file >= 0) { 30 | errno = 0; 31 | - d_entry = readdir(current_dir); 32 | + d_entry = d_list[0]; 33 | } 34 | 35 | - if (!current_dir || !d_entry) { 36 | + if (current_file < 0 || !d_entry) { 37 | int ret = 1; 38 | 39 | #ifdef USE_LIBSCHILY 40 | @@ -1191,8 +1193,8 @@ 41 | de->isorec.flags[0] &= ~ISO_DIRECTORY; 42 | ret = 0; 43 | } 44 | - if (current_dir) 45 | - closedir(current_dir); 46 | + if(d_list) 47 | + free(d_list); 48 | return (ret); 49 | } 50 | #ifdef ABORT_DEEP_ISO_ONLY 51 | @@ -1208,7 +1210,7 @@ 52 | errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n"); 53 | errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n"); 54 | } 55 | - closedir(current_dir); 56 | + free(d_list); 57 | return (1); 58 | } 59 | #endif 60 | @@ -1250,13 +1252,13 @@ 61 | * The first time through, skip this, since we already asked 62 | * for the first entry when we opened the directory. 63 | */ 64 | - if (dflag) 65 | - d_entry = readdir(current_dir); 66 | + if (dflag && current_file >= 0) 67 | + d_entry = d_list[current_file]; 68 | dflag++; 69 | 70 | - if (!d_entry) 71 | + if (current_file < 0) 72 | break; 73 | - 74 | + current_file--; 75 | /* OK, got a valid entry */ 76 | 77 | /* If we do not want all files, then pitch the backups. */ 78 | @@ -1348,7 +1350,7 @@ 79 | insert_file_entry(this_dir, whole_path, d_entry->d_name); 80 | #endif /* APPLE_HYB */ 81 | } 82 | - closedir(current_dir); 83 | + free(d_list); 84 | 85 | #ifdef APPLE_HYB 86 | /* -------------------------------------------------------------------------------- /contrib/osx/entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.apple.security.cs.allow-unsigned-executable-memory 8 | 9 | com.apple.security.cs.disable-library-validation 10 | 11 | 12 | 13 | 14 | com.apple.security.cs.allow-dyld-environment-variables 15 | 16 | com.apple.security.cs.allow-jit 17 | 18 | 19 | 20 | com.apple.security.device.camera 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /contrib/pull_locale: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import subprocess 4 | import io 5 | import zipfile 6 | import sys 7 | 8 | try: 9 | import requests 10 | except ImportError as e: 11 | sys.exit(f"Error: {str(e)}. Try 'sudo python3 -m pip install '") 12 | 13 | os.chdir(os.path.dirname(os.path.realpath(__file__))) 14 | os.chdir('..') 15 | 16 | cmd = "find electrum -type f -name '*.py' -o -name '*.kv'" 17 | 18 | files = subprocess.check_output(cmd, shell=True) 19 | 20 | with open("app.fil", "wb") as f: 21 | f.write(files) 22 | 23 | print("Found {} files to translate".format(len(files.splitlines()))) 24 | 25 | # Generate fresh translation template 26 | if not os.path.exists('electrum/locale'): 27 | os.mkdir('electrum/locale') 28 | cmd = 'xgettext -s --from-code UTF-8 --language Python --no-wrap -f app.fil --output=electrum/locale/messages.pot' 29 | print('Generate template') 30 | os.system(cmd) 31 | 32 | os.chdir('electrum') 33 | 34 | crowdin_identifier = 'electrum' 35 | crowdin_file_name = 'files[electrum-client/messages.pot]' 36 | locale_file_name = 'locale/messages.pot' 37 | 38 | # Download & unzip 39 | print('Download translations') 40 | s = requests.request('GET', 'https://crowdin.com/backend/download/project/' + crowdin_identifier + '.zip').content 41 | zfobj = zipfile.ZipFile(io.BytesIO(s)) 42 | 43 | print('Unzip translations') 44 | for name in zfobj.namelist(): 45 | if not name.startswith('electrum-client/locale'): 46 | continue 47 | if name.endswith('/'): 48 | if not os.path.exists(name[16:]): 49 | os.mkdir(name[16:]) 50 | else: 51 | with open(name[16:], 'wb') as output: 52 | output.write(zfobj.read(name)) 53 | 54 | # Convert .po to .mo 55 | print('Installing') 56 | for lang in os.listdir('locale'): 57 | if lang.startswith('messages'): 58 | continue 59 | # Check LC_MESSAGES folder 60 | mo_dir = 'locale/%s/LC_MESSAGES' % lang 61 | if not os.path.exists(mo_dir): 62 | os.mkdir(mo_dir) 63 | cmd = 'msgfmt --output-file="%s/electrum.mo" "locale/%s/electrum.po"' % (mo_dir,lang) 64 | print('Installing', lang) 65 | os.system(cmd) 66 | -------------------------------------------------------------------------------- /contrib/push_locale: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import subprocess 4 | import io 5 | import zipfile 6 | import sys 7 | 8 | try: 9 | import requests 10 | except ImportError as e: 11 | sys.exit(f"Error: {str(e)}. Try 'sudo python3 -m pip install '") 12 | 13 | os.chdir(os.path.dirname(os.path.realpath(__file__))) 14 | os.chdir('..') 15 | 16 | cmd = "find electrum -type f -name '*.py' -o -name '*.kv'" 17 | 18 | files = subprocess.check_output(cmd, shell=True) 19 | 20 | with open("app.fil", "wb") as f: 21 | f.write(files) 22 | 23 | print("Found {} files to translate".format(len(files.splitlines()))) 24 | 25 | # Generate fresh translation template 26 | if not os.path.exists('electrum/locale'): 27 | os.mkdir('electrum/locale') 28 | cmd = 'xgettext -s --from-code UTF-8 --language Python --no-wrap -f app.fil --output=electrum/locale/messages.pot' 29 | print('Generate template') 30 | os.system(cmd) 31 | 32 | os.chdir('electrum') 33 | 34 | crowdin_identifier = 'electrum' 35 | crowdin_file_name = 'files[electrum-client/messages.pot]' 36 | locale_file_name = 'locale/messages.pot' 37 | crowdin_api_key = None 38 | 39 | filename = os.path.expanduser('~/.crowdin_api_key') 40 | if os.path.exists(filename): 41 | with open(filename) as f: 42 | crowdin_api_key = f.read().strip() 43 | 44 | if "crowdin_api_key" in os.environ: 45 | crowdin_api_key = os.environ["crowdin_api_key"] 46 | 47 | if crowdin_api_key: 48 | # Push to Crowdin 49 | print('Push to Crowdin') 50 | url = ('https://api.crowdin.com/api/project/' + crowdin_identifier + '/update-file?key=' + crowdin_api_key) 51 | with open(locale_file_name, 'rb') as f: 52 | files = {crowdin_file_name: f} 53 | response = requests.request('POST', url, files=files) 54 | print("", "update-file:", "-"*20, response.text, "-"*20, sep="\n") 55 | # Build translations 56 | print('Build translations') 57 | response = requests.request('GET', 'https://api.crowdin.com/api/project/' + crowdin_identifier + '/export?key=' + crowdin_api_key) 58 | print("", "export:", "-" * 20, response.text, "-" * 20, sep="\n") 59 | 60 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-binaries-mac.txt: -------------------------------------------------------------------------------- 1 | PyQt5>=5.15.2 2 | cryptography>=2.6 3 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-binaries.txt: -------------------------------------------------------------------------------- 1 | PyQt5 2 | cryptography>=3.2 3 | pycryptodomex>=3.7 4 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-build-appimage.txt: -------------------------------------------------------------------------------- 1 | pip 2 | setuptools 3 | wheel 4 | 5 | # Note: hidapi requires Cython at build-time (not needed at runtime). 6 | # For reproducible builds, the version of Cython must be pinned down. 7 | # The pinned Cython must be installed before hidapi is built; 8 | # otherwise when installing hidapi, pip just downloads the latest Cython. 9 | # see https://github.com/spesmilo/electrum/issues/5859 10 | Cython>=0.27 11 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-build-mac.txt: -------------------------------------------------------------------------------- 1 | pip 2 | setuptools 3 | wheel 4 | 5 | # needed by pyinstaller: 6 | macholib>=1.8 7 | altgraph 8 | pyinstaller-hooks-contrib>=2020.6 9 | 10 | # Note: hidapi requires Cython at build-time (not needed at runtime). 11 | # For reproducible builds, the version of Cython must be pinned down. 12 | # The pinned Cython must be installed before hidapi is built; 13 | # otherwise when installing hidapi, pip just downloads the latest Cython. 14 | # see https://github.com/spesmilo/electrum/issues/5859 15 | Cython>=0.27 16 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-build-sdist.txt: -------------------------------------------------------------------------------- 1 | # need modern versions of pip (and maybe other build tools), the one in apt had issues 2 | pip 3 | setuptools 4 | wheel 5 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-build-wine.txt: -------------------------------------------------------------------------------- 1 | pip 2 | setuptools 3 | wheel 4 | 5 | # needed by pyinstaller: 6 | pefile>=2017.8.1 7 | altgraph 8 | pywin32-ctypes>=0.2.0 9 | pyinstaller-hooks-contrib>=2020.11 10 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-eth.txt: -------------------------------------------------------------------------------- 1 | pycryptodomex>=3.9.7 2 | https://github.com/icodeface/eth-hash/archive/master.zip 3 | https://github.com/icodeface/eth-utils/archive/master.zip 4 | https://github.com/icodeface/eth-abi/archive/master.zip -------------------------------------------------------------------------------- /contrib/requirements/requirements-hw.txt: -------------------------------------------------------------------------------- 1 | hidapi 2 | trezor[hidapi]>=0.13.0,<0.14 3 | safet>=0.1.5 4 | keepkey>=6.3.1 5 | ckcc-protocol>=0.7.7 6 | bitbox02>=5.2.0 7 | ledgercomm 8 | https://github.com/qtumproject/btchip-python/archive/master.zip 9 | https://github.com/qtumproject/ledger-qtum-py/archive/master.zip 10 | -------------------------------------------------------------------------------- /contrib/requirements/requirements-travis.txt: -------------------------------------------------------------------------------- 1 | tox 2 | coveralls 3 | tox-travis 4 | -------------------------------------------------------------------------------- /contrib/requirements/requirements.txt: -------------------------------------------------------------------------------- 1 | ecdsa>=0.14 2 | qrcode 3 | protobuf>=3.20,<4 4 | qdarkstyle<2.9 5 | aiorpcx>=0.18.7,<0.19 6 | aiohttp>=3.3.0,<4.0.0 7 | aiohttp_socks>=0.3 8 | certifi 9 | bitstring 10 | attrs>=19.2.0 11 | 12 | # Note that we also need the dnspython[DNSSEC] extra which pulls in cryptography, 13 | # but as that is not pure-python it cannot be listed in this file! 14 | dnspython>=2.0 15 | -------------------------------------------------------------------------------- /contrib/sign_packages: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import getpass 4 | 5 | if __name__ == '__main__': 6 | 7 | os.chdir("dist") 8 | password = getpass.getpass("Password:") 9 | for f in os.listdir('.'): 10 | if f.endswith('asc'): 11 | continue 12 | os.system( "gpg --sign --armor --detach --passphrase \"%s\" %s"%(password, f) ) 13 | 14 | os.chdir("..") 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /contrib/sign_version: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | version=`python3 -c "import electrum; print(electrum.version.ELECTRUM_VERSION)"` 3 | sig=`./run_electrum -o signmessage $SIGNING_ADDRESS $version -w $SIGNING_WALLET` 4 | echo "{ \"version\":\"$version\", \"signatures\":{ \"$SIGNING_ADDRESS\":\"$sig\"}}" 5 | -------------------------------------------------------------------------------- /contrib/udev/20-hw1.rules: -------------------------------------------------------------------------------- 1 | # HW.1 / Nano 2 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="1b7c|2b7c|3b7c|4b7c", TAG+="uaccess", TAG+="udev-acl" 3 | # Blue 4 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0000|0000|0001|0002|0003|0004|0005|0006|0007|0008|0009|000a|000b|000c|000d|000e|000f|0010|0011|0012|0013|0014|0015|0016|0017|0018|0019|001a|001b|001c|001d|001e|001f", TAG+="uaccess", TAG+="udev-acl" 5 | # Nano S 6 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0001|1000|1001|1002|1003|1004|1005|1006|1007|1008|1009|100a|100b|100c|100d|100e|100f|1010|1011|1012|1013|1014|1015|1016|1017|1018|1019|101a|101b|101c|101d|101e|101f", TAG+="uaccess", TAG+="udev-acl" 7 | # Aramis 8 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0002|2000|2001|2002|2003|2004|2005|2006|2007|2008|2009|200a|200b|200c|200d|200e|200f|2010|2011|2012|2013|2014|2015|2016|2017|2018|2019|201a|201b|201c|201d|201e|201f", TAG+="uaccess", TAG+="udev-acl" 9 | # HW2 10 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0003|3000|3001|3002|3003|3004|3005|3006|3007|3008|3009|300a|300b|300c|300d|300e|300f|3010|3011|3012|3013|3014|3015|3016|3017|3018|3019|301a|301b|301c|301d|301e|301f", TAG+="uaccess", TAG+="udev-acl" 11 | # Nano X 12 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0004|4000|4001|4002|4003|4004|4005|4006|4007|4008|4009|400a|400b|400c|400d|400e|400f|4010|4011|4012|4013|4014|4015|4016|4017|4018|4019|401a|401b|401c|401d|401e|401f", TAG+="uaccess", TAG+="udev-acl" 13 | -------------------------------------------------------------------------------- /contrib/udev/51-coinkite.rules: -------------------------------------------------------------------------------- 1 | # Linux udev support file. 2 | # 3 | # This is a example udev file for HIDAPI devices which changes the permissions 4 | # to 0666 (world readable/writable) for a specific device on Linux systems. 5 | # 6 | # - Copy this file into /etc/udev/rules.d and unplug and re-plug your Coldcard. 7 | # - Udev does not have to be restarted. 8 | # 9 | 10 | # probably not needed: 11 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="d13e", ATTRS{idProduct}=="cc10", GROUP="plugdev", MODE="0666" 12 | 13 | # required: 14 | # from 15 | KERNEL=="hidraw*", ATTRS{idVendor}=="d13e", ATTRS{idProduct}=="cc10", GROUP="plugdev", MODE="0666" 16 | 17 | -------------------------------------------------------------------------------- /contrib/udev/51-hid-digitalbitbox.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="usb", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="dbb%n", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2402" 2 | -------------------------------------------------------------------------------- /contrib/udev/51-safe-t.rules: -------------------------------------------------------------------------------- 1 | # Put this file into /usr/lib/udev/rules.d or /etc/udev/rules.d 2 | 3 | # Archos Safe-T mini 4 | SUBSYSTEM=="usb", ATTR{idVendor}=="0e79", ATTR{idProduct}=="6000", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="safe-tr%n" 5 | KERNEL=="hidraw*", ATTRS{idVendor}=="0e79", ATTRS{idProduct}=="6000", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" 6 | 7 | # Archos Safe-T mini Bootloader 8 | SUBSYSTEM=="usb", ATTR{idVendor}=="0e79", ATTR{idProduct}=="6001", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="safe-t%n" 9 | KERNEL=="hidraw*", ATTRS{idVendor}=="0e79", ATTRS{idProduct}=="6001", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" 10 | 11 | -------------------------------------------------------------------------------- /contrib/udev/51-trezor.rules: -------------------------------------------------------------------------------- 1 | # Trezor: The Original Hardware Wallet 2 | # https://trezor.io/ 3 | # 4 | # Put this file into /etc/udev/rules.d 5 | # 6 | # If you are creating a distribution package, 7 | # put this into /usr/lib/udev/rules.d or /lib/udev/rules.d 8 | # depending on your distribution 9 | 10 | # Trezor 11 | SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n" 12 | KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" 13 | 14 | # Trezor v2 15 | SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c0", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n" 16 | SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="53c1", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="trezor%n" 17 | KERNEL=="hidraw*", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" 18 | -------------------------------------------------------------------------------- /contrib/udev/51-usb-keepkey.rules: -------------------------------------------------------------------------------- 1 | # KeepKey: Your Private Bitcoin Vault 2 | # http://www.keepkey.com/ 3 | # Put this file into /usr/lib/udev/rules.d or /etc/udev/rules.d 4 | 5 | # KeepKey HID Firmware/Bootloader 6 | SUBSYSTEM=="usb", ATTR{idVendor}=="2b24", ATTR{idProduct}=="0001", MODE="0666", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="keepkey%n" 7 | KERNEL=="hidraw*", ATTRS{idVendor}=="2b24", ATTRS{idProduct}=="0001", MODE="0666", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" 8 | 9 | # KeepKey WebUSB Firmware/Bootloader 10 | SUBSYSTEM=="usb", ATTR{idVendor}=="2b24", ATTR{idProduct}=="0002", MODE="0666", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="keepkey%n" 11 | KERNEL=="hidraw*", ATTRS{idVendor}=="2b24", ATTRS{idProduct}=="0002", MODE="0666", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" 12 | -------------------------------------------------------------------------------- /contrib/udev/52-hid-digitalbitbox.rules: -------------------------------------------------------------------------------- 1 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2402", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="dbbf%n" 2 | -------------------------------------------------------------------------------- /contrib/udev/53-hid-bitbox02.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="usb", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="bitbox02_%n", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2403" 2 | -------------------------------------------------------------------------------- /contrib/udev/54-hid-bitbox02.rules: -------------------------------------------------------------------------------- 1 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2403", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="bitbox02-%n" 2 | -------------------------------------------------------------------------------- /contrib/udev/README.md: -------------------------------------------------------------------------------- 1 | # udev rules 2 | 3 | This directory contains all of the udev rules for the supported devices 4 | as retrieved from vendor websites and repositories. 5 | These are necessary for the devices to be usable on Linux environments. 6 | 7 | - `20-hw1.rules` (Ledger): https://github.com/LedgerHQ/udev-rules/blob/master/20-hw1.rules 8 | - `51-coinkite.rules` (Coldcard): https://github.com/Coldcard/ckcc-protocol/blob/master/51-coinkite.rules 9 | - `51-hid-digitalbitbox.rules`, `52-hid-digitalbitbox.rules` (Digital Bitbox): https://github.com/digitalbitbox/bitbox-wallet-app/blob/master/frontends/qt/resources/deb-afterinstall.sh 10 | - `53-hid-bitbox02.rules`, `54-hid-bitbox02.rules` (BitBox02): https://github.com/digitalbitbox/bitbox-wallet-app/blob/master/frontends/qt/resources/deb-afterinstall.sh 11 | - `51-trezor.rules` (Trezor): https://github.com/trezor/trezor-common/blob/master/udev/51-trezor.rules 12 | - `51-usb-keepkey.rules` (Keepkey): https://github.com/keepkey/udev-rules/blob/master/51-usb-keepkey.rules 13 | - `51-safe-t.rules` (Archos): https://github.com/archos-safe-t/safe-t-common/blob/master/udev/51-safe-t.rules 14 | 15 | # Usage 16 | 17 | Apply these rules by copying them to `/etc/udev/rules.d/` and notifying `udevadm`. 18 | Your user will need to be added to the `plugdev` group, which needs to be created if it does not already exist. 19 | 20 | ``` 21 | $ sudo groupadd plugdev 22 | $ sudo usermod -aG plugdev $(whoami) 23 | $ sudo cp contrib/udev/*.rules /etc/udev/rules.d/ 24 | $ sudo udevadm control --reload-rules && sudo udevadm trigger 25 | ``` 26 | -------------------------------------------------------------------------------- /contrib/upload: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | host=$1 6 | version=`git describe --tags` 7 | echo $version 8 | 9 | here=$(dirname "$0") 10 | cd $here/../dist 11 | 12 | sftp -oBatchMode=no -b - thomasv@$host << ! 13 | cd electrum-downloads 14 | mkdir $version 15 | cd $version 16 | mput * 17 | bye 18 | ! 19 | -------------------------------------------------------------------------------- /electrum-env: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # This script creates a virtualenv named 'env' and installs all 4 | # python dependencies before activating the env and running Electrum. 5 | # If 'env' already exists, it is activated and Electrum is started 6 | # without any installations. Additionally, the PYTHONPATH environment 7 | # variable is set properly before running Electrum. 8 | # 9 | # python-qt and its dependencies will still need to be installed with 10 | # your package manager. 11 | 12 | PYTHON_VER="$(python3 -c 'import sys; print(sys.version[:3])')" 13 | 14 | cd $(dirname $0) 15 | if [ -e ./env/bin/activate ]; then 16 | source ./env/bin/activate 17 | else 18 | virtualenv env -p `which python3` 19 | source ./env/bin/activate 20 | python3 -m pip install .[fast] 21 | fi 22 | 23 | export PYTHONPATH="/usr/local/lib/python${PYTHON_VER}/site-packages:$PYTHONPATH" 24 | 25 | ./run_electrum "$@" 26 | 27 | deactivate 28 | -------------------------------------------------------------------------------- /electrum.desktop: -------------------------------------------------------------------------------- 1 | # If you want Electrum to appear in a Linux app launcher ("start menu"), install this by doing: 2 | # sudo desktop-file-install electrum.desktop 3 | 4 | [Desktop Entry] 5 | Comment=Lightweight Qtum Client 6 | Exec=sh -c "PATH=\"\\$HOME/.local/bin:\\$PATH\"; electrum %u" 7 | GenericName[en_US]=Qtum Wallet 8 | GenericName=Qtum Wallet 9 | Icon=electrum 10 | Name[en_US]=Electrum Qtum Wallet 11 | Name=Electrum Qtum Wallet 12 | Categories=Finance;Network; 13 | StartupNotify=true 14 | StartupWMClass=electrum 15 | Terminal=false 16 | Type=Application 17 | MimeType=x-scheme-handler/qtum; 18 | Actions=Testnet; 19 | 20 | [Desktop Action Testnet] 21 | Exec=sh -c "PATH=\"\\$HOME/.local/bin:\\$PATH\"; electrum --testnet %u" 22 | Name=Testnet mode 23 | -------------------------------------------------------------------------------- /electrum/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | # these are ~duplicated from run_electrum: 5 | is_bundle = getattr(sys, 'frozen', False) 6 | is_local = not is_bundle and os.path.exists(os.path.join(os.path.dirname(os.path.dirname(__file__)), "electrum.desktop")) 7 | 8 | # when running from source, on Windows, also search for DLLs in inner 'electrum' folder 9 | if is_local and os.name == 'nt': 10 | if hasattr(os, 'add_dll_directory'): # requires python 3.8+ 11 | os.add_dll_directory(os.path.dirname(__file__)) 12 | 13 | 14 | class GuiImportError(ImportError): 15 | pass 16 | 17 | 18 | from .version import ELECTRUM_VERSION 19 | from .util import format_satoshis 20 | from .wallet import Wallet 21 | from .storage import WalletStorage 22 | from .coinchooser import COIN_CHOOSERS 23 | from .network import Network, pick_random_server 24 | from .interface import Interface 25 | from .simple_config import SimpleConfig 26 | from . import bitcoin 27 | from . import transaction 28 | from . import daemon 29 | from .transaction import Transaction 30 | from .plugin import BasePlugin 31 | from .commands import Commands, known_commands 32 | 33 | 34 | __version__ = ELECTRUM_VERSION 35 | -------------------------------------------------------------------------------- /electrum/checkpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "0": "000075aef83cf2853580f8ae8ce6f8c3096cfa21d98334d6e3f95e5582ed986c", 3 | "5000": "00006a5338e5647872bd91de1d291365e941e14dff1939b5f16d1804d1ce61cd", 4 | "45000": "060c6af680f6975184c7a17059f2ff4970544fcfd4104e73744fe7ab7be14cfc", 5 | "90000": "66fcf426b0aa6f2c9e3330cb2775e9e13c4a2b8ceedb50f8931ae0e12078ad50", 6 | "150000": "ae4699ac0a8f4d1170767167fd3b0639312850ce33dcb55a0afd0f5c1a88406f", 7 | "466601": "01d40e2b5bc2afba5d6b49a029d176a6d4e43ebc35da8653a476c0a0a0dedcd8", 8 | "640000": "d473634bf89f360a10e9692ddb207e22ef95ec28bdc55425a9a672512d26e886", 9 | "800000": "66a1f992bbe6e0cf156ec4ac5d175a17df0e515041af3a860905d76d710a84f6", 10 | "900000": "f1370a4d9246e9fb365c6cf9678913416c0ede1c280d15bd67208e320dd613ef" 11 | } 12 | -------------------------------------------------------------------------------- /electrum/checkpoints_testnet.json: -------------------------------------------------------------------------------- 1 | { 2 | "0": "0000e803ee215c0684ca0d2f9220594d3f828617972aad66feb2ba51f5e14222", 3 | "5000": "000000302bc22f2f65995506e757fff5c824545db5413e871d57d27a0997e8a0", 4 | "77000": "f41e2e8d09bca38827c23cad46ed6d434902da08415d2314d0c8ce285b1970cb", 5 | "446321": "249167339f87f239f8c1dc7b7e4b0b29b6d6bb93bc13fa71c655939466b7093a", 6 | "600000": "7a3a3c861204696c8965fe45af0dff16c24f38ca87eb81be5731c59db48c9f9e", 7 | "625001": "a9955a87d69fc45d24974c004b742a6f08dd89f4a51ae3baf7793f631cfa886c", 8 | "700000": "72fd594669a2d4461cd2e56e87bfddb768d03ca0548451be04d2acbf08d5142b", 9 | "780000": "a2f2800c675ff23b0a501553ac70733349dba2ffc095d21e2e82abee7c1107ac", 10 | "900000": "8b19761f06ad1beb9882e91c306fa6838f94cd6a3bc618eb1643a40dea6916c7" 11 | } 12 | -------------------------------------------------------------------------------- /electrum/currencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "Huobi": [ 3 | "BTC", 4 | "USDT" 5 | ], 6 | "OKEX": [ 7 | "USDT" 8 | ], 9 | "Binance": [ 10 | "BTC", 11 | "BUSD", 12 | "ETH", 13 | "USDT" 14 | ], 15 | "BitStamp": [ 16 | "USD", 17 | "EUR" 18 | ], 19 | "CoinCap": [ 20 | "USD" 21 | ], 22 | "CoinGecko": [ 23 | "AED", 24 | "ARS", 25 | "AUD", 26 | "BCH", 27 | "BDT", 28 | "BHD", 29 | "BMD", 30 | "BNB", 31 | "BRL", 32 | "BTC", 33 | "CAD", 34 | "CHF", 35 | "CLP", 36 | "CNY", 37 | "CZK", 38 | "DKK", 39 | "EOS", 40 | "ETH", 41 | "EUR", 42 | "GBP", 43 | "HKD", 44 | "HUF", 45 | "IDR", 46 | "ILS", 47 | "INR", 48 | "JPY", 49 | "KRW", 50 | "KWD", 51 | "LKR", 52 | "LTC", 53 | "MMK", 54 | "MXN", 55 | "MYR", 56 | "NOK", 57 | "NZD", 58 | "PHP", 59 | "PKR", 60 | "PLN", 61 | "RUB", 62 | "SAR", 63 | "SEK", 64 | "SGD", 65 | "THB", 66 | "TRY", 67 | "TWD", 68 | "USD", 69 | "VEF", 70 | "VND", 71 | "XAG", 72 | "XAU", 73 | "XDR", 74 | "XLM", 75 | "XRP", 76 | "ZAR" 77 | ] 78 | } 79 | -------------------------------------------------------------------------------- /electrum/electrum: -------------------------------------------------------------------------------- 1 | ../run_electrum -------------------------------------------------------------------------------- /electrum/gui/__init__.py: -------------------------------------------------------------------------------- 1 | # To create a new GUI, please add its code to this directory. 2 | # Three objects are passed to the ElectrumGui: config, daemon and plugins 3 | # The Wallet object is instantiated by the GUI 4 | 5 | # Notifications about network events are sent to the GUI by using network.register_callback() 6 | 7 | from typing import TYPE_CHECKING, Mapping, Optional 8 | 9 | if TYPE_CHECKING: 10 | from . import qt 11 | from . import kivy 12 | from electrum.simple_config import SimpleConfig 13 | from electrum.daemon import Daemon 14 | from electrum.plugin import Plugins 15 | 16 | 17 | class BaseElectrumGui: 18 | def __init__(self, *, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'): 19 | self.config = config 20 | self.daemon = daemon 21 | self.plugins = plugins 22 | 23 | def main(self) -> None: 24 | raise NotImplementedError() 25 | 26 | def stop(self) -> None: 27 | """Stops the GUI. 28 | This method must be thread-safe. 29 | """ 30 | pass 31 | 32 | @classmethod 33 | def version_info(cls) -> Mapping[str, Optional[str]]: 34 | return {} 35 | -------------------------------------------------------------------------------- /electrum/gui/icons/bitbox02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/bitbox02.png -------------------------------------------------------------------------------- /electrum/gui/icons/bitbox02_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/bitbox02_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/bitcoin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/bitcoin.png -------------------------------------------------------------------------------- /electrum/gui/icons/camera_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/camera_dark.png -------------------------------------------------------------------------------- /electrum/gui/icons/camera_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/camera_white.png -------------------------------------------------------------------------------- /electrum/gui/icons/clock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/clock1.png -------------------------------------------------------------------------------- /electrum/gui/icons/clock2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/clock2.png -------------------------------------------------------------------------------- /electrum/gui/icons/clock3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/clock3.png -------------------------------------------------------------------------------- /electrum/gui/icons/clock4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/clock4.png -------------------------------------------------------------------------------- /electrum/gui/icons/clock5.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/clock5.pdn -------------------------------------------------------------------------------- /electrum/gui/icons/clock5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/clock5.png -------------------------------------------------------------------------------- /electrum/gui/icons/coldcard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/coldcard.png -------------------------------------------------------------------------------- /electrum/gui/icons/coldcard_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/coldcard_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/confirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/confirmed.png -------------------------------------------------------------------------------- /electrum/gui/icons/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/copy.png -------------------------------------------------------------------------------- /electrum/gui/icons/digitalbitbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/digitalbitbox.png -------------------------------------------------------------------------------- /electrum/gui/icons/digitalbitbox_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/digitalbitbox_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/electrum.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum.icns -------------------------------------------------------------------------------- /electrum/gui/icons/electrum.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum.ico -------------------------------------------------------------------------------- /electrum/gui/icons/electrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum.png -------------------------------------------------------------------------------- /electrum/gui/icons/electrum_dark_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum_dark_icon.png -------------------------------------------------------------------------------- /electrum/gui/icons/electrum_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum_launcher.png -------------------------------------------------------------------------------- /electrum/gui/icons/electrum_light_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum_light_icon.png -------------------------------------------------------------------------------- /electrum/gui/icons/electrum_presplash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrum_presplash.png -------------------------------------------------------------------------------- /electrum/gui/icons/electrumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/electrumb.png -------------------------------------------------------------------------------- /electrum/gui/icons/expired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/expired.png -------------------------------------------------------------------------------- /electrum/gui/icons/eye1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/eye1.png -------------------------------------------------------------------------------- /electrum/gui/icons/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/file.png -------------------------------------------------------------------------------- /electrum/gui/icons/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/info.png -------------------------------------------------------------------------------- /electrum/gui/icons/keepkey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/keepkey.png -------------------------------------------------------------------------------- /electrum/gui/icons/keepkey_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/keepkey_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/key.png -------------------------------------------------------------------------------- /electrum/gui/icons/ledger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/ledger.png -------------------------------------------------------------------------------- /electrum/gui/icons/ledger_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/ledger_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/lightning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/lightning.png -------------------------------------------------------------------------------- /electrum/gui/icons/lightning_disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/lightning_disconnected.png -------------------------------------------------------------------------------- /electrum/gui/icons/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/lock.png -------------------------------------------------------------------------------- /electrum/gui/icons/microphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/microphone.png -------------------------------------------------------------------------------- /electrum/gui/icons/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/network.png -------------------------------------------------------------------------------- /electrum/gui/icons/offline_tx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/offline_tx.png -------------------------------------------------------------------------------- /electrum/gui/icons/preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/preferences.png -------------------------------------------------------------------------------- /electrum/gui/icons/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/qrcode.png -------------------------------------------------------------------------------- /electrum/gui/icons/qrcode_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/qrcode_white.png -------------------------------------------------------------------------------- /electrum/gui/icons/qtum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/qtum.png -------------------------------------------------------------------------------- /electrum/gui/icons/revealer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/revealer.png -------------------------------------------------------------------------------- /electrum/gui/icons/revealer_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/revealer_c.png -------------------------------------------------------------------------------- /electrum/gui/icons/safe-t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/safe-t.png -------------------------------------------------------------------------------- /electrum/gui/icons/safe-t_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/safe-t_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/seal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/seal.png -------------------------------------------------------------------------------- /electrum/gui/icons/seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/seed.png -------------------------------------------------------------------------------- /electrum/gui/icons/speaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/speaker.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_connected.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_connected_fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_connected_fork.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_connected_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_connected_proxy.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_connected_proxy_fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_connected_proxy_fork.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_disconnected.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_lagging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_lagging.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_lagging_fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_lagging_fork.png -------------------------------------------------------------------------------- /electrum/gui/icons/status_waiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/status_waiting.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_addresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_addresses.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_coins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_coins.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_console.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_contacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_contacts.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_history.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_receive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_receive.png -------------------------------------------------------------------------------- /electrum/gui/icons/tab_send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tab_send.png -------------------------------------------------------------------------------- /electrum/gui/icons/tor_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/tor_logo.png -------------------------------------------------------------------------------- /electrum/gui/icons/trezor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/trezor.png -------------------------------------------------------------------------------- /electrum/gui/icons/trezor_unpaired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/trezor_unpaired.png -------------------------------------------------------------------------------- /electrum/gui/icons/trustedcoin-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/trustedcoin-status.png -------------------------------------------------------------------------------- /electrum/gui/icons/trustedcoin-wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/trustedcoin-wizard.png -------------------------------------------------------------------------------- /electrum/gui/icons/unconfirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/unconfirmed.png -------------------------------------------------------------------------------- /electrum/gui/icons/unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/unlock.png -------------------------------------------------------------------------------- /electrum/gui/icons/unpaid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/unpaid.png -------------------------------------------------------------------------------- /electrum/gui/icons/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/update.png -------------------------------------------------------------------------------- /electrum/gui/icons/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/warning.png -------------------------------------------------------------------------------- /electrum/gui/icons/zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/icons/zoom.png -------------------------------------------------------------------------------- /electrum/gui/kivy/data/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/background.png -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/Roboto-Condensed.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/fonts/Roboto-Condensed.ttf -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/Roboto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/fonts/Roboto.ttf -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/tron/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2011, Jeff Bell [www.randombell.com] | [jeffbell@randombell.com]. 2 | This font may be distributed freely however must retain this document as well as the Readme.txt file. 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is available with a FAQ at: http://scripts.sil.org/OFL -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/tron/Readme.txt: -------------------------------------------------------------------------------- 1 | TR2N v1.3 2 | 3 | ABOUT THE FONT: 4 | A font based upon the poster text for TRON LEGACY. 5 | 6 | The font is different from the pre-existing TRON font currently on the web. Similar in minor aspects but different in most. Style based upon text from different region posters. 7 | 8 | UPDATE HISTORY: 9 | 3/7/11 - Adjusted the letter B (both lowercase and uppercase), capped off the ends of T, P and R, added a few more punctuation marks, as well as added the TR and TP ligature to allow for the solid bar connect as in the poster art. 10 | 11 | 1/22/11 - Made minor corrections to all previous letters and punctuation. Corrected issue with number 8's top filling in. 12 | 13 | ABOUT THE AUTHOR: 14 | Jeff Bell has produced fonts before, but this is the first one in over 10 years. His original 3 fonts were under the name DJ-JOHNNYRKA and include "CASPER", "BEVERLY HILLS COP", "THE GODFATHER" and "FIDDUMS FAMILY". 15 | 16 | For more information on Jeff Bell and his work can be found online: 17 | 18 | www.randombell.com 19 | www.damovieman.deviantart.com 20 | http://www.imdb.com/name/nm3983081/ 21 | http://www.vimeo.com/user4004969/videos -------------------------------------------------------------------------------- /electrum/gui/kivy/data/fonts/tron/Tr2n.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/fonts/tron/Tr2n.ttf -------------------------------------------------------------------------------- /electrum/gui/kivy/data/glsl/default.fs: -------------------------------------------------------------------------------- 1 | $HEADER$ 2 | void main (void){ 3 | gl_FragColor = frag_color * texture2D(texture0, tex_coord0); 4 | } 5 | -------------------------------------------------------------------------------- /electrum/gui/kivy/data/glsl/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/glsl/default.png -------------------------------------------------------------------------------- /electrum/gui/kivy/data/glsl/default.vs: -------------------------------------------------------------------------------- 1 | $HEADER$ 2 | void main (void) { 3 | frag_color = color * vec4(1.0, 1.0, 1.0, opacity); 4 | tex_coord0 = vTexCoords0; 5 | gl_Position = projection_mat * modelview_mat * vec4(vPosition.xy, 0.0, 1.0); 6 | } 7 | -------------------------------------------------------------------------------- /electrum/gui/kivy/data/glsl/header.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | /* Outputs from the vertex shader */ 6 | varying vec4 frag_color; 7 | varying vec2 tex_coord0; 8 | 9 | /* uniform texture samplers */ 10 | uniform sampler2D texture0; 11 | -------------------------------------------------------------------------------- /electrum/gui/kivy/data/glsl/header.vs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | /* Outputs to the fragment shader */ 6 | varying vec4 frag_color; 7 | varying vec2 tex_coord0; 8 | 9 | /* vertex attributes */ 10 | attribute vec2 vPosition; 11 | attribute vec2 vTexCoords0; 12 | 13 | /* uniform variables */ 14 | uniform mat4 modelview_mat; 15 | uniform mat4 projection_mat; 16 | uniform vec4 color; 17 | uniform float opacity; 18 | -------------------------------------------------------------------------------- /electrum/gui/kivy/data/images/defaulttheme-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/images/defaulttheme-0.png -------------------------------------------------------------------------------- /electrum/gui/kivy/data/logo/kivy-icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/data/logo/kivy-icon-32.png -------------------------------------------------------------------------------- /electrum/gui/kivy/i18n.py: -------------------------------------------------------------------------------- 1 | import gettext 2 | 3 | 4 | class _(str): 5 | 6 | observers = set() 7 | lang = None 8 | 9 | def __new__(cls, s): 10 | if _.lang is None: 11 | _.switch_lang('en') 12 | t = _.translate(s) 13 | o = super(_, cls).__new__(cls, t) 14 | o.source_text = s 15 | return o 16 | 17 | @staticmethod 18 | def translate(s, *args, **kwargs): 19 | return _.lang(s) 20 | 21 | @staticmethod 22 | def bind(label): 23 | try: 24 | _.observers.add(label) 25 | except: 26 | pass 27 | # garbage collection 28 | new = set() 29 | for label in _.observers: 30 | try: 31 | new.add(label) 32 | except: 33 | pass 34 | _.observers = new 35 | 36 | @staticmethod 37 | def switch_lang(lang): 38 | # get the right locales directory, and instanciate a gettext 39 | from electrum.i18n import LOCALE_DIR 40 | locales = gettext.translation('electrum', LOCALE_DIR, languages=[lang], fallback=True) 41 | _.lang = locales.gettext 42 | for label in _.observers: 43 | try: 44 | label.text = _(label.text.source_text) 45 | except: 46 | pass 47 | -------------------------------------------------------------------------------- /electrum/gui/kivy/nfc_scanner/__init__.py: -------------------------------------------------------------------------------- 1 | from kivy.uix.widget import Widget 2 | from kivy.properties import ObjectProperty 3 | from kivy.core import core_select_lib 4 | 5 | __all__ = ('NFCBase', 'NFCScanner') 6 | 7 | class NFCBase(Widget): 8 | ''' This is the base Abstract definition class that the actual hardware dependent 9 | implementations would be based on. If you want to define a feature that is 10 | accessible and implemented by every platform implementation then define that 11 | method in this class. 12 | ''' 13 | 14 | payload = ObjectProperty(None) 15 | '''This is the data gotten from the tag. 16 | ''' 17 | 18 | def nfc_init(self): 19 | ''' Initialize the adapter. 20 | ''' 21 | pass 22 | 23 | def nfc_disable(self): 24 | ''' Disable scanning 25 | ''' 26 | pass 27 | 28 | def nfc_enable(self): 29 | ''' Enable Scanning 30 | ''' 31 | pass 32 | 33 | def nfc_enable_exchange(self, data): 34 | ''' Enable P2P Ndef exchange 35 | ''' 36 | pass 37 | 38 | def nfc_disable_exchange(self): 39 | ''' Disable/Stop P2P Ndef exchange 40 | ''' 41 | pass 42 | 43 | # load NFCScanner implementation 44 | 45 | NFCScanner = core_select_lib('nfc_manager', ( 46 | # keep the dummy implementation as the last one to make it the fallback provider.NFCScanner = core_select_lib('nfc_scanner', ( 47 | ('android', 'scanner_android', 'ScannerAndroid'), 48 | ('dummy', 'scanner_dummy', 'ScannerDummy')), True, 'electrum.gui.kivy') 49 | -------------------------------------------------------------------------------- /electrum/gui/kivy/nfc_scanner/scanner_dummy.py: -------------------------------------------------------------------------------- 1 | ''' Dummy NFC Provider to be used on desktops in case no other provider is found 2 | ''' 3 | from . import NFCBase 4 | from kivy.clock import Clock 5 | from kivy.logger import Logger 6 | from kivy.app import App 7 | 8 | class ScannerDummy(NFCBase): 9 | '''This is the dummy interface that gets selected in case any other 10 | hardware interface to NFC is not available. 11 | ''' 12 | 13 | _initialised = False 14 | 15 | name = 'NFCDummy' 16 | 17 | def nfc_init(self): 18 | # print 'nfc_init()' 19 | 20 | Logger.debug('NFC: configure nfc') 21 | self._initialised = True 22 | self.nfc_enable() 23 | return True 24 | 25 | def on_new_intent(self, dt): 26 | tag_info = {'type': 'dymmy', 27 | 'message': 'dummy', 28 | 'extra details': None} 29 | 30 | # let Main app know that a tag has been detected 31 | app = App.get_running_app() 32 | app.tag_discovered(tag_info) 33 | app.show_info('New tag detected.', duration=2) 34 | Logger.debug('NFC: got new dummy tag') 35 | 36 | def nfc_enable(self): 37 | Logger.debug('NFC: enable') 38 | if self._initialised: 39 | Clock.schedule_interval(self.on_new_intent, 22) 40 | 41 | def nfc_disable(self): 42 | # print 'nfc_enable()' 43 | Clock.unschedule(self.on_new_intent) 44 | 45 | def nfc_enable_exchange(self, data): 46 | ''' Start sending data 47 | ''' 48 | Logger.debug('NFC: sending data {}'.format(data)) 49 | 50 | def nfc_disable_exchange(self): 51 | ''' Disable/Stop ndef exchange 52 | ''' 53 | Logger.debug('NFC: disable nfc exchange') 54 | -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/action_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/action_bar.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/action_button_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/action_button_group.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/action_group_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/action_group_dark.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/action_group_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/action_group_light.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/add_contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/add_contact.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/arrow_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/arrow_back.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/bit_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/bit_logo.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/blue_bg_round_rb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/blue_bg_round_rb.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/btn_create_account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/btn_create_account.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/btn_create_act_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/btn_create_act_disabled.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/btn_nfc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/btn_nfc.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/btn_send_address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/btn_send_address.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/btn_send_nfc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/btn_send_nfc.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/calculator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/calculator.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/camera.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/card.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/card_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/card_bottom.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/card_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/card_btn.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/card_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/card_top.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/carousel_deselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/carousel_deselected.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/carousel_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/carousel_selected.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/clock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/clock1.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/clock2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/clock2.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/clock3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/clock3.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/clock4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/clock4.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/clock5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/clock5.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/close.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/closebutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/closebutton.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/confirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/confirmed.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/contact.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/contact_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/contact_overlay.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/copy.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/create_act_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/create_act_text.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/create_act_text_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/create_act_text_active.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/delete.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/dialog.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/dropdown_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/dropdown_background.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/electrum_icon640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/electrum_icon640.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/error.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/eye1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/eye1.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/gear.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/globe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/globe.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/icon_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/icon_border.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/important.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/info.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/lightblue_bg_round_lb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/lightblue_bg_round_lb.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/lightning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/lightning.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/lightning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/list.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/logo.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/logo_atom_dull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/logo_atom_dull.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/mail_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/mail_icon.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/manualentry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/manualentry.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/network.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/network.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/nfc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/nfc.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/nfc_clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/nfc_clock.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/nfc_phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/nfc_phone.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/nfc_stage_one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/nfc_stage_one.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/overflow_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/overflow_background.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/overflow_btn_dn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/overflow_btn_dn.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/paste_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/paste_icon.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/pen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/pen.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/qrcode.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/save.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/settings.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/shadow.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/shadow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/shadow_right.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/share.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/star_big_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/star_big_inactive.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/stepper_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/stepper_full.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/stepper_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/stepper_left.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/stepper_restore_password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/stepper_restore_password.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/stepper_restore_seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/stepper_restore_seed.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/tab.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/tab_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/tab_btn.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/tab_btn_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/tab_btn_disabled.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/tab_btn_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/tab_btn_pressed.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/tab_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/tab_disabled.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/tab_strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/tab_strip.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/textinput_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/textinput_active.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/unconfirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/unconfirmed.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/wallet.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/wallets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/wallets.png -------------------------------------------------------------------------------- /electrum/gui/kivy/theming/light/white_bg_round_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/gui/kivy/theming/light/white_bg_round_top.png -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/checkbox_dialog.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.factory import Factory 3 | from kivy.properties import ObjectProperty 4 | from kivy.lang import Builder 5 | 6 | Builder.load_string(''' 7 | 8 | id: popup 9 | title: '' 10 | size_hint: 0.8, 0.8 11 | pos_hint: {'top':0.9} 12 | BoxLayout: 13 | orientation: 'vertical' 14 | Label: 15 | id: description 16 | text: '' 17 | halign: 'left' 18 | text_size: self.width, None 19 | size: self.texture_size 20 | BoxLayout: 21 | orientation: 'horizontal' 22 | size_hint: 1, 0.2 23 | Label: 24 | text: _('Enable') 25 | CheckBox: 26 | id:cb 27 | Widget: 28 | size_hint: 1, 0.1 29 | BoxLayout: 30 | orientation: 'horizontal' 31 | size_hint: 1, 0.2 32 | Button: 33 | text: 'Cancel' 34 | size_hint: 0.5, None 35 | height: '48dp' 36 | on_release: popup.dismiss() 37 | Button: 38 | text: 'OK' 39 | size_hint: 0.5, None 40 | height: '48dp' 41 | on_release: 42 | root.callback(cb.active) 43 | popup.dismiss() 44 | ''') 45 | 46 | class CheckBoxDialog(Factory.Popup): 47 | def __init__(self, title, text, status, callback): 48 | Factory.Popup.__init__(self) 49 | self.ids.cb.active = status 50 | self.ids.description.text = text 51 | self.callback = callback 52 | self.title = title 53 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/label_dialog.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.factory import Factory 3 | from kivy.properties import ObjectProperty 4 | from kivy.lang import Builder 5 | 6 | Builder.load_string(''' 7 | 8 | id: popup 9 | title: '' 10 | size_hint: 0.8, 0.3 11 | pos_hint: {'top':0.9} 12 | BoxLayout: 13 | orientation: 'vertical' 14 | Widget: 15 | size_hint: 1, 0.2 16 | TextInput: 17 | id:input 18 | padding: '5dp' 19 | size_hint: 1, None 20 | height: '27dp' 21 | pos_hint: {'center_y':.5} 22 | text:'' 23 | multiline: False 24 | background_normal: 'atlas://electrum/gui/kivy/theming/light/tab_btn' 25 | background_active: 'atlas://electrum/gui/kivy/theming/light/textinput_active' 26 | hint_text_color: self.foreground_color 27 | foreground_color: 1, 1, 1, 1 28 | font_size: '16dp' 29 | focus: True 30 | Widget: 31 | size_hint: 1, 0.2 32 | BoxLayout: 33 | orientation: 'horizontal' 34 | size_hint: 1, 0.5 35 | Button: 36 | text: 'Cancel' 37 | size_hint: 0.5, None 38 | height: '48dp' 39 | on_release: popup.dismiss() 40 | Button: 41 | text: 'OK' 42 | size_hint: 0.5, None 43 | height: '48dp' 44 | on_release: 45 | root.callback(input.text) 46 | popup.dismiss() 47 | ''') 48 | 49 | class LabelDialog(Factory.Popup): 50 | 51 | def __init__(self, title, text, callback): 52 | Factory.Popup.__init__(self) 53 | self.ids.input.text = text 54 | self.callback = callback 55 | self.title = title 56 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/nfc_transaction.py: -------------------------------------------------------------------------------- 1 | from kivy.properties import ObjectProperty, OptionProperty 2 | from kivy.factory import Factory 3 | 4 | 5 | class NFCTransactionDialog(Factory.AnimatedPopup): 6 | 7 | mode = OptionProperty('send', options=('send','receive')) 8 | 9 | scanner = ObjectProperty(None) 10 | 11 | def __init__(self, **kwargs): 12 | # Delayed Init 13 | global NFCSCanner 14 | if NFCSCanner is None: 15 | from electrum.gui.kivy.nfc_scanner import NFCScanner 16 | self.scanner = NFCSCanner 17 | 18 | super(NFCTransactionDialog, self).__init__(**kwargs) 19 | self.scanner.nfc_init() 20 | self.scanner.bind() 21 | 22 | def on_parent(self, instance, value): 23 | sctr = self.ids.sctr 24 | if value: 25 | def _cmp(*l): 26 | anim = Factory.Animation(rotation=2, scale=1, opacity=1) 27 | anim.start(sctr) 28 | anim.bind(on_complete=_start) 29 | 30 | def _start(*l): 31 | anim = Factory.Animation(rotation=350, scale=2, opacity=0) 32 | anim.start(sctr) 33 | anim.bind(on_complete=_cmp) 34 | _start() 35 | return 36 | Factory.Animation.cancel_all(sctr) 37 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/qr_scanner.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.factory import Factory 3 | from kivy.lang import Builder 4 | 5 | Factory.register('QRScanner', module='electrum.gui.kivy.qr_scanner') 6 | 7 | class QrScannerDialog(Factory.AnimatedPopup): 8 | 9 | __events__ = ('on_complete', ) 10 | 11 | def on_symbols(self, instance, value): 12 | instance.stop() 13 | self.dismiss() 14 | data = value[0].data 15 | self.dispatch('on_complete', data) 16 | 17 | def on_complete(self, x): 18 | ''' Default Handler for on_complete event. 19 | ''' 20 | print(x) 21 | 22 | 23 | Builder.load_string(''' 24 | 25 | title: 26 | _(\ 27 | '[size=18dp]Hold your QRCode up to the camera[/size][size=7dp]\\n[/size]') 28 | title_size: '24sp' 29 | border: 7, 7, 7, 7 30 | size_hint: None, None 31 | size: '340dp', '290dp' 32 | pos_hint: {'center_y': .53} 33 | #separator_color: .89, .89, .89, 1 34 | #separator_height: '1.2dp' 35 | #title_color: .437, .437, .437, 1 36 | #background: 'atlas://electrum/gui/kivy/theming/light/dialog' 37 | on_activate: 38 | qrscr.start() 39 | qrscr.size = self.size 40 | on_deactivate: qrscr.stop() 41 | QRScanner: 42 | id: qrscr 43 | on_symbols: root.on_symbols(*args) 44 | ''') 45 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/question.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.factory import Factory 3 | from kivy.properties import ObjectProperty 4 | from kivy.lang import Builder 5 | from kivy.uix.checkbox import CheckBox 6 | from kivy.uix.label import Label 7 | from kivy.uix.widget import Widget 8 | 9 | from electrum.gui.kivy.i18n import _ 10 | 11 | Builder.load_string(''' 12 | 13 | id: popup 14 | title: '' 15 | message: '' 16 | yes_str: '' 17 | no_str: '' 18 | size_hint: 0.8, 0.5 19 | pos_hint: {'top':0.9} 20 | BoxLayout: 21 | orientation: 'vertical' 22 | Label: 23 | id: label 24 | text: root.message 25 | text_size: self.width, None 26 | Widget: 27 | size_hint: 1, 0.1 28 | BoxLayout: 29 | orientation: 'horizontal' 30 | size_hint: 1, 0.2 31 | Button: 32 | text: root.no_str 33 | size_hint: 0.5, None 34 | height: '48dp' 35 | on_release: 36 | root.callback(False) 37 | popup.dismiss() 38 | Button: 39 | text: root.yes_str 40 | size_hint: 0.5, None 41 | height: '48dp' 42 | on_release: 43 | root.callback(True) 44 | popup.dismiss() 45 | ''') 46 | 47 | 48 | 49 | class Question(Factory.Popup): 50 | 51 | def __init__(self, msg, callback, *, 52 | yes_str: str = None, no_str: str = None, 53 | title: str = None): 54 | Factory.Popup.__init__(self) 55 | self.yes_str = yes_str or _('Yes') 56 | self.no_str = no_str or _('No') 57 | self.title = title or _('Question') 58 | self.message = msg 59 | self.callback = callback 60 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/seed_options.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.factory import Factory 3 | from kivy.properties import ObjectProperty 4 | from kivy.lang import Builder 5 | 6 | Builder.load_string(''' 7 | 8 | id: popup 9 | title: _('Seed Options') 10 | size_hint: 0.8, 0.8 11 | pos_hint: {'top':0.9} 12 | BoxLayout: 13 | orientation: 'vertical' 14 | Label: 15 | id: description 16 | text: _('You may extend your seed with custom words') 17 | halign: 'left' 18 | text_size: self.width, None 19 | size: self.texture_size 20 | BoxLayout: 21 | orientation: 'horizontal' 22 | size_hint: 1, 0.2 23 | Label: 24 | text: _('Extend Seed') 25 | CheckBox: 26 | id:ext 27 | BoxLayout: 28 | orientation: 'horizontal' 29 | size_hint: 1, 0.2 30 | Label: 31 | text: _('BIP39') 32 | id:bip39_label 33 | CheckBox: 34 | id:bip39 35 | Widget: 36 | size_hint: 1, 0.1 37 | BoxLayout: 38 | orientation: 'horizontal' 39 | size_hint: 1, 0.2 40 | Button: 41 | text: 'Cancel' 42 | size_hint: 0.5, None 43 | height: '48dp' 44 | on_release: popup.dismiss() 45 | Button: 46 | text: 'OK' 47 | size_hint: 0.5, None 48 | height: '48dp' 49 | on_release: 50 | root.callback(ext.active, bip39.active) 51 | popup.dismiss() 52 | ''') 53 | 54 | 55 | class SeedOptionsDialog(Factory.Popup): 56 | def __init__(self, is_ext, is_bip39, callback): 57 | Factory.Popup.__init__(self) 58 | self.ids.ext.active = is_ext 59 | if is_bip39 is None: 60 | self.ids.bip39.opacity = 0 61 | self.ids.bip39_label.opacity = 0 62 | self.ids.bip39.disabled = True 63 | else: 64 | self.ids.bip39.active = is_bip39 65 | self.callback = callback 66 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/dialogs/wallets.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from kivy.app import App 4 | from kivy.factory import Factory 5 | from kivy.properties import ObjectProperty 6 | from kivy.lang import Builder 7 | 8 | from electrum.util import base_units 9 | from electrum.storage import StorageReadWriteError 10 | 11 | from ...i18n import _ 12 | from .label_dialog import LabelDialog 13 | 14 | Builder.load_string(''' 15 | : 16 | title: _('Wallets') 17 | id: popup 18 | path: '' 19 | BoxLayout: 20 | orientation: 'vertical' 21 | padding: '10dp' 22 | FileChooserIconView: 23 | id: wallet_selector 24 | dirselect: False 25 | filter_dirs: True 26 | filter: '*.*' 27 | path: root.path 28 | rootpath: root.path 29 | size_hint_y: 0.6 30 | Widget 31 | size_hint_y: 0.1 32 | GridLayout: 33 | cols: 3 34 | size_hint_y: 0.1 35 | Button: 36 | id: open_button 37 | size_hint: 0.1, None 38 | height: '48dp' 39 | text: _('New') 40 | on_release: 41 | popup.dismiss() 42 | root.new_wallet(wallet_selector.path) 43 | Button: 44 | id: open_button 45 | size_hint: 0.1, None 46 | height: '48dp' 47 | text: _('Open') 48 | disabled: not wallet_selector.selection 49 | on_release: 50 | popup.dismiss() 51 | root.callback(wallet_selector.selection[0]) 52 | ''') 53 | 54 | class WalletDialog(Factory.Popup): 55 | 56 | def __init__(self, path, callback): 57 | Factory.Popup.__init__(self) 58 | self.path = path 59 | self.callback = callback 60 | 61 | def new_wallet(self, dirname): 62 | def cb(filename): 63 | if not filename: 64 | return 65 | # FIXME? "filename" might contain ".." (etc) and hence sketchy path traversals are possible 66 | self.callback(os.path.join(dirname, filename)) 67 | d = LabelDialog(_('Enter wallet name'), '', cb) 68 | d.open() 69 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/ui_screens/about.kv: -------------------------------------------------------------------------------- 1 | #:import VERSION electrum.version.ELECTRUM_VERSION 2 | 3 | Popup: 4 | title: _("About Electrum") 5 | BoxLayout: 6 | orientation: 'vertical' 7 | spacing: '10dp' 8 | padding: '10dp' 9 | GridLayout: 10 | cols: 2 11 | spacing: '10dp' 12 | TopLabel: 13 | text: _('Version') 14 | size_hint_x: 0.4 15 | TopLabel: 16 | text: VERSION 17 | size_hint_x: 0.6 18 | TopLabel: 19 | text: _('Licence') 20 | size_hint_x: 0.4 21 | TopLabel: 22 | text: "MIT Licence" 23 | size_hint_x: 0.6 24 | TopLabel: 25 | text: _('Homepage') 26 | size_hint_x: 0.4 27 | TopLabel: 28 | markup: True 29 | text: '[color=6666ff][ref=x]https://electrum.org[/ref][/color]' 30 | on_ref_press: 31 | import webbrowser 32 | webbrowser.open("https://electrum.org") 33 | size_hint_x: 0.6 34 | TopLabel: 35 | text: _('Developers') 36 | size_hint_x: 0.4 37 | TopLabel: 38 | text: '\n'.join(['Thomas Voegtlin', 'SomberNight']) 39 | size_hint_x: 0.6 40 | TopLabel: 41 | text: _('Distributed by Electrum Technologies GmbH') 42 | padding: '0dp', '20dp' 43 | Widget: 44 | size_hint: None, 0.5 45 | BoxLayout: 46 | size_hint: 1, None 47 | height: '48dp' 48 | Widget: 49 | size_hint: 0.5, None 50 | height: '48dp' 51 | Button: 52 | size_hint: 0.5, None 53 | height: '48dp' 54 | text: _('Close') 55 | on_release: root.dismiss() 56 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/ui_screens/lightning.kv: -------------------------------------------------------------------------------- 1 | Popup: 2 | id: ln 3 | title: _('Lightning Network') 4 | BoxLayout: 5 | orientation: 'vertical' 6 | ScrollView: 7 | GridLayout: 8 | id: scrollviewlayout 9 | cols:1 10 | size_hint: 1, None 11 | height: self.minimum_height 12 | padding: '10dp' 13 | SettingsItem: 14 | value: _("{} connections.").format(app.lightning_gossip_num_peers) if app.lightning_gossip_num_peers else _("Not connected") 15 | title: _("Gossip") + ': ' + self.value 16 | description: _("Connections with lightning nodes") 17 | CardSeparator 18 | SettingsItem: 19 | title: _("Nodes") + ': ' + str(app.lightning_gossip_num_nodes) 20 | description: _("Nodes in database.") 21 | CardSeparator 22 | SettingsItem: 23 | title: _("Channels") + ': ' + str(app.lightning_gossip_num_channels) 24 | description: _("Channels in database.") 25 | CardSeparator 26 | SettingsItem: 27 | title: _("Pending") + ': ' + str(app.lightning_gossip_num_queries) 28 | description: _("Channel updates to query.") 29 | -------------------------------------------------------------------------------- /electrum/gui/kivy/uix/ui_screens/server.kv: -------------------------------------------------------------------------------- 1 | Popup: 2 | id: nd 3 | title: _('Server') 4 | BoxLayout: 5 | orientation: 'vertical' 6 | padding: '10dp' 7 | spacing: '10dp' 8 | TopLabel: 9 | text: _("Electrum requests your transaction history from a single server. The returned history is checked against blockchain headers sent by other nodes, using Simple Payment Verification (SPV).") 10 | font_size: '6pt' 11 | Widget: 12 | size_hint: 1, 0.8 13 | GridLayout: 14 | cols: 2 15 | Label: 16 | height: '36dp' 17 | size_hint_x: 1 18 | size_hint_y: None 19 | text: _('Server') + ':' 20 | TextInput: 21 | id: server_str 22 | multiline: False 23 | height: '36dp' 24 | size_hint_x: 3 25 | size_hint_y: None 26 | text: app.network.get_parameters().server.net_addr_str() 27 | Widget 28 | Button: 29 | id: chooser 30 | text: _('Choose from peers') 31 | height: '36dp' 32 | size_hint_x: 0.5 33 | size_hint_y: None 34 | on_release: 35 | app.choose_server_dialog(root) 36 | Widget: 37 | size_hint: 1, 0.1 38 | BoxLayout: 39 | Widget: 40 | size_hint: 0.5, None 41 | Button: 42 | size_hint: 0.5, None 43 | height: '48dp' 44 | text: _('OK') 45 | on_release: 46 | app.maybe_switch_to_server(str(root.ids.server_str.text)) 47 | nd.dismiss() 48 | -------------------------------------------------------------------------------- /electrum/gui/kivy/util.py: -------------------------------------------------------------------------------- 1 | from kivy.utils import get_color_from_hex 2 | 3 | 4 | def address_colors(wallet, addr): 5 | """ 6 | Chooses the appropriate text color and background color to 7 | mark receiving, change and billing addresses. 8 | 9 | Returns: color, background_color 10 | """ 11 | 12 | # modified colors (textcolor, background_color) from electrum/gui/qt/util.py 13 | GREEN = ("#000000", "#8af296") 14 | YELLOW = ("#000000", "#ffff00") 15 | BLUE = ("#000000", "#8cb3f2") 16 | DEFAULT = ('#ffffff', '#4c4c4c') 17 | 18 | colors = DEFAULT 19 | if wallet.is_mine(addr): 20 | colors = YELLOW if wallet.is_change(addr) else GREEN 21 | elif wallet.is_billing_address(addr): 22 | colors = BLUE 23 | return (get_color_from_hex(color) for color in colors) 24 | -------------------------------------------------------------------------------- /electrum/gui/qt/qrreader/qtmultimedia/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Electron Cash - lightweight Bitcoin client 4 | # Copyright (C) 2019 Axel Gembe 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | from typing import Mapping 27 | 28 | from .camera_dialog import (QrReaderCameraDialog, CameraError, NoCamerasFound, 29 | NoCameraResolutionsFound) 30 | from .validator import (QrReaderValidatorResult, AbstractQrReaderValidator, 31 | QrReaderValidatorCounting, QrReaderValidatorColorizing, 32 | QrReaderValidatorStrong, QrReaderValidatorCounted) 33 | 34 | 35 | def find_system_cameras() -> Mapping[str, str]: 36 | """Returns a camera_description -> camera_path map.""" 37 | from PyQt5.QtMultimedia import QCameraInfo 38 | system_cameras = QCameraInfo.availableCameras() 39 | return {cam.description(): cam.deviceName() for cam in system_cameras} 40 | -------------------------------------------------------------------------------- /electrum/gui/qt/qrreader/qtmultimedia/video_widget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Electron Cash - lightweight Bitcoin client 4 | # Copyright (C) 2019 Axel Gembe 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | from PyQt5.QtWidgets import QWidget 27 | from PyQt5.QtGui import QPixmap, QPainter, QPaintEvent 28 | 29 | 30 | class QrReaderVideoWidget(QWidget): 31 | """ 32 | Simple widget for drawing a pixmap 33 | """ 34 | 35 | USE_BILINEAR_FILTER = True 36 | 37 | def __init__(self, parent: QWidget = None): 38 | super().__init__(parent) 39 | 40 | self.pixmap = None 41 | 42 | def paintEvent(self, _event: QPaintEvent): 43 | if not self.pixmap: 44 | return 45 | painter = QPainter(self) 46 | if self.USE_BILINEAR_FILTER: 47 | painter.setRenderHint(QPainter.SmoothPixmapTransform) 48 | painter.drawPixmap(self.rect(), self.pixmap, self.pixmap.rect()) 49 | 50 | def setPixmap(self, pixmap: QPixmap): 51 | self.pixmap = pixmap 52 | self.update() 53 | -------------------------------------------------------------------------------- /electrum/gui/qt/qrtextedit.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | from electrum.plugin import run_hook 3 | from electrum.simple_config import SimpleConfig 4 | 5 | from .util import ButtonsTextEdit, MessageBoxMixin 6 | 7 | 8 | class ShowQRTextEdit(ButtonsTextEdit): 9 | 10 | def __init__(self, text=None, *, config: SimpleConfig): 11 | ButtonsTextEdit.__init__(self, text) 12 | self.config = config 13 | self.setReadOnly(True) 14 | self.add_qr_show_button(config=config) 15 | run_hook('show_text_edit', self) 16 | 17 | def contextMenuEvent(self, e): 18 | m = self.createStandardContextMenu() 19 | m.addAction(_("Show as QR code"), self.on_qr_show_btn) 20 | m.exec_(e.globalPos()) 21 | 22 | 23 | class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin): 24 | 25 | def __init__(self, text="", allow_multi: bool = False, *, config: SimpleConfig): 26 | ButtonsTextEdit.__init__(self, text) 27 | self.setReadOnly(False) 28 | self.add_file_input_button(config=config, show_error=self.show_error) 29 | self.add_qr_input_button(config=config, show_error=self.show_error, allow_multi=allow_multi) 30 | run_hook('scan_text_edit', self) 31 | 32 | def contextMenuEvent(self, e): 33 | m = self.createStandardContextMenu() 34 | m.addSeparator() 35 | m.addAction(_("Read QR code from camera"), self.on_qr_from_camera_input_btn) 36 | m.addAction(_("Read QR code from screen"), self.on_qr_from_screenshot_input_btn) 37 | m.exec_(e.globalPos()) 38 | 39 | 40 | class ScanShowQRTextEdit(ButtonsTextEdit, MessageBoxMixin): 41 | 42 | def __init__(self, text="", allow_multi: bool = False, *, config: SimpleConfig): 43 | ButtonsTextEdit.__init__(self, text) 44 | self.setReadOnly(False) 45 | self.add_qr_input_button(config=config, show_error=self.show_error, allow_multi=allow_multi) 46 | self.add_qr_show_button(config=config) 47 | run_hook('scan_text_edit', self) 48 | run_hook('show_text_edit', self) 49 | 50 | def contextMenuEvent(self, e): 51 | m = self.createStandardContextMenu() 52 | m.addSeparator() 53 | m.addAction(_("Read QR code from camera"), self.on_qr_from_camera_input_btn) 54 | m.addAction(_("Read QR code from screen"), self.on_qr_from_screenshot_input_btn) 55 | m.addAction(_("Show as QR code"), self.on_qr_show_btn) 56 | m.exec_(e.globalPos()) 57 | -------------------------------------------------------------------------------- /electrum/gui/qt/qrwindow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Electrum - lightweight Bitcoin client 4 | # Copyright (C) 2014 Thomas Voegtlin 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | from PyQt5.QtCore import Qt 27 | from PyQt5.QtWidgets import QHBoxLayout, QWidget 28 | 29 | from .qrcodewidget import QRCodeWidget 30 | 31 | from electrum.i18n import _ 32 | 33 | 34 | class QR_Window(QWidget): 35 | 36 | def __init__(self, win): 37 | QWidget.__init__(self) 38 | self.win = win 39 | self.setWindowTitle('Electrum - '+_('Payment Request')) 40 | self.setMinimumSize(800, 800) 41 | self.setFocusPolicy(Qt.NoFocus) 42 | main_box = QHBoxLayout() 43 | self.qrw = QRCodeWidget() 44 | main_box.addWidget(self.qrw, 1) 45 | self.setLayout(main_box) 46 | -------------------------------------------------------------------------------- /electrum/gui/qt/stylesheet_patcher.py: -------------------------------------------------------------------------------- 1 | """This is used to patch the QApplication style sheet. 2 | It reads the current stylesheet, appends our modifications and sets the new stylesheet. 3 | """ 4 | 5 | import sys 6 | 7 | from PyQt5 import QtWidgets 8 | 9 | 10 | CUSTOM_PATCH_FOR_DARK_THEME = ''' 11 | /* PayToEdit text was being clipped */ 12 | QAbstractScrollArea { 13 | padding: 0px; 14 | } 15 | /* In History tab, labels while edited were being clipped (Windows) */ 16 | QAbstractItemView QLineEdit { 17 | padding: 0px; 18 | show-decoration-selected: 1; 19 | } 20 | /* Checked item in dropdowns have way too much height... 21 | see #6281 and https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/200 22 | */ 23 | QComboBox::item:checked { 24 | font-weight: bold; 25 | max-height: 30px; 26 | } 27 | ''' 28 | 29 | CUSTOM_PATCH_FOR_DEFAULT_THEME_MACOS = ''' 30 | /* On macOS, main window status bar icons have ugly frame (see #6300) */ 31 | StatusBarButton { 32 | background-color: transparent; 33 | border: 1px solid transparent; 34 | border-radius: 4px; 35 | margin: 0px; 36 | padding: 2px; 37 | } 38 | StatusBarButton:checked { 39 | background-color: transparent; 40 | border: 1px solid #1464A0; 41 | } 42 | StatusBarButton:checked:disabled { 43 | border: 1px solid #14506E; 44 | } 45 | StatusBarButton:pressed { 46 | margin: 1px; 47 | background-color: transparent; 48 | border: 1px solid #1464A0; 49 | } 50 | StatusBarButton:disabled { 51 | border: none; 52 | } 53 | StatusBarButton:hover { 54 | border: 1px solid #148CD2; 55 | } 56 | ''' 57 | 58 | 59 | def patch_qt_stylesheet(use_dark_theme: bool) -> None: 60 | custom_patch = "" 61 | if use_dark_theme: 62 | custom_patch = CUSTOM_PATCH_FOR_DARK_THEME 63 | else: # default theme (typically light) 64 | if sys.platform == 'darwin': 65 | custom_patch = CUSTOM_PATCH_FOR_DEFAULT_THEME_MACOS 66 | 67 | app = QtWidgets.QApplication.instance() 68 | style_sheet = app.styleSheet() + custom_patch 69 | app.setStyleSheet(style_sheet) 70 | -------------------------------------------------------------------------------- /electrum/lnwire/README.md: -------------------------------------------------------------------------------- 1 | These files are generated from the BOLT repository: 2 | ``` 3 | $ python3 tools/extract-formats.py 01-*.md 02-*.md 07-*.md > peer_wire.csv 4 | $ python3 tools/extract-formats.py 04-*.md > onion_wire.csv 5 | ``` 6 | -------------------------------------------------------------------------------- /electrum/plot.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | from collections import defaultdict 3 | 4 | import matplotlib 5 | matplotlib.use('Qt5Agg') 6 | import matplotlib.pyplot as plt 7 | import matplotlib.dates as md 8 | 9 | from .i18n import _ 10 | from .bitcoin import COIN 11 | 12 | 13 | class NothingToPlotException(Exception): 14 | def __str__(self): 15 | return _("Nothing to plot.") 16 | 17 | 18 | def plot_history(history): 19 | if len(history) == 0: 20 | raise NothingToPlotException() 21 | hist_in = defaultdict(int) 22 | hist_out = defaultdict(int) 23 | for item in history: 24 | if not item['confirmations']: 25 | continue 26 | if item['timestamp'] is None: 27 | continue 28 | value = item['value'].value/COIN 29 | date = item['date'] 30 | datenum = int(md.date2num(datetime.date(date.year, date.month, 1))) 31 | if value > 0: 32 | hist_in[datenum] += value 33 | else: 34 | hist_out[datenum] -= value 35 | 36 | f, axarr = plt.subplots(2, sharex=True) 37 | plt.subplots_adjust(bottom=0.2) 38 | plt.xticks( rotation=25 ) 39 | ax = plt.gca() 40 | plt.ylabel('BTC') 41 | plt.xlabel('Month') 42 | xfmt = md.DateFormatter('%Y-%m-%d') 43 | ax.xaxis.set_major_formatter(xfmt) 44 | axarr[0].set_title('Monthly Volume') 45 | xfmt = md.DateFormatter('%Y-%m') 46 | ax.xaxis.set_major_formatter(xfmt) 47 | width = 20 48 | 49 | r1 = None 50 | r2 = None 51 | dates_values = list(zip(*sorted(hist_in.items()))) 52 | if dates_values and len(dates_values) == 2: 53 | dates, values = dates_values 54 | r1 = axarr[0].bar(dates, values, width, label='incoming') 55 | axarr[0].legend(loc='upper left') 56 | dates_values = list(zip(*sorted(hist_out.items()))) 57 | if dates_values and len(dates_values) == 2: 58 | dates, values = dates_values 59 | r2 = axarr[1].bar(dates, values, width, color='r', label='outgoing') 60 | axarr[1].legend(loc='upper left') 61 | if r1 is None and r2 is None: 62 | raise NothingToPlotException() 63 | return plt 64 | -------------------------------------------------------------------------------- /electrum/plugins/README: -------------------------------------------------------------------------------- 1 | Plugin rules: 2 | 3 | * The plugin system of Electrum is designed to allow the development 4 | of new features without increasing the core code of Electrum. 5 | 6 | * Electrum is written in pure python. if you want to add a feature 7 | that requires non-python libraries, then it must be submitted as a 8 | plugin. If the feature you want to add requires communication with 9 | a remote server (not an Electrum server), then it should be a 10 | plugin as well. If the feature you want to add introduces new 11 | dependencies in the code, then it should probably be a plugin. 12 | 13 | * We expect plugin developers to maintain their plugin code. However, 14 | once a plugin is merged in Electrum, we will have to maintain it 15 | too, because changes in the Electrum code often require updates in 16 | the plugin code. Therefore, plugins have to be easy to maintain. If 17 | we believe that a plugin will create too much maintenance work in 18 | the future, it will be rejected. 19 | 20 | * Plugins should be compatible with Electrum's conventions. If your 21 | plugin does not fit with Electrum's architecture, or if we believe 22 | that it will create too much maintenance work, it will not be 23 | accepted. In particular, do not duplicate existing Electrum code in 24 | your plugin. 25 | 26 | * We may decide to remove a plugin after it has been merged in 27 | Electrum. For this reason, a plugin must be easily removable, 28 | without putting at risk the user's bitcoins. If we feel that a 29 | plugin cannot be removed without threatening users who rely on it, 30 | we will not merge it. 31 | 32 | -------------------------------------------------------------------------------- /electrum/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Electrum - lightweight Bitcoin client 4 | # Copyright (C) 2015 Thomas Voegtlin 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | 27 | -------------------------------------------------------------------------------- /electrum/plugins/audio_modem/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = _('Audio MODEM') 4 | description = _('Provides support for air-gapped transaction signing.') 5 | requires = [('amodem', 'http://github.com/romanz/amodem/')] 6 | available_for = ['qt'] 7 | 8 | -------------------------------------------------------------------------------- /electrum/plugins/bitbox02/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = "BitBox02" 4 | description = ( 5 | "Provides support for the BitBox02 hardware wallet" 6 | ) 7 | requires = [ 8 | ( 9 | "bitbox02", 10 | "https://github.com/digitalbitbox/bitbox02-firmware/tree/master/py/bitbox02", 11 | ) 12 | ] 13 | registers_keystore = ("hardware", "bitbox02", _("BitBox02")) 14 | available_for = [] # ["qt"] 15 | -------------------------------------------------------------------------------- /electrum/plugins/coldcard/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'Coldcard Wallet' 4 | description = 'Provides support for the Coldcard hardware wallet from Coinkite' 5 | requires = [('ckcc-protocol', 'github.com/Coldcard/ckcc-protocol')] 6 | registers_keystore = ('hardware', 'coldcard', _("Coldcard Wallet")) 7 | available_for = [] # ['qt', 'cmdline'] 8 | -------------------------------------------------------------------------------- /electrum/plugins/coldcard/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.plugin import hook 2 | from electrum.util import print_msg, raw_input, print_stderr 3 | from electrum.logging import get_logger 4 | 5 | from ..hw_wallet.cmdline import CmdLineHandler 6 | 7 | from .coldcard import ColdcardPlugin 8 | 9 | 10 | _logger = get_logger(__name__) 11 | 12 | 13 | class ColdcardCmdLineHandler(CmdLineHandler): 14 | 15 | def get_passphrase(self, msg, confirm): 16 | raise NotImplementedError 17 | 18 | def get_pin(self, msg, *, show_strength=True): 19 | raise NotImplementedError 20 | 21 | def prompt_auth(self, msg): 22 | raise NotImplementedError 23 | 24 | def yes_no_question(self, msg): 25 | print_msg(msg) 26 | return raw_input() in 'yY' 27 | 28 | def stop(self): 29 | pass 30 | 31 | def update_status(self, b): 32 | _logger.info(f'hw device status {b}') 33 | 34 | def finished(self): 35 | pass 36 | 37 | class Plugin(ColdcardPlugin): 38 | handler = ColdcardCmdLineHandler() 39 | 40 | @hook 41 | def init_keystore(self, keystore): 42 | if not isinstance(keystore, self.keystore_class): 43 | return 44 | keystore.handler = self.handler 45 | 46 | def create_handler(self, window): 47 | return self.handler 48 | 49 | # EOF 50 | -------------------------------------------------------------------------------- /electrum/plugins/cosigner_pool/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | fullname = _('Cosigner Pool') 3 | description = ' '.join([ 4 | _("This plugin facilitates the use of multi-signatures wallets."), 5 | _("It sends and receives partially signed transactions from/to your cosigner wallet."), 6 | _("Transactions are encrypted and stored on a remote server.") 7 | ]) 8 | #requires_wallet_type = ['2of2', '2of3'] 9 | available_for = ['qt'] 10 | -------------------------------------------------------------------------------- /electrum/plugins/digitalbitbox/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'Digital Bitbox' 4 | description = _('Provides support for Digital Bitbox hardware wallet') 5 | registers_keystore = ('hardware', 'digitalbitbox', _("Digital Bitbox wallet")) 6 | available_for = [] # ['qt', 'cmdline'] 7 | -------------------------------------------------------------------------------- /electrum/plugins/digitalbitbox/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.plugin import hook 2 | from .digitalbitbox import DigitalBitboxPlugin 3 | from ..hw_wallet import CmdLineHandler 4 | 5 | class Plugin(DigitalBitboxPlugin): 6 | handler = CmdLineHandler() 7 | @hook 8 | def init_keystore(self, keystore): 9 | if not isinstance(keystore, self.keystore_class): 10 | return 11 | keystore.handler = self.handler 12 | 13 | def create_handler(self, window): 14 | return self.handler 15 | -------------------------------------------------------------------------------- /electrum/plugins/digitalbitbox/qt.py: -------------------------------------------------------------------------------- 1 | from functools import partial 2 | 3 | from electrum.i18n import _ 4 | from electrum.plugin import hook 5 | from electrum.wallet import Standard_Wallet, Abstract_Wallet 6 | 7 | from ..hw_wallet.qt import QtHandlerBase, QtPluginBase 8 | from ..hw_wallet.plugin import only_hook_if_libraries_available 9 | from .digitalbitbox import DigitalBitboxPlugin 10 | 11 | 12 | class Plugin(DigitalBitboxPlugin, QtPluginBase): 13 | icon_unpaired = "digitalbitbox_unpaired.png" 14 | icon_paired = "digitalbitbox.png" 15 | 16 | def create_handler(self, window): 17 | return DigitalBitbox_Handler(window) 18 | 19 | @only_hook_if_libraries_available 20 | @hook 21 | def receive_menu(self, menu, addrs, wallet: Abstract_Wallet): 22 | if type(wallet) is not Standard_Wallet: 23 | return 24 | 25 | keystore = wallet.get_keystore() 26 | if type(keystore) is not self.keystore_class: 27 | return 28 | 29 | if not self.is_mobile_paired(): 30 | return 31 | 32 | if len(addrs) == 1: 33 | addr = addrs[0] 34 | if wallet.get_txin_type(addr) != 'p2pkh': 35 | return 36 | def show_address(): 37 | keystore.thread.add(partial(self.show_address, wallet, addr, keystore)) 38 | 39 | menu.addAction(_("Show on {}").format(self.device), show_address) 40 | 41 | 42 | class DigitalBitbox_Handler(QtHandlerBase): 43 | 44 | def __init__(self, win): 45 | super(DigitalBitbox_Handler, self).__init__(win, 'Digital Bitbox') 46 | -------------------------------------------------------------------------------- /electrum/plugins/email_requests/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = _('Email') 4 | description = _("Send and receive payment request with an email account") 5 | available_for = ['qt'] 6 | -------------------------------------------------------------------------------- /electrum/plugins/hw_wallet/__init__.py: -------------------------------------------------------------------------------- 1 | from .plugin import HW_PluginBase, HardwareClientBase, HardwareHandlerBase 2 | from .cmdline import CmdLineHandler 3 | -------------------------------------------------------------------------------- /electrum/plugins/hw_wallet/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.util import print_stderr, raw_input 2 | from electrum.logging import get_logger 3 | 4 | from .plugin import HardwareHandlerBase 5 | 6 | 7 | _logger = get_logger(__name__) 8 | 9 | 10 | class CmdLineHandler(HardwareHandlerBase): 11 | 12 | def get_passphrase(self, msg, confirm): 13 | import getpass 14 | print_stderr(msg) 15 | return getpass.getpass('') 16 | 17 | def get_pin(self, msg, *, show_strength=True): 18 | t = { 'a':'7', 'b':'8', 'c':'9', 'd':'4', 'e':'5', 'f':'6', 'g':'1', 'h':'2', 'i':'3'} 19 | print_stderr(msg) 20 | print_stderr("a b c\nd e f\ng h i\n-----") 21 | o = raw_input() 22 | try: 23 | return ''.join(map(lambda x: t[x], o)) 24 | except KeyError as e: 25 | raise Exception("Character {} not in matrix!".format(e)) from e 26 | 27 | def prompt_auth(self, msg): 28 | import getpass 29 | print_stderr(msg) 30 | response = getpass.getpass('') 31 | if len(response) == 0: 32 | return None 33 | return response 34 | 35 | def yes_no_question(self, msg): 36 | print_stderr(msg) 37 | return raw_input() in 'yY' 38 | 39 | def stop(self): 40 | pass 41 | 42 | def show_message(self, msg, on_cancel=None): 43 | print_stderr(msg) 44 | 45 | def show_error(self, msg, blocking=False): 46 | print_stderr(msg) 47 | 48 | def update_status(self, b): 49 | _logger.info(f'hw device status {b}') 50 | 51 | def finished(self): 52 | pass 53 | -------------------------------------------------------------------------------- /electrum/plugins/keepkey/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'KeepKey' 4 | description = _('Provides support for KeepKey hardware wallet') 5 | requires = [('keepkeylib','github.com/keepkey/python-keepkey')] 6 | registers_keystore = ('hardware', 'keepkey', _("KeepKey wallet")) 7 | available_for = [] # ['qt', 'cmdline'] 8 | -------------------------------------------------------------------------------- /electrum/plugins/keepkey/client.py: -------------------------------------------------------------------------------- 1 | from keepkeylib.client import proto, BaseClient, ProtocolMixin 2 | from .clientbase import KeepKeyClientBase 3 | 4 | class KeepKeyClient(KeepKeyClientBase, ProtocolMixin, BaseClient): 5 | def __init__(self, transport, handler, plugin): 6 | BaseClient.__init__(self, transport) 7 | ProtocolMixin.__init__(self, transport) 8 | KeepKeyClientBase.__init__(self, handler, plugin, proto) 9 | 10 | def recovery_device(self, *args): 11 | ProtocolMixin.recovery_device(self, False, *args) 12 | 13 | 14 | KeepKeyClientBase.wrap_methods(KeepKeyClient) 15 | -------------------------------------------------------------------------------- /electrum/plugins/keepkey/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.plugin import hook 2 | from .keepkey import KeepKeyPlugin 3 | from ..hw_wallet import CmdLineHandler 4 | 5 | class Plugin(KeepKeyPlugin): 6 | handler = CmdLineHandler() 7 | @hook 8 | def init_keystore(self, keystore): 9 | if not isinstance(keystore, self.keystore_class): 10 | return 11 | keystore.handler = self.handler 12 | 13 | def create_handler(self, window): 14 | return self.handler 15 | -------------------------------------------------------------------------------- /electrum/plugins/labels/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = _('LabelSync') 4 | description = ' '.join([ 5 | _("Save your wallet labels on a remote server, and synchronize them across multiple devices where you use Electrum."), 6 | _("Labels, transactions IDs and addresses are encrypted before they are sent to the remote server.") 7 | ]) 8 | available_for = ['qt', 'kivy', 'cmdline'] 9 | 10 | -------------------------------------------------------------------------------- /electrum/plugins/labels/cmdline.py: -------------------------------------------------------------------------------- 1 | from .labels import LabelsPlugin 2 | from electrum.plugin import hook 3 | 4 | class Plugin(LabelsPlugin): 5 | 6 | @hook 7 | def load_wallet(self, wallet, window): 8 | self.start_wallet(wallet) 9 | 10 | def on_pulled(self, wallet): 11 | self.logger.info('labels pulled from server') 12 | -------------------------------------------------------------------------------- /electrum/plugins/labels/kivy.py: -------------------------------------------------------------------------------- 1 | from .labels import LabelsPlugin 2 | from electrum.plugin import hook 3 | 4 | class Plugin(LabelsPlugin): 5 | 6 | @hook 7 | def load_wallet(self, wallet, window): 8 | self.window = window 9 | self.start_wallet(wallet) 10 | 11 | def on_pulled(self, wallet): 12 | self.logger.info('on pulled') 13 | self.window._trigger_update_history() 14 | 15 | -------------------------------------------------------------------------------- /electrum/plugins/ledger/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'Ledger Wallet' 4 | description = 'Provides support for Ledger hardware wallet' 5 | requires = [('btchip', 'github.com/qtumproject/btchip-python')] 6 | registers_keystore = ('hardware', 'ledger', _("Ledger wallet")) 7 | available_for = ['qt', 'cmdline'] 8 | -------------------------------------------------------------------------------- /electrum/plugins/ledger/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.plugin import hook 2 | from .ledger import LedgerPlugin 3 | from ..hw_wallet import CmdLineHandler 4 | 5 | class Plugin(LedgerPlugin): 6 | handler = CmdLineHandler() 7 | @hook 8 | def init_keystore(self, keystore): 9 | if not isinstance(keystore, self.keystore_class): 10 | return 11 | keystore.handler = self.handler 12 | 13 | def create_handler(self, window): 14 | return self.handler 15 | -------------------------------------------------------------------------------- /electrum/plugins/revealer/DejaVuSansMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/plugins/revealer/DejaVuSansMono-Bold.ttf -------------------------------------------------------------------------------- /electrum/plugins/revealer/SourceSansPro-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/electrum/plugins/revealer/SourceSansPro-Bold.otf -------------------------------------------------------------------------------- /electrum/plugins/revealer/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = _('Revealer Backup Utility') 4 | description = ''.join(["
", 5 | ""+_("Do you have something to hide ?")+"", '
', '
', 6 | _("This plug-in allows you to create a visually encrypted backup of your wallet seeds, or of custom alphanumeric secrets."), '
', '
', 7 | _("For more information, visit"), 8 | " https://revealer.cc", '
', '
', 9 | ]) 10 | available_for = ['qt'] 11 | 12 | 13 | -------------------------------------------------------------------------------- /electrum/plugins/revealer/hmac_drbg.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Copyright (c) 2014 David Lazar 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | ''' 22 | 23 | import hashlib 24 | import hmac 25 | 26 | class DRBG(object): 27 | def __init__(self, seed): 28 | self.key = b'\x00' * 64 29 | self.val = b'\x01' * 64 30 | self.reseed(seed) 31 | 32 | def hmac(self, key, val): 33 | return hmac.new(key, val, hashlib.sha512).digest() 34 | 35 | def reseed(self, data=b''): 36 | self.key = self.hmac(self.key, self.val + b'\x00' + data) 37 | self.val = self.hmac(self.key, self.val) 38 | 39 | if data: 40 | self.key = self.hmac(self.key, self.val + b'\x01' + data) 41 | self.val = self.hmac(self.key, self.val) 42 | 43 | def generate(self, n): 44 | xs = b'' 45 | while len(xs) < n: 46 | self.val = self.hmac(self.key, self.val) 47 | xs += self.val 48 | 49 | self.reseed() 50 | 51 | return xs[:n] 52 | -------------------------------------------------------------------------------- /electrum/plugins/safe_t/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'Safe-T mini Wallet' 4 | description = _('Provides support for Safe-T mini hardware wallet') 5 | requires = [('safetlib','github.com/archos-safe-t/python-safet')] 6 | registers_keystore = ('hardware', 'safe_t', _("Safe-T mini wallet")) 7 | available_for = [] # ['qt', 'cmdline'] 8 | 9 | -------------------------------------------------------------------------------- /electrum/plugins/safe_t/client.py: -------------------------------------------------------------------------------- 1 | from safetlib.client import proto, BaseClient, ProtocolMixin 2 | from .clientbase import SafeTClientBase 3 | 4 | class SafeTClient(SafeTClientBase, ProtocolMixin, BaseClient): 5 | def __init__(self, transport, handler, plugin): 6 | BaseClient.__init__(self, transport=transport) 7 | ProtocolMixin.__init__(self, transport=transport) 8 | SafeTClientBase.__init__(self, handler, plugin, proto) 9 | 10 | 11 | SafeTClientBase.wrap_methods(SafeTClient) 12 | -------------------------------------------------------------------------------- /electrum/plugins/safe_t/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.plugin import hook 2 | from .safe_t import SafeTPlugin 3 | from ..hw_wallet import CmdLineHandler 4 | 5 | class Plugin(SafeTPlugin): 6 | handler = CmdLineHandler() 7 | @hook 8 | def init_keystore(self, keystore): 9 | if not isinstance(keystore, self.keystore_class): 10 | return 11 | keystore.handler = self.handler 12 | 13 | def create_handler(self, window): 14 | return self.handler 15 | -------------------------------------------------------------------------------- /electrum/plugins/trezor/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'Trezor Wallet' 4 | description = _('Provides support for Trezor hardware wallet') 5 | requires = [('trezorlib','pypi.org/project/trezor/')] 6 | registers_keystore = ('hardware', 'trezor', _("Trezor wallet")) 7 | available_for = ['qt', 'cmdline'] 8 | 9 | -------------------------------------------------------------------------------- /electrum/plugins/trezor/cmdline.py: -------------------------------------------------------------------------------- 1 | from electrum.plugin import hook 2 | from electrum.i18n import _ 3 | from electrum.util import print_stderr 4 | from .trezor import TrezorPlugin, PASSPHRASE_ON_DEVICE 5 | from ..hw_wallet import CmdLineHandler 6 | 7 | class TrezorCmdLineHandler(CmdLineHandler): 8 | def __init__(self): 9 | self.passphrase_on_device = False 10 | super().__init__() 11 | 12 | def get_passphrase(self, msg, confirm): 13 | import getpass 14 | print_stderr(msg) 15 | if self.passphrase_on_device and self.yes_no_question(_('Enter passphrase on device?')): 16 | return PASSPHRASE_ON_DEVICE 17 | else: 18 | return getpass.getpass('') 19 | 20 | class Plugin(TrezorPlugin): 21 | handler = CmdLineHandler() 22 | @hook 23 | def init_keystore(self, keystore): 24 | if not isinstance(keystore, self.keystore_class): 25 | return 26 | keystore.handler = self.handler 27 | 28 | def create_handler(self, window): 29 | return self.handler 30 | -------------------------------------------------------------------------------- /electrum/plugins/trustedcoin/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = _('Two Factor Authentication') 4 | description = ''.join([ 5 | _("This plugin adds two-factor authentication to your wallet."), '
', 6 | _("For more information, visit"), 7 | " https://api.trustedcoin.com/#/electrum-help" 8 | ]) 9 | requires_wallet_type = ['2fa'] 10 | registers_wallet_type = '2fa' 11 | available_for = [] # ['qt', 'cmdline', 'kivy'] 12 | -------------------------------------------------------------------------------- /electrum/plugins/trustedcoin/cmdline.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Electrum - Lightweight Bitcoin Client 4 | # Copyright (C) 2015 Thomas Voegtlin 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | from electrum.i18n import _ 27 | from electrum.plugin import hook 28 | from .trustedcoin import TrustedCoinPlugin 29 | 30 | 31 | class Plugin(TrustedCoinPlugin): 32 | 33 | def prompt_user_for_otp(self, wallet, tx): # FIXME this is broken 34 | if not isinstance(wallet, self.wallet_class): 35 | return 36 | if not wallet.can_sign_without_server(): 37 | self.logger.info("twofactor:sign_tx") 38 | auth_code = None 39 | if wallet.keystores['x3/'].can_sign(tx, ignore_watching_only=True): 40 | msg = _('Please enter your Google Authenticator code:') 41 | auth_code = int(input(msg)) 42 | else: 43 | self.logger.info("twofactor: xpub3 not needed") 44 | wallet.auth_code = auth_code 45 | 46 | -------------------------------------------------------------------------------- /electrum/plugins/virtualkeyboard/__init__.py: -------------------------------------------------------------------------------- 1 | from electrum.i18n import _ 2 | 3 | fullname = 'Virtual Keyboard' 4 | description = '%s\n%s' % (_("Add an optional virtual keyboard to the password dialog."), _("Warning: do not use this if it makes you pick a weaker password.")) 5 | available_for = ['qt'] 6 | -------------------------------------------------------------------------------- /electrum/plugins/virtualkeyboard/qt.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from PyQt5.QtWidgets import (QVBoxLayout, QGridLayout, QPushButton) 4 | 5 | from electrum.plugin import BasePlugin, hook 6 | from electrum.i18n import _ 7 | 8 | 9 | class Plugin(BasePlugin): 10 | vkb = None 11 | vkb_index = 0 12 | 13 | @hook 14 | def password_dialog(self, pw, grid, pos): 15 | vkb_button = QPushButton(_("+")) 16 | vkb_button.setFixedWidth(20) 17 | vkb_button.clicked.connect(lambda: self.toggle_vkb(grid, pw)) 18 | grid.addWidget(vkb_button, pos, 2) 19 | self.kb_pos = 2 20 | self.vkb = None 21 | 22 | def toggle_vkb(self, grid, pw): 23 | if self.vkb: 24 | grid.removeItem(self.vkb) 25 | self.vkb = self.virtual_keyboard(self.vkb_index, pw) 26 | grid.addLayout(self.vkb, self.kb_pos, 0, 1, 3) 27 | self.vkb_index += 1 28 | 29 | def virtual_keyboard(self, i, pw): 30 | i = i % 3 31 | if i == 0: 32 | chars = 'abcdefghijklmnopqrstuvwxyz ' 33 | elif i == 1: 34 | chars = 'ABCDEFGHIJKLMNOPQRTSUVWXYZ ' 35 | elif i == 2: 36 | chars = '1234567890!?.,;:/%&()[]{}+-' 37 | 38 | n = len(chars) 39 | s = [] 40 | for i in range(n): 41 | while True: 42 | k = random.randint(0, n - 1) 43 | if k not in s: 44 | s.append(k) 45 | break 46 | 47 | def add_target(t): 48 | return lambda: pw.setText(str(pw.text()) + t) 49 | 50 | vbox = QVBoxLayout() 51 | grid = QGridLayout() 52 | grid.setSpacing(2) 53 | for i in range(n): 54 | l_button = QPushButton(chars[s[i]]) 55 | l_button.setFixedWidth(25) 56 | l_button.setFixedHeight(25) 57 | l_button.clicked.connect(add_target(chars[s[i]])) 58 | grid.addWidget(l_button, i // 6, i % 6) 59 | 60 | vbox.addLayout(grid) 61 | 62 | return vbox 63 | -------------------------------------------------------------------------------- /electrum/scripts/bip39_recovery.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import asyncio 5 | 6 | from electrum.util import json_encode, print_msg, create_and_start_event_loop, log_exceptions 7 | from electrum.simple_config import SimpleConfig 8 | from electrum.network import Network 9 | from electrum.keystore import bip39_to_seed 10 | from electrum.bip32 import BIP32Node 11 | from electrum.bip39_recovery import account_discovery 12 | 13 | try: 14 | mnemonic = sys.argv[1] 15 | passphrase = sys.argv[2] if len(sys.argv) > 2 else "" 16 | except Exception: 17 | print("usage: bip39_recovery []") 18 | sys.exit(1) 19 | 20 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 21 | 22 | config = SimpleConfig() 23 | network = Network(config) 24 | network.start() 25 | 26 | @log_exceptions 27 | async def f(): 28 | try: 29 | def get_account_xpub(account_path): 30 | root_seed = bip39_to_seed(mnemonic, passphrase) 31 | root_node = BIP32Node.from_rootseed(root_seed, xtype="standard") 32 | account_node = root_node.subkey_at_private_derivation(account_path) 33 | account_xpub = account_node.to_xpub() 34 | return account_xpub 35 | active_accounts = await account_discovery(network, get_account_xpub) 36 | print_msg(json_encode(active_accounts)) 37 | finally: 38 | stopping_fut.set_result(1) 39 | 40 | asyncio.run_coroutine_threadsafe(f(), loop) 41 | -------------------------------------------------------------------------------- /electrum/scripts/bip70.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # create a BIP70 payment request signed with a certificate 3 | # FIXME: the code here is outdated, and no longer working 4 | 5 | import tlslite 6 | 7 | from electrum.transaction import Transaction 8 | from electrum import paymentrequest 9 | from electrum import paymentrequest_pb2 as pb2 10 | from electrum.bitcoin import address_to_script 11 | 12 | chain_file = 'mychain.pem' 13 | cert_file = 'mycert.pem' 14 | amount = 1000000 15 | address = "18U5kpCAU4s8weFF8Ps5n8HAfpdUjDVF64" 16 | memo = "blah" 17 | out_file = "payreq" 18 | 19 | 20 | with open(chain_file, 'r') as f: 21 | chain = tlslite.X509CertChain() 22 | chain.parsePemList(f.read()) 23 | 24 | certificates = pb2.X509Certificates() 25 | certificates.certificate.extend(map(lambda x: str(x.bytes), chain.x509List)) 26 | 27 | with open(cert_file, 'r') as f: 28 | rsakey = tlslite.utils.python_rsakey.Python_RSAKey.parsePEM(f.read()) 29 | 30 | script = address_to_script(address) 31 | 32 | pr_string = paymentrequest.make_payment_request(amount, script, memo, rsakey) 33 | 34 | with open(out_file,'wb') as f: 35 | f.write(pr_string) 36 | 37 | print("Payment request was written to file '%s'"%out_file) 38 | -------------------------------------------------------------------------------- /electrum/scripts/block_headers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # A simple script that connects to a server and displays block headers 4 | 5 | import time 6 | import asyncio 7 | 8 | from electrum.network import Network 9 | from electrum.util import print_msg, json_encode, create_and_start_event_loop, log_exceptions 10 | from electrum.simple_config import SimpleConfig 11 | 12 | config = SimpleConfig() 13 | 14 | # start network 15 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 16 | network = Network(config) 17 | network.start() 18 | 19 | # wait until connected 20 | while not network.is_connected(): 21 | time.sleep(1) 22 | print_msg("waiting for network to get connected...") 23 | 24 | header_queue = asyncio.Queue() 25 | 26 | @log_exceptions 27 | async def f(): 28 | try: 29 | await network.interface.session.subscribe('blockchain.headers.subscribe', [], header_queue) 30 | # 3. wait for results 31 | while network.is_connected(): 32 | header = await header_queue.get() 33 | print_msg(json_encode(header)) 34 | finally: 35 | stopping_fut.set_result(1) 36 | 37 | # 2. send the subscription 38 | asyncio.run_coroutine_threadsafe(f(), loop) 39 | -------------------------------------------------------------------------------- /electrum/scripts/estimate_fee.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import asyncio 4 | from statistics import median 5 | from numbers import Number 6 | 7 | from electrum.network import filter_protocol, Network 8 | from electrum.util import create_and_start_event_loop, log_exceptions 9 | from electrum.simple_config import SimpleConfig 10 | 11 | 12 | config = SimpleConfig() 13 | 14 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 15 | network = Network(config) 16 | network.start() 17 | 18 | @log_exceptions 19 | async def f(): 20 | try: 21 | peers = await network.get_peers() 22 | peers = filter_protocol(peers) 23 | results = await network.send_multiple_requests(peers, 'blockchain.estimatefee', [2]) 24 | print(json.dumps(results, indent=4)) 25 | feerate_estimates = filter(lambda x: isinstance(x, Number), results.values()) 26 | print(f"median feerate: {median(feerate_estimates)}") 27 | finally: 28 | stopping_fut.set_result(1) 29 | 30 | asyncio.run_coroutine_threadsafe(f(), loop) 31 | -------------------------------------------------------------------------------- /electrum/scripts/get_history.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import asyncio 5 | 6 | from electrum import bitcoin 7 | from electrum.network import Network 8 | from electrum.util import json_encode, print_msg, create_and_start_event_loop, log_exceptions 9 | from electrum.simple_config import SimpleConfig 10 | 11 | 12 | try: 13 | addr = sys.argv[1] 14 | except Exception: 15 | print("usage: get_history ") 16 | sys.exit(1) 17 | 18 | config = SimpleConfig() 19 | 20 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 21 | network = Network(config) 22 | network.start() 23 | 24 | @log_exceptions 25 | async def f(): 26 | try: 27 | sh = bitcoin.address_to_scripthash(addr) 28 | hist = await network.get_history_for_scripthash(sh) 29 | print_msg(json_encode(hist)) 30 | finally: 31 | stopping_fut.set_result(1) 32 | 33 | asyncio.run_coroutine_threadsafe(f(), loop) 34 | -------------------------------------------------------------------------------- /electrum/scripts/peers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import asyncio 3 | 4 | from electrum.network import filter_protocol, Network 5 | from electrum.util import create_and_start_event_loop, log_exceptions 6 | from electrum.blockchain import hash_raw_header 7 | from electrum.simple_config import SimpleConfig 8 | 9 | 10 | config = SimpleConfig() 11 | 12 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 13 | network = Network(config) 14 | network.start() 15 | 16 | @log_exceptions 17 | async def f(): 18 | try: 19 | peers = await network.get_peers() 20 | peers = filter_protocol(peers) 21 | results = await network.send_multiple_requests(peers, 'blockchain.headers.subscribe', []) 22 | for server, header in sorted(results.items(), key=lambda x: x[1].get('height')): 23 | height = header.get('height') 24 | blockhash = hash_raw_header(header.get('hex')) 25 | print(server, height, blockhash) 26 | finally: 27 | stopping_fut.set_result(1) 28 | 29 | asyncio.run_coroutine_threadsafe(f(), loop) 30 | -------------------------------------------------------------------------------- /electrum/scripts/quick_start.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import asyncio 5 | 6 | from electrum.simple_config import SimpleConfig 7 | from electrum import constants 8 | from electrum.daemon import Daemon 9 | from electrum.storage import WalletStorage 10 | from electrum.wallet import Wallet, create_new_wallet 11 | from electrum.wallet_db import WalletDB 12 | from electrum.commands import Commands 13 | from electrum.util import create_and_start_event_loop, log_exceptions 14 | 15 | 16 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 17 | 18 | config = SimpleConfig({"testnet": True}) # to use ~/.electrum/testnet as datadir 19 | constants.set_testnet() # to set testnet magic bytes 20 | daemon = Daemon(config, listen_jsonrpc=False) 21 | network = daemon.network 22 | assert network.asyncio_loop.is_running() 23 | 24 | # get wallet on disk 25 | wallet_dir = os.path.dirname(config.get_wallet_path()) 26 | wallet_path = os.path.join(wallet_dir, "test_wallet") 27 | if not os.path.exists(wallet_path): 28 | create_new_wallet(path=wallet_path, config=config) 29 | 30 | # open wallet 31 | wallet = daemon.load_wallet(wallet_path, password=None, manual_upgrades=False) 32 | wallet.start_network(network) 33 | 34 | # you can use ~CLI commands by accessing command_runner 35 | command_runner = Commands(config=config, daemon=daemon, network=network) 36 | print("balance", network.run_from_another_thread(command_runner.getbalance(wallet=wallet))) 37 | print("addr", network.run_from_another_thread(command_runner.getunusedaddress(wallet=wallet))) 38 | print("gettx", network.run_from_another_thread( 39 | command_runner.gettransaction("bd3a700b2822e10a034d110c11a596ee7481732533eb6aca7f9ca02911c70a4f"))) 40 | 41 | 42 | # but you might as well interact with the underlying methods directly 43 | print("balance", wallet.get_balance()) 44 | print("addr", wallet.get_unused_address()) 45 | print("gettx", network.run_from_another_thread(network.get_transaction("bd3a700b2822e10a034d110c11a596ee7481732533eb6aca7f9ca02911c70a4f"))) 46 | 47 | stopping_fut.set_result(1) # to stop event loop 48 | -------------------------------------------------------------------------------- /electrum/scripts/servers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import asyncio 4 | 5 | from electrum.simple_config import SimpleConfig 6 | from electrum.network import filter_version, Network 7 | from electrum.util import create_and_start_event_loop, log_exceptions 8 | from electrum import constants 9 | 10 | # testnet? 11 | #constants.set_testnet() 12 | config = SimpleConfig({'testnet': False}) 13 | 14 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 15 | network = Network(config) 16 | network.start() 17 | 18 | @log_exceptions 19 | async def f(): 20 | try: 21 | peers = await network.get_peers() 22 | peers = filter_version(peers) 23 | print(json.dumps(peers, sort_keys=True, indent=4)) 24 | finally: 25 | stopping_fut.set_result(1) 26 | 27 | asyncio.run_coroutine_threadsafe(f(), loop) 28 | -------------------------------------------------------------------------------- /electrum/scripts/txradar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import asyncio 4 | 5 | from electrum.network import filter_protocol, Network 6 | from electrum.util import create_and_start_event_loop, log_exceptions 7 | from electrum.simple_config import SimpleConfig 8 | 9 | 10 | try: 11 | txid = sys.argv[1] 12 | except: 13 | print("usage: txradar txid") 14 | sys.exit(1) 15 | 16 | config = SimpleConfig() 17 | 18 | loop, stopping_fut, loop_thread = create_and_start_event_loop() 19 | network = Network(config) 20 | network.start() 21 | 22 | @log_exceptions 23 | async def f(): 24 | try: 25 | peers = await network.get_peers() 26 | peers = filter_protocol(peers) 27 | results = await network.send_multiple_requests(peers, 'blockchain.transaction.get', [txid]) 28 | r1, r2 = [], [] 29 | for k, v in results.items(): 30 | (r1 if not isinstance(v, Exception) else r2).append(k) 31 | print(f"Received {len(results)} answers") 32 | try: propagation = len(r1) * 100. / (len(r1) + len(r2)) 33 | except ZeroDivisionError: propagation = 0 34 | print(f"Propagation rate: {propagation:.1f} percent") 35 | finally: 36 | stopping_fut.set_result(1) 37 | 38 | asyncio.run_coroutine_threadsafe(f(), loop) 39 | -------------------------------------------------------------------------------- /electrum/scripts/watch_address.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import asyncio 5 | 6 | from electrum.network import Network 7 | from electrum.util import print_msg, create_and_start_event_loop 8 | from electrum.synchronizer import SynchronizerBase 9 | from electrum.simple_config import SimpleConfig 10 | 11 | 12 | try: 13 | addr = sys.argv[1] 14 | except Exception: 15 | print("usage: watch_address ") 16 | sys.exit(1) 17 | 18 | config = SimpleConfig() 19 | 20 | # start network 21 | loop = create_and_start_event_loop()[0] 22 | network = Network(config) 23 | network.start() 24 | 25 | 26 | class Notifier(SynchronizerBase): 27 | def __init__(self, network): 28 | SynchronizerBase.__init__(self, network) 29 | self.watched_addresses = set() 30 | self.watch_queue = asyncio.Queue() 31 | 32 | async def main(self): 33 | # resend existing subscriptions if we were restarted 34 | for addr in self.watched_addresses: 35 | await self._add_address(addr) 36 | # main loop 37 | while True: 38 | addr = await self.watch_queue.get() 39 | self.watched_addresses.add(addr) 40 | await self._add_address(addr) 41 | 42 | async def _on_address_status(self, addr, status): 43 | print_msg(f"addr {addr}, status {status}") 44 | 45 | 46 | notifier = Notifier(network) 47 | asyncio.run_coroutine_threadsafe(notifier.watch_queue.put(addr), loop) 48 | -------------------------------------------------------------------------------- /electrum/servers.json: -------------------------------------------------------------------------------- 1 | { 2 | "s1.electrum.qtum.site": { 3 | "pruning": "-", 4 | "t": "50001", 5 | "s": "50002", 6 | "version": "1.4" 7 | }, 8 | "s3.electrum.qtum.site": { 9 | "pruning": "-", 10 | "t": "50001", 11 | "s": "50002", 12 | "version": "1.4" 13 | }, 14 | "s4.electrum.qtum.site": { 15 | "pruning": "-", 16 | "t": "50001", 17 | "s": "50002", 18 | "version": "1.4" 19 | }, 20 | "s5.electrum.qtum.site": { 21 | "pruning": "-", 22 | "t": "50001", 23 | "s": "50002", 24 | "version": "1.4" 25 | }, 26 | "s7.electrum.qtum.site": { 27 | "pruning": "-", 28 | "t": "50001", 29 | "s": "50002", 30 | "version": "1.4" 31 | }, 32 | "s8.electrum.qtum.site": { 33 | "pruning": "-", 34 | "t": "50001", 35 | "s": "50002", 36 | "version": "1.4" 37 | }, 38 | "s9.electrum.qtum.site": { 39 | "pruning": "-", 40 | "t": "50001", 41 | "s": "50002", 42 | "version": "1.4" 43 | }, 44 | "s10.electrum.qtum.site": { 45 | "pruning": "-", 46 | "t": "50001", 47 | "s": "50002", 48 | "version": "1.4" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /electrum/servers_regtest.json: -------------------------------------------------------------------------------- 1 | { 2 | "127.0.0.1": { 3 | "pruning": "-", 4 | "s": "51002", 5 | "t": "51001", 6 | "version": "1.2" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /electrum/servers_testnet.json: -------------------------------------------------------------------------------- 1 | { 2 | "s2.electrum.qtum.site": { 3 | "pruning": "-", 4 | "t": "51001", 5 | "s": "51002", 6 | "version": "1.4" 7 | }, 8 | "s6.electrum.qtum.site": { 9 | "pruning": "-", 10 | "t": "51001", 11 | "s": "51002", 12 | "version": "1.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /electrum/sql_db.py: -------------------------------------------------------------------------------- 1 | import os 2 | import concurrent 3 | import queue 4 | import threading 5 | import asyncio 6 | import sqlite3 7 | 8 | from .logging import Logger 9 | from .util import test_read_write_permissions 10 | 11 | 12 | def sql(func): 13 | """wrapper for sql methods""" 14 | def wrapper(self: 'SqlDB', *args, **kwargs): 15 | assert threading.current_thread() != self.sql_thread 16 | f = asyncio.Future() 17 | self.db_requests.put((f, func, args, kwargs)) 18 | return f 19 | return wrapper 20 | 21 | 22 | class SqlDB(Logger): 23 | 24 | def __init__(self, asyncio_loop: asyncio.BaseEventLoop, path, commit_interval=None): 25 | Logger.__init__(self) 26 | self.asyncio_loop = asyncio_loop 27 | self.path = path 28 | test_read_write_permissions(path) 29 | self.commit_interval = commit_interval 30 | self.db_requests = queue.Queue() 31 | self.sql_thread = threading.Thread(target=self.run_sql) 32 | self.sql_thread.start() 33 | 34 | def filesize(self): 35 | return os.stat(self.path).st_size 36 | 37 | def run_sql(self): 38 | self.logger.info("SQL thread started") 39 | self.conn = sqlite3.connect(self.path) 40 | self.logger.info("Creating database") 41 | self.create_database() 42 | i = 0 43 | while self.asyncio_loop.is_running(): 44 | try: 45 | future, func, args, kwargs = self.db_requests.get(timeout=0.1) 46 | except queue.Empty: 47 | continue 48 | try: 49 | result = func(self, *args, **kwargs) 50 | except BaseException as e: 51 | self.asyncio_loop.call_soon_threadsafe(future.set_exception, e) 52 | continue 53 | if not future.cancelled(): 54 | self.asyncio_loop.call_soon_threadsafe(future.set_result, result) 55 | # note: in sweepstore session.commit() is called inside 56 | # the sql-decorated methods, so commiting to disk is awaited 57 | if self.commit_interval: 58 | i = (i + 1) % self.commit_interval 59 | if i == 0: 60 | self.conn.commit() 61 | # write 62 | self.conn.commit() 63 | self.conn.close() 64 | self.logger.info("SQL thread terminated") 65 | 66 | def create_database(self): 67 | raise NotImplementedError() 68 | -------------------------------------------------------------------------------- /electrum/tests/__init__.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import threading 3 | import tempfile 4 | import shutil 5 | 6 | from electrum import constants 7 | 8 | 9 | # Set this locally to make the test suite run faster. 10 | # If set, unit tests that would normally test functions with multiple implementations, 11 | # will only be run once, using the fastest implementation. 12 | # e.g. libsecp256k1 vs python-ecdsa. pycryptodomex vs pyaes. 13 | FAST_TESTS = False 14 | 15 | 16 | # some unit tests are modifying globals... 17 | class SequentialTestCase(unittest.TestCase): 18 | 19 | test_lock = threading.Lock() 20 | 21 | def setUp(self): 22 | super().setUp() 23 | self.test_lock.acquire() 24 | 25 | def tearDown(self): 26 | super().tearDown() 27 | self.test_lock.release() 28 | 29 | 30 | class ElectrumTestCase(SequentialTestCase): 31 | """Base class for our unit tests.""" 32 | 33 | def setUp(self): 34 | super().setUpClass() 35 | self.electrum_path = tempfile.mkdtemp() 36 | 37 | def tearDown(self): 38 | super().tearDownClass() 39 | shutil.rmtree(self.electrum_path) 40 | 41 | 42 | class TestCaseForTestnet(ElectrumTestCase): 43 | 44 | @classmethod 45 | def setUpClass(cls): 46 | super().setUpClass() 47 | constants.set_testnet() 48 | 49 | @classmethod 50 | def tearDownClass(cls): 51 | super().tearDownClass() 52 | constants.set_mainnet() 53 | -------------------------------------------------------------------------------- /electrum/tests/regtest.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import unittest 4 | import subprocess 5 | 6 | class TestLightning(unittest.TestCase): 7 | 8 | @staticmethod 9 | def run_shell(args, timeout=30): 10 | process = subprocess.Popen(['electrum/tests/regtest/regtest.sh'] + args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) 11 | for line in iter(process.stdout.readline, b''): 12 | sys.stdout.write(line.decode(sys.stdout.encoding)) 13 | process.wait(timeout=timeout) 14 | process.stdout.close() 15 | assert process.returncode == 0 16 | 17 | def setUp(self): 18 | test_name = self.id().split('.')[-1] 19 | sys.stdout.write("***** %s ******\n" % test_name) 20 | # initialize and get funds 21 | for agent in self.agents: 22 | self.run_shell(['init', agent]) 23 | # mine a block so that funds are confirmed 24 | self.run_shell(['new_block']) 25 | # extra configuration (optional) 26 | self.run_shell(['configure_' + test_name]) 27 | # start daemons 28 | for agent in self.agents: 29 | self.run_shell(['start', agent]) 30 | 31 | def tearDown(self): 32 | for agent in self.agents: 33 | self.run_shell(['stop', agent]) 34 | 35 | 36 | class TestLightningAB(TestLightning): 37 | agents = ['alice', 'bob'] 38 | 39 | def test_breach(self): 40 | self.run_shell(['breach']) 41 | 42 | def test_extract_preimage(self): 43 | self.run_shell(['extract_preimage']) 44 | 45 | def test_redeem_htlcs(self): 46 | self.run_shell(['redeem_htlcs']) 47 | 48 | def test_breach_with_unspent_htlc(self): 49 | self.run_shell(['breach_with_unspent_htlc']) 50 | 51 | def test_breach_with_spent_htlc(self): 52 | self.run_shell(['breach_with_spent_htlc']) 53 | 54 | 55 | class TestLightningABC(TestLightning): 56 | agents = ['alice', 'bob', 'carol'] 57 | 58 | def test_forwarding(self): 59 | self.run_shell(['forwarding']) 60 | 61 | def test_watchtower(self): 62 | self.run_shell(['watchtower']) 63 | -------------------------------------------------------------------------------- /electrum/tests/regtest/start_bitcoind.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export HOME=~ 3 | set -eux pipefail 4 | mkdir -p ~/.bitcoin 5 | cat > ~/.bitcoin/bitcoin.conf < /dev/null 25 | -------------------------------------------------------------------------------- /electrum/tests/regtest/start_electrumx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export HOME=~ 3 | set -eux pipefail 4 | cd 5 | rm -rf $HOME/electrumx_db 6 | mkdir $HOME/electrumx_db 7 | COST_SOFT_LIMIT=0 COST_HARD_LIMIT=0 COIN=BitcoinSegwit SERVICES=tcp://:51001,rpc:// NET=regtest DAEMON_URL=http://doggman:donkey@127.0.0.1:18554 DB_DIRECTORY=$HOME/electrumx_db electrumx_server > $HOME/electrumx.log & 8 | -------------------------------------------------------------------------------- /electrum/tests/test_coinchooser.py: -------------------------------------------------------------------------------- 1 | from electrum.coinchooser import CoinChooserPrivacy 2 | from electrum.util import NotEnoughFunds 3 | 4 | from . import ElectrumTestCase 5 | 6 | 7 | class TestCoinChooser(ElectrumTestCase): 8 | 9 | def test_bucket_candidates_with_empty_buckets(self): 10 | def sufficient_funds(buckets, *, bucket_value_sum): 11 | return True 12 | coin_chooser = CoinChooserPrivacy(enable_output_value_rounding=False) 13 | self.assertEqual([[]], coin_chooser.bucket_candidates_any([], sufficient_funds)) 14 | self.assertEqual([[]], coin_chooser.bucket_candidates_prefer_confirmed([], sufficient_funds)) 15 | def sufficient_funds(buckets, *, bucket_value_sum): 16 | return False 17 | with self.assertRaises(NotEnoughFunds): 18 | coin_chooser.bucket_candidates_any([], sufficient_funds) 19 | with self.assertRaises(NotEnoughFunds): 20 | coin_chooser.bucket_candidates_prefer_confirmed([], sufficient_funds) 21 | -------------------------------------------------------------------------------- /electrum/tests/test_verifier.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from electrum.bitcoin import hash_encode 4 | from electrum.transaction import Transaction 5 | from electrum.util import bfh 6 | from electrum.verifier import SPV, InnerNodeOfSpvProofIsValidTx 7 | 8 | from . import TestCaseForTestnet 9 | 10 | 11 | MERKLE_BRANCH = [ 12 | 'f2994fd4546086b21b4916b76cf901afb5c4db1c3ecbfc91d6f4cae1186dfe12', 13 | '6b65935528311901c7acda7db817bd6e3ce2f05d1c62c385b7caadb65fac7520'] 14 | 15 | MERKLE_ROOT = '11dbac015b6969ea75509dd1250f33c04ec4d562c2d895de139a65f62f808254' 16 | 17 | VALID_64_BYTE_TX = ('0200000001cb659c5528311901a7aada7db817bd6e3ce2f05d1c62c385b7caad' 18 | 'b65fac75201234000000fabcdefa01abcd1234010000000405060708fabcdefa') 19 | assert len(VALID_64_BYTE_TX) == 128 20 | 21 | 22 | class VerifierTestCase(TestCaseForTestnet): 23 | # these tests are regarding the attack described in 24 | # https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-June/016105.html 25 | 26 | def test_verify_ok_t_tx(self): 27 | """Actually mined 64 byte tx should not raise.""" 28 | t_tx = Transaction(VALID_64_BYTE_TX) 29 | t_tx_hash = t_tx.txid() 30 | self.assertEqual(MERKLE_ROOT, SPV.hash_merkle_root(MERKLE_BRANCH, t_tx_hash, 3)) 31 | 32 | def test_verify_fail_f_tx_odd(self): 33 | """Raise if inner node of merkle branch is valid tx. ('odd' fake leaf position)""" 34 | # first 32 bytes of T encoded as hash 35 | fake_branch_node = hash_encode(bfh(VALID_64_BYTE_TX[:64])) 36 | fake_mbranch = [fake_branch_node] + MERKLE_BRANCH 37 | # last 32 bytes of T encoded as hash 38 | f_tx_hash = hash_encode(bfh(VALID_64_BYTE_TX[64:])) 39 | with self.assertRaises(InnerNodeOfSpvProofIsValidTx): 40 | SPV.hash_merkle_root(fake_mbranch, f_tx_hash, 7) 41 | 42 | def test_verify_fail_f_tx_even(self): 43 | """Raise if inner node of merkle branch is valid tx. ('even' fake leaf position)""" 44 | # last 32 bytes of T encoded as hash 45 | fake_branch_node = hash_encode(bfh(VALID_64_BYTE_TX[64:])) 46 | fake_mbranch = [fake_branch_node] + MERKLE_BRANCH 47 | # first 32 bytes of T encoded as hash 48 | f_tx_hash = hash_encode(bfh(VALID_64_BYTE_TX[:64])) 49 | with self.assertRaises(InnerNodeOfSpvProofIsValidTx): 50 | SPV.hash_merkle_root(fake_mbranch, f_tx_hash, 6) 51 | -------------------------------------------------------------------------------- /electrum/version.py: -------------------------------------------------------------------------------- 1 | ELECTRUM_VERSION = '4.0.22' # version of the client package 2 | APK_VERSION = '4.0.3.0' # read by buildozer.spec 3 | 4 | PROTOCOL_VERSION = '1.5' # protocol version requested 5 | 6 | # The hash of the mnemonic seed must begin with this 7 | SEED_PREFIX = '01' # Standard wallet 8 | SEED_PREFIX_SW = '100' # Segwit wallet 9 | SEED_PREFIX_2FA = '101' # Two-factor authentication 10 | SEED_PREFIX_2FA_SW = '102' # Two-factor auth, using segwit 11 | 12 | 13 | def seed_prefix(seed_type): 14 | if seed_type == 'standard': 15 | return SEED_PREFIX 16 | elif seed_type == 'segwit': 17 | return SEED_PREFIX_SW 18 | # elif seed_type == '2fa': 19 | # return SEED_PREFIX_2FA 20 | # elif seed_type == '2fa_segwit': 21 | # return SEED_PREFIX_2FA_SW 22 | raise Exception(f"unknown seed_type: {seed_type}") 23 | -------------------------------------------------------------------------------- /screenshot/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/screenshot/history.png -------------------------------------------------------------------------------- /screenshot/tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qtumproject/qtum-electrum/e970c397831d0dc01e2989029f1dc6ea415b40c4/screenshot/tokens.png -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py36, py37 3 | 4 | [testenv] 5 | deps= 6 | pytest 7 | coverage 8 | commands= 9 | coverage run --source=electrum '--omit=electrum/gui/*,electrum/plugins/*,electrum/scripts/*,electrum/tests/*' -m py.test -v 10 | coverage report 11 | extras= 12 | tests 13 | --------------------------------------------------------------------------------