v0.2.6-pre.016-fix.002

This commit is contained in:
2026-08-22 08:37:56 +02:00
parent 738b340cc7
commit 5c0be421da
10 changed files with 206 additions and 159 deletions

View File

@@ -914,23 +914,23 @@ impl AppState {
std::result::Result::Err(_) => return std::result::Result::Err(session_lock_error()),
};
let previous = std::mem::replace(&mut *session, crate::WalletSession::no_selection());
match previous {
return match previous {
crate::WalletSession::ViewOperation { wallet_id: reserved_wallet_id, path: reserved_path, pubkey: reserved_pubkey }
if reserved_wallet_id == wallet_id && reserved_path == path && reserved_pubkey == pubkey =>
{
*session = crate::WalletSession::View { wallet_id: wallet_id.clone(), path, wallet: view };
ksp_logging_lib::info!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WALLET_SESSION, wallet_id = wallet_id.as_str(), operation, "Wallet VIEW privileged operation completed");
return std::result::Result::Ok(dto);
std::result::Result::Ok(dto)
},
other => {
*session = other;
drop(view);
return std::result::Result::Err(ksp_core_lib::Error::new(
std::result::Result::Err(ksp_core_lib::Error::new(
crate::ERROR_CODE_WALLET_SESSION_INVALID,
"Wallet VIEW operation completion no longer owns the selected session",
));
))
},
}
};
}
fn restore_view_after_operation_failure(&self, context: ViewOperationContext) {
@@ -1039,7 +1039,7 @@ impl AppState {
std::result::Result::Err(_) => return std::result::Result::Err(session_lock_error()),
};
let previous = std::mem::replace(&mut *session, crate::WalletSession::no_selection());
match previous {
return match previous {
crate::WalletSession::OwnerOperation {
wallet_id: reserved_wallet_id,
path: reserved_path,
@@ -1048,17 +1048,17 @@ impl AppState {
} if reserved_wallet_id == wallet_id && reserved_path == path && reserved_pubkey == pubkey && reserved_view_enabled == view_enabled => {
*session = crate::WalletSession::Owner { wallet_id: wallet_id.clone(), path, view_enabled: result_view_enabled, wallet: owner };
ksp_logging_lib::info!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WALLET_SESSION, wallet_id = wallet_id.as_str(), operation, "Wallet OWNER privileged operation completed");
return std::result::Result::Ok(dto);
std::result::Result::Ok(dto)
},
other => {
*session = other;
drop(owner);
return std::result::Result::Err(ksp_core_lib::Error::new(
std::result::Result::Err(ksp_core_lib::Error::new(
crate::ERROR_CODE_WALLET_SESSION_INVALID,
"Wallet OWNER operation completion no longer owns the selected session",
));
))
},
}
};
}
fn restore_owner_after_operation_failure(&self, context: OwnerOperationContext) {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-wallet-desk/tests/desktop_contract.rs
// version: 17
// version: 18
//! Desktop build, shell and Config-status contract audits for Wallet Desk.
@@ -16,6 +16,11 @@ fn read_text(path: &std::path::Path) -> String {
};
}
fn read_source(relative_path: &str) -> String {
let root = app_root();
return read_text(root.join(relative_path).as_path());
}
fn read_json(path: &std::path::Path) -> serde_json::Value {
let source = read_text(path);
let parsed = serde_json::from_str::<serde_json::Value>(source.as_str());

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-wallet-lib/src/runtime.rs
// version: 1
// version: 2
//! Version-neutral unlocked Wallet state dispatch used by stable OWNER/VIEW handles.
@@ -16,14 +16,6 @@ pub(crate) enum OwnerState {
}
impl OwnerState {
/// Returns the native format version owned by this OWNER state.
pub(crate) const fn format_version(&self) -> u32 {
return match self {
Self::V1(_) => crate::KSPWALLET_FORMAT_VERSION_V1,
Self::V2(_) => crate::KSPWALLET_FORMAT_VERSION_V2,
};
}
/// Exports the Solana identity through the requested external transfer format.
pub(crate) fn export_transfer(&self, format: crate::WalletTransferFormat) -> ksp_core_lib::Result<std::vec::Vec<u8>> {
return match self {
@@ -43,8 +35,8 @@ impl OwnerState {
/// Stages an authenticated metadata replacement without publishing it.
pub(crate) fn stage_metadata_payload(&self, payload: crate::MetadataPayloadV1) -> ksp_core_lib::Result<(StagedEnvelope, crate::WalletInfo)> {
return match self {
Self::V1(state) => state.stage_metadata_payload(payload).map(|(envelope, info)| (StagedEnvelope::V1(envelope), info)),
Self::V2(state) => state.stage_metadata_payload(payload).map(|(envelope, info)| (StagedEnvelope::V2(envelope), info)),
Self::V1(state) => state.stage_metadata_payload(payload).map(|(envelope, info)| return (StagedEnvelope::V1(envelope), info)),
Self::V2(state) => state.stage_metadata_payload(payload).map(|(envelope, info)| return (StagedEnvelope::V2(envelope), info)),
};
}
@@ -67,16 +59,16 @@ impl OwnerState {
/// Stages strong VIEW disable while retaining OWNER authority.
pub(crate) fn stage_disable_view(&self) -> ksp_core_lib::Result<(StagedEnvelope, crate::SecretKeyV1)> {
return match self {
Self::V1(state) => state.stage_disable_view().map(|(envelope, key)| (StagedEnvelope::V1(envelope), key)),
Self::V2(state) => state.stage_disable_view().map(|(envelope, key)| (StagedEnvelope::V2(envelope), key)),
Self::V1(state) => state.stage_disable_view().map(|(envelope, key)| return (StagedEnvelope::V1(envelope), key)),
Self::V2(state) => state.stage_disable_view().map(|(envelope, key)| return (StagedEnvelope::V2(envelope), key)),
};
}
/// Stages strong VIEW recreation under a new credential.
pub(crate) async fn stage_recreate_view(&self, password: crate::ViewPassword) -> ksp_core_lib::Result<(StagedEnvelope, crate::SecretKeyV1)> {
return match self {
Self::V1(state) => state.stage_recreate_view(password).await.map(|(envelope, key)| (StagedEnvelope::V1(envelope), key)),
Self::V2(state) => state.stage_recreate_view(password).await.map(|(envelope, key)| (StagedEnvelope::V2(envelope), key)),
Self::V1(state) => state.stage_recreate_view(password).await.map(|(envelope, key)| return (StagedEnvelope::V1(envelope), key)),
Self::V2(state) => state.stage_recreate_view(password).await.map(|(envelope, key)| return (StagedEnvelope::V2(envelope), key)),
};
}
@@ -155,14 +147,6 @@ pub(crate) enum ViewState {
}
impl ViewState {
/// Returns the native format version owned by this VIEW state.
pub(crate) const fn format_version(&self) -> u32 {
return match self {
Self::V1(_) => crate::KSPWALLET_FORMAT_VERSION_V1,
Self::V2(_) => crate::KSPWALLET_FORMAT_VERSION_V2,
};
}
/// Stages a VIEW credential rotation in the state native format.
pub(crate) async fn stage_view_password_rotation(&self, password: crate::ViewPassword) -> ksp_core_lib::Result<StagedEnvelope> {
return match self {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-wallet-lib/unit_tests/format.rs
// version: 1
// version: 2
#[test]
fn default_and_latest_are_explicit_and_currently_v2() {
@@ -12,7 +12,15 @@ fn default_and_latest_are_explicit_and_currently_v2() {
fn detector_distinguishes_v1_json_and_v2_binary_without_crypto() -> ksp_core_lib::Result<()> {
let v1 = include_bytes!("../tests/fixtures/kspwallet_v1_wire_only.json");
let v2 = include_bytes!("../tests/fixtures/kspwallet_v2_wire_only.bin");
assert_eq!(crate::detect_wallet_format(v1)?, crate::WalletFormat::V1);
assert_eq!(crate::detect_wallet_format(v2)?, crate::WalletFormat::V2);
let detected_v1 = match crate::detect_wallet_format(v1) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let detected_v2 = match crate::detect_wallet_format(v2) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(detected_v1, crate::WalletFormat::V1);
assert_eq!(detected_v2, crate::WalletFormat::V2);
return std::result::Result::Ok(());
}