v0.5.2-pre.006-fix-004

This commit is contained in:
2026-08-11 00:30:03 +02:00
parent 066d969f5a
commit 1ee1d0297d
17 changed files with 698 additions and 41 deletions

View File

@@ -1,5 +1,5 @@
// file: ks-wallet/src/lib.rs
// version: 8
// version: 9
//! Wallet boundary for local key storage and transaction signing.
#![warn(missing_docs)]
@@ -24,6 +24,10 @@ pub use self::manager::WalletManager;
pub use self::password::WalletPassword;
/// Explicit secret import/export format supported by the wallet boundary.
pub use self::transfer::WalletTransferFormat;
/// Safe public identity extracted from one validated transfer file.
pub use self::transfer::WalletTransferInspection;
/// Validates one external transfer file and returns only its public identity.
pub use self::transfer::inspect_transfer_file;
/// Authenticated signing capability for one unlocked persistent wallet.
pub use self::unlocked::UnlockedWallet;
/// Solana keypair kept private inside the wallet boundary.

View File

@@ -1,5 +1,5 @@
// file: ks-wallet/src/transfer.rs
// version: 1
// version: 2
//! Explicit migration and secret import/export adapters.
@@ -23,6 +23,74 @@ pub enum WalletTransferFormat {
SolanaPrivateKeyBase58,
}
impl WalletTransferFormat {
/// Returns every transfer format currently supported for both import and export.
pub const fn supported() -> [Self; 2] {
return [Self::SolanaCliJson, Self::SolanaPrivateKeyBase58];
}
/// Returns the stable machine-readable code of this transfer format.
pub const fn code(self) -> &'static str {
return match self {
Self::SolanaCliJson => "solana_cli_json",
Self::SolanaPrivateKeyBase58 => "solana_private_key_base58",
};
}
/// Returns the human-readable label of this transfer format.
pub const fn label(self) -> &'static str {
return match self {
Self::SolanaCliJson => "Solana CLI keypair JSON (64 bytes)",
Self::SolanaPrivateKeyBase58 => "Solana private key Base58 (64 bytes)",
};
}
/// Returns the conventional file extension used by this transfer format.
pub const fn default_extension(self) -> &'static str {
return match self {
Self::SolanaCliJson => "json",
Self::SolanaPrivateKeyBase58 => "txt",
};
}
}
/// Safe result of validating one external secret-transfer file.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct WalletTransferInspection {
public_key: std::string::String,
format: WalletTransferFormat,
}
impl WalletTransferInspection {
/// Returns the public key derived from the validated external keypair.
pub fn public_key(&self) -> &str {
return self.public_key.as_str();
}
/// Returns the transfer format used to validate the external keypair.
pub fn format(&self) -> WalletTransferFormat {
return self.format;
}
}
/// Validates one external transfer file and returns only its public identity.
///
/// The secret bytes never leave `ks-wallet`; callers receive only the derived
/// Solana public key and the format that was explicitly selected for validation.
pub async fn inspect_transfer_file(
source_path: impl std::convert::AsRef<std::path::Path>,
format: WalletTransferFormat,
) -> ks_core::Result<WalletTransferInspection> {
let keypair = match read_transfer_keypair(source_path.as_ref(), format).await {
std::result::Result::Ok(keypair) => keypair,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return std::result::Result::Ok(WalletTransferInspection {
public_key: keypair.pubkey().to_string(),
format,
});
}
impl crate::WalletManager {
/// Imports one secret file into a new password-protected native wallet.
///
@@ -136,7 +204,7 @@ impl crate::WalletManager {
action = "export_wallet_secret",
wallet_alias = alias.as_str(),
public_key = public_key.as_str(),
transfer_format = transfer_format_code(format),
transfer_format = format.code(),
"exported wallet secret after password authentication"
);
return std::result::Result::Ok(());
@@ -189,7 +257,7 @@ async fn persist_imported_keypair(
action = "import_wallet_secret",
wallet_alias = alias.as_str(),
public_key = %public_key,
transfer_format = transfer_format_code(format),
transfer_format = format.code(),
"imported wallet secret into native protected storage"
);
return std::result::Result::Ok(crate::UnlockedWallet::new(alias, keypair));
@@ -656,10 +724,3 @@ fn native_path(manager: &crate::WalletManager, alias: &crate::WalletAlias) -> st
crate::KSWALLET_FILE_EXTENSION
));
}
fn transfer_format_code(format: crate::WalletTransferFormat) -> &'static str {
return match format {
crate::WalletTransferFormat::SolanaCliJson => "solana_cli_json",
crate::WalletTransferFormat::SolanaPrivateKeyBase58 => "solana_private_key_base58",
};
}