From c172780bc6aa9a580bc87a4230f4efded6044494 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Mon, 4 May 2026 21:28:29 -0400 Subject: [PATCH] ci and add private account keys test --- keycard_test_3.sh | 18 ++++++++++++++++++ keycard_tests.sh | 13 ++++++------- keycard_tests_2.sh | 2 ++ wallet/src/cli/keycard.rs | 15 +++++++++++++++ wallet/src/cli/programs/token.rs | 32 ++++++++++++++++++++++++++++++-- wallet/src/lib.rs | 5 ++++- 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 keycard_test_3.sh diff --git a/keycard_test_3.sh b/keycard_test_3.sh new file mode 100644 index 00000000..b76f4f38 --- /dev/null +++ b/keycard_test_3.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# keycard_test_3.sh — tests for `wallet keycard get-private-keys`. +# +# Prerequisites: +# 1. Run wallet_with_keycard.sh once to install dependencies. +# 2. Keycard reader inserted with card loaded (wallet keycard load has been run). + +source venv/bin/activate +export KEYCARD_PIN=111111 + +echo "=== Test: wallet keycard get-private-keys path 0 ===" +wallet keycard get-private-keys --key-path "m/44'/60'/0'/0/0" + +echo "=== Test: wallet keycard get-private-keys path 1 ===" +wallet keycard get-private-keys --key-path "m/44'/60'/0'/0/1" + +echo "" +echo "=== All get-private-keys tests finished ===" diff --git a/keycard_tests.sh b/keycard_tests.sh index 9ec79cf6..f64673a5 100644 --- a/keycard_tests.sh +++ b/keycard_tests.sh @@ -58,13 +58,12 @@ wallet account get --key-path "m/44'/60'/0'/0/1" echo "" echo "=== Test (1): Shielded auth-transfer to owned private account ===" -wallet account new private --label priv-target 2>/dev/null || true - -wallet auth-transfer send --amount 40 \ +wallet auth-transfer send --amount 2 \ --from-key-path "m/44'/60'/0'/0/0" \ - --to-label priv-target + --to-npk "55204e2934045b044f06d8222b454d46b54788f33c7dec4f6733d441703bb0e6" \ + --to-vpk "02a8626b0c0ad9383c5678dad48c3969b4174fb377cdb03a6259648032c774cec8" echo "Shielded auth-transfer sent" -wallet account sync-private -echo "Private target account state (should show decoded balance = 40):" -wallet account get --account-label priv-target \ No newline at end of file +# TODO: add a time delay here + +wallet account get --key-path "m/44'/60'/0'/0/0" \ No newline at end of file diff --git a/keycard_tests_2.sh b/keycard_tests_2.sh index 509b6c09..54be3a4c 100644 --- a/keycard_tests_2.sh +++ b/keycard_tests_2.sh @@ -184,5 +184,7 @@ wallet amm remove-liquidity \ --min-amount-b 1 echo "Remove liquidity complete" + + echo "" echo "=== All keycard tests finished ===" diff --git a/wallet/src/cli/keycard.rs b/wallet/src/cli/keycard.rs index 3c35ebda..d39f5974 100644 --- a/wallet/src/cli/keycard.rs +++ b/wallet/src/cli/keycard.rs @@ -16,6 +16,12 @@ pub enum KeycardSubcommand { #[arg(short, long)] mnemonic: Option, }, + /// Export the private account keys (nsk, vsk) for the given key derivation path. + GetPrivateKeys { + /// BIP-32 key derivation path (e.g. `m/44'/60'/0'/0/0`). + #[arg(long)] + key_path: String, + }, } impl WalletSubcommand for KeycardSubcommand { @@ -43,6 +49,15 @@ impl WalletSubcommand for KeycardSubcommand { Ok(SubcommandReturnValue::Empty) } + Self::GetPrivateKeys { key_path } => { + let pin = read_pin()?; + let (nsk, vsk) = + KeycardWallet::get_private_keys_for_path_with_connect(&pin, &key_path) + .map_err(anyhow::Error::from)?; + println!("nsk: {}", hex::encode(nsk)); + println!("vsk: {}", hex::encode(vsk)); + Ok(SubcommandReturnValue::Empty) + } Self::Load { mnemonic } => { let pin = read_pin()?; diff --git a/wallet/src/cli/programs/token.rs b/wallet/src/cli/programs/token.rs index 2307cae3..7fc31069 100644 --- a/wallet/src/cli/programs/token.rs +++ b/wallet/src/cli/programs/token.rs @@ -377,6 +377,20 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand { let (supply_account_id, supply_addr_privacy) = parse_addr_with_privacy_prefix(&supply_account_id)?; + // Skip if already created — prevents a doomed on-chain rejection when the + // definition account is already initialised (e.g. on re-runs against the same + // chain). + if definition_addr_privacy == AccountPrivacyKind::Public { + let def_id: nssa::AccountId = definition_account_id.parse()?; + let def_account = wallet_core.get_account_public(def_id).await?; + if def_account != nssa::Account::default() { + println!( + "Token definition at {definition_account_id} is already initialized. Skipping." + ); + return Ok(SubcommandReturnValue::Empty); + } + } + let underlying_subcommand = match (definition_addr_privacy, supply_addr_privacy) { (AccountPrivacyKind::Public, AccountPrivacyKind::Public) => { TokenProgramSubcommand::Create( @@ -1025,7 +1039,7 @@ impl WalletSubcommand for TokenProgramSubcommandPublic { balance_to_move, sender_key_path, } => { - Token(wallet_core) + let tx_hash = Token(wallet_core) .send_transfer_transaction( sender_account_id.parse().unwrap(), recipient_account_id.parse().unwrap(), @@ -1033,6 +1047,13 @@ impl WalletSubcommand for TokenProgramSubcommandPublic { sender_key_path, ) .await?; + + println!("Transaction hash is {tx_hash}"); + + wallet_core.poll_native_token_transfer(tx_hash).await?; + + wallet_core.store_persistent_data().await?; + Ok(SubcommandReturnValue::Empty) } Self::BurnToken { @@ -1711,7 +1732,7 @@ impl WalletSubcommand for CreateNewTokenProgramSubcommand { definition_key_path, supply_key_path, } => { - Token(wallet_core) + let tx_hash = Token(wallet_core) .send_new_definition( definition_account_id.parse().unwrap(), supply_account_id.parse().unwrap(), @@ -1721,6 +1742,13 @@ impl WalletSubcommand for CreateNewTokenProgramSubcommand { supply_key_path.as_deref(), ) .await?; + + println!("Transaction hash is {tx_hash}"); + + wallet_core.poll_native_token_transfer(tx_hash).await?; + + wallet_core.store_persistent_data().await?; + Ok(SubcommandReturnValue::Empty) } } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index d480ae3a..315f1f7b 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -456,6 +456,7 @@ impl WalletCore { { pre.is_authorized = true; } + nonces.push(acc.account.nonce); } else { nonces.push(acc.account.nonce); account_ids.push(acc.account_id); @@ -716,7 +717,9 @@ impl WalletCore { signatures_and_public_keys.push( KeycardWallet::sign_message_for_path_with_connect(&pin, path, &message.hash()) - .expect("Expect a valid signature"), // TODO: Marvin tautology + .expect( + "`wallet::lib::sign_privacy_message_with_keycard()`: Invalid signature", + ), ); }