use std::io::Write;
use color_eyre::eyre::Context;
use inquire::CustomType;
use super::super::commands::transaction::send_meta_transaction::FileSignedMetaTransaction;
use super::super::commands::transaction::send_signed_transaction::FileSignedTransaction;
#[derive(Debug, Clone, interactive_clap_derive::InteractiveClap)]
#[interactive_clap(input_context = super::SubmitContext)]
#[interactive_clap(output_context = SaveToFileContext)]
pub struct SaveToFile {
#[interactive_clap(skip_default_input_arg)]
file_path: crate::types::path_buf::PathBuf,
}
#[derive(Debug, Clone)]
pub struct SaveToFileContext;
impl SaveToFileContext {
pub fn from_previous_context(
previous_context: super::SubmitContext,
scope: &<SaveToFile as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
) -> color_eyre::eyre::Result<Self> {
let file_path: std::path::PathBuf = scope.file_path.clone().into();
let storage_message = (previous_context.on_before_sending_transaction_callback)(
&previous_context.signed_transaction_or_signed_delegate_action,
&previous_context.network_config,
)
.map_err(color_eyre::Report::msg)?;
match previous_context.signed_transaction_or_signed_delegate_action {
super::SignedTransactionOrSignedDelegateAction::SignedTransaction(
signed_transaction,
) => {
let data_signed_transaction =
serde_json::to_value(FileSignedTransaction { signed_transaction })?;
std::fs::File::create(&file_path)
.wrap_err_with(|| format!("Failed to create file: {:?}", &file_path))?
.write(&serde_json::to_vec(&data_signed_transaction)?)
.wrap_err_with(|| format!("Failed to write to file: {:?}", &file_path))?;
eprintln!(
"\nThe file {:?} was created successfully. It has a signed transaction (serialized as base64).",
&file_path
);
eprintln!(
"This base64-encoded signed transaction is ready to be sent to the network. You can call RPC server directly, or use a helper command on near CLI:\n$ {} transaction send-signed-transaction\n",
crate::common::get_near_exec_path()
);
eprintln!("{storage_message}");
}
super::SignedTransactionOrSignedDelegateAction::SignedDelegateAction(
signed_delegate_action,
) => {
let data_signed_delegate_action =
serde_json::to_value(&FileSignedMetaTransaction {
signed_delegate_action: signed_delegate_action.into(),
})?;
std::fs::File::create(&file_path)
.wrap_err_with(|| format!("Failed to create file: {:?}", &file_path))?
.write(&serde_json::to_vec(&data_signed_delegate_action)?)
.wrap_err_with(|| format!("Failed to write to file: {:?}", &file_path))?;
eprintln!(
"\nThe file {:?} was created successfully. It has a signed delegate action (serialized as base64).",
&file_path
);
eprintln!(
"This base64-encoded signed delegate action is ready to be sent to the meta-transaction relayer. There is a helper command on near CLI that can do that:\n$ {} transaction send-meta-transaction\n",
crate::common::get_near_exec_path()
);
eprintln!("{storage_message}");
}
}
Ok(Self)
}
}
impl SaveToFile {
fn input_file_path(
context: &super::SubmitContext,
) -> color_eyre::eyre::Result<Option<crate::types::path_buf::PathBuf>> {
let starting_input = match &context.signed_transaction_or_signed_delegate_action {
super::SignedTransactionOrSignedDelegateAction::SignedTransaction(_) => {
"signed-transaction-info.json"
}
super::SignedTransactionOrSignedDelegateAction::SignedDelegateAction(_) => {
"signed-meta-transaction-info.json"
}
};
Ok(Some(
CustomType::new(
"What is the location of the file to save the transaction information?",
)
.with_starting_input(starting_input)
.prompt()?,
))
}
}