Open s-tikhomirov opened 4 years ago
It wants the output of the getroute
command as the first argument. You can use dev-rhash
for the second one.
That said sendpay
isnt meant to be used by [end users / directly from the cli] but rather by plugins or low-level applications, prefer using pay
.
@darosior I unserstand that pay
is the preferred way but still want to use sendpay
for my purposes. I'm gonna use it in a plugin eventually, just wanted to understand how it works using the CLI first.
Now I'm trying this (using getroute
output without whitespace as the first argument):
$ lightning-cli sendpay {"route":[{"id":"03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987","channel":"693x1x0","direction":0,"msatoshi":100,"amount_msat":"100msat","delay":9,"style":"tlv"}]} '1111111111111111111111111111111111111111111111111111111111111111'
lightning-cli: Incorrect 'id' in response: null
Am I on the right track?
What is dev-rhash
and how do I use it (the docs don't have any info on this)?
UPD Tried the same from a plugin.
Plugin code (initialization omitted):
@plugin.method("sendpay_test")
def sendpay_test(plugin, receiver):
route = plugin.rpc.getroute(
receiver,
1000,
0
)
sendpay_result = plugin.rpc.sendpay(
route=[n['id'] for n in route['route']],
payment_hash=1111111111111111111111111111111111111111111111111111111111111111,
msatoshi=1000
)
return sendpay_result
Then I call it with:
lightning-cli sendpay_test 03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987
I get:
"Error while processing sendpay_test: RpcError('RPC call failed: method: sendpay, payload: {\\'route\\': {\\'route\\': [{\\'id\\': \\'03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987\\', \\'channel\\': \\'693x1x0\\', \\'direction\\': 0, \\'msatoshi\\': 1000, \\'amount_msat\\': 1000msat, \\'delay\\': 9, \\'style\\': \\'tlv\\'}]}, \\'payment_hash\\': 1111111111111111111111111111111111111111111111111111111111111111, \\'msatoshi\\': 1000}, error: {\\'code\\': -32602, \\'message\\': \\'\\\\\\'route\\\\\\' should be an array, not \\\\\\'{\"route\": [{\"id\": \"03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987\", \"channel\": \"693x1x0\", \"direction\": 0, \"msatoshi\": 1000, \"amount_msat\": \"1000msat\", \"delay\": 9, \"style\": \"tlv\"}]}\\\\\\'\\'}',)"
I also tried extracting the list of node IDs from the output of getroute
(route = [n['id'] for n in route['route']]
) and passing it to sendpay
. Now I get:
"Error while processing sendpay_test: RpcError(\"RPC call failed: method: sendpay, payload: {'route': ['03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987'], 'payment_hash': 1111111111111111111111111111111111111111111111111111111111111111, 'msatoshi': 1000}, error: {'code': -32602, 'message': 'Expected array or object for params'}\",)"
UPD2 Here is what I actually works (issue #2010 helped).
The gist: sendpay
expects an array of objects describing a node. getroute
returns a dictionary ({}
) with that array as the value at key route
.
This is what works from the plugin:
sendpay_result = plugin.rpc.sendpay(
route=route['route'],
payment_hash=1111111111111111111111111111111111111111111111111111111111111111,
msatoshi=1000
)
And from CLI:
$ lightning-cli sendpay '[{"id": "03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987","channel": "693x1x0","direction": 0,"msatoshi": 1000,"amount_msat": "1000msat","delay": 9,"style":"tlv"}]' "1111111111111111111111111111111111111111111111111111111111111111"
I had no issues with the manually constructed hash value: a string of 64 characters in double-quotes is OK.
I've solved my particular issues, but I have to admit that searching for the solution involved a bit of guesswork which may have not been necessary with a more clear documentation.
Do not transform the route with a list comprehension, instead just pass it in directly:
route = plugin.rpc.getroute(receiver, whatever2, 1)
plugin.rpc.sendpay(route=route, payment_hash=whatever, msatoshi=whatever2)
(do not set riskfactor
to 0, as Strange Things (TM) will happen with getroute
. I think. @cdecker knows riskfactor
better than I do.)
Using the CLI to learn the interface of getroute
and sendpay
for routes is a bad idea: you need to understand how the shell does escapes and so on, making it difficult to use getroute
and sendpay
on the command line. Use them inside a plugin, and understand that the output of getroute
is designed to be the input to sendpay
.
dev-rhash
is a dev command and is not deliberately not documented in the user docs. It might not exist if you do not compile with DEVELOPER=1
. To use dev-
commands and --dev-
options, you should understand the source code, since such commands are usually expected to be useable only by people who do know the source code. Though dev-rhash
is simple enough that maybe a devtools/
program should have it and get some minimal documentation on this.
@ZmnSCPxj Thanks for the clarification!
Still, when I try to use the route
and sendpay
from a plugin as you describe, I get:
"Error while processing sendpay_test: RpcError('RPC call failed: method: sendpay, payload: {\\'route\\': {\\'route\\': [{\\'id\\': \\'03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987\\', \\'channel\\': \\'693x1x0\\', \\'direction\\': 0, \\'msatoshi\\': 1000, \\'amount_msat\\': 1000msat, \\'delay\\': 9, \\'style\\': \\'tlv\\'}]}, \\'payment_hash\\': 1111111111111111111111111111111111111111111111111111111111111111, \\'msatoshi\\': 1000}, error: {\\'code\\': -32602, \\'message\\': \\'\\\\\\'route\\\\\\' should be an array, not \\\\\\'{\"route\": [{\"id\": \"03b66cddd29beb92f9fbdce91924cde26904ba7f5c44ddf73c4d3e0379541b3987\", \"channel\": \"693x1x0\", \"direction\": 0, \"msatoshi\": 1000, \"amount_msat\": \"1000msat\", \"delay\": 9, \"style\": \"tlv\"}]}\\\\\\'\\'}',)"
But when I extract the route from the getroute
output as plugin.rpc.getroute(receiver, whatever2, 1)['route']
, it works...
Ah, yes, I forgot that getroute
returns an object which contains the route
, which is the actual array in use.
Still not a good idea to try it on the command line though, it can get complicated.
On the command line I usually do the following to do a one-off payment attempt:
lightning-cli sendpay $(lightning-cli getroute [destination_node_id] [amount_msat] 10 | jq .route) [payment_hash]
It's nesting the getroute
call inside the sendpay
command, but you can pull them apart:
ROUTE=$(lightning-cli getroute [destination_node_id] [amount_msat] 10 | jq .route)
lightning-cli sendpay $ROUTE [payment_hash]
Notice that I'm using jq .route
to unwrap the list containing the actual route from the outer wrapper object.
@cdecker This one doesn't work for me, surprisingly (I specify the directory explicitly due to #1768):
$ lightning-cli --lightning-dir=$HOME/.lightning-testnet sendpay $(lightning-cli --lightning-dir=$HOME/.lightning-testnet getroute 03d5e17a3c213fe490e1b0c389f8cfcfcea08a29717d50a9f453735e0ab2a7c003 1000000 10 | jq .route) "1111111111111111111111111111111111111111111111111111111111111111"
{
"code": -32602,
"message": "'route' should be an array, not '['"
}
@s-tikhomirov You need to quote the output and use -rc
, untested but that's what I use too when I (unusually want to use sendpay
from the CLI:
lightning-cli --lightning-dir=$HOME/.lightning-testnet sendpay "$(lightning-cli --lightning-dir=$HOME/.lightning-testnet getroute 03d5e17a3c213fe490e1b0c389f8cfcfcea08a29717d50a9f453735e0ab2a7c003 1000000 10 | jq -rc .route)" "1111111111111111111111111111111111111111111111111111111111111111"
Actually by just running
lightning-cli --lightning-dir=$HOME/.lightning-testnet getroute 03d5e17a3c213fe490e1b0c389f8cfcfcea08a29717d50a9f453735e0ab2a7c003 1000000 10 | jq .route
You'd have been able to see that the output is on multiple lines and thus won't work (and eventually adapt your command)..
Or just do not use the commandline for these, note that a good part of what you are now doing is fighting off the shell and its ad hoc methods of deciding what to pass to lightning-cli
.
fighting off the shell and its ad hoc methods
Fair enough. Are the considerations outlined in this issue worth including in the docs for sendpay
? Something along the lines of: "This method is intended to be used from a plugin. Using it from CLI may be troublesome due to [insert reasons]."
Seems reasonable.
This method is intended to be used directly from JSON-RPC libraries of your
preferred programming language.
Using it from *lightning-cli(1)* may be difficult from most shells, as you would
need to understand how your command line shell handles text replacement
and token parsing, which is beyond the scope of this document.
Does not have to be from a plugin, just any application that can execute JSON-RPC commands to the Lightning RPC (plugins are a subset of such applications).
I found the right expression in CLI that works:
lightning-cli sendpay '[{ "id": "~", "channel": "~", "direction": ~, "msatoshi": ~, "amount_msat": "~msat", "delay": ~, "style": "" } ]' payment_hash
You can get route info by getroute
, and payment_hash from here (https://lndecode.com/) by decoding LN invoice.
You can get route info by
getroute
, and payment_hash from here (https://lndecode.com/) by decoding LN invoice.
Even better you can get the payment_hash from decodepay
no need to use a 3rd party service.
Issue and Steps to Reproduce
It's not clear from the documentation how this command should be used:
I send a payment to a neighboring node 03b6 with the hash value of ones and get an error:
How should I use
sendpay
?getinfo
output