electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit d40bedb2ac77ed9e91c67bfd69451f7af69fece7
parent 37a124fa1c5e0a08f835694200bebedf2522ecd4
Author: SomberNight <somber.night@protonmail.com>
Date:   Wed,  9 Dec 2020 16:09:12 +0100

also support uppercase bip21 URIs

related https://github.com/btcpayserver/btcpayserver/issues/2110

Diffstat:
Melectrum/gui/kivy/main_window.py | 11++++++-----
Melectrum/gui/qt/main_window.py | 6+++---
Melectrum/gui/qt/paytoedit.py | 6+++---
Melectrum/util.py | 19++++++++++++++++---
Mrun_electrum | 4++--
5 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/electrum/gui/kivy/main_window.py b/electrum/gui/kivy/main_window.py @@ -75,7 +75,8 @@ Label.register('Roboto', 'electrum/gui/kivy/data/fonts/Roboto-Bold.ttf') -from electrum.util import (NoDynamicFeeEstimates, NotEnoughFunds) +from electrum.util import (NoDynamicFeeEstimates, NotEnoughFunds, + BITCOIN_BIP21_URI_SCHEME, LIGHTNING_URI_SCHEME) from .uix.dialogs.lightning_open_channel import LightningOpenChannelDialog from .uix.dialogs.lightning_channels import LightningChannelsDialog @@ -210,9 +211,9 @@ class ElectrumWindow(App, Logger): def on_new_intent(self, intent): data = str(intent.getDataString()) scheme = str(intent.getScheme()).lower() - if scheme == 'bitcoin': + if scheme == BITCOIN_BIP21_URI_SCHEME: self.set_URI(data) - elif scheme == 'lightning': + elif scheme == LIGHTNING_URI_SCHEME: self.set_ln_invoice(data) def on_language(self, instance, language): @@ -420,10 +421,10 @@ class ElectrumWindow(App, Logger): if is_address(data): self.set_URI(data) return - if data.startswith('bitcoin:'): + if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'): self.set_URI(data) return - if data.startswith('channel_backup:'): + if data.lower().startswith('channel_backup:'): self.import_channel_backup(data) return bolt11_invoice = maybe_extract_bolt11_invoice(data) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py @@ -61,7 +61,7 @@ from electrum.util import (format_time, get_new_wallet_name, send_exception_to_crash_reporter, InvalidBitcoinURI, maybe_extract_bolt11_invoice, NotEnoughFunds, NoDynamicFeeEstimates, MultipleSpendMaxTxOutputs, - AddTransactionException) + AddTransactionException, BITCOIN_BIP21_URI_SCHEME) from electrum.invoices import PR_TYPE_ONCHAIN, PR_TYPE_LN, PR_DEFAULT_EXPIRATION_WHEN_CREATING, Invoice from electrum.invoices import PR_PAID, PR_FAILED, pr_expiration_values, LNInvoice, OnchainInvoice from electrum.transaction import (Transaction, PartialTxInput, @@ -2688,10 +2688,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): if not data: return # if the user scanned a bitcoin URI - if str(data).startswith("bitcoin:"): + if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'): self.pay_to_URI(data) return - if data.startswith('channel_backup:'): + if data.lower().startswith('channel_backup:'): self.import_channel_backup(data) return # else if the user scanned an offline signed tx diff --git a/electrum/gui/qt/paytoedit.py b/electrum/gui/qt/paytoedit.py @@ -30,7 +30,7 @@ from typing import NamedTuple, Sequence, Optional, List, TYPE_CHECKING from PyQt5.QtGui import QFontMetrics, QFont from electrum import bitcoin -from electrum.util import bfh, maybe_extract_bolt11_invoice +from electrum.util import bfh, maybe_extract_bolt11_invoice, BITCOIN_BIP21_URI_SCHEME from electrum.transaction import PartialTxOutput from electrum.bitcoin import opcodes, construct_script from electrum.logging import Logger @@ -153,7 +153,7 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger): if len(lines) == 1: data = lines[0] # try bip21 URI - if data.startswith("bitcoin:"): + if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'): self.win.pay_to_URI(data) return # try LN invoice @@ -255,7 +255,7 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger): def qr_input(self): data = super(PayToEdit,self).qr_input() - if data.startswith("bitcoin:"): + if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'): self.win.pay_to_URI(data) # TODO: update fee diff --git a/electrum/util.py b/electrum/util.py @@ -825,6 +825,12 @@ def block_explorer_URL(config: 'SimpleConfig', kind: str, item: str) -> Optional #_ud = re.compile('%([0-9a-hA-H]{2})', re.MULTILINE) #urldecode = lambda x: _ud.sub(lambda m: chr(int(m.group(1), 16)), x) + +# note: when checking against these, use .lower() to support case-insensitivity +BITCOIN_BIP21_URI_SCHEME = 'bitcoin' +LIGHTNING_URI_SCHEME = 'lightning' + + class InvalidBitcoinURI(Exception): pass @@ -843,7 +849,7 @@ def parse_URI(uri: str, on_pr: Callable = None, *, loop=None) -> dict: return {'address': uri} u = urllib.parse.urlparse(uri) - if u.scheme != 'bitcoin': + if u.scheme.lower() != BITCOIN_BIP21_URI_SCHEME: raise InvalidBitcoinURI("Not a bitcoin URI") address = u.path @@ -931,14 +937,21 @@ def create_bip21_uri(addr, amount_sat: Optional[int], message: Optional[str], raise Exception(f"illegal key for URI: {repr(k)}") v = urllib.parse.quote(v) query.append(f"{k}={v}") - p = urllib.parse.ParseResult(scheme='bitcoin', netloc='', path=addr, params='', query='&'.join(query), fragment='') + p = urllib.parse.ParseResult( + scheme=BITCOIN_BIP21_URI_SCHEME, + netloc='', + path=addr, + params='', + query='&'.join(query), + fragment='', + ) return str(urllib.parse.urlunparse(p)) def maybe_extract_bolt11_invoice(data: str) -> Optional[str]: data = data.strip() # whitespaces data = data.lower() - if data.startswith('lightning:ln'): + if data.startswith(LIGHTNING_URI_SCHEME + ':ln'): data = data[10:] if data.startswith('ln'): return data diff --git a/run_electrum b/run_electrum @@ -87,7 +87,7 @@ from electrum.wallet_db import WalletDB from electrum.wallet import Wallet from electrum.storage import WalletStorage from electrum.util import print_msg, print_stderr, json_encode, json_decode, UserCancelled -from electrum.util import InvalidPassword +from electrum.util import InvalidPassword, BITCOIN_BIP21_URI_SCHEME from electrum.commands import get_parser, known_commands, Commands, config_variables from electrum import daemon from electrum import keystore @@ -343,7 +343,7 @@ def main(): # check uri uri = config_options.get('url') if uri: - if not uri.startswith('bitcoin:'): + if not uri.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'): print_stderr('unknown command:', uri) sys.exit(1)