Skip to content

Latest commit

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

lightning-cpp

A C++11 wrapper to build plugins for C-lightning and access its JSON-RPC interface

Installation

This library makes an extensive use of libjson-rpc-cpp. Recommended way is to build it from source (here are Debian instructions but you can find more here) :

apt install libcurl4 libmicrohttpd-dev libjsoncpp-dev libargtable2-dev cmake libhiredis-dev catch libcurl4-openssl-dev
git clone git://github.com/cinemast/libjson-rpc-cpp.git
mkdir -p libjson-rpc-cpp/build
cd libjson-rpc-cpp/build
cmake -DUNIX_DOMAIN_SOCKET_CLIENT=YES .. && make -j8
make install # as root
ldconfig # as root

Then you can install lightningcpp :

git clone git@github.com:darosior/lightningcpp.git
cd lightningcpp
make
su -c "make install"

Usage

RPC wrapper

#include<clightningrpc.h>
#include<iostream>
#include<string>intmain (int argc, char *argv[])
{
CLightningWrapper lightning = CLightningWrapper("/home/darosior/.lightning/lightning-rpc");
std::cout << lightning.getInfo() << std::endl;
return0;
}

Plugin

You can write a plugin by whether inheriting the RpcMethod class :

#include<clightningplugin.h>classHelloworld: publicRpcMethod {
public:Helloworld(): RpcMethod() {
name = "hello";
description = "launch me so that I can greet the world";
}
Json::Value main(Json::Value &params) {
returnJson::Value("Hello world !");
}
};
intmain(int argc, char *argv[]) {
Plugin testPlugin;
Helloworld helloworld;
testPlugin.addMethod(helloworld);
testPlugin.start();
return0;
}

Or you can instanciate an RpcMethod object and set the main function :

#include<clightningplugin.h>
#include<string>intmain(int argc, char *argv[]) {
Plugin testPlugin;
RpcMethod byeworld("bye", "[name]", "Launch me so I can say bye to someone", "I am a long description");
byeworld.setMain([&](Json::Value &params) {
std::string bye = "Bye bye ";
if (!params.empty())
returnJson::Value(bye + params.asString());
returnJson::Value(bye + "world !");
});
testPlugin.addMethod(byeworld);
testPlugin.start();
return0;
}

Options

You can add startup options, for example with the byebye plugin from above :

#include<clightningplugin.h>
#include<string>intmain(int argc, char *argv[]) {
Plugin testPlugin;
testPlugin.addOption("byename", "world", "who to say bye to");
RpcMethod byeworld("bye", "[name]", "Launch me so I can say bye to someone", "A LONG DESC");
byeworld.setMain([&](Json::Value &params) {
std::string bye = "Bye bye ";
if (params.size() == 1)
returnJson::Value(bye + params[0].asString() + " !");
returnJson::Value(bye + testPlugin.getOptionValue("byename").asString() + " !");
});
testPlugin.addMethod(byeworld);
testPlugin.start();
return0;
}

You can use addOption() by whether passing it a Json::Value, or the option name, default value, description, and type (which defaults to string and is not passed in the above example).

Notifications

You can subscribe to lightningd's notifications :

#include<clightningplugin.h>
#include<fstream>classHelloworld: publicRpcMethod {
public:Helloworld(): RpcMethod() {
name = "hello";
description = "launch me so that I can greet the world";
}
Json::Value main(Json::Value &params) {
returnJson::Value("Hello world !");
}
};
voiduselessLogger(Json::Value &params) {
std::ofstream logFile;
logFile.open("log_file.log", std::ios::app);
std::string what = params["warning"]["log"].asString();
logFile << what << std::endl;
logFile.close();
}
intmain(int argc, char *argv[]) {
Plugin testPlugin;
Helloworld helloworld;
testPlugin.addMethod(helloworld);
testPlugin.subscribe("warning", &uselessLogger);
testPlugin.start();
return0;
}

Hooks

You can subscribe to lightningd's hooks (but be sure of what you are doing) :

#include<clightningplugin.h>
#include<fstream>classHelloworld: publicRpcMethod {
public:Helloworld(): RpcMethod() {
name = "hello";
description = "launch me so that I can greet the world";
}
Json::Value main(Json::Value &params) {
returnJson::Value("Hello world !");
}
};
Json::Value dbDump(Json::Value &params) {
std::ofstream logFile;
logFile.open("db.log", std::ios::app);
std::string operation = params["writes"][0].asString();
logFile << operation << std::endl;
logFile.close();
returnJson::Value(true);
}
intmain(int argc, char *argv[]) {
Plugin testPlugin;
Helloworld helloworld;
testPlugin.addMethod(helloworld);
testPlugin.hookSubscribe("db_write", &dbDump);
testPlugin.start();
return0;
}

Design

Brief

Highly inspired by Christian Decker's pylightning.

Rpc wrapper

The RPC wrapper is just a class (CLightningRpc) with methods wrapping lightningd's API.

Plugin interface

There are 2 classes for the Plugin management : Plugin and RpcMethod. Every RPC method added to lightningd must be an instance of RpcMethod, which is composed of a method's attributes (namely the name, usage, description and long description) and a pointer to the function to be executed when the method is called through lightningd.

This pointer defaults to the main(Json::Value&) function of the same class.
Any method's main function must take a Json::Value object as parameter and return a Json::Value.
You can assign it after instanciation with the setMain() method (as per examples above).

More about C-lightning plugins

You can find more about C-lightning plugins :

Plugins in other languages :

LICENCE

BSD 3-clause clear

About

C-lightning plugins and RPC library

Topics

Resources

Stars

7 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages