ethcontract/transaction/
send.rs1use crate::errors::ExecutionError;
5use crate::transaction::confirm;
6use crate::transaction::{ResolveCondition, Transaction, TransactionBuilder};
7use web3::types::{TransactionReceipt, H256, U64};
8use web3::Transport;
9
10impl<T: Transport> TransactionBuilder<T> {
11 pub async fn send(mut self) -> Result<TransactionResult, ExecutionError> {
14 let web3 = self.web3.clone();
15 let resolve = self.resolve.take().unwrap_or_default();
16
17 let tx = self.build().await?;
18 let tx_hash = match tx {
19 Transaction::Request(tx) => web3.eth().send_transaction(tx).await?,
20 Transaction::Raw { bytes, hash } => {
21 let node_hash = web3.eth().send_raw_transaction(bytes).await?;
22 if node_hash != hash {
23 return Err(ExecutionError::UnexpectedTransactionHash);
24 }
25 hash
26 }
27 };
28
29 let tx_receipt = match resolve {
30 ResolveCondition::Pending => return Ok(TransactionResult::Hash(tx_hash)),
31 ResolveCondition::Confirmed(params) => {
32 confirm::wait_for_confirmation(&web3, tx_hash, params).await
33 }
34 }?;
35
36 match tx_receipt.status {
37 Some(U64([1])) => Ok(TransactionResult::Receipt(tx_receipt)),
38 _ => Err(ExecutionError::Failure(Box::new(tx_receipt))),
39 }
40 }
41}
42
43#[derive(Clone, Debug)]
52#[allow(clippy::large_enum_variant)]
53pub enum TransactionResult {
54 Hash(H256),
57 Receipt(TransactionReceipt),
60}
61
62impl TransactionResult {
63 pub fn is_hash(&self) -> bool {
66 matches!(self, TransactionResult::Hash(_))
67 }
68
69 pub fn hash(&self) -> H256 {
71 match self {
72 TransactionResult::Hash(hash) => *hash,
73 TransactionResult::Receipt(tx) => tx.transaction_hash,
74 }
75 }
76
77 pub fn is_receipt(&self) -> bool {
80 self.as_receipt().is_some()
81 }
82
83 pub fn as_receipt(&self) -> Option<&TransactionReceipt> {
87 match self {
88 TransactionResult::Receipt(ref tx) => Some(tx),
89 _ => None,
90 }
91 }
92}