2016-06-02 17:15:36 +02:00
#!/bin/bash
2018-01-11 19:23:17 +01:00
# Check if jq is installed. If not, display instructions and abort program
command -v jq >/dev/null 2>&1 || { echo -e "This tool requires jq.\nFor installation instructions, visit https://stedolan.github.io/jq/download/.\n\nAborting..."; exit 1; }
2018-11-14 00:35:16 +08:00
# curl installed? If not, give a hint
command -v curl >/dev/null 2>&1 || { echo -e "This tool requires curl.\n\nAborting..."; exit 1; }
2018-01-11 19:23:17 +01:00
FULL_OUTPUT='false'
URL='http://localhost:8080'
PASSWORD=''
# -------------------- METHODS
displayhelp() {
echo -e "Usage: eclair-cli [OPTION]... [COMMAND]
Client for an eclair node.
With COMMAND is one of the command listed by \e[01;33meclair-cli help\e[0m.
-p <password> api's password
-a <address> Override the api URL with <address>
-v Outputs full json returned by the API
Examples:
eclair-cli -a localhost:1234 peers list the peers
eclair-cli close 006fb... closes the channel with id 006fb...
Note: Uses the json-rpc api exposed by the node on localhost:8080. Make sure the api is enabled.
Full documentation at: <https://github.com/ACINQ/eclair>"
}
# Executes a JSON RPC call to a node listening on ${URL}
call() {
jqexp='if .error == null then .result else .error.message end'
# override default jq parsing expression
if [ $# -ge 3 ] && [ ${FULL_OUTPUT} == "false" ]; then jqexp=${3}; fi
# set password
if [ -z ${PASSWORD} ]; then auth="eclair-cli";
else auth="eclair-cli:"${PASSWORD}; fi
eval curl "--user ${auth} --silent --show-error -X POST -H \"Content-Type: application/json\" -d '{ \"method\": \"'${1}'\", \"params\": '${2}' }' ${URL}" | jq -r "$jqexp"
}
# get script options
while getopts 'vu:p:a:' flag; do
case "${flag}" in
p) PASSWORD="${OPTARG}" ;;
a) URL="${OPTARG}" ;;
v) FULL_OUTPUT="true" ;;
*) echo -e "\nAborting..."; exit 1; ;;
esac
done
shift $(($OPTIND - 1))
# assigning JSON RPC method and params values from arguments
METHOD=${1}
shift 1
# Create a JSON Array containing the remaining program args as QUOTED STRINGS, separated with a `,` character
PARAMS=""
i=1
for arg in "${@}"; do
if [ $i -eq 1 ]; then PARAMS=$(printf '"%s"' "$arg");
else PARAMS=$(printf '%s,"%s"' "$PARAMS" "$arg");
fi
let "i++"
done;
PARAMS="[${PARAMS}]"
# Whatever the arguments provided to eclair-cli, a call to the API will be sent. Let it fail!
case ${METHOD}_${#} in
""_*) displayhelp ;;
"help"*) displayhelp
echo -e "\nAvailable commands:\n"
call "help" [] ;;
"connect_3") call ${METHOD} "'$(printf '["%s","%s",%s]' "${1}" "${2}" "${3}")'" ;; # ${3} is numeric
"open_4") call ${METHOD} "'$(printf '["%s",%s,%s,%s]' "${1}" "${2}" "${3}" "${4}")'" ;; # ${2} ${3} ${4} are numeric (funding, push, flags)
"open_3") call ${METHOD} "'$(printf '["%s",%s,%s]' "${1}" "${2}" "${3}")'" ;; # ${2} ${3} are numeric (funding, push)
"open_2") call ${METHOD} "'$(printf '["%s",%s]' "${1}" "${2}")'" ;; # ${2} is numeric (funding)
"receive_2") call ${METHOD} "'$(printf '[%s,"%s"]' "${1}" "${2}")'" ;; # ${1} is numeric (amount to receive)
2018-06-19 12:13:07 +01:00
"receive_3") call ${METHOD} "'$(printf '[%s,"%s",%s]' "${1}" "${2}" "${3}")'" ;; # ${1} is numeric (amount to receive) as is ${2} for expiry in seconds
2018-01-11 19:23:17 +01:00
2018-09-24 11:49:05 +02:00
"channel_"*) call ${METHOD} "'${PARAMS}'" "if .error != null then .error.message else .result | { nodeId, shortChannelId: .data.shortChannelId, channelId, state, balanceSat: (try (.data.commitments.localCommit.spec.toLocalMsat / 1000 | floor) catch null), capacitySat: .data.commitments.commitInput.amountSatoshis, channelPoint: .data.commitments.commitInput.outPoint } end" ;;
2018-08-15 14:39:19 +02:00
2018-09-24 11:49:05 +02:00
"channels_"*) call ${METHOD} "'${PARAMS}'" "if .error != null then .error.message else .result | map( { nodeId, shortChannelId: .data.shortChannelId, channelId, state, balanceSat: (try (.data.commitments.localCommit.spec.toLocalMsat / 1000 | floor) catch null), capacitySat: .data.commitments.commitInput.amountSatoshis, channelPoint: .data.commitments.commitInput.outPoint } ) end" ;;
Audit: Keep track of sent/received/relayed payments and relay/network fees (#654)
Added a new `AuditDb` which keeps tracks of:
- every single payment (received/sent/relayed)
- every single network fee paid to the miners (funding, closing, and all commit/htlc transactions)
Note that network fees are considered paid when the corresponding tx has reached `min_depth`, it makes sense and allows us to compute the fee in one single place in the `CLOSING` handler. There is an exception for the funding tx, for which we consider the fee paid when the tx has successfully been published to the network. It simplifies the implementation and the tradeoff seems acceptable.
Three new functions have been added to the json-rpc api:
- `audit`: returns all individual payments, with optional filtering on timestamp.
- `networkfees`: returns every single fee paid to the miners, by type (`funding`, `mutual`, `revoked-commit`, etc.) and by channel, with optional filtering on timestamp.
- `channelstats`: maybe the most useful method; it returns a number of information per channel, including the `relayFee` (earned) and the `networkFee` (paid).
The `channels` method now returns details information about channels. It makes it far easier to compute aggregate information about channels using the command line.
Also added a new `ChannelFailed` event that allows e.g. the mobile app to know why a channel got closed.
2018-07-25 16:47:38 +02:00
2018-01-11 19:23:17 +01:00
"send_3") call ${METHOD} "'$(printf '[%s,"%s","%s"]' "${1}" "${2}" "${3}")'" ;; # ${1} is numeric (amount of the payment)
"send_2") call ${METHOD} "'$(printf '["%s",%s]' "${1}" "${2}")'" ;; # ${2} is numeric (amount overriding the payment request)
2018-08-15 14:39:19 +02:00
"audit_2") call ${METHOD} "'$(printf '[%s,%s]' "${1}" "${2}")'" ;; # ${1} and ${2} are numeric (unix timestamps)
2018-09-24 11:49:05 +02:00
2018-08-15 14:39:19 +02:00
"networkfees_2") call ${METHOD} "'$(printf '[%s,%s]' "${1}" "${2}")'" ;; # ${1} and ${2} are numeric (unix timestamps)
2018-01-11 19:23:17 +01:00
*) # Default case.
# Sends the method and, for parameters, use the JSON table containing the remaining args.
#
# NOTE: Arguments will be sent as QUOTED STRING so if this particular API call requires an INT param,
# this call will fail. In that case, a specific rule for that method MUST be set and the ${PARAMS} JSON array can not be used.
call ${METHOD} "'${PARAMS}'" ;;
2016-06-02 17:15:36 +02:00
esac