From fd736f34cd89e1fe91be67ca0387712750d4e00b Mon Sep 17 00:00:00 2001 From: llbartekll Date: Fri, 13 Sep 2024 08:24:56 +0200 Subject: [PATCH 1/2] add wait for user op receipt --- crates/ffi/src/account_client.rs | 10 ++++++ crates/ffi/src/lib.rs | 5 +++ crates/yttrium/src/account_client.rs | 31 +++++++++++++++++++ .../transaction/send/simple_account_test.rs | 20 ++++++------ .../swift/Sources/Yttrium/AccountClient.swift | 9 ++++++ 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/crates/ffi/src/account_client.rs b/crates/ffi/src/account_client.rs index 8eee30c..664758e 100644 --- a/crates/ffi/src/account_client.rs +++ b/crates/ffi/src/account_client.rs @@ -126,6 +126,16 @@ impl FFIAccountClient { .sign_message_with_mnemonic(message, mnemonic) .map_err(|e| FFIError::Unknown(e.to_string())) } + + pub async fn wait_for_user_operation_receipt( + &self, + user_operation_hash: String + ) -> Result { + self.account_client + .wait_for_user_operation_receipt(user_operation_hash) + .await + .map_err(|e| FFIError::Unknown(e.to_string())) + } } impl From for Transaction { diff --git a/crates/ffi/src/lib.rs b/crates/ffi/src/lib.rs index 3124b04..6318721 100644 --- a/crates/ffi/src/lib.rs +++ b/crates/ffi/src/lib.rs @@ -78,6 +78,11 @@ mod ffi { message: String, mnemonic: String, ) -> Result; + + pub async fn wait_for_user_operation_receipt( + &self, + user_operation_hash: String + ) -> Result; } extern "Rust" { diff --git a/crates/yttrium/src/account_client.rs b/crates/yttrium/src/account_client.rs index e4484ce..8a8e50b 100644 --- a/crates/yttrium/src/account_client.rs +++ b/crates/yttrium/src/account_client.rs @@ -2,10 +2,15 @@ use crate::config::Config; use crate::private_key_service::PrivateKeyService; use crate::sign_service::SignService; use crate::transaction::{send::send_transaction, Transaction}; +use crate::user_operation::user_operation_hash; use alloy::primitives::Address; use alloy::signers::local::PrivateKeySigner; use std::sync::Arc; use tokio::sync::Mutex; +use crate:: + bundler::{ + client::BundlerClient, config::BundlerConfig +}; #[derive(Clone)] pub enum SignerType { @@ -153,8 +158,34 @@ impl AccountClient { Ok(signature) } + + pub async fn wait_for_user_operation_receipt( + &self, + user_operation_hash: String + ) -> eyre::Result { + + println!("Querying for receipts..."); + + let bundler_base_url = self.config.clone().endpoints.bundler.base_url; + + let bundler_client = + BundlerClient::new(BundlerConfig::new(bundler_base_url.clone())); + let receipt = bundler_client + .wait_for_user_operation_receipt(user_operation_hash.clone()) + .await?; + + println!("Received User Operation receipt: {:?}", receipt); + + let tx_hash = receipt.receipt.transaction_hash; + println!( + "UserOperation included: https://sepolia.etherscan.io/tx/{}", + tx_hash + ); + Ok("".to_string()) + } } + impl AccountClient { pub fn mock() -> Self { AccountClient { diff --git a/crates/yttrium/src/transaction/send/simple_account_test.rs b/crates/yttrium/src/transaction/send/simple_account_test.rs index 4f8ca12..e68bd66 100644 --- a/crates/yttrium/src/transaction/send/simple_account_test.rs +++ b/crates/yttrium/src/transaction/send/simple_account_test.rs @@ -478,19 +478,19 @@ mod tests { ) .await?; - println!("Querying for receipts..."); + // println!("Querying for receipts..."); - let receipt = bundler_client - .wait_for_user_operation_receipt(user_operation_hash.clone()) - .await?; + // let receipt = bundler_client + // .wait_for_user_operation_receipt(user_operation_hash.clone()) + // .await?; - println!("Received User Operation receipt: {:?}", receipt); + // println!("Received User Operation receipt: {:?}", receipt); - let tx_hash = receipt.receipt.transaction_hash; - println!( - "UserOperation included: https://sepolia.etherscan.io/tx/{}", - tx_hash - ); + // let tx_hash = receipt.receipt.transaction_hash; + // println!( + // "UserOperation included: https://sepolia.etherscan.io/tx/{}", + // tx_hash + // ); Ok(user_operation_hash) } diff --git a/platforms/swift/Sources/Yttrium/AccountClient.swift b/platforms/swift/Sources/Yttrium/AccountClient.swift index e49630e..f25f1ad 100644 --- a/platforms/swift/Sources/Yttrium/AccountClient.swift +++ b/platforms/swift/Sources/Yttrium/AccountClient.swift @@ -125,6 +125,15 @@ public final class AccountClient: AccountClientProtocol { ) .toString() } + + public func waitForUserOperationReceipt( + userOperationHash: String + ) async throws -> String { + try await coreAccountClient.wait_for_user_operation_receipt( + userOperationHash.intoRustString() + ) + .toString() + } } extension Transaction { From 11cb36fa6b6162e059e3d4c6b31959c1fd1124f4 Mon Sep 17 00:00:00 2001 From: llbartekll Date: Fri, 13 Sep 2024 14:34:54 +0200 Subject: [PATCH 2/2] savepoint --- crates/ffi/src/account_client.rs | 6 +++- crates/yttrium/src/account_client.rs | 7 ++-- .../bundler/models/user_operation_receipt.rs | 4 +-- crates/yttrium/src/transaction/send.rs | 18 ---------- .../yttrium/src/transaction/send/safe_test.rs | 12 ------- .../transaction/send/simple_account_test.rs | 36 ------------------- 6 files changed, 11 insertions(+), 72 deletions(-) diff --git a/crates/ffi/src/account_client.rs b/crates/ffi/src/account_client.rs index d712120..91235ff 100644 --- a/crates/ffi/src/account_client.rs +++ b/crates/ffi/src/account_client.rs @@ -1,4 +1,5 @@ use super::ffi; +use yttrium::bundler::models::user_operation_receipt::UserOperationReceipt; use super::ffi::{FFIAccountClientConfig, FFIError}; use yttrium::{ account_client::{AccountClient, SignerType}, @@ -135,7 +136,10 @@ impl FFIAccountClient { self.account_client .wait_for_user_operation_receipt(user_operation_hash) .await - .map_err(|e| FFIError::Unknown(e.to_string())) + .map_err(|e: eyre::Error| FFIError::Unknown(e.to_string())) + .iter() + .flat_map(|receipt|{serde_json::to_string(&receipt)?.into_iter()}) + .collect::() } } diff --git a/crates/yttrium/src/account_client.rs b/crates/yttrium/src/account_client.rs index f43ab24..db85a52 100644 --- a/crates/yttrium/src/account_client.rs +++ b/crates/yttrium/src/account_client.rs @@ -8,6 +8,7 @@ use alloy::primitives::Address; use alloy::signers::local::PrivateKeySigner; use std::sync::Arc; use tokio::sync::Mutex; +use crate::bundler::models::user_operation_receipt::UserOperationReceipt; use crate:: bundler::{ client::BundlerClient, config::BundlerConfig @@ -170,7 +171,7 @@ impl AccountClient { pub async fn wait_for_user_operation_receipt( &self, user_operation_hash: String - ) -> eyre::Result { + ) -> eyre::Result { println!("Querying for receipts..."); @@ -184,12 +185,12 @@ impl AccountClient { println!("Received User Operation receipt: {:?}", receipt); - let tx_hash = receipt.receipt.transaction_hash; + let tx_hash = receipt.clone().receipt.transaction_hash; println!( "UserOperation included: https://sepolia.etherscan.io/tx/{}", tx_hash ); - Ok("".to_string()) + Ok(receipt) } } diff --git a/crates/yttrium/src/bundler/models/user_operation_receipt.rs b/crates/yttrium/src/bundler/models/user_operation_receipt.rs index e652b14..ba17fa0 100644 --- a/crates/yttrium/src/bundler/models/user_operation_receipt.rs +++ b/crates/yttrium/src/bundler/models/user_operation_receipt.rs @@ -1,7 +1,7 @@ use alloy::primitives::Address; use serde::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct UserOperationReceiptReceipt { pub transaction_hash: String, @@ -19,7 +19,7 @@ pub struct UserOperationReceiptReceipt { pub effective_gas_price: String, } -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize,)] #[serde(rename_all = "camelCase")] pub struct UserOperationReceipt { pub user_op_hash: String, diff --git a/crates/yttrium/src/transaction/send.rs b/crates/yttrium/src/transaction/send.rs index a41e09d..aa16a2b 100644 --- a/crates/yttrium/src/transaction/send.rs +++ b/crates/yttrium/src/transaction/send.rs @@ -349,24 +349,6 @@ mod tests { println!("Received User Operation hash: {:?}", user_operation_hash); - // let receipt = bundler_client - // .get_user_operation_receipt(user_operation_hash.clone()) - // .await?; - - // println!("Received User Operation receipt: {:?}", receipt); - - // println!("Querying for receipts..."); - - // let receipt = bundler_client - // .wait_for_user_operation_receipt(user_operation_hash.clone()) - // .await?; - - // let tx_hash = receipt.receipt.transaction_hash; - // println!( - // "UserOperation included: https://sepolia.etherscan.io/tx/{}", - // tx_hash - // ); - Ok(user_operation_hash) } diff --git a/crates/yttrium/src/transaction/send/safe_test.rs b/crates/yttrium/src/transaction/send/safe_test.rs index 184c884..acb8711 100644 --- a/crates/yttrium/src/transaction/send/safe_test.rs +++ b/crates/yttrium/src/transaction/send/safe_test.rs @@ -406,18 +406,6 @@ pub async fn send_transaction( println!("Received User Operation hash: {:?}", user_operation_hash); - println!("Querying for receipts..."); - - let receipt = bundler_client - .wait_for_user_operation_receipt(user_operation_hash.clone()) - .await?; - - let tx_hash = receipt.receipt.transaction_hash; - println!( - "SAFE UserOperation included: https://sepolia.etherscan.io/tx/{}", - tx_hash - ); - // Some extra calls to wait for/get the actual transaction. But these // aren't required since eth_getUserOperationReceipt already waits // let tx_hash = FixedBytes::from_slice( diff --git a/crates/yttrium/src/transaction/send/simple_account_test.rs b/crates/yttrium/src/transaction/send/simple_account_test.rs index e4162ed..f76495a 100644 --- a/crates/yttrium/src/transaction/send/simple_account_test.rs +++ b/crates/yttrium/src/transaction/send/simple_account_test.rs @@ -252,28 +252,6 @@ pub async fn send_transaction_with_signer( println!("Received User Operation hash: {:?}", user_operation_hash); - // TODO convert to polling - use std::time::Duration; - tokio::time::sleep(Duration::from_secs(2)).await; - - let receipt = bundler_client - .get_user_operation_receipt(user_operation_hash.clone()) - .await?; - - println!("Received User Operation receipt: {:?}", receipt); - - println!("Querying for receipts..."); - - let receipt = bundler_client - .wait_for_user_operation_receipt(user_operation_hash.clone()) - .await?; - - let tx_hash = receipt.receipt.transaction_hash; - println!( - "UserOperation included: https://sepolia.etherscan.io/tx/{}", - tx_hash - ); - Ok(user_operation_hash) } @@ -479,20 +457,6 @@ mod tests { ) .await?; - // println!("Querying for receipts..."); - - // let receipt = bundler_client - // .wait_for_user_operation_receipt(user_operation_hash.clone()) - // .await?; - - // println!("Received User Operation receipt: {:?}", receipt); - - // let tx_hash = receipt.receipt.transaction_hash; - // println!( - // "UserOperation included: https://sepolia.etherscan.io/tx/{}", - // tx_hash - // ); - Ok(user_operation_hash) }