2323 from .lnutil import LnFeatures
2424
2525
26- class LnInvoiceException (Exception ): pass
27- class LnDecodeException ( LnInvoiceException ): pass
28- class LnEncodeException ( LnInvoiceException ): pass
26+ class BOLT11InvoiceException (Exception ): pass
27+ class BOLT11DecodeException ( BOLT11InvoiceException ): pass
28+ class BOLT11EncodeException ( BOLT11InvoiceException ): pass
2929
3030
3131# BOLT #11:
@@ -68,7 +68,7 @@ def unshorten_amount(amount) -> Decimal:
6868 # A reader SHOULD fail if `amount` contains a non-digit, or is followed by
6969 # anything except a `multiplier` in the table above.
7070 if not re .fullmatch ("\\ d+[pnum]?" , str (amount )):
71- raise LnDecodeException ("Invalid amount '{}'" .format (amount ))
71+ raise BOLT11DecodeException ("Invalid amount '{}'" .format (amount ))
7272
7373 if unit in units .keys ():
7474 return Decimal (amount [:- 1 ]) / units [unit ]
@@ -88,7 +88,7 @@ def encode_fallback_addr(fallback: str, net: Type[AbstractNet]) -> Sequence[int]
8888 elif addrtype == net .ADDRTYPE_P2SH :
8989 wver = 18
9090 else :
91- raise LnEncodeException (f"Unknown address type { addrtype } for { net } " )
91+ raise BOLT11EncodeException (f"Unknown address type { addrtype } for { net } " )
9292 wprog = addr
9393 data5 = convertbits (wprog , 8 , 5 )
9494 assert data5 is not None
@@ -156,7 +156,7 @@ def pull_tagged(data5: bytearray) -> Tuple[str, Sequence[int]]:
156156 return ret
157157
158158
159- def lnencode (addr : 'LnAddr ' , privkey ) -> str :
159+ def encode_bolt11_invoice (addr : 'BOLT11Addr ' , privkey ) -> str :
160160 if addr .amount :
161161 amount = addr .net .BOLT11_HRP + shorten_amount (addr .amount )
162162 else :
@@ -185,7 +185,7 @@ def lnencode(addr: 'LnAddr', privkey) -> str:
185185 # A writer MUST NOT include more than one `d`, `h`, `n` or `x` fields,
186186 if k in ('d' , 'h' , 'n' , 'x' , 'p' , 's' , '9' ):
187187 if k in tags_set :
188- raise LnEncodeException ("Duplicate '{}' tag" .format (k ))
188+ raise BOLT11EncodeException ("Duplicate '{}' tag" .format (k ))
189189
190190 if k == 'r' :
191191 route = bytearray ()
@@ -228,7 +228,7 @@ def lnencode(addr: 'LnAddr', privkey) -> str:
228228 data5 += tagged5 ('9' , feature_bits )
229229 else :
230230 # FIXME: Support unknown tags?
231- raise LnEncodeException ("Unknown tag {}" .format (k ))
231+ raise BOLT11EncodeException ("Unknown tag {}" .format (k ))
232232
233233 tags_set .add (k )
234234
@@ -254,7 +254,7 @@ def lnencode(addr: 'LnAddr', privkey) -> str:
254254 return bech32_encode (segwit_addr .Encoding .BECH32 , hrp , data5 )
255255
256256
257- class LnAddr ( object ) :
257+ class BOLT11Addr :
258258 def __init__ (self , * , paymenthash : bytes = None , amount = None , net : Type [AbstractNet ] = None , tags = None , date = None ,
259259 payment_secret : bytes = None ):
260260 self .date = int (time .time ()) if not date else int (date )
@@ -274,16 +274,16 @@ def amount(self) -> Optional[Decimal]:
274274 @amount .setter
275275 def amount (self , value ):
276276 if not (isinstance (value , Decimal ) or value is None ):
277- raise LnInvoiceException (f"amount must be Decimal or None, not { value !r} " )
277+ raise BOLT11InvoiceException (f"amount must be Decimal or None, not { value !r} " )
278278 if value is None :
279279 self ._amount = None
280280 return
281281 assert isinstance (value , Decimal )
282282 if value .is_nan () or not (0 <= value <= TOTAL_COIN_SUPPLY_LIMIT_IN_BTC ):
283- raise LnInvoiceException (f"amount is out-of-bounds: { value !r} BTC" )
283+ raise BOLT11InvoiceException (f"amount is out-of-bounds: { value !r} BTC" )
284284 if value * 10 ** 12 % 10 :
285285 # max resolution is millisatoshi
286- raise LnInvoiceException (f"Cannot encode { value !r} : too many decimal places" )
286+ raise BOLT11InvoiceException (f"Cannot encode { value !r} : too many decimal places" )
287287 self ._amount = value
288288
289289 def get_amount_sat (self ) -> Optional [Decimal ]:
@@ -332,7 +332,8 @@ def get_features(self) -> 'LnFeatures':
332332 def validate_and_compare_features (self , myfeatures : 'LnFeatures' ) -> None :
333333 """Raises IncompatibleOrInsaneFeatures.
334334
335- note: these checks are not done by the parser (in lndecode), as then when we started requiring a new feature,
335+ note: these checks are not done by the parser (in decode_bolt11_invoice),
336+ as then when we started requiring a new feature,
336337 old saved already paid invoices could no longer be parsed.
337338 """
338339 from .lnutil import validate_features , ln_compare_features
@@ -341,7 +342,7 @@ def validate_and_compare_features(self, myfeatures: 'LnFeatures') -> None:
341342 ln_compare_features (myfeatures .for_invoice (), invoice_features )
342343
343344 def __str__ (self ):
344- return "LnAddr [{}, amount={}{} tags=[{}]]" .format (
345+ return "BOLT11Addr [{}, amount={}{} tags=[{}]]" .format (
345346 hexlify (self .pubkey .serialize ()).decode ('utf-8' ) if self .pubkey else None ,
346347 self .amount , self .net .BOLT11_HRP ,
347348 ", " .join ([k + '=' + str (v ) for k , v in self .tags ])
@@ -403,37 +404,37 @@ def serialize(self):
403404 return self .pubkey .get_public_key_bytes (True )
404405
405406
406- def lndecode (invoice : str , * , verbose = False , net = None ) -> LnAddr :
407- """Parses a string into an LnAddr object.
408- Can raise LnDecodeException or IncompatibleOrInsaneFeatures.
407+ def decode_bolt11_invoice (invoice : str , * , verbose = False , net = None ) -> BOLT11Addr :
408+ """Parses a string into a BOLT11Addr object.
409+ Can raise BOLT11DecodeException or IncompatibleOrInsaneFeatures.
409410 """
410411 if net is None :
411412 net = constants .net
412413 decoded_bech32 = bech32_decode (invoice , ignore_long_length = True )
413414 hrp = decoded_bech32 .hrp
414415 data5 = decoded_bech32 .data # "5" as in list of 5-bit integers
415416 if decoded_bech32 .encoding is None :
416- raise LnDecodeException ("Bad bech32 checksum" )
417+ raise BOLT11DecodeException ("Bad bech32 checksum" )
417418 if decoded_bech32 .encoding != segwit_addr .Encoding .BECH32 :
418- raise LnDecodeException ("Bad bech32 encoding: must be using vanilla BECH32" )
419+ raise BOLT11DecodeException ("Bad bech32 encoding: must be using vanilla BECH32" )
419420
420421 # BOLT #11:
421422 #
422423 # A reader MUST fail if it does not understand the `prefix`.
423424 if not hrp .startswith ('ln' ):
424- raise LnDecodeException ("Does not start with ln" )
425+ raise BOLT11DecodeException ("Does not start with ln" )
425426
426427 if not hrp [2 :].startswith (net .BOLT11_HRP ):
427- raise LnDecodeException (f"Wrong Lightning invoice HRP { hrp [2 :]} , should be { net .BOLT11_HRP } " )
428+ raise BOLT11DecodeException (f"Wrong Lightning invoice HRP { hrp [2 :]} , should be { net .BOLT11_HRP } " )
428429
429430 # Final signature 65 bytes, split it off.
430431 if len (data5 ) < 65 * 8 // 5 :
431- raise LnDecodeException ("Too short to contain signature" )
432+ raise BOLT11DecodeException ("Too short to contain signature" )
432433 sigdecoded = bytes (convertbits (data5 [- 65 * 8 // 5 :], 5 , 8 , False ))
433434 data5 = data5 [:- 65 * 8 // 5 ]
434435 data5_remaining = bytearray (data5 ) # note: bytearray is faster than list of ints
435436
436- addr = LnAddr ()
437+ addr = BOLT11Addr ()
437438 addr .pubkey = None
438439 addr .net = net
439440
@@ -580,7 +581,7 @@ def lndecode(invoice: str, *, verbose=False, net=None) -> LnAddr:
580581 # A reader MUST use the `n` field to validate the signature instead of
581582 # performing signature recovery if a valid `n` field is provided.
582583 if not ecc .ECPubkey (addr .pubkey ).ecdsa_verify (sigdecoded [:64 ], hrp_hash ):
583- raise LnDecodeException ("bad signature" )
584+ raise BOLT11DecodeException ("bad signature" )
584585 pubkey_copy = addr .pubkey
585586
586587 class WrappedBytesKey :
0 commit comments