diff --git a/cln-grpc/proto/primitives.proto b/cln-grpc/proto/primitives.proto index 5adc15f68..2dd740990 100644 --- a/cln-grpc/proto/primitives.proto +++ b/cln-grpc/proto/primitives.proto @@ -58,4 +58,18 @@ message Feerate { message OutputDesc { string address = 1; Amount amount = 2; +} + +message RouteHop { + bytes id = 1; + string short_channel_id = 2; + Amount feebase = 3; + uint32 feeprop = 4; + uint32 expirydelta = 5; +} +message Routehint { + repeated RouteHop hops = 1; +} +message RoutehintList { + repeated Routehint hints = 2; } \ No newline at end of file diff --git a/cln-grpc/src/pb.rs b/cln-grpc/src/pb.rs index 7fe8902ed..9fe021afe 100644 --- a/cln-grpc/src/pb.rs +++ b/cln-grpc/src/pb.rs @@ -2,7 +2,7 @@ tonic::include_proto!("cln"); use cln_rpc::primitives::{ Amount as JAmount, AmountOrAll as JAmountOrAll, AmountOrAny as JAmountOrAny, - Feerate as JFeerate, OutputDesc as JOutputDesc, Outpoint as JOutpoint, + Feerate as JFeerate, Outpoint as JOutpoint, OutputDesc as JOutputDesc, }; impl From for Amount { @@ -101,3 +101,28 @@ impl From<&AmountOrAny> for JAmountOrAny { } } } +impl From for cln_rpc::primitives::Routehop { + fn from(c: RouteHop) -> Self { + Self { + id: hex::encode(c.id), + scid: c.short_channel_id, + feebase: c.feebase.as_ref().unwrap().into(), + feeprop: c.feeprop, + expirydelta: c.expirydelta as u16, + } + } +} +impl From for cln_rpc::primitives::Routehint { + fn from(c: Routehint) -> Self { + Self { + hops: c.hops.into_iter().map(|h| h.into()).collect(), + } + } +} +impl From for cln_rpc::primitives::RoutehintList { + fn from(c: RoutehintList) -> Self { + Self { + hints: c.hints.into_iter().map(|h| h.into()).collect(), + } + } +} diff --git a/cln-rpc/src/primitives.rs b/cln-rpc/src/primitives.rs index bdff5434b..dd63b006a 100644 --- a/cln-rpc/src/primitives.rs +++ b/cln-rpc/src/primitives.rs @@ -284,7 +284,7 @@ impl Serialize for Feerate { where S: Serializer, { - let s: String = self.into(); + let s: String = self.into(); serializer.serialize_str(&s) } } @@ -425,3 +425,22 @@ impl Serialize for OutputDesc { map.end() } } + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Routehop { + pub id: String, + pub scid: String, + pub feebase: Amount, + pub feeprop: u32, + pub expirydelta: u16, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Routehint { + pub hops: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RoutehintList { + pub hints: Vec, +} diff --git a/contrib/msggen/msggen/grpc.py b/contrib/msggen/msggen/grpc.py index ad790ee26..f7e70f5c5 100644 --- a/contrib/msggen/msggen/grpc.py +++ b/contrib/msggen/msggen/grpc.py @@ -377,7 +377,7 @@ class GrpcUnconverterGenerator(GrpcConverterGenerator): if isinstance(f, ArrayField): typ = f.itemtype.typename mapping = { - 'hex': f'hex::decode(s).unwrap()', + 'hex': f'hex::encode(s)', 'u32': f's.clone()', }.get(typ, f's.into()') self.write(f"{name}: c.{name}.iter().map(|s| {mapping}).collect(),\n", numindent=3) @@ -410,6 +410,7 @@ class GrpcUnconverterGenerator(GrpcConverterGenerator): '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())', + 'RoutehintList?': f'c.{name}.clone().map(|rl| rl.into())', }.get( typ, f'c.{name}.clone()' # default to just assignment diff --git a/contrib/msggen/msggen/model.py b/contrib/msggen/msggen/model.py index db643cf94..7a7c205ff 100644 --- a/contrib/msggen/msggen/model.py +++ b/contrib/msggen/msggen/model.py @@ -340,6 +340,7 @@ InvoiceLabelField = PrimitiveField("string", None, None) DatastoreKeyField = ArrayField(itemtype=PrimitiveField("string", None, None), dims=1, path=None, description=None) InvoiceExposeprivatechannelsField = PrimitiveField("boolean", None, None) PayExclude = ArrayField(itemtype=PrimitiveField("string", None, None), dims=1, path=None, description=None) +RoutehintListField = PrimitiveField("RoutehintList", None, None) # Override fields with manually managed types, fieldpath -> field mapping overrides = { 'Invoice.label': InvoiceLabelField, @@ -350,6 +351,7 @@ overrides = { 'ListDatastore.key': DatastoreKeyField, 'Invoice.exposeprivatechannels': InvoiceExposeprivatechannelsField, 'Pay.exclude': PayExclude, + 'KeySend.routehints': RoutehintListField, } diff --git a/contrib/msggen/msggen/rust.py b/contrib/msggen/msggen/rust.py index e08a6febf..c5a5c7d4c 100644 --- a/contrib/msggen/msggen/rust.py +++ b/contrib/msggen/msggen/rust.py @@ -165,7 +165,7 @@ def gen_array(a): return ("", "") # Override said not to include itemtype = typemap.get(itemtype, itemtype) - alias = a.name.normalized()[:-2] # Strip the `[]` suffix for arrays. + alias = a.name.normalized() defi = f" #[serde(alias = \"{alias}\")]\n pub {name}: {'Vec<'*a.dims}{itemtype}{'>'*a.dims},\n" return (defi, decl)