From 9ac678291a4b2115013309cabb91a032e9f6807f Mon Sep 17 00:00:00 2001 From: wiesche Date: Mon, 7 Sep 2026 22:54:00 +0200 Subject: [PATCH] keep outgoing slatepacks readable --- api/src/owner.rs | 2 +- controller/src/command.rs | 1 - controller/tests/slatepack.rs | 13 ++++++++++--- libwallet/src/api_impl/owner.rs | 9 ++++++++- libwallet/src/contract/actions/README.md | 2 -- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/api/src/owner.rs b/api/src/owner.rs index b132a6b..24e583f 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -2345,7 +2345,7 @@ where /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using, if /// * `sender_index` - If Some(n), the index along the derivation path to include as the sender /// * `recipients` - Optional recipients for which to encrypt the slatepack's payload (i.e. the - /// slate). If an empty vec, the payload will remain unencrypted + /// slate). The sender is also able to decrypt it. If empty, the payload remains unencrypted /// /// # Returns /// * Ok with a String representing an armored slatepack if successful diff --git a/controller/src/command.rs b/controller/src/command.rs index 605c912..e2fa0dd 100644 --- a/controller/src/command.rs +++ b/controller/src/command.rs @@ -721,7 +721,6 @@ where Some(a) => vec![a], None => vec![], }; - // TODO: what is sender_index? message = api.create_slatepack_message(m, &slate, Some(0), recipients)?; // Trim the \n at the end. let len_withoutcrlf = message.trim_end().len(); diff --git a/controller/tests/slatepack.rs b/controller/tests/slatepack.rs index f4d44ac..b1a3e36 100644 --- a/controller/tests/slatepack.rs +++ b/controller/tests/slatepack.rs @@ -594,10 +594,17 @@ fn slatepack_api_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { ..Default::default() }; let slate = api.init_send_tx(m, args)?; - // create an encrypted slatepack (just encrypted for self) - let enc_addr = api.get_slatepack_address(m, 0)?; - let slatepack = api.create_slatepack_message(m, &slate, Some(0), vec![enc_addr])?; + let recipient_key = edDalekSecretKey::from_bytes(&[1u8; 32]); + let recipient = SlatepackAddress::new(&edDalekPublicKey::from(&recipient_key)); + let slatepack = api.create_slatepack_message(m, &slate, Some(0), vec![recipient])?; println!("{}", slatepack); + let recipient_packer = Slatepacker::new(SlatepackerArgs { + sender: None, + recipients: vec![], + dec_key: Some(&recipient_key), + }); + let recipient_copy = recipient_packer.deser_slatepack(slatepack.as_bytes(), true)?; + recipient_packer.get_slate(&recipient_copy)?; let slatepack_raw = api.decode_slatepack_message(m, slatepack.clone(), vec![0])?; println!("{}", slatepack_raw); let decoded_slate = api.slate_from_slatepack_message(m, slatepack, vec![0])?; diff --git a/libwallet/src/api_impl/owner.rs b/libwallet/src/api_impl/owner.rs index 7d2f3d7..cf43605 100644 --- a/libwallet/src/api_impl/owner.rs +++ b/libwallet/src/api_impl/owner.rs @@ -148,7 +148,7 @@ pub fn create_slatepack_message<'a, L, C, K>( keychain_mask: Option<&SecretKey>, slate: &Slate, sender_index: Option, - recipients: Vec, + mut recipients: Vec, ) -> Result where L: WalletLCProvider<'a, C, K>, @@ -159,6 +159,13 @@ where Some(i) => Some(get_slatepack_address(wallet_inst, keychain_mask, i)?), None => None, }; + if !recipients.is_empty() { + if let Some(sender) = &sender { + if !recipients.contains(sender) { + recipients.push(sender.clone()); + } + } + } let packer = Slatepacker::new(SlatepackerArgs { sender, recipients, diff --git a/libwallet/src/contract/actions/README.md b/libwallet/src/contract/actions/README.md index 21981f7..679e7db 100644 --- a/libwallet/src/contract/actions/README.md +++ b/libwallet/src/contract/actions/README.md @@ -44,8 +44,6 @@ Separating side effects until the 'save_step' part would make these functions mu - Expose the kernel feature constants from `grin_core` and reuse them here. - Move payment-proof creation and verification onto `Slate` so it can also be used outside contracts and is versioned with the slate format. - - Choose the sender derivation path explicitly and keep encrypted outgoing files - identifiable locally. - Add contract history, lookup and transport. - Decide whether the foreign JSON-RPC API should expose `new` and `sign`. - Add full API and RPC examples once the contract interface is stable.