mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-14 20:19:51 +00:00
python comments
This commit is contained in:
parent
aa8331df6c
commit
524a06099c
@ -12,12 +12,12 @@ 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
|
||||
cd keycard_wallet/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`).
|
||||
- Select (Re)Install Applet and upload the key binary (`keycard_wallet/keycard_applets/LEE_keycard.cap`).
|
||||

|
||||
|
||||
## Wallet with Keycard
|
||||
@ -25,13 +25,13 @@ Keycard functionality is available to Wallet CLI by setting up the following Pyt
|
||||
|
||||
```bash
|
||||
# Install appropriate version of `keycard-py`.
|
||||
git clone --branch lee-schnorr --single-branch https://github.com/bitgamma/keycard-py.git python/keycard-py
|
||||
git clone --branch lee-schnorr --single-branch https://github.com/bitgamma/keycard-py.git keycard_wallet/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
|
||||
pip install -e keycard_wallet/python/keycard-py
|
||||
```
|
||||
|
||||
**Important**: Keycard wallet commands only work within the virtual environment.
|
||||
|
||||
BIN
keycard_wallet/keycard_applets/LEE_keycard.cap
Normal file
BIN
keycard_wallet/keycard_applets/LEE_keycard.cap
Normal file
Binary file not shown.
BIN
keycard_wallet/keycard_applets/math.cap
Normal file
BIN
keycard_wallet/keycard_applets/math.cap
Normal file
Binary file not shown.
122
keycard_wallet/python/keycard_wallet.py
Normal file
122
keycard_wallet/python/keycard_wallet.py
Normal file
@ -0,0 +1,122 @@
|
||||
from smartcard.System import readers
|
||||
from keycard.exceptions import APDUError, TransportError
|
||||
from ecdsa import VerifyingKey, SECP256k1
|
||||
|
||||
from keycard.keycard import KeyCard
|
||||
|
||||
from mnemonic import Mnemonic
|
||||
from keycard import constants
|
||||
|
||||
import keycard
|
||||
|
||||
DEFAULT_PAIRING_PASSWORD = "KeycardDefaultPairing"
|
||||
|
||||
class KeycardWallet:
|
||||
def __init__(self):
|
||||
self.card = KeyCard()
|
||||
|
||||
def _is_smart_card_reader_detected(self) -> bool:
|
||||
try:
|
||||
return len(readers()) > 0
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _is_keycard_detected(self) -> bool:
|
||||
try:
|
||||
KeyCard().select()
|
||||
return True
|
||||
except (TransportError, APDUError, Exception):
|
||||
# No readers, no card, or card doesn't respond.
|
||||
return False
|
||||
|
||||
def is_unpaired_keycard_available(self) -> bool:
|
||||
if not self._is_smart_card_reader_detected():
|
||||
return False
|
||||
elif not self._is_keycard_detected():
|
||||
return False
|
||||
return True
|
||||
|
||||
def setup_communication(self, pin: str, password = DEFAULT_PAIRING_PASSWORD) -> bool:
|
||||
self.card.select()
|
||||
|
||||
if not self.card.is_initialized:
|
||||
raise RuntimeError(f"Error setting up communication: uninitialized keycard")
|
||||
|
||||
pairing_index, pairing_key = self.card.pair(password)
|
||||
self.pairing_index = pairing_index
|
||||
|
||||
try:
|
||||
self.card.open_secure_channel(pairing_index, pairing_key)
|
||||
self.card.verify_pin(pin)
|
||||
except Exception as e:
|
||||
try:
|
||||
self.card.unpair(pairing_index)
|
||||
except Exception:
|
||||
pass
|
||||
raise RuntimeError(f"Error setting up communication: {e}") from e
|
||||
|
||||
return True
|
||||
|
||||
def load_mnemonic(self, mnemonic: str) -> bool:
|
||||
try:
|
||||
# Convert mnemonic to seed
|
||||
mnemo = Mnemonic("english")
|
||||
seed = mnemo.to_seed(mnemonic)
|
||||
|
||||
# Load the LEE seed onto the card
|
||||
result = self.card.load_key(
|
||||
key_type = constants.LoadKeyType.LEE_SEED,
|
||||
lee_seed = seed
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Error loading mnemonic: {e}") from e
|
||||
|
||||
def disconnect(self) -> bool:
|
||||
try:
|
||||
if not self.card.is_secure_channel_open:
|
||||
return False
|
||||
|
||||
self.card.unpair(self.pairing_index)
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Error during disconnect: {e}") from e
|
||||
|
||||
def get_public_key_for_path(self, path: str = "m/44'/60'/0'/0/0") -> bytes | None:
|
||||
try:
|
||||
if not self.card.is_secure_channel_open or not self.card.is_pin_verified:
|
||||
return None
|
||||
|
||||
public_key = self.card.export_key(
|
||||
derivation_option = constants.DerivationOption.DERIVE,
|
||||
public_only = True,
|
||||
keypath = path
|
||||
)
|
||||
|
||||
public_key = public_key.public_key
|
||||
public_key = VerifyingKey.from_string(public_key[1:], curve=SECP256k1)
|
||||
public_key = public_key.to_string("compressed")[1:]
|
||||
|
||||
return public_key
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Error getting public key: {e}") from e
|
||||
|
||||
|
||||
def sign_message_for_path(self, message: bytes, path: str = "m/44'/60'/0'/0/0") -> bytes | None:
|
||||
try:
|
||||
if not self.card.is_secure_channel_open or not self.card.is_pin_verified:
|
||||
return None
|
||||
|
||||
signature = self.card.sign_with_path(
|
||||
digest = message,
|
||||
path = path,
|
||||
algorithm = constants.SigningAlgorithm.SCHNORR_BIP340,
|
||||
make_current = False
|
||||
)
|
||||
|
||||
return signature.signature
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Error signing message: {e}") from e
|
||||
@ -12,8 +12,11 @@ pub fn add_python_path(py: Python<'_>) -> PyResult<()> {
|
||||
.unwrap_or_else(|| current_dir.clone());
|
||||
|
||||
let mut paths_to_add: Vec<PathBuf> = vec![
|
||||
python_base.join("python"),
|
||||
python_base.join("python").join("keycard-py"),
|
||||
python_base.join("keycard_wallet").join("python"),
|
||||
python_base
|
||||
.join("keycard_wallet")
|
||||
.join("python")
|
||||
.join("keycard-py"),
|
||||
];
|
||||
|
||||
// If a virtualenv is active, add its site-packages so that dependencies
|
||||
|
||||
@ -236,7 +236,7 @@ impl WalletSubcommand for AccountSubcommand {
|
||||
let account_id: nssa::AccountId = account_id_str.parse()?;
|
||||
|
||||
// Add account id to the display for keycard users.
|
||||
log::info!("Account Id: {resolved}");
|
||||
println!("Account Id: {resolved}");
|
||||
|
||||
if let Some(label) = wallet_core.storage.labels.get(&account_id_str) {
|
||||
println!("Label: {label}");
|
||||
|
||||
@ -1,10 +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
|
||||
git clone --branch lee-schnorr --single-branch https://github.com/bitgamma/keycard-py.git keycard_wallet/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
|
||||
pip install -e keycard_wallet/python/keycard-py
|
||||
Loading…
x
Reference in New Issue
Block a user