Add descriptionHash
parameter to createinvoice
(#50)
A new parameter `descriptionHash` has been added to `createinvoice`, which takes a 32-bytes hex string. Either `description` or `descriptionHash` must be provided. The `description` field is now limited to 128 characters.
This commit is contained in:
parent
18035566f8
commit
dec1c59c80
@ -113,8 +113,16 @@ class Api(private val nodeParams: NodeParams, private val peer: Peer, private va
|
||||
post("createinvoice") {
|
||||
val formParameters = call.receiveParameters()
|
||||
val amount = formParameters.getOptionalLong("amountSat")?.sat
|
||||
val description = formParameters.getString("description")
|
||||
val invoice = peer.createInvoice(randomBytes32(), amount?.toMilliSatoshi(), Either.Left(description))
|
||||
val maxDescriptionSize = 128
|
||||
val description = formParameters["description"]
|
||||
?.also { if (it.length > maxDescriptionSize) badRequest("Request parameter description is too long (max $maxDescriptionSize characters)") }
|
||||
val descriptionHash = formParameters.getOptionalByteVector32("descriptionHash")
|
||||
val eitherDesc = when {
|
||||
description != null && descriptionHash == null -> Either.Left(description)
|
||||
description == null && descriptionHash != null -> Either.Right(descriptionHash)
|
||||
else -> badRequest("Must provide either a description or descriptionHash")
|
||||
}
|
||||
val invoice = peer.createInvoice(randomBytes32(), amount?.toMilliSatoshi(), eitherDesc)
|
||||
formParameters["externalId"]?.takeUnless { it.isBlank() }?.let { externalId ->
|
||||
paymentDb.metadataQueries.insertExternalId(WalletPaymentId.IncomingPaymentId(invoice.paymentHash), externalId)
|
||||
}
|
||||
@ -228,13 +236,17 @@ class Api(private val nodeParams: NodeParams, private val peer: Peer, private va
|
||||
|
||||
private fun invalidType(argName: String, typeName: String): Nothing = throw ParameterConversionException(argName, typeName)
|
||||
|
||||
private fun badRequest(message: String): Nothing = throw BadRequestException(message)
|
||||
|
||||
private fun Parameters.getString(argName: String): String = (this[argName] ?: missing(argName))
|
||||
|
||||
private fun Parameters.getByteVector32(argName: String): ByteVector32 = getString(argName).let { hex -> kotlin.runCatching { ByteVector32.fromValidHex(hex) }.getOrNull() ?: invalidType(argName, "hex32") }
|
||||
|
||||
private fun Parameters.getOptionalByteVector32(argName: String): ByteVector32? = this[argName]?.let { hex -> kotlin.runCatching { ByteVector32.fromValidHex(hex) }.getOrNull() ?: invalidType(argName, "hex32") }
|
||||
|
||||
private fun Parameters.getUUID(argName: String): UUID = getString(argName).let { uuid -> kotlin.runCatching { UUID.fromString(uuid) }.getOrNull() ?: invalidType(argName, "uuid") }
|
||||
|
||||
private fun Parameters.getAddressAndConvertToScript(argName: String): ByteVector = Script.write(Bitcoin.addressToPublicKeyScript(nodeParams.chainHash, getString(argName)).right ?: error("invalid address")).toByteVector()
|
||||
private fun Parameters.getAddressAndConvertToScript(argName: String): ByteVector = Script.write(Bitcoin.addressToPublicKeyScript(nodeParams.chainHash, getString(argName)).right ?: badRequest("Invalid address")).toByteVector()
|
||||
|
||||
private fun Parameters.getInvoice(argName: String): Bolt11Invoice = getString(argName).let { invoice -> Bolt11Invoice.read(invoice).getOrElse { invalidType(argName, "bolt11invoice") } }
|
||||
|
||||
|
@ -5,6 +5,9 @@ import com.github.ajalt.clikt.core.context
|
||||
import com.github.ajalt.clikt.core.requireObject
|
||||
import com.github.ajalt.clikt.core.subcommands
|
||||
import com.github.ajalt.clikt.output.MordantHelpFormatter
|
||||
import com.github.ajalt.clikt.parameters.groups.mutuallyExclusiveOptions
|
||||
import com.github.ajalt.clikt.parameters.groups.required
|
||||
import com.github.ajalt.clikt.parameters.groups.single
|
||||
import com.github.ajalt.clikt.parameters.options.*
|
||||
import com.github.ajalt.clikt.parameters.types.int
|
||||
import com.github.ajalt.clikt.parameters.types.long
|
||||
@ -12,6 +15,7 @@ import com.github.ajalt.clikt.sources.MapValueSource
|
||||
import fr.acinq.bitcoin.Base58Check
|
||||
import fr.acinq.bitcoin.Bech32
|
||||
import fr.acinq.bitcoin.ByteVector32
|
||||
import fr.acinq.bitcoin.utils.Either
|
||||
import fr.acinq.lightning.BuildVersions
|
||||
import fr.acinq.lightning.bin.conf.readConfFile
|
||||
import fr.acinq.lightning.bin.datadir
|
||||
@ -124,7 +128,7 @@ class GetOutgoingPayment : PhoenixCliCommand(name = "getoutgoingpayment", help =
|
||||
}
|
||||
|
||||
class GetIncomingPayment : PhoenixCliCommand(name = "getincomingpayment", help = "Get incoming payment") {
|
||||
private val paymentHash by option("--paymentHash", "--h").convert { ByteVector32.fromValidHex(it) }.required()
|
||||
private val paymentHash by option("--paymentHash", "--h").convert { it.toByteVector32() }.required()
|
||||
override suspend fun httpRequest() = commonOptions.httpClient.use {
|
||||
it.get(url = commonOptions.baseUrl / "payments/incoming/$paymentHash")
|
||||
}
|
||||
@ -143,7 +147,11 @@ class ListIncomingPayments : PhoenixCliCommand(name = "listincomingpayments", he
|
||||
|
||||
class CreateInvoice : PhoenixCliCommand(name = "createinvoice", help = "Create a Lightning invoice", printHelpOnEmptyArgs = true) {
|
||||
private val amountSat by option("--amountSat").long()
|
||||
private val description by option("--description", "--desc").required()
|
||||
private val description by mutuallyExclusiveOptions(
|
||||
option("--description", "--desc").convert { Either.Left(it) },
|
||||
option("--descriptionHash", "--desc-hash").convert { Either.Right(it.toByteVector32()) }
|
||||
).single().required()
|
||||
|
||||
private val externalId by option("--externalId")
|
||||
override suspend fun httpRequest() = commonOptions.httpClient.use {
|
||||
it.submitForm(
|
||||
@ -151,7 +159,10 @@ class CreateInvoice : PhoenixCliCommand(name = "createinvoice", help = "Create a
|
||||
formParameters = parameters {
|
||||
amountSat?.let { append("amountSat", it.toString()) }
|
||||
externalId?.let { append("externalId", it) }
|
||||
append("description", description)
|
||||
when(val d = description) {
|
||||
is Either.Left -> append("description", d.value)
|
||||
is Either.Right -> append("descriptionHash", d.value.toHex())
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -188,7 +199,7 @@ class SendToAddress : PhoenixCliCommand(name = "sendtoaddress", help = "Send to
|
||||
}
|
||||
|
||||
class CloseChannel : PhoenixCliCommand(name = "closechannel", help = "Close channel", printHelpOnEmptyArgs = true) {
|
||||
private val channelId by option("--channelId").convert { ByteVector32.fromValidHex(it) }.required()
|
||||
private val channelId by option("--channelId").convert { it.toByteVector32() }.required()
|
||||
private val address by option("--address").required().check { runCatching { Base58Check.decode(it) }.isSuccess || runCatching { Bech32.decodeWitnessAddress(it) }.isSuccess }
|
||||
private val feerateSatByte by option("--feerateSatByte").int().required()
|
||||
override suspend fun httpRequest() = commonOptions.httpClient.use {
|
||||
@ -203,4 +214,6 @@ class CloseChannel : PhoenixCliCommand(name = "closechannel", help = "Close chan
|
||||
}
|
||||
}
|
||||
|
||||
operator fun Url.div(path: String) = Url(URLBuilder(this).appendPathSegments(path))
|
||||
operator fun Url.div(path: String) = Url(URLBuilder(this).appendPathSegments(path))
|
||||
|
||||
fun String.toByteVector32(): ByteVector32 = kotlin.runCatching { ByteVector32.fromValidHex(this) }.recover { error("'$this' is not a valid 32-bytes hex string") }.getOrThrow()
|
Loading…
x
Reference in New Issue
Block a user