mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
json-rpc: Add createonion command similar to the devtools/onion tool
This allows us to create an onion in the JSON-RPC that we can then later inject with the `sendonion` command that we're about to implement.
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <common/bolt11.h>
|
#include <common/bolt11.h>
|
||||||
#include <common/json_command.h>
|
#include <common/json_command.h>
|
||||||
|
#include <common/json_helpers.h>
|
||||||
#include <common/jsonrpc_errors.h>
|
#include <common/jsonrpc_errors.h>
|
||||||
#include <common/param.h>
|
#include <common/param.h>
|
||||||
#include <common/timeout.h>
|
#include <common/timeout.h>
|
||||||
@@ -1103,3 +1104,99 @@ static const struct json_command listsendpays_command = {
|
|||||||
"Show sendpay, old and current, optionally limiting to {bolt11} or {payment_hash}."
|
"Show sendpay, old and current, optionally limiting to {bolt11} or {payment_hash}."
|
||||||
};
|
};
|
||||||
AUTODATA(json_command, &listsendpays_command);
|
AUTODATA(json_command, &listsendpays_command);
|
||||||
|
|
||||||
|
static struct command_result *json_createonion(struct command *cmd,
|
||||||
|
const char *buffer,
|
||||||
|
const jsmntok_t *obj UNNEEDED,
|
||||||
|
const jsmntok_t *params)
|
||||||
|
{
|
||||||
|
const jsmntok_t *hopstok, *hop, *payloadtok, *typetok, *pubkeytok;
|
||||||
|
enum sphinx_payload_type type;
|
||||||
|
size_t i, hop_count = 0;
|
||||||
|
struct json_stream *response;
|
||||||
|
struct pubkey pubkey;
|
||||||
|
struct secret *session_key, *shared_secrets;
|
||||||
|
struct sphinx_path *sp;
|
||||||
|
u8 *assocdata, *payload, *serialized;
|
||||||
|
struct onionpacket *packet;
|
||||||
|
|
||||||
|
if (!param(cmd, buffer, params,
|
||||||
|
p_req("hops", param_array, &hopstok),
|
||||||
|
p_req("assocdata", param_bin_from_hex, &assocdata),
|
||||||
|
p_opt("session_key", param_secret, &session_key),
|
||||||
|
NULL)) {
|
||||||
|
return command_param_failed();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session_key == NULL)
|
||||||
|
sp = sphinx_path_new(cmd, assocdata);
|
||||||
|
else
|
||||||
|
sp = sphinx_path_new_with_key(cmd, assocdata, session_key);
|
||||||
|
|
||||||
|
json_for_each_arr(i, hop, hopstok) {
|
||||||
|
payloadtok = json_get_member(buffer, hop, "payload");
|
||||||
|
typetok = json_get_member(buffer, hop, "type");
|
||||||
|
pubkeytok = json_get_member(buffer, hop, "pubkey");
|
||||||
|
|
||||||
|
if (!pubkeytok)
|
||||||
|
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||||
|
"Hop %zu does not have a pubkey", i);
|
||||||
|
|
||||||
|
if (!payloadtok)
|
||||||
|
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||||
|
"Hop %zu does not have a payload", i);
|
||||||
|
|
||||||
|
payload = json_tok_bin_from_hex(cmd, buffer, payloadtok);
|
||||||
|
if (!json_to_pubkey(buffer, pubkeytok, &pubkey))
|
||||||
|
return command_fail(
|
||||||
|
cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'pubkey' should be a pubkey, not '%.*s'",
|
||||||
|
pubkeytok->end - pubkeytok->start,
|
||||||
|
buffer + pubkeytok->start);
|
||||||
|
|
||||||
|
if (!payload)
|
||||||
|
return command_fail(
|
||||||
|
cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
|
"'payload' should be a hex encoded binary, not '%.*s'",
|
||||||
|
pubkeytok->end - pubkeytok->start,
|
||||||
|
buffer + pubkeytok->start);
|
||||||
|
|
||||||
|
if (!typetok || !json_tok_streq(buffer, typetok, "legacy")) {
|
||||||
|
type = SPHINX_RAW_PAYLOAD;
|
||||||
|
} else {
|
||||||
|
type = SPHINX_V0_PAYLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
sphinx_add_raw_hop(sp, &pubkey, type, payload);
|
||||||
|
hop_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hop_count == 0)
|
||||||
|
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||||
|
"Cannot create an onion without hops.");
|
||||||
|
|
||||||
|
|
||||||
|
packet = create_onionpacket(cmd, sp, &shared_secrets);
|
||||||
|
if (!packet)
|
||||||
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
|
"Could not create onion packet");
|
||||||
|
|
||||||
|
serialized = serialize_onionpacket(cmd, packet);
|
||||||
|
|
||||||
|
response = json_stream_success(cmd);
|
||||||
|
json_add_hex(response, "onion", serialized, tal_bytelen(serialized));
|
||||||
|
json_array_start(response, "shared_secrets");
|
||||||
|
for (size_t i=0; i<hop_count; i++) {
|
||||||
|
json_add_secret(response, NULL, &shared_secrets[i]);
|
||||||
|
}
|
||||||
|
json_array_end(response);
|
||||||
|
return command_success(cmd, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct json_command createonion_command = {
|
||||||
|
"createonion",
|
||||||
|
"payment",
|
||||||
|
json_createonion,
|
||||||
|
"Create an onion going through the provided nodes, each with its own payload"
|
||||||
|
};
|
||||||
|
AUTODATA(json_command, &createonion_command);
|
||||||
|
|||||||
Reference in New Issue
Block a user