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]",
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
}

@ -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
}

@ -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",

@ -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)
}

@ -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{

@ -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

@ -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,
}

@ -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";
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;
}

@ -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
# 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

Loading…
Cancel
Save