Skip to content

Commit

Permalink
fix: relayer fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bisht13 committed Jun 28, 2024
1 parent e7d793b commit 067ef20
Show file tree
Hide file tree
Showing 15 changed files with 334 additions and 566 deletions.
222 changes: 110 additions & 112 deletions Cargo.lock

Large diffs are not rendered by default.

425 changes: 0 additions & 425 deletions packages/relayer/eml_templates/account_not_created.html

This file was deleted.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/account_handler.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/erc_721.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/extension_handler.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/nft_extension.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/relayer_handler.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/test_erc20.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/relayer/src/abis/unclaims_handler.rs

Large diffs are not rendered by default.

18 changes: 16 additions & 2 deletions packages/relayer/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,14 @@ pub async fn handle_email(email: String) -> Result<EmailWalletEvent> {
info!(LOG, "Sender wallet address: {}", wallet_addr; "func" => function_name!());
let claims = DB.get_claims_by_email_addr(&from_addr).await?;
for claim in claims {
claim_unclaims(claim).await?;
match claim_unclaims(claim.clone()).await {
Ok(value) => {
if let Err(e) = handle_email_event(value).await {
error!(LOG, "Error handling email event: {}", e; "func" => function_name!());
}
}
Err(e) => error!(LOG, "Error claiming: {}", e; "func" => function_name!()),
}
}
return Ok(EmailWalletEvent::AccountCreated {
email_addr: from_addr,
Expand Down Expand Up @@ -347,7 +354,14 @@ pub async fn handle_email(email: String) -> Result<EmailWalletEvent> {
is_announced: false,
is_seen: false,
};
claim_unclaims(claim).await?;
match claim_unclaims(claim.clone()).await {
Ok(value) => {
if let Err(e) = handle_email_event(value).await {
error!(LOG, "Error handling email event: {}", e; "func" => function_name!());
}
}
Err(e) => error!(LOG, "Error claiming: {}", e; "func" => function_name!()),
}
trace!(LOG, "Added claim"; "func" => function_name!());
}
let message_id = parsed_email.get_message_id()?;
Expand Down
27 changes: 24 additions & 3 deletions packages/relayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,14 @@ pub async fn run(config: RelayerConfig) -> Result<()> {
is_announced: true,
is_seen: false,
};
claim_unclaims(claim.clone()).await?;
match claim_unclaims(claim.clone()).await {
Ok(value) => {
if let Err(e) = handle_email_event(value).await {
error!(LOG, "Error handling email event: {}", e; "func" => function_name!());
}
}
Err(e) => error!(LOG, "Error claiming: {}", e; "func" => function_name!()),
}
Ok(())
}) as Pin<Box<dyn Future<Output = Result<()>> + Send>> // Add + Send here
};
Expand All @@ -228,7 +235,14 @@ pub async fn run(config: RelayerConfig) -> Result<()> {
is_announced: true,
is_seen: false,
};
claim_unclaims(claim.clone()).await?;
match claim_unclaims(claim.clone()).await {
Ok(value) => {
if let Err(e) = handle_email_event(value).await {
error!(LOG, "Error handling email event: {}", e; "func" => function_name!());
}
}
Err(e) => error!(LOG, "Error claiming: {}", e; "func" => function_name!()),
}
Ok(())
}) as Pin<Box<dyn Future<Output = Result<()>> + Send>> // Add + Send here
};
Expand Down Expand Up @@ -291,7 +305,14 @@ async fn catch_claims_in_db_fn() -> Result<()> {
let claims = DB.get_claims_unexpired(now).await?;
for claim in claims {
info!(LOG, "Claiming claim for : {}", claim.email_address; "func" => function_name!());
claim_unclaims(claim.clone()).await?;
match claim_unclaims(claim.clone()).await {
Ok(value) => {
if let Err(e) = handle_email_event(value).await {
error!(LOG, "Error handling email event: {}", e; "func" => function_name!());
}
}
Err(e) => trace!(LOG, "Error claiming: {}", e; "func" => function_name!()),
}
}
let claims = DB.get_claims_expired(now).await?;
for claim in claims {
Expand Down
4 changes: 2 additions & 2 deletions packages/relayer/src/modules/claimer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub async fn claim_unclaims(mut claim: Claim) -> Result<EmailWalletEvent> {
&format!("0x{}", hex::encode(wallet_addr.as_bytes())),
)
.await?;
return Ok(EmailWalletEvent::AccountNotCreated {
return Ok(EmailWalletEvent::Invitation {
email_addr: claim.email_address,
account_code,
is_first: true,
Expand All @@ -87,7 +87,7 @@ pub async fn claim_unclaims(mut claim: Claim) -> Result<EmailWalletEvent> {
.check_if_account_created_by_account_code(&claim.email_address, &account_code_str)
.await?;
if !is_seen && !is_account_created {
return Ok(EmailWalletEvent::AccountNotCreated {
return Ok(EmailWalletEvent::Invitation {
email_addr: claim.email_address,
account_code: AccountCode(hex2field(&account_code_str)?),
is_first: false,
Expand Down
22 changes: 17 additions & 5 deletions packages/relayer/src/modules/mail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub enum EmailWalletEvent {
email_op: EmailOp,
tx_hash: String,
},
AccountNotCreated {
Invitation {
email_addr: String,
account_code: AccountCode,
// claim: Claim,
Expand Down Expand Up @@ -162,23 +162,35 @@ pub async fn handle_email_event(event: EmailWalletEvent) -> Result<()> {
};
send_email(email).await?;
}
EmailWalletEvent::AccountNotCreated {
EmailWalletEvent::Invitation {
email_addr,
account_code,
// claim,
is_first: _,
tx_hash,
} => {
let subject = format!("Your Email Wallet account is ready to be deployed.",);
let assets_msgs = vec!["ERC20: 100 TEST".to_string()];
let assets = search_user_assets(&email_addr).await?;

let invitation_code_hex = &field2hex(&account_code.0)[2..];
let subject = format!(
"Your Email Wallet Account is ready to be deployed. Code {}",
invitation_code_hex
);

let (assets_list_plain, assets_list_html) =
generate_asset_list_body(&assets, assets_msgs).await?;

let account_salt =
AccountSalt::new(&PaddedEmailAddr::from_email_addr(&email_addr), account_code)?;
let wallet_addr = CLIENT.get_wallet_addr_from_salt(&account_salt.0).await?;
let body_plain = format!(
"Hi {}!\nYour Email Wallet account is ready to be deployed. Your wallet address: {}/address/{}.\nPlease reply to this email to start using Email Wallet. You don't have to add any message in the reply 😄.",
email_addr, CHAIN_RPC_EXPLORER.get().unwrap(), wallet_addr,
);
let render_data = serde_json::json!({"userEmailAddr": email_addr, "walletAddr": wallet_addr, "transactionHash": tx_hash, "chainRPCExplorer": CHAIN_RPC_EXPLORER.get().unwrap()});
let body_html = render_html("account_not_created.html", render_data).await?;
let render_data = serde_json::json!({"userEmailAddr": email_addr, "walletAddr": wallet_addr, "assetsList": assets_list_html, "chainRPCExplorer": CHAIN_RPC_EXPLORER.get().unwrap()});
println!("render_data: {:?}", render_data);
let body_html = render_html("invitation.html", render_data).await?;
let email = EmailMessage {
to: email_addr.to_string(),
subject,
Expand Down
9 changes: 8 additions & 1 deletion packages/relayer/src/modules/web_server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,14 @@ async fn unclaim(payload: UnclaimRequest) -> Result<String> {
is_announced: false,
is_seen: false,
};
claim_unclaims(claim).await?;
match claim_unclaims(claim.clone()).await {
Ok(value) => {
if let Err(e) = handle_email_event(value).await {
error!(LOG, "Error handling email event: {}", e; "func" => function_name!());
}
}
Err(e) => error!(LOG, "Error claiming: {}", e; "func" => function_name!()),
}
trace!(LOG, "Unclaimed {} for {} is accepted", if payload.is_fund { "fund" } else { "state" }, payload.email_address; "func" => function_name!());

Ok(format!(
Expand Down
145 changes: 143 additions & 2 deletions packages/relayer/src/utils/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

use crate::*;
use chrono::{DateTime, Local};
use ethers::abi::Token;
use ethers::types::{Bytes, U256};
use ethers::{
abi::{self, ParamType, Token},
types::{Address, U256},
};
use relayer_utils::*;
use serde_json::Value;

use ::serde::Deserialize;

Expand All @@ -17,6 +20,21 @@ const DOMAIN_FIELDS: usize = 9;
const SUBJECT_FIELDS: usize = 17;
const EMAIL_ADDR_FIELDS: usize = 9;

pub enum Asset {
ERC20 {
token_addr: Address,
token_name: String,
amount: U256,
amount_str: String,
},
ERC721 {
token_addr: Address,
token_name: String,
token_id: U256,
token_uri: String,
},
}

#[derive(Debug, Clone, Deserialize)]
pub struct ProverRes {
proof: ProofJson,
Expand Down Expand Up @@ -130,3 +148,126 @@ pub fn derive_relayer_rand(private_key: &str) -> Result<RelayerRand> {
seed.append(&mut b"EMAIL WALLET RELAYER RAND".to_vec());
Ok(RelayerRand::new_from_seed(&seed)?)
}

pub async fn search_user_assets(email_addr: &str) -> Result<Vec<Asset>> {
let claims = DB.get_claims_by_email_addr(email_addr).await?;
let _is_for_nft_demo = false;
let mut assets = vec![];
for claim in claims {
if claim.is_fund {
let unclaim_fund = CLIENT.query_unclaimed_fund(claim.id).await?;
let token_decimal = CLIENT
.query_decimals_of_erc20_address(unclaim_fund.token_addr)
.await?;
let amount =
uint_to_decimal_string(unclaim_fund.amount.as_u128(), token_decimal as usize);
let name = CLIENT.query_token_name(unclaim_fund.token_addr).await?;
assets.push(Asset::ERC20 {
token_addr: unclaim_fund.token_addr,
token_name: name,
amount: unclaim_fund.amount,
amount_str: amount,
});
continue;
}
let unclaimed_state = CLIENT.query_unclaimed_state(claim.id).await?;
if unclaimed_state.extension_addr
!= CLIENT.query_default_extension_for_command("NFT").await?
{
continue;
}
let (nft_addr, nft_id, nft_name, nft_uri) = get_nft_info(&unclaimed_state.state).await?;
assets.push(Asset::ERC721 {
token_addr: nft_addr,
token_name: nft_name,
token_id: nft_id,
token_uri: nft_uri,
});
}
Ok(assets)
}

pub async fn get_nft_info(state: &[u8]) -> Result<(Address, U256, String, String)> {
let decoded = abi::decode(&[ParamType::Address, ParamType::Uint(256)], &state)?;
let nft_addr = decoded[0].clone().into_address().unwrap();
let nft_id = decoded[1].clone().into_uint().unwrap();
let nft_name = CLIENT.query_nft_name_of_address(nft_addr).await?;
let nft_uri = CLIENT
.query_erc721_token_uri_of_token(nft_addr, nft_id)
.await?;
Ok((nft_addr, nft_id, nft_name, nft_uri))
}

pub async fn download_img_from_uri(url: &str) -> Result<Vec<u8>> {
let response = reqwest::get(url).await?;
let bytes = response.bytes().await.map_err(|e| anyhow!(e))?;
Ok(bytes.to_vec())
}

pub async fn generate_asset_list_body(
assets: &[Asset],
mut assets_msgs: Vec<String>,
) -> Result<(String, Vec<Value>)> {
let mut images = vec![None; assets_msgs.len()];
for asset in assets {
match asset {
Asset::ERC20 {
token_addr: _,
token_name,
amount: _,
amount_str,
} => {
let mut token_name = token_name.clone();
if token_name == "WETH" {
token_name = "ETH".to_string();
}
assets_msgs.push(format!("ERC20: {} {}", amount_str, token_name));
images.push(None);
}
Asset::ERC721 {
token_addr: _,
token_name,
token_id,
token_uri,
} => {
let json_uri: Value = serde_json::from_str(
&String::from_utf8(
base64::decode(token_uri.split(",").nth(1).expect("Invalid base64 string"))
.expect("Failed to decode base64 string"),
)
.expect("Invalid UTF-8 sequence"),
)
.expect("Failed to parse JSON");
let img = json_uri.clone()["image"]
.as_str()
.unwrap_or_default()
.to_string();
images.push(Some(img));
assets_msgs.push(format!("NFT: ID {} of {}", token_id, token_name));
}
}
}
let mut assets_list_plain = String::new();
for asset_msg in assets_msgs.iter() {
assets_list_plain.push_str(&format!("{}\n", asset_msg));
}
let mut assets_list_html = vec![];
println!("assets_msgs: {:?}", assets_msgs);
for (idx, (asset_msg, image)) in assets_msgs.iter().zip(images.into_iter()).enumerate() {
if image.is_some() {
let value = serde_json::json!({
"msg": asset_msg,
"img": image.unwrap(),
"is_img": true,
});
assets_list_html.push(value);
}
let value = serde_json::json!({
"msg": asset_msg,
"img": "",
"is_img": false,
});
assets_list_html.push(value);
}
Ok((assets_list_plain, assets_list_html))
}

0 comments on commit 067ef20

Please sign in to comment.