use super::create_action::{read_send_with_results, write_send_with_results};
use super::*;
use crate::wallet::error::WalletError;
use crate::wallet::interfaces::*;
use crate::wallet::types::{BooleanDefaultFalse, BooleanDefaultTrue};
use std::collections::HashMap;
pub fn serialize_sign_action_args(args: &SignActionArgs) -> Result<Vec<u8>, WalletError> {
serialize_to_vec(|w| {
write_varint(w, args.spends.len() as u64)?;
let mut keys: Vec<u32> = args.spends.keys().copied().collect();
keys.sort();
for key in keys {
let spend = &args.spends[&key];
write_varint(w, key as u64)?;
write_bytes(w, &spend.unlocking_script)?;
write_optional_uint32(w, spend.sequence_number)?;
}
write_bytes(w, &args.reference)?;
if let Some(ref opts) = args.options {
write_byte(w, 1)?;
write_optional_bool(w, opts.accept_delayed_broadcast.0)?;
write_optional_bool(w, opts.return_txid_only.0)?;
write_optional_bool(w, opts.no_send.0)?;
if opts.send_with.is_empty() {
write_varint(w, NEGATIVE_ONE)?;
} else {
write_varint(w, opts.send_with.len() as u64)?;
for txid in &opts.send_with {
let txid_bytes = hex_decode(txid)?;
write_raw_bytes(w, &txid_bytes)?;
}
}
} else {
write_byte(w, 0)?;
}
Ok(())
})
}
pub fn deserialize_sign_action_args(data: &[u8]) -> Result<SignActionArgs, WalletError> {
let mut r = std::io::Cursor::new(data);
let spend_count = read_varint(&mut r)?;
let mut spends = HashMap::new();
for _ in 0..spend_count {
let index = read_varint(&mut r)? as u32;
let unlocking_script = read_bytes(&mut r)?;
let sequence_number = read_optional_uint32(&mut r)?;
spends.insert(
index,
SignActionSpend {
unlocking_script,
sequence_number,
},
);
}
let reference = read_bytes(&mut r)?;
let options_flag = read_byte(&mut r)?;
let options = if options_flag == 1 {
let accept_delayed_broadcast = BooleanDefaultTrue(read_optional_bool(&mut r)?);
let return_txid_only = BooleanDefaultFalse(read_optional_bool(&mut r)?);
let no_send = BooleanDefaultFalse(read_optional_bool(&mut r)?);
let send_count = read_varint(&mut r)?;
let send_with = if send_count == NEGATIVE_ONE {
Vec::new()
} else {
let mut txids = Vec::with_capacity(send_count as usize);
for _ in 0..send_count {
let txid_bytes = read_raw_bytes(&mut r, 32)?;
txids.push(hex_encode(&txid_bytes));
}
txids
};
Some(SignActionOptions {
accept_delayed_broadcast,
return_txid_only,
no_send,
send_with,
})
} else {
None
};
Ok(SignActionArgs {
reference,
spends,
options,
})
}
pub fn serialize_sign_action_result(result: &SignActionResult) -> Result<Vec<u8>, WalletError> {
serialize_to_vec(|w| {
write_optional_bytes_with_flag_fixed(
w,
result
.txid
.as_ref()
.and_then(|t| hex_decode(t).ok())
.as_deref(),
)?;
write_optional_bytes_with_flag(w, result.tx.as_deref())?;
write_send_with_results(w, &result.send_with_results)
})
}
pub fn deserialize_sign_action_result(data: &[u8]) -> Result<SignActionResult, WalletError> {
let mut r = std::io::Cursor::new(data);
let txid_bytes = read_optional_bytes_with_flag_fixed(&mut r, 32)?;
let txid = txid_bytes.map(|b| hex_encode(&b));
let tx = read_optional_bytes_with_flag(&mut r)?;
let send_with_results = read_send_with_results(&mut r)?;
Ok(SignActionResult {
txid,
tx,
send_with_results,
})
}