diff --git a/lnrpc/rest-annotations.yaml b/lnrpc/rest-annotations.yaml index 7b388da0..55a4042c 100644 --- a/lnrpc/rest-annotations.yaml +++ b/lnrpc/rest-annotations.yaml @@ -261,6 +261,8 @@ http: # stateservice.proto - selector: lnrpc.State.SubscribeState get: "/v1/state/subscribe" + - selector: lnrpc.State.GetState + get: "/v1/state" # verrpc/verrpc.proto - selector: verrpc.Versioner.GetVersion diff --git a/lnrpc/stateservice.pb.go b/lnrpc/stateservice.pb.go index ca2522a2..e28ebd34 100644 --- a/lnrpc/stateservice.pb.go +++ b/lnrpc/stateservice.pb.go @@ -169,6 +169,91 @@ func (x *SubscribeStateResponse) GetState() WalletState { return WalletState_NON_EXISTING } +type GetStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetStateRequest) Reset() { + *x = GetStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_stateservice_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStateRequest) ProtoMessage() {} + +func (x *GetStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_stateservice_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStateRequest.ProtoReflect.Descriptor instead. +func (*GetStateRequest) Descriptor() ([]byte, []int) { + return file_stateservice_proto_rawDescGZIP(), []int{2} +} + +type GetStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + State WalletState `protobuf:"varint,1,opt,name=State,proto3,enum=lnrpc.WalletState" json:"State,omitempty"` +} + +func (x *GetStateResponse) Reset() { + *x = GetStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_stateservice_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStateResponse) ProtoMessage() {} + +func (x *GetStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_stateservice_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStateResponse.ProtoReflect.Descriptor instead. +func (*GetStateResponse) Descriptor() ([]byte, []int) { + return file_stateservice_proto_rawDescGZIP(), []int{3} +} + +func (x *GetStateResponse) GetState() WalletState { + if x != nil { + return x.State + } + return WalletState_NON_EXISTING +} + var File_stateservice_proto protoreflect.FileDescriptor var file_stateservice_proto_rawDesc = []byte{ @@ -179,22 +264,31 @@ var file_stateservice_proto_rawDesc = []byte{ 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x60, 0x0a, 0x0b, 0x57, 0x61, 0x6c, 0x6c, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x4e, 0x5f, 0x45, - 0x58, 0x49, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x43, - 0x4b, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x50, 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, - 0x45, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x10, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x54, - 0x4f, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0xff, 0x01, 0x32, 0x58, 0x0a, 0x05, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x30, 0x01, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3c, 0x0a, 0x10, 0x47, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x28, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, + 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x60, 0x0a, 0x0b, 0x57, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x4e, 0x5f, + 0x45, 0x58, 0x49, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, + 0x43, 0x4b, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, + 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x50, 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x45, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x10, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, + 0x54, 0x4f, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0xff, 0x01, 0x32, 0x95, 0x01, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x16, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x6e, 0x72, + 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -210,21 +304,26 @@ func file_stateservice_proto_rawDescGZIP() []byte { } var file_stateservice_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_stateservice_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_stateservice_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_stateservice_proto_goTypes = []interface{}{ (WalletState)(0), // 0: lnrpc.WalletState (*SubscribeStateRequest)(nil), // 1: lnrpc.SubscribeStateRequest (*SubscribeStateResponse)(nil), // 2: lnrpc.SubscribeStateResponse + (*GetStateRequest)(nil), // 3: lnrpc.GetStateRequest + (*GetStateResponse)(nil), // 4: lnrpc.GetStateResponse } var file_stateservice_proto_depIdxs = []int32{ 0, // 0: lnrpc.SubscribeStateResponse.state:type_name -> lnrpc.WalletState - 1, // 1: lnrpc.State.SubscribeState:input_type -> lnrpc.SubscribeStateRequest - 2, // 2: lnrpc.State.SubscribeState:output_type -> lnrpc.SubscribeStateResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 0, // 1: lnrpc.GetStateResponse.State:type_name -> lnrpc.WalletState + 1, // 2: lnrpc.State.SubscribeState:input_type -> lnrpc.SubscribeStateRequest + 3, // 3: lnrpc.State.GetState:input_type -> lnrpc.GetStateRequest + 2, // 4: lnrpc.State.SubscribeState:output_type -> lnrpc.SubscribeStateResponse + 4, // 5: lnrpc.State.GetState:output_type -> lnrpc.GetStateResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_stateservice_proto_init() } @@ -257,6 +356,30 @@ func file_stateservice_proto_init() { return nil } } + file_stateservice_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_stateservice_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -264,7 +387,7 @@ func file_stateservice_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_stateservice_proto_rawDesc, NumEnums: 1, - NumMessages: 2, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, @@ -294,6 +417,9 @@ type StateClient interface { // SubscribeState subscribes to the state of the wallet. The current wallet // state will always be delivered immediately. SubscribeState(ctx context.Context, in *SubscribeStateRequest, opts ...grpc.CallOption) (State_SubscribeStateClient, error) + // GetState returns the current wallet state without streaming further + // changes. + GetState(ctx context.Context, in *GetStateRequest, opts ...grpc.CallOption) (*GetStateResponse, error) } type stateClient struct { @@ -336,11 +462,23 @@ func (x *stateSubscribeStateClient) Recv() (*SubscribeStateResponse, error) { return m, nil } +func (c *stateClient) GetState(ctx context.Context, in *GetStateRequest, opts ...grpc.CallOption) (*GetStateResponse, error) { + out := new(GetStateResponse) + err := c.cc.Invoke(ctx, "/lnrpc.State/GetState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // StateServer is the server API for State service. type StateServer interface { // SubscribeState subscribes to the state of the wallet. The current wallet // state will always be delivered immediately. SubscribeState(*SubscribeStateRequest, State_SubscribeStateServer) error + // GetState returns the current wallet state without streaming further + // changes. + GetState(context.Context, *GetStateRequest) (*GetStateResponse, error) } // UnimplementedStateServer can be embedded to have forward compatible implementations. @@ -350,6 +488,9 @@ type UnimplementedStateServer struct { func (*UnimplementedStateServer) SubscribeState(*SubscribeStateRequest, State_SubscribeStateServer) error { return status.Errorf(codes.Unimplemented, "method SubscribeState not implemented") } +func (*UnimplementedStateServer) GetState(context.Context, *GetStateRequest) (*GetStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetState not implemented") +} func RegisterStateServer(s *grpc.Server, srv StateServer) { s.RegisterService(&_State_serviceDesc, srv) @@ -376,10 +517,33 @@ func (x *stateSubscribeStateServer) Send(m *SubscribeStateResponse) error { return x.ServerStream.SendMsg(m) } +func _State_GetState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StateServer).GetState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/lnrpc.State/GetState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StateServer).GetState(ctx, req.(*GetStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _State_serviceDesc = grpc.ServiceDesc{ ServiceName: "lnrpc.State", HandlerType: (*StateServer)(nil), - Methods: []grpc.MethodDesc{}, + Methods: []grpc.MethodDesc{ + { + MethodName: "GetState", + Handler: _State_GetState_Handler, + }, + }, Streams: []grpc.StreamDesc{ { StreamName: "SubscribeState", diff --git a/lnrpc/stateservice.pb.gw.go b/lnrpc/stateservice.pb.gw.go index 74b45a6b..a017ca54 100644 --- a/lnrpc/stateservice.pb.gw.go +++ b/lnrpc/stateservice.pb.gw.go @@ -48,6 +48,24 @@ func request_State_SubscribeState_0(ctx context.Context, marshaler runtime.Marsh } +func request_State_GetState_0(ctx context.Context, marshaler runtime.Marshaler, client StateClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetStateRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_State_GetState_0(ctx context.Context, marshaler runtime.Marshaler, server StateServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetStateRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetState(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterStateHandlerServer registers the http handlers for service State to "mux". // UnaryRPC :call StateServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -60,6 +78,26 @@ func RegisterStateHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return }) + mux.Handle("GET", pattern_State_GetState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_State_GetState_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_State_GetState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -121,13 +159,37 @@ func RegisterStateHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_State_GetState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + 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_State_GetState_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_State_GetState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( pattern_State_SubscribeState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "state", "subscribe"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_State_GetState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "state"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( forward_State_SubscribeState_0 = runtime.ForwardResponseStream + + forward_State_GetState_0 = runtime.ForwardResponseMessage ) diff --git a/lnrpc/stateservice.proto b/lnrpc/stateservice.proto index 07cc8e6f..4bb8c9bd 100644 --- a/lnrpc/stateservice.proto +++ b/lnrpc/stateservice.proto @@ -29,6 +29,10 @@ service State { // state will always be delivered immediately. rpc SubscribeState (SubscribeStateRequest) returns (stream SubscribeStateResponse); + + // GetState returns the current wallet state without streaming further + // changes. + rpc GetState (GetStateRequest) returns (GetStateResponse); } enum WalletState { @@ -46,3 +50,10 @@ message SubscribeStateRequest { message SubscribeStateResponse { WalletState state = 1; } + +message GetStateRequest { +} + +message GetStateResponse { + WalletState State = 1; +} diff --git a/lnrpc/stateservice.swagger.json b/lnrpc/stateservice.swagger.json index 132efffc..766ed3d2 100644 --- a/lnrpc/stateservice.swagger.json +++ b/lnrpc/stateservice.swagger.json @@ -11,6 +11,29 @@ "application/json" ], "paths": { + "/v1/state": { + "get": { + "summary": "GetState returns the current wallet state without streaming further\nchanges.", + "operationId": "GetState", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/lnrpcGetStateResponse" + } + }, + "default": { + "description": "An unexpected error response", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + }, + "tags": [ + "State" + ] + } + }, "/v1/state/subscribe": { "get": { "summary": "SubscribeState subscribes to the state of the wallet. The current wallet\nstate will always be delivered immediately.", @@ -45,6 +68,14 @@ } }, "definitions": { + "lnrpcGetStateResponse": { + "type": "object", + "properties": { + "State": { + "$ref": "#/definitions/lnrpcWalletState" + } + } + }, "lnrpcSubscribeStateResponse": { "type": "object", "properties": { diff --git a/rpcperms/interceptor.go b/rpcperms/interceptor.go index 1d02673a..b4560708 100644 --- a/rpcperms/interceptor.go +++ b/rpcperms/interceptor.go @@ -82,6 +82,7 @@ var ( // The State service must be available at all times, even // before we can check macaroons, so we whitelist it. "/lnrpc.State/SubscribeState": {}, + "/lnrpc.State/GetState": {}, } ) @@ -193,6 +194,31 @@ func (r *InterceptorChain) SetRPCActive() { _ = r.ntfnServer.SendUpdate(r.state) } +// rpcStateToWalletState converts rpcState to lnrpc.WalletState. Returns +// WAITING_TO_START and an error on conversion error. +func rpcStateToWalletState(state rpcState) (lnrpc.WalletState, error) { + const defaultState = lnrpc.WalletState_WAITING_TO_START + var walletState lnrpc.WalletState + + switch state { + case waitingToStart: + walletState = lnrpc.WalletState_WAITING_TO_START + case walletNotCreated: + walletState = lnrpc.WalletState_NON_EXISTING + case walletLocked: + walletState = lnrpc.WalletState_LOCKED + case walletUnlocked: + walletState = lnrpc.WalletState_UNLOCKED + case rpcActive: + walletState = lnrpc.WalletState_RPC_ACTIVE + + default: + return defaultState, fmt.Errorf("unknown wallet state %v", state) + } + + return walletState, nil +} + // SubscribeState subscribes to the state of the wallet. The current wallet // state will always be delivered immediately. // @@ -201,24 +227,14 @@ func (r *InterceptorChain) SubscribeState(req *lnrpc.SubscribeStateRequest, stream lnrpc.State_SubscribeStateServer) error { sendStateUpdate := func(state rpcState) error { - resp := &lnrpc.SubscribeStateResponse{} - switch state { - case waitingToStart: - resp.State = lnrpc.WalletState_WAITING_TO_START - case walletNotCreated: - resp.State = lnrpc.WalletState_NON_EXISTING - case walletLocked: - resp.State = lnrpc.WalletState_LOCKED - case walletUnlocked: - resp.State = lnrpc.WalletState_UNLOCKED - case rpcActive: - resp.State = lnrpc.WalletState_RPC_ACTIVE - - default: - return fmt.Errorf("unknown wallet state %v", state) + walletState, err := rpcStateToWalletState(state) + if err != nil { + return err } - return stream.Send(resp) + return stream.Send(&lnrpc.SubscribeStateResponse{ + State: walletState, + }) } // Subscribe to state updates. @@ -262,6 +278,24 @@ func (r *InterceptorChain) SubscribeState(req *lnrpc.SubscribeStateRequest, } } +// GetState returns he current wallet state. +func (r *InterceptorChain) GetState(_ context.Context, + req *lnrpc.GetStateRequest) (*lnrpc.GetStateResponse, error) { + + r.RLock() + state := r.state + r.RUnlock() + + walletState, err := rpcStateToWalletState(state) + if err != nil { + return nil, err + } + + return &lnrpc.GetStateResponse{ + State: walletState, + }, nil +} + // AddMacaroonService adds a macaroon service to the interceptor. After this is // done every RPC call made will have to pass a valid macaroon to be accepted. func (r *InterceptorChain) AddMacaroonService(svc *macaroons.Service) {