Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mm2src/coins/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ mm2_event_stream = { path = "../mm2_event_stream" }
mm2_io = { path = "../mm2_io" }
mm2_metrics = { path = "../mm2_metrics" }
mm2_net = { path = "../mm2_net" }
mm2_eth = { path = "../mm2_eth" }
mm2_number = { path = "../mm2_number"}
mm2_p2p = { path = "../mm2_p2p", default-features = false }
mm2_rpc = { path = "../mm2_rpc" }
Expand Down
13 changes: 12 additions & 1 deletion mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub use eth_utils::{
};
use eth_utils::{
get_conf_param_or_from_plaform_coin, get_function_input_data, get_function_name, ESTIMATE_GAS_MULT,
GAS_PRICE_ADJUST, MAX_ETH_TX_TYPE_SUPPORTED, SWAP_GAS_FEE_POLICY,
GAS_PRICE_ADJUST, MAX_ETH_TX_TYPE_SUPPORTED, SWAP_GAS_FEE_POLICY, EIP4337_URL,
};

pub use rlp;
Expand All @@ -162,6 +162,8 @@ cfg_native! {

pub mod eth_balance_events;
mod eth_rpc;
mod eip4337_rpc;
use eip4337_rpc::Eip4337Rpc;
#[cfg(test)]
mod eth_tests;
#[cfg(target_arch = "wasm32")]
Expand Down Expand Up @@ -196,6 +198,7 @@ use eth_swap_v2::{extract_id_from_tx_data, EthPaymentType, PaymentMethod, SpendT

pub mod eth_utils;
pub mod tron;
mod eth_abstraction;

/// Default timeout to wait for eth rpc request to complete
pub(crate) const ETH_RPC_REQUEST_TIMEOUT_S: Duration = Duration::from_secs(30);
Expand Down Expand Up @@ -930,6 +933,7 @@ pub struct EthCoinImpl {
fallback_swap_contract: Option<Address>,
contract_supports_watchers: bool,
web3_instances: AsyncMutex<Vec<Web3Instance>>,
eip4337_rpc: Option<Uri>,
decimals: u8,
history_sync_state: Mutex<HistorySyncState>,
required_confirmations: AtomicU64,
Expand Down Expand Up @@ -6769,6 +6773,11 @@ pub async fn eth_coin_from_conf_and_request(
get_conf_param_or_from_plaform_coin(ctx, conf, &coin_type, SWAP_GAS_FEE_POLICY)?.unwrap_or_default();
let swap_gas_fee_policy: SwapGasFeePolicy =
json::from_value(req["swap_gas_fee_policy"].clone()).unwrap_or(swap_gas_fee_policy_default);
let eip4337_rpc = if let Ok(uri_str) = json::from_value::<String>(req[EIP4337_URL].clone()) {
Some(try_s!(uri_str.parse()))
} else {
None
};

let coin = EthCoinImpl {
priv_key_policy: key_pair,
Expand All @@ -6784,6 +6793,7 @@ pub async fn eth_coin_from_conf_and_request(
decimals,
ticker: ticker.into(),
web3_instances: AsyncMutex::new(web3_instances),
eip4337_rpc,
history_sync_state: Mutex::new(initial_history_state),
swap_gas_fee_policy: Mutex::new(swap_gas_fee_policy),
max_eth_tx_type,
Expand Down Expand Up @@ -7730,6 +7740,7 @@ impl EthCoin {
fallback_swap_contract: self.fallback_swap_contract,
contract_supports_watchers: self.contract_supports_watchers,
web3_instances: AsyncMutex::new(self.web3_instances.lock().await.clone()),
eip4337_rpc: None,
decimals: self.decimals,
history_sync_state: Mutex::new(self.history_sync_state.lock().unwrap().clone()),
required_confirmations: AtomicU64::new(
Expand Down
60 changes: 60 additions & 0 deletions mm2src/coins/eth/eip4337_rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use super::*;
use crate::eth::web3_transport::http_transport::de_rpc_response;
use crate::hd_wallet::AddrToString;
// use alloy::rpc::types::eth::erc4337::{SendUserOperation, SendUserOperationResponse};
// use alloy::sol_types::eip712_domain;
use mm2_net::transport::{slurp_post_json, SlurpResult};
use serde_json::{json, Value};
//use url::Url;

pub(crate) struct Eip4337Rpc;

impl Eip4337Rpc {

async fn call_api(rpc_uri: &Uri, method: &str, params: &Value) -> SlurpResult {
let req = json!({
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": 1
});
println!("Eip4337Rpc req: {}", serde_json::to_string_pretty(&req).unwrap());
//post_json(self.api_url.as_str(), serde_json::to_string(&req)?).await
slurp_post_json(&rpc_uri.to_string(), serde_json::to_string(&req)?).await
}

pub(crate) async fn send_user_operation(rpc_uri: &Uri, user_op: Value, entry_point: Address) -> Result<Value, web3::Error> {
let result = Self::call_api(
rpc_uri,
"eth_sendUserOperation",
&json!([
&user_op,
entry_point.addr_to_string()
])
).await;
decode_rpc_result(result, rpc_uri)
}
}



fn decode_rpc_result(result: SlurpResult, uri: &Uri) -> Result<Value, web3::Error> {
match result {
Ok((status, _, body)) => {
if !status.is_success() {
return Err(web3::Error::Transport(web3::error::TransportError::Code(status.as_u16())));
}

match de_rpc_response(body, &uri.to_string()) {
Ok(val) => Ok(val),
Err(err) => Err(web3::Error::InvalidResponse(
format!("Server: '{}', error: {}", uri, err)
)),
}
},
Err(err) => Err(web3::Error::Transport(
web3::error::TransportError::Message(
format!("Server: '{}', error: {}", uri, err.get_inner())
))),
}
}
Loading
Loading