use std::time::Duration;
use miden_node_proto::clients::{Builder, RemoteProverClient};
use miden_node_proto::errors::ConversionError;
use miden_node_proto::generated::miden::remote_prover::v1::prove_request::Request;
use miden_node_proto::generated::miden::remote_prover::v1::{DecodedProveResponse, ProveRequest};
use miden_node_proto::{BuildUnchecked, DecodeMessage};
use miden_protocol::transaction::{ProvenTransaction, TransactionInputs};
use miden_tx::TransactionProverError;
use url::Url;
#[derive(Clone)]
pub struct RemoteTransactionProver {
client: RemoteProverClient,
}
impl RemoteTransactionProver {
pub fn new(url: Url, timeout: Duration) -> anyhow::Result<Self> {
let client = Builder::new(url)
.with_tls()?
.with_timeout(timeout)
.without_metadata_version()
.without_metadata_genesis()
.without_auth_header()
.with_otel_context_injection()
.connect_lazy::<RemoteProverClient>();
Ok(Self { client })
}
pub async fn prove(
&self,
tx_inputs: &TransactionInputs,
) -> Result<ProvenTransaction, TransactionProverError> {
let request = tonic::Request::new(ProveRequest {
request: Some(Request::Transaction(tx_inputs.into())),
});
let response = self.client.clone().prove(request).await.map_err(|err| {
TransactionProverError::other_with_source("failed to prove transaction", err)
})?;
response
.into_inner()
.decode_fields()
.and_then(DecodedProveResponse::into_transaction)
.and_then(|transaction| transaction.build_unchecked().map_err(ConversionError::new))
.map_err(|error| {
TransactionProverError::other_with_source(
"invalid remote transaction proof response",
error,
)
})
}
}