-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathmod.rs
More file actions
154 lines (132 loc) · 5.43 KB
/
Copy pathmod.rs
File metadata and controls
154 lines (132 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use schemars::JsonSchema;
use serde::de::{Error, IntoDeserializer};
use serde::{Deserialize, Deserializer, Serialize};
use serde_with::{DisplayFromStr, PickFirst, serde_as};
use std::collections::HashMap;
use crate::transaction::InnerTransaction;
pub mod aa;
pub mod auto;
pub mod eip7702;
pub mod eoa;
// Base execution options for all transactions
// All specific execution options share this
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct BaseExecutionOptions {
#[serde_as(as = "PickFirst<(_, DisplayFromStr)>")]
pub chain_id: u64,
#[serde(default = "default_idempotency_key")]
pub idempotency_key: String,
}
fn default_idempotency_key() -> String {
uuid::Uuid::new_v4().to_string()
}
/// All supported specific execution options are contained here
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, utoipa::ToSchema)]
#[serde(tag = "type")]
#[schema(title = "Execution Option Variants")]
pub enum SpecificExecutionOptions {
#[serde(rename = "auto")]
#[schema(title = "Auto Determine Execution", default)]
Auto(auto::AutoExecutionOptions),
#[schema(title = "ERC-4337 Execution Options")]
ERC4337(aa::Erc4337ExecutionOptions),
#[serde(rename = "eoa")]
#[schema(title = "EOA Execution Options")]
EOA(eoa::EoaExecutionOptions),
#[schema(title = "EIP-7702 Execution Options")]
EIP7702(eip7702::Eip7702ExecutionOptions),
}
fn deserialize_with_default_auto<'de, D>(
deserializer: D,
) -> Result<SpecificExecutionOptions, D::Error>
where
D: Deserializer<'de>,
{
let mut map: HashMap<String, serde_json::Value> = HashMap::deserialize(deserializer)?;
// If no "type" field exists, add it with "Auto"
if !map.contains_key("type") {
map.insert(
"type".to_string(),
serde_json::Value::String("auto".to_string()),
);
}
// Convert HashMap back to deserializer and deserialize normally
SpecificExecutionOptions::deserialize(map.into_deserializer()).map_err(D::Error::custom)
}
/// This is the exposed API for execution options
/// Base and specific execution options are both flattened together
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ExecutionOptions {
#[serde(flatten)]
pub base: BaseExecutionOptions,
#[serde(flatten, deserialize_with = "deserialize_with_default_auto")]
pub specific: SpecificExecutionOptions,
}
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)]
pub struct WebhookOptions {
pub url: String,
pub secret: Option<String>,
}
/// Incoming transaction request, parsed into InnerTransaction
/// Exposed API will have varying `params` but will all parse into InnerTransaction before execution
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct SendTransactionRequest {
pub execution_options: ExecutionOptions,
pub params: Vec<InnerTransaction>,
#[serde(default)]
pub webhook_options: Vec<WebhookOptions>,
}
/// # QueuedTransaction
/// Response for any request that queues one or more transactions
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct QueuedTransaction {
/// The idempotency key this transaction was queued with
/// Either autogenerated UUID or provided by the user
/// Multiple queued transactions can have the same idempotency key
/// A "blockchain transaction" is uniquely identified by the idempotency key + batchIndex
pub id: String,
/// When multiple transactions are sent together via an execution mode that doesn't support atomic batching,
/// each transaction will have a unique batchIndex but the same id (idempotency key)
/// This maintains the relationship between different atomically sent blockchain transactions that were queued together
pub batch_index: u64,
/// The fully resolved execution options for this transaction, derived from the resolution of user specific execution options
/// Difference in naming is to prevent confusion when response executionParams contain different values than the request executionOptions
pub execution_params: ExecutionOptions,
/// This is the actual encoded inner transaction data that will be sent to the blockchain.
/// For non-atomic transactions, this will be a single transaction
/// For atomic transactions, this will be a list of transactions, because they were atomically sent together
pub transaction_params: Vec<InnerTransaction>,
}
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct QueuedTransactionsResponse {
pub transactions: Vec<QueuedTransaction>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExecutorType {
#[serde(rename = "ERC4337")]
Erc4337,
#[serde(rename = "EOA")]
Eoa,
#[serde(rename = "EIP7702")]
Eip7702,
}
impl ExecutionOptions {
pub fn executor_type(&self) -> ExecutorType {
match &self.specific {
SpecificExecutionOptions::ERC4337(_) => ExecutorType::Erc4337,
SpecificExecutionOptions::Auto(_) => ExecutorType::Erc4337,
SpecificExecutionOptions::EOA(_) => ExecutorType::Eoa,
SpecificExecutionOptions::EIP7702(_) => ExecutorType::Eip7702,
}
}
pub fn chain_id(&self) -> u64 {
self.base.chain_id
}
pub fn transaction_id(&self) -> &str {
&self.base.idempotency_key
}
}