From d98f13adde02f10c0b45d7e2508db62c1dcf75fa Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Wed, 6 May 2026 20:35:46 -0400 Subject: [PATCH] Ci fixes --- docs/LEZ testnet v0.1 tutorials/keycard.md | 31 +++++- keycard_tests.sh | 12 +-- keycard_tests_2.sh | 54 +++++----- wallet/src/cli/programs/amm.rs | 22 ++-- wallet/src/cli/programs/token.rs | 16 +-- wallet/src/program_facades/token.rs | 111 ++++++++++++++------- 6 files changed, 151 insertions(+), 95 deletions(-) diff --git a/docs/LEZ testnet v0.1 tutorials/keycard.md b/docs/LEZ testnet v0.1 tutorials/keycard.md index a6634313..0406f4d3 100644 --- a/docs/LEZ testnet v0.1 tutorials/keycard.md +++ b/docs/LEZ testnet v0.1 tutorials/keycard.md @@ -178,6 +178,33 @@ Account owned by authenticated transfer program | `wallet token burn` | ChainIndex (key path) for holding account | | `wallet token mint` | ChainIndices (key paths) for definition and holding public accounts | +These commands work as expected, but uses `key-path` features to use a public account via Keycard. + +1. Initialize new Token +```bash +wallet token new \ + --definition-key-path "m/44'/60'/0'/1/0" \ + --supply-key-path "m/44'/60'/0'/1/1" \ + --total-supply 100000 \ + --name SNT + + # Output: +Keycard PIN: +Transaction hash is 2f0ddd9ad46e1c8cde8dac4eb69ebb5d8fdf167647e421aa79900adaaa9b34d0 +``` + +2. Initialize new token holding +```bash +wallet token init \ + --definition-account-id "Public/$LEE_DEF_ID" \ + --holder-key-path "m/44'/60'/0'/0/2" + +# Output +Keycard PIN: +Transaction hash is d4442e32bf33efbac03672e3c5f6e181bc7e34f0911cf00ef915eeaee6787a5b +LEE holding initialized for keycard m/44'/60'/0'/0/2 +``` + ### AMM program | Command | Description | |--------------------------------|---------------------------------------------------------------------| @@ -185,4 +212,6 @@ Account owned by authenticated transfer program | `wallet amm swap-exact-input` | ChaindIndex (key path) to initialize Keycard public account | | `wallet amm swap-exact-output` | ChainIndices (key paths) for `from` and `to` public accounts | | `wallet amm add-liquidity` | ChainIndex (key path) for holding account | -| `wallet amm reemove-liquidity` | ChainIndices (key paths) for definition and holding public accounts | \ No newline at end of file +| `wallet amm remove-liquidity` | ChainIndices (key paths) for definition and holding public accounts | + +These commands work as expected, but uses `key-path` features to use a public account via Keycard. \ No newline at end of file diff --git a/keycard_tests.sh b/keycard_tests.sh index f64673a5..3d6504cd 100644 --- a/keycard_tests.sh +++ b/keycard_tests.sh @@ -33,6 +33,8 @@ wallet account get --key-path "m/44'/60'/0'/0/0" echo "=== Test: pinata claim path 0 ===" wallet pinata claim --key-path "m/44'/60'/0'/0/0" +sleep 5 + echo "=== Test: account get path 0 (after claim) ===" wallet account get --key-path "m/44'/60'/0'/0/0" @@ -48,13 +50,6 @@ echo "=== Test: account get path 0 ===" wallet account get --key-path "m/44'/60'/0'/0/0" echo "=== Test: account get path 1 ===" wallet account get --key-path "m/44'/60'/0'/0/1" - -# ============================================================================= -# (1) Shielded auth-transfer to an owned private account; verify decoded state. -# -# Use --to-label (ShieldedOwned path) so the wallet decodes the received note -# after sync and the balance is visible locally. -# ============================================================================= echo "" echo "=== Test (1): Shielded auth-transfer to owned private account ===" @@ -64,6 +59,5 @@ wallet auth-transfer send --amount 2 \ --to-vpk "02a8626b0c0ad9383c5678dad48c3969b4174fb377cdb03a6259648032c774cec8" echo "Shielded auth-transfer sent" -# TODO: add a time delay here - +sleep 5 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 513583bb..236d9374 100644 --- a/keycard_tests_2.sh +++ b/keycard_tests_2.sh @@ -1,17 +1,15 @@ source venv/bin/activate export KEYCARD_PIN=111111 -# ============================================================================= -# (2) Initialize token definitions + initial supply holdings for LEZ and LEE. -# All without keycard. -# ============================================================================= echo "" -echo "=== Test (2): Create LEZ and LEE token definitions (without keycard) ===" +echo "=== Create LEZ and LEE token definitions (without keycard) ===" -wallet account new public --label lez-def 2>/dev/null || true -wallet account new public --label lez-supply 2>/dev/null || true -wallet account new public --label lee-def 2>/dev/null || true -wallet account new public --label lee-supply 2>/dev/null || true +wallet account new public --label lez-def +wallet account new public --label lez-supply +wallet account new public --label lee-def +wallet account new public --label lee-supply + +sleep 5 LEZ_DEF_ID=$(wallet account id --account-label lez-def) LEE_DEF_ID=$(wallet account id --account-label lee-def) @@ -31,14 +29,12 @@ wallet token new \ echo "LEE token created" # ============================================================================= -# (3) Initialize LEE token holding accounts: +# Initialize LEE token holding accounts: # - two public keycard holders (paths 2 and 3) # - one private holder (without keycard) -# -# token init is idempotent: skips if the holder already has token data. # ============================================================================= echo "" -echo "=== Test (3): Initialize LEE token holding accounts ===" +echo "=== Initialize LEE/LEZ token holding accounts ===" wallet token init \ --definition-account-id "Public/$LEE_DEF_ID" \ @@ -50,6 +46,7 @@ wallet token init \ --holder-key-path "m/44'/60'/0'/0/3" echo "LEE holding initialized for keycard m/44'/60'/0'/0/3" +# For shielded transfer wallet account new private --label lee-priv-holder 2>/dev/null || true wallet token init \ --definition-account-id "Public/$LEE_DEF_ID" \ @@ -71,17 +68,20 @@ wallet token send \ --amount 5000 echo "Transferred 5000 LEE → keycard path 3" +sleep 5 + echo "Keycard path 2 LEE state (balance should be 5000):" wallet account get --key-path "m/44'/60'/0'/0/2" echo "Keycard path 3 LEE state (balance should be 5000):" wallet account get --key-path "m/44'/60'/0'/0/3" + # ============================================================================= -# (4) Shielded (public → private) LEE transfer from keycard holding to the -# private LEE holding account. +# Shielded (public → private) LEE transfer from keycard holding to the +# private LEE holding account. # ============================================================================= echo "" -echo "=== Test (4): Shielded transfer keycard LEE holding → private LEE holding ===" +echo "=== Test Shielded transfer keycard LEE holding → private LEE holding ===" wallet token send \ --from-key-path "m/44'/60'/0'/0/2" \ @@ -94,10 +94,10 @@ echo "Private LEE holder state (balance should be 500):" wallet account get --account-label lee-priv-holder # ============================================================================= -# (5) Create AMM pool for LEZ/LEE (without keycard) +# Create AMM pool for LEZ/LEE (without keycard) # ============================================================================= echo "" -echo "=== Test (5): Create AMM pool for LEZ/LEE (without keycard) ===" +echo "=== Test Create AMM pool for LEZ/LEE (without keycard) ===" wallet account new public --label amm-lp-lez-holding 2>/dev/null || true wallet account new public --label amm-lp-lee-holding 2>/dev/null || true @@ -122,7 +122,7 @@ wallet amm new \ echo "AMM pool created for LEZ/LEE" # ============================================================================= -# (6) Swaps, add liquidity, remove liquidity using keycard holding accounts. +# Swaps, add liquidity, remove liquidity using keycard holding accounts. # # Path layout: # path 2 → LEE holding (4500 LEE after step 4) @@ -130,7 +130,7 @@ echo "AMM pool created for LEZ/LEE" # path 4 → fresh; initialized below as LEZ holding (receives swapped LEZ) # ============================================================================= echo "" -echo "=== Test (6a): Initialize LEZ holding for keycard path 4 (swap output) ===" +echo "=== Test Initialize LEZ holding for keycard path 4 (swap output) ===" wallet token init \ --definition-account-id "Public/$LEZ_DEF_ID" \ --holder-key-path "m/44'/60'/0'/0/4" @@ -145,18 +145,16 @@ echo "Path 2: $PATH2_ID Path 3: $PATH3_ID Path 4: $PATH4_ID" echo "LEE def ID: $LEE_DEF_ID" echo "" -echo "=== Test (6b): Swap LEE → LEZ (path 2 sells LEE, path 4 receives LEZ) ===" -# user-holding-b (path 2) is the input (LEE); user-holding-a (path 4) receives LEZ. -# --key-path signs for the input account (path 2). +echo "=== Swap LEE → LEZ (path 2 sells LEE, path 4 receives LEZ) ===" wallet amm swap-exact-input \ - --user-holding-a "Public/$PATH4_ID" \ - --user-holding-b "Public/$PATH2_ID" \ - --amount-in 500 \ + --user-holding-a-key-path "m/44'/60'/0'/0/4" \ + --user-holding-b-key-path "m/44'/60'/0'/0/2" \ + --amount-in 100 \ --min-amount-out 1 \ --token-definition "$LEE_DEF_ID" \ - --key-path "m/44'/60'/0'/0/2" echo "Swap LEE→LEZ complete via keycard" + echo "Path 4 (LEZ) state:" wallet account get --key-path "m/44'/60'/0'/0/4" echo "Path 2 (LEE) state:" @@ -185,6 +183,6 @@ wallet amm remove-liquidity \ echo "Remove liquidity complete" - echo "" echo "=== All keycard tests finished ===" + diff --git a/wallet/src/cli/programs/amm.rs b/wallet/src/cli/programs/amm.rs index 9e0538e6..8e1748c1 100644 --- a/wallet/src/cli/programs/amm.rs +++ b/wallet/src/cli/programs/amm.rs @@ -30,8 +30,7 @@ pub enum AmmProgramAgnosticSubcommand { #[arg( long, conflicts_with = "user_holding_a", - conflicts_with = "user_holding_a_key_path", - required_unless_present_any = ["user_holding_a_label", "user_holding_a_key_path"] + conflicts_with = "user_holding_a_key_path" )] user_holding_a_label: Option, /// Key path for user holding A (uses Keycard, alternative to --user-holding-a/label). @@ -67,7 +66,8 @@ pub enum AmmProgramAgnosticSubcommand { #[arg( long, conflicts_with = "user_holding_lp_label", - conflicts_with = "user_holding_lp_key_path" + conflicts_with = "user_holding_lp_key_path", + required_unless_present_any = ["user_holding_lp_label", "user_holding_lp_key_path"] )] user_holding_lp: Option, /// User holding LP account label (alternative to --user-holding-lp). @@ -128,11 +128,19 @@ pub enum AmmProgramAgnosticSubcommand { /// `token_definition` - valid 32 byte base58 string WITHOUT privacy prefix. #[arg(long)] token_definition: String, - /// Key path for the input token's holding account (uses Keycard). - #[arg(long, conflicts_with = "user_holding_a")] + /// Key path for user token's holding account fpr Token A (uses Keycard). + #[arg( + long, + conflicts_with = "user_holding_a", + conflicts_with = "user_holding_a_label" + )] user_holding_a_key_path: Option, - /// Key path for the input token's holding account (uses Keycard). - #[arg(long, conflicts_with = "user_holding_b")] + /// Key path for user token's holding account fpr Token B (uses Keycard). + #[arg( + long, + conflicts_with = "user_holding_b", + conflicts_with = "user_holding_b_label" + )] user_holding_b_key_path: Option, }, /// Swap specifying exact output amount. diff --git a/wallet/src/cli/programs/token.rs b/wallet/src/cli/programs/token.rs index 7fc31069..8ade708a 100644 --- a/wallet/src/cli/programs/token.rs +++ b/wallet/src/cli/programs/token.rs @@ -117,7 +117,7 @@ pub enum TokenProgramAgnosticSubcommand { #[arg(long, conflicts_with = "from", conflicts_with = "from_key_path")] from_label: Option, /// to - valid 32 byte base58 string with privacy prefix. - #[arg(long, conflicts_with = "to_label")] + #[arg(long, conflicts_with = "to_label", conflicts_with = "to_key_path")] to: Option, /// To account label (alternative to --to). #[arg(long, conflicts_with = "to")] @@ -136,20 +136,10 @@ pub enum TokenProgramAgnosticSubcommand { #[arg(long)] amount: u128, /// `from_key_path` (alternative to --from) uses Keycard. - #[arg( - long, - conflicts_with = "from", - conflicts_with = "from", - conflicts_with = "from_label" - )] + #[arg(long, conflicts_with = "from", conflicts_with = "from_label")] from_key_path: Option, /// `to_key_path` (alternative to --to) uses Keycard. - #[arg( - long, - conflicts_with = "to", - conflicts_with = "to", - conflicts_with = "to_label" - )] + #[arg(long, conflicts_with = "to", conflicts_with = "to_label")] to_key_path: Option, }, /// Burn tokens on `holder`, modify `definition`. diff --git a/wallet/src/program_facades/token.rs b/wallet/src/program_facades/token.rs index 931be1a7..f86f4cb9 100644 --- a/wallet/src/program_facades/token.rs +++ b/wallet/src/program_facades/token.rs @@ -197,14 +197,46 @@ impl Token<'_> { let instruction = Instruction::Transfer { amount_to_transfer: amount, }; - // Only the sender authorises a token Transfer — the recipient holding must already be - // initialised (no recipient signature required, matching the burn pattern). - let nonces = self + + let mut nonces = self .0 .get_accounts_nonces(vec![sender_account_id]) .await .map_err(ExecutionFailureKind::SequencerError)?; + let private_keys = if sender_key_path.is_none() { + let mut private_keys = Vec::new(); + let sender_sk = self + .0 + .storage + .user_data + .get_pub_account_signing_key(sender_account_id) + .ok_or(ExecutionFailureKind::KeyNotFoundError)?; + private_keys.push(sender_sk); + + if let Some(recipient_sk) = self + .0 + .storage + .user_data + .get_pub_account_signing_key(recipient_account_id) + { + private_keys.push(recipient_sk); + let recipient_nonces = self + .0 + .get_accounts_nonces(vec![recipient_account_id]) + .await + .map_err(ExecutionFailureKind::SequencerError)?; + nonces.extend(recipient_nonces); + } else { + println!( + "Receiver's account ({recipient_account_id}) private key not found in wallet. Proceeding with only sender's key." + ); + } + private_keys + } else { + Vec::new() + }; + let message = nssa::public_transaction::Message::try_new( program_id, account_ids, @@ -227,13 +259,7 @@ impl Token<'_> { WitnessSet::from_list(&message, &[signature], &[public_key]) .map_err(ExecutionFailureKind::TransactionBuildError)? } else { - let sender_sk = self - .0 - .storage - .user_data - .get_pub_account_signing_key(sender_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - nssa::public_transaction::WitnessSet::for_message(&message, &[sender_sk]) + nssa::public_transaction::WitnessSet::for_message(&message, &private_keys) }; let tx = nssa::PublicTransaction::new(message, witness_set); @@ -660,24 +686,38 @@ impl Token<'_> { .await .map_err(ExecutionFailureKind::SequencerError)?; - if self - .0 - .storage - .user_data - .get_pub_account_signing_key(holder_account_id) - .is_some() - { - let recipient_nonces = self + let private_keys = if definition_key_path.is_none() { + let mut private_keys = Vec::new(); + let definition_sk = self .0 - .get_accounts_nonces(vec![holder_account_id]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - nonces.extend(recipient_nonces); + .storage + .user_data + .get_pub_account_signing_key(definition_account_id) + .ok_or(ExecutionFailureKind::KeyNotFoundError)?; + private_keys.push(definition_sk); + + if let Some(holder_sk) = self + .0 + .storage + .user_data + .get_pub_account_signing_key(holder_account_id) + { + private_keys.push(holder_sk); + let holder_nonce: Vec = self + .0 + .get_accounts_nonces(vec![holder_account_id]) + .await + .map_err(ExecutionFailureKind::SequencerError)?; + nonces.extend(holder_nonce); + } else { + println!( + "Holder's account ({holder_account_id}) private key not found in wallet. Proceeding with only definition's key." + ); + } + private_keys } else { - println!( - "Holder's account ({holder_account_id}) private key not found in wallet. Proceeding with only definition's key." - ); - } + Vec::new() + }; let message = nssa::public_transaction::Message::try_new( Program::token().id(), @@ -687,24 +727,21 @@ impl Token<'_> { ) .unwrap(); - let msg_hash = message.hash(); - let witness_set = if let Some(kp) = definition_key_path { + let witness_set = if let Some(definition_key_path) = definition_key_path { let pin = crate::helperfunctions::read_pin().map_err(|e| { ExecutionFailureKind::KeycardError(pyo3::PyErr::new::( e.to_string(), )) })?; - let (sig, pk) = KeycardWallet::sign_message_for_path_with_connect(&pin, kp, &msg_hash)?; - nssa::public_transaction::WitnessSet::from_list(&message, &[sig], &[pk]) + let (signature, public_key) = KeycardWallet::sign_message_for_path_with_connect( + &pin, + definition_key_path, + &message.hash(), + )?; + WitnessSet::from_list(&message, &[signature], &[public_key]) .map_err(ExecutionFailureKind::TransactionBuildError)? } else { - let signing_key = self - .0 - .storage - .user_data - .get_pub_account_signing_key(definition_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]) + nssa::public_transaction::WitnessSet::for_message(&message, &private_keys) }; let tx = nssa::PublicTransaction::new(message, witness_set);