fiatjaf / sparko

c-lightning RPC over HTTP with fine-grained permissions, SSE and spark-wallet support
38 stars 12 forks source link
bitcoin c-lightning lightning lightning-wallet lightningd-plugin sse wallet

The sparko plugin.

The famous Spark wallet repackaged as a single-binary lightningd plugin.

This works either as a personal wallet with a nice UI (see link above) or as a full-blown HTTP-RPC bridge to your node that can be used to develop apps.

It has some differences (advantages?) over the original Spark wallet:

How to install

This is distributed as a single binary for your delight (or you can compile it yourself with go get, or ask me for binaries for other systems if you need them).

Download it, call chmod +x <binary> and put it in ~/.lightning/plugins (create that directory if it doesn't exist).

You only need the binary you can get in the releases page, nothing else.

How to use

Just configure the options you want in you ~/.lightning/config file, like the following:

sparko-host=0.0.0.0
sparko-port=9737

# the tls path is just the directory where your self-signed key and certificate are.
# (see below for code snippets that generate them on Linux)
# the path is relative to your lightning-dir, so "sparko-tls" will translate to "~/.lightning/bitcoin/sparko-tls/"
# (you can also use an absolute path)
# if not specified the app will run without TLS (as http://)
sparko-tls-path=sparko-tls

# login credentials for using the wallet app.
# under the hood these are translated into an access key with full access.
# the default login is none, which doesn't allow you to use the wallet app,
#   but you can still use the /rpc endpoint with other keys specified at sparko-keys=
sparko-login=mywalletusername:mywalletpassword

# a list of semicolon-separated pairs of keys:permissions
#   - each possible callable RPC method is a permission.
#   - 'stream' is a special method that gives access to the SSE stream at /stream.
#   - just writing the key and nothing else means that key has all permissions.
#   - keys must be secret and random.
sparko-keys=masterkeythatcandoeverything; secretaccesskeythatcanreadstuff: getinfo, listchannels, listnodes; verysecretkeythatcanpayinvoices: pay; keythatcanlistentoallevents: stream
# for the example above the initialization logs (mixed with lightningd logs) should print something like
2019/09/27 00:48:46 plugin-sparko Keys read: masterkeythatcandoeverything (full-access), secretaccesskeythatcanreadstuff (3 permission), verysecretkeythatcanpayinvoices(1 permission), keythatcanlistentoallevents (1 permission)

To use TLS with a self-signed certificate (https://), generate your certificate first:

mkdir ~/.lightning/bitcoin/sparko-tls
cd ~/.lightning/bitcoin/sparko-tls/
openssl genrsa -out key.pem 2048
openssl req -new -x509 -sha256 -key key.pem -out cert.pem -days 3650

To use a certificate signed by LetsEncrypt, you must be able to bind to ports 80 and 443, which generally requires running as root. Specify options like the following:

sparko-host=sparko.mydomain.com
sparko-tls-path=sparko-letsencrypt
sparko-letsencrypt-email=myemail@gmail.com

Then try to visit http://sparko.mydomain.com/. If all is well you should get redirected to the https:// page, if something is wrong it should appear on the logs.

To expose Sparko over CORS (who knows why), add sparko-allow-cors=true to the config file.

Errors

When starting lightningd, check the logs for errors regarding sparko initialization, they will be prefixed with "plugin-sparko".

Call the HTTP RPC

Replace the following with your actual values:

curl -k https://0.0.0.0:9737/rpc -d '{"method": "pay", "params": ["lnbc..."]}' -H 'X-Access: masterkeythatcandoeverything'

See also a list of client libraries.

Range headers

You can also limit the number of things you're returning. For example, listinvoices and listsendpays tend to get out of hand quickly and you may not want to return all your invoices and payments. You can add a Range header to solve this issue:

curl -k https://0.0.0.0:9737/rpc -d '{"method": "listsendpays"}' -H 'X-Access: masterkeythatcandoeverything' -H 'Range: payments=0-99'

The above means that sparko will take the response it gets from lightningd and slice the array contained in the key "payments" to get values between 0 and 99, i.e., the first 100 payments. You could get the last 50 payments, for example, by passing -H 'Range: payments=-50' and so on. This is method-agnostic (that's why you must supply the payments= parameter), so you can use it on other methods and even methods provided by other plugins.

Listen to events

Sparko exposes a SSE endpoint at /stream that emits all events a plugin may receive, in raw format given by lightningd. In some cases that's what you want when developing applications that must talk to a Lightning node remotely, better than webhooks. There are libraries for listening to Server-Sent Events in all languages. The /stream endpoint requires the stream permission to be accessed.

Client libraries

Polar integration

Open the wallet UI

This is the same code used in Spark wallet.

Visit https://0.0.0.0:9737/. Only available if sparko-login is provided.

Built with github.com/fiatjaf/lightningd-gjson-rpc