diff --git a/CHANGELOG.md b/CHANGELOG.md index c888c20734..9c71c62c4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- [FIX][cli] `notes --send` now rejects a recipient address whose network doesn't match the client's configured network, instead of silently sending to it. ([#2525](https://github.com/0xMiden/rust-sdk/pull/2525)). + ### Breaking Changes * [BREAKING][behavior][rust] Notes fetched from the Note Transport Layer are screened when their tag matches a tracked account's tag, discarding the ones no tracked account can consume ([#2474](https://github.com/0xMiden/rust-sdk/pull/2474)). diff --git a/bin/miden-cli/src/commands/notes.rs b/bin/miden-cli/src/commands/notes.rs index d70aac0357..44c776eeb7 100644 --- a/bin/miden-cli/src/commands/notes.rs +++ b/bin/miden-cli/src/commands/notes.rs @@ -353,7 +353,14 @@ async fn send( let note: Note = note_record .try_into() .map_err(|e| CliError::from(ClientError::NoteRecordConversionError(e)))?; - let (_netid, address) = Address::decode(address).map_err(|e| CliError::Input(e.to_string()))?; + let (address_network_id, address) = + Address::decode(address).map_err(|e| CliError::Input(e.to_string()))?; + let client_network_id = client.network_id().await?; + if address_network_id != client_network_id { + return Err(CliError::Input(format!( + "Address network `{address_network_id}` does not match configured network `{client_network_id}`", + ))); + } match block_hint { Some(block_hint) => { @@ -529,6 +536,7 @@ fn note_summary( mod tests { use miden_client::Word; use miden_client::account::AccountId; + use miden_client::address::{Address, NetworkId}; use miden_client::note::{ Note, NoteAssets, @@ -568,4 +576,20 @@ mod tests { assert_eq!(summary.sender, sender.to_string()); assert_eq!(summary.tag, tag.to_string()); } + + /// `notes --send` must reject an address whose network doesn't match the client's configured + /// network. This checks the underlying decode step that the fix relies on: encoding an address + /// for one network and decoding it must not report a match against a different network. + #[test] + fn decoded_address_network_differs_across_networks() { + let account_id = + AccountId::try_from(ACCOUNT_ID_REGULAR_PRIVATE_ACCOUNT_UPDATABLE_CODE).unwrap(); + let address = Address::new(account_id); + + let encoded_for_testnet = address.encode(NetworkId::Testnet); + let (decoded_network_id, _decoded_address) = Address::decode(&encoded_for_testnet).unwrap(); + + assert_eq!(decoded_network_id, NetworkId::Testnet); + assert_ne!(decoded_network_id, NetworkId::Mainnet); + } }