refactor: lndgrpc, update grpcs file, use types and enums, LookupInvoiceV2 (#3469)

This commit is contained in:
dni ⚡ 2025-11-10 15:07:00 +01:00 committed by GitHub
parent c84d1b66c6
commit 691b7ad055
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 4781 additions and 704 deletions

View file

@ -2,7 +2,7 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: invoices.proto
# Protobuf Python Version: 5.28.1
# Protobuf Python Version: 5.29.0
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
@ -12,8 +12,8 @@ from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
5,
28,
1,
29,
0,
'',
'invoices.proto'
)
@ -24,6 +24,7 @@ _sym_db = _symbol_database.Default()
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as lightning__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0einvoices.proto\x12\x0binvoicesrpc\x1a\x0flightning.proto\"(\n\x10\x43\x61ncelInvoiceMsg\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\"\x13\n\x11\x43\x61ncelInvoiceResp\"\xe4\x01\n\x15\x41\x64\x64HoldInvoiceRequest\x12\x0c\n\x04memo\x18\x01 \x01(\t\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\x12\r\n\x05value\x18\x03 \x01(\x03\x12\x12\n\nvalue_msat\x18\n \x01(\x03\x12\x18\n\x10\x64\x65scription_hash\x18\x04 \x01(\x0c\x12\x0e\n\x06\x65xpiry\x18\x05 \x01(\x03\x12\x15\n\rfallback_addr\x18\x06 \x01(\t\x12\x13\n\x0b\x63ltv_expiry\x18\x07 \x01(\x04\x12%\n\x0broute_hints\x18\x08 \x03(\x0b\x32\x10.lnrpc.RouteHint\x12\x0f\n\x07private\x18\t \x01(\x08\"V\n\x12\x41\x64\x64HoldInvoiceResp\x12\x17\n\x0fpayment_request\x18\x01 \x01(\t\x12\x11\n\tadd_index\x18\x02 \x01(\x04\x12\x14\n\x0cpayment_addr\x18\x03 \x01(\x0c\"$\n\x10SettleInvoiceMsg\x12\x10\n\x08preimage\x18\x01 \x01(\x0c\"\x13\n\x11SettleInvoiceResp\"5\n\x1dSubscribeSingleInvoiceRequest\x12\x0e\n\x06r_hash\x18\x02 \x01(\x0cJ\x04\x08\x01\x10\x02\"\x99\x01\n\x10LookupInvoiceMsg\x12\x16\n\x0cpayment_hash\x18\x01 \x01(\x0cH\x00\x12\x16\n\x0cpayment_addr\x18\x02 \x01(\x0cH\x00\x12\x10\n\x06set_id\x18\x03 \x01(\x0cH\x00\x12\x34\n\x0flookup_modifier\x18\x04 \x01(\x0e\x32\x1b.invoicesrpc.LookupModifierB\r\n\x0binvoice_ref\".\n\nCircuitKey\x12\x0f\n\x07\x63han_id\x18\x01 \x01(\x04\x12\x0f\n\x07htlc_id\x18\x02 \x01(\x04\"\xdd\x02\n\x11HtlcModifyRequest\x12\x1f\n\x07invoice\x18\x01 \x01(\x0b\x32\x0e.lnrpc.Invoice\x12\x36\n\x15\x65xit_htlc_circuit_key\x18\x02 \x01(\x0b\x32\x17.invoicesrpc.CircuitKey\x12\x15\n\rexit_htlc_amt\x18\x03 \x01(\x04\x12\x18\n\x10\x65xit_htlc_expiry\x18\x04 \x01(\r\x12\x16\n\x0e\x63urrent_height\x18\x05 \x01(\r\x12\x64\n\x1d\x65xit_htlc_wire_custom_records\x18\x06 \x03(\x0b\x32=.invoicesrpc.HtlcModifyRequest.ExitHtlcWireCustomRecordsEntry\x1a@\n\x1e\x45xitHtlcWireCustomRecordsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"z\n\x12HtlcModifyResponse\x12,\n\x0b\x63ircuit_key\x18\x01 \x01(\x0b\x32\x17.invoicesrpc.CircuitKey\x12\x15\n\x08\x61mt_paid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x12\n\ncancel_set\x18\x03 \x01(\x08\x42\x0b\n\t_amt_paid*D\n\x0eLookupModifier\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x11\n\rHTLC_SET_ONLY\x10\x01\x12\x12\n\x0eHTLC_SET_BLANK\x10\x02\x32\xf0\x03\n\x08Invoices\x12V\n\x16SubscribeSingleInvoice\x12*.invoicesrpc.SubscribeSingleInvoiceRequest\x1a\x0e.lnrpc.Invoice0\x01\x12N\n\rCancelInvoice\x12\x1d.invoicesrpc.CancelInvoiceMsg\x1a\x1e.invoicesrpc.CancelInvoiceResp\x12U\n\x0e\x41\x64\x64HoldInvoice\x12\".invoicesrpc.AddHoldInvoiceRequest\x1a\x1f.invoicesrpc.AddHoldInvoiceResp\x12N\n\rSettleInvoice\x12\x1d.invoicesrpc.SettleInvoiceMsg\x1a\x1e.invoicesrpc.SettleInvoiceResp\x12@\n\x0fLookupInvoiceV2\x12\x1d.invoicesrpc.LookupInvoiceMsg\x1a\x0e.lnrpc.Invoice\x12S\n\x0cHtlcModifier\x12\x1f.invoicesrpc.HtlcModifyResponse\x1a\x1e.invoicesrpc.HtlcModifyRequest(\x01\x30\x01\x42\x33Z1github.com/lightningnetwork/lnd/lnrpc/invoicesrpcb\x06proto3')
_globals = globals()

View file

@ -0,0 +1,130 @@
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as _lightning_pb2
from google.protobuf.internal import containers as _containers
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
DESCRIPTOR: _descriptor.FileDescriptor
class LookupModifier(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
DEFAULT: _ClassVar[LookupModifier]
HTLC_SET_ONLY: _ClassVar[LookupModifier]
HTLC_SET_BLANK: _ClassVar[LookupModifier]
DEFAULT: LookupModifier
HTLC_SET_ONLY: LookupModifier
HTLC_SET_BLANK: LookupModifier
class CancelInvoiceMsg(_message.Message):
__slots__ = ("payment_hash",)
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
payment_hash: bytes
def __init__(self, payment_hash: _Optional[bytes] = ...) -> None: ...
class CancelInvoiceResp(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class AddHoldInvoiceRequest(_message.Message):
__slots__ = ("memo", "hash", "value", "value_msat", "description_hash", "expiry", "fallback_addr", "cltv_expiry", "route_hints", "private")
MEMO_FIELD_NUMBER: _ClassVar[int]
HASH_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
VALUE_MSAT_FIELD_NUMBER: _ClassVar[int]
DESCRIPTION_HASH_FIELD_NUMBER: _ClassVar[int]
EXPIRY_FIELD_NUMBER: _ClassVar[int]
FALLBACK_ADDR_FIELD_NUMBER: _ClassVar[int]
CLTV_EXPIRY_FIELD_NUMBER: _ClassVar[int]
ROUTE_HINTS_FIELD_NUMBER: _ClassVar[int]
PRIVATE_FIELD_NUMBER: _ClassVar[int]
memo: str
hash: bytes
value: int
value_msat: int
description_hash: bytes
expiry: int
fallback_addr: str
cltv_expiry: int
route_hints: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.RouteHint]
private: bool
def __init__(self, memo: _Optional[str] = ..., hash: _Optional[bytes] = ..., value: _Optional[int] = ..., value_msat: _Optional[int] = ..., description_hash: _Optional[bytes] = ..., expiry: _Optional[int] = ..., fallback_addr: _Optional[str] = ..., cltv_expiry: _Optional[int] = ..., route_hints: _Optional[_Iterable[_Union[_lightning_pb2.RouteHint, _Mapping]]] = ..., private: bool = ...) -> None: ...
class AddHoldInvoiceResp(_message.Message):
__slots__ = ("payment_request", "add_index", "payment_addr")
PAYMENT_REQUEST_FIELD_NUMBER: _ClassVar[int]
ADD_INDEX_FIELD_NUMBER: _ClassVar[int]
PAYMENT_ADDR_FIELD_NUMBER: _ClassVar[int]
payment_request: str
add_index: int
payment_addr: bytes
def __init__(self, payment_request: _Optional[str] = ..., add_index: _Optional[int] = ..., payment_addr: _Optional[bytes] = ...) -> None: ...
class SettleInvoiceMsg(_message.Message):
__slots__ = ("preimage",)
PREIMAGE_FIELD_NUMBER: _ClassVar[int]
preimage: bytes
def __init__(self, preimage: _Optional[bytes] = ...) -> None: ...
class SettleInvoiceResp(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class SubscribeSingleInvoiceRequest(_message.Message):
__slots__ = ("r_hash",)
R_HASH_FIELD_NUMBER: _ClassVar[int]
r_hash: bytes
def __init__(self, r_hash: _Optional[bytes] = ...) -> None: ...
class LookupInvoiceMsg(_message.Message):
__slots__ = ("payment_hash", "payment_addr", "set_id", "lookup_modifier")
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
PAYMENT_ADDR_FIELD_NUMBER: _ClassVar[int]
SET_ID_FIELD_NUMBER: _ClassVar[int]
LOOKUP_MODIFIER_FIELD_NUMBER: _ClassVar[int]
payment_hash: bytes
payment_addr: bytes
set_id: bytes
lookup_modifier: LookupModifier
def __init__(self, payment_hash: _Optional[bytes] = ..., payment_addr: _Optional[bytes] = ..., set_id: _Optional[bytes] = ..., lookup_modifier: _Optional[_Union[LookupModifier, str]] = ...) -> None: ...
class CircuitKey(_message.Message):
__slots__ = ("chan_id", "htlc_id")
CHAN_ID_FIELD_NUMBER: _ClassVar[int]
HTLC_ID_FIELD_NUMBER: _ClassVar[int]
chan_id: int
htlc_id: int
def __init__(self, chan_id: _Optional[int] = ..., htlc_id: _Optional[int] = ...) -> None: ...
class HtlcModifyRequest(_message.Message):
__slots__ = ("invoice", "exit_htlc_circuit_key", "exit_htlc_amt", "exit_htlc_expiry", "current_height", "exit_htlc_wire_custom_records")
class ExitHtlcWireCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
INVOICE_FIELD_NUMBER: _ClassVar[int]
EXIT_HTLC_CIRCUIT_KEY_FIELD_NUMBER: _ClassVar[int]
EXIT_HTLC_AMT_FIELD_NUMBER: _ClassVar[int]
EXIT_HTLC_EXPIRY_FIELD_NUMBER: _ClassVar[int]
CURRENT_HEIGHT_FIELD_NUMBER: _ClassVar[int]
EXIT_HTLC_WIRE_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
invoice: _lightning_pb2.Invoice
exit_htlc_circuit_key: CircuitKey
exit_htlc_amt: int
exit_htlc_expiry: int
current_height: int
exit_htlc_wire_custom_records: _containers.ScalarMap[int, bytes]
def __init__(self, invoice: _Optional[_Union[_lightning_pb2.Invoice, _Mapping]] = ..., exit_htlc_circuit_key: _Optional[_Union[CircuitKey, _Mapping]] = ..., exit_htlc_amt: _Optional[int] = ..., exit_htlc_expiry: _Optional[int] = ..., current_height: _Optional[int] = ..., exit_htlc_wire_custom_records: _Optional[_Mapping[int, bytes]] = ...) -> None: ...
class HtlcModifyResponse(_message.Message):
__slots__ = ("circuit_key", "amt_paid", "cancel_set")
CIRCUIT_KEY_FIELD_NUMBER: _ClassVar[int]
AMT_PAID_FIELD_NUMBER: _ClassVar[int]
CANCEL_SET_FIELD_NUMBER: _ClassVar[int]
circuit_key: CircuitKey
amt_paid: int
cancel_set: bool
def __init__(self, circuit_key: _Optional[_Union[CircuitKey, _Mapping]] = ..., amt_paid: _Optional[int] = ..., cancel_set: bool = ...) -> None: ...

View file

@ -6,7 +6,7 @@ import warnings
import lnbits.wallets.lnd_grpc_files.invoices_pb2 as invoices__pb2
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as lightning__pb2
GRPC_GENERATED_VERSION = '1.68.1'
GRPC_GENERATED_VERSION = '1.69.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ import warnings
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as lightning__pb2
GRPC_GENERATED_VERSION = '1.68.1'
GRPC_GENERATED_VERSION = '1.69.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
@ -237,6 +237,11 @@ class LightningStub(object):
request_serializer=lightning__pb2.InvoiceSubscription.SerializeToString,
response_deserializer=lightning__pb2.Invoice.FromString,
_registered_method=True)
self.DeleteCanceledInvoice = channel.unary_unary(
'/lnrpc.Lightning/DeleteCanceledInvoice',
request_serializer=lightning__pb2.DelCanceledInvoiceReq.SerializeToString,
response_deserializer=lightning__pb2.DelCanceledInvoiceResp.FromString,
_registered_method=True)
self.DecodePayReq = channel.unary_unary(
'/lnrpc.Lightning/DecodePayReq',
request_serializer=lightning__pb2.PayReqString.SerializeToString,
@ -749,10 +754,10 @@ class LightningServicer(object):
def SendPaymentSync(self, request, context):
"""
SendPaymentSync is the synchronous non-streaming version of SendPayment.
This RPC is intended to be consumed by clients of the REST proxy.
Additionally, this RPC expects the destination's public key and the payment
hash (if any) to be encoded as hex strings.
Deprecated, use routerrpc.SendPaymentV2. SendPaymentSync is the synchronous
non-streaming version of SendPayment. This RPC is intended to be consumed by
clients of the REST proxy. Additionally, this RPC expects the destination's
public key and the payment hash (if any) to be encoded as hex strings.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
@ -772,8 +777,9 @@ class LightningServicer(object):
def SendToRouteSync(self, request, context):
"""
SendToRouteSync is a synchronous version of SendToRoute. It Will block
until the payment either fails or succeeds.
Deprecated, use routerrpc.SendToRouteV2. SendToRouteSync is a synchronous
version of SendToRoute. It Will block until the payment either fails or
succeeds.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
@ -829,6 +835,15 @@ class LightningServicer(object):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def DeleteCanceledInvoice(self, request, context):
"""lncli: `deletecanceledinvoice`
DeleteCanceledInvoice removes a canceled invoice from the database. If the
invoice is not in the canceled state, an error will be returned.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def DecodePayReq(self, request, context):
"""lncli: `decodepayreq`
DecodePayReq takes an encoded payment request string and attempts to decode
@ -1100,9 +1115,10 @@ class LightningServicer(object):
def CheckMacaroonPermissions(self, request, context):
"""
CheckMacaroonPermissions checks whether a request follows the constraints
imposed on the macaroon and that the macaroon is authorized to follow the
provided permissions.
CheckMacaroonPermissions checks whether the provided macaroon contains all
the provided permissions. If the macaroon is valid (e.g. all caveats are
satisfied), and all permissions provided in the request are met, then
this RPC returns true.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
@ -1356,6 +1372,11 @@ def add_LightningServicer_to_server(servicer, server):
request_deserializer=lightning__pb2.InvoiceSubscription.FromString,
response_serializer=lightning__pb2.Invoice.SerializeToString,
),
'DeleteCanceledInvoice': grpc.unary_unary_rpc_method_handler(
servicer.DeleteCanceledInvoice,
request_deserializer=lightning__pb2.DelCanceledInvoiceReq.FromString,
response_serializer=lightning__pb2.DelCanceledInvoiceResp.SerializeToString,
),
'DecodePayReq': grpc.unary_unary_rpc_method_handler(
servicer.DecodePayReq,
request_deserializer=lightning__pb2.PayReqString.FromString,
@ -2539,6 +2560,33 @@ class Lightning(object):
metadata,
_registered_method=True)
@staticmethod
def DeleteCanceledInvoice(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/lnrpc.Lightning/DeleteCanceledInvoice',
lightning__pb2.DelCanceledInvoiceReq.SerializeToString,
lightning__pb2.DelCanceledInvoiceResp.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def DecodePayReq(request,
target,

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,623 @@
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as _lightning_pb2
from google.protobuf.internal import containers as _containers
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
DESCRIPTOR: _descriptor.FileDescriptor
class FailureDetail(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
UNKNOWN: _ClassVar[FailureDetail]
NO_DETAIL: _ClassVar[FailureDetail]
ONION_DECODE: _ClassVar[FailureDetail]
LINK_NOT_ELIGIBLE: _ClassVar[FailureDetail]
ON_CHAIN_TIMEOUT: _ClassVar[FailureDetail]
HTLC_EXCEEDS_MAX: _ClassVar[FailureDetail]
INSUFFICIENT_BALANCE: _ClassVar[FailureDetail]
INCOMPLETE_FORWARD: _ClassVar[FailureDetail]
HTLC_ADD_FAILED: _ClassVar[FailureDetail]
FORWARDS_DISABLED: _ClassVar[FailureDetail]
INVOICE_CANCELED: _ClassVar[FailureDetail]
INVOICE_UNDERPAID: _ClassVar[FailureDetail]
INVOICE_EXPIRY_TOO_SOON: _ClassVar[FailureDetail]
INVOICE_NOT_OPEN: _ClassVar[FailureDetail]
MPP_INVOICE_TIMEOUT: _ClassVar[FailureDetail]
ADDRESS_MISMATCH: _ClassVar[FailureDetail]
SET_TOTAL_MISMATCH: _ClassVar[FailureDetail]
SET_TOTAL_TOO_LOW: _ClassVar[FailureDetail]
SET_OVERPAID: _ClassVar[FailureDetail]
UNKNOWN_INVOICE: _ClassVar[FailureDetail]
INVALID_KEYSEND: _ClassVar[FailureDetail]
MPP_IN_PROGRESS: _ClassVar[FailureDetail]
CIRCULAR_ROUTE: _ClassVar[FailureDetail]
class PaymentState(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
IN_FLIGHT: _ClassVar[PaymentState]
SUCCEEDED: _ClassVar[PaymentState]
FAILED_TIMEOUT: _ClassVar[PaymentState]
FAILED_NO_ROUTE: _ClassVar[PaymentState]
FAILED_ERROR: _ClassVar[PaymentState]
FAILED_INCORRECT_PAYMENT_DETAILS: _ClassVar[PaymentState]
FAILED_INSUFFICIENT_BALANCE: _ClassVar[PaymentState]
class ResolveHoldForwardAction(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
SETTLE: _ClassVar[ResolveHoldForwardAction]
FAIL: _ClassVar[ResolveHoldForwardAction]
RESUME: _ClassVar[ResolveHoldForwardAction]
RESUME_MODIFIED: _ClassVar[ResolveHoldForwardAction]
class ChanStatusAction(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
ENABLE: _ClassVar[ChanStatusAction]
DISABLE: _ClassVar[ChanStatusAction]
AUTO: _ClassVar[ChanStatusAction]
UNKNOWN: FailureDetail
NO_DETAIL: FailureDetail
ONION_DECODE: FailureDetail
LINK_NOT_ELIGIBLE: FailureDetail
ON_CHAIN_TIMEOUT: FailureDetail
HTLC_EXCEEDS_MAX: FailureDetail
INSUFFICIENT_BALANCE: FailureDetail
INCOMPLETE_FORWARD: FailureDetail
HTLC_ADD_FAILED: FailureDetail
FORWARDS_DISABLED: FailureDetail
INVOICE_CANCELED: FailureDetail
INVOICE_UNDERPAID: FailureDetail
INVOICE_EXPIRY_TOO_SOON: FailureDetail
INVOICE_NOT_OPEN: FailureDetail
MPP_INVOICE_TIMEOUT: FailureDetail
ADDRESS_MISMATCH: FailureDetail
SET_TOTAL_MISMATCH: FailureDetail
SET_TOTAL_TOO_LOW: FailureDetail
SET_OVERPAID: FailureDetail
UNKNOWN_INVOICE: FailureDetail
INVALID_KEYSEND: FailureDetail
MPP_IN_PROGRESS: FailureDetail
CIRCULAR_ROUTE: FailureDetail
IN_FLIGHT: PaymentState
SUCCEEDED: PaymentState
FAILED_TIMEOUT: PaymentState
FAILED_NO_ROUTE: PaymentState
FAILED_ERROR: PaymentState
FAILED_INCORRECT_PAYMENT_DETAILS: PaymentState
FAILED_INSUFFICIENT_BALANCE: PaymentState
SETTLE: ResolveHoldForwardAction
FAIL: ResolveHoldForwardAction
RESUME: ResolveHoldForwardAction
RESUME_MODIFIED: ResolveHoldForwardAction
ENABLE: ChanStatusAction
DISABLE: ChanStatusAction
AUTO: ChanStatusAction
class SendPaymentRequest(_message.Message):
__slots__ = ("dest", "amt", "payment_hash", "final_cltv_delta", "payment_request", "timeout_seconds", "fee_limit_sat", "outgoing_chan_id", "cltv_limit", "route_hints", "dest_custom_records", "amt_msat", "fee_limit_msat", "last_hop_pubkey", "allow_self_payment", "dest_features", "max_parts", "no_inflight_updates", "outgoing_chan_ids", "payment_addr", "max_shard_size_msat", "amp", "time_pref", "cancelable", "first_hop_custom_records")
class DestCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
class FirstHopCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
DEST_FIELD_NUMBER: _ClassVar[int]
AMT_FIELD_NUMBER: _ClassVar[int]
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
FINAL_CLTV_DELTA_FIELD_NUMBER: _ClassVar[int]
PAYMENT_REQUEST_FIELD_NUMBER: _ClassVar[int]
TIMEOUT_SECONDS_FIELD_NUMBER: _ClassVar[int]
FEE_LIMIT_SAT_FIELD_NUMBER: _ClassVar[int]
OUTGOING_CHAN_ID_FIELD_NUMBER: _ClassVar[int]
CLTV_LIMIT_FIELD_NUMBER: _ClassVar[int]
ROUTE_HINTS_FIELD_NUMBER: _ClassVar[int]
DEST_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
FEE_LIMIT_MSAT_FIELD_NUMBER: _ClassVar[int]
LAST_HOP_PUBKEY_FIELD_NUMBER: _ClassVar[int]
ALLOW_SELF_PAYMENT_FIELD_NUMBER: _ClassVar[int]
DEST_FEATURES_FIELD_NUMBER: _ClassVar[int]
MAX_PARTS_FIELD_NUMBER: _ClassVar[int]
NO_INFLIGHT_UPDATES_FIELD_NUMBER: _ClassVar[int]
OUTGOING_CHAN_IDS_FIELD_NUMBER: _ClassVar[int]
PAYMENT_ADDR_FIELD_NUMBER: _ClassVar[int]
MAX_SHARD_SIZE_MSAT_FIELD_NUMBER: _ClassVar[int]
AMP_FIELD_NUMBER: _ClassVar[int]
TIME_PREF_FIELD_NUMBER: _ClassVar[int]
CANCELABLE_FIELD_NUMBER: _ClassVar[int]
FIRST_HOP_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
dest: bytes
amt: int
payment_hash: bytes
final_cltv_delta: int
payment_request: str
timeout_seconds: int
fee_limit_sat: int
outgoing_chan_id: int
cltv_limit: int
route_hints: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.RouteHint]
dest_custom_records: _containers.ScalarMap[int, bytes]
amt_msat: int
fee_limit_msat: int
last_hop_pubkey: bytes
allow_self_payment: bool
dest_features: _containers.RepeatedScalarFieldContainer[_lightning_pb2.FeatureBit]
max_parts: int
no_inflight_updates: bool
outgoing_chan_ids: _containers.RepeatedScalarFieldContainer[int]
payment_addr: bytes
max_shard_size_msat: int
amp: bool
time_pref: float
cancelable: bool
first_hop_custom_records: _containers.ScalarMap[int, bytes]
def __init__(self, dest: _Optional[bytes] = ..., amt: _Optional[int] = ..., payment_hash: _Optional[bytes] = ..., final_cltv_delta: _Optional[int] = ..., payment_request: _Optional[str] = ..., timeout_seconds: _Optional[int] = ..., fee_limit_sat: _Optional[int] = ..., outgoing_chan_id: _Optional[int] = ..., cltv_limit: _Optional[int] = ..., route_hints: _Optional[_Iterable[_Union[_lightning_pb2.RouteHint, _Mapping]]] = ..., dest_custom_records: _Optional[_Mapping[int, bytes]] = ..., amt_msat: _Optional[int] = ..., fee_limit_msat: _Optional[int] = ..., last_hop_pubkey: _Optional[bytes] = ..., allow_self_payment: bool = ..., dest_features: _Optional[_Iterable[_Union[_lightning_pb2.FeatureBit, str]]] = ..., max_parts: _Optional[int] = ..., no_inflight_updates: bool = ..., outgoing_chan_ids: _Optional[_Iterable[int]] = ..., payment_addr: _Optional[bytes] = ..., max_shard_size_msat: _Optional[int] = ..., amp: bool = ..., time_pref: _Optional[float] = ..., cancelable: bool = ..., first_hop_custom_records: _Optional[_Mapping[int, bytes]] = ...) -> None: ...
class TrackPaymentRequest(_message.Message):
__slots__ = ("payment_hash", "no_inflight_updates")
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
NO_INFLIGHT_UPDATES_FIELD_NUMBER: _ClassVar[int]
payment_hash: bytes
no_inflight_updates: bool
def __init__(self, payment_hash: _Optional[bytes] = ..., no_inflight_updates: bool = ...) -> None: ...
class TrackPaymentsRequest(_message.Message):
__slots__ = ("no_inflight_updates",)
NO_INFLIGHT_UPDATES_FIELD_NUMBER: _ClassVar[int]
no_inflight_updates: bool
def __init__(self, no_inflight_updates: bool = ...) -> None: ...
class RouteFeeRequest(_message.Message):
__slots__ = ("dest", "amt_sat", "payment_request", "timeout")
DEST_FIELD_NUMBER: _ClassVar[int]
AMT_SAT_FIELD_NUMBER: _ClassVar[int]
PAYMENT_REQUEST_FIELD_NUMBER: _ClassVar[int]
TIMEOUT_FIELD_NUMBER: _ClassVar[int]
dest: bytes
amt_sat: int
payment_request: str
timeout: int
def __init__(self, dest: _Optional[bytes] = ..., amt_sat: _Optional[int] = ..., payment_request: _Optional[str] = ..., timeout: _Optional[int] = ...) -> None: ...
class RouteFeeResponse(_message.Message):
__slots__ = ("routing_fee_msat", "time_lock_delay", "failure_reason")
ROUTING_FEE_MSAT_FIELD_NUMBER: _ClassVar[int]
TIME_LOCK_DELAY_FIELD_NUMBER: _ClassVar[int]
FAILURE_REASON_FIELD_NUMBER: _ClassVar[int]
routing_fee_msat: int
time_lock_delay: int
failure_reason: _lightning_pb2.PaymentFailureReason
def __init__(self, routing_fee_msat: _Optional[int] = ..., time_lock_delay: _Optional[int] = ..., failure_reason: _Optional[_Union[_lightning_pb2.PaymentFailureReason, str]] = ...) -> None: ...
class SendToRouteRequest(_message.Message):
__slots__ = ("payment_hash", "route", "skip_temp_err", "first_hop_custom_records")
class FirstHopCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
ROUTE_FIELD_NUMBER: _ClassVar[int]
SKIP_TEMP_ERR_FIELD_NUMBER: _ClassVar[int]
FIRST_HOP_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
payment_hash: bytes
route: _lightning_pb2.Route
skip_temp_err: bool
first_hop_custom_records: _containers.ScalarMap[int, bytes]
def __init__(self, payment_hash: _Optional[bytes] = ..., route: _Optional[_Union[_lightning_pb2.Route, _Mapping]] = ..., skip_temp_err: bool = ..., first_hop_custom_records: _Optional[_Mapping[int, bytes]] = ...) -> None: ...
class SendToRouteResponse(_message.Message):
__slots__ = ("preimage", "failure")
PREIMAGE_FIELD_NUMBER: _ClassVar[int]
FAILURE_FIELD_NUMBER: _ClassVar[int]
preimage: bytes
failure: _lightning_pb2.Failure
def __init__(self, preimage: _Optional[bytes] = ..., failure: _Optional[_Union[_lightning_pb2.Failure, _Mapping]] = ...) -> None: ...
class ResetMissionControlRequest(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class ResetMissionControlResponse(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class QueryMissionControlRequest(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class QueryMissionControlResponse(_message.Message):
__slots__ = ("pairs",)
PAIRS_FIELD_NUMBER: _ClassVar[int]
pairs: _containers.RepeatedCompositeFieldContainer[PairHistory]
def __init__(self, pairs: _Optional[_Iterable[_Union[PairHistory, _Mapping]]] = ...) -> None: ...
class XImportMissionControlRequest(_message.Message):
__slots__ = ("pairs", "force")
PAIRS_FIELD_NUMBER: _ClassVar[int]
FORCE_FIELD_NUMBER: _ClassVar[int]
pairs: _containers.RepeatedCompositeFieldContainer[PairHistory]
force: bool
def __init__(self, pairs: _Optional[_Iterable[_Union[PairHistory, _Mapping]]] = ..., force: bool = ...) -> None: ...
class XImportMissionControlResponse(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class PairHistory(_message.Message):
__slots__ = ("node_from", "node_to", "history")
NODE_FROM_FIELD_NUMBER: _ClassVar[int]
NODE_TO_FIELD_NUMBER: _ClassVar[int]
HISTORY_FIELD_NUMBER: _ClassVar[int]
node_from: bytes
node_to: bytes
history: PairData
def __init__(self, node_from: _Optional[bytes] = ..., node_to: _Optional[bytes] = ..., history: _Optional[_Union[PairData, _Mapping]] = ...) -> None: ...
class PairData(_message.Message):
__slots__ = ("fail_time", "fail_amt_sat", "fail_amt_msat", "success_time", "success_amt_sat", "success_amt_msat")
FAIL_TIME_FIELD_NUMBER: _ClassVar[int]
FAIL_AMT_SAT_FIELD_NUMBER: _ClassVar[int]
FAIL_AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
SUCCESS_TIME_FIELD_NUMBER: _ClassVar[int]
SUCCESS_AMT_SAT_FIELD_NUMBER: _ClassVar[int]
SUCCESS_AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
fail_time: int
fail_amt_sat: int
fail_amt_msat: int
success_time: int
success_amt_sat: int
success_amt_msat: int
def __init__(self, fail_time: _Optional[int] = ..., fail_amt_sat: _Optional[int] = ..., fail_amt_msat: _Optional[int] = ..., success_time: _Optional[int] = ..., success_amt_sat: _Optional[int] = ..., success_amt_msat: _Optional[int] = ...) -> None: ...
class GetMissionControlConfigRequest(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class GetMissionControlConfigResponse(_message.Message):
__slots__ = ("config",)
CONFIG_FIELD_NUMBER: _ClassVar[int]
config: MissionControlConfig
def __init__(self, config: _Optional[_Union[MissionControlConfig, _Mapping]] = ...) -> None: ...
class SetMissionControlConfigRequest(_message.Message):
__slots__ = ("config",)
CONFIG_FIELD_NUMBER: _ClassVar[int]
config: MissionControlConfig
def __init__(self, config: _Optional[_Union[MissionControlConfig, _Mapping]] = ...) -> None: ...
class SetMissionControlConfigResponse(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class MissionControlConfig(_message.Message):
__slots__ = ("half_life_seconds", "hop_probability", "weight", "maximum_payment_results", "minimum_failure_relax_interval", "model", "apriori", "bimodal")
class ProbabilityModel(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
APRIORI: _ClassVar[MissionControlConfig.ProbabilityModel]
BIMODAL: _ClassVar[MissionControlConfig.ProbabilityModel]
APRIORI: MissionControlConfig.ProbabilityModel
BIMODAL: MissionControlConfig.ProbabilityModel
HALF_LIFE_SECONDS_FIELD_NUMBER: _ClassVar[int]
HOP_PROBABILITY_FIELD_NUMBER: _ClassVar[int]
WEIGHT_FIELD_NUMBER: _ClassVar[int]
MAXIMUM_PAYMENT_RESULTS_FIELD_NUMBER: _ClassVar[int]
MINIMUM_FAILURE_RELAX_INTERVAL_FIELD_NUMBER: _ClassVar[int]
MODEL_FIELD_NUMBER: _ClassVar[int]
APRIORI_FIELD_NUMBER: _ClassVar[int]
BIMODAL_FIELD_NUMBER: _ClassVar[int]
half_life_seconds: int
hop_probability: float
weight: float
maximum_payment_results: int
minimum_failure_relax_interval: int
model: MissionControlConfig.ProbabilityModel
apriori: AprioriParameters
bimodal: BimodalParameters
def __init__(self, half_life_seconds: _Optional[int] = ..., hop_probability: _Optional[float] = ..., weight: _Optional[float] = ..., maximum_payment_results: _Optional[int] = ..., minimum_failure_relax_interval: _Optional[int] = ..., model: _Optional[_Union[MissionControlConfig.ProbabilityModel, str]] = ..., apriori: _Optional[_Union[AprioriParameters, _Mapping]] = ..., bimodal: _Optional[_Union[BimodalParameters, _Mapping]] = ...) -> None: ...
class BimodalParameters(_message.Message):
__slots__ = ("node_weight", "scale_msat", "decay_time")
NODE_WEIGHT_FIELD_NUMBER: _ClassVar[int]
SCALE_MSAT_FIELD_NUMBER: _ClassVar[int]
DECAY_TIME_FIELD_NUMBER: _ClassVar[int]
node_weight: float
scale_msat: int
decay_time: int
def __init__(self, node_weight: _Optional[float] = ..., scale_msat: _Optional[int] = ..., decay_time: _Optional[int] = ...) -> None: ...
class AprioriParameters(_message.Message):
__slots__ = ("half_life_seconds", "hop_probability", "weight", "capacity_fraction")
HALF_LIFE_SECONDS_FIELD_NUMBER: _ClassVar[int]
HOP_PROBABILITY_FIELD_NUMBER: _ClassVar[int]
WEIGHT_FIELD_NUMBER: _ClassVar[int]
CAPACITY_FRACTION_FIELD_NUMBER: _ClassVar[int]
half_life_seconds: int
hop_probability: float
weight: float
capacity_fraction: float
def __init__(self, half_life_seconds: _Optional[int] = ..., hop_probability: _Optional[float] = ..., weight: _Optional[float] = ..., capacity_fraction: _Optional[float] = ...) -> None: ...
class QueryProbabilityRequest(_message.Message):
__slots__ = ("from_node", "to_node", "amt_msat")
FROM_NODE_FIELD_NUMBER: _ClassVar[int]
TO_NODE_FIELD_NUMBER: _ClassVar[int]
AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
from_node: bytes
to_node: bytes
amt_msat: int
def __init__(self, from_node: _Optional[bytes] = ..., to_node: _Optional[bytes] = ..., amt_msat: _Optional[int] = ...) -> None: ...
class QueryProbabilityResponse(_message.Message):
__slots__ = ("probability", "history")
PROBABILITY_FIELD_NUMBER: _ClassVar[int]
HISTORY_FIELD_NUMBER: _ClassVar[int]
probability: float
history: PairData
def __init__(self, probability: _Optional[float] = ..., history: _Optional[_Union[PairData, _Mapping]] = ...) -> None: ...
class BuildRouteRequest(_message.Message):
__slots__ = ("amt_msat", "final_cltv_delta", "outgoing_chan_id", "hop_pubkeys", "payment_addr", "first_hop_custom_records")
class FirstHopCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
FINAL_CLTV_DELTA_FIELD_NUMBER: _ClassVar[int]
OUTGOING_CHAN_ID_FIELD_NUMBER: _ClassVar[int]
HOP_PUBKEYS_FIELD_NUMBER: _ClassVar[int]
PAYMENT_ADDR_FIELD_NUMBER: _ClassVar[int]
FIRST_HOP_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
amt_msat: int
final_cltv_delta: int
outgoing_chan_id: int
hop_pubkeys: _containers.RepeatedScalarFieldContainer[bytes]
payment_addr: bytes
first_hop_custom_records: _containers.ScalarMap[int, bytes]
def __init__(self, amt_msat: _Optional[int] = ..., final_cltv_delta: _Optional[int] = ..., outgoing_chan_id: _Optional[int] = ..., hop_pubkeys: _Optional[_Iterable[bytes]] = ..., payment_addr: _Optional[bytes] = ..., first_hop_custom_records: _Optional[_Mapping[int, bytes]] = ...) -> None: ...
class BuildRouteResponse(_message.Message):
__slots__ = ("route",)
ROUTE_FIELD_NUMBER: _ClassVar[int]
route: _lightning_pb2.Route
def __init__(self, route: _Optional[_Union[_lightning_pb2.Route, _Mapping]] = ...) -> None: ...
class SubscribeHtlcEventsRequest(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class HtlcEvent(_message.Message):
__slots__ = ("incoming_channel_id", "outgoing_channel_id", "incoming_htlc_id", "outgoing_htlc_id", "timestamp_ns", "event_type", "forward_event", "forward_fail_event", "settle_event", "link_fail_event", "subscribed_event", "final_htlc_event")
class EventType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
UNKNOWN: _ClassVar[HtlcEvent.EventType]
SEND: _ClassVar[HtlcEvent.EventType]
RECEIVE: _ClassVar[HtlcEvent.EventType]
FORWARD: _ClassVar[HtlcEvent.EventType]
UNKNOWN: HtlcEvent.EventType
SEND: HtlcEvent.EventType
RECEIVE: HtlcEvent.EventType
FORWARD: HtlcEvent.EventType
INCOMING_CHANNEL_ID_FIELD_NUMBER: _ClassVar[int]
OUTGOING_CHANNEL_ID_FIELD_NUMBER: _ClassVar[int]
INCOMING_HTLC_ID_FIELD_NUMBER: _ClassVar[int]
OUTGOING_HTLC_ID_FIELD_NUMBER: _ClassVar[int]
TIMESTAMP_NS_FIELD_NUMBER: _ClassVar[int]
EVENT_TYPE_FIELD_NUMBER: _ClassVar[int]
FORWARD_EVENT_FIELD_NUMBER: _ClassVar[int]
FORWARD_FAIL_EVENT_FIELD_NUMBER: _ClassVar[int]
SETTLE_EVENT_FIELD_NUMBER: _ClassVar[int]
LINK_FAIL_EVENT_FIELD_NUMBER: _ClassVar[int]
SUBSCRIBED_EVENT_FIELD_NUMBER: _ClassVar[int]
FINAL_HTLC_EVENT_FIELD_NUMBER: _ClassVar[int]
incoming_channel_id: int
outgoing_channel_id: int
incoming_htlc_id: int
outgoing_htlc_id: int
timestamp_ns: int
event_type: HtlcEvent.EventType
forward_event: ForwardEvent
forward_fail_event: ForwardFailEvent
settle_event: SettleEvent
link_fail_event: LinkFailEvent
subscribed_event: SubscribedEvent
final_htlc_event: FinalHtlcEvent
def __init__(self, incoming_channel_id: _Optional[int] = ..., outgoing_channel_id: _Optional[int] = ..., incoming_htlc_id: _Optional[int] = ..., outgoing_htlc_id: _Optional[int] = ..., timestamp_ns: _Optional[int] = ..., event_type: _Optional[_Union[HtlcEvent.EventType, str]] = ..., forward_event: _Optional[_Union[ForwardEvent, _Mapping]] = ..., forward_fail_event: _Optional[_Union[ForwardFailEvent, _Mapping]] = ..., settle_event: _Optional[_Union[SettleEvent, _Mapping]] = ..., link_fail_event: _Optional[_Union[LinkFailEvent, _Mapping]] = ..., subscribed_event: _Optional[_Union[SubscribedEvent, _Mapping]] = ..., final_htlc_event: _Optional[_Union[FinalHtlcEvent, _Mapping]] = ...) -> None: ...
class HtlcInfo(_message.Message):
__slots__ = ("incoming_timelock", "outgoing_timelock", "incoming_amt_msat", "outgoing_amt_msat")
INCOMING_TIMELOCK_FIELD_NUMBER: _ClassVar[int]
OUTGOING_TIMELOCK_FIELD_NUMBER: _ClassVar[int]
INCOMING_AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
OUTGOING_AMT_MSAT_FIELD_NUMBER: _ClassVar[int]
incoming_timelock: int
outgoing_timelock: int
incoming_amt_msat: int
outgoing_amt_msat: int
def __init__(self, incoming_timelock: _Optional[int] = ..., outgoing_timelock: _Optional[int] = ..., incoming_amt_msat: _Optional[int] = ..., outgoing_amt_msat: _Optional[int] = ...) -> None: ...
class ForwardEvent(_message.Message):
__slots__ = ("info",)
INFO_FIELD_NUMBER: _ClassVar[int]
info: HtlcInfo
def __init__(self, info: _Optional[_Union[HtlcInfo, _Mapping]] = ...) -> None: ...
class ForwardFailEvent(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class SettleEvent(_message.Message):
__slots__ = ("preimage",)
PREIMAGE_FIELD_NUMBER: _ClassVar[int]
preimage: bytes
def __init__(self, preimage: _Optional[bytes] = ...) -> None: ...
class FinalHtlcEvent(_message.Message):
__slots__ = ("settled", "offchain")
SETTLED_FIELD_NUMBER: _ClassVar[int]
OFFCHAIN_FIELD_NUMBER: _ClassVar[int]
settled: bool
offchain: bool
def __init__(self, settled: bool = ..., offchain: bool = ...) -> None: ...
class SubscribedEvent(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class LinkFailEvent(_message.Message):
__slots__ = ("info", "wire_failure", "failure_detail", "failure_string")
INFO_FIELD_NUMBER: _ClassVar[int]
WIRE_FAILURE_FIELD_NUMBER: _ClassVar[int]
FAILURE_DETAIL_FIELD_NUMBER: _ClassVar[int]
FAILURE_STRING_FIELD_NUMBER: _ClassVar[int]
info: HtlcInfo
wire_failure: _lightning_pb2.Failure.FailureCode
failure_detail: FailureDetail
failure_string: str
def __init__(self, info: _Optional[_Union[HtlcInfo, _Mapping]] = ..., wire_failure: _Optional[_Union[_lightning_pb2.Failure.FailureCode, str]] = ..., failure_detail: _Optional[_Union[FailureDetail, str]] = ..., failure_string: _Optional[str] = ...) -> None: ...
class PaymentStatus(_message.Message):
__slots__ = ("state", "preimage", "htlcs")
STATE_FIELD_NUMBER: _ClassVar[int]
PREIMAGE_FIELD_NUMBER: _ClassVar[int]
HTLCS_FIELD_NUMBER: _ClassVar[int]
state: PaymentState
preimage: bytes
htlcs: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.HTLCAttempt]
def __init__(self, state: _Optional[_Union[PaymentState, str]] = ..., preimage: _Optional[bytes] = ..., htlcs: _Optional[_Iterable[_Union[_lightning_pb2.HTLCAttempt, _Mapping]]] = ...) -> None: ...
class CircuitKey(_message.Message):
__slots__ = ("chan_id", "htlc_id")
CHAN_ID_FIELD_NUMBER: _ClassVar[int]
HTLC_ID_FIELD_NUMBER: _ClassVar[int]
chan_id: int
htlc_id: int
def __init__(self, chan_id: _Optional[int] = ..., htlc_id: _Optional[int] = ...) -> None: ...
class ForwardHtlcInterceptRequest(_message.Message):
__slots__ = ("incoming_circuit_key", "incoming_amount_msat", "incoming_expiry", "payment_hash", "outgoing_requested_chan_id", "outgoing_amount_msat", "outgoing_expiry", "custom_records", "onion_blob", "auto_fail_height", "in_wire_custom_records")
class CustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
class InWireCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
INCOMING_CIRCUIT_KEY_FIELD_NUMBER: _ClassVar[int]
INCOMING_AMOUNT_MSAT_FIELD_NUMBER: _ClassVar[int]
INCOMING_EXPIRY_FIELD_NUMBER: _ClassVar[int]
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
OUTGOING_REQUESTED_CHAN_ID_FIELD_NUMBER: _ClassVar[int]
OUTGOING_AMOUNT_MSAT_FIELD_NUMBER: _ClassVar[int]
OUTGOING_EXPIRY_FIELD_NUMBER: _ClassVar[int]
CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
ONION_BLOB_FIELD_NUMBER: _ClassVar[int]
AUTO_FAIL_HEIGHT_FIELD_NUMBER: _ClassVar[int]
IN_WIRE_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
incoming_circuit_key: CircuitKey
incoming_amount_msat: int
incoming_expiry: int
payment_hash: bytes
outgoing_requested_chan_id: int
outgoing_amount_msat: int
outgoing_expiry: int
custom_records: _containers.ScalarMap[int, bytes]
onion_blob: bytes
auto_fail_height: int
in_wire_custom_records: _containers.ScalarMap[int, bytes]
def __init__(self, incoming_circuit_key: _Optional[_Union[CircuitKey, _Mapping]] = ..., incoming_amount_msat: _Optional[int] = ..., incoming_expiry: _Optional[int] = ..., payment_hash: _Optional[bytes] = ..., outgoing_requested_chan_id: _Optional[int] = ..., outgoing_amount_msat: _Optional[int] = ..., outgoing_expiry: _Optional[int] = ..., custom_records: _Optional[_Mapping[int, bytes]] = ..., onion_blob: _Optional[bytes] = ..., auto_fail_height: _Optional[int] = ..., in_wire_custom_records: _Optional[_Mapping[int, bytes]] = ...) -> None: ...
class ForwardHtlcInterceptResponse(_message.Message):
__slots__ = ("incoming_circuit_key", "action", "preimage", "failure_message", "failure_code", "in_amount_msat", "out_amount_msat", "out_wire_custom_records")
class OutWireCustomRecordsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: int
value: bytes
def __init__(self, key: _Optional[int] = ..., value: _Optional[bytes] = ...) -> None: ...
INCOMING_CIRCUIT_KEY_FIELD_NUMBER: _ClassVar[int]
ACTION_FIELD_NUMBER: _ClassVar[int]
PREIMAGE_FIELD_NUMBER: _ClassVar[int]
FAILURE_MESSAGE_FIELD_NUMBER: _ClassVar[int]
FAILURE_CODE_FIELD_NUMBER: _ClassVar[int]
IN_AMOUNT_MSAT_FIELD_NUMBER: _ClassVar[int]
OUT_AMOUNT_MSAT_FIELD_NUMBER: _ClassVar[int]
OUT_WIRE_CUSTOM_RECORDS_FIELD_NUMBER: _ClassVar[int]
incoming_circuit_key: CircuitKey
action: ResolveHoldForwardAction
preimage: bytes
failure_message: bytes
failure_code: _lightning_pb2.Failure.FailureCode
in_amount_msat: int
out_amount_msat: int
out_wire_custom_records: _containers.ScalarMap[int, bytes]
def __init__(self, incoming_circuit_key: _Optional[_Union[CircuitKey, _Mapping]] = ..., action: _Optional[_Union[ResolveHoldForwardAction, str]] = ..., preimage: _Optional[bytes] = ..., failure_message: _Optional[bytes] = ..., failure_code: _Optional[_Union[_lightning_pb2.Failure.FailureCode, str]] = ..., in_amount_msat: _Optional[int] = ..., out_amount_msat: _Optional[int] = ..., out_wire_custom_records: _Optional[_Mapping[int, bytes]] = ...) -> None: ...
class UpdateChanStatusRequest(_message.Message):
__slots__ = ("chan_point", "action")
CHAN_POINT_FIELD_NUMBER: _ClassVar[int]
ACTION_FIELD_NUMBER: _ClassVar[int]
chan_point: _lightning_pb2.ChannelPoint
action: ChanStatusAction
def __init__(self, chan_point: _Optional[_Union[_lightning_pb2.ChannelPoint, _Mapping]] = ..., action: _Optional[_Union[ChanStatusAction, str]] = ...) -> None: ...
class UpdateChanStatusResponse(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...
class AddAliasesRequest(_message.Message):
__slots__ = ("alias_maps",)
ALIAS_MAPS_FIELD_NUMBER: _ClassVar[int]
alias_maps: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.AliasMap]
def __init__(self, alias_maps: _Optional[_Iterable[_Union[_lightning_pb2.AliasMap, _Mapping]]] = ...) -> None: ...
class AddAliasesResponse(_message.Message):
__slots__ = ("alias_maps",)
ALIAS_MAPS_FIELD_NUMBER: _ClassVar[int]
alias_maps: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.AliasMap]
def __init__(self, alias_maps: _Optional[_Iterable[_Union[_lightning_pb2.AliasMap, _Mapping]]] = ...) -> None: ...
class DeleteAliasesRequest(_message.Message):
__slots__ = ("alias_maps",)
ALIAS_MAPS_FIELD_NUMBER: _ClassVar[int]
alias_maps: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.AliasMap]
def __init__(self, alias_maps: _Optional[_Iterable[_Union[_lightning_pb2.AliasMap, _Mapping]]] = ...) -> None: ...
class DeleteAliasesResponse(_message.Message):
__slots__ = ("alias_maps",)
ALIAS_MAPS_FIELD_NUMBER: _ClassVar[int]
alias_maps: _containers.RepeatedCompositeFieldContainer[_lightning_pb2.AliasMap]
def __init__(self, alias_maps: _Optional[_Iterable[_Union[_lightning_pb2.AliasMap, _Mapping]]] = ...) -> None: ...
class FindBaseAliasRequest(_message.Message):
__slots__ = ("alias",)
ALIAS_FIELD_NUMBER: _ClassVar[int]
alias: int
def __init__(self, alias: _Optional[int] = ...) -> None: ...
class FindBaseAliasResponse(_message.Message):
__slots__ = ("base",)
BASE_FIELD_NUMBER: _ClassVar[int]
base: int
def __init__(self, base: _Optional[int] = ...) -> None: ...

View file

@ -6,7 +6,7 @@ import warnings
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as lightning__pb2
import lnbits.wallets.lnd_grpc_files.router_pb2 as router__pb2
GRPC_GENERATED_VERSION = '1.68.1'
GRPC_GENERATED_VERSION = '1.69.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
@ -154,6 +154,11 @@ class RouterStub(object):
request_serializer=router__pb2.DeleteAliasesRequest.SerializeToString,
response_deserializer=router__pb2.DeleteAliasesResponse.FromString,
_registered_method=True)
self.XFindBaseLocalChanAlias = channel.unary_unary(
'/routerrpc.Router/XFindBaseLocalChanAlias',
request_serializer=router__pb2.FindBaseAliasRequest.SerializeToString,
response_deserializer=router__pb2.FindBaseAliasResponse.FromString,
_registered_method=True)
class RouterServicer(object):
@ -391,6 +396,15 @@ class RouterServicer(object):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def XFindBaseLocalChanAlias(self, request, context):
"""
XFindBaseLocalChanAlias is an experimental API that looks up the base scid
for a local chan alias that was registered during the current runtime.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_RouterServicer_to_server(servicer, server):
rpc_method_handlers = {
@ -494,6 +508,11 @@ def add_RouterServicer_to_server(servicer, server):
request_deserializer=router__pb2.DeleteAliasesRequest.FromString,
response_serializer=router__pb2.DeleteAliasesResponse.SerializeToString,
),
'XFindBaseLocalChanAlias': grpc.unary_unary_rpc_method_handler(
servicer.XFindBaseLocalChanAlias,
request_deserializer=router__pb2.FindBaseAliasRequest.FromString,
response_serializer=router__pb2.FindBaseAliasResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'routerrpc.Router', rpc_method_handlers)
@ -1063,3 +1082,30 @@ class Router(object):
timeout,
metadata,
_registered_method=True)
@staticmethod
def XFindBaseLocalChanAlias(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/routerrpc.Router/XFindBaseLocalChanAlias',
router__pb2.FindBaseAliasRequest.SerializeToString,
router__pb2.FindBaseAliasResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)

View file

@ -0,0 +1,12 @@
wget -q https://raw.githubusercontent.com/lightningnetwork/lnd/refs/heads/master/lnrpc/lightning.proto
wget -q https://raw.githubusercontent.com/lightningnetwork/lnd/refs/heads/master/lnrpc/routerrpc/router.proto
wget -q https://raw.githubusercontent.com/lightningnetwork/lnd/refs/heads/master/lnrpc/invoicesrpc/invoices.proto
uv run python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. --pyi_out=. lightning.proto
echo "generated lightning.proto"
uv run python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. --pyi_out=. router.proto
echo "generated router.proto"
uv run python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. --pyi_out=. invoices.proto
echo "generated invoices.proto"
rm lightning.proto router.proto invoices.proto

View file

@ -7,14 +7,33 @@ from os import environ
import grpc
from loguru import logger
import lnbits.wallets.lnd_grpc_files.invoices_pb2 as invoices
import lnbits.wallets.lnd_grpc_files.invoices_pb2_grpc as invoicesrpc
import lnbits.wallets.lnd_grpc_files.lightning_pb2 as ln
import lnbits.wallets.lnd_grpc_files.lightning_pb2_grpc as lnrpc
import lnbits.wallets.lnd_grpc_files.router_pb2 as router
from lnbits.helpers import normalize_endpoint
from lnbits.settings import settings
from lnbits.utils.crypto import random_secret_and_hash
from lnbits.wallets.lnd_grpc_files.invoices_pb2 import (
AddHoldInvoiceRequest,
AddHoldInvoiceResp,
CancelInvoiceMsg,
CancelInvoiceResp,
LookupInvoiceMsg,
SettleInvoiceMsg,
SettleInvoiceResp,
)
from lnbits.wallets.lnd_grpc_files.invoices_pb2_grpc import InvoicesStub
from lnbits.wallets.lnd_grpc_files.lightning_pb2 import (
AddInvoiceResponse,
ChannelBalanceRequest,
ChannelBalanceResponse,
Invoice,
InvoiceSubscription,
Payment,
PaymentFailureReason,
)
from lnbits.wallets.lnd_grpc_files.lightning_pb2_grpc import LightningStub
from lnbits.wallets.lnd_grpc_files.router_pb2 import (
SendPaymentRequest,
TrackPaymentRequest,
)
from lnbits.wallets.lnd_grpc_files.router_pb2_grpc import RouterStub
from .base import (
@ -32,6 +51,7 @@ from .macaroon import load_macaroon
def b64_to_bytes(checking_id: str) -> bytes:
return base64.b64decode(checking_id.replace("_", "/"))
@ -64,6 +84,10 @@ environ["GRPC_SSL_CIPHER_SUITES"] = "HIGH+ECDSA"
class LndWallet(Wallet):
rpc: LightningStub
router_rpc: RouterStub
invoices_rpc: InvoicesStub
features = [Feature.holdinvoice]
def __init__(self):
@ -99,9 +123,9 @@ class LndWallet(Wallet):
channel = grpc.aio.secure_channel(
f"{self.endpoint}:{self.port}", composite_creds
)
self.rpc = lnrpc.LightningStub(channel)
self.routerpc = RouterStub(channel)
self.invoicesrpc = invoicesrpc.InvoicesStub(channel)
self.rpc = LightningStub(channel)
self.router_rpc = RouterStub(channel)
self.invoices_rpc = InvoicesStub(channel)
def metadata_callback(self, _, callback):
callback([("macaroon", self.macaroon)], None)
@ -111,11 +135,12 @@ class LndWallet(Wallet):
async def status(self) -> StatusResponse:
try:
resp = await self.rpc.ChannelBalance(ln.ChannelBalanceRequest()) # type: ignore
req = ChannelBalanceRequest()
res: ChannelBalanceResponse = await self.rpc.ChannelBalance(req)
except Exception as exc:
return StatusResponse(f"Unable to connect, got: '{exc}'", 0)
return StatusResponse(None, resp.balance * 1000)
return StatusResponse(None, res.balance * 1000)
async def create_invoice(
self,
@ -125,18 +150,6 @@ class LndWallet(Wallet):
unhashed_description: bytes | None = None,
**kwargs,
) -> InvoiceResponse:
data: dict = {
"description_hash": b"",
"value": amount,
"private": True,
"memo": memo or "",
}
if kwargs.get("expiry"):
data["expiry"] = kwargs["expiry"]
if description_hash:
data["description_hash"] = description_hash
elif unhashed_description:
data["description_hash"] = sha256(unhashed_description).digest()
preimage = kwargs.get("preimage")
if preimage:
@ -144,82 +157,71 @@ class LndWallet(Wallet):
else:
preimage, payment_hash = random_secret_and_hash()
data["r_hash"] = bytes.fromhex(payment_hash)
data["r_preimage"] = bytes.fromhex(preimage)
invoice = Invoice(
value=amount,
private=True,
memo=memo or "",
r_hash=bytes.fromhex(payment_hash),
r_preimage=bytes.fromhex(preimage),
)
if kwargs.get("expiry"):
invoice.expiry = kwargs.get("expiry", 3600)
if description_hash:
invoice.description_hash = description_hash
elif unhashed_description:
invoice.description_hash = sha256(unhashed_description).digest()
try:
req = ln.Invoice(**data) # type: ignore
resp = await self.rpc.AddInvoice(req)
# response model
# {
# "r_hash": <bytes>,
# "payment_request": <string>,
# "add_index": <uint64>,
# "payment_addr": <bytes>,
# }
res: AddInvoiceResponse = await self.rpc.AddInvoice(invoice)
except Exception as exc:
logger.warning(exc)
return InvoiceResponse(ok=False, error_message=str(exc))
checking_id = bytes_to_hex(resp.r_hash)
payment_request = str(resp.payment_request)
return InvoiceResponse(
ok=True,
checking_id=checking_id,
payment_request=payment_request,
checking_id=bytes_to_hex(res.r_hash),
payment_request=res.payment_request,
preimage=preimage,
)
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
# fee_limit_fixed = ln.FeeLimit(fixed=fee_limit_msat // 1000)
req = router.SendPaymentRequest( # type: ignore
req = SendPaymentRequest(
payment_request=bolt11,
fee_limit_msat=fee_limit_msat,
timeout_seconds=30,
no_inflight_updates=True,
)
try:
resp = await self.routerpc.SendPaymentV2(req).read()
res: Payment = await self.router_rpc.SendPaymentV2(req).read()
except Exception as exc:
logger.warning(exc)
return PaymentResponse(error_message=str(exc))
# PaymentStatus from https://github.com/lightningnetwork/lnd/blob/master/channeldb/payments.go#L178
statuses = {
0: None, # NON_EXISTENT
1: None, # IN_FLIGHT
2: True, # SUCCEEDED
3: False, # FAILED
}
failure_reasons = {
0: "Payment failed: No error given.",
1: "Payment failed: Payment timed out.",
2: "Payment failed: No route to destination.",
3: "Payment failed: Error.",
4: "Payment failed: Incorrect payment details.",
5: "Payment failed: Insufficient balance.",
}
fee_msat = None
preimage = None
error_message = None
checking_id = None
if statuses[resp.status] is True: # SUCCEEDED
fee_msat = -resp.htlcs[-1].route.total_fees_msat
preimage = resp.payment_preimage
checking_id = resp.payment_hash
if res.status == Payment.PaymentStatus.SUCCEEDED:
return PaymentResponse(
ok=True, checking_id=checking_id, fee_msat=fee_msat, preimage=preimage
ok=True,
checking_id=res.payment_hash,
fee_msat=abs(res.fee_msat),
preimage=res.payment_preimage,
)
elif res.status == Payment.PaymentStatus.FAILED:
error_message = PaymentFailureReason.Name(res.failure_reason)
return PaymentResponse(
ok=False, error_message=f"Payment failed: {error_message}"
)
elif res.status == Payment.PaymentStatus.IN_FLIGHT:
return PaymentResponse(
ok=None,
checking_id=res.payment_hash,
error_message="Payment is IN_FLIGHT.",
)
elif statuses[resp.status] is False:
error_message = failure_reasons[resp.failure_reason]
return PaymentResponse(ok=False, error_message=error_message)
else:
return PaymentResponse(
ok=None,
checking_id=checking_id,
error_message="Payment in flight or non-existant.",
checking_id=res.payment_hash,
error_message="Payment is non-existant.",
)
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
@ -229,73 +231,80 @@ class LndWallet(Wallet):
# this may happen if we switch between backend wallets
# that use different checking_id formats
raise ValueError
resp = await self.rpc.LookupInvoice(ln.PaymentHash(r_hash=r_hash)) # type: ignore
if resp.settled:
return PaymentSuccessStatus(preimage=resp.r_preimage.hex())
if resp.state == "CANCELED":
return PaymentFailedStatus()
return PaymentPendingStatus()
except grpc.RpcError as exc:
logger.warning(exc)
req = LookupInvoiceMsg(payment_hash=r_hash)
res: Invoice = await self.invoices_rpc.LookupInvoiceV2(req)
except grpc.aio.AioRpcError as exc:
logger.warning(
f"LndWallet.get_invoice_status grpc exception: {exc.details()}"
)
return PaymentPendingStatus()
except Exception as exc:
logger.warning(exc)
logger.warning(f"LndWallet.get_invoice_status exception: {exc}")
return PaymentPendingStatus()
if res.settled:
return PaymentSuccessStatus(preimage=res.r_preimage.hex())
if res.state == Invoice.InvoiceState.CANCELED:
return PaymentFailedStatus()
return PaymentPendingStatus()
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
"""
This routine checks the payment status using routerpc.TrackPaymentV2.
This routine checks the payment status using router_rpc.TrackPaymentV2.
https://lightning.engineering/api-docs/api/lnd/router/track-payment-v2/#lnrpcpayment
"""
try:
r_hash = hex_to_bytes(checking_id)
if len(r_hash) != 32:
raise ValueError
except ValueError:
# this may happen if we switch between backend wallets
# that use different checking_id formats
logger.error(
f"LndWallet: Invalid checking_id ({checking_id}),"
" was the fundingsource changed? Returning pending status."
)
return PaymentPendingStatus()
# # HTLCAttempt.HTLCStatus:
# # https://github.com/lightningnetwork/lnd/blob/master/lnrpc/lightning.proto#L3641
# htlc_statuses = {
# 0: None, # IN_FLIGHT
# 1: True, # "SUCCEEDED"
# 2: False, # "FAILED"
# }
statuses = {
0: None, # NON_EXISTENT
1: None, # IN_FLIGHT
2: True, # SUCCEEDED
3: False, # FAILED
}
try:
resp = self.routerpc.TrackPaymentV2(
router.TrackPaymentRequest(payment_hash=r_hash) # type: ignore
req = TrackPaymentRequest(payment_hash=r_hash)
res = self.router_rpc.TrackPaymentV2(req)
except grpc.aio.AioRpcError as exc:
logger.error(
f"Payment Status grpc exception: {exc.details() or exc.code()}"
)
async for payment in resp:
if len(payment.htlcs) and statuses[payment.status]:
return PaymentSuccessStatus(
fee_msat=-payment.htlcs[-1].route.total_fees_msat,
preimage=bytes_to_hex(payment.htlcs[-1].preimage),
)
return PaymentStatus(statuses[payment.status])
except Exception: # most likely the payment wasn't found
return PaymentPendingStatus()
except Exception as exc: # most likely the payment wasn't found
logger.error(f"Payment Status exception: {exc}")
return PaymentPendingStatus()
try:
async for payment in res:
if payment.status == Payment.PaymentStatus.SUCCEEDED:
return PaymentSuccessStatus(
fee_msat=abs(payment.fee_msat),
preimage=payment.payment_preimage,
)
elif payment.status == Payment.PaymentStatus.FAILED:
logger.info(f"LND Payment failed: {payment.failure_reason}")
return PaymentFailedStatus()
elif payment.status == Payment.PaymentStatus.IN_FLIGHT:
logger.info(f"LND Payment in flight: {checking_id}")
return PaymentPendingStatus()
except grpc.aio.AioRpcError as exc:
logger.error(
f"Payment Status grpc exception: {exc.details() or exc.code()}"
)
return PaymentPendingStatus()
logger.info(f"LND Payment non-existent: {checking_id}")
return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while settings.lnbits_running:
try:
request = ln.InvoiceSubscription() # type: ignore
async for i in self.rpc.SubscribeInvoices(request):
req = InvoiceSubscription()
async for i in self.rpc.SubscribeInvoices(req):
if not i.settled:
continue
checking_id = bytes_to_hex(i.r_hash)
yield checking_id
except Exception as exc:
@ -314,35 +323,35 @@ class LndWallet(Wallet):
unhashed_description: bytes | None = None,
**kwargs,
) -> InvoiceResponse:
data: dict = {
"description_hash": b"",
"value": amount,
"hash": hex_to_bytes(payment_hash),
"private": True,
"memo": memo or "",
}
hold_invoice = AddHoldInvoiceRequest(
value=amount,
hash=hex_to_bytes(payment_hash),
private=True,
memo=memo or "",
)
if kwargs.get("expiry"):
data["expiry"] = kwargs["expiry"]
hold_invoice.expiry = kwargs.get("expiry", 3600)
if description_hash:
data["description_hash"] = description_hash
hold_invoice.description_hash = description_hash
elif unhashed_description:
data["description_hash"] = sha256(unhashed_description).digest()
hold_invoice.description_hash = sha256(unhashed_description).digest()
try:
req = invoices.AddHoldInvoiceRequest(**data) # type: ignore
res = await self.invoicesrpc.AddHoldInvoice(req)
res: AddHoldInvoiceResp = await self.invoices_rpc.AddHoldInvoice(
hold_invoice
)
logger.debug(f"AddHoldInvoice response: {res}")
except Exception as exc:
logger.warning(exc)
error_message = str(exc)
return InvoiceResponse(ok=False, error_message=error_message)
return InvoiceResponse(ok=False, error_message=str(exc))
return InvoiceResponse(
ok=True, checking_id=payment_hash, payment_request=str(res.payment_request)
ok=True, checking_id=payment_hash, payment_request=res.payment_request
)
async def settle_hold_invoice(self, preimage: str) -> InvoiceResponse:
try:
req = invoices.SettleInvoiceMsg(preimage=hex_to_bytes(preimage)) # type: ignore
await self.invoicesrpc.SettleInvoice(req)
req = SettleInvoiceMsg(preimage=hex_to_bytes(preimage))
res: SettleInvoiceResp = await self.invoices_rpc.SettleInvoice(req)
logger.debug(f"SettleInvoice response: {res}")
except grpc.aio.AioRpcError as exc:
return InvoiceResponse(
ok=False, error_message=exc.details() or "unknown grpc exception"
@ -354,8 +363,8 @@ class LndWallet(Wallet):
async def cancel_hold_invoice(self, payment_hash: str) -> InvoiceResponse:
try:
req = invoices.CancelInvoiceMsg(payment_hash=hex_to_bytes(payment_hash)) # type: ignore
res = await self.invoicesrpc.CancelInvoice(req)
req = CancelInvoiceMsg(payment_hash=hex_to_bytes(payment_hash))
res: CancelInvoiceResp = await self.invoices_rpc.CancelInvoice(req)
logger.debug(f"CancelInvoice response: {res}")
except Exception as exc:
logger.warning(exc)

View file

@ -684,7 +684,7 @@
"response_type": "data",
"response": {}
},
"routerpc": {
"router_rpc": {
"method": "lnbits.wallets.lnd_grpc_files.router_pb2_grpc.RouterStub.__new__",
"request_type": "function",
"response_type": "data",
@ -766,7 +766,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "one HTLCs",
"response": {
@ -779,6 +779,7 @@
"response_type": "data",
"response": {
"status": 2,
"fee_msat": 50,
"htlcs": [
{
"route": {
@ -806,6 +807,7 @@
"response_type": "data",
"response": {
"status": 2,
"fee_msat": 50,
"htlcs": [
{
"route": {
@ -892,7 +894,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "No error given.",
"response": {
@ -1076,7 +1078,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "RPC error.",
"response": {
@ -1144,7 +1146,7 @@
},
"lndrpc": {
"rpc": [],
"routerpc": []
"router_rpc": []
}
}
},
@ -1238,11 +1240,17 @@
"response_type": "data",
"response": {}
},
"routerpc": {
"router_rpc": {
"method": "lnbits.wallets.lnd_grpc_files.router_pb2_grpc.RouterStub.__new__",
"request_type": "function",
"response_type": "data",
"response": {}
},
"invoices_rpc": {
"method": "lnbits.wallets.lnd_grpc_files.invoices_pb2_grpc.InvoicesStub.__new__",
"request_type": "function",
"response_type": "data",
"response": {}
}
}
},
@ -1315,20 +1323,25 @@
]
},
"lndrpc": {
"routerpc": [
"rpc": [
{
"response": {}
}
],
"rpc": [
"router_rpc": [
{
"response": {}
}
],
"invoices_rpc": [
{
"response": {
"LookupInvoice": {
"LookupInvoiceV2": {
"request_type": "async-function",
"request_data": {
"klass": "lnbits.wallets.lnd_grpc_files.lightning_pb2.PaymentHash",
"klass": "lnbits.wallets.lnd_grpc_files.invoices_pb2.LookupInvoiceMsg",
"kwargs": {
"__eval__:r_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
"__eval__:payment_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
}
},
"response_type": "data",
@ -1573,25 +1586,31 @@
]
},
"lndrpc": {
"routerpc": [
"rpc": [
{
"response": {}
}
],
"rpc": [
"router_rpc": [
{
"response": {}
}
],
"invoices_rpc": [
{
"description": "not settled",
"response": {
"LookupInvoice": {
"LookupInvoiceV2": {
"request_type": "async-function",
"request_data": {
"klass": "lnbits.wallets.lnd_grpc_files.lightning_pb2.PaymentHash",
"klass": "lnbits.wallets.lnd_grpc_files.invoices_pb2.LookupInvoiceMsg",
"kwargs": {
"__eval__:r_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
"__eval__:payment_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
}
},
"response_type": "data",
"response": {
"state": 0,
"settled": false
}
}
@ -1600,12 +1619,12 @@
{
"description": "rpc error",
"response": {
"LookupInvoice": {
"LookupInvoiceV2": {
"request_type": "async-function",
"request_data": {
"klass": "lnbits.wallets.lnd_grpc_files.lightning_pb2.PaymentHash",
"klass": "lnbits.wallets.lnd_grpc_files.invoices_pb2.LookupInvoiceMsg",
"kwargs": {
"__eval__:r_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
"__eval__:payment_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
}
},
"response_type": "exception",
@ -1620,12 +1639,12 @@
{
"description": "rpc error",
"response": {
"LookupInvoice": {
"LookupInvoiceV2": {
"request_type": "async-function",
"request_data": {
"klass": "lnbits.wallets.lnd_grpc_files.lightning_pb2.PaymentHash",
"klass": "lnbits.wallets.lnd_grpc_files.invoices_pb2.LookupInvoiceMsg",
"kwargs": {
"__eval__:r_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
"__eval__:payment_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
}
},
"response_type": "exception",
@ -1688,7 +1707,7 @@
]
},
"lndrpc": {
"routerpc": [
"router_rpc": [
{
"response": {}
}
@ -1776,7 +1795,7 @@
]
},
"lndrpc": {
"routerpc": [],
"router_rpc": [],
"rpc": []
}
}
@ -1825,11 +1844,17 @@
"response_type": "data",
"response": {}
},
"routerpc": {
"router_rpc": {
"method": "lnbits.wallets.lnd_grpc_files.router_pb2_grpc.RouterStub.__new__",
"request_type": "function",
"response_type": "data",
"response": {}
},
"invoices_rpc": {
"method": "lnbits.wallets.lnd_grpc_files.invoices_pb2_grpc.InvoicesStub.__new__",
"request_type": "function",
"response_type": "data",
"response": {}
}
}
},
@ -1905,7 +1930,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "two HTLC",
"response": {
@ -1921,6 +1946,8 @@
"response": [
{
"status": 2,
"fee_msat": 50,
"payment_preimage": "0000000000000000000000000000000000000000000000000000000000000000",
"htlcs": [
{
"route": {
@ -1953,7 +1980,7 @@
"success": true,
"failed": false,
"pending": false,
"fee_msat": null,
"fee_msat": 50,
"preimage": null
},
"mocks": {
@ -1965,7 +1992,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "two HTLC",
"response": {
@ -1981,6 +2008,9 @@
"response": [
{
"status": 2,
"failure_reason": 1,
"fee_msat": 50,
"payment_preimage": null,
"htlcs": []
}
]
@ -2122,7 +2152,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "no HTLC",
"response": {
@ -2138,6 +2168,7 @@
"response": [
{
"status": 0,
"failure_reason": 1,
"htlcs": []
}
]
@ -2160,22 +2191,6 @@
}
}
},
{
"description": "no status",
"response": {
"TrackPaymentV2": {
"request_type": "function",
"request_data": {
"klass": "lnbits.wallets.lnd_grpc_files.router_pb2.TrackPaymentRequest",
"kwargs": {
"__eval__:payment_hash": "bytes.fromhex(\"c386d8e8d07342f2e39e189c8e6c57bb205bb373fe4e3a6f69404a8bb767b417\")"
}
},
"response_type": "__aiter__",
"response": [{}]
}
}
},
{
"description": "status: non-existend",
"response": {
@ -2317,7 +2332,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "no HTLC",
"response": {}
@ -2390,7 +2405,7 @@
"response": {}
}
],
"routerpc": [
"router_rpc": [
{
"description": "two HTLC",
"response": {
@ -2406,6 +2421,7 @@
"response": [
{
"status": 3,
"failure_reason": 1,
"htlcs": []
}
]