Merge pull request #14 from wpaulino/looprpc-rest

looprpc+cmd/loopd: add client REST definitions and REST proxy
pull/15/head
Olaoluwa Osuntokun 5 years ago committed by GitHub
commit 7b769d57bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,11 +14,11 @@ var loopOutCommand = cli.Command{
ArgsUsage: "amt [addr]", ArgsUsage: "amt [addr]",
Description: ` Description: `
Attempts loop out the target amount into either the backing lnd's Attempts loop out the target amount into either the backing lnd's
wallet, or a targeted address. wallet, or a targeted address.
The amount is to be specified in satoshis.
Optionally a BASE58/bech32 encoded bitcoin destination address may be The amount is to be specified in satoshis.
Optionally a BASE58/bech32 encoded bitcoin destination address may be
specified. If not specified, a new wallet address will be generated.`, specified. If not specified, a new wallet address will be generated.`,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.Uint64Flag{ cli.Uint64Flag{
@ -55,12 +55,10 @@ func loopOut(ctx *cli.Context) error {
} }
defer cleanup() defer cleanup()
quote, err := client.GetLoopOutQuote( quoteReq := &looprpc.QuoteRequest{
context.Background(), Amt: int64(amt),
&looprpc.QuoteRequest{ }
Amt: int64(amt), quote, err := client.LoopOutQuote(context.Background(), quoteReq)
},
)
if err != nil { if err != nil {
return err return err
} }

@ -13,7 +13,7 @@ import (
var termsCommand = cli.Command{ var termsCommand = cli.Command{
Name: "terms", Name: "terms",
Usage: "show current server swap terms", Usage: "Display the current swap terms imposed by the server.",
Action: terms, Action: terms,
} }
@ -24,9 +24,8 @@ func terms(ctx *cli.Context) error {
} }
defer cleanup() defer cleanup()
terms, err := client.GetLoopOutTerms( req := &looprpc.TermsRequest{}
context.Background(), &looprpc.TermsRequest{}, terms, err := client.LoopOutTerms(context.Background(), req)
)
if err != nil { if err != nil {
return err return err
} }

@ -12,7 +12,8 @@ type config struct {
Insecure bool `long:"insecure" description:"disable tls"` Insecure bool `long:"insecure" description:"disable tls"`
Network string `long:"network" description:"network to run on" choice:"regtest" choice:"testnet" choice:"mainnet" choice:"simnet"` Network string `long:"network" description:"network to run on" choice:"regtest" choice:"testnet" choice:"mainnet" choice:"simnet"`
SwapServer string `long:"swapserver" description:"swap server address host:port"` SwapServer string `long:"swapserver" description:"swap server address host:port"`
Listen string `long:"listen" description:"address to listen on for rpc lcients"` RPCListen string `long:"rpclisten" description:"Address to listen on for gRPC clients"`
RESTListen string `long:"restlisten" description:"Address to listen on for REST clients"`
Lnd *lndConfig `group:"lnd" namespace:"lnd"` Lnd *lndConfig `group:"lnd" namespace:"lnd"`
@ -22,7 +23,8 @@ type config struct {
var defaultConfig = config{ var defaultConfig = config{
Network: "mainnet", Network: "mainnet",
SwapServer: "swap.lightning.today:11009", SwapServer: "swap.lightning.today:11009",
Listen: "localhost:11010", RPCListen: "localhost:11010",
RESTListen: "localhost:8081",
Insecure: false, Insecure: false,
Lnd: &lndConfig{ Lnd: &lndConfig{
Host: "localhost:10009", Host: "localhost:10009",

@ -4,12 +4,14 @@ import (
"context" "context"
"fmt" "fmt"
"net" "net"
"net/http"
"os" "os"
"os/signal" "os/signal"
"runtime/pprof" "runtime/pprof"
"sync" "sync"
"time" "time"
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/lightninglabs/loop" "github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/looprpc" "github.com/lightninglabs/loop/looprpc"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -59,15 +61,38 @@ func daemon(config *config) error {
grpcServer := grpc.NewServer(serverOpts...) grpcServer := grpc.NewServer(serverOpts...)
looprpc.RegisterSwapClientServer(grpcServer, &server) looprpc.RegisterSwapClientServer(grpcServer, &server)
// Next, Start the gRPC server listening for HTTP/2 connections. // Next, start the gRPC server listening for HTTP/2 connections.
logger.Infof("Starting RPC listener") logger.Infof("Starting gRPC listener")
lis, err := net.Listen("tcp", config.Listen) grpcListener, err := net.Listen("tcp", config.RPCListen)
if err != nil { if err != nil {
return fmt.Errorf("RPC server unable to listen on %s", return fmt.Errorf("RPC server unable to listen on %s",
config.Listen) config.RPCListen)
} }
defer lis.Close() defer grpcListener.Close()
// We'll also create and start an accompanying proxy to serve clients
// through REST.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
mux := proxy.NewServeMux()
proxyOpts := []grpc.DialOption{grpc.WithInsecure()}
err = looprpc.RegisterSwapClientHandlerFromEndpoint(
ctx, mux, config.RPCListen, proxyOpts,
)
if err != nil {
return err
}
logger.Infof("Starting REST proxy listener")
restListener, err := net.Listen("tcp", config.RESTListen)
if err != nil {
return fmt.Errorf("REST proxy unable to listen on %s",
config.RESTListen)
}
defer restListener.Close()
proxy := &http.Server{Handler: mux}
go proxy.Serve(restListener)
statusChan := make(chan loop.SwapInfo) statusChan := make(chan loop.SwapInfo)
@ -124,9 +149,10 @@ func daemon(config *config) error {
go func() { go func() {
defer wg.Done() defer wg.Done()
logger.Infof("RPC server listening on %s", lis.Addr()) logger.Infof("RPC server listening on %s", grpcListener.Addr())
logger.Infof("REST proxy listening on %s", restListener.Addr())
err = grpcServer.Serve(lis) err = grpcServer.Serve(grpcListener)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
} }

@ -208,8 +208,8 @@ func (s *swapClientServer) Monitor(in *looprpc.MonitorRequest,
} }
} }
// GetTerms returns the terms that the server enforces for swaps. // LoopOutTerms returns the terms that the server enforces for loop out swaps.
func (s *swapClientServer) GetLoopOutTerms(ctx context.Context, func (s *swapClientServer) LoopOutTerms(ctx context.Context,
req *looprpc.TermsRequest) (*looprpc.TermsResponse, error) { req *looprpc.TermsRequest) (*looprpc.TermsResponse, error) {
logger.Infof("Terms request received") logger.Infof("Terms request received")
@ -230,8 +230,9 @@ func (s *swapClientServer) GetLoopOutTerms(ctx context.Context,
}, nil }, nil
} }
// GetQuote returns a quote for a swap with the provided parameters. // LoopOutQuote returns a quote for a loop out swap with the provided
func (s *swapClientServer) GetLoopOutQuote(ctx context.Context, // parameters.
func (s *swapClientServer) LoopOutQuote(ctx context.Context,
req *looprpc.QuoteRequest) (*looprpc.QuoteResponse, error) { req *looprpc.QuoteRequest) (*looprpc.QuoteResponse, error) {
quote, err := s.impl.LoopOutQuote(ctx, &loop.LoopOutQuoteRequest{ quote, err := s.impl.LoopOutQuote(ctx, &loop.LoopOutQuoteRequest{

@ -7,6 +7,7 @@ require (
github.com/coreos/bbolt v0.0.0-20180223184059-7ee3ded59d4835e10f3e7d0f7603c42aa5e83820 github.com/coreos/bbolt v0.0.0-20180223184059-7ee3ded59d4835e10f3e7d0f7603c42aa5e83820
github.com/fortytw2/leaktest v1.3.0 github.com/fortytw2/leaktest v1.3.0
github.com/golang/protobuf v1.2.0 github.com/golang/protobuf v1.2.0
github.com/grpc-ecosystem/grpc-gateway v0.0.0-20170724004829-f2862b476edc
github.com/jessevdk/go-flags v0.0.0-20170926144705-f88afde2fa19 github.com/jessevdk/go-flags v0.0.0-20170926144705-f88afde2fa19
github.com/lightningnetwork/lnd v0.0.0 github.com/lightningnetwork/lnd v0.0.0
github.com/urfave/cli v1.20.0 github.com/urfave/cli v1.20.0

@ -6,6 +6,7 @@ package looprpc
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
import _ "google.golang.org/genproto/googleapis/api/annotations"
import ( import (
context "golang.org/x/net/context" context "golang.org/x/net/context"
@ -41,7 +42,7 @@ func (x SwapType) String() string {
return proto.EnumName(SwapType_name, int32(x)) return proto.EnumName(SwapType_name, int32(x))
} }
func (SwapType) EnumDescriptor() ([]byte, []int) { func (SwapType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{0} return fileDescriptor_client_ecf1f0d12250b1cb, []int{0}
} }
type SwapState int32 type SwapState int32
@ -86,7 +87,7 @@ func (x SwapState) String() string {
return proto.EnumName(SwapState_name, int32(x)) return proto.EnumName(SwapState_name, int32(x))
} }
func (SwapState) EnumDescriptor() ([]byte, []int) { func (SwapState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{1} return fileDescriptor_client_ecf1f0d12250b1cb, []int{1}
} }
type LoopOutRequest struct { type LoopOutRequest struct {
@ -144,7 +145,7 @@ func (m *LoopOutRequest) Reset() { *m = LoopOutRequest{} }
func (m *LoopOutRequest) String() string { return proto.CompactTextString(m) } func (m *LoopOutRequest) String() string { return proto.CompactTextString(m) }
func (*LoopOutRequest) ProtoMessage() {} func (*LoopOutRequest) ProtoMessage() {}
func (*LoopOutRequest) Descriptor() ([]byte, []int) { func (*LoopOutRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{0} return fileDescriptor_client_ecf1f0d12250b1cb, []int{0}
} }
func (m *LoopOutRequest) XXX_Unmarshal(b []byte) error { func (m *LoopOutRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LoopOutRequest.Unmarshal(m, b) return xxx_messageInfo_LoopOutRequest.Unmarshal(m, b)
@ -234,7 +235,7 @@ func (m *SwapResponse) Reset() { *m = SwapResponse{} }
func (m *SwapResponse) String() string { return proto.CompactTextString(m) } func (m *SwapResponse) String() string { return proto.CompactTextString(m) }
func (*SwapResponse) ProtoMessage() {} func (*SwapResponse) ProtoMessage() {}
func (*SwapResponse) Descriptor() ([]byte, []int) { func (*SwapResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{1} return fileDescriptor_client_ecf1f0d12250b1cb, []int{1}
} }
func (m *SwapResponse) XXX_Unmarshal(b []byte) error { func (m *SwapResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SwapResponse.Unmarshal(m, b) return xxx_messageInfo_SwapResponse.Unmarshal(m, b)
@ -271,7 +272,7 @@ func (m *MonitorRequest) Reset() { *m = MonitorRequest{} }
func (m *MonitorRequest) String() string { return proto.CompactTextString(m) } func (m *MonitorRequest) String() string { return proto.CompactTextString(m) }
func (*MonitorRequest) ProtoMessage() {} func (*MonitorRequest) ProtoMessage() {}
func (*MonitorRequest) Descriptor() ([]byte, []int) { func (*MonitorRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{2} return fileDescriptor_client_ecf1f0d12250b1cb, []int{2}
} }
func (m *MonitorRequest) XXX_Unmarshal(b []byte) error { func (m *MonitorRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_MonitorRequest.Unmarshal(m, b) return xxx_messageInfo_MonitorRequest.Unmarshal(m, b)
@ -324,7 +325,7 @@ func (m *SwapStatus) Reset() { *m = SwapStatus{} }
func (m *SwapStatus) String() string { return proto.CompactTextString(m) } func (m *SwapStatus) String() string { return proto.CompactTextString(m) }
func (*SwapStatus) ProtoMessage() {} func (*SwapStatus) ProtoMessage() {}
func (*SwapStatus) Descriptor() ([]byte, []int) { func (*SwapStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{3} return fileDescriptor_client_ecf1f0d12250b1cb, []int{3}
} }
func (m *SwapStatus) XXX_Unmarshal(b []byte) error { func (m *SwapStatus) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SwapStatus.Unmarshal(m, b) return xxx_messageInfo_SwapStatus.Unmarshal(m, b)
@ -403,7 +404,7 @@ func (m *TermsRequest) Reset() { *m = TermsRequest{} }
func (m *TermsRequest) String() string { return proto.CompactTextString(m) } func (m *TermsRequest) String() string { return proto.CompactTextString(m) }
func (*TermsRequest) ProtoMessage() {} func (*TermsRequest) ProtoMessage() {}
func (*TermsRequest) Descriptor() ([]byte, []int) { func (*TermsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{4} return fileDescriptor_client_ecf1f0d12250b1cb, []int{4}
} }
func (m *TermsRequest) XXX_Unmarshal(b []byte) error { func (m *TermsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TermsRequest.Unmarshal(m, b) return xxx_messageInfo_TermsRequest.Unmarshal(m, b)
@ -458,7 +459,7 @@ func (m *TermsResponse) Reset() { *m = TermsResponse{} }
func (m *TermsResponse) String() string { return proto.CompactTextString(m) } func (m *TermsResponse) String() string { return proto.CompactTextString(m) }
func (*TermsResponse) ProtoMessage() {} func (*TermsResponse) ProtoMessage() {}
func (*TermsResponse) Descriptor() ([]byte, []int) { func (*TermsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{5} return fileDescriptor_client_ecf1f0d12250b1cb, []int{5}
} }
func (m *TermsResponse) XXX_Unmarshal(b []byte) error { func (m *TermsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TermsResponse.Unmarshal(m, b) return xxx_messageInfo_TermsResponse.Unmarshal(m, b)
@ -536,7 +537,7 @@ func (m *TermsResponse) GetMaxCltv() int32 {
type QuoteRequest struct { type QuoteRequest struct {
// * // *
// Requested swap amount in sat. // The amount to swap in satoshis.
Amt int64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"` Amt int64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -547,7 +548,7 @@ func (m *QuoteRequest) Reset() { *m = QuoteRequest{} }
func (m *QuoteRequest) String() string { return proto.CompactTextString(m) } func (m *QuoteRequest) String() string { return proto.CompactTextString(m) }
func (*QuoteRequest) ProtoMessage() {} func (*QuoteRequest) ProtoMessage() {}
func (*QuoteRequest) Descriptor() ([]byte, []int) { func (*QuoteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{6} return fileDescriptor_client_ecf1f0d12250b1cb, []int{6}
} }
func (m *QuoteRequest) XXX_Unmarshal(b []byte) error { func (m *QuoteRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QuoteRequest.Unmarshal(m, b) return xxx_messageInfo_QuoteRequest.Unmarshal(m, b)
@ -579,12 +580,10 @@ type QuoteResponse struct {
// The fee that the swap server is charging for the swap. // The fee that the swap server is charging for the swap.
SwapFee int64 `protobuf:"varint,1,opt,name=swap_fee,json=swapFee,proto3" json:"swap_fee,omitempty"` SwapFee int64 `protobuf:"varint,1,opt,name=swap_fee,json=swapFee,proto3" json:"swap_fee,omitempty"`
// * // *
// The part of the swap fee that is requested as a // The part of the swap fee that is requested as a prepayment.
// prepayment.
PrepayAmt int64 `protobuf:"varint,2,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"` PrepayAmt int64 `protobuf:"varint,2,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"`
// * // *
// An estimate of the on-chain fee that needs to be paid to // An estimate of the on-chain fee that needs to be paid to sweep the HTLC.
// sweep the htlc.
MinerFee int64 `protobuf:"varint,3,opt,name=miner_fee,json=minerFee,proto3" json:"miner_fee,omitempty"` MinerFee int64 `protobuf:"varint,3,opt,name=miner_fee,json=minerFee,proto3" json:"miner_fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -595,7 +594,7 @@ func (m *QuoteResponse) Reset() { *m = QuoteResponse{} }
func (m *QuoteResponse) String() string { return proto.CompactTextString(m) } func (m *QuoteResponse) String() string { return proto.CompactTextString(m) }
func (*QuoteResponse) ProtoMessage() {} func (*QuoteResponse) ProtoMessage() {}
func (*QuoteResponse) Descriptor() ([]byte, []int) { func (*QuoteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_client_e8e8b003a83cbb2b, []int{7} return fileDescriptor_client_ecf1f0d12250b1cb, []int{7}
} }
func (m *QuoteResponse) XXX_Unmarshal(b []byte) error { func (m *QuoteResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QuoteResponse.Unmarshal(m, b) return xxx_messageInfo_QuoteResponse.Unmarshal(m, b)
@ -661,21 +660,23 @@ const _ = grpc.SupportPackageIsVersion4
// //
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type SwapClientClient interface { type SwapClientClient interface {
// * // * loop: `out`
// LoopOut initiates an loop out swap with the given parameters. The call // LoopOut initiates an loop out swap with the given parameters. The call
// returns after the swap has been set up with the swap server. From that // returns after the swap has been set up with the swap server. From that
// point onwards, progress can be tracked via the SwapStatus stream that is // point onwards, progress can be tracked via the SwapStatus stream that is
// returned from Monitor(). // returned from Monitor().
LoopOut(ctx context.Context, in *LoopOutRequest, opts ...grpc.CallOption) (*SwapResponse, error) LoopOut(ctx context.Context, in *LoopOutRequest, opts ...grpc.CallOption) (*SwapResponse, error)
// * // * loop: `monitor`
// Monitor will return a stream of swap updates for currently active swaps. // Monitor will return a stream of swap updates for currently active swaps.
// TODO: add MonitorSync version for REST clients.
Monitor(ctx context.Context, in *MonitorRequest, opts ...grpc.CallOption) (SwapClient_MonitorClient, error) Monitor(ctx context.Context, in *MonitorRequest, opts ...grpc.CallOption) (SwapClient_MonitorClient, error)
// * // * loop: `terms`
// GetLoopOutTerms returns the terms that the server enforces for swaps. // LoopOutTerms returns the terms that the server enforces for a loop out swap.
GetLoopOutTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error) LoopOutTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error)
// * // * loop: `quote`
// GetLoopOutQuote returns a quote for a swap with the provided parameters. // LoopOutQuote returns a quote for a loop out swap with the provided
GetLoopOutQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error) // parameters.
LoopOutQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error)
} }
type swapClientClient struct { type swapClientClient struct {
@ -727,18 +728,18 @@ func (x *swapClientMonitorClient) Recv() (*SwapStatus, error) {
return m, nil return m, nil
} }
func (c *swapClientClient) GetLoopOutTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error) { func (c *swapClientClient) LoopOutTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error) {
out := new(TermsResponse) out := new(TermsResponse)
err := c.cc.Invoke(ctx, "/looprpc.SwapClient/GetLoopOutTerms", in, out, opts...) err := c.cc.Invoke(ctx, "/looprpc.SwapClient/LoopOutTerms", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *swapClientClient) GetLoopOutQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error) { func (c *swapClientClient) LoopOutQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error) {
out := new(QuoteResponse) out := new(QuoteResponse)
err := c.cc.Invoke(ctx, "/looprpc.SwapClient/GetLoopOutQuote", in, out, opts...) err := c.cc.Invoke(ctx, "/looprpc.SwapClient/LoopOutQuote", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -747,21 +748,23 @@ func (c *swapClientClient) GetLoopOutQuote(ctx context.Context, in *QuoteRequest
// SwapClientServer is the server API for SwapClient service. // SwapClientServer is the server API for SwapClient service.
type SwapClientServer interface { type SwapClientServer interface {
// * // * loop: `out`
// LoopOut initiates an loop out swap with the given parameters. The call // LoopOut initiates an loop out swap with the given parameters. The call
// returns after the swap has been set up with the swap server. From that // returns after the swap has been set up with the swap server. From that
// point onwards, progress can be tracked via the SwapStatus stream that is // point onwards, progress can be tracked via the SwapStatus stream that is
// returned from Monitor(). // returned from Monitor().
LoopOut(context.Context, *LoopOutRequest) (*SwapResponse, error) LoopOut(context.Context, *LoopOutRequest) (*SwapResponse, error)
// * // * loop: `monitor`
// Monitor will return a stream of swap updates for currently active swaps. // Monitor will return a stream of swap updates for currently active swaps.
// TODO: add MonitorSync version for REST clients.
Monitor(*MonitorRequest, SwapClient_MonitorServer) error Monitor(*MonitorRequest, SwapClient_MonitorServer) error
// * // * loop: `terms`
// GetLoopOutTerms returns the terms that the server enforces for swaps. // LoopOutTerms returns the terms that the server enforces for a loop out swap.
GetLoopOutTerms(context.Context, *TermsRequest) (*TermsResponse, error) LoopOutTerms(context.Context, *TermsRequest) (*TermsResponse, error)
// * // * loop: `quote`
// GetLoopOutQuote returns a quote for a swap with the provided parameters. // LoopOutQuote returns a quote for a loop out swap with the provided
GetLoopOutQuote(context.Context, *QuoteRequest) (*QuoteResponse, error) // parameters.
LoopOutQuote(context.Context, *QuoteRequest) (*QuoteResponse, error)
} }
func RegisterSwapClientServer(s *grpc.Server, srv SwapClientServer) { func RegisterSwapClientServer(s *grpc.Server, srv SwapClientServer) {
@ -807,38 +810,38 @@ func (x *swapClientMonitorServer) Send(m *SwapStatus) error {
return x.ServerStream.SendMsg(m) return x.ServerStream.SendMsg(m)
} }
func _SwapClient_GetLoopOutTerms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SwapClient_LoopOutTerms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TermsRequest) in := new(TermsRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SwapClientServer).GetLoopOutTerms(ctx, in) return srv.(SwapClientServer).LoopOutTerms(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/looprpc.SwapClient/GetLoopOutTerms", FullMethod: "/looprpc.SwapClient/LoopOutTerms",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SwapClientServer).GetLoopOutTerms(ctx, req.(*TermsRequest)) return srv.(SwapClientServer).LoopOutTerms(ctx, req.(*TermsRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SwapClient_GetLoopOutQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SwapClient_LoopOutQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QuoteRequest) in := new(QuoteRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SwapClientServer).GetLoopOutQuote(ctx, in) return srv.(SwapClientServer).LoopOutQuote(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/looprpc.SwapClient/GetLoopOutQuote", FullMethod: "/looprpc.SwapClient/LoopOutQuote",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SwapClientServer).GetLoopOutQuote(ctx, req.(*QuoteRequest)) return srv.(SwapClientServer).LoopOutQuote(ctx, req.(*QuoteRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
@ -852,12 +855,12 @@ var _SwapClient_serviceDesc = grpc.ServiceDesc{
Handler: _SwapClient_LoopOut_Handler, Handler: _SwapClient_LoopOut_Handler,
}, },
{ {
MethodName: "GetLoopOutTerms", MethodName: "LoopOutTerms",
Handler: _SwapClient_GetLoopOutTerms_Handler, Handler: _SwapClient_LoopOutTerms_Handler,
}, },
{ {
MethodName: "GetLoopOutQuote", MethodName: "LoopOutQuote",
Handler: _SwapClient_GetLoopOutQuote_Handler, Handler: _SwapClient_LoopOutQuote_Handler,
}, },
}, },
Streams: []grpc.StreamDesc{ Streams: []grpc.StreamDesc{
@ -870,55 +873,60 @@ var _SwapClient_serviceDesc = grpc.ServiceDesc{
Metadata: "client.proto", Metadata: "client.proto",
} }
func init() { proto.RegisterFile("client.proto", fileDescriptor_client_e8e8b003a83cbb2b) } func init() { proto.RegisterFile("client.proto", fileDescriptor_client_ecf1f0d12250b1cb) }
var fileDescriptor_client_e8e8b003a83cbb2b = []byte{ var fileDescriptor_client_ecf1f0d12250b1cb = []byte{
// 749 bytes of a gzipped FileDescriptorProto // 825 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xcf, 0x72, 0xda, 0x3a, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xcb, 0x72, 0xe3, 0x44,
0x14, 0xc6, 0x83, 0xf9, 0xeb, 0x83, 0x31, 0xa0, 0xdc, 0xe4, 0x92, 0xdc, 0xc9, 0x1d, 0xae, 0xe7, 0x14, 0x1d, 0xc9, 0x4e, 0x6c, 0xdd, 0xc8, 0x8a, 0xdd, 0xf3, 0xf2, 0x18, 0x86, 0x32, 0x2a, 0x1e,
0xb6, 0x65, 0xb2, 0x48, 0x3b, 0xc9, 0x2a, 0xbb, 0x52, 0x20, 0x19, 0x3a, 0x49, 0xa1, 0x86, 0x74, 0xae, 0x2c, 0x22, 0xc8, 0xac, 0x60, 0x67, 0x1c, 0x0f, 0x65, 0x2a, 0x21, 0xa6, 0xed, 0x50, 0xc5,
0xeb, 0x51, 0x40, 0x69, 0x3c, 0x63, 0xd9, 0xae, 0x25, 0x27, 0xf0, 0x02, 0x7d, 0x9a, 0xae, 0xfa, 0x4a, 0xd5, 0x63, 0xf7, 0x64, 0x54, 0xa5, 0x56, 0x6b, 0xd4, 0xad, 0x8c, 0x5d, 0x14, 0x1b, 0x7e,
0x6e, 0xdd, 0x77, 0xf4, 0x07, 0x62, 0xa7, 0xed, 0xce, 0xf3, 0xe9, 0x3b, 0x47, 0xd6, 0x4f, 0xdf, 0x81, 0xdf, 0x60, 0xc5, 0xaf, 0xb0, 0xe0, 0x07, 0xf8, 0x05, 0xf6, 0x54, 0x3f, 0xec, 0x48, 0x81,
0x11, 0x58, 0x8b, 0xc0, 0x27, 0x21, 0x3f, 0x89, 0x93, 0x88, 0x47, 0xa8, 0x1a, 0x44, 0x51, 0x9c, 0xd9, 0x75, 0x9d, 0x3e, 0xf7, 0x74, 0xf7, 0xb9, 0xe7, 0x36, 0xf8, 0xab, 0x34, 0xa1, 0x99, 0x3c,
0xc4, 0x0b, 0xe7, 0xbb, 0x01, 0xf6, 0x55, 0x14, 0xc5, 0x93, 0x94, 0xbb, 0xe4, 0x4b, 0x4a, 0x18, 0xcd, 0x0b, 0x2e, 0x39, 0x6a, 0xa5, 0x9c, 0xe7, 0x45, 0xbe, 0x1a, 0x7c, 0x78, 0xc3, 0xf9, 0x4d,
0x47, 0x2d, 0x28, 0x62, 0xca, 0x3b, 0x85, 0x6e, 0xa1, 0x57, 0x74, 0xc5, 0x27, 0x42, 0x50, 0x5a, 0x4a, 0x23, 0x92, 0x27, 0x11, 0xc9, 0x32, 0x2e, 0x89, 0x4c, 0x78, 0x26, 0x0c, 0x2d, 0xfc, 0xc3,
0x12, 0xc6, 0x3b, 0x46, 0xb7, 0xd0, 0x33, 0x5d, 0xf9, 0x8d, 0x5e, 0xc3, 0x5f, 0x14, 0xaf, 0x3c, 0x85, 0xe0, 0x82, 0xf3, 0xfc, 0xaa, 0x94, 0x98, 0xbe, 0x2d, 0xa9, 0x90, 0xa8, 0x0b, 0x0d, 0xc2,
0xf6, 0x88, 0x63, 0x2f, 0x89, 0x52, 0xee, 0x87, 0x9f, 0xbd, 0x3b, 0x42, 0x3a, 0x45, 0x59, 0xd6, 0x64, 0xdf, 0x19, 0x3a, 0xa3, 0x06, 0x56, 0x4b, 0x84, 0xa0, 0xb9, 0xa6, 0x42, 0xf6, 0xdd, 0xa1,
0xa6, 0x78, 0x35, 0x7b, 0xc4, 0xb1, 0xab, 0x56, 0x2e, 0x08, 0x41, 0x67, 0xb0, 0x2f, 0x0a, 0xe2, 0x33, 0xf2, 0xb0, 0x5e, 0xa3, 0x08, 0x1e, 0x31, 0xb2, 0x89, 0xc5, 0x3b, 0x92, 0xc7, 0x05, 0x2f,
0x84, 0xc4, 0x78, 0x9d, 0x2b, 0x29, 0xc9, 0x92, 0x5d, 0x8a, 0x57, 0x53, 0xb9, 0x98, 0x29, 0xea, 0x65, 0x92, 0xdd, 0xc4, 0xaf, 0x29, 0xed, 0x37, 0x74, 0x59, 0x8f, 0x91, 0xcd, 0xe2, 0x1d, 0xc9,
0x82, 0xb5, 0xdd, 0x45, 0x58, 0xcb, 0xd2, 0x0a, 0xba, 0xbb, 0x70, 0xfc, 0x0f, 0x76, 0xa6, 0xad, 0xb1, 0xd9, 0x79, 0x49, 0x29, 0x7a, 0x01, 0x4f, 0x54, 0x41, 0x5e, 0xd0, 0x9c, 0x6c, 0x6b, 0x25,
0xf8, 0xf1, 0x8a, 0xf4, 0x58, 0xdb, 0x76, 0x7d, 0xca, 0x91, 0x03, 0x0d, 0xe1, 0xa2, 0x7e, 0x48, 0x4d, 0x5d, 0xf2, 0x90, 0x91, 0xcd, 0x5c, 0x6f, 0x56, 0x8a, 0x86, 0xe0, 0xef, 0x4f, 0x51, 0xd4,
0x12, 0xd9, 0xa8, 0x2a, 0x4d, 0x75, 0x8a, 0x57, 0xd7, 0x42, 0x13, 0x9d, 0x7a, 0xd0, 0x12, 0x54, 0x03, 0x4d, 0x05, 0xab, 0xae, 0x18, 0x9f, 0x40, 0x50, 0x91, 0x55, 0x17, 0x3f, 0xd4, 0x1c, 0x7f,
0xbc, 0x28, 0xe5, 0xde, 0xe2, 0x1e, 0x87, 0x21, 0x09, 0x3a, 0xb5, 0x6e, 0xa1, 0x57, 0x72, 0xed, 0x2f, 0x37, 0x66, 0x12, 0x85, 0xd0, 0x51, 0x2c, 0x96, 0x64, 0xb4, 0xd0, 0x42, 0x2d, 0x4d, 0x3a,
0x40, 0x11, 0x1a, 0x28, 0xd5, 0xf9, 0x17, 0x2c, 0x79, 0x38, 0xc2, 0xe2, 0x28, 0x64, 0x04, 0xd9, 0x62, 0x64, 0x73, 0xa9, 0x30, 0xa5, 0x34, 0x82, 0xae, 0xf2, 0x2c, 0xe6, 0xa5, 0x8c, 0x57, 0x6f,
0x60, 0xf8, 0x4b, 0x09, 0xcc, 0x74, 0x0d, 0x7f, 0xe9, 0xb4, 0xc0, 0xbe, 0x8e, 0x42, 0x9f, 0x47, 0x48, 0x96, 0xd1, 0xb4, 0xdf, 0x1e, 0x3a, 0xa3, 0x26, 0x0e, 0x52, 0xe3, 0xd0, 0xc4, 0xa0, 0xe1,
0x89, 0x66, 0xea, 0xfc, 0x28, 0x00, 0x88, 0x92, 0x19, 0xc7, 0x3c, 0x65, 0xbf, 0x41, 0xac, 0x5a, 0x47, 0xe0, 0xeb, 0xc7, 0x51, 0x91, 0xf3, 0x4c, 0x50, 0x14, 0x80, 0x9b, 0xac, 0xb5, 0x61, 0x1e,
0x18, 0x9b, 0x16, 0xe8, 0x05, 0x94, 0xf8, 0x3a, 0x56, 0x38, 0xed, 0xd3, 0xf6, 0x89, 0xbe, 0xaf, 0x76, 0x93, 0x75, 0xd8, 0x85, 0xe0, 0x92, 0x67, 0x89, 0xe4, 0x85, 0xf5, 0x34, 0xfc, 0xc7, 0x01,
0x13, 0xd1, 0x64, 0xbe, 0x8e, 0x89, 0x2b, 0x97, 0x51, 0x0f, 0xca, 0x8c, 0x63, 0xae, 0x18, 0xda, 0x50, 0x25, 0x0b, 0x49, 0x64, 0x29, 0xfe, 0xc7, 0x62, 0x23, 0xe1, 0xee, 0x24, 0xd0, 0xa7, 0xd0,
0xa7, 0x28, 0xe7, 0x13, 0x9b, 0x11, 0x57, 0x19, 0xd0, 0x2b, 0x68, 0xfa, 0xa1, 0xcf, 0x7d, 0xcc, 0x94, 0xdb, 0xdc, 0xd8, 0x19, 0x9c, 0xf5, 0x4e, 0x6d, 0x37, 0x4f, 0x95, 0xc8, 0x72, 0x9b, 0x53,
0xfd, 0x28, 0xf4, 0xb8, 0x4f, 0x37, 0x30, 0xed, 0x27, 0x79, 0xee, 0x53, 0x85, 0x01, 0x33, 0xee, 0xac, 0xb7, 0xd1, 0x08, 0x0e, 0x84, 0x24, 0xd2, 0x78, 0x18, 0x9c, 0xa1, 0x1a, 0x4f, 0x1d, 0x46,
0xa5, 0xf1, 0x12, 0x73, 0xa2, 0x9c, 0x0a, 0xa9, 0x2d, 0xf4, 0x1b, 0x29, 0x4b, 0xe7, 0x7f, 0x60, 0xb1, 0x21, 0xa0, 0xcf, 0xe1, 0x38, 0xc9, 0x12, 0x99, 0xe8, 0xee, 0xc7, 0x32, 0x61, 0x3b, 0x33,
0xdd, 0xf3, 0x60, 0xe1, 0xe1, 0xe5, 0x32, 0x21, 0x8c, 0x49, 0xa6, 0xa6, 0x5b, 0x17, 0x5a, 0x5f, 0x83, 0x3b, 0x78, 0x99, 0x30, 0x63, 0x03, 0x11, 0x32, 0x2e, 0xf3, 0x35, 0x91, 0xd4, 0x30, 0x8d,
0x49, 0x8e, 0x0d, 0xd6, 0x9c, 0x24, 0x94, 0x6d, 0x38, 0x7c, 0x33, 0xa0, 0xa1, 0x05, 0xcd, 0xee, 0xa5, 0x81, 0xc2, 0xaf, 0x35, 0xac, 0x99, 0x1f, 0x83, 0xff, 0x46, 0xa6, 0xab, 0x98, 0xac, 0xd7,
0x18, 0xda, 0xf2, 0x76, 0x63, 0xbc, 0xa6, 0x24, 0xe4, 0x9e, 0x0c, 0x9a, 0x42, 0xd9, 0x14, 0x0b, 0x05, 0x15, 0x42, 0x7b, 0xea, 0xe1, 0x23, 0x85, 0x8d, 0x0d, 0x14, 0x06, 0xe0, 0x2f, 0x69, 0xc1,
0x53, 0xa5, 0x0f, 0x45, 0xe6, 0x1c, 0x68, 0x6c, 0x92, 0xe0, 0xdd, 0x62, 0x46, 0x24, 0xaf, 0xa2, 0xc4, 0xce, 0x87, 0xdf, 0x5d, 0xe8, 0x58, 0xc0, 0x7a, 0x77, 0x02, 0x3d, 0xdd, 0xdd, 0x9c, 0x6c,
0x5b, 0x67, 0x2a, 0x0b, 0xef, 0x30, 0x23, 0x39, 0x4f, 0x22, 0xc8, 0x14, 0x73, 0x1e, 0x57, 0xb0, 0x19, 0xcd, 0x64, 0xac, 0x83, 0x66, 0xac, 0x3c, 0x56, 0x1b, 0x73, 0x83, 0x9f, 0xab, 0xcc, 0x85,
0x38, 0x02, 0xc8, 0xe4, 0x45, 0xc5, 0xcf, 0x8c, 0xb7, 0x61, 0x79, 0x09, 0x4d, 0xea, 0x87, 0x2a, 0xd0, 0xd9, 0x25, 0x21, 0x7e, 0x45, 0x04, 0xd5, 0x7e, 0x35, 0xf0, 0x91, 0x30, 0x59, 0xf8, 0x86,
0x74, 0x98, 0x46, 0x69, 0xc8, 0x35, 0xaa, 0x06, 0xf5, 0x43, 0x01, 0xb6, 0x2f, 0x45, 0xe9, 0xdb, 0x08, 0x5a, 0xe3, 0x14, 0xca, 0x99, 0x46, 0x8d, 0x83, 0x95, 0x17, 0xcf, 0x01, 0x2a, 0x79, 0x31,
0x84, 0x53, 0xfb, 0x2a, 0xda, 0xa7, 0xf2, 0xa9, 0x7d, 0x47, 0x00, 0x8b, 0x80, 0x3f, 0x78, 0x4b, 0xf1, 0xf3, 0xf2, 0x7d, 0x58, 0x3e, 0x83, 0x63, 0x96, 0x64, 0x26, 0x74, 0x84, 0xf1, 0x32, 0x93,
0x12, 0x70, 0x2c, 0x29, 0x95, 0x5d, 0x53, 0x28, 0x43, 0x21, 0xa0, 0x03, 0xa8, 0x89, 0x36, 0x42, 0xd6, 0xaa, 0x0e, 0x4b, 0x32, 0x65, 0xec, 0x58, 0x83, 0x9a, 0xb7, 0x0b, 0xa7, 0xe5, 0x1d, 0x5a,
0x90, 0x79, 0x2b, 0xbb, 0x55, 0x8a, 0x57, 0x83, 0x80, 0x3f, 0x38, 0x5d, 0xb0, 0x3e, 0xa6, 0x11, 0x9e, 0xc9, 0xa7, 0xe5, 0x3d, 0x07, 0x58, 0xa5, 0xf2, 0x36, 0x5e, 0xd3, 0x54, 0x12, 0xed, 0xd2,
0x27, 0x7f, 0x1c, 0x4d, 0xe7, 0x0e, 0x1a, 0xda, 0xa1, 0x79, 0x1e, 0x40, 0x6d, 0x3b, 0x2d, 0xca, 0x01, 0xf6, 0x14, 0x72, 0xae, 0x00, 0xf4, 0x0c, 0xda, 0x4a, 0x46, 0x01, 0x3a, 0x6f, 0x07, 0xb8,
0x57, 0xd5, 0x47, 0x7f, 0x76, 0x6c, 0xe3, 0xf9, 0xb1, 0xff, 0x01, 0xf3, 0x69, 0x3e, 0x14, 0xb5, 0xc5, 0xc8, 0x66, 0x92, 0xca, 0xdb, 0x70, 0x08, 0xfe, 0x0f, 0x25, 0x97, 0xf4, 0xbd, 0xa3, 0x19,
0x1a, 0xd5, 0xc3, 0x71, 0xdc, 0x81, 0xda, 0x26, 0x7a, 0xc8, 0x82, 0xda, 0xd5, 0x64, 0x32, 0xf5, 0xbe, 0x86, 0x8e, 0x65, 0x58, 0x3f, 0x9f, 0x41, 0x7b, 0x3f, 0x2d, 0x86, 0xd7, 0xb2, 0x4f, 0xbf,
0x26, 0x37, 0xf3, 0xd6, 0xce, 0xf1, 0x7b, 0x30, 0xb7, 0x61, 0x43, 0x0d, 0x30, 0xc7, 0x1f, 0xc6, 0xf7, 0x6c, 0xf7, 0xfe, 0xb3, 0x3f, 0x00, 0xef, 0x6e, 0x3e, 0x8c, 0x6b, 0x6d, 0x66, 0x87, 0xe3,
0xf3, 0x71, 0x7f, 0x3e, 0x1a, 0xb6, 0x76, 0xd0, 0x1e, 0xb4, 0xa7, 0xee, 0x68, 0x7c, 0xdd, 0xbf, 0xa4, 0x0f, 0xed, 0x5d, 0xf4, 0x90, 0x0f, 0xed, 0x8b, 0xab, 0xab, 0x79, 0x7c, 0x75, 0xbd, 0xec,
0x1c, 0x79, 0xee, 0xe8, 0xd3, 0xa8, 0x7f, 0x35, 0x1a, 0xb6, 0x0a, 0xa8, 0x0e, 0xd5, 0xd9, 0xcd, 0x3e, 0x38, 0xf9, 0x0e, 0xbc, 0x7d, 0xd8, 0x50, 0x07, 0xbc, 0xd9, 0xf7, 0xb3, 0xe5, 0x6c, 0xbc,
0x60, 0x30, 0x9a, 0xcd, 0x5a, 0x45, 0x04, 0x50, 0xb9, 0xe8, 0x8f, 0xc5, 0x42, 0xe9, 0xf4, 0xab, 0x9c, 0x9e, 0x77, 0x1f, 0xa0, 0xc7, 0xd0, 0x9b, 0xe3, 0xe9, 0xec, 0x72, 0xfc, 0xed, 0x34, 0xc6,
0xa1, 0xc6, 0x64, 0x20, 0xdf, 0x2a, 0x74, 0x0e, 0x55, 0xfd, 0x36, 0xa1, 0xbf, 0xb7, 0xc9, 0xce, 0xd3, 0x1f, 0xa7, 0xe3, 0x8b, 0xe9, 0x79, 0xd7, 0x41, 0x47, 0xd0, 0x5a, 0x5c, 0x4f, 0x26, 0xd3,
0xbf, 0x56, 0x87, 0x7b, 0xb9, 0xc8, 0x6f, 0x31, 0x9c, 0x43, 0x55, 0x8f, 0x60, 0xa6, 0x34, 0x3f, 0xc5, 0xa2, 0xdb, 0x40, 0x00, 0x87, 0x2f, 0xc7, 0x33, 0xb5, 0xd1, 0x3c, 0xfb, 0xcb, 0x35, 0x63,
0x94, 0x87, 0xbb, 0xbf, 0x4c, 0x4b, 0xca, 0xde, 0x14, 0xd0, 0x5b, 0x68, 0x5e, 0x12, 0xae, 0xb7, 0x32, 0xd1, 0x3f, 0x19, 0xc2, 0xd0, 0xb2, 0x7f, 0x13, 0x7a, 0xba, 0x4f, 0x76, 0xfd, 0xb7, 0x1a,
0x91, 0x61, 0x45, 0x4f, 0x9b, 0x64, 0xd3, 0x7c, 0xb8, 0xff, 0x5c, 0xd6, 0x9b, 0xe7, 0x3a, 0xc8, 0x3c, 0xae, 0x45, 0x7e, 0x67, 0x43, 0xf8, 0xf4, 0xd7, 0x3f, 0xff, 0xfe, 0xcd, 0xed, 0x85, 0x7e,
0xeb, 0xc9, 0x74, 0xc8, 0x5e, 0x68, 0xa6, 0x43, 0xee, 0x16, 0x6f, 0x2b, 0xf2, 0x99, 0x3e, 0xfb, 0x74, 0xfb, 0x65, 0xa4, 0x18, 0x11, 0x2f, 0xe5, 0xd7, 0xce, 0x09, 0xfa, 0x0a, 0x5a, 0x76, 0x36,
0x19, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x15, 0xc0, 0x11, 0xb6, 0x05, 0x00, 0x00, 0x2b, 0x9a, 0xf5, 0x69, 0x1d, 0x3c, 0xfc, 0xcf, 0x18, 0x95, 0xe2, 0x0b, 0x07, 0xfd, 0x04, 0xbe,
0x3d, 0x5c, 0x47, 0x18, 0xdd, 0x1d, 0x5d, 0xcd, 0xf8, 0xe0, 0xc9, 0x7d, 0xd8, 0x5e, 0x69, 0xa0,
0xaf, 0xf4, 0x08, 0xa1, 0xea, 0x95, 0x22, 0xa9, 0xa5, 0xe2, 0xbd, 0xb4, 0xee, 0x66, 0x45, 0xba,
0xda, 0xff, 0x8a, 0x74, 0xad, 0xe9, 0xe1, 0x50, 0x4b, 0x0f, 0x50, 0xbf, 0x26, 0xfd, 0x56, 0x71,
0xa2, 0x9f, 0x09, 0x93, 0xbf, 0xbc, 0x3a, 0xd4, 0xdf, 0xfd, 0x8b, 0x7f, 0x03, 0x00, 0x00, 0xff,
0xff, 0x2d, 0xba, 0xce, 0x65, 0x25, 0x06, 0x00, 0x00,
} }

@ -0,0 +1,214 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: client.proto
/*
Package looprpc is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package looprpc
import (
"io"
"net/http"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
func request_SwapClient_LoopOut_0(ctx context.Context, marshaler runtime.Marshaler, client SwapClientClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq LoopOutRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.LoopOut(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func request_SwapClient_LoopOutTerms_0(ctx context.Context, marshaler runtime.Marshaler, client SwapClientClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TermsRequest
var metadata runtime.ServerMetadata
msg, err := client.LoopOutTerms(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func request_SwapClient_LoopOutQuote_0(ctx context.Context, marshaler runtime.Marshaler, client SwapClientClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QuoteRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["amt"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "amt")
}
protoReq.Amt, err = runtime.Int64(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "amt", err)
}
msg, err := client.LoopOutQuote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
// RegisterSwapClientHandlerFromEndpoint is same as RegisterSwapClientHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterSwapClientHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterSwapClientHandler(ctx, mux, conn)
}
// RegisterSwapClientHandler registers the http handlers for service SwapClient to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterSwapClientHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
client := NewSwapClientClient(conn)
mux.Handle("POST", pattern_SwapClient_LoopOut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_SwapClient_LoopOut_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_SwapClient_LoopOut_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_SwapClient_LoopOutTerms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_SwapClient_LoopOutTerms_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_SwapClient_LoopOutTerms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_SwapClient_LoopOutQuote_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_SwapClient_LoopOutQuote_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_SwapClient_LoopOutQuote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_SwapClient_LoopOut_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "loop", "out"}, ""))
pattern_SwapClient_LoopOutTerms_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "loop", "out", "terms"}, ""))
pattern_SwapClient_LoopOutQuote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "loop", "out", "quote", "amt"}, ""))
)
var (
forward_SwapClient_LoopOut_0 = runtime.ForwardResponseMessage
forward_SwapClient_LoopOutTerms_0 = runtime.ForwardResponseMessage
forward_SwapClient_LoopOutQuote_0 = runtime.ForwardResponseMessage
)

@ -1,5 +1,7 @@
syntax = "proto3"; syntax = "proto3";
import "google/api/annotations.proto";
package looprpc; package looprpc;
/** /**
@ -7,28 +9,43 @@ SwapClient is a service that handles the client side process of onchain/offchain
swaps. The service is designed for a single client. swaps. The service is designed for a single client.
*/ */
service SwapClient { service SwapClient {
/** /** loop: `out`
LoopOut initiates an loop out swap with the given parameters. The call LoopOut initiates an loop out swap with the given parameters. The call
returns after the swap has been set up with the swap server. From that returns after the swap has been set up with the swap server. From that
point onwards, progress can be tracked via the SwapStatus stream that is point onwards, progress can be tracked via the SwapStatus stream that is
returned from Monitor(). returned from Monitor().
*/ */
rpc LoopOut(LoopOutRequest) returns (SwapResponse); rpc LoopOut(LoopOutRequest) returns (SwapResponse) {
option (google.api.http) = {
/** post: "/v1/loop/out"
body: "*"
};
}
/** loop: `monitor`
Monitor will return a stream of swap updates for currently active swaps. Monitor will return a stream of swap updates for currently active swaps.
TODO: add MonitorSync version for REST clients.
*/ */
rpc Monitor(MonitorRequest) returns(stream SwapStatus); rpc Monitor(MonitorRequest) returns(stream SwapStatus);
/** /** loop: `terms`
GetLoopOutTerms returns the terms that the server enforces for swaps. LoopOutTerms returns the terms that the server enforces for a loop out swap.
*/ */
rpc GetLoopOutTerms(TermsRequest) returns(TermsResponse); rpc LoopOutTerms(TermsRequest) returns(TermsResponse) {
option (google.api.http) = {
get: "/v1/loop/out/terms"
};
}
/** /** loop: `quote`
GetLoopOutQuote returns a quote for a swap with the provided parameters. LoopOutQuote returns a quote for a loop out swap with the provided
parameters.
*/ */
rpc GetLoopOutQuote(QuoteRequest) returns(QuoteResponse); rpc LoopOutQuote(QuoteRequest) returns(QuoteResponse) {
option (google.api.http) = {
get: "/v1/loop/out/quote/{amt}"
};
}
} }
message LoopOutRequest { message LoopOutRequest {
@ -74,7 +91,7 @@ message LoopOutRequest {
sweep the on-chain htlc and the fee estimate turns out higher than this sweep the on-chain htlc and the fee estimate turns out higher than this
value, we cancel the swap. If the fee estimate is lower, we publish the value, we cancel the swap. If the fee estimate is lower, we publish the
sweep tx. sweep tx.
If the sweep tx is not confirmed, we are forced to ratchet up fees until it If the sweep tx is not confirmed, we are forced to ratchet up fees until it
is swept. Possibly even exceeding max_miner_fee if we get close to the htlc is swept. Possibly even exceeding max_miner_fee if we get close to the htlc
timeout. Because the initial publication revealed the preimage, we have no timeout. Because the initial publication revealed the preimage, we have no
@ -82,11 +99,11 @@ message LoopOutRequest {
when the fee becomes higher than the swap amount, we can only wait for fees when the fee becomes higher than the swap amount, we can only wait for fees
to come down and hope - if we are past the timeout - that the server is not to come down and hope - if we are past the timeout - that the server is not
publishing the revocation. publishing the revocation.
max_miner_fee is typically taken from the response of the GetQuote call. max_miner_fee is typically taken from the response of the GetQuote call.
*/ */
int64 max_miner_fee = 7; int64 max_miner_fee = 7;
/** /**
The channel to loop out, the channel to loop out is selected based on the The channel to loop out, the channel to loop out is selected based on the
lowest routing fee for the swap payment to the server. lowest routing fee for the swap payment to the server.
@ -108,7 +125,7 @@ message MonitorRequest{
message SwapStatus { message SwapStatus {
/** /**
Requested swap amount in sat. This does not include the swap and miner Requested swap amount in sat. This does not include the swap and miner
fee. fee.
*/ */
int64 amt = 1; int64 amt = 1;
@ -145,7 +162,7 @@ message SwapStatus {
string htlc_address = 7; string htlc_address = 7;
} }
enum SwapType { enum SwapType {
// LOOP_OUT indicates an loop out swap (off-chain to on-chain) // LOOP_OUT indicates an loop out swap (off-chain to on-chain)
LOOP_OUT = 0; LOOP_OUT = 0;
} }
@ -228,7 +245,7 @@ message TermsResponse {
message QuoteRequest { message QuoteRequest {
/** /**
Requested swap amount in sat. The amount to swap in satoshis.
*/ */
int64 amt = 1; int64 amt = 1;
} }
@ -240,14 +257,12 @@ message QuoteResponse {
int64 swap_fee = 1; int64 swap_fee = 1;
/** /**
The part of the swap fee that is requested as a The part of the swap fee that is requested as a prepayment.
prepayment.
*/ */
int64 prepay_amt = 2; int64 prepay_amt = 2;
/** /**
An estimate of the on-chain fee that needs to be paid to An estimate of the on-chain fee that needs to be paid to sweep the HTLC.
sweep the htlc.
*/ */
int64 miner_fee = 3; int64 miner_fee = 3;
} }

@ -0,0 +1,263 @@
{
"swagger": "2.0",
"info": {
"title": "client.proto",
"version": "version not set"
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/v1/loop/out": {
"post": {
"summary": "* loop: `out`\nLoopOut initiates an loop out swap with the given parameters. The call\nreturns after the swap has been set up with the swap server. From that\npoint onwards, progress can be tracked via the SwapStatus stream that is\nreturned from Monitor().",
"operationId": "LoopOut",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/looprpcSwapResponse"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/looprpcLoopOutRequest"
}
}
],
"tags": [
"SwapClient"
]
}
},
"/v1/loop/out/quote/{amt}": {
"get": {
"summary": "* loop: `quote`\nLoopOutQuote returns a quote for a loop out swap with the provided\nparameters.",
"operationId": "LoopOutQuote",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/looprpcQuoteResponse"
}
}
},
"parameters": [
{
"name": "amt",
"in": "path",
"required": true,
"type": "string",
"format": "int64"
}
],
"tags": [
"SwapClient"
]
}
},
"/v1/loop/out/terms": {
"get": {
"summary": "* loop: `terms`\nLoopOutTerms returns the terms that the server enforces for a loop out swap.",
"operationId": "LoopOutTerms",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/looprpcTermsResponse"
}
}
},
"tags": [
"SwapClient"
]
}
}
},
"definitions": {
"looprpcLoopOutRequest": {
"type": "object",
"properties": {
"amt": {
"type": "string",
"format": "int64",
"description": "*\nRequested swap amount in sat. This does not include the swap and miner fee."
},
"dest": {
"type": "string",
"description": "*\nBase58 encoded destination address for the swap."
},
"max_swap_routing_fee": {
"type": "string",
"format": "int64",
"description": "*\nMaximum off-chain fee in msat that may be paid for payment to the server.\nThis limit is applied during path finding. Typically this value is taken\nfrom the response of the GetQuote call."
},
"max_prepay_routing_fee": {
"type": "string",
"format": "int64",
"description": "*\nMaximum off-chain fee in msat that may be paid for payment to the server.\nThis limit is applied during path finding. Typically this value is taken\nfrom the response of the GetQuote call."
},
"max_swap_fee": {
"type": "string",
"format": "int64",
"description": "*\nMaximum we are willing to pay the server for the swap. This value is not\ndisclosed in the swap initiation call, but if the server asks for a\nhigher fee, we abort the swap. Typically this value is taken from the\nresponse of the GetQuote call. It includes the prepay amount."
},
"max_prepay_amt": {
"type": "string",
"format": "int64",
"description": "*\nMaximum amount of the swap fee that may be charged as a prepayment."
},
"max_miner_fee": {
"type": "string",
"format": "int64",
"description": "*\nMaximum in on-chain fees that we are willing to spent. If we want to\nsweep the on-chain htlc and the fee estimate turns out higher than this\nvalue, we cancel the swap. If the fee estimate is lower, we publish the\nsweep tx.\n\nIf the sweep tx is not confirmed, we are forced to ratchet up fees until it\nis swept. Possibly even exceeding max_miner_fee if we get close to the htlc\ntimeout. Because the initial publication revealed the preimage, we have no\nother choice. The server may already have pulled the off-chain htlc. Only\nwhen the fee becomes higher than the swap amount, we can only wait for fees\nto come down and hope - if we are past the timeout - that the server is not\npublishing the revocation.\n\nmax_miner_fee is typically taken from the response of the GetQuote call."
},
"loop_out_channel": {
"type": "string",
"format": "uint64",
"description": "*\nThe channel to loop out, the channel to loop out is selected based on the\nlowest routing fee for the swap payment to the server."
}
}
},
"looprpcQuoteResponse": {
"type": "object",
"properties": {
"swap_fee": {
"type": "string",
"format": "int64",
"description": "*\nThe fee that the swap server is charging for the swap."
},
"prepay_amt": {
"type": "string",
"format": "int64",
"description": "*\nThe part of the swap fee that is requested as a prepayment."
},
"miner_fee": {
"type": "string",
"format": "int64",
"description": "*\nAn estimate of the on-chain fee that needs to be paid to sweep the HTLC."
}
}
},
"looprpcSwapResponse": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "*\nSwap identifier to track status in the update stream that is returned from\nthe Start() call. Currently this is the hash that locks the htlcs."
}
}
},
"looprpcSwapState": {
"type": "string",
"enum": [
"INITIATED",
"PREIMAGE_REVEALED",
"SUCCESS",
"FAILED"
],
"default": "INITIATED",
"description": " - INITIATED: *\nINITIATED is the initial state of a swap. At that point, the initiation\ncall to the server has been made and the payment process has been started\nfor the swap and prepayment invoices.\n - PREIMAGE_REVEALED: *\nPREIMAGE_REVEALED is reached when the sweep tx publication is first\nattempted. From that point on, we should consider the preimage to no\nlonger be secret and we need to do all we can to get the sweep confirmed.\nThis state will mostly coalesce with StateHtlcConfirmed, except in the\ncase where we wait for fees to come down before we sweep.\n - SUCCESS: *\nSUCCESS is the final swap state that is reached when the sweep tx has\nthe required confirmation depth.\n - FAILED: *\nFAILED is the final swap state for a failed swap with or without loss of\nthe swap amount."
},
"looprpcSwapStatus": {
"type": "object",
"properties": {
"amt": {
"type": "string",
"format": "int64",
"description": "*\nRequested swap amount in sat. This does not include the swap and miner\nfee."
},
"id": {
"type": "string",
"description": "*\nSwap identifier to track status in the update stream that is returned from\nthe Start() call. Currently this is the hash that locks the htlcs."
},
"type": {
"$ref": "#/definitions/looprpcSwapType",
"title": "*\nSwap type"
},
"state": {
"$ref": "#/definitions/looprpcSwapState",
"description": "*\nState the swap is currently in, see State enum."
},
"initiation_time": {
"type": "string",
"format": "int64",
"description": "*\nInitiation time of the swap."
},
"last_update_time": {
"type": "string",
"format": "int64",
"description": "*\nInitiation time of the swap."
},
"htlc_address": {
"type": "string",
"description": "*\nHtlc address."
}
}
},
"looprpcSwapType": {
"type": "string",
"enum": [
"LOOP_OUT"
],
"default": "LOOP_OUT",
"title": "- LOOP_OUT: LOOP_OUT indicates an loop out swap (off-chain to on-chain)"
},
"looprpcTermsResponse": {
"type": "object",
"properties": {
"swap_payment_dest": {
"type": "string",
"description": "*\nThe node pubkey where the swap payment needs to be paid\nto. This can be used to test connectivity before initiating the swap."
},
"swap_fee_base": {
"type": "string",
"format": "int64",
"title": "*\nThe base fee for a swap (sat)"
},
"swap_fee_rate": {
"type": "string",
"format": "int64",
"title": "*\nThe fee rate for a swap (parts per million)"
},
"prepay_amt": {
"type": "string",
"format": "int64",
"title": "*\nRequired prepay amount"
},
"min_swap_amount": {
"type": "string",
"format": "int64",
"title": "*\nMinimum swap amount (sat)"
},
"max_swap_amount": {
"type": "string",
"format": "int64",
"title": "*\nMaximum swap amount (sat)"
},
"cltv_delta": {
"type": "integer",
"format": "int32",
"title": "*\nOn-chain cltv expiry delta"
},
"max_cltv": {
"type": "integer",
"format": "int32",
"title": "*\nMaximum cltv expiry delta"
}
}
}
}
}

@ -1,13 +1,24 @@
#!/bin/sh #!/bin/sh
# Generate the server protos. set -e
protoc -I/usr/local/include -I.\
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ # Generate the gRPC bindings for all proto files.
--go_out=plugins=grpc,paths=source_relative:. \ for file in ./*.proto
server.proto do
protoc -I/usr/local/include -I. \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc,paths=source_relative:. \
${file}
done
# Only generate the REST proxy and definitions for the client component.
protoc -I/usr/local/include -I. \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--grpc-gateway_out=logtostderr=true:. \
client.proto
# Generate the client protos.
protoc -I/usr/local/include -I. \ protoc -I/usr/local/include -I. \
-I$GOPATH/src \ -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc:. \ --swagger_out=logtostderr=true:. \
client.proto client.proto

Loading…
Cancel
Save