diff --git a/cmd/loop/loopout.go b/cmd/loop/loopout.go index 6767a84..af472d3 100644 --- a/cmd/loop/loopout.go +++ b/cmd/loop/loopout.go @@ -14,11 +14,11 @@ var loopOutCommand = cli.Command{ ArgsUsage: "amt [addr]", Description: ` Attempts loop out the target amount into either the backing lnd's - wallet, or a targeted address. - - The amount is to be specified in satoshis. + wallet, or a targeted address. - 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.`, Flags: []cli.Flag{ cli.Uint64Flag{ @@ -55,12 +55,10 @@ func loopOut(ctx *cli.Context) error { } defer cleanup() - quote, err := client.GetLoopOutQuote( - context.Background(), - &looprpc.QuoteRequest{ - Amt: int64(amt), - }, - ) + quoteReq := &looprpc.QuoteRequest{ + Amt: int64(amt), + } + quote, err := client.LoopOutQuote(context.Background(), quoteReq) if err != nil { return err } diff --git a/cmd/loop/terms.go b/cmd/loop/terms.go index 960779b..dbf18f2 100644 --- a/cmd/loop/terms.go +++ b/cmd/loop/terms.go @@ -13,7 +13,7 @@ import ( var termsCommand = cli.Command{ Name: "terms", - Usage: "show current server swap terms", + Usage: "Display the current swap terms imposed by the server.", Action: terms, } @@ -24,9 +24,8 @@ func terms(ctx *cli.Context) error { } defer cleanup() - terms, err := client.GetLoopOutTerms( - context.Background(), &looprpc.TermsRequest{}, - ) + req := &looprpc.TermsRequest{} + terms, err := client.LoopOutTerms(context.Background(), req) if err != nil { return err } diff --git a/cmd/loopd/config.go b/cmd/loopd/config.go index 04e4315..e37dcd9 100644 --- a/cmd/loopd/config.go +++ b/cmd/loopd/config.go @@ -12,7 +12,8 @@ type config struct { Insecure bool `long:"insecure" description:"disable tls"` 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"` - 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"` @@ -22,7 +23,8 @@ type config struct { var defaultConfig = config{ Network: "mainnet", SwapServer: "swap.lightning.today:11009", - Listen: "localhost:11010", + RPCListen: "localhost:11010", + RESTListen: "localhost:8081", Insecure: false, Lnd: &lndConfig{ Host: "localhost:10009", diff --git a/cmd/loopd/daemon.go b/cmd/loopd/daemon.go index 9018763..dd5875d 100644 --- a/cmd/loopd/daemon.go +++ b/cmd/loopd/daemon.go @@ -4,12 +4,14 @@ import ( "context" "fmt" "net" + "net/http" "os" "os/signal" "runtime/pprof" "sync" "time" + proxy "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/lightninglabs/loop" "github.com/lightninglabs/loop/looprpc" "google.golang.org/grpc" @@ -59,15 +61,38 @@ func daemon(config *config) error { grpcServer := grpc.NewServer(serverOpts...) looprpc.RegisterSwapClientServer(grpcServer, &server) - // Next, Start the gRPC server listening for HTTP/2 connections. - logger.Infof("Starting RPC listener") - lis, err := net.Listen("tcp", config.Listen) + // Next, start the gRPC server listening for HTTP/2 connections. + logger.Infof("Starting gRPC listener") + grpcListener, err := net.Listen("tcp", config.RPCListen) if err != nil { 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) @@ -124,9 +149,10 @@ func daemon(config *config) error { go func() { 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 { logger.Error(err) } diff --git a/cmd/loopd/swapclient_server.go b/cmd/loopd/swapclient_server.go index 875cb01..6678fb0 100644 --- a/cmd/loopd/swapclient_server.go +++ b/cmd/loopd/swapclient_server.go @@ -208,8 +208,8 @@ func (s *swapClientServer) Monitor(in *looprpc.MonitorRequest, } } -// GetTerms returns the terms that the server enforces for swaps. -func (s *swapClientServer) GetLoopOutTerms(ctx context.Context, +// LoopOutTerms returns the terms that the server enforces for loop out swaps. +func (s *swapClientServer) LoopOutTerms(ctx context.Context, req *looprpc.TermsRequest) (*looprpc.TermsResponse, error) { logger.Infof("Terms request received") @@ -230,8 +230,9 @@ func (s *swapClientServer) GetLoopOutTerms(ctx context.Context, }, nil } -// GetQuote returns a quote for a swap with the provided parameters. -func (s *swapClientServer) GetLoopOutQuote(ctx context.Context, +// LoopOutQuote returns a quote for a loop out swap with the provided +// parameters. +func (s *swapClientServer) LoopOutQuote(ctx context.Context, req *looprpc.QuoteRequest) (*looprpc.QuoteResponse, error) { quote, err := s.impl.LoopOutQuote(ctx, &loop.LoopOutQuoteRequest{ diff --git a/go.mod b/go.mod index d1d3823..535d759 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/coreos/bbolt v0.0.0-20180223184059-7ee3ded59d4835e10f3e7d0f7603c42aa5e83820 github.com/fortytw2/leaktest v1.3.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/lightningnetwork/lnd v0.0.0 github.com/urfave/cli v1.20.0 diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index c14c261..5f9a660 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -6,6 +6,7 @@ package looprpc import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" import ( context "golang.org/x/net/context" @@ -41,7 +42,7 @@ func (x SwapType) String() string { return proto.EnumName(SwapType_name, int32(x)) } func (SwapType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_client_e8e8b003a83cbb2b, []int{0} + return fileDescriptor_client_ecf1f0d12250b1cb, []int{0} } type SwapState int32 @@ -86,7 +87,7 @@ func (x SwapState) String() string { return proto.EnumName(SwapState_name, int32(x)) } func (SwapState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_client_e8e8b003a83cbb2b, []int{1} + return fileDescriptor_client_ecf1f0d12250b1cb, []int{1} } type LoopOutRequest struct { @@ -144,7 +145,7 @@ func (m *LoopOutRequest) Reset() { *m = LoopOutRequest{} } func (m *LoopOutRequest) String() string { return proto.CompactTextString(m) } func (*LoopOutRequest) ProtoMessage() {} 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 { 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 (*SwapResponse) ProtoMessage() {} 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 { 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 (*MonitorRequest) ProtoMessage() {} 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 { 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 (*SwapStatus) ProtoMessage() {} 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 { 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 (*TermsRequest) ProtoMessage() {} 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 { 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 (*TermsResponse) ProtoMessage() {} 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 { return xxx_messageInfo_TermsResponse.Unmarshal(m, b) @@ -536,7 +537,7 @@ func (m *TermsResponse) GetMaxCltv() int32 { 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"` XXX_NoUnkeyedLiteral struct{} `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 (*QuoteRequest) ProtoMessage() {} 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 { 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. 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 - // prepayment. + // The part of the swap fee that is requested as a prepayment. 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 - // sweep the htlc. + // An estimate of the on-chain fee that needs to be paid to sweep the HTLC. MinerFee int64 `protobuf:"varint,3,opt,name=miner_fee,json=minerFee,proto3" json:"miner_fee,omitempty"` XXX_NoUnkeyedLiteral struct{} `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 (*QuoteResponse) ProtoMessage() {} 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 { 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. type SwapClientClient interface { - // * + // * loop: `out` // 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 // point onwards, progress can be tracked via the SwapStatus stream that is // returned from Monitor(). 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. + // TODO: add MonitorSync version for REST clients. Monitor(ctx context.Context, in *MonitorRequest, opts ...grpc.CallOption) (SwapClient_MonitorClient, error) - // * - // GetLoopOutTerms returns the terms that the server enforces for swaps. - GetLoopOutTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error) - // * - // GetLoopOutQuote returns a quote for a swap with the provided parameters. - GetLoopOutQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error) + // * loop: `terms` + // LoopOutTerms returns the terms that the server enforces for a loop out swap. + LoopOutTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error) + // * loop: `quote` + // LoopOutQuote returns a quote for a loop out swap with the provided + // parameters. + LoopOutQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error) } type swapClientClient struct { @@ -727,18 +728,18 @@ func (x *swapClientMonitorClient) Recv() (*SwapStatus, error) { 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) - 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 { return nil, err } 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) - 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 { return nil, err } @@ -747,21 +748,23 @@ func (c *swapClientClient) GetLoopOutQuote(ctx context.Context, in *QuoteRequest // SwapClientServer is the server API for SwapClient service. type SwapClientServer interface { - // * + // * loop: `out` // 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 // point onwards, progress can be tracked via the SwapStatus stream that is // returned from Monitor(). LoopOut(context.Context, *LoopOutRequest) (*SwapResponse, error) - // * + // * loop: `monitor` // Monitor will return a stream of swap updates for currently active swaps. + // TODO: add MonitorSync version for REST clients. Monitor(*MonitorRequest, SwapClient_MonitorServer) error - // * - // GetLoopOutTerms returns the terms that the server enforces for swaps. - GetLoopOutTerms(context.Context, *TermsRequest) (*TermsResponse, error) - // * - // GetLoopOutQuote returns a quote for a swap with the provided parameters. - GetLoopOutQuote(context.Context, *QuoteRequest) (*QuoteResponse, error) + // * loop: `terms` + // LoopOutTerms returns the terms that the server enforces for a loop out swap. + LoopOutTerms(context.Context, *TermsRequest) (*TermsResponse, error) + // * loop: `quote` + // LoopOutQuote returns a quote for a loop out swap with the provided + // parameters. + LoopOutQuote(context.Context, *QuoteRequest) (*QuoteResponse, error) } func RegisterSwapClientServer(s *grpc.Server, srv SwapClientServer) { @@ -807,38 +810,38 @@ func (x *swapClientMonitorServer) Send(m *SwapStatus) error { 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) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(SwapClientServer).GetLoopOutTerms(ctx, in) + return srv.(SwapClientServer).LoopOutTerms(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/looprpc.SwapClient/GetLoopOutTerms", + FullMethod: "/looprpc.SwapClient/LoopOutTerms", } 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) } -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) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(SwapClientServer).GetLoopOutQuote(ctx, in) + return srv.(SwapClientServer).LoopOutQuote(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/looprpc.SwapClient/GetLoopOutQuote", + FullMethod: "/looprpc.SwapClient/LoopOutQuote", } 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) } @@ -852,12 +855,12 @@ var _SwapClient_serviceDesc = grpc.ServiceDesc{ Handler: _SwapClient_LoopOut_Handler, }, { - MethodName: "GetLoopOutTerms", - Handler: _SwapClient_GetLoopOutTerms_Handler, + MethodName: "LoopOutTerms", + Handler: _SwapClient_LoopOutTerms_Handler, }, { - MethodName: "GetLoopOutQuote", - Handler: _SwapClient_GetLoopOutQuote_Handler, + MethodName: "LoopOutQuote", + Handler: _SwapClient_LoopOutQuote_Handler, }, }, Streams: []grpc.StreamDesc{ @@ -870,55 +873,60 @@ var _SwapClient_serviceDesc = grpc.ServiceDesc{ Metadata: "client.proto", } -func init() { proto.RegisterFile("client.proto", fileDescriptor_client_e8e8b003a83cbb2b) } - -var fileDescriptor_client_e8e8b003a83cbb2b = []byte{ - // 749 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xcf, 0x72, 0xda, 0x3a, - 0x14, 0xc6, 0x83, 0xf9, 0xeb, 0x83, 0x31, 0xa0, 0xdc, 0xe4, 0x92, 0xdc, 0xc9, 0x1d, 0xae, 0xe7, - 0xb6, 0x65, 0xb2, 0x48, 0x3b, 0xc9, 0x2a, 0xbb, 0x52, 0x20, 0x19, 0x3a, 0x49, 0xa1, 0x86, 0x74, - 0xeb, 0x51, 0x40, 0x69, 0x3c, 0x63, 0xd9, 0xae, 0x25, 0x27, 0xf0, 0x02, 0x7d, 0x9a, 0xae, 0xfa, - 0x6e, 0xdd, 0x77, 0xf4, 0x07, 0x62, 0xa7, 0xed, 0xce, 0xf3, 0xe9, 0x3b, 0x47, 0xd6, 0x4f, 0xdf, - 0x11, 0x58, 0x8b, 0xc0, 0x27, 0x21, 0x3f, 0x89, 0x93, 0x88, 0x47, 0xa8, 0x1a, 0x44, 0x51, 0x9c, - 0xc4, 0x0b, 0xe7, 0xbb, 0x01, 0xf6, 0x55, 0x14, 0xc5, 0x93, 0x94, 0xbb, 0xe4, 0x4b, 0x4a, 0x18, - 0x47, 0x2d, 0x28, 0x62, 0xca, 0x3b, 0x85, 0x6e, 0xa1, 0x57, 0x74, 0xc5, 0x27, 0x42, 0x50, 0x5a, - 0x12, 0xc6, 0x3b, 0x46, 0xb7, 0xd0, 0x33, 0x5d, 0xf9, 0x8d, 0x5e, 0xc3, 0x5f, 0x14, 0xaf, 0x3c, - 0xf6, 0x88, 0x63, 0x2f, 0x89, 0x52, 0xee, 0x87, 0x9f, 0xbd, 0x3b, 0x42, 0x3a, 0x45, 0x59, 0xd6, - 0xa6, 0x78, 0x35, 0x7b, 0xc4, 0xb1, 0xab, 0x56, 0x2e, 0x08, 0x41, 0x67, 0xb0, 0x2f, 0x0a, 0xe2, - 0x84, 0xc4, 0x78, 0x9d, 0x2b, 0x29, 0xc9, 0x92, 0x5d, 0x8a, 0x57, 0x53, 0xb9, 0x98, 0x29, 0xea, - 0x82, 0xb5, 0xdd, 0x45, 0x58, 0xcb, 0xd2, 0x0a, 0xba, 0xbb, 0x70, 0xfc, 0x0f, 0x76, 0xa6, 0xad, - 0xf8, 0xf1, 0x8a, 0xf4, 0x58, 0xdb, 0x76, 0x7d, 0xca, 0x91, 0x03, 0x0d, 0xe1, 0xa2, 0x7e, 0x48, - 0x12, 0xd9, 0xa8, 0x2a, 0x4d, 0x75, 0x8a, 0x57, 0xd7, 0x42, 0x13, 0x9d, 0x7a, 0xd0, 0x12, 0x54, - 0xbc, 0x28, 0xe5, 0xde, 0xe2, 0x1e, 0x87, 0x21, 0x09, 0x3a, 0xb5, 0x6e, 0xa1, 0x57, 0x72, 0xed, - 0x40, 0x11, 0x1a, 0x28, 0xd5, 0xf9, 0x17, 0x2c, 0x79, 0x38, 0xc2, 0xe2, 0x28, 0x64, 0x04, 0xd9, - 0x60, 0xf8, 0x4b, 0x09, 0xcc, 0x74, 0x0d, 0x7f, 0xe9, 0xb4, 0xc0, 0xbe, 0x8e, 0x42, 0x9f, 0x47, - 0x89, 0x66, 0xea, 0xfc, 0x28, 0x00, 0x88, 0x92, 0x19, 0xc7, 0x3c, 0x65, 0xbf, 0x41, 0xac, 0x5a, - 0x18, 0x9b, 0x16, 0xe8, 0x05, 0x94, 0xf8, 0x3a, 0x56, 0x38, 0xed, 0xd3, 0xf6, 0x89, 0xbe, 0xaf, - 0x13, 0xd1, 0x64, 0xbe, 0x8e, 0x89, 0x2b, 0x97, 0x51, 0x0f, 0xca, 0x8c, 0x63, 0xae, 0x18, 0xda, - 0xa7, 0x28, 0xe7, 0x13, 0x9b, 0x11, 0x57, 0x19, 0xd0, 0x2b, 0x68, 0xfa, 0xa1, 0xcf, 0x7d, 0xcc, - 0xfd, 0x28, 0xf4, 0xb8, 0x4f, 0x37, 0x30, 0xed, 0x27, 0x79, 0xee, 0x53, 0x85, 0x01, 0x33, 0xee, - 0xa5, 0xf1, 0x12, 0x73, 0xa2, 0x9c, 0x0a, 0xa9, 0x2d, 0xf4, 0x1b, 0x29, 0x4b, 0xe7, 0x7f, 0x60, - 0xdd, 0xf3, 0x60, 0xe1, 0xe1, 0xe5, 0x32, 0x21, 0x8c, 0x49, 0xa6, 0xa6, 0x5b, 0x17, 0x5a, 0x5f, - 0x49, 0x8e, 0x0d, 0xd6, 0x9c, 0x24, 0x94, 0x6d, 0x38, 0x7c, 0x33, 0xa0, 0xa1, 0x05, 0xcd, 0xee, - 0x18, 0xda, 0xf2, 0x76, 0x63, 0xbc, 0xa6, 0x24, 0xe4, 0x9e, 0x0c, 0x9a, 0x42, 0xd9, 0x14, 0x0b, - 0x53, 0xa5, 0x0f, 0x45, 0xe6, 0x1c, 0x68, 0x6c, 0x92, 0xe0, 0xdd, 0x62, 0x46, 0x24, 0xaf, 0xa2, - 0x5b, 0x67, 0x2a, 0x0b, 0xef, 0x30, 0x23, 0x39, 0x4f, 0x22, 0xc8, 0x14, 0x73, 0x1e, 0x57, 0xb0, - 0x38, 0x02, 0xc8, 0xe4, 0x45, 0xc5, 0xcf, 0x8c, 0xb7, 0x61, 0x79, 0x09, 0x4d, 0xea, 0x87, 0x2a, - 0x74, 0x98, 0x46, 0x69, 0xc8, 0x35, 0xaa, 0x06, 0xf5, 0x43, 0x01, 0xb6, 0x2f, 0x45, 0xe9, 0xdb, - 0x84, 0x53, 0xfb, 0x2a, 0xda, 0xa7, 0xf2, 0xa9, 0x7d, 0x47, 0x00, 0x8b, 0x80, 0x3f, 0x78, 0x4b, - 0x12, 0x70, 0x2c, 0x29, 0x95, 0x5d, 0x53, 0x28, 0x43, 0x21, 0xa0, 0x03, 0xa8, 0x89, 0x36, 0x42, - 0x90, 0x79, 0x2b, 0xbb, 0x55, 0x8a, 0x57, 0x83, 0x80, 0x3f, 0x38, 0x5d, 0xb0, 0x3e, 0xa6, 0x11, - 0x27, 0x7f, 0x1c, 0x4d, 0xe7, 0x0e, 0x1a, 0xda, 0xa1, 0x79, 0x1e, 0x40, 0x6d, 0x3b, 0x2d, 0xca, - 0x57, 0xd5, 0x47, 0x7f, 0x76, 0x6c, 0xe3, 0xf9, 0xb1, 0xff, 0x01, 0xf3, 0x69, 0x3e, 0x14, 0xb5, - 0x1a, 0xd5, 0xc3, 0x71, 0xdc, 0x81, 0xda, 0x26, 0x7a, 0xc8, 0x82, 0xda, 0xd5, 0x64, 0x32, 0xf5, - 0x26, 0x37, 0xf3, 0xd6, 0xce, 0xf1, 0x7b, 0x30, 0xb7, 0x61, 0x43, 0x0d, 0x30, 0xc7, 0x1f, 0xc6, - 0xf3, 0x71, 0x7f, 0x3e, 0x1a, 0xb6, 0x76, 0xd0, 0x1e, 0xb4, 0xa7, 0xee, 0x68, 0x7c, 0xdd, 0xbf, - 0x1c, 0x79, 0xee, 0xe8, 0xd3, 0xa8, 0x7f, 0x35, 0x1a, 0xb6, 0x0a, 0xa8, 0x0e, 0xd5, 0xd9, 0xcd, - 0x60, 0x30, 0x9a, 0xcd, 0x5a, 0x45, 0x04, 0x50, 0xb9, 0xe8, 0x8f, 0xc5, 0x42, 0xe9, 0xf4, 0xab, - 0xa1, 0xc6, 0x64, 0x20, 0xdf, 0x2a, 0x74, 0x0e, 0x55, 0xfd, 0x36, 0xa1, 0xbf, 0xb7, 0xc9, 0xce, - 0xbf, 0x56, 0x87, 0x7b, 0xb9, 0xc8, 0x6f, 0x31, 0x9c, 0x43, 0x55, 0x8f, 0x60, 0xa6, 0x34, 0x3f, - 0x94, 0x87, 0xbb, 0xbf, 0x4c, 0x4b, 0xca, 0xde, 0x14, 0xd0, 0x5b, 0x68, 0x5e, 0x12, 0xae, 0xb7, - 0x91, 0x61, 0x45, 0x4f, 0x9b, 0x64, 0xd3, 0x7c, 0xb8, 0xff, 0x5c, 0xd6, 0x9b, 0xe7, 0x3a, 0xc8, - 0xeb, 0xc9, 0x74, 0xc8, 0x5e, 0x68, 0xa6, 0x43, 0xee, 0x16, 0x6f, 0x2b, 0xf2, 0x99, 0x3e, 0xfb, - 0x19, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x15, 0xc0, 0x11, 0xb6, 0x05, 0x00, 0x00, +func init() { proto.RegisterFile("client.proto", fileDescriptor_client_ecf1f0d12250b1cb) } + +var fileDescriptor_client_ecf1f0d12250b1cb = []byte{ + // 825 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xcb, 0x72, 0xe3, 0x44, + 0x14, 0x1d, 0xc9, 0x4e, 0x6c, 0xdd, 0xc8, 0x8a, 0xdd, 0xf3, 0xf2, 0x18, 0x86, 0x32, 0x2a, 0x1e, + 0xae, 0x2c, 0x22, 0xc8, 0xac, 0x60, 0x67, 0x1c, 0x0f, 0x65, 0x2a, 0x21, 0xa6, 0xed, 0x50, 0xc5, + 0x4a, 0xd5, 0x63, 0xf7, 0x64, 0x54, 0xa5, 0x56, 0x6b, 0xd4, 0xad, 0x8c, 0x5d, 0x14, 0x1b, 0x7e, + 0x81, 0xdf, 0x60, 0xc5, 0xaf, 0xb0, 0xe0, 0x07, 0xf8, 0x05, 0xf6, 0x54, 0x3f, 0xec, 0x48, 0x81, + 0xd9, 0x75, 0x9d, 0x3e, 0xf7, 0x74, 0xf7, 0xb9, 0xe7, 0x36, 0xf8, 0xab, 0x34, 0xa1, 0x99, 0x3c, + 0xcd, 0x0b, 0x2e, 0x39, 0x6a, 0xa5, 0x9c, 0xe7, 0x45, 0xbe, 0x1a, 0x7c, 0x78, 0xc3, 0xf9, 0x4d, + 0x4a, 0x23, 0x92, 0x27, 0x11, 0xc9, 0x32, 0x2e, 0x89, 0x4c, 0x78, 0x26, 0x0c, 0x2d, 0xfc, 0xc3, + 0x85, 0xe0, 0x82, 0xf3, 0xfc, 0xaa, 0x94, 0x98, 0xbe, 0x2d, 0xa9, 0x90, 0xa8, 0x0b, 0x0d, 0xc2, + 0x64, 0xdf, 0x19, 0x3a, 0xa3, 0x06, 0x56, 0x4b, 0x84, 0xa0, 0xb9, 0xa6, 0x42, 0xf6, 0xdd, 0xa1, + 0x33, 0xf2, 0xb0, 0x5e, 0xa3, 0x08, 0x1e, 0x31, 0xb2, 0x89, 0xc5, 0x3b, 0x92, 0xc7, 0x05, 0x2f, + 0x65, 0x92, 0xdd, 0xc4, 0xaf, 0x29, 0xed, 0x37, 0x74, 0x59, 0x8f, 0x91, 0xcd, 0xe2, 0x1d, 0xc9, + 0xb1, 0xd9, 0x79, 0x49, 0x29, 0x7a, 0x01, 0x4f, 0x54, 0x41, 0x5e, 0xd0, 0x9c, 0x6c, 0x6b, 0x25, + 0x4d, 0x5d, 0xf2, 0x90, 0x91, 0xcd, 0x5c, 0x6f, 0x56, 0x8a, 0x86, 0xe0, 0xef, 0x4f, 0x51, 0xd4, + 0x03, 0x4d, 0x05, 0xab, 0xae, 0x18, 0x9f, 0x40, 0x50, 0x91, 0x55, 0x17, 0x3f, 0xd4, 0x1c, 0x7f, + 0x2f, 0x37, 0x66, 0x12, 0x85, 0xd0, 0x51, 0x2c, 0x96, 0x64, 0xb4, 0xd0, 0x42, 0x2d, 0x4d, 0x3a, + 0x62, 0x64, 0x73, 0xa9, 0x30, 0xa5, 0x34, 0x82, 0xae, 0xf2, 0x2c, 0xe6, 0xa5, 0x8c, 0x57, 0x6f, + 0x48, 0x96, 0xd1, 0xb4, 0xdf, 0x1e, 0x3a, 0xa3, 0x26, 0x0e, 0x52, 0xe3, 0xd0, 0xc4, 0xa0, 0xe1, + 0x47, 0xe0, 0xeb, 0xc7, 0x51, 0x91, 0xf3, 0x4c, 0x50, 0x14, 0x80, 0x9b, 0xac, 0xb5, 0x61, 0x1e, + 0x76, 0x93, 0x75, 0xd8, 0x85, 0xe0, 0x92, 0x67, 0x89, 0xe4, 0x85, 0xf5, 0x34, 0xfc, 0xc7, 0x01, + 0x50, 0x25, 0x0b, 0x49, 0x64, 0x29, 0xfe, 0xc7, 0x62, 0x23, 0xe1, 0xee, 0x24, 0xd0, 0xa7, 0xd0, + 0x94, 0xdb, 0xdc, 0xd8, 0x19, 0x9c, 0xf5, 0x4e, 0x6d, 0x37, 0x4f, 0x95, 0xc8, 0x72, 0x9b, 0x53, + 0xac, 0xb7, 0xd1, 0x08, 0x0e, 0x84, 0x24, 0xd2, 0x78, 0x18, 0x9c, 0xa1, 0x1a, 0x4f, 0x1d, 0x46, + 0xb1, 0x21, 0xa0, 0xcf, 0xe1, 0x38, 0xc9, 0x12, 0x99, 0xe8, 0xee, 0xc7, 0x32, 0x61, 0x3b, 0x33, + 0x83, 0x3b, 0x78, 0x99, 0x30, 0x63, 0x03, 0x11, 0x32, 0x2e, 0xf3, 0x35, 0x91, 0xd4, 0x30, 0x8d, + 0xa5, 0x81, 0xc2, 0xaf, 0x35, 0xac, 0x99, 0x1f, 0x83, 0xff, 0x46, 0xa6, 0xab, 0x98, 0xac, 0xd7, + 0x05, 0x15, 0x42, 0x7b, 0xea, 0xe1, 0x23, 0x85, 0x8d, 0x0d, 0x14, 0x06, 0xe0, 0x2f, 0x69, 0xc1, + 0xc4, 0xce, 0x87, 0xdf, 0x5d, 0xe8, 0x58, 0xc0, 0x7a, 0x77, 0x02, 0x3d, 0xdd, 0xdd, 0x9c, 0x6c, + 0x19, 0xcd, 0x64, 0xac, 0x83, 0x66, 0xac, 0x3c, 0x56, 0x1b, 0x73, 0x83, 0x9f, 0xab, 0xcc, 0x85, + 0xd0, 0xd9, 0x25, 0x21, 0x7e, 0x45, 0x04, 0xd5, 0x7e, 0x35, 0xf0, 0x91, 0x30, 0x59, 0xf8, 0x86, + 0x08, 0x5a, 0xe3, 0x14, 0xca, 0x99, 0x46, 0x8d, 0x83, 0x95, 0x17, 0xcf, 0x01, 0x2a, 0x79, 0x31, + 0xf1, 0xf3, 0xf2, 0x7d, 0x58, 0x3e, 0x83, 0x63, 0x96, 0x64, 0x26, 0x74, 0x84, 0xf1, 0x32, 0x93, + 0xd6, 0xaa, 0x0e, 0x4b, 0x32, 0x65, 0xec, 0x58, 0x83, 0x9a, 0xb7, 0x0b, 0xa7, 0xe5, 0x1d, 0x5a, + 0x9e, 0xc9, 0xa7, 0xe5, 0x3d, 0x07, 0x58, 0xa5, 0xf2, 0x36, 0x5e, 0xd3, 0x54, 0x12, 0xed, 0xd2, + 0x01, 0xf6, 0x14, 0x72, 0xae, 0x00, 0xf4, 0x0c, 0xda, 0x4a, 0x46, 0x01, 0x3a, 0x6f, 0x07, 0xb8, + 0xc5, 0xc8, 0x66, 0x92, 0xca, 0xdb, 0x70, 0x08, 0xfe, 0x0f, 0x25, 0x97, 0xf4, 0xbd, 0xa3, 0x19, + 0xbe, 0x86, 0x8e, 0x65, 0x58, 0x3f, 0x9f, 0x41, 0x7b, 0x3f, 0x2d, 0x86, 0xd7, 0xb2, 0x4f, 0xbf, + 0xf7, 0x6c, 0xf7, 0xfe, 0xb3, 0x3f, 0x00, 0xef, 0x6e, 0x3e, 0x8c, 0x6b, 0x6d, 0x66, 0x87, 0xe3, + 0xa4, 0x0f, 0xed, 0x5d, 0xf4, 0x90, 0x0f, 0xed, 0x8b, 0xab, 0xab, 0x79, 0x7c, 0x75, 0xbd, 0xec, + 0x3e, 0x38, 0xf9, 0x0e, 0xbc, 0x7d, 0xd8, 0x50, 0x07, 0xbc, 0xd9, 0xf7, 0xb3, 0xe5, 0x6c, 0xbc, + 0x9c, 0x9e, 0x77, 0x1f, 0xa0, 0xc7, 0xd0, 0x9b, 0xe3, 0xe9, 0xec, 0x72, 0xfc, 0xed, 0x34, 0xc6, + 0xd3, 0x1f, 0xa7, 0xe3, 0x8b, 0xe9, 0x79, 0xd7, 0x41, 0x47, 0xd0, 0x5a, 0x5c, 0x4f, 0x26, 0xd3, + 0xc5, 0xa2, 0xdb, 0x40, 0x00, 0x87, 0x2f, 0xc7, 0x33, 0xb5, 0xd1, 0x3c, 0xfb, 0xcb, 0x35, 0x63, + 0x32, 0xd1, 0x3f, 0x19, 0xc2, 0xd0, 0xb2, 0x7f, 0x13, 0x7a, 0xba, 0x4f, 0x76, 0xfd, 0xb7, 0x1a, + 0x3c, 0xae, 0x45, 0x7e, 0x67, 0x43, 0xf8, 0xf4, 0xd7, 0x3f, 0xff, 0xfe, 0xcd, 0xed, 0x85, 0x7e, + 0x74, 0xfb, 0x65, 0xa4, 0x18, 0x11, 0x2f, 0xe5, 0xd7, 0xce, 0x09, 0xfa, 0x0a, 0x5a, 0x76, 0x36, + 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, } diff --git a/looprpc/client.pb.gw.go b/looprpc/client.pb.gw.go new file mode 100644 index 0000000..390078f --- /dev/null +++ b/looprpc/client.pb.gw.go @@ -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 +) diff --git a/looprpc/client.proto b/looprpc/client.proto index d876232..104994b 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +import "google/api/annotations.proto"; + 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. */ service SwapClient { - /** + /** loop: `out` 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 point onwards, progress can be tracked via the SwapStatus stream that is 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. + TODO: add MonitorSync version for REST clients. */ rpc Monitor(MonitorRequest) returns(stream SwapStatus); - /** - GetLoopOutTerms returns the terms that the server enforces for swaps. + /** loop: `terms` + 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" + }; + } - /** - GetLoopOutQuote returns a quote for a swap with the provided parameters. + /** loop: `quote` + 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 { @@ -74,7 +91,7 @@ message LoopOutRequest { 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 sweep tx. - + 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 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 to come down and hope - if we are past the timeout - that the server is not publishing the revocation. - + max_miner_fee is typically taken from the response of the GetQuote call. */ int64 max_miner_fee = 7; - + /** 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. @@ -108,7 +125,7 @@ message MonitorRequest{ 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. */ int64 amt = 1; @@ -145,7 +162,7 @@ message SwapStatus { string htlc_address = 7; } -enum SwapType { +enum SwapType { // LOOP_OUT indicates an loop out swap (off-chain to on-chain) LOOP_OUT = 0; } @@ -228,7 +245,7 @@ message TermsResponse { message QuoteRequest { /** - Requested swap amount in sat. + The amount to swap in satoshis. */ int64 amt = 1; } @@ -240,14 +257,12 @@ message QuoteResponse { int64 swap_fee = 1; /** - The part of the swap fee that is requested as a - prepayment. + The part of the swap fee that is requested as a prepayment. */ int64 prepay_amt = 2; /** - An estimate of the on-chain fee that needs to be paid to - sweep the htlc. + An estimate of the on-chain fee that needs to be paid to sweep the HTLC. */ int64 miner_fee = 3; } diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json new file mode 100644 index 0000000..efdaaf6 --- /dev/null +++ b/looprpc/client.swagger.json @@ -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" + } + } + } + } +} diff --git a/looprpc/gen_protos.sh b/looprpc/gen_protos.sh index fbb8ac3..ece9832 100755 --- a/looprpc/gen_protos.sh +++ b/looprpc/gen_protos.sh @@ -1,13 +1,24 @@ #!/bin/sh -# Generate the server protos. - 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:. \ - server.proto +set -e + +# Generate the gRPC bindings for all proto files. +for file in ./*.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. \ - -I$GOPATH/src \ - --go_out=plugins=grpc:. \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --swagger_out=logtostderr=true:. \ client.proto