2018-11-06 04:12:43 +01:00
# Plugins
Plugins are a simple yet powerful way to extend the functionality
provided by c-lightning. They are subprocesses that are started by the
main `lightningd` daemon and can interact with `lightningd` in a
variety of ways:
- **Command line option passthrough** allows plugins to register their
own command line options that are exposed through `lightningd` so
that only the main process needs to be configured.
- **JSON-RPC command passthrough** adds a way for plugins to add their
own commands to the JSON-RPC interface.
- **Event stream subscriptions** provide plugins with a push-based
notification mechanism about events from the `lightningd` .
- **Hooks** are a primitive that allows plugins to be notified about
internal events in `lightningd` and alter its behavior or inject
custom behaviors.
2019-01-11 06:51:08 +01:00
*Note: Hooks are not yet implemented, and the API is under active development.*
2018-11-06 04:12:43 +01:00
A plugin may be written in any language, and communicates with
`lightningd` through the plugin's `stdin` and `stdout` . JSON-RPCv2 is
used as protocol on top of the two streams, with the plugin acting as
2018-12-06 18:37:48 +01:00
server and `lightningd` acting as client. The plugin file needs to be
executable (e.g. use `chmod a+x plugin_name` )
2018-11-06 04:12:43 +01:00
## A day in the life of a plugin
During startup of `lightningd` you can use the `--plugin=` option to
2018-12-06 18:46:54 +01:00
register one or more plugins that should be started. In case you wish
to start several plugins you have to use the `--plugin=` argument
once for each plugin. An example call might look like:
```
lightningd --plugin=/path/to/plugin1 --plugin=path/to/plugin2
```
`lightningd` will write JSON-RPC requests to the plugin's `stdin` and
will read replies from its `stdout` . To initialize the plugin two RPC
methods are required:
2018-11-06 04:12:43 +01:00
- `getmanifest` asks the plugin for command line options and JSON-RPC
commands that should be passed through
- `init` is called after the command line options have been
parsed and passes them through with the real values. This is also
the signal that `lightningd` 's JSON-RPC over Unix Socket is now up
and ready to receive incoming requests from the plugin.
Once those two methods were called `lightningd` will start passing
through incoming JSON-RPC commands that were registered and the plugin
may interact with `lightningd` using the JSON-RPC over Unix-Socket
interface.
### The `getmanifest` method
The `getmanifest` method is required for all plugins and will be called on
startup without any params. It MUST return a JSON object similar to
this example:
```json
{
"options": [
{
"name": "greeting",
"type": "string",
"default": "World",
"description": "What name should I call you?"
}
],
"rpcmethods": [
{
"name": "hello",
2019-02-05 01:44:16 +01:00
"usage": "[name]",
2018-11-06 04:12:43 +01:00
"description": "Returns a personalized greeting for {greeting} (set via options)."
},
{
"name": "gettime",
2019-02-05 01:44:16 +01:00
"usage": "",
2018-11-06 04:12:43 +01:00
"description": "Returns the current time in {timezone}",
2018-11-21 21:57:50 +01:00
"long_description": "Returns the current time in the timezone that is given as the only parameter.\nThis description may be quite long and is allowed to span multiple lines."
2018-11-06 04:12:43 +01:00
}
2018-12-13 17:14:54 +01:00
],
"subscriptions": [
"connect",
"disconnect"
2018-11-06 04:12:43 +01:00
]
}
```
The `options` will be added to the list of command line options that
`lightningd` accepts. The above will add a `--greeting` option with a
default value of `World` and the specified description. *Notice that
currently only string options are supported.*
The `rpcmethods` are methods that will be exposed via `lightningd` 's
JSON-RPC over Unix-Socket interface, just like the builtin
commands. Any parameters given to the JSON-RPC calls will be passed
2019-02-05 01:44:16 +01:00
through verbatim. Notice that the `name` , `description` and `usage` fields
2018-11-29 15:56:12 +01:00
are mandatory, while the `long_description` can be omitted (it'll be
2019-02-05 01:44:16 +01:00
set to `description` if it was not provided). `usage` should surround optional
parameter names in `[]` .
2018-11-29 15:56:12 +01:00
Plugins are free to register any `name` for their `rpcmethod` as long
as the name was not previously registered. This includes both built-in
methods, such as `help` and `getinfo` , as well as methods registered
by other plugins. If there is a conflict then `lightningd` will report
an error and exit.
2018-11-06 04:12:43 +01:00
### The `init` method
The `init` method is required so that `lightningd` can pass back the
filled command line options and notify the plugin that `lightningd` is
now ready to receive JSON-RPC commands. The `params` of the call are a
simple JSON object containing the options:
```json
{
2018-12-13 17:14:54 +01:00
"options": {
2018-11-06 04:12:43 +01:00
"greeting": "World"
2018-12-13 17:14:54 +01:00
},
"configuration": {
"lightning-dir": "/home/user/.lightning",
"rpc-file": "lightning-rpc"
2018-11-06 04:12:43 +01:00
}
}
```
The plugin must respond to `init` calls, however the response can be
arbitrary and will currently be discarded by `lightningd` . JSON-RPC
commands were chosen over notifications in order not to force plugins
to implement notifications which are not that well supported.
2018-12-13 17:14:54 +01:00
## JSON-RPC passthrough
2018-11-06 04:12:43 +01:00
2018-12-13 17:14:54 +01:00
Plugins may register their own JSON-RPC methods that are exposed
through the JSON-RPC provided by `lightningd` . This provides users
with a single interface to interact with, while allowing the addition
of custom methods without having to modify the daemon itself.
JSON-RPC methods are registered as part of the `getmanifest`
result. Each registered method must provide a `name` and a
`description` . An optional `long_description` may also be
provided. This information is then added to the internal dispatch
table, and used to return the help text when using `lightning-cli
help`, and the methods can be called using the `name` .
For example the above `getmanifest` result will register two methods,
called `hello` and `gettime` :
```json
...
"rpcmethods": [
{
"name": "hello",
2019-02-05 01:44:16 +01:00
"usage": "[name]",
2018-12-13 17:14:54 +01:00
"description": "Returns a personalized greeting for {greeting} (set via options)."
},
{
"name": "gettime",
"description": "Returns the current time in {timezone}",
2019-02-05 01:44:16 +01:00
"usage": "",
2018-12-13 17:14:54 +01:00
"long_description": "Returns the current time in the timezone that is given as the only parameter.\nThis description may be quite long and is allowed to span multiple lines."
}
],
...
```
The RPC call will be passed through unmodified, with the exception of
the JSON-RPC call `id` , which is internally remapped to a unique
integer instead, in order to avoid collisions. When passing the result
back the `id` field is restored to its original value.
## Event notifications
2018-11-06 04:12:43 +01:00
2018-12-13 17:14:54 +01:00
Event notifications allow a plugin to subscribe to events in
`lightningd` . `lightningd` will then send a push notification if an
event matching the subscription occurred. A notification is defined in
the JSON-RPC [specification][jsonrpc-spec] as an RPC call that does
not include an `id` parameter:
> A Notification is a Request object without an "id" member. A Request
> object that is a Notification signifies the Client's lack of
> interest in the corresponding Response object, and as such no
> Response object needs to be returned to the client. The Server MUST
> NOT reply to a Notification, including those that are within a batch
> request.
>
> Notifications are not confirmable by definition, since they do not
> have a Response object to be returned. As such, the Client would not
> be aware of any errors (like e.g. "Invalid params","Internal
> error").
Plugins subscribe by returning an array of subscriptions as part of
the `getmanifest` response. The result for the `getmanifest` call
above for example subscribes to the two topics `connect` and
`disconnect` . The topics that are currently defined and the
corresponding payloads are listed below.
### Notification Types
#### `connect`
A notification for topic `connect` is sent every time a new connection
to a peer is established.
```json
{
"id": "02f6725f9c1c40333b67faea92fd211c183050f28df32cac3f9d69685fe9665432",
"address": "1.2.3.4"
}
```
#### `disconnect`
A notification for topic `disconnect` is sent every time a connection
to a peer was lost.
```json
{
"id": "02f6725f9c1c40333b67faea92fd211c183050f28df32cac3f9d69685fe9665432"
}
```
2018-11-06 04:12:43 +01:00
## Hooks
*TBD*
2018-12-13 17:14:54 +01:00
[jsonrpc-spec]: https://www.jsonrpc.org/specification
[jsonrpc-notification-spec]: https://www.jsonrpc.org/specification#notification