1818 _extract_message ,
1919)
2020from .types import (
21+ AddressInvoiceResponse ,
2122 AddressResponse ,
2223 ApiKeyResponse ,
2324 BackupPasskeyBeginResponse ,
2425 CreateWalletResponse ,
2526 CreateWebhookResponse ,
2627 InvoiceEvent ,
2728 InvoiceResponse ,
29+ PaymentEvent ,
2830 PaymentResponse ,
2931 RecoveryBackupResponse ,
3032 RecoveryRestoreResponse ,
@@ -137,6 +139,16 @@ def get(self, number: int) -> InvoiceResponse:
137139 """Get a single invoice by its number."""
138140 return parse (InvoiceResponse , self ._c ._get (f"/v1/invoices/{ number } " ))
139141
142+ def create_for_wallet (self , * , wallet_id : str , amount : int , reference : str | None = None , comment : str | None = None ) -> AddressInvoiceResponse :
143+ """Create an invoice for a specific wallet by ID. No authentication required."""
144+ body = to_camel ({"wallet_id" : wallet_id , "amount" : amount , "reference" : reference , "comment" : comment })
145+ return parse (AddressInvoiceResponse , self ._c ._post ("/v1/invoices/for-wallet" , body ))
146+
147+ def create_for_address (self , * , address : str , amount : int , tag : str | None = None , comment : str | None = None ) -> AddressInvoiceResponse :
148+ """Create an invoice for a Lightning address. No authentication required."""
149+ body = to_camel ({"address" : address , "amount" : amount , "tag" : tag , "comment" : comment })
150+ return parse (AddressInvoiceResponse , self ._c ._post ("/v1/invoices/for-address" , body ))
151+
140152 def watch (self , number : int , * , timeout : int | None = None ) -> Iterator [InvoiceEvent ]:
141153 """Stream SSE events until the invoice is settled or expires."""
142154 params = _qs ({"timeout" : timeout })
@@ -161,13 +173,13 @@ def watch(self, number: int, *, timeout: int | None = None) -> Iterator[InvoiceE
161173
162174
163175class PaymentsResource :
164- """Send sats to Lightning addresses or BOLT11 invoices."""
176+ """Send sats to Lightning addresses, LNURLs, or BOLT11 invoices."""
165177
166178 def __init__ (self , client : LnBot ) -> None :
167179 self ._c = client
168180
169181 def create (self , * , target : str , amount : int | None = None , idempotency_key : str | None = None , max_fee : int | None = None , reference : str | None = None ) -> PaymentResponse :
170- """Send a payment to *target* (Lightning address or BOLT11 invoice)."""
182+ """Send a payment to *target* (Lightning address, LNURL, or BOLT11 invoice)."""
171183 body = to_camel ({"target" : target , "amount" : amount , "idempotency_key" : idempotency_key , "max_fee" : max_fee , "reference" : reference })
172184 return parse (PaymentResponse , self ._c ._post ("/v1/payments" , body ))
173185
@@ -179,6 +191,28 @@ def get(self, number: int) -> PaymentResponse:
179191 """Get a single payment by its number."""
180192 return parse (PaymentResponse , self ._c ._get (f"/v1/payments/{ number } " ))
181193
194+ def watch (self , number : int , * , timeout : int | None = None ) -> Iterator [PaymentEvent ]:
195+ """Stream SSE events until the payment settles or fails."""
196+ params = _qs ({"timeout" : timeout })
197+ headers = {"Accept" : "text/event-stream" , "User-Agent" : _USER_AGENT }
198+ if self ._c ._api_key :
199+ headers ["Authorization" ] = f"Bearer { self ._c ._api_key } "
200+ with self ._c ._http .stream ("GET" , f"{ self ._c ._base_url } /v1/payments/{ number } /events" , params = params , headers = headers ) as resp :
201+ _raise_for_status (resp )
202+ event_type = ""
203+ for line in resp .iter_lines ():
204+ if line .startswith ("event:" ):
205+ event_type = line [6 :].strip ()
206+ elif line .startswith ("data:" ):
207+ raw = line [5 :].strip ()
208+ if raw and event_type :
209+ try :
210+ data = parse (PaymentResponse , json .loads (raw ))
211+ yield PaymentEvent (event = event_type , data = data ) # type: ignore[arg-type]
212+ except (json .JSONDecodeError , TypeError ):
213+ pass
214+ event_type = ""
215+
182216
183217class AddressesResource :
184218 """Lightning address management."""
@@ -397,6 +431,16 @@ async def get(self, number: int) -> InvoiceResponse:
397431 """Get a single invoice by its number."""
398432 return parse (InvoiceResponse , await self ._c ._get (f"/v1/invoices/{ number } " ))
399433
434+ async def create_for_wallet (self , * , wallet_id : str , amount : int , reference : str | None = None , comment : str | None = None ) -> AddressInvoiceResponse :
435+ """Create an invoice for a specific wallet by ID. No authentication required."""
436+ body = to_camel ({"wallet_id" : wallet_id , "amount" : amount , "reference" : reference , "comment" : comment })
437+ return parse (AddressInvoiceResponse , await self ._c ._post ("/v1/invoices/for-wallet" , body ))
438+
439+ async def create_for_address (self , * , address : str , amount : int , tag : str | None = None , comment : str | None = None ) -> AddressInvoiceResponse :
440+ """Create an invoice for a Lightning address. No authentication required."""
441+ body = to_camel ({"address" : address , "amount" : amount , "tag" : tag , "comment" : comment })
442+ return parse (AddressInvoiceResponse , await self ._c ._post ("/v1/invoices/for-address" , body ))
443+
400444 async def watch (self , number : int , * , timeout : int | None = None ) -> AsyncIterator [InvoiceEvent ]:
401445 """Stream SSE events until the invoice is settled or expires."""
402446 params = _qs ({"timeout" : timeout })
@@ -421,13 +465,13 @@ async def watch(self, number: int, *, timeout: int | None = None) -> AsyncIterat
421465
422466
423467class AsyncPaymentsResource :
424- """Send sats to Lightning addresses or BOLT11 invoices (async)."""
468+ """Send sats to Lightning addresses, LNURLs, or BOLT11 invoices (async)."""
425469
426470 def __init__ (self , client : AsyncLnBot ) -> None :
427471 self ._c = client
428472
429473 async def create (self , * , target : str , amount : int | None = None , idempotency_key : str | None = None , max_fee : int | None = None , reference : str | None = None ) -> PaymentResponse :
430- """Send a payment to *target* (Lightning address or BOLT11 invoice)."""
474+ """Send a payment to *target* (Lightning address, LNURL, or BOLT11 invoice)."""
431475 body = to_camel ({"target" : target , "amount" : amount , "idempotency_key" : idempotency_key , "max_fee" : max_fee , "reference" : reference })
432476 return parse (PaymentResponse , await self ._c ._post ("/v1/payments" , body ))
433477
@@ -439,6 +483,28 @@ async def get(self, number: int) -> PaymentResponse:
439483 """Get a single payment by its number."""
440484 return parse (PaymentResponse , await self ._c ._get (f"/v1/payments/{ number } " ))
441485
486+ async def watch (self , number : int , * , timeout : int | None = None ) -> AsyncIterator [PaymentEvent ]:
487+ """Stream SSE events until the payment settles or fails."""
488+ params = _qs ({"timeout" : timeout })
489+ headers = {"Accept" : "text/event-stream" , "User-Agent" : _USER_AGENT }
490+ if self ._c ._api_key :
491+ headers ["Authorization" ] = f"Bearer { self ._c ._api_key } "
492+ async with self ._c ._http .stream ("GET" , f"{ self ._c ._base_url } /v1/payments/{ number } /events" , params = params , headers = headers ) as resp :
493+ _raise_for_status (resp )
494+ event_type = ""
495+ async for line in resp .aiter_lines ():
496+ if line .startswith ("event:" ):
497+ event_type = line [6 :].strip ()
498+ elif line .startswith ("data:" ):
499+ raw = line [5 :].strip ()
500+ if raw and event_type :
501+ try :
502+ data = parse (PaymentResponse , json .loads (raw ))
503+ yield PaymentEvent (event = event_type , data = data ) # type: ignore[arg-type]
504+ except (json .JSONDecodeError , TypeError ):
505+ pass
506+ event_type = ""
507+
442508
443509class AsyncAddressesResource :
444510 """Lightning address management (async)."""
0 commit comments