From c9e4f23cf465bd3ab3ddfcc53dbcaf0e168c1a21 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Tue, 5 May 2020 22:08:35 +0200 Subject: [PATCH] v0.10.0 with support for routerrpc --- Gemfile.lock | 2 +- README.md | 3 + lib/lnrpc.rb | 20 +- lib/lnrpc/client.rb | 66 ++-- lib/lnrpc/grpc_wrapper.rb | 66 ++++ lib/lnrpc/router.proto | 560 ++++++++++++++++++++++++++++++++ lib/lnrpc/router_pb.rb | 198 +++++++++++ lib/lnrpc/router_services_pb.rb | 69 ++++ 8 files changed, 933 insertions(+), 51 deletions(-) create mode 100644 lib/lnrpc/grpc_wrapper.rb create mode 100644 lib/lnrpc/router.proto create mode 100644 lib/lnrpc/router_pb.rb create mode 100644 lib/lnrpc/router_services_pb.rb diff --git a/Gemfile.lock b/Gemfile.lock index 793c904..49b3806 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - lnrpc (0.8.0.beta) + lnrpc (0.10.0) google-protobuf (>= 3.7) grpc (>= 1.19.0) diff --git a/README.md b/README.md index 8658132..a910f61 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ a [gRPC](https://grpc.io/) client for [LND, the Lightning Network Daemon](https: ## Installation +Note: there is still an GRPC/protobuf [issue with Ruby 2.7](https://github.com/protocolbuffers/protobuf/issues/7070). +So lnrpc requires Ruby < 2.7. + Add this line to your application's Gemfile: ```ruby diff --git a/lib/lnrpc.rb b/lib/lnrpc.rb index 301e49a..5e716d0 100644 --- a/lib/lnrpc.rb +++ b/lib/lnrpc.rb @@ -1,10 +1,22 @@ -require "lnrpc/version" -require "lnrpc/rpc_services_pb" +require 'lnrpc/version' +require 'lnrpc/rpc_services_pb' +require 'lnrpc/router_services_pb' +require 'securerandom' module Lnrpc class Error < StandardError; end autoload :Client, 'lnrpc/client' + autoload :GrpcWrapper, 'lnrpc/grpc_wrapper' autoload :MacaroonInterceptor, 'lnrpc/macaroon_interceptor' + + PREIMAGE_BYTE_LENGTH = 32 + KEY_SEND_PREIMAGE_TYPE = 5482373484 + + def self.create_preimage + SecureRandom.random_bytes(PREIMAGE_BYTE_LENGTH) + end + + def self.to_byte_array(str) + [str].pack("H*") + end end - - diff --git a/lib/lnrpc/client.rb b/lib/lnrpc/client.rb index 2d83a2a..963b1da 100644 --- a/lib/lnrpc/client.rb +++ b/lib/lnrpc/client.rb @@ -3,32 +3,12 @@ require "lnrpc/macaroon_interceptor" module Lnrpc class Client attr_accessor :address, :credentials, :macaroon - attr_writer :grpc_client LND_HOME_DIR = ENV['LND_HOME'] || "~/.lnd" DEFAULT_ADDRESS = 'localhost:10009' DEFAULT_CREDENTIALS_PATH = "#{LND_HOME_DIR}/tls.cert" DEFAULT_MACAROON_PATH = "#{LND_HOME_DIR}/data/chain/bitcoin/mainnet/admin.macaroon" - NON_CONVENTION_REQUEST_CLASSES = { - add_invoice: Lnrpc::Invoice, - send_payment: Lnrpc::SendRequest, - send_payment_sync: Lnrpc::SendRequest, - open_channel_sync: Lnrpc::OpenChannelRequest, - send_to_route_sync: Lnrpc::SendToRouteRequest, - lookup_invoice: Lnrpc::PaymentHash, - decode_pay_req: Lnrpc::PayReqString, - describe_graph: Lnrpc::ChannelGraphRequest, - get_chan_info: Lnrpc::ChanInfoRequest, - get_node_info: Lnrpc::NodeInfoRequest, - get_network_info: Lnrpc::NetworkInfoRequest, - stop_daemon: Lnrpc::StopRequest, - update_channel_policy: Lnrpc::PolicyUpdateResponse, - subscribe_channel_graph: Lnrpc::GraphTopologySubscription, - subscribe_invoices: Lnrpc::InvoiceSubscription, - subscribe_transactions: Lnrpc::GetTransactionsRequest - } - def initialize(options={}) self.address = options[:address] || DEFAULT_ADDRESS @@ -46,42 +26,36 @@ module Lnrpc self.macaroon = options[:macaroon] end - def grpc_client - @grpc_client ||= Lnrpc::Lightning::Stub.new(self.address, - GRPC::Core::ChannelCredentials.new(self.credentials), - interceptors: [Lnrpc::MacaroonInterceptor.new(self.macaroon)] - ) + def lightning + @lightning ||= GrpcWrapper.new(Lnrpc::Lightning::Stub.new(address, + GRPC::Core::ChannelCredentials.new(credentials), + interceptors: [Lnrpc::MacaroonInterceptor.new(macaroon)] + )) end - def pay(payreq) - self.send_payment_sync(Lnrpc::SendRequest.new(payment_request: payreq)) + def router + @router ||= GrpcWrapper.new(Routerrpc::Router::Stub.new(address, + GRPC::Core::ChannelCredentials.new(credentials), + interceptors: [Lnrpc::MacaroonInterceptor.new(macaroon)] + )) end - def method_missing(m, *args, &block) - if self.grpc_client.respond_to?(m) - params = args[0] + def keysend(args) + args[:dest_custom_records] ||= {} + args[:dest_custom_records][Lnrpc::KEY_SEND_PREIMAGE_TYPE] ||= Lnrpc.create_preimage + args[:payment_hash] ||= Digest::SHA256.digest(args[:dest_custom_records][Lnrpc::KEY_SEND_PREIMAGE_TYPE]) + args[:timeout_seconds] ||= 60 + router.send_payment_v2(args) + end - args[0] = params.nil? ? request_class_for(m).new : request_class_for(m).new(params) - self.grpc_client.send(m, *args, &block) - else - super - end + def pay(args) + args[:timeout_seconds] ||= 60 + router.send_payment_v2(args) end def inspect "#{self.to_s} @address=\"#{self.address}\"" end - private - def request_class_for(method_name) - if NON_CONVENTION_REQUEST_CLASSES.key?(method_name.to_sym) - NON_CONVENTION_REQUEST_CLASSES[method_name.to_sym] - else - klass = method_name.to_s.sub(/^[a-z\d]*/) { |match| match.capitalize } - klass.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" } - Lnrpc.const_get("#{klass}Request") - end - end end end - diff --git a/lib/lnrpc/grpc_wrapper.rb b/lib/lnrpc/grpc_wrapper.rb new file mode 100644 index 0000000..97352ce --- /dev/null +++ b/lib/lnrpc/grpc_wrapper.rb @@ -0,0 +1,66 @@ +module Lnrpc + class GrpcWrapper + NON_CONVENTION_REQUEST_CLASSES = { + add_invoice: Lnrpc::Invoice, + decode_pay_req: Lnrpc::PayReqString, + describe_graph: Lnrpc::ChannelGraphRequest, + export_all_channel_backups: Lnrpc::ChanBackupExportRequest, + funding_state_step: Lnrpc::FundingTransitionMsg, + get_chan_info: Lnrpc::ChanInfoRequest, + get_network_info: Lnrpc::NetworkInfoRequest, + get_node_info: Lnrpc::NodeInfoRequest, + get_node_metrics: Lnrpc::NodeMetricsRequest, + lookup_invoice: Lnrpc::PaymentHash, + open_channel_sync: Lnrpc::OpenChannelRequest, + send_payment_sync: Lnrpc::SendRequest, + send_to_route_sync: Lnrpc::SendToRouteRequest, + stop_daemon: Lnrpc::StopRequest, + subscribe_channel_backups: Lnrpc::ChannelBackupSubscription, + subscribe_channel_event: Lnrpc::ChannelEventSubscription, + subscribe_channel_graph: Lnrpc::GraphTopologySubscription, + subscribe_invoices: Lnrpc::InvoiceSubscription, + subscribe_peer_event: Lnrpc::PeerEventSubscription, + subscribe_transactions: Lnrpc::GetTransactionsRequest, + update_channel_policy: Lnrpc::PolicyUpdateResponse, + varify_channel_backup: Lnrpc::ChanBackupSnapshot, + + estimate_route_fee: Routerrpc::RouteFeeRequest, + send_payment: Routerrpc::SendPaymentRequest, + send_payment_v2: Routerrpc::SendPaymentRequest, + track_payment_v2: Routerrpc::TrackPaymentRequest + } + + attr_reader :grpc + + def initialize(grpc) + @grpc = grpc + end + + def method_missing(m, *args, &block) + if self.grpc.respond_to?(m) + params = args[0] + + args[0] = params.nil? ? request_class_for(m).new : request_class_for(m).new(params) + self.grpc.send(m, *args, &block) + else + super + end + end + + def inspect + "#{self.to_s} @grpc=\"#{self.grpc.to_s}\"" + end + + private + + def request_class_for(method_name) + if NON_CONVENTION_REQUEST_CLASSES.key?(method_name.to_sym) + NON_CONVENTION_REQUEST_CLASSES[method_name.to_sym] + else + klass = method_name.to_s.sub(/^[a-z\d]*/) { |match| match.capitalize } + klass.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" } + Module.const_get(grpc.class.name.to_s[/.+?(?=::)/]).const_get("#{klass}Request") + end + end + end +end diff --git a/lib/lnrpc/router.proto b/lib/lnrpc/router.proto new file mode 100644 index 0000000..673ffb9 --- /dev/null +++ b/lib/lnrpc/router.proto @@ -0,0 +1,560 @@ +syntax = "proto3"; + +import "rpc.proto"; + +package routerrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/routerrpc"; + +message SendPaymentRequest { + /// The identity pubkey of the payment recipient + bytes dest = 1; + + /** + Number of satoshis to send. + + The fields amt and amt_msat are mutually exclusive. + */ + int64 amt = 2; + + /** + Number of millisatoshis to send. + + The fields amt and amt_msat are mutually exclusive. + */ + int64 amt_msat = 12; + + /// The hash to use within the payment's HTLC + bytes payment_hash = 3; + + /** + The CLTV delta from the current height that should be used to set the + timelock for the final hop. + */ + int32 final_cltv_delta = 4; + + /** + 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. The amount in the payment request may be zero. In + that case it is required to set the amt field as well. If no payment request + is specified, the following fields are required: dest, amt and payment_hash. + */ + string payment_request = 5; + + /** + An upper limit on the amount of time we should spend when attempting to + fulfill the payment. This is expressed in seconds. If we cannot make a + successful payment within this time frame, an error will be returned. + This field must be non-zero. + */ + int32 timeout_seconds = 6; + + /** + The maximum number of satoshis that will be paid as a fee of the payment. + If this field is left to the default value of 0, only zero-fee routes will + be considered. This usually means single hop routes connecting directly to + the destination. To send the payment without a fee limit, use max int here. + + The fields fee_limit_sat and fee_limit_msat are mutually exclusive. + */ + int64 fee_limit_sat = 7; + + /** + The maximum number of millisatoshis that will be paid as a fee of the + payment. If this field is left to the default value of 0, only zero-fee + routes will be considered. This usually means single hop routes connecting + directly to the destination. To send the payment without a fee limit, use + max int here. + + The fields fee_limit_sat and fee_limit_msat are mutually exclusive. + */ + int64 fee_limit_msat = 13; + + /** + The channel id of the channel that must be taken to the first hop. If zero, + any channel may be used. + */ + uint64 outgoing_chan_id = 8 [jstype = JS_STRING]; + + /** + The pubkey of the last hop of the route. If empty, any hop may be used. + */ + bytes last_hop_pubkey = 14; + + /** + An optional maximum total time lock for the route. This should not exceed + lnd's `--max-cltv-expiry` setting. If zero, then the value of + `--max-cltv-expiry` is enforced. + */ + int32 cltv_limit = 9; + + /** + Optional route hints to reach the destination through private channels. + */ + repeated lnrpc.RouteHint route_hints = 10; + + /** + An optional field that can be used to pass an arbitrary set of TLV records + to a peer which understands the new records. This can be used to pass + application specific data during the payment attempt. Record types are + required to be in the custom range >= 65536. When using REST, the values + must be encoded as base64. + */ + map dest_custom_records = 11; + + /// If set, circular payments to self are permitted. + bool allow_self_payment = 15; + + /** + Features assumed to be supported by the final node. All transitive feature + dependencies must also be set properly. For a given feature bit pair, either + optional or remote may be set, but not both. If this field is nil or empty, + the router will try to load destination features from the graph as a + fallback. + */ + repeated lnrpc.FeatureBit dest_features = 16; + + /** + The maximum number of partial payments that may be use to complete the full + amount. + */ + uint32 max_parts = 17; + + /** + If set, only the final payment update is streamed back. Intermediate updates + that show which htlcs are still in flight are suppressed. + */ + bool no_inflight_updates = 18; +} + +message TrackPaymentRequest { + /// The hash of the payment to look up. + bytes payment_hash = 1; + + /** + If set, only the final payment update is streamed back. Intermediate updates + that show which htlcs are still in flight are suppressed. + */ + bool no_inflight_updates = 2; +} + +message RouteFeeRequest { + /** + The destination once wishes to obtain a routing fee quote to. + */ + bytes dest = 1; + + /** + The amount one wishes to send to the target destination. + */ + int64 amt_sat = 2; +} + +message RouteFeeResponse { + /** + A lower bound of the estimated fee to the target destination within the + network, expressed in milli-satoshis. + */ + int64 routing_fee_msat = 1; + + /** + An estimate of the worst case time delay that can occur. Note that callers + will still need to factor in the final CLTV delta of the last hop into this + value. + */ + int64 time_lock_delay = 2; +} + +message SendToRouteRequest { + /// The payment hash to use for the HTLC. + bytes payment_hash = 1; + + /// Route that should be used to attempt to complete the payment. + lnrpc.Route route = 2; +} + +message SendToRouteResponse { + /// The preimage obtained by making the payment. + bytes preimage = 1; + + /// The failure message in case the payment failed. + lnrpc.Failure failure = 2; +} + +message ResetMissionControlRequest { +} + +message ResetMissionControlResponse { +} + +message QueryMissionControlRequest { +} + +/// QueryMissionControlResponse contains mission control state. +message QueryMissionControlResponse { + reserved 1; + + /// Node pair-level mission control state. + repeated PairHistory pairs = 2; +} + +/// PairHistory contains the mission control state for a particular node pair. +message PairHistory { + /// The source node pubkey of the pair. + bytes node_from = 1; + + /// The destination node pubkey of the pair. + bytes node_to = 2; + + reserved 3, 4, 5, 6; + + PairData history = 7; +} + +message PairData { + /// Time of last failure. + int64 fail_time = 1; + + /** + Lowest amount that failed to forward rounded to whole sats. This may be + set to zero if the failure is independent of amount. + */ + int64 fail_amt_sat = 2; + + /** + Lowest amount that failed to forward in millisats. This may be + set to zero if the failure is independent of amount. + */ + int64 fail_amt_msat = 4; + + reserved 3; + + /// Time of last success. + int64 success_time = 5; + + /// Highest amount that we could successfully forward rounded to whole sats. + int64 success_amt_sat = 6; + + /// Highest amount that we could successfully forward in millisats. + int64 success_amt_msat = 7; +} + +message QueryProbabilityRequest { + /// The source node pubkey of the pair. + bytes from_node = 1; + + /// The destination node pubkey of the pair. + bytes to_node = 2; + + /// The amount for which to calculate a probability. + int64 amt_msat = 3; +} + +message QueryProbabilityResponse { + /// The success probability for the requested pair. + double probability = 1; + + /// The historical data for the requested pair. + PairData history = 2; +} + +message BuildRouteRequest { + /** + The amount to send expressed in msat. If set to zero, the minimum routable + amount is used. + */ + int64 amt_msat = 1; + + /** + CLTV delta from the current height that should be used for the timelock + of the final hop + */ + int32 final_cltv_delta = 2; + + /** + The channel id of the channel that must be taken to the first hop. If zero, + any channel may be used. + */ + uint64 outgoing_chan_id = 3 [jstype = JS_STRING]; + + /** + A list of hops that defines the route. This does not include the source hop + pubkey. + */ + repeated bytes hop_pubkeys = 4; +} + +message BuildRouteResponse { + /** + Fully specified route that can be used to execute the payment. + */ + lnrpc.Route route = 1; +} + +message SubscribeHtlcEventsRequest { +} + +/** +HtlcEvent contains the htlc event that was processed. These are served on a +best-effort basis; events are not persisted, delivery is not guaranteed +(in the event of a crash in the switch, forward events may be lost) and +some events may be replayed upon restart. Events consumed from this package +should be de-duplicated by the htlc's unique combination of incoming and +outgoing channel id and htlc id. [EXPERIMENTAL] +*/ +message HtlcEvent { + /** + The short channel id that the incoming htlc arrived at our node on. This + value is zero for sends. + */ + uint64 incoming_channel_id = 1; + + /** + The short channel id that the outgoing htlc left our node on. This value + is zero for receives. + */ + uint64 outgoing_channel_id = 2; + + /** + Incoming id is the index of the incoming htlc in the incoming channel. + This value is zero for sends. + */ + uint64 incoming_htlc_id = 3; + + /** + Outgoing id is the index of the outgoing htlc in the outgoing channel. + This value is zero for receives. + */ + uint64 outgoing_htlc_id = 4; + + /** + The time in unix nanoseconds that the event occurred. + */ + uint64 timestamp_ns = 5; + + enum EventType { + UNKNOWN = 0; + SEND = 1; + RECEIVE = 2; + FORWARD = 3; + } + + /** + The event type indicates whether the htlc was part of a send, receive or + forward. + */ + EventType event_type = 6; + + oneof event { + ForwardEvent forward_event = 7; + ForwardFailEvent forward_fail_event = 8; + SettleEvent settle_event = 9; + LinkFailEvent link_fail_event = 10; + } +} + +message HtlcInfo { + // The timelock on the incoming htlc. + uint32 incoming_timelock = 1; + + // The timelock on the outgoing htlc. + uint32 outgoing_timelock = 2; + + // The amount of the incoming htlc. + uint64 incoming_amt_msat = 3; + + // The amount of the outgoing htlc. + uint64 outgoing_amt_msat = 4; +} + +message ForwardEvent { + // Info contains details about the htlc that was forwarded. + HtlcInfo info = 1; +} + +message ForwardFailEvent { +} + +message SettleEvent { +} + +message LinkFailEvent { + // Info contains details about the htlc that we failed. + HtlcInfo info = 1; + + // FailureCode is the BOLT error code for the failure. + lnrpc.Failure.FailureCode wire_failure = 2; + + /** + FailureDetail provides additional information about the reason for the + failure. This detail enriches the information provided by the wire message + and may be 'no detail' if the wire message requires no additional metadata. + */ + FailureDetail failure_detail = 3; + + // A string representation of the link failure. + string failure_string = 4; +} + +enum FailureDetail { + UNKNOWN = 0; + NO_DETAIL = 1; + ONION_DECODE = 2; + LINK_NOT_ELIGIBLE = 3; + ON_CHAIN_TIMEOUT = 4; + HTLC_EXCEEDS_MAX = 5; + INSUFFICIENT_BALANCE = 6; + INCOMPLETE_FORWARD = 7; + HTLC_ADD_FAILED = 8; + FORWARDS_DISABLED = 9; + INVOICE_CANCELED = 10; + INVOICE_UNDERPAID = 11; + INVOICE_EXPIRY_TOO_SOON = 12; + INVOICE_NOT_OPEN = 13; + MPP_INVOICE_TIMEOUT = 14; + ADDRESS_MISMATCH = 15; + SET_TOTAL_MISMATCH = 16; + SET_TOTAL_TOO_LOW = 17; + SET_OVERPAID = 18; + UNKNOWN_INVOICE = 19; + INVALID_KEYSEND = 20; + MPP_IN_PROGRESS = 21; + CIRCULAR_ROUTE = 22; +} + +enum PaymentState { + /** + Payment is still in flight. + */ + IN_FLIGHT = 0; + + /** + Payment completed successfully. + */ + SUCCEEDED = 1; + + /** + There are more routes to try, but the payment timeout was exceeded. + */ + FAILED_TIMEOUT = 2; + + /** + All possible routes were tried and failed permanently. Or were no + routes to the destination at all. + */ + FAILED_NO_ROUTE = 3; + + /** + A non-recoverable error has occured. + */ + FAILED_ERROR = 4; + + /** + Payment details incorrect (unknown hash, invalid amt or + invalid final cltv delta) + */ + FAILED_INCORRECT_PAYMENT_DETAILS = 5; + + /** + Insufficient local balance. + */ + FAILED_INSUFFICIENT_BALANCE = 6; +} + +message PaymentStatus { + /// Current state the payment is in. + PaymentState state = 1; + + /** + The pre-image of the payment when state is SUCCEEDED. + */ + bytes preimage = 2; + + reserved 3; + + /** + The HTLCs made in attempt to settle the payment [EXPERIMENTAL]. + */ + repeated lnrpc.HTLCAttempt htlcs = 4; +} + +service Router { + /** + SendPaymentV2 attempts to route a payment described by the passed + PaymentRequest to the final destination. The call returns a stream of + payment updates. + */ + rpc SendPaymentV2 (SendPaymentRequest) returns (stream lnrpc.Payment); + + /** + TrackPaymentV2 returns an update stream for the payment identified by the + payment hash. + */ + rpc TrackPaymentV2 (TrackPaymentRequest) returns (stream lnrpc.Payment); + + /** + EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it + may cost to send an HTLC to the target end destination. + */ + rpc EstimateRouteFee (RouteFeeRequest) returns (RouteFeeResponse); + + /** + SendToRoute attempts to make a payment via the specified route. This method + differs from SendPayment in that it allows users to specify a full route + manually. This can be used for things like rebalancing, and atomic swaps. + */ + rpc SendToRoute (SendToRouteRequest) returns (SendToRouteResponse); + + /** + ResetMissionControl clears all mission control state and starts with a clean + slate. + */ + rpc ResetMissionControl (ResetMissionControlRequest) + returns (ResetMissionControlResponse); + + /** + QueryMissionControl exposes the internal mission control state to callers. + It is a development feature. + */ + rpc QueryMissionControl (QueryMissionControlRequest) + returns (QueryMissionControlResponse); + + /** + QueryProbability returns the current success probability estimate for a + given node pair and amount. + */ + rpc QueryProbability (QueryProbabilityRequest) + returns (QueryProbabilityResponse); + + /** + BuildRoute builds a fully specified route based on a list of hop public + keys. It retrieves the relevant channel policies from the graph in order to + calculate the correct fees and time locks. + */ + rpc BuildRoute (BuildRouteRequest) returns (BuildRouteResponse); + + /** + SubscribeHtlcEvents creates a uni-directional stream from the server to + the client which delivers a stream of htlc events. + */ + rpc SubscribeHtlcEvents (SubscribeHtlcEventsRequest) + returns (stream HtlcEvent); + + /** + Deprecated, use SendPaymentV2. SendPayment attempts to route a payment + described by the passed PaymentRequest to the final destination. The call + returns a stream of payment status updates. + */ + rpc SendPayment(SendPaymentRequest) returns (stream PaymentStatus) { + option deprecated = true; + } + + /** + Deprecated, use TrackPaymentV2. TrackPayment returns an update stream for + the payment identified by the payment hash. + */ + rpc TrackPayment(TrackPaymentRequest) returns (stream PaymentStatus) { + option deprecated = true; + } +} diff --git a/lib/lnrpc/router_pb.rb b/lib/lnrpc/router_pb.rb new file mode 100644 index 0000000..f456bd6 --- /dev/null +++ b/lib/lnrpc/router_pb.rb @@ -0,0 +1,198 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: router.proto + +require 'google/protobuf' + +require_relative 'rpc_pb' +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "routerrpc.SendPaymentRequest" do + optional :dest, :bytes, 1 + optional :amt, :int64, 2 + optional :amt_msat, :int64, 12 + optional :payment_hash, :bytes, 3 + optional :final_cltv_delta, :int32, 4 + optional :payment_request, :string, 5 + optional :timeout_seconds, :int32, 6 + optional :fee_limit_sat, :int64, 7 + optional :fee_limit_msat, :int64, 13 + optional :outgoing_chan_id, :uint64, 8 + optional :last_hop_pubkey, :bytes, 14 + optional :cltv_limit, :int32, 9 + repeated :route_hints, :message, 10, "lnrpc.RouteHint" + map :dest_custom_records, :uint64, :bytes, 11 + optional :allow_self_payment, :bool, 15 + repeated :dest_features, :enum, 16, "lnrpc.FeatureBit" + optional :max_parts, :uint32, 17 + optional :no_inflight_updates, :bool, 18 + end + add_message "routerrpc.TrackPaymentRequest" do + optional :payment_hash, :bytes, 1 + optional :no_inflight_updates, :bool, 2 + end + add_message "routerrpc.RouteFeeRequest" do + optional :dest, :bytes, 1 + optional :amt_sat, :int64, 2 + end + add_message "routerrpc.RouteFeeResponse" do + optional :routing_fee_msat, :int64, 1 + optional :time_lock_delay, :int64, 2 + end + add_message "routerrpc.SendToRouteRequest" do + optional :payment_hash, :bytes, 1 + optional :route, :message, 2, "lnrpc.Route" + end + add_message "routerrpc.SendToRouteResponse" do + optional :preimage, :bytes, 1 + optional :failure, :message, 2, "lnrpc.Failure" + end + add_message "routerrpc.ResetMissionControlRequest" do + end + add_message "routerrpc.ResetMissionControlResponse" do + end + add_message "routerrpc.QueryMissionControlRequest" do + end + add_message "routerrpc.QueryMissionControlResponse" do + repeated :pairs, :message, 2, "routerrpc.PairHistory" + end + add_message "routerrpc.PairHistory" do + optional :node_from, :bytes, 1 + optional :node_to, :bytes, 2 + optional :history, :message, 7, "routerrpc.PairData" + end + add_message "routerrpc.PairData" do + optional :fail_time, :int64, 1 + optional :fail_amt_sat, :int64, 2 + optional :fail_amt_msat, :int64, 4 + optional :success_time, :int64, 5 + optional :success_amt_sat, :int64, 6 + optional :success_amt_msat, :int64, 7 + end + add_message "routerrpc.QueryProbabilityRequest" do + optional :from_node, :bytes, 1 + optional :to_node, :bytes, 2 + optional :amt_msat, :int64, 3 + end + add_message "routerrpc.QueryProbabilityResponse" do + optional :probability, :double, 1 + optional :history, :message, 2, "routerrpc.PairData" + end + add_message "routerrpc.BuildRouteRequest" do + optional :amt_msat, :int64, 1 + optional :final_cltv_delta, :int32, 2 + optional :outgoing_chan_id, :uint64, 3 + repeated :hop_pubkeys, :bytes, 4 + end + add_message "routerrpc.BuildRouteResponse" do + optional :route, :message, 1, "lnrpc.Route" + end + add_message "routerrpc.SubscribeHtlcEventsRequest" do + end + add_message "routerrpc.HtlcEvent" do + optional :incoming_channel_id, :uint64, 1 + optional :outgoing_channel_id, :uint64, 2 + optional :incoming_htlc_id, :uint64, 3 + optional :outgoing_htlc_id, :uint64, 4 + optional :timestamp_ns, :uint64, 5 + optional :event_type, :enum, 6, "routerrpc.HtlcEvent.EventType" + oneof :event do + optional :forward_event, :message, 7, "routerrpc.ForwardEvent" + optional :forward_fail_event, :message, 8, "routerrpc.ForwardFailEvent" + optional :settle_event, :message, 9, "routerrpc.SettleEvent" + optional :link_fail_event, :message, 10, "routerrpc.LinkFailEvent" + end + end + add_enum "routerrpc.HtlcEvent.EventType" do + value :UNKNOWN, 0 + value :SEND, 1 + value :RECEIVE, 2 + value :FORWARD, 3 + end + add_message "routerrpc.HtlcInfo" do + optional :incoming_timelock, :uint32, 1 + optional :outgoing_timelock, :uint32, 2 + optional :incoming_amt_msat, :uint64, 3 + optional :outgoing_amt_msat, :uint64, 4 + end + add_message "routerrpc.ForwardEvent" do + optional :info, :message, 1, "routerrpc.HtlcInfo" + end + add_message "routerrpc.ForwardFailEvent" do + end + add_message "routerrpc.SettleEvent" do + end + add_message "routerrpc.LinkFailEvent" do + optional :info, :message, 1, "routerrpc.HtlcInfo" + optional :wire_failure, :enum, 2, "lnrpc.Failure.FailureCode" + optional :failure_detail, :enum, 3, "routerrpc.FailureDetail" + optional :failure_string, :string, 4 + end + add_message "routerrpc.PaymentStatus" do + optional :state, :enum, 1, "routerrpc.PaymentState" + optional :preimage, :bytes, 2 + repeated :htlcs, :message, 4, "lnrpc.HTLCAttempt" + end + add_enum "routerrpc.FailureDetail" do + value :UNKNOWN, 0 + value :NO_DETAIL, 1 + value :ONION_DECODE, 2 + value :LINK_NOT_ELIGIBLE, 3 + value :ON_CHAIN_TIMEOUT, 4 + value :HTLC_EXCEEDS_MAX, 5 + value :INSUFFICIENT_BALANCE, 6 + value :INCOMPLETE_FORWARD, 7 + value :HTLC_ADD_FAILED, 8 + value :FORWARDS_DISABLED, 9 + value :INVOICE_CANCELED, 10 + value :INVOICE_UNDERPAID, 11 + value :INVOICE_EXPIRY_TOO_SOON, 12 + value :INVOICE_NOT_OPEN, 13 + value :MPP_INVOICE_TIMEOUT, 14 + value :ADDRESS_MISMATCH, 15 + value :SET_TOTAL_MISMATCH, 16 + value :SET_TOTAL_TOO_LOW, 17 + value :SET_OVERPAID, 18 + value :UNKNOWN_INVOICE, 19 + value :INVALID_KEYSEND, 20 + value :MPP_IN_PROGRESS, 21 + value :CIRCULAR_ROUTE, 22 + end + add_enum "routerrpc.PaymentState" do + value :IN_FLIGHT, 0 + value :SUCCEEDED, 1 + value :FAILED_TIMEOUT, 2 + value :FAILED_NO_ROUTE, 3 + value :FAILED_ERROR, 4 + value :FAILED_INCORRECT_PAYMENT_DETAILS, 5 + value :FAILED_INSUFFICIENT_BALANCE, 6 + end +end + +module Routerrpc + SendPaymentRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.SendPaymentRequest").msgclass + TrackPaymentRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.TrackPaymentRequest").msgclass + RouteFeeRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.RouteFeeRequest").msgclass + RouteFeeResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.RouteFeeResponse").msgclass + SendToRouteRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.SendToRouteRequest").msgclass + SendToRouteResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.SendToRouteResponse").msgclass + ResetMissionControlRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.ResetMissionControlRequest").msgclass + ResetMissionControlResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.ResetMissionControlResponse").msgclass + QueryMissionControlRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.QueryMissionControlRequest").msgclass + QueryMissionControlResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.QueryMissionControlResponse").msgclass + PairHistory = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.PairHistory").msgclass + PairData = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.PairData").msgclass + QueryProbabilityRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.QueryProbabilityRequest").msgclass + QueryProbabilityResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.QueryProbabilityResponse").msgclass + BuildRouteRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.BuildRouteRequest").msgclass + BuildRouteResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.BuildRouteResponse").msgclass + SubscribeHtlcEventsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.SubscribeHtlcEventsRequest").msgclass + HtlcEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.HtlcEvent").msgclass + HtlcEvent::EventType = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.HtlcEvent.EventType").enummodule + HtlcInfo = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.HtlcInfo").msgclass + ForwardEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.ForwardEvent").msgclass + ForwardFailEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.ForwardFailEvent").msgclass + SettleEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.SettleEvent").msgclass + LinkFailEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.LinkFailEvent").msgclass + PaymentStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.PaymentStatus").msgclass + FailureDetail = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.FailureDetail").enummodule + PaymentState = Google::Protobuf::DescriptorPool.generated_pool.lookup("routerrpc.PaymentState").enummodule +end diff --git a/lib/lnrpc/router_services_pb.rb b/lib/lnrpc/router_services_pb.rb new file mode 100644 index 0000000..e58da1a --- /dev/null +++ b/lib/lnrpc/router_services_pb.rb @@ -0,0 +1,69 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: router.proto for package 'routerrpc' + +require 'grpc' +require_relative 'router_pb' + +module Routerrpc + module Router + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'routerrpc.Router' + + # * + # SendPaymentV2 attempts to route a payment described by the passed + # PaymentRequest to the final destination. The call returns a stream of + # payment updates. + rpc :SendPaymentV2, SendPaymentRequest, stream(Lnrpc::Payment) + # * + # TrackPaymentV2 returns an update stream for the payment identified by the + # payment hash. + rpc :TrackPaymentV2, TrackPaymentRequest, stream(Lnrpc::Payment) + # * + # EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it + # may cost to send an HTLC to the target end destination. + rpc :EstimateRouteFee, RouteFeeRequest, RouteFeeResponse + # * + # SendToRoute attempts to make a payment via the specified route. This method + # differs from SendPayment in that it allows users to specify a full route + # manually. This can be used for things like rebalancing, and atomic swaps. + rpc :SendToRoute, SendToRouteRequest, SendToRouteResponse + # * + # ResetMissionControl clears all mission control state and starts with a clean + # slate. + rpc :ResetMissionControl, ResetMissionControlRequest, ResetMissionControlResponse + # * + # QueryMissionControl exposes the internal mission control state to callers. + # It is a development feature. + rpc :QueryMissionControl, QueryMissionControlRequest, QueryMissionControlResponse + # * + # QueryProbability returns the current success probability estimate for a + # given node pair and amount. + rpc :QueryProbability, QueryProbabilityRequest, QueryProbabilityResponse + # * + # BuildRoute builds a fully specified route based on a list of hop public + # keys. It retrieves the relevant channel policies from the graph in order to + # calculate the correct fees and time locks. + rpc :BuildRoute, BuildRouteRequest, BuildRouteResponse + # * + # SubscribeHtlcEvents creates a uni-directional stream from the server to + # the client which delivers a stream of htlc events. + rpc :SubscribeHtlcEvents, SubscribeHtlcEventsRequest, stream(HtlcEvent) + # * + # Deprecated, use SendPaymentV2. SendPayment attempts to route a payment + # described by the passed PaymentRequest to the final destination. The call + # returns a stream of payment status updates. + rpc :SendPayment, SendPaymentRequest, stream(PaymentStatus) + # * + # Deprecated, use TrackPaymentV2. TrackPayment returns an update stream for + # the payment identified by the payment hash. + rpc :TrackPayment, TrackPaymentRequest, stream(PaymentStatus) + end + + Stub = Service.rpc_stub_class + end +end