diff --git a/cln-grpc/proto/node.proto b/cln-grpc/proto/node.proto index f3a6dd23a..cfd390c23 100644 --- a/cln-grpc/proto/node.proto +++ b/cln-grpc/proto/node.proto @@ -558,7 +558,7 @@ message DelinvoiceResponse { } message InvoiceRequest { - Amount msatoshi = 1; + AmountOrAny msatoshi = 1; string description = 2; string label = 3; repeated string fallbacks = 4; @@ -910,7 +910,7 @@ message NewaddrResponse { message WithdrawRequest { bytes destination = 1; - optional Amount satoshi = 2; + optional AmountOrAll satoshi = 2; optional Feerate feerate = 5; optional uint32 minconf = 3; repeated Utxo utxos = 4; diff --git a/cln-grpc/proto/primitives.proto b/cln-grpc/proto/primitives.proto index 2f04e1410..c76730949 100644 --- a/cln-grpc/proto/primitives.proto +++ b/cln-grpc/proto/primitives.proto @@ -5,6 +5,20 @@ message Amount { uint64 msat = 1; } +message AmountOrAll { + oneof value { + Amount amount = 1; + bool all = 2; + } +} + +message AmountOrAny { + oneof value { + Amount amount = 1; + bool any = 2; + } +} + enum ChannelSide { IN = 0; OUT = 1; diff --git a/cln-grpc/src/convert.rs b/cln-grpc/src/convert.rs index 61b09b814..cb7d8d54b 100644 --- a/cln-grpc/src/convert.rs +++ b/cln-grpc/src/convert.rs @@ -1028,7 +1028,7 @@ impl From<&pb::DelinvoiceRequest> for requests::DelinvoiceRequest { impl From<&pb::InvoiceRequest> for requests::InvoiceRequest { fn from(c: &pb::InvoiceRequest) -> Self { Self { - msatoshi: c.msatoshi.as_ref().unwrap().into(), // Rule #1 for type msat + msatoshi: c.msatoshi.as_ref().unwrap().into(), // Rule #1 for type msat|any description: c.description.clone(), // Rule #1 for type string label: c.label.clone(), // Rule #1 for type string fallbacks: c.fallbacks.iter().map(|s| s.into()).collect(), @@ -1156,7 +1156,7 @@ impl From<&pb::WithdrawRequest> for requests::WithdrawRequest { fn from(c: &pb::WithdrawRequest) -> Self { Self { destination: hex::encode(&c.destination), // Rule #1 for type pubkey - satoshi: c.satoshi.as_ref().map(|a| a.into()), // Rule #1 for type msat? + satoshi: c.satoshi.as_ref().map(|a| a.into()), // Rule #1 for type msat|all? feerate: c.feerate.as_ref().map(|a| a.into()), // Rule #1 for type feerate? minconf: c.minconf.map(|v| v as u16), // Rule #1 for type u16? utxos: c.utxos.iter().map(|s| s.into()).collect(), diff --git a/cln-grpc/src/pb.rs b/cln-grpc/src/pb.rs index 2c2b98828..910f09caf 100644 --- a/cln-grpc/src/pb.rs +++ b/cln-grpc/src/pb.rs @@ -1,7 +1,8 @@ tonic::include_proto!("cln"); use cln_rpc::primitives::{ - Amount as JAmount, Feerate as JFeerate, OutputDesc as JOutputDesc, Utxo as JUtxo, + Amount as JAmount, AmountOrAll as JAmountOrAll, AmountOrAny as JAmountOrAny, + Feerate as JFeerate, OutputDesc as JOutputDesc, Utxo as JUtxo, }; impl From for Amount { @@ -55,3 +56,48 @@ impl From<&OutputDesc> for JOutputDesc { } } } + +impl From for AmountOrAll { + fn from(a: JAmountOrAll) -> Self { + match a { + JAmountOrAll::Amount(a) => AmountOrAll { + value: Some(amount_or_all::Value::Amount(a.into())), + }, + JAmountOrAll::All => AmountOrAll { + value: Some(amount_or_all::Value::All(true)), + }, + } + } +} + +impl From<&AmountOrAll> for JAmountOrAll { + fn from(a: &AmountOrAll) -> Self { + match &a.value { + Some(amount_or_all::Value::Amount(a)) => JAmountOrAll::Amount(a.into()), + Some(amount_or_all::Value::All(_)) => JAmountOrAll::All, + None => panic!("AmountOrAll is neither amount nor all: {:?}", a), + } + } +} + +impl From for AmountOrAny { + fn from(a: JAmountOrAny) -> Self { + match a { + JAmountOrAny::Amount(a) => AmountOrAny { + value: Some(amount_or_any::Value::Amount(a.into())), + }, + JAmountOrAny::Any => AmountOrAny { + value: Some(amount_or_any::Value::Any(true)), + }, + } + } +} +impl From<&AmountOrAny> for JAmountOrAny { + fn from(a: &AmountOrAny) -> Self { + match &a.value { + Some(amount_or_any::Value::Amount(a)) => JAmountOrAny::Amount(a.into()), + Some(amount_or_any::Value::Any(_)) => JAmountOrAny::Any, + None => panic!("AmountOrAll is neither amount nor any: {:?}", a), + } + } +} diff --git a/cln-rpc/src/lib.rs b/cln-rpc/src/lib.rs index 0197d4b39..c57bf2432 100644 --- a/cln-rpc/src/lib.rs +++ b/cln-rpc/src/lib.rs @@ -75,7 +75,7 @@ impl ClnRpc { // serde_json knows which variant of [`Request`] should be // used. response["method"] = req2["method"].clone(); - + log::warn!("XXX {:?}", response); serde_json::from_value(response).context("converting response into enum") } } diff --git a/cln-rpc/src/model.rs b/cln-rpc/src/model.rs index 9d767e310..be76d10ce 100644 --- a/cln-rpc/src/model.rs +++ b/cln-rpc/src/model.rs @@ -321,7 +321,7 @@ pub mod requests { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct InvoiceRequest { #[serde(alias = "msatoshi")] - pub msatoshi: Amount, + pub msatoshi: AmountOrAny, #[serde(alias = "description")] pub description: String, #[serde(alias = "label")] @@ -477,7 +477,7 @@ pub mod requests { #[serde(alias = "destination")] pub destination: String, #[serde(alias = "satoshi", skip_serializing_if = "Option::is_none")] - pub satoshi: Option, + pub satoshi: Option, #[serde(alias = "feerate", skip_serializing_if = "Option::is_none")] pub feerate: Option, #[serde(alias = "minconf", skip_serializing_if = "Option::is_none")] diff --git a/contrib/msggen/msggen/grpc.py b/contrib/msggen/msggen/grpc.py index e29e8312a..61084e7cf 100644 --- a/contrib/msggen/msggen/grpc.py +++ b/contrib/msggen/msggen/grpc.py @@ -10,6 +10,8 @@ typemap = { 'boolean': 'bool', 'hex': 'bytes', 'msat': 'Amount', + 'msat|all': 'AmountOrAll', + 'msat|any': 'AmountOrAny', 'number': 'sint64', 'pubkey': 'bytes', 'short_channel_id': 'string', @@ -395,6 +397,10 @@ class GrpcUnconverterGenerator(GrpcConverterGenerator): 'pubkey?': f'c.{name}.clone().map(|v| hex::encode(v))', 'msat': f'c.{name}.as_ref().unwrap().into()', 'msat?': f'c.{name}.as_ref().map(|a| a.into())', + 'msat|all': f'c.{name}.as_ref().unwrap().into()', + 'msat|all?': f'c.{name}.as_ref().map(|a| a.into())', + 'msat|any': f'c.{name}.as_ref().unwrap().into()', + 'msat|any?': f'c.{name}.as_ref().map(|a| a.into())', 'feerate': f'c.{name}.as_ref().unwrap().into()', 'feerate?': f'c.{name}.as_ref().map(|a| a.into())', }.get( diff --git a/contrib/msggen/msggen/model.py b/contrib/msggen/msggen/model.py index db5812917..49215203a 100644 --- a/contrib/msggen/msggen/model.py +++ b/contrib/msggen/msggen/model.py @@ -224,6 +224,8 @@ class PrimitiveField(Field): "pubkey", "signature", "msat", + "msat|any", + "msat|all", "hex", "short_channel_id", "txid", diff --git a/contrib/msggen/msggen/rust.py b/contrib/msggen/msggen/rust.py index ea5aaf3cc..0de946b7f 100644 --- a/contrib/msggen/msggen/rust.py +++ b/contrib/msggen/msggen/rust.py @@ -32,6 +32,8 @@ typemap = { 'boolean': 'bool', 'hex': 'String', 'msat': 'Amount', + 'msat|all': 'AmountOrAll', + 'msat|any': 'AmountOrAny', 'number': 'i64', 'pubkey': 'String', 'short_channel_id': 'String', diff --git a/doc/schemas/invoice.request.json b/doc/schemas/invoice.request.json index 282311bd8..34d40c267 100644 --- a/doc/schemas/invoice.request.json +++ b/doc/schemas/invoice.request.json @@ -9,7 +9,7 @@ ], "properties": { "msatoshi": { - "type": "msat", + "type": "msat|any", "description": "" }, "description": { diff --git a/doc/schemas/withdraw.request.json b/doc/schemas/withdraw.request.json index d098171c8..0637f1f16 100644 --- a/doc/schemas/withdraw.request.json +++ b/doc/schemas/withdraw.request.json @@ -9,7 +9,7 @@ "type": "pubkey" }, "satoshi": { - "type": "msat" + "type": "msat|all" }, "feerate": { "type": "feerate" diff --git a/tests/test_cln_rs.py b/tests/test_cln_rs.py index 4fb62b810..140ffa392 100644 --- a/tests/test_cln_rs.py +++ b/tests/test_cln_rs.py @@ -5,6 +5,7 @@ from pyln.testing.utils import env, TEST_NETWORK, wait_for from ephemeral_port_reserve import reserve import grpc import node_pb2 as nodepb +from primitives_pb2 import AmountOrAny import pytest import subprocess @@ -101,6 +102,15 @@ def test_grpc_connect(node_factory): response = stub.ListFunds(nodepb.ListfundsRequest()) print(response) + inv = stub.Invoice(nodepb.InvoiceRequest( + msatoshi=AmountOrAny(any=True), + description="hello", + label="lbl1", + preimage=b"\x00" * 32, + cltv=24 + )) + print(inv) + def test_grpc_generate_certificate(node_factory): """Test whether we correctly generate the certificates.