From e7b42a5177641455a8917bd2e29db20afd9690e5 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Tue, 12 May 2026 18:07:44 -0400 Subject: [PATCH] first round of comments --- docs/LEZ testnet v0.1 tutorials/keycard.md | 148 +++++++++++++++++++++ keycard_tests.sh | 6 +- nssa/src/encoding/public_transaction.rs | 2 +- python/keycard_applets/LEE_keycard.cap | Bin 0 -> 102136 bytes python/keycard_applets/math.cap | Bin 0 -> 4874 bytes wallet/src/cli/keycard.rs | 19 +-- wallet/src/cli/mod.rs | 2 +- wallet/src/helperfunctions.rs | 13 ++ wallet_with_keycard.sh | 21 +-- 9 files changed, 177 insertions(+), 34 deletions(-) create mode 100644 docs/LEZ testnet v0.1 tutorials/keycard.md create mode 100644 python/keycard_applets/LEE_keycard.cap create mode 100644 python/keycard_applets/math.cap diff --git a/docs/LEZ testnet v0.1 tutorials/keycard.md b/docs/LEZ testnet v0.1 tutorials/keycard.md new file mode 100644 index 00000000..78ce8441 --- /dev/null +++ b/docs/LEZ testnet v0.1 tutorials/keycard.md @@ -0,0 +1,148 @@ +This tutorial walks you through using Keycard with Wallet CLI. Keycard is optional hardware that can offer enhance security to a LEZ wallet. A LEZ wallet that utilizes Keycard does not store any secret keys for public accounts (eventually, this will extend to private accounts). Instead, Wallet CLI retrieves the appropriate public keys and signatures from Keycard. + + +## Keycard Setup + +### Required hardware +- Keycard (Blank) - a Keycard, directly, from Keycard.tech cannot (currently) be updated to support LEE. +- Smartcard reader + +### Firmware installation +Installation: + +1. Install math applet on your keycard; this process only needs to be done once. In the root of repo: + ``` + cd python/keycard_applets + java -jar gp.jar --key c212e073ff8b4bbfaff4de8ab655221f --load math.cap + ``` +2. Install `keycard-desktop` from [github](https://github.com/choppu/keycard-desktop) + - Keycard Desktop is used to install the LEE key protocol to a blank keycard. + - Select (Re)Install Applet and upload the key binary (`python/keycard_applets/LEE_keycard.cap`). + ![keycard-desktop.png](keycard-desktop.png) + +## Wallet with Keycard +Keycard functionality is available to Wallet CLI by setting up the following Python virtual environment: + +```bash +# Install appropriate version of `keycard-py`. +git clone --branch lee-schnorr --single-branch https://github.com/bitgamma/keycard-py.git python/keycard-py + +# Set up virtual environment. +python3 -m venv venv +source venv/bin/activate +pip install pyscard mnemonic ecdsa pyaes +pip install -e python/keycard-py +``` + +**Important**: Keycard wallet commands only work within the virtual environment. +```bash +# In the root of LEE repo: +source venv/bin/activate +``` + +## Keycard Commands + +### Keycard + +| Command | Key-path options | Description | +|-----------------------------------|------------------|--------------------------------------------------------------------------| +| `wallet keycard available` | — | Checks whether a Keycard reader and card are accessible | +| `wallet keycard load` | — | Loads a mnemonic phrase onto the Keycard | +| `wallet keycard get-private-keys` | `--key-path` | Retrieves private account keys (nsk, vsk) for the given BIP32 path | + +1. Check keycard availability +```bash +wallet keycard available + +# Output: +✅ Keycard is available. +``` + +2. Load a mnemonic phrase +```bash +wallet keycard load --mnemonic "fashion degree mountain wool question damp current pond grow dolphin chronic then" + +# Output: +Keycard PIN: +✅ Keycard is now connected to wallet. +``` + +3. Get private keys for a path +```bash +wallet keycard get-private-keys --key-path "m/44'/60'/0'/0/0" + +# Output: +Keycard PIN: +nsk: 55e505bf925e536c843a12ebc08c41ca5f4761eeeb7fa33725f0b44e6f1ac2e4 +vsk: 30f798893977a7b7263d1f77abf58e11e014428c92030d6a02fe363cceb41ffa +``` + +### Pinata (testnet) + +| Command | Key-path options | Description | +|-----------------------|-------------------------------|--------------------------------------------------------------------------| +| `wallet pinata claim` | `--key-path` | Claims a testnet pinata reward to a public or private recipient account | + +Note: The recipient account must be initialized with `wallet auth-transfer init` before claiming. + +1. Claim to a Keycard public account +```bash +wallet pinata claim --key-path "m/44'/60'/0'/0/0" + +# Output: +Keycard PIN: +Computing solution for pinata... +Found solution 989106 in 33.739525ms +Transaction hash is fd320c01f5469e62d2486afa1d9d5be39afcca0cd01d1575905b7acd95cf6397 +``` + +2. Claim to a local wallet account by label +```bash +wallet pinata claim --to-label my-account + +# Output: +Transaction hash is 2c8a4f1e903d5b76e80214c5b82e1d46a105e28930ad71bcce48f2d07b49a16f +``` + +### Authenticated-transfer program + +| Command | Key-path options | Description | +|-----------------------------|--------------------------------------|------------------------------------------------------------------------------------| +| `wallet auth-transfer init` | `--key-path` | Registers a public or private account with the auth-transfer program | +| `wallet auth-transfer send` | `--from-key-path`, `--to-key-path` | Sends native tokens; either or both endpoints can be Keycard public accounts | + +For `send`, `--from-key-path` and `--to-key-path` can be used together (both Keycard) or individually (one Keycard, one local/label). Shielded sends to foreign private accounts use `--to-npk`/`--to-vpk` instead of `--to-key-path`. + +1. Initialize a Keycard public account +```bash +wallet auth-transfer init --key-path "m/44'/60'/0'/0/0" + +# Output: +Keycard PIN: +Transaction hash is 49c16940493e1618c393645c1211b5c793d405838221c29ac6562a8a4b11c5a7 +``` + +2. Send native tokens between two Keycard accounts +```bash +wallet auth-transfer send \ + --from-key-path "m/44'/60'/0'/0/0" \ + --to-key-path "m/44'/60'/0'/0/1" \ + --amount 40 + +# Output: +Keycard PIN: +Transaction hash is 1a9764ab20763dcc1ffb51c6e9badd5a6316a773759032ca48e0eee59caaf488 +``` + +3. Send native tokens from Keycard to a local wallet account +```bash +# Note: non-keycard account ID below — replace with actual account ID or use --to-label +wallet auth-transfer send \ + --from-key-path "m/44'/60'/0'/0/0" \ + --to "Public/9bKmZ4n7PqVRxEtY3dWsQjA2cHrFT5LpDoGXM8wJuNv6" \ + --amount 20 + +# Output: +Keycard PIN: +Transaction hash is 3e7b2a91cf804d56fe19084b3c8b25d07e8f243829bc50addf6e2c78b4b09d34 +``` \ No newline at end of file diff --git a/keycard_tests.sh b/keycard_tests.sh index 4cb844ec..7b4e7ae5 100644 --- a/keycard_tests.sh +++ b/keycard_tests.sh @@ -10,8 +10,10 @@ echo "Test: wallet keycard available" wallet keycard available # Install a new mnemonic phrase to keycard -echo 'Test: wallet keycard load --mnemonic "fashion degree mountain wool question damp current pond grow dolphin chronic then"' -wallet keycard load --mnemonic "fashion degree mountain wool question damp current pond grow dolphin chronic then" +echo "Test: wallet keycard load" +export KEYCARD_MNEMONIC="fashion degree mountain wool question damp current pond grow dolphin chronic then" +wallet keycard load +unset KEYCARD_MNEMONIC echo "Test: wallet auth-transfer init --key-path \"m/44'/60'/0'/0/0\"" wallet auth-transfer init --key-path "m/44'/60'/0'/0/0" diff --git a/nssa/src/encoding/public_transaction.rs b/nssa/src/encoding/public_transaction.rs index b689e403..043bd4f7 100644 --- a/nssa/src/encoding/public_transaction.rs +++ b/nssa/src/encoding/public_transaction.rs @@ -14,6 +14,6 @@ impl PublicTransaction { } pub fn from_bytes(bytes: &[u8]) -> Result { - Ok(borsh::from_slice(bytes).expect("Autoderived borsh serialization failure")) + Ok(borsh::from_slice(bytes)?) } } diff --git a/python/keycard_applets/LEE_keycard.cap b/python/keycard_applets/LEE_keycard.cap new file mode 100644 index 0000000000000000000000000000000000000000..b44835c455a351bbd8b8a2888ec5d4c9f444f38b GIT binary patch literal 102136 zcmeFad0<^t)i=EN*=M>#?maid?Y$Xq+NMo9q)j@dgwot5X&aj+AxVc&Xp*M4ZQ2Z% zB!x5;NLrvkTMCGe45G}Ucqv0gP-IY0Ktw@Q1QAgmR8%HWne+YDKIdj=E6?-&^L>B3 zZ_<;q_Pq95Yp=ETI{Tb9tPyHDGfk7FwO(^3oA8s)RJOLdIXbtdZsokS(Yl(I)lJRC zYgc~yG-F@9dTsyp^R0{DdgkrCfiAz&(pLZU+9&>X=%Xu#eqTH9+U$jQuU+(7Wybf@ zMn7`z^VAjm==I1I8^7oO=&l#vdMNdg8=rfB<{c|vShsH*f9HG6{8v}};itxZZR_`4 za-;vwZ(8^A$KO3;=X3v+civlfC5{#Hc{e?E^%dV)e@nv)u970pm1lRafBTc@ihcL) zTXOix`Ad2$vR;_~>brltb~)d6eQe+NuQ+(>)>|LxS)F~|%g_A#oJT!Rrro;E^YEYc ze*2+?m)-2m`pNE>FZ^lz$p@Z3?=8=({a?Or)tB#``{sRrd8A_Com~ai7u?Ui_{aZx zW=hR_uG{W>W!cRa7T5jjm%qrp`r?|#KezY3>;CuRDKv^YH1{=mVMYfsWtb{?AXI8~NQYMjrkBqnFj>KYM6Sk z;?#!4OPgQ1^wOh`J>E33w$r!%-$!!)`qzO+vVt%4JX9Tf-u3$S${Q{k6t}*0$C=)N zUv5=Dz2M@xv%dDdH*4>>@04j*JnTO-@2BzeUpu?3_b

q5Zbko_g==XU+cZviE(T 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 z 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 literal 0 HcmV?d00001 diff --git a/python/keycard_applets/math.cap b/python/keycard_applets/math.cap new file mode 100644 index 0000000000000000000000000000000000000000..b9c0e99f7cb534501781bbfeada8f9fd09a6acf3 GIT binary patch literal 4874 zcmcgve{d9c6@TB&-mm1Agxp=iVSZ{FEl7y&oYL?iZIk zOw!IkrMjZ`P8aoO&Voa!2q)jFKXjPDQ3bmG2I-Tjzsg|}=iv-`>yWDoy zVD>L|=k0#K@4NeX@B4o3KCdT_w}R1V1oO8?w!!BPEAY_1p|h!eWRP5Xg=Qk-tJR7S08Nm3_UY>WY3G^25$W9_`|O(E;-logE8aGjr}9t z;-eMEFO1x{_|t!MJ3cL5wqc#O>vzjtZ?Af3!oP2{@#&7$@BgLZXH%!99H);x^MpHG zXZ_{1me+sy$|G;DI$zzj?~3dDAG$Am+5O!jd&k}3!h5drduvXQ{(R8Y^ycXKr$70` zx_{-NCz`(}wr(pOe6RV?zxB%#AHVhbt7X+wchziqwXbL5WBs$eSDx*u^QPZ9vh&G3 zZEuuan2dgPO5b-Vy12!6skQ&o<=XI;9o4R4XVtyyJ{mso<{kg)J6^T++5?CGcJ#H; z&cU(A9*m8DWyzfH;t=Od)KXe zvez_y?(BoXiGP-QJqF`VXU*Y<8Gt(vz>AK|2QY%QcDyI6J{o*cBnze?+U?|xT5EBd>e?N2ceU9UR8AcJ12d-r9*OekCcP_hF zgQAG)HHdVFlc7K=o*W{n98`k?3BV2|V1+Ko2NM|JKJEtc@Zi)t9DC}qNXrg4 zMicR5ie&L%&+ZNUz!)nyzY8O}ant$^Z(O-0@AZ==JK_^HBF$|E*^2AqF|=|l<&DQ9 zBuR&R(dqX9=pTYSBo2v3VoEUw4^Ep)5uT_{iL=mPQPf+@VBve-!+h8P|xkAa4!z zw#5U89*@!fO&EdzI-SjCD^vpi^;%^oNhQ)^(+z{O!IuvPhQZ9#F;M%Hj&J!9ji>=> zJ|nn81A$~Xf%!w47QlUoNJ)bF0tOgvSw|DbFeny)g~lAi@W_ty7zRpq%rj`gKqB+g z+h*j`X=O$E;~w{TlL4z348fYE#Yr?T`YAxhB>bihW^@RtZwoMEEYS2gH z!KPpk3LQNzpKq2BhKa!SxPTWsdV7KSaL^Wt0rLazCl2qIrZM1S(lka>0&7o4q`NQe zm+o6bK`6+9BQQEjIyrP9nHAl@BO#N^+^~dTH6%XZN&!06gsVmlJ)2K%&#YP)&I<4m z3x{qbhg$N`lhS~P!pxEmiZUEMEX)iHP@GvZBAoQFDH{(IHw*DBmQI@_wEXr6T_lO5 zuL13J#qAMVDG9B@O1ub#ws2?-gKS=5*1W>3d4*Z?3Ov3^mKStc8wymM$(Te1P>T*R z!xCj0y?m(a=nGi5iT+O+QAT%ws{fgp-yTQY72w2z0$^hc0WOrg=JC)@pIu#`BT@0 zp)6v7>T#h4ls-83(GXJvhkhJV3ehdYL9UcVbdxyQJj#f`M9K^>lb9lv&_%v@IvEHx zhowy^ZAX>COvz(_rDps&Dl)@zy42I90V@&E*bRdL(Mwtw!3P2^Da)LfS zPQ2p}An2A(0{ayXI4KJC60-m!jy`_U0~m)3aE7ul|1&TD2w@1svaGD!&f9c0z1?6l z+DylQlcA*Yk}UxQ*PD4I3x_XDYb3&grRQXngtdk4}V^9^aUKz{>n5cnx|Hj%7$Iq_w7@(T!W&#T2U%BRkvBu3aHGw{+ro& z5^}CT20FEhRI`>yDz-{a5^_!#a!wb}VHu|jIj0MfTgmByl2_>H*@)muMjB*-7^cJ80Il3S|k5HoW=mDR0`8eQG9$mqMYpwD(NYFKr%BEw$L04ujHYFu@X zA>*bo)aEmWs^d_DtJ@42{LdP|RZWK)T-|EO;10~I`81as4>hj3;gE5MHQ*}S4>h*B xJ&>^-SoY`BIoB+xVb#A&GHe_hwOha{e*mPPC$C3GUmvVV0z7~o8ln#){1=8l7BBz+ literal 0 HcmV?d00001 diff --git a/wallet/src/cli/keycard.rs b/wallet/src/cli/keycard.rs index 3c35ebda..02d10bd5 100644 --- a/wallet/src/cli/keycard.rs +++ b/wallet/src/cli/keycard.rs @@ -5,17 +5,14 @@ use pyo3::prelude::*; use crate::{ WalletCore, - cli::{SubcommandReturnValue, WalletSubcommand, read_pin}, + cli::{SubcommandReturnValue, WalletSubcommand, read_mnemonic, read_pin}, }; /// Represents generic chain CLI subcommand. #[derive(Subcommand, Debug, Clone)] pub enum KeycardSubcommand { Available, - Load { - #[arg(short, long)] - mnemonic: Option, - }, + Load, } impl WalletSubcommand for KeycardSubcommand { @@ -43,8 +40,9 @@ impl WalletSubcommand for KeycardSubcommand { Ok(SubcommandReturnValue::Empty) } - Self::Load { mnemonic } => { + Self::Load => { let pin = read_pin()?; + let mnemonic = read_mnemonic()?; Python::with_gil(|py| { python_path::add_python_path(py).expect("keycard_wallet.py not found"); @@ -62,14 +60,7 @@ impl WalletSubcommand for KeycardSubcommand { println!("\u{274c} Keycard is not connected to wallet."); } - drop( - wallet.load_mnemonic( - py, - &mnemonic.expect( - "E`wallet::keycard::load`: invalid data received for mnemonic", - ), - ), - ); + drop(wallet.load_mnemonic(py, &mnemonic)); drop(wallet.disconnect(py)); }); diff --git a/wallet/src/cli/mod.rs b/wallet/src/cli/mod.rs index 1ce0ea2c..17a90f79 100644 --- a/wallet/src/cli/mod.rs +++ b/wallet/src/cli/mod.rs @@ -8,7 +8,7 @@ use futures::TryFutureExt as _; use nssa::{ProgramDeploymentTransaction, program::Program}; use sequencer_service_rpc::RpcClient as _; -pub use crate::helperfunctions::read_pin; +pub use crate::helperfunctions::{read_mnemonic, read_pin}; use crate::{ WalletCore, cli::{ diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index 54883fdb..2222ffe6 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -65,6 +65,19 @@ pub fn read_pin() -> Result> { .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() -> Result> { + 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) +} + /// Resolve an account id-or-label pair to a `Privacy/id` string. /// /// Exactly one of `id` or `label` must be `Some`. If `id` is provided it is diff --git a/wallet_with_keycard.sh b/wallet_with_keycard.sh index 0a19972e..a0b4de46 100644 --- a/wallet_with_keycard.sh +++ b/wallet_with_keycard.sh @@ -1,21 +1,10 @@ cargo install --path wallet --force +# Install appropriate version of `keycard-py`. +git clone --branch lee-schnorr --single-branch https://github.com/bitgamma/keycard-py.git python/keycard-py +# Set up virtual environment. python3 -m venv venv source venv/bin/activate -python3 -m pip install pyscard -python3 -m pip install mnemonic -python3 -m pip install ecdsa -python3 -m pip install pyaes - -cd python - -# Need to use local version till fix applet -git clone --branch lee-schnorr --single-branch https://github.com/bitgamma/keycard-py.git -cd keycard-py -python3 -m venv venv -source venv/bin/activate -pip install -e . - - - +pip install pyscard mnemonic ecdsa pyaes +pip install -e python/keycard-py \ No newline at end of file