use std::io::Cursor;
use bsv::transaction::beef::Beef;
use bsv::transaction::beef_party::BeefParty;
use bsv::wallet::error::WalletError;
pub fn verify_returned_txid_only(
beef: &mut Beef,
wallet_beef: &BeefParty,
return_txid_only: bool,
known_txids: Option<&[String]>,
) -> Result<(), WalletError> {
if return_txid_only {
return Ok(());
}
let txid_only: Vec<String> = beef
.txs
.iter()
.filter(|btx| btx.is_txid_only())
.map(|btx| btx.txid.clone())
.collect();
for txid in &txid_only {
if let Some(known) = known_txids {
if known.contains(txid) {
continue;
}
}
if let Some(full_btx) = wallet_beef.beef.find_txid(txid) {
if !full_btx.is_txid_only() {
if let Err(e) = beef.merge_beef(&wallet_beef.beef) {
return Err(WalletError::Internal(format!(
"unable to merge txid {} into beef: {}",
txid, e
)));
}
continue;
}
}
return Err(WalletError::Internal(format!(
"unable to merge txid {} into beef",
txid
)));
}
for btx in &beef.txs {
if btx.is_txid_only() {
if let Some(known) = known_txids {
if known.contains(&btx.txid) {
continue;
}
}
return Err(WalletError::Internal(format!(
"remaining txidOnly {} is not known",
btx.txid
)));
}
}
Ok(())
}
pub fn verify_returned_txid_only_atomic_beef(
beef_bytes: &[u8],
wallet_beef: &BeefParty,
return_txid_only: bool,
known_txids: Option<&[String]>,
) -> Result<Vec<u8>, WalletError> {
if return_txid_only {
return Ok(beef_bytes.to_vec());
}
let mut cursor = Cursor::new(beef_bytes);
let mut beef = Beef::from_binary(&mut cursor)
.map_err(|e| WalletError::Internal(format!("failed to parse AtomicBEEF: {}", e)))?;
let atomic_txid = beef
.atomic_txid
.clone()
.ok_or_else(|| WalletError::Internal("AtomicBEEF missing atomic txid".to_string()))?;
verify_returned_txid_only(&mut beef, wallet_beef, return_txid_only, known_txids)?;
beef.to_binary_atomic(&atomic_txid)
.map_err(|e| WalletError::Internal(format!("failed to serialize AtomicBEEF: {}", e)))
}
pub fn verify_returned_txid_only_beef(
beef_bytes: &[u8],
wallet_beef: &BeefParty,
return_txid_only: bool,
) -> Result<Vec<u8>, WalletError> {
if return_txid_only {
return Ok(beef_bytes.to_vec());
}
let mut cursor = Cursor::new(beef_bytes);
let mut beef = Beef::from_binary(&mut cursor)
.map_err(|e| WalletError::Internal(format!("failed to parse BEEF: {}", e)))?;
verify_returned_txid_only(&mut beef, wallet_beef, return_txid_only, None)?;
let mut output = Vec::new();
beef.to_binary(&mut output)
.map_err(|e| WalletError::Internal(format!("failed to serialize BEEF: {}", e)))?;
Ok(output)
}
pub fn get_known_txids(beef: &mut BeefParty, new_known_txids: Option<&[String]>) -> Vec<String> {
if let Some(txids) = new_known_txids {
for txid in txids {
if beef.beef.find_txid(txid).is_none() {
beef.beef
.txs
.push(bsv::transaction::beef_tx::BeefTx::from_txid(txid.clone()));
}
}
}
beef.beef.sort_txs();
beef.beef.txs.iter().map(|btx| btx.txid.clone()).collect()
}