ree-exchange-sdk 0.7.0

REE exchange rust SDK.
Documentation
use crate::Utxo;
use bitcoin::{
    self,
    psbt::Psbt,
    sighash::{Prevouts, SighashCache},
    OutPoint, TapSighashType, Witness,
};

fn cmp<'a>(mine: &'a Utxo, outpoint: &OutPoint) -> bool {
    Into::<bitcoin::Txid>::into(mine.txid) == outpoint.txid && mine.vout == outpoint.vout
}

/// Signs the PSBT inputs using IC chain-key that match the provided pool inputs with a Taproot key spend signature.
pub async fn ree_pool_sign(
    psbt: &mut Psbt,
    pool_inputs: Vec<&Utxo>,
    schnorr_key_name: &str,
    derivation_path: Vec<Vec<u8>>,
) -> Result<(), String> {
    let mut cache = SighashCache::new(&psbt.unsigned_tx);
    let mut prevouts = vec![];
    for input in psbt.inputs.iter() {
        let pout = input
            .witness_utxo
            .as_ref()
            .cloned()
            .ok_or("witness_utxo required".to_string())?;
        prevouts.push(pout);
    }
    for (i, input) in psbt.unsigned_tx.input.iter().enumerate() {
        let outpoint = &input.previous_output;
        if let Some(_) = pool_inputs.iter().find(|input| cmp(input, outpoint)) {
            (i < psbt.inputs.len()).then(|| ()).ok_or(format!(
                "Input index {i} exceeds available inputs ({})",
                psbt.inputs.len()
            ))?;
            let input = &mut psbt.inputs[i];
            let sighash = cache
                .taproot_key_spend_signature_hash(
                    i,
                    &Prevouts::All(&prevouts),
                    TapSighashType::Default,
                )
                .expect("couldn't construct taproot sighash");
            let raw_sig = crate::schnorr::sign_prehash_with_schnorr(
                &sighash,
                schnorr_key_name.to_string(),
                derivation_path.clone(),
            )
            .await
            .map_err(|e| e.to_string())?;
            let inner_sig = bitcoin::secp256k1::schnorr::Signature::from_slice(&raw_sig)
                .expect("assert: chain-key schnorr signature is 64-bytes format");
            let signature = bitcoin::taproot::Signature {
                signature: inner_sig,
                sighash_type: TapSighashType::Default,
            };
            input.final_script_witness = Some(Witness::p2tr_key_spend(&signature));
        }
    }
    Ok(())
}