Skip to content

Commit

Permalink
feat: add simulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Bisht13 committed Oct 16, 2024
1 parent dc607f4 commit 5f5f28e
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 8 deletions.
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.

3 changes: 1 addition & 2 deletions packages/relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ serde_json = "1.0.128"
sqlx = { version = "0.8.2", features = ["postgres", "runtime-tokio", "migrate", "uuid", "time", "chrono"] }
tokio = { version = "1.40.0", features = ["full"] }
tower-http = { version = "0.6.1", features = ["cors"] }
# relayer-utils = { git = "https://github.com/zkemail/relayer-utils.git", branch = "main" }
relayer-utils = { path = "../../../relayer-utils" }
relayer-utils = { git = "https://github.com/zkemail/relayer-utils.git", branch = "main" }
slog = { version = "2.7.0", features = [
"max_level_trace",
"release_max_level_warn",
Expand Down
4 changes: 3 additions & 1 deletion packages/relayer/config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"databaseUrl": "postgres://test@localhost:5432/relayer",
"smtpUrl": "http://localhost:3000",
"proverUrl": "https://zkemail--email-auth-prover-v1-4-0-flask-app.modal.run",
"alchemyApiKey": "",
"paths": {
"pem": "./.ic.pem",
"emailTemplates": "./email_templates"
Expand All @@ -16,7 +17,8 @@
"privateKey": "0x...",
"rpcUrl": "https://mainnet.infura.io/v3/...",
"explorerUrl": "https://etherscan.io/tx/",
"chainId": 1
"chainId": 1,
"alchemyName": "base-sepolia"
}
},
"jsonLogger": true
Expand Down
78 changes: 75 additions & 3 deletions packages/relayer/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use ethers::prelude::*;
use ethers::signers::Signer;
use ethers::utils::hex;
use model::RequestModel;
use relayer_utils::{bytes_to_hex, h160_to_hex, u256_to_hex};
use slog::error;
use statics::SHARED_MUTEX;

const CONFIRMATIONS: usize = 1;
Expand Down Expand Up @@ -120,7 +122,12 @@ impl ChainClient {
Ok(is_valid)
}

pub async fn call(&self, request: RequestModel, email_auth_msg: EmailAuthMsg) -> Result<()> {
pub async fn call(
&self,
request: RequestModel,
email_auth_msg: EmailAuthMsg,
relayer_state: RelayerState,
) -> Result<()> {
let abi = Abi {
functions: vec![request.email_tx_auth.function_abi.clone()]
.into_iter()
Expand Down Expand Up @@ -158,9 +165,74 @@ impl ChainClient {

// Now you can use the tokens vector to call the contract function
let call = contract.method::<_, ()>(&function.name, custom_tokens)?;
let tx = call.clone().tx;
let from = h160_to_hex(&self.client.address());
let to = h160_to_hex(
tx.to()
.expect("to not found")
.as_address()
.expect("to not found"),
);
let data = bytes_to_hex(&tx.data().expect("data not found").to_vec());

// Call Alchemy to check for asset changes (Make a POST request to Alchemy)
let alchemy_url = format!(
"https://{}.g.alchemy.com/v2/{}",
relayer_state.config.chains[request.email_tx_auth.chain.as_str()].alchemy_name,
relayer_state.config.alchemy_api_key
);

// Prepare the JSON body for the POST request using extracted transaction details
let json_body = serde_json::json!({
"id": 1,
"jsonrpc": "2.0",
"method": "alchemy_simulateAssetChanges",
"params": [
{
"from": from,
"to": to,
"value": "0x0",
"data": data,
}
]
});

info!(LOG, "Alchemy request: {:?}", json_body);

let tx = call.send().await?.await?;
info!(LOG, "tx: {:?}", tx.expect("tx not found").transaction_hash);
// Send the POST request
let response = relayer_state
.http_client
.post(&alchemy_url)
.header("accept", "application/json")
.header("content-type", "application/json")
.json(&json_body)
.send()
.await?;

// Handle the response
if response.status().is_success() {
let response_text = response.text().await?;
info!(LOG, "Alchemy response: {:?}", response_text);

// Parse the response to check if changes is empty
let response_json: serde_json::Value = serde_json::from_str(&response_text)?;
if let Some(changes) = response_json["result"]["changes"].as_array() {
if !changes.is_empty() {
error!(LOG, "Unexpected changes in Alchemy response: {:?}", changes);
return Err(anyhow!("Unexpected changes in Alchemy response"));
}
}
} else {
let error_text = response.text().await?;
error!(LOG, "Alchemy request failed: {:?}", error_text);
}

let receipt = call.send().await?.await?;
info!(
LOG,
"tx hash: {:?}",
receipt.expect("tx not found").transaction_hash
);

Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions packages/relayer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct Config {
pub database_url: String,
pub smtp_url: String,
pub prover_url: String,
pub alchemy_api_key: String,
pub path: PathConfig,
pub icp: IcpConfig,
pub chains: HashMap<String, ChainConfig>,
Expand Down Expand Up @@ -39,6 +40,7 @@ pub struct ChainConfig {
pub rpc_url: String,
pub explorer_url: String,
pub chain_id: u32,
pub alchemy_name: String,
}

// Function to load the configuration from a JSON file
Expand Down
6 changes: 4 additions & 2 deletions packages/relayer/src/mail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,11 @@ pub async fn handle_email(
)
.await?;

let email_auth_msg = get_email_auth_msg(&email, request.clone(), relayer_state).await?;
let email_auth_msg = get_email_auth_msg(&email, request.clone(), relayer_state.clone()).await?;

chain_client.call(request.clone(), email_auth_msg).await?;
chain_client
.call(request.clone(), email_auth_msg, relayer_state)
.await?;

Ok(EmailEvent::Completion {
email_addr: parsed_email.get_from_addr()?,
Expand Down

0 comments on commit 5f5f28e

Please sign in to comment.