diff --git a/src/api/dart_ffi.rs b/src/api/dart_ffi.rs index fad148a..3d15234 100644 --- a/src/api/dart_ffi.rs +++ b/src/api/dart_ffi.rs @@ -637,7 +637,7 @@ pub async unsafe extern "C" fn sign( from_c_str!(tx_plan); let res = async { let tx_plan: TransactionPlan = serde_json::from_str(&tx_plan)?; - let raw_tx = crate::api::payment_v2::sign_plan(coin, account, &tx_plan)?; + let raw_tx = crate::api::payment_v2::sign_plan(coin, account, &tx_plan, false)?; let tx_str = base64::encode(&raw_tx); Ok::<_, anyhow::Error>(tx_str) }; diff --git a/src/api/payment_v2.rs b/src/api/payment_v2.rs index c18f65b..4ec5d54 100644 --- a/src/api/payment_v2.rs +++ b/src/api/payment_v2.rs @@ -122,7 +122,7 @@ pub async fn build_tx_plan( Ok(tx_plan) } -pub fn sign_plan(coin: u8, account: u32, tx_plan: &TransactionPlan) -> anyhow::Result> { +pub fn sign_plan(coin: u8, account: u32, tx_plan: &TransactionPlan, frost: bool) -> anyhow::Result> { let c = CoinConfig::get(coin); let network = c.chain.network(); let fvk = { @@ -146,7 +146,7 @@ pub fn sign_plan(coin: u8, account: u32, tx_plan: &TransactionPlan) -> anyhow::R } let keys = get_secret_keys(coin, account)?; - let tx = build_tx(c.chain.network(), &keys, &tx_plan, OsRng)?; + let tx = build_tx(c.chain.network(), &keys, &tx_plan, frost, OsRng)?; Ok(tx) } @@ -155,7 +155,7 @@ pub async fn sign_and_broadcast( account: u32, tx_plan: &TransactionPlan, ) -> anyhow::Result { - let tx = sign_plan(coin, account, tx_plan)?; + let tx = sign_plan(coin, account, tx_plan, false)?; let txid = broadcast_tx(&tx).await?; let id_notes: Vec<_> = tx_plan .spends diff --git a/src/main/rpc.rs b/src/main/rpc.rs index 5ec4a65..4805acc 100644 --- a/src/main/rpc.rs +++ b/src/main/rpc.rs @@ -349,7 +349,7 @@ pub async fn build_from_plan(tx_plan: Json) -> Result anyhow::Result<()> { orchard: orchard_sk, }; - let tx = build_tx(&network, &keys, &tx_plan, OsRng)?; + let tx = build_tx(&network, &keys, &tx_plan, true, OsRng)?; fs::write(out_filename, hex::encode(&tx))?; Ok(()) diff --git a/src/note_selection/builder.rs b/src/note_selection/builder.rs index df63cc5..6807b65 100644 --- a/src/note_selection/builder.rs +++ b/src/note_selection/builder.rs @@ -11,6 +11,7 @@ use orchard::builder::Builder as OrchardBuilder; use orchard::bundle::Flags; use orchard::keys::{FullViewingKey, Scope, SpendAuthorizingKey, SpendingKey}; use orchard::note::Nullifier; +use orchard::primitives::redpallas::{self, SpendAuth}; use orchard::value::NoteValue; use orchard::{Address, Anchor, Bundle}; use rand::{CryptoRng, RngCore}; @@ -72,6 +73,7 @@ pub fn build_tx( network: &Network, skeys: &SecretKeys, plan: &TransactionPlan, + frost: bool, mut rng: impl RngCore + CryptoRng + Clone, ) -> anyhow::Result> { let secp = Secp256k1::::new(); @@ -251,6 +253,10 @@ pub fn build_tx( let sig_hash = signature_hash(&unauthed_tx, &SignableInput::Shielded, &txid_parts); let sig_hash: [u8; 32] = sig_hash.as_ref().clone(); + if frost { + println!("SIGHASH: {}", hex::encode(&sig_hash)); + } + let transparent_bundle = unauthed_tx .transparent_bundle() .map(|tb| tb.clone().apply_signatures(&unauthed_tx, &txid_parts)); @@ -272,9 +278,26 @@ pub fn build_tx( .clone() .create_proof(get_proving_key(), &mut rng) .unwrap(); - proven - .apply_signatures(&mut rng, sig_hash, &orchard_signing_keys) - .unwrap() + if frost { + let mut buffer = String::new(); + let stdin = std::io::stdin(); + println!("Input hex-encoded signature: "); + stdin.read_line(&mut buffer).unwrap(); + let signature = hex::decode(buffer.trim()).unwrap(); + let signature: [u8; 64] = signature.try_into().unwrap(); + let signature = redpallas::Signature::::from(signature); + + proven + .prepare(&mut rng, sig_hash) + .append_signatures(&[signature]) + .unwrap() + .finalize() + .unwrap() + } else { + proven + .apply_signatures(&mut rng, sig_hash, &orchard_signing_keys) + .unwrap() + } }); let tx_data: TransactionData = diff --git a/src/taddr.rs b/src/taddr.rs index 3f8105a..f7189e3 100644 --- a/src/taddr.rs +++ b/src/taddr.rs @@ -353,7 +353,7 @@ pub async fn sweep_tkey( orchard: None, }; println!("build_tx"); - let tx = build_tx(network, &skeys, &tx_plan, OsRng)?; + let tx = build_tx(network, &skeys, &tx_plan, false, OsRng)?; println!("broadcast_tx"); let txid = broadcast_tx(&tx).await?; Ok(txid)