also support uppercase bip21 URIs
related https://github.com/btcpayserver/btcpayserver/issues/2110
This commit is contained in:
@@ -75,7 +75,8 @@ Label.register('Roboto',
|
|||||||
'electrum/gui/kivy/data/fonts/Roboto-Bold.ttf')
|
'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_open_channel import LightningOpenChannelDialog
|
||||||
from .uix.dialogs.lightning_channels import LightningChannelsDialog
|
from .uix.dialogs.lightning_channels import LightningChannelsDialog
|
||||||
@@ -210,9 +211,9 @@ class ElectrumWindow(App, Logger):
|
|||||||
def on_new_intent(self, intent):
|
def on_new_intent(self, intent):
|
||||||
data = str(intent.getDataString())
|
data = str(intent.getDataString())
|
||||||
scheme = str(intent.getScheme()).lower()
|
scheme = str(intent.getScheme()).lower()
|
||||||
if scheme == 'bitcoin':
|
if scheme == BITCOIN_BIP21_URI_SCHEME:
|
||||||
self.set_URI(data)
|
self.set_URI(data)
|
||||||
elif scheme == 'lightning':
|
elif scheme == LIGHTNING_URI_SCHEME:
|
||||||
self.set_ln_invoice(data)
|
self.set_ln_invoice(data)
|
||||||
|
|
||||||
def on_language(self, instance, language):
|
def on_language(self, instance, language):
|
||||||
@@ -420,10 +421,10 @@ class ElectrumWindow(App, Logger):
|
|||||||
if is_address(data):
|
if is_address(data):
|
||||||
self.set_URI(data)
|
self.set_URI(data)
|
||||||
return
|
return
|
||||||
if data.startswith('bitcoin:'):
|
if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'):
|
||||||
self.set_URI(data)
|
self.set_URI(data)
|
||||||
return
|
return
|
||||||
if data.startswith('channel_backup:'):
|
if data.lower().startswith('channel_backup:'):
|
||||||
self.import_channel_backup(data)
|
self.import_channel_backup(data)
|
||||||
return
|
return
|
||||||
bolt11_invoice = maybe_extract_bolt11_invoice(data)
|
bolt11_invoice = maybe_extract_bolt11_invoice(data)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ from electrum.util import (format_time,
|
|||||||
get_new_wallet_name, send_exception_to_crash_reporter,
|
get_new_wallet_name, send_exception_to_crash_reporter,
|
||||||
InvalidBitcoinURI, maybe_extract_bolt11_invoice, NotEnoughFunds,
|
InvalidBitcoinURI, maybe_extract_bolt11_invoice, NotEnoughFunds,
|
||||||
NoDynamicFeeEstimates, MultipleSpendMaxTxOutputs,
|
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_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.invoices import PR_PAID, PR_FAILED, pr_expiration_values, LNInvoice, OnchainInvoice
|
||||||
from electrum.transaction import (Transaction, PartialTxInput,
|
from electrum.transaction import (Transaction, PartialTxInput,
|
||||||
@@ -2688,10 +2688,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
if not data:
|
if not data:
|
||||||
return
|
return
|
||||||
# if the user scanned a bitcoin URI
|
# 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)
|
self.pay_to_URI(data)
|
||||||
return
|
return
|
||||||
if data.startswith('channel_backup:'):
|
if data.lower().startswith('channel_backup:'):
|
||||||
self.import_channel_backup(data)
|
self.import_channel_backup(data)
|
||||||
return
|
return
|
||||||
# else if the user scanned an offline signed tx
|
# else if the user scanned an offline signed tx
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ from typing import NamedTuple, Sequence, Optional, List, TYPE_CHECKING
|
|||||||
from PyQt5.QtGui import QFontMetrics, QFont
|
from PyQt5.QtGui import QFontMetrics, QFont
|
||||||
|
|
||||||
from electrum import bitcoin
|
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.transaction import PartialTxOutput
|
||||||
from electrum.bitcoin import opcodes, construct_script
|
from electrum.bitcoin import opcodes, construct_script
|
||||||
from electrum.logging import Logger
|
from electrum.logging import Logger
|
||||||
@@ -153,7 +153,7 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger):
|
|||||||
if len(lines) == 1:
|
if len(lines) == 1:
|
||||||
data = lines[0]
|
data = lines[0]
|
||||||
# try bip21 URI
|
# try bip21 URI
|
||||||
if data.startswith("bitcoin:"):
|
if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'):
|
||||||
self.win.pay_to_URI(data)
|
self.win.pay_to_URI(data)
|
||||||
return
|
return
|
||||||
# try LN invoice
|
# try LN invoice
|
||||||
@@ -255,7 +255,7 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger):
|
|||||||
|
|
||||||
def qr_input(self):
|
def qr_input(self):
|
||||||
data = super(PayToEdit,self).qr_input()
|
data = super(PayToEdit,self).qr_input()
|
||||||
if data.startswith("bitcoin:"):
|
if data.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'):
|
||||||
self.win.pay_to_URI(data)
|
self.win.pay_to_URI(data)
|
||||||
# TODO: update fee
|
# TODO: update fee
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
#_ud = re.compile('%([0-9a-hA-H]{2})', re.MULTILINE)
|
||||||
#urldecode = lambda x: _ud.sub(lambda m: chr(int(m.group(1), 16)), x)
|
#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
|
class InvalidBitcoinURI(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
@@ -843,7 +849,7 @@ def parse_URI(uri: str, on_pr: Callable = None, *, loop=None) -> dict:
|
|||||||
return {'address': uri}
|
return {'address': uri}
|
||||||
|
|
||||||
u = urllib.parse.urlparse(uri)
|
u = urllib.parse.urlparse(uri)
|
||||||
if u.scheme != 'bitcoin':
|
if u.scheme.lower() != BITCOIN_BIP21_URI_SCHEME:
|
||||||
raise InvalidBitcoinURI("Not a bitcoin URI")
|
raise InvalidBitcoinURI("Not a bitcoin URI")
|
||||||
address = u.path
|
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)}")
|
raise Exception(f"illegal key for URI: {repr(k)}")
|
||||||
v = urllib.parse.quote(v)
|
v = urllib.parse.quote(v)
|
||||||
query.append(f"{k}={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))
|
return str(urllib.parse.urlunparse(p))
|
||||||
|
|
||||||
|
|
||||||
def maybe_extract_bolt11_invoice(data: str) -> Optional[str]:
|
def maybe_extract_bolt11_invoice(data: str) -> Optional[str]:
|
||||||
data = data.strip() # whitespaces
|
data = data.strip() # whitespaces
|
||||||
data = data.lower()
|
data = data.lower()
|
||||||
if data.startswith('lightning:ln'):
|
if data.startswith(LIGHTNING_URI_SCHEME + ':ln'):
|
||||||
data = data[10:]
|
data = data[10:]
|
||||||
if data.startswith('ln'):
|
if data.startswith('ln'):
|
||||||
return data
|
return data
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ from electrum.wallet_db import WalletDB
|
|||||||
from electrum.wallet import Wallet
|
from electrum.wallet import Wallet
|
||||||
from electrum.storage import WalletStorage
|
from electrum.storage import WalletStorage
|
||||||
from electrum.util import print_msg, print_stderr, json_encode, json_decode, UserCancelled
|
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.commands import get_parser, known_commands, Commands, config_variables
|
||||||
from electrum import daemon
|
from electrum import daemon
|
||||||
from electrum import keystore
|
from electrum import keystore
|
||||||
@@ -343,7 +343,7 @@ def main():
|
|||||||
# check uri
|
# check uri
|
||||||
uri = config_options.get('url')
|
uri = config_options.get('url')
|
||||||
if uri:
|
if uri:
|
||||||
if not uri.startswith('bitcoin:'):
|
if not uri.lower().startswith(BITCOIN_BIP21_URI_SCHEME + ':'):
|
||||||
print_stderr('unknown command:', uri)
|
print_stderr('unknown command:', uri)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user