diff --git a/src/silentpayments.rs b/src/silentpayments.rs index cb815d3..d7c835e 100644 --- a/src/silentpayments.rs +++ b/src/silentpayments.rs @@ -35,6 +35,63 @@ use crate::crypto::AnkSharedSecret; // } // } +pub fn create_transaction(sp_address: SilentPaymentAddress, sp_wallet: &SpWallet, fee_rate: Amount) -> Result { + let available_outpoints = sp_wallet.get_outputs().to_spendable_list(); + + // Here we need to add more heuristics about which outpoint we spend + // For now let's keep it simple + + let mut inputs: HashMap = HashMap::new(); + + let mut total_available = Amount::from_sat(0); + for (outpoint, output) in available_outpoints { + total_available += output.amount; + inputs.insert(outpoint, output); + if total_available > Amount::from_sat(1000) { + break; + } + } + + if total_available < Amount::from_sat(1000) { + return Err(Error::msg("Not enough available funds")); + } + + let recipient = Recipient { + address: sp_address.into(), + amount: Amount::from_sat(1000), + nb_outputs: 1, + }; + + let mut new_psbt = sp_wallet.get_client().create_new_psbt( + inputs, + vec![recipient], + None, + )?; + + let change_addr = sp_wallet.get_client().sp_receiver.get_change_address(); + SpClient::set_fees(&mut new_psbt, fee_rate, change_addr)?; + + let partial_secret = sp_wallet + .get_client() + .get_partial_secret_from_psbt(&new_psbt)?; + + // This wouldn't work with many recipients in the same transaction + // each address (or more precisely each scan public key) would have its own point + let shared_point = shared_secret_point(&sp_address.get_scan_key(), &partial_secret); + + sp_wallet + .get_client() + .fill_sp_outputs(&mut new_psbt, partial_secret)?; + let mut aux_rand = [0u8; 32]; + rand::thread_rng().fill(&mut aux_rand); + let mut signed = sp_wallet.get_client().sign_psbt(new_psbt, &aux_rand)?; + SpClient::finalize_psbt(&mut signed)?; + + let final_tx = signed.extract_tx()?; + + Ok(final_tx) +} + pub fn create_transaction_for_address_with_shared_secret( sp_address: SilentPaymentAddress, sp_wallet: &SpWallet,