pi: allow emaillike pi with 'lightning:' prefix
What changed, and why it matters
This commit lets Electrum recognize email-style payment identifiers (like user@domain.com) even when they have a 'lightning:' prefix in front. Previously, 'lightning:user@domain.com' would not be treated as a resolvable Lightning address. The change simply strips the prefix before checking if the rest looks like an email address. It is a small usability improvement, not a fix for a known security flaw.
No security action required. Treat as a normal feature/usability improvement. Reviewers may optionally verify that remove_uri_prefix handles case and whitespace consistently with other URI prefix stripping in the codebase.
Security signals we found
No memory-safety, cryptographic, or authorization changes
No input validation removed; only an additional accepted prefix form
No CVE, advisory, or security-related wording in commit message or diff
Change is additive and covered by unit tests
Evidence from the diff
The patch modifies PaymentIdentifier parsing so that remove_uri_prefix(text, prefix=LIGHTNING_URI_SCHEME) is applied before matching against RE_EMAIL. If the stripped string matches an email-like Lightning address, it is stored as the emaillike field and marked NEED_RESOLVE. Tests are added for ‘lightning:’ prefixed email-like, lnbc-like, lnurl-like, and onchain-like strings. No validation, trust, or resolution logic is changed.
Changed components
electrum/payment_identifier.pytests/test_payment_identifier.pyInspect captured patch +7 / −2
diff --git a/electrum/payment_identifier.py b/electrum/payment_identifier.py
index 72f8e53..130907a 100644
--- a/electrum/payment_identifier.py
+++ b/electrum/payment_identifier.py
@@ -293,9 +293,9 @@ class PaymentIdentifier(Logger):
self._type = PaymentIdentifierType.EMAILLIKE
self.emaillike = contact['address']
self.set_state(PaymentIdentifierState.NEED_RESOLVE)
- elif re.match(RE_EMAIL, text):
+ elif re.match(RE_EMAIL, (maybe_emaillike := remove_uri_prefix(text, prefix=LIGHTNING_URI_SCHEME))):
self._type = PaymentIdentifierType.EMAILLIKE
- self.emaillike = text
+ self.emaillike = maybe_emaillike
self.set_state(PaymentIdentifierState.NEED_RESOLVE)
elif re.match(RE_DOMAIN, text):
self._type = PaymentIdentifierType.DOMAINLIKE
diff --git a/tests/test_payment_identifier.py b/tests/test_payment_identifier.py
index e44f906..0f3a3bf 100644
--- a/tests/test_payment_identifier.py
+++ b/tests/test_payment_identifier.py
@@ -378,6 +378,11 @@ class TestPaymentIdentifier(ElectrumTestCase):
'lnbcuser@some.domain',
'lnurluser@some.domain',
'bc1quser@some.domain',
+ 'lightning:user@some.domain',
+ 'lightning:user@some.weird.but.valid.domain',
+ 'lightning:lnbcuser@some.domain',
+ 'lightning:lnurluser@some.domain',
+ 'lightning:bc1quser@some.domain',
)
for pi_str in email_pi_strings:
pi = PaymentIdentifier(None, pi_str)
Why this scored 21/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.