feat(zcash): pass firmware version in ZcashAccounts pairing QR
What changed, and why it matters
This commit adds the device's firmware version number to the QR code that a Keystone hardware wallet shows when pairing with Zcash wallet software. The change is informational only and matches what the wallet already does for other cryptocurrencies like MetaMask and OKX. There is no indication it fixes a security bug or introduces a security weakness.
No security action required. Treat as a normal feature commit. If reviewing the dependency update (ur-registry crate), verify that device_version is serialized safely and that the new field does not alter existing ZcashAccounts parsing incompatibly.
Security signals we found
No memory-safety issues visible in diff (null check on C string, optional Rust handling)
No input validation bypass or cryptographic change
No vendor disclosure of security relevance
Feature parity change matching existing MultiAccounts.deviceVersion behavior
Evidence from the diff
The patch threads GetSoftWareVersionNumber() through the Zcash connect-wallet flow so the generated ZcashAccounts uniform-resource (UR) includes a device_version field. It updates generate_sync_ur() in rust/apps/wallets/src/zcash.rs to accept an optional device_version string, exposes a new device_version parameter in the unsafe extern C binding get_connect_zcash_wallet_ur, and passes the firmware version from the C UI layer in GuiGetZecData(). The change depends on an updated ur-registry crate that adds device_version to ZcashAccounts.
Changed components
rust/apps/wallets/src/zcash.rsrust/rust_c/src/wallet/cypherpunk_wallet/zcash.rssrc/ui/gui_widgets/multi/cypherpunk/gui_connect_wallet_widgets.cZcashAccounts UR generation flowInspect captured patch +18 / −5
diff --git a/rust/apps/wallets/src/zcash.rs b/rust/apps/wallets/src/zcash.rs
index 4bdcdad..5663012 100644
--- a/rust/apps/wallets/src/zcash.rs
+++ b/rust/apps/wallets/src/zcash.rs
@@ -1,4 +1,4 @@
-use alloc::string::String;
+use alloc::string::{String, ToString};
use alloc::vec::Vec;
@@ -19,6 +19,7 @@ impl_public_struct!(UFVKInfo {
pub fn generate_sync_ur(
key_infos: Vec<UFVKInfo>,
seed_fingerprint: [u8; 32],
+ device_version: Option<&str>,
) -> URResult<ZcashAccounts> {
let keys = key_infos
.iter()
@@ -30,7 +31,10 @@ pub fn generate_sync_ur(
))
})
.collect::<URResult<Vec<ZcashUnifiedFullViewingKey>>>()?;
- let accounts = ZcashAccounts::new(seed_fingerprint.to_vec(), keys);
+ let mut accounts = ZcashAccounts::new(seed_fingerprint.to_vec(), keys);
+ if let Some(version) = device_version {
+ accounts.set_device_version(version.to_string());
+ }
Ok(accounts)
}
@@ -56,7 +60,7 @@ mod tests {
},
];
- let result = generate_sync_ur(key_infos, seed_fingerprint);
+ let result = generate_sync_ur(key_infos, seed_fingerprint, Some("1.2.3"));
assert!(result.is_ok());
let accounts = result.unwrap();
diff --git a/rust/rust_c/src/wallet/cypherpunk_wallet/zcash.rs b/rust/rust_c/src/wallet/cypherpunk_wallet/zcash.rs
index 32752b6..22d94ce 100644
--- a/rust/rust_c/src/wallet/cypherpunk_wallet/zcash.rs
+++ b/rust/rust_c/src/wallet/cypherpunk_wallet/zcash.rs
@@ -18,6 +18,7 @@ pub unsafe extern "C" fn get_connect_zcash_wallet_ur(
seed_fingerprint: PtrBytes,
seed_fingerprint_len: u32,
zcash_keys: Ptr<CSliceFFI<ZcashKey>>,
+ device_version: PtrString,
) -> *mut UREncodeResult {
if seed_fingerprint_len != 32 {
return UREncodeResult::from(URError::UrEncodeError(format!(
@@ -41,7 +42,12 @@ pub unsafe extern "C" fn get_connect_zcash_wallet_ur(
)
})
.collect();
- let result = generate_sync_ur(ufvks, seed_fingerprint);
+ let version = if device_version.is_null() {
+ None
+ } else {
+ Some(recover_c_char(device_version))
+ };
+ let result = generate_sync_ur(ufvks, seed_fingerprint, version.as_deref());
match result.map(|v| v.try_into()) {
Ok(v) => match v {
Ok(data) => UREncodeResult::encode(
diff --git a/src/ui/gui_widgets/multi/cypherpunk/gui_connect_wallet_widgets.c b/src/ui/gui_widgets/multi/cypherpunk/gui_connect_wallet_widgets.c
index 7e36138..5d9748f 100644
--- a/src/ui/gui_widgets/multi/cypherpunk/gui_connect_wallet_widgets.c
+++ b/src/ui/gui_widgets/multi/cypherpunk/gui_connect_wallet_widgets.c
@@ -1,5 +1,6 @@
#include "gui_connect_wallet_widgets.h"
#include "account_public_info.h"
+#include "version.h"
#include "gui.h"
#include "gui_button.h"
#include "gui_hintbox.h"
@@ -365,7 +366,9 @@ UREncodeResult *GuiGetZecData(void)
data[0].key_text = ufvk;
data[0].key_name = GetWalletName();
data[0].index = 0;
- return get_connect_zcash_wallet_ur(sfp, 32, keys);
+ char firmwareVersion[32];
+ GetSoftWareVersionNumber(firmwareVersion);
+ return get_connect_zcash_wallet_ur(sfp, 32, keys, firmwareVersion);
}
void GuiPrepareArConnectWalletView(void)
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.