diff --git a/cmd/loop/staticaddr.go b/cmd/loop/staticaddr.go index 4de4e7c28..9a7eb6905 100644 --- a/cmd/loop/staticaddr.go +++ b/cmd/loop/staticaddr.go @@ -9,7 +9,10 @@ import ( "strings" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightninglabs/loop/labels" "github.com/lightninglabs/loop/looprpc" + "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightningnetwork/lnd/routing/route" "github.com/urfave/cli" ) @@ -24,6 +27,46 @@ var staticAddressCommands = cli.Command{ withdrawalCommand, summaryCommand, }, + Description: ` + TODO . + `, + Flags: []cli.Flag{ + cli.StringSliceFlag{ + Name: "utxo", + Usage: "specify the utxos of deposits as " + + "outpoints(tx:idx) that should be looped in.", + }, + cli.StringFlag{ + Name: "last_hop", + Usage: "the pubkey of the last hop to use for this " + + "swap", + }, + cli.StringFlag{ + Name: "label", + Usage: fmt.Sprintf("an optional label for this swap,"+ + "limited to %v characters. The label may not "+ + "start with our reserved prefix: %v.", + labels.MaxLength, labels.Reserved), + }, + cli.StringSliceFlag{ + Name: "route_hints", + Usage: "route hints that can each be individually " + + "used to assist in reaching the invoice's " + + "destination", + }, + cli.BoolFlag{ + Name: "private", + Usage: "generates and passes routehints. Should be " + + "used if the connected node is only " + + "reachable via private channels", + }, + cli.BoolFlag{ + Name: "force, f", + Usage: "Assumes yes during confirmation. Using this " + + "option will result in an immediate swap", + }, + }, + Action: staticAddressLoopIn, } var newStaticAddressCommand = cli.Command{ @@ -196,7 +239,7 @@ var summaryCommand = cli.Command{ Usage: "specify a filter to only display deposits in " + "the specified state. The state can be one " + "of [deposited|withdrawing|withdrawn|" + - "publish_expired_deposit|" + + "loopingin|loopedin|publish_expired_deposit|" + "wait_for_expiry_sweep|expired|failed].", }, }, @@ -229,6 +272,12 @@ func summary(ctx *cli.Context) error { case "withdrawn": filterState = looprpc.DepositState_WITHDRAWN + case "loopingin": + filterState = looprpc.DepositState_LOOPING_IN + + case "loopedin": + filterState = looprpc.DepositState_LOOPED_IN + case "publish_expired_deposit": filterState = looprpc.DepositState_PUBLISH_EXPIRED @@ -297,3 +346,137 @@ func NewProtoOutPoint(op string) (*looprpc.OutPoint, error) { OutputIndex: uint32(outputIndex), }, nil } + +func staticAddressLoopIn(ctx *cli.Context) error { + if ctx.NArg() > 0 { + return cli.ShowCommandHelp(ctx, "static") + } + + client, cleanup, err := getClient(ctx) + if err != nil { + return err + } + defer cleanup() + + var ( + ctxb = context.Background() + isAllSelected = ctx.IsSet("all") + isUtxoSelected = ctx.IsSet("utxo") + label = ctx.String("static-loop-in") + hints []*swapserverrpc.RouteHint + lastHop []byte + ) + + // Validate our label early so that we can fail before getting a quote. + if err := labels.Validate(label); err != nil { + return err + } + + // Private and route hints are mutually exclusive as setting private + // means we retrieve our own route hints from the connected node. + hints, err = validateRouteHints(ctx) + if err != nil { + return err + } + + if ctx.IsSet(lastHopFlag.Name) { + lastHopVertex, err := route.NewVertexFromStr( + ctx.String(lastHopFlag.Name), + ) + if err != nil { + return err + } + + lastHop = lastHopVertex[:] + } + + // Get the amount we need to quote for. + summaryResp, err := client.GetStaticAddressSummary( + ctxb, &looprpc.StaticAddressSummaryRequest{ + StateFilter: looprpc.DepositState_DEPOSITED, + }, + ) + if err != nil { + return err + } + + var quoteAmount int64 + var depositOutpoints []string + switch { + case isAllSelected == isUtxoSelected: + return errors.New("must select either all or some utxos") + + case isAllSelected: + quoteAmount = summaryResp.ValueDeposited + depositOutpoints = depositsToOutpoints( + summaryResp.FilteredDeposits, + ) + + case isUtxoSelected: + depositOutpoints = ctx.StringSlice("utxo") + quoteAmount = sumOutpointValues( + depositOutpoints, summaryResp.FilteredDeposits, + ) + + default: + return fmt.Errorf("unknown quote request") + } + + quote, err := client.GetLoopInQuote( + ctxb, &looprpc.QuoteRequest{ + Amt: quoteAmount, + LoopInRouteHints: hints, + LoopInLastHop: lastHop, + Private: ctx.Bool(privateFlag.Name), + DepositOutpoints: depositOutpoints, + }, + ) + if err != nil { + return err + } + + limits := getInLimits(quote) + + req := &looprpc.StaticAddressLoopInRequest{ + Outpoints: depositOutpoints, + MaxMinerFee: int64(limits.maxMinerFee), + MaxSwapFee: int64(limits.maxSwapFee), + LastHop: lastHop, + Label: label, + Initiator: defaultInitiator, + RouteHints: hints, + Private: ctx.Bool("private"), + } + + resp, err := client.StaticAddressLoopIn(ctxb, req) + if err != nil { + return err + } + + fmt.Printf("Static loop-in response from the server: %v\n", resp) + + return nil +} + +func sumOutpointValues(outpoints []string, deposits []*looprpc.Deposit) int64 { + var total int64 + for _, outpoint := range outpoints { + for _, deposit := range deposits { + if deposit.Outpoint == outpoint { + total += deposit.Value + break + } + } + } + + return total +} + +func depositsToOutpoints(deposits []*looprpc.Deposit) []string { + outpoints := make([]string, 0, len(deposits)) + for _, deposit := range deposits { + outpoints = append(outpoints, deposit.Outpoint) + } + + return outpoints +} diff --git a/instantout/actions.go b/instantout/actions.go index 71a411fdc..2cf51409b 100644 --- a/instantout/actions.go +++ b/instantout/actions.go @@ -425,22 +425,23 @@ func (f *FSM) PushPreimageAction(eventCtx fsm.EventContext) fsm.EventType { return OnErrorPublishHtlc } - txLabel := fmt.Sprintf("sweepless-sweep-%v", - f.InstantOut.swapPreimage.Hash()) + return OnErrorPublishHtlc // Publish the sweepless sweep transaction. - err = f.cfg.Wallet.PublishTransaction(f.ctx, sweepTx, txLabel) - if err != nil { - f.LastActionError = err - return OnErrorPublishHtlc - } + /* err = f.cfg.Wallet.PublishTransaction(f.ctx, sweepTx, txLabel) + if err != nil { + f.LastActionError = err + return OnErrorPublishHtlc + } + txLabel := fmt.Sprintf("sweepless-sweep-%v", + f.InstantOut.swapPreimage.Hash()) - f.InstantOut.FinalizedSweeplessSweepTx = sweepTx - txHash := f.InstantOut.FinalizedSweeplessSweepTx.TxHash() + f.InstantOut.FinalizedSweeplessSweepTx = sweepTx + txHash := f.InstantOut.FinalizedSweeplessSweepTx.TxHash() - f.InstantOut.SweepTxHash = &txHash + f.InstantOut.SweepTxHash = &txHash - return OnSweeplessSweepPublished + return OnSweeplessSweepPublished*/ } // WaitForSweeplessSweepConfirmedAction waits for the sweepless sweep diff --git a/interface.go b/interface.go index 390515969..15bd8e1da 100644 --- a/interface.go +++ b/interface.go @@ -234,6 +234,52 @@ type LoopInRequest struct { RouteHints [][]zpay32.HopHint } +// StaticAddressLoopInRequest contains the required parameters for the swap. +type StaticAddressLoopInRequest struct { + DepositOutpoints []string + + // MaxSwapFee is the maximum we are willing to pay the server for the + // swap. This value is not disclosed in the swap initiation call, but if + // the server asks for a higher fee, we abort the swap. Typically this + // value is taken from the response of the LoopInQuote call. It + // includes the prepay amount. + MaxSwapFee btcutil.Amount + + // MaxMinerFee is the maximum in on-chain fees that we are willing to + // spent. If we publish the on-chain htlc and the fee estimate turns out + // higher than this value, we cancel the swap. + // + // MaxMinerFee is typically taken from the response of the LoopInQuote + // call. + MaxMinerFee btcutil.Amount + + // LastHop optionally specifies the last hop to use for the loop in + // payment. + LastHop *route.Vertex + + // Label contains an optional label for the swap. + Label string + + // Initiator is an optional string that identifies what software + // initiated the swap (loop CLI, autolooper, LiT UI and so on) and is + // appended to the user agent string. + Initiator string + + // Private indicates whether the destination node should be considered + // private. In which case, loop will generate hophints to assist with + // probing and payment. + Private bool + + // RouteHints are optional route hints to reach the destination through + // private channels. + RouteHints [][]zpay32.HopHint +} + +// StaticAddressLoopInResponse contains the parameters for the static address +// loop-in. +type StaticAddressLoopInResponse struct { +} + // LoopInTerms are the server terms on which it executes loop in swaps. type LoopInTerms struct { // MinSwapAmount is the minimum amount that the server requires for a diff --git a/loopd/daemon.go b/loopd/daemon.go index 0a31e7fab..5ee1e6d54 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "errors" "fmt" + "github.com/lightninglabs/loop/staticaddr/loopin" "net" "net/http" "strings" @@ -513,6 +514,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { staticAddressManager *address.Manager depositManager *deposit.Manager withdrawalManager *withdraw.Manager + staticLoopInManager *loopin.Manager ) // Create the reservation and instantout managers. if d.cfg.EnableExperimental { @@ -589,6 +591,23 @@ func (d *Daemon) initialize(withMacaroonService bool) error { Signer: d.lnd.Signer, } withdrawalManager = withdraw.NewManager(withdrawalCfg) + + // Static address loop-in manager setup. + loopinCfg := &loopin.Config{ + StaticAddressServerClient: staticAddressClient, + SwapClient: swapClient, + LndClient: d.lnd.Client, + InvoicesClient: d.lnd.Invoices, + NodePubkey: d.lnd.NodePubkey, + AddressManager: staticAddressManager, + DepositManager: depositManager, + WithdrawalManager: withdrawalManager, + WalletKit: d.lnd.WalletKit, + ChainNotifier: d.lnd.ChainNotifier, + ChainParams: d.lnd.ChainParams, + Signer: d.lnd.Signer, + } + staticLoopInManager = loopin.NewManager(loopinCfg) } // Now finally fully initialize the swap client RPC server instance. @@ -607,6 +626,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { staticAddressManager: staticAddressManager, depositManager: depositManager, withdrawalManager: withdrawalManager, + staticLoopInManager: staticLoopInManager, } // Retrieve all currently existing swaps from the database. @@ -764,6 +784,33 @@ func (d *Daemon) initialize(withMacaroonService bool) error { withdrawalManager.WaitInitComplete() } + // Start the static address loop-in manager. + if staticLoopInManager != nil { + d.wg.Add(1) + go func() { + defer d.wg.Done() + + // Lnd's GetInfo call supplies us with the current block + // height. + info, err := d.lnd.Client.GetInfo(d.mainCtx) + if err != nil { + d.internalErrChan <- err + return + } + + log.Info("Starting static address loop-in manager...") + err = staticLoopInManager.Run( + d.mainCtx, info.BlockHeight, + ) + if err != nil && !errors.Is(context.Canceled, err) { + d.internalErrChan <- err + } + log.Info("Starting static address loop-in manager " + + "stopped") + }() + staticLoopInManager.WaitInitComplete() + } + // Last, start our internal error handler. This will return exactly one // error or nil on the main error channel to inform the caller that // something went wrong or that shutdown is complete. We don't add to diff --git a/loopd/perms/perms.go b/loopd/perms/perms.go index e04762f8c..663fd2e72 100644 --- a/loopd/perms/perms.go +++ b/loopd/perms/perms.go @@ -101,6 +101,13 @@ var RequiredPermissions = map[string][]bakery.Op{ Entity: "loop", Action: "in", }}, + "/looprpc.SwapClient/StaticAddressLoopIn": {{ + Entity: "swap", + Action: "read", + }, { + Entity: "loop", + Action: "in", + }}, "/looprpc.SwapClient/GetLsatTokens": {{ Entity: "auth", Action: "read", diff --git a/loopd/swapclient_server.go b/loopd/swapclient_server.go index ab0cecf4b..fcaefa45b 100644 --- a/loopd/swapclient_server.go +++ b/loopd/swapclient_server.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/lightninglabs/loop/staticaddr/loopin" "reflect" "sort" "strings" @@ -91,6 +92,7 @@ type swapClientServer struct { staticAddressManager *address.Manager depositManager *deposit.Manager withdrawalManager *withdraw.Manager + staticLoopInManager *loopin.Manager swaps map[lntypes.Hash]loop.SwapInfo subscribers map[int]chan<- interface{} statusChan chan loop.SwapInfo @@ -797,15 +799,16 @@ func (s *swapClientServer) GetLoopInQuote(ctx context.Context, // The requested amount should be 0 here if the request contained // deposit outpoints. - amount := btcutil.Amount(req.Amt) - if amount != 0 && len(summary.FilteredDeposits) > 0 { - return nil, fmt.Errorf("amount should be 0 for deposit " + - "quotes") - } + /* + if amount != 0 && len(summary.FilteredDeposits) > 0 { + return nil, fmt.Errorf("amount should be 0 for deposit " + + "quotes") + }*/ // In case we quote for deposits we send the server both the total value // and the number of deposits. This is so the server can probe the total // amount and calculate the per input fee. + amount := btcutil.Amount(req.Amt) if amount == 0 && len(summary.FilteredDeposits) > 0 { for _, deposit := range summary.FilteredDeposits { amount += btcutil.Amount(deposit.Value) @@ -1456,6 +1459,46 @@ func (s *swapClientServer) GetStaticAddressSummary(ctx context.Context, ) } +type LoopInRequest struct { +} + +// StaticAddressLoopIn ... +func (s *swapClientServer) StaticAddressLoopIn(ctx context.Context, + in *clientrpc.StaticAddressLoopInRequest) ( + *clientrpc.StaticAddressLoopInResponse, error) { + + log.Infof("Static loop in request received") + + routeHints, err := unmarshallRouteHints(in.RouteHints) + if err != nil { + return nil, err + } + + req := &loop.StaticAddressLoopInRequest{ + DepositOutpoints: in.Outpoints, + MaxMinerFee: btcutil.Amount(in.MaxMinerFee), + MaxSwapFee: btcutil.Amount(in.MaxSwapFee), + Label: in.Label, + Initiator: in.Initiator, + RouteHints: routeHints, + Private: in.Private, + } + if in.LastHop != nil { + lastHop, err := route.NewVertexFromBytes(in.LastHop) + if err != nil { + return nil, err + } + req.LastHop = &lastHop + } + + err = s.staticLoopInManager.LoopIn(req) + if err != nil { + return nil, err + } + + return &clientrpc.StaticAddressLoopInResponse{}, nil +} + func (s *swapClientServer) depositSummary(ctx context.Context, deposits []*deposit.Deposit, stateFilter clientrpc.DepositState, outpointsFilter []string) (*clientrpc.StaticAddressSummaryResponse, @@ -1467,6 +1510,7 @@ func (s *swapClientServer) depositSummary(ctx context.Context, valueDeposited int64 valueExpired int64 valueWithdrawn int64 + valueLoopedIn int64 ) // Value unconfirmed. @@ -1492,6 +1536,9 @@ func (s *swapClientServer) depositSummary(ctx context.Context, case deposit.Withdrawn: valueWithdrawn += value + + case deposit.LoopedIn: + valueLoopedIn += value } } @@ -1544,6 +1591,7 @@ func (s *swapClientServer) depositSummary(ctx context.Context, ValueDeposited: valueDeposited, ValueExpired: valueExpired, ValueWithdrawn: valueWithdrawn, + ValueLoopedIn: valueLoopedIn, FilteredDeposits: clientDeposits, }, nil } @@ -1587,6 +1635,12 @@ func toClientState(state fsm.StateType) clientrpc.DepositState { case deposit.PublishExpiredDeposit: return clientrpc.DepositState_PUBLISH_EXPIRED + case deposit.LoopingIn: + return clientrpc.DepositState_LOOPING_IN + + case deposit.LoopedIn: + return clientrpc.DepositState_LOOPED_IN + case deposit.WaitForExpirySweep: return clientrpc.DepositState_WAIT_FOR_EXPIRY_SWEEP @@ -1612,6 +1666,12 @@ func toServerState(state clientrpc.DepositState) fsm.StateType { case clientrpc.DepositState_WITHDRAWN: return deposit.Withdrawn + case clientrpc.DepositState_LOOPING_IN: + return deposit.LoopingIn + + case clientrpc.DepositState_LOOPED_IN: + return deposit.LoopedIn + case clientrpc.DepositState_PUBLISH_EXPIRED: return deposit.PublishExpiredDeposit diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index 3e781c5e3..978267413 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -453,17 +453,23 @@ const ( DepositState_WITHDRAWING DepositState = 2 // WITHDRAWN indicates that the deposit has been withdrawn. DepositState_WITHDRAWN DepositState = 3 + // LOOPING_IN indicates that the deposit is currently being used in a static + // address loop-in swap. + DepositState_LOOPING_IN DepositState = 4 + // LOOPED_IN indicates that the deposit was used in a static address loop-in + // swap. + DepositState_LOOPED_IN DepositState = 5 // PUBLISH_EXPIRED indicates that the deposit has expired and the sweep // transaction has been published. - DepositState_PUBLISH_EXPIRED DepositState = 4 + DepositState_PUBLISH_EXPIRED DepositState = 6 // WAIT_FOR_EXPIRY_SWEEP indicates that the deposit has expired and the sweep // transaction has not yet been sufficiently confirmed. - DepositState_WAIT_FOR_EXPIRY_SWEEP DepositState = 5 + DepositState_WAIT_FOR_EXPIRY_SWEEP DepositState = 7 // EXPIRED indicates that the deposit has expired and the sweep transaction // has been sufficiently confirmed. - DepositState_EXPIRED DepositState = 6 + DepositState_EXPIRED DepositState = 8 // FAILED_STATE indicates that the deposit has failed. - DepositState_FAILED_STATE DepositState = 7 + DepositState_FAILED_STATE DepositState = 9 ) // Enum value maps for DepositState. @@ -473,20 +479,24 @@ var ( 1: "DEPOSITED", 2: "WITHDRAWING", 3: "WITHDRAWN", - 4: "PUBLISH_EXPIRED", - 5: "WAIT_FOR_EXPIRY_SWEEP", - 6: "EXPIRED", - 7: "FAILED_STATE", + 4: "LOOPING_IN", + 5: "LOOPED_IN", + 6: "PUBLISH_EXPIRED", + 7: "WAIT_FOR_EXPIRY_SWEEP", + 8: "EXPIRED", + 9: "FAILED_STATE", } DepositState_value = map[string]int32{ "UNKNOWN_STATE": 0, "DEPOSITED": 1, "WITHDRAWING": 2, "WITHDRAWN": 3, - "PUBLISH_EXPIRED": 4, - "WAIT_FOR_EXPIRY_SWEEP": 5, - "EXPIRED": 6, - "FAILED_STATE": 7, + "LOOPING_IN": 4, + "LOOPED_IN": 5, + "PUBLISH_EXPIRED": 6, + "WAIT_FOR_EXPIRY_SWEEP": 7, + "EXPIRED": 8, + "FAILED_STATE": 9, } ) @@ -4483,8 +4493,10 @@ type StaticAddressSummaryResponse struct { ValueExpired int64 `protobuf:"varint,5,opt,name=value_expired,json=valueExpired,proto3" json:"value_expired,omitempty"` // The total value of all deposits that have been withdrawn. ValueWithdrawn int64 `protobuf:"varint,6,opt,name=value_withdrawn,json=valueWithdrawn,proto3" json:"value_withdrawn,omitempty"` + // The total value of all loop-ins that have been finalized. + ValueLoopedIn int64 `protobuf:"varint,7,opt,name=value_looped_in,json=valueLoopedIn,proto3" json:"value_looped_in,omitempty"` // A list of all deposits that match the filtered state. - FilteredDeposits []*Deposit `protobuf:"bytes,7,rep,name=filtered_deposits,json=filteredDeposits,proto3" json:"filtered_deposits,omitempty"` + FilteredDeposits []*Deposit `protobuf:"bytes,8,rep,name=filtered_deposits,json=filteredDeposits,proto3" json:"filtered_deposits,omitempty"` } func (x *StaticAddressSummaryResponse) Reset() { @@ -4561,6 +4573,13 @@ func (x *StaticAddressSummaryResponse) GetValueWithdrawn() int64 { return 0 } +func (x *StaticAddressSummaryResponse) GetValueLoopedIn() int64 { + if x != nil { + return x.ValueLoopedIn + } + return 0 +} + func (x *StaticAddressSummaryResponse) GetFilteredDeposits() []*Deposit { if x != nil { return x.FilteredDeposits @@ -4652,6 +4671,171 @@ func (x *Deposit) GetConfirmationHeight() int64 { return 0 } +type StaticAddressLoopInRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The outpoints of the deposits to loop-in. + Outpoints []string `protobuf:"bytes,1,rep,name=outpoints,proto3" json:"outpoints,omitempty"` + // Maximum we are willing to pay the server for the swap. This value is not + // disclosed in the swap initiation call, but if the server asks for a higher + // fee, we abort the swap. Typically this value is taken from the response of + // the GetQuote call. + MaxSwapFee int64 `protobuf:"varint,2,opt,name=max_swap_fee,json=maxSwapFee,proto3" json:"max_swap_fee,omitempty"` + // Maximum in on-chain fees that we are willing to spend. If we want to publish + // the on-chain htlc and the fee estimate turns out higher than this value, we + // cancel the swap. + // + // max_miner_fee is typically taken from the response of the GetQuote call. + MaxMinerFee int64 `protobuf:"varint,3,opt,name=max_miner_fee,json=maxMinerFee,proto3" json:"max_miner_fee,omitempty"` + // Optionally the client can specify the last hop pubkey when requesting a + // loop-in quote. This is useful to get better off-chain routing fee from the + // server. + LastHop []byte `protobuf:"bytes,4,opt,name=last_hop,json=lastHop,proto3" json:"last_hop,omitempty"` + // An optional label for this swap. This field is limited to 500 characters and + // may not be one of the reserved values in loop/labels Reserved list. + Label string `protobuf:"bytes,5,opt,name=label,proto3" json:"label,omitempty"` + // An optional identification string that will be appended to the user agent + // string sent to the server to give information about the usage of loop. This + // initiator part is meant for user interfaces to add their name to give the + // full picture of the binary used (loopd, LiT) and the method used for + // triggering the swap (loop CLI, autolooper, LiT UI, other 3rd party UI). + Initiator string `protobuf:"bytes,6,opt,name=initiator,proto3" json:"initiator,omitempty"` + // Optional route hints to reach the destination through private channels. + RouteHints []*swapserverrpc.RouteHint `protobuf:"bytes,7,rep,name=route_hints,json=routeHints,proto3" json:"route_hints,omitempty"` + // Private indicates whether the destination node should be considered private. + // In which case, loop will generate hop hints to assist with probing and + // payment. + Private bool `protobuf:"varint,8,opt,name=private,proto3" json:"private,omitempty"` +} + +func (x *StaticAddressLoopInRequest) Reset() { + *x = StaticAddressLoopInRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StaticAddressLoopInRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StaticAddressLoopInRequest) ProtoMessage() {} + +func (x *StaticAddressLoopInRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[54] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StaticAddressLoopInRequest.ProtoReflect.Descriptor instead. +func (*StaticAddressLoopInRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{54} +} + +func (x *StaticAddressLoopInRequest) GetOutpoints() []string { + if x != nil { + return x.Outpoints + } + return nil +} + +func (x *StaticAddressLoopInRequest) GetMaxSwapFee() int64 { + if x != nil { + return x.MaxSwapFee + } + return 0 +} + +func (x *StaticAddressLoopInRequest) GetMaxMinerFee() int64 { + if x != nil { + return x.MaxMinerFee + } + return 0 +} + +func (x *StaticAddressLoopInRequest) GetLastHop() []byte { + if x != nil { + return x.LastHop + } + return nil +} + +func (x *StaticAddressLoopInRequest) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *StaticAddressLoopInRequest) GetInitiator() string { + if x != nil { + return x.Initiator + } + return "" +} + +func (x *StaticAddressLoopInRequest) GetRouteHints() []*swapserverrpc.RouteHint { + if x != nil { + return x.RouteHints + } + return nil +} + +func (x *StaticAddressLoopInRequest) GetPrivate() bool { + if x != nil { + return x.Private + } + return false +} + +type StaticAddressLoopInResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *StaticAddressLoopInResponse) Reset() { + *x = StaticAddressLoopInResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StaticAddressLoopInResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StaticAddressLoopInResponse) ProtoMessage() {} + +func (x *StaticAddressLoopInResponse) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[55] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StaticAddressLoopInResponse.ProtoReflect.Descriptor instead. +func (*StaticAddressLoopInResponse) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{55} +} + var File_client_proto protoreflect.FileDescriptor var file_client_proto_rawDesc = []byte{ @@ -5189,7 +5373,7 @@ var file_client_proto_rawDesc = []byte{ 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, - 0xd6, 0x02, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0xfe, 0x02, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, @@ -5206,218 +5390,249 @@ var file_client_proto_rawDesc = []byte{ 0x28, 0x03, 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x12, 0x3d, 0x0a, 0x11, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x07, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, - 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x07, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x2a, 0x3b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, - 0x0e, 0x54, 0x41, 0x50, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x10, - 0x01, 0x2a, 0x25, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, - 0x08, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, - 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, - 0x5f, 0x52, 0x45, 0x56, 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48, - 0x54, 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, - 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, - 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f, - 0x49, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xeb, 0x02, - 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, - 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, - 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, - 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48, - 0x41, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, - 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, - 0x54, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, - 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, - 0x4e, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, - 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, - 0x50, 0x4f, 0x52, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, - 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, - 0x52, 0x45, 0x43, 0x54, 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x1c, 0x0a, - 0x18, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x41, 0x42, 0x41, 0x4e, 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x07, 0x12, 0x31, 0x0a, 0x2d, 0x46, + 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x65, 0x64, 0x49, + 0x6e, 0x12, 0x3d, 0x0a, 0x11, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x64, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x10, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, + 0x22, 0xa9, 0x01, 0x0a, 0x07, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x75, 0x74, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x75, 0x74, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x9e, 0x02, 0x0a, + 0x1a, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, + 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6f, + 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x6d, 0x61, 0x78, + 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0a, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x46, 0x65, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d, + 0x61, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x46, 0x65, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x33, + 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x48, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x69, + 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0x1d, 0x0a, + 0x1b, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, + 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3b, 0x0a, 0x0b, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x41, + 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x41, 0x50, 0x52, 0x4f, 0x4f, 0x54, + 0x5f, 0x50, 0x55, 0x42, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x2a, 0x25, 0x0a, 0x08, 0x53, 0x77, 0x61, + 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, + 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x01, + 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, + 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, + 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x56, 0x45, 0x41, 0x4c, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, 0x4c, + 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, + 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, + 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xeb, 0x02, 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, + 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, + 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, + 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, + 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, + 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x41, 0x49, + 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, + 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, - 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, - 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x08, 0x12, 0x2b, - 0x0a, 0x27, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, - 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, - 0x41, 0x4d, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x50, 0x54, 0x10, 0x09, 0x2a, 0x2f, 0x0a, 0x11, 0x4c, - 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, - 0x09, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6, 0x03, 0x0a, - 0x0a, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x41, - 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55, 0x54, 0x4f, - 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x46, 0x45, - 0x45, 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41, 0x50, 0x53, - 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x04, 0x12, - 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, - 0x57, 0x41, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, - 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x46, - 0x45, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, - 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, - 0x55, 0x52, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12, 0x18, 0x0a, - 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, - 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, - 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x0a, - 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b, 0x12, 0x23, - 0x0a, 0x1f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, - 0x44, 0x47, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, - 0x54, 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, - 0x4f, 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, - 0x45, 0x4e, 0x54, 0x10, 0x0d, 0x2a, 0x9f, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, - 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x45, 0x50, - 0x4f, 0x53, 0x49, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x57, 0x49, 0x54, 0x48, - 0x44, 0x52, 0x41, 0x57, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x49, 0x54, - 0x48, 0x44, 0x52, 0x41, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x55, 0x42, 0x4c, - 0x49, 0x53, 0x48, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x12, 0x19, 0x0a, - 0x15, 0x57, 0x41, 0x49, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, - 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x50, 0x49, - 0x52, 0x45, 0x44, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x07, 0x32, 0xd4, 0x0e, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, - 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, - 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, + 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, + 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x4f, 0x52, 0x41, 0x52, 0x59, 0x10, 0x05, + 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x41, 0x4d, 0x4f, + 0x55, 0x4e, 0x54, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, 0x42, 0x41, 0x4e, 0x44, 0x4f, 0x4e, 0x45, + 0x44, 0x10, 0x07, 0x12, 0x31, 0x0a, 0x2d, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, + 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, + 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x42, 0x41, 0x4c, + 0x41, 0x4e, 0x43, 0x45, 0x10, 0x08, 0x12, 0x2b, 0x0a, 0x27, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, + 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, + 0x43, 0x54, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, 0x4d, 0x54, 0x5f, 0x53, 0x57, 0x45, 0x50, + 0x54, 0x10, 0x09, 0x2a, 0x2f, 0x0a, 0x11, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, + 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, + 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6, 0x03, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, + 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, + 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, + 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, + 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, + 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, + 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41, 0x50, 0x53, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, + 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x46, + 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, + 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x10, + 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, + 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x45, 0x50, + 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, + 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, + 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, + 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x09, 0x12, + 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, + 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x0a, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x55, 0x54, 0x4f, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, + 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, + 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x53, + 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x41, + 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x49, + 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0d, 0x2a, 0xbe, 0x01, + 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, + 0x0a, 0x0d, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, + 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x0f, 0x0a, 0x0b, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, 0x57, 0x49, 0x4e, 0x47, 0x10, + 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, 0x57, 0x4e, 0x10, 0x03, + 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x4f, 0x4f, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x49, 0x4e, 0x10, 0x04, + 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x4f, 0x4f, 0x50, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x10, 0x05, 0x12, + 0x13, 0x0a, 0x0f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, + 0x45, 0x44, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x57, 0x41, 0x49, 0x54, 0x5f, 0x46, 0x4f, 0x52, + 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x10, 0x07, 0x12, + 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x08, 0x12, 0x10, 0x0a, 0x0c, + 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x09, 0x32, 0xb6, + 0x0f, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, + 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x70, + 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, + 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x37, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, - 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, - 0x70, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61, - 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x48, 0x0a, 0x0b, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, - 0x77, 0x61, 0x70, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, - 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, - 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, - 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, - 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, - 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, - 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, - 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x34, 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x73, 0x61, 0x74, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, - 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, - 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, - 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, - 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x45, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1a, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, - 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, - 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, - 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x12, - 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x4c, - 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, - 0x10, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, 0x68, - 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x12, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, - 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, - 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x09, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x48, 0x0a, 0x0b, 0x41, + 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x41, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, + 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, + 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x54, + 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x34, + 0x30, 0x32, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, 0x74, + 0x4c, 0x73, 0x61, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, + 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, + 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, + 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, + 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, + 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, + 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, + 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, + 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x74, 0x4f, 0x75, 0x74, 0x12, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, + 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4f, 0x75, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4e, 0x65, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x65, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, + 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x44, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x6e, 0x73, + 0x70, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, + 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, + 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x23, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x24, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, + 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5433,7 +5648,7 @@ func file_client_proto_rawDescGZIP() []byte { } var file_client_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_client_proto_msgTypes = make([]protoimpl.MessageInfo, 54) +var file_client_proto_msgTypes = make([]protoimpl.MessageInfo, 56) var file_client_proto_goTypes = []interface{}{ (AddressType)(0), // 0: looprpc.AddressType (SwapType)(0), // 1: looprpc.SwapType @@ -5497,19 +5712,21 @@ var file_client_proto_goTypes = []interface{}{ (*StaticAddressSummaryRequest)(nil), // 59: looprpc.StaticAddressSummaryRequest (*StaticAddressSummaryResponse)(nil), // 60: looprpc.StaticAddressSummaryResponse (*Deposit)(nil), // 61: looprpc.Deposit - (*swapserverrpc.RouteHint)(nil), // 62: looprpc.RouteHint + (*StaticAddressLoopInRequest)(nil), // 62: looprpc.StaticAddressLoopInRequest + (*StaticAddressLoopInResponse)(nil), // 63: looprpc.StaticAddressLoopInResponse + (*swapserverrpc.RouteHint)(nil), // 64: looprpc.RouteHint } var file_client_proto_depIdxs = []int32{ 0, // 0: looprpc.LoopOutRequest.account_addr_type:type_name -> looprpc.AddressType - 62, // 1: looprpc.LoopInRequest.route_hints:type_name -> looprpc.RouteHint + 64, // 1: looprpc.LoopInRequest.route_hints:type_name -> looprpc.RouteHint 1, // 2: looprpc.SwapStatus.type:type_name -> looprpc.SwapType 2, // 3: looprpc.SwapStatus.state:type_name -> looprpc.SwapState 3, // 4: looprpc.SwapStatus.failure_reason:type_name -> looprpc.FailureReason 14, // 5: looprpc.ListSwapsRequest.list_swap_filter:type_name -> looprpc.ListSwapsFilter 7, // 6: looprpc.ListSwapsFilter.swap_type:type_name -> looprpc.ListSwapsFilter.SwapTypeFilter 12, // 7: looprpc.ListSwapsResponse.swaps:type_name -> looprpc.SwapStatus - 62, // 8: looprpc.QuoteRequest.loop_in_route_hints:type_name -> looprpc.RouteHint - 62, // 9: looprpc.ProbeRequest.route_hints:type_name -> looprpc.RouteHint + 64, // 8: looprpc.QuoteRequest.loop_in_route_hints:type_name -> looprpc.RouteHint + 64, // 9: looprpc.ProbeRequest.route_hints:type_name -> looprpc.RouteHint 27, // 10: looprpc.TokensResponse.tokens:type_name -> looprpc.L402Token 28, // 11: looprpc.GetInfoResponse.loop_out_stats:type_name -> looprpc.LoopStats 28, // 12: looprpc.GetInfoResponse.loop_in_stats:type_name -> looprpc.LoopStats @@ -5529,61 +5746,64 @@ var file_client_proto_depIdxs = []int32{ 6, // 26: looprpc.StaticAddressSummaryRequest.state_filter:type_name -> looprpc.DepositState 61, // 27: looprpc.StaticAddressSummaryResponse.filtered_deposits:type_name -> looprpc.Deposit 6, // 28: looprpc.Deposit.state:type_name -> looprpc.DepositState - 8, // 29: looprpc.SwapClient.LoopOut:input_type -> looprpc.LoopOutRequest - 9, // 30: looprpc.SwapClient.LoopIn:input_type -> looprpc.LoopInRequest - 11, // 31: looprpc.SwapClient.Monitor:input_type -> looprpc.MonitorRequest - 13, // 32: looprpc.SwapClient.ListSwaps:input_type -> looprpc.ListSwapsRequest - 16, // 33: looprpc.SwapClient.SwapInfo:input_type -> looprpc.SwapInfoRequest - 39, // 34: looprpc.SwapClient.AbandonSwap:input_type -> looprpc.AbandonSwapRequest - 17, // 35: looprpc.SwapClient.LoopOutTerms:input_type -> looprpc.TermsRequest - 20, // 36: looprpc.SwapClient.LoopOutQuote:input_type -> looprpc.QuoteRequest - 17, // 37: looprpc.SwapClient.GetLoopInTerms:input_type -> looprpc.TermsRequest - 20, // 38: looprpc.SwapClient.GetLoopInQuote:input_type -> looprpc.QuoteRequest - 23, // 39: looprpc.SwapClient.Probe:input_type -> looprpc.ProbeRequest - 25, // 40: looprpc.SwapClient.GetL402Tokens:input_type -> looprpc.TokensRequest - 25, // 41: looprpc.SwapClient.GetLsatTokens:input_type -> looprpc.TokensRequest - 29, // 42: looprpc.SwapClient.GetInfo:input_type -> looprpc.GetInfoRequest - 31, // 43: looprpc.SwapClient.GetLiquidityParams:input_type -> looprpc.GetLiquidityParamsRequest - 34, // 44: looprpc.SwapClient.SetLiquidityParams:input_type -> looprpc.SetLiquidityParamsRequest - 36, // 45: looprpc.SwapClient.SuggestSwaps:input_type -> looprpc.SuggestSwapsRequest - 41, // 46: looprpc.SwapClient.ListReservations:input_type -> looprpc.ListReservationsRequest - 44, // 47: looprpc.SwapClient.InstantOut:input_type -> looprpc.InstantOutRequest - 46, // 48: looprpc.SwapClient.InstantOutQuote:input_type -> looprpc.InstantOutQuoteRequest - 48, // 49: looprpc.SwapClient.ListInstantOuts:input_type -> looprpc.ListInstantOutsRequest - 51, // 50: looprpc.SwapClient.NewStaticAddress:input_type -> looprpc.NewStaticAddressRequest - 53, // 51: looprpc.SwapClient.ListUnspentDeposits:input_type -> looprpc.ListUnspentDepositsRequest - 56, // 52: looprpc.SwapClient.WithdrawDeposits:input_type -> looprpc.WithdrawDepositsRequest - 59, // 53: looprpc.SwapClient.GetStaticAddressSummary:input_type -> looprpc.StaticAddressSummaryRequest - 10, // 54: looprpc.SwapClient.LoopOut:output_type -> looprpc.SwapResponse - 10, // 55: looprpc.SwapClient.LoopIn:output_type -> looprpc.SwapResponse - 12, // 56: looprpc.SwapClient.Monitor:output_type -> looprpc.SwapStatus - 15, // 57: looprpc.SwapClient.ListSwaps:output_type -> looprpc.ListSwapsResponse - 12, // 58: looprpc.SwapClient.SwapInfo:output_type -> looprpc.SwapStatus - 40, // 59: looprpc.SwapClient.AbandonSwap:output_type -> looprpc.AbandonSwapResponse - 19, // 60: looprpc.SwapClient.LoopOutTerms:output_type -> looprpc.OutTermsResponse - 22, // 61: looprpc.SwapClient.LoopOutQuote:output_type -> looprpc.OutQuoteResponse - 18, // 62: looprpc.SwapClient.GetLoopInTerms:output_type -> looprpc.InTermsResponse - 21, // 63: looprpc.SwapClient.GetLoopInQuote:output_type -> looprpc.InQuoteResponse - 24, // 64: looprpc.SwapClient.Probe:output_type -> looprpc.ProbeResponse - 26, // 65: looprpc.SwapClient.GetL402Tokens:output_type -> looprpc.TokensResponse - 26, // 66: looprpc.SwapClient.GetLsatTokens:output_type -> looprpc.TokensResponse - 30, // 67: looprpc.SwapClient.GetInfo:output_type -> looprpc.GetInfoResponse - 32, // 68: looprpc.SwapClient.GetLiquidityParams:output_type -> looprpc.LiquidityParameters - 35, // 69: looprpc.SwapClient.SetLiquidityParams:output_type -> looprpc.SetLiquidityParamsResponse - 38, // 70: looprpc.SwapClient.SuggestSwaps:output_type -> looprpc.SuggestSwapsResponse - 42, // 71: looprpc.SwapClient.ListReservations:output_type -> looprpc.ListReservationsResponse - 45, // 72: looprpc.SwapClient.InstantOut:output_type -> looprpc.InstantOutResponse - 47, // 73: looprpc.SwapClient.InstantOutQuote:output_type -> looprpc.InstantOutQuoteResponse - 49, // 74: looprpc.SwapClient.ListInstantOuts:output_type -> looprpc.ListInstantOutsResponse - 52, // 75: looprpc.SwapClient.NewStaticAddress:output_type -> looprpc.NewStaticAddressResponse - 54, // 76: looprpc.SwapClient.ListUnspentDeposits:output_type -> looprpc.ListUnspentDepositsResponse - 57, // 77: looprpc.SwapClient.WithdrawDeposits:output_type -> looprpc.WithdrawDepositsResponse - 60, // 78: looprpc.SwapClient.GetStaticAddressSummary:output_type -> looprpc.StaticAddressSummaryResponse - 54, // [54:79] is the sub-list for method output_type - 29, // [29:54] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name + 64, // 29: looprpc.StaticAddressLoopInRequest.route_hints:type_name -> looprpc.RouteHint + 8, // 30: looprpc.SwapClient.LoopOut:input_type -> looprpc.LoopOutRequest + 9, // 31: looprpc.SwapClient.LoopIn:input_type -> looprpc.LoopInRequest + 11, // 32: looprpc.SwapClient.Monitor:input_type -> looprpc.MonitorRequest + 13, // 33: looprpc.SwapClient.ListSwaps:input_type -> looprpc.ListSwapsRequest + 16, // 34: looprpc.SwapClient.SwapInfo:input_type -> looprpc.SwapInfoRequest + 39, // 35: looprpc.SwapClient.AbandonSwap:input_type -> looprpc.AbandonSwapRequest + 17, // 36: looprpc.SwapClient.LoopOutTerms:input_type -> looprpc.TermsRequest + 20, // 37: looprpc.SwapClient.LoopOutQuote:input_type -> looprpc.QuoteRequest + 17, // 38: looprpc.SwapClient.GetLoopInTerms:input_type -> looprpc.TermsRequest + 20, // 39: looprpc.SwapClient.GetLoopInQuote:input_type -> looprpc.QuoteRequest + 23, // 40: looprpc.SwapClient.Probe:input_type -> looprpc.ProbeRequest + 25, // 41: looprpc.SwapClient.GetL402Tokens:input_type -> looprpc.TokensRequest + 25, // 42: looprpc.SwapClient.GetLsatTokens:input_type -> looprpc.TokensRequest + 29, // 43: looprpc.SwapClient.GetInfo:input_type -> looprpc.GetInfoRequest + 31, // 44: looprpc.SwapClient.GetLiquidityParams:input_type -> looprpc.GetLiquidityParamsRequest + 34, // 45: looprpc.SwapClient.SetLiquidityParams:input_type -> looprpc.SetLiquidityParamsRequest + 36, // 46: looprpc.SwapClient.SuggestSwaps:input_type -> looprpc.SuggestSwapsRequest + 41, // 47: looprpc.SwapClient.ListReservations:input_type -> looprpc.ListReservationsRequest + 44, // 48: looprpc.SwapClient.InstantOut:input_type -> looprpc.InstantOutRequest + 46, // 49: looprpc.SwapClient.InstantOutQuote:input_type -> looprpc.InstantOutQuoteRequest + 48, // 50: looprpc.SwapClient.ListInstantOuts:input_type -> looprpc.ListInstantOutsRequest + 51, // 51: looprpc.SwapClient.NewStaticAddress:input_type -> looprpc.NewStaticAddressRequest + 53, // 52: looprpc.SwapClient.ListUnspentDeposits:input_type -> looprpc.ListUnspentDepositsRequest + 56, // 53: looprpc.SwapClient.WithdrawDeposits:input_type -> looprpc.WithdrawDepositsRequest + 59, // 54: looprpc.SwapClient.GetStaticAddressSummary:input_type -> looprpc.StaticAddressSummaryRequest + 62, // 55: looprpc.SwapClient.StaticAddressLoopIn:input_type -> looprpc.StaticAddressLoopInRequest + 10, // 56: looprpc.SwapClient.LoopOut:output_type -> looprpc.SwapResponse + 10, // 57: looprpc.SwapClient.LoopIn:output_type -> looprpc.SwapResponse + 12, // 58: looprpc.SwapClient.Monitor:output_type -> looprpc.SwapStatus + 15, // 59: looprpc.SwapClient.ListSwaps:output_type -> looprpc.ListSwapsResponse + 12, // 60: looprpc.SwapClient.SwapInfo:output_type -> looprpc.SwapStatus + 40, // 61: looprpc.SwapClient.AbandonSwap:output_type -> looprpc.AbandonSwapResponse + 19, // 62: looprpc.SwapClient.LoopOutTerms:output_type -> looprpc.OutTermsResponse + 22, // 63: looprpc.SwapClient.LoopOutQuote:output_type -> looprpc.OutQuoteResponse + 18, // 64: looprpc.SwapClient.GetLoopInTerms:output_type -> looprpc.InTermsResponse + 21, // 65: looprpc.SwapClient.GetLoopInQuote:output_type -> looprpc.InQuoteResponse + 24, // 66: looprpc.SwapClient.Probe:output_type -> looprpc.ProbeResponse + 26, // 67: looprpc.SwapClient.GetL402Tokens:output_type -> looprpc.TokensResponse + 26, // 68: looprpc.SwapClient.GetLsatTokens:output_type -> looprpc.TokensResponse + 30, // 69: looprpc.SwapClient.GetInfo:output_type -> looprpc.GetInfoResponse + 32, // 70: looprpc.SwapClient.GetLiquidityParams:output_type -> looprpc.LiquidityParameters + 35, // 71: looprpc.SwapClient.SetLiquidityParams:output_type -> looprpc.SetLiquidityParamsResponse + 38, // 72: looprpc.SwapClient.SuggestSwaps:output_type -> looprpc.SuggestSwapsResponse + 42, // 73: looprpc.SwapClient.ListReservations:output_type -> looprpc.ListReservationsResponse + 45, // 74: looprpc.SwapClient.InstantOut:output_type -> looprpc.InstantOutResponse + 47, // 75: looprpc.SwapClient.InstantOutQuote:output_type -> looprpc.InstantOutQuoteResponse + 49, // 76: looprpc.SwapClient.ListInstantOuts:output_type -> looprpc.ListInstantOutsResponse + 52, // 77: looprpc.SwapClient.NewStaticAddress:output_type -> looprpc.NewStaticAddressResponse + 54, // 78: looprpc.SwapClient.ListUnspentDeposits:output_type -> looprpc.ListUnspentDepositsResponse + 57, // 79: looprpc.SwapClient.WithdrawDeposits:output_type -> looprpc.WithdrawDepositsResponse + 60, // 80: looprpc.SwapClient.GetStaticAddressSummary:output_type -> looprpc.StaticAddressSummaryResponse + 63, // 81: looprpc.SwapClient.StaticAddressLoopIn:output_type -> looprpc.StaticAddressLoopInResponse + 56, // [56:82] is the sub-list for method output_type + 30, // [30:56] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name } func init() { file_client_proto_init() } @@ -6240,6 +6460,30 @@ func file_client_proto_init() { return nil } } + file_client_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StaticAddressLoopInRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StaticAddressLoopInResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -6247,7 +6491,7 @@ func file_client_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_client_proto_rawDesc, NumEnums: 8, - NumMessages: 54, + NumMessages: 56, NumExtensions: 0, NumServices: 1, }, diff --git a/looprpc/client.proto b/looprpc/client.proto index 43d4e3822..477721eb9 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -168,6 +168,9 @@ service SwapClient { */ rpc GetStaticAddressSummary (StaticAddressSummaryRequest) returns (StaticAddressSummaryResponse); + + rpc StaticAddressLoopIn (StaticAddressLoopInRequest) + returns (StaticAddressLoopInResponse); } message LoopOutRequest { @@ -1615,10 +1618,15 @@ message StaticAddressSummaryResponse { */ int64 value_withdrawn = 6; + /* + The total value of all loop-ins that have been finalized. + */ + int64 value_looped_in = 7; + /* A list of all deposits that match the filtered state. */ - repeated Deposit filtered_deposits = 7; + repeated Deposit filtered_deposits = 8; } enum DepositState { @@ -1645,28 +1653,40 @@ enum DepositState { */ WITHDRAWN = 3; + /* + LOOPING_IN indicates that the deposit is currently being used in a static + address loop-in swap. + */ + LOOPING_IN = 4; + + /* + LOOPED_IN indicates that the deposit was used in a static address loop-in + swap. + */ + LOOPED_IN = 5; + /* PUBLISH_EXPIRED indicates that the deposit has expired and the sweep transaction has been published. */ - PUBLISH_EXPIRED = 4; + PUBLISH_EXPIRED = 6; /* WAIT_FOR_EXPIRY_SWEEP indicates that the deposit has expired and the sweep transaction has not yet been sufficiently confirmed. */ - WAIT_FOR_EXPIRY_SWEEP = 5; + WAIT_FOR_EXPIRY_SWEEP = 7; /* EXPIRED indicates that the deposit has expired and the sweep transaction has been sufficiently confirmed. */ - EXPIRED = 6; + EXPIRED = 8; /* FAILED_STATE indicates that the deposit has failed. */ - FAILED_STATE = 7; + FAILED_STATE = 9; } message Deposit { @@ -1695,3 +1715,64 @@ message Deposit { */ int64 confirmation_height = 5; } + +message StaticAddressLoopInRequest { + /* + The outpoints of the deposits to loop-in. + */ + repeated string outpoints = 1; + + /* + Maximum we are willing to pay the server for the swap. This value is not + disclosed in the swap initiation call, but if the server asks for a higher + fee, we abort the swap. Typically this value is taken from the response of + the GetQuote call. + */ + int64 max_swap_fee = 2; + + /* + Maximum in on-chain fees that we are willing to spend. If we want to publish + the on-chain htlc and the fee estimate turns out higher than this value, we + cancel the swap. + + max_miner_fee is typically taken from the response of the GetQuote call. + */ + int64 max_miner_fee = 3; + + /* + Optionally the client can specify the last hop pubkey when requesting a + loop-in quote. This is useful to get better off-chain routing fee from the + server. + */ + bytes last_hop = 4; + + /* + An optional label for this swap. This field is limited to 500 characters and + may not be one of the reserved values in loop/labels Reserved list. + */ + string label = 5; + + /* + An optional identification string that will be appended to the user agent + string sent to the server to give information about the usage of loop. This + initiator part is meant for user interfaces to add their name to give the + full picture of the binary used (loopd, LiT) and the method used for + triggering the swap (loop CLI, autolooper, LiT UI, other 3rd party UI). + */ + string initiator = 6; + + /* + Optional route hints to reach the destination through private channels. + */ + repeated looprpc.RouteHint route_hints = 7; + + /* + Private indicates whether the destination node should be considered private. + In which case, loop will generate hop hints to assist with probing and + payment. + */ + bool private = 8; +} + +message StaticAddressLoopInResponse { +} diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json index 91d7a8aa1..38a7b2637 100644 --- a/looprpc/client.swagger.json +++ b/looprpc/client.swagger.json @@ -698,13 +698,15 @@ "DEPOSITED", "WITHDRAWING", "WITHDRAWN", + "LOOPING_IN", + "LOOPED_IN", "PUBLISH_EXPIRED", "WAIT_FOR_EXPIRY_SWEEP", "EXPIRED", "FAILED_STATE" ], "default": "UNKNOWN_STATE", - "description": " - UNKNOWN_STATE: UNKNOWN_STATE is the default state of a deposit.\n - DEPOSITED: DEPOSITED indicates that the deposit has been sufficiently confirmed on\nchain.\n - WITHDRAWING: WITHDRAWING indicates that the deposit is currently being withdrawn. It\nflips to WITHDRAWN once the withdrawal transaction has been sufficiently\nconfirmed.\n - WITHDRAWN: WITHDRAWN indicates that the deposit has been withdrawn.\n - PUBLISH_EXPIRED: PUBLISH_EXPIRED indicates that the deposit has expired and the sweep\ntransaction has been published.\n - WAIT_FOR_EXPIRY_SWEEP: WAIT_FOR_EXPIRY_SWEEP indicates that the deposit has expired and the sweep\ntransaction has not yet been sufficiently confirmed.\n - EXPIRED: EXPIRED indicates that the deposit has expired and the sweep transaction\nhas been sufficiently confirmed.\n - FAILED_STATE: FAILED_STATE indicates that the deposit has failed." + "description": " - UNKNOWN_STATE: UNKNOWN_STATE is the default state of a deposit.\n - DEPOSITED: DEPOSITED indicates that the deposit has been sufficiently confirmed on\nchain.\n - WITHDRAWING: WITHDRAWING indicates that the deposit is currently being withdrawn. It\nflips to WITHDRAWN once the withdrawal transaction has been sufficiently\nconfirmed.\n - WITHDRAWN: WITHDRAWN indicates that the deposit has been withdrawn.\n - LOOPING_IN: LOOPING_IN indicates that the deposit is currently being used in a static\naddress loop-in swap.\n - LOOPED_IN: LOOPED_IN indicates that the deposit was used in a static address loop-in\nswap.\n - PUBLISH_EXPIRED: PUBLISH_EXPIRED indicates that the deposit has expired and the sweep\ntransaction has been published.\n - WAIT_FOR_EXPIRY_SWEEP: WAIT_FOR_EXPIRY_SWEEP indicates that the deposit has expired and the sweep\ntransaction has not yet been sufficiently confirmed.\n - EXPIRED: EXPIRED indicates that the deposit has expired and the sweep transaction\nhas been sufficiently confirmed.\n - FAILED_STATE: FAILED_STATE indicates that the deposit has failed." }, "looprpcDisqualified": { "type": "object", @@ -1503,6 +1505,9 @@ "looprpcSetLiquidityParamsResponse": { "type": "object" }, + "looprpcStaticAddressLoopInResponse": { + "type": "object" + }, "looprpcStaticAddressSummaryResponse": { "type": "object", "properties": { @@ -1535,6 +1540,11 @@ "format": "int64", "description": "The total value of all deposits that have been withdrawn." }, + "value_looped_in": { + "type": "string", + "format": "int64", + "description": "The total value of all loop-ins that have been finalized." + }, "filtered_deposits": { "type": "array", "items": { diff --git a/looprpc/client_grpc.pb.go b/looprpc/client_grpc.pb.go index f9a47f4b7..af88da49a 100644 --- a/looprpc/client_grpc.pb.go +++ b/looprpc/client_grpc.pb.go @@ -115,6 +115,7 @@ type SwapClientClient interface { // GetStaticAddressSummary returns a summary of static address related // statistics. GetStaticAddressSummary(ctx context.Context, in *StaticAddressSummaryRequest, opts ...grpc.CallOption) (*StaticAddressSummaryResponse, error) + StaticAddressLoopIn(ctx context.Context, in *StaticAddressLoopInRequest, opts ...grpc.CallOption) (*StaticAddressLoopInResponse, error) } type swapClientClient struct { @@ -373,6 +374,15 @@ func (c *swapClientClient) GetStaticAddressSummary(ctx context.Context, in *Stat return out, nil } +func (c *swapClientClient) StaticAddressLoopIn(ctx context.Context, in *StaticAddressLoopInRequest, opts ...grpc.CallOption) (*StaticAddressLoopInResponse, error) { + out := new(StaticAddressLoopInResponse) + err := c.cc.Invoke(ctx, "/looprpc.SwapClient/StaticAddressLoopIn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SwapClientServer is the server API for SwapClient service. // All implementations must embed UnimplementedSwapClientServer // for forward compatibility @@ -474,6 +484,7 @@ type SwapClientServer interface { // GetStaticAddressSummary returns a summary of static address related // statistics. GetStaticAddressSummary(context.Context, *StaticAddressSummaryRequest) (*StaticAddressSummaryResponse, error) + StaticAddressLoopIn(context.Context, *StaticAddressLoopInRequest) (*StaticAddressLoopInResponse, error) mustEmbedUnimplementedSwapClientServer() } @@ -556,6 +567,9 @@ func (UnimplementedSwapClientServer) WithdrawDeposits(context.Context, *Withdraw func (UnimplementedSwapClientServer) GetStaticAddressSummary(context.Context, *StaticAddressSummaryRequest) (*StaticAddressSummaryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStaticAddressSummary not implemented") } +func (UnimplementedSwapClientServer) StaticAddressLoopIn(context.Context, *StaticAddressLoopInRequest) (*StaticAddressLoopInResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StaticAddressLoopIn not implemented") +} func (UnimplementedSwapClientServer) mustEmbedUnimplementedSwapClientServer() {} // UnsafeSwapClientServer may be embedded to opt out of forward compatibility for this service. @@ -1022,6 +1036,24 @@ func _SwapClient_GetStaticAddressSummary_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _SwapClient_StaticAddressLoopIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StaticAddressLoopInRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SwapClientServer).StaticAddressLoopIn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.SwapClient/StaticAddressLoopIn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SwapClientServer).StaticAddressLoopIn(ctx, req.(*StaticAddressLoopInRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SwapClient_ServiceDesc is the grpc.ServiceDesc for SwapClient service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1125,6 +1157,10 @@ var SwapClient_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetStaticAddressSummary", Handler: _SwapClient_GetStaticAddressSummary_Handler, }, + { + MethodName: "StaticAddressLoopIn", + Handler: _SwapClient_StaticAddressLoopIn_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/looprpc/swapclient.pb.json.go b/looprpc/swapclient.pb.json.go index ab13090a2..d825fe53c 100644 --- a/looprpc/swapclient.pb.json.go +++ b/looprpc/swapclient.pb.json.go @@ -662,4 +662,29 @@ func RegisterSwapClientJSONCallbacks(registry map[string]func(ctx context.Contex } callback(string(respBytes), nil) } + + registry["looprpc.SwapClient.StaticAddressLoopIn"] = func(ctx context.Context, + conn *grpc.ClientConn, reqJSON string, callback func(string, error)) { + + req := &StaticAddressLoopInRequest{} + err := marshaler.Unmarshal([]byte(reqJSON), req) + if err != nil { + callback("", err) + return + } + + client := NewSwapClientClient(conn) + resp, err := client.StaticAddressLoopIn(ctx, req) + if err != nil { + callback("", err) + return + } + + respBytes, err := marshaler.Marshal(resp) + if err != nil { + callback("", err) + return + } + callback(string(respBytes), nil) + } } diff --git a/staticaddr/deposit/actions.go b/staticaddr/deposit/actions.go index 199fe6cc7..7be3a8c42 100644 --- a/staticaddr/deposit/actions.go +++ b/staticaddr/deposit/actions.go @@ -148,9 +148,9 @@ func (f *FSM) SweptExpiredDepositAction(_ fsm.EventContext) fsm.EventType { return fsm.NoOp } -// WithdrawnDepositAction is the final action after a withdrawal. It signals to +// FinalizeDepositAction is the final action after a withdrawal. It signals to // the manager that the deposit has been swept and the FSM can be removed. -func (f *FSM) WithdrawnDepositAction(_ fsm.EventContext) fsm.EventType { +func (f *FSM) FinalizeDepositAction(_ fsm.EventContext) fsm.EventType { select { case <-f.ctx.Done(): return fsm.OnError diff --git a/staticaddr/deposit/deposit.go b/staticaddr/deposit/deposit.go index 3e23f9a6f..c0ba757de 100644 --- a/staticaddr/deposit/deposit.go +++ b/staticaddr/deposit/deposit.go @@ -72,7 +72,8 @@ func (d *Deposit) IsInFinalState() bool { d.Lock() defer d.Unlock() - return d.state == Expired || d.state == Withdrawn || d.state == Failed + return d.state == Expired || d.state == Withdrawn || + d.state == Failed || d.state == LoopedIn } func (d *Deposit) IsExpired(currentHeight, expiry uint32) bool { diff --git a/staticaddr/deposit/fsm.go b/staticaddr/deposit/fsm.go index a2607a6e5..df01d3598 100644 --- a/staticaddr/deposit/fsm.go +++ b/staticaddr/deposit/fsm.go @@ -33,6 +33,10 @@ var ( Withdrawn = fsm.StateType("Withdrawn") + LoopingIn = fsm.StateType("LoopingIn") + + LoopedIn = fsm.StateType("LoopedIn") + PublishExpiredDeposit = fsm.StateType("PublishExpiredDeposit") WaitForExpirySweep = fsm.StateType("WaitForExpirySweep") @@ -47,6 +51,8 @@ var ( OnStart = fsm.EventType("OnStart") OnWithdrawInitiated = fsm.EventType("OnWithdrawInitiated") OnWithdrawn = fsm.EventType("OnWithdrawn") + OnLoopinInitiated = fsm.EventType("OnLoopinInitiated") + OnLoopedIn = fsm.EventType("OnLoopedIn") OnExpiry = fsm.EventType("OnExpiry") OnExpiryPublished = fsm.EventType("OnExpiryPublished") OnExpirySwept = fsm.EventType("OnExpirySwept") @@ -169,6 +175,7 @@ func (f *FSM) DepositStatesV0() fsm.States { Transitions: fsm.Transitions{ OnExpiry: PublishExpiredDeposit, OnWithdrawInitiated: Withdrawing, + OnLoopinInitiated: LoopingIn, OnRecover: Deposited, }, Action: fsm.NoOpAction, @@ -232,7 +239,40 @@ func (f *FSM) DepositStatesV0() fsm.States { Transitions: fsm.Transitions{ OnExpiry: Expired, }, - Action: f.WithdrawnDepositAction, + Action: f.FinalizeDepositAction, + }, + LoopingIn: fsm.State{ + Transitions: fsm.Transitions{ + // This event is triggered when the loop in + // payment has been received. We consider the + // swap to be completed and transition to a + // final state. + OnLoopedIn: LoopedIn, + + // If the deposit expires while the loop in is + // still pending, we publish the expiry sweep. + OnExpiry: PublishExpiredDeposit, + + // Upon recovery, we start from the beginning. + OnRecover: Deposited, + + OnLoopinInitiated: LoopingIn, + + fsm.OnError: Deposited, + }, + Action: fsm.NoOpAction, + }, + LoopedIn: fsm.State{ + Transitions: fsm.Transitions{ + OnExpiry: Expired, + }, + Action: f.FinalizeDepositAction, + }, + Withdrawn: fsm.State{ + Transitions: fsm.Transitions{ + OnExpiry: Expired, + }, + Action: f.FinalizeDepositAction, }, Failed: fsm.State{ Transitions: fsm.Transitions{ diff --git a/staticaddr/deposit/manager.go b/staticaddr/deposit/manager.go index 26ce7e802..0d53a412f 100644 --- a/staticaddr/deposit/manager.go +++ b/staticaddr/deposit/manager.go @@ -3,6 +3,7 @@ package deposit import ( "context" "fmt" + "github.com/btcsuite/btcd/btcutil" "sort" "sync" "time" @@ -480,6 +481,22 @@ func (m *Manager) AllOutpointsActiveDeposits(outpoints []wire.OutPoint, return deposits, true } +func (m *Manager) AllStringOutpointsActiveDeposits(outpoints []string, + stateFilter fsm.StateType) ([]*Deposit, bool) { + + outPoints := make([]wire.OutPoint, len(outpoints)) + for i, o := range outpoints { + op, err := wire.NewOutPointFromString(o) + if err != nil { + return nil, false + } + + outPoints[i] = *op + } + + return m.AllOutpointsActiveDeposits(outPoints, stateFilter) +} + // TransitionDeposits allows a caller to transition a set of deposits to a new // state. func (m *Manager) TransitionDeposits(deposits []*Deposit, event fsm.EventType, @@ -512,3 +529,11 @@ func (m *Manager) TransitionDeposits(deposits []*Deposit, event fsm.EventType, func (m *Manager) UpdateDeposit(d *Deposit) error { return m.cfg.Store.UpdateDeposit(m.runCtx, d) } + +func TotalDepositAmount(deposits []*Deposit) btcutil.Amount { + var total btcutil.Amount + for _, d := range deposits { + total += d.Value + } + return total +} diff --git a/staticaddr/log.go b/staticaddr/log.go index fc5eb0108..cfd9e0b9d 100644 --- a/staticaddr/log.go +++ b/staticaddr/log.go @@ -4,6 +4,7 @@ import ( "github.com/btcsuite/btclog" "github.com/lightninglabs/loop/staticaddr/address" "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightninglabs/loop/staticaddr/loopin" "github.com/lightninglabs/loop/staticaddr/withdraw" "github.com/lightningnetwork/lnd/build" ) @@ -27,4 +28,5 @@ func UseLogger(logger btclog.Logger) { address.UseLogger(log) deposit.UseLogger(log) withdraw.UseLogger(log) + loopin.UseLogger(log) } diff --git a/staticaddr/loopin/actions.go b/staticaddr/loopin/actions.go new file mode 100644 index 000000000..3e035c2a1 --- /dev/null +++ b/staticaddr/loopin/actions.go @@ -0,0 +1,752 @@ +package loopin + +import ( + "bytes" + "context" + "crypto/rand" + "crypto/sha256" + "fmt" + "github.com/lightninglabs/loop/labels" + "reflect" + "time" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/staticaddr/address" + "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightninglabs/loop/staticaddr/script" + "github.com/lightninglabs/loop/staticaddr/version" + "github.com/lightninglabs/loop/swap" + "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/invoices" + "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" + "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/lnwallet/chainfee" + "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/routing/route" + "github.com/lightningnetwork/lnd/zpay32" +) + +const ( + defaultConfTarget = 3 +) + +// RequestContext is the context passed to the instant out FSM when +// it is initialized. +type RequestContext struct { + depositOutpoints []string + maxSwapFee btcutil.Amount + maxMinerFee btcutil.Amount + lastHop *route.Vertex + label string + userAgent string + private bool + routeHints [][]zpay32.HopHint +} + +// ValidateRequestAction ... +func (f *FSM) ValidateRequestAction(eventCtx fsm.EventContext) fsm.EventType { + req, ok := eventCtx.(*RequestContext) + if !ok { + return f.HandleError(fmt.Errorf("unexpected context type")) + } + + if len(req.depositOutpoints) == 0 { + return f.HandleError(fmt.Errorf("no deposits specified")) + } + f.loopIn.DepositOutpoints = req.depositOutpoints + + // Retrieve all deposits referenced by the outpoints and ensure that + // they are in state Deposited. + deposits, active := f.cfg.DepositManager.AllStringOutpointsActiveDeposits( //nolint:lll + f.loopIn.DepositOutpoints, deposit.Deposited, + ) + if !active { + return f.HandleError(fmt.Errorf("not all deposits are active")) + } + + f.loopIn.Deposits = deposits + + f.loopIn.Value = deposit.TotalDepositAmount(f.loopIn.Deposits) + + // Check that the label is valid. + if err := labels.Validate(req.label); err != nil { + return f.HandleError(err) + } + + // Private and route hints are mutually exclusive as setting private + // means we retrieve our own route hints from the connected node. + if len(req.routeHints) != 0 && req.private { + return f.HandleError(fmt.Errorf("route hints and private are " + + "mutually exclusive")) + } + + // If private is set, we generate route hints. + var err error + if req.private { + // If last_hop is set, we'll only add channels with peers set to + // the last_hop parameter. + includeNodes := make(map[route.Vertex]struct{}) + if req.lastHop != nil { + includeNodes[*req.lastHop] = struct{}{} + } + + // Because the Private flag is set, we'll generate our own set + // of hop hints. + req.routeHints, err = loop.SelectHopHints( + f.ctx, f.cfg.LndClient, f.loopIn.Value, + loop.DefaultMaxHopHints, includeNodes, + ) + if err != nil { + return f.HandleError(err) + } + } + + // Request current server loop in terms and use these to calculate the + // swap fee that we should subtract from the swap amount in the payment + // request that we send to the server. We pass nil as optional route + // hints as hop hint selection when generating invoices with private + // channels is an LND side black box feature. Advanced users will quote + // directly anyway and there they have the option to add specific route + // hints. + // The quote call will also request a probe from the server to ensure + // feasibility of a loop-in for the totalDepositAmount. + quote, err := f.cfg.SwapClient.Server.GetLoopInQuote( + f.ctx, f.loopIn.Value, f.cfg.NodePubkey, req.lastHop, + req.routeHints, req.userAgent, uint32(len(deposits)), + ) + if err != nil { + return f.HandleError(err) + } + + if quote.SwapFee > req.maxSwapFee { + log.Warnf("Swap fee %v exceeding maximum of %v", + quote.SwapFee, req.maxSwapFee) + + return f.HandleError(loop.ErrSwapFeeTooHigh) + } + + // Calculate the swap invoice amount. The pre-pay is added which + // effectively forces the server to pay us back our prepayment on a + // successful swap. + swapInvoiceAmt := f.loopIn.Value - quote.SwapFee + + // Generate random preimage. + var swapPreimage lntypes.Preimage + if _, err := rand.Read(swapPreimage[:]); err != nil { + log.Error("Cannot generate preimage") + } + f.loopIn.SwapPreimage = swapPreimage + f.loopIn.SwapHash = sha256.Sum256(swapPreimage[:]) + + // Derive a client key for the HTLC. + keyDesc, err := f.cfg.WalletKit.DeriveNextKey( + f.ctx, swap.StaticAddressKeyFamily, + ) + if err != nil { + return f.HandleError(err) + } + f.loopIn.ClientPubkey = keyDesc.PubKey + f.loopIn.HtlcKeyLocator = keyDesc.KeyLocator + + var clientKey [33]byte + copy(clientKey[:], keyDesc.PubKey.SerializeCompressed()) + fmt.Printf("client htlc key: %x\n", clientKey) + fmt.Printf("swap hash %x\n", f.loopIn.SwapHash[:]) + fmt.Printf("preimage %x\n", f.loopIn.SwapPreimage[:]) + + // Create the swap invoice in lnd. + _, swapInvoice, err := f.cfg.LndClient.AddInvoice( + f.ctx, &invoicesrpc.AddInvoiceData{ + Preimage: &swapPreimage, + Value: lnwire.NewMSatFromSatoshis(swapInvoiceAmt), + Memo: "static address loop-in", + Expiry: 3600 * 24 * 365, + RouteHints: req.routeHints, + }, + ) + if err != nil { + return f.HandleError(err) + } + f.loopIn.SwapInvoice = swapInvoice + + f.loopIn.StaticAddressProtocolVersion = version.AddressProtocolVersion( + version.CurrentRPCProtocolVersion(), + ) + + loopInReq := &swapserverrpc.ServerStaticAddressLoopInRequest{ + SwapHash: f.loopIn.SwapHash[:], + DepositOutpoints: f.loopIn.DepositOutpoints, + HtlcClientKey: f.loopIn.ClientPubkey.SerializeCompressed(), + SwapInvoice: f.loopIn.SwapInvoice, + ProtocolVersion: version.CurrentRPCProtocolVersion(), + UserAgent: req.userAgent, + } + if req.lastHop != nil { + loopInReq.LastHop = req.lastHop[:] + f.loopIn.LastHop = req.lastHop[:] + } + + loopInResp, err := f.cfg.StaticAddressServerClient.ServerStaticAddressLoopIn( //nolint:lll + f.ctx, loopInReq, + ) + if err != nil { + return f.HandleError(err) + } + + var id ID + err = id.FromByteSlice(loopInResp.LoopInId) + if err != nil { + return f.HandleError(err) + } + f.loopIn.ID = id + + serverPubkey, err := btcec.ParsePubKey(loopInResp.HtlcServerKey) + if err != nil { + return f.HandleError(err) + } + f.loopIn.ServerPubkey = serverPubkey + fmt.Printf("server htlc key %x\n", f.loopIn.ServerPubkey.SerializeCompressed()) + + f.loopIn.HtlcExpiry = loopInResp.HtlcExpiry + + f.htlcServerNonces, err = toNonces(loopInResp.HtlcServerNonces) + + f.loopIn.HtlcFeeRate = chainfee.SatPerKWeight(loopInResp.HtlcFeeRate) + + // Lock the deposits and transition them to the LoopingIn state. + err = f.cfg.DepositManager.TransitionDeposits( + deposits, deposit.OnLoopinInitiated, deposit.LoopingIn, + ) + if err != nil { + return f.HandleError(err) + } + + return OnValidRequest +} + +// SignHtlcTxAction ... +func (f *FSM) SignHtlcTxAction(_ fsm.EventContext) fsm.EventType { + // Create htlc and get pkScript to sign the deposit <-> htlc tx, then + // send sig to server. + htlc, err := swap.NewHtlcV2( + f.loopIn.HtlcExpiry, pubkeyTo33ByteSlice(f.loopIn.ClientPubkey), + pubkeyTo33ByteSlice(f.loopIn.ServerPubkey), f.loopIn.SwapHash, + f.cfg.ChainParams, + ) + if err != nil { + return f.HandleError(err) + } + + fmt.Printf("LoopIn htlc pkscript: %x\n", htlc.PkScript) + + // /////////////////////// HTLC MUSIG_2 STUFF + f.loopIn.AddressParams, err = f.cfg.AddressManager.GetStaticAddressParameters( + f.ctx, + ) + if err != nil { + return f.HandleError(err) + } + + f.loopIn.Address, err = f.cfg.AddressManager.GetStaticAddress(f.ctx) + if err != nil { + return f.HandleError(err) + } + + // Create a musig2 session for each deposit. + htlcSessions, clientHtlcNonces, err := createMusig2Sessions( + f.ctx, f.loopIn.Deposits, f.loopIn.AddressParams, + f.loopIn.Address, f.cfg.Signer, + ) + if err != nil { + return f.HandleError(err) + } + f.htlcMusig2Sessions = htlcSessions + f.htlcClientNonces, err = toNonces(clientHtlcNonces) + if err != nil { + return f.HandleError(err) + } + + prevOuts := toPrevOuts( + f.loopIn.Deposits, f.loopIn.AddressParams.PkScript, + ) + totalValue := totalValue(prevOuts) + + outpoints := toOutpoints(f.loopIn.Deposits) + htlcTx, err := createHtlcTx( + outpoints, totalValue, htlc.Address, f.loopIn.HtlcFeeRate, + ) + if err != nil { + return f.HandleError(err) + } + fmt.Printf("client nonces: %x\n", clientHtlcNonces) + fmt.Printf("server nonces: %x\n", f.htlcServerNonces) + + var buffer bytes.Buffer + htlcTx.Serialize(&buffer) + + fmt.Printf("htlc tx: %x\n", buffer) + + // Next we'll get our htlc tx signatures. + prevOutFetcher := txscript.NewMultiPrevOutFetcher(prevOuts) + htlcSigs, err := signMusig2Tx( + f.ctx, prevOutFetcher, outpoints, f.cfg.Signer, htlcTx, + htlcSessions, f.htlcServerNonces, + ) + if err != nil { + return f.HandleError(err) + } + f.htlcClientSigs = htlcSigs + fmt.Printf("client htlc sigs: %x\n", htlcSigs) + + // Push Htlc sigs to server + pushHtlcReq := &swapserverrpc.PushStaticAddressHtlcSigsRequest{ + LoopInId: f.loopIn.ID[:], + HtlcClientNonces: clientHtlcNonces, + HtlcClientSigs: htlcSigs, + } + sigPushResp, err := f.cfg.StaticAddressServerClient.PushStaticAddressHtlcSigs( //nolint:lll + f.ctx, pushHtlcReq, + ) + if err != nil { + return f.HandleError(err) + } + + f.sweeplessServerNonces, err = toNonces( + sigPushResp.SweeplessServerNonces, + ) + sweeplessAddress, err := btcutil.DecodeAddress( + sigPushResp.SweeplessSweepAddr, f.cfg.ChainParams, + ) + if err != nil { + return f.HandleError(err) + } + f.loopIn.SweeplessSweepAddress = sweeplessAddress + f.loopIn.SweeplessFeeRate = chainfee.SatPerKWeight( + sigPushResp.SweeplessFeeRate, + ) + + return OnHtlcTxSigned +} + +// MonitorInvoiceAction ... +func (f *FSM) MonitorInvoiceAction(_ fsm.EventContext) fsm.EventType { + // Monitor the swap invoice. + updateChan, errChan, err := f.cfg.InvoicesClient.SubscribeSingleInvoice( + f.ctx, f.loopIn.SwapHash, + ) + if err != nil { + return f.HandleError(err) + } + + for { + select { + case err := <-errChan: + return f.HandleError(err) + + case update := <-updateChan: + f.Debugf("received off-chain payment: %v update: %v", + f.loopIn.SwapHash, update.State) + + switch update.State { + case invoices.ContractOpen: + case invoices.ContractAccepted: + case invoices.ContractSettled: + // Unlock the deposits and transition them to + // the LoopedIn state. + err = f.cfg.DepositManager.TransitionDeposits( + f.loopIn.Deposits, + deposit.OnLoopedIn, + deposit.LoopedIn, + ) + if err != nil { + return f.HandleError(err) + } + return OnPaymentReceived + + case invoices.ContractCanceled: + return f.HandleError(fmt.Errorf("invoice " + + "canceled")) + + default: + return f.HandleError(fmt.Errorf("unexpected "+ + "invoice state: %v", update.State)) + } + + case <-time.After(5 * time.Minute): + return f.HandleError(fmt.Errorf("timeout waiting for " + + "invoice to be accepted")) + + case <-f.ctx.Done(): + return f.HandleError(f.ctx.Err()) + } + } + + return f.HandleError(fmt.Errorf("unexpected payment state")) +} + +func (f *FSM) SignSweeplessSweepAction(_ fsm.EventContext) fsm.EventType { + // Create a musig2 session for each deposit. + musig2Sessions, clientNonces, err := createMusig2Sessions( + f.ctx, f.loopIn.Deposits, f.loopIn.AddressParams, + f.loopIn.Address, f.cfg.Signer, + ) + if err != nil { + return f.HandleError(err) + } + f.sweeplessMusig2Sessions = musig2Sessions + f.sweeplessClientNonces, err = toNonces(clientNonces) + if err != nil { + return f.HandleError(err) + } + + prevOuts := toPrevOuts( + f.loopIn.Deposits, f.loopIn.AddressParams.PkScript, + ) + totalValue := totalValue(prevOuts) + + outpoints := toOutpoints(f.loopIn.Deposits) + sweeplessTx, err := createSweeplessSweepTx( + outpoints, totalValue, f.loopIn.SweeplessSweepAddress, + f.loopIn.SweeplessFeeRate, + ) + if err != nil { + return f.HandleError(err) + } + fmt.Printf("sweeplessTx: %v\n", sweeplessTx.TxHash()) + fmt.Printf("sweepless client nonces: %x\n", f.sweeplessClientNonces) + fmt.Printf("sweepless server nonces: %x\n", f.sweeplessServerNonces) + + // Next we'll get our htlc tx signatures. + prevOutFetcher := txscript.NewMultiPrevOutFetcher(prevOuts) + sweeplessSigs, err := signMusig2Tx( + f.ctx, prevOutFetcher, outpoints, f.cfg.Signer, sweeplessTx, + f.sweeplessMusig2Sessions, f.sweeplessServerNonces, + ) + if err != nil { + return f.HandleError(err) + } + f.sweeplessClientSigs = sweeplessSigs + fmt.Printf("client htlc sigs: %x\n", sweeplessSigs) + + // Push Htlc sigs to server + pushSweeplessSigsReq := &swapserverrpc.PushStaticAddressSweeplessSigsRequest{ + LoopInId: f.loopIn.ID[:], + SweeplessClientNonces: fromNonces(f.sweeplessClientNonces), + SweeplessClientSigs: f.sweeplessClientSigs, + } + _, err = f.cfg.StaticAddressServerClient.PushStaticAddressSweeplessSigs( //nolint:lll + f.ctx, pushSweeplessSigsReq, + ) + if err != nil { + return f.HandleError(err) + } + + return OnSweeplessSweepSigned +} + +// toNonces converts a byte slice to a 66 byte slice. +func toNonces(nonces [][]byte) ([][musig2.PubNonceSize]byte, error) { + res := make([][musig2.PubNonceSize]byte, 0, len(nonces)) + for _, n := range nonces { + n := n + nonce, err := byteSliceTo66ByteSlice(n) + if err != nil { + return nil, err + } + + res = append(res, nonce) + } + + return res, nil +} + +// byteSliceTo66ByteSlice converts a byte slice to a 66 byte slice. +func byteSliceTo66ByteSlice(b []byte) ([musig2.PubNonceSize]byte, error) { + if len(b) != musig2.PubNonceSize { + return [musig2.PubNonceSize]byte{}, + fmt.Errorf("invalid byte slice length") + } + + var res [musig2.PubNonceSize]byte + copy(res[:], b) + + return res, nil +} + +// createMusig2Sessions creates a musig2 session for a number of deposits. +func createMusig2Sessions(ctx context.Context, deposits []*deposit.Deposit, + addressParams *address.Parameters, address *script.StaticAddress, + signer lndclient.SignerClient) ([]*input.MuSig2SessionInfo, [][]byte, + error) { + + musig2Sessions := make([]*input.MuSig2SessionInfo, len(deposits)) + clientNonces := make([][]byte, len(deposits)) + + // Create the sessions and nonces from the deposits. + for i := 0; i < len(deposits); i++ { + session, err := createMusig2Session( + ctx, addressParams, address, signer, + ) + if err != nil { + return nil, nil, err + } + + musig2Sessions[i] = session + clientNonces[i] = session.PublicNonce[:] + } + + return musig2Sessions, clientNonces, nil +} + +// Musig2CreateSession creates a musig2 session for the deposit. +func createMusig2Session(ctx context.Context, addressParams *address.Parameters, + address *script.StaticAddress, + signer lndclient.SignerClient) (*input.MuSig2SessionInfo, error) { + + signers := [][]byte{ + addressParams.ClientPubkey.SerializeCompressed(), + addressParams.ServerPubkey.SerializeCompressed(), + } + + expiryLeaf := address.TimeoutLeaf + + rootHash := expiryLeaf.TapHash() + + return signer.MuSig2CreateSession( + ctx, input.MuSig2Version100RC2, &addressParams.KeyLocator, + signers, lndclient.MuSig2TaprootTweakOpt(rootHash[:], false), + ) +} + +func toPrevOuts(deposits []*deposit.Deposit, + pkScript []byte) map[wire.OutPoint]*wire.TxOut { + + prevOuts := make(map[wire.OutPoint]*wire.TxOut, len(deposits)) + for _, d := range deposits { + outpoint := wire.OutPoint{ + Hash: d.Hash, + Index: d.Index, + } + txOut := &wire.TxOut{ + Value: int64(d.Value), + PkScript: pkScript, + } + prevOuts[outpoint] = txOut + } + + return prevOuts +} + +func totalValue(prevOuts map[wire.OutPoint]*wire.TxOut) btcutil.Amount { + var value btcutil.Amount + for _, prevOut := range prevOuts { + value += btcutil.Amount(prevOut.Value) + } + return value +} + +func createHtlcTx(outpoints []wire.OutPoint, withdrawlAmount btcutil.Amount, + sweepAddress btcutil.Address, + feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error) { + + // First Create the tx. + msgTx := wire.NewMsgTx(2) + + // Add the deposit inputs to the transaction in the order the server + // signed them. + for _, outpoint := range outpoints { + msgTx.AddTxIn(&wire.TxIn{ + PreviousOutPoint: outpoint, + }) + } + + // Calculate htlc tx fee for server provided fee rate. + weight := htlcWeight(len(outpoints)) + fee := feeRate.FeeForWeight(weight) + + pkscript, err := txscript.PayToAddrScript(sweepAddress) + if err != nil { + return nil, err + } + + // Create the sweep output + sweepOutput := &wire.TxOut{ + Value: int64(withdrawlAmount) - int64(fee), + PkScript: pkscript, + } + + msgTx.AddTxOut(sweepOutput) + + return msgTx, nil +} + +func createSweeplessSweepTx(outpoints []wire.OutPoint, + withdrawlAmount btcutil.Amount, clientSweepAddress btcutil.Address, + feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error) { + + // First Create the tx. + msgTx := wire.NewMsgTx(2) + + // Add the deposit inputs to the transaction in the order the server + // signed them. + for _, outpoint := range outpoints { + msgTx.AddTxIn(&wire.TxIn{ + PreviousOutPoint: outpoint, + }) + } + + // Calculate tx fee for server provided fee rate. + weight, err := sweeplessSweepWeight(len(outpoints), clientSweepAddress) + if err != nil { + return nil, err + } + fee := feeRate.FeeForWeight(weight) + + pkscript, err := txscript.PayToAddrScript(clientSweepAddress) + if err != nil { + return nil, err + } + + // Create the sweep output + sweepOutput := &wire.TxOut{ + Value: int64(withdrawlAmount) - int64(fee), + PkScript: pkscript, + } + + msgTx.AddTxOut(sweepOutput) + + return msgTx, nil +} + +// signMusig2Tx adds the server nonces to the musig2 sessions and signs the +// transaction. +func signMusig2Tx(ctx context.Context, + prevOutFetcher *txscript.MultiPrevOutFetcher, outpoints []wire.OutPoint, + signer lndclient.SignerClient, tx *wire.MsgTx, + musig2sessions []*input.MuSig2SessionInfo, + counterPartyNonces [][musig2.PubNonceSize]byte) ([][]byte, error) { + + sigHashes := txscript.NewTxSigHashes(tx, prevOutFetcher) + sigs := make([][]byte, len(outpoints)) + + for idx, outpoint := range outpoints { + if !reflect.DeepEqual(tx.TxIn[idx].PreviousOutPoint, + outpoint) { + + return nil, fmt.Errorf("tx input does not match " + + "deposits") + } + + taprootSigHash, err := txscript.CalcTaprootSignatureHash( + sigHashes, txscript.SigHashDefault, tx, idx, + prevOutFetcher, + ) + if err != nil { + return nil, err + } + + var digest [32]byte + copy(digest[:], taprootSigHash) + + // Register the server's nonce before attempting to create our + // partial signature. + haveAllNonces, err := signer.MuSig2RegisterNonces( + ctx, musig2sessions[idx].SessionID, + [][musig2.PubNonceSize]byte{counterPartyNonces[idx]}, + ) + if err != nil { + return nil, err + } + + // Sanity check that we have all the nonces. + if !haveAllNonces { + return nil, fmt.Errorf("invalid MuSig2 session: " + + "nonces missing") + } + + // Since our MuSig2 session has all nonces, we can now create + // the local partial signature by signing the sig hash. + sig, err := signer.MuSig2Sign( + ctx, musig2sessions[idx].SessionID, digest, false, + ) + if err != nil { + return nil, err + } + + sigs[idx] = sig + } + + return sigs, nil +} + +// htlcWeight returns the weight for the htlc transaction. +func htlcWeight(numInputs int) lntypes.WeightUnit { + var weightEstimator input.TxWeightEstimator + for i := 0; i < numInputs; i++ { + weightEstimator.AddTaprootKeySpendInput( + txscript.SigHashDefault, + ) + } + + weightEstimator.AddP2WSHOutput() + + return weightEstimator.Weight() +} + +// sweeplessSweepWeight ... +func sweeplessSweepWeight(numInputs int, + sweepAddress btcutil.Address) (lntypes.WeightUnit, error) { + + var weightEstimator input.TxWeightEstimator + for i := 0; i < numInputs; i++ { + weightEstimator.AddTaprootKeySpendInput( + txscript.SigHashDefault, + ) + } + + // Get the weight of the sweep output. + switch sweepAddress.(type) { + case *btcutil.AddressWitnessPubKeyHash: + weightEstimator.AddP2WKHOutput() + + case *btcutil.AddressTaproot: + weightEstimator.AddP2TROutput() + + default: + return 0, fmt.Errorf("invalid sweep address type %T", + sweepAddress) + } + + return weightEstimator.Weight(), nil +} + +func toOutpoints(deposits []*deposit.Deposit) []wire.OutPoint { + outpoints := make([]wire.OutPoint, len(deposits)) + for i, d := range deposits { + outpoints[i] = wire.OutPoint{ + Hash: d.Hash, + Index: d.Index, + } + } + + return outpoints +} + +func fromNonces(nonces [][musig2.PubNonceSize]byte) [][]byte { + var result [][]byte + for _, nonce := range nonces { + temp := make([]byte, musig2.PubNonceSize) + copy(temp, nonce[:]) + result = append(result, temp) + } + + return result +} diff --git a/staticaddr/loopin/fsm.go b/staticaddr/loopin/fsm.go new file mode 100644 index 000000000..59398c6f5 --- /dev/null +++ b/staticaddr/loopin/fsm.go @@ -0,0 +1,250 @@ +package loopin + +import ( + "context" + "fmt" + + "github.com/btcsuite/btcd/btcec/v2/schnorr/musig2" + "github.com/btcsuite/btcd/chaincfg" + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/swapserverrpc" + "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/routing/route" +) + +// Config contains the services required for the instant out FSM. +type Config struct { + // StaticAddressServerClient is the client that calls the swap server + // rpcs to negotiate static address withdrawals. + StaticAddressServerClient swapserverrpc.StaticAddressServerClient + + // AddressManager gives the withdrawal manager access to static address + // parameters. + AddressManager AddressManager + + // DepositManager gives the withdrawal manager access to the deposits + // enabling it to create and manage withdrawals. + DepositManager DepositManager + + WithdrawalManager WithdrawalManager + + LndClient lndclient.LightningClient + + InvoicesClient lndclient.InvoicesClient + + SwapClient *loop.Client + + NodePubkey route.Vertex + + // WalletKit is the wallet client that is used to derive new keys from + // lnd's wallet. + WalletKit lndclient.WalletKitClient + + // ChainParams is the chain configuration(mainnet, testnet...) this + // manager uses. + ChainParams *chaincfg.Params + + // ChainNotifier is the chain notifier that is used to listen for new + // blocks. + ChainNotifier lndclient.ChainNotifierClient + + // Signer is the signer client that is used to sign transactions. + Signer lndclient.SignerClient + + // Store is the database store that is used to store static address + // related records. + Store SqlStore +} + +// FSM embeds an FSM and extends it with a static loop-in and a config. +// It is used to run a reservation state machine. +type FSM struct { + *fsm.StateMachine + + cfg *Config + + loopIn *StaticAddressLoopIn + + ctx context.Context + + // htlcMusig2Sessions contains all the reservations input musig2 + // sessions that will be used for the htlc transaction. + htlcMusig2Sessions []*input.MuSig2SessionInfo + + // htlcClientNonces contains all the nonces that the client sent for + // the htlc musig2 sessions. + htlcClientNonces [][musig2.PubNonceSize]byte + + // htlcServerNonces contains all the nonces that the server generated + // for the htlc musig2 sessions. + htlcServerNonces [][musig2.PubNonceSize]byte + + // htlcClientSigs contains all the signatures that the client generated + // for the htlc musig2 sessions. + htlcClientSigs [][]byte + + // sweeplessMusig2Sessions ... + sweeplessMusig2Sessions []*input.MuSig2SessionInfo + + // sweeplessClientNonces ... + sweeplessClientNonces [][musig2.PubNonceSize]byte + + // sweeplessServerNonces ... + sweeplessServerNonces [][musig2.PubNonceSize]byte + + // sweeplessClientSigs ... + sweeplessClientSigs [][]byte +} + +// NewFSM creates... +func NewFSM(ctx context.Context, cfg *Config) *FSM { + loopInFsm := &FSM{ + ctx: ctx, + cfg: cfg, + loopIn: &StaticAddressLoopIn{}, + } + + loopInFsm.StateMachine = fsm.NewStateMachine(loopInFsm.GetStates(), 20) + loopInFsm.ActionEntryFunc = loopInFsm.updateLoopIn + + return loopInFsm +} + +// States. The full FSM diagram can be seen in the reservation/fsm.md file. +var ( + ValidateRequest = fsm.StateType("ValidateRequest") + SignHtlcTx = fsm.StateType("SignHtlcTx") + MonitorInvoice = fsm.StateType("MonitorInvoice") + SignSweeplessSweep = fsm.StateType("SignSweeplessSweep") + Succeeded = fsm.StateType("Succeeded") + Failed = fsm.StateType("Failed") +) + +// Events +var ( + OnNewRequest = fsm.EventType("OnNewRequest") + OnValidRequest = fsm.EventType("OnValidRequest") + OnHtlcTxSigned = fsm.EventType("OnHtlcTxSigned") + OnPaymentReceived = fsm.EventType("OnPaymentReceived") + OnSweeplessSweepSigned = fsm.EventType("OnSweeplessSweepSigned") + OnRecover = fsm.EventType("OnRecover") +) + +// GetStates returns the state and transition map for the reservation state +// machine. The state map can be viewed in the fsm.md file. +func (f *FSM) GetStates() fsm.States { + return fsm.States{ + fsm.EmptyState: fsm.State{ + Transitions: fsm.Transitions{ + OnNewRequest: ValidateRequest, + }, + Action: fsm.NoOpAction, + }, + ValidateRequest: fsm.State{ + Transitions: fsm.Transitions{ + OnValidRequest: SignHtlcTx, + OnRecover: Failed, + fsm.OnError: Failed, + }, + Action: f.ValidateRequestAction, + }, + SignHtlcTx: fsm.State{ + Transitions: fsm.Transitions{ + OnHtlcTxSigned: MonitorInvoice, + OnRecover: Failed, + fsm.OnError: Failed, + }, + Action: f.SignHtlcTxAction, + }, + MonitorInvoice: fsm.State{ + Transitions: fsm.Transitions{ + OnPaymentReceived: SignSweeplessSweep, + OnRecover: Failed, + fsm.OnError: Failed, + }, + // TODO: WARNING: If the server publishes the HTLC + // without paying the invoice we need to sweep the + // timeout path. + Action: f.MonitorInvoiceAction, + }, + SignSweeplessSweep: fsm.State{ + Transitions: fsm.Transitions{ + OnSweeplessSweepSigned: Succeeded, + OnRecover: Failed, + fsm.OnError: Failed, + }, + Action: f.SignSweeplessSweepAction, + }, + Succeeded: fsm.State{ + Action: fsm.NoOpAction, + }, + Failed: fsm.State{ + Action: fsm.NoOpAction, + }, + } +} + +// updateReservation is called after every action and updates the reservation +// in the db. +func (f *FSM) updateLoopIn(notification fsm.Notification) { + f.Infof("Current: %v", notification.NextState) + + // Skip the update if the reservation is not yet initialized. + if f.loopIn == nil { + return + } + + f.loopIn.SetState(notification.NextState) + + // If we're in the early stages we don't have created the loop-in in the + // store yet and won't need to update it. + if f.loopIn.GetState() == fsm.EmptyState { + return + } + + /* err := l.cfg.Store.UpdateStaticAddressLoopIn(l.ctx, l.loopIn) + if err != nil { + log.Errorf("Error updating reservation: %v", err) + return + } + + */ +} + +// Infof logs an info message with the reservation id. +func (f *FSM) Infof(format string, args ...interface{}) { + if f.loopIn == nil { + log.Infof(format, args...) + return + } + log.Infof( + "StaticAddr loop-in %x: %s", f.loopIn.ID, + fmt.Sprintf(format, args...), + ) +} + +// Debugf logs a debug message with the reservation id. +func (f *FSM) Debugf(format string, args ...interface{}) { + if f.loopIn == nil { + log.Infof(format, args...) + return + } + log.Debugf( + "StaticAddr loop-in %x: %s", f.loopIn.ID, + fmt.Sprintf(format, args...), + ) +} + +// Errorf logs an error message with the reservation id. +func (f *FSM) Errorf(format string, args ...interface{}) { + if f.loopIn == nil { + log.Errorf(format, args...) + return + } + log.Errorf( + "StaticAddr loop-in %x: %s", f.loopIn.ID, + fmt.Sprintf(format, args...), + ) +} diff --git a/staticaddr/loopin/interface.go b/staticaddr/loopin/interface.go new file mode 100644 index 000000000..27124e938 --- /dev/null +++ b/staticaddr/loopin/interface.go @@ -0,0 +1,104 @@ +package loopin + +import ( + "context" + "github.com/btcsuite/btcd/btcutil" + "github.com/lightningnetwork/lnd/routing/route" + "github.com/lightningnetwork/lnd/zpay32" + + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/loop/fsm" + "github.com/lightninglabs/loop/staticaddr/address" + "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightninglabs/loop/staticaddr/script" + "github.com/lightningnetwork/lnd/lnwallet" +) + +const ( + IdLength = 32 +) + +// Request contains the required parameters for the swap. +type Request struct { + // Amount specifies the requested swap amount in sat. This does not + // include the swap and miner fee. + Amount btcutil.Amount + + // MaxSwapFee is the maximum we are willing to pay the server for the + // swap. This value is not disclosed in the swap initiation call, but if + // the server asks for a higher fee, we abort the swap. Typically this + // value is taken from the response of the LoopInQuote call. It + // includes the prepay amount. + MaxSwapFee btcutil.Amount + + // MaxMinerFee is the maximum in on-chain fees that we are willing to + // spent. If we publish the on-chain htlc and the fee estimate turns out + // higher than this value, we cancel the swap. + // + // MaxMinerFee is typically taken from the response of the LoopInQuote + // call. + MaxMinerFee btcutil.Amount + + // HtlcConfTarget specifies the targeted confirmation target for the + // client htlc tx. + HtlcConfTarget int32 + + // LastHop optionally specifies the last hop to use for the loop in + // payment. + LastHop *route.Vertex + + // ExternalHtlc specifies whether the htlc is published by an external + // source. + ExternalHtlc bool + + // Label contains an optional label for the swap. + Label string + + // Initiator is an optional string that identifies what software + // initiated the swap (loop CLI, autolooper, LiT UI and so on) and is + // appended to the user agent string. + Initiator string + + // Private indicates whether the destination node should be considered + // private. In which case, loop will generate hophints to assist with + // probing and payment. + Private bool + + // RouteHints are optional route hints to reach the destination through + // private channels. + RouteHints [][]zpay32.HopHint +} + +// AddressManager handles fetching of address parameters. +type AddressManager interface { + // GetStaticAddressParameters returns the static address parameters. + GetStaticAddressParameters(ctx context.Context) (*address.Parameters, + error) + + // GetStaticAddress returns the deposit address for the given + // client and server public keys. + GetStaticAddress(ctx context.Context) (*script.StaticAddress, error) + + // ListUnspent returns a list of utxos at the static address. + ListUnspent(ctx context.Context, minConfs, + maxConfs int32) ([]*lnwallet.Utxo, error) +} + +type DepositManager interface { + GetActiveDepositsInState(stateFilter fsm.StateType) ([]*deposit.Deposit, + error) + + AllOutpointsActiveDeposits(outpoints []wire.OutPoint, + stateFilter fsm.StateType) ([]*deposit.Deposit, bool) + + AllStringOutpointsActiveDeposits(outpoints []string, + stateFilter fsm.StateType) ([]*deposit.Deposit, bool) + + TransitionDeposits(deposits []*deposit.Deposit, event fsm.EventType, + expectedFinalState fsm.StateType) error + + UpdateDeposit(d *deposit.Deposit) error +} + +type WithdrawalManager interface { +} diff --git a/staticaddr/loopin/log.go b/staticaddr/loopin/log.go new file mode 100644 index 000000000..99816e9cb --- /dev/null +++ b/staticaddr/loopin/log.go @@ -0,0 +1,24 @@ +package loopin + +import ( + "github.com/btcsuite/btclog" + "github.com/lightningnetwork/lnd/build" +) + +// Subsystem defines the sub system name of this package. +const Subsystem = "SADDR" + +// log is a logger that is initialized with no output filters. This means the +// package will not perform any logging by default until the caller requests it. +var log btclog.Logger + +// The default amount of logging is none. +func init() { + UseLogger(build.NewSubLogger(Subsystem, nil)) +} + +// UseLogger uses a specified Logger to output package logging info. This should +// be used in preference to SetLogWriter if the caller is also using btclog. +func UseLogger(logger btclog.Logger) { + log = logger +} diff --git a/staticaddr/loopin/loopin.go b/staticaddr/loopin/loopin.go new file mode 100644 index 000000000..a7d4f6513 --- /dev/null +++ b/staticaddr/loopin/loopin.go @@ -0,0 +1,152 @@ +package loopin + +import ( + "fmt" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightninglabs/aperture/l402" + "github.com/lightninglabs/loop/staticaddr/address" + "github.com/lightninglabs/loop/staticaddr/deposit" + "github.com/lightninglabs/loop/staticaddr/script" + "github.com/lightninglabs/loop/staticaddr/version" + "github.com/lightninglabs/loop/swap" + "github.com/lightningnetwork/lnd/keychain" + "github.com/lightningnetwork/lnd/lntypes" + "github.com/lightningnetwork/lnd/lnwallet/chainfee" + "github.com/lightningnetwork/lnd/zpay32" + "sync" + + "github.com/lightninglabs/loop/fsm" +) + +// ID is a unique identifier for a deposit. +type ID [IdLength]byte + +// FromByteSlice creates a deposit id from a byte slice. +func (r *ID) FromByteSlice(b []byte) error { + if len(b) != IdLength { + return fmt.Errorf("deposit id must be 32 bytes, got %d, %x", + len(b), b) + } + + copy(r[:], b) + + return nil +} + +// StaticAddressLoopIn ... +type StaticAddressLoopIn struct { + // ID is the unique identifier of the deposit. + ID ID + + // ProtocolVersion is the protocol version of the static address. + StaticAddressProtocolVersion version.AddressProtocolVersion + + SwapInvoice string + + SwapPayRequest *zpay32.Invoice + + // SwapHash is the hash of the swap. + SwapHash lntypes.Hash + + // SwapPreimage is the preimage that is used for the swap. + SwapPreimage lntypes.Preimage + + LastHop []byte + + // State is the current state of the swap. + state fsm.StateType + + // InitiationHeight is the height at which the swap was initiated. + InitiationHeight uint32 + + // L402ID is the main identifier of the L402 that was used to perform + // a swap. If the legacy server interface without aperture/L402 is used, + // this will be nil. + L402ID l402.TokenID + + AddressParams *address.Parameters + + Address *script.StaticAddress + + DepositOutpoints []string + + Deposits []*deposit.Deposit + + // Value is the amount that is swapped. + Value btcutil.Amount + + // ///////////////// HTLC Fields ////////////////////// + // ClientPubkey is the pubkey of the client that is used for the swap. + ClientPubkey *btcec.PublicKey + + // ServerPubkey is the pubkey of the server that is used for the swap. + ServerPubkey *btcec.PublicKey + + // HtlcExpiry is the expiry of the swap. + HtlcExpiry int32 + + // HtlcKeyLocator is the locator of the server's htlc key. + HtlcKeyLocator keychain.KeyLocator + + // HtlcFeeRate is the fee rate that is used for the htlc transaction. + HtlcFeeRate chainfee.SatPerKWeight + + // ///////////////// Sweepless Tx Fields ////////////////////// + // SweeplessFeeRate is the fee rate that is used for the htlc + // transaction. + SweeplessFeeRate chainfee.SatPerKWeight + + // SweeplessSweepAddress is the address that is used to cooperatively + // sweep the deposits as part of the loop in swap. + SweeplessSweepAddress btcutil.Address + + // SweepTxHash is the hash of the sweep transaction. + SweepTxHash *chainhash.Hash + + // SweepConfirmationHeight is the height at which the sweep + // transaction was confirmed. + SweepConfirmationHeight uint32 + + sync.Mutex +} + +func (l *StaticAddressLoopIn) getHtlc(chainParams *chaincfg.Params) (*swap.Htlc, + error) { + + return swap.NewHtlcV2( + l.HtlcExpiry, pubkeyTo33ByteSlice(l.ClientPubkey), + pubkeyTo33ByteSlice(l.ServerPubkey), l.SwapHash, chainParams, + ) +} + +func (l *StaticAddressLoopIn) GetState() fsm.StateType { + l.Lock() + defer l.Unlock() + + return l.state +} + +func (l *StaticAddressLoopIn) SetState(state fsm.StateType) { + l.Lock() + defer l.Unlock() + + l.state = state +} + +func (l *StaticAddressLoopIn) IsInState(state fsm.StateType) bool { + l.Lock() + defer l.Unlock() + + return l.state == state +} + +// pubkeyTo33ByteSlice converts a pubkey to a 33 byte slice. +func pubkeyTo33ByteSlice(pubkey *btcec.PublicKey) [33]byte { + var pubkeyBytes [33]byte + copy(pubkeyBytes[:], pubkey.SerializeCompressed()) + + return pubkeyBytes +} diff --git a/staticaddr/loopin/manager.go b/staticaddr/loopin/manager.go new file mode 100644 index 000000000..ed449cca9 --- /dev/null +++ b/staticaddr/loopin/manager.go @@ -0,0 +1,136 @@ +package loopin + +import ( + "context" + "sync" + "time" + + "github.com/lightninglabs/loop" +) + +var ( + // hopHintFactor is factor by which we scale the total amount of + // inbound capacity we want our hop hints to represent, allowing us to + // have some leeway if peers go offline. + hopHintFactor = 2 +) + +// Manager manages the address state machines. +type Manager struct { + cfg *Config + + runCtx context.Context + + sync.Mutex + + // initChan signals the daemon that the address manager has completed + // its initialization. + initChan chan struct{} + + // initiationHeight stores the currently best known block height. + initiationHeight uint32 + + // currentHeight stores the currently best known block height. + currentHeight uint32 + + activeLoopIns map[ID]*FSM +} + +// NewManager creates a new deposit withdrawal manager. +func NewManager(cfg *Config) *Manager { + return &Manager{ + cfg: cfg, + initChan: make(chan struct{}), + activeLoopIns: make(map[ID]*FSM), + } +} + +// Run runs the deposit withdrawal manager. +func (m *Manager) Run(ctx context.Context, currentHeight uint32) error { + m.runCtx = ctx + + m.Lock() + m.currentHeight, m.initiationHeight = currentHeight, currentHeight + m.Unlock() + + newBlockChan, newBlockErrChan, err := m.cfg.ChainNotifier.RegisterBlockEpochNtfn(m.runCtx) //nolint:lll + if err != nil { + return err + } + + err = m.recover() + if err != nil { + return err + } + + // Communicate to the caller that the address manager has completed its + // initialization. + close(m.initChan) + + for { + select { + case height := <-newBlockChan: + m.Lock() + m.currentHeight = uint32(height) + m.Unlock() + + case err = <-newBlockErrChan: + return err + + case <-m.runCtx.Done(): + return m.runCtx.Err() + } + } +} + +func (m *Manager) recover() error { + return nil +} + +// WaitInitComplete waits until the static address loop-in manager has completed +// its setup. +func (m *Manager) WaitInitComplete() { + defer log.Debugf("Static address loop-in manager initiation complete.") + <-m.initChan +} + +// LoopIn ... +func (m *Manager) LoopIn(req *loop.StaticAddressLoopInRequest) error { + requestContext := &RequestContext{ + depositOutpoints: req.DepositOutpoints, + maxSwapFee: req.MaxSwapFee, + maxMinerFee: req.MaxMinerFee, + lastHop: req.LastHop, + label: req.Label, + userAgent: req.Initiator, + private: req.Private, + routeHints: req.RouteHints, + } + + return m.startLoopInFsm(requestContext) +} + +func (m *Manager) startLoopInFsm(reqCtx *RequestContext) error { + // Create a state machine for a given deposit. + fsm := NewFSM(m.runCtx, m.cfg) + + // Add the FSM to the active FSMs map. + m.Lock() + m.activeLoopIns[fsm.loopIn.ID] = fsm + m.Unlock() + + // Send the start event to the state machine. + go func() { + err := fsm.SendEvent(OnNewRequest, reqCtx) + if err != nil { + log.Errorf("Error sending OnNewRequest event: %v", err) + } + }() + + err := fsm.DefaultObserver.WaitForState(m.runCtx, time.Minute, Succeeded) + if err != nil { + return err + } + + return nil +} diff --git a/staticaddr/loopin/sql_store.go b/staticaddr/loopin/sql_store.go new file mode 100644 index 000000000..5540fe571 --- /dev/null +++ b/staticaddr/loopin/sql_store.go @@ -0,0 +1,39 @@ +package loopin + +import ( + "context" + "github.com/lightninglabs/loop/loopdb" + "github.com/lightningnetwork/lnd/clock" +) + +// SqlStore is the backing store for static address deposits. +type SqlStore struct { + baseDB *loopdb.BaseDB + + clock clock.Clock +} + +// NewSqlStore constructs a new SQLStore from a BaseDB. The BaseDB is agnostic +// to the underlying driver which can be postgres or sqlite. +func NewSqlStore(db *loopdb.BaseDB) *SqlStore { + return &SqlStore{ + baseDB: db, + + clock: clock.NewDefaultClock(), + } +} + +// CreateLoopIn ... +func (s *SqlStore) CreateLoopIn(ctx context.Context, loopIn *StaticAddressLoopIn) error { + return nil +} + +// UpdateLoopIn updates the loop-in in the database. +func (s *SqlStore) UpdateLoopIn(ctx context.Context, loopIn *StaticAddressLoopIn) error { + return nil +} + +// Close closes the database connection. +func (s *SqlStore) Close() { + s.baseDB.DB.Close() +} diff --git a/swapserverrpc/server.pb.go b/swapserverrpc/server.pb.go index a30cbe915..44d294695 100644 --- a/swapserverrpc/server.pb.go +++ b/swapserverrpc/server.pb.go @@ -3108,6 +3108,428 @@ func (x *ServerWithdrawResponse) GetServerNonces() [][]byte { return nil } +type ServerStaticAddressLoopInRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The protocol version that the client adheres to. + ProtocolVersion StaticAddressProtocolVersion `protobuf:"varint,6,opt,name=protocol_version,json=protocolVersion,proto3,enum=looprpc.StaticAddressProtocolVersion" json:"protocol_version,omitempty"` + HtlcClientKey []byte `protobuf:"bytes,1,opt,name=htlc_client_key,json=htlcClientKey,proto3" json:"htlc_client_key,omitempty"` + SwapHash []byte `protobuf:"bytes,2,opt,name=swap_hash,json=swapHash,proto3" json:"swap_hash,omitempty"` + DepositOutpoints []string `protobuf:"bytes,3,rep,name=deposit_outpoints,json=depositOutpoints,proto3" json:"deposit_outpoints,omitempty"` + SwapInvoice string `protobuf:"bytes,4,opt,name=swap_invoice,json=swapInvoice,proto3" json:"swap_invoice,omitempty"` + LastHop []byte `protobuf:"bytes,5,opt,name=last_hop,json=lastHop,proto3" json:"last_hop,omitempty"` + // The user agent string that identifies the software running on the user's + // side. This can be changed in the user's client software but it _SHOULD_ + // conform to the following pattern: + // + // Agent-Name/semver-version(/additional-info) + // + // Examples: + // + // loopd/v0.10.0-beta/commit=3b635821 + // litd/v0.2.0-alpha/commit=326d754 + UserAgent string `protobuf:"bytes,7,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"` +} + +func (x *ServerStaticAddressLoopInRequest) Reset() { + *x = ServerStaticAddressLoopInRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerStaticAddressLoopInRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerStaticAddressLoopInRequest) ProtoMessage() {} + +func (x *ServerStaticAddressLoopInRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerStaticAddressLoopInRequest.ProtoReflect.Descriptor instead. +func (*ServerStaticAddressLoopInRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{39} +} + +func (x *ServerStaticAddressLoopInRequest) GetProtocolVersion() StaticAddressProtocolVersion { + if x != nil { + return x.ProtocolVersion + } + return StaticAddressProtocolVersion_V0 +} + +func (x *ServerStaticAddressLoopInRequest) GetHtlcClientKey() []byte { + if x != nil { + return x.HtlcClientKey + } + return nil +} + +func (x *ServerStaticAddressLoopInRequest) GetSwapHash() []byte { + if x != nil { + return x.SwapHash + } + return nil +} + +func (x *ServerStaticAddressLoopInRequest) GetDepositOutpoints() []string { + if x != nil { + return x.DepositOutpoints + } + return nil +} + +func (x *ServerStaticAddressLoopInRequest) GetSwapInvoice() string { + if x != nil { + return x.SwapInvoice + } + return "" +} + +func (x *ServerStaticAddressLoopInRequest) GetLastHop() []byte { + if x != nil { + return x.LastHop + } + return nil +} + +func (x *ServerStaticAddressLoopInRequest) GetUserAgent() string { + if x != nil { + return x.UserAgent + } + return "" +} + +type ServerStaticAddressLoopInResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LoopInId []byte `protobuf:"bytes,1,opt,name=loop_in_id,json=loopInId,proto3" json:"loop_in_id,omitempty"` + HtlcServerKey []byte `protobuf:"bytes,2,opt,name=htlc_server_key,json=htlcServerKey,proto3" json:"htlc_server_key,omitempty"` + HtlcExpiry int32 `protobuf:"varint,3,opt,name=htlc_expiry,json=htlcExpiry,proto3" json:"htlc_expiry,omitempty"` + // The nonces that the server used to generate the htlc sigs. + HtlcServerNonces [][]byte `protobuf:"bytes,4,rep,name=htlc_server_nonces,json=htlcServerNonces,proto3" json:"htlc_server_nonces,omitempty"` + // The fee rate in sat/kw that the server wants to use for the htlc tx. + HtlcFeeRate uint64 `protobuf:"varint,5,opt,name=htlc_fee_rate,json=htlcFeeRate,proto3" json:"htlc_fee_rate,omitempty"` +} + +func (x *ServerStaticAddressLoopInResponse) Reset() { + *x = ServerStaticAddressLoopInResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerStaticAddressLoopInResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerStaticAddressLoopInResponse) ProtoMessage() {} + +func (x *ServerStaticAddressLoopInResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerStaticAddressLoopInResponse.ProtoReflect.Descriptor instead. +func (*ServerStaticAddressLoopInResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{40} +} + +func (x *ServerStaticAddressLoopInResponse) GetLoopInId() []byte { + if x != nil { + return x.LoopInId + } + return nil +} + +func (x *ServerStaticAddressLoopInResponse) GetHtlcServerKey() []byte { + if x != nil { + return x.HtlcServerKey + } + return nil +} + +func (x *ServerStaticAddressLoopInResponse) GetHtlcExpiry() int32 { + if x != nil { + return x.HtlcExpiry + } + return 0 +} + +func (x *ServerStaticAddressLoopInResponse) GetHtlcServerNonces() [][]byte { + if x != nil { + return x.HtlcServerNonces + } + return nil +} + +func (x *ServerStaticAddressLoopInResponse) GetHtlcFeeRate() uint64 { + if x != nil { + return x.HtlcFeeRate + } + return 0 +} + +type PushStaticAddressHtlcSigsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LoopInId []byte `protobuf:"bytes,1,opt,name=loop_in_id,json=loopInId,proto3" json:"loop_in_id,omitempty"` + // The nonces that the client used to generate the htlc sigs. + HtlcClientNonces [][]byte `protobuf:"bytes,2,rep,name=htlc_client_nonces,json=htlcClientNonces,proto3" json:"htlc_client_nonces,omitempty"` + // The musig2 htlc sigs that the client generated for the htlc. + HtlcClientSigs [][]byte `protobuf:"bytes,3,rep,name=htlc_client_sigs,json=htlcClientSigs,proto3" json:"htlc_client_sigs,omitempty"` +} + +func (x *PushStaticAddressHtlcSigsRequest) Reset() { + *x = PushStaticAddressHtlcSigsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushStaticAddressHtlcSigsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushStaticAddressHtlcSigsRequest) ProtoMessage() {} + +func (x *PushStaticAddressHtlcSigsRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushStaticAddressHtlcSigsRequest.ProtoReflect.Descriptor instead. +func (*PushStaticAddressHtlcSigsRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{41} +} + +func (x *PushStaticAddressHtlcSigsRequest) GetLoopInId() []byte { + if x != nil { + return x.LoopInId + } + return nil +} + +func (x *PushStaticAddressHtlcSigsRequest) GetHtlcClientNonces() [][]byte { + if x != nil { + return x.HtlcClientNonces + } + return nil +} + +func (x *PushStaticAddressHtlcSigsRequest) GetHtlcClientSigs() [][]byte { + if x != nil { + return x.HtlcClientSigs + } + return nil +} + +type PushStaticAddressHtlcSigsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The nonces that the client used to generate the htlc sigs. + SweeplessServerNonces [][]byte `protobuf:"bytes,1,rep,name=sweepless_server_nonces,json=sweeplessServerNonces,proto3" json:"sweepless_server_nonces,omitempty"` + // The fee rate in sat/kw that the server wants to use for the htlc tx. + SweeplessFeeRate uint64 `protobuf:"varint,2,opt,name=sweepless_fee_rate,json=sweeplessFeeRate,proto3" json:"sweepless_fee_rate,omitempty"` + // The address that the client wants to sweep the static address deposits + // to. + SweeplessSweepAddr string `protobuf:"bytes,3,opt,name=sweepless_sweep_addr,json=sweeplessSweepAddr,proto3" json:"sweepless_sweep_addr,omitempty"` +} + +func (x *PushStaticAddressHtlcSigsResponse) Reset() { + *x = PushStaticAddressHtlcSigsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushStaticAddressHtlcSigsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushStaticAddressHtlcSigsResponse) ProtoMessage() {} + +func (x *PushStaticAddressHtlcSigsResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushStaticAddressHtlcSigsResponse.ProtoReflect.Descriptor instead. +func (*PushStaticAddressHtlcSigsResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{42} +} + +func (x *PushStaticAddressHtlcSigsResponse) GetSweeplessServerNonces() [][]byte { + if x != nil { + return x.SweeplessServerNonces + } + return nil +} + +func (x *PushStaticAddressHtlcSigsResponse) GetSweeplessFeeRate() uint64 { + if x != nil { + return x.SweeplessFeeRate + } + return 0 +} + +func (x *PushStaticAddressHtlcSigsResponse) GetSweeplessSweepAddr() string { + if x != nil { + return x.SweeplessSweepAddr + } + return "" +} + +type PushStaticAddressSweeplessSigsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LoopInId []byte `protobuf:"bytes,1,opt,name=loop_in_id,json=loopInId,proto3" json:"loop_in_id,omitempty"` + // The nonces that the client used to generate the htlc sigs. + SweeplessClientNonces [][]byte `protobuf:"bytes,2,rep,name=sweepless_client_nonces,json=sweeplessClientNonces,proto3" json:"sweepless_client_nonces,omitempty"` + // The musig2 htlc sigs that the client generated for the htlc. + SweeplessClientSigs [][]byte `protobuf:"bytes,3,rep,name=sweepless_client_sigs,json=sweeplessClientSigs,proto3" json:"sweepless_client_sigs,omitempty"` +} + +func (x *PushStaticAddressSweeplessSigsRequest) Reset() { + *x = PushStaticAddressSweeplessSigsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushStaticAddressSweeplessSigsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushStaticAddressSweeplessSigsRequest) ProtoMessage() {} + +func (x *PushStaticAddressSweeplessSigsRequest) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushStaticAddressSweeplessSigsRequest.ProtoReflect.Descriptor instead. +func (*PushStaticAddressSweeplessSigsRequest) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{43} +} + +func (x *PushStaticAddressSweeplessSigsRequest) GetLoopInId() []byte { + if x != nil { + return x.LoopInId + } + return nil +} + +func (x *PushStaticAddressSweeplessSigsRequest) GetSweeplessClientNonces() [][]byte { + if x != nil { + return x.SweeplessClientNonces + } + return nil +} + +func (x *PushStaticAddressSweeplessSigsRequest) GetSweeplessClientSigs() [][]byte { + if x != nil { + return x.SweeplessClientSigs + } + return nil +} + +type PushStaticAddressSweeplessSigsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PushStaticAddressSweeplessSigsResponse) Reset() { + *x = PushStaticAddressSweeplessSigsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_server_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushStaticAddressSweeplessSigsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushStaticAddressSweeplessSigsResponse) ProtoMessage() {} + +func (x *PushStaticAddressSweeplessSigsResponse) ProtoReflect() protoreflect.Message { + mi := &file_server_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushStaticAddressSweeplessSigsResponse.ProtoReflect.Descriptor instead. +func (*PushStaticAddressSweeplessSigsResponse) Descriptor() ([]byte, []int) { + return file_server_proto_rawDescGZIP(), []int{44} +} + var File_server_proto protoreflect.FileDescriptor var file_server_proto_rawDesc = []byte{ @@ -3475,183 +3897,276 @@ var file_server_proto_rawDesc = []byte{ 0x0f, 0x6d, 0x75, 0x73, 0x69, 0x67, 0x32, 0x53, 0x77, 0x65, 0x65, 0x70, 0x53, 0x69, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, - 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x2a, 0xef, 0x01, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x45, 0x47, - 0x41, 0x43, 0x59, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4c, - 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x4e, 0x41, 0x54, - 0x49, 0x56, 0x45, 0x5f, 0x53, 0x45, 0x47, 0x57, 0x49, 0x54, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, - 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, - 0x5f, 0x50, 0x55, 0x53, 0x48, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x03, - 0x12, 0x18, 0x0a, 0x14, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x5f, - 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x54, - 0x4c, 0x43, 0x5f, 0x56, 0x32, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x55, 0x4c, 0x54, 0x49, - 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, - 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x07, 0x12, - 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x4f, - 0x55, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x10, 0x09, 0x12, 0x0b, - 0x0a, 0x07, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x56, 0x33, 0x10, 0x0a, 0x12, 0x0a, 0x0a, 0x06, 0x4d, - 0x55, 0x53, 0x49, 0x47, 0x32, 0x10, 0x0b, 0x2a, 0x9e, 0x04, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x53, - 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x48, 0x54, 0x4c, 0x43, - 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, - 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, - 0x12, 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, - 0x44, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x53, - 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, - 0x48, 0x54, 0x4c, 0x43, 0x10, 0x04, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x05, 0x12, 0x23, 0x0a, - 0x1f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4f, - 0x46, 0x46, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, - 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, - 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x1f, 0x0a, - 0x1b, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x53, - 0x57, 0x41, 0x50, 0x5f, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x08, 0x12, 0x22, - 0x0a, 0x1e, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, - 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x10, 0x09, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x49, 0x4d, - 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x0a, - 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x58, 0x50, - 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x0b, 0x12, - 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x43, - 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, 0x0c, 0x12, 0x1f, 0x0a, 0x1b, 0x53, 0x45, - 0x52, 0x56, 0x45, 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x50, - 0x41, 0x59, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x0d, 0x12, 0x20, 0x0a, 0x1c, 0x53, - 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x56, - 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x0e, 0x12, 0x27, 0x0a, - 0x23, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4d, - 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x53, 0x43, 0x52, - 0x49, 0x50, 0x54, 0x53, 0x10, 0x0f, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, - 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x10, 0x2a, 0x4a, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, - 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, - 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, - 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x52, 0x4f, 0x55, - 0x54, 0x45, 0x10, 0x02, 0x2a, 0xf1, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, - 0x17, 0x4c, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x4c, 0x4e, - 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, - 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4c, 0x4e, - 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, - 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x4c, - 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, - 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x30, 0x0a, 0x2c, 0x4c, 0x4e, 0x44, + 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0xc3, 0x02, 0x0a, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, + 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50, 0x0a, 0x10, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, + 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x68, 0x74, 0x6c, 0x63, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x6f, 0x75, 0x74, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x21, + 0x0a, 0x0c, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x6f, 0x70, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x6f, 0x70, 0x12, 0x1d, 0x0a, 0x0a, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x22, 0xdc, 0x01, 0x0a, 0x21, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x49, 0x64, 0x12, + 0x26, 0x0a, 0x0f, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x68, 0x74, 0x6c, 0x63, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x74, 0x6c, 0x63, 0x5f, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x68, 0x74, + 0x6c, 0x63, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x68, 0x74, 0x6c, 0x63, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x66, + 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x68, + 0x74, 0x6c, 0x63, 0x46, 0x65, 0x65, 0x52, 0x61, 0x74, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x20, 0x50, + 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x0a, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x49, 0x64, 0x12, 0x2c, 0x0a, + 0x12, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x6f, 0x6e, + 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x68, + 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x68, 0x74, 0x6c, 0x63, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x53, 0x69, 0x67, 0x73, 0x22, 0xbb, 0x01, 0x0a, 0x21, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, + 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, + 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x15, 0x73, 0x77, + 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, + 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x10, 0x73, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x46, 0x65, 0x65, 0x52, 0x61, 0x74, + 0x65, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x73, + 0x77, 0x65, 0x65, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x12, 0x73, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x41, + 0x64, 0x64, 0x72, 0x22, 0xb1, 0x01, 0x0a, 0x25, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, + 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, + 0x0a, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x17, 0x73, + 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x15, 0x73, 0x77, + 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x6e, + 0x63, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, + 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x13, 0x73, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x73, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x75, 0x73, 0x68, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, + 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2a, 0xef, 0x01, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x10, + 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, + 0x4f, 0x55, 0x54, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x4e, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, + 0x53, 0x45, 0x47, 0x57, 0x49, 0x54, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x02, + 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x50, 0x55, 0x53, + 0x48, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x59, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, + 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x56, + 0x32, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4c, 0x4f, 0x4f, + 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, + 0x55, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 0x50, + 0x52, 0x4f, 0x42, 0x45, 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x4f, 0x55, 0x54, 0x49, 0x4e, + 0x47, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x10, 0x09, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x54, + 0x4c, 0x43, 0x5f, 0x56, 0x33, 0x10, 0x0a, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x55, 0x53, 0x49, 0x47, + 0x32, 0x10, 0x0b, 0x2a, 0x9e, 0x04, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x77, + 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, + 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, + 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x45, 0x52, 0x56, + 0x45, 0x52, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, + 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x48, 0x54, 0x4c, 0x43, + 0x10, 0x04, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x48, 0x54, 0x4c, 0x43, + 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4f, 0x46, 0x46, 0x5f, 0x43, + 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x06, 0x12, 0x19, + 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, + 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, + 0x44, 0x45, 0x41, 0x44, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x08, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x48, 0x54, 0x4c, 0x43, + 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x1c, + 0x0a, 0x18, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, + 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x1d, 0x0a, 0x19, + 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x45, + 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x0b, 0x12, 0x19, 0x0a, 0x15, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x48, 0x54, 0x4c, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, + 0x52, 0x4d, 0x45, 0x44, 0x10, 0x0c, 0x12, 0x1f, 0x0a, 0x1b, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, + 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x5f, 0x43, + 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x0d, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, + 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x0e, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, + 0x50, 0x4c, 0x45, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x53, + 0x10, 0x0f, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x10, 0x10, 0x2a, 0x4a, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x4f, 0x55, 0x54, + 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, + 0x52, 0x45, 0x50, 0x41, 0x59, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, + 0x0d, 0x49, 0x4e, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, 0x02, + 0x2a, 0xf1, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x4c, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, - 0x49, 0x4e, 0x43, 0x4f, 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x10, 0x04, 0x12, 0x2b, 0x0a, 0x27, 0x4c, - 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, - 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, - 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x05, 0x2a, 0x27, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, - 0x45, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x4f, 0x57, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, - 0x01, 0x2a, 0x26, 0x0a, 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x30, 0x10, 0x00, 0x32, 0xdc, 0x0a, 0x0a, 0x0a, 0x53, 0x77, - 0x61, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, - 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x4c, 0x4e, 0x44, 0x5f, 0x46, 0x41, + 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, + 0x45, 0x4f, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4c, 0x4e, 0x44, 0x5f, 0x46, 0x41, + 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x5f, + 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x4c, 0x4e, 0x44, 0x5f, 0x46, + 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x30, 0x0a, 0x2c, 0x4c, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, + 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, + 0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, + 0x54, 0x41, 0x49, 0x4c, 0x53, 0x10, 0x04, 0x12, 0x2b, 0x0a, 0x27, 0x4c, 0x4e, 0x44, 0x5f, 0x46, + 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, + 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, + 0x43, 0x45, 0x10, 0x05, 0x2a, 0x27, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, + 0x0c, 0x0a, 0x08, 0x4c, 0x4f, 0x57, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x01, 0x2a, 0x26, 0x0a, + 0x1c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x06, 0x0a, + 0x02, 0x56, 0x30, 0x10, 0x00, 0x32, 0xdc, 0x0a, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x54, + 0x65, 0x72, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, - 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, - 0x70, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x4f, 0x0a, 0x0e, 0x4e, 0x65, 0x77, - 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1d, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, - 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, - 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x4c, 0x6f, + 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x4f, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x4c, 0x6f, 0x6f, 0x70, + 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x13, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, + 0x74, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x29, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x65, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, - 0x70, 0x4f, 0x75, 0x74, 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, - 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, - 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, - 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, - 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, - 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, - 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x4c, 0x6f, - 0x6f, 0x70, 0x49, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, - 0x75, 0x6f, 0x74, 0x65, 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, - 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, - 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x17, 0x53, + 0x50, 0x75, 0x73, 0x68, 0x50, 0x72, 0x65, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, + 0x75, 0x6f, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, + 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, + 0x65, 0x72, 0x6d, 0x73, 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, + 0x72, 0x6d, 0x73, 0x12, 0x4c, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, + 0x53, 0x77, 0x61, 0x70, 0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x6f, 0x70, - 0x4f, 0x75, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x30, 0x01, 0x12, 0x65, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x20, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x27, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x11, 0x43, - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, - 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, - 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, - 0x6e, 0x63, 0x65, 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, - 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x72, - 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x16, 0x52, - 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, + 0x12, 0x65, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4c, 0x6f, 0x6f, + 0x70, 0x49, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x11, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x12, 0x21, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4c, 0x6f, 0x6f, + 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x1b, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, + 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x16, 0x52, 0x65, 0x63, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x12, 0x57, 0x0a, - 0x13, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, - 0x53, 0x69, 0x67, 0x6e, 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x77, - 0x65, 0x65, 0x70, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x77, 0x65, 0x65, 0x70, - 0x52, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x50, 0x75, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x19, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, - 0x75, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x73, 0x68, 0x4b, 0x65, - 0x79, 0x52, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, - 0x32, 0x12, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x4c, 0x34, 0x30, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc9, 0x01, 0x0a, 0x13, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x12, 0x57, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x73, 0x77, 0x61, 0x70, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x13, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, + 0x71, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, + 0x53, 0x77, 0x65, 0x65, 0x70, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, + 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, + 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x77, 0x65, 0x65, 0x70, 0x52, 0x65, 0x73, 0x12, + 0x3f, 0x0a, 0x07, 0x50, 0x75, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x73, 0x68, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x73, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x12, 0x42, 0x0a, 0x09, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x12, 0x19, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, + 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x34, 0x30, 0x32, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb5, 0x04, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x57, 0x0a, 0x10, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x20, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x57, + 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, + 0x1e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x72, 0x0a, 0x19, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x29, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x19, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, + 0x73, 0x12, 0x29, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, + 0x63, 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x74, 0x6c, 0x63, 0x53, 0x69, 0x67, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x50, 0x75, 0x73, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, + 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, 0x53, 0x69, 0x67, 0x73, 0x12, 0x2e, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, + 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x77, 0x65, 0x65, 0x70, 0x6c, 0x65, 0x73, 0x73, + 0x53, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x73, 0x77, + 0x61, 0x70, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -3667,61 +4182,67 @@ func file_server_proto_rawDescGZIP() []byte { } var file_server_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_server_proto_msgTypes = make([]protoimpl.MessageInfo, 39) +var file_server_proto_msgTypes = make([]protoimpl.MessageInfo, 45) var file_server_proto_goTypes = []interface{}{ - (ProtocolVersion)(0), // 0: looprpc.ProtocolVersion - (ServerSwapState)(0), // 1: looprpc.ServerSwapState - (RoutePaymentType)(0), // 2: looprpc.RoutePaymentType - (PaymentFailureReason)(0), // 3: looprpc.PaymentFailureReason - (RoutingPlugin)(0), // 4: looprpc.RoutingPlugin - (StaticAddressProtocolVersion)(0), // 5: looprpc.StaticAddressProtocolVersion - (*ServerLoopOutRequest)(nil), // 6: looprpc.ServerLoopOutRequest - (*ServerLoopOutResponse)(nil), // 7: looprpc.ServerLoopOutResponse - (*ServerLoopOutQuoteRequest)(nil), // 8: looprpc.ServerLoopOutQuoteRequest - (*ServerLoopOutQuote)(nil), // 9: looprpc.ServerLoopOutQuote - (*ServerLoopOutTermsRequest)(nil), // 10: looprpc.ServerLoopOutTermsRequest - (*ServerLoopOutTerms)(nil), // 11: looprpc.ServerLoopOutTerms - (*ServerLoopInRequest)(nil), // 12: looprpc.ServerLoopInRequest - (*ServerLoopInResponse)(nil), // 13: looprpc.ServerLoopInResponse - (*ServerLoopInQuoteRequest)(nil), // 14: looprpc.ServerLoopInQuoteRequest - (*ServerLoopInQuoteResponse)(nil), // 15: looprpc.ServerLoopInQuoteResponse - (*ServerLoopInTermsRequest)(nil), // 16: looprpc.ServerLoopInTermsRequest - (*ServerLoopInTerms)(nil), // 17: looprpc.ServerLoopInTerms - (*ServerLoopOutPushPreimageRequest)(nil), // 18: looprpc.ServerLoopOutPushPreimageRequest - (*ServerLoopOutPushPreimageResponse)(nil), // 19: looprpc.ServerLoopOutPushPreimageResponse - (*SubscribeUpdatesRequest)(nil), // 20: looprpc.SubscribeUpdatesRequest - (*SubscribeLoopOutUpdatesResponse)(nil), // 21: looprpc.SubscribeLoopOutUpdatesResponse - (*SubscribeLoopInUpdatesResponse)(nil), // 22: looprpc.SubscribeLoopInUpdatesResponse - (*RouteCancel)(nil), // 23: looprpc.RouteCancel - (*HtlcAttempt)(nil), // 24: looprpc.HtlcAttempt - (*CancelLoopOutSwapRequest)(nil), // 25: looprpc.CancelLoopOutSwapRequest - (*CancelLoopOutSwapResponse)(nil), // 26: looprpc.CancelLoopOutSwapResponse - (*ServerProbeRequest)(nil), // 27: looprpc.ServerProbeRequest - (*ServerProbeResponse)(nil), // 28: looprpc.ServerProbeResponse - (*RecommendRoutingPluginReq)(nil), // 29: looprpc.RecommendRoutingPluginReq - (*RecommendRoutingPluginRes)(nil), // 30: looprpc.RecommendRoutingPluginRes - (*ReportRoutingResultReq)(nil), // 31: looprpc.ReportRoutingResultReq - (*ReportRoutingResultRes)(nil), // 32: looprpc.ReportRoutingResultRes - (*MuSig2SignSweepReq)(nil), // 33: looprpc.MuSig2SignSweepReq - (*PrevoutInfo)(nil), // 34: looprpc.PrevoutInfo - (*MuSig2SignSweepRes)(nil), // 35: looprpc.MuSig2SignSweepRes - (*ServerPushKeyReq)(nil), // 36: looprpc.ServerPushKeyReq - (*ServerPushKeyRes)(nil), // 37: looprpc.ServerPushKeyRes - (*FetchL402Request)(nil), // 38: looprpc.FetchL402Request - (*FetchL402Response)(nil), // 39: looprpc.FetchL402Response - (*ServerNewAddressRequest)(nil), // 40: looprpc.ServerNewAddressRequest - (*ServerNewAddressResponse)(nil), // 41: looprpc.ServerNewAddressResponse - (*ServerAddressParameters)(nil), // 42: looprpc.ServerAddressParameters - (*ServerWithdrawRequest)(nil), // 43: looprpc.ServerWithdrawRequest - (*ServerWithdrawResponse)(nil), // 44: looprpc.ServerWithdrawResponse - (*RouteHint)(nil), // 45: looprpc.RouteHint + (ProtocolVersion)(0), // 0: looprpc.ProtocolVersion + (ServerSwapState)(0), // 1: looprpc.ServerSwapState + (RoutePaymentType)(0), // 2: looprpc.RoutePaymentType + (PaymentFailureReason)(0), // 3: looprpc.PaymentFailureReason + (RoutingPlugin)(0), // 4: looprpc.RoutingPlugin + (StaticAddressProtocolVersion)(0), // 5: looprpc.StaticAddressProtocolVersion + (*ServerLoopOutRequest)(nil), // 6: looprpc.ServerLoopOutRequest + (*ServerLoopOutResponse)(nil), // 7: looprpc.ServerLoopOutResponse + (*ServerLoopOutQuoteRequest)(nil), // 8: looprpc.ServerLoopOutQuoteRequest + (*ServerLoopOutQuote)(nil), // 9: looprpc.ServerLoopOutQuote + (*ServerLoopOutTermsRequest)(nil), // 10: looprpc.ServerLoopOutTermsRequest + (*ServerLoopOutTerms)(nil), // 11: looprpc.ServerLoopOutTerms + (*ServerLoopInRequest)(nil), // 12: looprpc.ServerLoopInRequest + (*ServerLoopInResponse)(nil), // 13: looprpc.ServerLoopInResponse + (*ServerLoopInQuoteRequest)(nil), // 14: looprpc.ServerLoopInQuoteRequest + (*ServerLoopInQuoteResponse)(nil), // 15: looprpc.ServerLoopInQuoteResponse + (*ServerLoopInTermsRequest)(nil), // 16: looprpc.ServerLoopInTermsRequest + (*ServerLoopInTerms)(nil), // 17: looprpc.ServerLoopInTerms + (*ServerLoopOutPushPreimageRequest)(nil), // 18: looprpc.ServerLoopOutPushPreimageRequest + (*ServerLoopOutPushPreimageResponse)(nil), // 19: looprpc.ServerLoopOutPushPreimageResponse + (*SubscribeUpdatesRequest)(nil), // 20: looprpc.SubscribeUpdatesRequest + (*SubscribeLoopOutUpdatesResponse)(nil), // 21: looprpc.SubscribeLoopOutUpdatesResponse + (*SubscribeLoopInUpdatesResponse)(nil), // 22: looprpc.SubscribeLoopInUpdatesResponse + (*RouteCancel)(nil), // 23: looprpc.RouteCancel + (*HtlcAttempt)(nil), // 24: looprpc.HtlcAttempt + (*CancelLoopOutSwapRequest)(nil), // 25: looprpc.CancelLoopOutSwapRequest + (*CancelLoopOutSwapResponse)(nil), // 26: looprpc.CancelLoopOutSwapResponse + (*ServerProbeRequest)(nil), // 27: looprpc.ServerProbeRequest + (*ServerProbeResponse)(nil), // 28: looprpc.ServerProbeResponse + (*RecommendRoutingPluginReq)(nil), // 29: looprpc.RecommendRoutingPluginReq + (*RecommendRoutingPluginRes)(nil), // 30: looprpc.RecommendRoutingPluginRes + (*ReportRoutingResultReq)(nil), // 31: looprpc.ReportRoutingResultReq + (*ReportRoutingResultRes)(nil), // 32: looprpc.ReportRoutingResultRes + (*MuSig2SignSweepReq)(nil), // 33: looprpc.MuSig2SignSweepReq + (*PrevoutInfo)(nil), // 34: looprpc.PrevoutInfo + (*MuSig2SignSweepRes)(nil), // 35: looprpc.MuSig2SignSweepRes + (*ServerPushKeyReq)(nil), // 36: looprpc.ServerPushKeyReq + (*ServerPushKeyRes)(nil), // 37: looprpc.ServerPushKeyRes + (*FetchL402Request)(nil), // 38: looprpc.FetchL402Request + (*FetchL402Response)(nil), // 39: looprpc.FetchL402Response + (*ServerNewAddressRequest)(nil), // 40: looprpc.ServerNewAddressRequest + (*ServerNewAddressResponse)(nil), // 41: looprpc.ServerNewAddressResponse + (*ServerAddressParameters)(nil), // 42: looprpc.ServerAddressParameters + (*ServerWithdrawRequest)(nil), // 43: looprpc.ServerWithdrawRequest + (*ServerWithdrawResponse)(nil), // 44: looprpc.ServerWithdrawResponse + (*ServerStaticAddressLoopInRequest)(nil), // 45: looprpc.ServerStaticAddressLoopInRequest + (*ServerStaticAddressLoopInResponse)(nil), // 46: looprpc.ServerStaticAddressLoopInResponse + (*PushStaticAddressHtlcSigsRequest)(nil), // 47: looprpc.PushStaticAddressHtlcSigsRequest + (*PushStaticAddressHtlcSigsResponse)(nil), // 48: looprpc.PushStaticAddressHtlcSigsResponse + (*PushStaticAddressSweeplessSigsRequest)(nil), // 49: looprpc.PushStaticAddressSweeplessSigsRequest + (*PushStaticAddressSweeplessSigsResponse)(nil), // 50: looprpc.PushStaticAddressSweeplessSigsResponse + (*RouteHint)(nil), // 51: looprpc.RouteHint } var file_server_proto_depIdxs = []int32{ 0, // 0: looprpc.ServerLoopOutRequest.protocol_version:type_name -> looprpc.ProtocolVersion 0, // 1: looprpc.ServerLoopOutQuoteRequest.protocol_version:type_name -> looprpc.ProtocolVersion 0, // 2: looprpc.ServerLoopOutTermsRequest.protocol_version:type_name -> looprpc.ProtocolVersion 0, // 3: looprpc.ServerLoopInRequest.protocol_version:type_name -> looprpc.ProtocolVersion - 45, // 4: looprpc.ServerLoopInQuoteRequest.route_hints:type_name -> looprpc.RouteHint + 51, // 4: looprpc.ServerLoopInQuoteRequest.route_hints:type_name -> looprpc.RouteHint 0, // 5: looprpc.ServerLoopInQuoteRequest.protocol_version:type_name -> looprpc.ProtocolVersion 0, // 6: looprpc.ServerLoopInTermsRequest.protocol_version:type_name -> looprpc.ProtocolVersion 0, // 7: looprpc.ServerLoopOutPushPreimageRequest.protocol_version:type_name -> looprpc.ProtocolVersion @@ -3734,7 +4255,7 @@ var file_server_proto_depIdxs = []int32{ 0, // 14: looprpc.CancelLoopOutSwapRequest.protocol_version:type_name -> looprpc.ProtocolVersion 23, // 15: looprpc.CancelLoopOutSwapRequest.route_cancel:type_name -> looprpc.RouteCancel 0, // 16: looprpc.ServerProbeRequest.protocol_version:type_name -> looprpc.ProtocolVersion - 45, // 17: looprpc.ServerProbeRequest.route_hints:type_name -> looprpc.RouteHint + 51, // 17: looprpc.ServerProbeRequest.route_hints:type_name -> looprpc.RouteHint 0, // 18: looprpc.RecommendRoutingPluginReq.protocol_version:type_name -> looprpc.ProtocolVersion 4, // 19: looprpc.RecommendRoutingPluginRes.plugin:type_name -> looprpc.RoutingPlugin 0, // 20: looprpc.ReportRoutingResultReq.protocol_version:type_name -> looprpc.ProtocolVersion @@ -3745,47 +4266,54 @@ var file_server_proto_depIdxs = []int32{ 5, // 25: looprpc.ServerNewAddressRequest.protocol_version:type_name -> looprpc.StaticAddressProtocolVersion 42, // 26: looprpc.ServerNewAddressResponse.params:type_name -> looprpc.ServerAddressParameters 34, // 27: looprpc.ServerWithdrawRequest.outpoints:type_name -> looprpc.PrevoutInfo - 10, // 28: looprpc.SwapServer.LoopOutTerms:input_type -> looprpc.ServerLoopOutTermsRequest - 6, // 29: looprpc.SwapServer.NewLoopOutSwap:input_type -> looprpc.ServerLoopOutRequest - 18, // 30: looprpc.SwapServer.LoopOutPushPreimage:input_type -> looprpc.ServerLoopOutPushPreimageRequest - 8, // 31: looprpc.SwapServer.LoopOutQuote:input_type -> looprpc.ServerLoopOutQuoteRequest - 16, // 32: looprpc.SwapServer.LoopInTerms:input_type -> looprpc.ServerLoopInTermsRequest - 12, // 33: looprpc.SwapServer.NewLoopInSwap:input_type -> looprpc.ServerLoopInRequest - 14, // 34: looprpc.SwapServer.LoopInQuote:input_type -> looprpc.ServerLoopInQuoteRequest - 20, // 35: looprpc.SwapServer.SubscribeLoopOutUpdates:input_type -> looprpc.SubscribeUpdatesRequest - 20, // 36: looprpc.SwapServer.SubscribeLoopInUpdates:input_type -> looprpc.SubscribeUpdatesRequest - 25, // 37: looprpc.SwapServer.CancelLoopOutSwap:input_type -> looprpc.CancelLoopOutSwapRequest - 27, // 38: looprpc.SwapServer.Probe:input_type -> looprpc.ServerProbeRequest - 29, // 39: looprpc.SwapServer.RecommendRoutingPlugin:input_type -> looprpc.RecommendRoutingPluginReq - 31, // 40: looprpc.SwapServer.ReportRoutingResult:input_type -> looprpc.ReportRoutingResultReq - 33, // 41: looprpc.SwapServer.MuSig2SignSweep:input_type -> looprpc.MuSig2SignSweepReq - 36, // 42: looprpc.SwapServer.PushKey:input_type -> looprpc.ServerPushKeyReq - 38, // 43: looprpc.SwapServer.FetchL402:input_type -> looprpc.FetchL402Request - 40, // 44: looprpc.StaticAddressServer.ServerNewAddress:input_type -> looprpc.ServerNewAddressRequest - 43, // 45: looprpc.StaticAddressServer.ServerWithdrawDeposits:input_type -> looprpc.ServerWithdrawRequest - 11, // 46: looprpc.SwapServer.LoopOutTerms:output_type -> looprpc.ServerLoopOutTerms - 7, // 47: looprpc.SwapServer.NewLoopOutSwap:output_type -> looprpc.ServerLoopOutResponse - 19, // 48: looprpc.SwapServer.LoopOutPushPreimage:output_type -> looprpc.ServerLoopOutPushPreimageResponse - 9, // 49: looprpc.SwapServer.LoopOutQuote:output_type -> looprpc.ServerLoopOutQuote - 17, // 50: looprpc.SwapServer.LoopInTerms:output_type -> looprpc.ServerLoopInTerms - 13, // 51: looprpc.SwapServer.NewLoopInSwap:output_type -> looprpc.ServerLoopInResponse - 15, // 52: looprpc.SwapServer.LoopInQuote:output_type -> looprpc.ServerLoopInQuoteResponse - 21, // 53: looprpc.SwapServer.SubscribeLoopOutUpdates:output_type -> looprpc.SubscribeLoopOutUpdatesResponse - 22, // 54: looprpc.SwapServer.SubscribeLoopInUpdates:output_type -> looprpc.SubscribeLoopInUpdatesResponse - 26, // 55: looprpc.SwapServer.CancelLoopOutSwap:output_type -> looprpc.CancelLoopOutSwapResponse - 28, // 56: looprpc.SwapServer.Probe:output_type -> looprpc.ServerProbeResponse - 30, // 57: looprpc.SwapServer.RecommendRoutingPlugin:output_type -> looprpc.RecommendRoutingPluginRes - 32, // 58: looprpc.SwapServer.ReportRoutingResult:output_type -> looprpc.ReportRoutingResultRes - 35, // 59: looprpc.SwapServer.MuSig2SignSweep:output_type -> looprpc.MuSig2SignSweepRes - 37, // 60: looprpc.SwapServer.PushKey:output_type -> looprpc.ServerPushKeyRes - 39, // 61: looprpc.SwapServer.FetchL402:output_type -> looprpc.FetchL402Response - 41, // 62: looprpc.StaticAddressServer.ServerNewAddress:output_type -> looprpc.ServerNewAddressResponse - 44, // 63: looprpc.StaticAddressServer.ServerWithdrawDeposits:output_type -> looprpc.ServerWithdrawResponse - 46, // [46:64] is the sub-list for method output_type - 28, // [28:46] is the sub-list for method input_type - 28, // [28:28] is the sub-list for extension type_name - 28, // [28:28] is the sub-list for extension extendee - 0, // [0:28] is the sub-list for field type_name + 5, // 28: looprpc.ServerStaticAddressLoopInRequest.protocol_version:type_name -> looprpc.StaticAddressProtocolVersion + 10, // 29: looprpc.SwapServer.LoopOutTerms:input_type -> looprpc.ServerLoopOutTermsRequest + 6, // 30: looprpc.SwapServer.NewLoopOutSwap:input_type -> looprpc.ServerLoopOutRequest + 18, // 31: looprpc.SwapServer.LoopOutPushPreimage:input_type -> looprpc.ServerLoopOutPushPreimageRequest + 8, // 32: looprpc.SwapServer.LoopOutQuote:input_type -> looprpc.ServerLoopOutQuoteRequest + 16, // 33: looprpc.SwapServer.LoopInTerms:input_type -> looprpc.ServerLoopInTermsRequest + 12, // 34: looprpc.SwapServer.NewLoopInSwap:input_type -> looprpc.ServerLoopInRequest + 14, // 35: looprpc.SwapServer.LoopInQuote:input_type -> looprpc.ServerLoopInQuoteRequest + 20, // 36: looprpc.SwapServer.SubscribeLoopOutUpdates:input_type -> looprpc.SubscribeUpdatesRequest + 20, // 37: looprpc.SwapServer.SubscribeLoopInUpdates:input_type -> looprpc.SubscribeUpdatesRequest + 25, // 38: looprpc.SwapServer.CancelLoopOutSwap:input_type -> looprpc.CancelLoopOutSwapRequest + 27, // 39: looprpc.SwapServer.Probe:input_type -> looprpc.ServerProbeRequest + 29, // 40: looprpc.SwapServer.RecommendRoutingPlugin:input_type -> looprpc.RecommendRoutingPluginReq + 31, // 41: looprpc.SwapServer.ReportRoutingResult:input_type -> looprpc.ReportRoutingResultReq + 33, // 42: looprpc.SwapServer.MuSig2SignSweep:input_type -> looprpc.MuSig2SignSweepReq + 36, // 43: looprpc.SwapServer.PushKey:input_type -> looprpc.ServerPushKeyReq + 38, // 44: looprpc.SwapServer.FetchL402:input_type -> looprpc.FetchL402Request + 40, // 45: looprpc.StaticAddressServer.ServerNewAddress:input_type -> looprpc.ServerNewAddressRequest + 43, // 46: looprpc.StaticAddressServer.ServerWithdrawDeposits:input_type -> looprpc.ServerWithdrawRequest + 45, // 47: looprpc.StaticAddressServer.ServerStaticAddressLoopIn:input_type -> looprpc.ServerStaticAddressLoopInRequest + 47, // 48: looprpc.StaticAddressServer.PushStaticAddressHtlcSigs:input_type -> looprpc.PushStaticAddressHtlcSigsRequest + 49, // 49: looprpc.StaticAddressServer.PushStaticAddressSweeplessSigs:input_type -> looprpc.PushStaticAddressSweeplessSigsRequest + 11, // 50: looprpc.SwapServer.LoopOutTerms:output_type -> looprpc.ServerLoopOutTerms + 7, // 51: looprpc.SwapServer.NewLoopOutSwap:output_type -> looprpc.ServerLoopOutResponse + 19, // 52: looprpc.SwapServer.LoopOutPushPreimage:output_type -> looprpc.ServerLoopOutPushPreimageResponse + 9, // 53: looprpc.SwapServer.LoopOutQuote:output_type -> looprpc.ServerLoopOutQuote + 17, // 54: looprpc.SwapServer.LoopInTerms:output_type -> looprpc.ServerLoopInTerms + 13, // 55: looprpc.SwapServer.NewLoopInSwap:output_type -> looprpc.ServerLoopInResponse + 15, // 56: looprpc.SwapServer.LoopInQuote:output_type -> looprpc.ServerLoopInQuoteResponse + 21, // 57: looprpc.SwapServer.SubscribeLoopOutUpdates:output_type -> looprpc.SubscribeLoopOutUpdatesResponse + 22, // 58: looprpc.SwapServer.SubscribeLoopInUpdates:output_type -> looprpc.SubscribeLoopInUpdatesResponse + 26, // 59: looprpc.SwapServer.CancelLoopOutSwap:output_type -> looprpc.CancelLoopOutSwapResponse + 28, // 60: looprpc.SwapServer.Probe:output_type -> looprpc.ServerProbeResponse + 30, // 61: looprpc.SwapServer.RecommendRoutingPlugin:output_type -> looprpc.RecommendRoutingPluginRes + 32, // 62: looprpc.SwapServer.ReportRoutingResult:output_type -> looprpc.ReportRoutingResultRes + 35, // 63: looprpc.SwapServer.MuSig2SignSweep:output_type -> looprpc.MuSig2SignSweepRes + 37, // 64: looprpc.SwapServer.PushKey:output_type -> looprpc.ServerPushKeyRes + 39, // 65: looprpc.SwapServer.FetchL402:output_type -> looprpc.FetchL402Response + 41, // 66: looprpc.StaticAddressServer.ServerNewAddress:output_type -> looprpc.ServerNewAddressResponse + 44, // 67: looprpc.StaticAddressServer.ServerWithdrawDeposits:output_type -> looprpc.ServerWithdrawResponse + 46, // 68: looprpc.StaticAddressServer.ServerStaticAddressLoopIn:output_type -> looprpc.ServerStaticAddressLoopInResponse + 48, // 69: looprpc.StaticAddressServer.PushStaticAddressHtlcSigs:output_type -> looprpc.PushStaticAddressHtlcSigsResponse + 50, // 70: looprpc.StaticAddressServer.PushStaticAddressSweeplessSigs:output_type -> looprpc.PushStaticAddressSweeplessSigsResponse + 50, // [50:71] is the sub-list for method output_type + 29, // [29:50] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_server_proto_init() } @@ -4263,6 +4791,78 @@ func file_server_proto_init() { return nil } } + file_server_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerStaticAddressLoopInRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerStaticAddressLoopInResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushStaticAddressHtlcSigsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushStaticAddressHtlcSigsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushStaticAddressSweeplessSigsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_server_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushStaticAddressSweeplessSigsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_server_proto_msgTypes[19].OneofWrappers = []interface{}{ (*CancelLoopOutSwapRequest_RouteCancel)(nil), @@ -4273,7 +4873,7 @@ func file_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_server_proto_rawDesc, NumEnums: 6, - NumMessages: 39, + NumMessages: 45, NumExtensions: 0, NumServices: 2, }, diff --git a/swapserverrpc/server.proto b/swapserverrpc/server.proto index dcd434481..6046de28d 100644 --- a/swapserverrpc/server.proto +++ b/swapserverrpc/server.proto @@ -672,6 +672,15 @@ service StaticAddressServer { // the partial sigs for the client's selected deposits. rpc ServerWithdrawDeposits (ServerWithdrawRequest) returns (ServerWithdrawResponse); + + rpc ServerStaticAddressLoopIn (ServerStaticAddressLoopInRequest) + returns (ServerStaticAddressLoopInResponse); + + rpc PushStaticAddressHtlcSigs (PushStaticAddressHtlcSigsRequest) + returns (PushStaticAddressHtlcSigsResponse); + + rpc PushStaticAddressSweeplessSigs (PushStaticAddressSweeplessSigsRequest) + returns (PushStaticAddressSweeplessSigsResponse); } message ServerNewAddressRequest { @@ -715,4 +724,77 @@ message ServerWithdrawResponse { // The nonces that the server used to generate the sweepless sweep sigs. repeated bytes server_nonces = 2; +} + +message ServerStaticAddressLoopInRequest { + // The protocol version that the client adheres to. + StaticAddressProtocolVersion protocol_version = 6; + + bytes htlc_client_key = 1; + + bytes swap_hash = 2; + + repeated string deposit_outpoints = 3; + + string swap_invoice = 4; + + bytes last_hop = 5; + + // The user agent string that identifies the software running on the user's + // side. This can be changed in the user's client software but it _SHOULD_ + // conform to the following pattern: + // Agent-Name/semver-version(/additional-info) + // Examples: + // loopd/v0.10.0-beta/commit=3b635821 + // litd/v0.2.0-alpha/commit=326d754 + string user_agent = 7; +} + +message ServerStaticAddressLoopInResponse { + bytes loop_in_id = 1; + + bytes htlc_server_key = 2; + + int32 htlc_expiry = 3; + + // The nonces that the server used to generate the htlc sigs. + repeated bytes htlc_server_nonces = 4; + + // The fee rate in sat/kw that the server wants to use for the htlc tx. + uint64 htlc_fee_rate = 5; +} + +message PushStaticAddressHtlcSigsRequest { + bytes loop_in_id = 1; + + // The nonces that the client used to generate the htlc sigs. + repeated bytes htlc_client_nonces = 2; + + // The musig2 htlc sigs that the client generated for the htlc. + repeated bytes htlc_client_sigs = 3; +} + +message PushStaticAddressHtlcSigsResponse { + // The nonces that the client used to generate the htlc sigs. + repeated bytes sweepless_server_nonces = 1; + + // The fee rate in sat/kw that the server wants to use for the htlc tx. + uint64 sweepless_fee_rate = 2; + + // The address that the client wants to sweep the static address deposits + // to. + string sweepless_sweep_addr = 3; +} + +message PushStaticAddressSweeplessSigsRequest { + bytes loop_in_id = 1; + + // The nonces that the client used to generate the htlc sigs. + repeated bytes sweepless_client_nonces = 2; + + // The musig2 htlc sigs that the client generated for the htlc. + repeated bytes sweepless_client_sigs = 3; +} + +message PushStaticAddressSweeplessSigsResponse { } \ No newline at end of file diff --git a/swapserverrpc/server_grpc.pb.go b/swapserverrpc/server_grpc.pb.go index 21e6f5c75..0949cc55c 100644 --- a/swapserverrpc/server_grpc.pb.go +++ b/swapserverrpc/server_grpc.pb.go @@ -711,6 +711,9 @@ type StaticAddressServerClient interface { // haven't timed out yet to the client's wallet. The server will generate // the partial sigs for the client's selected deposits. ServerWithdrawDeposits(ctx context.Context, in *ServerWithdrawRequest, opts ...grpc.CallOption) (*ServerWithdrawResponse, error) + ServerStaticAddressLoopIn(ctx context.Context, in *ServerStaticAddressLoopInRequest, opts ...grpc.CallOption) (*ServerStaticAddressLoopInResponse, error) + PushStaticAddressHtlcSigs(ctx context.Context, in *PushStaticAddressHtlcSigsRequest, opts ...grpc.CallOption) (*PushStaticAddressHtlcSigsResponse, error) + PushStaticAddressSweeplessSigs(ctx context.Context, in *PushStaticAddressSweeplessSigsRequest, opts ...grpc.CallOption) (*PushStaticAddressSweeplessSigsResponse, error) } type staticAddressServerClient struct { @@ -739,6 +742,33 @@ func (c *staticAddressServerClient) ServerWithdrawDeposits(ctx context.Context, return out, nil } +func (c *staticAddressServerClient) ServerStaticAddressLoopIn(ctx context.Context, in *ServerStaticAddressLoopInRequest, opts ...grpc.CallOption) (*ServerStaticAddressLoopInResponse, error) { + out := new(ServerStaticAddressLoopInResponse) + err := c.cc.Invoke(ctx, "/looprpc.StaticAddressServer/ServerStaticAddressLoopIn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *staticAddressServerClient) PushStaticAddressHtlcSigs(ctx context.Context, in *PushStaticAddressHtlcSigsRequest, opts ...grpc.CallOption) (*PushStaticAddressHtlcSigsResponse, error) { + out := new(PushStaticAddressHtlcSigsResponse) + err := c.cc.Invoke(ctx, "/looprpc.StaticAddressServer/PushStaticAddressHtlcSigs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *staticAddressServerClient) PushStaticAddressSweeplessSigs(ctx context.Context, in *PushStaticAddressSweeplessSigsRequest, opts ...grpc.CallOption) (*PushStaticAddressSweeplessSigsResponse, error) { + out := new(PushStaticAddressSweeplessSigsResponse) + err := c.cc.Invoke(ctx, "/looprpc.StaticAddressServer/PushStaticAddressSweeplessSigs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // StaticAddressServerServer is the server API for StaticAddressServer service. // All implementations must embed UnimplementedStaticAddressServerServer // for forward compatibility @@ -751,6 +781,9 @@ type StaticAddressServerServer interface { // haven't timed out yet to the client's wallet. The server will generate // the partial sigs for the client's selected deposits. ServerWithdrawDeposits(context.Context, *ServerWithdrawRequest) (*ServerWithdrawResponse, error) + ServerStaticAddressLoopIn(context.Context, *ServerStaticAddressLoopInRequest) (*ServerStaticAddressLoopInResponse, error) + PushStaticAddressHtlcSigs(context.Context, *PushStaticAddressHtlcSigsRequest) (*PushStaticAddressHtlcSigsResponse, error) + PushStaticAddressSweeplessSigs(context.Context, *PushStaticAddressSweeplessSigsRequest) (*PushStaticAddressSweeplessSigsResponse, error) mustEmbedUnimplementedStaticAddressServerServer() } @@ -764,6 +797,15 @@ func (UnimplementedStaticAddressServerServer) ServerNewAddress(context.Context, func (UnimplementedStaticAddressServerServer) ServerWithdrawDeposits(context.Context, *ServerWithdrawRequest) (*ServerWithdrawResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ServerWithdrawDeposits not implemented") } +func (UnimplementedStaticAddressServerServer) ServerStaticAddressLoopIn(context.Context, *ServerStaticAddressLoopInRequest) (*ServerStaticAddressLoopInResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ServerStaticAddressLoopIn not implemented") +} +func (UnimplementedStaticAddressServerServer) PushStaticAddressHtlcSigs(context.Context, *PushStaticAddressHtlcSigsRequest) (*PushStaticAddressHtlcSigsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PushStaticAddressHtlcSigs not implemented") +} +func (UnimplementedStaticAddressServerServer) PushStaticAddressSweeplessSigs(context.Context, *PushStaticAddressSweeplessSigsRequest) (*PushStaticAddressSweeplessSigsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PushStaticAddressSweeplessSigs not implemented") +} func (UnimplementedStaticAddressServerServer) mustEmbedUnimplementedStaticAddressServerServer() {} // UnsafeStaticAddressServerServer may be embedded to opt out of forward compatibility for this service. @@ -813,6 +855,60 @@ func _StaticAddressServer_ServerWithdrawDeposits_Handler(srv interface{}, ctx co return interceptor(ctx, in, info, handler) } +func _StaticAddressServer_ServerStaticAddressLoopIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ServerStaticAddressLoopInRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StaticAddressServerServer).ServerStaticAddressLoopIn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.StaticAddressServer/ServerStaticAddressLoopIn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StaticAddressServerServer).ServerStaticAddressLoopIn(ctx, req.(*ServerStaticAddressLoopInRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StaticAddressServer_PushStaticAddressHtlcSigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PushStaticAddressHtlcSigsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StaticAddressServerServer).PushStaticAddressHtlcSigs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.StaticAddressServer/PushStaticAddressHtlcSigs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StaticAddressServerServer).PushStaticAddressHtlcSigs(ctx, req.(*PushStaticAddressHtlcSigsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _StaticAddressServer_PushStaticAddressSweeplessSigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PushStaticAddressSweeplessSigsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StaticAddressServerServer).PushStaticAddressSweeplessSigs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/looprpc.StaticAddressServer/PushStaticAddressSweeplessSigs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StaticAddressServerServer).PushStaticAddressSweeplessSigs(ctx, req.(*PushStaticAddressSweeplessSigsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // StaticAddressServer_ServiceDesc is the grpc.ServiceDesc for StaticAddressServer service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -828,6 +924,18 @@ var StaticAddressServer_ServiceDesc = grpc.ServiceDesc{ MethodName: "ServerWithdrawDeposits", Handler: _StaticAddressServer_ServerWithdrawDeposits_Handler, }, + { + MethodName: "ServerStaticAddressLoopIn", + Handler: _StaticAddressServer_ServerStaticAddressLoopIn_Handler, + }, + { + MethodName: "PushStaticAddressHtlcSigs", + Handler: _StaticAddressServer_PushStaticAddressHtlcSigs_Handler, + }, + { + MethodName: "PushStaticAddressSweeplessSigs", + Handler: _StaticAddressServer_PushStaticAddressSweeplessSigs_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "server.proto",