lnrpc/walletrpc: add new sub-RPC server, the WalletKit

In this commit, we add a new sub-RPC server to the existing set of gRPC
servers. This new sub-RPC server is the WalletKit. It's a utility
toolkit that contains method which allow clients to perform common
interactions with a wallet such as getting a new address, or sending a
transaction. It also includes some supplementary actions such as fee
estimation.

One thing to note in the RPC file is that we _import_ the existing
signer.proto file in order to get at some existing proto definitions
which are useful in our use case.
This commit is contained in:
Olaoluwa Osuntokun 2018-10-24 19:27:44 -07:00
parent 45f49899ae
commit 097b6f7f6d
4 changed files with 684 additions and 0 deletions

@ -376,6 +376,7 @@ func (m *InputScript) GetSigScript() []byte {
}
type InputScriptResp struct {
// / The set of fully valid input scripts requested.
InputScripts []*InputScript `protobuf:"bytes,1,rep,name=input_scripts,json=inputScripts" json:"input_scripts,omitempty"`
}

6
lnrpc/walletrpc/gen_protos.sh Executable file

@ -0,0 +1,6 @@
#!/bin/sh
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
--go_out=plugins=grpc:. \
walletkit.proto

@ -0,0 +1,555 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: walletrpc/walletkit.proto
/*
Package walletrpc is a generated protocol buffer package.
It is generated from these files:
walletrpc/walletkit.proto
It has these top-level messages:
KeyReq
AddrRequest
AddrResponse
Transaction
PublishResponse
SendOutputsRequest
SendOutputsResponse
EstimateFeeRequest
EstimateFeeResponse
*/
package walletrpc
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import signrpc "github.com/lightningnetwork/lnd/lnrpc/signrpc"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type KeyReq struct {
// *
// Is the key finger print of the root pubkey that this request is targeting.
// This allows the WalletKit to possibly serve out keys for multiple HD chains
// via public derivation.
KeyFingerPrint int32 `protobuf:"varint,1,opt,name=key_finger_print,json=keyFingerPrint" json:"key_finger_print,omitempty"`
// *
// The target key family to derive a key from. In other contexts, this is
// known as the "account".
KeyFamily int32 `protobuf:"varint,2,opt,name=key_family,json=keyFamily" json:"key_family,omitempty"`
}
func (m *KeyReq) Reset() { *m = KeyReq{} }
func (m *KeyReq) String() string { return proto.CompactTextString(m) }
func (*KeyReq) ProtoMessage() {}
func (*KeyReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *KeyReq) GetKeyFingerPrint() int32 {
if m != nil {
return m.KeyFingerPrint
}
return 0
}
func (m *KeyReq) GetKeyFamily() int32 {
if m != nil {
return m.KeyFamily
}
return 0
}
type AddrRequest struct {
}
func (m *AddrRequest) Reset() { *m = AddrRequest{} }
func (m *AddrRequest) String() string { return proto.CompactTextString(m) }
func (*AddrRequest) ProtoMessage() {}
func (*AddrRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type AddrResponse struct {
// *
// The address encoded using a bech32 format.
Addr string `protobuf:"bytes,1,opt,name=addr" json:"addr,omitempty"`
}
func (m *AddrResponse) Reset() { *m = AddrResponse{} }
func (m *AddrResponse) String() string { return proto.CompactTextString(m) }
func (*AddrResponse) ProtoMessage() {}
func (*AddrResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *AddrResponse) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
type Transaction struct {
// *
// The raw serialized transaction.
TxHex []byte `protobuf:"bytes,1,opt,name=tx_hex,json=txHex,proto3" json:"tx_hex,omitempty"`
}
func (m *Transaction) Reset() { *m = Transaction{} }
func (m *Transaction) String() string { return proto.CompactTextString(m) }
func (*Transaction) ProtoMessage() {}
func (*Transaction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *Transaction) GetTxHex() []byte {
if m != nil {
return m.TxHex
}
return nil
}
type PublishResponse struct {
// *
// If blank, then no error occurred and the transaction was successfully
// published. If not the empty string, then a string representation of the
// broadcast error.
//
// TODO(roasbeef): map to a proper enum type
PublishError string `protobuf:"bytes,1,opt,name=publish_error,json=publishError" json:"publish_error,omitempty"`
}
func (m *PublishResponse) Reset() { *m = PublishResponse{} }
func (m *PublishResponse) String() string { return proto.CompactTextString(m) }
func (*PublishResponse) ProtoMessage() {}
func (*PublishResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *PublishResponse) GetPublishError() string {
if m != nil {
return m.PublishError
}
return ""
}
type SendOutputsRequest struct {
// *
// The number of satoshis per kilo weight that should be used when crafting
// this transaction.
SatPerKw int64 `protobuf:"varint,1,opt,name=sat_per_kw,json=satPerKw" json:"sat_per_kw,omitempty"`
// *
// A slice of the outputs that should be created in the transaction produced.
Outputs []*signrpc.TxOut `protobuf:"bytes,2,rep,name=outputs" json:"outputs,omitempty"`
}
func (m *SendOutputsRequest) Reset() { *m = SendOutputsRequest{} }
func (m *SendOutputsRequest) String() string { return proto.CompactTextString(m) }
func (*SendOutputsRequest) ProtoMessage() {}
func (*SendOutputsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *SendOutputsRequest) GetSatPerKw() int64 {
if m != nil {
return m.SatPerKw
}
return 0
}
func (m *SendOutputsRequest) GetOutputs() []*signrpc.TxOut {
if m != nil {
return m.Outputs
}
return nil
}
type SendOutputsResponse struct {
// *
// The serialized transaction sent out on the network.
RawTx []byte `protobuf:"bytes,1,opt,name=raw_tx,json=rawTx,proto3" json:"raw_tx,omitempty"`
}
func (m *SendOutputsResponse) Reset() { *m = SendOutputsResponse{} }
func (m *SendOutputsResponse) String() string { return proto.CompactTextString(m) }
func (*SendOutputsResponse) ProtoMessage() {}
func (*SendOutputsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *SendOutputsResponse) GetRawTx() []byte {
if m != nil {
return m.RawTx
}
return nil
}
type EstimateFeeRequest struct {
// *
// The number of confirmations to shoot for when estimating the fee.
ConfTarget int32 `protobuf:"varint,1,opt,name=conf_target,json=confTarget" json:"conf_target,omitempty"`
}
func (m *EstimateFeeRequest) Reset() { *m = EstimateFeeRequest{} }
func (m *EstimateFeeRequest) String() string { return proto.CompactTextString(m) }
func (*EstimateFeeRequest) ProtoMessage() {}
func (*EstimateFeeRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *EstimateFeeRequest) GetConfTarget() int32 {
if m != nil {
return m.ConfTarget
}
return 0
}
type EstimateFeeResponse struct {
// *
// The amount of satoshis per kw that should be used in order to reach the
// confirmation target in the request.
SatPerKw int64 `protobuf:"varint,1,opt,name=sat_per_kw,json=satPerKw" json:"sat_per_kw,omitempty"`
}
func (m *EstimateFeeResponse) Reset() { *m = EstimateFeeResponse{} }
func (m *EstimateFeeResponse) String() string { return proto.CompactTextString(m) }
func (*EstimateFeeResponse) ProtoMessage() {}
func (*EstimateFeeResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *EstimateFeeResponse) GetSatPerKw() int64 {
if m != nil {
return m.SatPerKw
}
return 0
}
func init() {
proto.RegisterType((*KeyReq)(nil), "walletrpc.KeyReq")
proto.RegisterType((*AddrRequest)(nil), "walletrpc.AddrRequest")
proto.RegisterType((*AddrResponse)(nil), "walletrpc.AddrResponse")
proto.RegisterType((*Transaction)(nil), "walletrpc.Transaction")
proto.RegisterType((*PublishResponse)(nil), "walletrpc.PublishResponse")
proto.RegisterType((*SendOutputsRequest)(nil), "walletrpc.SendOutputsRequest")
proto.RegisterType((*SendOutputsResponse)(nil), "walletrpc.SendOutputsResponse")
proto.RegisterType((*EstimateFeeRequest)(nil), "walletrpc.EstimateFeeRequest")
proto.RegisterType((*EstimateFeeResponse)(nil), "walletrpc.EstimateFeeResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for WalletKit service
type WalletKitClient interface {
// *
// DeriveNextKey attempts to derive the *next* key within the key family
// (account in BIP43) specified. This method should return the next external
// child within this branch.
DeriveNextKey(ctx context.Context, in *KeyReq, opts ...grpc.CallOption) (*signrpc.KeyDescriptor, error)
// *
// DeriveKey attempts to derive an arbitrary key specified by the passed
// KeyLocator.
DeriveKey(ctx context.Context, in *signrpc.KeyLocator, opts ...grpc.CallOption) (*signrpc.KeyDescriptor, error)
// *
// NextAddr returns the next unused address within the wallet.
NextAddr(ctx context.Context, in *AddrRequest, opts ...grpc.CallOption) (*AddrResponse, error)
// *
// PublishTransaction attempts to publish the passed transaction to the
// network. Once this returns without an error, the wallet will continually
// attempt to re-broadcast the transaction on start up, until it enters the
// chain.
PublishTransaction(ctx context.Context, in *Transaction, opts ...grpc.CallOption) (*PublishResponse, error)
// *
// SendOutputs is similar to the existing sendmany call in Bitcoind, and
// allows the caller to create a transaction that sends to several outputs at
// once. This is ideal when wanting to batch create a set of transactions.
SendOutputs(ctx context.Context, in *SendOutputsRequest, opts ...grpc.CallOption) (*SendOutputsResponse, error)
// *
// EstimateFee attempts to query the internal fee estimator of the wallet to
// determine the fee (in sat/kw) to attach to a transaction in order to
// achieve the confirmation target.
EstimateFee(ctx context.Context, in *EstimateFeeRequest, opts ...grpc.CallOption) (*EstimateFeeResponse, error)
}
type walletKitClient struct {
cc *grpc.ClientConn
}
func NewWalletKitClient(cc *grpc.ClientConn) WalletKitClient {
return &walletKitClient{cc}
}
func (c *walletKitClient) DeriveNextKey(ctx context.Context, in *KeyReq, opts ...grpc.CallOption) (*signrpc.KeyDescriptor, error) {
out := new(signrpc.KeyDescriptor)
err := grpc.Invoke(ctx, "/walletrpc.WalletKit/DeriveNextKey", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *walletKitClient) DeriveKey(ctx context.Context, in *signrpc.KeyLocator, opts ...grpc.CallOption) (*signrpc.KeyDescriptor, error) {
out := new(signrpc.KeyDescriptor)
err := grpc.Invoke(ctx, "/walletrpc.WalletKit/DeriveKey", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *walletKitClient) NextAddr(ctx context.Context, in *AddrRequest, opts ...grpc.CallOption) (*AddrResponse, error) {
out := new(AddrResponse)
err := grpc.Invoke(ctx, "/walletrpc.WalletKit/NextAddr", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *walletKitClient) PublishTransaction(ctx context.Context, in *Transaction, opts ...grpc.CallOption) (*PublishResponse, error) {
out := new(PublishResponse)
err := grpc.Invoke(ctx, "/walletrpc.WalletKit/PublishTransaction", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *walletKitClient) SendOutputs(ctx context.Context, in *SendOutputsRequest, opts ...grpc.CallOption) (*SendOutputsResponse, error) {
out := new(SendOutputsResponse)
err := grpc.Invoke(ctx, "/walletrpc.WalletKit/SendOutputs", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *walletKitClient) EstimateFee(ctx context.Context, in *EstimateFeeRequest, opts ...grpc.CallOption) (*EstimateFeeResponse, error) {
out := new(EstimateFeeResponse)
err := grpc.Invoke(ctx, "/walletrpc.WalletKit/EstimateFee", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for WalletKit service
type WalletKitServer interface {
// *
// DeriveNextKey attempts to derive the *next* key within the key family
// (account in BIP43) specified. This method should return the next external
// child within this branch.
DeriveNextKey(context.Context, *KeyReq) (*signrpc.KeyDescriptor, error)
// *
// DeriveKey attempts to derive an arbitrary key specified by the passed
// KeyLocator.
DeriveKey(context.Context, *signrpc.KeyLocator) (*signrpc.KeyDescriptor, error)
// *
// NextAddr returns the next unused address within the wallet.
NextAddr(context.Context, *AddrRequest) (*AddrResponse, error)
// *
// PublishTransaction attempts to publish the passed transaction to the
// network. Once this returns without an error, the wallet will continually
// attempt to re-broadcast the transaction on start up, until it enters the
// chain.
PublishTransaction(context.Context, *Transaction) (*PublishResponse, error)
// *
// SendOutputs is similar to the existing sendmany call in Bitcoind, and
// allows the caller to create a transaction that sends to several outputs at
// once. This is ideal when wanting to batch create a set of transactions.
SendOutputs(context.Context, *SendOutputsRequest) (*SendOutputsResponse, error)
// *
// EstimateFee attempts to query the internal fee estimator of the wallet to
// determine the fee (in sat/kw) to attach to a transaction in order to
// achieve the confirmation target.
EstimateFee(context.Context, *EstimateFeeRequest) (*EstimateFeeResponse, error)
}
func RegisterWalletKitServer(s *grpc.Server, srv WalletKitServer) {
s.RegisterService(&_WalletKit_serviceDesc, srv)
}
func _WalletKit_DeriveNextKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(KeyReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).DeriveNextKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/DeriveNextKey",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).DeriveNextKey(ctx, req.(*KeyReq))
}
return interceptor(ctx, in, info, handler)
}
func _WalletKit_DeriveKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(signrpc.KeyLocator)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).DeriveKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/DeriveKey",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).DeriveKey(ctx, req.(*signrpc.KeyLocator))
}
return interceptor(ctx, in, info, handler)
}
func _WalletKit_NextAddr_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddrRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).NextAddr(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/NextAddr",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).NextAddr(ctx, req.(*AddrRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WalletKit_PublishTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Transaction)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).PublishTransaction(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/PublishTransaction",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).PublishTransaction(ctx, req.(*Transaction))
}
return interceptor(ctx, in, info, handler)
}
func _WalletKit_SendOutputs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SendOutputsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).SendOutputs(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/SendOutputs",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).SendOutputs(ctx, req.(*SendOutputsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WalletKit_EstimateFee_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(EstimateFeeRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).EstimateFee(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/EstimateFee",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).EstimateFee(ctx, req.(*EstimateFeeRequest))
}
return interceptor(ctx, in, info, handler)
}
var _WalletKit_serviceDesc = grpc.ServiceDesc{
ServiceName: "walletrpc.WalletKit",
HandlerType: (*WalletKitServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "DeriveNextKey",
Handler: _WalletKit_DeriveNextKey_Handler,
},
{
MethodName: "DeriveKey",
Handler: _WalletKit_DeriveKey_Handler,
},
{
MethodName: "NextAddr",
Handler: _WalletKit_NextAddr_Handler,
},
{
MethodName: "PublishTransaction",
Handler: _WalletKit_PublishTransaction_Handler,
},
{
MethodName: "SendOutputs",
Handler: _WalletKit_SendOutputs_Handler,
},
{
MethodName: "EstimateFee",
Handler: _WalletKit_EstimateFee_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "walletrpc/walletkit.proto",
}
func init() { proto.RegisterFile("walletrpc/walletkit.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 514 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0x55, 0x1b, 0x1a, 0x9a, 0x49, 0x52, 0x60, 0xa3, 0x96, 0x60, 0x51, 0xa8, 0x0c, 0x87, 0x1c,
0x90, 0x23, 0xb5, 0x02, 0xa1, 0x72, 0x42, 0x6a, 0xab, 0x4a, 0xa9, 0x68, 0x30, 0x91, 0xb8, 0x20,
0x59, 0x1b, 0x7b, 0xea, 0xac, 0xe2, 0xec, 0xba, 0xeb, 0x31, 0xb6, 0xff, 0x0f, 0x3f, 0x14, 0xf9,
0x23, 0xc6, 0x21, 0x94, 0x93, 0xd7, 0x6f, 0xde, 0xbc, 0x99, 0xd9, 0x79, 0x0b, 0x2f, 0x12, 0x1e,
0x04, 0x48, 0x3a, 0x74, 0xc7, 0xe5, 0x69, 0x29, 0xc8, 0x0a, 0xb5, 0x22, 0xc5, 0x3a, 0x75, 0xc8,
0x38, 0xf7, 0x05, 0x2d, 0xe2, 0xb9, 0xe5, 0xaa, 0xd5, 0x38, 0x10, 0xfe, 0x82, 0xa4, 0x90, 0xbe,
0x44, 0x4a, 0x94, 0x5e, 0x8e, 0x03, 0xe9, 0x8d, 0x03, 0x99, 0x2b, 0x44, 0xc2, 0xaf, 0xbf, 0xa8,
0x4b, 0x19, 0xf3, 0x2b, 0xb4, 0x27, 0x98, 0xd9, 0x78, 0xcf, 0x46, 0xf0, 0x74, 0x89, 0x99, 0x73,
0x27, 0xa4, 0x8f, 0xda, 0x09, 0xb5, 0x90, 0x34, 0xdc, 0x39, 0xd9, 0x19, 0xed, 0xd9, 0x07, 0x4b,
0xcc, 0xae, 0x0a, 0x78, 0x9a, 0xa3, 0xec, 0x18, 0xa0, 0x60, 0xf2, 0x95, 0x08, 0xb2, 0xe1, 0x6e,
0xc1, 0xe9, 0xe4, 0x9c, 0x02, 0x30, 0xfb, 0xd0, 0xfd, 0xec, 0x79, 0xda, 0xc6, 0xfb, 0x18, 0x23,
0x32, 0x4d, 0xe8, 0x95, 0xbf, 0x51, 0xa8, 0x64, 0x84, 0x8c, 0xc1, 0x23, 0xee, 0x79, 0xba, 0xd0,
0xee, 0xd8, 0xc5, 0xd9, 0x7c, 0x0b, 0xdd, 0x99, 0xe6, 0x32, 0xe2, 0x2e, 0x09, 0x25, 0xd9, 0x21,
0xb4, 0x29, 0x75, 0x16, 0x98, 0x16, 0xa4, 0x9e, 0xbd, 0x47, 0xe9, 0x35, 0xa6, 0xe6, 0x07, 0x78,
0x32, 0x8d, 0xe7, 0x81, 0x88, 0x16, 0xb5, 0xd8, 0x1b, 0xe8, 0x87, 0x25, 0xe4, 0xa0, 0xd6, 0x6a,
0xad, 0xda, 0xab, 0xc0, 0xcb, 0x1c, 0x33, 0x7f, 0x00, 0xfb, 0x86, 0xd2, 0xbb, 0x8d, 0x29, 0x8c,
0x29, 0xaa, 0xfa, 0x62, 0x2f, 0x01, 0x22, 0x4e, 0x4e, 0x88, 0xda, 0x59, 0x26, 0x45, 0x5e, 0xcb,
0xde, 0x8f, 0x38, 0x4d, 0x51, 0x4f, 0x12, 0x36, 0x82, 0xc7, 0xaa, 0xe4, 0x0f, 0x77, 0x4f, 0x5a,
0xa3, 0xee, 0xe9, 0x81, 0x55, 0xdd, 0x9f, 0x35, 0x4b, 0x6f, 0x63, 0xb2, 0xd7, 0x61, 0xf3, 0x1d,
0x0c, 0x36, 0xd4, 0xab, 0xce, 0x0e, 0xa1, 0xad, 0x79, 0xe2, 0x50, 0x3d, 0x83, 0xe6, 0xc9, 0x2c,
0x35, 0xdf, 0x03, 0xbb, 0x8c, 0x48, 0xac, 0x38, 0xe1, 0x15, 0xe2, 0xba, 0x97, 0xd7, 0xd0, 0x75,
0x95, 0xbc, 0x73, 0x88, 0x6b, 0x1f, 0xd7, 0xd7, 0x0e, 0x39, 0x34, 0x2b, 0x10, 0xf3, 0x0c, 0x06,
0x1b, 0x69, 0x55, 0x91, 0xff, 0xce, 0x70, 0xfa, 0xab, 0x05, 0x9d, 0xef, 0x85, 0x4b, 0x26, 0x82,
0xd8, 0x39, 0xf4, 0x2f, 0x50, 0x8b, 0x9f, 0xf8, 0x05, 0x53, 0x9a, 0x60, 0xc6, 0x9e, 0x59, 0xb5,
0x85, 0xac, 0xd2, 0x03, 0xc6, 0x51, 0x3d, 0xe4, 0x04, 0xb3, 0x0b, 0x8c, 0x5c, 0x2d, 0x42, 0x52,
0x9a, 0x7d, 0x84, 0x4e, 0x99, 0x9b, 0xe7, 0x0d, 0x9a, 0xa4, 0x1b, 0xe5, 0x72, 0x52, 0xfa, 0xc1,
0xcc, 0x4f, 0xb0, 0x9f, 0xd7, 0xcb, 0x1d, 0xc0, 0x8e, 0x1a, 0x05, 0x1b, 0x0e, 0x31, 0x9e, 0x6f,
0xe1, 0xd5, 0x78, 0xd7, 0xc0, 0xaa, 0x85, 0x37, 0xdd, 0xd1, 0x94, 0x69, 0xe0, 0x86, 0xd1, 0xc0,
0xff, 0xf6, 0xc9, 0x0d, 0x74, 0x1b, 0x4b, 0x62, 0xc7, 0x0d, 0xea, 0xb6, 0x35, 0x8c, 0x57, 0x0f,
0x85, 0xff, 0xa8, 0x35, 0xb6, 0xb1, 0xa1, 0xb6, 0xbd, 0xdc, 0x0d, 0xb5, 0x7f, 0x2c, 0x71, 0xde,
0x2e, 0x5e, 0xe2, 0xd9, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xad, 0xc3, 0xe0, 0x58, 0xed, 0x03,
0x00, 0x00,
}

@ -0,0 +1,122 @@
syntax = "proto3";
import "github.com/lightningnetwork/lnd/lnrpc/signrpc/signer.proto";
package walletrpc;
message KeyReq {
/**
Is the key finger print of the root pubkey that this request is targeting.
This allows the WalletKit to possibly serve out keys for multiple HD chains
via public derivation.
*/
int32 key_finger_print = 1;
/**
The target key family to derive a key from. In other contexts, this is
known as the "account".
*/
int32 key_family = 2;
}
message AddrRequest{
// No fields, as we always give out a p2wkh address.
}
message AddrResponse {
/**
The address encoded using a bech32 format.
*/
string addr = 1;
}
message Transaction {
/**
The raw serialized transaction.
*/
bytes tx_hex = 1;
}
message PublishResponse {
/**
If blank, then no error occurred and the transaction was successfully
published. If not the empty string, then a string representation of the
broadcast error.
TODO(roasbeef): map to a proper enum type
*/
string publish_error = 1;
}
message SendOutputsRequest {
/**
The number of satoshis per kilo weight that should be used when crafting
this transaction.
*/
int64 sat_per_kw = 1;
/**
A slice of the outputs that should be created in the transaction produced.
*/
repeated signrpc.TxOut outputs = 2;
}
message SendOutputsResponse {
/**
The serialized transaction sent out on the network.
*/
bytes raw_tx = 1;
}
message EstimateFeeRequest {
/**
The number of confirmations to shoot for when estimating the fee.
*/
int32 conf_target = 1;
}
message EstimateFeeResponse {
/**
The amount of satoshis per kw that should be used in order to reach the
confirmation target in the request.
*/
int64 sat_per_kw = 1;
}
service WalletKit {
/**
DeriveNextKey attempts to derive the *next* key within the key family
(account in BIP43) specified. This method should return the next external
child within this branch.
*/
rpc DeriveNextKey(KeyReq) returns (signrpc.KeyDescriptor);
/**
DeriveKey attempts to derive an arbitrary key specified by the passed
KeyLocator.
*/
rpc DeriveKey(signrpc.KeyLocator) returns (signrpc.KeyDescriptor);
/**
NextAddr returns the next unused address within the wallet.
*/
rpc NextAddr(AddrRequest) returns (AddrResponse);
/**
PublishTransaction attempts to publish the passed transaction to the
network. Once this returns without an error, the wallet will continually
attempt to re-broadcast the transaction on start up, until it enters the
chain.
*/
rpc PublishTransaction(Transaction) returns (PublishResponse);
/**
SendOutputs is similar to the existing sendmany call in Bitcoind, and
allows the caller to create a transaction that sends to several outputs at
once. This is ideal when wanting to batch create a set of transactions.
*/
rpc SendOutputs(SendOutputsRequest) returns (SendOutputsResponse);
/**
EstimateFee attempts to query the internal fee estimator of the wallet to
determine the fee (in sat/kw) to attach to a transaction in order to
achieve the confirmation target.
*/
rpc EstimateFee(EstimateFeeRequest) returns (EstimateFeeResponse);
}