From 60936dd0bb9fb5fff013af1789ceafebff5ddd42 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:09:01 +0930 Subject: [PATCH 01/19] Makefile: fix $(FORCE) in sub-Makefiles It needs to be defined before we include them. Signed-off-by: Rusty Russell --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3628bc7347ea..39324e7168e1 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,11 @@ endif default: show-flags all-programs all-test-programs doc-all +ifneq ($(SUPPRESS_GENERATION),1) +FORCE = FORCE +FORCE:: +endif + show-flags: config.vars @$(ECHO) "CC: $(CC) $(CFLAGS) -c -o" @$(ECHO) "LD: $(LINK.o) $(filter-out %.a,$^) $(LOADLIBES) $(EXTERNAL_LDLIBS) $(LDLIBS) -o" @@ -536,11 +541,6 @@ ncc: ${TARGET_DIR}/libwally-core-build/src/libwallycore.la TAGS: $(RM) TAGS; find * -name test -type d -prune -o -name '*.[ch]' -print -o -name '*.py' -print | xargs etags --append -ifneq ($(SUPPRESS_GENERATION),1) -FORCE = FORCE -FORCE:: -endif - ccan/ccan/cdump/tools/cdump-enumstr: ccan/ccan/cdump/tools/cdump-enumstr.o $(CDUMP_OBJS) $(CCAN_OBJS) ALL_PROGRAMS += ccan/ccan/cdump/tools/cdump-enumstr From c268dcd592bce64fb1f9008bbb1b8bbba78fd3d6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:10:01 +0930 Subject: [PATCH 02/19] Makefile: allow postfixes to SHA256STAMP. For markdown, there's no simple comment prefix: we need a postfix too. We also need to use "" since we want to use ' in some of the Makefiles in future when V=1. Signed-off-by: Rusty Russell --- Makefile | 14 +++++++------- doc/Makefile | 2 +- wallet/Makefile | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 39324e7168e1..6480f94768d6 100644 --- a/Makefile +++ b/Makefile @@ -293,30 +293,30 @@ else # Git doesn't maintain timestamps, so we only regen if sources actually changed: # We place the SHA inside some generated files so we can tell if they need updating. # Usage: $(call SHA256STAMP_CHANGED) -SHA256STAMP_CHANGED = [ x"`sed -n 's/.*SHA256STAMP://p' $@ 2>/dev/null`" != x"`cat $(sort $(filter-out FORCE,$^)) | $(SHA256SUM) | cut -c1-64`" ] -# Usage: $(call SHA256STAMP,commentprefix) -SHA256STAMP = echo '$(1) SHA256STAMP:'`cat $(sort $(filter-out FORCE,$^)) | $(SHA256SUM) | cut -c1-64` >> $@ +SHA256STAMP_CHANGED = [ x"`sed -n 's/.*SHA256STAMP:\([a-f0-9]*\).*/\1/p' $@ 2>/dev/null`" != x"`cat $(sort $(filter-out FORCE,$^)) | $(SHA256SUM) | cut -c1-64`" ] +# Usage: $(call SHA256STAMP,commentprefix,commentpostfix) +SHA256STAMP = echo "$(1) SHA256STAMP:"`cat $(sort $(filter-out FORCE,$^)) | $(SHA256SUM) | cut -c1-64`"$(2)" >> $@ endif # generate-wire.py --page [header|impl] hdrfilename wirename < csv > file %_wiregen.h: %_wire.csv $(WIRE_GEN_DEPS) @if $(call SHA256STAMP_CHANGED); then if [ "$$NO_PYTHON" = 1 ]; then echo "Error: NO_PYTHON on $@"; exit 1; fi; \ - $(call VERBOSE,"wiregen $@",tools/generate-wire.py --page header $($@_args) $@ `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//)); \ + $(call VERBOSE,"wiregen $@",tools/generate-wire.py --page header $($@_args) $@ `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//,)); \ fi %_wiregen.c: %_wire.csv $(WIRE_GEN_DEPS) @if $(call SHA256STAMP_CHANGED); then if [ "$$NO_PYTHON" = 1 ]; then echo "Error: NO_PYTHON on $@"; exit 1; fi; \ - $(call VERBOSE,"wiregen $@",tools/generate-wire.py --page impl $($@_args) ${@:.c=.h} `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//)); \ + $(call VERBOSE,"wiregen $@",tools/generate-wire.py --page impl $($@_args) ${@:.c=.h} `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//,)); \ fi %_printgen.h: %_wire.csv $(WIRE_GEN_DEPS) @if $(call SHA256STAMP_CHANGED); then if [ "$$NO_PYTHON" = 1 ]; then echo "Error: NO_PYTHON on $@"; exit 1; fi; \ - $(call VERBOSE,"printgen $@",tools/generate-wire.py -s -P --page header $($@_args) $@ `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//)); \ + $(call VERBOSE,"printgen $@",tools/generate-wire.py -s -P --page header $($@_args) $@ `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//,)); \ fi %_printgen.c: %_wire.csv $(WIRE_GEN_DEPS) @if $(call SHA256STAMP_CHANGED); then if [ "$$NO_PYTHON" = 1 ]; then echo "Error: NO_PYTHON on $@"; exit 1; fi; \ - $(call VERBOSE,"printgen $@",tools/generate-wire.py -s -P --page impl $($@_args) ${@:.c=.h} `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//)); \ + $(call VERBOSE,"printgen $@",tools/generate-wire.py -s -P --page impl $($@_args) ${@:.c=.h} `basename $< .csv | sed 's/_exp_/_/'` < $< > $@ && $(call SHA256STAMP,//,)); \ fi include external/Makefile diff --git a/doc/Makefile b/doc/Makefile index 525c657774c9..a5cb7e2d73ff 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -87,7 +87,7 @@ MANPAGES := doc/lightning-cli.1 \ doc-all: $(MANPAGES) doc/index.rst $(MANPAGES): doc/%: doc/%.md - @if $(call SHA256STAMP_CHANGED); then $(call VERBOSE, "mrkd $<", mrkd $< $@ && $(call SHA256STAMP,\")); else touch $@; fi + @if $(call SHA256STAMP_CHANGED); then $(call VERBOSE, "mrkd $<", mrkd $< $@ && $(call SHA256STAMP,\\\",)); else touch $@; fi $(MANPAGES): $(FORCE) diff --git a/wallet/Makefile b/wallet/Makefile index 705290d7ae2b..a3bcda1da785 100644 --- a/wallet/Makefile +++ b/wallet/Makefile @@ -38,12 +38,12 @@ SQL_FILES := \ wallet/statements_gettextgen.po: $(SQL_FILES) $(FORCE) @if $(call SHA256STAMP_CHANGED); then if [ "$$NO_PYTHON" = 1 ]; then echo "Error: NO_PYTHON on $@"; exit 1; fi; \ - $(call VERBOSE,"xgettext $@",xgettext -kNAMED_SQL -kSQL --add-location --no-wrap --omit-header -o $@ $(SQL_FILES) && $(call SHA256STAMP,# )); \ + $(call VERBOSE,"xgettext $@",xgettext -kNAMED_SQL -kSQL --add-location --no-wrap --omit-header -o $@ $(SQL_FILES) && $(call SHA256STAMP,# ,)); \ fi wallet/db_%_sqlgen.c: wallet/statements_gettextgen.po devtools/sql-rewrite.py $(FORCE) @if $(call SHA256STAMP_CHANGED); then if [ "$$NO_PYTHON" = 1 ]; then echo "Error: NO_PYTHON on $@"; exit 1; fi; \ - $(call VERBOSE,"sql-rewrite $@",devtools/sql-rewrite.py wallet/statements_gettextgen.po $* > $@ && $(call SHA256STAMP,//)); \ + $(call VERBOSE,"sql-rewrite $@",devtools/sql-rewrite.py wallet/statements_gettextgen.po $* > $@ && $(call SHA256STAMP,//,)); \ fi maintainer-clean: wallet-maintainer-clean From 864f0848cf790104da4f687e260af17ff81807c8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:11:01 +0930 Subject: [PATCH 03/19] doc: fix up mangled nroff from mkrd. Nested lists don't work (it puts the .RS at the end of the line instead of on a line by itself), so we sed it. https://github.com/refi64/mrkd/issues/4 This fixes up formatting on a number of existing pages.. Signed-off-by: Rusty Russell --- doc/Makefile | 4 +++- doc/lightning-getinfo.7 | 3 ++- doc/lightning-getlog.7 | 3 ++- doc/lightning-listconfigs.7 | 3 ++- doc/lightning-listnodes.7 | 3 ++- doc/lightning-listpeers.7 | 3 ++- doc/lightning-listtransactions.7 | 6 ++++-- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index a5cb7e2d73ff..abc5bd35c678 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -86,8 +86,10 @@ MANPAGES := doc/lightning-cli.1 \ doc-all: $(MANPAGES) doc/index.rst +# mrkd doesn't format nested lists properly, so we fixup with sed (see doc/lightning-connect.7 +# and https://github.com/refi64/mrkd/issues/4 $(MANPAGES): doc/%: doc/%.md - @if $(call SHA256STAMP_CHANGED); then $(call VERBOSE, "mrkd $<", mrkd $< $@ && $(call SHA256STAMP,\\\",)); else touch $@; fi + @if $(call SHA256STAMP_CHANGED); then $(call VERBOSE, "mrkd $<", mrkd $< $@.tmp && sed -e 's/\(.\)\.RS$$/\1\n.RS/' < $@.tmp > $@ && rm $@.tmp && $(call SHA256STAMP,\\\",)); else touch $@; fi $(MANPAGES): $(FORCE) diff --git a/doc/lightning-getinfo.7 b/doc/lightning-getinfo.7 index 5d1bb242f748..92bab929a7a1 100644 --- a/doc/lightning-getinfo.7 +++ b/doc/lightning-getinfo.7 @@ -40,7 +40,8 @@ On success, an object with the following information is returned: .IP \[bu] \fInum_inactive_channels\fR: A integer that represents the number of channel which are closing\. .IP \[bu] -\fIaddress\fR: An array that represents all published addresses of the node, each object inside the array contains the following proprieties:.RS +\fIaddress\fR: An array that represents all published addresses of the node, each object inside the array contains the following proprieties: +.RS .IP \[bu] \fItype\fR: A string that represents the type of the address (currently \fBipv4\fR, \fBipv6\fR, \fBtorv3\fR or \fBtorv4\fR)\. .IP \[bu] diff --git a/doc/lightning-getlog.7 b/doc/lightning-getlog.7 index 003940c85ebf..13eedfb0471d 100644 --- a/doc/lightning-getlog.7 +++ b/doc/lightning-getlog.7 @@ -39,7 +39,8 @@ On success, a object will be return with the following parameters: .IP \[bu] \fIbytes_max\fR: An integer that represents the max dimension in bytes of log file\. .IP \[bu] -\fIlog\fR: An array of objects where each element contains the following proprieties:.RS +\fIlog\fR: An array of objects where each element contains the following proprieties: +.RS .IP \[bu] \fItype\fR: A string that represents the log level\. The propriety can have an value equal to SKIPPED to indicate the existence of omitted entries\. .IP \[bu] diff --git a/doc/lightning-listconfigs.7 b/doc/lightning-listconfigs.7 index d54182a7f5f9..771a04504ca7 100644 --- a/doc/lightning-listconfigs.7 +++ b/doc/lightning-listconfigs.7 @@ -35,7 +35,8 @@ Additional members include: .IP \[bu] \fI# version\fR: A string that represents the version of node\. .IP \[bu] -\fIplugins\fR: A array that represents the non-important plugin registered\. Each object contains the following members:.RS +\fIplugins\fR: A array that represents the non-important plugin registered\. Each object contains the following members: +.RS .IP \[bu] \fIpath\fR: A string that represents the path of plugin\. .IP \[bu] diff --git a/doc/lightning-listnodes.7 b/doc/lightning-listnodes.7 index 886638a5d8d1..a80ef7b13715 100644 --- a/doc/lightning-listnodes.7 +++ b/doc/lightning-listnodes.7 @@ -45,7 +45,8 @@ are also returned: .IP \[bu] \fIfeatures\fR: A string that represents the features value\. .IP \[bu] -\fIaddresses\fR: An array that represents the addreses avaible\. Each address is represented with an object with the following properties:.RS +\fIaddresses\fR: An array that represents the addreses avaible\. Each address is represented with an object with the following properties: +.RS .IP \[bu] \fItype\fR: A string that represents the address type (ipv4 or ipv6)\. .IP \[bu] diff --git a/doc/lightning-listpeers.7 b/doc/lightning-listpeers.7 index 1e312024079b..04ace1236a24 100644 --- a/doc/lightning-listpeers.7 +++ b/doc/lightning-listpeers.7 @@ -72,7 +72,8 @@ The objects in the \fIchannels\fR array will have at least these fields: .RS .IP \[bu] -\fIstate\fR: Any of these strings:.RS +\fIstate\fR: Any of these strings: +.RS .IP \[bu] \fB"OPENINGD"\fR: The channel funding protocol with the peer is ongoing and both sides are negotiating parameters\. diff --git a/doc/lightning-listtransactions.7 b/doc/lightning-listtransactions.7 index 9355dd788432..f87ff7b9c438 100644 --- a/doc/lightning-listtransactions.7 +++ b/doc/lightning-listtransactions.7 @@ -38,7 +38,8 @@ On success, the command will return a list of transactions, each object represen .IP \[bu] \fIversion\fR: An integer that represents the nVersion field\. .IP \[bu] -\fIinputs\fR: A list of spent transaction outputs, each spent transaction output is represented with an object with the following properties:.RS +\fIinputs\fR: A list of spent transaction outputs, each spent transaction output is represented with an object with the following properties: +.RS .IP \[bu] \fItxid\fR: A string that represents the hash of transaction\. This is the output index of the transaction output being spent\. .IP \[bu] @@ -49,7 +50,8 @@ On success, the command will return a list of transactions, each object represen .RE .IP \[bu] -\fIoutputs\fR: A list of transactions, each transaction is represented with an object with the following proprieties:.RS +\fIoutputs\fR: A list of transactions, each transaction is represented with an object with the following proprieties: +.RS .IP \[bu] \fIindex\fR: An integer that represents the index of transaction\. .IP \[bu] From 9f3191f364e84ac46cab64e4f48f27c8dcc88016 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:12:01 +0930 Subject: [PATCH 04/19] pytest: don't use command_success_str in test_libplugin.c result should *always* be an object. This allows it to add fields without breaking the API. A command which returns "result" as a string is living in sin. This changes one of the two callers of "command_success_str". Signed-off-by: Rusty Russell --- tests/plugins/test_libplugin.c | 2 +- tests/test_plugin.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/plugins/test_libplugin.c b/tests/plugins/test_libplugin.c index 6197116d8303..ef62ab96311b 100644 --- a/tests/plugins/test_libplugin.c +++ b/tests/plugins/test_libplugin.c @@ -22,7 +22,7 @@ static struct command_result *json_helloworld(struct command *cmd, if (!name) name = name_option ? name_option : tal_strdup(tmpctx, "world"); - return command_success_str(cmd, tal_fmt(tmpctx, "hello %s", name)); + return command_success(cmd, json_out_obj(cmd, "hello", name)); } static struct command_result * diff --git a/tests/test_plugin.py b/tests/test_plugin.py index cb3f6fe4d925..212eb7ccebf5 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1412,15 +1412,15 @@ def test_libplugin(node_factory): l1.rpc.check("helloworld") # Test commands - assert l1.rpc.call("helloworld") == "hello world" - assert l1.rpc.call("helloworld", {"name": "test"}) == "hello test" + assert l1.rpc.call("helloworld") == {"hello": "world"} + assert l1.rpc.call("helloworld", {"name": "test"}) == {"hello": "test"} l1.stop() l1.daemon.opts["plugin"] = plugin l1.daemon.opts["name"] = "test_opt" l1.start() - assert l1.rpc.call("helloworld") == "hello test_opt" + assert l1.rpc.call("helloworld") == {"hello": "test_opt"} # But param takes over! - assert l1.rpc.call("helloworld", {"name": "test"}) == "hello test" + assert l1.rpc.call("helloworld", {"name": "test"}) == {"hello": "test"} # Test hooks and notifications l2 = node_factory.get_node() @@ -1460,7 +1460,7 @@ def test_libplugin_deprecated(node_factory): 'name-deprecated': 'test_opt depr', 'allow-deprecated-apis': True}) - assert l1.rpc.call("helloworld") == "hello test_opt depr" + assert l1.rpc.call("helloworld") == {"hello": "test_opt depr"} l1.rpc.help('testrpc-deprecated') assert l1.rpc.call("testrpc-deprecated") == l1.rpc.getinfo() From a1f72d752486ca3cc3d0e209c9f09bdf985e7300 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:13:01 +0930 Subject: [PATCH 05/19] autoclean: don't return a raw string as result. This is hard to parse, and not extensible in future, and disagrees with the man page (and caught by schema). Technically this is an API break, but it can't be done neatly anyway and it's unlikely someone is relying on this today :( Signed-off-by: Rusty Russell Changelog-Changed: JSONRPC: `autocleaninvoice` now returns an object, not a raw string. --- plugins/autoclean.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/autoclean.c b/plugins/autoclean.c index 21f0c8d30c58..3b80815b0a47 100644 --- a/plugins/autoclean.c +++ b/plugins/autoclean.c @@ -39,6 +39,7 @@ static struct command_result *json_autocleaninvoice(struct command *cmd, { u64 *cycle; u64 *exby; + struct json_stream *response; if (!param(cmd, buffer, params, p_opt_def("cycle_seconds", param_u64, &cycle, 3600), @@ -50,18 +51,19 @@ static struct command_result *json_autocleaninvoice(struct command *cmd, expired_by = *exby; if (cycle_seconds == 0) { - tal_free(cleantimer); - return command_success_str(cmd, "Autoclean timer disabled"); + response = jsonrpc_stream_success(cmd); + json_add_bool(response, "enabled", false); + return command_finished(cmd, response); } tal_free(cleantimer); cleantimer = plugin_timer(cmd->plugin, time_from_sec(cycle_seconds), do_clean, cmd->plugin); - return command_success_str(cmd, - tal_fmt(cmd, "Autocleaning %"PRIu64 - "-second old invoices every %"PRIu64 - " seconds", - expired_by, cycle_seconds)); + response = jsonrpc_stream_success(cmd); + json_add_bool(response, "enabled", true); + json_add_u64(response, "cycle_seconds", cycle_seconds); + json_add_u64(response, "expired_by", expired_by); + return command_finished(cmd, response); } static const char *init(struct plugin *p, From 501642da135ba6228539791f442161a3ff1c17e1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:14:01 +0930 Subject: [PATCH 06/19] libplugin: remove command_success_str function. As mentioned in previous commits: "result" must be an object, and anything else is an antipattern. Signed-off-by: Rusty Russell --- plugins/libplugin.c | 17 +---------------- plugins/libplugin.h | 5 ----- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/plugins/libplugin.c b/plugins/libplugin.c index b522dbcaf75d..f28f5be722ed 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -345,21 +345,6 @@ command_success(struct command *cmd, const struct json_out *result) return command_complete(cmd, js); } -struct command_result *WARN_UNUSED_RESULT -command_success_str(struct command *cmd, const char *str) -{ - struct json_stream *js = jsonrpc_stream_start(cmd); - - if (str) - json_add_string(js, "result", str); - else { - /* Use an empty object if they don't want anything. */ - json_object_start(js, "result"); - json_object_end(js); - } - return command_complete(cmd, js); -} - struct command_result *command_done_err(struct command *cmd, errcode_t code, const char *errmsg, @@ -904,7 +889,7 @@ static struct command_result *handle_init(struct command *cmd, if (with_rpc) io_new_conn(p, p->rpc_conn->fd, rpc_conn_init, p); - return command_success_str(cmd, NULL); + return command_success(cmd, json_out_obj(cmd, NULL, NULL)); } char *u64_option(const char *arg, u64 *i) diff --git a/plugins/libplugin.h b/plugins/libplugin.h index a70fa8078b6f..6ae600fd9b90 100644 --- a/plugins/libplugin.h +++ b/plugins/libplugin.h @@ -181,11 +181,6 @@ struct command_result *command_err_raw(struct command *cmd, struct command_result *WARN_UNUSED_RESULT command_success(struct command *cmd, const struct json_out *result); -/* Simple version where we just want to send a string, or NULL means an empty - * result object. @cmd cannot be NULL. */ -struct command_result *WARN_UNUSED_RESULT -command_success_str(struct command *cmd, const char *str); - /* End a hook normally (with "result": "continue") */ struct command_result *WARN_UNUSED_RESULT command_hook_success(struct command *cmd); From 4801c23fe109e7114836f649488b05c3ddb6078a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:15:01 +0930 Subject: [PATCH 07/19] close: add "unopened" type if we simply discard channel. Undocumented (caught by json schema!) if we discard channel because it wasn't open yet, then close returned the empty object. Make it return a new type in this case. Signed-off-by: Rusty Russell Changelog-Added: JSONRPC: `close` returns `type` "unopened" if it simply discards channel instead of empty object. --- lightningd/peer_control.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 93b31c17f045..f1ddbf6cbbfe 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1667,13 +1667,12 @@ static struct command_result *json_close(struct command *cmd, if (uc) { /* Easy case: peer can simply be forgotten. */ kill_uncommitted_channel(uc, "close command called"); - - return command_success(cmd, json_stream_success(cmd)); + goto discard_unopened; } if ((channel = peer_unsaved_channel(peer))) { channel_unsaved_close_conn(channel, "close command called"); - return command_success(cmd, json_stream_success(cmd)); + goto discard_unopened; } return command_fail(cmd, LIGHTNINGD, "Peer has no active channel"); @@ -1833,6 +1832,12 @@ static struct command_result *json_close(struct command *cmd, /* Wait until close drops down to chain. */ return command_still_pending(cmd); + +discard_unopened: { + struct json_stream *result = json_stream_success(cmd); + json_add_string(result, "type", "unopened"); + return command_success(cmd, result); + } } static const struct json_command close_command = { From c1289bf60781891defa9b7c5dda0a5e8e4dd4962 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:16:01 +0930 Subject: [PATCH 08/19] decode: always return "valid" field. Otherwise our schema is pretty meaningless, since invalid decodes can have missing "required" fields. Also fix a typo "blinded_payindo". Signed-off-by: Rusty Russell Changelog-Experimental: JSON-RPC: `decode` now gives a `valid` boolean (it does partial decodes of some invalid data). --- plugins/offers.c | 125 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 35 deletions(-) diff --git a/plugins/offers.c b/plugins/offers.c index 5bf5a5da1a42..fd98b2e13570 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -224,7 +224,8 @@ static void json_add_onionmsg_path(struct json_stream *js, json_object_end(js); } -static void json_add_blinded_paths(struct json_stream *js, +/* Returns true if valid */ +static bool json_add_blinded_paths(struct json_stream *js, struct blinded_path **paths, struct blinded_payinfo **blindedpay) { @@ -250,9 +251,13 @@ static void json_add_blinded_paths(struct json_stream *js, * exactly as many `payinfo` as total `onionmsg_path` in * `blinded_path`. */ - if (blindedpay && n != tal_count(blindedpay)) + if (blindedpay && n != tal_count(blindedpay)) { json_add_string(js, "warning_invoice_invalid_blinded_payinfo", "invoice does not have correct number of blinded_payinfo"); + return false; + } + + return true; } static const char *recurrence_time_unit_name(u8 time_unit) @@ -276,6 +281,7 @@ static const char *recurrence_time_unit_name(u8 time_unit) static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer) { struct sha256 offer_id; + bool valid = true; merkle_tlv(offer->fields, &offer_id); json_add_sha256(js, "offer_id", &offer_id); @@ -312,9 +318,11 @@ static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer json_add_stringn(js, "description", offer->description, tal_bytelen(offer->description)); - else + else { json_add_string(js, "warning_offer_missing_description", "offers without a description are invalid"); + valid = false; + } if (offer->vendor) json_add_stringn(js, "vendor", offer->vendor, @@ -325,7 +333,7 @@ static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer json_add_u64(js, "absolute_expiry", *offer->absolute_expiry); if (offer->paths) - json_add_blinded_paths(js, offer->paths, NULL); + valid &= json_add_blinded_paths(js, offer->paths, NULL); if (offer->quantity_min) json_add_u64(js, "quantity_min", *offer->quantity_min); @@ -363,9 +371,12 @@ static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer /* offer_decode fails if node_id or signature not set */ json_add_pubkey32(js, "node_id", offer->node_id); json_add_bip340sig(js, "signature", offer->signature); + + json_add_bool(js, "valid", valid); } -static void json_add_fallback_address(struct json_stream *js, +/* Returns true if valid */ +static bool json_add_fallback_address(struct json_stream *js, const struct chainparams *chain, u8 version, const u8 *address) { @@ -373,19 +384,23 @@ static void json_add_fallback_address(struct json_stream *js, /* Does extra checks, in particular checks v0 sizes */ if (segwit_addr_encode(out, chain->bip173_name, version, - address, tal_bytelen(address))) + address, tal_bytelen(address))) { json_add_string(js, "address", out); - else - json_add_string(js, - "warning_invoice_fallbacks_address_invalid", - "invalid fallback address for this version"); + return true; + } + json_add_string(js, + "warning_invoice_fallbacks_address_invalid", + "invalid fallback address for this version"); + return false; } -static void json_add_fallbacks(struct json_stream *js, +/* Returns true if valid */ +static bool json_add_fallbacks(struct json_stream *js, const struct bitcoin_blkid *chains, struct fallback_address **fallbacks) { const struct chainparams *chain; + bool valid = true; /* Present address as first chain mentioned. */ if (tal_count(chains) != 0) @@ -414,23 +429,29 @@ static void json_add_fallbacks(struct json_stream *js, json_add_string(js, "warning_invoice_fallbacks_version_invalid", "invoice fallback version > 16"); + valid = false; } else if (addrlen < 2 || addrlen > 40) { json_add_string(js, "warning_invoice_fallbacks_address_invalid", "invoice fallback address bad length"); + valid = false; } else if (chain) { - json_add_fallback_address(js, chain, - fallbacks[i]->version, - fallbacks[i]->address); + valid &= json_add_fallback_address(js, chain, + fallbacks[i]->version, + fallbacks[i]->address); } json_object_end(js); } json_array_end(js); + + return valid; } static void json_add_b12_invoice(struct json_stream *js, const struct tlv_invoice *invoice) { + bool valid = true; + if (invoice->chains) json_add_chains(js, invoice->chains); if (invoice->offer_id) @@ -442,9 +463,11 @@ static void json_add_b12_invoice(struct json_stream *js, if (invoice->amount) json_add_amount_msat_only(js, "amount_msat", amount_msat(*invoice->amount)); - else + else { json_add_string(js, "warning_invoice_missing_amount", "invoices without an amount are invalid"); + valid = false; + } /* BOLT-offers #12: * - MUST reject the invoice if `description` is not present. @@ -452,9 +475,12 @@ static void json_add_b12_invoice(struct json_stream *js, if (invoice->description) json_add_stringn(js, "description", invoice->description, tal_bytelen(invoice->description)); - else + else { json_add_string(js, "warning_invoice_missing_description", "invoices without a description are invalid"); + valid = false; + } + if (invoice->vendor) json_add_stringn(js, "vendor", invoice->vendor, tal_bytelen(invoice->vendor)); @@ -469,10 +495,12 @@ static void json_add_b12_invoice(struct json_stream *js, * contain exactly as many `payinfo` as total `onionmsg_path` * in `blinded_path`. */ - if (!invoice->blindedpay) + if (!invoice->blindedpay) { json_add_string(js, "warning_invoice_missing_blinded_payinfo", - "invoices with blinded_path without blinded_payindo are invalid"); - json_add_blinded_paths(js, invoice->paths, invoice->blindedpay); + "invoices with blinded_path without blinded_payinfo are invalid"); + valid = false; + } + valid &= json_add_blinded_paths(js, invoice->paths, invoice->blindedpay); } if (invoice->quantity) json_add_u64(js, "quantity", *invoice->quantity); @@ -494,9 +522,11 @@ static void json_add_b12_invoice(struct json_stream *js, if (invoice->recurrence_basetime) json_add_u64(js, "recurrence_basetime", *invoice->recurrence_basetime); - else + else { json_add_string(js, "warning_invoice_missing_recurrence_basetime", "recurring invoices without a recurrence_basetime are invalid"); + valid = false; + } } if (invoice->payer_key) @@ -509,18 +539,22 @@ static void json_add_b12_invoice(struct json_stream *js, */ if (invoice->timestamp) json_add_u64(js, "timestamp", *invoice->timestamp); - else + else { json_add_string(js, "warning_invoice_missing_timestamp", "invoices without a timestamp are invalid"); + valid = false; + } /* BOLT-offers #12: * - MUST reject the invoice if `payment_hash` is not present. */ if (invoice->payment_hash) json_add_sha256(js, "payment_hash", invoice->payment_hash); - else + else { json_add_string(js, "warning_invoice_missing_payment_hash", "invoices without a payment_hash are invalid"); + valid = false; + } /* BOLT-offers #12: * @@ -544,8 +578,8 @@ static void json_add_b12_invoice(struct json_stream *js, json_add_u32(js, "min_final_cltv_expiry", 18); if (invoice->fallbacks) - json_add_fallbacks(js, invoice->chains, - invoice->fallbacks->fallbacks); + valid &= json_add_fallbacks(js, invoice->chains, + invoice->fallbacks->fallbacks); /* BOLT-offers #12: * - if the offer contained `refund_for`: @@ -560,28 +594,37 @@ static void json_add_b12_invoice(struct json_stream *js, if (invoice->refund_signature) { json_add_bip340sig(js, "refund_signature", invoice->refund_signature); - if (!invoice->payer_key) + if (!invoice->payer_key) { json_add_string(js, "warning_invoice_refund_signature_missing_payer_key", "Can't have refund_signature without payer key"); - else if (!bolt12_check_signature(invoice->fields, - "invoice", - "refund_signature", - invoice->payer_key, - invoice->refund_signature)) + valid = false; + } else if (!bolt12_check_signature(invoice->fields, + "invoice", + "refund_signature", + invoice->payer_key, + invoice->refund_signature)) { json_add_string(js, "warning_invoice_refund_signature_invalid", "refund_signature does not match"); - } else if (invoice->refund_for) + valid = false; + } + } else if (invoice->refund_for) { json_add_string(js, "warning_invoice_refund_missing_signature", "refund_for requires refund_signature"); + valid = false; + } /* invoice_decode checked these */ json_add_pubkey32(js, "node_id", invoice->node_id); json_add_bip340sig(js, "signature", invoice->signature); + + json_add_bool(js, "valid", valid); } static void json_add_invoice_request(struct json_stream *js, const struct tlv_invoice_request *invreq) { + bool valid = true; + if (invreq->chains) json_add_chains(js, invreq->chains); /* BOLT-offers #12: @@ -592,9 +635,11 @@ static void json_add_invoice_request(struct json_stream *js, */ if (invreq->offer_id) json_add_sha256(js, "offer_id", invreq->offer_id); - else + else { json_add_string(js, "warning_invoice_request_missing_offer_id", "invoice_request requires offer_id"); + valid = false; + } if (invreq->amount) json_add_amount_msat_only(js, "amount_msat", amount_msat(*invreq->amount)); @@ -611,9 +656,11 @@ static void json_add_invoice_request(struct json_stream *js, *invreq->recurrence_start); if (invreq->payer_key) json_add_pubkey32(js, "payer_key", invreq->payer_key); - else + else { json_add_string(js, "warning_invoice_request_missing_payer_key", "invoice_request requires payer_key"); + valid = false; + } if (invreq->payer_info) json_add_hex_talarr(js, "payer_info", invreq->payer_info); @@ -631,13 +678,18 @@ static void json_add_invoice_request(struct json_stream *js, "invoice_request", "recurrence_signature", invreq->payer_key, - invreq->recurrence_signature)) + invreq->recurrence_signature)) { json_add_string(js, "warning_invoice_request_invalid_recurrence_signature", "Bad recurrence_signature"); + valid = false; + } } else if (invreq->recurrence_counter) { json_add_string(js, "warning_invoice_request_missing_recurrence_signature", "invoice_request requires recurrence_signature"); + valid = false; } + + json_add_bool(js, "valid", valid); } static struct command_result *json_decode(struct command *cmd, @@ -660,8 +712,11 @@ static struct command_result *json_decode(struct command *cmd, json_add_invoice_request(response, decodable->invreq); if (decodable->invoice) json_add_b12_invoice(response, decodable->invoice); - if (decodable->b11) + if (decodable->b11) { + /* The bolt11 decoder simply refuses to decode bad invs. */ json_add_bolt11(response, decodable->b11); + json_add_bool(response, "valid", true); + } return command_finished(cmd, response); } From 841711599c4bd6b497ab32c47847149619621644 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:17:01 +0930 Subject: [PATCH 09/19] pytest: add schema support for JSON responses. This adds our first (basic) schema, and sews support into pyln-testing so it will load schemas for any method for doc/schemas/{method}.schema.json. All JSON responses in a test run are checked against the schema (if any). Signed-off-by: Rusty Russell --- contrib/pyln-client/pyln/client/lightning.py | 1 + contrib/pyln-testing/pyln/testing/fixtures.py | 144 +++++++++++++++++- contrib/pyln-testing/pyln/testing/utils.py | 21 ++- contrib/pyln-testing/requirements.txt | 1 + doc/schemas/listpays.schema.json | 72 +++++++++ tests/fixtures.py | 2 +- 6 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 doc/schemas/listpays.schema.json diff --git a/contrib/pyln-client/pyln/client/lightning.py b/contrib/pyln-client/pyln/client/lightning.py index 74858285ce4b..f4e53f31935d 100644 --- a/contrib/pyln-client/pyln/client/lightning.py +++ b/contrib/pyln-client/pyln/client/lightning.py @@ -349,6 +349,7 @@ def call(self, method, payload=None): "enable": True }, }) + # FIXME: Notification schema support? _, buf = self._readobj(sock, buf) request = { diff --git a/contrib/pyln-testing/pyln/testing/fixtures.py b/contrib/pyln-testing/pyln/testing/fixtures.py index 6f1d96b0e482..d4e25ffaf066 100644 --- a/contrib/pyln-testing/pyln/testing/fixtures.py +++ b/contrib/pyln-testing/pyln/testing/fixtures.py @@ -1,13 +1,17 @@ from concurrent import futures from pyln.testing.db import SqliteDbProvider, PostgresDbProvider from pyln.testing.utils import NodeFactory, BitcoinD, ElementsD, env, DEVELOPER, LightningNode, TEST_DEBUG, Throttler +from pyln.client import Millisatoshi from typing import Dict +import json +import jsonschema # type: ignore import logging import os import pytest # type: ignore import re import shutil +import string import sys import tempfile @@ -202,8 +206,145 @@ def throttler(test_base_dir): yield Throttler(test_base_dir) +def _extra_validator(): + """JSON Schema validator with additions for our specialized types""" + def is_hex(checker, instance): + """Hex string""" + if not checker.is_type(instance, "string"): + return False + return all(c in string.hexdigits for c in instance) + + def is_u64(checker, instance): + """64-bit integer""" + if not checker.is_type(instance, "integer"): + return False + return instance >= 0 and instance < 2**64 + + def is_u32(checker, instance): + """32-bit integer""" + if not checker.is_type(instance, "integer"): + return False + return instance >= 0 and instance < 2**32 + + def is_u16(checker, instance): + """16-bit integer""" + if not checker.is_type(instance, "integer"): + return False + return instance >= 0 and instance < 2**16 + + def is_short_channel_id(checker, instance): + """Short channel id""" + if not checker.is_type(instance, "string"): + return False + parts = instance.split("x") + if len(parts) != 3: + return False + # May not be integers + try: + blocknum = int(parts[0]) + txnum = int(parts[1]) + outnum = int(parts[2]) + except ValueError: + return False + + # BOLT #7: + # ## Definition of `short_channel_id` + # + # The `short_channel_id` is the unique description of the funding transaction. + # It is constructed as follows: + # 1. the most significant 3 bytes: indicating the block height + # 2. the next 3 bytes: indicating the transaction index within the block + # 3. the least significant 2 bytes: indicating the output index that pays to the + # channel. + return (blocknum >= 0 and blocknum < 2**24 + and txnum >= 0 and txnum < 2**24 + and outnum >= 0 and outnum < 2**16) + + def is_pubkey(checker, instance): + """SEC1 encoded compressed pubkey""" + if not checker.is_type(instance, "hex"): + return False + if len(instance) != 66: + return False + return instance[0:2] == "02" or instance[0:2] == "03" + + def is_pubkey32(checker, instance): + """x-only BIP-340 public key""" + if not checker.is_type(instance, "hex"): + return False + if len(instance) != 64: + return False + return True + + def is_signature(checker, instance): + """DER encoded secp256k1 ECDSA signature""" + if not checker.is_type(instance, "hex"): + return False + if len(instance) > 72 * 2: + return False + return True + + def is_bip340sig(checker, instance): + """Hex encoded secp256k1 Schnorr signature""" + if not checker.is_type(instance, "hex"): + return False + if len(instance) != 64 * 2: + return False + return True + + def is_msat(checker, instance): + """String number ending in msat""" + return type(instance) is Millisatoshi + + def is_txid(checker, instance): + """Bitcoin transaction ID""" + if not checker.is_type(instance, "hex"): + return False + return len(instance) == 64 + + type_checker = jsonschema.Draft7Validator.TYPE_CHECKER.redefine_many({ + "hex": is_hex, + "u64": is_u64, + "u32": is_u32, + "u16": is_u16, + "pubkey": is_pubkey, + "msat": is_msat, + "txid": is_txid, + "signature": is_signature, + "bip340sig": is_bip340sig, + "pubkey32": is_pubkey32, + "short_channel_id": is_short_channel_id, + }) + + return jsonschema.validators.extend(jsonschema.Draft7Validator, + type_checker=type_checker) + + +def _load_schema(filename): + """Load the schema from @filename and create a validator for it""" + with open(filename, 'r') as f: + return _extra_validator()(json.load(f)) + + +@pytest.fixture(autouse=True) +def jsonschemas(): + """Load schema files if they exist""" + try: + schemafiles = os.listdir('doc/schemas') + except FileNotFoundError: + schemafiles = [] + + schemas = {} + for fname in schemafiles: + if not fname.endswith('.schema.json'): + continue + schemas[fname.rpartition('.schema')[0]] = _load_schema(os.path.join('doc/schemas', + fname)) + return schemas + + @pytest.fixture -def node_factory(request, directory, test_name, bitcoind, executor, db_provider, teardown_checks, node_cls, throttler): +def node_factory(request, directory, test_name, bitcoind, executor, db_provider, teardown_checks, node_cls, throttler, jsonschemas): nf = NodeFactory( request, test_name, @@ -213,6 +354,7 @@ def node_factory(request, directory, test_name, bitcoind, executor, db_provider, db_provider=db_provider, node_cls=node_cls, throttler=throttler, + jsonschemas=jsonschemas, ) yield nf diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index fbc6a26317b7..3fb3c7eaa67b 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -601,7 +601,17 @@ class PrettyPrintingLightningRpc(LightningRpc): eyes. It has some overhead since we re-serialize the request and result to json in order to pretty print it. + Also validates (optional) schemas for us. """ + def __init__(self, socket_path, executor=None, logger=logging, + patch_json=True, jsonschemas={}): + super().__init__( + socket_path, + executor, + logger, + patch_json, + ) + self.jsonschemas = jsonschemas def call(self, method, payload=None): id = self.next_id @@ -615,6 +625,10 @@ def call(self, method, payload=None): "id": id, "result": res }, indent=2)) + + if method in self.jsonschemas: + self.jsonschemas[method].validate(res) + return res @@ -625,6 +639,7 @@ def __init__(self, node_id, lightning_dir, bitcoind, executor, valgrind, may_fai allow_warning=False, allow_bad_gossip=False, db=None, port=None, disconnect=None, random_hsm=None, options=None, + jsonschemas={}, **kwargs): self.bitcoin = bitcoind self.executor = executor @@ -639,7 +654,7 @@ def __init__(self, node_id, lightning_dir, bitcoind, executor, valgrind, may_fai self.rc = 0 socket_path = os.path.join(lightning_dir, TEST_NETWORK, "lightning-rpc").format(node_id) - self.rpc = PrettyPrintingLightningRpc(socket_path, self.executor) + self.rpc = PrettyPrintingLightningRpc(socket_path, self.executor, jsonschemas=jsonschemas) self.daemon = LightningD( lightning_dir, bitcoindproxy=bitcoind.get_proxy(), @@ -1196,7 +1211,7 @@ class NodeFactory(object): """A factory to setup and start `lightningd` daemons. """ def __init__(self, request, testname, bitcoind, executor, directory, - db_provider, node_cls, throttler): + db_provider, node_cls, throttler, jsonschemas): if request.node.get_closest_marker("slow_test") and SLOW_MACHINE: self.valgrind = False else: @@ -1211,6 +1226,7 @@ def __init__(self, request, testname, bitcoind, executor, directory, self.db_provider = db_provider self.node_cls = node_cls self.throttler = throttler + self.jsonschemas = jsonschemas def split_options(self, opts): """Split node options from cli options @@ -1289,6 +1305,7 @@ def get_node(self, node_id=None, options=None, dbfile=None, node = self.node_cls( node_id, lightning_dir, self.bitcoind, self.executor, self.valgrind, db=db, port=port, options=options, may_fail=may_fail or expect_fail, + jsonschemas=self.jsonschemas, **kwargs ) diff --git a/contrib/pyln-testing/requirements.txt b/contrib/pyln-testing/requirements.txt index 55031d6aa6d2..1b9fcc647929 100644 --- a/contrib/pyln-testing/requirements.txt +++ b/contrib/pyln-testing/requirements.txt @@ -9,3 +9,4 @@ pytest-timeout ~= 1.4.2 pytest-xdist ~= 2.2.0 pytest==6.1.* python-bitcoinlib==0.11.* +jsonschema==3.2.* diff --git a/doc/schemas/listpays.schema.json b/doc/schemas/listpays.schema.json new file mode 100644 index 000000000000..15d0e685b383 --- /dev/null +++ b/doc/schemas/listpays.schema.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "pays": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "payment_hash": { + "type": "hex", + "description": "the hash of the *payment_preimage* which will prove payment", + "maxLength": 64, + "minLength": 64 + }, + "status": { + "type": "string", + "enum": [ "pending", "failed", "complete" ], + "description": "status of the payment" + }, + "destination": { + "type": "pubkey", + "description": "the final destination of the payment if known" + }, + "amount_msat": { + "type": "msat", + "description": "the amount the destination received, if known (**status** *complete* or *pending*)" + }, + "amount_sent_msat": { + "type": "msat", + "description": "the amount we actually sent, including fees (**status** *complete* or *pending*)" + }, + "created_at": { + "type": "u64", + "description": "the UNIX timestamp showing when this payment was initiated" + }, + "preimage": { + "type": "hex", + "description": "proof of payment, only if (and always if) **status** is *complete*", + "FIXME": "we should enforce the status/payment_preimage relation in the schema!", + "maxLength": 64, + "minLength": 64 + }, + "label": { + "type": "string", + "description": "the label, if given to sendpay" + }, + "bolt11": { + "type": "string", + "description": "the bolt11 string (if pay supplied one)" + }, + "bolt12": { + "type": "string", + "description": "the bolt12 string (if supplied for pay: **experimental-offers** only)." + }, + "erroronion": { + "type": "hex", + "description": "the error onion returned on failure, if any." + }, + "number_of_parts": { + "type": "u64", + "description": "the number of parts for a successful payment (only if more than one, and **status** is *complete*)." + } + }, + "required": [ "payment_hash", "status", "created_at" ] + } + } + }, + "required": [ "pays" ] +} diff --git a/tests/fixtures.py b/tests/fixtures.py index c5a9aefadf17..e1fdc12388bf 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -1,5 +1,5 @@ from utils import DEVELOPER, TEST_NETWORK # noqa: F401,F403 -from pyln.testing.fixtures import directory, test_base_dir, test_name, chainparams, node_factory, bitcoind, teardown_checks, throttler, db_provider, executor, setup_logging # noqa: F401,F403 +from pyln.testing.fixtures import directory, test_base_dir, test_name, chainparams, node_factory, bitcoind, teardown_checks, throttler, db_provider, executor, setup_logging, jsonschemas # noqa: F401,F403 from pyln.testing import utils from utils import COMPAT From b88a5e310112528a1414f488dc3ba45c60d7119c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:18:01 +0930 Subject: [PATCH 10/19] tools/fromschema.py: tool to replace start/end markers in markdown with schema. It can also be run standalone for debugging. Signed-off-by: Rusty Russell --- tools/fromschema.py | 247 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100755 tools/fromschema.py diff --git a/tools/fromschema.py b/tools/fromschema.py new file mode 100755 index 000000000000..a4d655336809 --- /dev/null +++ b/tools/fromschema.py @@ -0,0 +1,247 @@ +#! /usr/bin/env python3 +# Script to turn JSON schema into markdown documentation and replace in-place. +# Released by Rusty Russell under CC0: +# https://creativecommons.org/publicdomain/zero/1.0/ +from argparse import ArgumentParser +import json + + +def json_value(obj): + """Format obj in the JSON style for a value""" + if type(obj) is bool: + if obj: + return '*true*' + return '*false*' + if type(obj) is str: + return '"' + obj + '"' + assert False + + +def outputs(lines): + """Add these lines to the final output""" + print(''.join(lines), end='') + + +def output(line): + """Add this line to the final output""" + print(line, end='') + + +def output_type(properties, is_optional): + typename = properties['type'] + if typename == 'array': + typename += ' of {}s'.format(properties['items']['type']) + if is_optional: + typename += ", optional" + output(" ({})".format(typename)) + + +def output_range(properties): + if 'maximum' and 'minimum' in properties: + output(" ({} to {} inclusive)".format(properties['minimum'], + properties['maximum'])) + elif 'maximum' in properties: + output(" (max {})".format(properties['maximum'])) + elif 'minimum' in properties: + output(" (min {})".format(properties['minimum'])) + + if 'maxLength' and 'minLength' in properties: + if properties['minLength'] == properties['maxLength']: + output(' (always {} characters)'.format(properties['minLength'])) + else: + output(' ({} to {} characters)'.format(properties['minLength'], + properties['maxLength'])) + elif 'maxLength' in properties: + output(' (up to {} characters)'.format(properties['maxLength'])) + elif 'minLength' in properties: + output(' (at least {} characters)'.format(properties['minLength'])) + + if 'enum' in properties: + if len(properties['enum']) == 1: + output(" (always {})".format(json_value(properties['enum'][0]))) + else: + output(' (one of {})'.format(', '.join([json_value(p) for p in properties['enum']]))) + + +def output_member(propname, properties, is_optional, indent, print_type=True): + """Generate description line(s) for this member""" + output(indent + '- **{}**'.format(propname)) + if print_type: + output_type(properties, is_optional) + + if 'description' in properties: + output(": {}".format(properties['description'])) + + output_range(properties) + + if properties['type'] == 'object': + output(':\n') + output_members(properties, indent + ' ') + elif properties['type'] == 'array': + output(':\n') + output_array(properties['items'], indent + ' ') + else: + output('\n') + + +def output_array(items, indent): + """We've already said it's an array of {type}""" + if items['type'] == 'object': + output_members(items, indent) + elif items['type'] == 'array': + output(indent + '- {}:\n'.format(items['description'])) + output_array(items['items'], indent + ' ') + else: + output(indent + '- {}'.format(items['description'])) + output_range(items) + output('\n') + + +def output_members(sub, indent=''): + """Generate lines for these properties""" + warnings = [] + + # Remove deprecated and stub properties, collect warnings + # (Stubs required to keep additionalProperties: false happy) + for p in list(sub['properties'].keys()): + if len(sub['properties'][p]) == 0 or 'deprecated' in sub['properties'][p]: + del sub['properties'][p] + elif p.startswith('warning'): + warnings.append(p) + + # First list always-present properties + for p in sub['properties']: + if p.startswith('warning'): + continue + if p in sub['required']: + output_member(p, sub['properties'][p], False, indent) + + for p in sub['properties']: + if p.startswith('warning'): + continue + if p not in sub['required']: + output_member(p, sub['properties'][p], True, indent) + + if warnings != []: + output(indent + "- the following warnings are possible:\n") + for w in warnings: + output_member(w, sub['properties'][w], False, indent + ' ', print_type=False) + + # Not handled. + assert 'oneOf' not in sub + + # If we have multiple ifs, we have to wrap them in allOf. + if 'allOf' in sub: + ifclauses = sub['allOf'] + elif 'if' in sub: + ifclauses = [sub] + else: + ifclauses = [] + + # We partially handle if, assuming it depends on particular values of prior properties. + for ifclause in ifclauses: + conditions = [] + + # "required" are fields that simply must be present + for r in ifclause['if'].get('required', []): + conditions.append('**{}** is present'.format(r)) + + # "properties" are enums of field values + for tag, vals in ifclause['if'].get('properties', {}).items(): + # Don't have a description field here, it's not used. + assert 'description' not in vals + whichvalues = vals['enum'] + + cond = "**{}** is".format(tag) + if len(whichvalues) == 1: + cond += " {}".format(json_value(whichvalues[0])) + else: + cond += " {} or {}".format(", ".join([json_value(v) for v in whichvalues[:-1]]), + json_value(whichvalues[-1])) + conditions.append(cond) + + sentence = indent + "If " + ", and ".join(conditions) + ":\n" + # Prefix with blank line. + outputs(['\n', sentence]) + + output_members(ifclause['then'], indent + ' ') + + +def generate_from_schema(schema): + """This is not general, but works for us""" + assert schema['type'] == 'object' + + toplevels = [] + warnings = [] + props = schema['properties'] + + # We handle warnings on top-level objects with a separate section, + # so collect them now and remove them + for toplevel in list(props.keys()): + if toplevel.startswith('warning'): + warnings.append((toplevel, props[toplevel]['description'])) + del props[toplevel] + else: + toplevels.append(toplevel) + + # No properties -> empty object. + if toplevels == []: + output('On success, an empty object is returned.\n') + sub = schema + elif len(toplevels) == 1 and props[toplevels[0]]['type'] == 'object': + output('On success, an object containing **{}** is returned. It is an object containing:\n'.format(toplevels[0])) + # Don't have a description field here, it's not used. + assert 'description' not in toplevels[0] + sub = props[toplevels[0]] + elif len(toplevels) == 1 and props[toplevels[0]]['type'] == 'array': + output('On success, an object containing **{}** is returned. It is an array of objects, where each object contains:\n'.format(toplevels[0])) + # Don't have a description field here, it's not used. + assert 'description' not in toplevels[0] + sub = props[toplevels[0]]['items'] + else: + output('On success, an object is returned, containing:\n') + sub = schema + + output_members(sub) + + if warnings: + outputs(['\n', 'The following warnings may also be returned:\n']) + for w, desc in warnings: + output("- **{}**: {}\n".format(w, desc)) + + +def main(schemafile, markdownfile): + start_marker = '[comment]: # (GENERATE-FROM-SCHEMA-START)\n' + end_marker = '[comment]: # (GENERATE-FROM-SCHEMA-END)\n' + + if markdownfile is None: + with open(schemafile, "r") as f: + schema = json.load(f) + generate_from_schema(schema) + return + + with open(markdownfile, "r") as f: + md = f.readlines() + + suppress_output = False + for line in md: + if line == end_marker: + suppress_output = False + + if not suppress_output: + print(line, end='') + + if line == start_marker: + with open(schemafile, "r") as f: + schema = json.load(f) + generate_from_schema(schema) + suppress_output = True + + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument('schemafile', help='The schema file to use') + parser.add_argument('--markdownfile', help='The markdown file to read') + parsed_args = parser.parse_args() + + main(parsed_args.schemafile, parsed_args.markdownfile) From d117cdcaede51fa1f127d114e3ded5007085e482 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:19:01 +0930 Subject: [PATCH 11/19] doc/schemas: generate manpage section from schema. We start with the listpays manpage. Which is now complete! Signed-off-by: Rusty Russell --- doc/Makefile | 11 +++ doc/lightning-listpays.7 | 77 +++++++++---------- doc/lightning-listpays.7.md | 59 ++++++--------- doc/schemas/listpays.schema.json | 126 ++++++++++++++++++++++++------- 4 files changed, 170 insertions(+), 103 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index abc5bd35c678..30f4804d7168 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -86,12 +86,23 @@ MANPAGES := doc/lightning-cli.1 \ doc-all: $(MANPAGES) doc/index.rst +# Some manpages use a schema, so need that added. +MARKDOWN_WITH_SCHEMA := $(shell grep -l GENERATE-FROM-SCHEMA $(MANPAGES:=.md)) + +# These are hard to use in $(call) functions. +LBRACKET=( +RBRACKET=) + +$(MARKDOWN_WITH_SCHEMA): doc/lightning-%.7.md: doc/schemas/%.schema.json tools/fromschema.py + @if $(call SHA256STAMP_CHANGED); then $(call VERBOSE, "fromschema $@", tools/fromschema.py --markdownfile=$@ doc/schemas/$*.schema.json > $@.tmp && grep -v SHA256STAMP: $@.tmp > $@ && rm -f $@.tmp && $(call SHA256STAMP,[comment]: # $(LBRACKET),$(RBRACKET))); else touch $@; fi + # mrkd doesn't format nested lists properly, so we fixup with sed (see doc/lightning-connect.7 # and https://github.com/refi64/mrkd/issues/4 $(MANPAGES): doc/%: doc/%.md @if $(call SHA256STAMP_CHANGED); then $(call VERBOSE, "mrkd $<", mrkd $< $@.tmp && sed -e 's/\(.\)\.RS$$/\1\n.RS/' < $@.tmp > $@ && rm $@.tmp && $(call SHA256STAMP,\\\",)); else touch $@; fi $(MANPAGES): $(FORCE) +$(MARKDOWN_WITH_SCHEMA): $(FORCE) doc/protocol-%.svg: test/test_protocol test/test_protocol --svg < test/commits/$*.script > $@ diff --git a/doc/lightning-listpays.7 b/doc/lightning-listpays.7 index 8d0f0a0aa849..0d2c828a1f2d 100644 --- a/doc/lightning-listpays.7 +++ b/doc/lightning-listpays.7 @@ -12,56 +12,53 @@ single one if either \fIbolt11\fR or \fIpayment_hash\fR was specified\. .SH RETURN VALUE -On success, an array of objects is returned\. Each object contains: +On success, an object containing \fBpays\fR is returned\. It is an array of objects, where each object contains: +.RS +.IP \[bu] +\fBpayment_hash\fR (hex): the hash of the \fIpayment_preimage\fR which will prove payment (always 64 characters) +.IP \[bu] +\fBstatus\fR (string): status of the payment (one of "pending", "failed", "complete") +.IP \[bu] +\fBcreated_at\fR (u64): the UNIX timestamp showing when this payment was initiated +.IP \[bu] +\fBdestination\fR (pubkey, optional): the final destination of the payment if known +.IP \[bu] +\fBlabel\fR (string, optional): the label, if given to sendpay +.IP \[bu] +\fBbolt11\fR (string, optional): the bolt11 string (if pay supplied one) +.IP \[bu] +\fBbolt12\fR (string, optional): the bolt12 string (if supplied for pay: \fBexperimental-offers\fR only)\. - \fIbolt11\fR -the \fIbolt11\fR invoice if provided to \fBpay\fR\. +.RE +If \fBstatus\fR is "pending" or "complete": - \fIbolt12\fR -if \fBexperimental-offers\fR is enabled, and \fBpay\fR was a given a bolt12 -invoice, this field will appear instead of \fIbolt11\fR\. +.RS +.IP \[bu] +\fBamount_sent_msat\fR (msat): the amount we actually sent, including fees +.IP \[bu] +\fBamount_msat\fR (msat, optional): the amount the destination received, if known +.RE - \fIpayment_hash\fR -the \fIpayment_hash\fR of the payment\. +If \fBstatus\fR is "complete": +.RS +.IP \[bu] +\fBpreimage\fR (hex): proof of payment (always 64 characters) +.IP \[bu] +\fBnumber_of_parts\fR (u64, optional): the number of parts for a successful payment (only if more than one)\. - \fIstatus\fR -one of \fIcomplete\fR, \fIfailed\fR or \fIpending\fR\. +.RE +If \fBstatus\fR is "failed": - \fIpayment_preimage\fR -if \fIstatus\fR is \fIcomplete\fR\. - - - \fIlabel\fR -optional \fIlabel\fR, if provided to \fIpay\fR or \fIsendonion\fR\. - - - \fIamount_sent_msat\fR -total amount sent, in "NNNmsat" format\. - - -For old payments (pre-0\.7) we didn’t save the \fIbolt11\fR string, so in its -place are three other fields: - - - \fIpayment_hash\fR -the hash of the \fIpayment_preimage\fR which will prove payment\. - - - \fIdestination\fR -the final destination of the payment\. - - - \fIamount_msat\fR -the amount the destination received, in "NNNmsat" format\. - - -These three can all be extracted from \fIbolt11\fR, hence are obsolete\. +.RS +.IP \[bu] +\fBerroronion\fR (hex, optional): the error onion returned on failure, if any\. +.RE .SH AUTHOR Rusty Russell \fI is mainly responsible\. @@ -74,4 +71,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:5a0e016e18f52ce18484d064c3e659aca2687eeafca4b4365e3037faa1fba53f +\" SHA256STAMP:e27d57394bef9bdaf9b99ae0d9050c9044c194ab66f6c94c43b532a86e1a0031 diff --git a/doc/lightning-listpays.7.md b/doc/lightning-listpays.7.md index 87cab6a683b5..0ade89123bb0 100644 --- a/doc/lightning-listpays.7.md +++ b/doc/lightning-listpays.7.md @@ -15,43 +15,27 @@ single one if either *bolt11* or *payment_hash* was specified. RETURN VALUE ------------ -On success, an array of objects is returned. Each object contains: - - *bolt11* -the *bolt11* invoice if provided to `pay`. - - *bolt12* -if **experimental-offers** is enabled, and `pay` was a given a bolt12 -invoice, this field will appear instead of *bolt11*. - - *payment_hash* -the *payment_hash* of the payment. - - *status* -one of *complete*, *failed* or *pending*. - - *payment\_preimage* -if *status* is *complete*. - - *label* -optional *label*, if provided to *pay* or *sendonion*. - - *amount\_sent\_msat* -total amount sent, in "NNNmsat" format. - -For old payments (pre-0.7) we didn’t save the *bolt11* string, so in its -place are three other fields: - - *payment\_hash* -the hash of the *payment\_preimage* which will prove payment. - - *destination* -the final destination of the payment. - - *amount\_msat* -the amount the destination received, in "NNNmsat" format. - -These three can all be extracted from *bolt11*, hence are obsolete. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object containing **pays** is returned. It is an array of objects, where each object contains: +- **payment_hash** (hex): the hash of the *payment_preimage* which will prove payment (always 64 characters) +- **status** (string): status of the payment (one of "pending", "failed", "complete") +- **created_at** (u64): the UNIX timestamp showing when this payment was initiated +- **destination** (pubkey, optional): the final destination of the payment if known +- **label** (string, optional): the label, if given to sendpay +- **bolt11** (string, optional): the bolt11 string (if pay supplied one) +- **bolt12** (string, optional): the bolt12 string (if supplied for pay: **experimental-offers** only). + +If **status** is "pending" or "complete": + - **amount_sent_msat** (msat): the amount we actually sent, including fees + - **amount_msat** (msat, optional): the amount the destination received, if known + +If **status** is "complete": + - **preimage** (hex): proof of payment (always 64 characters) + - **number_of_parts** (u64, optional): the number of parts for a successful payment (only if more than one). + +If **status** is "failed": + - **erroronion** (hex, optional): the error onion returned on failure, if any. +[comment]: # (GENERATE-FROM-SCHEMA-END) AUTHOR ------ @@ -68,3 +52,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:12e7b91fc59ee65b61d9aba4e8586fda8fbb524a7e548ffa36862e204952c46b) diff --git a/doc/schemas/listpays.schema.json b/doc/schemas/listpays.schema.json index 15d0e685b383..82c9e4548430 100644 --- a/doc/schemas/listpays.schema.json +++ b/doc/schemas/listpays.schema.json @@ -2,12 +2,14 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, + "required": [ "pays" ], "properties": { "pays": { "type": "array", "items": { "type": "object", - "additionalProperties": false, + "additionalProperties": true, + "required": [ "payment_hash", "status", "created_at" ], "properties": { "payment_hash": { "type": "hex", @@ -24,25 +26,10 @@ "type": "pubkey", "description": "the final destination of the payment if known" }, - "amount_msat": { - "type": "msat", - "description": "the amount the destination received, if known (**status** *complete* or *pending*)" - }, - "amount_sent_msat": { - "type": "msat", - "description": "the amount we actually sent, including fees (**status** *complete* or *pending*)" - }, "created_at": { "type": "u64", "description": "the UNIX timestamp showing when this payment was initiated" }, - "preimage": { - "type": "hex", - "description": "proof of payment, only if (and always if) **status** is *complete*", - "FIXME": "we should enforce the status/payment_preimage relation in the schema!", - "maxLength": 64, - "minLength": 64 - }, "label": { "type": "string", "description": "the label, if given to sendpay" @@ -54,19 +41,106 @@ "bolt12": { "type": "string", "description": "the bolt12 string (if supplied for pay: **experimental-offers** only)." + } + }, + "allOf": [ + { + "if": { + "properties": { + "status": { + "type": "string", + "enum": [ "pending", "complete" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "amount_sent_msat" ], + "properties": { + "payment_hash": { }, + "status": { }, + "destination": { }, + "created_at": { }, + "label": { }, + "bolt11": { }, + "bolt12": { }, + "preimage": { }, + "number_of_parts": { }, + "amount_msat": { + "type": "msat", + "description": "the amount the destination received, if known" + }, + "amount_sent_msat": { + "type": "msat", + "description": "the amount we actually sent, including fees" + } + } + } }, - "erroronion": { - "type": "hex", - "description": "the error onion returned on failure, if any." + { + "if": { + "properties": { + "status": { + "type": "string", + "enum": [ "complete" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "preimage" ], + "properties": { + "payment_hash": { }, + "status": { }, + "destination": { }, + "created_at": { }, + "label": { }, + "bolt11": { }, + "bolt12": { }, + "amount_msat": { }, + "amount_sent_msat": { }, + "preimage": { + "type": "hex", + "description": "proof of payment", + "maxLength": 64, + "minLength": 64 + }, + "number_of_parts": { + "type": "u64", + "description": "the number of parts for a successful payment (only if more than one)." + } + } + } }, - "number_of_parts": { - "type": "u64", - "description": "the number of parts for a successful payment (only if more than one, and **status** is *complete*)." + { + "if": { + "properties": { + "status": { + "type": "string", + "enum": [ "failed" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ ], + "properties": { + "payment_hash": { }, + "status": { }, + "destination": { }, + "created_at": { }, + "label": { }, + "bolt11": { }, + "bolt12": { }, + "erroronion": { + "type": "hex", + "description": "the error onion returned on failure, if any." + } + } + } } - }, - "required": [ "payment_hash", "status", "created_at" ] + ] } } - }, - "required": [ "pays" ] + } } From 64f1ecba5e800f1bcf94d08f9b760b1eee264544 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:20:01 +0930 Subject: [PATCH 12/19] doc/schemas: add some simple schemas and generate manpages from them addgossip, check, createinvoice, createonion. Signed-off-by: Rusty Russell --- doc/lightning-addgossip.7 | 2 +- doc/lightning-addgossip.7.md | 3 ++ doc/lightning-check.7 | 10 ++-- doc/lightning-check.7.md | 7 ++- doc/lightning-createinvoice.7 | 38 +++++++++++++-- doc/lightning-createinvoice.7.md | 22 ++++++++- doc/lightning-createonion.7 | 24 ++++++++-- doc/lightning-createonion.7.md | 16 +++++-- doc/schemas/addgossip.schema.json | 7 +++ doc/schemas/check.schema.json | 12 +++++ doc/schemas/createinvoice.schema.json | 67 +++++++++++++++++++++++++++ doc/schemas/createonion.schema.json | 22 +++++++++ 12 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 doc/schemas/addgossip.schema.json create mode 100644 doc/schemas/check.schema.json create mode 100644 doc/schemas/createinvoice.schema.json create mode 100644 doc/schemas/createonion.schema.json diff --git a/doc/lightning-addgossip.7 b/doc/lightning-addgossip.7 index adac5d48eb76..a050c3b3eb43 100644 --- a/doc/lightning-addgossip.7 +++ b/doc/lightning-addgossip.7 @@ -35,4 +35,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:40440e0a1159025d8fac68fc127029bf8539b103c0473d6bfaacd7cef5b56bea +\" SHA256STAMP:dd8b1fd2ffcf7c57629a042f44f2fbc526d8892a2c933de6e82511721a8ffdea diff --git a/doc/lightning-addgossip.7.md b/doc/lightning-addgossip.7.md index 1ff80f997f20..2bac1588465a 100644 --- a/doc/lightning-addgossip.7.md +++ b/doc/lightning-addgossip.7.md @@ -22,7 +22,9 @@ messages within error replies. RETURN VALUE ------------ +[comment]: # (GENERATE-FROM-SCHEMA-START) On success, an empty object is returned. +[comment]: # (GENERATE-FROM-SCHEMA-END) AUTHOR ------ @@ -39,3 +41,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:f974a3848c4db5b73fffa969a741ef6619c9a375783fabe731882d84a6bbf5ff) diff --git a/doc/lightning-check.7 b/doc/lightning-check.7 index abfa871a33f2..27dd0e436690 100644 --- a/doc/lightning-check.7 +++ b/doc/lightning-check.7 @@ -23,9 +23,13 @@ find a route even if checking the parameters succeeds\. .SH RETURN VALUE -On success, the \fIcommand_to_check\fR is returned\. On failure, the -relevant RPC error is returned\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBcommand_to_check\fR (string): the \fIcommand_to_check\fR argument + +.RE .SH AUTHOR Mark Beckwith \fI and Rusty Russell @@ -35,4 +39,4 @@ Mark Beckwith \fI and Rusty Russell Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:8ff7c586849eae5646f182b088351b4a5baa61e9e628a31763a6647e74a7fc0a +\" SHA256STAMP:9e78651117d3546edaf5150621630ee5dc4ccefd6e6a17b52b9dc8f86e8ba0c9 diff --git a/doc/lightning-check.7.md b/doc/lightning-check.7.md index a0303c75abd3..67bd9ecec8da 100644 --- a/doc/lightning-check.7.md +++ b/doc/lightning-check.7.md @@ -23,8 +23,10 @@ find a route even if checking the parameters succeeds. RETURN VALUE ------------ -On success, the *command\_to\_check* is returned. On failure, the -relevant RPC error is returned. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **command_to_check** (string): the *command_to_check* argument +[comment]: # (GENERATE-FROM-SCHEMA-END) AUTHOR ------ @@ -37,3 +39,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:5b399ee88a5fb6b7eac0e1ac349a68a8715154f8c6468aedf446c703c91ac165) diff --git a/doc/lightning-createinvoice.7 b/doc/lightning-createinvoice.7 index 11ef5c4a4d25..499537c23fcf 100644 --- a/doc/lightning-createinvoice.7 +++ b/doc/lightning-createinvoice.7 @@ -28,9 +28,41 @@ the invoice\. .SH RETURN VALUE -On success, an invoice object is returned, as per \fBlistinvoices\fR(7)\. +(Note: the return format is the same as \fBlightning-listinvoices\fR(7))\. +On success, an object is returned, containing: + +.RS +.IP \[bu] +\fBlabel\fR (string): the label for the invoice +.IP \[bu] +\fBpayment_hash\fR (hex): the hash of the \fIpayment_preimage\fR which will prove payment (always 64 characters) +.IP \[bu] +\fBstatus\fR (string): Whether it has been paid, or can no longer be paid (one of "paid", "expired", "unpaid") +.IP \[bu] +\fBdescription\fR (string): Description extracted from \fBbolt11\fR or \fBbolt12\fR +.IP \[bu] +\fBexpires_at\fR (u64): UNIX timestamp of when invoice expires (or expired) +.IP \[bu] +\fBbolt11\fR (string, optional): the bolt11 string (always present unless \fBbolt12\fR is) +.IP \[bu] +\fBbolt12\fR (string, optional): the bolt12 string instead of \fBbolt11\fR (\fBexperimental-offers\fR only) +.IP \[bu] +\fBamount_msat\fR (msat, optional): The amount of the invoice (if it has one) +.IP \[bu] +\fBpay_index\fR (u64, optional): Incrementing id for when this was paid (\fBstatus\fR \fIpaid\fR only) +.IP \[bu] +\fBamount_received_msat\fR (msat, optional): Amount actually received (\fBstatus\fR \fIpaid\fR only) +.IP \[bu] +\fBpaid_at\fR (u64, optional): UNIX timestamp of when invoice was paid (\fBstatus\fR \fIpaid\fR only) +.IP \[bu] +\fBpayment_preimage\fR (hex, optional): the proof of payment: SHA256 of this \fBpayment_hash\fR (always 64 characters) +.IP \[bu] +\fBlocal_offer_id\fR (hex, optional): the \fIid\fR of our offer which created this invoice (\fBexperimental-offers\fR only)\. (always 64 characters) + +.RE + On failure, an error is returned and no invoice is created\. If the lightning process fails before responding, the caller should use \fBlightning-listinvoices\fR(7) to query whether this invoice was created or @@ -53,10 +85,10 @@ Rusty Russell \fI is mainly responsible\. .SH SEE ALSO \fBlightning-invoice\fR(7), \fBlightning-listinvoices\fR(7), \fBlightning-delinvoice\fR(7), -\fBlightning-getroute\fR(7), \fBlightning-sendpay\fR(7)\. +\fBlightning-getroute\fR(7), \fBlightning-sendpay\fR(7), \fBlightning-offer\fR(7)\. .SH RESOURCES Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:155724c3e3130ed7f96d50a37dff99711dfcb4056c57d7eeb488fdb2b7925839 +\" SHA256STAMP:2d654675f966516a0fb0553f66e5bacd3ab96482d20cd9701a84e15ae49a4d92 diff --git a/doc/lightning-createinvoice.7.md b/doc/lightning-createinvoice.7.md index 1f5ee4d0ab37..99f5ce7ac859 100644 --- a/doc/lightning-createinvoice.7.md +++ b/doc/lightning-createinvoice.7.md @@ -28,7 +28,24 @@ the invoice. RETURN VALUE ------------ -On success, an invoice object is returned, as per listinvoices(7). +(Note: the return format is the same as lightning-listinvoices(7)). + +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **label** (string): the label for the invoice +- **payment_hash** (hex): the hash of the *payment_preimage* which will prove payment (always 64 characters) +- **status** (string): Whether it has been paid, or can no longer be paid (one of "paid", "expired", "unpaid") +- **description** (string): Description extracted from **bolt11** or **bolt12** +- **expires_at** (u64): UNIX timestamp of when invoice expires (or expired) +- **bolt11** (string, optional): the bolt11 string (always present unless **bolt12** is) +- **bolt12** (string, optional): the bolt12 string instead of **bolt11** (**experimental-offers** only) +- **amount_msat** (msat, optional): The amount of the invoice (if it has one) +- **pay_index** (u64, optional): Incrementing id for when this was paid (**status** *paid* only) +- **amount_received_msat** (msat, optional): Amount actually received (**status** *paid* only) +- **paid_at** (u64, optional): UNIX timestamp of when invoice was paid (**status** *paid* only) +- **payment_preimage** (hex, optional): the proof of payment: SHA256 of this **payment_hash** (always 64 characters) +- **local_offer_id** (hex, optional): the *id* of our offer which created this invoice (**experimental-offers** only). (always 64 characters) +[comment]: # (GENERATE-FROM-SCHEMA-END) On failure, an error is returned and no invoice is created. If the lightning process fails before responding, the caller should use @@ -48,10 +65,11 @@ SEE ALSO -------- lightning-invoice(7), lightning-listinvoices(7), lightning-delinvoice(7), -lightning-getroute(7), lightning-sendpay(7). +lightning-getroute(7), lightning-sendpay(7), lightning-offer(7). RESOURCES --------- Main web site: +[comment]: # ( SHA256STAMP:95a2fbf9c94fa1e01a322658035473c694bfb93e02d32c2cefafe6ef5b676695) diff --git a/doc/lightning-createonion.7 b/doc/lightning-createonion.7 index 41a0a9dce284..2f075852f805 100644 --- a/doc/lightning-createonion.7 +++ b/doc/lightning-createonion.7 @@ -104,9 +104,25 @@ routing\. .SH RETURN VALUE -On success, an object containing the onion and the shared secrets will be -returned\. Otherwise an error will be reported\. The following example is the -result of calling \fIcreateonion\fR with the above hops parameter: +On success, an object is returned, containing: + +.RS +.IP \[bu] +\fBonion\fR (hex): the onion packet (\fIonion_size\fR bytes) +.IP \[bu] +\fBshared_secrets\fR (array of hexs): one shared secret for each node in the \fIhops\fR parameter: +.RS +.IP \[bu] +the shared secret with this hop (always 64 characters) + +.RE + + +.RE +.SH EXAMPLE + +The following example is the result of calling \fIcreateonion\fR with the +above hops parameter: .nf .RS @@ -137,4 +153,4 @@ Christian Decker \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:d32334049025248f8b6088afed4e3322be75815ea6b976f79a007c619518f98a +\" SHA256STAMP:c21aa197637bea17068072cd5907ad3302b48586067a8a5a8d748fd8e7e0a668 diff --git a/doc/lightning-createonion.7.md b/doc/lightning-createonion.7.md index 630f327aa574..b10ecfce8dd0 100644 --- a/doc/lightning-createonion.7.md +++ b/doc/lightning-createonion.7.md @@ -92,9 +92,18 @@ routing. RETURN VALUE ------------ -On success, an object containing the onion and the shared secrets will be -returned. Otherwise an error will be reported. The following example is the -result of calling *createonion* with the above hops parameter: +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **onion** (hex): the onion packet (*onion_size* bytes) +- **shared_secrets** (array of hexs): one shared secret for each node in the *hops* parameter: + - the shared secret with this hop (always 64 characters) +[comment]: # (GENERATE-FROM-SCHEMA-END) + +EXAMPLE +------- + +The following example is the result of calling *createonion* with the +above hops parameter: ```json { @@ -126,3 +135,4 @@ RESOURCES Main web site: [bolt04]: https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md +[comment]: # ( SHA256STAMP:a5a64325f4232f27bccbbe1c9fc62bfb602ba60c81f46a1ef2df25b06dac807e) diff --git a/doc/schemas/addgossip.schema.json b/doc/schemas/addgossip.schema.json new file mode 100644 index 000000000000..b797a82c2f6f --- /dev/null +++ b/doc/schemas/addgossip.schema.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + } +} diff --git a/doc/schemas/check.schema.json b/doc/schemas/check.schema.json new file mode 100644 index 000000000000..faecc7d78a6a --- /dev/null +++ b/doc/schemas/check.schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "command_to_check": { + "type": "string", + "description": "the *command_to_check* argument" + } + }, + "required": [ "command_to_check" ] +} diff --git a/doc/schemas/createinvoice.schema.json b/doc/schemas/createinvoice.schema.json new file mode 100644 index 000000000000..b1e6aa13107f --- /dev/null +++ b/doc/schemas/createinvoice.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "label", "payment_hash", "status", "description", "expires_at" ], + "properties": { + "label": { + "type": "string", + "description": "the label for the invoice" + }, + "bolt11": { + "type": "string", + "description": "the bolt11 string (always present unless **bolt12** is)" + }, + "bolt12": { + "type": "string", + "description": "the bolt12 string instead of **bolt11** (**experimental-offers** only)" + }, + "payment_hash": { + "type": "hex", + "description": "the hash of the *payment_preimage* which will prove payment", + "maxLength": 64, + "minLength": 64 + }, + "amount_msat": { + "type": "msat", + "description": "The amount of the invoice (if it has one)" + }, + "status": { + "type": "string", + "enum": [ "paid", "expired", "unpaid" ], + "description": "Whether it has been paid, or can no longer be paid" + }, + "description": { + "type": "string", + "description": "Description extracted from **bolt11** or **bolt12**" + }, + "expires_at": { + "type": "u64", + "description": "UNIX timestamp of when invoice expires (or expired)" + }, + "pay_index": { + "type": "u64", + "description": "Incrementing id for when this was paid (**status** *paid* only)" + }, + "amount_received_msat": { + "type": "msat", + "description": "Amount actually received (**status** *paid* only)" + }, + "paid_at": { + "type": "u64", + "description": "UNIX timestamp of when invoice was paid (**status** *paid* only)" + }, + "payment_preimage": { + "type": "hex", + "description": "the proof of payment: SHA256 of this **payment_hash**", + "maxLength": 64, + "minLength": 64 + }, + "local_offer_id": { + "type": "hex", + "description": "the *id* of our offer which created this invoice (**experimental-offers** only).", + "maxLength": 64, + "minLength": 64 + } + } +} diff --git a/doc/schemas/createonion.schema.json b/doc/schemas/createonion.schema.json new file mode 100644 index 000000000000..7917163e18df --- /dev/null +++ b/doc/schemas/createonion.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "onion", "shared_secrets" ], + "properties": { + "onion": { + "type": "hex", + "description": "the onion packet (*onion_size* bytes)" + }, + "shared_secrets": { + "type": "array", + "description": "one shared secret for each node in the *hops* parameter", + "items": { + "type": "hex", + "description": "the shared secret with this hop", + "maxLength": 64, + "minLength": 64 + } + } + } +} From da8c82d413287e660101fdb6a7e431ed7ed7569e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:21:01 +0930 Subject: [PATCH 13/19] doc/schemas: add schema for autoclean. Signed-off-by: Rusty Russell --- doc/lightning-autocleaninvoice.7 | 19 +++++++++-- doc/lightning-autocleaninvoice.7.md | 10 +++++- doc/schemas/autocleaninvoice.schema.json | 41 ++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 doc/schemas/autocleaninvoice.schema.json diff --git a/doc/lightning-autocleaninvoice.7 b/doc/lightning-autocleaninvoice.7 index fcbf233e4dc0..0c9dfead0e36 100644 --- a/doc/lightning-autocleaninvoice.7 +++ b/doc/lightning-autocleaninvoice.7 @@ -25,8 +25,23 @@ On startup of the daemon, no autoclean is set up\. .SH RETURN VALUE -On success, an empty object is returned\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBenabled\fR (boolean): whether invoice autocleaning is active + +.RE + +If \fBenabled\fR is \fItrue\fR: + +.RS +.IP \[bu] +\fBexpired_by\fR (u64): how long an invoice must be expired (seconds) before we delete it +.IP \[bu] +\fBcycle_seconds\fR (u64): how long an invoice must be expired (seconds) before we delete it + +.RE .SH AUTHOR ZmnSCPxj \fI is mainly responsible\. @@ -39,4 +54,4 @@ ZmnSCPxj \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:df05ece680710d67202b28af635a274d7adc38d9f334c79d88ee28b80a2cae60 +\" SHA256STAMP:dd3f512e81f45ab6084b608bc05fba5679b1d20d493aad98d422bdf593182604 diff --git a/doc/lightning-autocleaninvoice.7.md b/doc/lightning-autocleaninvoice.7.md index d741fa433f33..6e649ee2fd36 100644 --- a/doc/lightning-autocleaninvoice.7.md +++ b/doc/lightning-autocleaninvoice.7.md @@ -25,7 +25,14 @@ On startup of the daemon, no autoclean is set up. RETURN VALUE ------------ -On success, an empty object is returned. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **enabled** (boolean): whether invoice autocleaning is active + +If **enabled** is *true*: + - **expired_by** (u64): how long an invoice must be expired (seconds) before we delete it + - **cycle_seconds** (u64): how long an invoice must be expired (seconds) before we delete it +[comment]: # (GENERATE-FROM-SCHEMA-END) AUTHOR ------ @@ -42,3 +49,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:2accf7788133af97ae097f7e4e8a80b35bbb431eb7e787e5ae12dd5c7d2c296d) diff --git a/doc/schemas/autocleaninvoice.schema.json b/doc/schemas/autocleaninvoice.schema.json new file mode 100644 index 000000000000..7ed3db3d513b --- /dev/null +++ b/doc/schemas/autocleaninvoice.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "required": [ "enabled" ], + "properties": { + "enabled": { + "type": "boolean", + "description": "whether invoice autocleaning is active" + } + }, + "if": { + "properties": { + "enabled": { + "type": "boolean", + "enum": [ true ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "expired_by", "cycle_seconds" ], + "properties": { + "enabled": { }, + "expired_by": { + "type": "u64", + "description": "how long an invoice must be expired (seconds) before we delete it" + }, + "cycle_seconds": { + "type": "u64", + "description": "how long an invoice must be expired (seconds) before we delete it" + } + } + }, + "else": { + "additionalProperties": false, + "properties": { + "enabled": { } + } + } +} From 0f924a3e897d35dacc78a00864e8f5458d1347c7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:22:01 +0930 Subject: [PATCH 14/19] doc/schemas: create close schema. Signed-off-by: Rusty Russell --- doc/lightning-close.7 | 24 ++++++++++++++------ doc/lightning-close.7.md | 15 ++++++++----- doc/schemas/close.schema.json | 41 +++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 doc/schemas/close.schema.json diff --git a/doc/lightning-close.7 b/doc/lightning-close.7 index e6478dd0638b..c6313e41716a 100644 --- a/doc/lightning-close.7 +++ b/doc/lightning-close.7 @@ -83,13 +83,23 @@ if the peer is offline and we are waiting\. .SH RETURN VALUE -On success, an object with fields \fItx\fR and \fItxid\fR containing the closing -transaction are returned\. It will also have a field \fItype\fR which is -either the JSON string \fImutual\fR or the JSON string \fIunilateral\fR\. A -\fImutual\fR close means that we could negotiate a close with the peer, -while a \fIunilateral\fR close means that the \fIforce\fR flag was set and we -had to close the channel without waiting for the counterparty\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBtype\fR (string): Whether we successfully negotiated a mutual close, closed without them, or discarded not-yet-opened channel (one of "mutual", "unilateral", "unopened") + +.RE + +If \fBtype\fR is "mutual" or "unilateral": + +.RS +.IP \[bu] +\fBtx\fR (hex): the raw bitcoin transaction used to close the channel (if it was open) +.IP \[bu] +\fBtxid\fR (txid): the transaction id of the \fItx\fR field + +.RE A unilateral close may still occur at any time if the peer did not behave correctly during the close negotiation\. @@ -110,4 +120,4 @@ ZmnSCPxj \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:c8a4fe414eeb72880346601be2e73f1ad6decb31b4d4e291549d8b339e47b68d +\" SHA256STAMP:507a9ca707e244eef65c5e16daa5a4d7ba8f59e93e988d252f7e854ae9f44781 diff --git a/doc/lightning-close.7.md b/doc/lightning-close.7.md index 676272a48824..306598ca7a85 100644 --- a/doc/lightning-close.7.md +++ b/doc/lightning-close.7.md @@ -74,12 +74,14 @@ if the peer is offline and we are waiting. RETURN VALUE ------------ -On success, an object with fields *tx* and *txid* containing the closing -transaction are returned. It will also have a field *type* which is -either the JSON string *mutual* or the JSON string *unilateral*. A -*mutual* close means that we could negotiate a close with the peer, -while a *unilateral* close means that the *force* flag was set and we -had to close the channel without waiting for the counterparty. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **type** (string): Whether we successfully negotiated a mutual close, closed without them, or discarded not-yet-opened channel (one of "mutual", "unilateral", "unopened") + +If **type** is "mutual" or "unilateral": + - **tx** (hex): the raw bitcoin transaction used to close the channel (if it was open) + - **txid** (txid): the transaction id of the *tx* field +[comment]: # (GENERATE-FROM-SCHEMA-END) A unilateral close may still occur at any time if the peer did not behave correctly during the close negotiation. @@ -102,3 +104,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:9159304cd705d8135c32e12bd029c0e95baff0d495e6f9092a75888dab2f5fb3) diff --git a/doc/schemas/close.schema.json b/doc/schemas/close.schema.json new file mode 100644 index 000000000000..b28dee6459c9 --- /dev/null +++ b/doc/schemas/close.schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "type" ], + "properties": { + "type": { + "type": "string", + "enum": [ "mutual", "unilateral", "unopened" ], + "description": "Whether we successfully negotiated a mutual close, closed without them, or discarded not-yet-opened channel" + } + }, + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "mutual", "unilateral" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "tx", "txid" ], + "properties": { + "type": { }, + "tx": { + "type": "hex", + "description": "the raw bitcoin transaction used to close the channel (if it was open)" + }, + "txid": { + "type": "txid", + "description": "the transaction id of the *tx* field" + } + } + }, + "else": { + "additionalProperties": false, + "properties": { + "type": { } + } + } +} From 8a541e64b34da7b5a704dc527acf8d05038b53c0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:23:01 +0930 Subject: [PATCH 15/19] doc/schemas: schema for connect. Signed-off-by: Rusty Russell --- doc/lightning-connect.7 | 45 +++++++++++++++--- doc/lightning-connect.7.md | 21 +++++++-- doc/schemas/connect.schema.json | 82 +++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 doc/schemas/connect.schema.json diff --git a/doc/lightning-connect.7 b/doc/lightning-connect.7 index 5ee4cb737761..4bafbaf8a3ee 100644 --- a/doc/lightning-connect.7 +++ b/doc/lightning-connect.7 @@ -42,12 +42,45 @@ another node\. Once the peer is connected a channel can be opened with .SH RETURN VALUE -On success the peer \fIid\fR is returned, as well as a hexidecimal -\fIfeatures\fR bitmap, a \fIdirection\fR ("in" if they connected to us, "out" -if we connected to them") and an \fIaddress\fR object as per -\fBlightning-listnodes\fR(7)\. Note that \fIaddress\fR will be less useful if -"direction" is "in", especially if a proxy is in use\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBid\fR (pubkey): the peer we connected to +.IP \[bu] +\fBfeatures\fR (hex): BOLT 9 features bitmap offered by peer +.IP \[bu] +\fBdirection\fR (string): Whether they initiated connection or we did (one of "in", "out") +.IP \[bu] + +\fBaddress\fR (object): Address information (mainly useful if \fBdirection\fR is \fIout\fR): + +.RS +.IP \[bu] +\fBtype\fR (string): Type of connection (\fItorv2\fR/\fItorv3\fR only if \fBdirection\fR is \fIout\fR) (one of "local socket", "ipv4", "ipv6", "torv2", "torv3") + +.RE + +If \fBtype\fR is "local socket": + +.RS +.IP \[bu] +\fBsocket\fR (string): socket filename + +.RE + +If \fBtype\fR is "ipv4", "ipv6", "torv2" or "torv3": + +.RS +.IP \[bu] +\fBaddress\fR (string): address in expected format for \fBtype\fR +.IP \[bu] +\fBport\fR (u16): port number + +.RE + + +.RE .SH ERRORS On failure, one of the following errors will be returned: @@ -97,4 +130,4 @@ Felix \fI is the original author of this manpage\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:a392b6683fad5fe218e7a985e1eaf5d7439f38d7c74212c275cfa64db284efc0 +\" SHA256STAMP:ff422184feb295e6d3e17e88c0305405edcb24eac59482a43caf750ef281e0ed diff --git a/doc/lightning-connect.7.md b/doc/lightning-connect.7.md index 823cadda7b2d..be1df3d74914 100644 --- a/doc/lightning-connect.7.md +++ b/doc/lightning-connect.7.md @@ -39,11 +39,21 @@ lightning-fundchannel(7). RETURN VALUE ------------ -On success the peer *id* is returned, as well as a hexidecimal -*features* bitmap, a *direction* ("in" if they connected to us, "out" -if we connected to them") and an *address* object as per -lightning-listnodes(7). Note that *address* will be less useful if -"direction" is "in", especially if a proxy is in use. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **id** (pubkey): the peer we connected to +- **features** (hex): BOLT 9 features bitmap offered by peer +- **direction** (string): Whether they initiated connection or we did (one of "in", "out") +- **address** (object): Address information (mainly useful if **direction** is *out*): + - **type** (string): Type of connection (*torv2*/*torv3* only if **direction** is *out*) (one of "local socket", "ipv4", "ipv6", "torv2", "torv3") + + If **type** is "local socket": + - **socket** (string): socket filename + + If **type** is "ipv4", "ipv6", "torv2" or "torv3": + - **address** (string): address in expected format for **type** + - **port** (u16): port number +[comment]: # (GENERATE-FROM-SCHEMA-END) ERRORS ------ @@ -78,3 +88,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:5b168e7998d3db6a842eabf92bcbb74352fe831726ea42a801e39ff5c3f812ca) diff --git a/doc/schemas/connect.schema.json b/doc/schemas/connect.schema.json new file mode 100644 index 000000000000..3ce55591c5fb --- /dev/null +++ b/doc/schemas/connect.schema.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "id", "features", "direction", "address" ], + "properties": { + "id": { + "type": "pubkey", + "description": "the peer we connected to" + }, + "features": { + "type": "hex", + "description": "BOLT 9 features bitmap offered by peer" + }, + "direction": { + "type": "string", + "enum": [ "in", "out" ], + "description": "Whether they initiated connection or we did" + }, + "address": { + "type": "object", + "description": "Address information (mainly useful if **direction** is *out*)", + "additionalProperties": true, + "required": [ "type" ], + "properties": { + "type": { + "type": "string", + "enum": [ "local socket", "ipv4", "ipv6", "torv2", "torv3" ], + "description": "Type of connection (*torv2*/*torv3* only if **direction** is *out*)" + } + }, + "allOf": [ + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "local socket" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "socket" ], + "properties": { + "type": { }, + "socket": { + "type": "string", + "description": "socket filename" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "ipv4", "ipv6", "torv2", "torv3" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "address", "port" ], + "properties": { + "type": { }, + "address": { + "type": "string", + "description": "address in expected format for **type**" + }, + "port": { + "type": "u16", + "description": "port number" + } + } + } + } + ] + } + } +} From f6b803f6cf3d5ece1ac424f40d880c90a2fd4e97 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:24:01 +0930 Subject: [PATCH 16/19] doc/schemas: decode, decodepay One of the more complex ones. Signed-off-by: Rusty Russell --- doc/lightning-decode.7 | 443 ++++++++++++---- doc/lightning-decode.7.md | 237 +++++---- doc/lightning-decodepay.7 | 77 ++- doc/lightning-decodepay.7.md | 52 +- doc/schemas/decode.schema.json | 806 ++++++++++++++++++++++++++++++ doc/schemas/decodepay.schema.json | 146 ++++++ 6 files changed, 1524 insertions(+), 237 deletions(-) create mode 100644 doc/schemas/decode.schema.json create mode 100644 doc/schemas/decodepay.schema.json diff --git a/doc/lightning-decode.7 b/doc/lightning-decode.7 index 0b4e80e4d857..a497de756f0b 100644 --- a/doc/lightning-decode.7 +++ b/doc/lightning-decode.7 @@ -17,140 +17,385 @@ other formats in future\. .SH RETURN VALUE -On success, an object is returned with a \fItype\fR member indicating the -type of the decoding: +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBtype\fR (string): what kind of object it decoded to (one of "bolt12 offer", "bolt12 invoice", "bolt12 invoice_request", "bolt11 invoice") +.IP \[bu] +\fBvalid\fR (boolean): if this is false, you \fIMUST\fR not use the result except for diagnostics! + +.RE -\fItype\fR: "bolt12 offer" +If \fBtype\fR is "bolt12 offer", and \fBvalid\fR is \fItrue\fR: -.nf .RS -- *offer_id*: the id of this offer (merkle hash of non-signature fields) -- *chains* (optional): if set, an array of genesis hashes of supported chains. (Unset implies bitcoin mainnet). -- *currency* (optional): ISO 4217 code of the currency. -- *minor_unit* (optional): the number of decimal places to apply to amount (if currency known) -- *amount* (optional): the amount in the *currency* adjusted by *minor_unit*, if any. -- *amount_msat* (optional): the amount (with "msat" appended) if there is no *currency*. -- *send_invoice* (optional): `true` if this is a send_invoice offer. -- *refund_for* (optional): the sha256 payment_preimage of invoice this is a refund for. -- *description* (optional): the UTF-8 description of the purpose of the offer. -- *vendor* (optional): the UTF-8 name of the vendor for this offer. -- *features* (optional): hex array of feature bits. -- *absolute_expiry* (optional): UNIX timestamp of when this offer expires. -- *paths* (optional): Array of objects containing *blinding*, *path* array; each *path* entry contains an object with *node_id* and *enctlv*. -- *quantity_min* (optional): minimum valid quantity for offer responses -- *quantity_max* (optional): maximum valid quantity for offer responses -- *recurrence* (optional): an object containing *time_unit*, *time_unit_name* (optional, a string), *period*, *basetime* (optional), *start_any_period* (optional), *limit* (optional), and *paywindow* (optional) object containing *seconds_before*, *seconds_after* and *proportional_amount* (optional). -- *node_id*: 32-byte (x-only) public key of the offering node. -- *signature*: BIP-340 signature of the *node_id* on this offer. +.IP \[bu] +\fBoffer_id\fR (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters) +.IP \[bu] +\fBnode_id\fR (pubkey32): x-only public key of the offering node +.IP \[bu] +\fBsignature\fR (bip340sig): BIP-340 signature of the \fInode_id\fR on this offer +.IP \[bu] +\fBdescription\fR (string): the description of the purpose of the offer +.IP \[bu] +\fBchains\fR (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): +.RS +.IP \[bu] +the genesis blockhash (always 64 characters) +.RE + +.IP \[bu] +\fBcurrency\fR (string, optional): ISO 4217 code of the currency (missing implies Bitcoin) (always 3 characters) +.IP \[bu] +\fBminor_unit\fR (u32, optional): the number of decimal places to apply to amount (if currency known) +.IP \[bu] +\fBamount\fR (u64, optional): the amount in the \fIcurrency\fR adjusted by \fIminor_unit\fR, if any +.IP \[bu] +\fBamount_msat\fR (msat, optional): the amount in bitcoin (if specified, and no \fIcurrency\fR) +.IP \[bu] +\fBsend_invoice\fR (boolean, optional): present if this is a send_invoice offer (always \fItrue\fR) +.IP \[bu] +\fBrefund_for\fR (hex, optional): the \fIpayment_preimage\fR of invoice this is a refund for (always 64 characters) +.IP \[bu] +\fBvendor\fR (string, optional): the name of the vendor for this offer +.IP \[bu] +\fBfeatures\fR (hex, optional): the array of feature bits for this offer +.IP \[bu] +\fBabsolute_expiry\fR (u64, optional): UNIX timestamp of when this offer expires +.IP \[bu] +\fBpaths\fR (array of objects, optional): Paths to the destination: +.RS +.IP \[bu] +\fBblinding\fR (pubkey): blinding factor for this path +.IP \[bu] +\fBpath\fR (array of objects): an individual path: +.RS +.IP \[bu] +\fBnode_id\fR (pubkey): node_id of the hop +.IP \[bu] +\fBenctlv\fR (hex): encrypted TLV entry for this hop .RE -.fi -\fItype\fR: "bolt12 invoice" +.RE -.nf +.IP \[bu] +\fBquantity_min\fR (u64, optional): the minimum quantity +.IP \[bu] +\fBquantity_max\fR (u64, optional): the maximum quantity +.IP \[bu] +\fBrecurrence\fR (object, optional): how often to this offer should be used: .RS -- *chains* (optional): if set, an array of genesis hashes of supported chains. (Unset implies bitcoin mainnet). -- *offer_id* (optional): id of the offer this invoice is for. -- *amount_msat* (optional): the amount (with "msat" appended). -- *description* (optional): the UTF-8 description of the purpose of the offer. -- *vendor* (optional): the UTF-8 name of the vendor for this offer. -- *features* (optional): hex array of feature bits. -- *paths* (optional): Array of objects containing *blinding*, *path* array; each *path* entry contains an object with *node_id*, *enctlv*, *fee_base_msat* (optional), *fee_proportional_millionths* (optional), *cltv_expiry_delta* (optional), and *features* (optional). -- *quantity* (optional): quantity of items. -- *send_invoice* (optional): `true` if this is a response to a send_invoice offer. -- *refund_for* (optional): the sha256 payment_preimage of invoice this is a refund for. -- *recurrence_counter* (optional): the zero-based number of the invoice for a recurring offer. -- *recurrence_start* (optional): the zero-based offet of the first invoice for the recurring offer. -- *recurrence_basetime* (optional): the UNIX timestamp of the first period of the offer. -- *payer_key* (optional): the 32-byte (x-only) id of the payer. -- *payer_info* (optional): a variable-length blob for the payer to derive their key. -- *timestamp* (optional): the UNIX timestamp of the invoice. -- *payment_hash* (optional): the hex SHA256 of the payment_preimage. -- *expiry* (optional): seconds from *timestamp* when invoice expires. -- *min_final_cltv_expiry*: required CLTV for final hop. -- *fallbacks* (optional): an array containing objects with *version*, and *hex* fields for each fallback address, and *address* (optional) if it's parsable. -- *refund_signature* (optional): BIP-340 signature of the *payer_key* on this offer. -- *node_id*: 32-byte (x-only) public key of the invoicing node. -- *signature*: BIP-340 signature of the *node_id* on this invoice. +.IP \[bu] +\fBtime_unit\fR (u32): the BOLT12 time unit +.IP \[bu] +\fBperiod\fR (u32): how many \fItime_unit\fR per payment period +.IP \[bu] +\fBtime_unit_name\fR (string, optional): the name of \fItime_unit\fR (if valid) +.IP \[bu] +\fBbasetime\fR (u64, optional): period starts at this UNIX timestamp +.IP \[bu] +\fBstart_any_period\fR (u64, optional): you can start at any period (only if \fBbasetime\fR present) +.IP \[bu] +\fBlimit\fR (u32, optional): maximum period number for recurrence +.IP \[bu] +\fBpaywindow\fR (object, optional): when within a period will payment be accepted (default is prior and during the period): +.RS +.IP \[bu] +\fBseconds_before\fR (u32): seconds prior to period start +.IP \[bu] +\fBseconds_after\fR (u32): seconds after to period start +.IP \[bu] +\fBproportional_amount\fR (boolean, optional): amount should be scaled if payed after period start (always \fItrue\fR) +.RE + + +.RE + +.IP \[bu] +the following warnings are possible: +.RS +.IP \[bu] +\fBwarning_offer_unknown_currency\fR: The currency code is unknown (so no \fBminor_unit\fR) .RE -.fi -\fItype\fR: "bolt12 invoice_request" +.RE + +If \fBtype\fR is "bolt12 offer", and \fBvalid\fR is \fIfalse\fR: -.nf .RS -- *chains* (optional): if set, an array of genesis hashes of supported chains. (Unset implies bitcoin mainnet). -- *offer_id* (optional): id of the offer this invoice is for. -- *amount_msat* (optional): the amount (with "msat" appended). -- *features* (optional): hex array of feature bits. -- *quantity* (optional): quantity of items. -- *recurrence_counter* (optional): the zero-based number of the invoice for a recurring offer. -- *recurrence_start* (optional): the zero-based offet of the first invoice for the recurring offer. -- *payer_key* (optional): the 32-byte (x-only) id of the payer. -- *payer_info* (optional): a variable-length blob for the payer to derive their key. -- *recurrence_signature* (optional): BIP-340 signature of the *payer_key* on this offer. +.IP \[bu] +the following warnings are possible: +.RS +.IP \[bu] +\fBwarning_offer_missing_description\fR: No \fBdescription\fR + +.RE .RE -.fi +If \fBtype\fR is "bolt12 invoice", and \fBvalid\fR is \fItrue\fR: -\fItype\fR: "bolt11 invoice" +.RS +.IP \[bu] +\fBnode_id\fR (pubkey32): x-only public key of the offering node +.IP \[bu] +\fBsignature\fR (bip340sig): BIP-340 signature of the \fInode_id\fR on this offer +.IP \[bu] +\fBamount_msat\fR (msat): the amount in bitcoin +.IP \[bu] +\fBdescription\fR (string): the description of the purpose of the offer +.IP \[bu] +\fBtimestamp\fR (u64): the UNIX timestamp of the invoice +.IP \[bu] +\fBpayment_hash\fR (hex): the hash of the \fIpayment_preimage\fR (always 64 characters) +.IP \[bu] +\fBrelative_expiry\fR (u32): the number of seconds after \fItimestamp\fR when this expires +.IP \[bu] +\fBmin_final_cltv_expiry\fR (u32): the number of blocks required by destination +.IP \[bu] +\fBoffer_id\fR (hex, optional): the id of this offer (merkle hash of non-signature fields) (always 64 characters) +.IP \[bu] +\fBchains\fR (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): +.RS +.IP \[bu] +the genesis blockhash (always 64 characters) + +.RE -.nf +.IP \[bu] +\fBsend_invoice\fR (boolean, optional): present if this offer was a send_invoice offer (always \fItrue\fR) +.IP \[bu] +\fBrefund_for\fR (hex, optional): the \fIpayment_preimage\fR of invoice this is a refund for (always 64 characters) +.IP \[bu] +\fBvendor\fR (string, optional): the name of the vendor for this offer +.IP \[bu] +\fBfeatures\fR (hex, optional): the array of feature bits for this offer +.IP \[bu] +\fBpaths\fR (array of objects, optional): Paths to the destination: +.RS +.IP \[bu] +\fBblinding\fR (pubkey): blinding factor for this path +.IP \[bu] +\fBpath\fR (array of objects): an individual path: .RS -- *currency*: the BIP173 name for the currency. -- *timestamp*: the UNIX-style timestamp of the invoice. -- *expiry*: the number of seconds this is valid after *timestamp*. -- *payee*: the public key of the recipient. -- *payment_hash*: the payment hash of the request. -- *signature*: the DER-encoded signature. -- *description*: the UTF-8 description of the purpose of the purchase. -- *msatoshi* (optional): the number of millisatoshi requested (if any). -- *amount_msat* (optional): the same as above, with *msat* appended (if any). -- *fallbacks* (optional): array of fallback address object containing a *hex* string, and both *type* and *addr* if it is recognized as one of *P2PKH*, *P2SH*, *P2WPKH*, or *P2WSH*. -- *routes* (optional): an array of routes. Each route is an arrays of objects, each containing *pubkey*, *short_channel_id*, *fee_base_msat*, *fee_proportional_millionths* and *cltv_expiry_delta*. -- *extra* (optional): an array of objects representing unknown fields, each with one-character *tag* and a *data* bech32 string. +.IP \[bu] +\fBnode_id\fR (pubkey): node_id of the hop +.IP \[bu] +\fBenctlv\fR (hex): encrypted TLV entry for this hop + +.RE .RE -.fi +.IP \[bu] +\fBquantity\fR (u64, optional): the quantity ordered +.IP \[bu] +\fBrecurrence_counter\fR (u32, optional): the 0-based counter for a recurring payment +.IP \[bu] +\fBrecurrence_start\fR (u32, optional): the optional start period for a recurring payment +.IP \[bu] +\fBrecurrence_basetime\fR (u32, optional): the UNIX timestamp of the first recurrence period start +.IP \[bu] +\fBpayer_key\fR (pubkey32, optional): the transient key which identifies the payer +.IP \[bu] +\fBpayer_info\fR (hex, optional): the payer-provided blob to derive payer_key +.IP \[bu] +\fBfallbacks\fR (array of objects, optional): onchain addresses: +.RS +.IP \[bu] +\fBversion\fR (u8): Segwit address version +.IP \[bu] +\fBhex\fR (hex): Raw encoded segwit address +.IP \[bu] +\fBaddress\fR (string, optional): bech32 segwit address -Some invalid strings can still be parsed, and warnings will be given: +.RE -.nf +.IP \[bu] +\fBrefund_signature\fR (bip340sig, optional): the payer key signature to get a refund + +.RE + +If \fBtype\fR is "bolt12 invoice", and \fBvalid\fR is \fIfalse\fR: + +.RS +.IP \[bu] +\fBfallbacks\fR (array of objects, optional): .RS -- "warning_offer_unknown_currency": unknown or invalid *currency* code. -- "warning_offer_missing_description": invalid due to missing description. -- "warning_invoice_invalid_blinded_payinfo": blinded_payinfo does not match paths. -- "warning_invoice_fallbacks_version_invalid": a fallback version is not a valid segwit version -- "warning_invoice_fallbacks_address_invalid": a fallback address is not a valid segwit address (within an object in the *fallback* array) -- "warning_invoice_missing_amount": amount field is missing. -- "warning_invoice_missing_description": description field is missing. -- "warning_invoice_missing_blinded_payinfo": blindedpay is missing. -- "warning_invoice_missing_recurrence_basetime: recurrence_basetime is missing. -- "warning_invoice_missing_timestamp": timestamp is missing. -- "warning_invoice_missing_payment_hash": payment hash is missing. -- "warning_invoice_refund_signature_missing_payer_key": payer_key is missing for refund_signature. -- "warning_invoice_refund_signature_invalid": refund_signature does not match. -- "warning_invoice_refund_missing_signature": refund_signature is missing. -- "warning_invoice_request_missing_offer_id": offer_id is missing. -- "warning_invoice_request_missing_payer_key": payer_key is missing. -- "warning_invoice_request_invalid_recurrence_signature": recurrence_signature does not match. -- "warning_invoice_request_missing_recurrence_signature": recurrence_signature is missing. +.IP \[bu] +the following warnings are possible: +.RS +.IP \[bu] +\fBwarning_invoice_fallbacks_version_invalid\fR: \fBversion\fR is > 16 + +.RE + +.RE + +.IP \[bu] +the following warnings are possible: +.RS +.IP \[bu] +\fBwarning_invoice_missing_amount\fR: *\fIamount_msat\fR missing +.IP \[bu] +\fBwarning_invoice_missing_description\fR: No \fBdescription\fR +.IP \[bu] +\fBwarning_invoice_missing_blinded_payinfo\fR: Has \fBpaths\fR without payinfo +.IP \[bu] +\fBwarning_invoice_invalid_blinded_payinfo\fR: Does not have exactly one payinfo for each of \fBpaths\fR +.IP \[bu] +\fBwarning_invoice_missing_recurrence_basetime\fR: Has \fBrecurrence_counter\fR without \fBrecurrence_basetime\fR +.IP \[bu] +\fBwarning_invoice_missing_timestamp\fR: Missing \fBtimestamp\fR +.IP \[bu] +\fBwarning_invoice_missing_payment_hash\fR: Missing \fBpayment_hash\fR +.IP \[bu] +\fBwarning_invoice_refund_signature_missing_payer_key\fR: Missing \fBpayer_key\fR for refund_signature +.IP \[bu] +\fBwarning_invoice_refund_signature_invalid\fR: \fBrefund_signature\fR incorrect +.IP \[bu] +\fBwarning_invoice_refund_missing_signature\fR: No \fBrefund_signature\fR .RE -.fi + +.RE + +If \fBtype\fR is "bolt12 invoice_request", and \fBvalid\fR is \fItrue\fR: + +.RS +.IP \[bu] +\fBoffer_id\fR (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters) +.IP \[bu] +\fBpayer_key\fR (pubkey32): the transient key which identifies the payer +.IP \[bu] +\fBchains\fR (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): +.RS +.IP \[bu] +the genesis blockhash (always 64 characters) + +.RE + +.IP \[bu] +\fBamount_msat\fR (msat, optional): the amount in bitcoin +.IP \[bu] +\fBfeatures\fR (hex, optional): the array of feature bits for this offer +.IP \[bu] +\fBquantity\fR (u64, optional): the quantity ordered +.IP \[bu] +\fBrecurrence_counter\fR (u32, optional): the 0-based counter for a recurring payment +.IP \[bu] +\fBrecurrence_start\fR (u32, optional): the optional start period for a recurring payment +.IP \[bu] +\fBpayer_info\fR (hex, optional): the payer-provided blob to derive payer_key +.IP \[bu] +\fBrecurrence_signature\fR (bip340sig, optional): the payer key signature + +.RE + +If \fBtype\fR is "bolt12 invoice_request", and \fBvalid\fR is \fIfalse\fR: + +.RS +.IP \[bu] +the following warnings are possible: +.RS +.IP \[bu] +\fBwarning_invoice_request_missing_offer_id\fR: No \fBoffer_id\fR +.IP \[bu] +\fBwarning_invoice_request_missing_payer_key\fR: No \fBpayer_key\fR +.IP \[bu] +\fBwarning_invoice_request_missing_recurrence_signature\fR: No \fBrecurrence_signature\fR +.IP \[bu] +\fBwarning_invoice_request_invalid_recurrence_signature\fR: \fBrecurrence_signature\fR incorrect + +.RE + + +.RE + +If \fBtype\fR is "bolt11 invoice", and \fBvalid\fR is \fItrue\fR: + +.RS +.IP \[bu] +\fBcurrency\fR (string): the BIP173 name for the currency +.IP \[bu] +\fBcreated_at\fR (u64): the UNIX-style timestamp of the invoice +.IP \[bu] +\fBexpiry\fR (u64): the number of seconds this is valid after \fItimestamp\fR +.IP \[bu] +\fBpayee\fR (pubkey): the public key of the recipient +.IP \[bu] +\fBpayment_hash\fR (hex): the hash of the \fIpayment_preimage\fR (always 64 characters) +.IP \[bu] +\fBsignature\fR (signature): signature of the \fIpayee\fR on this invoice +.IP \[bu] +\fBmin_final_cltv_expiry\fR (u32): the minimum CLTV delay for the final node +.IP \[bu] +\fBamount_msat\fR (msat, optional): Amount the invoice asked for +.IP \[bu] +\fBdescription\fR (string, optional): the description of the purpose of the purchase +.IP \[bu] +\fBdescription_hash\fR (hex, optional): the hash of the description, in place of \fIdescription\fR (always 64 characters) +.IP \[bu] +\fBpayment_secret\fR (hex, optional): the secret to hand to the payee node (always 64 characters) +.IP \[bu] +\fBfeatures\fR (hex, optional): the features bitmap for this invoice +.IP \[bu] +\fBfallbacks\fR (array of objects, optional): onchain addresses: +.RS +.IP \[bu] +\fBtype\fR (string): the address type (if known) (one of "P2PKH", "P2SH", "P2WPKH", "P2WSH") +.IP \[bu] +\fBhex\fR (hex): Raw encoded address +.IP \[bu] +\fBaddr\fR (string, optional): the address in appropriate format for \fItype\fR + +.RE + +.IP \[bu] +\fBroutes\fR (array of arrays, optional): Route hints to the \fIpayee\fR: +.RS +.IP \[bu] +hops in the route: +.RS +.IP \[bu] +\fBpubkey\fR (pubkey): the public key of the node +.IP \[bu] +\fBshort_channel_id\fR (short_channel_id): a channel to the next peer +.IP \[bu] +\fBfee_base_msat\fR (u32): the base fee for payments +.IP \[bu] +\fBfee_proportional_millionths\fR (u32): the parts-per-million fee for payments +.IP \[bu] +\fBcltv_expiry_delta\fR (u32): the CLTV delta across this hop + +.RE + + +.RE + +.IP \[bu] +\fBextra\fR (array of objects, optional): Any extra fields we didn't know how to parse: +.RS +.IP \[bu] +\fBtag\fR (string): The bech32 letter which identifies this field (always 1 characters) +.IP \[bu] +\fBdata\fR (string): The bech32 data for this field + +.RE + + +.RE .SH AUTHOR Rusty Russell \fI is mainly responsible\. @@ -169,4 +414,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:4a01fe92de9520e78656495ff9093184cdf4836283af7102ee6b50ab0c826132 +\" SHA256STAMP:403b7cf3cadd8b260b8b2b02746c76d7d21a8319fe386b4174f4f58b3e5dcdbd diff --git a/doc/lightning-decode.7.md b/doc/lightning-decode.7.md index 6966b9ecc2f9..356162493914 100644 --- a/doc/lightning-decode.7.md +++ b/doc/lightning-decode.7.md @@ -19,99 +19,149 @@ other formats in future. RETURN VALUE ------------ -On success, an object is returned with a *type* member indicating the -type of the decoding: - -*type*: "bolt12 offer" - - *offer_id*: the id of this offer (merkle hash of non-signature fields) - - *chains* (optional): if set, an array of genesis hashes of supported chains. (Unset implies bitcoin mainnet). - - *currency* (optional): ISO 4217 code of the currency. - - *minor_unit* (optional): the number of decimal places to apply to amount (if currency known) - - *amount* (optional): the amount in the *currency* adjusted by *minor_unit*, if any. - - *amount_msat* (optional): the amount (with "msat" appended) if there is no *currency*. - - *send_invoice* (optional): `true` if this is a send_invoice offer. - - *refund_for* (optional): the sha256 payment_preimage of invoice this is a refund for. - - *description* (optional): the UTF-8 description of the purpose of the offer. - - *vendor* (optional): the UTF-8 name of the vendor for this offer. - - *features* (optional): hex array of feature bits. - - *absolute_expiry* (optional): UNIX timestamp of when this offer expires. - - *paths* (optional): Array of objects containing *blinding*, *path* array; each *path* entry contains an object with *node_id* and *enctlv*. - - *quantity_min* (optional): minimum valid quantity for offer responses - - *quantity_max* (optional): maximum valid quantity for offer responses - - *recurrence* (optional): an object containing *time_unit*, *time_unit_name* (optional, a string), *period*, *basetime* (optional), *start_any_period* (optional), *limit* (optional), and *paywindow* (optional) object containing *seconds_before*, *seconds_after* and *proportional_amount* (optional). - - *node_id*: 32-byte (x-only) public key of the offering node. - - *signature*: BIP-340 signature of the *node_id* on this offer. - -*type*: "bolt12 invoice" - - *chains* (optional): if set, an array of genesis hashes of supported chains. (Unset implies bitcoin mainnet). - - *offer_id* (optional): id of the offer this invoice is for. - - *amount_msat* (optional): the amount (with "msat" appended). - - *description* (optional): the UTF-8 description of the purpose of the offer. - - *vendor* (optional): the UTF-8 name of the vendor for this offer. - - *features* (optional): hex array of feature bits. - - *paths* (optional): Array of objects containing *blinding*, *path* array; each *path* entry contains an object with *node_id*, *enctlv*, *fee_base_msat* (optional), *fee_proportional_millionths* (optional), *cltv_expiry_delta* (optional), and *features* (optional). - - *quantity* (optional): quantity of items. - - *send_invoice* (optional): `true` if this is a response to a send_invoice offer. - - *refund_for* (optional): the sha256 payment_preimage of invoice this is a refund for. - - *recurrence_counter* (optional): the zero-based number of the invoice for a recurring offer. - - *recurrence_start* (optional): the zero-based offet of the first invoice for the recurring offer. - - *recurrence_basetime* (optional): the UNIX timestamp of the first period of the offer. - - *payer_key* (optional): the 32-byte (x-only) id of the payer. - - *payer_info* (optional): a variable-length blob for the payer to derive their key. - - *timestamp* (optional): the UNIX timestamp of the invoice. - - *payment_hash* (optional): the hex SHA256 of the payment_preimage. - - *expiry* (optional): seconds from *timestamp* when invoice expires. - - *min_final_cltv_expiry*: required CLTV for final hop. - - *fallbacks* (optional): an array containing objects with *version*, and *hex* fields for each fallback address, and *address* (optional) if it's parsable. - - *refund_signature* (optional): BIP-340 signature of the *payer_key* on this offer. - - *node_id*: 32-byte (x-only) public key of the invoicing node. - - *signature*: BIP-340 signature of the *node_id* on this invoice. - -*type*: "bolt12 invoice_request" - - *chains* (optional): if set, an array of genesis hashes of supported chains. (Unset implies bitcoin mainnet). - - *offer_id* (optional): id of the offer this invoice is for. - - *amount_msat* (optional): the amount (with "msat" appended). - - *features* (optional): hex array of feature bits. - - *quantity* (optional): quantity of items. - - *recurrence_counter* (optional): the zero-based number of the invoice for a recurring offer. - - *recurrence_start* (optional): the zero-based offet of the first invoice for the recurring offer. - - *payer_key* (optional): the 32-byte (x-only) id of the payer. - - *payer_info* (optional): a variable-length blob for the payer to derive their key. - - *recurrence_signature* (optional): BIP-340 signature of the *payer_key* on this offer. - -*type*: "bolt11 invoice" - - *currency*: the BIP173 name for the currency. - - *timestamp*: the UNIX-style timestamp of the invoice. - - *expiry*: the number of seconds this is valid after *timestamp*. - - *payee*: the public key of the recipient. - - *payment_hash*: the payment hash of the request. - - *signature*: the DER-encoded signature. - - *description*: the UTF-8 description of the purpose of the purchase. - - *msatoshi* (optional): the number of millisatoshi requested (if any). - - *amount_msat* (optional): the same as above, with *msat* appended (if any). - - *fallbacks* (optional): array of fallback address object containing a *hex* string, and both *type* and *addr* if it is recognized as one of *P2PKH*, *P2SH*, *P2WPKH*, or *P2WSH*. - - *routes* (optional): an array of routes. Each route is an arrays of objects, each containing *pubkey*, *short_channel_id*, *fee_base_msat*, *fee_proportional_millionths* and *cltv_expiry_delta*. - - *extra* (optional): an array of objects representing unknown fields, each with one-character *tag* and a *data* bech32 string. - -Some invalid strings can still be parsed, and warnings will be given: - - "warning_offer_unknown_currency": unknown or invalid *currency* code. - - "warning_offer_missing_description": invalid due to missing description. - - "warning_invoice_invalid_blinded_payinfo": blinded_payinfo does not match paths. - - "warning_invoice_fallbacks_version_invalid": a fallback version is not a valid segwit version - - "warning_invoice_fallbacks_address_invalid": a fallback address is not a valid segwit address (within an object in the *fallback* array) - - "warning_invoice_missing_amount": amount field is missing. - - "warning_invoice_missing_description": description field is missing. - - "warning_invoice_missing_blinded_payinfo": blindedpay is missing. - - "warning_invoice_missing_recurrence_basetime: recurrence_basetime is missing. - - "warning_invoice_missing_timestamp": timestamp is missing. - - "warning_invoice_missing_payment_hash": payment hash is missing. - - "warning_invoice_refund_signature_missing_payer_key": payer_key is missing for refund_signature. - - "warning_invoice_refund_signature_invalid": refund_signature does not match. - - "warning_invoice_refund_missing_signature": refund_signature is missing. - - "warning_invoice_request_missing_offer_id": offer_id is missing. - - "warning_invoice_request_missing_payer_key": payer_key is missing. - - "warning_invoice_request_invalid_recurrence_signature": recurrence_signature does not match. - - "warning_invoice_request_missing_recurrence_signature": recurrence_signature is missing. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **type** (string): what kind of object it decoded to (one of "bolt12 offer", "bolt12 invoice", "bolt12 invoice_request", "bolt11 invoice") +- **valid** (boolean): if this is false, you *MUST* not use the result except for diagnostics! + +If **type** is "bolt12 offer", and **valid** is *true*: + - **offer_id** (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters) + - **node_id** (pubkey32): x-only public key of the offering node + - **signature** (bip340sig): BIP-340 signature of the *node_id* on this offer + - **description** (string): the description of the purpose of the offer + - **chains** (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): + - the genesis blockhash (always 64 characters) + - **currency** (string, optional): ISO 4217 code of the currency (missing implies Bitcoin) (always 3 characters) + - **minor_unit** (u32, optional): the number of decimal places to apply to amount (if currency known) + - **amount** (u64, optional): the amount in the *currency* adjusted by *minor_unit*, if any + - **amount_msat** (msat, optional): the amount in bitcoin (if specified, and no *currency*) + - **send_invoice** (boolean, optional): present if this is a send_invoice offer (always *true*) + - **refund_for** (hex, optional): the *payment_preimage* of invoice this is a refund for (always 64 characters) + - **vendor** (string, optional): the name of the vendor for this offer + - **features** (hex, optional): the array of feature bits for this offer + - **absolute_expiry** (u64, optional): UNIX timestamp of when this offer expires + - **paths** (array of objects, optional): Paths to the destination: + - **blinding** (pubkey): blinding factor for this path + - **path** (array of objects): an individual path: + - **node_id** (pubkey): node_id of the hop + - **enctlv** (hex): encrypted TLV entry for this hop + - **quantity_min** (u64, optional): the minimum quantity + - **quantity_max** (u64, optional): the maximum quantity + - **recurrence** (object, optional): how often to this offer should be used: + - **time_unit** (u32): the BOLT12 time unit + - **period** (u32): how many *time_unit* per payment period + - **time_unit_name** (string, optional): the name of *time_unit* (if valid) + - **basetime** (u64, optional): period starts at this UNIX timestamp + - **start_any_period** (u64, optional): you can start at any period (only if **basetime** present) + - **limit** (u32, optional): maximum period number for recurrence + - **paywindow** (object, optional): when within a period will payment be accepted (default is prior and during the period): + - **seconds_before** (u32): seconds prior to period start + - **seconds_after** (u32): seconds after to period start + - **proportional_amount** (boolean, optional): amount should be scaled if payed after period start (always *true*) + - the following warnings are possible: + - **warning_offer_unknown_currency**: The currency code is unknown (so no **minor_unit**) + +If **type** is "bolt12 offer", and **valid** is *false*: + - the following warnings are possible: + - **warning_offer_missing_description**: No **description** + +If **type** is "bolt12 invoice", and **valid** is *true*: + - **node_id** (pubkey32): x-only public key of the offering node + - **signature** (bip340sig): BIP-340 signature of the *node_id* on this offer + - **amount_msat** (msat): the amount in bitcoin + - **description** (string): the description of the purpose of the offer + - **timestamp** (u64): the UNIX timestamp of the invoice + - **payment_hash** (hex): the hash of the *payment_preimage* (always 64 characters) + - **relative_expiry** (u32): the number of seconds after *timestamp* when this expires + - **min_final_cltv_expiry** (u32): the number of blocks required by destination + - **offer_id** (hex, optional): the id of this offer (merkle hash of non-signature fields) (always 64 characters) + - **chains** (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): + - the genesis blockhash (always 64 characters) + - **send_invoice** (boolean, optional): present if this offer was a send_invoice offer (always *true*) + - **refund_for** (hex, optional): the *payment_preimage* of invoice this is a refund for (always 64 characters) + - **vendor** (string, optional): the name of the vendor for this offer + - **features** (hex, optional): the array of feature bits for this offer + - **paths** (array of objects, optional): Paths to the destination: + - **blinding** (pubkey): blinding factor for this path + - **path** (array of objects): an individual path: + - **node_id** (pubkey): node_id of the hop + - **enctlv** (hex): encrypted TLV entry for this hop + - **quantity** (u64, optional): the quantity ordered + - **recurrence_counter** (u32, optional): the 0-based counter for a recurring payment + - **recurrence_start** (u32, optional): the optional start period for a recurring payment + - **recurrence_basetime** (u32, optional): the UNIX timestamp of the first recurrence period start + - **payer_key** (pubkey32, optional): the transient key which identifies the payer + - **payer_info** (hex, optional): the payer-provided blob to derive payer_key + - **fallbacks** (array of objects, optional): onchain addresses: + - **version** (u8): Segwit address version + - **hex** (hex): Raw encoded segwit address + - **address** (string, optional): bech32 segwit address + - **refund_signature** (bip340sig, optional): the payer key signature to get a refund + +If **type** is "bolt12 invoice", and **valid** is *false*: + - **fallbacks** (array of objects, optional): + - the following warnings are possible: + - **warning_invoice_fallbacks_version_invalid**: **version** is > 16 + - the following warnings are possible: + - **warning_invoice_missing_amount**: **amount_msat* missing + - **warning_invoice_missing_description**: No **description** + - **warning_invoice_missing_blinded_payinfo**: Has **paths** without payinfo + - **warning_invoice_invalid_blinded_payinfo**: Does not have exactly one payinfo for each of **paths** + - **warning_invoice_missing_recurrence_basetime**: Has **recurrence_counter** without **recurrence_basetime** + - **warning_invoice_missing_timestamp**: Missing **timestamp** + - **warning_invoice_missing_payment_hash**: Missing **payment_hash** + - **warning_invoice_refund_signature_missing_payer_key**: Missing **payer_key** for refund_signature + - **warning_invoice_refund_signature_invalid**: **refund_signature** incorrect + - **warning_invoice_refund_missing_signature**: No **refund_signature** + +If **type** is "bolt12 invoice_request", and **valid** is *true*: + - **offer_id** (hex): the id of this offer (merkle hash of non-signature fields) (always 64 characters) + - **payer_key** (pubkey32): the transient key which identifies the payer + - **chains** (array of hexs, optional): which blockchains this offer is for (missing implies bitcoin mainnet only): + - the genesis blockhash (always 64 characters) + - **amount_msat** (msat, optional): the amount in bitcoin + - **features** (hex, optional): the array of feature bits for this offer + - **quantity** (u64, optional): the quantity ordered + - **recurrence_counter** (u32, optional): the 0-based counter for a recurring payment + - **recurrence_start** (u32, optional): the optional start period for a recurring payment + - **payer_info** (hex, optional): the payer-provided blob to derive payer_key + - **recurrence_signature** (bip340sig, optional): the payer key signature + +If **type** is "bolt12 invoice_request", and **valid** is *false*: + - the following warnings are possible: + - **warning_invoice_request_missing_offer_id**: No **offer_id** + - **warning_invoice_request_missing_payer_key**: No **payer_key** + - **warning_invoice_request_missing_recurrence_signature**: No **recurrence_signature** + - **warning_invoice_request_invalid_recurrence_signature**: **recurrence_signature** incorrect + +If **type** is "bolt11 invoice", and **valid** is *true*: + - **currency** (string): the BIP173 name for the currency + - **created_at** (u64): the UNIX-style timestamp of the invoice + - **expiry** (u64): the number of seconds this is valid after *timestamp* + - **payee** (pubkey): the public key of the recipient + - **payment_hash** (hex): the hash of the *payment_preimage* (always 64 characters) + - **signature** (signature): signature of the *payee* on this invoice + - **min_final_cltv_expiry** (u32): the minimum CLTV delay for the final node + - **amount_msat** (msat, optional): Amount the invoice asked for + - **description** (string, optional): the description of the purpose of the purchase + - **description_hash** (hex, optional): the hash of the description, in place of *description* (always 64 characters) + - **payment_secret** (hex, optional): the secret to hand to the payee node (always 64 characters) + - **features** (hex, optional): the features bitmap for this invoice + - **fallbacks** (array of objects, optional): onchain addresses: + - **type** (string): the address type (if known) (one of "P2PKH", "P2SH", "P2WPKH", "P2WSH") + - **hex** (hex): Raw encoded address + - **addr** (string, optional): the address in appropriate format for *type* + - **routes** (array of arrays, optional): Route hints to the *payee*: + - hops in the route: + - **pubkey** (pubkey): the public key of the node + - **short_channel_id** (short_channel_id): a channel to the next peer + - **fee_base_msat** (u32): the base fee for payments + - **fee_proportional_millionths** (u32): the parts-per-million fee for payments + - **cltv_expiry_delta** (u32): the CLTV delta across this hop + - **extra** (array of objects, optional): Any extra fields we didn't know how to parse: + - **tag** (string): The bech32 letter which identifies this field (always 1 characters) + - **data** (string): The bech32 data for this field +[comment]: # (GENERATE-FROM-SCHEMA-END) AUTHOR ------ @@ -133,3 +183,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:733d22404e5230882682b846ace92451d8988cf028fa903d735f61b7c61f1c08) diff --git a/doc/lightning-decodepay.7 b/doc/lightning-decodepay.7 index ad51e9d79e69..e491f7348cf5 100644 --- a/doc/lightning-decodepay.7 +++ b/doc/lightning-decodepay.7 @@ -12,46 +12,77 @@ specified by the BOLT 11 specification\. .SH RETURN VALUE -On success, an object is returned with the following fields, as -specified by BOLT11: +On success, an object is returned, containing: .RS .IP \[bu] -\fIcurrency\fR: the BIP173 name for the currency\. +\fBcurrency\fR (string): the BIP173 name for the currency .IP \[bu] -\fItimestamp\fR: the UNIX-style timestamp of the invoice\. +\fBcreated_at\fR (u64): the UNIX-style timestamp of the invoice .IP \[bu] -\fIexpiry\fR: the number of seconds this is valid after \fItimestamp\fR\. +\fBexpiry\fR (u64): the number of seconds this is valid after \fItimestamp\fR .IP \[bu] -\fIpayee\fR: the public key of the recipient\. +\fBpayee\fR (pubkey): the public key of the recipient .IP \[bu] -\fIpayment_hash\fR: the payment hash of the request\. +\fBpayment_hash\fR (hex): the hash of the \fIpayment_preimage\fR (always 64 characters) .IP \[bu] -\fIsignature\fR: the DER-encoded signature\. +\fBsignature\fR (signature): signature of the \fIpayee\fR on this invoice .IP \[bu] -\fIdescription\fR: the description of the purpose of the purchase (see -below) +\fBmin_final_cltv_expiry\fR (u32): the minimum CLTV delay for the final node +.IP \[bu] +\fBamount_msat\fR (msat, optional): Amount the invoice asked for +.IP \[bu] +\fBdescription\fR (string, optional): the description of the purpose of the purchase +.IP \[bu] +\fBdescription_hash\fR (hex, optional): the hash of the description, in place of \fIdescription\fR (always 64 characters) +.IP \[bu] +\fBpayment_secret\fR (hex, optional): the secret to hand to the payee node (always 64 characters) +.IP \[bu] +\fBfeatures\fR (hex, optional): the features bitmap for this invoice +.IP \[bu] +\fBfallbacks\fR (array of objects, optional): onchain addresses: +.RS +.IP \[bu] +\fBtype\fR (string): the address type (if known) (one of "P2PKH", "P2SH", "P2WPKH", "P2WSH") +.IP \[bu] +\fBhex\fR (hex): Raw encoded address +.IP \[bu] +\fBaddr\fR (string, optional): the address in appropriate format for \fItype\fR .RE -The following fields are optional: - +.IP \[bu] +\fBroutes\fR (array of arrays, optional): Route hints to the \fIpayee\fR: +.RS +.IP \[bu] +hops in the route: .RS .IP \[bu] -\fImsatoshi\fR: the number of millisatoshi requested (if any)\. +\fBpubkey\fR (pubkey): the public key of the node .IP \[bu] -\fIamount_msat\fR: the same as above, with \fImsat\fR appended (if any)\. +\fBshort_channel_id\fR (short_channel_id): a channel to the next peer .IP \[bu] -\fIfallbacks\fR: array of fallback address object containing a \fIhex\fR -string, and both \fItype\fR and \fIaddr\fR if it is recognized as one of -\fIP2PKH\fR, \fIP2SH\fR, \fIP2WPKH\fR, or \fIP2WSH\fR\. +\fBfee_base_msat\fR (u32): the base fee for payments .IP \[bu] -\fIroutes\fR: an array of routes\. Each route is an arrays of objects, -each containing \fIpubkey\fR, \fIshort_channel_id\fR, \fIfee_base_msat\fR, -\fIfee_proportional_millionths\fR and \fIcltv_expiry_delta\fR\. +\fBfee_proportional_millionths\fR (u32): the parts-per-million fee for payments .IP \[bu] -\fIextra\fR: an array of objects representing unknown fields, each with -one-character \fItag\fR and a \fIdata\fR bech32 string\. +\fBcltv_expiry_delta\fR (u32): the CLTV delta across this hop + +.RE + + +.RE + +.IP \[bu] +\fBextra\fR (array of objects, optional): Any extra fields we didn't know how to parse: +.RS +.IP \[bu] +\fBtag\fR (string): The bech32 letter which identifies this field (always 1 characters) +.IP \[bu] +\fBdata\fR (string): The bech32 data for this field + +.RE + .RE @@ -76,4 +107,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:d3944c14e16584577e0336dda8c2689881524717428eb921e23f8831144ec566 +\" SHA256STAMP:1b0e5c34291b3c252c651e952109f57fe68a90770fecaa0eeebf9070ed8c2dad diff --git a/doc/lightning-decodepay.7.md b/doc/lightning-decodepay.7.md index 695315171dc6..786a692ef76a 100644 --- a/doc/lightning-decodepay.7.md +++ b/doc/lightning-decodepay.7.md @@ -15,28 +15,35 @@ specified by the BOLT 11 specification. RETURN VALUE ------------ -On success, an object is returned with the following fields, as -specified by BOLT11: -- *currency*: the BIP173 name for the currency. -- *timestamp*: the UNIX-style timestamp of the invoice. -- *expiry*: the number of seconds this is valid after *timestamp*. -- *payee*: the public key of the recipient. -- *payment\_hash*: the payment hash of the request. -- *signature*: the DER-encoded signature. -- *description*: the description of the purpose of the purchase (see - below) - -The following fields are optional: -- *msatoshi*: the number of millisatoshi requested (if any). -- *amount\_msat*: the same as above, with *msat* appended (if any). -- *fallbacks*: array of fallback address object containing a *hex* - string, and both *type* and *addr* if it is recognized as one of - *P2PKH*, *P2SH*, *P2WPKH*, or *P2WSH*. -- *routes*: an array of routes. Each route is an arrays of objects, - each containing *pubkey*, *short\_channel\_id*, *fee\_base\_msat*, - *fee\_proportional\_millionths* and *cltv\_expiry\_delta*. -- *extra*: an array of objects representing unknown fields, each with - one-character *tag* and a *data* bech32 string. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **currency** (string): the BIP173 name for the currency +- **created_at** (u64): the UNIX-style timestamp of the invoice +- **expiry** (u64): the number of seconds this is valid after *timestamp* +- **payee** (pubkey): the public key of the recipient +- **payment_hash** (hex): the hash of the *payment_preimage* (always 64 characters) +- **signature** (signature): signature of the *payee* on this invoice +- **min_final_cltv_expiry** (u32): the minimum CLTV delay for the final node +- **amount_msat** (msat, optional): Amount the invoice asked for +- **description** (string, optional): the description of the purpose of the purchase +- **description_hash** (hex, optional): the hash of the description, in place of *description* (always 64 characters) +- **payment_secret** (hex, optional): the secret to hand to the payee node (always 64 characters) +- **features** (hex, optional): the features bitmap for this invoice +- **fallbacks** (array of objects, optional): onchain addresses: + - **type** (string): the address type (if known) (one of "P2PKH", "P2SH", "P2WPKH", "P2WSH") + - **hex** (hex): Raw encoded address + - **addr** (string, optional): the address in appropriate format for *type* +- **routes** (array of arrays, optional): Route hints to the *payee*: + - hops in the route: + - **pubkey** (pubkey): the public key of the node + - **short_channel_id** (short_channel_id): a channel to the next peer + - **fee_base_msat** (u32): the base fee for payments + - **fee_proportional_millionths** (u32): the parts-per-million fee for payments + - **cltv_expiry_delta** (u32): the CLTV delta across this hop +- **extra** (array of objects, optional): Any extra fields we didn't know how to parse: + - **tag** (string): The bech32 letter which identifies this field (always 1 characters) + - **data** (string): The bech32 data for this field +[comment]: # (GENERATE-FROM-SCHEMA-END) Technically, the *description* field is optional if a *description\_hash* field is given, but in this case **decodepay** will @@ -61,3 +68,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:33a160a1d9e56690e59b71c4d9d3e141bf7604c111cd5a5624bda692b85c9026) diff --git a/doc/schemas/decode.schema.json b/doc/schemas/decode.schema.json new file mode 100644 index 000000000000..f76db53578a4 --- /dev/null +++ b/doc/schemas/decode.schema.json @@ -0,0 +1,806 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "type", "valid" ], + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 offer", "bolt12 invoice", "bolt12 invoice_request", "bolt11 invoice" ], + "description": "what kind of object it decoded to" + }, + "valid": { + "type": "boolean", + "description": "if this is false, you *MUST* not use the result except for diagnostics!" + } + }, + "allOf": [ + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 offer" ] + }, + "valid": { + "type": "boolean", + "enum": [ true ] + } + } + }, + "then": { + "required": [ "offer_id", "node_id", "signature", "description" ], + "additionalProperties": false, + "properties": { + "type": { }, + "valid": { }, + "offer_id": { + "type": "hex", + "description": "the id of this offer (merkle hash of non-signature fields)", + "maxLength": 64, + "minLength": 64 + }, + "node_id": { + "type": "pubkey32", + "description": "x-only public key of the offering node" + }, + "signature": { + "type": "bip340sig", + "description": "BIP-340 signature of the *node_id* on this offer" + }, + "chains": { + "type": "array", + "description": "which blockchains this offer is for (missing implies bitcoin mainnet only)", + "items": { + "type": "hex", + "description": "the genesis blockhash", + "maxLength": 64, + "minLength": 64 + } + }, + "currency": { + "type": "string", + "description": "ISO 4217 code of the currency (missing implies Bitcoin)", + "maxLength": 3, + "minLength": 3 + }, + "minor_unit": { + "type": "u32", + "description": "the number of decimal places to apply to amount (if currency known)" + }, + "warning_offer_unknown_currency": { + "type": "string", + "description": "The currency code is unknown (so no **minor_unit**)" + }, + "amount": { + "type": "u64", + "description": "the amount in the *currency* adjusted by *minor_unit*, if any" + }, + "amount_msat": { + "type": "msat", + "description": "the amount in bitcoin (if specified, and no *currency*)" + }, + "send_invoice": { + "type": "boolean", + "description": "present if this is a send_invoice offer", + "enum" : [ true ] + }, + "refund_for": { + "type": "hex", + "description": "the *payment_preimage* of invoice this is a refund for", + "maxLength": 64, + "minLength": 64 + }, + "description": { + "type": "string", + "description": "the description of the purpose of the offer" + }, + "vendor": { + "type": "string", + "description": "the name of the vendor for this offer" + }, + "features": { + "type": "hex", + "description": "the array of feature bits for this offer" + }, + "absolute_expiry": { + "type": "u64", + "description": "UNIX timestamp of when this offer expires" + }, + "paths": { + "type": "array", + "description": "Paths to the destination", + "items": { + "type": "object", + "required": [ "blinding", "path" ], + "additionalProperties": false, + "properties": { + "blinding": { + "type": "pubkey", + "description": "blinding factor for this path" + }, + "path": { + "type": "array", + "description": "an individual path", + "items": { + "type": "object", + "required": [ "node_id", "enctlv" ], + "additionalProperties": false, + "properties": { + "node_id": { + "type": "pubkey", + "description": "node_id of the hop" + }, + "enctlv": { + "type": "hex", + "description": "encrypted TLV entry for this hop" + } + } + } + } + } + } + }, + "quantity_min": { + "type": "u64", + "description": "the minimum quantity" + }, + "quantity_max": { + "type": "u64", + "description": "the maximum quantity" + }, + "recurrence": { + "type": "object", + "description": "how often to this offer should be used", + "required": [ "period", "time_unit" ], + "additionalProperties": false, + "properties": { + "time_unit": { + "type": "u32", + "description": "the BOLT12 time unit" + }, + "time_unit_name": { + "type": "string", + "description": "the name of *time_unit* (if valid)" + }, + "period": { + "type": "u32", + "description": "how many *time_unit* per payment period" + }, + "basetime": { + "type": "u64", + "description": "period starts at this UNIX timestamp" + }, + "start_any_period": { + "type": "u64", + "description": "you can start at any period (only if **basetime** present)" + }, + "limit": { + "type": "u32", + "description": "maximum period number for recurrence" + }, + "paywindow": { + "type": "object", + "description": "when within a period will payment be accepted (default is prior and during the period)", + "required": [ "seconds_before", "seconds_after" ], + "additionalProperties": false, + "properties": { + "seconds_before": { + "type": "u32", + "description": "seconds prior to period start" + }, + "seconds_after": { + "type": "u32", + "description": "seconds after to period start" + }, + "proportional_amount": { + "type": "boolean", + "enum": [ true ], + "description": "amount should be scaled if payed after period start" + } + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 offer" ] + }, + "valid": { + "type": "boolean", + "enum": [false ] + } + } + }, + "then": { + "required": [ ], + "additionalProperties": false, + "properties": { + "type": { }, + "valid": { }, + "offer_id": { }, + "node_id": { }, + "signature": { }, + "chains": { }, + "currency": { }, + "minor_unit": { }, + "warning_offer_unknown_currency": { }, + "amount": { }, + "amount_msat": { }, + "send_invoice": { }, + "refund_for": { }, + "description": { }, + "vendor": { }, + "features": { }, + "absolute_expiry": { }, + "paths": { }, + "quantity_min": { }, + "quantity_max": { }, + "recurrence": { }, + "warning_offer_missing_description": { + "type": "string", + "description": "No **description**" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 invoice" ] + }, + "valid": { + "type": "boolean", + "enum": [ true ] + } + } + }, + "then": { + "required": [ "node_id", "signature", "amount_msat", "description", "timestamp", "payment_hash", "relative_expiry", "min_final_cltv_expiry" ], + "additionalProperties": false, + "properties": { + "type": { }, + "valid": { }, + "offer_id": { + "type": "hex", + "description": "the id of this offer (merkle hash of non-signature fields)", + "maxLength": 64, + "minLength": 64 + }, + "node_id": { + "type": "pubkey32", + "description": "x-only public key of the offering node" + }, + "signature": { + "type": "bip340sig", + "description": "BIP-340 signature of the *node_id* on this offer" + }, + "chains": { + "type": "array", + "description": "which blockchains this offer is for (missing implies bitcoin mainnet only)", + "items": { + "type": "hex", + "description": "the genesis blockhash", + "maxLength": 64, + "minLength": 64 + } + }, + "amount_msat": { + "type": "msat", + "description": "the amount in bitcoin" + }, + "send_invoice": { + "type": "boolean", + "description": "present if this offer was a send_invoice offer", + "enum" : [ true ] + }, + "refund_for": { + "type": "hex", + "description": "the *payment_preimage* of invoice this is a refund for", + "maxLength": 64, + "minLength": 64 + }, + "description": { + "type": "string", + "description": "the description of the purpose of the offer" + }, + "vendor": { + "type": "string", + "description": "the name of the vendor for this offer" + }, + "features": { + "type": "hex", + "description": "the array of feature bits for this offer" + }, + "paths": { + "type": "array", + "description": "Paths to the destination", + "items": { + "type": "object", + "required": [ "blinding", "path" ], + "additionalProperties": false, + "properties": { + "blinding": { + "type": "pubkey", + "description": "blinding factor for this path" + }, + "path": { + "type": "array", + "description": "an individual path", + "items": { + "type": "object", + "required": [ "node_id", "enctlv" ], + "additionalProperties": false, + "properties": { + "node_id": { + "type": "pubkey", + "description": "node_id of the hop" + }, + "enctlv": { + "type": "hex", + "description": "encrypted TLV entry for this hop" + } + } + } + } + } + } + }, + "quantity": { + "type": "u64", + "description": "the quantity ordered" + }, + "recurrence_counter": { + "type": "u32", + "description": "the 0-based counter for a recurring payment" + }, + "recurrence_start": { + "type": "u32", + "description": "the optional start period for a recurring payment" + }, + "recurrence_basetime": { + "type": "u32", + "description": "the UNIX timestamp of the first recurrence period start" + }, + "payer_key": { + "type": "pubkey32", + "description": "the transient key which identifies the payer" + }, + "payer_info": { + "type": "hex", + "description": "the payer-provided blob to derive payer_key" + }, + "timestamp": { + "type": "u64", + "description": "the UNIX timestamp of the invoice" + }, + "payment_hash": { + "type": "hex", + "description": "the hash of the *payment_preimage*", + "maxLength": 64, + "minLength": 64 + }, + "relative_expiry": { + "type": "u32", + "description": "the number of seconds after *timestamp* when this expires" + }, + "min_final_cltv_expiry": { + "type": "u32", + "description": "the number of blocks required by destination" + }, + "fallbacks": { + "type": "array", + "description": "onchain addresses", + "items": { + "type": "object", + "required": ["version", "hex"], + "additionalProperties": false, + "properties": { + "version": { + "type": "u8", + "description": "Segwit address version" + }, + "hex": { + "type": "hex", + "description": "Raw encoded segwit address" + }, + "address": { + "type": "string", + "description": "bech32 segwit address" + } + } + } + }, + "refund_signature": { + "type": "bip340sig", + "description": "the payer key signature to get a refund" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 invoice" ] + }, + "valid": { + "type": "boolean", + "enum": [ false ] + } + } + }, + "then": { + "required": [ ], + "additionalProperties": false, + "properties": { + "type": { }, + "valid": { }, + "offer_id": { }, + "node_id": { }, + "signature": { }, + "chains": { }, + "amount_msat": { }, + "send_invoice": { }, + "refund_for": { }, + "description": { }, + "vendor": { }, + "features": { }, + "paths": { }, + "quantity": { }, + "recurrence_counter": { }, + "recurrence_start": { }, + "recurrence_basetime": { }, + "payer_key": { }, + "payer_info": { }, + "timestamp": { }, + "payment_hash": { }, + "relative_expiry": { }, + "min_final_cltv_expiry": { }, + "fallbacks": { }, + "refund_signature": { }, + "warning_invoice_missing_amount": { + "type": "string", + "description": "**amount_msat* missing" + }, + "warning_invoice_missing_description": { + "type": "string", + "description": "No **description**" + }, + "warning_invoice_missing_blinded_payinfo": { + "type": "string", + "description": "Has **paths** without payinfo" + }, + "warning_invoice_invalid_blinded_payinfo": { + "type": "string", + "description": "Does not have exactly one payinfo for each of **paths**" + }, + "warning_invoice_missing_recurrence_basetime": { + "type": "string", + "description": "Has **recurrence_counter** without **recurrence_basetime**" + }, + "warning_invoice_missing_timestamp": { + "type": "string", + "description": "Missing **timestamp**" + }, + "warning_invoice_missing_payment_hash": { + "type": "string", + "description": "Missing **payment_hash**" + }, + "warning_invoice_refund_signature_missing_payer_key": { + "type": "string", + "description": "Missing **payer_key** for refund_signature" + }, + "warning_invoice_refund_signature_invalid": { + "type": "string", + "description": "**refund_signature** incorrect" + }, + "warning_invoice_refund_missing_signature": { + "type": "string", + "description": "No **refund_signature**" + }, + "fallbacks": { + "type": "array", + "items": { + "type": "object", + "required": ["version", "hex"], + "properties": { + "version": { }, + "hex": { }, + "address": { }, + "warning_invoice_fallbacks_version_invalid": { + "type": "string", + "description": "**version** is > 16" + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 invoice_request" ] + }, + "valid": { + "type": "boolean", + "enum": [ true ] + } + } + }, + "then": { + "required": [ "offer_id", "payer_key" ], + "additionalProperties": false, + "properties": { + "type": { }, + "valid": { }, + "offer_id": { + "type": "hex", + "description": "the id of this offer (merkle hash of non-signature fields)", + "maxLength": 64, + "minLength": 64 + }, + "chains": { + "type": "array", + "description": "which blockchains this offer is for (missing implies bitcoin mainnet only)", + "items": { + "type": "hex", + "description": "the genesis blockhash", + "maxLength": 64, + "minLength": 64 + } + }, + "amount_msat": { + "type": "msat", + "description": "the amount in bitcoin" + }, + "features": { + "type": "hex", + "description": "the array of feature bits for this offer" + }, + "quantity": { + "type": "u64", + "description": "the quantity ordered" + }, + "recurrence_counter": { + "type": "u32", + "description": "the 0-based counter for a recurring payment" + }, + "recurrence_start": { + "type": "u32", + "description": "the optional start period for a recurring payment" + }, + "payer_key": { + "type": "pubkey32", + "description": "the transient key which identifies the payer" + }, + "payer_info": { + "type": "hex", + "description": "the payer-provided blob to derive payer_key" + }, + "recurrence_signature": { + "type": "bip340sig", + "description": "the payer key signature" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt12 invoice_request" ] + }, + "valid": { + "type": "boolean", + "enum": [ false ] + } + } + }, + "then": { + "required": [ ], + "additionalProperties": false, + "properties": { + "type": { }, + "valid": { }, + "offer_id": { }, + "chains": { }, + "amount_msat": { }, + "features": { }, + "quantity": { }, + "recurrence_counter": { }, + "recurrence_start": { }, + "payer_key": { }, + "payer_info": { }, + "recurrence_signature": { }, + "warning_invoice_request_missing_offer_id": { + "type": "string", + "description": "No **offer_id**" + }, + "warning_invoice_request_missing_payer_key": { + "type": "string", + "description": "No **payer_key**" + }, + "warning_invoice_request_missing_recurrence_signature": { + "type": "string", + "description": "No **recurrence_signature**" + }, + "warning_invoice_request_invalid_recurrence_signature": { + "type": "string", + "description": "**recurrence_signature** incorrect" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "type": "string", + "enum": [ "bolt11 invoice" ] + }, + "valid": { + "type": "boolean", + "enum": [ true ] + } + } + }, + "then": { + "required": [ "currency", "created_at", "expiry", "payee", "min_final_cltv_expiry", "payment_hash", "signature" ], + "additionalProperties": false, + "properties": { + "currency": { + "type": "string", + "description": "the BIP173 name for the currency" + }, + "created_at": { + "type": "u64", + "description": "the UNIX-style timestamp of the invoice" + }, + "expiry": { + "type": "u64", + "description": "the number of seconds this is valid after *timestamp*" + }, + "payee": { + "type": "pubkey", + "description": "the public key of the recipient" + }, + "msatoshi": { + "type": "u64", + "deprecated": true + }, + "amount_msat": { + "type": "msat", + "description": "Amount the invoice asked for" + }, + "payment_hash": { + "type": "hex", + "description": "the hash of the *payment_preimage*", + "maxLength": 64, + "minLength": 64 + }, + "signature": { + "type": "signature", + "description": "signature of the *payee* on this invoice" + }, + "description": { + "type": "string", + "description": "the description of the purpose of the purchase" + }, + "description_hash": { + "type": "hex", + "description": "the hash of the description, in place of *description*", + "maxLength": 64, + "minLength": 64 + }, + "min_final_cltv_expiry": { + "type": "u32", + "description": "the minimum CLTV delay for the final node" + }, + "payment_secret": { + "type": "hex", + "description": "the secret to hand to the payee node", + "maxLength": 64, + "minLength": 64 + }, + "features": { + "type": "hex", + "description": "the features bitmap for this invoice" + }, + "fallbacks": { + "type": "array", + "description": "onchain addresses", + "items": { + "type": "object", + "required": ["type", "hex"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "description": "the address type (if known)", + "enum": [ "P2PKH", "P2SH", "P2WPKH", "P2WSH" ] + }, + "addr": { + "type": "string", + "description": "the address in appropriate format for *type*" + }, + "hex": { + "type": "hex", + "description": "Raw encoded address" + } + } + } + }, + "routes": { + "type": "array", + "description": "Route hints to the *payee*", + "items": { + "type": "array", + "description": "hops in the route", + "items": { + "type": "object", + "required": [ "pubkey", "short_channel_id", "fee_base_msat", "fee_proportional_millionths", "cltv_expiry_delta" ], + "additionalProperties": false, + "properties": { + "pubkey": { + "type": "pubkey", + "description": "the public key of the node" + }, + "short_channel_id": { + "type": "short_channel_id", + "description": "a channel to the next peer" + }, + "fee_base_msat": { + "type": "u32", + "description": "the base fee for payments" + }, + "fee_proportional_millionths": { + "type": "u32", + "description": "the parts-per-million fee for payments" + }, + "cltv_expiry_delta": { + "type": "u32", + "description": "the CLTV delta across this hop" + } + } + } + } + }, + "extra": { + "type": "array", + "description": "Any extra fields we didn't know how to parse", + "items": { + "type": "object", + "required": [ "tag", "data" ], + "additionalProperties": false, + "properties": { + "tag": { + "type": "string", + "description": "The bech32 letter which identifies this field", + "maxLength": 1, + "minLength": 1 + }, + "data": { + "type": "string", + "description": "The bech32 data for this field" + } + } + } + } + } + } + } + ] +} diff --git a/doc/schemas/decodepay.schema.json b/doc/schemas/decodepay.schema.json new file mode 100644 index 000000000000..9494042936c6 --- /dev/null +++ b/doc/schemas/decodepay.schema.json @@ -0,0 +1,146 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "currency", "created_at", "expiry", "payee", "min_final_cltv_expiry", "payment_hash", "signature" ], + "additionalProperties": false, + "properties": { + "currency": { + "type": "string", + "description": "the BIP173 name for the currency" + }, + "created_at": { + "type": "u64", + "description": "the UNIX-style timestamp of the invoice" + }, + "expiry": { + "type": "u64", + "description": "the number of seconds this is valid after *timestamp*" + }, + "payee": { + "type": "pubkey", + "description": "the public key of the recipient" + }, + "msatoshi": { + "type": "u64", + "deprecated": true + }, + "amount_msat": { + "type": "msat", + "description": "Amount the invoice asked for" + }, + "payment_hash": { + "type": "hex", + "description": "the hash of the *payment_preimage*", + "maxLength": 64, + "minLength": 64 + }, + "signature": { + "type": "signature", + "description": "signature of the *payee* on this invoice" + }, + "description": { + "type": "string", + "description": "the description of the purpose of the purchase" + }, + "description_hash": { + "type": "hex", + "description": "the hash of the description, in place of *description*", + "maxLength": 64, + "minLength": 64 + }, + "min_final_cltv_expiry": { + "type": "u32", + "description": "the minimum CLTV delay for the final node" + }, + "payment_secret": { + "type": "hex", + "description": "the secret to hand to the payee node", + "maxLength": 64, + "minLength": 64 + }, + "features": { + "type": "hex", + "description": "the features bitmap for this invoice" + }, + "fallbacks": { + "type": "array", + "description": "onchain addresses", + "items": { + "type": "object", + "required": ["type", "hex"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "description": "the address type (if known)", + "enum": [ "P2PKH", "P2SH", "P2WPKH", "P2WSH" ] + }, + "addr": { + "type": "string", + "description": "the address in appropriate format for *type*" + }, + "hex": { + "type": "hex", + "description": "Raw encoded address" + } + } + } + }, + "routes": { + "type": "array", + "description": "Route hints to the *payee*", + "items": { + "type": "array", + "description": "hops in the route", + "items": { + "type": "object", + "required": [ "pubkey", "short_channel_id", "fee_base_msat", "fee_proportional_millionths", "cltv_expiry_delta" ], + "additionalProperties": false, + "properties": { + "pubkey": { + "type": "pubkey", + "description": "the public key of the node" + }, + "short_channel_id": { + "type": "short_channel_id", + "description": "a channel to the next peer" + }, + "fee_base_msat": { + "type": "u32", + "description": "the base fee for payments" + }, + "fee_proportional_millionths": { + "type": "u32", + "description": "the parts-per-million fee for payments" + }, + "cltv_expiry_delta": { + "type": "u32", + "description": "the CLTV delta across this hop" + } + } + } + } + }, + "extra": { + "type": "array", + "description": "Any extra fields we didn't know how to parse", + "items": { + "type": "object", + "required": [ "tag", "data" ], + "additionalProperties": false, + "properties": { + "tag": { + "type": "string", + "description": "The bech32 letter which identifies this field", + "maxLength": 1, + "minLength": 1 + }, + "data": { + "type": "string", + "description": "The bech32 data for this field" + } + } + } + } + } +} From a77d15c7b180abfa81caa7a530f91465374467a8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 15:25:01 +0930 Subject: [PATCH 17/19] doc/schemas: delexpiredinvoice, delinvoice, delpay. Signed-off-by: Rusty Russell --- doc/lightning-delexpiredinvoice.7 | 2 +- doc/lightning-delexpiredinvoice.7.md | 3 + doc/lightning-delinvoice.7 | 43 +++++++++++- doc/lightning-delinvoice.7.md | 22 ++++++- doc/lightning-delpay.7 | 39 ++++++++++- doc/lightning-delpay.7.md | 23 ++++++- doc/schemas/delexpiredinvoice.schema.json | 8 +++ doc/schemas/delinvoice.schema.json | 79 +++++++++++++++++++++++ doc/schemas/delpay.schema.json | 75 +++++++++++++++++++++ 9 files changed, 283 insertions(+), 11 deletions(-) create mode 100644 doc/schemas/delexpiredinvoice.schema.json create mode 100644 doc/schemas/delinvoice.schema.json create mode 100644 doc/schemas/delpay.schema.json diff --git a/doc/lightning-delexpiredinvoice.7 b/doc/lightning-delexpiredinvoice.7 index a71442906cfc..680de0f1210f 100644 --- a/doc/lightning-delexpiredinvoice.7 +++ b/doc/lightning-delexpiredinvoice.7 @@ -30,4 +30,4 @@ ZmnSCPxj \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:f7cd68f4d2ef071b45ee705da17a1180775096a2cc64c370822c8c610d1a3979 +\" SHA256STAMP:a47d47609d9b39bbe6c0f0c61e28d255ceb496a49ad306db22ef23011c6f8cb8 diff --git a/doc/lightning-delexpiredinvoice.7.md b/doc/lightning-delexpiredinvoice.7.md index ecf22b3cce15..0f12ecbb8680 100644 --- a/doc/lightning-delexpiredinvoice.7.md +++ b/doc/lightning-delexpiredinvoice.7.md @@ -18,7 +18,9 @@ deleted. RETURN VALUE ------------ +[comment]: # (GENERATE-FROM-SCHEMA-START) On success, an empty object is returned. +[comment]: # (GENERATE-FROM-SCHEMA-END) AUTHOR ------ @@ -35,3 +37,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:f267fd509a5e3e55e2322ddc8b233eb820638ed5f50f606e3e6c8ae17f1c8421) diff --git a/doc/lightning-delinvoice.7 b/doc/lightning-delinvoice.7 index 876fbde1add0..ef620be23636 100644 --- a/doc/lightning-delinvoice.7 +++ b/doc/lightning-delinvoice.7 @@ -16,9 +16,46 @@ The caller should be particularly aware of the error case caused by the .SH RETURN VALUE -On success, an invoice description will be returned as per -\fBlightning-listinvoice\fR(7)\. +Note: The return is the same as an object from \fBlightning-listinvoice\fR(7)\. + +On success, an object is returned, containing: + +.RS +.IP \[bu] +\fBlabel\fR (string): Unique label given at creation time +.IP \[bu] +\fBstatus\fR (string): State of invoice (one of "paid", "expired", "unpaid") +.IP \[bu] +\fBexpires_at\fR (u64): UNIX timestamp when invoice expires (or expired) +.IP \[bu] +\fBbolt11\fR (string, optional): BOLT11 string +.IP \[bu] +\fBbolt12\fR (string, optional): BOLT12 string + +.RE + +If \fBbolt12\fR is present: + +.RS +.IP \[bu] +\fBlocal_offer_id\fR (hex, optional): offer for which this invoice was created + +.RE + +If \fBstatus\fR is "paid": + +.RS +.IP \[bu] +\fBpay_index\fR (u64): unique index for this invoice payment +.IP \[bu] +\fBamount_received_msat\fR (msat): how much was actually received +.IP \[bu] +\fBpaid_at\fR (u64): UNIX timestamp of when payment was received +.IP \[bu] +\fBpayment_preimage\fR (hex): SHA256 of this is the \fIpayment_hash\fR offered in the invoice (always 64 characters) + +.RE .SH ERRORS The following errors may be reported: @@ -50,4 +87,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:92ad4501574b253334bb570960d1835c8bd84483e318ea058e6b565d34109832 +\" SHA256STAMP:28d1e97fe8e8925008b20815c55db569b7ed8dad33d958c0914945c71fb9d654 diff --git a/doc/lightning-delinvoice.7.md b/doc/lightning-delinvoice.7.md index 96feb506d767..c699bc7de2fb 100644 --- a/doc/lightning-delinvoice.7.md +++ b/doc/lightning-delinvoice.7.md @@ -18,8 +18,25 @@ The caller should be particularly aware of the error case caused by the RETURN VALUE ------------ -On success, an invoice description will be returned as per -lightning-listinvoice(7). +Note: The return is the same as an object from lightning-listinvoice(7). + +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **label** (string): Unique label given at creation time +- **status** (string): State of invoice (one of "paid", "expired", "unpaid") +- **expires_at** (u64): UNIX timestamp when invoice expires (or expired) +- **bolt11** (string, optional): BOLT11 string +- **bolt12** (string, optional): BOLT12 string + +If **bolt12** is present: + - **local_offer_id** (hex, optional): offer for which this invoice was created + +If **status** is "paid": + - **pay_index** (u64): unique index for this invoice payment + - **amount_received_msat** (msat): how much was actually received + - **paid_at** (u64): UNIX timestamp of when payment was received + - **payment_preimage** (hex): SHA256 of this is the *payment_hash* offered in the invoice (always 64 characters) +[comment]: # (GENERATE-FROM-SCHEMA-END) ERRORS ------ @@ -51,3 +68,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:8cd84ec57d229dacb6d6c52510334da87846f1c8eea7db286063a2513e8318cb) diff --git a/doc/lightning-delpay.7 b/doc/lightning-delpay.7 index 356bf9862169..2a20c2445c68 100644 --- a/doc/lightning-delpay.7 +++ b/doc/lightning-delpay.7 @@ -33,10 +33,43 @@ Only deletes if the payment status matches\. .fi .SH RETURN VALUE -If successful the command returns a payment object, in the same format as \fBlistsendpays\fR\. If the payment is a multi-part payment (MPP) the command return a list of -payments will be return -- one payment object for each partid\. +The returned format is the same as \fBlightning-listsendpays\fR(7)\. If the +payment is a multi-part payment (MPP) the command return a list of +payments will be returned -- one payment object for each partid\. +On success, an object containing \fBpayments\fR is returned\. It is an array of objects, where each object contains: + +.RS +.IP \[bu] +\fBid\fR (u64): unique ID for this payment attempt +.IP \[bu] +\fBpayment_hash\fR (hex): the hash of the \fIpayment_preimage\fR which will prove payment (always 64 characters) +.IP \[bu] +\fBstatus\fR (string): status of the payment (one of "pending", "failed", "complete") +.IP \[bu] +\fBamount_sent_msat\fR (msat): the amount we actually sent, including fees +.IP \[bu] +\fBcreated_at\fR (u64): the UNIX timestamp showing when this payment was initiated +.IP \[bu] +\fBpartid\fR (u64, optional): unique ID within this (multi-part) payment +.IP \[bu] +\fBdestination\fR (pubkey, optional): the final destination of the payment if known +.IP \[bu] +\fBamount_msat\fR (msat, optional): the amount the destination received, if known +.IP \[bu] +\fBpayment_preimage\fR (hex, optional): proof of payment (always 64 characters) +.IP \[bu] +\fBlabel\fR (string, optional): the label, if given to sendpay +.IP \[bu] +\fBbolt11\fR (string, optional): the bolt11 string (if pay supplied one) +.IP \[bu] +\fBbolt12\fR (string, optional): the bolt12 string (if supplied for pay: \fBexperimental-offers\fR only)\. +.IP \[bu] +\fBerroronion\fR (hex, optional): the error onion returned on failure, if any\. + +.RE + On failure, an error is returned\. If the lightning process fails before responding, the caller should use \fBlightning-listsentpays\fR(7) or \fBlightning-listpays\fR(7) to query whether this payment was deleted or not\. @@ -87,4 +120,4 @@ Vincenzo Palazzo \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:b10dd430aaace8b9f3607e72c871e2a883934f9a51d5bc0068a024df5ef1d6ee +\" SHA256STAMP:520f0b56c7288ed46509a0ab90be0959b3b1489b56b7e94f223de19cf7028758 diff --git a/doc/lightning-delpay.7.md b/doc/lightning-delpay.7.md index 8c9a78f27c45..d3c7094a45fe 100644 --- a/doc/lightning-delpay.7.md +++ b/doc/lightning-delpay.7.md @@ -31,8 +31,26 @@ EXAMPLE JSON REQUEST RETURN VALUE ------------ -If successful the command returns a payment object, in the same format as **listsendpays**. If the payment is a multi-part payment (MPP) the command return a list of -payments will be return -- one payment object for each partid. +The returned format is the same as lightning-listsendpays(7). If the +payment is a multi-part payment (MPP) the command return a list of +payments will be returned -- one payment object for each partid. + +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object containing **payments** is returned. It is an array of objects, where each object contains: +- **id** (u64): unique ID for this payment attempt +- **payment_hash** (hex): the hash of the *payment_preimage* which will prove payment (always 64 characters) +- **status** (string): status of the payment (one of "pending", "failed", "complete") +- **amount_sent_msat** (msat): the amount we actually sent, including fees +- **created_at** (u64): the UNIX timestamp showing when this payment was initiated +- **partid** (u64, optional): unique ID within this (multi-part) payment +- **destination** (pubkey, optional): the final destination of the payment if known +- **amount_msat** (msat, optional): the amount the destination received, if known +- **payment_preimage** (hex, optional): proof of payment (always 64 characters) +- **label** (string, optional): the label, if given to sendpay +- **bolt11** (string, optional): the bolt11 string (if pay supplied one) +- **bolt12** (string, optional): the bolt12 string (if supplied for pay: **experimental-offers** only). +- **erroronion** (hex, optional): the error onion returned on failure, if any. +[comment]: # (GENERATE-FROM-SCHEMA-END) On failure, an error is returned. If the lightning process fails before responding, the caller should use lightning-listsentpays(7) or lightning-listpays(7) to query whether this payment was deleted or not. @@ -81,3 +99,4 @@ RESOURCES --------- Main web site: +[comment]: # ( SHA256STAMP:26e293e5b3de31a95572763a6d7c360c0f9f78112b3fcef12c639d001b0fa9b5) diff --git a/doc/schemas/delexpiredinvoice.schema.json b/doc/schemas/delexpiredinvoice.schema.json new file mode 100644 index 000000000000..3f3efd17a47a --- /dev/null +++ b/doc/schemas/delexpiredinvoice.schema.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ ], + "additionalProperties": false, + "properties": { + } +} diff --git a/doc/schemas/delinvoice.schema.json b/doc/schemas/delinvoice.schema.json new file mode 100644 index 000000000000..846237a30951 --- /dev/null +++ b/doc/schemas/delinvoice.schema.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "label", "payment_hash", "amount_msat", "status", "expires_at" ], + "additionalProperties": true, + "properties": { + "label": { + "type": "string", + "description": "Unique label given at creation time" + }, + "bolt11": { + "type": "string", + "description": "BOLT11 string" + }, + "bolt12": { + "type": "string", + "description": "BOLT12 string" + }, + "status": { + "type": "string", + "description": "State of invoice", + "enum": [ "paid", "expired", "unpaid" ] + }, + "expires_at": { + "type": "u64", + "description": "UNIX timestamp when invoice expires (or expired)" + } + }, + "allOf": [ + { + "if": { + "required": [ "bolt12" ] + }, + "then": { + "required": [ ], + "properties": { + "local_offer_id": { + "type": "hex", + "description": "offer for which this invoice was created" + } + } + } + }, + { + "if": { + "properties": { + "status": { + "type": "string", + "enum": [ "paid" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "pay_index", "amount_received_msat", "paid_at", "payment_preimage" ], + "properties": { + "pay_index": { + "type": "u64", + "description": "unique index for this invoice payment" + }, + "amount_received_msat": { + "type": "msat", + "description": "how much was actually received" + }, + "paid_at": { + "type": "u64", + "description": "UNIX timestamp of when payment was received" + }, + "payment_preimage": { + "type": "hex", + "description": "SHA256 of this is the *payment_hash* offered in the invoice", + "maxLength": 64, + "minLength": 64 + } + } + } + } + ] +} diff --git a/doc/schemas/delpay.schema.json b/doc/schemas/delpay.schema.json new file mode 100644 index 000000000000..3a1ed1ba633e --- /dev/null +++ b/doc/schemas/delpay.schema.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "payments" ], + "additionalProperties": false, + "properties": { + "payments": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "required": [ "id", "payment_hash", "status", "amount_sent_msat", "created_at" ], + "properties": { + "id": { + "type": "u64", + "description": "unique ID for this payment attempt" + }, + "payment_hash": { + "type": "hex", + "description": "the hash of the *payment_preimage* which will prove payment", + "maxLength": 64, + "minLength": 64 + }, + "status": { + "type": "string", + "enum": [ "pending", "failed", "complete" ], + "description": "status of the payment" + }, + "amount_sent_msat": { + "type": "msat", + "description": "the amount we actually sent, including fees" + }, + "partid": { + "type": "u64", + "description": "unique ID within this (multi-part) payment" + }, + "destination": { + "type": "pubkey", + "description": "the final destination of the payment if known" + }, + "amount_msat": { + "type": "msat", + "description": "the amount the destination received, if known" + }, + "created_at": { + "type": "u64", + "description": "the UNIX timestamp showing when this payment was initiated" + }, + "payment_preimage": { + "type": "hex", + "description": "proof of payment", + "maxLength": 64, + "minLength": 64 + }, + "label": { + "type": "string", + "description": "the label, if given to sendpay" + }, + "bolt11": { + "type": "string", + "description": "the bolt11 string (if pay supplied one)" + }, + "bolt12": { + "type": "string", + "description": "the bolt12 string (if supplied for pay: **experimental-offers** only)." + }, + "erroronion": { + "type": "hex", + "description": "the error onion returned on failure, if any." + } + } + } + } + } +} From 2ab804366c4c39f97de553ac25c0934489f543f8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 May 2021 17:05:01 +0930 Subject: [PATCH 18/19] doc/schemas: disableoffer, disconnect, feerates, fetchinvoice, fundchannel, fundchannel_cancel, fundchannel_complete, fundchannel_start, fundpsbt, getinfo, getlog, getroute. We also add a test for getlog, since it was never called by the testsuite. Signed-off-by: Rusty Russell --- doc/lightning-disableoffer.7 | 23 +++- doc/lightning-disableoffer.7.md | 14 +- doc/lightning-disconnect.7 | 2 +- doc/lightning-disconnect.7.md | 3 + doc/lightning-feerates.7 | 94 ++++++++------ doc/lightning-feerates.7.md | 72 +++++------ doc/lightning-fetchinvoice.7 | 50 +++----- doc/lightning-fetchinvoice.7.md | 40 +++--- doc/lightning-fundchannel.7 | 23 ++-- doc/lightning-fundchannel.7.md | 17 +-- doc/lightning-fundchannel_cancel.7 | 10 +- doc/lightning-fundchannel_cancel.7.md | 7 +- doc/lightning-fundchannel_complete.7 | 12 +- doc/lightning-fundchannel_complete.7.md | 8 +- doc/lightning-fundchannel_start.7 | 15 ++- doc/lightning-fundchannel_start.7.md | 10 +- doc/lightning-fundpsbt.7 | 2 +- doc/lightning-fundpsbt.7.md | 1 + doc/lightning-getinfo.7 | 60 ++++++--- doc/lightning-getinfo.7.md | 46 ++++--- doc/lightning-getlog.7 | 54 ++++++-- doc/lightning-getlog.7.md | 37 ++++-- doc/lightning-getroute.7 | 28 ++-- doc/lightning-getroute.7.md | 20 ++- doc/schemas/disableoffer.schema.json | 35 +++++ doc/schemas/disconnect.schema.json | 7 + doc/schemas/feerates.schema.json | 119 +++++++++++++++++ doc/schemas/fetchinvoice.schema.json | 68 ++++++++++ doc/schemas/fundchannel.schema.json | 30 +++++ doc/schemas/fundchannel_cancel.schema.json | 12 ++ doc/schemas/fundchannel_complete.schema.json | 19 +++ doc/schemas/fundchannel_start.schema.json | 20 +++ doc/schemas/fundpsbt.schema.json | 61 +++++++++ doc/schemas/getinfo.schema.json | 124 ++++++++++++++++++ doc/schemas/getlog.schema.json | 127 +++++++++++++++++++ doc/schemas/getroute.schema.json | 47 +++++++ tests/test_misc.py | 13 ++ 37 files changed, 1083 insertions(+), 247 deletions(-) create mode 100644 doc/schemas/disableoffer.schema.json create mode 100644 doc/schemas/disconnect.schema.json create mode 100644 doc/schemas/feerates.schema.json create mode 100644 doc/schemas/fetchinvoice.schema.json create mode 100644 doc/schemas/fundchannel.schema.json create mode 100644 doc/schemas/fundchannel_cancel.schema.json create mode 100644 doc/schemas/fundchannel_complete.schema.json create mode 100644 doc/schemas/fundchannel_start.schema.json create mode 100644 doc/schemas/fundpsbt.schema.json create mode 100644 doc/schemas/getinfo.schema.json create mode 100644 doc/schemas/getlog.schema.json create mode 100644 doc/schemas/getroute.schema.json diff --git a/doc/lightning-disableoffer.7 b/doc/lightning-disableoffer.7 index 1b1547e38bed..88f923c77d86 100644 --- a/doc/lightning-disableoffer.7 +++ b/doc/lightning-disableoffer.7 @@ -33,9 +33,26 @@ forgotten entirely (there may be invoices which refer to this offer)\. .fi .SH RETURN VALUE -If successful the command returns an object, in the same format as \fBlistoffers\fR\. -The "active" field will always be false\. +Note: the returned object is the same format as \fBlistoffers\fR\. + +On success, an object is returned, containing: + +.RS +.IP \[bu] +\fBoffer_id\fR (hex): the merkle hash of the offer (always 64 characters) +.IP \[bu] +\fBactive\fR (boolean): Whether the offer can produce invoices/payments (always "false") +.IP \[bu] +\fBsingle_use\fR (boolean): Whether the offer is disabled after first successful use +.IP \[bu] +\fBbolt12\fR (string): The bolt12 string representing this offer +.IP \[bu] +\fBused\fR (boolean): Whether the offer has had an invoice paid / payment made +.IP \[bu] +\fBlabel\fR (string, optional): The label provided when offer was created + +.RE .SH EXAMPLE JSON RESPONSE .nf .RS @@ -61,4 +78,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:55cfb050fa2d28f58750dc74659d9f7bc5ec00499e218ccffd058db51efc38d2 +\" SHA256STAMP:33b8cddae4a830e710906268c1d0d301442bc7ab0711e1d6ce670f86c77ae320 diff --git a/doc/lightning-disableoffer.7.md b/doc/lightning-disableoffer.7.md index 398fd04387ce..201cd99c5f91 100644 --- a/doc/lightning-disableoffer.7.md +++ b/doc/lightning-disableoffer.7.md @@ -32,8 +32,17 @@ EXAMPLE JSON REQUEST RETURN VALUE ------------ -If successful the command returns an object, in the same format as **listoffers**. -The "active" field will always be false. +Note: the returned object is the same format as **listoffers**. + +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **offer_id** (hex): the merkle hash of the offer (always 64 characters) +- **active** (boolean): Whether the offer can produce invoices/payments (always "false") +- **single_use** (boolean): Whether the offer is disabled after first successful use +- **bolt12** (string): The bolt12 string representing this offer +- **used** (boolean): Whether the offer has had an invoice paid / payment made +- **label** (string, optional): The label provided when offer was created +[comment]: # (GENERATE-FROM-SCHEMA-END) EXAMPLE JSON RESPONSE ----- @@ -63,3 +72,4 @@ RESOURCES --------- Main web site: +[comment]: # ( SHA256STAMP:6b0ae21e38a83742735f38e9c022b33ed4a436cacc746ff22e63d7b00779e4d0) diff --git a/doc/lightning-disconnect.7 b/doc/lightning-disconnect.7 index bbea46d36085..5110a38014c2 100644 --- a/doc/lightning-disconnect.7 +++ b/doc/lightning-disconnect.7 @@ -63,4 +63,4 @@ Michael Hawkins \fI\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:fe16ccb06f56e5b59a1aea19b1a6625624b93e668cd07bba9e3f581873fa3eab +\" SHA256STAMP:7efc0fbbb7397d3767ea170ba091b5bc00f4efaf8e1283c7b7ed1aaaccfd3c4d diff --git a/doc/lightning-disconnect.7.md b/doc/lightning-disconnect.7.md index e3bc72a7f450..30571804aa24 100644 --- a/doc/lightning-disconnect.7.md +++ b/doc/lightning-disconnect.7.md @@ -33,7 +33,9 @@ connection. RETURN VALUE ------------ +[comment]: # (GENERATE-FROM-SCHEMA-START) On success, an empty object is returned. +[comment]: # (GENERATE-FROM-SCHEMA-END) On error the returned object will contain `code` and `message` properties, with `code` being one of the following: @@ -56,3 +58,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:f974a3848c4db5b73fffa969a741ef6619c9a375783fabe731882d84a6bbf5ff) diff --git a/doc/lightning-feerates.7 b/doc/lightning-feerates.7 index c6ec64de2a00..294aeaf2fc46 100644 --- a/doc/lightning-feerates.7 +++ b/doc/lightning-feerates.7 @@ -54,61 +54,77 @@ which will override the recommended feerates returned by \fBfeerates\fR\. .SH RETURN VALUE -The \fBfeerates\fR command returns the feerates in an object named -\fIperkw\fR or \fIperkb\fR, depending on your \fIstyle\fR parameter\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBperkb\fR (object, optional): If \fIstyle\fR parameter was perkb: +.RS +.IP \[bu] +\fBmin_acceptable\fR (u32): The smallest feerate that you can use, usually the minimum relayed feerate of the backend +.IP \[bu] +\fBmax_acceptable\fR (u32): The largest feerate we will accept from remote negotiations\. If a peer attempts to set the feerate higher than this we will unilaterally close the channel (or simply forget it if it's not open yet)\. +.IP \[bu] +\fBopening\fR (u32, optional): Default feerate for \fBlightning-fundchannel\fR(7) and \fBlightning-withdraw\fR(7) +.IP \[bu] +\fBmutual_close\fR (u32, optional): Feerate to aim for in cooperative shutdown\. Note that since mutual close is a \fBnegotiation\fR, the actual feerate used in mutual close will be somewhere between this and the corresponding mutual close feerate of the peer\. +.IP \[bu] +\fBunilateral_close\fR (u32, optional): Feerate for commitment_transaction in a live channel which we originally funded +.IP \[bu] +\fBdelayed_to_us\fR (u32, optional): Feerate for returning unilateral close funds to our wallet +.IP \[bu] +\fBhtlc_resolution\fR (u32, optional): Feerate for returning unilateral close HTLC outputs to our wallet +.IP \[bu] +\fBpenalty\fR (u32, optional): Feerate to start at when penalizing a cheat attempt -Some of these estimations may be missing, except for \fImin_acceptable\fR -and \fImax_acceptable\fR, which are always present\. +.RE +.IP \[bu] +\fBperkw\fR (object, optional): If \fIstyle\fR parameter was perkw: +.RS +.IP \[bu] +\fBmin_acceptable\fR (u32): The smallest feerate that you can use, usually the minimum relayed feerate of the backend +.IP \[bu] +\fBmax_acceptable\fR (u32): The largest feerate we will accept from remote negotiations\. If a peer attempts to set the feerate higher than this we will unilaterally close the channel (or simply forget it if it's not open yet)\. +.IP \[bu] +\fBopening\fR (u32, optional): Default feerate for \fBlightning-fundchannel\fR(7) and \fBlightning-withdraw\fR(7) +.IP \[bu] +\fBmutual_close\fR (u32, optional): Feerate to aim for in cooperative shutdown\. Note that since mutual close is a \fBnegotiation\fR, the actual feerate used in mutual close will be somewhere between this and the corresponding mutual close feerate of the peer\. +.IP \[bu] +\fBunilateral_close\fR (u32, optional): Feerate for commitment_transaction in a live channel which we originally funded +.IP \[bu] +\fBdelayed_to_us\fR (u32, optional): Feerate for returning unilateral close funds to our wallet +.IP \[bu] +\fBhtlc_resolution\fR (u32, optional): Feerate for returning unilateral close HTLC outputs to our wallet +.IP \[bu] +\fBpenalty\fR (u32, optional): Feerate to start at when penalizing a cheat attempt -The \fIperkw\fR or \fIperkb\fR object may have fields containing the estimates: +.RE -.RS .IP \[bu] -\fIopening\fR - feerate used for channel opening by \fBlightning-fundchannel\fR(7), -as well as normal onchain-to-onchain spends by \fBlightning-withdraw\fR(7)\. -In general, for all normal onchain-to-onchain spends, this is the feerate -you should also use\. +\fBonchain_fee_estimates\fR (object, optional): +.RS .IP \[bu] -\fImutual_close\fR - the starting feerate used in mutual close negotiation\. -Note that since mutual close is a \fBnegotiation\fR, -the actual feerate used in mutual close -will be somewhere between this -and the corresponding mutual close feerate of the peer\. +\fBopening_channel_satoshis\fR (u64): Estimated cost of typical channel open .IP \[bu] -\fIunilateral_close\fR - the feerate we will pay for when a unilateral close -is done on a channel we originally funded\. -When anchor commitments are implemented, -this will be the feerate we will use -for a unilateral close we initiated\. +\fBmutual_close_satoshis\fR (u64): Estimated cost of typical channel close .IP \[bu] -\fIdelayed_to_us\fR - the feerate we will use when claiming our output from -a unilateral close we initiated\. +\fBunilateral_close_satoshis\fR (u64): Estimated cost of typical unilateral close (without HTLCs) .IP \[bu] -\fIhtlc_resolution\fR - the feerate we will use to claim HTLCs -from a unilateral close we initiated\. +\fBhtlc_timeout_satoshis\fR (u64): Estimated cost of typical HTLC timeout transaction .IP \[bu] -\fIpenalty\fR - the feerate we will use to revoke old state, -if the counterparty attempts to cheat us\. +\fBhtlc_success_satoshis\fR (u64): Estimated cost of typical HTLC fulfillment transaction .RE -The following fields are always present in the \fIperkw\fR or \fIperkb\fR object: + +.RE + +The following warnings may also be returned: .RS .IP \[bu] -\fImin_acceptable\fR - the smallest feerate that you can use, -usually the minimum relayed feerate of the backend\. -.IP \[bu] -\fImax_acceptable\fR - the largest feerate we will accept -from remote negotiations\. -If a peer attempts to open a channel to us but wants a unilateral close -feerate larger than \fImax_acceptable\fR, we reject the open attempt\. -If the peer attempts to change the unilateral close feerate of a channel it -opened to us, such that the new feerate exceeds \fImax_acceptable\fR, we -unilaterally close the channel -(at the current unilateral close feerate instead of the new one)\. +\fBwarning_missing_feerates\fR: Some fee estimates are missing .RE .SH ERRORS @@ -153,4 +169,4 @@ manpage\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:f0fc7218cc1286cb6fb299cf81553d851d4ba4fee570e7bb169593d17aea951b +\" SHA256STAMP:6e1ae2f26676a76231461ac1f696066e538edabfab00ec9480550a5c6bc6981e diff --git a/doc/lightning-feerates.7.md b/doc/lightning-feerates.7.md index 043ab6237a1e..79ae753e669e 100644 --- a/doc/lightning-feerates.7.md +++ b/doc/lightning-feerates.7.md @@ -44,47 +44,36 @@ which will override the recommended feerates returned by **feerates**. RETURN VALUE ------------ -The **feerates** command returns the feerates in an object named -*perkw* or *perkb*, depending on your *style* parameter. - -Some of these estimations may be missing, except for *min\_acceptable* -and *max\_acceptable*, which are always present. - -The *perkw* or *perkb* object may have fields containing the estimates: - -* *opening* - feerate used for channel opening by lightning-fundchannel(7), - as well as normal onchain-to-onchain spends by lightning-withdraw(7). - In general, for all normal onchain-to-onchain spends, this is the feerate - you should also use. -* *mutual\_close* - the starting feerate used in mutual close negotiation. - Note that since mutual close is a **negotiation**, - the actual feerate used in mutual close - will be somewhere between this - and the corresponding mutual close feerate of the peer. -* *unilateral\_close* - the feerate we will pay for when a unilateral close - is done on a channel we originally funded. - When anchor commitments are implemented, - this will be the feerate we will use - for a unilateral close we initiated. -* *delayed\_to\_us* - the feerate we will use when claiming our output from - a unilateral close we initiated. -* *htlc_resolution* - the feerate we will use to claim HTLCs - from a unilateral close we initiated. -* *penalty* - the feerate we will use to revoke old state, - if the counterparty attempts to cheat us. - -The following fields are always present in the *perkw* or *perkb* object: - -* *min\_acceptable* - the smallest feerate that you can use, - usually the minimum relayed feerate of the backend. -* *max\_acceptable* - the largest feerate we will accept - from remote negotiations. - If a peer attempts to open a channel to us but wants a unilateral close - feerate larger than *max\_acceptable*, we reject the open attempt. - If the peer attempts to change the unilateral close feerate of a channel it - opened to us, such that the new feerate exceeds *max\_acceptable*, we - unilaterally close the channel - (at the current unilateral close feerate instead of the new one). +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **perkb** (object, optional): If *style* parameter was perkb: + - **min_acceptable** (u32): The smallest feerate that you can use, usually the minimum relayed feerate of the backend + - **max_acceptable** (u32): The largest feerate we will accept from remote negotiations. If a peer attempts to set the feerate higher than this we will unilaterally close the channel (or simply forget it if it's not open yet). + - **opening** (u32, optional): Default feerate for lightning-fundchannel(7) and lightning-withdraw(7) + - **mutual_close** (u32, optional): Feerate to aim for in cooperative shutdown. Note that since mutual close is a **negotiation**, the actual feerate used in mutual close will be somewhere between this and the corresponding mutual close feerate of the peer. + - **unilateral_close** (u32, optional): Feerate for commitment_transaction in a live channel which we originally funded + - **delayed_to_us** (u32, optional): Feerate for returning unilateral close funds to our wallet + - **htlc_resolution** (u32, optional): Feerate for returning unilateral close HTLC outputs to our wallet + - **penalty** (u32, optional): Feerate to start at when penalizing a cheat attempt +- **perkw** (object, optional): If *style* parameter was perkw: + - **min_acceptable** (u32): The smallest feerate that you can use, usually the minimum relayed feerate of the backend + - **max_acceptable** (u32): The largest feerate we will accept from remote negotiations. If a peer attempts to set the feerate higher than this we will unilaterally close the channel (or simply forget it if it's not open yet). + - **opening** (u32, optional): Default feerate for lightning-fundchannel(7) and lightning-withdraw(7) + - **mutual_close** (u32, optional): Feerate to aim for in cooperative shutdown. Note that since mutual close is a **negotiation**, the actual feerate used in mutual close will be somewhere between this and the corresponding mutual close feerate of the peer. + - **unilateral_close** (u32, optional): Feerate for commitment_transaction in a live channel which we originally funded + - **delayed_to_us** (u32, optional): Feerate for returning unilateral close funds to our wallet + - **htlc_resolution** (u32, optional): Feerate for returning unilateral close HTLC outputs to our wallet + - **penalty** (u32, optional): Feerate to start at when penalizing a cheat attempt +- **onchain_fee_estimates** (object, optional): + - **opening_channel_satoshis** (u64): Estimated cost of typical channel open + - **mutual_close_satoshis** (u64): Estimated cost of typical channel close + - **unilateral_close_satoshis** (u64): Estimated cost of typical unilateral close (without HTLCs) + - **htlc_timeout_satoshis** (u64): Estimated cost of typical HTLC timeout transaction + - **htlc_success_satoshis** (u64): Estimated cost of typical HTLC fulfillment transaction + +The following warnings may also be returned: +- **warning_missing_feerates**: Some fee estimates are missing +[comment]: # (GENERATE-FROM-SCHEMA-END) ERRORS ------ @@ -129,3 +118,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:e16ae963e528995f1e01c80b4ed4e9b0d6c457a559928e98ab6cf32624557894) diff --git a/doc/lightning-fetchinvoice.7 b/doc/lightning-fetchinvoice.7 index ec1223ca1a07..753f4c66ec18 100644 --- a/doc/lightning-fetchinvoice.7 +++ b/doc/lightning-fetchinvoice.7 @@ -47,55 +47,43 @@ we fail (default, 60 seconds)\. .SH RETURN VALUE -On success, an object as follows is returned: +On success, an object is returned, containing: .RS .IP \[bu] -\fIinvoice\fR: the bolt12-encoded invoice string, starting with "lni1"\. +\fBinvoice\fR (string): The BOLT12 invoice we fetched .IP \[bu] -\fIchanges\fR: an object detailing changes between the offer and invoice\. - -.RE - -Optionally: - +\fBchanges\fR (object): Summary of changes from offer: .RS .IP \[bu] -\fInext_period\fR: an object returned for recurring invoices if the next -period is under the recurrence_limit (if any)\. - -.RE - -The \fIchanges\fR object can have and of the following members: - -.RS -.IP \[bu] -\fIdescription_appended\fR: extra characters appended to the \fIdescription\fR field\. +\fBdescription_appended\fR (string, optional): extra characters appended to the \fIdescription\fR field\. .IP \[bu] -\fIdescription\fR: a completely replaced \fIdescription\fR field\. +\fBdescription\fR (string, optional): a completely replaced \fIdescription\fR field .IP \[bu] -\fIvendor_removed\fR": the offer vendor field, which has been omitted from the invoice\. +\fBvendor_removed\fR (string, optional): The \fIvendor\fR from the offer, which is missing in the invoice .IP \[bu] -\fIvendor\fR": the offer vendor field, which has changed from the invoice\. +\fBvendor\fR (string, optional): a completely replaced \fIvendor\fR field .IP \[bu] -\fImsat\fR": the amount, if different from the offer amount multiplied -by any \fIquantity\fR (or the offer had no amount, or was not in BTC)\. +\fBmsat\fR (msat, optional): the amount, if different from the offer amount multiplied by any \fIquantity\fR (or the offer had no amount, or was not in BTC)\. .RE -The \fInext_period\fR object has at least the following members: - +.IP \[bu] +\fBnext_period\fR (object, optional): Only for recurring invoices if the next period is under the \fIrecurrence_limit\fR: .RS .IP \[bu] -\fIcounter\fR: the index of the next period to be fetchinvoice\. +\fBcounter\fR (u64): the index of the next period to fetchinvoice .IP \[bu] -\fIstarttime\fR: the time that the next period starts (seconds since 1970) +\fBstarttime\fR (u64): UNIX timestamp that the next period starts .IP \[bu] -\fIendtime\fR: the time that the next period ends (seconds since 1970) +\fBendtime\fR (u64): UNIX timestamp that the next period ends .IP \[bu] -\fIpaywindow_start\fR: the earliest time that the next invoice can be fetched (seconds since 1970) +\fBpaywindow_start\fR (u64): UNIX timestamp of the earliest time that the next invoice can be fetched .IP \[bu] -\fIpaywindow_end\fR: the latest time that the next invoice can be fetched (seconds since 1970) +\fBpaywindow_end\fR (u64): UNIX timestamp of the latest time that the next invoice can be fetched + +.RE + .RE @@ -126,4 +114,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:a96df8e4f480c093c83268688d683db82575341ecb4176ab586eae9baf69d9c1 +\" SHA256STAMP:23be8c105314c109fa0f7c532c3eebf9b2cbe47f520d600d3d2159765def3cbd diff --git a/doc/lightning-fetchinvoice.7.md b/doc/lightning-fetchinvoice.7.md index de1faafb1316..46de11de5c81 100644 --- a/doc/lightning-fetchinvoice.7.md +++ b/doc/lightning-fetchinvoice.7.md @@ -42,29 +42,22 @@ we fail (default, 60 seconds). RETURN VALUE ------------ -On success, an object as follows is returned: - -* *invoice*: the bolt12-encoded invoice string, starting with "lni1". -* *changes*: an object detailing changes between the offer and invoice. - -Optionally: -* *next_period*: an object returned for recurring invoices if the next - period is under the recurrence_limit (if any). - -The *changes* object can have and of the following members: -* *description_appended*: extra characters appended to the *description* field. -* *description*: a completely replaced *description* field. -* *vendor_removed*": the offer vendor field, which has been omitted from the invoice. -* *vendor*": the offer vendor field, which has changed from the invoice. -* *msat*": the amount, if different from the offer amount multiplied - by any *quantity* (or the offer had no amount, or was not in BTC). - -The *next_period* object has at least the following members: -* *counter*: the index of the next period to be fetchinvoice. -* *starttime*: the time that the next period starts (seconds since 1970) -* *endtime*: the time that the next period ends (seconds since 1970) -* *paywindow_start*: the earliest time that the next invoice can be fetched (seconds since 1970) -* *paywindow_end*: the latest time that the next invoice can be fetched (seconds since 1970) +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **invoice** (string): The BOLT12 invoice we fetched +- **changes** (object): Summary of changes from offer: + - **description_appended** (string, optional): extra characters appended to the *description* field. + - **description** (string, optional): a completely replaced *description* field + - **vendor_removed** (string, optional): The *vendor* from the offer, which is missing in the invoice + - **vendor** (string, optional): a completely replaced *vendor* field + - **msat** (msat, optional): the amount, if different from the offer amount multiplied by any *quantity* (or the offer had no amount, or was not in BTC). +- **next_period** (object, optional): Only for recurring invoices if the next period is under the *recurrence_limit*: + - **counter** (u64): the index of the next period to fetchinvoice + - **starttime** (u64): UNIX timestamp that the next period starts + - **endtime** (u64): UNIX timestamp that the next period ends + - **paywindow_start** (u64): UNIX timestamp of the earliest time that the next invoice can be fetched + - **paywindow_end** (u64): UNIX timestamp of the latest time that the next invoice can be fetched +[comment]: # (GENERATE-FROM-SCHEMA-END) The following error codes may occur: - -1: Catchall nonspecific error. @@ -88,3 +81,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:e2b81ad7a61dd6a6d55e21c5367c3286aaf00cee734b2719a8e38bc87f7ac8aa) diff --git a/doc/lightning-fundchannel.7 b/doc/lightning-fundchannel.7 index 73860c32aee0..69944ba73735 100644 --- a/doc/lightning-fundchannel.7 +++ b/doc/lightning-fundchannel.7 @@ -86,16 +86,21 @@ lightning-cli -k fundchannel id=03f...fc1 amount=all feerate=normal utxos='["bcc .fi .SH RETURN VALUE -On success, the \fItx\fR and \fItxid\fR of the transaction is returned, as well -as the \fIoutnum\fR indicating the output index which creates the channel, as well -as the \fIchannel_id\fR of the newly created channel\. On failure, an error -is reported and the channel is not funded\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBtx\fR (hex): The raw transaction which funded the channel +.IP \[bu] +\fBtxid\fR (txid): The txid of the transaction which funded the channel +.IP \[bu] +\fBoutnum\fR (u32): The 0-based output index showing which output funded the channel +.IP \[bu] +\fBchannel_id\fR (hex): The channel_id of the resulting channel (always 64 characters) +.IP \[bu] +\fBclose_to\fR (hex, optional): The raw scriptPubkey which mutual close will go to; only present if \fIclose_to\fR parameter was specified and peer supports \fBoption_upfront_shutdown_script\fR -If a \fBclose_to\fR address was provided, will close to this address -iff the \fBclose_to\fR script is returned in the response\. Otherwise, -the peer does not support \fBoption_upfront_shutdownscript\fR\. - +.RE The following error codes may occur: @@ -125,4 +130,4 @@ channel parameters (funding limits, channel reserves, fees, etc\.)\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:6b8356d6c8f33ffa6885060386776334b6ee4eaf051362eed188541e3582e1e5 +\" SHA256STAMP:ee8d7d247d9d4f263f8bbed936a2ba4b61d4afc5c48580f462a0d6142c13dbbd diff --git a/doc/lightning-fundchannel.7.md b/doc/lightning-fundchannel.7.md index 723914ed326c..deaa3904e8c8 100644 --- a/doc/lightning-fundchannel.7.md +++ b/doc/lightning-fundchannel.7.md @@ -73,14 +73,14 @@ This example shows how to use lightning-cli to open new channel with peer 03f... RETURN VALUE ------------ -On success, the *tx* and *txid* of the transaction is returned, as well -as the *outnum* indicating the output index which creates the channel, as well -as the *channel\_id* of the newly created channel. On failure, an error -is reported and the channel is not funded. - -If a `close_to` address was provided, will close to this address -iff the `close_to` script is returned in the response. Otherwise, -the peer does not support `option_upfront_shutdownscript`. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **tx** (hex): The raw transaction which funded the channel +- **txid** (txid): The txid of the transaction which funded the channel +- **outnum** (u32): The 0-based output index showing which output funded the channel +- **channel_id** (hex): The channel_id of the resulting channel (always 64 characters) +- **close_to** (hex, optional): The raw scriptPubkey which mutual close will go to; only present if *close_to* parameter was specified and peer supports `option_upfront_shutdown_script` +[comment]: # (GENERATE-FROM-SCHEMA-END) The following error codes may occur: - -1: Catchall nonspecific error. @@ -103,3 +103,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:5b17c334b90f840a986750f9fcdb6a6bfa79bd1a3da11319a1957ba87bc4b0a7) diff --git a/doc/lightning-fundchannel_cancel.7 b/doc/lightning-fundchannel_cancel.7 index e2c94a58d792..663e39ccdd80 100644 --- a/doc/lightning-fundchannel_cancel.7 +++ b/doc/lightning-fundchannel_cancel.7 @@ -25,9 +25,13 @@ to remote peer again before opening channel\. .SH RETURN VALUE -On success, returns confirmation that the channel establishment has been -canceled\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBcancelled\fR (string): A message indicating it was cancelled by RPC + +.RE On error the returned object will contain \fBcode\fR and \fBmessage\fR properties, with \fBcode\fR being one of the following: @@ -60,4 +64,4 @@ lightning-openchannel_\fBsigned\fR(7), lightning-openchannel_\fBabort\fR(7) Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:72ea44cf6efea20b369fb3ecfb61c8ede142800cbc8b427dbb9a26ec254452ce +\" SHA256STAMP:d9006c6b2519f1ae2009a683e3e8131af6e182929d8f0025e451155e4e7d6fe6 diff --git a/doc/lightning-fundchannel_cancel.7.md b/doc/lightning-fundchannel_cancel.7.md index 8c2da4d26e45..80f24c3794f5 100644 --- a/doc/lightning-fundchannel_cancel.7.md +++ b/doc/lightning-fundchannel_cancel.7.md @@ -25,8 +25,10 @@ to remote peer again before opening channel. RETURN VALUE ------------ -On success, returns confirmation that the channel establishment has been -canceled. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **cancelled** (string): A message indicating it was cancelled by RPC +[comment]: # (GENERATE-FROM-SCHEMA-END) On error the returned object will contain `code` and `message` properties, with `code` being one of the following: @@ -56,3 +58,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:f639e58991b8a9b58b181e9f4bd325fb24368af5cb76f94a94ca21675421829b) diff --git a/doc/lightning-fundchannel_complete.7 b/doc/lightning-fundchannel_complete.7 index 41a0acda82c3..566fabe0d92b 100644 --- a/doc/lightning-fundchannel_complete.7 +++ b/doc/lightning-fundchannel_complete.7 @@ -26,9 +26,15 @@ unrecoverable loss of funds\. .SH RETURN VALUE -On success, returns a confirmation that \fIcommitments_secured\fR and the -derived \fIchannel_id\fR\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBchannel_id\fR (hex): The channel_id of the resulting channel (always 64 characters) +.IP \[bu] +\fBcommitments_secured\fR (boolean): Indication that channel is safe to use (always \fItrue\fR) + +.RE On error the returned object will contain \fBcode\fR and \fBmessage\fR properties, with \fBcode\fR being one of the following: @@ -62,4 +68,4 @@ lightning-openchannel_\fBabort\fR(7) Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:13e5fee7b987b38e9b08685f4b49062314ec9e2cf52afbb5a2c5a4965fe2b01f +\" SHA256STAMP:72b7e8826beb42061bf53e59b72c35c4fba6cdb421e491ffe6bf07dc51412342 diff --git a/doc/lightning-fundchannel_complete.7.md b/doc/lightning-fundchannel_complete.7.md index 06b8b53b7d89..8a2a95957032 100644 --- a/doc/lightning-fundchannel_complete.7.md +++ b/doc/lightning-fundchannel_complete.7.md @@ -26,8 +26,11 @@ unrecoverable loss of funds. RETURN VALUE ------------ -On success, returns a confirmation that *commitments\_secured* and the -derived *channel\_id*. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **channel_id** (hex): The channel_id of the resulting channel (always 64 characters) +- **commitments_secured** (boolean): Indication that channel is safe to use (always *true*) +[comment]: # (GENERATE-FROM-SCHEMA-END) On error the returned object will contain `code` and `message` properties, with `code` being one of the following: @@ -57,3 +60,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:7cb52658d81c5834e34a6011c04283bf740fe6e5feedb0208778abad5fddc519) diff --git a/doc/lightning-fundchannel_start.7 b/doc/lightning-fundchannel_start.7 index 256e0e0e3c59..fa212251fff1 100644 --- a/doc/lightning-fundchannel_start.7 +++ b/doc/lightning-fundchannel_start.7 @@ -45,10 +45,17 @@ transaction before that can lead to unrecoverable loss of funds\. .SH RETURN VALUE -On success, returns the \fIfunding_address\fR and the \fIscriptpubkey\fR for the channel funding output\. -If a \fBclose_to\fR address was provided, will close to this address iff the \fBclose_to\fR address is -returned in the response\. Otherwise, the peer does not support \fBoption_upfront_shutdownscript\fR\. +On success, an object is returned, containing: +.RS +.IP \[bu] +\fBfunding_address\fR (string): The address to send funding to for the channel +.IP \[bu] +\fBscriptpubkey\fR (hex): The raw scriptPubkey for the address +.IP \[bu] +\fBclose_to\fR (hex, optional): The raw scriptPubkey which mutual close will go to; only present if \fIclose_to\fR parameter was specified and peer supports \fBoption_upfront_shutdown_script\fR + +.RE On error the returned object will contain \fBcode\fR and \fBmessage\fR properties, with \fBcode\fR being one of the following: @@ -86,4 +93,4 @@ lightning-openchannel_\fBabort\fR(7) Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:6dd30561d6b00b1f2d5595cfe199e09576eb4ba2afea7ba52e8f38546720c76c +\" SHA256STAMP:959e97d593fb77f9403e8c5024d5582a2ae81b5cffae1799a285e0a26281b770 diff --git a/doc/lightning-fundchannel_start.7.md b/doc/lightning-fundchannel_start.7.md index ff1d8b046149..5f34431b6d42 100644 --- a/doc/lightning-fundchannel_start.7.md +++ b/doc/lightning-fundchannel_start.7.md @@ -41,9 +41,12 @@ transaction before that can lead to unrecoverable loss of funds. RETURN VALUE ------------ -On success, returns the *funding\_address* and the *scriptpubkey* for the channel funding output. -If a `close_to` address was provided, will close to this address iff the `close_to` address is -returned in the response. Otherwise, the peer does not support `option_upfront_shutdownscript`. +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **funding_address** (string): The address to send funding to for the channel +- **scriptpubkey** (hex): The raw scriptPubkey for the address +- **close_to** (hex, optional): The raw scriptPubkey which mutual close will go to; only present if *close_to* parameter was specified and peer supports `option_upfront_shutdown_script` +[comment]: # (GENERATE-FROM-SCHEMA-END) On error the returned object will contain `code` and `message` properties, with `code` being one of the following: @@ -75,3 +78,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:9417a2d8d48b69f3557b08984d6b362e20cf20eeefcbef168fdc84b6f1de6411) diff --git a/doc/lightning-fundpsbt.7 b/doc/lightning-fundpsbt.7 index 160885b3e12d..b7c12cc51030 100644 --- a/doc/lightning-fundpsbt.7 +++ b/doc/lightning-fundpsbt.7 @@ -122,4 +122,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:6420ab94377f1a25df686e97e79da3c67c69f99978b6177432426dfd45296052 +\" SHA256STAMP:b02d5c31f0fe6b5423871f4f5859519b41a882388d17f460bd7331f714880126 diff --git a/doc/lightning-fundpsbt.7.md b/doc/lightning-fundpsbt.7.md index 9e15a668d047..ae5bde3896f1 100644 --- a/doc/lightning-fundpsbt.7.md +++ b/doc/lightning-fundpsbt.7.md @@ -110,3 +110,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:25b32367f5bbf6f1e53036c38b7b7d19eebf62fa749a3ab580e4093eedc88584) diff --git a/doc/lightning-getinfo.7 b/doc/lightning-getinfo.7 index 92bab929a7a1..402fc691badb 100644 --- a/doc/lightning-getinfo.7 +++ b/doc/lightning-getinfo.7 @@ -22,43 +22,69 @@ The \fBgetinfo\fR gives a summary of the current running node\. .fi .SH RETURN VALUE -On success, an object with the following information is returned: +On success, an object is returned, containing: .RS .IP \[bu] -\fIid\fR: A string that represents the public key of the node\. It will represents the node on the public network\. +\fBid\fR (pubkey): The public key unique to this node .IP \[bu] -\fIalias\fR: A string that represents the alias of the node, by default is calculate from the public key (node id)\. This is just for fun; the name can be anything and is not unique! +\fBalias\fR (string): The fun alias this node will advertize (up to 32 characters) .IP \[bu] -\fIcolor\fR: A string that represents the preferred color of the node\. +\fBcolor\fR (hex): The favorite RGB color this node will advertize (always 6 characters) .IP \[bu] -\fInum_peers\fR: An integer that represents the number of peer connect to the node\. +\fBnum_peers\fR (u32): The total count of peers, connected or with channels .IP \[bu] -\fInum_pending_channels\fR: An integer that represents the number of channel which are still awaiting opening confirmation\. +\fBnum_pending_channels\fR (u32): The total count of channels being opened .IP \[bu] -\fInum_active_channels\fR: A integer that represents the number of channel which are currently open\. +\fBnum_active_channels\fR (u32): The total count of channels in normal state .IP \[bu] -\fInum_inactive_channels\fR: A integer that represents the number of channel which are closing\. +\fBnum_inactive_channels\fR (u32): The total count of channels waiting for opening or closing transactions to be mined .IP \[bu] -\fIaddress\fR: An array that represents all published addresses of the node, each object inside the array contains the following proprieties: +\fBversion\fR (string): Identifies what bugs you are running into +.IP \[bu] +\fBlightning-dir\fR (string): Identifies where you can find the configuration and other related files +.IP \[bu] +\fBblockheight\fR (u32): The highest block height we've learned +.IP \[bu] +\fBnetwork\fR (string): represents the type of network on the node are working (e\.g: \fBbitcoin\fR, \fBtestnet\fR, or \fBregtest\fR) +.IP \[bu] +\fBfees_collected_msat\fR (msat): Total routing fees collected by this node +.IP \[bu] +\fBaddress\fR (array of objects, optional): The addresses we announce to the world: .RS .IP \[bu] -\fItype\fR: A string that represents the type of the address (currently \fBipv4\fR, \fBipv6\fR, \fBtorv3\fR or \fBtorv4\fR)\. +\fBtype\fR (string): Type of connection (one of "ipv4", "ipv6", "torv2", "torv3") .IP \[bu] -\fIaddress\fR: A string that represents the value of the address\. +\fBaddress\fR (string): address in expected format for \fBtype\fR .IP \[bu] -\fIport\fR: An integer that represents the port where the node is listening with this address\. +\fBport\fR (u16): port number .RE .IP \[bu] -\fIbinding\fR: An array that represents all addresses where the node is binded\. Each object contains the same object type of the address propriety above\. +\fBbinding\fR (array of objects, optional): The addresses we are listening on: +.RS +.IP \[bu] +\fBtype\fR (string): Type of connection (one of "local socket", "ipv4", "ipv6", "torv2", "torv3") +.IP \[bu] +\fBaddress\fR (string, optional): address in expected format for \fBtype\fR +.IP \[bu] +\fBport\fR (u16, optional): port number .IP \[bu] -\fIversion\fR: A string that represents the version of the node\. +\fBsocket\fR (string, optional): socket filename (only if \fBtype\fR is "local socket") + +.RE + + +.RE + +The following warnings may also be returned: + +.RS .IP \[bu] -\fIblockheight\fR: An integer that represents the blockchain height\. +\fBwarning_bitcoind_sync\fR: Bitcoind is not up-to-date with network\. .IP \[bu] -\fInetwork\fR: A string that represents the type of network on the node are working (e\.g: \fBbitcoin\fR, \fBtestnet\fR, or \fBregtest\fR)\. +\fBwarning_lightningd_sync\fR: Lightningd is still loading latest blocks from bitcoind\. .RE @@ -121,4 +147,4 @@ Vincenzo Palazzo \fI wrote the initial versi Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:9e6a0e0c25569bfc9d23b07e84392a3f70f6c94a86cd482fbf48c3d668a1796d +\" SHA256STAMP:637babe08b35ca524666bc51f1d0191e2006064af2b4c22997fbbe49cc7f935c diff --git a/doc/lightning-getinfo.7.md b/doc/lightning-getinfo.7.md index a5e09b2313a9..3419953eaac6 100644 --- a/doc/lightning-getinfo.7.md +++ b/doc/lightning-getinfo.7.md @@ -25,23 +25,34 @@ EXAMPLE JSON REQUEST RETURN VALUE ------------ -On success, an object with the following information is returned: - -- *id*: A string that represents the public key of the node. It will represents the node on the public network. -- *alias*: A string that represents the alias of the node, by default is calculate from the public key (node id). This is just for fun; the name can be anything and is not unique! -- *color*: A string that represents the preferred color of the node. -- *num_peers*: An integer that represents the number of peer connect to the node. -- *num_pending_channels*: An integer that represents the number of channel which are still awaiting opening confirmation. -- *num_active_channels*: A integer that represents the number of channel which are currently open. -- *num_inactive_channels*: A integer that represents the number of channel which are closing. -- *address*: An array that represents all published addresses of the node, each object inside the array contains the following proprieties: - - *type*: A string that represents the type of the address (currently `ipv4`, `ipv6`, `torv3` or `torv4`). - - *address*: A string that represents the value of the address. - - *port*: An integer that represents the port where the node is listening with this address. -- *binding*: An array that represents all addresses where the node is binded. Each object contains the same object type of the address propriety above. -- *version*: A string that represents the version of the node. -- *blockheight*: An integer that represents the blockchain height. -- *network*: A string that represents the type of network on the node are working (e.g: `bitcoin`, `testnet`, or `regtest`). +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **id** (pubkey): The public key unique to this node +- **alias** (string): The fun alias this node will advertize (up to 32 characters) +- **color** (hex): The favorite RGB color this node will advertize (always 6 characters) +- **num_peers** (u32): The total count of peers, connected or with channels +- **num_pending_channels** (u32): The total count of channels being opened +- **num_active_channels** (u32): The total count of channels in normal state +- **num_inactive_channels** (u32): The total count of channels waiting for opening or closing transactions to be mined +- **version** (string): Identifies what bugs you are running into +- **lightning-dir** (string): Identifies where you can find the configuration and other related files +- **blockheight** (u32): The highest block height we've learned +- **network** (string): represents the type of network on the node are working (e.g: `bitcoin`, `testnet`, or `regtest`) +- **fees_collected_msat** (msat): Total routing fees collected by this node +- **address** (array of objects, optional): The addresses we announce to the world: + - **type** (string): Type of connection (one of "ipv4", "ipv6", "torv2", "torv3") + - **address** (string): address in expected format for **type** + - **port** (u16): port number +- **binding** (array of objects, optional): The addresses we are listening on: + - **type** (string): Type of connection (one of "local socket", "ipv4", "ipv6", "torv2", "torv3") + - **address** (string, optional): address in expected format for **type** + - **port** (u16, optional): port number + - **socket** (string, optional): socket filename (only if **type** is "local socket") + +The following warnings may also be returned: +- **warning_bitcoind_sync**: Bitcoind is not up-to-date with network. +- **warning_lightningd_sync**: Lightningd is still loading latest blocks from bitcoind. +[comment]: # (GENERATE-FROM-SCHEMA-END) On failure, one of the following error codes may be returned: @@ -103,3 +114,4 @@ RESOURCES --------- Main web site: +[comment]: # ( SHA256STAMP:2aa0f0cf9de7b2d373bdce8b337535a0197ad8cb1df2cdb0e043ba49c3704816) diff --git a/doc/lightning-getlog.7 b/doc/lightning-getlog.7 index 13eedfb0471d..2fe16a77e5a2 100644 --- a/doc/lightning-getlog.7 +++ b/doc/lightning-getlog.7 @@ -29,31 +29,63 @@ The \fBgetlog\fR the RPC command to show logs, with optional log \fIlevel\fR\. .fi .SH RETURN VALUE -On success, a object will be return with the following parameters: +On success, an object is returned, containing: .RS .IP \[bu] -\fIcreated_at\fR: An floating point value that represents the UNIX timestamp when logging began\. +\fBcreated_at\fR (string): UNIX timestamp with 9 decimal places, when logging was initialized .IP \[bu] -\fIbytes_used\fR: A string that represents the dimension in bytes of the log file\. +\fBbytes_used\fR (u32): The number of bytes used by logging records .IP \[bu] -\fIbytes_max\fR: An integer that represents the max dimension in bytes of log file\. +\fBbytes_max\fR (u32): The bytes_used values at which records will be trimmed .IP \[bu] -\fIlog\fR: An array of objects where each element contains the following proprieties: + +\fBlog\fR (array of objects): + .RS .IP \[bu] -\fItype\fR: A string that represents the log level\. The propriety can have an value equal to SKIPPED to indicate the existence of omitted entries\. +\fBtype\fR (string) (one of "SKIPPED", "BROKEN", "UNUSUAL", "INFO", "DEBUG", "IO_IN", "IO_OUT") + +.RE + +If \fBtype\fR is "SKIPPED": + +.RS .IP \[bu] -\fItime\fR: A floating point value that represents the time since \fIcreated_at\fR\. +\fBnum_skipped\fR (u32): number of unprinted log entries (deleted or below \fIlevel\fR parameter) + +.RE + +If \fBtype\fR is "BROKEN", "UNUSUAL", "INFO" or "DEBUG": + +.RS .IP \[bu] -\fIsource\fR: A string that represents the source of line\. +\fBtime\fR (string): UNIX timestamp with 9 decimal places after \fBcreated_at\fR .IP \[bu] -\fIlog\fR: A string that represents the content of line\. +\fBsource\fR (string): The particular logbook this was found in +.IP \[bu] +\fBlog\fR (string): The actual log message +.IP \[bu] +\fBnode_id\fR (pubkey, optional): The peer this is associated with .RE +If \fBtype\fR is "IO_IN" or "IO_OUT": + +.RS +.IP \[bu] +\fBtime\fR (string): Seconds after \fBcreated_at\fR, with 9 decimal places +.IP \[bu] +\fBsource\fR (string): The particular logbook this was found in .IP \[bu] -\fInum_skipped\fR: An integer that it is present only if the log level is equal to SKIPPED\. +\fBlog\fR (string): The associated log message +.IP \[bu] +\fBdata\fR (hex): The IO which occurred +.IP \[bu] +\fBnode_id\fR (pubkey, optional): The peer this is associated with + +.RE + .RE @@ -95,4 +127,4 @@ Vincenzo Palazzo \fI wrote the initial versi Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:789e23927120d0fefd374592a3c655244fd6c28a122368bdd8da2f3cdde66798 +\" SHA256STAMP:13e3ab43fb6811bff8bee102ba85e7d4cb8eb97d11bb0720ae5c0c576ba021ec diff --git a/doc/lightning-getlog.7.md b/doc/lightning-getlog.7.md index dad81dc0fecb..4fffb2d8d1be 100644 --- a/doc/lightning-getlog.7.md +++ b/doc/lightning-getlog.7.md @@ -28,18 +28,30 @@ EXAMPLE JSON REQUEST RETURN VALUE ------------ -On success, a object will be return with the following parameters: - -- *created_at*: An floating point value that represents the UNIX timestamp when logging began. -- *bytes_used*: A string that represents the dimension in bytes of the log file. -- *bytes_max*: An integer that represents the max dimension in bytes of log file. -- *log*: An array of objects where each element contains the following proprieties: - - *type*: A string that represents the log level. The propriety can have an value equal to SKIPPED to indicate the existence of omitted entries. - - *time*: A floating point value that represents the time since *created_at*. - - *source*: A string that represents the source of line. - - *log*: A string that represents the content of line. -- *num_skipped*: An integer that it is present only if the log level is equal to SKIPPED. - +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object is returned, containing: +- **created_at** (string): UNIX timestamp with 9 decimal places, when logging was initialized +- **bytes_used** (u32): The number of bytes used by logging records +- **bytes_max** (u32): The bytes_used values at which records will be trimmed +- **log** (array of objects): + - **type** (string) (one of "SKIPPED", "BROKEN", "UNUSUAL", "INFO", "DEBUG", "IO_IN", "IO_OUT") + + If **type** is "SKIPPED": + - **num_skipped** (u32): number of unprinted log entries (deleted or below *level* parameter) + + If **type** is "BROKEN", "UNUSUAL", "INFO" or "DEBUG": + - **time** (string): UNIX timestamp with 9 decimal places after **created_at** + - **source** (string): The particular logbook this was found in + - **log** (string): The actual log message + - **node_id** (pubkey, optional): The peer this is associated with + + If **type** is "IO_IN" or "IO_OUT": + - **time** (string): Seconds after **created_at**, with 9 decimal places + - **source** (string): The particular logbook this was found in + - **log** (string): The associated log message + - **data** (hex): The IO which occurred + - **node_id** (pubkey, optional): The peer this is associated with +[comment]: # (GENERATE-FROM-SCHEMA-END) On failure, one of the following error codes may be returned: @@ -77,3 +89,4 @@ RESOURCES --------- Main web site: +[comment]: # ( SHA256STAMP:db99eeb155bb44ebda8b77afdc1fad773e82fa8892e1df6afd61c60a1f4b7ec3) diff --git a/doc/lightning-getroute.7 b/doc/lightning-getroute.7 index 70f2675d9162..3d2d9c88caf4 100644 --- a/doc/lightning-getroute.7 +++ b/doc/lightning-getroute.7 @@ -111,17 +111,29 @@ factor for larger amounts, and is basically ignored for tiny ones\. .SH RETURN VALUE -On success, a "route" array is returned\. Each array element contains -\fIid\fR (the node being routed through), \fImsatoshi\fR (the millisatoshis -sent), \fIamount_msat\fR (the same, with \fImsat\fR appended), \fIdelay\fR (the -number of blocks to timeout at this node), and \fIstyle\fR (indicating -the features which can be used for this hop)\. +On success, an object containing \fBroute\fR is returned\. It is an array of objects, where each object contains: +.RS +.IP \[bu] +\fBid\fR (pubkey): The node at the end of this hop +.IP \[bu] +\fBchannel\fR (short_channel_id): The channel joining these nodes +.IP \[bu] +\fBdirection\fR (u32): 0 if this channel is traversed from lesser to greater \fBid\fR, otherwise 1 +.IP \[bu] +\fBamount_msat\fR (msat): The amount expected by the node at the end of this hop +.IP \[bu] +\fBdelay\fR (u32): The total CLTV expected by the node at the end of this hop +.IP \[bu] +\fBstyle\fR (string): The features understood by the destination node (one of "legacy", "tlv") + +.RE The final \fIid\fR will be the destination \fIid\fR given in the input\. The difference between the first \fImsatoshi\fR minus the \fImsatoshi\fR given in -the input is the fee\. The first \fIdelay\fR is the very worst case timeout -for the payment failure, in blocks\. +the input is the fee (assuming the first hop is free)\. The first +\fIdelay\fR is the very worst case timeout for the payment failure, in +blocks\. .SH AUTHOR @@ -135,4 +147,4 @@ Rusty Russell \fI is mainly responsible\. Main web site: \fIhttps://github.com/ElementsProject/lightning\fR -\" SHA256STAMP:52fe58e923c36f62601e6cb2779031d0428d3561bdeae2ab8eadf3dff84a3179 +\" SHA256STAMP:aaf1dab77352de52f8bf8a5c3e4a6449769b5dbfa51bdbf9b1a06575c8ae37fe diff --git a/doc/lightning-getroute.7.md b/doc/lightning-getroute.7.md index 435e3142c84e..1c84d58fc819 100644 --- a/doc/lightning-getroute.7.md +++ b/doc/lightning-getroute.7.md @@ -277,16 +277,21 @@ factor for larger amounts, and is basically ignored for tiny ones. RETURN VALUE ------------ -On success, a "route" array is returned. Each array element contains -*id* (the node being routed through), *msatoshi* (the millisatoshis -sent), *amount\_msat* (the same, with *msat* appended), *delay* (the -number of blocks to timeout at this node), and *style* (indicating -the features which can be used for this hop). +[comment]: # (GENERATE-FROM-SCHEMA-START) +On success, an object containing **route** is returned. It is an array of objects, where each object contains: +- **id** (pubkey): The node at the end of this hop +- **channel** (short_channel_id): The channel joining these nodes +- **direction** (u32): 0 if this channel is traversed from lesser to greater **id**, otherwise 1 +- **amount_msat** (msat): The amount expected by the node at the end of this hop +- **delay** (u32): The total CLTV expected by the node at the end of this hop +- **style** (string): The features understood by the destination node (one of "legacy", "tlv") +[comment]: # (GENERATE-FROM-SCHEMA-END) The final *id* will be the destination *id* given in the input. The difference between the first *msatoshi* minus the *msatoshi* given in -the input is the fee. The first *delay* is the very worst case timeout -for the payment failure, in blocks. +the input is the fee (assuming the first hop is free). The first +*delay* is the very worst case timeout for the payment failure, in +blocks. AUTHOR ------ @@ -303,3 +308,4 @@ RESOURCES Main web site: +[comment]: # ( SHA256STAMP:c15c56751270e8a3df25f3e3f72fbe8ea56366e5fe1157a8485b85cec1878982) diff --git a/doc/schemas/disableoffer.schema.json b/doc/schemas/disableoffer.schema.json new file mode 100644 index 000000000000..6b745c8b7b7a --- /dev/null +++ b/doc/schemas/disableoffer.schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ "offer_id", "active", "single_use", "bolt12", "used" ], + "additionalProperties": false, + "properties": { + "offer_id": { + "type": "hex", + "description": "the merkle hash of the offer", + "maxLength": 64, + "minLength": 64 + }, + "active": { + "type": "boolean", + "enum": [ "false" ], + "description": "Whether the offer can produce invoices/payments" + }, + "single_use": { + "type": "boolean", + "description": "Whether the offer is disabled after first successful use" + }, + "bolt12": { + "type": "string", + "description": "The bolt12 string representing this offer" + }, + "used": { + "type": "boolean", + "description": "Whether the offer has had an invoice paid / payment made" + }, + "label": { + "type": "string", + "description": "The label provided when offer was created" + } + } +} diff --git a/doc/schemas/disconnect.schema.json b/doc/schemas/disconnect.schema.json new file mode 100644 index 000000000000..b797a82c2f6f --- /dev/null +++ b/doc/schemas/disconnect.schema.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + } +} diff --git a/doc/schemas/feerates.schema.json b/doc/schemas/feerates.schema.json new file mode 100644 index 000000000000..3f25817e7303 --- /dev/null +++ b/doc/schemas/feerates.schema.json @@ -0,0 +1,119 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ ], + "properties": { + "warning_missing_feerates": { + "type": "string", + "description": "Some fee estimates are missing" + }, + "perkb": { + "type": "object", + "description": "If *style* parameter was perkb", + "additionalProperties": false, + "required": [ "min_acceptable", "max_acceptable" ], + "properties": { + "min_acceptable": { + "type": "u32", + "description": "The smallest feerate that you can use, usually the minimum relayed feerate of the backend" + }, + "max_acceptable": { + "type": "u32", + "description": "The largest feerate we will accept from remote negotiations. If a peer attempts to set the feerate higher than this we will unilaterally close the channel (or simply forget it if it's not open yet)." + }, + "opening": { + "type": "u32", + "description": "Default feerate for lightning-fundchannel(7) and lightning-withdraw(7)" + }, + "mutual_close": { + "type": "u32", + "description": "Feerate to aim for in cooperative shutdown. Note that since mutual close is a **negotiation**, the actual feerate used in mutual close will be somewhere between this and the corresponding mutual close feerate of the peer." + }, + "unilateral_close": { + "type": "u32", + "description": "Feerate for commitment_transaction in a live channel which we originally funded" + }, + "delayed_to_us": { + "type": "u32", + "description": "Feerate for returning unilateral close funds to our wallet" + }, + "htlc_resolution": { + "type": "u32", + "description": "Feerate for returning unilateral close HTLC outputs to our wallet" + }, + "penalty": { + "type": "u32", + "description": "Feerate to start at when penalizing a cheat attempt" + } + } + }, + "perkw": { + "type": "object", + "description": "If *style* parameter was perkw", + "additionalProperties": false, + "required": [ "min_acceptable", "max_acceptable" ], + "properties": { + "min_acceptable": { + "type": "u32", + "description": "The smallest feerate that you can use, usually the minimum relayed feerate of the backend" + }, + "max_acceptable": { + "type": "u32", + "description": "The largest feerate we will accept from remote negotiations. If a peer attempts to set the feerate higher than this we will unilaterally close the channel (or simply forget it if it's not open yet)." + }, + "opening": { + "type": "u32", + "description": "Default feerate for lightning-fundchannel(7) and lightning-withdraw(7)" + }, + "mutual_close": { + "type": "u32", + "description": "Feerate to aim for in cooperative shutdown. Note that since mutual close is a **negotiation**, the actual feerate used in mutual close will be somewhere between this and the corresponding mutual close feerate of the peer." + }, + "unilateral_close": { + "type": "u32", + "description": "Feerate for commitment_transaction in a live channel which we originally funded" + }, + "delayed_to_us": { + "type": "u32", + "description": "Feerate for returning unilateral close funds to our wallet" + }, + "htlc_resolution": { + "type": "u32", + "description": "Feerate for returning unilateral close HTLC outputs to our wallet" + }, + "penalty": { + "type": "u32", + "description": "Feerate to start at when penalizing a cheat attempt" + } + } + }, + "onchain_fee_estimates": { + "type": "object", + "additionalProperties": false, + "required": [ "opening_channel_satoshis", "mutual_close_satoshis", "unilateral_close_satoshis", "htlc_timeout_satoshis", "htlc_success_satoshis" ], + "properties": { + "opening_channel_satoshis": { + "type": "u64", + "description": "Estimated cost of typical channel open" + }, + "mutual_close_satoshis": { + "type": "u64", + "description": "Estimated cost of typical channel close" + }, + "unilateral_close_satoshis": { + "type": "u64", + "description": "Estimated cost of typical unilateral close (without HTLCs)" + }, + "htlc_timeout_satoshis": { + "type": "u64", + "description": "Estimated cost of typical HTLC timeout transaction" + }, + "htlc_success_satoshis": { + "type": "u64", + "description": "Estimated cost of typical HTLC fulfillment transaction" + } + } + } + } +} diff --git a/doc/schemas/fetchinvoice.schema.json b/doc/schemas/fetchinvoice.schema.json new file mode 100644 index 000000000000..ff538b58cfda --- /dev/null +++ b/doc/schemas/fetchinvoice.schema.json @@ -0,0 +1,68 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "invoice", "changes" ], + "properties": { + "invoice": { + "type": "string", + "description": "The BOLT12 invoice we fetched" + }, + "changes": { + "type": "object", + "description": "Summary of changes from offer", + "additionalProperties": false, + "required": [ ], + "properties": { + "description_appended": { + "type": "string", + "description": "extra characters appended to the *description* field." + }, + "description": { + "type": "string", + "description": "a completely replaced *description* field" + }, + "vendor_removed": { + "type": "string", + "description": "The *vendor* from the offer, which is missing in the invoice" + }, + "vendor": { + "type": "string", + "description": "a completely replaced *vendor* field" + }, + "msat": { + "type": "msat", + "description": "the amount, if different from the offer amount multiplied by any *quantity* (or the offer had no amount, or was not in BTC)." + } + } + }, + "next_period": { + "type": "object", + "description": "Only for recurring invoices if the next period is under the *recurrence_limit*", + "additionalProperties": false, + "required": [ "counter", "starttime", "endtime", "paywindow_start", "paywindow_end" ], + "properties": { + "counter": { + "type": "u64", + "description": "the index of the next period to fetchinvoice" + }, + "starttime": { + "type": "u64", + "description": "UNIX timestamp that the next period starts" + }, + "endtime": { + "type": "u64", + "description": "UNIX timestamp that the next period ends" + }, + "paywindow_start": { + "type": "u64", + "description": "UNIX timestamp of the earliest time that the next invoice can be fetched" + }, + "paywindow_end": { + "type": "u64", + "description": "UNIX timestamp of the latest time that the next invoice can be fetched" + } + } + } + } +} diff --git a/doc/schemas/fundchannel.schema.json b/doc/schemas/fundchannel.schema.json new file mode 100644 index 000000000000..44775d377513 --- /dev/null +++ b/doc/schemas/fundchannel.schema.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "tx", "txid", "outnum", "channel_id" ], + "properties": { + "tx": { + "type": "hex", + "description": "The raw transaction which funded the channel" + }, + "txid": { + "type": "txid", + "description": "The txid of the transaction which funded the channel" + }, + "outnum": { + "type": "u32", + "description": "The 0-based output index showing which output funded the channel" + }, + "channel_id": { + "type": "hex", + "description": "The channel_id of the resulting channel", + "minLength": 64, + "maxLength": 64 + }, + "close_to": { + "type": "hex", + "description": "The raw scriptPubkey which mutual close will go to; only present if *close_to* parameter was specified and peer supports `option_upfront_shutdown_script`" + } + } +} diff --git a/doc/schemas/fundchannel_cancel.schema.json b/doc/schemas/fundchannel_cancel.schema.json new file mode 100644 index 000000000000..a9e1e663e091 --- /dev/null +++ b/doc/schemas/fundchannel_cancel.schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "cancelled" ], + "properties": { + "cancelled": { + "type": "string", + "description": "A message indicating it was cancelled by RPC" + } + } +} diff --git a/doc/schemas/fundchannel_complete.schema.json b/doc/schemas/fundchannel_complete.schema.json new file mode 100644 index 000000000000..90b29faeefc0 --- /dev/null +++ b/doc/schemas/fundchannel_complete.schema.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "channel_id", "commitments_secured" ], + "properties": { + "channel_id": { + "type": "hex", + "description": "The channel_id of the resulting channel", + "minLength": 64, + "maxLength": 64 + }, + "commitments_secured": { + "type": "boolean", + "enum": [ true ], + "description": "Indication that channel is safe to use" + } + } +} diff --git a/doc/schemas/fundchannel_start.schema.json b/doc/schemas/fundchannel_start.schema.json new file mode 100644 index 000000000000..335e1eb1f0b4 --- /dev/null +++ b/doc/schemas/fundchannel_start.schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "funding_address", "scriptpubkey" ], + "properties": { + "funding_address": { + "type": "string", + "description": "The address to send funding to for the channel" + }, + "scriptpubkey": { + "type": "hex", + "description": "The raw scriptPubkey for the address" + }, + "close_to": { + "type": "hex", + "description": "The raw scriptPubkey which mutual close will go to; only present if *close_to* parameter was specified and peer supports `option_upfront_shutdown_script`" + } + } +} diff --git a/doc/schemas/fundpsbt.schema.json b/doc/schemas/fundpsbt.schema.json new file mode 100644 index 000000000000..c935136224c0 --- /dev/null +++ b/doc/schemas/fundpsbt.schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "psbt", "feerate_per_kw", "estimated_final_weight", "excess_msat" ], + "properties": { + "psbt": { + "type": "string", + "description": "Unsigned PSBT which fulfills the parameters given" + }, + "feerate_per_kw": { + "type": "u32", + "description": "The feerate used to create the PSBT, in satoshis-per-kiloweight" + }, + "estimated_final_weight": { + "type": "u32", + "description": "The estimated weight of the transaction once fully signed" + }, + "excess_msat": { + "type": "msat", + "description": "The amount above *satoshi* which is available. This could be zero, or dust; it will be zero if *change_outnum* is also returned" + }, + "change_outnum": { + "type": "u32", + "description": "The 0-based output number where change was placed (only if parameter *excess_as_change* was true and there was sufficient funds)" + }, + "reservations": { + "type": "array", + "description": "If the *reserve* was true, just as per lightning-reserveinputs(7)", + "items": { + "type": "object", + "required": ["txid", "vout", "was_reserved", "reserved", "reserved_to_block" ], + "additionalProperties": false, + "properties": { + "txid": { + "type": "txid", + "description": "The txid of the transaction" + }, + "vout": { + "type": "u32", + "description": "The 0-based output number" + }, + "was_reserved": { + "type": "boolean", + "enum": [ false ], + "description": "Whether this output was previously reserved" + }, + "reserved": { + "type": "boolean", + "enum": [ true ], + "description": "Whether this output is now reserved" + }, + "reserved_to_block": { + "type": "u32", + "description": "The blockheight the reservation will expire" + } + } + } + } + } +} diff --git a/doc/schemas/getinfo.schema.json b/doc/schemas/getinfo.schema.json new file mode 100644 index 000000000000..3c964fee25f9 --- /dev/null +++ b/doc/schemas/getinfo.schema.json @@ -0,0 +1,124 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "id", "alias", "color", "num_peers", "num_pending_channels", "num_active_channels", "num_inactive_channels", "version", "blockheight", "network", "fees_collected_msat", "lightning-dir" ], + "properties": { + "id": { + "type": "pubkey", + "description": "The public key unique to this node" + }, + "alias": { + "type": "string", + "description": "The fun alias this node will advertize", + "maxLength": 32 + }, + "color": { + "type": "hex", + "description": "The favorite RGB color this node will advertize", + "minLength": 6, + "maxLength": 6 + }, + "num_peers": { + "type": "u32", + "description": "The total count of peers, connected or with channels" + }, + "num_pending_channels": { + "type": "u32", + "description": "The total count of channels being opened" + }, + "num_active_channels": { + "type": "u32", + "description": "The total count of channels in normal state" + }, + "num_inactive_channels": { + "type": "u32", + "description": "The total count of channels waiting for opening or closing transactions to be mined" + }, + "version": { + "type": "string", + "description": "Identifies what bugs you are running into" + }, + "lightning-dir": { + "type": "string", + "description": "Identifies where you can find the configuration and other related files" + }, + "blockheight": { + "type": "u32", + "description": "The highest block height we've learned" + }, + "network": { + "type": "string", + "description": "represents the type of network on the node are working (e.g: `bitcoin`, `testnet`, or `regtest`)" + }, + "msatoshi_fees_collected": { + "type": "u64", + "deprecated": true + }, + "fees_collected_msat": { + "type": "msat", + "description": "Total routing fees collected by this node" + }, + "address": { + "type": "array", + "description": "The addresses we announce to the world", + "items": { + "type": "object", + "required": [ "type", "address", "port" ], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": [ "ipv4", "ipv6", "torv2", "torv3" ], + "description": "Type of connection" + }, + "address": { + "type": "string", + "description": "address in expected format for **type**" + }, + "port": { + "type": "u16", + "description": "port number" + } + } + } + }, + "binding": { + "type": "array", + "description": "The addresses we are listening on", + "items": { + "type": "object", + "required": [ "type" ], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "*FIXME*": "The variant in connect.schema.json is more complete", + "enum": [ "local socket", "ipv4", "ipv6", "torv2", "torv3" ], + "description": "Type of connection" + }, + "address": { + "type": "string", + "description": "address in expected format for **type**" + }, + "port": { + "type": "u16", + "description": "port number" + }, + "socket": { + "type": "string", + "description": "socket filename (only if **type** is \"local socket\")" + } + } + } + }, + "warning_bitcoind_sync": { + "type": "string", + "description": "Bitcoind is not up-to-date with network." + }, + "warning_lightningd_sync": { + "type": "string", + "description": "Lightningd is still loading latest blocks from bitcoind." + } + } +} diff --git a/doc/schemas/getlog.schema.json b/doc/schemas/getlog.schema.json new file mode 100644 index 000000000000..23c9981b5b69 --- /dev/null +++ b/doc/schemas/getlog.schema.json @@ -0,0 +1,127 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "created_at", "bytes_used", "bytes_max", "log" ], + "properties": { + "created_at": { + "type": "string", + "description": "UNIX timestamp with 9 decimal places, when logging was initialized" + }, + "bytes_used": { + "type": "u32", + "description": "The number of bytes used by logging records" + }, + "bytes_max": { + "type": "u32", + "description": "The bytes_used values at which records will be trimmed " + }, + "log": { + "type": "array", + "items": { + "type": "object", + "required": [ "type" ], + "additionalProperties": true, + "properties": { + "type": { + "type": "string", + "enum": [ "SKIPPED", "BROKEN", "UNUSUAL", "INFO", "DEBUG", "IO_IN", "IO_OUT" ] + } + }, + "allOf": [ + { + "if": { + "additionalProperties": true, + "properties": { + "type": { + "enum": [ "SKIPPED" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "num_skipped" ], + "properties": { + "type": { }, + "num_skipped": { + "type": "u32", + "description": "number of unprinted log entries (deleted or below *level* parameter)" + } + } + } + }, + { + "if": { + "additionalProperties": true, + "properties": { + "type": { + "enum": [ "BROKEN", "UNUSUAL", "INFO", "DEBUG" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "time", "source", "log" ], + "properties": { + "type": { }, + "time": { + "type": "string", + "description": "UNIX timestamp with 9 decimal places after **created_at**" + }, + "source": { + "type": "string", + "description": "The particular logbook this was found in" + }, + "log": { + "type": "string", + "description": "The actual log message" + }, + "node_id": { + "type": "pubkey", + "description": "The peer this is associated with" + } + } + } + }, + { + "if": { + "additionalProperties": true, + "properties": { + "type": { + "enum": [ "IO_IN", "IO_OUT" ] + } + } + }, + "then": { + "additionalProperties": false, + "required": [ "time", "source", "log", "data" ], + "properties": { + "type": { }, + "time": { + "type": "string", + "description": "Seconds after **created_at**, with 9 decimal places" + }, + "source": { + "type": "string", + "description": "The particular logbook this was found in" + }, + "log": { + "type": "string", + "description": "The associated log message" + }, + "node_id": { + "type": "pubkey", + "description": "The peer this is associated with" + }, + "data": { + "type": "hex", + "description": "The IO which occurred" + } + } + } + } + ] + } + } + } +} diff --git a/doc/schemas/getroute.schema.json b/doc/schemas/getroute.schema.json new file mode 100644 index 000000000000..9e5ebe7ebc03 --- /dev/null +++ b/doc/schemas/getroute.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "required": [ "route" ], + "properties": { + "route": { + "type": "array", + "items": { + "type": "object", + "required": [ "id", "direction", "channel", "amount_msat", "delay", "style" ], + "additionalProperties": false, + "properties": { + "id": { + "type": "pubkey", + "description": "The node at the end of this hop" + }, + "channel": { + "type": "short_channel_id", + "description": "The channel joining these nodes" + }, + "direction": { + "type": "u32", + "description": "0 if this channel is traversed from lesser to greater **id**, otherwise 1" + }, + "msatoshi": { + "type": "u64", + "deprecated": true + }, + "amount_msat": { + "type": "msat", + "description": "The amount expected by the node at the end of this hop" + }, + "delay": { + "type": "u32", + "description": "The total CLTV expected by the node at the end of this hop" + }, + "style": { + "type": "string", + "description": "The features understood by the destination node", + "enum": [ "legacy", "tlv" ] + } + } + } + } + } +} diff --git a/tests/test_misc.py b/tests/test_misc.py index 14692bc2ddb5..69d78dc0390d 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -2544,3 +2544,16 @@ def test_notimestamp_logging(node_factory): assert l1.daemon.logs[0].startswith("DEBUG") assert l1.rpc.listconfigs()['log-timestamps'] is False + + +def test_getlog(node_factory): + """Test the getlog command""" + l1 = node_factory.get_node(options={'log-level': 'io'}) + + # Default will skip some entries + logs = l1.rpc.getlog()['log'] + assert [l for l in logs if l['type'] == 'SKIPPED'] != [] + + # This should not + logs = l1.rpc.getlog(level='io')['log'] + assert [l for l in logs if l['type'] == 'SKIPPED'] == [] From b22e8ac17cae08dd96152640f754019a4cb91475 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 27 May 2021 13:55:58 +0930 Subject: [PATCH 19/19] plugins/test/Makefile: fix typo causing build race. Signed-off-by: Rusty Russell --- plugins/test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/test/Makefile b/plugins/test/Makefile index a65ae8b11ea8..67591ecc5ed3 100644 --- a/plugins/test/Makefile +++ b/plugins/test/Makefile @@ -4,7 +4,7 @@ PLUGIN_TEST_SRC := $(wildcard plugins/test/run-*.c) PLUGIN_TEST_OBJS := $(PLUGIN_TEST_SRC:.c=.o) PLUGIN_TEST_PROGRAMS := $(PLUGIN_TEST_OBJS:.o=) -ALL_C_SOURCES += $(PLUGIN__TEST_SRC) +ALL_C_SOURCES += $(PLUGIN_TEST_SRC) ALL_TEST_PROGRAMS += $(PLUGIN_TEST_PROGRAMS) PLUGIN_TEST_COMMON_OBJS := \