use casper_types::{
account::AccountHash, AsymmetricType, Deploy, PublicKey, TransferTarget, UIntParseError, URef,
U512,
};
use super::{
parse, transaction::get_maybe_secret_key, CliError, DeployStrParams, PaymentStrParams,
SessionStrParams,
};
use crate::{
cli::DeployBuilder,
rpcs::results::{PutDeployResult, SpeculativeExecResult},
SuccessResponse, MAX_SERIALIZED_SIZE_OF_DEPLOY,
};
const DEFAULT_GAS_PRICE: u64 = 1;
pub async fn put_deploy(
maybe_rpc_id: &str,
node_address: &str,
verbosity_level: u64,
deploy_params: DeployStrParams<'_>,
session_params: SessionStrParams<'_>,
payment_params: PaymentStrParams<'_>,
) -> Result<SuccessResponse<PutDeployResult>, CliError> {
let rpc_id = parse::rpc_id(maybe_rpc_id);
let verbosity = parse::verbosity(verbosity_level);
let deploy = with_payment_and_session(deploy_params, payment_params, session_params, false)?;
#[allow(deprecated)]
crate::put_deploy(rpc_id, node_address, verbosity, deploy)
.await
.map_err(CliError::from)
}
pub async fn speculative_put_deploy(
maybe_rpc_id: &str,
node_address: &str,
verbosity_level: u64,
deploy_params: DeployStrParams<'_>,
session_params: SessionStrParams<'_>,
payment_params: PaymentStrParams<'_>,
) -> Result<SuccessResponse<SpeculativeExecResult>, CliError> {
let rpc_id = parse::rpc_id(maybe_rpc_id);
let verbosity = parse::verbosity(verbosity_level);
let deploy = with_payment_and_session(deploy_params, payment_params, session_params, false)?;
#[allow(deprecated)]
crate::speculative_exec(rpc_id, node_address, verbosity, deploy)
.await
.map_err(CliError::from)
}
pub fn make_deploy(
#[allow(unused_variables)] maybe_output_path: &str,
deploy_params: DeployStrParams<'_>,
session_params: SessionStrParams<'_>,
payment_params: PaymentStrParams<'_>,
#[allow(unused_variables)] force: bool,
) -> Result<Deploy, CliError> {
let deploy = with_payment_and_session(deploy_params, payment_params, session_params, true)?;
#[cfg(feature = "std-fs-io")]
{
let output = parse::output_kind(maybe_output_path, force);
#[allow(deprecated)]
crate::output_deploy(output, &deploy).map_err(CliError::from)?;
}
Ok(deploy)
}
#[cfg(feature = "std-fs-io")]
pub fn sign_deploy_file(
input_path: &str,
secret_key_path: &str,
maybe_output_path: &str,
force: bool,
) -> Result<(), CliError> {
let secret_key = parse::secret_key_from_file(secret_key_path)?;
let output = parse::output_kind(maybe_output_path, force);
#[allow(deprecated)]
crate::sign_deploy_file(input_path, &secret_key, output).map_err(CliError::from)
}
#[cfg(feature = "std-fs-io")]
pub async fn send_deploy_file(
maybe_rpc_id: &str,
node_address: &str,
verbosity_level: u64,
input_path: &str,
) -> Result<SuccessResponse<PutDeployResult>, CliError> {
let rpc_id = parse::rpc_id(maybe_rpc_id);
let verbosity = parse::verbosity(verbosity_level);
#[allow(deprecated)]
let deploy = crate::read_deploy_file(input_path)?;
#[allow(deprecated)]
crate::put_deploy(rpc_id, node_address, verbosity, deploy)
.await
.map_err(CliError::from)
}
#[cfg(feature = "std-fs-io")]
pub async fn speculative_send_deploy_file(
maybe_rpc_id: &str,
node_address: &str,
verbosity_level: u64,
input_path: &str,
) -> Result<SuccessResponse<SpeculativeExecResult>, CliError> {
let rpc_id = parse::rpc_id(maybe_rpc_id);
let verbosity = parse::verbosity(verbosity_level);
#[allow(deprecated)]
let deploy = crate::read_deploy_file(input_path)?;
#[allow(deprecated)]
crate::speculative_exec(rpc_id, node_address, verbosity, deploy)
.await
.map_err(CliError::from)
}
#[allow(clippy::too_many_arguments)]
pub async fn transfer(
maybe_rpc_id: &str,
node_address: &str,
verbosity_level: u64,
amount: &str,
target_account: &str,
transfer_id: &str,
deploy_params: DeployStrParams<'_>,
payment_params: PaymentStrParams<'_>,
) -> Result<SuccessResponse<PutDeployResult>, CliError> {
let rpc_id = parse::rpc_id(maybe_rpc_id);
let verbosity = parse::verbosity(verbosity_level);
let deploy = new_transfer(
amount,
None,
target_account,
transfer_id,
deploy_params,
payment_params,
false,
)?;
#[allow(deprecated)]
crate::put_deploy(rpc_id, node_address, verbosity, deploy)
.await
.map_err(CliError::from)
}
#[allow(clippy::too_many_arguments)]
pub async fn speculative_transfer(
maybe_rpc_id: &str,
node_address: &str,
verbosity_level: u64,
amount: &str,
target_account: &str,
transfer_id: &str,
deploy_params: DeployStrParams<'_>,
payment_params: PaymentStrParams<'_>,
) -> Result<SuccessResponse<SpeculativeExecResult>, CliError> {
let rpc_id = parse::rpc_id(maybe_rpc_id);
let verbosity = parse::verbosity(verbosity_level);
let deploy = new_transfer(
amount,
None,
target_account,
transfer_id,
deploy_params,
payment_params,
false,
)?;
#[allow(deprecated)]
crate::speculative_exec(rpc_id, node_address, verbosity, deploy)
.await
.map_err(CliError::from)
}
pub fn make_transfer(
#[allow(unused_variables)] maybe_output_path: &str,
amount: &str,
target_account: &str,
transfer_id: &str,
deploy_params: DeployStrParams<'_>,
payment_params: PaymentStrParams<'_>,
#[allow(unused_variables)] force: bool,
) -> Result<Deploy, CliError> {
let deploy = new_transfer(
amount,
None,
target_account,
transfer_id,
deploy_params,
payment_params,
true,
)?;
#[cfg(feature = "std-fs-io")]
{
let output = parse::output_kind(maybe_output_path, force);
#[allow(deprecated)]
crate::output_deploy(output, &deploy).map_err(CliError::from)?;
}
Ok(deploy)
}
pub fn with_payment_and_session(
deploy_params: DeployStrParams,
payment_params: PaymentStrParams,
session_params: SessionStrParams,
allow_unsigned_deploy: bool,
) -> Result<Deploy, CliError> {
let gas_price: u64 = deploy_params
.gas_price_tolerance
.parse::<u64>()
.unwrap_or(DEFAULT_GAS_PRICE);
let chain_name = deploy_params.chain_name.to_string();
let session = parse::session_executable_deploy_item(session_params)?;
let payment = parse::payment_executable_deploy_item(payment_params)?;
let timestamp = parse::timestamp(deploy_params.timestamp)?;
let ttl = parse::ttl(deploy_params.ttl)?;
let maybe_session_account = parse::session_account(deploy_params.session_account)?;
let mut deploy_builder = DeployBuilder::new(chain_name, session)
.with_payment(payment)
.with_timestamp(timestamp)
.with_gas_price(gas_price)
.with_ttl(ttl);
let maybe_secret_key = get_maybe_secret_key(
deploy_params.secret_key,
allow_unsigned_deploy,
"with_payment_and_session",
)?;
if let Some(secret_key) = &maybe_secret_key {
deploy_builder = deploy_builder.with_secret_key(secret_key);
}
if let Some(account) = maybe_session_account {
deploy_builder = deploy_builder.with_account(account);
}
let deploy = deploy_builder.build().map_err(crate::Error::from)?;
deploy
.is_valid_size(MAX_SERIALIZED_SIZE_OF_DEPLOY)
.map_err(crate::Error::from)?;
Ok(deploy)
}
pub fn new_transfer(
amount: &str,
source_purse: Option<URef>,
target_account: &str,
transfer_id: &str,
deploy_params: DeployStrParams,
payment_params: PaymentStrParams,
allow_unsigned_deploy: bool,
) -> Result<Deploy, CliError> {
let chain_name = deploy_params.chain_name.to_string();
let payment = parse::payment_executable_deploy_item(payment_params)?;
let amount = U512::from_dec_str(amount).map_err(|err| CliError::FailedToParseUint {
context: "new_transfer amount",
error: UIntParseError::FromDecStr(err),
})?;
let target = if let Ok(public_key) = PublicKey::from_hex(target_account) {
TransferTarget::PublicKey(public_key)
} else if let Ok(account_hash) = AccountHash::from_formatted_str(target_account) {
TransferTarget::AccountHash(account_hash)
} else if let Ok(uref) = URef::from_formatted_str(target_account) {
TransferTarget::URef(uref)
} else {
return Err(CliError::InvalidArgument {
context: "new_transfer target_account",
error: format!(
"allowed types: PublicKey, AccountHash or URef, got {}",
target_account
),
});
};
let transfer_id = parse::transfer_id(transfer_id)?;
let maybe_transfer_id = Some(transfer_id);
let timestamp = parse::timestamp(deploy_params.timestamp)?;
let ttl = parse::ttl(deploy_params.ttl)?;
let maybe_session_account = parse::session_account(deploy_params.session_account)?;
let gas_price: u64 = deploy_params
.gas_price_tolerance
.parse::<u64>()
.unwrap_or(DEFAULT_GAS_PRICE);
let mut deploy_builder =
DeployBuilder::new_transfer(chain_name, amount, source_purse, target, maybe_transfer_id)
.with_payment(payment)
.with_timestamp(timestamp)
.with_gas_price(gas_price)
.with_ttl(ttl);
let maybe_secret_key = get_maybe_secret_key(
deploy_params.secret_key,
allow_unsigned_deploy,
"new_transfer",
)?;
if let Some(secret_key) = &maybe_secret_key {
deploy_builder = deploy_builder.with_secret_key(secret_key);
}
if let Some(account) = maybe_session_account {
deploy_builder = deploy_builder.with_account(account);
}
let deploy = deploy_builder.build().map_err(crate::Error::from)?;
deploy
.is_valid_size(MAX_SERIALIZED_SIZE_OF_DEPLOY)
.map_err(crate::Error::from)?;
Ok(deploy)
}