331 lines
11 KiB
Rust
Raw Normal View History

use std::{io::Write as _, path::PathBuf, str::FromStr};
2025-12-09 15:18:48 -03:00
2026-03-04 18:42:33 +03:00
use anyhow::{Context as _, Result};
fix(wallet): use cryptographically secure entropy for mnemonic generation The mnemonic/wallet generation was using a constant zero-byte array for entropy ([0u8; 32]), making all wallets deterministic based solely on the password. This commit introduces proper random entropy using OsRng and enables users to back up their recovery phrase. Changes: - SeedHolder::new_mnemonic() now uses OsRng for 256-bit random entropy and returns the generated mnemonic - Added SeedHolder::from_mnemonic() to recover a wallet from an existing mnemonic phrase - WalletChainStore::new_storage() returns the mnemonic for user backup - Added WalletChainStore::restore_storage() for recovery from a mnemonic - WalletCore::new_init_storage() now returns the mnemonic - Renamed reset_storage to restore_storage, which accepts a mnemonic for recovery - CLI displays the recovery phrase when a new wallet is created - RestoreKeys command now prompts for the mnemonic phrase via read_mnemonic_from_stdin() Note: The password parameter is retained for future storage encryption but is no longer used in seed derivation (empty passphrase is used instead). This means the mnemonic alone is sufficient to recover accounts. Usage: On first wallet initialization, users will see: IMPORTANT: Write down your recovery phrase and store it securely. This is the only way to recover your wallet if you lose access. Recovery phrase: word1 word2 word3 ... word24 To restore keys: wallet restore-keys --depth 5 Input recovery phrase: <24 words> Input password: <password>
2026-01-20 16:47:34 +01:00
use bip39::Mnemonic;
use clap::{Parser, Subcommand};
use common::{HashType, transaction::LeeTransaction};
use derive_more::Display;
2026-03-13 22:56:14 +03:00
use futures::TryFutureExt as _;
use lee::{ProgramDeploymentTransaction, program::Program};
use sequencer_service_rpc::RpcClient as _;
2025-10-13 17:25:36 +03:00
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
pub use crate::helperfunctions::{read_mnemonic, read_pin};
use crate::{
WalletCore,
account::{AccountIdWithPrivacy, Label},
cli::{
account::AccountSubcommand,
chain::ChainSubcommand,
config::ConfigSubcommand,
group::GroupSubcommand,
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
keycard::KeycardSubcommand,
programs::{
amm::AmmProgramAgnosticSubcommand, ata::AtaSubcommand,
native_token_transfer::AuthTransferSubcommand, pinata::PinataProgramAgnosticSubcommand,
token::TokenProgramAgnosticSubcommand,
},
},
storage::Storage,
};
2025-10-13 17:25:36 +03:00
2025-10-20 10:01:54 +03:00
pub mod account;
2025-10-14 15:29:18 +03:00
pub mod chain;
2025-11-03 15:45:50 +02:00
pub mod config;
pub mod group;
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
pub mod keycard;
pub mod programs;
2025-10-13 17:25:36 +03:00
pub(crate) trait WalletSubcommand {
async fn handle_subcommand(self, wallet_core: &mut WalletCore)
-> Result<SubcommandReturnValue>;
}
2026-03-10 00:17:43 +03:00
/// Represents CLI command for a wallet.
#[derive(Subcommand, Debug, Clone)]
#[clap(about)]
pub enum Command {
2026-03-10 00:17:43 +03:00
/// Authenticated transfer subcommand.
#[command(subcommand)]
AuthTransfer(AuthTransferSubcommand),
2026-03-10 00:17:43 +03:00
/// Generic chain info subcommand.
#[command(subcommand)]
ChainInfo(ChainSubcommand),
2026-03-10 00:17:43 +03:00
/// Account view and sync subcommand.
#[command(subcommand)]
Account(AccountSubcommand),
2026-03-10 00:17:43 +03:00
/// Pinata program interaction subcommand.
#[command(subcommand)]
Pinata(PinataProgramAgnosticSubcommand),
2026-03-10 00:17:43 +03:00
/// Token program interaction subcommand.
#[command(subcommand)]
Token(TokenProgramAgnosticSubcommand),
2026-03-10 00:17:43 +03:00
/// AMM program interaction subcommand.
2025-12-16 14:05:34 +02:00
#[command(subcommand)]
AMM(AmmProgramAgnosticSubcommand),
/// Associated Token Account program interaction subcommand.
#[command(subcommand)]
Ata(AtaSubcommand),
/// Group key management (create, invite, join, derive keys).
#[command(subcommand)]
Group(GroupSubcommand),
/// Check the wallet can connect to the node and builtin local programs
2026-03-10 00:17:43 +03:00
/// match the remote versions.
2026-03-04 18:42:33 +03:00
CheckHealth,
2026-03-10 00:17:43 +03:00
/// Command to setup config, get and set config fields.
#[command(subcommand)]
Config(ConfigSubcommand),
2026-03-10 00:17:43 +03:00
/// Restoring keys from given password at given `depth`.
2025-12-03 13:10:07 +02:00
///
2026-03-10 00:17:43 +03:00
/// !!!WARNING!!! will rewrite current storage.
RestoreKeys {
#[arg(short, long)]
2025-12-03 13:10:07 +02:00
/// Indicates, how deep in tree accounts may be. Affects command complexity.
depth: u32,
},
2026-03-10 00:17:43 +03:00
/// Deploy a program.
DeployProgram { binary_filepath: PathBuf },
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
/// Keycard hardware wallet management.
#[command(subcommand)]
Keycard(KeycardSubcommand),
}
/// To execute commands, env var `LEE_WALLET_HOME_DIR` must be set into directory with config.
///
2025-12-08 18:26:35 +03:00
/// All account addresses must be valid 32 byte base58 strings.
///
2026-03-03 23:21:08 +03:00
/// All account `account_ids` must be provided as {`privacy_prefix}/{account_id`},
2026-03-10 00:17:43 +03:00
/// where valid options for `privacy_prefix` is `Public` and `Private`.
#[derive(Parser, Debug)]
#[clap(version, about)]
pub struct Args {
2026-03-10 00:17:43 +03:00
/// Continious run flag.
#[arg(short, long)]
pub continuous_run: bool,
2026-03-10 00:17:43 +03:00
/// Basic authentication in the format `user` or `user:password`.
2025-12-08 18:26:35 +03:00
#[arg(long)]
pub auth: Option<String>,
2026-03-10 00:17:43 +03:00
/// Wallet command.
#[command(subcommand)]
2025-12-03 13:10:07 +02:00
pub command: Option<Command>,
}
#[derive(Debug, Clone)]
pub enum SubcommandReturnValue {
PrivacyPreservingTransfer { tx_hash: HashType },
RegisterAccount { account_id: lee::AccountId },
Account(lee::Account),
Empty,
SyncedToBlock(u64),
}
#[derive(Debug, Display, Clone, PartialEq, Eq, Hash)]
pub enum CliAccountMention {
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
#[display("{_0}")]
Id(AccountIdWithPrivacy),
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
#[display("{_0}")]
Label(Label),
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
#[display("{_0}")]
KeyPath(String),
}
impl CliAccountMention {
pub fn resolve(&self, storage: &Storage) -> Result<AccountIdWithPrivacy> {
match self {
Self::Id(account_id) => Ok(*account_id),
Self::Label(label) => storage
.resolve_label(label)
.ok_or_else(|| anyhow::anyhow!("No account found for label `{label}`")),
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
Self::KeyPath(path) => {
let pin = read_pin()?;
let id_str =
keycard_wallet::KeycardWallet::get_account_id_for_path_with_connect(&pin, path)
.map_err(anyhow::Error::from)?;
AccountIdWithPrivacy::from_str(&id_str)
.map_err(|e| anyhow::anyhow!("Invalid account id from keycard: {e}"))
}
}
}
}
impl FromStr for CliAccountMention {
type Err = std::convert::Infallible;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
if s.starts_with("m/") {
return Ok(Self::KeyPath(s.to_owned()));
}
AccountIdWithPrivacy::from_str(s).map_or_else(
|_| Ok(Self::Label(Label::new(s.to_owned()))),
|account_id| Ok(Self::Id(account_id)),
)
}
}
impl From<Label> for CliAccountMention {
fn from(label: Label) -> Self {
Self::Label(label)
}
}
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
impl Default for CliAccountMention {
fn default() -> Self {
Self::Label(Label::new(String::new()))
}
}
pub async fn execute_subcommand(
wallet_core: &mut WalletCore,
2025-12-08 18:26:35 +03:00
command: Command,
) -> Result<SubcommandReturnValue> {
let subcommand_ret = match command {
Command::AuthTransfer(transfer_subcommand) => {
transfer_subcommand.handle_subcommand(wallet_core).await?
}
Command::ChainInfo(chain_subcommand) => {
chain_subcommand.handle_subcommand(wallet_core).await?
}
Command::Account(account_subcommand) => {
account_subcommand.handle_subcommand(wallet_core).await?
}
Command::Pinata(pinata_subcommand) => {
pinata_subcommand.handle_subcommand(wallet_core).await?
}
2026-03-04 18:42:33 +03:00
Command::CheckHealth => {
let remote_program_ids = wallet_core
.sequencer_client
.get_program_ids()
.await
.expect("Error fetching program ids");
let Some(authenticated_transfer_id) = remote_program_ids.get("authenticated_transfer")
else {
panic!("Missing authenticated transfer ID from remote");
};
2026-03-03 23:21:08 +03:00
assert!(
authenticated_transfer_id == &Program::authenticated_transfer_program().id(),
"Local ID for authenticated transfer program is different from remote"
);
let Some(token_id) = remote_program_ids.get("token") else {
panic!("Missing token program ID from remote");
};
2026-03-03 23:21:08 +03:00
assert!(
token_id == &Program::token().id(),
"Local ID for token program is different from remote"
);
let Some(circuit_id) = remote_program_ids.get("privacy_preserving_circuit") else {
panic!("Missing privacy preserving circuit ID from remote");
};
2026-03-03 23:21:08 +03:00
assert!(
circuit_id == &lee::PRIVACY_PRESERVING_CIRCUIT_ID,
2026-03-03 23:21:08 +03:00
"Local ID for privacy preserving circuit is different from remote"
);
let Some(amm_id) = remote_program_ids.get("amm") else {
panic!("Missing AMM program ID from remote");
};
2026-03-03 23:21:08 +03:00
assert!(
amm_id == &Program::amm().id(),
"Local ID for AMM program is different from remote"
);
2026-03-04 18:42:33 +03:00
println!("\u{2705}All looks good!");
SubcommandReturnValue::Empty
}
Command::Token(token_subcommand) => token_subcommand.handle_subcommand(wallet_core).await?,
Command::AMM(amm_subcommand) => amm_subcommand.handle_subcommand(wallet_core).await?,
Command::Ata(ata_subcommand) => ata_subcommand.handle_subcommand(wallet_core).await?,
Command::Group(group_subcommand) => group_subcommand.handle_subcommand(wallet_core).await?,
feat(wallet): add keycard support for public tx for auth-transfer (#451) * feat: add basic commands for communicating with keycard * initialize changes * reorganization * add script file for easier wallet access * update commands * fixes * fixed load for non continuous run * Updates for signatures with keycard * fix BIP-340 signatures for fixed sized messages * fmt * refactor and add pin support to program facades * fix unit test * fixes * Revert "fixes" This reverts commit 41f34f4ff4145b7abb60fd9bec168ae4b60f23b4. * fixes * fixes * Removed privacy keycard calls * Revert "Removed privacy keycard calls" This reverts commit d70ef505a1f40b87159099761f5fce5a31e3f17b. * Add domain separators * Removed privacy txs for keycard * CI fixes * CI fixes * addressed some comments * fix ci * ci fixes * fix integration test issue and updated keycard firmware * addressed more comments * fixed deny * remove keycard-py * fixed from earlier merge * add hash_message tests * add test * fix deny * CI fixes * fixed integration tests * Update public.rs * update artifacts * ci and comments * addressed comments * comment fixes * fixes from merging main * first round of comments * Revert "Merge branch 'main' into marvin/keycard-commands" This reverts commit 3fce53f663a3996938dddf77680854570063ca21, reversing changes made to e7b42a5177641455a8917bd2e29db20afd9690e5. * python comments * addressed comments * compile error fixed * fix artifacts * fix main merge error * adjust signer logic workflow * fmt * merge main and shift keycard tests * deny fix * artifacts fix * remove keycard scripts from root * tps fix * fmt
2026-05-21 20:46:13 -04:00
Command::Keycard(keycard_subcommand) => {
keycard_subcommand.handle_subcommand(wallet_core).await?
}
Command::Config(config_subcommand) => {
config_subcommand.handle_subcommand(wallet_core).await?
}
2025-12-03 13:10:07 +02:00
Command::RestoreKeys { depth } => {
fix(wallet): use cryptographically secure entropy for mnemonic generation The mnemonic/wallet generation was using a constant zero-byte array for entropy ([0u8; 32]), making all wallets deterministic based solely on the password. This commit introduces proper random entropy using OsRng and enables users to back up their recovery phrase. Changes: - SeedHolder::new_mnemonic() now uses OsRng for 256-bit random entropy and returns the generated mnemonic - Added SeedHolder::from_mnemonic() to recover a wallet from an existing mnemonic phrase - WalletChainStore::new_storage() returns the mnemonic for user backup - Added WalletChainStore::restore_storage() for recovery from a mnemonic - WalletCore::new_init_storage() now returns the mnemonic - Renamed reset_storage to restore_storage, which accepts a mnemonic for recovery - CLI displays the recovery phrase when a new wallet is created - RestoreKeys command now prompts for the mnemonic phrase via read_mnemonic_from_stdin() Note: The password parameter is retained for future storage encryption but is no longer used in seed derivation (empty passphrase is used instead). This means the mnemonic alone is sufficient to recover accounts. Usage: On first wallet initialization, users will see: IMPORTANT: Write down your recovery phrase and store it securely. This is the only way to recover your wallet if you lose access. Recovery phrase: word1 word2 word3 ... word24 To restore keys: wallet restore-keys --depth 5 Input recovery phrase: <24 words> Input password: <password>
2026-01-20 16:47:34 +01:00
let mnemonic = read_mnemonic_from_stdin()?;
2025-12-03 13:10:07 +02:00
let password = read_password_from_stdin()?;
fix(wallet): use cryptographically secure entropy for mnemonic generation The mnemonic/wallet generation was using a constant zero-byte array for entropy ([0u8; 32]), making all wallets deterministic based solely on the password. This commit introduces proper random entropy using OsRng and enables users to back up their recovery phrase. Changes: - SeedHolder::new_mnemonic() now uses OsRng for 256-bit random entropy and returns the generated mnemonic - Added SeedHolder::from_mnemonic() to recover a wallet from an existing mnemonic phrase - WalletChainStore::new_storage() returns the mnemonic for user backup - Added WalletChainStore::restore_storage() for recovery from a mnemonic - WalletCore::new_init_storage() now returns the mnemonic - Renamed reset_storage to restore_storage, which accepts a mnemonic for recovery - CLI displays the recovery phrase when a new wallet is created - RestoreKeys command now prompts for the mnemonic phrase via read_mnemonic_from_stdin() Note: The password parameter is retained for future storage encryption but is no longer used in seed derivation (empty passphrase is used instead). This means the mnemonic alone is sufficient to recover accounts. Usage: On first wallet initialization, users will see: IMPORTANT: Write down your recovery phrase and store it securely. This is the only way to recover your wallet if you lose access. Recovery phrase: word1 word2 word3 ... word24 To restore keys: wallet restore-keys --depth 5 Input recovery phrase: <24 words> Input password: <password>
2026-01-20 16:47:34 +01:00
wallet_core.restore_storage(&mnemonic, &password)?;
execute_keys_restoration(wallet_core, depth).await?;
2025-12-03 13:10:07 +02:00
SubcommandReturnValue::Empty
}
2025-12-05 17:54:51 -03:00
Command::DeployProgram { binary_filepath } => {
let bytecode: Vec<u8> = std::fs::read(&binary_filepath).context(format!(
"Failed to read program binary at {}",
binary_filepath.display()
))?;
let message = lee::program_deployment_transaction::Message::new(bytecode);
2025-12-05 17:54:51 -03:00
let transaction = ProgramDeploymentTransaction::new(message);
let _response = wallet_core
2025-12-05 17:54:51 -03:00
.sequencer_client
.send_transaction(LeeTransaction::ProgramDeployment(transaction))
2025-12-05 17:54:51 -03:00
.await
2026-02-24 19:41:01 +03:00
.context("Transaction submission error")?;
2025-12-05 17:54:51 -03:00
SubcommandReturnValue::Empty
}
};
Ok(subcommand_ret)
}
pub async fn execute_continuous_run(wallet_core: &mut WalletCore) -> Result<()> {
loop {
wallet_core.sync_to_latest_block().await?;
tokio::time::sleep(wallet_core.config().seq_poll_timeout).await;
}
}
2025-12-03 13:10:07 +02:00
pub fn read_password_from_stdin() -> Result<String> {
let mut password = String::new();
print!("Input password: ");
std::io::stdout().flush()?;
std::io::stdin().read_line(&mut password)?;
2026-03-04 18:42:33 +03:00
Ok(password.trim().to_owned())
2025-12-03 13:10:07 +02:00
}
fix(wallet): use cryptographically secure entropy for mnemonic generation The mnemonic/wallet generation was using a constant zero-byte array for entropy ([0u8; 32]), making all wallets deterministic based solely on the password. This commit introduces proper random entropy using OsRng and enables users to back up their recovery phrase. Changes: - SeedHolder::new_mnemonic() now uses OsRng for 256-bit random entropy and returns the generated mnemonic - Added SeedHolder::from_mnemonic() to recover a wallet from an existing mnemonic phrase - WalletChainStore::new_storage() returns the mnemonic for user backup - Added WalletChainStore::restore_storage() for recovery from a mnemonic - WalletCore::new_init_storage() now returns the mnemonic - Renamed reset_storage to restore_storage, which accepts a mnemonic for recovery - CLI displays the recovery phrase when a new wallet is created - RestoreKeys command now prompts for the mnemonic phrase via read_mnemonic_from_stdin() Note: The password parameter is retained for future storage encryption but is no longer used in seed derivation (empty passphrase is used instead). This means the mnemonic alone is sufficient to recover accounts. Usage: On first wallet initialization, users will see: IMPORTANT: Write down your recovery phrase and store it securely. This is the only way to recover your wallet if you lose access. Recovery phrase: word1 word2 word3 ... word24 To restore keys: wallet restore-keys --depth 5 Input recovery phrase: <24 words> Input password: <password>
2026-01-20 16:47:34 +01:00
pub fn read_mnemonic_from_stdin() -> Result<Mnemonic> {
let mut phrase = String::new();
print!("Input recovery phrase: ");
std::io::stdout().flush()?;
std::io::stdin().read_line(&mut phrase)?;
Mnemonic::from_str(phrase.trim()).context("Invalid mnemonic phrase")
}
pub async fn execute_keys_restoration(wallet_core: &mut WalletCore, depth: u32) -> Result<()> {
wallet_core
.storage
.key_chain_mut()
.generate_trees_for_depth(depth);
println!(
"Public tree generated\n\
Private tree generated"
);
wallet_core.sync_to_latest_block().await?;
wallet_core
.storage
.key_chain_mut()
.cleanup_trees_remove_uninit_layered(depth, |account_id| {
wallet_core
.sequencer_client
.get_account(account_id)
.map_err(Into::into)
})
.await?;
println!(
"Public tree cleaned up\n\
Private tree cleaned up"
);
wallet_core.store_persistent_data()?;
Ok(())
}