Skip to content

Commit

Permalink
feat: fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bisht13 committed Mar 31, 2024
1 parent 4b3c90e commit 92c85e6
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 65 deletions.
5 changes: 3 additions & 2 deletions packages/relayer/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
EMAIL_AUTH_ADDRESS= # Address of the deployed wallet contract.
PRIVATE_KEY= # Private key for Relayer's account.
CHAIN_RPC_PROVIDER=http://127.0.0.1:8545
CHAIN_RPC_EXPLORER=
CHAIN_ID=11155111 # Chain ID of the testnet.

# IMAP + SMTP (Settings will be provided by your email provider)
Expand All @@ -22,8 +23,8 @@ CIRCUITS_DIR_PATH= #Path to email-wallet/packages/circuits
INPUT_FILES_DIR_PATH= #Path to email-wallet/packages/relayer/input_files
EMAIL_TEMPLATES_PATH= #Path to email templates, e.g. ./packages/relayer/eml_templates/

CANISTER_ID="i73e6-2qaaa-aaaan-qepxa-cai"
CANISTER_ID="q7eci-dyaaa-aaaak-qdbia-cai"
PEM_PATH="./.ic.pem"
IC_REPLICA_URL="https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=i73e6-2qaaa-aaaan-qepxa-cai"
IC_REPLICA_URL="https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=q7eci-dyaaa-aaaak-qdbia-cai"

JSON_LOGGER=false
2 changes: 1 addition & 1 deletion packages/relayer/eml_templates/acceptance_request.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
>
You have received an guardian request from the wallet address <strong>{{walletAddress}}</strong>.
<br>
Your request ID is <strong>#{{requestId}}</strong>.
Your request ID is #{{requestId}}.
<br><br>
If you did not initiate this request, please contact us immediately.
</p>
Expand Down
45 changes: 26 additions & 19 deletions packages/relayer/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl ChainClient {
wallet.with_chain_id(*CHAIN_ID.get().unwrap()),
));
let email_auth = EmailAuth::new(
CORE_CONTRACT_ADDRESS.get().unwrap().parse::<Address>()?,
EMAIL_AUTH_ADDRESS.get().unwrap().parse::<Address>()?,
client.clone(),
);
let ecdsa_owned_dkim_registry =
Expand All @@ -47,17 +47,15 @@ impl ChainClient {
domain_name: String,
public_key_hash: [u8; 32],
signature: Bytes,
dkim: H160,
) -> Result<String> {
// Mutex is used to prevent nonce conflicts.
let mut mutex = SHARED_MUTEX.lock().await;
*mutex += 1;

let call = self.ecdsa_owned_dkim_registry.set_dkim_public_key_hash(
selector,
domain_name,
public_key_hash,
signature,
);
let contract = ECDSAOwnedDKIMRegistry::new(dkim, self.client.clone());
let call =
contract.set_dkim_public_key_hash(selector, domain_name, public_key_hash, signature);
let tx = call.send().await?;
let receipt = tx
.log()
Expand All @@ -69,32 +67,41 @@ impl ChainClient {
Ok(tx_hash)
}

#[named]
pub async fn check_if_dkim_public_key_hash_valid(
&self,
domain_name: ::std::string::String,
public_key_hash: [u8; 32],
dkim: H160,
) -> Result<bool> {
let is_valid = self
.ecdsa_owned_dkim_registry
.is_dkim_public_key_hash_valid(domain_name.clone(), public_key_hash)
let contract = ECDSAOwnedDKIMRegistry::new(dkim, self.client.clone());
let is_valid = contract
.is_dkim_public_key_hash_valid(domain_name, public_key_hash)
.call()
.await?;
info!(
LOG,
"{:?} for {} is already registered: {}", public_key_hash, domain_name, is_valid; "func" => function_name!()
);
Ok(is_valid)
}

pub async fn get_dkim_from_wallet(&self, wallet_addr: &String) -> Result<H160> {
let wallet_address: H160 = wallet_addr.parse()?;
let contract = EmailAccountRecovery::new(wallet_address, self.client.clone());
let dkim = contract.dkim().call().await?;
Ok(dkim)
}

pub async fn get_latest_block_number(&self) -> U64 {
self.client.get_block_number().await.unwrap()
}

pub async fn is_wallet_deployed(&self, wallet_addr: &String) -> bool {
// Check the bytecode of the contract
let code = self.client.get_code(wallet_addr, None).await.unwrap();
!code.is_empty()
pub async fn is_wallet_deployed(&self, wallet_addr_str: &String) -> bool {
let wallet_addr: H160 = wallet_addr_str.parse().unwrap();
match self.client.get_code(wallet_addr, None).await {
Ok(code) => !code.is_empty(),
Err(e) => {
// Log the error or handle it as needed
eprintln!("Error querying contract code: {:?}", e);
false
}
}
}

pub async fn get_acceptance_subject_templates(
Expand Down
15 changes: 8 additions & 7 deletions packages/relayer/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,25 @@ pub async fn handle_email<P: EmailsPool>(
let padded_from_addr = PaddedEmailAddr::from_email_addr(&guardian_email_addr);
trace!(LOG, "From address: {}", guardian_email_addr; "func" => function_name!());
let subject = parsed_email.get_subject_all()?;

let account_key_str = db
.get_account_key(&guardian_email_addr)
.get_invitation_code_from_email_addr(&guardian_email_addr)
.await?
.ok_or(anyhow!(
"The user of email address {} is not registered.",
guardian_email_addr
))?;
let account_key = AccountKey(hex2field(&account_key_str)?);
let account_key = AccountKey(hex2field(&format!("0x{}", account_key_str))?);
let wallet_salt = WalletSalt::new(&padded_from_addr, account_key)?;

let request_decomposed_def =
serde_json::from_str(include_str!("./regex_json/request_def.json"))?;
let request_idxes = extract_substr_idxes(&subject, &request_decomposed_def)?;
let request_idxes = extract_substr_idxes(&email, &request_decomposed_def)?;
if request_idxes.is_empty() {
bail!(WRONG_SUBJECT_FORMAT);
}
let request_id = &subject[request_idxes[0].0..request_idxes[0].1];
info!(LOG, "Request idxes: {:?}", request_idxes; "func" => function_name!());
let request_id = &email[request_idxes[0].0..request_idxes[0].1];
let request_id_u64 = request_id
.parse::<u64>()
.map_err(|e| anyhow!("Failed to parse request_id to u64: {}", e))?;
Expand All @@ -52,7 +53,7 @@ pub async fn handle_email<P: EmailsPool>(
});
}
let request = request_record.unwrap();
check_and_update_dkim(&email, &parsed_email, &chain_client).await?;
check_and_update_dkim(&email, &parsed_email, &chain_client, &request.wallet_eth_addr).await?;
let subject_template = chain_client
.get_acceptance_subject_templates(&request.wallet_eth_addr, request.template_idx)
.await?;
Expand All @@ -76,7 +77,7 @@ pub async fn handle_email<P: EmailsPool>(
trace!(LOG, "Email with account code"; "func" => function_name!());
let account_key = AccountKey::from(hex2field(&format!("0x{}", invitation_code))?);
let stored_account_key = db
.get_invitation_code_from_email(&guardian_email_addr)
.get_invitation_code_from_email_addr(&guardian_email_addr)
.await?;
if let Some(stored_account_key) = stored_account_key.as_ref() {
if stored_account_key != &field2hex(&account_key.0) {
Expand Down
38 changes: 11 additions & 27 deletions packages/relayer/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ impl Database {

sqlx::query(
"CREATE TABLE IF NOT EXISTS requests (
request_id INT PRIMARY KEY,
request_id BIGINT PRIMARY KEY,
wallet_eth_addr TEXT NOT NULL,
guardian_email_addr TEXT NOT NULL,
random TEXT NOT NULL,
email_addr_commit TEXT NOT NULL,
is_for_recovery BOOLEAN NOT NULL DEFAULT FALSE,
template_idx INT NOT NULL,
is_processed BOOLEAN NOT NULL DEFAULT FALSE,
Expand Down Expand Up @@ -109,26 +107,11 @@ impl Database {
Ok(())
}

pub(crate) async fn get_account_key(&self, email: &str) -> Result<Option<String>> {
let row = sqlx::query("SELECT * FROM codes WHERE guardian_email_addr = $1")
.bind(email)
.fetch_optional(&self.db)
.await?;

match row {
Some(row) => {
let account_code: String = row.get("account_code");
Ok(Some(account_code))
}
None => Ok(None),
}
}

#[named]
pub(crate) async fn insert_credentials(&self, row: &Credentials) -> Result<()> {
info!(LOG, "insert row {:?}", row; "func" => function_name!());
let row = sqlx::query(
"INSERT INTO users (account_code, wallet_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *",
"INSERT INTO codes (account_code, wallet_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *",
)
.bind(&row.account_code)
.bind(&row.wallet_eth_addr)
Expand Down Expand Up @@ -161,7 +144,7 @@ impl Database {
#[named]
pub async fn set_guardian_in_credentials(&self, account_code: &str) -> Result<()> {
info!(LOG, "account_code {}", account_code; "func" => function_name!());
let res = sqlx::query("UPDATE users SET is_set = TRUE WHERE account_code = $1")
let res = sqlx::query("UPDATE codes SET is_set = TRUE WHERE account_code = $1")
.bind(account_code)
.execute(&self.db)
.await?;
Expand All @@ -186,7 +169,7 @@ impl Database {
let wallet_eth_addr: String = row.get("wallet_eth_addr");
let guardian_email_addr: String = row.get("guardian_email_addr");
let is_for_recovery: bool = row.get("is_for_recovery");
let template_idx: u64 = row.get::<i64, _>("template_idx") as u64;
let template_idx: i32 = row.get("template_idx");
let is_processed: bool = row.get("is_processed");
let is_success: Option<bool> = row.get("is_success");
let email_nullifier: Option<String> = row.get("email_nullifier");
Expand All @@ -196,7 +179,7 @@ impl Database {
wallet_eth_addr,
guardian_email_addr,
is_for_recovery,
template_idx,
template_idx: template_idx as u64,
is_processed,
is_success,
email_nullifier,
Expand Down Expand Up @@ -225,12 +208,13 @@ impl Database {
Ok(())
}

pub(crate) async fn get_invitation_code_from_email(
pub(crate) async fn get_invitation_code_from_email_addr(
&self,
email: &str,
email_addr: &str,
) -> Result<Option<String>> {
println!("email_addr: {}", email_addr);
let row = sqlx::query("SELECT * FROM codes WHERE guardian_email_addr = $1")
.bind(email)
.bind(email_addr)
.fetch_optional(&self.db)
.await?;

Expand Down Expand Up @@ -280,7 +264,7 @@ impl Database {
let wallet_eth_addr: String = row.get("wallet_eth_addr");
let guardian_email_addr: String = row.get("guardian_email_addr");
let is_for_recovery: bool = row.get("is_for_recovery");
let template_idx: u64 = row.get::<i64, _>("template_idx") as u64;
let template_idx: i32 = row.get("template_idx");
let is_processed: bool = row.get("is_processed");
let is_success: Option<bool> = row.get("is_success");
let email_nullifier: Option<String> = row.get("email_nullifier");
Expand All @@ -290,7 +274,7 @@ impl Database {
wallet_eth_addr,
guardian_email_addr,
is_for_recovery,
template_idx,
template_idx: template_idx as u64,
is_processed,
is_success,
email_nullifier,
Expand Down
1 change: 0 additions & 1 deletion packages/relayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ pub static CHAIN_ID: OnceLock<u32> = OnceLock::new();
pub static EMAIL_AUTH_ADDRESS: OnceLock<String> = OnceLock::new();
pub static CHAIN_RPC_PROVIDER: OnceLock<String> = OnceLock::new();
pub static CHAIN_RPC_EXPLORER: OnceLock<String> = OnceLock::new();
pub static CORE_CONTRACT_ADDRESS: OnceLock<String> = OnceLock::new();
pub static INPUT_FILES_DIR: OnceLock<String> = OnceLock::new();
pub static EMAIL_TEMPLATES: OnceLock<String> = OnceLock::new();
pub static RELAYER_EMAIL_ADDRESS: OnceLock<String> = OnceLock::new();
Expand Down
12 changes: 11 additions & 1 deletion packages/relayer/src/modules/dkim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,24 @@ pub async fn check_and_update_dkim(
email: &str,
parsed_email: &ParsedEmail,
chain_client: &Arc<ChainClient>,
wallet_addr: &str,
) -> Result<()> {
let mut public_key_n = parsed_email.public_key.clone();
public_key_n.reverse();
let public_key_hash = public_key_hash(&public_key_n)?;
info!(LOG, "public_key_hash {:?}", public_key_hash; "func" => function_name!());
let domain = parsed_email.get_email_domain()?;
info!(LOG, "domain {:?}", domain; "func" => function_name!());
let dkim = chain_client
.get_dkim_from_wallet(&wallet_addr.to_string())
.await?;
info!(LOG, "dkim {:?}", dkim; "func" => function_name!());
if chain_client
.check_if_dkim_public_key_hash_valid(domain.clone(), fr_to_bytes32(&public_key_hash)?)
.check_if_dkim_public_key_hash_valid(
domain.clone(),
fr_to_bytes32(&public_key_hash)?,
dkim.clone(),
)
.await?
{
info!(LOG, "public key registered"; "func" => function_name!());
Expand Down Expand Up @@ -109,6 +118,7 @@ pub async fn check_and_update_dkim(
domain,
TryInto::<[u8; 32]>::try_into(public_key_hash).unwrap(),
signature,
dkim,
)
.await?;
info!(LOG, "DKIM registry updated {:?}", tx_hash; "func" => function_name!());
Expand Down
10 changes: 3 additions & 7 deletions packages/relayer/src/modules/email_client/mail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,11 @@ async fn event_consumer_fn(event: EmailAuthEvent, sender: EmailForwardSender) ->
guardian_email_addr,
request_id,
} => {
let invitation_code = DB.get_invitation_code_from_email(&wallet_eth_addr).await?;
let invitation_code = DB.get_invitation_code_from_email_addr(&guardian_email_addr).await?;
println!("Invitation code: {:?}", invitation_code);
let mut hex_invitation_code = String::new();
if let Some(code_str) = invitation_code {
if let Ok(code) = u64::from_str_radix(&code_str, 16) {
// Assuming the code is in hexadecimal string form
hex_invitation_code = format!("{:x}", code);
} else {
return Err(anyhow!("Failed to parse account code"));
}
hex_invitation_code = code_str.to_string();
} else {
return Err(anyhow!("Account code not found"));
}
Expand Down
4 changes: 4 additions & 0 deletions packages/relayer/src/regex_json/request_def.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
{
"is_public": true,
"regex_def": "[0-9]+"
},
{
"is_public": false,
"regex_def": "."
}
]
}

0 comments on commit 92c85e6

Please sign in to comment.