mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-16 13:09:33 +00:00
compile error fixed
This commit is contained in:
parent
d2b6597119
commit
dd4ee70797
@ -64,14 +64,13 @@ unset KEYCARD_PIN
|
||||
|
||||
### Keycard
|
||||
|
||||
| Command | Description |
|
||||
|-----------------------------------|--------------------------------------------------------------------------|
|
||||
| `wallet keycard available` | Checks whether a Keycard reader and card are accessible |
|
||||
| `wallet keycard init` | Initializes a blank Keycard with a PIN and a generated PUK |
|
||||
| `wallet keycard connect` | Establishes and saves a pairing with the Keycard |
|
||||
| `wallet keycard disconnect` | Unpairs the Keycard and clears the saved pairing |
|
||||
| `wallet keycard load` | Loads a mnemonic phrase onto the Keycard |
|
||||
| `wallet keycard get-private-keys` | Retrieves private account keys (nsk, vsk) for a given BIP32 path |
|
||||
| Command | Description |
|
||||
|-----------------------------|------------------------------------------------------------|
|
||||
| `wallet keycard available` | Checks whether a Keycard reader and card are accessible |
|
||||
| `wallet keycard init` | Initializes a blank Keycard with a PIN and a generated PUK |
|
||||
| `wallet keycard connect` | Establishes and saves a pairing with the Keycard |
|
||||
| `wallet keycard disconnect` | Unpairs the Keycard and clears the saved pairing |
|
||||
| `wallet keycard load` | Loads a mnemonic phrase onto the Keycard |
|
||||
|
||||
1. Check keycard availability
|
||||
```bash
|
||||
@ -114,17 +113,7 @@ Keycard PIN:
|
||||
✅ Mnemonic phrase loaded successfully.
|
||||
```
|
||||
|
||||
5. 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
|
||||
```
|
||||
|
||||
6. Disconnect (unpair and clear saved pairing)
|
||||
5. Disconnect (unpair and clear saved pairing)
|
||||
```bash
|
||||
wallet keycard disconnect
|
||||
|
||||
@ -172,7 +161,7 @@ Transaction hash is 2c8a4f1e903d5b76e80214c5b82e1d46a105e28930ad71bcce48f2d07b49
|
||||
| `wallet auth-transfer init` | Registers an account with the auth-transfer program |
|
||||
| `wallet auth-transfer send` | Sends native tokens between accounts |
|
||||
|
||||
`--account` (for `init`) and `--from`/`--to` (for `send`) each accept any of:
|
||||
`--account-id` (for `init`) and `--from`/`--to` (for `send`) each accept any of:
|
||||
- A BIP32 key path — uses Keycard (e.g. `m/44'/60'/0'/0/0`)
|
||||
- An account ID with privacy prefix (e.g. `Public/9bKm...`)
|
||||
- An account label (e.g. `my-account`)
|
||||
@ -181,7 +170,7 @@ For `send`, foreign recipient accounts (not in the local wallet and not a Keycar
|
||||
|
||||
1. Initialize a Keycard public account
|
||||
```bash
|
||||
wallet auth-transfer init --account "m/44'/60'/0'/0/0"
|
||||
wallet auth-transfer init --account-id "m/44'/60'/0'/0/0"
|
||||
|
||||
# Output:
|
||||
Keycard PIN:
|
||||
|
||||
@ -16,8 +16,8 @@ export KEYCARD_MNEMONIC="fashion degree mountain wool question damp current pond
|
||||
wallet keycard load
|
||||
unset KEYCARD_MNEMONIC
|
||||
|
||||
echo "Test: wallet auth-transfer init --account \"m/44'/60'/0'/0/0\""
|
||||
wallet auth-transfer init --account "m/44'/60'/0'/0/0"
|
||||
echo "Test: wallet auth-transfer init --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet auth-transfer init --account-id "m/44'/60'/0'/0/0"
|
||||
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet account get --account-id "m/44'/60'/0'/0/0"
|
||||
@ -29,7 +29,7 @@ echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet account get --account-id "m/44'/60'/0'/0/0"
|
||||
|
||||
echo "Test: wallet auth-transfer init and send between two keycard accounts"
|
||||
wallet auth-transfer init --account "m/44'/60'/0'/0/1"
|
||||
wallet auth-transfer init --account-id "m/44'/60'/0'/0/1"
|
||||
wallet auth-transfer send --amount 40 --from "m/44'/60'/0'/0/0" --to "m/44'/60'/0'/0/1"
|
||||
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
@ -38,9 +38,44 @@ wallet account get --account-id "m/44'/60'/0'/0/0"
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/1\""
|
||||
wallet account get --account-id "m/44'/60'/0'/0/1"
|
||||
|
||||
# Send from keycard account to a local wallet account
|
||||
echo "Test: create local wallet account"
|
||||
LOCAL_ACCOUNT_ID=$(wallet account new public 2>&1 | grep -oP '(?<=Public/)\S+')
|
||||
echo "Created local account: Public/${LOCAL_ACCOUNT_ID}"
|
||||
|
||||
echo "Test: wallet auth-transfer init local account"
|
||||
wallet auth-transfer init --account-id "Public/${LOCAL_ACCOUNT_ID}"
|
||||
|
||||
|
||||
echo "Test: wallet auth-transfer send from keycard to local account"
|
||||
wallet auth-transfer send --amount 10 --from "m/44'/60'/0'/0/0" --to "Public/${LOCAL_ACCOUNT_ID}"
|
||||
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet account get --account-id "m/44'/60'/0'/0/0"
|
||||
|
||||
echo "Test: wallet account get --account-id \"Public/${LOCAL_ACCOUNT_ID}\""
|
||||
wallet account get --account-id "Public/${LOCAL_ACCOUNT_ID}"
|
||||
|
||||
# Create a local wallet account, fund it, and send to keycard account (co-signed: local key + keycard)
|
||||
|
||||
echo "Test: wallet auth-transfer send from local account to keycard account"
|
||||
wallet auth-transfer send --amount 10 --from "Public/${LOCAL_ACCOUNT_ID}" --to "m/44'/60'/0'/0/1"
|
||||
|
||||
echo "Test: wallet account get --account-id \"Public/${LOCAL_ACCOUNT_ID}\""
|
||||
wallet account get --account-id "Public/${LOCAL_ACCOUNT_ID}"
|
||||
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/1\""
|
||||
wallet account get --account-id "m/44'/60'/0'/0/1"
|
||||
|
||||
# Send from keycard account to a local wallet account (foreign recipient — no signature needed)
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet account get --account-id "Public/7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo"
|
||||
|
||||
echo "Test: wallet auth-transfer send from keycard to local account"
|
||||
wallet auth-transfer send --amount 10 --from "m/44'/60'/0'/0/0" --to "Public/7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo"
|
||||
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet account get --account-id "m/44'/60'/0'/0/0"
|
||||
|
||||
echo "Test: wallet account get --account-id \"m/44'/60'/0'/0/0\""
|
||||
wallet account get --account-id "Public/7wHg9sbJwc6h3NP1S9bekfAzB8CHifEcxKswCKUt3YQo"
|
||||
|
||||
@ -67,7 +67,10 @@ impl KeycardWallet {
|
||||
) -> PyResult<bool> {
|
||||
self.instance
|
||||
.bind(py)
|
||||
.call_method1("setup_communication_with_pairing", (pin, index, key.to_vec()))?
|
||||
.call_method1(
|
||||
"setup_communication_with_pairing",
|
||||
(pin, index, key.to_vec()),
|
||||
)?
|
||||
.extract()
|
||||
}
|
||||
|
||||
@ -197,7 +200,11 @@ impl KeycardWallet {
|
||||
fn pairing_file_path() -> Option<PathBuf> {
|
||||
let home = std::env::var("NSSA_WALLET_HOME_DIR")
|
||||
.map(PathBuf::from)
|
||||
.or_else(|_| std::env::home_dir().map(|h| h.join(".nssa").join("wallet")).ok_or(()))
|
||||
.or_else(|_| {
|
||||
std::env::home_dir()
|
||||
.map(|h| h.join(".nssa").join("wallet"))
|
||||
.ok_or(())
|
||||
})
|
||||
.ok()?;
|
||||
Some(home.join("keycard_pairing.json"))
|
||||
}
|
||||
|
||||
@ -4,8 +4,7 @@ use std::{ffi::CString, ptr};
|
||||
|
||||
use nssa::AccountId;
|
||||
use wallet::{
|
||||
account::AccountIdWithPrivacy,
|
||||
cli::CliAccountMention,
|
||||
account::AccountIdWithPrivacy, cli::CliAccountMention,
|
||||
program_facades::native_token_transfer::NativeTokenTransfer,
|
||||
};
|
||||
|
||||
@ -79,7 +78,13 @@ pub unsafe extern "C" fn wallet_ffi_transfer_public(
|
||||
let from_mention = CliAccountMention::Id(AccountIdWithPrivacy::Public(from_id));
|
||||
let to_mention = CliAccountMention::Id(AccountIdWithPrivacy::Public(to_id));
|
||||
|
||||
match block_on(transfer.send_public_transfer(from_id, to_id, amount, &from_mention, &to_mention)) {
|
||||
match block_on(transfer.send_public_transfer(
|
||||
from_id,
|
||||
to_id,
|
||||
amount,
|
||||
&from_mention,
|
||||
&to_mention,
|
||||
)) {
|
||||
Ok(tx_hash) => {
|
||||
let tx_hash = CString::new(tx_hash.to_string())
|
||||
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
|
||||
|
||||
@ -52,7 +52,8 @@ impl WalletSubcommand for KeycardSubcommand {
|
||||
let wallet = KeycardWallet::new(py)
|
||||
.expect("`wallet::keycard::connect`: invalid keycard wallet provided");
|
||||
|
||||
wallet.connect(py, &pin)
|
||||
wallet
|
||||
.connect(py, &pin)
|
||||
.expect("`wallet::keycard::connect`: failed to connect to keycard");
|
||||
|
||||
println!("\u{2705} Keycard paired and ready.");
|
||||
@ -70,10 +71,12 @@ impl WalletSubcommand for KeycardSubcommand {
|
||||
let wallet = KeycardWallet::new(py)
|
||||
.expect("`wallet::keycard::disconnect`: invalid keycard wallet provided");
|
||||
|
||||
wallet.connect(py, &pin)
|
||||
wallet
|
||||
.connect(py, &pin)
|
||||
.expect("`wallet::keycard::disconnect`: failed to open session");
|
||||
|
||||
wallet.disconnect(py)
|
||||
wallet
|
||||
.disconnect(py)
|
||||
.expect("`wallet::keycard::disconnect`: failed to unpair keycard");
|
||||
|
||||
clear_pairing();
|
||||
@ -91,7 +94,8 @@ impl WalletSubcommand for KeycardSubcommand {
|
||||
let wallet = KeycardWallet::new(py)
|
||||
.expect("`wallet::keycard::init`: invalid keycard wallet provided");
|
||||
|
||||
let initialized = wallet.initialize(py, &pin)
|
||||
let initialized = wallet
|
||||
.initialize(py, &pin)
|
||||
.expect("`wallet::keycard::init`: failed to initialize keycard");
|
||||
|
||||
if initialized {
|
||||
@ -112,7 +116,8 @@ impl WalletSubcommand for KeycardSubcommand {
|
||||
let wallet = KeycardWallet::new(py)
|
||||
.expect("`wallet::keycard::load`: invalid keycard wallet provided");
|
||||
|
||||
wallet.connect(py, &pin)
|
||||
wallet
|
||||
.connect(py, &pin)
|
||||
.expect("`wallet::keycard::load`: failed to connect to keycard");
|
||||
|
||||
println!("\u{2705} Keycard is now connected to wallet.");
|
||||
|
||||
@ -9,6 +9,7 @@ use futures::TryFutureExt as _;
|
||||
use nssa::{ProgramDeploymentTransaction, program::Program};
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
|
||||
pub use crate::helperfunctions::{read_mnemonic, read_pin};
|
||||
use crate::{
|
||||
WalletCore,
|
||||
account::{AccountIdWithPrivacy, Label},
|
||||
@ -27,8 +28,6 @@ use crate::{
|
||||
storage::Storage,
|
||||
};
|
||||
|
||||
pub use crate::helperfunctions::{read_mnemonic, read_pin};
|
||||
|
||||
pub mod account;
|
||||
pub mod chain;
|
||||
pub mod config;
|
||||
@ -138,8 +137,9 @@ impl CliAccountMention {
|
||||
.ok_or_else(|| anyhow::anyhow!("No account found for label `{label}`")),
|
||||
Self::KeyPath(path) => {
|
||||
let pin = read_pin()?;
|
||||
let id_str = keycard_wallet::KeycardWallet::get_account_id_for_path_with_connect(&pin, path)
|
||||
.map_err(anyhow::Error::from)?;
|
||||
let id_str =
|
||||
keycard_wallet::KeycardWallet::get_account_id_for_path_with_connect(&pin, path)
|
||||
.map_err(anyhow::Error::from)?;
|
||||
AccountIdWithPrivacy::from_str(&id_str)
|
||||
.map_err(|e| anyhow::anyhow!("Invalid account id from keycard: {e}"))
|
||||
}
|
||||
@ -175,18 +175,25 @@ impl CliAccountMention {
|
||||
|
||||
/// Resolve to an [`AccountSigner`] for a recipient — returns `Foreign` when the account
|
||||
/// has no local key and no keycard path, meaning no signature or nonce is required.
|
||||
pub fn to_recipient_signer(&self, wallet_core: &WalletCore) -> Result<crate::signing::AccountSigner> {
|
||||
pub fn to_recipient_signer(
|
||||
&self,
|
||||
wallet_core: &WalletCore,
|
||||
) -> Result<crate::signing::AccountSigner> {
|
||||
if let Self::KeyPath(path) = self {
|
||||
return Ok(crate::signing::AccountSigner::Keycard(path.clone()));
|
||||
}
|
||||
let account = self.resolve(wallet_core.storage())?;
|
||||
match account {
|
||||
AccountIdWithPrivacy::Public(id) => {
|
||||
Ok(match wallet_core.storage().key_chain().pub_account_signing_key(id) {
|
||||
AccountIdWithPrivacy::Public(id) => Ok(
|
||||
match wallet_core
|
||||
.storage()
|
||||
.key_chain()
|
||||
.pub_account_signing_key(id)
|
||||
{
|
||||
Some(_) => crate::signing::AccountSigner::Local(id),
|
||||
None => crate::signing::AccountSigner::Foreign,
|
||||
})
|
||||
}
|
||||
},
|
||||
),
|
||||
AccountIdWithPrivacy::Private(_) => {
|
||||
anyhow::bail!("Private accounts not supported as recipients here")
|
||||
}
|
||||
|
||||
@ -58,9 +58,9 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
Self::Init { account_id } => {
|
||||
let resolved = account_id.resolve(wallet_core.storage())?;
|
||||
match resolved {
|
||||
AccountIdWithPrivacy::Public(account_id) => {
|
||||
AccountIdWithPrivacy::Public(pub_account_id) => {
|
||||
let tx_hash = NativeTokenTransfer(wallet_core)
|
||||
.register_account(account_id, &account)
|
||||
.register_account(pub_account_id, &account_id)
|
||||
.await?;
|
||||
|
||||
println!("Transaction hash is {tx_hash}");
|
||||
@ -124,7 +124,13 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
}
|
||||
(Some(to), None, None) => match (from, to) {
|
||||
(AccountIdWithPrivacy::Public(from), AccountIdWithPrivacy::Public(to)) => {
|
||||
NativeTokenTransferProgramSubcommand::Public { from, to, amount }
|
||||
NativeTokenTransferProgramSubcommand::Public {
|
||||
from,
|
||||
to,
|
||||
amount,
|
||||
from_mention: from_account,
|
||||
to_mention: to_account.expect("matched Some branch"),
|
||||
}
|
||||
}
|
||||
(
|
||||
AccountIdWithPrivacy::Private(from),
|
||||
@ -481,7 +487,13 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommand {
|
||||
|
||||
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
|
||||
}
|
||||
Self::Public { from, to, amount, from_mention, to_mention } => {
|
||||
Self::Public {
|
||||
from,
|
||||
to,
|
||||
amount,
|
||||
from_mention,
|
||||
to_mention,
|
||||
} => {
|
||||
let tx_hash = NativeTokenTransfer(wallet_core)
|
||||
.send_public_transfer(from, to, amount, &from_mention, &to_mention)
|
||||
.await?;
|
||||
|
||||
@ -10,9 +10,7 @@ use sequencer_service_rpc::RpcClient as _;
|
||||
|
||||
use super::NativeTokenTransfer;
|
||||
use crate::{
|
||||
ExecutionFailureKind,
|
||||
cli::CliAccountMention,
|
||||
helperfunctions::read_pin,
|
||||
ExecutionFailureKind, cli::CliAccountMention, helperfunctions::read_pin,
|
||||
signing::KeycardSessionContext,
|
||||
};
|
||||
|
||||
@ -25,13 +23,12 @@ impl NativeTokenTransfer<'_> {
|
||||
from_mention: &CliAccountMention,
|
||||
to_mention: &CliAccountMention,
|
||||
) -> Result<HashType, ExecutionFailureKind> {
|
||||
|
||||
let from_signer = from_mention
|
||||
.to_signer(self.0)
|
||||
.map_err(|e| ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string())))?;
|
||||
let to_signer = to_mention
|
||||
.to_recipient_signer(self.0)
|
||||
.map_err(|e| ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string())))?;
|
||||
let from_signer = from_mention.to_signer(self.0).map_err(|e| {
|
||||
ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string()))
|
||||
})?;
|
||||
let to_signer = to_mention.to_recipient_signer(self.0).map_err(|e| {
|
||||
ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string()))
|
||||
})?;
|
||||
|
||||
let account_ids = vec![from, to];
|
||||
let signing_ids: Vec<AccountId> = if to_signer.needs_signature() {
|
||||
@ -51,13 +48,19 @@ impl NativeTokenTransfer<'_> {
|
||||
program_id,
|
||||
account_ids,
|
||||
nonces,
|
||||
AuthTransferInstruction::Transfer { amount: balance_to_move },
|
||||
AuthTransferInstruction::Transfer {
|
||||
amount: balance_to_move,
|
||||
},
|
||||
)
|
||||
.map_err(ExecutionFailureKind::TransactionBuildError)?;
|
||||
|
||||
let pin = if from_mention.is_keycard() || to_mention.is_keycard() {
|
||||
read_pin()
|
||||
.map_err(|e| ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string())))?
|
||||
.map_err(|e| {
|
||||
ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(
|
||||
e.to_string(),
|
||||
))
|
||||
})?
|
||||
.as_str()
|
||||
.to_owned()
|
||||
} else {
|
||||
@ -93,34 +96,6 @@ impl NativeTokenTransfer<'_> {
|
||||
.sequencer_client
|
||||
.send_transaction(NSSATransaction::Public(tx))
|
||||
.await?)
|
||||
} else {
|
||||
println!(
|
||||
"Receiver's account ({to}) private key not found in wallet. Proceeding with only sender's key."
|
||||
);
|
||||
}
|
||||
|
||||
let message = Message::try_new(
|
||||
program_id,
|
||||
account_ids,
|
||||
nonces,
|
||||
AuthTransferInstruction::Transfer {
|
||||
amount: balance_to_move,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let witness_set = WitnessSet::for_message(&message, &private_keys);
|
||||
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self
|
||||
.0
|
||||
.sequencer_client
|
||||
.send_transaction(NSSATransaction::Public(tx))
|
||||
.await?)
|
||||
} else {
|
||||
Err(ExecutionFailureKind::InsufficientFundsError)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub async fn register_account(
|
||||
@ -144,13 +119,17 @@ impl NativeTokenTransfer<'_> {
|
||||
)
|
||||
.map_err(ExecutionFailureKind::TransactionBuildError)?;
|
||||
|
||||
let signer = account_mention
|
||||
.to_signer(self.0)
|
||||
.map_err(|e| ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string())))?;
|
||||
let signer = account_mention.to_signer(self.0).map_err(|e| {
|
||||
ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string()))
|
||||
})?;
|
||||
|
||||
let pin = if account_mention.is_keycard() {
|
||||
read_pin()
|
||||
.map_err(|e| ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(e.to_string())))?
|
||||
.map_err(|e| {
|
||||
ExecutionFailureKind::KeycardError(pyo3::PyErr::new::<PyRuntimeError, _>(
|
||||
e.to_string(),
|
||||
))
|
||||
})?
|
||||
.as_str()
|
||||
.to_owned()
|
||||
} else {
|
||||
|
||||
@ -34,8 +34,19 @@ impl AccountSigner {
|
||||
) -> Option<Result<(Signature, PublicKey)>> {
|
||||
match self {
|
||||
Self::Local(id) => {
|
||||
let key = wallet_core.storage().key_chain().pub_account_signing_key(*id)?;
|
||||
Some(Ok((Signature::new(key, hash), PublicKey::new_from_private_key(key))))
|
||||
let key = wallet_core
|
||||
.storage()
|
||||
.key_chain()
|
||||
.pub_account_signing_key(*id);
|
||||
Some(key.map_or_else(
|
||||
|| Err(anyhow::anyhow!("signing key not found for account {id}")),
|
||||
|key| {
|
||||
Ok((
|
||||
Signature::new(key, hash),
|
||||
PublicKey::new_from_private_key(key),
|
||||
))
|
||||
},
|
||||
))
|
||||
}
|
||||
Self::Keycard(path) => Some(
|
||||
ctx.get_or_connect(py)
|
||||
@ -55,10 +66,16 @@ pub struct KeycardSessionContext {
|
||||
|
||||
impl KeycardSessionContext {
|
||||
pub fn new(pin: impl Into<String>) -> Self {
|
||||
Self { pin: pin.into(), wallet: None }
|
||||
Self {
|
||||
pin: pin.into(),
|
||||
wallet: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_or_connect<'py>(&'py mut self, py: Python<'py>) -> pyo3::PyResult<&'py KeycardWallet> {
|
||||
pub fn get_or_connect<'py>(
|
||||
&'py mut self,
|
||||
py: Python<'py>,
|
||||
) -> pyo3::PyResult<&'py KeycardWallet> {
|
||||
if self.wallet.is_none() {
|
||||
python_path::add_python_path(py)?;
|
||||
let wallet = KeycardWallet::new(py)?;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user