logos-execution-zone/wallet/src/helperfunctions.rs

80 lines
2.6 KiB
Rust
Raw Normal View History

use std::{path::PathBuf, str::FromStr as _};
2025-08-07 14:07:34 +03:00
2026-03-18 18:32:05 +02:00
use anyhow::{Context as _, Result};
2025-11-26 00:27:20 +03:00
use nssa_core::account::Nonce;
2026-03-04 18:42:33 +03:00
use rand::{RngCore as _, rngs::OsRng};
2025-08-07 14:07:34 +03:00
use crate::HOME_DIR_ENV_VAR;
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11: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
/// Read the Keycard PIN without echoing it.
///
/// Checks `KEYCARD_PIN` first so non-interactive callers (CI, scripts) can
/// supply it via the environment. Falls back to a TTY prompt via `rpassword`
/// so the value never appears in argv, shell history, or `ps` output.
pub fn read_pin() -> anyhow::Result<zeroize::Zeroizing<String>> {
if let Ok(pin) = std::env::var("KEYCARD_PIN") {
return Ok(zeroize::Zeroizing::new(pin));
}
rpassword::prompt_password("Keycard PIN: ")
.map(zeroize::Zeroizing::new)
.map_err(Into::into)
}
/// Read the mnemonic phrase without echoing it.
///
/// Checks `KEYCARD_MNEMONIC` first for non-interactive callers. Falls back to
/// a TTY prompt so the phrase never appears in argv, shell history, or `ps`.
pub fn read_mnemonic() -> anyhow::Result<zeroize::Zeroizing<String>> {
if let Ok(mnemonic) = std::env::var("KEYCARD_MNEMONIC") {
return Ok(zeroize::Zeroizing::new(mnemonic));
}
rpassword::prompt_password("Mnemonic phrase: ")
.map(zeroize::Zeroizing::new)
.map_err(Into::into)
}
/// Get home dir for wallet. Env var `NSSA_WALLET_HOME_DIR` must be set before execution to succeed.
fn get_home_nssa_var() -> Result<PathBuf> {
2025-08-07 14:07:34 +03:00
Ok(PathBuf::from_str(&std::env::var(HOME_DIR_ENV_VAR)?)?)
}
2025-10-30 15:33:58 +02:00
/// Get home dir for wallet. Env var `HOME` must be set before execution to succeed.
fn get_home_default_path() -> Result<PathBuf> {
2025-10-30 15:33:58 +02:00
std::env::home_dir()
.map(|path| path.join(".nssa").join("wallet"))
2026-03-09 18:27:56 +03:00
.context("Failed to get HOME")
2025-10-29 13:23:07 +02:00
}
2025-10-30 15:33:58 +02:00
/// Get home dir for wallet.
pub fn get_home() -> Result<PathBuf> {
2026-03-09 18:27:56 +03:00
get_home_nssa_var().or_else(|_| get_home_default_path())
2025-10-30 15:33:58 +02:00
}
2026-03-10 00:17:43 +03:00
/// Fetch config path from default home.
pub fn fetch_config_path() -> Result<PathBuf> {
let home = get_home()?;
let config_path = home.join("wallet_config.json");
Ok(config_path)
2025-12-08 18:26:35 +03:00
}
2026-03-10 00:17:43 +03:00
/// Fetch path to data storage from default home.
2025-08-08 15:22:04 +03:00
///
2025-11-26 07:32:35 +02:00
/// File must be created through setup beforehand.
pub fn fetch_persistent_storage_path() -> Result<PathBuf> {
2025-08-08 15:22:04 +03:00
let home = get_home()?;
2025-10-28 16:02:30 +02:00
let accs_path = home.join("storage.json");
Ok(accs_path)
2025-08-08 15:22:04 +03:00
}
2025-08-20 17:16:51 +03:00
2026-03-18 13:10:36 -04:00
#[expect(dead_code, reason = "Maybe used later")]
pub(crate) fn produce_random_nonces(size: usize) -> Vec<Nonce> {
let mut result = vec![[0; 16]; size];
2026-03-03 23:21:08 +03:00
for bytes in &mut result {
OsRng.fill_bytes(bytes);
}
2026-03-18 10:28:52 -04:00
result
.into_iter()
.map(|x| Nonce(u128::from_le_bytes(x)))
.collect()
}