Skip to content

Commit b5b907f

Browse files
committed
add clnrest object to plugin manifest
1 parent f77d4d7 commit b5b907f

File tree

14 files changed

+427
-131
lines changed

14 files changed

+427
-131
lines changed

.msggen.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,10 +1462,17 @@
14621462
},
14631463
"HelpHelp": {
14641464
"Help.help[].category": 2,
1465+
"Help.help[].clnrest": 5,
14651466
"Help.help[].command": 1,
14661467
"Help.help[].description": 3,
14671468
"Help.help[].verbose": 4
14681469
},
1470+
"HelpHelpClnrest": {
1471+
"Help.help[].clnrest.content_type": 3,
1472+
"Help.help[].clnrest.method": 2,
1473+
"Help.help[].clnrest.path": 1,
1474+
"Help.help[].clnrest.rune": 4
1475+
},
14691476
"HelpRequest": {
14701477
"Help.command": 1
14711478
},
@@ -6184,6 +6191,26 @@
61846191
"added": "pre-v0.10.1",
61856192
"deprecated": null
61866193
},
6194+
"Help.help[].clnrest": {
6195+
"added": "v24.08",
6196+
"deprecated": null
6197+
},
6198+
"Help.help[].clnrest.content_type": {
6199+
"added": "v24.08",
6200+
"deprecated": null
6201+
},
6202+
"Help.help[].clnrest.method": {
6203+
"added": "v24.08",
6204+
"deprecated": null
6205+
},
6206+
"Help.help[].clnrest.path": {
6207+
"added": "v24.08",
6208+
"deprecated": null
6209+
},
6210+
"Help.help[].clnrest.rune": {
6211+
"added": "v24.08",
6212+
"deprecated": null
6213+
},
61876214
"Help.help[].command": {
61886215
"added": "pre-v0.10.1",
61896216
"deprecated": null

cln-grpc/proto/node.proto

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cln-grpc/src/convert.rs

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cln-rpc/src/model.rs

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/msggen/msggen/schema.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12779,6 +12779,34 @@
1277912779
"description": [
1278012780
"The command."
1278112781
]
12782+
},
12783+
"clnrest": {
12784+
"type": "object",
12785+
"additionalProperties": false,
12786+
"required": [],
12787+
"added": "v24.08",
12788+
"properties": {
12789+
"path": {
12790+
"type": "string",
12791+
"description": "the path to the HTTP endpoint for this command",
12792+
"added": "v24.08"
12793+
},
12794+
"method": {
12795+
"type": "string",
12796+
"description": "the HTTP method for this command",
12797+
"added": "v24.08"
12798+
},
12799+
"content_type": {
12800+
"type": "string",
12801+
"description": "http content-type that clnrest should return",
12802+
"added": "v24.08"
12803+
},
12804+
"rune": {
12805+
"type": "boolean",
12806+
"description": "whether or not this command requires a rune for authentication",
12807+
"added": "v24.08"
12808+
}
12809+
}
1278212810
}
1278312811
}
1278412812
}

contrib/pyln-client/pyln/client/plugin.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from dataclasses import dataclass
1313
from enum import Enum
1414
from threading import RLock
15-
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
15+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union, TypedDict
1616

1717
from .lightning import LightningRpc, Millisatoshi
1818

@@ -37,6 +37,11 @@ class RequestState(Enum):
3737
FINISHED = 'finished'
3838
FAILED = 'failed'
3939

40+
class CLNRestData(TypedDict):
41+
path: str
42+
method: str
43+
content_type: str
44+
rune: bool
4045

4146
class Method(object):
4247
"""Description of methods that are registered with the plugin.
@@ -49,7 +54,8 @@ class Method(object):
4954
def __init__(self, name: str, func: Callable[..., JSONType],
5055
mtype: MethodType = MethodType.RPCMETHOD,
5156
category: str = None, desc: str = None,
52-
long_desc: str = None, deprecated: Union[bool, List[str]] = None):
57+
long_desc: str = None, deprecated: Union[bool, List[str]] = None,
58+
clnrest_data: CLNRestData = None):
5359
self.name = name
5460
self.func = func
5561
self.mtype = mtype
@@ -60,6 +66,7 @@ def __init__(self, name: str, func: Callable[..., JSONType],
6066
self.deprecated = deprecated
6167
self.before: List[str] = []
6268
self.after: List[str] = []
69+
self.clnrest = clnrest_data
6370

6471

6572
class RpcException(Exception):
@@ -330,7 +337,8 @@ def add_method(self, name: str, func: Callable[..., Any],
330337
category: Optional[str] = None,
331338
desc: Optional[str] = None,
332339
long_desc: Optional[str] = None,
333-
deprecated: Optional[Union[bool, List[str]]] = None) -> None:
340+
deprecated: Optional[Union[bool, List[str]]] = None,
341+
clnrest_data: CLNRestData = None) -> None:
334342
"""Add a plugin method to the dispatch table.
335343
336344
The function will be expected at call time (see `_dispatch`)
@@ -372,7 +380,7 @@ def add_method(self, name: str, func: Callable[..., Any],
372380
# Register the function with the name
373381
method = Method(
374382
name, func, MethodType.RPCMETHOD, category, desc, long_desc,
375-
deprecated
383+
deprecated, clnrest_data
376384
)
377385

378386
method.background = background
@@ -491,22 +499,24 @@ def get_option(self, name: str) -> Optional[Any]:
491499
def async_method(self, method_name: str, category: Optional[str] = None,
492500
desc: Optional[str] = None,
493501
long_desc: Optional[str] = None,
494-
deprecated: Optional[Union[bool, List[str]]] = None) -> NoneDecoratorType:
502+
deprecated: Optional[Union[bool, List[str]]] = None,
503+
clnrest_data: CLNRestData = None) -> NoneDecoratorType:
495504
"""Decorator to add an async plugin method to the dispatch table.
496505
497506
Internally uses add_method.
498507
"""
499508
def decorator(f: Callable[..., None]) -> Callable[..., None]:
500509
self.add_method(method_name, f, background=True, category=category,
501510
desc=desc, long_desc=long_desc,
502-
deprecated=deprecated)
511+
deprecated=deprecated, clnrest_data=clnrest_data)
503512
return f
504513
return decorator
505514

506515
def method(self, method_name: str, category: Optional[str] = None,
507516
desc: Optional[str] = None,
508517
long_desc: Optional[str] = None,
509-
deprecated: Union[bool, List[str]] = None) -> JsonDecoratorType:
518+
deprecated: Union[bool, List[str]] = None,
519+
clnrest_data: Optional[CLNRestData] = None) -> JsonDecoratorType:
510520
"""Decorator to add a plugin method to the dispatch table.
511521
512522
Internally uses add_method.
@@ -518,7 +528,8 @@ def decorator(f: Callable[..., JSONType]) -> Callable[..., JSONType]:
518528
category=category,
519529
desc=desc,
520530
long_desc=long_desc,
521-
deprecated=deprecated)
531+
deprecated=deprecated,
532+
clnrest_data=clnrest_data)
522533
return f
523534
return decorator
524535

@@ -964,6 +975,9 @@ def _getmanifest(self, **kwargs) -> JSONType:
964975
if method.long_desc:
965976
m = methods[len(methods) - 1]
966977
m["long_description"] = method.long_desc
978+
if method.clnrest:
979+
m = methods[len(methods) - 1]
980+
m["clnrest"] = method.clnrest
967981

968982
manifest = {
969983
'options': list(d.json() for d in self.options.values()),

contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py

Lines changed: 110 additions & 108 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/pyln-testing/pyln/testing/grpc2py.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,6 +2636,15 @@ def stop2py(m):
26362636
})
26372637

26382638

2639+
def help_help_clnrest2py(m):
2640+
return remove_default({
2641+
"content_type": m.content_type, # PrimitiveField in generate_composite
2642+
"method": m.method, # PrimitiveField in generate_composite
2643+
"path": m.path, # PrimitiveField in generate_composite
2644+
"rune": m.rune, # PrimitiveField in generate_composite
2645+
})
2646+
2647+
26392648
def help_help2py(m):
26402649
return remove_default({
26412650
"command": m.command, # PrimitiveField in generate_composite

doc/schemas/lightning-help.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,34 @@
3939
"description": [
4040
"The command."
4141
]
42+
},
43+
"clnrest": {
44+
"type": "object",
45+
"additionalProperties": false,
46+
"required": [],
47+
"added": "v24.08",
48+
"properties": {
49+
"path": {
50+
"type": "string",
51+
"description": "the path to the HTTP endpoint for this command",
52+
"added": "v24.08"
53+
},
54+
"method": {
55+
"type": "string",
56+
"description": "the HTTP method for this command",
57+
"added": "v24.08"
58+
},
59+
"content_type": {
60+
"type": "string",
61+
"description": "http content-type that clnrest should return",
62+
"added": "v24.08"
63+
},
64+
"rune": {
65+
"type": "boolean",
66+
"description": "whether or not this command requires a rune for authentication",
67+
"added": "v24.08"
68+
}
69+
}
4270
}
4371
}
4472
}

lightningd/jsonrpc.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,23 @@ static void json_add_help_command(struct command *cmd,
462462
json_command->name));
463463
json_object_start(response, NULL);
464464
json_add_string(response, "command", usage);
465+
466+
if (json_command->clnrest) {
467+
json_object_start(response, "clnrest");
468+
if (json_command->clnrest->method) {
469+
json_add_string(response, "method", json_command->clnrest->method);
470+
}
471+
if (json_command->clnrest->path) {
472+
json_add_string(response, "path", json_command->clnrest->path);
473+
}
474+
if (json_command->clnrest->content_type) {
475+
json_add_string(response, "content_type", json_command->clnrest->content_type);
476+
}
477+
if (json_command->clnrest->rune) {
478+
json_add_bool(response, "rune", *json_command->clnrest->rune);
479+
}
480+
json_object_end(response);
481+
}
465482
json_object_end(response);
466483
}
467484

@@ -1357,14 +1374,39 @@ static void destroy_json_command(struct json_command *command, struct jsonrpc *r
13571374
abort();
13581375
}
13591376

1360-
static bool command_add(struct jsonrpc *rpc, struct json_command *command)
1377+
static bool command_add(struct jsonrpc *rpc, struct json_command *command,
1378+
char **collision_name)
13611379
{
13621380
size_t count = tal_count(rpc->commands);
13631381

13641382
/* Check that we don't clobber a method */
1365-
for (size_t i = 0; i < count; i++)
1366-
if (streq(rpc->commands[i]->name, command->name))
1383+
for (size_t i = 0; i < count; i++) {
1384+
1385+
if (streq(rpc->commands[i]->name, command->name)) {
1386+
if (collision_name) {
1387+
*collision_name =
1388+
tal_strdup(tmpctx, rpc->commands[i]->name);
1389+
}
13671390
return false;
1391+
}
1392+
1393+
/* Check for clnrest conflict */
1394+
if (command->clnrest && rpc->commands[i]->clnrest) {
1395+
bool method_match =
1396+
streq(command->clnrest->method,
1397+
rpc->commands[i]->clnrest->method);
1398+
bool path_match =
1399+
streq(command->clnrest->path,
1400+
rpc->commands[i]->clnrest->path);
1401+
if (method_match && path_match) {
1402+
if (collision_name) {
1403+
*collision_name = tal_strdup(
1404+
tmpctx, rpc->commands[i]->name);
1405+
}
1406+
return false;
1407+
}
1408+
}
1409+
}
13681410

13691411
tal_arr_expand(&rpc->commands, command);
13701412
return true;
@@ -1388,9 +1430,9 @@ static void setup_command_usage(struct lightningd *ld,
13881430
}
13891431

13901432
bool jsonrpc_command_add(struct jsonrpc *rpc, struct json_command *command,
1391-
const char *usage TAKES)
1433+
const char *usage TAKES, char **collision_name)
13921434
{
1393-
if (!command_add(rpc, command))
1435+
if (!command_add(rpc, command, collision_name))
13941436
return false;
13951437
usage = tal_strdup(command, usage);
13961438
strmap_add(&rpc->usagemap, command->name, usage);
@@ -1402,7 +1444,7 @@ static bool jsonrpc_command_add_perm(struct lightningd *ld,
14021444
struct jsonrpc *rpc,
14031445
struct json_command *command)
14041446
{
1405-
if (!command_add(rpc, command))
1447+
if (!command_add(rpc, command, NULL))
14061448
return false;
14071449
setup_command_usage(ld, command);
14081450
return true;

0 commit comments

Comments
 (0)