penumbra_sdk_wallet/
build.rs

1use anyhow::Result;
2
3use penumbra_sdk_custody::{AuthorizeRequest, CustodyClient};
4use penumbra_sdk_keys::FullViewingKey;
5use penumbra_sdk_transaction::{AuthorizationData, Transaction, TransactionPlan};
6use penumbra_sdk_view::ViewClient;
7
8pub async fn build_transaction<V, C>(
9    fvk: &FullViewingKey,
10    view: &mut V,
11    custody: &mut C,
12    plan: TransactionPlan,
13) -> Result<Transaction>
14where
15    V: ViewClient,
16    C: CustodyClient,
17{
18    // Get the authorization data from the custody service...
19    let auth_data: AuthorizationData = custody
20        .authorize(AuthorizeRequest {
21            plan: plan.clone(),
22            pre_authorizations: Vec::new(),
23        })
24        .await?
25        .data
26        .ok_or_else(|| anyhow::anyhow!("empty AuthorizeResponse message"))?
27        .try_into()?;
28
29    // Send a witness request to the view service to get witness data
30    let witness_data = view.witness(&plan).await?;
31
32    // ... and then build the transaction:
33    #[cfg(not(feature = "parallel"))]
34    {
35        let tx = plan.build(fvk, &witness_data, &auth_data)?;
36        return Ok(tx);
37    }
38
39    #[cfg(feature = "parallel")]
40    {
41        let tx = plan
42            .build_concurrent(fvk, &witness_data, &auth_data)
43            .await
44            .map_err(|_| tonic::Status::failed_precondition("Error building transaction"))?;
45
46        Ok(tx)
47    }
48}