diff --git a/.env_sample b/.env_sample index 7c54efb..0682df0 100644 --- a/.env_sample +++ b/.env_sample @@ -71,8 +71,10 @@ bitcoind_zmq_block_port_testnet=28332 bitcoind_user=raspibolt bitcoind_pw=please_please_update_me_please -# lnd or clightning (clightning is not yet implemented!) -ln_node=lnd +# lnd_grpc, cln_grpc +# Please refer to the documentation for the install procedure +# for each implementation. +ln_node=lnd_grpc # LND macaroon in HEX format lnd_macaroon=0201036...2211 # LND certificate in HEX format @@ -81,6 +83,16 @@ lnd_grpc_ip=192.168.1.18 lnd_grpc_port=10009 lnd_rest_port=8080 +# cln grpc connection data, cert files are in .lightning data folder +# xxd -p -c2000 client.pem +cln_grpc_cert="2d2d2d2d2d...d2d2d2d0a" +# xxd -p -c2000 client-key.pem +cln_grpc_key="2d2d2d2d2d...d2d2d2d0a" +# xxd -p -c2000 ca.pem +cln_grpc_ca="2d2d2d2d2d...d2d2d2d0a" +cln_grpc_ip=127.0.0.1 +cln_grpc_port=9537 + # Tor url of this system. Ignored on platform Raspiblitz. # Defaults to empty string # np_tor_address="" diff --git a/app/models/lightning.py b/app/models/lightning.py index 348d2af..5543dbc 100644 --- a/app/models/lightning.py +++ b/app/models/lightning.py @@ -21,7 +21,7 @@ class InvoiceState(str, Enum): ACCEPTED = "accepted" @classmethod - def from_grpc(cls, id) -> "InvoiceState": + def from_lnd_grpc(cls, id) -> "InvoiceState": if id == 0: return InvoiceState.OPEN elif id == 1: @@ -33,6 +33,28 @@ class InvoiceState(str, Enum): else: raise NotImplementedError(f"InvoiceState {id} is not implemented") + @classmethod + def from_cln_json(cls, id) -> "InvoiceState": + if id == "unpaid": + return InvoiceState.OPEN + elif id == "paid": + return InvoiceState.SETTLED + elif id == "expired": + return InvoiceState.CANCELED + else: + raise NotImplementedError(f"InvoiceState {id} is not implemented") + + @classmethod + def from_cln_grpc(cls, i) -> "InvoiceState": + if i.status == 0: + return InvoiceState.OPEN + elif i.status == 1: + return InvoiceState.SETTLED + elif i.status == 2: + return InvoiceState.CANCELED + else: + raise NotImplementedError(f"InvoiceState {id} is not implemented") + class InvoiceHTLCState(str, Enum): ACCEPTED = "accepted" @@ -40,7 +62,7 @@ class InvoiceHTLCState(str, Enum): CANCELED = "canceled" @classmethod - def from_grpc(cls, id) -> "InvoiceHTLCState": + def from_lnd_grpc(cls, id) -> "InvoiceHTLCState": if id == 0: return InvoiceHTLCState.ACCEPTED elif id == 1: @@ -65,13 +87,21 @@ class FeeRevenue(BaseModel): ) @classmethod - def from_grpc(cls, fee_report) -> "FeeRevenue": + def from_lnd_grpc(cls, fee_report) -> "FeeRevenue": return cls( day=int(fee_report.day_fee_sum), week=int(fee_report.week_fee_sum), month=int(fee_report.month_fee_sum), ) + @classmethod + def from_cln_json(cls, fee_report) -> "FeeRevenue": + return cls( + day=int(fee_report["day_fee_sum"]), + week=int(fee_report["week_fee_sum"]), + month=int(fee_report["month_fee_sum"]), + ) + class ForwardSuccessEvent(BaseModel): timestamp_ns: int = Query( @@ -100,7 +130,7 @@ class ForwardSuccessEvent(BaseModel): ) @classmethod - def from_grpc(cls, evt) -> "ForwardSuccessEvent": + def from_lnd_grpc(cls, evt) -> "ForwardSuccessEvent": return cls( timestamp=int(evt.timestamp), chan_id_in=int(evt.chan_id_in), @@ -110,30 +140,63 @@ class ForwardSuccessEvent(BaseModel): fee_msat=int(evt.fee_msat), ) + @classmethod + def from_cln_json(cls, fwd) -> "ForwardSuccessEvent": + return cls( + timestamp_ns=fwd["resolved_time"], + chan_id_in=fwd["in_channel"], + chan_id_out=fwd["out_channel"], + amt_in_msat=fwd["in_msatoshi"], + amt_out_msat=fwd["out_msatoshi"], + fee_msat=fwd["fee"], + ) + + @classmethod + def from_cln_grpc(cls, fwd) -> "ForwardSuccessEvent": + return cls( + timestamp_ns=fwd.received_time, + chan_id_in=fwd.in_channel, + chan_id_out=fwd.out_channel, + amt_in_msat=fwd.in_msat.msat, + amt_out_msat=fwd.out_msat.msat, + fee_msat=fwd.fee_msat.msat, + ) + class Feature(BaseModel): name: str - is_required: bool - is_known: bool + is_required: Optional[bool] + is_known: Optional[bool] @classmethod - def from_grpc(cls, f) -> "Feature": + def from_lnd_grpc(cls, f) -> "Feature": return cls( name=f.name, is_required=f.is_required, is_known=f.is_known, ) + @classmethod + def from_cln_json(cls, f) -> "Feature": + return cls(name=f) + class FeaturesEntry(BaseModel): key: int value: Feature @classmethod - def from_grpc(cls, entry_key, feature) -> "FeaturesEntry": + def from_lnd_grpc(cls, entry_key, feature) -> "FeaturesEntry": return cls( key=entry_key, - value=Feature.from_grpc(feature), + value=Feature.from_lnd_grpc(feature), + ) + + @classmethod + def from_cln_json(self, entry_key, feature): + return self( + key=entry_key, + value=Feature.from_cln_json(feature), ) @@ -158,7 +221,7 @@ class AMP(BaseModel): preimage: str @classmethod - def from_grpc(cls, a) -> "AMP": + def from_lnd_grpc(cls, a) -> "AMP": return cls( root_share=a.root_share.hex(), set_id=a.set_id.hex(), @@ -173,7 +236,7 @@ class CustomRecordsEntry(BaseModel): value: str @classmethod - def from_grpc(cls, e) -> "CustomRecordsEntry": + def from_lnd_grpc(cls, e) -> "CustomRecordsEntry": return cls( key=e.key, value=e.value, @@ -181,46 +244,51 @@ class CustomRecordsEntry(BaseModel): class InvoiceHTLC(BaseModel): - # Short channel id over which the htlc was received. - chan_id: int + chan_id: int = Query( + ..., description="The channel ID over which the HTLC was received." + ) - # Index identifying the htlc on the channel. - htlc_index: int + htlc_index: int = Query(..., description="The index of the HTLC on the channel.") - # The amount of the htlc in msat. - amt_msat: int + amt_msat: int = Query(..., description="The amount of the HTLC in msat.") - # Block height at which this htlc was accepted. - accept_height: int + accept_height: int = Query( + ..., description="The block height at which this HTLC was accepted." + ) - # Time at which this htlc was accepted. - accept_time: int + accept_time: int = Query( + ..., description="The time at which this HTLC was accepted." + ) - # Time at which this htlc was settled or canceled. - resolve_time: int + resolve_time: int = Query( + ..., description="The time at which this HTLC was resolved." + ) - # Block height at which this htlc expires. - expiry_height: int + expiry_height: int = Query( + ..., description="The block height at which this HTLC expires." + ) - # Current state the htlc is in. - state: InvoiceHTLCState + state: InvoiceHTLCState = Query(..., description="The state of the HTLC.") - # Custom tlv records. - custom_records: List[CustomRecordsEntry] + custom_records: List[CustomRecordsEntry] = Query( + [], description="Custom tlv records." + ) - # The total amount of the mpp payment in msat. - mpp_total_amt_msat: int + mpp_total_amt_msat: int = Query( + ..., description="The total amount of the mpp payment in msat." + ) - # Details relevant to AMP HTLCs, only populated - # if this is an AMP HTLC. - amp: AMP + amp: AMP = Query( + None, + description="Details relevant to AMP HTLCs, only populated if this is an AMP HTLC.", + ) @classmethod - def from_grpc(cls, h) -> "InvoiceHTLC": + def from_lnd_grpc(cls, h) -> "InvoiceHTLC": def _crecords(recs): l = [] for r in recs: - l.append(CustomRecordsEntry.from_grpc(r)) + l.append(CustomRecordsEntry.from_lnd_grpc(r)) return l return cls( @@ -231,32 +299,35 @@ class InvoiceHTLC(BaseModel): accept_time=h.accept_time, resolve_time=h.resolve_time, expiry_height=h.expiry_height, - state=InvoiceHTLCState.from_grpc(h.state), + state=InvoiceHTLCState.from_lnd_grpc(h.state), custom_records=_crecords(h.custom_records), mpp_total_amt_msat=h.mpp_total_amt_msat, - amp=AMP.from_grpc(h.amp), + amp=AMP.from_lnd_grpc(h.amp), ) class HopHint(BaseModel): - # The public key of the node at the start of the channel. - node_id: str + node_id: str = Query( + ..., description="The public key of the node at the start of the channel." + ) - # The unique identifier of the channel. - chan_id: int + chan_id: int = Query(..., description="The unique identifier of the channel.") - # The base fee of the channel denominated in millisatoshis. - fee_base_msat: int + fee_base_msat: int = Query( + ..., description="The base fee of the channel denominated in msat." + ) - # The fee rate of the channel for sending one satoshi - # across it denominated in millionths of a satoshi. - fee_proportional_millionths: int + fee_proportional_millionths: int = Query( + ..., + description="The fee rate of the channel for sending one satoshi across it denominated in msat", + ) - # The time-lock delta of the channel. - cltv_expiry_delta: int + cltv_expiry_delta: int = Query( + ..., description="The time-lock delta of the channel." + ) @classmethod - def from_grpc(cls, h) -> "HopHint": + def from_lnd_grpc(cls, h) -> "HopHint": return cls( node_id=h.node_id, chan_id=h.chan_id, @@ -265,6 +336,16 @@ class HopHint(BaseModel): cltv_expiry_delta=h.cltv_expiry_delta, ) + @classmethod + def from_cln_json(cls, h) -> "HopHint": + return cls( + node_id=h["pubkey"], + chan_id=h["short_channel_id"], + fee_base_msat=h["fee_base_msat"], + fee_proportional_millionths=h["fee_proportional_millionths"], + cltv_expiry_delta=h["cltv_expiry_delta"], + ) + class RouteHint(BaseModel): hop_hints: List[HopHint] = Query( @@ -273,8 +354,13 @@ class RouteHint(BaseModel): ) @classmethod - def from_grpc(cls, h) -> "RouteHint": - hop_hints = [HopHint.from_grpc(hh) for hh in h.hop_hints] + def from_lnd_grpc(cls, h) -> "RouteHint": + hop_hints = [HopHint.from_lnd_grpc(hh) for hh in h.hop_hints] + return cls(hop_hints=hop_hints) + + @classmethod + def from_cln_json(cls, h) -> "RouteHint": + hop_hints = [HopHint.from_cln_json(hh) for hh in h.hop_hints] return cls(hop_hints=hop_hints) @@ -291,7 +377,7 @@ class Channel(BaseModel): balance_capacity: Optional[int] @classmethod - def from_grpc(cls, c) -> "Channel": + def from_lnd_grpc(cls, c) -> "Channel": return cls( active=c.active, channel_id=c.channel_point, # use channel point as id because thats needed for closing the channel with lnd @@ -303,7 +389,7 @@ class Channel(BaseModel): ) @classmethod - def from_grpc_pending(cls, c) -> "Channel": + def from_lnd_grpc_pending(cls, c) -> "Channel": return cls( active=False, channel_id=c.channel_point, # use channel point as id because thats needed for closing the channel with lnd @@ -314,133 +400,181 @@ class Channel(BaseModel): balance_capacity=c.capacity, ) + @classmethod + def from_cln_grpc(cls, c) -> "Channel": + # TODO: get alias and balance of the channel + return cls( + active=c.active, + channel_id=c.short_channel_id, # use channel point as id because thats needed for closing the channel with lnd + peer_publickey=c.destination.hex(), + peer_alias="n/a", + balance_local=-1, + balance_remote=-1, + balance_capacity=c.amount_msat.msat, + ) + class Invoice(BaseModel): - # optional memo to attach along with the invoice. - # Used for record keeping purposes for the invoice's - # creator, and will also be set in the description - # field of the encoded payment request if the - # description_hash field is not being used. - memo: Optional[str] + memo: str = Query( + None, + description="""Optional memo to attach along with the invoice. Used for record keeping purposes for the invoice's creator, + and will also be set in the description field of the encoded payment request if the description_hash field is not being used.""", + ) - # The hex-encoded preimage(32 byte) which will allow - # settling an incoming HTLC payable to this preimage. - r_preimage: Optional[str] + r_preimage: str = Query( + None, + description="""The hex-encoded preimage(32 byte) which will allow settling an incoming HTLC payable to this preimage.""", + ) - # The hash of the preimage. - r_hash: Optional[str] + r_hash: str = Query(None, description="The hash of the preimage.") - # The value of this invoice in satoshis - # The fields value and value_msat are mutually exclusive. - value: Optional[int] - # The value of this invoice in millisatoshis The - # fields value and value_msat are mutually exclusive. - value_msat: Optional[int] + value_msat: int = Query( + ..., description="The value of this invoice in milli satoshis." + ) - # Whether this invoice has been fulfilled - settled: Optional[bool] + settled: bool = Query(False, description="Whether this invoice has been fulfilled") - # When this invoice was created - creation_date: Optional[int] + creation_date: int = Query( + None, + description="When this invoice was created. Not available with CLN.", + ) - # When this invoice was settled - settle_date: Optional[int] + settle_date: int = Query( + None, + description="When this invoice was settled. Not available with pending invoices.", + ) - # A bare-bones invoice for a payment within the - # Lightning Network. With the details of the invoice, - # the sender has all the data necessary to send a - # payment to the recipient. - payment_request: Optional[str] + expiry_date: int = Query(None, description="The time at which this invoice expires") - # Hash(SHA-256) of a description of the payment. - # Used if the description of payment(memo) is too - # long to naturally fit within the description field of - # an encoded payment request. - description_hash: Optional[str] + payment_request: str = Query( + None, + description="""A bare-bones invoice for a payment within the + Lightning Network. With the details of the invoice, the sender has all the data necessary to + send a payment to the recipient. + """, + ) - # Payment request expiry time in seconds. Default is 3600 (1 hour). - expiry: Optional[int] + description_hash: str = Query( + None, + description=""" + Hash(SHA-256) of a description of the payment. Used if the description of payment(memo) is too + long to naturally fit within the description field of an encoded payment request. + """, + ) - # Fallback on-chain address. - fallback_addr: Optional[str] + expiry: int = Query( + None, + description="Payment request expiry time in seconds. Default is 3600 (1 hour).", + ) - # Delta to use for the time-lock of the CLTV extended to the final hop. - cltv_expiry: Optional[int] + fallback_addr: str = Query(None, description="Fallback on-chain address.") - # Route hints that can each be individually used - # to assist in reaching the invoice's destination. - route_hints: Optional[List[RouteHint]] + cltv_expiry: int = Query( + None, + description="Delta to use for the time-lock of the CLTV extended to the final hop.", + ) - # Whether this invoice should include routing hints for private channels. - private: Optional[bool] + route_hints: List[RouteHint] = Query( + None, + description=""" + Route hints that can each be individually used to assist in reaching the invoice's destination. + """, + ) - # The "add" index of this invoice. Each newly created invoice - # will increment this index making it monotonically increasing. - # Callers to the SubscribeInvoices call can use this to instantly - # get notified of all added invoices with an add_index greater than this one. - add_index: Optional[int] + private: bool = Query( + None, + description="Whether this invoice should include routing hints for private channels.", + ) - # The "settle" index of this invoice. Each newly settled invoice will - # increment this index making it monotonically increasing. Callers to - # the SubscribeInvoices call can use this to instantly get notified of - # all settled invoices with an settle_index greater than this one. - settle_index: Optional[int] + add_index: str = Query( + ..., + description=""" +The index of this invoice. Each newly created invoice will increment this index making it monotonically increasing. +CLN and LND handle ids differently. LND will generate an auto incremented integer id, while CLN will use a user supplied string id. +To unify both, we auto generate an id for CLN and use the add_index for LND. - # The amount that was accepted for this invoice, in satoshis. This - # will ONLY be set if this invoice has been settled. We provide - # this field as if the invoice was created with a zero value, - # then we need to record what amount was ultimately accepted. - # Additionally, it's possible that the sender paid MORE that - # was specified in the original invoice. So we'll record that here as well. - amt_paid_sat: Optional[int] +For `LND` this will be an `integer` in string form. This is auto generated by LND. - # The amount that was accepted for this invoice, in millisatoshis. - # This will ONLY be set if this invoice has been settled. We - # provide this field as if the invoice was created with a zero value, - # then we need to record what amount was ultimately accepted. Additionally, - # it's possible that the sender paid MORE that was specified in the - # original invoice. So we'll record that here as well. - amt_paid_msat: Optional[int] +For `CLN` this will be a `string`. If the invoice was generated by BlitzAPI, this will be a +[Firebase-like PushID](https://firebase.blog/posts/2015/02/the-2120-ways-to-ensure-unique_68). +If generated by some other method, it'll be the string supplied by the user at the time of creation of the invoice. +""", + ) - # The state the invoice is in. - state: Optional[InvoiceState] + settle_index: int = Query( + None, + description=""" + The "settle" index of this invoice. Each newly settled invoice will increment this index making it monotonically increasing. + """, + ) - # List of HTLCs paying to this invoice[EXPERIMENTAL]. - htlcs: Optional[List[InvoiceHTLC]] + amt_paid_sat: int = Query( + None, + description=""" + The amount that was accepted for this invoice, in satoshis. This + will ONLY be set if this invoice has been settled. We provide + this field as if the invoice was created with a zero value, + then we need to record what amount was ultimately accepted. + Additionally, it's possible that the sender paid MORE that + was specified in the original invoice. So we'll record that here as well. + """, + ) - # List of features advertised on the invoice. - features: Optional[List[FeaturesEntry]] + amt_paid_msat: int = Query( + None, + description=""" + The amount that was accepted for this invoice, in millisatoshis. + This will ONLY be set if this invoice has been settled. We + provide this field as if the invoice was created with a zero value, + then we need to record what amount was ultimately accepted. Additionally, + it's possible that the sender paid MORE that was specified in the + original invoice. So we'll record that here as well. + """, + ) - # Indicates if this invoice was a spontaneous payment - # that arrived via keysend[EXPERIMENTAL]. - is_keysend: Optional[bool] + state: InvoiceState = Query(..., description="The state the invoice is in.") - # The payment address of this invoice. This value will - # be used in MPP payments, and also for newer invoices - # that always require the MPP payload for added end-to-end security. - payment_addr: Optional[str] + htlcs: List[InvoiceHTLC] = Query( + None, description="List of HTLCs paying to this invoice[EXPERIMENTAL]." + ) - # Signals whether or not this is an AMP invoice. - is_amp: Optional[bool] + features: List[FeaturesEntry] = Query( + None, description="List of features advertised on the invoice." + ) + + is_keysend: bool = Query( + None, + description="[LND only] Indicates if this invoice was a spontaneous payment that arrived via keysend[EXPERIMENTAL].", + ) + + payment_addr: str = Query( + None, + description=""" The payment address of this invoice. This value will be used in MPP payments, + and also for newer invoices that always require the MPP payload for added end-to-end security.""", + ) + + is_amp: bool = Query( + None, description="Signals whether or not this is an AMP invoice." + ) @classmethod - def from_grpc(cls, i) -> "Invoice": + def from_lnd_grpc(cls, i) -> "Invoice": def _route_hints(hints): l = [] for h in hints: - l.append(RouteHint.from_grpc((h))) + l.append(RouteHint.from_lnd_grpc((h))) return l def _htlcs(htlcs): l = [] for h in htlcs: - l.append(InvoiceHTLC.from_grpc(h)) + l.append(InvoiceHTLC.from_lnd_grpc(h)) return l def _features(features): l = [] for k in features: - l.append(FeaturesEntry.from_grpc(k, features[k])) + l.append(FeaturesEntry.from_lnd_grpc(k, features[k])) return l return cls( @@ -451,6 +585,7 @@ class Invoice(BaseModel): value_msat=i.value_msat, settled=i.settled, creation_date=i.creation_date, + expiry_date=i.creation_date + i.expiry, settle_date=i.settle_date, payment_request=i.payment_request, description_hash=i.description_hash, @@ -463,7 +598,7 @@ class Invoice(BaseModel): settle_index=i.settle_index, amt_paid_sat=i.amt_paid_sat, amt_paid_msat=i.amt_paid_msat, - state=InvoiceState.from_grpc(i.state), + state=InvoiceState.from_lnd_grpc(i.state), htlcs=_htlcs(i.htlcs), features=_features(i.features), is_keysend=i.is_keysend, @@ -471,6 +606,49 @@ class Invoice(BaseModel): is_amp=i.is_amp, ) + @classmethod + def from_cln_json(cls, i) -> "Invoice": + return cls( + add_index=i["label"], + memo=i["description"], + r_preimage=i["payment_preimage"] if "payment_preimage" in i else None, + r_hash=i["payment_hash"], + value=i["msatoshi"] / 1000, + value_msat=i["msatoshi"], + settled=True if i["status"] == "paid" else False, + expiry_date=i["expires_at"], + settle_date=i["paid_at"] if "paid_at" in i else None, + payment_request=i["bolt11"], + settle_index=i["pay_index"] if "pay_index" in i else None, + amt_paid_sat=i["amount_received_msat"] / 1000 + if "amount_received_msat" in i + else None, + amt_paid_msat=i["amount_received_msat"] + if "amount_received_msat" in i + else None, + state=InvoiceState.from_cln_json(i["status"]), + ) + + @classmethod + def from_cln_grpc(cls, i) -> "Invoice": + state = InvoiceState.from_cln_grpc(i) + return cls( + add_index=i.label, + memo=i.description, + r_preimage=i.payment_preimage.hex(), + r_hash=i.payment_hash.hex(), + value=i.amount_msat.msat / 1000, + value_msat=i.amount_msat.msat, + settled=True if state == InvoiceState.SETTLED else False, + expiry_date=i.expires_at, + settle_date=i.paid_at, + payment_request=i.bolt11, + settle_index=i.pay_index, + amt_paid_sat=i.amount_received_msat.msat / 1000, + amt_paid_msat=i.amount_received_msat.msat, + state=state, + ) + class PaymentStatus(str, Enum): UNKNOWN = "unknown" @@ -479,7 +657,7 @@ class PaymentStatus(str, Enum): FAILED = "failed" @classmethod - def from_grpc(cls, id) -> "PaymentStatus": + def from_lnd_grpc(cls, id) -> "PaymentStatus": if id == 0: return PaymentStatus.UNKNOWN elif id == 1: @@ -491,6 +669,17 @@ class PaymentStatus(str, Enum): else: raise NotImplementedError(f"PaymentStatus {id} is not implemented") + @classmethod + def from_cln_grpc(cls, id) -> "PaymentStatus": + if id == 0: + return PaymentStatus.IN_FLIGHT + elif id == 1: + return PaymentStatus.FAILED + elif id == 2: + return PaymentStatus.SUCCEEDED + else: + raise NotImplementedError(f"PaymentStatus {id} is not implemented") + class PaymentFailureReason(str, Enum): # Payment isn't failed(yet). @@ -515,7 +704,7 @@ class PaymentFailureReason(str, Enum): FAILURE_REASON_INSUFFICIENT_BALANCE = "FAILURE_REASON_INSUFFICIENT_BALANCE" @classmethod - def from_grpc(cls, f) -> "PaymentFailureReason": + def from_lnd_grpc(cls, f) -> "PaymentFailureReason": if f == 0: return PaymentFailureReason.FAILURE_REASON_NONE elif f == 1: @@ -531,6 +720,16 @@ class PaymentFailureReason(str, Enum): else: raise NotImplementedError(f"PaymentFailureReason {id} is not implemented") + @classmethod + def from_cln_grpc(cls, p) -> "PaymentFailureReason": + if p.status == 0 or p.status == 2: + return PaymentFailureReason.FAILURE_REASON_NONE + + # TODO: find a way to describe the failure reason. CLN currently doesn't + # seem to provide an API for this. + + return PaymentFailureReason.FAILURE_REASON_ERROR + class ChannelUpdate(BaseModel): # The signature that validates the announced data and proves the ownership of node id. @@ -584,7 +783,7 @@ class ChannelUpdate(BaseModel): extra_opaque_data: str @classmethod - def from_grpc(cls, u) -> "ChannelUpdate": + def from_lnd_grpc(cls, u) -> "ChannelUpdate": return cls( signature=u.signature, chain_hash=u.chain_hash, @@ -624,7 +823,7 @@ class Hop(BaseModel): tlv_payload: bool @classmethod - def from_grpc(cls, h) -> "Hop": + def from_lnd_grpc(cls, h) -> "Hop": return cls( chan_id=h.chan_id, chan_capacity=h.chan_capacity, @@ -643,7 +842,7 @@ class MPPRecord(BaseModel): total_amt_msat: int @classmethod - def from_grpc(cls, r) -> "MPPRecord": + def from_lnd_grpc(cls, r) -> "MPPRecord": return cls( payment_addr=r.payment_addr, total_amt_msat=r.total_amt_msat, @@ -656,7 +855,7 @@ class AMPRecord(BaseModel): child_index: int @classmethod - def from_grpc(cls, r) -> "AMPRecord": + def from_lnd_grpc(cls, r) -> "AMPRecord": return cls( root_share=r.root_share, set_id=r.set_id, @@ -676,7 +875,7 @@ class Route(BaseModel): custom_records: List[CustomRecordsEntry] @classmethod - def from_grpc(cls, r): + def from_lnd_grpc(cls, r): def _crecords(recs): l = [] for r in recs: @@ -686,16 +885,16 @@ class Route(BaseModel): def _get_hops(hops) -> List[Hop]: l = [] for h in hops: - l.append(Hop.from_grpc(h)) + l.append(Hop.from_lnd_grpc(h)) return l mpp = None if hasattr(r, "mpp_record"): - mpp = MPPRecord.from_grpc(r.mpp_record) + mpp = MPPRecord.from_lnd_grpc(r.mpp_record) amp = None if hasattr(r, "amp_record"): - amp = AMPRecord.from_grpc(r.amp_record) + amp = AMPRecord.from_lnd_grpc(r.amp_record) crecords = [] if hasattr(r, "custom_records"): @@ -742,7 +941,7 @@ class HTLCAttemptFailure(BaseModel): height: int @classmethod - def from_grpc(cls, f) -> "HTLCAttemptFailure": + def from_lnd_grpc(cls, f) -> "HTLCAttemptFailure": code = None if hasattr(f, "code"): code = f.code @@ -753,7 +952,7 @@ class HTLCAttemptFailure(BaseModel): return cls( code=code, - channel_update=ChannelUpdate.from_grpc(f.channel_update), + channel_update=ChannelUpdate.from_lnd_grpc(f.channel_update), htlc_msat=htlc_msat, onion_sha_256=f.onion_sha_256, cltv_expiry=f.cltv_expiry, @@ -769,7 +968,7 @@ class HTLCStatus(str, Enum): FAILED = "failed" @classmethod - def from_grpc(cls, s) -> "HTLCStatus": + def from_lnd_grpc(cls, s) -> "HTLCStatus": if s == 0: return HTLCStatus.IN_FLIGHT elif s == 1: @@ -804,57 +1003,64 @@ class HTLCAttempt(BaseModel): preimage: str @classmethod - def from_grpc(cls, a) -> "HTLCAttempt": + def from_lnd_grpc(cls, a) -> "HTLCAttempt": return cls( attempt_id=a.attempt_id, - status=HTLCStatus.from_grpc(a.status), - route=Route.from_grpc(a.route), + status=HTLCStatus.from_lnd_grpc(a.status), + route=Route.from_lnd_grpc(a.route), attempt_time_ns=a.attempt_time_ns, resolve_time_ns=a.resolve_time_ns, - failure=HTLCAttemptFailure.from_grpc(a.failure), + failure=HTLCAttemptFailure.from_lnd_grpc(a.failure), preimage=a.preimage.hex(), ) class Payment(BaseModel): - # The payment hash - payment_hash: str + payment_hash: str = Query(..., description="The payment hash") - # The payment preimage - payment_preimage: Optional[str] + payment_preimage: Optional[str] = Query(None, description="The payment preimage") - # The value of the payment in milli-satoshis - value_msat: int + value_msat: int = Query( + ..., description="The value of the payment in milli-satoshis" + ) - # The optional payment request being fulfilled. - payment_request: Optional[str] + payment_request: str = Query( + None, description="The optional payment request being fulfilled." + ) - # The status of the payment. - status: PaymentStatus = PaymentStatus.UNKNOWN + status: PaymentStatus = Query( + PaymentStatus.UNKNOWN, description="The status of the payment." + ) - # The fee paid for this payment in milli-satoshis - fee_msat: int + fee_msat: int = Query(..., description="The fee paid for this payment in msat") - # The time in UNIX nanoseconds at which the payment was created. - creation_time_ns: int + creation_time_ns: int = Query( + ..., + description="The time in UNIX nanoseconds at which the payment was created.", + ) - # The HTLCs made in attempt to settle the payment. - htlcs: List[HTLCAttempt] = [] + htlcs: List[HTLCAttempt] = Query( + [], description="The HTLCs made in attempt to settle the payment." + ) - # The creation index of this payment. Each payment can be uniquely - # identified by this index, which may not strictly increment by 1 - # for payments made in older versions of lnd. - payment_index: int + payment_index: int = Query( + 0, description="The payment index. Only set with LND, 0 otherwise." + ) - # The failure reason - failure_reason: PaymentFailureReason + label: str = Query( + "", description="The payment label. Only set with CLN, empty otherwise." + ) + + failure_reason: PaymentFailureReason = Query( + PaymentFailureReason.FAILURE_REASON_NONE, description="The failure reason" + ) @classmethod - def from_grpc(cls, p) -> "Payment": + def from_lnd_grpc(cls, p) -> "Payment": def _get_attempts(attempts): l = [] for a in attempts: - l.append(HTLCAttempt.from_grpc(a)) + l.append(HTLCAttempt.from_lnd_grpc(a)) return l return cls( @@ -862,12 +1068,26 @@ class Payment(BaseModel): payment_preimage=p.payment_preimage, value_msat=p.value_msat, payment_request=p.payment_request, - status=PaymentStatus.from_grpc(p.status), + status=PaymentStatus.from_lnd_grpc(p.status), fee_msat=p.fee_msat, creation_time_ns=p.creation_time_ns, htlcs=_get_attempts(p.htlcs), payment_index=p.payment_index, - failure_reason=PaymentFailureReason.from_grpc(p.failure_reason), + failure_reason=PaymentFailureReason.from_lnd_grpc(p.failure_reason), + ) + + @classmethod + def from_cln_grpc(cls, p) -> "Payment": + return cls( + payment_hash=p.payment_hash.hex(), + payment_preimage="", # CLN currently doesn't return the preimage + value_msat=p.amount_sent_msat.msat, + payment_request=p.bolt11, + status=PaymentStatus.from_cln_grpc(p.status), + fee_msat=p.amount_sent_msat.msat - p.amount_msat.msat, + creation_time_ns=p.created_at, + label=p.label, + failure_reason=PaymentFailureReason.from_cln_grpc(p), ) @@ -896,18 +1116,20 @@ class SendCoinsInput(BaseModel): description="The number of bitcoin denominated in satoshis to send", ) target_conf: int = Query( - 0, + None, description="The number of blocks that the transaction *should* confirm in, will be used for fee estimation", ) sat_per_vbyte: int = Query( - 0, + None, description="A manual fee expressed in sat/vbyte that should be used when crafting the transaction (default: 0)", ) min_confs: int = Query( 1, description="The minimum number of confirmations each one of your outputs used for the transaction must satisfy", ) - label: str = Query("", description="A label for the transaction") + label: str = Query( + "", description="A label for the transaction. Ignored by CLN backend." + ) class SendCoinsResponse(BaseModel): @@ -920,10 +1142,21 @@ class SendCoinsResponse(BaseModel): ..., description="The number of bitcoin denominated in satoshis which where sent", ) - label: str = Query("", description="The label used for the transaction") + label: str = Query( + "", description="The label used for the transaction. Ignored by CLN backend." + ) @classmethod - def from_grpc(cls, r, input: SendCoinsInput): + def from_lnd_grpc(cls, r, input: SendCoinsInput): + return cls( + txid=r.txid, + address=input.address, + amount=input.amount, + label=input.label, + ) + + @classmethod + def from_cln_grpc(cls, r, input: SendCoinsInput): return cls( txid=r.txid, address=input.address, @@ -942,62 +1175,72 @@ class Chain(BaseModel): class LnInfo(BaseModel): implementation: str = Query( - ..., description="Lightning software implementation (LND, c-lightning)" + ..., description="Lightning software implementation (LND, CLN)" ) - # The version of the LND software that the node is running. - version: str - # The SHA1 commit hash that the daemon is compiled with. - commit_hash: str + version: str = Query( + ..., description="The version of the software that the node is running." + ) - # The identity pubkey of the current node. - identity_pubkey: str = Query("the nodes pubkey") + commit_hash: str = Query( + ..., description="The SHA1 commit hash that the daemon is compiled with." + ) - # The complete URI (pubkey@physicaladdress:port) the current node. - identity_uri: str = Query("the nodes complete URI") + identity_pubkey: str = Query("The identity pubkey of the current node.") - # If applicable, the alias of the current node, e.g. "bob" - alias: str + identity_uri: str = Query( + "The complete URI (pubkey@physicaladdress:port) the current node." + ) - # The color of the current node in hex code format - color: str + alias: str = Query(..., description="The alias of the node.") - # Number of pending channels - num_pending_channels: int + color: str = Query( + ..., description="The color of the current node in hex code format." + ) - # Number of active channels - num_active_channels: int + num_pending_channels: int = Query(..., description="Number of pending channels.") - # Number of inactive channels - num_inactive_channels: int + num_active_channels: int = Query(..., description="Number of active channels.") - # Number of peers - num_peers: int + num_inactive_channels: int = Query(..., description="Number of inactive channels.") - # The node's current view of the height of the best block - block_height: int + num_peers: int = Query(..., description="Number of peers.") - # The node's current view of the hash of the best block - block_hash: str + block_height: int = Query( + ..., + description="The node's current view of the height of the best block. Only available with LND.", + ) - # Timestamp of the block best known to the wallet - best_header_timestamp: int + block_hash: str = Query( + "", + description="The node's current view of the hash of the best block. Only available with LND.", + ) - # Whether the wallet's view is synced to the main chain - synced_to_chain: bool + best_header_timestamp: int = Query( + None, + description="Timestamp of the block best known to the wallet. Only available with LND.", + ) - # Whether we consider ourselves synced with the public channel graph. - synced_to_graph: bool + synced_to_chain: bool = Query( + None, + description="Whether the wallet's view is synced to the main chain. Only available with LND.", + ) - # A list of active chains the node is connected to - chains: List[Chain] + synced_to_graph: bool = Query( + None, + description="Whether we consider ourselves synced with the public channel graph. Only available with LND.", + ) - # The URIs of the current node. - uris: List[str] + chains: List[Chain] = Query( + [], description="A list of active chains the node is connected to" + ) - # Features that our node has advertised in our init message, - # node announcements and invoices. - features: List[FeaturesEntry] + uris: List[str] = Query([], description="The URIs of the current node.") + + features: List[FeaturesEntry] = Query( + [], + description="Features that our node has advertised in our init message node announcements and invoices. Not yet implemented with CLN", + ) def __eq__(self, other): if isinstance(other, self.__class__): @@ -1010,14 +1253,14 @@ class LnInfo(BaseModel): return not self.__eq__(other) @classmethod - def from_grpc(cls, implementation, i) -> "LnInfo": + def from_lnd_grpc(cls, implementation, i) -> "LnInfo": _chains = [] for c in i.chains: _chains.append(Chain(chain=c.chain, network=c.network)) _features = [] for f in i.features: - _features.append(FeaturesEntry.from_grpc(f, i.features[f])) + _features.append(FeaturesEntry.from_lnd_grpc(f, i.features[f])) _uris = [u for u in i.uris] @@ -1042,6 +1285,66 @@ class LnInfo(BaseModel): features=_features, ) + @classmethod + def from_cln_json(cls, implementation, i) -> "LnInfo": + _chains = [Chain(chain="bitcoin", network=i["network"])] + + _features = [] + # TODO: Map CLN's feature advertisements to LND's + # for k in i["our_features"].keys(): + # _features.append(FeaturesEntry.from_cln_json(i["our_features"][k], k)) + + _uris = [] + for b in i["binding"]: + _uris.append(f"{b['address']}:{b['port']}") + + return LnInfo( + implementation=implementation, + version=i["version"], + commit_hash=i["version"].split("-")[-1], + identity_pubkey=i["id"], + alias=i["alias"], + color=i["color"], + num_pending_channels=i["num_pending_channels"], + num_active_channels=i["num_active_channels"], + num_inactive_channels=i["num_inactive_channels"], + num_peers=i["num_peers"], + block_height=i["blockheight"], + chains=_chains, + uris=_uris, + features=_features, + ) + + @classmethod + def from_cln_grpc(cls, implementation, i) -> "LnInfo": + _chains = [Chain(chain="bitcoin", network=i.network)] + + _features = [] + # TODO: Map CLN's feature advertisements to LND's + # for k in i["our_features"].keys(): + # _features.append(FeaturesEntry.from_cln_json(i["our_features"][k], k)) + + _uris = [] + for b in i.binding: + _uris.append(f"{b.address}:{b.port}") + + return LnInfo( + implementation=implementation, + version=i.version, + commit_hash=i.version.split("-")[-1], + identity_pubkey=i.id.hex(), + alias=i.alias, + color=i.color.hex(), + num_pending_channels=i.num_pending_channels, + num_active_channels=i.num_active_channels, + num_inactive_channels=i.num_inactive_channels, + num_peers=i.num_peers, + block_height=i.blockheight, + chains=_chains, + uris=_uris, + features=_features, + ) + class LightningInfoLite(BaseModel): implementation: str = Query( @@ -1056,15 +1359,15 @@ class LightningInfoLite(BaseModel): ..., description="The node's current view of the height of the best block" ) synced_to_chain: bool = Query( - ..., description="Whether the wallet's view is synced to the main chain" + None, description="Whether the wallet's view is synced to the main chain" ) synced_to_graph: bool = Query( - ..., + None, description="Whether we consider ourselves synced with the public channel graph.", ) @classmethod - def from_grpc(cls, info: LnInfo): + def from_lninfo(cls, info: LnInfo): return cls( implementation=info.implementation, version=info.version, @@ -1110,7 +1413,7 @@ class WalletBalance(BaseModel): ) @classmethod - def from_grpc(cls, onchain, channel) -> "WalletBalance": + def from_lnd_grpc(cls, onchain, channel) -> "WalletBalance": return cls( onchain_confirmed_balance=onchain.confirmed_balance, onchain_total_balance=onchain.total_balance, @@ -1127,22 +1430,24 @@ class WalletBalance(BaseModel): class PaymentRequest(BaseModel): destination: str payment_hash: str - num_satoshis: int + num_satoshis: int = Query( + None, description="Deprecated. User num_msat instead", deprecated=True + ) timestamp: int expiry: int description: str - description_hash: str + description_hash: Optional[str] fallback_addr: Optional[str] cltv_expiry: int route_hints: List[RouteHint] = Query( [], description="A list of [HopHint] for the RouteHint" ) - payment_addr: str = Query(..., description="The payment address in hex format") - num_msat: int + payment_addr: str = Query("", description="The payment address in hex format") + num_msat: Optional[int] features: List[FeaturesEntry] = Query([]) @classmethod - def from_grpc(cls, r): + def from_lnd_grpc(cls, r): return cls( destination=r.destination, payment_hash=r.payment_hash, @@ -1153,10 +1458,86 @@ class PaymentRequest(BaseModel): description_hash=r.description_hash, fallback_addr=r.fallback_addr, cltv_expiry=r.cltv_expiry, - route_hints=[RouteHint.from_grpc(rh) for rh in r.route_hints], + route_hints=[RouteHint.from_lnd_grpc(rh) for rh in r.route_hints], payment_addr=r.payment_addr.hex(), num_msat=r.num_msat, - features=[FeaturesEntry.from_grpc(k, r.features[k]) for k in r.features], + features=[ + FeaturesEntry.from_lnd_grpc(k, r.features[k]) for k in r.features + ], + ) + + @classmethod + def from_cln_json(cls, r): + routes = [] + if "routes" in r.keys(): + routes = [RouteHint.from_cln_json(rh) for rh in r["routes"]] + + msat = 0 + if "msatoshi" in r: + msat = r["msatoshi"] + + features = [] + # TODO: Map CLN's feature advertisements to LND's + # if "features" in r: + # features = [ + # FeaturesEntry.from_cln_json(k, r["features"][k]) for k in r["features"] + # ] + + return cls( + destination=r["payee"], + payment_hash=r["payment_hash"], + num_satoshis=msat / 1000, + timestamp=r["created_at"], + expiry=r["expiry"], + description=r["description"], + description_hash="" if "payment_hash" not in r else r["payment_hash"], + fallback_addr="" if "fallbacks" not in r else r["fallbacks"][0], + cltv_expiry=r["min_final_cltv_expiry"], + route_hints=routes, + num_msat=msat, + payment_addr=r["payment_secret"], + features=features, + ) + + @classmethod + def from_cln_grpc(cls, r): + routes = [] + if "routes" in r.keys(): + routes = [RouteHint.from_cln_json(rh) for rh in r["routes"]] + + msat = 0 + if "amount_msat" in r: + msat = r["amount_msat"] + + features = [] + # TODO: Map CLN's feature advertisements to LND's + # if "features" in r: + # features = [ + # FeaturesEntry.from_cln_json(k, r["features"][k]) for k in r["features"] + # ] + + dhash = "" + if hasattr(r, "payment_hash"): + dhash = r.payment_hash.hex() + + fback = [] + if hasattr(r, "fallbacks"): + fback = r["fallbacks"][0] + + return cls( + destination=r.payee, + payment_hash=r.payment_hash.hex(), + num_satoshis=msat / 1000, + timestamp=r.created_at, + expiry=r.expiry, + description=r.description, + description_hash=dhash, + fallback_addr=fback, + cltv_expiry=r.min_final_cltv_expiry, + route_hints=routes, + num_msat=msat, + payment_addr=r.payment_secret, + features=features, ) @@ -1179,7 +1560,7 @@ class OnChainTransaction(BaseModel): ) @classmethod - def from_grpc(cls, t): + def from_lnd_grpc(cls, t): addrs = [a for a in t.dest_addresses] return cls( tx_hash=t.tx_hash, @@ -1237,7 +1618,7 @@ class GenericTx(BaseModel): total_fees: int = Query(None, description="Total fees paid for this transaction") @classmethod - def from_grpc_invoice(cls, i): + def from_lnd_grpc_invoice(cls, i) -> "GenericTx": status = TxStatus.UNKNOWN time_stamp = i.creation_date amount = i.value_msat @@ -1261,7 +1642,7 @@ class GenericTx(BaseModel): ) @classmethod - def from_grpc_onchain_tx(cls, tx): + def from_lnd_grpc_onchain_tx(cls, tx) -> "GenericTx": s = TxStatus.SUCCEEDED if tx.num_confirmations > 0 else TxStatus.IN_FLIGHT t = TxType.UNKNOWN @@ -1284,7 +1665,7 @@ class GenericTx(BaseModel): ) @classmethod - def from_grpc_payment(cls, payment, comment: str = ""): + def from_lnd_grpc_payment(cls, payment, comment: str = "") -> "GenericTx": status = TxStatus.UNKNOWN if payment.status == 1: status = TxStatus.IN_FLIGHT @@ -1303,3 +1684,149 @@ class GenericTx(BaseModel): total_fees=payment.fee_msat, comment=comment, ) + + @classmethod + def from_cln_json_invoice(cls, i) -> "GenericTx": + status = TxStatus.UNKNOWN + time_stamp = i["expires_at"] + amount = i["msatoshi"] + if i["status"] == "paid": + status = TxStatus.SUCCEEDED + time_stamp = i["paid_at"] + amount = i["amount_received_msat"] + elif i["status"] == "unpaid": + status = TxStatus.IN_FLIGHT + elif i["status"] == "expired": + status = TxStatus.FAILED + + return cls( + id=i["bolt11"], + category=TxCategory.LIGHTNING, + type=TxType.RECEIVE, + amount=amount, + time_stamp=time_stamp, + comment=i["description"], + status=status, + ) + + @classmethod + def from_cln_json_onchain_tx(cls, tx, current_block_height: int) -> "GenericTx": + confs = current_block_height - tx["blockheight"] + s = TxStatus.SUCCEEDED if confs > 0 else TxStatus.IN_FLIGHT + + print(tx["hash"]) + + for ins in tx["inputs"]: + print(f"i: {ins['index']}") + + amount = 0 + for out in tx["outputs"]: + amount += out["msat"].millisatoshis + + t = TxType.UNKNOWN + if amount > 0: + t = TxType.RECEIVE + elif amount < 0: + t = TxType.SEND + + return cls( + id=tx["hash"], + category=TxCategory.ONCHAIN, + type=t, + amount=amount, + time_stamp=0, + status=s, + comment="", + block_height=tx["blockheight"], + num_confs=confs, + ) + + @classmethod + def from_cln_json_payment(cls, payment, comment: str = "") -> "GenericTx": + status = TxStatus.UNKNOWN # “pending”, “failed”, “complete” + if payment["status"] == "pending": + status = TxStatus.IN_FLIGHT + elif payment["status"] == "complete": + status = TxStatus.SUCCEEDED + elif payment["status"] == "failed": + status = TxStatus.FAILED + + return cls( + id=payment["bolt11"], + category=TxCategory.LIGHTNING, + type=TxType.SEND, + time_stamp=payment["created_at"], + amount=-payment["amount_msat"].millisatoshis, + status=status, + total_fees=payment["amount_sent_msat"].millisatoshis + - payment["amount_msat"].millisatoshis, + comment=comment, + ) + + @classmethod + def from_cln_grpc_invoice(cls, i) -> "GenericTx": + status = TxStatus.UNKNOWN + time_stamp = i.expires_at + amount = i.amount_msat.msat + if i.status == 0: # unpaid + status = TxStatus.IN_FLIGHT + elif i.status == 1: # paid + status = TxStatus.SUCCEEDED + time_stamp = i.paid_at + amount = i.amount_received_msat.msat + elif i.status == 2: # expired + status = TxStatus.FAILED + + return cls( + id=i.bolt11, + category=TxCategory.LIGHTNING, + type=TxType.RECEIVE, + amount=amount, + time_stamp=time_stamp, + comment=i.description, + status=status, + ) + + @classmethod + def from_cln_grpc_onchain_tx( + cls, tx: OnChainTransaction, current_block_height: int + ) -> "GenericTx": + confs = current_block_height - tx.block_height + s = TxStatus.SUCCEEDED if confs > 0 else TxStatus.IN_FLIGHT + + t = TxType.SEND + if tx.total_fees == 0: + t = TxType.RECEIVE + + return cls( + id=tx.tx_hash, + category=TxCategory.ONCHAIN, + type=t, + amount=tx.amount, + time_stamp=0, + status=s, + comment="", + block_height=tx.block_height, + num_confs=confs, + ) + + @classmethod + def from_cln_grpc_payment(cls, payment, comment: str = "") -> "GenericTx": + status = TxStatus.UNKNOWN + if payment.status == 0: # pending + status = TxStatus.IN_FLIGHT + elif payment.status == 1: # failed + status = TxStatus.FAILED + elif payment.status == 2: # complete + status = TxStatus.SUCCEEDED + + return cls( + id=payment.bolt11, + category=TxCategory.LIGHTNING, + type=TxType.SEND, + time_stamp=payment.created_at, + amount=-payment.amount_msat.msat, + status=status, + total_fees=payment.amount_sent_msat.msat - payment.amount_msat.msat, + comment=comment, + ) diff --git a/app/repositories/lightning.py b/app/repositories/lightning.py index 7656800..6f652c8 100644 --- a/app/repositories/lightning.py +++ b/app/repositories/lightning.py @@ -24,47 +24,11 @@ from app.models.system import APIPlatform from app.utils import SSE, lightning_config, redis_get, send_sse_message if lightning_config.ln_node == "lnd": - from app.repositories.ln_impl.lnd import ( - add_invoice_impl, - channel_close_impl, - channel_list_impl, - channel_open_impl, - decode_pay_request_impl, - get_fee_revenue_impl, - get_ln_info_impl, - get_wallet_balance_impl, - list_all_tx_impl, - list_invoices_impl, - list_on_chain_tx_impl, - list_payments_impl, - listen_forward_events, - listen_invoices, - new_address_impl, - send_coins_impl, - send_payment_impl, - unlock_wallet_impl, - ) -else: - from app.repositories.ln_impl.clightning import ( - add_invoice_impl, - channel_close_impl, - channel_list_impl, - channel_open_impl, - decode_pay_request_impl, - get_fee_revenue_impl, - get_ln_info_impl, - get_wallet_balance_impl, - list_all_tx_impl, - list_invoices_impl, - list_on_chain_tx_impl, - list_payments_impl, - listen_forward_events, - listen_invoices, - new_address_impl, - send_coins_impl, - send_payment_impl, - unlock_wallet_impl, - ) + import app.repositories.ln_impl.lnd_grpc as ln +elif lightning_config.ln_node == "cln_grpc": + import app.repositories.ln_impl.cln_grpc as ln +elif lightning_config.ln_node == "cln_unix_socket": + import app.repositories.ln_impl.cln_unix_socket as ln GATHER_INFO_INTERVALL = config("gather_ln_info_interval", default=2, cast=float) @@ -84,24 +48,24 @@ if FWD_GATHER_INTERVAL < 0.3: async def get_ln_info_lite() -> LightningInfoLite: - ln_info = await get_ln_info_impl() - return LightningInfoLite.from_grpc(ln_info) + ln_info = await ln.get_ln_info_impl() + return LightningInfoLite.from_lninfo(ln_info) async def get_wallet_balance(): - return await get_wallet_balance_impl() + return await ln.get_wallet_balance_impl() async def list_all_tx( successfull_only: bool, index_offset: int, max_tx: int, reversed: bool ) -> List[GenericTx]: - return await list_all_tx_impl(successfull_only, index_offset, max_tx, reversed) + return await ln.list_all_tx_impl(successfull_only, index_offset, max_tx, reversed) async def list_invoices( pending_only: bool, index_offset: int, num_max_invoices: int, reversed: bool ) -> List[Invoice]: - return await list_invoices_impl( + return await ln.list_invoices_impl( pending_only, index_offset, num_max_invoices, @@ -110,13 +74,13 @@ async def list_invoices( async def list_on_chain_tx() -> List[OnChainTransaction]: - return await list_on_chain_tx_impl() + return await ln.list_on_chain_tx_impl() async def list_payments( include_incomplete: bool, index_offset: int, max_payments: int, reversed: bool ) -> List[Payment]: - return await list_payments_impl( + return await ln.list_payments_impl( include_incomplete, index_offset, max_payments, reversed ) @@ -124,19 +88,19 @@ async def list_payments( async def add_invoice( value_msat: int, memo: str = "", expiry: int = 3600, is_keysend: bool = False ) -> Invoice: - return await add_invoice_impl(memo, value_msat, expiry, is_keysend) + return await ln.add_invoice_impl(memo, value_msat, expiry, is_keysend) async def decode_pay_request(pay_req: str) -> PaymentRequest: - return await decode_pay_request_impl(pay_req) + return await ln.decode_pay_request_impl(pay_req) async def new_address(input: NewAddressInput) -> str: - return await new_address_impl(input) + return await ln.new_address_impl(input) async def send_coins(input: SendCoinsInput) -> SendCoinsResponse: - res = await send_coins_impl(input) + res = await ln.send_coins_impl(input) _schedule_wallet_balance_update() return res @@ -147,7 +111,9 @@ async def send_payment( fee_limit_msat: int, amount_msat: Optional[int] = None, ) -> Payment: - res = await send_payment_impl(pay_req, timeout_seconds, fee_limit_msat, amount_msat) + res = await ln.send_payment_impl( + pay_req, timeout_seconds, fee_limit_msat, amount_msat + ) _schedule_wallet_balance_update() return res @@ -168,29 +134,29 @@ async def channel_open( if not "@" in node_URI: raise ValueError("node_URI must contain @ with node physical address") - res = await channel_open_impl(local_funding_amount, node_URI, target_confs) + res = await ln.channel_open_impl(local_funding_amount, node_URI, target_confs) return res async def channel_list() -> List[Channel]: - res = await channel_list_impl() + res = await ln.channel_list_impl() return res async def channel_close(channel_id: int, force_close: bool) -> str: - res = await channel_close_impl(channel_id, force_close) + res = await ln.channel_close_impl(channel_id, force_close) return res async def get_ln_info() -> LnInfo: - ln_info = await get_ln_info_impl() + ln_info = await ln.get_ln_info_impl() if PLATFORM == APIPlatform.RASPIBLITZ: ln_info.identity_uri = await redis_get("ln_default_address") return ln_info async def unlock_wallet(password: str) -> bool: - res = await unlock_wallet_impl(password) + res = await ln.unlock_wallet_impl(password) if res: for l in _WALLET_UNLOCK_LISTENERS: await l.put("unlocked") @@ -198,7 +164,7 @@ async def unlock_wallet(password: str) -> bool: async def get_fee_revenue() -> FeeRevenue: - return await get_fee_revenue_impl() + return await ln.get_fee_revenue_impl() async def register_lightning_listener(): @@ -211,7 +177,7 @@ async def register_lightning_listener(): """ try: - await get_ln_info_impl() + await ln.get_ln_info_impl() loop = asyncio.get_event_loop() loop.create_task(_handle_info_listener()) @@ -245,13 +211,13 @@ async def _handle_info_listener(): last_info = None last_info_lite = None while True: - info = await get_ln_info_impl() + info = await ln.get_ln_info_impl() if last_info != info: await send_sse_message(SSE.LN_INFO, info.dict()) last_info = info - info_lite = LightningInfoLite.from_grpc(info) + info_lite = LightningInfoLite.from_lninfo(info) if last_info_lite != info_lite: await send_sse_message(SSE.LN_INFO_LITE, info_lite.dict()) @@ -261,7 +227,7 @@ async def _handle_info_listener(): async def _handle_invoice_listener(): - async for i in listen_invoices(): + async for i in ln.listen_invoices(): await send_sse_message(SSE.LN_INVOICE_STATUS, i.dict()) _schedule_wallet_balance_update() @@ -290,7 +256,7 @@ async def _handle_forward_event_listener(): _fwd_update_scheduled = False - async for i in listen_forward_events(): + async for i in ln.listen_forward_events(): if ENABLE_FWD_NOTIFICATIONS: _fwd_successes.append(i.dict()) @@ -307,7 +273,7 @@ def _schedule_wallet_balance_update(): global _wallet_balance_update_scheduled _wallet_balance_update_scheduled = True await asyncio.sleep(1.1) - wb = await get_wallet_balance_impl() + wb = await ln.get_wallet_balance_impl() if _CACHE["wallet_balance"] != wb: await send_sse_message(SSE.WALLET_BALANCE, wb.dict()) _CACHE["wallet_balance"] = wb @@ -339,7 +305,7 @@ def listen_for_ssh_unlock(): async def _do_check_unlock(): while True: try: - _ = await get_ln_info_impl() + _ = await ln.get_ln_info_impl() for l in _WALLET_UNLOCK_LISTENERS: await l.put("unlocked") break diff --git a/app/repositories/ln_impl/clightning.py b/app/repositories/ln_impl/clightning.py deleted file mode 100644 index b1df28a..0000000 --- a/app/repositories/ln_impl/clightning.py +++ /dev/null @@ -1,107 +0,0 @@ -from typing import List, Optional - -from app.models.lightning import ( - Channel, - FeeRevenue, - ForwardSuccessEvent, - GenericTx, - Invoice, - LnInfo, - NewAddressInput, - OnChainTransaction, - Payment, - PaymentRequest, - SendCoinsInput, - SendCoinsResponse, -) - - -def get_implementation_name() -> str: - return "c-lightning" - - -async def get_wallet_balance_impl(): - raise NotImplementedError("c-lightning not yet implemented") - - -async def list_all_tx_impl( - successful_only: bool, index_offset: int, max_tx: int, reversed: bool -) -> List[GenericTx]: - raise NotImplementedError("c-lightning not yet implemented") - - -async def list_invoices_impl( - pending_only: bool, index_offset: int, num_max_invoices: int, reversed: bool -): - raise NotImplementedError("c-lightning not yet implemented") - - -async def list_on_chain_tx_impl() -> List[OnChainTransaction]: - raise NotImplementedError("c-lightning not yet implemented") - - -async def list_payments_impl( - include_incomplete: bool, index_offset: int, max_payments: int, reversed: bool -): - raise NotImplementedError("c-lightning not yet implemented") - - -async def add_invoice_impl( - value_msat: int, memo: str = "", expiry: int = 3600, is_keysend: bool = False -) -> Invoice: - raise NotImplementedError("c-lightning not yet implemented") - - -async def decode_pay_request_impl(pay_req: str) -> PaymentRequest: - raise NotImplementedError("c-lightning not yet implemented") - - -async def get_fee_revenue_impl() -> FeeRevenue: - raise NotImplementedError("c-lightning not yet implemented") - - -async def new_address_impl(input: NewAddressInput) -> str: - raise NotImplementedError("c-lightning not yet implemented") - - -async def send_coins_impl(input: SendCoinsInput) -> SendCoinsResponse: - raise NotImplementedError("c-lightning not yet implemented") - - -async def send_payment_impl( - pay_req: str, - timeout_seconds: int, - fee_limit_msat: int, - amount_msat: Optional[int] = None, -) -> Payment: - raise NotImplementedError("c-lightning not yet implemented") - - -async def get_ln_info_impl() -> LnInfo: - raise NotImplementedError("c-lightning not yet implemented") - - -async def unlock_wallet_impl(password: str) -> bool: - raise NotImplementedError("c-lightning not yet implemented") - - -async def listen_invoices() -> Invoice: - raise NotImplementedError("c-lightning not yet implemented") - - -async def listen_forward_events() -> ForwardSuccessEvent: - raise NotImplementedError("c-lightning not yet implemented") - - -async def channel_open_impl( - local_funding_amount: int, node_URI: str, target_confs: int -) -> str: - raise NotImplementedError("not yet implemented") - - -async def channel_list_impl() -> List[Channel]: - raise NotImplementedError("not yet implemented") - - -async def channel_close_impl(channel_id: int, force_close: bool) -> str: - raise NotImplementedError("not yet implemented") diff --git a/app/repositories/ln_impl/cln_grpc.py b/app/repositories/ln_impl/cln_grpc.py new file mode 100644 index 0000000..18d1bd2 --- /dev/null +++ b/app/repositories/ln_impl/cln_grpc.py @@ -0,0 +1,666 @@ +import asyncio +import json +import logging +import shutil +import sqlite3 +import time +from typing import AsyncGenerator, List, Optional + +import grpc +from decouple import config +from fastapi.exceptions import HTTPException +from starlette import status + +import app.repositories.ln_impl.protos.cln.node_pb2 as ln +import app.repositories.ln_impl.protos.cln.primitives_pb2 as lnp +from app.models.lightning import ( + Channel, + FeeRevenue, + ForwardSuccessEvent, + GenericTx, + Invoice, + InvoiceState, + LnInfo, + NewAddressInput, + OnchainAddressType, + OnChainTransaction, + Payment, + PaymentRequest, + SendCoinsInput, + SendCoinsResponse, + TxStatus, + WalletBalance, +) +from app.utils import bitcoin_rpc_async +from app.utils import lightning_config as lncfg +from app.utils import next_push_id + + +async def _make_local_call(cmd: str): + # FIXME: this is a hack because some of the commands are not exposed + # in the CLN grpc interface yet. + + testnet = config("network") == "testnet" + cmd = f"lightning-cli -k {'--testnet ' if testnet else ''}{cmd}" + proc = await asyncio.create_subprocess_shell( + cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + return await proc.communicate() + + +def get_implementation_name() -> str: + return "CLN_GRPC" + + +async def get_wallet_balance_impl() -> WalletBalance: + req = ln.ListfundsRequest() + res = await lncfg.cln_stub.ListFunds(req) + onchain_confirmed = onchain_unconfirmed = onchain_total = 0 + + for o in res.outputs: + sat = o.amount_msat.msat + onchain_total += sat + if o.status == 0: + onchain_unconfirmed += sat + elif o.status == 1: + onchain_confirmed += sat + # 2 is spent => ignore + + chan_local = chan_remote = chan_pending_local = chan_pending_remote = 0 + for c in res.channels: + our_msat = c.our_amount_msat.msat + their_msat = c.amount_msat.msat - our_msat + + if c.state == 2: # ChanneldNormal + chan_local += our_msat + chan_remote += their_msat + else: + # treat everything else as pending for now + chan_pending_local += our_msat + chan_pending_remote += their_msat + + return WalletBalance( + onchain_confirmed_balance=onchain_confirmed, + onchain_total_balance=onchain_total, + onchain_unconfirmed_balance=onchain_unconfirmed, + channel_local_balance=chan_local, + channel_remote_balance=chan_remote, + # TODO: find out how to get these values with CLN + channel_unsettled_local_balance=0, + channel_unsettled_remote_balance=0, + channel_pending_open_local_balance=chan_pending_local, + channel_pending_open_remote_balance=chan_pending_remote, + ) + + +# Decoding the payment request take a long time, +# hence we build a simple cache here. +memo_cache = {} +block_cache = {} + + +async def _get_block_time(block_height: int) -> tuple: + if block_height is None or block_height < 0: + raise ValueError("block_height cannot be None or negative") + + if block_height in block_cache: + return block_cache[block_height] + + res = await bitcoin_rpc_async("getblockstats", params=[block_height]) + hash = res["result"]["blockhash"] + block = await bitcoin_rpc_async("getblock", params=[hash]) + block_cache[block_height] = (block["result"]["time"], block["result"]["mediantime"]) + return block_cache[block_height] + + +# Decoding the payment request take a long time, +# hence we build a simple cache here. +memo_cache = {} + + +async def list_all_tx_impl( + successfull_only: bool, index_offset: int, max_tx: int, reversed: bool +) -> List[GenericTx]: + list_invoice_req = ln.ListinvoicesRequest() + list_payments_req = ln.ListpaysRequest() + + try: + res = await asyncio.gather( + *[ + lncfg.cln_stub.ListInvoices(list_invoice_req), + list_on_chain_tx_impl(), + lncfg.cln_stub.ListPays(list_payments_req), + get_ln_info_impl(), + ] + ) + tx = [] + for invoice in res[0].invoices: + i = GenericTx.from_cln_grpc_invoice(invoice) + if successfull_only and i.status == TxStatus.SUCCEEDED: + tx.append(i) + continue + tx.append(i) + + for transaction in res[1]: + t = GenericTx.from_cln_grpc_onchain_tx(transaction, res[3].block_height) + if successfull_only and t.status == TxStatus.SUCCEEDED: + tx.append(t) + continue + + tx.append(t) + + for pay in res[2].pays: + comment = "" + + if pay.bolt11 in memo_cache: + comment = memo_cache[pay.bolt11] + else: + pr = await decode_pay_request_impl(pay.bolt11) + comment = pr.description + memo_cache[pay.bolt11] = pr.description + p = GenericTx.from_cln_grpc_payment(pay, comment) + + if successfull_only and p.status == TxStatus.SUCCEEDED: + tx.append(p) + continue + + tx.append(p) + + def sortKey(e: GenericTx): + return e.time_stamp + + tx.sort(key=sortKey) + + if reversed: + tx.reverse() + + l = len(tx) + for invoice in range(l): + tx[invoice].index = invoice + + if max_tx == 0: + max_tx = l + + return tx[index_offset : index_offset + max_tx] + except grpc.aio._call.AioRpcError as error: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details() + ) + + +async def list_invoices_impl( + pending_only: bool, index_offset: int, num_max_invoices: int, reversed: bool +) -> List[Invoice]: + req = ln.ListinvoicesRequest() + res = await lncfg.cln_stub.ListInvoices(req) + + tx = [] + for i in res.invoices: + if pending_only: + if i.status == 0: + tx.append(Invoice.from_cln_grpc(i)) + else: + tx.append(Invoice.from_cln_grpc(i)) + + if reversed: + tx.reverse() + + if num_max_invoices == 0 or num_max_invoices is None: + return tx + + return tx[index_offset : index_offset + num_max_invoices] + + +async def list_on_chain_tx_impl() -> List[OnChainTransaction]: + # Make a temporary copy of the file to avoid locking the db. + # CLN might want to write while we read. + info = await get_ln_info_impl() + + # FIXME(#87): Once Core Lightnings accountability plugin is available + src = "/home/admin/.lightning/testnet/lightningd.sqlite3" + dest = "/tmp/lightningd.sqlite3" + shutil.copyfile(src, dest) + + conn = sqlite3.connect(dest, uri=True) + cur = conn.execute("select * from outputs") + res = cur.fetchall() + conn.close() + + txs = [] + for o in res: + prev_out_tx = o[0].hex() + amount = o[2] + conf_block = o[9] + spent_block = o[10] + conf_time = (await _get_block_time(conf_block))[0] + txs.append( + OnChainTransaction( + tx_hash=f"prev_out_tx {prev_out_tx}", + amount=amount, + num_confirmations=info.block_height - conf_block, + block_height=conf_block, + time_stamp=conf_time, + total_fees=0, + ) + ) + + if spent_block is not None: + spent_time = (await _get_block_time(spent_block))[0] + txs.append( + OnChainTransaction( + tx_hash=f"prev_out_tx {prev_out_tx}", + amount=-amount, + num_confirmations=info.block_height - spent_block, + block_height=spent_block, + time_stamp=spent_time, + total_fees=0, + ), + ) + + return txs + + +async def list_payments_impl( + include_incomplete: bool, index_offset: int, max_payments: int, reversed: bool +): + req = ln.ListpaysRequest() + res = await lncfg.cln_stub.ListPays(req) + + pays = [] + for p in res.pays: + if p.status == 2: + # always include completed payments + pays.append(Payment.from_cln_grpc(p)) + continue + + if include_incomplete: + pays.append(Payment.from_cln_grpc(p)) + + if reversed: + pays.reverse() + + if max_payments == 0 or max_payments is None: + return pays + + return pays[index_offset : index_offset + max_payments] + + +async def add_invoice_impl( + value_msat: int, memo: str = "", expiry: int = 3600, is_keysend: bool = False +) -> Invoice: + if value_msat < 0: + raise ValueError("value_msat cannot be negative") + + msat = None + if value_msat == 0: + msat = lnp.AmountOrAny(any=True) + elif value_msat > 0: + msat = lnp.AmountOrAny(amount=lnp.Amount(msat=value_msat)) + + id = next_push_id() + req = ln.InvoiceRequest( + msatoshi=msat, + description=memo, + label=id, + expiry=expiry, + ) + + res = await lncfg.cln_stub.Invoice(req) + + return Invoice( + payment_request=res.bolt11, + memo=memo, + value_msat=value_msat, + expiry_date=res.expires_at, + add_index=id, + state=InvoiceState.OPEN, + ) + + +async def decode_pay_request_impl(pay_req: str) -> PaymentRequest: + res = await _make_local_call(f"decodepay bolt11={pay_req}") + + if not res: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Unknown CLN error decoding pay request", + ) + + if len(res) == 0: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="No response from CLN decoding pay request", + ) + + decoded = res[0].decode() + + if "Invalid bolt11: Bad bech32 string" in decoded: + raise HTTPException( + status.HTTP_400_BAD_REQUEST, detail="Invalid bolt11: Bad bech32 string" + ) + + return PaymentRequest.from_cln_json(json.loads(decoded)) + + +async def get_fee_revenue_impl() -> FeeRevenue: + # status 1 == "settled" + req = ln.ListforwardsRequest(status=1) + res = await lncfg.cln_stub.ListForwards(req) + + day = week = month = year = total = 0 + + now = time.time() + t_day = now - 86400.0 # 1 day + t_week = now - 604800.0 # 1 week + t_month = now - 2592000.0 # 1 month + t_year = now - 31536000.0 # 1 year + + # TODO: performance: cache this in redis + for f in res.forwards: + received_time = f.received_time + fee = f.fee_msat.msat + total += fee + + if received_time > t_day: + day += fee + week += fee + month += fee + year += fee + elif received_time > t_week: + week += fee + month += fee + year += fee + elif received_time > t_month: + month += fee + year += fee + elif received_time > t_year: + year += fee + + return FeeRevenue(day=day, week=week, month=month, year=year, total=total) + + +async def new_address_impl(input: NewAddressInput) -> str: + if input.type == OnchainAddressType.P2WKH: + req = ln.NewaddrRequest(addresstype=2) + res = await lncfg.cln_stub.NewAddr(req) + return res.bech32 + + req = ln.NewaddrRequest(addresstype=1) + res = await lncfg.cln_stub.NewAddr(req) + return res.p2sh_segwit + + +async def send_coins_impl(input: SendCoinsInput) -> SendCoinsResponse: + fee_rate: lnp.Feerate = None + if input.sat_per_vbyte != None and input.sat_per_vbyte > 0: + fee_rate = lnp.Feerate(perkw=input.sat_per_vbyte) + elif input.target_conf != None and input.target_conf == 1: + fee_rate = lnp.Feerate(urgent=True) + elif input.target_conf != None and input.target_conf >= 2: + fee_rate = lnp.Feerate(normal=True) + elif input.target_conf != None and input.target_conf >= 10: + fee_rate = lnp.Feerate(slow=True) + + try: + funds = await lncfg.cln_stub.ListFunds(ln.ListfundsRequest()) + if len(funds.outputs) == 0: + raise HTTPException( + status.HTTP_412_PRECONDITION_FAILED, + detail=f"Could not afford {input.amount}sat. No UTXOs available at all", + ) + + utxos = [] + max_amt = 0 + for o in funds.outputs: + utxos.append(lnp.Outpoint(txid=o.txid, outnum=o.output)) + max_amt += o.amount_msat.msat + + if max_amt <= input.amount: + raise HTTPException( + status.HTTP_412_PRECONDITION_FAILED, + detail=f"Could not afford {input.amount}sat. Not enough funds available", + ) + + req = ln.WithdrawRequest( + destination=input.address, + satoshi=lnp.AmountOrAll(amount=lnp.Amount(msat=input.amount), all=False), + minconf=input.min_confs, + feerate=fee_rate, + utxos=utxos, + ) + res = await lncfg.cln_stub.Withdraw(req) + return SendCoinsResponse.from_cln_grpc(res, input) + except grpc.aio._call.AioRpcError as error: + details = error.details() + if details and details.find("Could not parse destination address") > -1: + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + detail="Could not parse destination address, destination should be a valid address.", + ) + elif ( + details + and details.find("UTXO") > -1 + and details.find("already reserved") > -1 + ): + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Server tried to use a reserved UTXO. Please submit an issue to the BlitzAPI repository.", + ) + elif details and details.find("insufficient funds available") > -1: + raise HTTPException(status.HTTP_412_PRECONDITION_FAILED, detail=details) + else: + raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=details) + + +async def send_payment_impl( + pay_req: str, + timeout_seconds: int, + fee_limit_msat: int, + amount_msat: Optional[int] = None, +) -> Payment: + amt = lnp.Amount(msat=amount_msat) + fee_limit = lnp.Amount(msat=fee_limit_msat) + req = ln.PayRequest( + bolt11=pay_req, + msatoshi=amt, + maxfee=fee_limit, + retry_for=timeout_seconds, + ) + res = await lncfg.cln_stub.Pay(req) + return Payment.from_cln_grpc(res) + + +async def get_ln_info_impl() -> LnInfo: + req = ln.GetinfoRequest() + res = await lncfg.cln_stub.Getinfo(req) + return LnInfo.from_cln_grpc(get_implementation_name(), res) + + +async def unlock_wallet_impl(password: str) -> bool: + # Core Lightning doesn't lock wallets, + # so we don't need to do anything here + return True + + +async def listen_invoices() -> AsyncGenerator[Invoice, None]: + lastpay_index = 0 + invoices = await list_invoices_impl( + pending_only=False, + index_offset=0, + num_max_invoices=9999999999999, + reversed=False, + ) + + for i in invoices: # type Invoice + if i.state == InvoiceState.SETTLED and i.settle_index > lastpay_index: + lastpay_index = i.settle_index + + while True: + req = ln.WaitanyinvoiceRequest(lastpay_index=lastpay_index) + i = await lncfg.cln_stub.WaitAnyInvoice(req) + i = Invoice.from_cln_grpc(i) + lastpay_index = i.settle_index + yield i + + +async def listen_forward_events() -> ForwardSuccessEvent: + # CLN has no subscription to forwarded events. + # We must poll instead. + + interval = config("gather_ln_info_interval", default=2, cast=float) + + # make sure we know how many forewards we have + # we need to calculate the difference between each iteration + # status=1 == "settled" + req = ln.ListforwardsRequest(status=1) + res = await lncfg.cln_stub.ListForwards(req) + num_fwd_last_poll = len(res.forwards) + while True: + res = await lncfg.cln_stub.ListForwards(req) + if len(res.forwards) > num_fwd_last_poll: + fwds = res.forwards[num_fwd_last_poll:] + for fwd in fwds: + yield ForwardSuccessEvent.from_cln_grpc(fwd) + + num_fwd_last_poll = len(res.forwards) + await asyncio.sleep(interval - 0.1) + + +async def connect_peer_impl(node_URI: str) -> bool: + try: + id = node_URI.split("@")[0] + stdout, stderr = await _make_local_call(f"connect id={node_URI}") + if stdout: + if id in stdout.decode(): + return True + if "Connection timed out" in stdout.decode(): + raise HTTPException( + status.HTTP_504_GATEWAY_TIMEOUT, + detail="Connection establishment: Connection timed out.", + ) + if "Connection refused" in stdout.decode(): + raise HTTPException( + status.HTTP_504_GATEWAY_TIMEOUT, + detail="Connection establishment: Connection refused.", + ) + if stderr: + logging.error(stderr.decode()) + + return False + + except grpc.aio._call.AioRpcError as error: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details() + ) + + +async def channel_open_impl( + local_funding_amount: int, node_URI: str, target_confs: int +) -> str: + fee_rate = None + if target_confs == 1: + fee_rate = "urgent" + elif target_confs >= 2 and target_confs <= 9: + fee_rate = "normal" + elif target_confs >= 10: + fee_rate = "slow" + + try: + res = await connect_peer_impl(node_URI) + if not res: + raise HTTPException( + status.HTTP_408_REQUEST_TIMEOUT, + detail="Unknown error while trying to connect to peer", + ) + + cmd = f"fundchannel id={node_URI} amount={local_funding_amount} feerate={fee_rate}" + stdout, stderr = await _make_local_call(cmd) + if stdout: + o = stdout.decode() + j = json.loads(o) + if "txid" in o and "channel_id" in o: + return j["txid"] + if "Unknown peer" in o: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="We where able to connect to the peer but CLN can't find it when opening a channel.", + ) + if "Owning subdaemon openingd died" in o: + # https://github.com/ElementsProject/lightning/issues/2798#issuecomment-511205719 + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + detail="Likely the peer didn't like our channel opening proposal and disconnected from us.", + ) + if "Could not afford " in o: + raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=j["message"]) + if "Number of pending channels exceed maximum" in o: + raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=j["message"]) + + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, detail=j["message"] + ) + if stderr: + logging.error(stderr.decode()) + + return False + except grpc.aio._call.AioRpcError as error: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details() + ) + + +async def channel_list_impl() -> List[Channel]: + try: + i = await get_ln_info_impl() + req = ln.ListchannelsRequest(source=bytes.fromhex(i.identity_pubkey)) + res = await lncfg.cln_stub.ListChannels(req) + + channels = [] + for c in res.channels: + chan = Channel.from_cln_grpc(c) + channels.append(chan) + + return channels + except grpc.aio._call.AioRpcError as error: + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details() + ) + + +async def channel_close_impl(channel_id: int, force_close: bool) -> str: + try: + # on CLN we wait for 2 minutes to negotiate a channel close + # if peer doesn't respond we force close + wait_time_before_unilateral_close = 120 if force_close else 0 + req = ln.CloseRequest( + id=channel_id, + unilateraltimeout=wait_time_before_unilateral_close, + feerange=[lnp.Feerate(slow=True), lnp.Feerate(urgent=True)], + ) + res = await lncfg.cln_stub.Close(req) + + # “mutual”, “unilateral”, “unopened” + t = res.item_type + if t == 0 or t == 1: # mutual, unilateral + return res.txid.hex() + elif t == 2: # unopened + raise HTTPException( + status.HTTP_400_BAD_REQUEST, detail="Channel is not open yet." + ) + + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + detail=f"CLN returned unknown close type: {t}", + ) + except grpc.aio._call.AioRpcError as error: + if "Channel is in state AWAITING_UNILATERAL" in error.details(): + raise HTTPException( + status.HTTP_400_BAD_REQUEST, + detail="Channel is awaiting an unilateral close.", + ) + + raise HTTPException( + status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details() + ) diff --git a/app/repositories/ln_impl/cln_unix_socket.py b/app/repositories/ln_impl/cln_unix_socket.py new file mode 100644 index 0000000..935c033 --- /dev/null +++ b/app/repositories/ln_impl/cln_unix_socket.py @@ -0,0 +1,435 @@ +import asyncio +import functools +import shutil +import sqlite3 +import time +from typing import AsyncGenerator, List, Optional + +from decouple import config +from fastapi.exceptions import HTTPException +from starlette import status + +from app.models.lightning import ( + FeeRevenue, + ForwardSuccessEvent, + GenericTx, + Invoice, + InvoiceState, + LnInfo, + NewAddressInput, + OnChainTransaction, + Payment, + PaymentRequest, + SendCoinsInput, + SendCoinsResponse, + TxCategory, + TxStatus, + TxType, + WalletBalance, +) +from app.utils import bitcoin_rpc +from app.utils import lightning_config as lncfg + + +# https://gist.github.com/phizaz/20c36c6734878c6ec053245a477572ec +# pyln does not yet support asyncio, so we need to force wrap them +# with an async function. +def force_async(fn): + """ + turns a sync function to async function using threads + """ + from concurrent.futures import ThreadPoolExecutor + + pool = ThreadPoolExecutor() + + @functools.wraps(fn) + def wrapper(*args, **kwargs): + future = pool.submit(fn, *args, **kwargs) + return asyncio.wrap_future(future) # make it awaitable + + return wrapper + + +def get_implementation_name() -> str: + return "CLN_UNIX_SOCKET" + + +async def get_wallet_balance_impl(): + @force_async + def _list_funds() -> WalletBalance: + res = lncfg.cln_sock.listfunds() + onchain_confirmed = onchain_unconfirmed = onchain_total = 0 + + for o in res["outputs"]: + sat = o["value"] + onchain_total += sat + if o["status"] == "confirmed": + onchain_confirmed += sat + else: + onchain_unconfirmed += sat + + chan_local = chan_remote = chan_pending_local = chan_pending_remote = 0 + for c in res["channels"]: + our_msat = c["our_amount_msat"].millisatoshis + their_msat = c["amount_msat"].millisatoshis - our_msat + + if c["state"] == "CHANNELD_NORMAL": + chan_local += our_msat + chan_remote += their_msat + else: + chan_pending_local += our_msat + chan_pending_remote += their_msat + + return WalletBalance( + onchain_confirmed_balance=onchain_confirmed, + onchain_total_balance=onchain_total, + onchain_unconfirmed_balance=onchain_unconfirmed, + channel_local_balance=chan_local, + channel_remote_balance=chan_remote, + # TODO: find out how to get these values with CLN + channel_unsettled_local_balance=0, + channel_unsettled_remote_balance=0, + channel_pending_open_local_balance=chan_pending_local, + channel_pending_open_remote_balance=chan_pending_remote, + ) + + return await _list_funds() + + +# Decoding the payment request take a long time, +# hence we build a simple cache here. +memo_cache = {} +block_cache = {} + + +class CLNOutput: + prev_out_tx: str + prev_out_index: int + value: int + type: int + status: int + keyindex: int + channel_id: int + peer_id: str + commitment_point: str + confirmation_height: int + spend_height: int + scriptpubkey: str + reserved_til: int + option_anchor_output: int + csv_lock: int + + @classmethod + def from_db_entry(cls, entry): + pass + + +def _get_block_time(block_height: int) -> tuple: + if block_height is None or block_height < 0: + raise ValueError("block_height cannot be None or negative") + + if block_height in block_cache: + print("cache hit") + return block_cache[block_height] + + res = bitcoin_rpc("getblockstats", params=[block_height]).json() + hash = res["result"]["blockhash"] + block = bitcoin_rpc("getblock", params=[hash]).json()["result"] + block_cache[block_height] = (block["time"], block["mediantime"]) + return block_cache[block_height] + + +async def list_all_tx_impl( + successfull_only: bool, index_offset: int, max_tx: int, reversed: bool +) -> List[GenericTx]: + @force_async + def _list_invoices(): + return lncfg.cln_sock.listinvoices() + + @force_async + def _list_payments(): + return lncfg.cln_sock.listpays() + + @force_async + def _list_transactions(current_block_height: int): + # Make a temporary copy of the file to avoid locking the db. + # CLN might want to write while we read. + src = "/home/fusion44/.lightning/testnet/lightningd.sqlite3" + dest = "/tmp/lightningd.sqlite3" + shutil.copyfile(src, dest) + + conn = sqlite3.connect(dest, uri=True) + cur = conn.execute("select * from outputs") + res = cur.fetchall() + conn.close() + + txs = [] + for o in res: + amount = o[2] + conf_block = o[9] + spent_block = o[10] + conf_time = _get_block_time(conf_block)[0] + + txs.append( + GenericTx( + id="my id", + category=TxCategory.ONCHAIN, + type=TxType.RECEIVE, + amount=amount, + time_stamp=conf_time, + status=TxStatus.SUCCEEDED, + comment="", + block_height=conf_block, + num_confs=current_block_height - conf_block, + ) + ) + + if spent_block is not None: + spent_time = _get_block_time(conf_block)[0] + txs.append( + GenericTx( + id="my id", + category=TxCategory.ONCHAIN, + type=TxType.SEND, + amount=amount, + time_stamp=spent_time, + status=TxStatus.SUCCEEDED, + comment="", + block_height=spent_block, + num_confs=current_block_height - spent_block, + ) + ) + + return txs + + try: + start = time.time() + + info = await get_ln_info_impl() # for the current block height + res = await asyncio.gather( + *[ + _list_invoices(), + _list_transactions(info.block_height), + _list_payments(), + ] + ) + + tx = [] + for i in res[0]["invoices"]: + tx.append(GenericTx.from_cln_json_invoice(i)) + + # add all transactions + tx = tx + res[1] + + for p in res[2]["pays"]: + bolt11 = p["bolt11"] + comment = "" + if bolt11 in memo_cache: + comment = memo_cache[bolt11] + else: + pr = await decode_pay_request_impl(bolt11) + comment = pr.description + memo_cache[bolt11] = pr.description + tx.append(GenericTx.from_cln_json_payment(p, comment)) + + def sortKey(e: GenericTx): + return e.time_stamp + + tx.sort(key=sortKey) + + if reversed: + tx.reverse() + + l = len(tx) + for i in range(l): + tx[i].index = i + + if max_tx == 0: + max_tx = l + + end = time.time() + print("The time of execution of above program is :", end - start) + + return tx[index_offset : index_offset + max_tx] + except sqlite3.OperationalError as e: + print("Error while trying to open the database:", e) + + +async def list_invoices_impl( + pending_only: bool, index_offset: int, num_max_invoices: int, reversed: bool +) -> List[Invoice]: + # TODO: Core Lightning returns way less information about + # the invoice compared to LND. Only way to extract the data is to + # decode the pay request... seems inefficient. + # TODO: Core Lightning does not yet allow for proper paging. Cache this? + @force_async + def _list_invoices(): + return lncfg.cln_sock.listinvoices() + + res = await _list_invoices() + + tx = [] + for i in res["invoices"]: + if pending_only: + if i["status"] == "unpaid": + tx.append(Invoice.from_cln_json(i)) + else: + tx.append(Invoice.from_cln_json(i)) + + if reversed: + tx.reverse() + + if num_max_invoices == 0 or num_max_invoices is None: + return tx + + return tx[index_offset : index_offset + num_max_invoices] + + +async def list_on_chain_tx_impl() -> List[OnChainTransaction]: + raise NotImplementedError("c-lightning not yet implemented") + + +async def list_payments_impl( + include_incomplete: bool, index_offset: int, max_payments: int, reversed: bool +): + raise NotImplementedError("c-lightning not yet implemented") + + +async def add_invoice_impl( + value_msat: int, memo: str = "", expiry: int = 3600, is_keysend: bool = False +) -> Invoice: + raise NotImplementedError("c-lightning not yet implemented") + + +async def decode_pay_request_impl(pay_req: str) -> PaymentRequest: + @force_async + def _decode() -> PaymentRequest: + return PaymentRequest.from_cln_json(lncfg.cln_sock.decodepay(pay_req)) + + return await _decode() + + +async def get_fee_revenue_impl() -> FeeRevenue: + @force_async + def _get_fee_revenue() -> FeeRevenue: + res = lncfg.cln_sock.listforwards(status="settled") + day = week = month = year = total = 0 + + now = time.time() + t_day = now - 86400.0 # 1 day + t_week = now - 604800.0 # 1 week + t_month = now - 2592000.0 # 1 month + t_year = now - 31536000.0 # 1 year + + # TODO: performance: cache this in redis + for f in res["forwards"]: + resolved_time = f["resolved_time"] + fee = f["fee"] + total += fee + + if resolved_time > t_day: + day += fee + week += fee + month += fee + year += fee + elif resolved_time > t_week: + week += fee + month += fee + year += fee + elif resolved_time > t_month: + month += fee + year += fee + elif resolved_time > t_year: + year += fee + + return FeeRevenue(day=day, week=week, month=month, year=year, total=total) + + return await _get_fee_revenue() + + +async def new_address_impl(input: NewAddressInput) -> str: + raise NotImplementedError("c-lightning not yet implemented") + + +async def send_coins_impl(input: SendCoinsInput) -> SendCoinsResponse: + raise NotImplementedError("c-lightning not yet implemented") + + +async def send_payment_impl( + pay_req: str, + timeout_seconds: int, + fee_limit_msat: int, + amount_msat: Optional[int] = None, +) -> Payment: + raise NotImplementedError("c-lightning not yet implemented") + + +async def get_ln_info_impl() -> LnInfo: + @force_async + def _get_info() -> LnInfo: + res = lncfg.cln_sock.getinfo() + return LnInfo.from_cln_json(get_implementation_name(), res) + + return await _get_info() + + +async def unlock_wallet_impl(password: str) -> bool: + raise NotImplementedError("c-lightning not yet implemented") + + +async def listen_invoices() -> AsyncGenerator[Invoice, None]: + @force_async + def _wrapper(ln, last_pay_index): + "async wrapper for waitanyinvoice" + return ln.waitanyinvoice(last_pay_index) + + lastpay_index = 0 + invoices = await list_invoices_impl( + pending_only=False, + index_offset=0, + num_max_invoices=9999999999999, + reversed=False, + ) + + for i in invoices: # type Invoice + if i.state == InvoiceState.SETTLED and i.settle_index > lastpay_index: + lastpay_index = i.settle_index + + # wait for the invoices + try: + while True: + r = await _wrapper(lncfg.cln_sock, last_pay_index=lastpay_index) + r = Invoice.from_cln_json(r) + lastpay_index = r.settle_index + yield r + except TypeError as e: + raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=e) + except AttributeError as ae: + raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=ae) + + +async def listen_forward_events() -> ForwardSuccessEvent: + # CLN has no subscription to forwarded events. + # We must poll instead. + + interval = config("gather_ln_info_interval", default=2, cast=float) + if interval > 0.2: + # We don't want to poll too often, as it will slow down the + # server but we still want to be a bit quicker than the + # routine that sends the SSE messages in the lightning + # repository. + interval - 0.1 + + # make sure we know how many forewards we have + # we need to calculate the difference between each iteration + res = lncfg.cln_sock.listforwards(status="settled") + num_fwd_last_poll = len(res["forwards"]) + while True: + res = lncfg.cln_sock.listforwards(status="settled") + if len(res["forwards"]) > num_fwd_last_poll: + fwds = res["forwards"][num_fwd_last_poll:] + for fwd in fwds: + yield ForwardSuccessEvent.from_cln_json(fwd) + + num_fwd_last_poll = len(res["forwards"]) + await asyncio.sleep(interval - 0.1) diff --git a/app/repositories/ln_impl/lnd.py b/app/repositories/ln_impl/lnd_grpc.py similarity index 91% rename from app/repositories/ln_impl/lnd.py rename to app/repositories/ln_impl/lnd_grpc.py index 577ec77..06bbbfc 100644 --- a/app/repositories/ln_impl/lnd.py +++ b/app/repositories/ln_impl/lnd_grpc.py @@ -5,9 +5,9 @@ import grpc from fastapi.exceptions import HTTPException from starlette import status -import app.repositories.ln_impl.protos.lightning_pb2 as ln -import app.repositories.ln_impl.protos.router_pb2 as router -import app.repositories.ln_impl.protos.walletunlocker_pb2 as unlocker +import app.repositories.ln_impl.protos.lnd.lightning_pb2 as ln +import app.repositories.ln_impl.protos.lnd.router_pb2 as router +import app.repositories.ln_impl.protos.lnd.walletunlocker_pb2 as unlocker from app.models.lightning import ( Channel, FeeRevenue, @@ -42,7 +42,7 @@ async def get_wallet_balance_impl() -> WalletBalance: c_req = ln.ChannelBalanceRequest() channel = await lncfg.lnd_stub.ChannelBalance(c_req) - return WalletBalance.from_grpc(onchain, channel) + return WalletBalance.from_lnd_grpc(onchain, channel) except grpc.aio._call.AioRpcError as error: _check_if_locked(error) raise HTTPException( @@ -86,9 +86,9 @@ async def list_all_tx_impl( tx = [] for i in res[0].invoices: - tx.append(GenericTx.from_grpc_invoice(i)) + tx.append(GenericTx.from_lnd_grpc_invoice(i)) for t in res[1].transactions: - tx.append(GenericTx.from_grpc_onchain_tx(t)) + tx.append(GenericTx.from_lnd_grpc_onchain_tx(t)) for p in res[2].payments: comment = "" if p.payment_request in memo_cache: @@ -97,7 +97,7 @@ async def list_all_tx_impl( pr = await decode_pay_request_impl(p.payment_request) comment = pr.description memo_cache[p.payment_request] = pr.description - tx.append(GenericTx.from_grpc_payment(p, comment)) + tx.append(GenericTx.from_lnd_grpc_payment(p, comment)) def sortKey(e: GenericTx): return e.time_stamp @@ -133,7 +133,7 @@ async def list_invoices_impl( reversed=reversed, ) response = await lncfg.lnd_stub.ListInvoices(req) - return [Invoice.from_grpc(i) for i in response.invoices] + return [Invoice.from_lnd_grpc(i) for i in response.invoices] except grpc.aio._call.AioRpcError as error: _check_if_locked(error) raise HTTPException( @@ -145,7 +145,7 @@ async def list_on_chain_tx_impl() -> List[OnChainTransaction]: try: req = ln.GetTransactionsRequest() response = await lncfg.lnd_stub.GetTransactions(req) - return [OnChainTransaction.from_grpc(t) for t in response.transactions] + return [OnChainTransaction.from_lnd_grpc(t) for t in response.transactions] except grpc.aio._call.AioRpcError as error: _check_if_locked(error) raise HTTPException( @@ -164,7 +164,7 @@ async def list_payments_impl( reversed=reversed, ) response = await lncfg.lnd_stub.ListPayments(req) - return [Payment.from_grpc(p) for p in response.payments] + return [Payment.from_lnd_grpc(p) for p in response.payments] except grpc.aio._call.AioRpcError as error: _check_if_locked(error) raise HTTPException( @@ -185,7 +185,7 @@ async def add_invoice_impl( response = await lncfg.lnd_stub.AddInvoice(i) - # Can't use Invoice.from_grpc() here because + # Can't use Invoice.from_lnd_grpc() here because # the response is not a standard invoice invoice = Invoice( memo=memo, @@ -210,7 +210,7 @@ async def decode_pay_request_impl(pay_req: str) -> PaymentRequest: try: req = ln.PayReqString(pay_req=pay_req) res = await lncfg.lnd_stub.DecodePayReq(req) - return PaymentRequest.from_grpc(res) + return PaymentRequest.from_lnd_grpc(res) except grpc.aio._call.AioRpcError as error: _check_if_locked(error) if error.details() != None and error.details().find("checksum failed.") > -1: @@ -226,7 +226,7 @@ async def decode_pay_request_impl(pay_req: str) -> PaymentRequest: async def get_fee_revenue_impl() -> FeeRevenue: req = ln.FeeReportRequest() res = await lncfg.lnd_stub.FeeReport(req) - return FeeRevenue.from_grpc(res) + return FeeRevenue.from_lnd_grpc(res) async def new_address_impl(input: NewAddressInput) -> str: @@ -254,7 +254,7 @@ async def send_coins_impl(input: SendCoinsInput) -> SendCoinsResponse: ) response = await lncfg.lnd_stub.SendCoins(r) - r = SendCoinsResponse.from_grpc(response, input) + r = SendCoinsResponse.from_lnd_grpc(response, input) await send_sse_message(SSE.LN_ONCHAIN_PAYMENT_STATUS, r.dict()) return r except grpc.aio._call.AioRpcError as error: @@ -262,16 +262,13 @@ async def send_coins_impl(input: SendCoinsInput) -> SendCoinsResponse: details = error.details() if details and details.find("invalid bech32 string") > -1: raise HTTPException( - status.HTTP_400_BAD_REQUEST, detail="Invalid payment request string" + status.HTTP_400_BAD_REQUEST, + detail="Could not parse destination address, destination should be a valid address.", ) elif details and details.find("insufficient funds available") > -1: - raise HTTPException( - status.HTTP_412_PRECONDITION_FAILED, detail=error.details() - ) + raise HTTPException(status.HTTP_412_PRECONDITION_FAILED, detail=details) else: - raise HTTPException( - status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details() - ) + raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=details) async def send_payment_impl( @@ -290,7 +287,7 @@ async def send_payment_impl( p = None async for response in lncfg.router_stub.SendPaymentV2(r): - p = Payment.from_grpc(response) + p = Payment.from_lnd_grpc(response) await send_sse_message(SSE.LN_PAYMENT_STATUS, p.dict()) return p except grpc.aio._call.AioRpcError as error: @@ -341,7 +338,7 @@ async def get_ln_info_impl() -> LnInfo: try: req = ln.GetInfoRequest() response = await lncfg.lnd_stub.GetInfo(req) - return LnInfo.from_grpc(get_implementation_name(), response) + return LnInfo.from_lnd_grpc(get_implementation_name(), response) except grpc.aio._call.AioRpcError as error: _check_if_locked(error) raise HTTPException( @@ -371,7 +368,7 @@ async def listen_invoices() -> Invoice: request = ln.InvoiceSubscription() try: async for r in lncfg.lnd_stub.SubscribeInvoices(request): - yield Invoice.from_grpc(r) + yield Invoice.from_lnd_grpc(r) except grpc.aio._call.AioRpcError as error: _check_if_locked(error) raise HTTPException( @@ -493,14 +490,14 @@ async def channel_list_impl() -> List[Channel]: channels = [] for channel_grpc in response.channels: - channel = Channel.from_grpc(channel_grpc) + channel = Channel.from_lnd_grpc(channel_grpc) channel.peer_alias = await peer_resolve_alias(channel.peer_publickey) channels.append(channel) request = ln.PendingChannelsRequest() response = await lncfg.lnd_stub.PendingChannels(request) for channel_grpc in response.pending_open_channels: - channel = Channel.from_grpc_pending(channel_grpc.channel) + channel = Channel.from_lnd_grpc_pending(channel_grpc.channel) channel.peer_alias = await peer_resolve_alias(channel.peer_publickey) channels.append(channel) diff --git a/app/repositories/ln_impl/protos/__init__.py b/app/repositories/ln_impl/protos/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/repositories/ln_impl/protos/cln/README.md b/app/repositories/ln_impl/protos/cln/README.md new file mode 100644 index 0000000..3b8415e --- /dev/null +++ b/app/repositories/ln_impl/protos/cln/README.md @@ -0,0 +1,12 @@ +# Build the Python gRPC files + +Build for lightningd v0.11.0.1 + +```sh +cd ~/dev/lightning/clightning/cln-grpc/proto +poetry shell +pip install grpcio grpcio-tools googleapis-common-protos +git clone https://github.com/googleapis/googleapis.git +python -m grpc_tools.protoc --proto_path=googleapis:. --python_out=. --grpc_python_out=. primitives.proto +python -m grpc_tools.protoc --proto_path=googleapis:. --python_out=. --grpc_python_out=. node.proto +``` diff --git a/app/repositories/ln_impl/protos/cln/node_pb2.py b/app/repositories/ln_impl/protos/cln/node_pb2.py new file mode 100644 index 0000000..07a53c6 --- /dev/null +++ b/app/repositories/ln_impl/protos/cln/node_pb2.py @@ -0,0 +1,1929 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: node.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import app.repositories.ln_impl.protos.cln.primitives_pb2 as primitives__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\nnode.proto\x12\x03\x63ln\x1a\x10primitives.proto"\x10\n\x0eGetinfoRequest"\xec\x03\n\x0fGetinfoResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\r\n\x05\x61lias\x18\x02 \x01(\t\x12\r\n\x05\x63olor\x18\x03 \x01(\x0c\x12\x11\n\tnum_peers\x18\x04 \x01(\r\x12\x1c\n\x14num_pending_channels\x18\x05 \x01(\r\x12\x1b\n\x13num_active_channels\x18\x06 \x01(\r\x12\x1d\n\x15num_inactive_channels\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\rlightning_dir\x18\t \x01(\t\x12\x13\n\x0b\x62lockheight\x18\x0b \x01(\r\x12\x0f\n\x07network\x18\x0c \x01(\t\x12(\n\x13\x66\x65\x65s_collected_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x07\x61\x64\x64ress\x18\x0e \x03(\x0b\x32\x13.cln.GetinfoAddress\x12$\n\x07\x62inding\x18\x0f \x03(\x0b\x32\x13.cln.GetinfoBinding\x12"\n\x15warning_bitcoind_sync\x18\x10 \x01(\tH\x00\x88\x01\x01\x12$\n\x17warning_lightningd_sync\x18\x11 \x01(\tH\x01\x88\x01\x01\x42\x18\n\x16_warning_bitcoind_syncB\x1a\n\x18_warning_lightningd_sync"S\n\x13GetinfoOur_features\x12\x0c\n\x04init\x18\x01 \x01(\x0c\x12\x0c\n\x04node\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\x0c\x12\x0f\n\x07invoice\x18\x04 \x01(\x0c"\xd3\x01\n\x0eGetinfoAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoAddress.GetinfoAddressType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01"V\n\x12GetinfoAddressType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x12\r\n\tWEBSOCKET\x10\x05\x42\n\n\x08_address"\xfb\x01\n\x0eGetinfoBinding\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoBinding.GetinfoBindingType\x12\x14\n\x07\x61\x64\x64ress\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06socket\x18\x04 \x01(\tH\x02\x88\x01\x01"P\n\x12GetinfoBindingType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_addressB\x07\n\x05_portB\t\n\x07_socket"H\n\x10ListpeersRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\x05level\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x05\n\x03_idB\x08\n\x06_level"7\n\x11ListpeersResponse\x12"\n\x05peers\x18\x01 \x03(\x0b\x32\x13.cln.ListpeersPeers"\xb8\x01\n\x0eListpeersPeers\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x11\n\tconnected\x18\x02 \x01(\x08\x12#\n\x03log\x18\x03 \x03(\x0b\x32\x16.cln.ListpeersPeersLog\x12-\n\x08\x63hannels\x18\x04 \x03(\x0b\x32\x1b.cln.ListpeersPeersChannels\x12\x0f\n\x07netaddr\x18\x05 \x03(\t\x12\x15\n\x08\x66\x65\x61tures\x18\x06 \x01(\x0cH\x00\x88\x01\x01\x42\x0b\n\t_features"\xfd\x02\n\x11ListpeersPeersLog\x12?\n\titem_type\x18\x01 \x01(\x0e\x32,.cln.ListpeersPeersLog.ListpeersPeersLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01"i\n\x15ListpeersPeersLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data"\xd8\x15\n\x16ListpeersPeersChannels\x12\x46\n\x05state\x18\x01 \x01(\x0e\x32\x37.cln.ListpeersPeersChannels.ListpeersPeersChannelsState\x12\x19\n\x0cscratch_txid\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\x05owner\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x17\n\nchannel_id\x18\x06 \x01(\x0cH\x03\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\x07 \x01(\x0cH\x04\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x08 \x01(\rH\x05\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\t \x01(\tH\x06\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\n \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0c \x01(\rH\t\x88\x01\x01\x12\x35\n\x08inflight\x18\r \x03(\x0b\x32#.cln.ListpeersPeersChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x0e \x01(\x0cH\n\x88\x01\x01\x12\x14\n\x07private\x18\x0f \x01(\x08H\x0b\x88\x01\x01\x12 \n\x06opener\x18\x10 \x01(\x0e\x32\x10.cln.ChannelSide\x12\x10\n\x08\x66\x65\x61tures\x18\x12 \x03(\t\x12$\n\nto_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.AmountH\x0c\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.AmountH\r\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x16 \x01(\x0b\x32\x0b.cln.AmountH\x0e\x88\x01\x01\x12$\n\ntotal_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x0f\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x10\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x19 \x01(\rH\x11\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x12\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x13\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x14\x88\x01\x01\x12*\n\x10our_reserve_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12(\n\x0espendable_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12)\n\x0freceivable_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18\x30 \x01(\x0b\x32\x0b.cln.AmountH\x19\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH\x1a\x88\x01\x01\x12 \n\x13their_to_self_delay\x18! \x01(\rH\x1b\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18" \x01(\rH\x1c\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18# \x01(\rH\x1d\x88\x01\x01\x12\x0e\n\x06status\x18% \x03(\t\x12 \n\x13in_payments_offered\x18& \x01(\x04H\x1e\x88\x01\x01\x12)\n\x0fin_offered_msat\x18\' \x01(\x0b\x32\x0b.cln.AmountH\x1f\x88\x01\x01\x12"\n\x15in_payments_fulfilled\x18( \x01(\x04H \x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18) \x01(\x0b\x32\x0b.cln.AmountH!\x88\x01\x01\x12!\n\x14out_payments_offered\x18* \x01(\x04H"\x88\x01\x01\x12*\n\x10out_offered_msat\x18+ \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18, \x01(\x04H$\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12/\n\x05htlcs\x18. \x03(\x0b\x32 .cln.ListpeersPeersChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18/ \x01(\tH&\x88\x01\x01"\xa1\x02\n\x1bListpeersPeersChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\nB\x0f\n\r_scratch_txidB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addr"=\n\x1dListpeersPeersChannelsFeerate\x12\r\n\x05perkw\x18\x01 \x01(\r\x12\r\n\x05perkb\x18\x02 \x01(\r"\xc5\x01\n\x1eListpeersPeersChannelsInflight\x12\x14\n\x0c\x66unding_txid\x18\x01 \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\x02 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x03 \x01(\t\x12\'\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscratch_txid\x18\x06 \x01(\x0c"\x84\x01\n\x1dListpeersPeersChannelsFunding\x12\x1f\n\nlocal_msat\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0bremote_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0bpushed_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount"\xd2\x02\n\x1bListpeersPeersChannelsHtlcs\x12X\n\tdirection\x18\x01 \x01(\x0e\x32\x45.cln.ListpeersPeersChannelsHtlcs.ListpeersPeersChannelsHtlcsDirection\x12\n\n\x02id\x18\x02 \x01(\x04\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06\x65xpiry\x18\x04 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x01\x88\x01\x01"7\n$ListpeersPeersChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x10\n\x0e_local_trimmedB\t\n\x07_status"0\n\x10ListfundsRequest\x12\x12\n\x05spent\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_spent"e\n\x11ListfundsResponse\x12&\n\x07outputs\x18\x01 \x03(\x0b\x32\x15.cln.ListfundsOutputs\x12(\n\x08\x63hannels\x18\x02 \x03(\x0b\x32\x16.cln.ListfundsChannels"\xe3\x02\n\x10ListfundsOutputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06output\x18\x02 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptpubkey\x18\x04 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0credeemscript\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12<\n\x06status\x18\x07 \x01(\x0e\x32,.cln.ListfundsOutputs.ListfundsOutputsStatus\x12\x18\n\x0b\x62lockheight\x18\x08 \x01(\rH\x02\x88\x01\x01"C\n\x16ListfundsOutputsStatus\x12\x0f\n\x0bUNCONFIRMED\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\t\n\x05SPENT\x10\x02\x42\n\n\x08_addressB\x0f\n\r_redeemscriptB\x0e\n\x0c_blockheight"\x83\x02\n\x11ListfundsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12$\n\x0four_amount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x04 \x01(\x0c\x12\x16\n\x0e\x66unding_output\x18\x05 \x01(\r\x12\x11\n\tconnected\x18\x06 \x01(\x08\x12 \n\x05state\x18\x07 \x01(\x0e\x32\x11.cln.ChannelState\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x00\x88\x01\x01\x42\x13\n\x11_short_channel_id"\xd5\x02\n\x0eSendpayRequest\x12 \n\x05route\x18\x01 \x03(\x0b\x32\x11.cln.SendpayRoute\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12"\n\x08msatoshi\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x06 \x01(\x0cH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x19\n\x0clocalofferid\x18\x08 \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\t \x01(\x04H\x06\x88\x01\x01\x42\x08\n\x06_labelB\x0b\n\t_msatoshiB\t\n\x07_bolt11B\x11\n\x0f_payment_secretB\t\n\x07_partidB\x0f\n\r_localofferidB\n\n\x08_groupid"\xa5\x04\n\x0fSendpayResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x32\n\x06status\x18\x04 \x01(\x0e\x32".cln.SendpayResponse.SendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x14\n\x07message\x18\x0e \x01(\tH\x08\x88\x01\x01"*\n\rSendpayStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_message"Y\n\x0cSendpayRoute\x12\x1d\n\x08msatoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\n\n\x02id\x18\x02 \x01(\x0c\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\t"\x93\x01\n\x13ListchannelsRequest\x12\x1d\n\x10short_channel_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06source\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\t\n\x07_sourceB\x0e\n\x0c_destination"C\n\x14ListchannelsResponse\x12+\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x19.cln.ListchannelsChannels"\xa0\x03\n\x14ListchannelsChannels\x12\x0e\n\x06source\x18\x01 \x01(\x0c\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\x0c\x12\x18\n\x10short_channel_id\x18\x03 \x01(\t\x12\x0e\n\x06public\x18\x04 \x01(\x08\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\rmessage_flags\x18\x06 \x01(\r\x12\x15\n\rchannel_flags\x18\x07 \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x08 \x01(\x08\x12\x13\n\x0blast_update\x18\t \x01(\r\x12\x1d\n\x15\x62\x61se_fee_millisatoshi\x18\n \x01(\r\x12\x19\n\x11\x66\x65\x65_per_millionth\x18\x0b \x01(\r\x12\r\n\x05\x64\x65lay\x18\x0c \x01(\r\x12&\n\x11htlc_minimum_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x11htlc_maximum_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x0f \x01(\x0c\x42\x14\n\x12_htlc_maximum_msat"#\n\x10\x41\x64\x64gossipRequest\x12\x0f\n\x07message\x18\x01 \x01(\x0c"\x13\n\x11\x41\x64\x64gossipResponse"o\n\x17\x41utocleaninvoiceRequest\x12\x17\n\nexpired_by\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rcycle_seconds\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_expired_byB\x10\n\x0e_cycle_seconds"\x81\x01\n\x18\x41utocleaninvoiceResponse\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\nexpired_by\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rcycle_seconds\x18\x03 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_expired_byB\x10\n\x0e_cycle_seconds"U\n\x13\x43heckmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05zbase\x18\x02 \x01(\t\x12\x13\n\x06pubkey\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\t\n\x07_pubkey"H\n\x14\x43heckmessageResponse\x12\x10\n\x08verified\x18\x01 \x01(\x08\x12\x13\n\x06pubkey\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x42\t\n\x07_pubkey"\xbc\x02\n\x0c\x43loseRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1e\n\x11unilateraltimeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\tH\x01\x88\x01\x01\x12!\n\x14\x66\x65\x65_negotiation_step\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rwrong_funding\x18\x05 \x01(\x0cH\x03\x88\x01\x01\x12\x1f\n\x12\x66orce_lease_closed\x18\x06 \x01(\x08H\x04\x88\x01\x01\x12\x1e\n\x08\x66\x65\x65range\x18\x07 \x03(\x0b\x32\x0c.cln.FeerateB\x14\n\x12_unilateraltimeoutB\x0e\n\x0c_destinationB\x17\n\x15_fee_negotiation_stepB\x10\n\x0e_wrong_fundingB\x15\n\x13_force_lease_closed"\xab\x01\n\rCloseResponse\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.CloseResponse.CloseType\x12\x0f\n\x02tx\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04txid\x18\x03 \x01(\x0cH\x01\x88\x01\x01"5\n\tCloseType\x12\n\n\x06MUTUAL\x10\x00\x12\x0e\n\nUNILATERAL\x10\x01\x12\x0c\n\x08UNOPENED\x10\x02\x42\x05\n\x03_txB\x07\n\x05_txid"T\n\x0e\x43onnectRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x04host\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_hostB\x07\n\x05_port"\x8e\x01\n\x0f\x43onnectResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0c\x12\x38\n\tdirection\x18\x03 \x01(\x0e\x32%.cln.ConnectResponse.ConnectDirection"#\n\x10\x43onnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01"\xfb\x01\n\x0e\x43onnectAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.ConnectAddress.ConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01"P\n\x12\x43onnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port"J\n\x14\x43reateinvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c"\xf3\x04\n\x15\x43reateinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12>\n\x06status\x18\x06 \x01(\x0e\x32..cln.CreateinvoiceResponse.CreateinvoiceStatus\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x16\n\tpay_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x06\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\r \x01(\x0cH\x07\x88\x01\x01\x12\x17\n\npayer_note\x18\x0e \x01(\tH\x08\x88\x01\x01"8\n\x13\x43reateinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimageB\x11\n\x0f_local_offer_idB\r\n\x0b_payer_note"\xb4\x02\n\x10\x44\x61tastoreRequest\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x13\n\x06string\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x36\n\x04mode\x18\x03 \x01(\x0e\x32#.cln.DatastoreRequest.DatastoreModeH\x02\x88\x01\x01\x12\x17\n\ngeneration\x18\x04 \x01(\x04H\x03\x88\x01\x01"p\n\rDatastoreMode\x12\x0f\n\x0bMUST_CREATE\x10\x00\x12\x10\n\x0cMUST_REPLACE\x10\x01\x12\x15\n\x11\x43REATE_OR_REPLACE\x10\x02\x12\x0f\n\x0bMUST_APPEND\x10\x03\x12\x14\n\x10\x43REATE_OR_APPEND\x10\x04\x42\t\n\x07_stringB\x06\n\x04_hexB\x07\n\x05_modeB\r\n\x0b_generation"\x82\x01\n\x11\x44\x61tastoreResponse\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string"\x9d\x01\n\x12\x43reateonionRequest\x12"\n\x04hops\x18\x01 \x03(\x0b\x32\x14.cln.CreateonionHops\x12\x11\n\tassocdata\x18\x02 \x01(\x0c\x12\x18\n\x0bsession_key\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x17\n\nonion_size\x18\x04 \x01(\rH\x01\x88\x01\x01\x42\x0e\n\x0c_session_keyB\r\n\x0b_onion_size"<\n\x13\x43reateonionResponse\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12\x16\n\x0eshared_secrets\x18\x02 \x03(\x0c"2\n\x0f\x43reateonionHops\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c"J\n\x13\x44\x65ldatastoreRequest\x12\x0b\n\x03key\x18\x03 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x42\r\n\x0b_generation"\x85\x01\n\x14\x44\x65ldatastoreResponse\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string"H\n\x18\x44\x65lexpiredinvoiceRequest\x12\x1a\n\rmaxexpirytime\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\x10\n\x0e_maxexpirytime"\x1b\n\x19\x44\x65lexpiredinvoiceResponse"\xb6\x01\n\x11\x44\x65linvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\x12\x37\n\x06status\x18\x02 \x01(\x0e\x32\'.cln.DelinvoiceRequest.DelinvoiceStatus\x12\x15\n\x08\x64\x65sconly\x18\x03 \x01(\x08H\x00\x88\x01\x01"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\x0b\n\t_desconly"\xb7\x03\n\x12\x44\x65linvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x38\n\x06status\x18\x07 \x01(\x0e\x32(.cln.DelinvoiceResponse.DelinvoiceStatus\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x17\n\npayer_note\x18\n \x01(\tH\x05\x88\x01\x01"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x11\n\x0f_local_offer_idB\r\n\x0b_payer_note"\xb5\x02\n\x0eInvoiceRequest\x12"\n\x08msatoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAny\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\x12\x13\n\x06\x65xpiry\x18\x07 \x01(\x04H\x00\x88\x01\x01\x12\x11\n\tfallbacks\x18\x04 \x03(\t\x12\x15\n\x08preimage\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12"\n\x15\x65xposeprivatechannels\x18\x08 \x01(\x08H\x02\x88\x01\x01\x12\x11\n\x04\x63ltv\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x19\n\x0c\x64\x65schashonly\x18\t \x01(\x08H\x04\x88\x01\x01\x42\t\n\x07_expiryB\x0b\n\t_preimageB\x18\n\x16_exposeprivatechannelsB\x07\n\x05_cltvB\x0f\n\r_deschashonly"\xe7\x02\n\x0fInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x03 \x01(\x0c\x12\x12\n\nexpires_at\x18\x04 \x01(\x04\x12\x1d\n\x10warning_capacity\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x1c\n\x0fwarning_offline\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10warning_deadends\x18\x07 \x01(\tH\x02\x88\x01\x01\x12#\n\x16warning_private_unused\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0bwarning_mpp\x18\t \x01(\tH\x04\x88\x01\x01\x42\x13\n\x11_warning_capacityB\x12\n\x10_warning_offlineB\x13\n\x11_warning_deadendsB\x19\n\x17_warning_private_unusedB\x0e\n\x0c_warning_mpp"#\n\x14ListdatastoreRequest\x12\x0b\n\x03key\x18\x02 \x03(\t"G\n\x15ListdatastoreResponse\x12.\n\tdatastore\x18\x01 \x03(\x0b\x32\x1b.cln.ListdatastoreDatastore"\x87\x01\n\x16ListdatastoreDatastore\x12\x0b\n\x03key\x18\x01 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string"\xa9\x01\n\x13ListinvoicesRequest\x12\x12\n\x05label\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tinvstring\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08offer_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x42\x08\n\x06_labelB\x0c\n\n_invstringB\x0f\n\r_payment_hashB\x0b\n\t_offer_id"C\n\x14ListinvoicesResponse\x12+\n\x08invoices\x18\x01 \x03(\x0b\x32\x19.cln.ListinvoicesInvoices"\x94\x05\n\x14ListinvoicesInvoices\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListinvoicesInvoices.ListinvoicesInvoicesStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x17\n\npayer_note\x18\n \x01(\tH\x05\x88\x01\x01\x12\x16\n\tpay_index\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x12\x14\n\x07paid_at\x18\r \x01(\x04H\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0e \x01(\x0cH\t\x88\x01\x01"?\n\x1aListinvoicesInvoicesStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x11\n\x0f_local_offer_idB\r\n\x0b_payer_noteB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage"\xd6\x02\n\x10SendonionRequest\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\x05label\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x16\n\x0eshared_secrets\x18\x05 \x03(\x0c\x12\x13\n\x06partid\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12"\n\x08msatoshi\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x19\n\x0clocalofferid\x18\n \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x06\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\x0b\n\t_msatoshiB\x0e\n\x0c_destinationB\x0f\n\r_localofferidB\n\n\x08_groupid"\x8b\x04\n\x11SendonionResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x36\n\x06status\x18\x03 \x01(\x0e\x32&.cln.SendonionResponse.SendonionStatus\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x12\n\ncreated_at\x18\x06 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06partid\x18\r \x01(\x04H\x05\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0b \x01(\x0cH\x06\x88\x01\x01\x12\x14\n\x07message\x18\x0c \x01(\tH\x07\x88\x01\x01",\n\x0fSendonionStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\t\n\x07_partidB\x13\n\x11_payment_preimageB\n\n\x08_message"Q\n\x12SendonionFirst_hop\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r"\xeb\x01\n\x13ListsendpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12@\n\x06status\x18\x03 \x01(\x0e\x32+.cln.ListsendpaysRequest.ListsendpaysStatusH\x02\x88\x01\x01";\n\x12ListsendpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_status"C\n\x14ListsendpaysResponse\x12+\n\x08payments\x18\x01 \x03(\x0b\x32\x19.cln.ListsendpaysPayments"\xe5\x04\n\x14ListsendpaysPayments\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListsendpaysPayments.ListsendpaysPaymentsStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\n \x01(\tH\x04\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0b \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x07\x88\x01\x01\x12\x17\n\nerroronion\x18\r \x01(\x0cH\x08\x88\x01\x01"C\n\x1aListsendpaysPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\x0e\n\x0c_descriptionB\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\r\n\x0b_erroronion"\x19\n\x17ListtransactionsRequest"S\n\x18ListtransactionsResponse\x12\x37\n\x0ctransactions\x18\x01 \x03(\x0b\x32!.cln.ListtransactionsTransactions"\x9a\x02\n\x1cListtransactionsTransactions\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\r\n\x05rawtx\x18\x02 \x01(\x0c\x12\x13\n\x0b\x62lockheight\x18\x03 \x01(\r\x12\x0f\n\x07txindex\x18\x04 \x01(\r\x12\x14\n\x07\x63hannel\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x37\n\x06inputs\x18\t \x03(\x0b\x32\'.cln.ListtransactionsTransactionsInputs\x12\x39\n\x07outputs\x18\n \x03(\x0b\x32(.cln.ListtransactionsTransactionsOutputsB\n\n\x08_channel"\x84\x04\n"ListtransactionsTransactionsInputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\r\n\x05index\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\x12\x66\n\titem_type\x18\x04 \x01(\x0e\x32N.cln.ListtransactionsTransactionsInputs.ListtransactionsTransactionsInputsTypeH\x00\x88\x01\x01\x12\x14\n\x07\x63hannel\x18\x05 \x01(\tH\x01\x88\x01\x01"\x96\x02\n&ListtransactionsTransactionsInputsType\x12\n\n\x06THEIRS\x10\x00\x12\x0b\n\x07\x44\x45POSIT\x10\x01\x12\x0c\n\x08WITHDRAW\x10\x02\x12\x13\n\x0f\x43HANNEL_FUNDING\x10\x03\x12\x18\n\x14\x43HANNEL_MUTUAL_CLOSE\x10\x04\x12\x1c\n\x18\x43HANNEL_UNILATERAL_CLOSE\x10\x05\x12\x11\n\rCHANNEL_SWEEP\x10\x06\x12\x18\n\x14\x43HANNEL_HTLC_SUCCESS\x10\x07\x12\x18\n\x14\x43HANNEL_HTLC_TIMEOUT\x10\x08\x12\x13\n\x0f\x43HANNEL_PENALTY\x10\t\x12\x1c\n\x18\x43HANNEL_UNILATERAL_CHEAT\x10\nB\x0c\n\n_item_typeB\n\n\x08_channel"\x99\x04\n#ListtransactionsTransactionsOutputs\x12\r\n\x05index\x18\x01 \x01(\r\x12\x19\n\x04msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptPubKey\x18\x03 \x01(\x0c\x12h\n\titem_type\x18\x04 \x01(\x0e\x32P.cln.ListtransactionsTransactionsOutputs.ListtransactionsTransactionsOutputsTypeH\x00\x88\x01\x01\x12\x14\n\x07\x63hannel\x18\x05 \x01(\tH\x01\x88\x01\x01"\x97\x02\n\'ListtransactionsTransactionsOutputsType\x12\n\n\x06THEIRS\x10\x00\x12\x0b\n\x07\x44\x45POSIT\x10\x01\x12\x0c\n\x08WITHDRAW\x10\x02\x12\x13\n\x0f\x43HANNEL_FUNDING\x10\x03\x12\x18\n\x14\x43HANNEL_MUTUAL_CLOSE\x10\x04\x12\x1c\n\x18\x43HANNEL_UNILATERAL_CLOSE\x10\x05\x12\x11\n\rCHANNEL_SWEEP\x10\x06\x12\x18\n\x14\x43HANNEL_HTLC_SUCCESS\x10\x07\x12\x18\n\x14\x43HANNEL_HTLC_TIMEOUT\x10\x08\x12\x13\n\x0f\x43HANNEL_PENALTY\x10\t\x12\x1c\n\x18\x43HANNEL_UNILATERAL_CHEAT\x10\nB\x0c\n\n_item_typeB\n\n\x08_channel"\xd2\x03\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12"\n\x08msatoshi\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\nriskfactor\x18\x08 \x01(\x01H\x02\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x03\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x04\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x05\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x19\n\x0clocalofferid\x18\t \x01(\x0cH\x07\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\n \x03(\t\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0c \x01(\tH\t\x88\x01\x01\x42\x0b\n\t_msatoshiB\x08\n\x06_labelB\r\n\x0b_riskfactorB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\x0f\n\r_localofferidB\t\n\x07_maxfeeB\x0e\n\x0c_description"\xfb\x02\n\x0bPayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12*\n\x06status\x18\t \x01(\x0e\x32\x1a.cln.PayResponse.PayStatus"2\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion"*\n\x10ListnodesRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id"7\n\x11ListnodesResponse\x12"\n\x05nodes\x18\x01 \x03(\x0b\x32\x13.cln.ListnodesNodes"\xe1\x01\n\x0eListnodesNodes\x12\x0e\n\x06nodeid\x18\x01 \x01(\x0c\x12\x1b\n\x0elast_timestamp\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05\x63olor\x18\x04 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x05 \x01(\x0cH\x03\x88\x01\x01\x12/\n\taddresses\x18\x06 \x03(\x0b\x32\x1c.cln.ListnodesNodesAddressesB\x11\n\x0f_last_timestampB\x08\n\x06_aliasB\x08\n\x06_colorB\x0b\n\t_features"\xf7\x01\n\x17ListnodesNodesAddresses\x12K\n\titem_type\x18\x01 \x01(\x0e\x32\x38.cln.ListnodesNodesAddresses.ListnodesNodesAddressesType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01"_\n\x1bListnodesNodesAddressesType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x12\r\n\tWEBSOCKET\x10\x05\x42\n\n\x08_address"g\n\x15WaitanyinvoiceRequest\x12\x1a\n\rlastpay_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x10\n\x0e_lastpay_indexB\n\n\x08_timeout"\x93\x04\n\x16WaitanyinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12@\n\x06status\x18\x04 \x01(\x0e\x32\x30.cln.WaitanyinvoiceResponse.WaitanyinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x06\x88\x01\x01"-\n\x14WaitanyinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage"#\n\x12WaitinvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t"\x87\x04\n\x13WaitinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitinvoiceResponse.WaitinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x03\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x05\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x06\x88\x01\x01"*\n\x11WaitinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x13\n\x11_payment_preimage"\x8e\x01\n\x12WaitsendpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x14\n\x07timeout\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06partid\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x02\x88\x01\x01\x42\n\n\x08_timeoutB\t\n\x07_partidB\n\n\x08_groupid"\x86\x04\n\x13WaitsendpayResponse\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitsendpayResponse.WaitsendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x04\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\x07\x88\x01\x01"!\n\x11WaitsendpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimage"\x9e\x01\n\x0eNewaddrRequest\x12@\n\x0b\x61\x64\x64resstype\x18\x01 \x01(\x0e\x32&.cln.NewaddrRequest.NewaddrAddresstypeH\x00\x88\x01\x01":\n\x12NewaddrAddresstype\x12\n\n\x06\x42\x45\x43H32\x10\x00\x12\x0f\n\x0bP2SH_SEGWIT\x10\x01\x12\x07\n\x03\x41LL\x10\x02\x42\x0e\n\x0c_addresstype"[\n\x0fNewaddrResponse\x12\x13\n\x06\x62\x65\x63h32\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bp2sh_segwit\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_bech32B\x0e\n\x0c_p2sh_segwit"\xca\x01\n\x0fWithdrawRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\t\x12&\n\x07satoshi\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAllH\x00\x88\x01\x01\x12"\n\x07\x66\x65\x65rate\x18\x05 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_satoshiB\n\n\x08_feerateB\n\n\x08_minconf":\n\x10WithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0c\n\x04psbt\x18\x03 \x01(\t"\xc9\x02\n\x0eKeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12\x1d\n\x08msatoshi\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12+\n\nroutehints\x18\x08 \x01(\x0b\x32\x12.cln.RoutehintListH\x05\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_routehints"\xf2\x02\n\x0fKeysendResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x32\n\x06status\x18\t \x01(\x0e\x32".cln.KeysendResponse.KeysendStatus"\x1d\n\rKeysendStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion"\x12\n\x10KeysendExtratlvs"\xb7\x02\n\x0f\x46undpsbtRequest\x12\x1c\n\x07satoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x14\n\x07minconf\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\x08 \x01(\x08H\x04\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_change"\xd9\x01\n\x10\x46undpsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.FundpsbtReservationsB\x10\n\x0e_change_outnum"u\n\x14\x46undpsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r"A\n\x0fSendpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\n\n\x08_reserve",\n\x10SendpsbtResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c"1\n\x0fSignpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x10\n\x08signonly\x18\x02 \x03(\r"\'\n\x10SignpsbtResponse\x12\x13\n\x0bsigned_psbt\x18\x01 \x01(\t"\xdb\x02\n\x0fUtxopsbtRequest\x12\x1c\n\x07satoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x17\n\nreservedok\x18\x08 \x01(\x08H\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\t \x01(\x08H\x04\x88\x01\x01\x42\n\n\x08_reserveB\r\n\x0b_reservedokB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_change"\xd9\x01\n\x10UtxopsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.UtxopsbtReservationsB\x10\n\x0e_change_outnum"u\n\x14UtxopsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r" \n\x10TxdiscardRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c"6\n\x11TxdiscardResponse\x12\x13\n\x0bunsigned_tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c"\xa4\x01\n\x10TxprepareRequest\x12 \n\x07outputs\x18\x05 \x03(\x0b\x32\x0f.cln.OutputDesc\x12"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_feerateB\n\n\x08_minconf"D\n\x11TxprepareResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x13\n\x0bunsigned_tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c"\x1d\n\rTxsendRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c"8\n\x0eTxsendResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c"=\n\x11\x44isconnectRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x66orce\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_force"\x14\n\x12\x44isconnectResponse"k\n\x0f\x46\x65\x65ratesRequest\x12\x31\n\x05style\x18\x01 \x01(\x0e\x32".cln.FeeratesRequest.FeeratesStyle"%\n\rFeeratesStyle\x12\t\n\x05PERKB\x10\x00\x12\t\n\x05PERKW\x10\x01"V\n\x10\x46\x65\x65ratesResponse\x12%\n\x18warning_missing_feerates\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x1b\n\x19_warning_missing_feerates"\xc3\x02\n\rFeeratesPerkb\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x14\n\x07opening\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x05\x88\x01\x01\x42\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penalty"\xc3\x02\n\rFeeratesPerkw\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x14\n\x07opening\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x03\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x05\x88\x01\x01\x42\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penalty"\xc1\x01\n\x1d\x46\x65\x65ratesOnchain_fee_estimates\x12 \n\x18opening_channel_satoshis\x18\x01 \x01(\x04\x12\x1d\n\x15mutual_close_satoshis\x18\x02 \x01(\x04\x12!\n\x19unilateral_close_satoshis\x18\x03 \x01(\x04\x12\x1d\n\x15htlc_timeout_satoshis\x18\x04 \x01(\x04\x12\x1d\n\x15htlc_success_satoshis\x18\x05 \x01(\x04"\xe9\x01\n\x0fGetrouteRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x1d\n\x08msatoshi\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\nriskfactor\x18\x03 \x01(\x04\x12\x11\n\x04\x63ltv\x18\x04 \x01(\x01H\x00\x88\x01\x01\x12\x13\n\x06\x66romid\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x66uzzpercent\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\x07 \x03(\t\x12\x14\n\x07maxhops\x18\x08 \x01(\rH\x03\x88\x01\x01\x42\x07\n\x05_cltvB\t\n\x07_fromidB\x0e\n\x0c_fuzzpercentB\n\n\x08_maxhops"5\n\x10GetrouteResponse\x12!\n\x05route\x18\x01 \x03(\x0b\x32\x12.cln.GetrouteRoute"\xc5\x01\n\rGetrouteRoute\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\t\x12\x11\n\tdirection\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x05 \x01(\r\x12\x34\n\x05style\x18\x06 \x01(\x0e\x32%.cln.GetrouteRoute.GetrouteRouteStyle"\x1d\n\x12GetrouteRouteStyle\x12\x07\n\x03TLV\x10\x00"\x82\x02\n\x13ListforwardsRequest\x12@\n\x06status\x18\x01 \x01(\x0e\x32+.cln.ListforwardsRequest.ListforwardsStatusH\x00\x88\x01\x01\x12\x17\n\nin_channel\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x03 \x01(\tH\x02\x88\x01\x01"L\n\x12ListforwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\x42\t\n\x07_statusB\r\n\x0b_in_channelB\x0e\n\x0c_out_channel"C\n\x14ListforwardsResponse\x12+\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x19.cln.ListforwardsForwards"\xb8\x04\n\x14ListforwardsForwards\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x1c\n\x07in_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x44\n\x06status\x18\x03 \x01(\x0e\x32\x34.cln.ListforwardsForwards.ListforwardsForwardsStatus\x12\x15\n\rreceived_time\x18\x04 \x01(\x01\x12\x18\n\x0bout_channel\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12G\n\x05style\x18\t \x01(\x0e\x32\x33.cln.ListforwardsForwards.ListforwardsForwardsStyleH\x02\x88\x01\x01\x12"\n\x08\x66\x65\x65_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12"\n\x08out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01"T\n\x1aListforwardsForwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03"0\n\x19ListforwardsForwardsStyle\x12\n\n\x06LEGACY\x10\x00\x12\x07\n\x03TLV\x10\x01\x42\x0e\n\x0c_out_channelB\x0f\n\r_payment_hashB\x08\n\x06_styleB\x0b\n\t_fee_msatB\x0b\n\t_out_msat"\xdb\x01\n\x0fListpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x38\n\x06status\x18\x03 \x01(\x0e\x32#.cln.ListpaysRequest.ListpaysStatusH\x02\x88\x01\x01"7\n\x0eListpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_status"3\n\x10ListpaysResponse\x12\x1f\n\x04pays\x18\x01 \x03(\x0b\x32\x11.cln.ListpaysPays"\xfd\x03\n\x0cListpaysPays\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x34\n\x06status\x18\x02 \x01(\x0e\x32$.cln.ListpaysPays.ListpaysPaysStatus\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\ncreated_at\x18\x04 \x01(\x04\x12\x12\n\x05label\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0b \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x04\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12*\n\x10\x61mount_sent_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x17\n\nerroronion\x18\n \x01(\x0cH\x07\x88\x01\x01";\n\x12ListpaysPaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\x0e\n\x0c_descriptionB\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x13\n\x11_amount_sent_msatB\r\n\x0b_erroronion"Y\n\x0bPingRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x03len\x18\x02 \x01(\x01H\x00\x88\x01\x01\x12\x16\n\tpongbytes\x18\x03 \x01(\x01H\x01\x88\x01\x01\x42\x06\n\x04_lenB\x0c\n\n_pongbytes"\x1e\n\x0cPingResponse\x12\x0e\n\x06totlen\x18\x01 \x01(\r"%\n\x12SignmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t"F\n\x13SignmessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\r\n\x05recid\x18\x02 \x01(\x0c\x12\r\n\x05zbase\x18\x03 \x01(\t2\xfd\x15\n\x04Node\x12\x36\n\x07Getinfo\x12\x13.cln.GetinfoRequest\x1a\x14.cln.GetinfoResponse"\x00\x12<\n\tListPeers\x12\x15.cln.ListpeersRequest\x1a\x16.cln.ListpeersResponse"\x00\x12<\n\tListFunds\x12\x15.cln.ListfundsRequest\x1a\x16.cln.ListfundsResponse"\x00\x12\x36\n\x07SendPay\x12\x13.cln.SendpayRequest\x1a\x14.cln.SendpayResponse"\x00\x12\x45\n\x0cListChannels\x12\x18.cln.ListchannelsRequest\x1a\x19.cln.ListchannelsResponse"\x00\x12<\n\tAddGossip\x12\x15.cln.AddgossipRequest\x1a\x16.cln.AddgossipResponse"\x00\x12Q\n\x10\x41utoCleanInvoice\x12\x1c.cln.AutocleaninvoiceRequest\x1a\x1d.cln.AutocleaninvoiceResponse"\x00\x12\x45\n\x0c\x43heckMessage\x12\x18.cln.CheckmessageRequest\x1a\x19.cln.CheckmessageResponse"\x00\x12\x30\n\x05\x43lose\x12\x11.cln.CloseRequest\x1a\x12.cln.CloseResponse"\x00\x12:\n\x0b\x43onnectPeer\x12\x13.cln.ConnectRequest\x1a\x14.cln.ConnectResponse"\x00\x12H\n\rCreateInvoice\x12\x19.cln.CreateinvoiceRequest\x1a\x1a.cln.CreateinvoiceResponse"\x00\x12<\n\tDatastore\x12\x15.cln.DatastoreRequest\x1a\x16.cln.DatastoreResponse"\x00\x12\x42\n\x0b\x43reateOnion\x12\x17.cln.CreateonionRequest\x1a\x18.cln.CreateonionResponse"\x00\x12\x45\n\x0c\x44\x65lDatastore\x12\x18.cln.DeldatastoreRequest\x1a\x19.cln.DeldatastoreResponse"\x00\x12T\n\x11\x44\x65lExpiredInvoice\x12\x1d.cln.DelexpiredinvoiceRequest\x1a\x1e.cln.DelexpiredinvoiceResponse"\x00\x12?\n\nDelInvoice\x12\x16.cln.DelinvoiceRequest\x1a\x17.cln.DelinvoiceResponse"\x00\x12\x36\n\x07Invoice\x12\x13.cln.InvoiceRequest\x1a\x14.cln.InvoiceResponse"\x00\x12H\n\rListDatastore\x12\x19.cln.ListdatastoreRequest\x1a\x1a.cln.ListdatastoreResponse"\x00\x12\x45\n\x0cListInvoices\x12\x18.cln.ListinvoicesRequest\x1a\x19.cln.ListinvoicesResponse"\x00\x12<\n\tSendOnion\x12\x15.cln.SendonionRequest\x1a\x16.cln.SendonionResponse"\x00\x12\x45\n\x0cListSendPays\x12\x18.cln.ListsendpaysRequest\x1a\x19.cln.ListsendpaysResponse"\x00\x12Q\n\x10ListTransactions\x12\x1c.cln.ListtransactionsRequest\x1a\x1d.cln.ListtransactionsResponse"\x00\x12*\n\x03Pay\x12\x0f.cln.PayRequest\x1a\x10.cln.PayResponse"\x00\x12<\n\tListNodes\x12\x15.cln.ListnodesRequest\x1a\x16.cln.ListnodesResponse"\x00\x12K\n\x0eWaitAnyInvoice\x12\x1a.cln.WaitanyinvoiceRequest\x1a\x1b.cln.WaitanyinvoiceResponse"\x00\x12\x42\n\x0bWaitInvoice\x12\x17.cln.WaitinvoiceRequest\x1a\x18.cln.WaitinvoiceResponse"\x00\x12\x42\n\x0bWaitSendPay\x12\x17.cln.WaitsendpayRequest\x1a\x18.cln.WaitsendpayResponse"\x00\x12\x36\n\x07NewAddr\x12\x13.cln.NewaddrRequest\x1a\x14.cln.NewaddrResponse"\x00\x12\x39\n\x08Withdraw\x12\x14.cln.WithdrawRequest\x1a\x15.cln.WithdrawResponse"\x00\x12\x36\n\x07KeySend\x12\x13.cln.KeysendRequest\x1a\x14.cln.KeysendResponse"\x00\x12\x39\n\x08\x46undPsbt\x12\x14.cln.FundpsbtRequest\x1a\x15.cln.FundpsbtResponse"\x00\x12\x39\n\x08SendPsbt\x12\x14.cln.SendpsbtRequest\x1a\x15.cln.SendpsbtResponse"\x00\x12\x39\n\x08SignPsbt\x12\x14.cln.SignpsbtRequest\x1a\x15.cln.SignpsbtResponse"\x00\x12\x39\n\x08UtxoPsbt\x12\x14.cln.UtxopsbtRequest\x1a\x15.cln.UtxopsbtResponse"\x00\x12<\n\tTxDiscard\x12\x15.cln.TxdiscardRequest\x1a\x16.cln.TxdiscardResponse"\x00\x12<\n\tTxPrepare\x12\x15.cln.TxprepareRequest\x1a\x16.cln.TxprepareResponse"\x00\x12\x33\n\x06TxSend\x12\x12.cln.TxsendRequest\x1a\x13.cln.TxsendResponse"\x00\x12?\n\nDisconnect\x12\x16.cln.DisconnectRequest\x1a\x17.cln.DisconnectResponse"\x00\x12\x39\n\x08\x46\x65\x65rates\x12\x14.cln.FeeratesRequest\x1a\x15.cln.FeeratesResponse"\x00\x12\x39\n\x08GetRoute\x12\x14.cln.GetrouteRequest\x1a\x15.cln.GetrouteResponse"\x00\x12\x45\n\x0cListForwards\x12\x18.cln.ListforwardsRequest\x1a\x19.cln.ListforwardsResponse"\x00\x12\x39\n\x08ListPays\x12\x14.cln.ListpaysRequest\x1a\x15.cln.ListpaysResponse"\x00\x12-\n\x04Ping\x12\x10.cln.PingRequest\x1a\x11.cln.PingResponse"\x00\x12\x42\n\x0bSignMessage\x12\x17.cln.SignmessageRequest\x1a\x18.cln.SignmessageResponse"\x00\x62\x06proto3' +) + + +_GETINFOREQUEST = DESCRIPTOR.message_types_by_name["GetinfoRequest"] +_GETINFORESPONSE = DESCRIPTOR.message_types_by_name["GetinfoResponse"] +_GETINFOOUR_FEATURES = DESCRIPTOR.message_types_by_name["GetinfoOur_features"] +_GETINFOADDRESS = DESCRIPTOR.message_types_by_name["GetinfoAddress"] +_GETINFOBINDING = DESCRIPTOR.message_types_by_name["GetinfoBinding"] +_LISTPEERSREQUEST = DESCRIPTOR.message_types_by_name["ListpeersRequest"] +_LISTPEERSRESPONSE = DESCRIPTOR.message_types_by_name["ListpeersResponse"] +_LISTPEERSPEERS = DESCRIPTOR.message_types_by_name["ListpeersPeers"] +_LISTPEERSPEERSLOG = DESCRIPTOR.message_types_by_name["ListpeersPeersLog"] +_LISTPEERSPEERSCHANNELS = DESCRIPTOR.message_types_by_name["ListpeersPeersChannels"] +_LISTPEERSPEERSCHANNELSFEERATE = DESCRIPTOR.message_types_by_name[ + "ListpeersPeersChannelsFeerate" +] +_LISTPEERSPEERSCHANNELSINFLIGHT = DESCRIPTOR.message_types_by_name[ + "ListpeersPeersChannelsInflight" +] +_LISTPEERSPEERSCHANNELSFUNDING = DESCRIPTOR.message_types_by_name[ + "ListpeersPeersChannelsFunding" +] +_LISTPEERSPEERSCHANNELSHTLCS = DESCRIPTOR.message_types_by_name[ + "ListpeersPeersChannelsHtlcs" +] +_LISTFUNDSREQUEST = DESCRIPTOR.message_types_by_name["ListfundsRequest"] +_LISTFUNDSRESPONSE = DESCRIPTOR.message_types_by_name["ListfundsResponse"] +_LISTFUNDSOUTPUTS = DESCRIPTOR.message_types_by_name["ListfundsOutputs"] +_LISTFUNDSCHANNELS = DESCRIPTOR.message_types_by_name["ListfundsChannels"] +_SENDPAYREQUEST = DESCRIPTOR.message_types_by_name["SendpayRequest"] +_SENDPAYRESPONSE = DESCRIPTOR.message_types_by_name["SendpayResponse"] +_SENDPAYROUTE = DESCRIPTOR.message_types_by_name["SendpayRoute"] +_LISTCHANNELSREQUEST = DESCRIPTOR.message_types_by_name["ListchannelsRequest"] +_LISTCHANNELSRESPONSE = DESCRIPTOR.message_types_by_name["ListchannelsResponse"] +_LISTCHANNELSCHANNELS = DESCRIPTOR.message_types_by_name["ListchannelsChannels"] +_ADDGOSSIPREQUEST = DESCRIPTOR.message_types_by_name["AddgossipRequest"] +_ADDGOSSIPRESPONSE = DESCRIPTOR.message_types_by_name["AddgossipResponse"] +_AUTOCLEANINVOICEREQUEST = DESCRIPTOR.message_types_by_name["AutocleaninvoiceRequest"] +_AUTOCLEANINVOICERESPONSE = DESCRIPTOR.message_types_by_name["AutocleaninvoiceResponse"] +_CHECKMESSAGEREQUEST = DESCRIPTOR.message_types_by_name["CheckmessageRequest"] +_CHECKMESSAGERESPONSE = DESCRIPTOR.message_types_by_name["CheckmessageResponse"] +_CLOSEREQUEST = DESCRIPTOR.message_types_by_name["CloseRequest"] +_CLOSERESPONSE = DESCRIPTOR.message_types_by_name["CloseResponse"] +_CONNECTREQUEST = DESCRIPTOR.message_types_by_name["ConnectRequest"] +_CONNECTRESPONSE = DESCRIPTOR.message_types_by_name["ConnectResponse"] +_CONNECTADDRESS = DESCRIPTOR.message_types_by_name["ConnectAddress"] +_CREATEINVOICEREQUEST = DESCRIPTOR.message_types_by_name["CreateinvoiceRequest"] +_CREATEINVOICERESPONSE = DESCRIPTOR.message_types_by_name["CreateinvoiceResponse"] +_DATASTOREREQUEST = DESCRIPTOR.message_types_by_name["DatastoreRequest"] +_DATASTORERESPONSE = DESCRIPTOR.message_types_by_name["DatastoreResponse"] +_CREATEONIONREQUEST = DESCRIPTOR.message_types_by_name["CreateonionRequest"] +_CREATEONIONRESPONSE = DESCRIPTOR.message_types_by_name["CreateonionResponse"] +_CREATEONIONHOPS = DESCRIPTOR.message_types_by_name["CreateonionHops"] +_DELDATASTOREREQUEST = DESCRIPTOR.message_types_by_name["DeldatastoreRequest"] +_DELDATASTORERESPONSE = DESCRIPTOR.message_types_by_name["DeldatastoreResponse"] +_DELEXPIREDINVOICEREQUEST = DESCRIPTOR.message_types_by_name["DelexpiredinvoiceRequest"] +_DELEXPIREDINVOICERESPONSE = DESCRIPTOR.message_types_by_name[ + "DelexpiredinvoiceResponse" +] +_DELINVOICEREQUEST = DESCRIPTOR.message_types_by_name["DelinvoiceRequest"] +_DELINVOICERESPONSE = DESCRIPTOR.message_types_by_name["DelinvoiceResponse"] +_INVOICEREQUEST = DESCRIPTOR.message_types_by_name["InvoiceRequest"] +_INVOICERESPONSE = DESCRIPTOR.message_types_by_name["InvoiceResponse"] +_LISTDATASTOREREQUEST = DESCRIPTOR.message_types_by_name["ListdatastoreRequest"] +_LISTDATASTORERESPONSE = DESCRIPTOR.message_types_by_name["ListdatastoreResponse"] +_LISTDATASTOREDATASTORE = DESCRIPTOR.message_types_by_name["ListdatastoreDatastore"] +_LISTINVOICESREQUEST = DESCRIPTOR.message_types_by_name["ListinvoicesRequest"] +_LISTINVOICESRESPONSE = DESCRIPTOR.message_types_by_name["ListinvoicesResponse"] +_LISTINVOICESINVOICES = DESCRIPTOR.message_types_by_name["ListinvoicesInvoices"] +_SENDONIONREQUEST = DESCRIPTOR.message_types_by_name["SendonionRequest"] +_SENDONIONRESPONSE = DESCRIPTOR.message_types_by_name["SendonionResponse"] +_SENDONIONFIRST_HOP = DESCRIPTOR.message_types_by_name["SendonionFirst_hop"] +_LISTSENDPAYSREQUEST = DESCRIPTOR.message_types_by_name["ListsendpaysRequest"] +_LISTSENDPAYSRESPONSE = DESCRIPTOR.message_types_by_name["ListsendpaysResponse"] +_LISTSENDPAYSPAYMENTS = DESCRIPTOR.message_types_by_name["ListsendpaysPayments"] +_LISTTRANSACTIONSREQUEST = DESCRIPTOR.message_types_by_name["ListtransactionsRequest"] +_LISTTRANSACTIONSRESPONSE = DESCRIPTOR.message_types_by_name["ListtransactionsResponse"] +_LISTTRANSACTIONSTRANSACTIONS = DESCRIPTOR.message_types_by_name[ + "ListtransactionsTransactions" +] +_LISTTRANSACTIONSTRANSACTIONSINPUTS = DESCRIPTOR.message_types_by_name[ + "ListtransactionsTransactionsInputs" +] +_LISTTRANSACTIONSTRANSACTIONSOUTPUTS = DESCRIPTOR.message_types_by_name[ + "ListtransactionsTransactionsOutputs" +] +_PAYREQUEST = DESCRIPTOR.message_types_by_name["PayRequest"] +_PAYRESPONSE = DESCRIPTOR.message_types_by_name["PayResponse"] +_LISTNODESREQUEST = DESCRIPTOR.message_types_by_name["ListnodesRequest"] +_LISTNODESRESPONSE = DESCRIPTOR.message_types_by_name["ListnodesResponse"] +_LISTNODESNODES = DESCRIPTOR.message_types_by_name["ListnodesNodes"] +_LISTNODESNODESADDRESSES = DESCRIPTOR.message_types_by_name["ListnodesNodesAddresses"] +_WAITANYINVOICEREQUEST = DESCRIPTOR.message_types_by_name["WaitanyinvoiceRequest"] +_WAITANYINVOICERESPONSE = DESCRIPTOR.message_types_by_name["WaitanyinvoiceResponse"] +_WAITINVOICEREQUEST = DESCRIPTOR.message_types_by_name["WaitinvoiceRequest"] +_WAITINVOICERESPONSE = DESCRIPTOR.message_types_by_name["WaitinvoiceResponse"] +_WAITSENDPAYREQUEST = DESCRIPTOR.message_types_by_name["WaitsendpayRequest"] +_WAITSENDPAYRESPONSE = DESCRIPTOR.message_types_by_name["WaitsendpayResponse"] +_NEWADDRREQUEST = DESCRIPTOR.message_types_by_name["NewaddrRequest"] +_NEWADDRRESPONSE = DESCRIPTOR.message_types_by_name["NewaddrResponse"] +_WITHDRAWREQUEST = DESCRIPTOR.message_types_by_name["WithdrawRequest"] +_WITHDRAWRESPONSE = DESCRIPTOR.message_types_by_name["WithdrawResponse"] +_KEYSENDREQUEST = DESCRIPTOR.message_types_by_name["KeysendRequest"] +_KEYSENDRESPONSE = DESCRIPTOR.message_types_by_name["KeysendResponse"] +_KEYSENDEXTRATLVS = DESCRIPTOR.message_types_by_name["KeysendExtratlvs"] +_FUNDPSBTREQUEST = DESCRIPTOR.message_types_by_name["FundpsbtRequest"] +_FUNDPSBTRESPONSE = DESCRIPTOR.message_types_by_name["FundpsbtResponse"] +_FUNDPSBTRESERVATIONS = DESCRIPTOR.message_types_by_name["FundpsbtReservations"] +_SENDPSBTREQUEST = DESCRIPTOR.message_types_by_name["SendpsbtRequest"] +_SENDPSBTRESPONSE = DESCRIPTOR.message_types_by_name["SendpsbtResponse"] +_SIGNPSBTREQUEST = DESCRIPTOR.message_types_by_name["SignpsbtRequest"] +_SIGNPSBTRESPONSE = DESCRIPTOR.message_types_by_name["SignpsbtResponse"] +_UTXOPSBTREQUEST = DESCRIPTOR.message_types_by_name["UtxopsbtRequest"] +_UTXOPSBTRESPONSE = DESCRIPTOR.message_types_by_name["UtxopsbtResponse"] +_UTXOPSBTRESERVATIONS = DESCRIPTOR.message_types_by_name["UtxopsbtReservations"] +_TXDISCARDREQUEST = DESCRIPTOR.message_types_by_name["TxdiscardRequest"] +_TXDISCARDRESPONSE = DESCRIPTOR.message_types_by_name["TxdiscardResponse"] +_TXPREPAREREQUEST = DESCRIPTOR.message_types_by_name["TxprepareRequest"] +_TXPREPARERESPONSE = DESCRIPTOR.message_types_by_name["TxprepareResponse"] +_TXSENDREQUEST = DESCRIPTOR.message_types_by_name["TxsendRequest"] +_TXSENDRESPONSE = DESCRIPTOR.message_types_by_name["TxsendResponse"] +_DISCONNECTREQUEST = DESCRIPTOR.message_types_by_name["DisconnectRequest"] +_DISCONNECTRESPONSE = DESCRIPTOR.message_types_by_name["DisconnectResponse"] +_FEERATESREQUEST = DESCRIPTOR.message_types_by_name["FeeratesRequest"] +_FEERATESRESPONSE = DESCRIPTOR.message_types_by_name["FeeratesResponse"] +_FEERATESPERKB = DESCRIPTOR.message_types_by_name["FeeratesPerkb"] +_FEERATESPERKW = DESCRIPTOR.message_types_by_name["FeeratesPerkw"] +_FEERATESONCHAIN_FEE_ESTIMATES = DESCRIPTOR.message_types_by_name[ + "FeeratesOnchain_fee_estimates" +] +_GETROUTEREQUEST = DESCRIPTOR.message_types_by_name["GetrouteRequest"] +_GETROUTERESPONSE = DESCRIPTOR.message_types_by_name["GetrouteResponse"] +_GETROUTEROUTE = DESCRIPTOR.message_types_by_name["GetrouteRoute"] +_LISTFORWARDSREQUEST = DESCRIPTOR.message_types_by_name["ListforwardsRequest"] +_LISTFORWARDSRESPONSE = DESCRIPTOR.message_types_by_name["ListforwardsResponse"] +_LISTFORWARDSFORWARDS = DESCRIPTOR.message_types_by_name["ListforwardsForwards"] +_LISTPAYSREQUEST = DESCRIPTOR.message_types_by_name["ListpaysRequest"] +_LISTPAYSRESPONSE = DESCRIPTOR.message_types_by_name["ListpaysResponse"] +_LISTPAYSPAYS = DESCRIPTOR.message_types_by_name["ListpaysPays"] +_PINGREQUEST = DESCRIPTOR.message_types_by_name["PingRequest"] +_PINGRESPONSE = DESCRIPTOR.message_types_by_name["PingResponse"] +_SIGNMESSAGEREQUEST = DESCRIPTOR.message_types_by_name["SignmessageRequest"] +_SIGNMESSAGERESPONSE = DESCRIPTOR.message_types_by_name["SignmessageResponse"] +_GETINFOADDRESS_GETINFOADDRESSTYPE = _GETINFOADDRESS.enum_types_by_name[ + "GetinfoAddressType" +] +_GETINFOBINDING_GETINFOBINDINGTYPE = _GETINFOBINDING.enum_types_by_name[ + "GetinfoBindingType" +] +_LISTPEERSPEERSLOG_LISTPEERSPEERSLOGTYPE = _LISTPEERSPEERSLOG.enum_types_by_name[ + "ListpeersPeersLogType" +] +_LISTPEERSPEERSCHANNELS_LISTPEERSPEERSCHANNELSSTATE = ( + _LISTPEERSPEERSCHANNELS.enum_types_by_name["ListpeersPeersChannelsState"] +) +_LISTPEERSPEERSCHANNELSHTLCS_LISTPEERSPEERSCHANNELSHTLCSDIRECTION = ( + _LISTPEERSPEERSCHANNELSHTLCS.enum_types_by_name[ + "ListpeersPeersChannelsHtlcsDirection" + ] +) +_LISTFUNDSOUTPUTS_LISTFUNDSOUTPUTSSTATUS = _LISTFUNDSOUTPUTS.enum_types_by_name[ + "ListfundsOutputsStatus" +] +_SENDPAYRESPONSE_SENDPAYSTATUS = _SENDPAYRESPONSE.enum_types_by_name["SendpayStatus"] +_CLOSERESPONSE_CLOSETYPE = _CLOSERESPONSE.enum_types_by_name["CloseType"] +_CONNECTRESPONSE_CONNECTDIRECTION = _CONNECTRESPONSE.enum_types_by_name[ + "ConnectDirection" +] +_CONNECTADDRESS_CONNECTADDRESSTYPE = _CONNECTADDRESS.enum_types_by_name[ + "ConnectAddressType" +] +_CREATEINVOICERESPONSE_CREATEINVOICESTATUS = _CREATEINVOICERESPONSE.enum_types_by_name[ + "CreateinvoiceStatus" +] +_DATASTOREREQUEST_DATASTOREMODE = _DATASTOREREQUEST.enum_types_by_name["DatastoreMode"] +_DELINVOICEREQUEST_DELINVOICESTATUS = _DELINVOICEREQUEST.enum_types_by_name[ + "DelinvoiceStatus" +] +_DELINVOICERESPONSE_DELINVOICESTATUS = _DELINVOICERESPONSE.enum_types_by_name[ + "DelinvoiceStatus" +] +_LISTINVOICESINVOICES_LISTINVOICESINVOICESSTATUS = ( + _LISTINVOICESINVOICES.enum_types_by_name["ListinvoicesInvoicesStatus"] +) +_SENDONIONRESPONSE_SENDONIONSTATUS = _SENDONIONRESPONSE.enum_types_by_name[ + "SendonionStatus" +] +_LISTSENDPAYSREQUEST_LISTSENDPAYSSTATUS = _LISTSENDPAYSREQUEST.enum_types_by_name[ + "ListsendpaysStatus" +] +_LISTSENDPAYSPAYMENTS_LISTSENDPAYSPAYMENTSSTATUS = ( + _LISTSENDPAYSPAYMENTS.enum_types_by_name["ListsendpaysPaymentsStatus"] +) +_LISTTRANSACTIONSTRANSACTIONSINPUTS_LISTTRANSACTIONSTRANSACTIONSINPUTSTYPE = ( + _LISTTRANSACTIONSTRANSACTIONSINPUTS.enum_types_by_name[ + "ListtransactionsTransactionsInputsType" + ] +) +_LISTTRANSACTIONSTRANSACTIONSOUTPUTS_LISTTRANSACTIONSTRANSACTIONSOUTPUTSTYPE = ( + _LISTTRANSACTIONSTRANSACTIONSOUTPUTS.enum_types_by_name[ + "ListtransactionsTransactionsOutputsType" + ] +) +_PAYRESPONSE_PAYSTATUS = _PAYRESPONSE.enum_types_by_name["PayStatus"] +_LISTNODESNODESADDRESSES_LISTNODESNODESADDRESSESTYPE = ( + _LISTNODESNODESADDRESSES.enum_types_by_name["ListnodesNodesAddressesType"] +) +_WAITANYINVOICERESPONSE_WAITANYINVOICESTATUS = ( + _WAITANYINVOICERESPONSE.enum_types_by_name["WaitanyinvoiceStatus"] +) +_WAITINVOICERESPONSE_WAITINVOICESTATUS = _WAITINVOICERESPONSE.enum_types_by_name[ + "WaitinvoiceStatus" +] +_WAITSENDPAYRESPONSE_WAITSENDPAYSTATUS = _WAITSENDPAYRESPONSE.enum_types_by_name[ + "WaitsendpayStatus" +] +_NEWADDRREQUEST_NEWADDRADDRESSTYPE = _NEWADDRREQUEST.enum_types_by_name[ + "NewaddrAddresstype" +] +_KEYSENDRESPONSE_KEYSENDSTATUS = _KEYSENDRESPONSE.enum_types_by_name["KeysendStatus"] +_FEERATESREQUEST_FEERATESSTYLE = _FEERATESREQUEST.enum_types_by_name["FeeratesStyle"] +_GETROUTEROUTE_GETROUTEROUTESTYLE = _GETROUTEROUTE.enum_types_by_name[ + "GetrouteRouteStyle" +] +_LISTFORWARDSREQUEST_LISTFORWARDSSTATUS = _LISTFORWARDSREQUEST.enum_types_by_name[ + "ListforwardsStatus" +] +_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS = ( + _LISTFORWARDSFORWARDS.enum_types_by_name["ListforwardsForwardsStatus"] +) +_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE = ( + _LISTFORWARDSFORWARDS.enum_types_by_name["ListforwardsForwardsStyle"] +) +_LISTPAYSREQUEST_LISTPAYSSTATUS = _LISTPAYSREQUEST.enum_types_by_name["ListpaysStatus"] +_LISTPAYSPAYS_LISTPAYSPAYSSTATUS = _LISTPAYSPAYS.enum_types_by_name[ + "ListpaysPaysStatus" +] +GetinfoRequest = _reflection.GeneratedProtocolMessageType( + "GetinfoRequest", + (_message.Message,), + { + "DESCRIPTOR": _GETINFOREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetinfoRequest) + }, +) +_sym_db.RegisterMessage(GetinfoRequest) + +GetinfoResponse = _reflection.GeneratedProtocolMessageType( + "GetinfoResponse", + (_message.Message,), + { + "DESCRIPTOR": _GETINFORESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetinfoResponse) + }, +) +_sym_db.RegisterMessage(GetinfoResponse) + +GetinfoOur_features = _reflection.GeneratedProtocolMessageType( + "GetinfoOur_features", + (_message.Message,), + { + "DESCRIPTOR": _GETINFOOUR_FEATURES, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetinfoOur_features) + }, +) +_sym_db.RegisterMessage(GetinfoOur_features) + +GetinfoAddress = _reflection.GeneratedProtocolMessageType( + "GetinfoAddress", + (_message.Message,), + { + "DESCRIPTOR": _GETINFOADDRESS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetinfoAddress) + }, +) +_sym_db.RegisterMessage(GetinfoAddress) + +GetinfoBinding = _reflection.GeneratedProtocolMessageType( + "GetinfoBinding", + (_message.Message,), + { + "DESCRIPTOR": _GETINFOBINDING, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetinfoBinding) + }, +) +_sym_db.RegisterMessage(GetinfoBinding) + +ListpeersRequest = _reflection.GeneratedProtocolMessageType( + "ListpeersRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersRequest) + }, +) +_sym_db.RegisterMessage(ListpeersRequest) + +ListpeersResponse = _reflection.GeneratedProtocolMessageType( + "ListpeersResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersResponse) + }, +) +_sym_db.RegisterMessage(ListpeersResponse) + +ListpeersPeers = _reflection.GeneratedProtocolMessageType( + "ListpeersPeers", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeers) + }, +) +_sym_db.RegisterMessage(ListpeersPeers) + +ListpeersPeersLog = _reflection.GeneratedProtocolMessageType( + "ListpeersPeersLog", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERSLOG, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeersLog) + }, +) +_sym_db.RegisterMessage(ListpeersPeersLog) + +ListpeersPeersChannels = _reflection.GeneratedProtocolMessageType( + "ListpeersPeersChannels", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERSCHANNELS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeersChannels) + }, +) +_sym_db.RegisterMessage(ListpeersPeersChannels) + +ListpeersPeersChannelsFeerate = _reflection.GeneratedProtocolMessageType( + "ListpeersPeersChannelsFeerate", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERSCHANNELSFEERATE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeersChannelsFeerate) + }, +) +_sym_db.RegisterMessage(ListpeersPeersChannelsFeerate) + +ListpeersPeersChannelsInflight = _reflection.GeneratedProtocolMessageType( + "ListpeersPeersChannelsInflight", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERSCHANNELSINFLIGHT, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeersChannelsInflight) + }, +) +_sym_db.RegisterMessage(ListpeersPeersChannelsInflight) + +ListpeersPeersChannelsFunding = _reflection.GeneratedProtocolMessageType( + "ListpeersPeersChannelsFunding", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERSCHANNELSFUNDING, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeersChannelsFunding) + }, +) +_sym_db.RegisterMessage(ListpeersPeersChannelsFunding) + +ListpeersPeersChannelsHtlcs = _reflection.GeneratedProtocolMessageType( + "ListpeersPeersChannelsHtlcs", + (_message.Message,), + { + "DESCRIPTOR": _LISTPEERSPEERSCHANNELSHTLCS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpeersPeersChannelsHtlcs) + }, +) +_sym_db.RegisterMessage(ListpeersPeersChannelsHtlcs) + +ListfundsRequest = _reflection.GeneratedProtocolMessageType( + "ListfundsRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTFUNDSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListfundsRequest) + }, +) +_sym_db.RegisterMessage(ListfundsRequest) + +ListfundsResponse = _reflection.GeneratedProtocolMessageType( + "ListfundsResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTFUNDSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListfundsResponse) + }, +) +_sym_db.RegisterMessage(ListfundsResponse) + +ListfundsOutputs = _reflection.GeneratedProtocolMessageType( + "ListfundsOutputs", + (_message.Message,), + { + "DESCRIPTOR": _LISTFUNDSOUTPUTS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListfundsOutputs) + }, +) +_sym_db.RegisterMessage(ListfundsOutputs) + +ListfundsChannels = _reflection.GeneratedProtocolMessageType( + "ListfundsChannels", + (_message.Message,), + { + "DESCRIPTOR": _LISTFUNDSCHANNELS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListfundsChannels) + }, +) +_sym_db.RegisterMessage(ListfundsChannels) + +SendpayRequest = _reflection.GeneratedProtocolMessageType( + "SendpayRequest", + (_message.Message,), + { + "DESCRIPTOR": _SENDPAYREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendpayRequest) + }, +) +_sym_db.RegisterMessage(SendpayRequest) + +SendpayResponse = _reflection.GeneratedProtocolMessageType( + "SendpayResponse", + (_message.Message,), + { + "DESCRIPTOR": _SENDPAYRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendpayResponse) + }, +) +_sym_db.RegisterMessage(SendpayResponse) + +SendpayRoute = _reflection.GeneratedProtocolMessageType( + "SendpayRoute", + (_message.Message,), + { + "DESCRIPTOR": _SENDPAYROUTE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendpayRoute) + }, +) +_sym_db.RegisterMessage(SendpayRoute) + +ListchannelsRequest = _reflection.GeneratedProtocolMessageType( + "ListchannelsRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTCHANNELSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListchannelsRequest) + }, +) +_sym_db.RegisterMessage(ListchannelsRequest) + +ListchannelsResponse = _reflection.GeneratedProtocolMessageType( + "ListchannelsResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTCHANNELSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListchannelsResponse) + }, +) +_sym_db.RegisterMessage(ListchannelsResponse) + +ListchannelsChannels = _reflection.GeneratedProtocolMessageType( + "ListchannelsChannels", + (_message.Message,), + { + "DESCRIPTOR": _LISTCHANNELSCHANNELS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListchannelsChannels) + }, +) +_sym_db.RegisterMessage(ListchannelsChannels) + +AddgossipRequest = _reflection.GeneratedProtocolMessageType( + "AddgossipRequest", + (_message.Message,), + { + "DESCRIPTOR": _ADDGOSSIPREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.AddgossipRequest) + }, +) +_sym_db.RegisterMessage(AddgossipRequest) + +AddgossipResponse = _reflection.GeneratedProtocolMessageType( + "AddgossipResponse", + (_message.Message,), + { + "DESCRIPTOR": _ADDGOSSIPRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.AddgossipResponse) + }, +) +_sym_db.RegisterMessage(AddgossipResponse) + +AutocleaninvoiceRequest = _reflection.GeneratedProtocolMessageType( + "AutocleaninvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _AUTOCLEANINVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.AutocleaninvoiceRequest) + }, +) +_sym_db.RegisterMessage(AutocleaninvoiceRequest) + +AutocleaninvoiceResponse = _reflection.GeneratedProtocolMessageType( + "AutocleaninvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _AUTOCLEANINVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.AutocleaninvoiceResponse) + }, +) +_sym_db.RegisterMessage(AutocleaninvoiceResponse) + +CheckmessageRequest = _reflection.GeneratedProtocolMessageType( + "CheckmessageRequest", + (_message.Message,), + { + "DESCRIPTOR": _CHECKMESSAGEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CheckmessageRequest) + }, +) +_sym_db.RegisterMessage(CheckmessageRequest) + +CheckmessageResponse = _reflection.GeneratedProtocolMessageType( + "CheckmessageResponse", + (_message.Message,), + { + "DESCRIPTOR": _CHECKMESSAGERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CheckmessageResponse) + }, +) +_sym_db.RegisterMessage(CheckmessageResponse) + +CloseRequest = _reflection.GeneratedProtocolMessageType( + "CloseRequest", + (_message.Message,), + { + "DESCRIPTOR": _CLOSEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CloseRequest) + }, +) +_sym_db.RegisterMessage(CloseRequest) + +CloseResponse = _reflection.GeneratedProtocolMessageType( + "CloseResponse", + (_message.Message,), + { + "DESCRIPTOR": _CLOSERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CloseResponse) + }, +) +_sym_db.RegisterMessage(CloseResponse) + +ConnectRequest = _reflection.GeneratedProtocolMessageType( + "ConnectRequest", + (_message.Message,), + { + "DESCRIPTOR": _CONNECTREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ConnectRequest) + }, +) +_sym_db.RegisterMessage(ConnectRequest) + +ConnectResponse = _reflection.GeneratedProtocolMessageType( + "ConnectResponse", + (_message.Message,), + { + "DESCRIPTOR": _CONNECTRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ConnectResponse) + }, +) +_sym_db.RegisterMessage(ConnectResponse) + +ConnectAddress = _reflection.GeneratedProtocolMessageType( + "ConnectAddress", + (_message.Message,), + { + "DESCRIPTOR": _CONNECTADDRESS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ConnectAddress) + }, +) +_sym_db.RegisterMessage(ConnectAddress) + +CreateinvoiceRequest = _reflection.GeneratedProtocolMessageType( + "CreateinvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _CREATEINVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CreateinvoiceRequest) + }, +) +_sym_db.RegisterMessage(CreateinvoiceRequest) + +CreateinvoiceResponse = _reflection.GeneratedProtocolMessageType( + "CreateinvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _CREATEINVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CreateinvoiceResponse) + }, +) +_sym_db.RegisterMessage(CreateinvoiceResponse) + +DatastoreRequest = _reflection.GeneratedProtocolMessageType( + "DatastoreRequest", + (_message.Message,), + { + "DESCRIPTOR": _DATASTOREREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DatastoreRequest) + }, +) +_sym_db.RegisterMessage(DatastoreRequest) + +DatastoreResponse = _reflection.GeneratedProtocolMessageType( + "DatastoreResponse", + (_message.Message,), + { + "DESCRIPTOR": _DATASTORERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DatastoreResponse) + }, +) +_sym_db.RegisterMessage(DatastoreResponse) + +CreateonionRequest = _reflection.GeneratedProtocolMessageType( + "CreateonionRequest", + (_message.Message,), + { + "DESCRIPTOR": _CREATEONIONREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CreateonionRequest) + }, +) +_sym_db.RegisterMessage(CreateonionRequest) + +CreateonionResponse = _reflection.GeneratedProtocolMessageType( + "CreateonionResponse", + (_message.Message,), + { + "DESCRIPTOR": _CREATEONIONRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CreateonionResponse) + }, +) +_sym_db.RegisterMessage(CreateonionResponse) + +CreateonionHops = _reflection.GeneratedProtocolMessageType( + "CreateonionHops", + (_message.Message,), + { + "DESCRIPTOR": _CREATEONIONHOPS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.CreateonionHops) + }, +) +_sym_db.RegisterMessage(CreateonionHops) + +DeldatastoreRequest = _reflection.GeneratedProtocolMessageType( + "DeldatastoreRequest", + (_message.Message,), + { + "DESCRIPTOR": _DELDATASTOREREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DeldatastoreRequest) + }, +) +_sym_db.RegisterMessage(DeldatastoreRequest) + +DeldatastoreResponse = _reflection.GeneratedProtocolMessageType( + "DeldatastoreResponse", + (_message.Message,), + { + "DESCRIPTOR": _DELDATASTORERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DeldatastoreResponse) + }, +) +_sym_db.RegisterMessage(DeldatastoreResponse) + +DelexpiredinvoiceRequest = _reflection.GeneratedProtocolMessageType( + "DelexpiredinvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _DELEXPIREDINVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DelexpiredinvoiceRequest) + }, +) +_sym_db.RegisterMessage(DelexpiredinvoiceRequest) + +DelexpiredinvoiceResponse = _reflection.GeneratedProtocolMessageType( + "DelexpiredinvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _DELEXPIREDINVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DelexpiredinvoiceResponse) + }, +) +_sym_db.RegisterMessage(DelexpiredinvoiceResponse) + +DelinvoiceRequest = _reflection.GeneratedProtocolMessageType( + "DelinvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _DELINVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DelinvoiceRequest) + }, +) +_sym_db.RegisterMessage(DelinvoiceRequest) + +DelinvoiceResponse = _reflection.GeneratedProtocolMessageType( + "DelinvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _DELINVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DelinvoiceResponse) + }, +) +_sym_db.RegisterMessage(DelinvoiceResponse) + +InvoiceRequest = _reflection.GeneratedProtocolMessageType( + "InvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _INVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.InvoiceRequest) + }, +) +_sym_db.RegisterMessage(InvoiceRequest) + +InvoiceResponse = _reflection.GeneratedProtocolMessageType( + "InvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _INVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.InvoiceResponse) + }, +) +_sym_db.RegisterMessage(InvoiceResponse) + +ListdatastoreRequest = _reflection.GeneratedProtocolMessageType( + "ListdatastoreRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTDATASTOREREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListdatastoreRequest) + }, +) +_sym_db.RegisterMessage(ListdatastoreRequest) + +ListdatastoreResponse = _reflection.GeneratedProtocolMessageType( + "ListdatastoreResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTDATASTORERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListdatastoreResponse) + }, +) +_sym_db.RegisterMessage(ListdatastoreResponse) + +ListdatastoreDatastore = _reflection.GeneratedProtocolMessageType( + "ListdatastoreDatastore", + (_message.Message,), + { + "DESCRIPTOR": _LISTDATASTOREDATASTORE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListdatastoreDatastore) + }, +) +_sym_db.RegisterMessage(ListdatastoreDatastore) + +ListinvoicesRequest = _reflection.GeneratedProtocolMessageType( + "ListinvoicesRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTINVOICESREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListinvoicesRequest) + }, +) +_sym_db.RegisterMessage(ListinvoicesRequest) + +ListinvoicesResponse = _reflection.GeneratedProtocolMessageType( + "ListinvoicesResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTINVOICESRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListinvoicesResponse) + }, +) +_sym_db.RegisterMessage(ListinvoicesResponse) + +ListinvoicesInvoices = _reflection.GeneratedProtocolMessageType( + "ListinvoicesInvoices", + (_message.Message,), + { + "DESCRIPTOR": _LISTINVOICESINVOICES, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListinvoicesInvoices) + }, +) +_sym_db.RegisterMessage(ListinvoicesInvoices) + +SendonionRequest = _reflection.GeneratedProtocolMessageType( + "SendonionRequest", + (_message.Message,), + { + "DESCRIPTOR": _SENDONIONREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendonionRequest) + }, +) +_sym_db.RegisterMessage(SendonionRequest) + +SendonionResponse = _reflection.GeneratedProtocolMessageType( + "SendonionResponse", + (_message.Message,), + { + "DESCRIPTOR": _SENDONIONRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendonionResponse) + }, +) +_sym_db.RegisterMessage(SendonionResponse) + +SendonionFirst_hop = _reflection.GeneratedProtocolMessageType( + "SendonionFirst_hop", + (_message.Message,), + { + "DESCRIPTOR": _SENDONIONFIRST_HOP, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendonionFirst_hop) + }, +) +_sym_db.RegisterMessage(SendonionFirst_hop) + +ListsendpaysRequest = _reflection.GeneratedProtocolMessageType( + "ListsendpaysRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTSENDPAYSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListsendpaysRequest) + }, +) +_sym_db.RegisterMessage(ListsendpaysRequest) + +ListsendpaysResponse = _reflection.GeneratedProtocolMessageType( + "ListsendpaysResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTSENDPAYSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListsendpaysResponse) + }, +) +_sym_db.RegisterMessage(ListsendpaysResponse) + +ListsendpaysPayments = _reflection.GeneratedProtocolMessageType( + "ListsendpaysPayments", + (_message.Message,), + { + "DESCRIPTOR": _LISTSENDPAYSPAYMENTS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListsendpaysPayments) + }, +) +_sym_db.RegisterMessage(ListsendpaysPayments) + +ListtransactionsRequest = _reflection.GeneratedProtocolMessageType( + "ListtransactionsRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTTRANSACTIONSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListtransactionsRequest) + }, +) +_sym_db.RegisterMessage(ListtransactionsRequest) + +ListtransactionsResponse = _reflection.GeneratedProtocolMessageType( + "ListtransactionsResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTTRANSACTIONSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListtransactionsResponse) + }, +) +_sym_db.RegisterMessage(ListtransactionsResponse) + +ListtransactionsTransactions = _reflection.GeneratedProtocolMessageType( + "ListtransactionsTransactions", + (_message.Message,), + { + "DESCRIPTOR": _LISTTRANSACTIONSTRANSACTIONS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListtransactionsTransactions) + }, +) +_sym_db.RegisterMessage(ListtransactionsTransactions) + +ListtransactionsTransactionsInputs = _reflection.GeneratedProtocolMessageType( + "ListtransactionsTransactionsInputs", + (_message.Message,), + { + "DESCRIPTOR": _LISTTRANSACTIONSTRANSACTIONSINPUTS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListtransactionsTransactionsInputs) + }, +) +_sym_db.RegisterMessage(ListtransactionsTransactionsInputs) + +ListtransactionsTransactionsOutputs = _reflection.GeneratedProtocolMessageType( + "ListtransactionsTransactionsOutputs", + (_message.Message,), + { + "DESCRIPTOR": _LISTTRANSACTIONSTRANSACTIONSOUTPUTS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListtransactionsTransactionsOutputs) + }, +) +_sym_db.RegisterMessage(ListtransactionsTransactionsOutputs) + +PayRequest = _reflection.GeneratedProtocolMessageType( + "PayRequest", + (_message.Message,), + { + "DESCRIPTOR": _PAYREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.PayRequest) + }, +) +_sym_db.RegisterMessage(PayRequest) + +PayResponse = _reflection.GeneratedProtocolMessageType( + "PayResponse", + (_message.Message,), + { + "DESCRIPTOR": _PAYRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.PayResponse) + }, +) +_sym_db.RegisterMessage(PayResponse) + +ListnodesRequest = _reflection.GeneratedProtocolMessageType( + "ListnodesRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTNODESREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListnodesRequest) + }, +) +_sym_db.RegisterMessage(ListnodesRequest) + +ListnodesResponse = _reflection.GeneratedProtocolMessageType( + "ListnodesResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTNODESRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListnodesResponse) + }, +) +_sym_db.RegisterMessage(ListnodesResponse) + +ListnodesNodes = _reflection.GeneratedProtocolMessageType( + "ListnodesNodes", + (_message.Message,), + { + "DESCRIPTOR": _LISTNODESNODES, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListnodesNodes) + }, +) +_sym_db.RegisterMessage(ListnodesNodes) + +ListnodesNodesAddresses = _reflection.GeneratedProtocolMessageType( + "ListnodesNodesAddresses", + (_message.Message,), + { + "DESCRIPTOR": _LISTNODESNODESADDRESSES, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListnodesNodesAddresses) + }, +) +_sym_db.RegisterMessage(ListnodesNodesAddresses) + +WaitanyinvoiceRequest = _reflection.GeneratedProtocolMessageType( + "WaitanyinvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _WAITANYINVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WaitanyinvoiceRequest) + }, +) +_sym_db.RegisterMessage(WaitanyinvoiceRequest) + +WaitanyinvoiceResponse = _reflection.GeneratedProtocolMessageType( + "WaitanyinvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _WAITANYINVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WaitanyinvoiceResponse) + }, +) +_sym_db.RegisterMessage(WaitanyinvoiceResponse) + +WaitinvoiceRequest = _reflection.GeneratedProtocolMessageType( + "WaitinvoiceRequest", + (_message.Message,), + { + "DESCRIPTOR": _WAITINVOICEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WaitinvoiceRequest) + }, +) +_sym_db.RegisterMessage(WaitinvoiceRequest) + +WaitinvoiceResponse = _reflection.GeneratedProtocolMessageType( + "WaitinvoiceResponse", + (_message.Message,), + { + "DESCRIPTOR": _WAITINVOICERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WaitinvoiceResponse) + }, +) +_sym_db.RegisterMessage(WaitinvoiceResponse) + +WaitsendpayRequest = _reflection.GeneratedProtocolMessageType( + "WaitsendpayRequest", + (_message.Message,), + { + "DESCRIPTOR": _WAITSENDPAYREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WaitsendpayRequest) + }, +) +_sym_db.RegisterMessage(WaitsendpayRequest) + +WaitsendpayResponse = _reflection.GeneratedProtocolMessageType( + "WaitsendpayResponse", + (_message.Message,), + { + "DESCRIPTOR": _WAITSENDPAYRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WaitsendpayResponse) + }, +) +_sym_db.RegisterMessage(WaitsendpayResponse) + +NewaddrRequest = _reflection.GeneratedProtocolMessageType( + "NewaddrRequest", + (_message.Message,), + { + "DESCRIPTOR": _NEWADDRREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.NewaddrRequest) + }, +) +_sym_db.RegisterMessage(NewaddrRequest) + +NewaddrResponse = _reflection.GeneratedProtocolMessageType( + "NewaddrResponse", + (_message.Message,), + { + "DESCRIPTOR": _NEWADDRRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.NewaddrResponse) + }, +) +_sym_db.RegisterMessage(NewaddrResponse) + +WithdrawRequest = _reflection.GeneratedProtocolMessageType( + "WithdrawRequest", + (_message.Message,), + { + "DESCRIPTOR": _WITHDRAWREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WithdrawRequest) + }, +) +_sym_db.RegisterMessage(WithdrawRequest) + +WithdrawResponse = _reflection.GeneratedProtocolMessageType( + "WithdrawResponse", + (_message.Message,), + { + "DESCRIPTOR": _WITHDRAWRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.WithdrawResponse) + }, +) +_sym_db.RegisterMessage(WithdrawResponse) + +KeysendRequest = _reflection.GeneratedProtocolMessageType( + "KeysendRequest", + (_message.Message,), + { + "DESCRIPTOR": _KEYSENDREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.KeysendRequest) + }, +) +_sym_db.RegisterMessage(KeysendRequest) + +KeysendResponse = _reflection.GeneratedProtocolMessageType( + "KeysendResponse", + (_message.Message,), + { + "DESCRIPTOR": _KEYSENDRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.KeysendResponse) + }, +) +_sym_db.RegisterMessage(KeysendResponse) + +KeysendExtratlvs = _reflection.GeneratedProtocolMessageType( + "KeysendExtratlvs", + (_message.Message,), + { + "DESCRIPTOR": _KEYSENDEXTRATLVS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.KeysendExtratlvs) + }, +) +_sym_db.RegisterMessage(KeysendExtratlvs) + +FundpsbtRequest = _reflection.GeneratedProtocolMessageType( + "FundpsbtRequest", + (_message.Message,), + { + "DESCRIPTOR": _FUNDPSBTREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FundpsbtRequest) + }, +) +_sym_db.RegisterMessage(FundpsbtRequest) + +FundpsbtResponse = _reflection.GeneratedProtocolMessageType( + "FundpsbtResponse", + (_message.Message,), + { + "DESCRIPTOR": _FUNDPSBTRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FundpsbtResponse) + }, +) +_sym_db.RegisterMessage(FundpsbtResponse) + +FundpsbtReservations = _reflection.GeneratedProtocolMessageType( + "FundpsbtReservations", + (_message.Message,), + { + "DESCRIPTOR": _FUNDPSBTRESERVATIONS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FundpsbtReservations) + }, +) +_sym_db.RegisterMessage(FundpsbtReservations) + +SendpsbtRequest = _reflection.GeneratedProtocolMessageType( + "SendpsbtRequest", + (_message.Message,), + { + "DESCRIPTOR": _SENDPSBTREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendpsbtRequest) + }, +) +_sym_db.RegisterMessage(SendpsbtRequest) + +SendpsbtResponse = _reflection.GeneratedProtocolMessageType( + "SendpsbtResponse", + (_message.Message,), + { + "DESCRIPTOR": _SENDPSBTRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SendpsbtResponse) + }, +) +_sym_db.RegisterMessage(SendpsbtResponse) + +SignpsbtRequest = _reflection.GeneratedProtocolMessageType( + "SignpsbtRequest", + (_message.Message,), + { + "DESCRIPTOR": _SIGNPSBTREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SignpsbtRequest) + }, +) +_sym_db.RegisterMessage(SignpsbtRequest) + +SignpsbtResponse = _reflection.GeneratedProtocolMessageType( + "SignpsbtResponse", + (_message.Message,), + { + "DESCRIPTOR": _SIGNPSBTRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SignpsbtResponse) + }, +) +_sym_db.RegisterMessage(SignpsbtResponse) + +UtxopsbtRequest = _reflection.GeneratedProtocolMessageType( + "UtxopsbtRequest", + (_message.Message,), + { + "DESCRIPTOR": _UTXOPSBTREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.UtxopsbtRequest) + }, +) +_sym_db.RegisterMessage(UtxopsbtRequest) + +UtxopsbtResponse = _reflection.GeneratedProtocolMessageType( + "UtxopsbtResponse", + (_message.Message,), + { + "DESCRIPTOR": _UTXOPSBTRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.UtxopsbtResponse) + }, +) +_sym_db.RegisterMessage(UtxopsbtResponse) + +UtxopsbtReservations = _reflection.GeneratedProtocolMessageType( + "UtxopsbtReservations", + (_message.Message,), + { + "DESCRIPTOR": _UTXOPSBTRESERVATIONS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.UtxopsbtReservations) + }, +) +_sym_db.RegisterMessage(UtxopsbtReservations) + +TxdiscardRequest = _reflection.GeneratedProtocolMessageType( + "TxdiscardRequest", + (_message.Message,), + { + "DESCRIPTOR": _TXDISCARDREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.TxdiscardRequest) + }, +) +_sym_db.RegisterMessage(TxdiscardRequest) + +TxdiscardResponse = _reflection.GeneratedProtocolMessageType( + "TxdiscardResponse", + (_message.Message,), + { + "DESCRIPTOR": _TXDISCARDRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.TxdiscardResponse) + }, +) +_sym_db.RegisterMessage(TxdiscardResponse) + +TxprepareRequest = _reflection.GeneratedProtocolMessageType( + "TxprepareRequest", + (_message.Message,), + { + "DESCRIPTOR": _TXPREPAREREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.TxprepareRequest) + }, +) +_sym_db.RegisterMessage(TxprepareRequest) + +TxprepareResponse = _reflection.GeneratedProtocolMessageType( + "TxprepareResponse", + (_message.Message,), + { + "DESCRIPTOR": _TXPREPARERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.TxprepareResponse) + }, +) +_sym_db.RegisterMessage(TxprepareResponse) + +TxsendRequest = _reflection.GeneratedProtocolMessageType( + "TxsendRequest", + (_message.Message,), + { + "DESCRIPTOR": _TXSENDREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.TxsendRequest) + }, +) +_sym_db.RegisterMessage(TxsendRequest) + +TxsendResponse = _reflection.GeneratedProtocolMessageType( + "TxsendResponse", + (_message.Message,), + { + "DESCRIPTOR": _TXSENDRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.TxsendResponse) + }, +) +_sym_db.RegisterMessage(TxsendResponse) + +DisconnectRequest = _reflection.GeneratedProtocolMessageType( + "DisconnectRequest", + (_message.Message,), + { + "DESCRIPTOR": _DISCONNECTREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DisconnectRequest) + }, +) +_sym_db.RegisterMessage(DisconnectRequest) + +DisconnectResponse = _reflection.GeneratedProtocolMessageType( + "DisconnectResponse", + (_message.Message,), + { + "DESCRIPTOR": _DISCONNECTRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.DisconnectResponse) + }, +) +_sym_db.RegisterMessage(DisconnectResponse) + +FeeratesRequest = _reflection.GeneratedProtocolMessageType( + "FeeratesRequest", + (_message.Message,), + { + "DESCRIPTOR": _FEERATESREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FeeratesRequest) + }, +) +_sym_db.RegisterMessage(FeeratesRequest) + +FeeratesResponse = _reflection.GeneratedProtocolMessageType( + "FeeratesResponse", + (_message.Message,), + { + "DESCRIPTOR": _FEERATESRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FeeratesResponse) + }, +) +_sym_db.RegisterMessage(FeeratesResponse) + +FeeratesPerkb = _reflection.GeneratedProtocolMessageType( + "FeeratesPerkb", + (_message.Message,), + { + "DESCRIPTOR": _FEERATESPERKB, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FeeratesPerkb) + }, +) +_sym_db.RegisterMessage(FeeratesPerkb) + +FeeratesPerkw = _reflection.GeneratedProtocolMessageType( + "FeeratesPerkw", + (_message.Message,), + { + "DESCRIPTOR": _FEERATESPERKW, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FeeratesPerkw) + }, +) +_sym_db.RegisterMessage(FeeratesPerkw) + +FeeratesOnchain_fee_estimates = _reflection.GeneratedProtocolMessageType( + "FeeratesOnchain_fee_estimates", + (_message.Message,), + { + "DESCRIPTOR": _FEERATESONCHAIN_FEE_ESTIMATES, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.FeeratesOnchain_fee_estimates) + }, +) +_sym_db.RegisterMessage(FeeratesOnchain_fee_estimates) + +GetrouteRequest = _reflection.GeneratedProtocolMessageType( + "GetrouteRequest", + (_message.Message,), + { + "DESCRIPTOR": _GETROUTEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetrouteRequest) + }, +) +_sym_db.RegisterMessage(GetrouteRequest) + +GetrouteResponse = _reflection.GeneratedProtocolMessageType( + "GetrouteResponse", + (_message.Message,), + { + "DESCRIPTOR": _GETROUTERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetrouteResponse) + }, +) +_sym_db.RegisterMessage(GetrouteResponse) + +GetrouteRoute = _reflection.GeneratedProtocolMessageType( + "GetrouteRoute", + (_message.Message,), + { + "DESCRIPTOR": _GETROUTEROUTE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.GetrouteRoute) + }, +) +_sym_db.RegisterMessage(GetrouteRoute) + +ListforwardsRequest = _reflection.GeneratedProtocolMessageType( + "ListforwardsRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTFORWARDSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListforwardsRequest) + }, +) +_sym_db.RegisterMessage(ListforwardsRequest) + +ListforwardsResponse = _reflection.GeneratedProtocolMessageType( + "ListforwardsResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTFORWARDSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListforwardsResponse) + }, +) +_sym_db.RegisterMessage(ListforwardsResponse) + +ListforwardsForwards = _reflection.GeneratedProtocolMessageType( + "ListforwardsForwards", + (_message.Message,), + { + "DESCRIPTOR": _LISTFORWARDSFORWARDS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListforwardsForwards) + }, +) +_sym_db.RegisterMessage(ListforwardsForwards) + +ListpaysRequest = _reflection.GeneratedProtocolMessageType( + "ListpaysRequest", + (_message.Message,), + { + "DESCRIPTOR": _LISTPAYSREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpaysRequest) + }, +) +_sym_db.RegisterMessage(ListpaysRequest) + +ListpaysResponse = _reflection.GeneratedProtocolMessageType( + "ListpaysResponse", + (_message.Message,), + { + "DESCRIPTOR": _LISTPAYSRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpaysResponse) + }, +) +_sym_db.RegisterMessage(ListpaysResponse) + +ListpaysPays = _reflection.GeneratedProtocolMessageType( + "ListpaysPays", + (_message.Message,), + { + "DESCRIPTOR": _LISTPAYSPAYS, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.ListpaysPays) + }, +) +_sym_db.RegisterMessage(ListpaysPays) + +PingRequest = _reflection.GeneratedProtocolMessageType( + "PingRequest", + (_message.Message,), + { + "DESCRIPTOR": _PINGREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.PingRequest) + }, +) +_sym_db.RegisterMessage(PingRequest) + +PingResponse = _reflection.GeneratedProtocolMessageType( + "PingResponse", + (_message.Message,), + { + "DESCRIPTOR": _PINGRESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.PingResponse) + }, +) +_sym_db.RegisterMessage(PingResponse) + +SignmessageRequest = _reflection.GeneratedProtocolMessageType( + "SignmessageRequest", + (_message.Message,), + { + "DESCRIPTOR": _SIGNMESSAGEREQUEST, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SignmessageRequest) + }, +) +_sym_db.RegisterMessage(SignmessageRequest) + +SignmessageResponse = _reflection.GeneratedProtocolMessageType( + "SignmessageResponse", + (_message.Message,), + { + "DESCRIPTOR": _SIGNMESSAGERESPONSE, + "__module__": "node_pb2" + # @@protoc_insertion_point(class_scope:cln.SignmessageResponse) + }, +) +_sym_db.RegisterMessage(SignmessageResponse) + +_NODE = DESCRIPTOR.services_by_name["Node"] +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _GETINFOREQUEST._serialized_start = 37 + _GETINFOREQUEST._serialized_end = 53 + _GETINFORESPONSE._serialized_start = 56 + _GETINFORESPONSE._serialized_end = 548 + _GETINFOOUR_FEATURES._serialized_start = 550 + _GETINFOOUR_FEATURES._serialized_end = 633 + _GETINFOADDRESS._serialized_start = 636 + _GETINFOADDRESS._serialized_end = 847 + _GETINFOADDRESS_GETINFOADDRESSTYPE._serialized_start = 749 + _GETINFOADDRESS_GETINFOADDRESSTYPE._serialized_end = 835 + _GETINFOBINDING._serialized_start = 850 + _GETINFOBINDING._serialized_end = 1101 + _GETINFOBINDING_GETINFOBINDINGTYPE._serialized_start = 989 + _GETINFOBINDING_GETINFOBINDINGTYPE._serialized_end = 1069 + _LISTPEERSREQUEST._serialized_start = 1103 + _LISTPEERSREQUEST._serialized_end = 1175 + _LISTPEERSRESPONSE._serialized_start = 1177 + _LISTPEERSRESPONSE._serialized_end = 1232 + _LISTPEERSPEERS._serialized_start = 1235 + _LISTPEERSPEERS._serialized_end = 1419 + _LISTPEERSPEERSLOG._serialized_start = 1422 + _LISTPEERSPEERSLOG._serialized_end = 1803 + _LISTPEERSPEERSLOG_LISTPEERSPEERSLOGTYPE._serialized_start = 1633 + _LISTPEERSPEERSLOG_LISTPEERSPEERSLOGTYPE._serialized_end = 1738 + _LISTPEERSPEERSCHANNELS._serialized_start = 1806 + _LISTPEERSPEERSCHANNELS._serialized_end = 4582 + _LISTPEERSPEERSCHANNELS_LISTPEERSPEERSCHANNELSSTATE._serialized_start = 3497 + _LISTPEERSPEERSCHANNELS_LISTPEERSPEERSCHANNELSSTATE._serialized_end = 3786 + _LISTPEERSPEERSCHANNELSFEERATE._serialized_start = 4584 + _LISTPEERSPEERSCHANNELSFEERATE._serialized_end = 4645 + _LISTPEERSPEERSCHANNELSINFLIGHT._serialized_start = 4648 + _LISTPEERSPEERSCHANNELSINFLIGHT._serialized_end = 4845 + _LISTPEERSPEERSCHANNELSFUNDING._serialized_start = 4848 + _LISTPEERSPEERSCHANNELSFUNDING._serialized_end = 4980 + _LISTPEERSPEERSCHANNELSHTLCS._serialized_start = 4983 + _LISTPEERSPEERSCHANNELSHTLCS._serialized_end = 5321 + _LISTPEERSPEERSCHANNELSHTLCS_LISTPEERSPEERSCHANNELSHTLCSDIRECTION._serialized_start = ( + 5237 + ) + _LISTPEERSPEERSCHANNELSHTLCS_LISTPEERSPEERSCHANNELSHTLCSDIRECTION._serialized_end = ( + 5292 + ) + _LISTFUNDSREQUEST._serialized_start = 5323 + _LISTFUNDSREQUEST._serialized_end = 5371 + _LISTFUNDSRESPONSE._serialized_start = 5373 + _LISTFUNDSRESPONSE._serialized_end = 5474 + _LISTFUNDSOUTPUTS._serialized_start = 5477 + _LISTFUNDSOUTPUTS._serialized_end = 5832 + _LISTFUNDSOUTPUTS_LISTFUNDSOUTPUTSSTATUS._serialized_start = 5720 + _LISTFUNDSOUTPUTS_LISTFUNDSOUTPUTSSTATUS._serialized_end = 5787 + _LISTFUNDSCHANNELS._serialized_start = 5835 + _LISTFUNDSCHANNELS._serialized_end = 6094 + _SENDPAYREQUEST._serialized_start = 6097 + _SENDPAYREQUEST._serialized_end = 6438 + _SENDPAYRESPONSE._serialized_start = 6441 + _SENDPAYRESPONSE._serialized_end = 6990 + _SENDPAYRESPONSE_SENDPAYSTATUS._serialized_start = 6828 + _SENDPAYRESPONSE_SENDPAYSTATUS._serialized_end = 6870 + _SENDPAYROUTE._serialized_start = 6992 + _SENDPAYROUTE._serialized_end = 7081 + _LISTCHANNELSREQUEST._serialized_start = 7084 + _LISTCHANNELSREQUEST._serialized_end = 7231 + _LISTCHANNELSRESPONSE._serialized_start = 7233 + _LISTCHANNELSRESPONSE._serialized_end = 7300 + _LISTCHANNELSCHANNELS._serialized_start = 7303 + _LISTCHANNELSCHANNELS._serialized_end = 7719 + _ADDGOSSIPREQUEST._serialized_start = 7721 + _ADDGOSSIPREQUEST._serialized_end = 7756 + _ADDGOSSIPRESPONSE._serialized_start = 7758 + _ADDGOSSIPRESPONSE._serialized_end = 7777 + _AUTOCLEANINVOICEREQUEST._serialized_start = 7779 + _AUTOCLEANINVOICEREQUEST._serialized_end = 7890 + _AUTOCLEANINVOICERESPONSE._serialized_start = 7893 + _AUTOCLEANINVOICERESPONSE._serialized_end = 8022 + _CHECKMESSAGEREQUEST._serialized_start = 8024 + _CHECKMESSAGEREQUEST._serialized_end = 8109 + _CHECKMESSAGERESPONSE._serialized_start = 8111 + _CHECKMESSAGERESPONSE._serialized_end = 8183 + _CLOSEREQUEST._serialized_start = 8186 + _CLOSEREQUEST._serialized_end = 8502 + _CLOSERESPONSE._serialized_start = 8505 + _CLOSERESPONSE._serialized_end = 8676 + _CLOSERESPONSE_CLOSETYPE._serialized_start = 8607 + _CLOSERESPONSE_CLOSETYPE._serialized_end = 8660 + _CONNECTREQUEST._serialized_start = 8678 + _CONNECTREQUEST._serialized_end = 8762 + _CONNECTRESPONSE._serialized_start = 8765 + _CONNECTRESPONSE._serialized_end = 8907 + _CONNECTRESPONSE_CONNECTDIRECTION._serialized_start = 8872 + _CONNECTRESPONSE_CONNECTDIRECTION._serialized_end = 8907 + _CONNECTADDRESS._serialized_start = 8910 + _CONNECTADDRESS._serialized_end = 9161 + _CONNECTADDRESS_CONNECTADDRESSTYPE._serialized_start = 9049 + _CONNECTADDRESS_CONNECTADDRESSTYPE._serialized_end = 9129 + _CREATEINVOICEREQUEST._serialized_start = 9163 + _CREATEINVOICEREQUEST._serialized_end = 9237 + _CREATEINVOICERESPONSE._serialized_start = 9240 + _CREATEINVOICERESPONSE._serialized_end = 9867 + _CREATEINVOICERESPONSE_CREATEINVOICESTATUS._serialized_start = 9667 + _CREATEINVOICERESPONSE_CREATEINVOICESTATUS._serialized_end = 9723 + _DATASTOREREQUEST._serialized_start = 9870 + _DATASTOREREQUEST._serialized_end = 10178 + _DATASTOREREQUEST_DATASTOREMODE._serialized_start = 10023 + _DATASTOREREQUEST_DATASTOREMODE._serialized_end = 10135 + _DATASTORERESPONSE._serialized_start = 10181 + _DATASTORERESPONSE._serialized_end = 10311 + _CREATEONIONREQUEST._serialized_start = 10314 + _CREATEONIONREQUEST._serialized_end = 10471 + _CREATEONIONRESPONSE._serialized_start = 10473 + _CREATEONIONRESPONSE._serialized_end = 10533 + _CREATEONIONHOPS._serialized_start = 10535 + _CREATEONIONHOPS._serialized_end = 10585 + _DELDATASTOREREQUEST._serialized_start = 10587 + _DELDATASTOREREQUEST._serialized_end = 10661 + _DELDATASTORERESPONSE._serialized_start = 10664 + _DELDATASTORERESPONSE._serialized_end = 10797 + _DELEXPIREDINVOICEREQUEST._serialized_start = 10799 + _DELEXPIREDINVOICEREQUEST._serialized_end = 10871 + _DELEXPIREDINVOICERESPONSE._serialized_start = 10873 + _DELEXPIREDINVOICERESPONSE._serialized_end = 10900 + _DELINVOICEREQUEST._serialized_start = 10903 + _DELINVOICEREQUEST._serialized_end = 11085 + _DELINVOICEREQUEST_DELINVOICESTATUS._serialized_start = 11019 + _DELINVOICEREQUEST_DELINVOICESTATUS._serialized_end = 11072 + _DELINVOICERESPONSE._serialized_start = 11088 + _DELINVOICERESPONSE._serialized_end = 11527 + _DELINVOICERESPONSE_DELINVOICESTATUS._serialized_start = 11019 + _DELINVOICERESPONSE_DELINVOICESTATUS._serialized_end = 11072 + _INVOICEREQUEST._serialized_start = 11530 + _INVOICEREQUEST._serialized_end = 11839 + _INVOICERESPONSE._serialized_start = 11842 + _INVOICERESPONSE._serialized_end = 12201 + _LISTDATASTOREREQUEST._serialized_start = 12203 + _LISTDATASTOREREQUEST._serialized_end = 12238 + _LISTDATASTORERESPONSE._serialized_start = 12240 + _LISTDATASTORERESPONSE._serialized_end = 12311 + _LISTDATASTOREDATASTORE._serialized_start = 12314 + _LISTDATASTOREDATASTORE._serialized_end = 12449 + _LISTINVOICESREQUEST._serialized_start = 12452 + _LISTINVOICESREQUEST._serialized_end = 12621 + _LISTINVOICESRESPONSE._serialized_start = 12623 + _LISTINVOICESRESPONSE._serialized_end = 12690 + _LISTINVOICESINVOICES._serialized_start = 12693 + _LISTINVOICESINVOICES._serialized_end = 13353 + _LISTINVOICESINVOICES_LISTINVOICESINVOICESSTATUS._serialized_start = 13130 + _LISTINVOICESINVOICES_LISTINVOICESINVOICESSTATUS._serialized_end = 13193 + _SENDONIONREQUEST._serialized_start = 13356 + _SENDONIONREQUEST._serialized_end = 13698 + _SENDONIONRESPONSE._serialized_start = 13701 + _SENDONIONRESPONSE._serialized_end = 14224 + _SENDONIONRESPONSE_SENDONIONSTATUS._serialized_start = 14072 + _SENDONIONRESPONSE_SENDONIONSTATUS._serialized_end = 14116 + _SENDONIONFIRST_HOP._serialized_start = 14226 + _SENDONIONFIRST_HOP._serialized_end = 14307 + _LISTSENDPAYSREQUEST._serialized_start = 14310 + _LISTSENDPAYSREQUEST._serialized_end = 14545 + _LISTSENDPAYSREQUEST_LISTSENDPAYSSTATUS._serialized_start = 14447 + _LISTSENDPAYSREQUEST_LISTSENDPAYSSTATUS._serialized_end = 14506 + _LISTSENDPAYSRESPONSE._serialized_start = 14547 + _LISTSENDPAYSRESPONSE._serialized_end = 14614 + _LISTSENDPAYSPAYMENTS._serialized_start = 14617 + _LISTSENDPAYSPAYMENTS._serialized_end = 15230 + _LISTSENDPAYSPAYMENTS_LISTSENDPAYSPAYMENTSSTATUS._serialized_start = 15035 + _LISTSENDPAYSPAYMENTS_LISTSENDPAYSPAYMENTSSTATUS._serialized_end = 15102 + _LISTTRANSACTIONSREQUEST._serialized_start = 15232 + _LISTTRANSACTIONSREQUEST._serialized_end = 15257 + _LISTTRANSACTIONSRESPONSE._serialized_start = 15259 + _LISTTRANSACTIONSRESPONSE._serialized_end = 15342 + _LISTTRANSACTIONSTRANSACTIONS._serialized_start = 15345 + _LISTTRANSACTIONSTRANSACTIONS._serialized_end = 15627 + _LISTTRANSACTIONSTRANSACTIONSINPUTS._serialized_start = 15630 + _LISTTRANSACTIONSTRANSACTIONSINPUTS._serialized_end = 16146 + _LISTTRANSACTIONSTRANSACTIONSINPUTS_LISTTRANSACTIONSTRANSACTIONSINPUTSTYPE._serialized_start = ( + 15842 + ) + _LISTTRANSACTIONSTRANSACTIONSINPUTS_LISTTRANSACTIONSTRANSACTIONSINPUTSTYPE._serialized_end = ( + 16120 + ) + _LISTTRANSACTIONSTRANSACTIONSOUTPUTS._serialized_start = 16149 + _LISTTRANSACTIONSTRANSACTIONSOUTPUTS._serialized_end = 16686 + _LISTTRANSACTIONSTRANSACTIONSOUTPUTS_LISTTRANSACTIONSTRANSACTIONSOUTPUTSTYPE._serialized_start = ( + 16381 + ) + _LISTTRANSACTIONSTRANSACTIONSOUTPUTS_LISTTRANSACTIONSTRANSACTIONSOUTPUTSTYPE._serialized_end = ( + 16660 + ) + _PAYREQUEST._serialized_start = 16689 + _PAYREQUEST._serialized_end = 17155 + _PAYRESPONSE._serialized_start = 17158 + _PAYRESPONSE._serialized_end = 17537 + _PAYRESPONSE_PAYSTATUS._serialized_start = 17440 + _PAYRESPONSE_PAYSTATUS._serialized_end = 17490 + _LISTNODESREQUEST._serialized_start = 17539 + _LISTNODESREQUEST._serialized_end = 17581 + _LISTNODESRESPONSE._serialized_start = 17583 + _LISTNODESRESPONSE._serialized_end = 17638 + _LISTNODESNODES._serialized_start = 17641 + _LISTNODESNODES._serialized_end = 17866 + _LISTNODESNODESADDRESSES._serialized_start = 17869 + _LISTNODESNODESADDRESSES._serialized_end = 18116 + _LISTNODESNODESADDRESSES_LISTNODESNODESADDRESSESTYPE._serialized_start = 18009 + _LISTNODESNODESADDRESSES_LISTNODESNODESADDRESSESTYPE._serialized_end = 18104 + _WAITANYINVOICEREQUEST._serialized_start = 18118 + _WAITANYINVOICEREQUEST._serialized_end = 18221 + _WAITANYINVOICERESPONSE._serialized_start = 18224 + _WAITANYINVOICERESPONSE._serialized_end = 18755 + _WAITANYINVOICERESPONSE_WAITANYINVOICESTATUS._serialized_start = 18600 + _WAITANYINVOICERESPONSE_WAITANYINVOICESTATUS._serialized_end = 18645 + _WAITINVOICEREQUEST._serialized_start = 18757 + _WAITINVOICEREQUEST._serialized_end = 18792 + _WAITINVOICERESPONSE._serialized_start = 18795 + _WAITINVOICERESPONSE._serialized_end = 19314 + _WAITINVOICERESPONSE_WAITINVOICESTATUS._serialized_start = 19162 + _WAITINVOICERESPONSE_WAITINVOICESTATUS._serialized_end = 19204 + _WAITSENDPAYREQUEST._serialized_start = 19317 + _WAITSENDPAYREQUEST._serialized_end = 19459 + _WAITSENDPAYRESPONSE._serialized_start = 19462 + _WAITSENDPAYRESPONSE._serialized_end = 19980 + _WAITSENDPAYRESPONSE_WAITSENDPAYSTATUS._serialized_start = 19839 + _WAITSENDPAYRESPONSE_WAITSENDPAYSTATUS._serialized_end = 19872 + _NEWADDRREQUEST._serialized_start = 19983 + _NEWADDRREQUEST._serialized_end = 20141 + _NEWADDRREQUEST_NEWADDRADDRESSTYPE._serialized_start = 20067 + _NEWADDRREQUEST_NEWADDRADDRESSTYPE._serialized_end = 20125 + _NEWADDRRESPONSE._serialized_start = 20143 + _NEWADDRRESPONSE._serialized_end = 20234 + _WITHDRAWREQUEST._serialized_start = 20237 + _WITHDRAWREQUEST._serialized_end = 20439 + _WITHDRAWRESPONSE._serialized_start = 20441 + _WITHDRAWRESPONSE._serialized_end = 20499 + _KEYSENDREQUEST._serialized_start = 20502 + _KEYSENDREQUEST._serialized_end = 20831 + _KEYSENDRESPONSE._serialized_start = 20834 + _KEYSENDRESPONSE._serialized_end = 21204 + _KEYSENDRESPONSE_KEYSENDSTATUS._serialized_start = 21128 + _KEYSENDRESPONSE_KEYSENDSTATUS._serialized_end = 21157 + _KEYSENDEXTRATLVS._serialized_start = 21206 + _KEYSENDEXTRATLVS._serialized_end = 21224 + _FUNDPSBTREQUEST._serialized_start = 21227 + _FUNDPSBTREQUEST._serialized_end = 21538 + _FUNDPSBTRESPONSE._serialized_start = 21541 + _FUNDPSBTRESPONSE._serialized_end = 21758 + _FUNDPSBTRESERVATIONS._serialized_start = 21760 + _FUNDPSBTRESERVATIONS._serialized_end = 21877 + _SENDPSBTREQUEST._serialized_start = 21879 + _SENDPSBTREQUEST._serialized_end = 21944 + _SENDPSBTRESPONSE._serialized_start = 21946 + _SENDPSBTRESPONSE._serialized_end = 21990 + _SIGNPSBTREQUEST._serialized_start = 21992 + _SIGNPSBTREQUEST._serialized_end = 22041 + _SIGNPSBTRESPONSE._serialized_start = 22043 + _SIGNPSBTRESPONSE._serialized_end = 22082 + _UTXOPSBTREQUEST._serialized_start = 22085 + _UTXOPSBTREQUEST._serialized_end = 22432 + _UTXOPSBTRESPONSE._serialized_start = 22435 + _UTXOPSBTRESPONSE._serialized_end = 22652 + _UTXOPSBTRESERVATIONS._serialized_start = 22654 + _UTXOPSBTRESERVATIONS._serialized_end = 22771 + _TXDISCARDREQUEST._serialized_start = 22773 + _TXDISCARDREQUEST._serialized_end = 22805 + _TXDISCARDRESPONSE._serialized_start = 22807 + _TXDISCARDRESPONSE._serialized_end = 22861 + _TXPREPAREREQUEST._serialized_start = 22864 + _TXPREPAREREQUEST._serialized_end = 23028 + _TXPREPARERESPONSE._serialized_start = 23030 + _TXPREPARERESPONSE._serialized_end = 23098 + _TXSENDREQUEST._serialized_start = 23100 + _TXSENDREQUEST._serialized_end = 23129 + _TXSENDRESPONSE._serialized_start = 23131 + _TXSENDRESPONSE._serialized_end = 23187 + _DISCONNECTREQUEST._serialized_start = 23189 + _DISCONNECTREQUEST._serialized_end = 23250 + _DISCONNECTRESPONSE._serialized_start = 23252 + _DISCONNECTRESPONSE._serialized_end = 23272 + _FEERATESREQUEST._serialized_start = 23274 + _FEERATESREQUEST._serialized_end = 23381 + _FEERATESREQUEST_FEERATESSTYLE._serialized_start = 23344 + _FEERATESREQUEST_FEERATESSTYLE._serialized_end = 23381 + _FEERATESRESPONSE._serialized_start = 23383 + _FEERATESRESPONSE._serialized_end = 23469 + _FEERATESPERKB._serialized_start = 23472 + _FEERATESPERKB._serialized_end = 23795 + _FEERATESPERKW._serialized_start = 23798 + _FEERATESPERKW._serialized_end = 24121 + _FEERATESONCHAIN_FEE_ESTIMATES._serialized_start = 24124 + _FEERATESONCHAIN_FEE_ESTIMATES._serialized_end = 24317 + _GETROUTEREQUEST._serialized_start = 24320 + _GETROUTEREQUEST._serialized_end = 24553 + _GETROUTERESPONSE._serialized_start = 24555 + _GETROUTERESPONSE._serialized_end = 24608 + _GETROUTEROUTE._serialized_start = 24611 + _GETROUTEROUTE._serialized_end = 24808 + _GETROUTEROUTE_GETROUTEROUTESTYLE._serialized_start = 24779 + _GETROUTEROUTE_GETROUTEROUTESTYLE._serialized_end = 24808 + _LISTFORWARDSREQUEST._serialized_start = 24811 + _LISTFORWARDSREQUEST._serialized_end = 25069 + _LISTFORWARDSREQUEST_LISTFORWARDSSTATUS._serialized_start = 24951 + _LISTFORWARDSREQUEST_LISTFORWARDSSTATUS._serialized_end = 25027 + _LISTFORWARDSRESPONSE._serialized_start = 25071 + _LISTFORWARDSRESPONSE._serialized_end = 25138 + _LISTFORWARDSFORWARDS._serialized_start = 25141 + _LISTFORWARDSFORWARDS._serialized_end = 25709 + _LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS._serialized_start = 25506 + _LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS._serialized_end = 25590 + _LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE._serialized_start = 25592 + _LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE._serialized_end = 25640 + _LISTPAYSREQUEST._serialized_start = 25712 + _LISTPAYSREQUEST._serialized_end = 25931 + _LISTPAYSREQUEST_LISTPAYSSTATUS._serialized_start = 25837 + _LISTPAYSREQUEST_LISTPAYSSTATUS._serialized_end = 25892 + _LISTPAYSRESPONSE._serialized_start = 25933 + _LISTPAYSRESPONSE._serialized_end = 25984 + _LISTPAYSPAYS._serialized_start = 25987 + _LISTPAYSPAYS._serialized_end = 26496 + _LISTPAYSPAYS_LISTPAYSPAYSSTATUS._serialized_start = 26321 + _LISTPAYSPAYS_LISTPAYSPAYSSTATUS._serialized_end = 26380 + _PINGREQUEST._serialized_start = 26498 + _PINGREQUEST._serialized_end = 26587 + _PINGRESPONSE._serialized_start = 26589 + _PINGRESPONSE._serialized_end = 26619 + _SIGNMESSAGEREQUEST._serialized_start = 26621 + _SIGNMESSAGEREQUEST._serialized_end = 26658 + _SIGNMESSAGERESPONSE._serialized_start = 26660 + _SIGNMESSAGERESPONSE._serialized_end = 26730 + _NODE._serialized_start = 26733 + _NODE._serialized_end = 29546 +# @@protoc_insertion_point(module_scope) diff --git a/app/repositories/ln_impl/protos/cln/node_pb2_grpc.py b/app/repositories/ln_impl/protos/cln/node_pb2_grpc.py new file mode 100644 index 0000000..5b8d2c8 --- /dev/null +++ b/app/repositories/ln_impl/protos/cln/node_pb2_grpc.py @@ -0,0 +1,2014 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import app.repositories.ln_impl.protos.cln.node_pb2 as node__pb2 + + +class NodeStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Getinfo = channel.unary_unary( + "/cln.Node/Getinfo", + request_serializer=node__pb2.GetinfoRequest.SerializeToString, + response_deserializer=node__pb2.GetinfoResponse.FromString, + ) + self.ListPeers = channel.unary_unary( + "/cln.Node/ListPeers", + request_serializer=node__pb2.ListpeersRequest.SerializeToString, + response_deserializer=node__pb2.ListpeersResponse.FromString, + ) + self.ListFunds = channel.unary_unary( + "/cln.Node/ListFunds", + request_serializer=node__pb2.ListfundsRequest.SerializeToString, + response_deserializer=node__pb2.ListfundsResponse.FromString, + ) + self.SendPay = channel.unary_unary( + "/cln.Node/SendPay", + request_serializer=node__pb2.SendpayRequest.SerializeToString, + response_deserializer=node__pb2.SendpayResponse.FromString, + ) + self.ListChannels = channel.unary_unary( + "/cln.Node/ListChannels", + request_serializer=node__pb2.ListchannelsRequest.SerializeToString, + response_deserializer=node__pb2.ListchannelsResponse.FromString, + ) + self.AddGossip = channel.unary_unary( + "/cln.Node/AddGossip", + request_serializer=node__pb2.AddgossipRequest.SerializeToString, + response_deserializer=node__pb2.AddgossipResponse.FromString, + ) + self.AutoCleanInvoice = channel.unary_unary( + "/cln.Node/AutoCleanInvoice", + request_serializer=node__pb2.AutocleaninvoiceRequest.SerializeToString, + response_deserializer=node__pb2.AutocleaninvoiceResponse.FromString, + ) + self.CheckMessage = channel.unary_unary( + "/cln.Node/CheckMessage", + request_serializer=node__pb2.CheckmessageRequest.SerializeToString, + response_deserializer=node__pb2.CheckmessageResponse.FromString, + ) + self.Close = channel.unary_unary( + "/cln.Node/Close", + request_serializer=node__pb2.CloseRequest.SerializeToString, + response_deserializer=node__pb2.CloseResponse.FromString, + ) + self.ConnectPeer = channel.unary_unary( + "/cln.Node/ConnectPeer", + request_serializer=node__pb2.ConnectRequest.SerializeToString, + response_deserializer=node__pb2.ConnectResponse.FromString, + ) + self.CreateInvoice = channel.unary_unary( + "/cln.Node/CreateInvoice", + request_serializer=node__pb2.CreateinvoiceRequest.SerializeToString, + response_deserializer=node__pb2.CreateinvoiceResponse.FromString, + ) + self.Datastore = channel.unary_unary( + "/cln.Node/Datastore", + request_serializer=node__pb2.DatastoreRequest.SerializeToString, + response_deserializer=node__pb2.DatastoreResponse.FromString, + ) + self.CreateOnion = channel.unary_unary( + "/cln.Node/CreateOnion", + request_serializer=node__pb2.CreateonionRequest.SerializeToString, + response_deserializer=node__pb2.CreateonionResponse.FromString, + ) + self.DelDatastore = channel.unary_unary( + "/cln.Node/DelDatastore", + request_serializer=node__pb2.DeldatastoreRequest.SerializeToString, + response_deserializer=node__pb2.DeldatastoreResponse.FromString, + ) + self.DelExpiredInvoice = channel.unary_unary( + "/cln.Node/DelExpiredInvoice", + request_serializer=node__pb2.DelexpiredinvoiceRequest.SerializeToString, + response_deserializer=node__pb2.DelexpiredinvoiceResponse.FromString, + ) + self.DelInvoice = channel.unary_unary( + "/cln.Node/DelInvoice", + request_serializer=node__pb2.DelinvoiceRequest.SerializeToString, + response_deserializer=node__pb2.DelinvoiceResponse.FromString, + ) + self.Invoice = channel.unary_unary( + "/cln.Node/Invoice", + request_serializer=node__pb2.InvoiceRequest.SerializeToString, + response_deserializer=node__pb2.InvoiceResponse.FromString, + ) + self.ListDatastore = channel.unary_unary( + "/cln.Node/ListDatastore", + request_serializer=node__pb2.ListdatastoreRequest.SerializeToString, + response_deserializer=node__pb2.ListdatastoreResponse.FromString, + ) + self.ListInvoices = channel.unary_unary( + "/cln.Node/ListInvoices", + request_serializer=node__pb2.ListinvoicesRequest.SerializeToString, + response_deserializer=node__pb2.ListinvoicesResponse.FromString, + ) + self.SendOnion = channel.unary_unary( + "/cln.Node/SendOnion", + request_serializer=node__pb2.SendonionRequest.SerializeToString, + response_deserializer=node__pb2.SendonionResponse.FromString, + ) + self.ListSendPays = channel.unary_unary( + "/cln.Node/ListSendPays", + request_serializer=node__pb2.ListsendpaysRequest.SerializeToString, + response_deserializer=node__pb2.ListsendpaysResponse.FromString, + ) + self.ListTransactions = channel.unary_unary( + "/cln.Node/ListTransactions", + request_serializer=node__pb2.ListtransactionsRequest.SerializeToString, + response_deserializer=node__pb2.ListtransactionsResponse.FromString, + ) + self.Pay = channel.unary_unary( + "/cln.Node/Pay", + request_serializer=node__pb2.PayRequest.SerializeToString, + response_deserializer=node__pb2.PayResponse.FromString, + ) + self.ListNodes = channel.unary_unary( + "/cln.Node/ListNodes", + request_serializer=node__pb2.ListnodesRequest.SerializeToString, + response_deserializer=node__pb2.ListnodesResponse.FromString, + ) + self.WaitAnyInvoice = channel.unary_unary( + "/cln.Node/WaitAnyInvoice", + request_serializer=node__pb2.WaitanyinvoiceRequest.SerializeToString, + response_deserializer=node__pb2.WaitanyinvoiceResponse.FromString, + ) + self.WaitInvoice = channel.unary_unary( + "/cln.Node/WaitInvoice", + request_serializer=node__pb2.WaitinvoiceRequest.SerializeToString, + response_deserializer=node__pb2.WaitinvoiceResponse.FromString, + ) + self.WaitSendPay = channel.unary_unary( + "/cln.Node/WaitSendPay", + request_serializer=node__pb2.WaitsendpayRequest.SerializeToString, + response_deserializer=node__pb2.WaitsendpayResponse.FromString, + ) + self.NewAddr = channel.unary_unary( + "/cln.Node/NewAddr", + request_serializer=node__pb2.NewaddrRequest.SerializeToString, + response_deserializer=node__pb2.NewaddrResponse.FromString, + ) + self.Withdraw = channel.unary_unary( + "/cln.Node/Withdraw", + request_serializer=node__pb2.WithdrawRequest.SerializeToString, + response_deserializer=node__pb2.WithdrawResponse.FromString, + ) + self.KeySend = channel.unary_unary( + "/cln.Node/KeySend", + request_serializer=node__pb2.KeysendRequest.SerializeToString, + response_deserializer=node__pb2.KeysendResponse.FromString, + ) + self.FundPsbt = channel.unary_unary( + "/cln.Node/FundPsbt", + request_serializer=node__pb2.FundpsbtRequest.SerializeToString, + response_deserializer=node__pb2.FundpsbtResponse.FromString, + ) + self.SendPsbt = channel.unary_unary( + "/cln.Node/SendPsbt", + request_serializer=node__pb2.SendpsbtRequest.SerializeToString, + response_deserializer=node__pb2.SendpsbtResponse.FromString, + ) + self.SignPsbt = channel.unary_unary( + "/cln.Node/SignPsbt", + request_serializer=node__pb2.SignpsbtRequest.SerializeToString, + response_deserializer=node__pb2.SignpsbtResponse.FromString, + ) + self.UtxoPsbt = channel.unary_unary( + "/cln.Node/UtxoPsbt", + request_serializer=node__pb2.UtxopsbtRequest.SerializeToString, + response_deserializer=node__pb2.UtxopsbtResponse.FromString, + ) + self.TxDiscard = channel.unary_unary( + "/cln.Node/TxDiscard", + request_serializer=node__pb2.TxdiscardRequest.SerializeToString, + response_deserializer=node__pb2.TxdiscardResponse.FromString, + ) + self.TxPrepare = channel.unary_unary( + "/cln.Node/TxPrepare", + request_serializer=node__pb2.TxprepareRequest.SerializeToString, + response_deserializer=node__pb2.TxprepareResponse.FromString, + ) + self.TxSend = channel.unary_unary( + "/cln.Node/TxSend", + request_serializer=node__pb2.TxsendRequest.SerializeToString, + response_deserializer=node__pb2.TxsendResponse.FromString, + ) + self.Disconnect = channel.unary_unary( + "/cln.Node/Disconnect", + request_serializer=node__pb2.DisconnectRequest.SerializeToString, + response_deserializer=node__pb2.DisconnectResponse.FromString, + ) + self.Feerates = channel.unary_unary( + "/cln.Node/Feerates", + request_serializer=node__pb2.FeeratesRequest.SerializeToString, + response_deserializer=node__pb2.FeeratesResponse.FromString, + ) + self.GetRoute = channel.unary_unary( + "/cln.Node/GetRoute", + request_serializer=node__pb2.GetrouteRequest.SerializeToString, + response_deserializer=node__pb2.GetrouteResponse.FromString, + ) + self.ListForwards = channel.unary_unary( + "/cln.Node/ListForwards", + request_serializer=node__pb2.ListforwardsRequest.SerializeToString, + response_deserializer=node__pb2.ListforwardsResponse.FromString, + ) + self.ListPays = channel.unary_unary( + "/cln.Node/ListPays", + request_serializer=node__pb2.ListpaysRequest.SerializeToString, + response_deserializer=node__pb2.ListpaysResponse.FromString, + ) + self.Ping = channel.unary_unary( + "/cln.Node/Ping", + request_serializer=node__pb2.PingRequest.SerializeToString, + response_deserializer=node__pb2.PingResponse.FromString, + ) + self.SignMessage = channel.unary_unary( + "/cln.Node/SignMessage", + request_serializer=node__pb2.SignmessageRequest.SerializeToString, + response_deserializer=node__pb2.SignmessageResponse.FromString, + ) + + +class NodeServicer(object): + """Missing associated documentation comment in .proto file.""" + + def Getinfo(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListPeers(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListFunds(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def SendPay(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListChannels(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def AddGossip(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def AutoCleanInvoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def CheckMessage(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Close(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ConnectPeer(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def CreateInvoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Datastore(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def CreateOnion(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DelDatastore(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DelExpiredInvoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def DelInvoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Invoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListDatastore(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListInvoices(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def SendOnion(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListSendPays(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListTransactions(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Pay(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListNodes(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def WaitAnyInvoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def WaitInvoice(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def WaitSendPay(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def NewAddr(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Withdraw(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def KeySend(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def FundPsbt(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def SendPsbt(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def SignPsbt(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def UtxoPsbt(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def TxDiscard(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def TxPrepare(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def TxSend(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Disconnect(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Feerates(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def GetRoute(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListForwards(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def ListPays(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def Ping(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + def SignMessage(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details("Method not implemented!") + raise NotImplementedError("Method not implemented!") + + +def add_NodeServicer_to_server(servicer, server): + rpc_method_handlers = { + "Getinfo": grpc.unary_unary_rpc_method_handler( + servicer.Getinfo, + request_deserializer=node__pb2.GetinfoRequest.FromString, + response_serializer=node__pb2.GetinfoResponse.SerializeToString, + ), + "ListPeers": grpc.unary_unary_rpc_method_handler( + servicer.ListPeers, + request_deserializer=node__pb2.ListpeersRequest.FromString, + response_serializer=node__pb2.ListpeersResponse.SerializeToString, + ), + "ListFunds": grpc.unary_unary_rpc_method_handler( + servicer.ListFunds, + request_deserializer=node__pb2.ListfundsRequest.FromString, + response_serializer=node__pb2.ListfundsResponse.SerializeToString, + ), + "SendPay": grpc.unary_unary_rpc_method_handler( + servicer.SendPay, + request_deserializer=node__pb2.SendpayRequest.FromString, + response_serializer=node__pb2.SendpayResponse.SerializeToString, + ), + "ListChannels": grpc.unary_unary_rpc_method_handler( + servicer.ListChannels, + request_deserializer=node__pb2.ListchannelsRequest.FromString, + response_serializer=node__pb2.ListchannelsResponse.SerializeToString, + ), + "AddGossip": grpc.unary_unary_rpc_method_handler( + servicer.AddGossip, + request_deserializer=node__pb2.AddgossipRequest.FromString, + response_serializer=node__pb2.AddgossipResponse.SerializeToString, + ), + "AutoCleanInvoice": grpc.unary_unary_rpc_method_handler( + servicer.AutoCleanInvoice, + request_deserializer=node__pb2.AutocleaninvoiceRequest.FromString, + response_serializer=node__pb2.AutocleaninvoiceResponse.SerializeToString, + ), + "CheckMessage": grpc.unary_unary_rpc_method_handler( + servicer.CheckMessage, + request_deserializer=node__pb2.CheckmessageRequest.FromString, + response_serializer=node__pb2.CheckmessageResponse.SerializeToString, + ), + "Close": grpc.unary_unary_rpc_method_handler( + servicer.Close, + request_deserializer=node__pb2.CloseRequest.FromString, + response_serializer=node__pb2.CloseResponse.SerializeToString, + ), + "ConnectPeer": grpc.unary_unary_rpc_method_handler( + servicer.ConnectPeer, + request_deserializer=node__pb2.ConnectRequest.FromString, + response_serializer=node__pb2.ConnectResponse.SerializeToString, + ), + "CreateInvoice": grpc.unary_unary_rpc_method_handler( + servicer.CreateInvoice, + request_deserializer=node__pb2.CreateinvoiceRequest.FromString, + response_serializer=node__pb2.CreateinvoiceResponse.SerializeToString, + ), + "Datastore": grpc.unary_unary_rpc_method_handler( + servicer.Datastore, + request_deserializer=node__pb2.DatastoreRequest.FromString, + response_serializer=node__pb2.DatastoreResponse.SerializeToString, + ), + "CreateOnion": grpc.unary_unary_rpc_method_handler( + servicer.CreateOnion, + request_deserializer=node__pb2.CreateonionRequest.FromString, + response_serializer=node__pb2.CreateonionResponse.SerializeToString, + ), + "DelDatastore": grpc.unary_unary_rpc_method_handler( + servicer.DelDatastore, + request_deserializer=node__pb2.DeldatastoreRequest.FromString, + response_serializer=node__pb2.DeldatastoreResponse.SerializeToString, + ), + "DelExpiredInvoice": grpc.unary_unary_rpc_method_handler( + servicer.DelExpiredInvoice, + request_deserializer=node__pb2.DelexpiredinvoiceRequest.FromString, + response_serializer=node__pb2.DelexpiredinvoiceResponse.SerializeToString, + ), + "DelInvoice": grpc.unary_unary_rpc_method_handler( + servicer.DelInvoice, + request_deserializer=node__pb2.DelinvoiceRequest.FromString, + response_serializer=node__pb2.DelinvoiceResponse.SerializeToString, + ), + "Invoice": grpc.unary_unary_rpc_method_handler( + servicer.Invoice, + request_deserializer=node__pb2.InvoiceRequest.FromString, + response_serializer=node__pb2.InvoiceResponse.SerializeToString, + ), + "ListDatastore": grpc.unary_unary_rpc_method_handler( + servicer.ListDatastore, + request_deserializer=node__pb2.ListdatastoreRequest.FromString, + response_serializer=node__pb2.ListdatastoreResponse.SerializeToString, + ), + "ListInvoices": grpc.unary_unary_rpc_method_handler( + servicer.ListInvoices, + request_deserializer=node__pb2.ListinvoicesRequest.FromString, + response_serializer=node__pb2.ListinvoicesResponse.SerializeToString, + ), + "SendOnion": grpc.unary_unary_rpc_method_handler( + servicer.SendOnion, + request_deserializer=node__pb2.SendonionRequest.FromString, + response_serializer=node__pb2.SendonionResponse.SerializeToString, + ), + "ListSendPays": grpc.unary_unary_rpc_method_handler( + servicer.ListSendPays, + request_deserializer=node__pb2.ListsendpaysRequest.FromString, + response_serializer=node__pb2.ListsendpaysResponse.SerializeToString, + ), + "ListTransactions": grpc.unary_unary_rpc_method_handler( + servicer.ListTransactions, + request_deserializer=node__pb2.ListtransactionsRequest.FromString, + response_serializer=node__pb2.ListtransactionsResponse.SerializeToString, + ), + "Pay": grpc.unary_unary_rpc_method_handler( + servicer.Pay, + request_deserializer=node__pb2.PayRequest.FromString, + response_serializer=node__pb2.PayResponse.SerializeToString, + ), + "ListNodes": grpc.unary_unary_rpc_method_handler( + servicer.ListNodes, + request_deserializer=node__pb2.ListnodesRequest.FromString, + response_serializer=node__pb2.ListnodesResponse.SerializeToString, + ), + "WaitAnyInvoice": grpc.unary_unary_rpc_method_handler( + servicer.WaitAnyInvoice, + request_deserializer=node__pb2.WaitanyinvoiceRequest.FromString, + response_serializer=node__pb2.WaitanyinvoiceResponse.SerializeToString, + ), + "WaitInvoice": grpc.unary_unary_rpc_method_handler( + servicer.WaitInvoice, + request_deserializer=node__pb2.WaitinvoiceRequest.FromString, + response_serializer=node__pb2.WaitinvoiceResponse.SerializeToString, + ), + "WaitSendPay": grpc.unary_unary_rpc_method_handler( + servicer.WaitSendPay, + request_deserializer=node__pb2.WaitsendpayRequest.FromString, + response_serializer=node__pb2.WaitsendpayResponse.SerializeToString, + ), + "NewAddr": grpc.unary_unary_rpc_method_handler( + servicer.NewAddr, + request_deserializer=node__pb2.NewaddrRequest.FromString, + response_serializer=node__pb2.NewaddrResponse.SerializeToString, + ), + "Withdraw": grpc.unary_unary_rpc_method_handler( + servicer.Withdraw, + request_deserializer=node__pb2.WithdrawRequest.FromString, + response_serializer=node__pb2.WithdrawResponse.SerializeToString, + ), + "KeySend": grpc.unary_unary_rpc_method_handler( + servicer.KeySend, + request_deserializer=node__pb2.KeysendRequest.FromString, + response_serializer=node__pb2.KeysendResponse.SerializeToString, + ), + "FundPsbt": grpc.unary_unary_rpc_method_handler( + servicer.FundPsbt, + request_deserializer=node__pb2.FundpsbtRequest.FromString, + response_serializer=node__pb2.FundpsbtResponse.SerializeToString, + ), + "SendPsbt": grpc.unary_unary_rpc_method_handler( + servicer.SendPsbt, + request_deserializer=node__pb2.SendpsbtRequest.FromString, + response_serializer=node__pb2.SendpsbtResponse.SerializeToString, + ), + "SignPsbt": grpc.unary_unary_rpc_method_handler( + servicer.SignPsbt, + request_deserializer=node__pb2.SignpsbtRequest.FromString, + response_serializer=node__pb2.SignpsbtResponse.SerializeToString, + ), + "UtxoPsbt": grpc.unary_unary_rpc_method_handler( + servicer.UtxoPsbt, + request_deserializer=node__pb2.UtxopsbtRequest.FromString, + response_serializer=node__pb2.UtxopsbtResponse.SerializeToString, + ), + "TxDiscard": grpc.unary_unary_rpc_method_handler( + servicer.TxDiscard, + request_deserializer=node__pb2.TxdiscardRequest.FromString, + response_serializer=node__pb2.TxdiscardResponse.SerializeToString, + ), + "TxPrepare": grpc.unary_unary_rpc_method_handler( + servicer.TxPrepare, + request_deserializer=node__pb2.TxprepareRequest.FromString, + response_serializer=node__pb2.TxprepareResponse.SerializeToString, + ), + "TxSend": grpc.unary_unary_rpc_method_handler( + servicer.TxSend, + request_deserializer=node__pb2.TxsendRequest.FromString, + response_serializer=node__pb2.TxsendResponse.SerializeToString, + ), + "Disconnect": grpc.unary_unary_rpc_method_handler( + servicer.Disconnect, + request_deserializer=node__pb2.DisconnectRequest.FromString, + response_serializer=node__pb2.DisconnectResponse.SerializeToString, + ), + "Feerates": grpc.unary_unary_rpc_method_handler( + servicer.Feerates, + request_deserializer=node__pb2.FeeratesRequest.FromString, + response_serializer=node__pb2.FeeratesResponse.SerializeToString, + ), + "GetRoute": grpc.unary_unary_rpc_method_handler( + servicer.GetRoute, + request_deserializer=node__pb2.GetrouteRequest.FromString, + response_serializer=node__pb2.GetrouteResponse.SerializeToString, + ), + "ListForwards": grpc.unary_unary_rpc_method_handler( + servicer.ListForwards, + request_deserializer=node__pb2.ListforwardsRequest.FromString, + response_serializer=node__pb2.ListforwardsResponse.SerializeToString, + ), + "ListPays": grpc.unary_unary_rpc_method_handler( + servicer.ListPays, + request_deserializer=node__pb2.ListpaysRequest.FromString, + response_serializer=node__pb2.ListpaysResponse.SerializeToString, + ), + "Ping": grpc.unary_unary_rpc_method_handler( + servicer.Ping, + request_deserializer=node__pb2.PingRequest.FromString, + response_serializer=node__pb2.PingResponse.SerializeToString, + ), + "SignMessage": grpc.unary_unary_rpc_method_handler( + servicer.SignMessage, + request_deserializer=node__pb2.SignmessageRequest.FromString, + response_serializer=node__pb2.SignmessageResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + "cln.Node", rpc_method_handlers + ) + server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class Node(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def Getinfo( + 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, + "/cln.Node/Getinfo", + node__pb2.GetinfoRequest.SerializeToString, + node__pb2.GetinfoResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListPeers( + 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, + "/cln.Node/ListPeers", + node__pb2.ListpeersRequest.SerializeToString, + node__pb2.ListpeersResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListFunds( + 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, + "/cln.Node/ListFunds", + node__pb2.ListfundsRequest.SerializeToString, + node__pb2.ListfundsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SendPay( + 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, + "/cln.Node/SendPay", + node__pb2.SendpayRequest.SerializeToString, + node__pb2.SendpayResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListChannels( + 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, + "/cln.Node/ListChannels", + node__pb2.ListchannelsRequest.SerializeToString, + node__pb2.ListchannelsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def AddGossip( + 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, + "/cln.Node/AddGossip", + node__pb2.AddgossipRequest.SerializeToString, + node__pb2.AddgossipResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def AutoCleanInvoice( + 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, + "/cln.Node/AutoCleanInvoice", + node__pb2.AutocleaninvoiceRequest.SerializeToString, + node__pb2.AutocleaninvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CheckMessage( + 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, + "/cln.Node/CheckMessage", + node__pb2.CheckmessageRequest.SerializeToString, + node__pb2.CheckmessageResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Close( + 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, + "/cln.Node/Close", + node__pb2.CloseRequest.SerializeToString, + node__pb2.CloseResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ConnectPeer( + 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, + "/cln.Node/ConnectPeer", + node__pb2.ConnectRequest.SerializeToString, + node__pb2.ConnectResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CreateInvoice( + 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, + "/cln.Node/CreateInvoice", + node__pb2.CreateinvoiceRequest.SerializeToString, + node__pb2.CreateinvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Datastore( + 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, + "/cln.Node/Datastore", + node__pb2.DatastoreRequest.SerializeToString, + node__pb2.DatastoreResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CreateOnion( + 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, + "/cln.Node/CreateOnion", + node__pb2.CreateonionRequest.SerializeToString, + node__pb2.CreateonionResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DelDatastore( + 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, + "/cln.Node/DelDatastore", + node__pb2.DeldatastoreRequest.SerializeToString, + node__pb2.DeldatastoreResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DelExpiredInvoice( + 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, + "/cln.Node/DelExpiredInvoice", + node__pb2.DelexpiredinvoiceRequest.SerializeToString, + node__pb2.DelexpiredinvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DelInvoice( + 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, + "/cln.Node/DelInvoice", + node__pb2.DelinvoiceRequest.SerializeToString, + node__pb2.DelinvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Invoice( + 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, + "/cln.Node/Invoice", + node__pb2.InvoiceRequest.SerializeToString, + node__pb2.InvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListDatastore( + 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, + "/cln.Node/ListDatastore", + node__pb2.ListdatastoreRequest.SerializeToString, + node__pb2.ListdatastoreResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListInvoices( + 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, + "/cln.Node/ListInvoices", + node__pb2.ListinvoicesRequest.SerializeToString, + node__pb2.ListinvoicesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SendOnion( + 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, + "/cln.Node/SendOnion", + node__pb2.SendonionRequest.SerializeToString, + node__pb2.SendonionResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListSendPays( + 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, + "/cln.Node/ListSendPays", + node__pb2.ListsendpaysRequest.SerializeToString, + node__pb2.ListsendpaysResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListTransactions( + 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, + "/cln.Node/ListTransactions", + node__pb2.ListtransactionsRequest.SerializeToString, + node__pb2.ListtransactionsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Pay( + 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, + "/cln.Node/Pay", + node__pb2.PayRequest.SerializeToString, + node__pb2.PayResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListNodes( + 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, + "/cln.Node/ListNodes", + node__pb2.ListnodesRequest.SerializeToString, + node__pb2.ListnodesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def WaitAnyInvoice( + 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, + "/cln.Node/WaitAnyInvoice", + node__pb2.WaitanyinvoiceRequest.SerializeToString, + node__pb2.WaitanyinvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def WaitInvoice( + 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, + "/cln.Node/WaitInvoice", + node__pb2.WaitinvoiceRequest.SerializeToString, + node__pb2.WaitinvoiceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def WaitSendPay( + 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, + "/cln.Node/WaitSendPay", + node__pb2.WaitsendpayRequest.SerializeToString, + node__pb2.WaitsendpayResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def NewAddr( + 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, + "/cln.Node/NewAddr", + node__pb2.NewaddrRequest.SerializeToString, + node__pb2.NewaddrResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Withdraw( + 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, + "/cln.Node/Withdraw", + node__pb2.WithdrawRequest.SerializeToString, + node__pb2.WithdrawResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def KeySend( + 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, + "/cln.Node/KeySend", + node__pb2.KeysendRequest.SerializeToString, + node__pb2.KeysendResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def FundPsbt( + 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, + "/cln.Node/FundPsbt", + node__pb2.FundpsbtRequest.SerializeToString, + node__pb2.FundpsbtResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SendPsbt( + 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, + "/cln.Node/SendPsbt", + node__pb2.SendpsbtRequest.SerializeToString, + node__pb2.SendpsbtResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SignPsbt( + 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, + "/cln.Node/SignPsbt", + node__pb2.SignpsbtRequest.SerializeToString, + node__pb2.SignpsbtResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def UtxoPsbt( + 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, + "/cln.Node/UtxoPsbt", + node__pb2.UtxopsbtRequest.SerializeToString, + node__pb2.UtxopsbtResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def TxDiscard( + 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, + "/cln.Node/TxDiscard", + node__pb2.TxdiscardRequest.SerializeToString, + node__pb2.TxdiscardResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def TxPrepare( + 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, + "/cln.Node/TxPrepare", + node__pb2.TxprepareRequest.SerializeToString, + node__pb2.TxprepareResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def TxSend( + 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, + "/cln.Node/TxSend", + node__pb2.TxsendRequest.SerializeToString, + node__pb2.TxsendResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Disconnect( + 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, + "/cln.Node/Disconnect", + node__pb2.DisconnectRequest.SerializeToString, + node__pb2.DisconnectResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Feerates( + 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, + "/cln.Node/Feerates", + node__pb2.FeeratesRequest.SerializeToString, + node__pb2.FeeratesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetRoute( + 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, + "/cln.Node/GetRoute", + node__pb2.GetrouteRequest.SerializeToString, + node__pb2.GetrouteResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListForwards( + 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, + "/cln.Node/ListForwards", + node__pb2.ListforwardsRequest.SerializeToString, + node__pb2.ListforwardsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListPays( + 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, + "/cln.Node/ListPays", + node__pb2.ListpaysRequest.SerializeToString, + node__pb2.ListpaysResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Ping( + 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, + "/cln.Node/Ping", + node__pb2.PingRequest.SerializeToString, + node__pb2.PingResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SignMessage( + 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, + "/cln.Node/SignMessage", + node__pb2.SignmessageRequest.SerializeToString, + node__pb2.SignmessageResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/app/repositories/ln_impl/protos/cln/primitives_pb2.py b/app/repositories/ln_impl/protos/cln/primitives_pb2.py new file mode 100644 index 0000000..d822744 --- /dev/null +++ b/app/repositories/ln_impl/protos/cln/primitives_pb2.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: primitives.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import enum_type_wrapper + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x10primitives.proto\x12\x03\x63ln"\x16\n\x06\x41mount\x12\x0c\n\x04msat\x18\x01 \x01(\x04"D\n\x0b\x41mountOrAll\x12\x1d\n\x06\x61mount\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x12\r\n\x03\x61ll\x18\x02 \x01(\x08H\x00\x42\x07\n\x05value"D\n\x0b\x41mountOrAny\x12\x1d\n\x06\x61mount\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x12\r\n\x03\x61ny\x18\x02 \x01(\x08H\x00\x42\x07\n\x05value"\x19\n\x17\x43hannelStateChangeCause"(\n\x08Outpoint\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06outnum\x18\x02 \x01(\r"h\n\x07\x46\x65\x65rate\x12\x0e\n\x04slow\x18\x01 \x01(\x08H\x00\x12\x10\n\x06normal\x18\x02 \x01(\x08H\x00\x12\x10\n\x06urgent\x18\x03 \x01(\x08H\x00\x12\x0f\n\x05perkb\x18\x04 \x01(\rH\x00\x12\x0f\n\x05perkw\x18\x05 \x01(\rH\x00\x42\x07\n\x05style":\n\nOutputDesc\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x1b\n\x06\x61mount\x18\x02 \x01(\x0b\x32\x0b.cln.Amount"t\n\x08RouteHop\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x18\n\x10short_channel_id\x18\x02 \x01(\t\x12\x1c\n\x07\x66\x65\x65\x62\x61se\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x0f\n\x07\x66\x65\x65prop\x18\x04 \x01(\r\x12\x13\n\x0b\x65xpirydelta\x18\x05 \x01(\r"(\n\tRoutehint\x12\x1b\n\x04hops\x18\x01 \x03(\x0b\x32\r.cln.RouteHop".\n\rRoutehintList\x12\x1d\n\x05hints\x18\x02 \x03(\x0b\x32\x0e.cln.Routehint*\x1e\n\x0b\x43hannelSide\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01*\x84\x02\n\x0c\x43hannelState\x12\x0c\n\x08Openingd\x10\x00\x12\x1a\n\x16\x43hanneldAwaitingLockin\x10\x01\x12\x12\n\x0e\x43hanneldNormal\x10\x02\x12\x18\n\x14\x43hanneldShuttingDown\x10\x03\x12\x17\n\x13\x43losingdSigexchange\x10\x04\x12\x14\n\x10\x43losingdComplete\x10\x05\x12\x16\n\x12\x41waitingUnilateral\x10\x06\x12\x14\n\x10\x46undingSpendSeen\x10\x07\x12\x0b\n\x07Onchain\x10\x08\x12\x15\n\x11\x44ualopendOpenInit\x10\t\x12\x1b\n\x17\x44ualopendAwaitingLockin\x10\nb\x06proto3' +) + +_CHANNELSIDE = DESCRIPTOR.enum_types_by_name["ChannelSide"] +ChannelSide = enum_type_wrapper.EnumTypeWrapper(_CHANNELSIDE) +_CHANNELSTATE = DESCRIPTOR.enum_types_by_name["ChannelState"] +ChannelState = enum_type_wrapper.EnumTypeWrapper(_CHANNELSTATE) +IN = 0 +OUT = 1 +Openingd = 0 +ChanneldAwaitingLockin = 1 +ChanneldNormal = 2 +ChanneldShuttingDown = 3 +ClosingdSigexchange = 4 +ClosingdComplete = 5 +AwaitingUnilateral = 6 +FundingSpendSeen = 7 +Onchain = 8 +DualopendOpenInit = 9 +DualopendAwaitingLockin = 10 + + +_AMOUNT = DESCRIPTOR.message_types_by_name["Amount"] +_AMOUNTORALL = DESCRIPTOR.message_types_by_name["AmountOrAll"] +_AMOUNTORANY = DESCRIPTOR.message_types_by_name["AmountOrAny"] +_CHANNELSTATECHANGECAUSE = DESCRIPTOR.message_types_by_name["ChannelStateChangeCause"] +_OUTPOINT = DESCRIPTOR.message_types_by_name["Outpoint"] +_FEERATE = DESCRIPTOR.message_types_by_name["Feerate"] +_OUTPUTDESC = DESCRIPTOR.message_types_by_name["OutputDesc"] +_ROUTEHOP = DESCRIPTOR.message_types_by_name["RouteHop"] +_ROUTEHINT = DESCRIPTOR.message_types_by_name["Routehint"] +_ROUTEHINTLIST = DESCRIPTOR.message_types_by_name["RoutehintList"] +Amount = _reflection.GeneratedProtocolMessageType( + "Amount", + (_message.Message,), + { + "DESCRIPTOR": _AMOUNT, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.Amount) + }, +) +_sym_db.RegisterMessage(Amount) + +AmountOrAll = _reflection.GeneratedProtocolMessageType( + "AmountOrAll", + (_message.Message,), + { + "DESCRIPTOR": _AMOUNTORALL, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.AmountOrAll) + }, +) +_sym_db.RegisterMessage(AmountOrAll) + +AmountOrAny = _reflection.GeneratedProtocolMessageType( + "AmountOrAny", + (_message.Message,), + { + "DESCRIPTOR": _AMOUNTORANY, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.AmountOrAny) + }, +) +_sym_db.RegisterMessage(AmountOrAny) + +ChannelStateChangeCause = _reflection.GeneratedProtocolMessageType( + "ChannelStateChangeCause", + (_message.Message,), + { + "DESCRIPTOR": _CHANNELSTATECHANGECAUSE, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.ChannelStateChangeCause) + }, +) +_sym_db.RegisterMessage(ChannelStateChangeCause) + +Outpoint = _reflection.GeneratedProtocolMessageType( + "Outpoint", + (_message.Message,), + { + "DESCRIPTOR": _OUTPOINT, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.Outpoint) + }, +) +_sym_db.RegisterMessage(Outpoint) + +Feerate = _reflection.GeneratedProtocolMessageType( + "Feerate", + (_message.Message,), + { + "DESCRIPTOR": _FEERATE, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.Feerate) + }, +) +_sym_db.RegisterMessage(Feerate) + +OutputDesc = _reflection.GeneratedProtocolMessageType( + "OutputDesc", + (_message.Message,), + { + "DESCRIPTOR": _OUTPUTDESC, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.OutputDesc) + }, +) +_sym_db.RegisterMessage(OutputDesc) + +RouteHop = _reflection.GeneratedProtocolMessageType( + "RouteHop", + (_message.Message,), + { + "DESCRIPTOR": _ROUTEHOP, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.RouteHop) + }, +) +_sym_db.RegisterMessage(RouteHop) + +Routehint = _reflection.GeneratedProtocolMessageType( + "Routehint", + (_message.Message,), + { + "DESCRIPTOR": _ROUTEHINT, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.Routehint) + }, +) +_sym_db.RegisterMessage(Routehint) + +RoutehintList = _reflection.GeneratedProtocolMessageType( + "RoutehintList", + (_message.Message,), + { + "DESCRIPTOR": _ROUTEHINTLIST, + "__module__": "primitives_pb2" + # @@protoc_insertion_point(class_scope:cln.RoutehintList) + }, +) +_sym_db.RegisterMessage(RoutehintList) + +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _CHANNELSIDE._serialized_start = 632 + _CHANNELSIDE._serialized_end = 662 + _CHANNELSTATE._serialized_start = 665 + _CHANNELSTATE._serialized_end = 925 + _AMOUNT._serialized_start = 25 + _AMOUNT._serialized_end = 47 + _AMOUNTORALL._serialized_start = 49 + _AMOUNTORALL._serialized_end = 117 + _AMOUNTORANY._serialized_start = 119 + _AMOUNTORANY._serialized_end = 187 + _CHANNELSTATECHANGECAUSE._serialized_start = 189 + _CHANNELSTATECHANGECAUSE._serialized_end = 214 + _OUTPOINT._serialized_start = 216 + _OUTPOINT._serialized_end = 256 + _FEERATE._serialized_start = 258 + _FEERATE._serialized_end = 362 + _OUTPUTDESC._serialized_start = 364 + _OUTPUTDESC._serialized_end = 422 + _ROUTEHOP._serialized_start = 424 + _ROUTEHOP._serialized_end = 540 + _ROUTEHINT._serialized_start = 542 + _ROUTEHINT._serialized_end = 582 + _ROUTEHINTLIST._serialized_start = 584 + _ROUTEHINTLIST._serialized_end = 630 +# @@protoc_insertion_point(module_scope) diff --git a/app/repositories/ln_impl/protos/cln/primitives_pb2_grpc.py b/app/repositories/ln_impl/protos/cln/primitives_pb2_grpc.py new file mode 100644 index 0000000..8a93939 --- /dev/null +++ b/app/repositories/ln_impl/protos/cln/primitives_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc diff --git a/app/repositories/ln_impl/protos/lightning_pb2.py b/app/repositories/ln_impl/protos/lnd/lightning_pb2.py similarity index 100% rename from app/repositories/ln_impl/protos/lightning_pb2.py rename to app/repositories/ln_impl/protos/lnd/lightning_pb2.py diff --git a/app/repositories/ln_impl/protos/lightning_pb2_grpc.py b/app/repositories/ln_impl/protos/lnd/lightning_pb2_grpc.py similarity index 99% rename from app/repositories/ln_impl/protos/lightning_pb2_grpc.py rename to app/repositories/ln_impl/protos/lnd/lightning_pb2_grpc.py index 5deee92..d4f554e 100644 --- a/app/repositories/ln_impl/protos/lightning_pb2_grpc.py +++ b/app/repositories/ln_impl/protos/lnd/lightning_pb2_grpc.py @@ -2,7 +2,7 @@ """Client and server classes corresponding to protobuf-defined services.""" import grpc -import app.repositories.ln_impl.protos.lightning_pb2 as lightning__pb2 +import app.repositories.ln_impl.protos.lnd.lightning_pb2 as lightning__pb2 class LightningStub(object): diff --git a/app/repositories/ln_impl/protos/router_pb2.py b/app/repositories/ln_impl/protos/lnd/router_pb2.py similarity index 99% rename from app/repositories/ln_impl/protos/router_pb2.py rename to app/repositories/ln_impl/protos/lnd/router_pb2.py index 644529a..5502c3d 100644 --- a/app/repositories/ln_impl/protos/router_pb2.py +++ b/app/repositories/ln_impl/protos/lnd/router_pb2.py @@ -8,7 +8,7 @@ from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import enum_type_wrapper -import app.repositories.ln_impl.protos.lightning_pb2 as lightning__pb2 +import app.repositories.ln_impl.protos.lnd.lightning_pb2 as lightning__pb2 # @@protoc_insertion_point(imports) diff --git a/app/repositories/ln_impl/protos/router_pb2_grpc.py b/app/repositories/ln_impl/protos/lnd/router_pb2_grpc.py similarity index 99% rename from app/repositories/ln_impl/protos/router_pb2_grpc.py rename to app/repositories/ln_impl/protos/lnd/router_pb2_grpc.py index 2178962..3a1beb0 100644 --- a/app/repositories/ln_impl/protos/router_pb2_grpc.py +++ b/app/repositories/ln_impl/protos/lnd/router_pb2_grpc.py @@ -2,8 +2,8 @@ """Client and server classes corresponding to protobuf-defined services.""" import grpc -import app.repositories.ln_impl.protos.lightning_pb2 as lightning__pb2 -import app.repositories.ln_impl.protos.router_pb2 as router__pb2 +import app.repositories.ln_impl.protos.lnd.lightning_pb2 as lightning__pb2 +import app.repositories.ln_impl.protos.lnd.router_pb2 as router__pb2 class RouterStub(object): diff --git a/app/repositories/ln_impl/protos/signer_pb2.py b/app/repositories/ln_impl/protos/lnd/signer_pb2.py similarity index 100% rename from app/repositories/ln_impl/protos/signer_pb2.py rename to app/repositories/ln_impl/protos/lnd/signer_pb2.py diff --git a/app/repositories/ln_impl/protos/signer_pb2_grpc.py b/app/repositories/ln_impl/protos/lnd/signer_pb2_grpc.py similarity index 100% rename from app/repositories/ln_impl/protos/signer_pb2_grpc.py rename to app/repositories/ln_impl/protos/lnd/signer_pb2_grpc.py diff --git a/app/repositories/ln_impl/protos/walletunlocker_pb2.py b/app/repositories/ln_impl/protos/lnd/walletunlocker_pb2.py similarity index 99% rename from app/repositories/ln_impl/protos/walletunlocker_pb2.py rename to app/repositories/ln_impl/protos/lnd/walletunlocker_pb2.py index b75850a..258783c 100644 --- a/app/repositories/ln_impl/protos/walletunlocker_pb2.py +++ b/app/repositories/ln_impl/protos/lnd/walletunlocker_pb2.py @@ -12,7 +12,7 @@ from google.protobuf import symbol_database as _symbol_database _sym_db = _symbol_database.Default() -import app.repositories.ln_impl.protos.lightning_pb2 as lightning__pb2 +import app.repositories.ln_impl.protos.lnd.lightning_pb2 as lightning__pb2 DESCRIPTOR = _descriptor.FileDescriptor( name="walletunlocker.proto", diff --git a/app/repositories/ln_impl/protos/walletunlocker_pb2_grpc.py b/app/repositories/ln_impl/protos/lnd/walletunlocker_pb2_grpc.py similarity index 99% rename from app/repositories/ln_impl/protos/walletunlocker_pb2_grpc.py rename to app/repositories/ln_impl/protos/lnd/walletunlocker_pb2_grpc.py index 5e4b29b..e7f9909 100644 --- a/app/repositories/ln_impl/protos/walletunlocker_pb2_grpc.py +++ b/app/repositories/ln_impl/protos/lnd/walletunlocker_pb2_grpc.py @@ -2,7 +2,7 @@ """Client and server classes corresponding to protobuf-defined services.""" import grpc -import app.repositories.ln_impl.protos.walletunlocker_pb2 as walletunlocker__pb2 +import app.repositories.ln_impl.protos.lnd.walletunlocker_pb2 as walletunlocker__pb2 class WalletUnlockerStub(object): diff --git a/app/routers/lightning.py b/app/routers/lightning.py index e5d3b57..f8b2f2e 100644 --- a/app/routers/lightning.py +++ b/app/routers/lightning.py @@ -42,6 +42,7 @@ from app.repositories.lightning import ( from app.routers.lightning_docs import ( get_balance_response_desc, new_address_desc, + open_channel_desc, send_coins_desc, send_payment_desc, ) @@ -51,7 +52,9 @@ _PREFIX = "lightning" router = APIRouter(prefix=f"/{_PREFIX}", tags=["Lightning"]) responses = { - 423: {"description": "Wallet is locked. Unlock via /lightning/unlock-wallet"} + 423: { + "description": "LND only: Wallet is locked. Unlock via /lightning/unlock-wallet." + } } @@ -273,7 +276,10 @@ async def new_address_path(input: NewAddressInput): response_description="Either an error or a SendCoinsResponse object on success", dependencies=[Depends(JWTBearer())], response_model=SendCoinsResponse, - responses=responses, + responses={ + 412: {"description": "When not enough funds are available."}, + 423: responses[423], + }, ) async def send_coins_path(input: SendCoinsInput): try: @@ -288,10 +294,14 @@ async def send_coins_path(input: SendCoinsInput): "/open-channel", name=f"{_PREFIX}.open-channel", summary="open a new lightning channel", - description="For additional information see [LND docs](https://api.lightning.community/#openchannel)", + description=open_channel_desc, dependencies=[Depends(JWTBearer())], response_model=str, - responses=responses, + responses={ + 412: {"description": "When not enough funds are available."}, + 423: responses[423], + 504: {"description": "When the peer is not reachable."}, + }, ) async def channelopen(local_funding_amount: int, node_URI: str, target_confs: int = 3): try: diff --git a/app/routers/lightning_docs.py b/app/routers/lightning_docs.py index 5942e56..a7ca345 100644 --- a/app/routers/lightning_docs.py +++ b/app/routers/lightning_docs.py @@ -1,3 +1,13 @@ +add_invoice_desc = """ +Adds a new invoice to the database. + +LND is generating a unique auto-incrementing `add_index` for the invoice. + +CLN will receive a [Firebase-like PushID](https://firebase.blog/posts/2015/02/the-2120-ways-to-ensure-unique_68) from the backend for the `label` when creating the invoice. + +Please refer to the response schema docs for more information. +""" + get_balance_response_desc = """ A JSON String with on chain wallet balances with on-chain balances in **sat** and channel balances in **msat**. Detailed description is in @@ -31,3 +41,17 @@ This endpoints attempts to pay a payment request. Intermediate status updates will be sent via the SSE channel. This endpoint returns the last success or error message from the node. """ + +open_channel_desc = """ +__open-channel__ attempts to open a channel with a peer. + +### LND: +__target_conf__: The target number of blocks that the funding transaction should be confirmed by. + +### c-lightning: +* Set __target_conf__ ==1: interpreted as urgent (aim for next block) +* Set __target_conf__ >=2: interpreted as normal (next 4 blocks or so, **default**) +* Set __target_cont__ >=10: interpreted as slow (next 100 blocks or so) + +> 👉 See [https://lightning.readthedocs.io/lightning-txprepare.7.html](https://lightning.readthedocs.io/lightning-txprepare.7.html) +""" diff --git a/app/utils.py b/app/utils.py index 30b386e..4aa17a8 100644 --- a/app/utils.py +++ b/app/utils.py @@ -1,8 +1,11 @@ +import array import asyncio import json import logging import os +import random import re +import time from types import coroutine from typing import Dict @@ -14,9 +17,19 @@ from fastapi.encoders import jsonable_encoder from fastapi_plugins import redis_plugin from starlette import status -import app.repositories.ln_impl.protos.lightning_pb2_grpc as lnrpc -import app.repositories.ln_impl.protos.router_pb2_grpc as routerrpc -import app.repositories.ln_impl.protos.walletunlocker_pb2_grpc as unlockerrpc +node_type = config("ln_node") +if node_type == "lnd": + import app.repositories.ln_impl.protos.lnd.lightning_pb2_grpc as lnrpc + import app.repositories.ln_impl.protos.lnd.router_pb2_grpc as routerrpc + import app.repositories.ln_impl.protos.lnd.walletunlocker_pb2_grpc as unlockerrpc +elif node_type == "cln_grpc": + import app.repositories.ln_impl.protos.cln.node_pb2_grpc as clnrpc +elif node_type == "cln_unix_socket": + from pyln.client import LightningRpc +else: + raise ValueError(f"Unknown node type: {node_type}") + + from app.models.bitcoind import BlockRpcFunc @@ -48,8 +61,9 @@ class LightningConfig: def __init__(self) -> None: self.network = config("network") self.ln_node = config("ln_node") + self.cln_sock: "LightningRpc" = None - if self.ln_node == "lnd": + if self.ln_node == "lnd_grpc": # Due to updated ECDSA generated tls.cert we need to let gprc know that # we need to use that cipher suite otherwise there will be a handshake # error when we communicate with the lnd rpc server. @@ -74,9 +88,22 @@ class LightningConfig: self.lnd_stub = lnrpc.LightningStub(self._channel) self.router_stub = routerrpc.RouterStub(self._channel) self.wallet_unlocker = unlockerrpc.WalletUnlockerStub(self._channel) - elif self.ln_node == "clightning": - # TODO: implement c-lightning - pass + elif self.ln_node == "cln_unix_socket": + self._cln_socket_path = config("cln_socket_path") + self.cln_sock = LightningRpc(self._cln_socket_path) # type: LightningRpc + elif self.ln_node == "cln_grpc": + cln_grpc_cert = bytes.fromhex(config("cln_grpc_cert")) + cln_grpc_key = bytes.fromhex(config("cln_grpc_key")) + cln_grpc_ca = bytes.fromhex(config("cln_grpc_ca")) + cln_grpc_url = config("cln_grpc_ip") + ":" + config("cln_grpc_port") + creds = grpc.ssl_channel_credentials( + root_certificates=cln_grpc_ca, + private_key=cln_grpc_key, + certificate_chain=cln_grpc_cert, + ) + opts = (("grpc.ssl_target_name_override", "cln"),) + self._channel = grpc.aio.secure_channel(cln_grpc_url, creds, options=opts) + self.cln_stub = clnrpc.NodeStub(self._channel) elif self.ln_node == "": # its ok to run raspiblitz also without lightning pass @@ -238,3 +265,78 @@ def parse_key_value_lines(lines: list) -> dict: def parse_key_value_text(text: str) -> dict: return parse_key_value_lines(text.splitlines()) + + +# https://gist.github.com/risent/4cab3878d995bec7d1c2 +# https://firebase.blog/posts/2015/02/the-2120-ways-to-ensure-unique_68 +# https://gist.github.com/mikelehen/3596a30bd69384624c11 +class _PushID(object): + # Modeled after base64 web-safe chars, but ordered by ASCII. + PUSH_CHARS = ( + "-0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "_abcdefghijklmnopqrstuvwxyz" + ) + + def __init__(self): + + # Timestamp of last push, used to prevent local collisions if you + # pushtwice in one ms. + self.last_push_time = 0 + + # We generate 72-bits of randomness which get turned into 12 + # characters and appended to the timestamp to prevent + # collisions with other clients. We store the last characters + # we generated because in the event of a collision, we'll use + # those same characters except "incremented" by one. + self.last_rand_chars = array.array("i", [i for i in range(12)]) + + def next_id(self): + now = int(time.time() * 1000) + duplicate_time = now == self.last_push_time + self.last_push_time = now + time_stamp_chars = array.array("u", "12345678") + + for i in range(7, -1, -1): + time_stamp_chars[i] = self.PUSH_CHARS[now % 64] + now = int(now / 64) + + if now != 0: + raise ValueError("We should have converted the entire timestamp.") + + uid = "".join(time_stamp_chars) + + if not duplicate_time: + for i in range(12): + self.last_rand_chars[i] = int(random.random() * 64) + else: + # If the timestamp hasn't changed since last push, use the + # same random number, except incremented by 1. + for i in range(11, -1, -1): + if self.last_rand_chars[i] == 63: + self.last_rand_chars[i] = 0 + else: + break + self.last_rand_chars[i] += 1 + + for i in range(12): + uid += self.PUSH_CHARS[self.last_rand_chars[i]] + + if len(uid) != 20: + raise ValueError("Length should be 20.") + + return uid + + +pid_gen = _PushID() + + +def next_push_id() -> str: + """Generates a unique random 20 character long string id + + * They're based on timestamp so that they sort *after* any existing ids. + * They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs. + * They sort *lexicographically* (so the timestamp is converted to characters that will sort properly). + * They're monotonically increasing. Even if you generate more than one in the same timestamp, the + latter ones will sort after the former ones. We do this by using the previous random bits + but "incrementing" them by 1 (only in the case of a timestamp collision). + """ + return pid_gen.next_id()