near_kit/types/
wait_level.rs1use crate::error::Error;
28use crate::types::AccountId;
29
30use super::block_reference::TxExecutionStatus;
31use super::rpc::{FinalExecutionOutcome, RawTransactionResponse, SendTxResponse};
32
33mod sealed {
34 pub trait Sealed {}
35}
36
37pub trait WaitLevel: sealed::Sealed + Send + Sync + 'static {
46 type Response: Send + 'static;
48
49 fn status() -> TxExecutionStatus;
51
52 #[doc(hidden)]
58 fn convert(
59 response: RawTransactionResponse,
60 sender_id: &AccountId,
61 ) -> Result<Self::Response, Error>;
62}
63
64#[derive(Clone, Copy, Debug)]
74pub struct Submitted;
75
76impl sealed::Sealed for Submitted {}
77impl WaitLevel for Submitted {
78 type Response = SendTxResponse;
79 fn status() -> TxExecutionStatus {
80 TxExecutionStatus::None
81 }
82 fn convert(
83 response: RawTransactionResponse,
84 sender_id: &AccountId,
85 ) -> Result<Self::Response, Error> {
86 Ok(SendTxResponse {
87 transaction_hash: response.transaction_hash,
88 sender_id: sender_id.clone(),
89 })
90 }
91}
92
93#[derive(Clone, Copy, Debug)]
97pub struct Included;
98
99impl sealed::Sealed for Included {}
100impl WaitLevel for Included {
101 type Response = SendTxResponse;
102 fn status() -> TxExecutionStatus {
103 TxExecutionStatus::Included
104 }
105 fn convert(
106 response: RawTransactionResponse,
107 sender_id: &AccountId,
108 ) -> Result<Self::Response, Error> {
109 Ok(SendTxResponse {
110 transaction_hash: response.transaction_hash,
111 sender_id: sender_id.clone(),
112 })
113 }
114}
115
116#[derive(Clone, Copy, Debug)]
120pub struct IncludedFinal;
121
122impl sealed::Sealed for IncludedFinal {}
123impl WaitLevel for IncludedFinal {
124 type Response = SendTxResponse;
125 fn status() -> TxExecutionStatus {
126 TxExecutionStatus::IncludedFinal
127 }
128 fn convert(
129 response: RawTransactionResponse,
130 sender_id: &AccountId,
131 ) -> Result<Self::Response, Error> {
132 Ok(SendTxResponse {
133 transaction_hash: response.transaction_hash,
134 sender_id: sender_id.clone(),
135 })
136 }
137}
138
139fn extract_outcome(
145 response: RawTransactionResponse,
146 level: &str,
147) -> Result<FinalExecutionOutcome, Error> {
148 let outcome = response.outcome.ok_or_else(|| {
149 Error::InvalidTransaction(format!(
150 "RPC returned no execution outcome for transaction {} at wait level {}",
151 response.transaction_hash, level,
152 ))
153 })?;
154
155 use super::error::TxExecutionError;
156 use super::rpc::FinalExecutionStatus;
157 match outcome.status {
158 FinalExecutionStatus::Failure(TxExecutionError::InvalidTxError(e)) => {
159 Err(Error::InvalidTx(Box::new(e)))
160 }
161 _ => Ok(outcome),
162 }
163}
164
165#[derive(Clone, Copy, Debug)]
170pub struct ExecutedOptimistic;
171
172impl sealed::Sealed for ExecutedOptimistic {}
173impl WaitLevel for ExecutedOptimistic {
174 type Response = FinalExecutionOutcome;
175 fn status() -> TxExecutionStatus {
176 TxExecutionStatus::ExecutedOptimistic
177 }
178 fn convert(
179 response: RawTransactionResponse,
180 _sender_id: &AccountId,
181 ) -> Result<Self::Response, Error> {
182 extract_outcome(response, "ExecutedOptimistic")
183 }
184}
185
186#[derive(Clone, Copy, Debug)]
190pub struct Executed;
191
192impl sealed::Sealed for Executed {}
193impl WaitLevel for Executed {
194 type Response = FinalExecutionOutcome;
195 fn status() -> TxExecutionStatus {
196 TxExecutionStatus::Executed
197 }
198 fn convert(
199 response: RawTransactionResponse,
200 _sender_id: &AccountId,
201 ) -> Result<Self::Response, Error> {
202 extract_outcome(response, "Executed")
203 }
204}
205
206#[derive(Clone, Copy, Debug)]
210pub struct Final;
211
212impl sealed::Sealed for Final {}
213impl WaitLevel for Final {
214 type Response = FinalExecutionOutcome;
215 fn status() -> TxExecutionStatus {
216 TxExecutionStatus::Final
217 }
218 fn convert(
219 response: RawTransactionResponse,
220 _sender_id: &AccountId,
221 ) -> Result<Self::Response, Error> {
222 extract_outcome(response, "Final")
223 }
224}