use js_export_macro::js_export;
use miden_client::Word as NativeWord;
use miden_client::note::{
Note as NativeNote,
NoteDetails as NativeNoteDetails,
NoteRecipient as NativeNoteRecipient,
NoteTag as NativeNoteTag,
};
use miden_client::transaction::{
ForeignAccount as NativeForeignAccount,
NoteArgs as NativeNoteArgs,
TransactionRequestBuilder as NativeTransactionRequestBuilder,
TransactionScript as NativeTransactionScript,
};
use miden_client::vm::AdviceMap as NativeAdviceMap;
use crate::js_error_with_context;
use crate::models::advice_map::AdviceMap;
use crate::models::foreign_account::ForeignAccount;
use crate::models::miden_arrays::{
ForeignAccountArray,
NoteAndArgsArray,
NoteArray,
NoteDetailsAndTagArray,
NoteRecipientArray,
};
use crate::models::note_recipient::NoteRecipient;
use crate::models::transaction_request::TransactionRequest;
use crate::models::transaction_request::note_and_args::NoteAndArgs;
use crate::models::transaction_request::note_details_and_tag::NoteDetailsAndTag;
use crate::models::transaction_script::TransactionScript;
use crate::models::word::Word;
use crate::platform::JsErr;
#[derive(Clone)]
#[js_export]
pub struct TransactionRequestBuilder(NativeTransactionRequestBuilder);
impl TransactionRequestBuilder {
pub(crate) fn new() -> TransactionRequestBuilder {
let native_transaction_request = NativeTransactionRequestBuilder::new();
TransactionRequestBuilder(native_transaction_request)
}
}
#[js_export]
impl TransactionRequestBuilder {
#[js_export(constructor)]
pub fn js_new() -> TransactionRequestBuilder {
TransactionRequestBuilder::new()
}
#[js_export(js_name = "withInputNotes")]
pub fn with_input_notes(&mut self, notes: NoteAndArgsArray) -> Self {
let items: Vec<NoteAndArgs> = notes.into();
let native_note_and_note_args: Vec<(NativeNote, Option<NativeNoteArgs>)> =
items.into_iter().map(Into::into).collect();
self.0 = self.0.clone().input_notes(native_note_and_note_args);
self.clone()
}
#[js_export(js_name = "withOwnOutputNotes")]
pub fn with_own_output_notes(&mut self, notes: NoteArray) -> Self {
let native_notes: Vec<NativeNote> = notes.into();
self.0 = self.0.clone().own_output_notes(native_notes);
self.clone()
}
#[js_export(js_name = "withCustomScript")]
pub fn with_custom_script(&mut self, script: &TransactionScript) -> Self {
let native_script: NativeTransactionScript = script.into();
self.0 = self.0.clone().custom_script(native_script);
self.clone()
}
#[js_export(js_name = "withExpirationDelta")]
pub fn with_expiration_delta(&mut self, expiration_delta: u16) -> Self {
self.0 = self.0.clone().expiration_delta(expiration_delta);
self.clone()
}
#[js_export(js_name = "withExpectedOutputRecipients")]
pub fn with_expected_output_notes(&mut self, recipients: NoteRecipientArray) -> Self {
let items: Vec<NoteRecipient> = recipients.into();
let native_recipients: Vec<NativeNoteRecipient> =
items.into_iter().map(NativeNoteRecipient::from).collect();
self.0 = self.0.clone().expected_output_recipients(native_recipients);
self.clone()
}
#[js_export(js_name = "withExpectedFutureNotes")]
pub fn with_expected_future_notes(
&mut self,
note_details_and_tag: NoteDetailsAndTagArray,
) -> Self {
let items: Vec<NoteDetailsAndTag> = note_details_and_tag.into();
let native_note_details_and_tag: Vec<(NativeNoteDetails, NativeNoteTag)> =
items.into_iter().map(Into::into).collect();
self.0 = self.0.clone().expected_future_notes(native_note_details_and_tag);
self.clone()
}
#[js_export(js_name = "extendAdviceMap")]
pub fn extend_advice_map(&mut self, advice_map: &AdviceMap) -> Self {
let native_advice_map: NativeAdviceMap = advice_map.into();
self.0 = self.0.clone().extend_advice_map(native_advice_map);
self.clone()
}
#[js_export(js_name = "withForeignAccounts")]
pub fn with_foreign_accounts(&mut self, foreign_accounts: ForeignAccountArray) -> Self {
let items: Vec<ForeignAccount> = foreign_accounts.into();
let native_foreign_accounts: Vec<NativeForeignAccount> =
items.into_iter().map(Into::into).collect();
self.0 = self.0.clone().foreign_accounts(native_foreign_accounts);
self.clone()
}
#[js_export(js_name = "withScriptArg")]
pub fn with_script_arg(&mut self, script_arg: &Word) -> Self {
let native_word: NativeWord = script_arg.into();
self.0 = self.0.clone().script_arg(native_word);
self.clone()
}
#[js_export(js_name = "withAuthArg")]
pub fn with_auth_arg(&mut self, auth_arg: &Word) -> Self {
let native_word: NativeWord = auth_arg.into();
self.0 = self.0.clone().auth_arg(native_word);
self.clone()
}
pub fn build(&self) -> Result<TransactionRequest, JsErr> {
self.0
.clone()
.build()
.map(TransactionRequest)
.map_err(|err| js_error_with_context(err, "failed to build transaction request"))
}
}
impl From<TransactionRequestBuilder> for NativeTransactionRequestBuilder {
fn from(transaction_request: TransactionRequestBuilder) -> Self {
transaction_request.0
}
}
impl From<&TransactionRequestBuilder> for NativeTransactionRequestBuilder {
fn from(transaction_request: &TransactionRequestBuilder) -> Self {
transaction_request.0.clone()
}
}
impl Default for TransactionRequestBuilder {
fn default() -> Self {
Self::new()
}
}