From af9a9691bcd4baada6251a1b2db56a31bd588216 Mon Sep 17 00:00:00 2001 From: Andrea Date: Wed, 13 Mar 2019 13:13:01 +0100 Subject: [PATCH] [WIP] fix eclair-cli to use the new APIs --- eclair-core/eclair-cli | 21 ++++++++---- .../fr/acinq/eclair/api/NewService.scala | 32 +++++++++++++------ 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/eclair-core/eclair-cli b/eclair-core/eclair-cli index 66e9cd358..fac784925 100755 --- a/eclair-core/eclair-cli +++ b/eclair-core/eclair-cli @@ -7,7 +7,7 @@ command -v curl >/dev/null 2>&1 || { echo -e "This tool requires curl.\n\nAborti FULL_OUTPUT='false' URL='http://localhost:8080' -PASSWORD='' +PASSWORD='foobar' # -------------------- METHODS @@ -31,13 +31,19 @@ Full documentation at: " # Executes a JSON RPC call to a node listening on ${URL} call() { - jqexp='if .error == null then .result else .error.message end' + 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" + # collect form data from 2nd parameter + form_data="" + for param in ${2}; do + form_data="$form_data -F \"$param\"" + done; + + eval curl "--user ${auth} --silent --show-error -X POST $form_data ${URL}/${1}" | jq -r "$jqexp" } # get script options @@ -80,12 +86,15 @@ case ${METHOD}_${#} in "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) + "receive_2") call ${METHOD} " "$(printf amountMsat=%s ${1})" "$(printf description=%s ${2})" " ;; # ${1} is numeric (amount to receive) + + + "receive_3") call ${METHOD} "'$(printf '[%s,"%s",%s]' "${1}" "${2}" "${3}")'" ;; # ${1} is numeric (amount to receive) as is ${2} for expiry in seconds - "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" ;; + "channel_"*) call ${METHOD} "'${PARAMS}'" "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 } )" ;; - "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" ;; + "channels_"*) call ${METHOD} "'${PARAMS}'" "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 } )" ;; "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) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/NewService.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/NewService.scala index 74df84de7..c7db13d5a 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/api/NewService.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/NewService.scala @@ -16,7 +16,7 @@ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.model.headers.CacheDirectives.{`max-age`, `no-store`, public} import akka.http.scaladsl.model.headers.{`Access-Control-Allow-Headers`, `Access-Control-Allow-Methods`, `Cache-Control`} import akka.http.scaladsl.model.ws.{Message, TextMessage} -import akka.http.scaladsl.server.directives.Credentials +import akka.http.scaladsl.server.directives.{Credentials, LoggingMagnet} import akka.stream.{ActorMaterializer, OverflowStrategy} import akka.stream.scaladsl.{BroadcastHub, Flow, Keep, Source} import fr.acinq.eclair.channel._ @@ -69,7 +69,10 @@ trait NewService extends Directives with WithJsonSerializers with Logging with M // register an actor that feeds the queue when a payment is received appKit.system.actorOf(Props(new Actor { override def preStart: Unit = context.system.eventStream.subscribe(self, classOf[PaymentReceived]) - def receive: Receive = { case received: PaymentReceived => flowInput.offer(received.paymentHash.toString) } + + def receive: Receive = { + case received: PaymentReceived => flowInput.offer(received.paymentHash.toString) + } })) Flow[Message] @@ -79,12 +82,16 @@ trait NewService extends Directives with WithJsonSerializers with Logging with M } val route: Route = { - respondWithDefaultHeaders(customHeaders){ - handleExceptions(apiExceptionHandler){ - authenticateBasicAsync(realm = "Access restricted", userPassAuthenticator){ _ => + respondWithDefaultHeaders(customHeaders) { + handleExceptions(apiExceptionHandler) { + authenticateBasicAsync(realm = "Access restricted", userPassAuthenticator) { _ => post { - path("getinfo") { complete(getInfoResponse) } ~ - path("help") { complete(help.mkString) } ~ + path("getinfo") { + complete(getInfoResponse) + } ~ + path("help") { + complete(help.mkString) + } ~ path("connect") { formFields("nodeId".as[PublicKey], "address".as[NodeAddress]) { (nodeId, addr) => complete(connect(s"$nodeId@$addr")) @@ -126,8 +133,12 @@ trait NewService extends Directives with WithJsonSerializers with Logging with M complete(channelInfo(channelId)) } } ~ - path("allnodes") { complete(allnodes()) } ~ - path("allchannels") { complete(allchannels()) } ~ + path("allnodes") { + complete(allnodes()) + } ~ + path("allchannels") { + complete(allchannels()) + } ~ path("allupdates") { formFields("nodeId".as[PublicKey].?) { nodeId_opt => complete(allupdates(nodeId_opt)) @@ -178,6 +189,7 @@ trait NewService extends Directives with WithJsonSerializers with Logging with M } } } + } def connect(uri: String): Future[String] = { @@ -254,7 +266,7 @@ trait NewService extends Directives with WithJsonSerializers with Logging with M case (Some(nodeId), Some(amount), Some(ph), None) => (nodeId, ph, amount) case (None, None, None, Some(invoice@PaymentRequest(_, Some(amount), _, target, _, _))) => (target, invoice.paymentHash, amount.toLong) case (None, Some(amount), None, Some(invoice@PaymentRequest(_, Some(_), _, target, _, _))) => (target, invoice.paymentHash, amount) // invoice amount is overridden - case _ => throw ApiError("send", "Wrong params list, call 'help' to know more about it") + case _ => throw ApiError("send", "Wrong params list, call 'help' to know more about it") } val sendPayment = SendPayment(amountMsat, paymentHash, targetNodeId, assistedRoutes = invoice_opt.map(_.routingInfo).getOrElse(Seq.empty)) // TODO add minFinalCltvExpiry