I'm trying to build a gRPC client for LND in C++, starting with the WalletBalance function. I've never used gRPC before, and I use make instead of cmake, but according to the documentation this is supposed to be possible. I am using the pkg-config files that get installed with gRPC, but they are not working.
Here is what I've successfully been able to do so far.
- Build gRPC
- Compile lightning.proto
- Compile
lightning.pb.ccandlightning.grpc.pb.cc - Link with
lightning.pb.cc.o(but notlightning.grpc.pb.cc.o)
This is my cpp file:
#include <iostream>
#include <string>
#include <grpcpp/grpcpp.h>
#include "lightning.grpc.pb.h"
#include "lightning.pb.h"
using namespace std;
using namespace lnrpc;
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
class LightningClient
{
private:
unique_ptr<Lightning::Stub> stub_;
public:
LightningClient (shared_ptr<grpc::Channel> channel) : stub_ (Lightning::NewStub (channel)) {}
unsigned long WalletBalance (const string& user)
{
WalletBalanceRequest request;
WalletBalanceResponse reply;
ClientContext context;
Status status = stub_->WalletBalance (&context, request, &reply);
if (status.ok ())
return reply.total_balance ();
else
cout << status.error_code () << ": " << status.error_message () << endl;
return 0;
}
};
int main (int argc, char *argv [])
{
shared_ptr<grpc::Channel> channel;// = CreateChannel ("localhost:10009", grpc::InsecureChannelCredentials ());
return 0;
}
This is my makefile:
lnd-grpc-client : lnd-grpc-client.o lightning.pb.cc.o lightning.grpc.pb.cc.o
g++-10 -pthread -o lnd-grpc-client lnd-grpc-client.o lightning.pb.cc.o `pkg-config --libs --static protobuf`
lightning.grpc.pb.cc.o : lightning.grpc.pb.cc
g++-10 -std=c++20 `pkg-config protobuf --cflags` -c -o lightning.grpc.pb.cc.o lightning.grpc.pb.cc
lightning.pb.cc.o : lightning.pb.cc
g++-10 -std=c++20 `pkg-config protobuf --cflags` -c -o lightning.pb.cc.o lightning.pb.cc
lnd-grpc-client.o : lnd-grpc-client.cpp
g++-10 -std=c++20 `pkg-config protobuf --cflags` -c -o lnd-grpc-client.o lnd-grpc-client.cpp
All of that compiles and links just fine. But I have the CreateChannel function commented out in my cpp file and I am not linking with lightning.grpc.pb.cc.o, both of which would be required if I am to get this working.
If I uncomment the CreateChannel function, it gives me a linker error saying undefined reference to 'grpc::InsecureChannelCredentials()'. But there does not seem to be any pkg-config that solves that problem.
If I try to link with lightning.grpc.pb.cc.o, I get hundreds of linker errors. I can't post all of them, but here are a few:
lightning.grpc.pb.cc:(.text._ZN4grpc5SliceD2Ev[_ZN4grpc5SliceD5Ev]+0x20): undefined reference to 'grpc_slice_unref'
/usr/bin/ld: lightning.grpc.pb.cc.o: in function 'grpc::Slice::Slice(unsigned long)':
lightning.grpc.pb.cc:(.text._ZN4grpc5SliceC2Em[_ZN4grpc5SliceC5Em]+0x32): undefined reference to 'grpc_slice_malloc'
/usr/bin/ld: lightning.grpc.pb.cc.o: in function 'grpc::SliceReferencingString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
lightning.grpc.pb.cc:(.text._ZN4grpc22SliceReferencingStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN4grpc22SliceReferencingStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x50): undefined reference to 'grpc_slice_from_static_buffer'
/usr/bin/ld: lightning.grpc.pb.cc.o: in function 'grpc::ByteBuffer::ByteBuffer(grpc::Slice const*, unsigned long)':
lightning.grpc.pb.cc:(.text._ZN4grpc10ByteBufferC2EPKNS_5SliceEm[_ZN4grpc10ByteBufferC5EPKNS_5SliceEm]+0x27): undefined reference to 'grpc_raw_byte_buffer_create'
/usr/bin/ld: lightning.grpc.pb.cc.o: in function 'grpc::ByteBuffer::~ByteBuffer()':
lightning.grpc.pb.cc:(.text._ZN4grpc10ByteBufferD2Ev[_ZN4grpc10ByteBufferD5Ev]+0x27): undefined reference to 'grpc_byte_buffer_destroy'
/usr/bin/ld: lightning.grpc.pb.cc.o: in function 'grpc::ByteBuffer::Clear()':
lightning.grpc.pb.cc:(.text._ZN4grpc10ByteBuffer5ClearEv[_ZN4grpc10ByteBuffer5ClearEv]+0x27): undefined reference to 'grpc_byte_buffer_destroy'
I tried adding the grpc and grpc++ pkg-config files to my makefile's link command, but that did not solve the problem.
Has anyone actually built a gRPC client for LND in C++? If so, how do you know which libraries to link with and how do you link with them?