REST APIs for c-lightning written in Node.js
Docker image: https://hub.docker.com/repository/docker/saubyk/c-lightning-rest
- A node running c-lightning
- Node.js, which can be downloaded here
Download a specific version by following the instructions on the release page
Download from master (not recommended), by following the below steps:
$ git clone https://github.com/saubyk/c-lightning-REST
$ cd c-lightning-REST
$ npm install
The below run time configuration are available, which can be configured either via library specific config file or C-Lightning config
file:
- Port - Port for serving the APIs
- Documentation port - Port for serving the swagger documentation
- Protocol - Http protocol for communication with the REST server. Two options are supported
https
andhttp
(unencrypted and insecure communication between API server and the app) - Execution mode - Control for more detailed log info. The options supported are
test
andproduction
- Lightning-RPC Path - Configure the path where
lightning-rpc
file is located. It will default to standard lightning path if not configured - RPC Command - - Enable additional RPC commands for
/rpc
endpoint
For running the server, rename the file sample-cl-rest-config.json
to cl-rest-config.json
. Following parameters can be configured in the config file:
- PORT (Default:
3001
) - DOCPORT (Default:
4001
) - PROTOCOL (Default:
https
) - EXECMODE (Default:
production
) - LNRPCPATH (Default:
- RPCCOMMANDS (Default:
["*"]
)
If running as a plugin, configure the below options in your c-lightning config
file:
rest-port
rest-docport
rest-protocol
rest-execmode
rest-lnrpcpath
rest-rpc
Defaults are the same as in option # 1 with the exception that rest-rpc
is a comma separated string.
You can choose from the below options to run the API server
$ node cl-rest.js
Access the APIs on the default port 3001 or the port configured in the config file.
Pass arguments when launching lightningd:
$ lightningd --plugin=PATH_TO_PLUGIN [--rest-port=N] [--rest-protocol=http|https] [--rest-execmode=MODE]
E.g. $ lightningd --plugin=/Users/<user>/c-lightning-REST/plugin.js --rest-port=3003
OR
Set plugin
, [rest-port]
, [rest-docport]
, [rest-protocol]
, and [rest-execmode]
in lightningd config
E.g. add below to the config
file in .lightning
folder
plugin=/Users/<user>/c-lightning-REST/plugin.js
rest-port=3002
rest-docport=4001
rest-protocol=https
In case you are running a headless Rpi or a Linux node, you can configure c-lightning-REST as a service.
- Create c-lightning-REST systemd unit and with the following content. Save and exit.
# Raspibolt c-lightning-REST: systemd unit for c-lightning-REST
# /etc/systemd/system/c-lightning-REST.service
[Unit]
Description=c-lightning-REST daemon
Wants=lightningd.service
After=lightningd.service
[Service]
ExecStart=/usr/bin/node <Full path of the c-lightning-REST folder>/cl-rest.js
User=<user>
Restart=always
TimeoutSec=120
RestartSec=30
[Install]
WantedBy=multi-user.target
- enable and start c-lightning-REST
$ sudo systemctl enable c-lightning-REST
$ sudo systemctl start c-lightning-REST
- montior the c-lightning-REST log file in realtime(exit with Ctrl-C)
$ sudo journalctl -f -u c-lightning-REST
With the default config, APIs will be served over https
(a self signed certificate and key will be generated in the certs folder with openssl).
Sample url: https://localhost:3001/v1/getinfo/
Authentication has been implemented with macaroons. Macaroons are bearer tokens, which will be verified by the server.
A file access.macaroon
will be generated in the certs
folder in the application root.
The access.macaroon
has to be read by the requesting application, converted to base64
or hex
, and passed in the header with key value macaroon
.
Encoding Options for passing macaroon in the header:
- Request header:
macaroon
set as the macaroon coverted to base64 string. - Sample code to convert macaroon to base64 string:
var abc = fs.readFileSync (macaroonFile);
var macaroon = Buffer.from(abc).toString("base64");
- Request header:
macaroon
set as the macaroon coverted to hex string andencodingtype
with value set ashex
- Sample code to convert macaroon to hex string:
var abc = fs.readFileSync (macaroonFile);
var macaroon = Buffer.from(abc).toString("hex");
If you need help converting your macaroon to hex format you can use the Node.js script from the Zeus project, found here. Alternatively, if you're running a Unix-based operating system (eg. macOS, Linux) you can run xxd -ps -u -c 1000 /path/to/access.macaroon
to generate your macaroon in hex format.
Sample url for Swagger documentation of APIs: http://localhost:4001/api-docs/
C-Lightning commands covered by this API suite is here
- getinfo (/v1/getinfo) -
GET
: Get node information - listfunds (/v1/listFunds) -
GET
: Returns on-chain funds and channel funds information - getbalance (/v1/getBalance) -
GET
: Returns total, confirmed and unconfirmed on-chain balances - getfees (/v1/getFees) -
GET
: Returns the routing fee collected by the node - signmessage (/v1/utility/signMessage) -
POST
: Creates a digital signature of the message using node's secret key - verifymessage(/v1/utility/verifyMessage) -
GET
: Verifies a signature and the pubkey of the node which signed the message - decode (/v1/utility/decode) -
GET
: Decodes various invoice strings including BOLT12
- newaddr (/v1/newaddr) -
GET
: Generate address for recieving on-chain funds - withdraw (/v1/withdraw) -
POST
: Withdraw on-chain funds to an address
- connect (/v1/peer/connect) -
POST
: Connect with a network peer - listpeers (/v1/peer/listPeers) -
GET
: Returns the list of peers connected with the node - disconnect (/v1/peer/disconnect) -
DEL
: Disconnect from a connected network peer
- fundchannel (/v1/channel/openChannel) -
POST
: Open channel with a connected peer node - listchannels (/v1/channel/listChannels) -
GET
: Get the list of channels open on the node - setchannelfee (/v1/channel/setChannelFee) -
POST
: Update the fee policy for a channel - close (/v1/channel/closeChannel) -
DEL
: Close channel - listforwards (/v1/channel/listForwards) -
GET
: Get the list of forwarded htlcs by the node - localremotebal (/v1/channel/localremotebal) -
GET
: Summarizes local and remote channel balances on the node
- pay (/v1/pay) -
POST
: Pay a bolt11 invoice - listpays (/v1/pay/listPays) -
GET
: List result of payment {bolt11}, or all - listsendpays (/v1/pay/listPayments) -
GET
: List outgoing payments {bolt11}, or all. This api has more detailed output than listpays - decodepay (/v1/pay/decodePay) -
GET
: Decode the bolt11 invoice - keysend (/v1/pay/keysend) -
POST
: Send funds to a node without an invoice
- invoice (/v1/invoice/genInvoice) -
POST
: Generates a bolt11 invoice provided amount in msat, label, description, expiry in seconds (optional) - listinvoices (/v1/invoice/listInvoices) -
GET
: Lists the invoice on the node, for a {label} or all. - delexpiredinvoice (v1/invoice/delExpiredInvoice) -
DEL
: Delete expired invoices. - delinvoice (v1/invoice/delInvoice) -
DEL
: Delete a particular invoice with a label and status.
- getroute (/v1/network/getRoute) -
GET
: List the best route for the payment of [msatoshi] to a lightning node [id] - listnodes (/v1/network/listNode) -
GET
: Lookup node info from the network graph, for a given [pubkey] - listchannels (/v1/network/listChannel) -
GET
: Lookup channel info from the network graph, for a given [short_channel_id] - feerates (/v1/network/feeRates) -
GET
: Lookup fee rates on the network, for a given rate style (perkb
orperkw
) - estimatefees (/v1/network/estimateFees) -
GET
: Get the urgent, normal and slow Bitcoin feerates as sat/kVB.
- offer (/v1/offers/offer) -
POST
: Create an offer - listoffers (/v1/offers/listOffers) -
GET
: Returns a list of all the offers on the node - fetchinvoice (/v1/offers/fetchInvoice) -
POST
: Fetch an invoice for an offer - disableoffer (v1/offers/disableOffer) -
DEL
: Disables an existing offer, so that it cannot be used for future payments
- rpc (/v1/rpc) -
POST
: additional access to RPC comands. Examples of body param for rpc:
{"method": "getinfo}
{"method":"signmessage", "params": ["message"]}
{"method":"mymethod", "params: {"key1": "value1"...}}
PRs are welcome! :-)