diff --git a/api/src/owner.rs b/api/src/owner.rs index 92119b5e..13726946 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -2117,13 +2117,16 @@ where } /// Decode an armored slatepack, returning a Slatepack object that can be - /// viewed, manipulated, output as json, etc + /// viewed, manipulated, output as json, etc. The resulting slatepack will be + /// decrypted by this wallet if possible /// /// # Arguments /// /// * `keychain_mask` - Wallet secret mask to XOR against the stored wallet seed before using /// * `slatepack` - A string representing an armored slatepack - /// * `decrypt` - If true and the slatepack message content is encrypted, attempt to decrypt + /// * `secret_indices` - Indices along this wallet's deriviation path with which to attempt + /// decryption. If this wallet can't decrypt this slatepack, the payload of the returned + /// Slatepack will remain encrypted. /// /// # Returns /// * Ok with a [Slatepack](../grin_wallet_libwallet/slatepack/types/struct.Slatepack.html) if successful @@ -2143,18 +2146,25 @@ where /// # let slatepack_string = String::from(""); /// // .. receive a slatepack from somewhere /// let res = api_owner.decode_slatepack_message( + /// None, /// slatepack_string, - /// false, + /// vec![0, 1, 2], /// ); /// /// ``` pub fn decode_slatepack_message( &self, + keychain_mask: Option<&SecretKey>, slatepack: String, - decrypt: bool, + secret_indices: Vec, ) -> Result { - owner::decode_slatepack_message(slatepack, decrypt) + owner::decode_slatepack_message( + self.wallet_inst.clone(), + keychain_mask, + slatepack, + secret_indices, + ) } // PAYMENT PROOFS diff --git a/api/src/owner_rpc.rs b/api/src/owner_rpc.rs index 2ff1373f..dbcb3829 100644 --- a/api/src/owner_rpc.rs +++ b/api/src/owner_rpc.rs @@ -1577,8 +1577,9 @@ pub trait OwnerRpc { "jsonrpc": "2.0", "method": "decode_slatepack_message", "params": { - "message": "BEGINSLATEPACK. t9EcGgrKr1GFCQB SK2jPCxME6Hgpqx bntpQm3zKFycoPY nW4UeoL4KQ7ExNK At6EQsvpz6MjUs8 6WG8KHEbMfqufJQ ZJTw2gkcdJmJjiJ f29oGgYqqXDZox4 ujPSjrtoxCN4h3e i1sZ8dYsm3dPeXL 7VQLsYNjAefciqj ZJXPm4Pqd7VDdd4 okGBGBu3YJvYzT6 arAxeCEx66us31h AJLcDweFwyWBkW5 J1DLiYAjt5ftFTo CjpfW9KjiLq2LM5 jepXWEHJPSDAYVK 4macDZUhRbJiG6E hrQcPrJBVC716mb Hw5E1PFrE6on5wq oEmrS4j9vaB5nw8 Z9ZyXvPc2LN7tER yt6pSHZeY9EpYdY zv4bthzfRfF8ePT TMeMpV2gpgyRXQa CPD2TR. ENDSLATEPACK.\n", - "decrypt" : false + "token": "d202964900000000d302964900000000d402964900000000d502964900000000", + "secret_indices": [0], + "message": "BEGINSLATEPACK. t9EcGgrKr1GFCQB SK2jPCxME6Hgpqx bntpQm3zKFycoPY nW4UeoL4KQ7ExNK At6EQsvpz6MjUs8 6WG8KHEbMfqufJQ ZJTw2gkcdJmJjiJ f29oGgYqqXDZox4 ujPSjrtoxCN4h3e i1sZ8dYsm3dPeXL 7VQLsYNjAefciqj ZJXPm4Pqd7VDdd4 okGBGBu3YJvYzT6 arAxeCEx66us31h AJLcDweFwyWBkW5 J1DLiYAjt5ftFTo CjpfW9KjiLq2LM5 jepXWEHJPSDAYVK 4macDZUhRbJiG6E hrQcPrJBVC716mb Hw5E1PFrE6on5wq oEmrS4j9vaB5nw8 Z9ZyXvPc2LN7tER yt6pSHZeY9EpYdY zv4bthzfRfF8ePT TMeMpV2gpgyRXQa CPD2TR. ENDSLATEPACK.\n" }, "id": 1 } @@ -1604,8 +1605,9 @@ pub trait OwnerRpc { fn decode_slatepack_message( &self, + token: Token, message: String, - decrypt: bool, + secret_indices: Vec, ) -> Result; /** @@ -2077,10 +2079,17 @@ where fn decode_slatepack_message( &self, + token: Token, message: String, - decrypt: bool, + secret_indices: Vec, ) -> Result { - Owner::decode_slatepack_message(self, message, decrypt).map_err(|e| e.kind()) + Owner::decode_slatepack_message( + self, + (&token.keychain_mask).as_ref(), + message, + secret_indices, + ) + .map_err(|e| e.kind()) } fn retrieve_payment_proof( diff --git a/controller/src/command.rs b/controller/src/command.rs index ba6579a4..59299f0e 100644 --- a/controller/src/command.rs +++ b/controller/src/command.rs @@ -626,7 +626,8 @@ where |api, m| { slate = api.slate_from_slatepack_message(m, message.clone(), vec![0])?; - let slatepack = api.decode_slatepack_message(message, true)?; + let slatepack = + api.decode_slatepack_message(m, message.clone(), vec![0])?; ret_address = slatepack.sender; Ok(()) }, @@ -735,8 +736,8 @@ where None => match args.input_slatepack_message { Some(mes) => { let mut sp = Slatepack::default(); - controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, _| { - sp = api.decode_slatepack_message(mes, false)?; + controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { + sp = api.decode_slatepack_message(m, mes, vec![])?; Ok(()) })?; sp diff --git a/controller/tests/slatepack.rs b/controller/tests/slatepack.rs index bc7c8cc5..4dc06a50 100644 --- a/controller/tests/slatepack.rs +++ b/controller/tests/slatepack.rs @@ -496,7 +496,7 @@ fn slatepack_api_impl(test_dir: &'static str) -> Result<(), libwallet::Error> { let enc_addr = api.get_slatepack_address(m, 0)?; let slatepack = api.create_slatepack_message(m, &slate, Some(0), vec![enc_addr])?; println!("{}", slatepack); - let slatepack_raw = api.decode_slatepack_message(slatepack.clone(), true)?; + 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])?; println!("{}", decoded_slate); diff --git a/libwallet/src/api_impl/owner.rs b/libwallet/src/api_impl/owner.rs index aaa41f7a..b327c051 100644 --- a/libwallet/src/api_impl/owner.rs +++ b/libwallet/src/api_impl/owner.rs @@ -201,13 +201,49 @@ where } /// Decode a slatepack message, to allow viewing -pub fn decode_slatepack_message(slatepack: String, decrypt: bool) -> Result { +/// Will decrypt if possible, otherwise will return +/// undecrypted slatepack +pub fn decode_slatepack_message<'a, L, C, K>( + wallet_inst: Arc>>>, + keychain_mask: Option<&SecretKey>, + slatepack: String, + secret_indices: Vec, +) -> Result +where + L: WalletLCProvider<'a, C, K>, + C: NodeClient + 'a, + K: Keychain + 'a, +{ let packer = Slatepacker::new(SlatepackerArgs { sender: None, recipients: vec![], dec_key: None, }); - packer.deser_slatepack(slatepack.as_bytes().to_vec(), decrypt) + if secret_indices.is_empty() { + packer.deser_slatepack(slatepack.as_bytes().to_vec(), false) + } else { + for index in secret_indices { + let dec_key = Some(get_slatepack_secret_key( + wallet_inst.clone(), + keychain_mask, + index, + )?); + let packer = Slatepacker::new(SlatepackerArgs { + sender: None, + recipients: vec![], + dec_key: (&dec_key).as_ref(), + }); + let res = packer.deser_slatepack(slatepack.as_bytes().to_vec(), true); + let slatepack = match res { + Ok(sp) => sp, + Err(_) => { + continue; + } + }; + return Ok(slatepack); + } + packer.deser_slatepack(slatepack.as_bytes().to_vec(), false) + } } /// retrieve outputs