mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-14 03:59:30 +00:00
122 lines
4.4 KiB
Rust
122 lines
4.4 KiB
Rust
use common::{HashType, transaction::NSSATransaction};
|
|
use keycard_wallet::KeycardWallet;
|
|
use nssa::{
|
|
AccountId, PublicTransaction,
|
|
program::Program,
|
|
public_transaction::{Message, WitnessSet},
|
|
};
|
|
use sequencer_service_rpc::RpcClient as _;
|
|
|
|
use super::NativeTokenTransfer;
|
|
use crate::{ExecutionFailureKind, WalletCore};
|
|
|
|
impl NativeTokenTransfer<'_> {
|
|
pub async fn send_public_transfer(
|
|
&self,
|
|
from: AccountId,
|
|
to: AccountId,
|
|
balance_to_move: u128,
|
|
pin: &Option<String>,
|
|
key_path: &Option<String>,
|
|
) -> Result<HashType, ExecutionFailureKind> {
|
|
let balance = self
|
|
.0
|
|
.get_account_balance(from)
|
|
.await
|
|
.map_err(ExecutionFailureKind::SequencerError)?;
|
|
|
|
if balance < balance_to_move {
|
|
return Err(ExecutionFailureKind::InsufficientFundsError);
|
|
}
|
|
|
|
let account_ids = vec![from, to];
|
|
let program_id = Program::authenticated_transfer_program().id();
|
|
|
|
// Fetch nonces for both accounts unconditionally
|
|
let nonces = self
|
|
.0
|
|
.get_accounts_nonces(account_ids.clone())
|
|
.await
|
|
.map_err(ExecutionFailureKind::SequencerError)?;
|
|
|
|
let message = Message::try_new(program_id, account_ids, nonces, balance_to_move).unwrap();
|
|
|
|
let witness_set = pin.as_ref().map_or_else(|| {
|
|
let sign_ids = self.0.filter_owned_accounts(&[from, to]);
|
|
WalletCore::sign_public_message(self.0, &message, &sign_ids)
|
|
.expect("`WalletCore::sign_public_message() failed to produce a signature for a NativeTokenTransfer.")
|
|
}, |pin| {
|
|
let key_path = key_path.as_ref().expect("`NativeTokenTransfer::send_public_transfer() expected a String for `key_path`.");
|
|
let pub_key = KeycardWallet::get_public_key_for_path_with_connect(
|
|
pin,
|
|
key_path,
|
|
);
|
|
let signature = KeycardWallet::sign_message_for_path_with_connect(
|
|
pin,
|
|
key_path,
|
|
&message.hash_message(),
|
|
)
|
|
.expect("`NativeTokenTransfer::send_public_transfer() failed to produce a Signature for the given `pin` and `key_path`.");
|
|
WitnessSet::from_list(&[signature], &[pub_key])
|
|
});
|
|
|
|
let tx = PublicTransaction::new(message, witness_set);
|
|
|
|
Ok(self
|
|
.0
|
|
.sequencer_client
|
|
.send_transaction(NSSATransaction::Public(tx))
|
|
.await?)
|
|
}
|
|
|
|
pub async fn register_account(
|
|
&self,
|
|
from: AccountId,
|
|
pin: &Option<String>, // Used by Keycard.
|
|
key_path: &Option<String>, // Used by Keycard.
|
|
) -> Result<HashType, ExecutionFailureKind> {
|
|
let nonces = self
|
|
.0
|
|
.get_accounts_nonces(vec![from])
|
|
.await
|
|
.map_err(ExecutionFailureKind::SequencerError)?;
|
|
|
|
let instruction: u128 = 0;
|
|
let account_ids = vec![from];
|
|
let program_id = Program::authenticated_transfer_program().id();
|
|
let message = Message::try_new(program_id, account_ids, nonces, instruction)
|
|
.expect("Expect a valid Message");
|
|
|
|
let witness_set = if pin.is_none() {
|
|
let signing_key = self.0.storage.user_data.get_pub_account_signing_key(from);
|
|
|
|
let Some(signing_key) = signing_key else {
|
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
};
|
|
|
|
WitnessSet::for_message(&message, &[signing_key])
|
|
} else {
|
|
let pub_key = KeycardWallet::get_public_key_for_path_with_connect(
|
|
pin.as_ref().expect("Expect a pin as a String."),
|
|
key_path.as_ref().expect("Expect a key path String."),
|
|
);
|
|
|
|
let signature = KeycardWallet::sign_message_for_path_with_connect(
|
|
pin.as_ref().as_ref().expect("Expect a pin as a String."),
|
|
key_path.as_ref().expect("Expect a key path String."),
|
|
&message.hash_message(),
|
|
)
|
|
.expect("Expect a valid Signature.");
|
|
WitnessSet::from_list(&[signature], &[pub_key])
|
|
};
|
|
|
|
let tx = PublicTransaction::new(message, witness_set);
|
|
|
|
Ok(self
|
|
.0
|
|
.sequencer_client
|
|
.send_transaction(NSSATransaction::Public(tx))
|
|
.await?)
|
|
}
|
|
}
|