diff --git a/.gitignore b/.gitignore
index 6c6e6de8..11170544 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,11 +33,7 @@ packages/contracts/deployments
# Relayer
target
-packages/relayer/db/*
-packages/relayer/*.db
-packages/relayer/received_eml/*.eml
-packages/relayer/received_eml/*.json
-packages/relayer/proofs
+packages/relayer/.sqlx/*
packages/relayer/logs
packages/relayer/config.json
.ic.pem
diff --git a/Cargo.lock b/Cargo.lock
index ab3fd146..7eaf65d6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -14,19 +14,13 @@ dependencies = [
[[package]]
name = "addr2line"
-version = "0.22.0"
+version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
[[package]]
name = "adler2"
version = "2.0.0"
@@ -94,9 +88,9 @@ checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
[[package]]
name = "arrayref"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a"
+checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
[[package]]
name = "arrayvec"
@@ -115,13 +109,13 @@ dependencies = [
[[package]]
name = "async-trait"
-version = "0.1.82"
+version = "0.1.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1"
+checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -144,6 +138,12 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
[[package]]
name = "auto_impl"
version = "1.2.0"
@@ -152,14 +152,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
name = "autocfg"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "axum"
@@ -189,7 +189,7 @@ dependencies = [
"serde_urlencoded",
"sync_wrapper 1.0.1",
"tokio",
- "tower 0.5.1",
+ "tower",
"tower-layer",
"tower-service",
"tracing",
@@ -218,17 +218,17 @@ dependencies = [
[[package]]
name = "backtrace"
-version = "0.3.73"
+version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
+checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
- "cc",
"cfg-if",
"libc",
- "miniz_oxide 0.7.4",
+ "miniz_oxide",
"object",
"rustc-demangle",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -368,9 +368,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.7.1"
+version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
+checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
dependencies = [
"serde",
]
@@ -430,9 +430,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.1.15"
+version = "1.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6"
+checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1"
dependencies = [
"jobserver",
"libc",
@@ -579,9 +579,9 @@ dependencies = [
[[package]]
name = "const-hex"
-version = "1.12.0"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6"
+checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -626,9 +626,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "cpufeatures"
-version = "0.2.13"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
+checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
dependencies = [
"libc",
]
@@ -761,7 +761,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -798,7 +798,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -1141,10 +1141,10 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
- "reqwest",
+ "reqwest 0.11.27",
"serde",
"serde_json",
- "syn 2.0.77",
+ "syn 2.0.79",
"toml",
"walkdir",
]
@@ -1162,7 +1162,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_json",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -1188,7 +1188,7 @@ dependencies = [
"serde",
"serde_json",
"strum",
- "syn 2.0.77",
+ "syn 2.0.79",
"tempfile",
"thiserror",
"tiny-keccak",
@@ -1203,7 +1203,7 @@ checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649"
dependencies = [
"chrono",
"ethers-core",
- "reqwest",
+ "reqwest 0.11.27",
"semver 1.0.23",
"serde",
"serde_json",
@@ -1228,7 +1228,7 @@ dependencies = [
"futures-locks",
"futures-util",
"instant",
- "reqwest",
+ "reqwest 0.11.27",
"serde",
"serde_json",
"thiserror",
@@ -1260,7 +1260,7 @@ dependencies = [
"jsonwebtoken",
"once_cell",
"pin-project",
- "reqwest",
+ "reqwest 0.11.27",
"serde",
"serde_json",
"thiserror",
@@ -1411,12 +1411,12 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
-version = "1.0.33"
+version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
+checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
dependencies = [
"crc32fast",
- "miniz_oxide 0.8.0",
+ "miniz_oxide",
]
[[package]]
@@ -1436,6 +1436,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@@ -1463,9 +1478,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
@@ -1478,9 +1493,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
@@ -1488,15 +1503,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
@@ -1516,9 +1531,9 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-locks"
@@ -1532,26 +1547,26 @@ dependencies = [
[[package]]
name = "futures-macro"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
name = "futures-sink"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-timer"
@@ -1565,9 +1580,9 @@ dependencies = [
[[package]]
name = "futures-util"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
@@ -1616,9 +1631,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.29.0"
+version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "glob"
@@ -1661,7 +1676,26 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
- "indexmap 2.5.0",
+ "indexmap 2.6.0",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "h2"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "http 1.1.0",
+ "indexmap 2.6.0",
"slab",
"tokio",
"tokio-util",
@@ -1671,7 +1705,7 @@ dependencies = [
[[package]]
name = "halo2curves"
version = "0.7.0"
-source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#b753a832e92d5c86c5c997327a9cf9de86a18851"
+source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#8771fe5a5d54fc03e74dbc8915db5dad3ab46a83"
dependencies = [
"blake2",
"digest",
@@ -1697,7 +1731,7 @@ dependencies = [
[[package]]
name = "halo2derive"
version = "0.1.0"
-source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#b753a832e92d5c86c5c997327a9cf9de86a18851"
+source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#8771fe5a5d54fc03e74dbc8915db5dad3ab46a83"
dependencies = [
"num-bigint",
"num-integer",
@@ -1707,6 +1741,20 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "handlebars"
+version = "6.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce25b617d1375ef96eeb920ae717e3da34a02fc979fe632c75128350f9e1f74a"
+dependencies = [
+ "log",
+ "pest",
+ "pest_derive",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
[[package]]
name = "hashbrown"
version = "0.12.3"
@@ -1723,6 +1771,12 @@ dependencies = [
"allocator-api2",
]
+[[package]]
+name = "hashbrown"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
+
[[package]]
name = "hashers"
version = "1.0.1"
@@ -1872,9 +1926,9 @@ dependencies = [
[[package]]
name = "httparse"
-version = "1.9.4"
+version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
+checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
[[package]]
name = "httpdate"
@@ -1892,7 +1946,7 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
- "h2",
+ "h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
@@ -1915,6 +1969,7 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
+ "h2 0.4.6",
"http 1.1.0",
"http-body 1.0.1",
"httparse",
@@ -1923,6 +1978,7 @@ dependencies = [
"pin-project-lite",
"smallvec",
"tokio",
+ "want",
]
[[package]]
@@ -1934,33 +1990,81 @@ dependencies = [
"futures-util",
"http 0.2.12",
"hyper 0.14.30",
- "rustls",
+ "rustls 0.21.12",
+ "tokio",
+ "tokio-rustls 0.24.1",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.27.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
+dependencies = [
+ "futures-util",
+ "http 1.1.0",
+ "hyper 1.4.1",
+ "hyper-util",
+ "rustls 0.23.14",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls 0.26.0",
+ "tower-service",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper 0.14.30",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
+dependencies = [
+ "bytes",
+ "http-body-util",
+ "hyper 1.4.1",
+ "hyper-util",
+ "native-tls",
"tokio",
- "tokio-rustls",
+ "tokio-native-tls",
+ "tower-service",
]
[[package]]
name = "hyper-util"
-version = "0.1.7"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
+checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b"
dependencies = [
"bytes",
+ "futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.1",
"hyper 1.4.1",
"pin-project-lite",
+ "socket2",
"tokio",
- "tower 0.4.13",
"tower-service",
+ "tracing",
]
[[package]]
name = "iana-time-zone"
-version = "0.1.60"
+version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
+checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
@@ -2056,12 +2160,12 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.5.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
+checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
- "hashbrown 0.14.5",
+ "hashbrown 0.15.0",
]
[[package]]
@@ -2096,9 +2200,9 @@ dependencies = [
[[package]]
name = "ipnet"
-version = "2.9.0"
+version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
+checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
[[package]]
name = "is-terminal"
@@ -2178,9 +2282,9 @@ dependencies = [
[[package]]
name = "k256"
-version = "0.13.3"
+version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b"
+checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
dependencies = [
"cfg-if",
"ecdsa",
@@ -2240,9 +2344,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.158"
+version = "0.2.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
+checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
[[package]]
name = "libloading"
@@ -2385,15 +2489,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-[[package]]
-name = "miniz_oxide"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
-dependencies = [
- "adler",
-]
-
[[package]]
name = "miniz_oxide"
version = "0.8.0"
@@ -2415,6 +2510,23 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "native-tls"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
+dependencies = [
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
[[package]]
name = "neon"
version = "0.10.1"
@@ -2564,23 +2676,23 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
name = "object"
-version = "0.36.4"
+version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
+checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "open-fastrlp"
@@ -2607,6 +2719,50 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "openssl"
+version = "0.10.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
+dependencies = [
+ "bitflags 2.6.0",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -2650,9 +2806,9 @@ dependencies = [
[[package]]
name = "parking"
-version = "2.2.0"
+version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
@@ -2761,6 +2917,51 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+[[package]]
+name = "pest"
+version = "2.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9"
+dependencies = [
+ "memchr",
+ "thiserror",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f"
+dependencies = [
+ "once_cell",
+ "pest",
+ "sha2",
+]
+
[[package]]
name = "petgraph"
version = "0.6.5"
@@ -2768,7 +2969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
- "indexmap 2.5.0",
+ "indexmap 2.6.0",
]
[[package]]
@@ -2811,7 +3012,7 @@ dependencies = [
"phf_shared 0.11.2",
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -2834,22 +3035,22 @@ dependencies = [
[[package]]
name = "pin-project"
-version = "1.1.5"
+version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
+checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.1.5"
+version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
+checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -2887,9 +3088,9 @@ dependencies = [
[[package]]
name = "pkg-config"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "poseidon-rs"
@@ -2931,7 +3132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
dependencies = [
"proc-macro2",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -2959,9 +3160,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
dependencies = [
"unicode-ident",
]
@@ -3076,9 +3277,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.5.3"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
+checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
"bitflags 2.6.0",
]
@@ -3096,9 +3297,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.10.6"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
+checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
dependencies = [
"aho-corasick",
"memchr",
@@ -3108,9 +3309,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.7"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
dependencies = [
"aho-corasick",
"memchr",
@@ -3119,9 +3320,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.4"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "relayer"
@@ -3130,7 +3331,11 @@ dependencies = [
"anyhow",
"axum",
"chrono",
+ "ethers",
+ "handlebars",
+ "regex",
"relayer-utils",
+ "reqwest 0.12.8",
"serde",
"serde_json",
"slog",
@@ -3143,7 +3348,6 @@ dependencies = [
[[package]]
name = "relayer-utils"
version = "0.3.7"
-source = "git+https://github.com/zkemail/relayer-utils.git?branch=main#5764f93c4e803cba39c0f06f8ced0cab1d229a25"
dependencies = [
"anyhow",
"base64 0.21.7",
@@ -3155,6 +3359,7 @@ dependencies = [
"hmac-sha256",
"itertools 0.10.5",
"lazy_static",
+ "mailparse",
"neon",
"num-bigint",
"num-traits",
@@ -3162,6 +3367,7 @@ dependencies = [
"poseidon-rs",
"rand_core",
"regex",
+ "reqwest 0.11.27",
"rsa",
"serde",
"serde_json",
@@ -3184,27 +3390,30 @@ dependencies = [
"encoding_rs",
"futures-core",
"futures-util",
- "h2",
+ "h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.30",
- "hyper-rustls",
+ "hyper-rustls 0.24.2",
+ "hyper-tls 0.5.0",
"ipnet",
"js-sys",
"log",
"mime",
+ "native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
- "rustls",
- "rustls-pemfile",
+ "rustls 0.21.12",
+ "rustls-pemfile 1.0.4",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 0.1.2",
- "system-configuration",
+ "system-configuration 0.5.1",
"tokio",
- "tokio-rustls",
+ "tokio-native-tls",
+ "tokio-rustls 0.24.1",
"tower-service",
"url",
"wasm-bindgen",
@@ -3214,6 +3423,49 @@ dependencies = [
"winreg",
]
+[[package]]
+name = "reqwest"
+version = "0.12.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2 0.4.6",
+ "http 1.1.0",
+ "http-body 1.0.1",
+ "http-body-util",
+ "hyper 1.4.1",
+ "hyper-rustls 0.27.3",
+ "hyper-tls 0.6.0",
+ "hyper-util",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls-pemfile 2.2.0",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper 1.0.1",
+ "system-configuration 0.6.1",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "windows-registry",
+]
+
[[package]]
name = "resolv-conf"
version = "0.7.0"
@@ -3340,9 +3592,9 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.35"
+version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f"
+checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
"bitflags 2.6.0",
"errno",
@@ -3359,10 +3611,23 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
"ring 0.17.8",
- "rustls-webpki",
+ "rustls-webpki 0.101.7",
"sct",
]
+[[package]]
+name = "rustls"
+version = "0.23.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8"
+dependencies = [
+ "once_cell",
+ "rustls-pki-types",
+ "rustls-webpki 0.102.8",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
@@ -3372,6 +3637,21 @@ dependencies = [
"base64 0.21.7",
]
+[[package]]
+name = "rustls-pemfile"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55"
+
[[package]]
name = "rustls-webpki"
version = "0.101.7"
@@ -3382,6 +3662,17 @@ dependencies = [
"untrusted 0.9.0",
]
+[[package]]
+name = "rustls-webpki"
+version = "0.102.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
+dependencies = [
+ "ring 0.17.8",
+ "rustls-pki-types",
+ "untrusted 0.9.0",
+]
+
[[package]]
name = "rustversion"
version = "1.0.17"
@@ -3436,6 +3727,15 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "schannel"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
[[package]]
name = "scoped-tls"
version = "1.0.1"
@@ -3484,6 +3784,29 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags 2.6.0",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
[[package]]
name = "semver"
version = "0.9.0"
@@ -3548,7 +3871,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -3575,9 +3898,9 @@ dependencies = [
[[package]]
name = "serde_spanned"
-version = "0.6.7"
+version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
+checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
@@ -3792,9 +4115,9 @@ dependencies = [
[[package]]
name = "sqlformat"
-version = "0.2.4"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f"
+checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790"
dependencies = [
"nom",
"unicode_categories",
@@ -3834,7 +4157,7 @@ dependencies = [
"hashbrown 0.14.5",
"hashlink",
"hex",
- "indexmap 2.5.0",
+ "indexmap 2.6.0",
"log",
"memchr",
"once_cell",
@@ -3846,10 +4169,12 @@ dependencies = [
"smallvec",
"sqlformat",
"thiserror",
+ "time",
"tokio",
"tokio-stream",
"tracing",
"url",
+ "uuid 1.10.0",
]
[[package]]
@@ -3862,7 +4187,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -3885,7 +4210,7 @@ dependencies = [
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
- "syn 2.0.77",
+ "syn 2.0.79",
"tempfile",
"tokio",
"url",
@@ -3929,7 +4254,9 @@ dependencies = [
"sqlx-core",
"stringprep",
"thiserror",
+ "time",
"tracing",
+ "uuid 1.10.0",
"whoami",
]
@@ -3967,7 +4294,9 @@ dependencies = [
"sqlx-core",
"stringprep",
"thiserror",
+ "time",
"tracing",
+ "uuid 1.10.0",
"whoami",
]
@@ -3990,8 +4319,10 @@ dependencies = [
"serde",
"serde_urlencoded",
"sqlx-core",
+ "time",
"tracing",
"url",
+ "uuid 1.10.0",
]
[[package]]
@@ -4043,7 +4374,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -4062,7 +4393,7 @@ dependencies = [
"fs2",
"hex",
"once_cell",
- "reqwest",
+ "reqwest 0.11.27",
"semver 1.0.23",
"serde",
"serde_json",
@@ -4085,9 +4416,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.77"
+version = "2.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
+checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
dependencies = [
"proc-macro2",
"quote",
@@ -4116,6 +4447,9 @@ name = "sync_wrapper"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
+dependencies = [
+ "futures-core",
+]
[[package]]
name = "system-configuration"
@@ -4125,7 +4459,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
- "system-configuration-sys",
+ "system-configuration-sys 0.5.0",
+]
+
+[[package]]
+name = "system-configuration"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
+dependencies = [
+ "bitflags 2.6.0",
+ "core-foundation",
+ "system-configuration-sys 0.6.0",
]
[[package]]
@@ -4138,6 +4483,16 @@ dependencies = [
"libc",
]
+[[package]]
+name = "system-configuration-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
[[package]]
name = "take_mut"
version = "0.2.2"
@@ -4152,9 +4507,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
-version = "3.12.0"
+version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
+checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
dependencies = [
"cfg-if",
"fastrand",
@@ -4176,22 +4531,22 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.63"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
+checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.63"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
+checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -4285,7 +4640,17 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
]
[[package]]
@@ -4294,15 +4659,26 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
- "rustls",
+ "rustls 0.21.12",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
+dependencies = [
+ "rustls 0.23.14",
+ "rustls-pki-types",
"tokio",
]
[[package]]
name = "tokio-stream"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
+checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -4317,18 +4693,18 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
dependencies = [
"futures-util",
"log",
- "rustls",
+ "rustls 0.21.12",
"tokio",
- "tokio-rustls",
+ "tokio-rustls 0.24.1",
"tungstenite",
"webpki-roots",
]
[[package]]
name = "tokio-util"
-version = "0.7.11"
+version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
+checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
dependencies = [
"bytes",
"futures-core",
@@ -4360,32 +4736,17 @@ dependencies = [
[[package]]
name = "toml_edit"
-version = "0.22.20"
+version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
+checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
- "indexmap 2.5.0",
+ "indexmap 2.6.0",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
-[[package]]
-name = "tower"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
-dependencies = [
- "futures-core",
- "futures-util",
- "pin-project",
- "pin-project-lite",
- "tokio",
- "tower-layer",
- "tower-service",
-]
-
[[package]]
name = "tower"
version = "0.5.1"
@@ -4448,7 +4809,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -4534,7 +4895,7 @@ dependencies = [
"httparse",
"log",
"rand",
- "rustls",
+ "rustls 0.21.12",
"sha1",
"thiserror",
"url",
@@ -4547,6 +4908,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+[[package]]
+name = "ucd-trie"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
+
[[package]]
name = "uint"
version = "0.9.5"
@@ -4567,36 +4934,36 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicode-bidi"
-version = "0.3.15"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-normalization"
-version = "0.1.23"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
+checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-properties"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524"
+checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unicode-xid"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "unicode_categories"
@@ -4730,7 +5097,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
"wasm-bindgen-shared",
]
@@ -4764,7 +5131,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -4798,7 +5165,7 @@ checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
@@ -4873,6 +5240,36 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows-registry"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
+dependencies = [
+ "windows-result",
+ "windows-strings",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
+dependencies = [
+ "windows-result",
+ "windows-targets 0.52.6",
+]
+
[[package]]
name = "windows-sys"
version = "0.48.0"
@@ -5023,9 +5420,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
-version = "0.6.18"
+version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
+checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
dependencies = [
"memchr",
]
@@ -5092,7 +5489,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.77",
+ "syn 2.0.79",
]
[[package]]
diff --git a/packages/relayer/Cargo.toml b/packages/relayer/Cargo.toml
index b46f4954..2675f1bd 100644
--- a/packages/relayer/Cargo.toml
+++ b/packages/relayer/Cargo.toml
@@ -8,13 +8,18 @@ anyhow = "1.0.89"
axum = "0.7.7"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
-sqlx = { version = "0.8.2", features = ["postgres", "runtime-tokio"] }
+sqlx = { version = "0.8.2", features = ["postgres", "runtime-tokio", "migrate", "uuid", "time"] }
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 = { git = "https://github.com/zkemail/relayer-utils.git", branch = "main" }
+relayer-utils = { path = "../../../relayer-utils" }
slog = { version = "2.7.0", features = [
"max_level_trace",
"release_max_level_warn",
] }
uuid = { version = "1.10.0", features = ["serde", "v4"] }
chrono = { version = "0.4.38", features = ["serde"] }
+ethers = "2.0.14"
+reqwest = { version = "0.12.8", features = ["json"] }
+handlebars = "6.1.0"
+regex = "1.11.0"
diff --git a/packages/relayer/config.example.json b/packages/relayer/config.example.json
index 415ec936..ce5da39f 100644
--- a/packages/relayer/config.example.json
+++ b/packages/relayer/config.example.json
@@ -1,10 +1,14 @@
{
"port": 8000,
"databaseUrl": "postgres://test@localhost:5432/relayer",
+ "smtpUrl": "http://localhost:3000",
"proverUrl": "https://zkemail--email-auth-prover-v1-4-0-flask-app.modal.run",
+ "paths": {
+ "pem": "./.ic.pem",
+ "emailTemplates": "./email_templates"
+ },
"icp": {
"canisterId": "q7eci-dyaaa-aaaak-qdbia-cai",
- "pemPath": "./.ic.pem",
"icReplicaUrl": "https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=q7eci-dyaaa-aaaak-qdbia-cai"
},
"chains": {
diff --git a/packages/relayer/email_templates/command_template.html b/packages/relayer/email_templates/command_template.html
index e3ca9232..91ad7ce2 100644
--- a/packages/relayer/email_templates/command_template.html
+++ b/packages/relayer/email_templates/command_template.html
@@ -126,7 +126,7 @@
Reply "Confirm" to this email to accept the request.
- Your request ID is #{{requestId}}.
+ Your request ID is {{requestId}}.
If you did not initiate this request, please contact us immediately.
diff --git a/packages/relayer/migrations/20241008135456_init.down.sql b/packages/relayer/migrations/20241008135456_init.down.sql
new file mode 100644
index 00000000..2ff0f67a
--- /dev/null
+++ b/packages/relayer/migrations/20241008135456_init.down.sql
@@ -0,0 +1,5 @@
+-- Add down migration script here
+
+DROP TABLE IF EXISTS requests;
+
+DROP TABLE IF EXISTS expected_replies;
\ No newline at end of file
diff --git a/packages/relayer/migrations/20241008135456_init.up.sql b/packages/relayer/migrations/20241008135456_init.up.sql
new file mode 100644
index 00000000..bf18f5b3
--- /dev/null
+++ b/packages/relayer/migrations/20241008135456_init.up.sql
@@ -0,0 +1,18 @@
+-- Add up migration script here
+
+CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
+
+CREATE TYPE status_enum AS ENUM ('Request received', 'Email sent', 'Email response received', 'Proving', 'Performing on chain transaction', 'Finished');
+
+CREATE TABLE IF NOT EXISTS requests (
+ id UUID PRIMARY KEY NOT NULL DEFAULT (uuid_generate_v4()),
+ status status_enum NOT NULL DEFAULT 'Request received',
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
+);
+
+CREATE TABLE IF NOT EXISTS expected_replies (
+ message_id VARCHAR(255) PRIMARY KEY,
+ request_id VARCHAR(255),
+ has_reply BOOLEAN DEFAULT FALSE,
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
+);
\ No newline at end of file
diff --git a/packages/relayer/src/config.rs b/packages/relayer/src/config.rs
index a1c191c9..05bf998b 100644
--- a/packages/relayer/src/config.rs
+++ b/packages/relayer/src/config.rs
@@ -10,17 +10,25 @@ use std::io::Read;
pub struct Config {
pub port: usize,
pub database_url: String,
+ pub smtp_url: String,
pub prover_url: String,
+ pub path: PathConfig,
pub icp: IcpConfig,
pub chains: HashMap,
pub json_logger: bool,
}
+#[derive(Deserialize, Debug, Clone)]
+#[serde(rename_all = "camelCase")]
+pub struct PathConfig {
+ pub pem: String,
+ pub email_templates: String,
+}
+
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct IcpConfig {
pub canister_id: String,
- pub pem_path: String,
pub ic_replica_url: String,
}
diff --git a/packages/relayer/src/db/mod.rs b/packages/relayer/src/db/mod.rs
deleted file mode 100644
index ee2d47ae..00000000
--- a/packages/relayer/src/db/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-mod model;
diff --git a/packages/relayer/src/db/model.rs b/packages/relayer/src/db/model.rs
deleted file mode 100644
index fe91c428..00000000
--- a/packages/relayer/src/db/model.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use serde::{Deserialize, Serialize};
-use sqlx::FromRow;
-use uuid::Uuid;
-
-#[derive(Debug, FromRow, Deserialize, Serialize)]
-#[allow(non_snake_case)]
-pub struct RequestModel {
- pub id: Uuid,
- pub status: String,
- #[serde(rename = "updatedAt")]
- pub updated_at: Option>,
-}
diff --git a/packages/relayer/src/handler.rs b/packages/relayer/src/handler.rs
index 98ea8958..7cbc431b 100644
--- a/packages/relayer/src/handler.rs
+++ b/packages/relayer/src/handler.rs
@@ -1,4 +1,19 @@
-use axum::{response::IntoResponse, Json};
+use std::sync::Arc;
+
+use axum::{extract::State, http::StatusCode, response::IntoResponse, Json};
+use regex::Regex;
+use relayer_utils::{field_to_hex, ParsedEmail, LOG};
+use serde_json::{json, Value};
+use slog::info;
+use uuid::Uuid;
+
+use crate::{
+ mail::handle_email_event,
+ model::{create_request, update_request, RequestStatus},
+ schema::EmailTxAuthSchema,
+ utils::parse_command_template,
+ RelayerState,
+};
pub async fn health_checker_handler() -> impl IntoResponse {
const MESSAGE: &str = "Hello from ZK Email!";
@@ -10,3 +25,134 @@ pub async fn health_checker_handler() -> impl IntoResponse {
Json(json_response)
}
+
+pub async fn submit_handler(
+ State(relayer_state): State>,
+ Json(body): Json,
+) -> Result)> {
+ info!(LOG, "Payload: {:?}", body);
+
+ let uuid = create_request(&relayer_state.db).await.map_err(|e| {
+ (
+ axum::http::StatusCode::INTERNAL_SERVER_ERROR,
+ axum::Json(json!({"error": e.to_string()})),
+ )
+ })?;
+
+ let command = parse_command_template(&body.command_template, &body.command_params);
+
+ let account_code = if body.code_exists_in_email {
+ let hex_code = field_to_hex(&body.account_code.clone().0);
+ Some(hex_code.trim_start_matches("0x").to_string())
+ } else {
+ None
+ };
+
+ handle_email_event(
+ crate::mail::EmailEvent::Command {
+ request_id: uuid,
+ email_address: body.email_address.clone(),
+ command,
+ account_code,
+ subject: body.subject.clone(),
+ body: body.body.clone(),
+ },
+ (*relayer_state).clone(),
+ )
+ .await
+ .map_err(|e| {
+ // Convert the error to the desired type
+ (
+ reqwest::StatusCode::INTERNAL_SERVER_ERROR,
+ axum::Json(json!({"error": e.to_string()})),
+ )
+ })?;
+
+ let response = json!({
+ "status": "success",
+ "message": "email sent",
+ "request_id": uuid
+ });
+
+ return Ok((StatusCode::OK, Json(response)));
+}
+
+pub async fn receive_email_handler(
+ State(relayer_state): State>,
+ body: String,
+) -> Result)> {
+ // Define the regex pattern for UUID
+ let uuid_regex = Regex::new(
+ r"\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b",
+ )
+ .unwrap();
+
+ // Attempt to find a UUID in the body
+ let request_id = uuid_regex.find(&body).map(|m| m.as_str());
+
+ match request_id {
+ Some(request_id) => {
+ info!(LOG, "Extracted UUID: {:?}", request_id);
+ }
+ None => {
+ info!(LOG, "No UUID found in the body");
+ // Handle the case where no UUID is found
+ let response = json!({
+ "status": "error",
+ "message": "No UUID found in the email body",
+ });
+ return Ok((StatusCode::BAD_REQUEST, Json(response)));
+ }
+ }
+
+ let request_id = request_id
+ .ok_or_else(|| {
+ (
+ reqwest::StatusCode::BAD_REQUEST,
+ axum::Json(json!({"error": "Request ID is None"})),
+ )
+ })
+ .and_then(|id| {
+ id.parse::().map_err(|_| {
+ (
+ reqwest::StatusCode::BAD_REQUEST,
+ axum::Json(json!({"error": "Failed to parse request ID"})),
+ )
+ })
+ })?;
+
+ update_request(
+ &relayer_state.db,
+ request_id,
+ RequestStatus::EmailResponseReceived,
+ )
+ .await
+ .map_err(|e| {
+ // Convert the error to the expected type
+ (
+ reqwest::StatusCode::INTERNAL_SERVER_ERROR,
+ axum::Json(json!({"error": e.to_string()})),
+ )
+ })?;
+
+ // Log the received body
+ info!(LOG, "Received email body: {:?}", body);
+
+ let parsed_email = ParsedEmail::new_from_raw_email(&body).await.map_err(|e| {
+ // Convert the error to the expected type
+ (
+ reqwest::StatusCode::INTERNAL_SERVER_ERROR,
+ axum::Json(json!({"error": e.to_string()})),
+ )
+ })?;
+
+ // Process the body as needed
+ // For example, you might want to parse it or pass it to another function
+
+ let response = json!({
+ "status": "success",
+ "message": "email received",
+ });
+
+ Ok((StatusCode::OK, Json(response)))
+}
diff --git a/packages/relayer/src/mail.rs b/packages/relayer/src/mail.rs
new file mode 100644
index 00000000..4ca859a1
--- /dev/null
+++ b/packages/relayer/src/mail.rs
@@ -0,0 +1,334 @@
+use std::path::PathBuf;
+
+use anyhow::Result;
+use handlebars::Handlebars;
+use relayer_utils::ParsedEmail;
+use serde::{Deserialize, Serialize};
+use serde_json::Value;
+use sqlx::PgPool;
+use tokio::fs::read_to_string;
+use uuid::Uuid;
+
+use crate::{
+ config::PathConfig,
+ model::{insert_expected_reply, is_valid_reply, update_request, RequestStatus},
+ RelayerState,
+};
+
+/// Represents an email message to be sent.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct EmailMessage {
+ pub to: String,
+ pub subject: String,
+ pub reference: Option,
+ pub reply_to: Option,
+ pub body_plain: String,
+ pub body_html: String,
+ pub body_attachments: Option>,
+}
+
+/// Represents an attachment in an email message.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct EmailAttachment {
+ pub inline_id: String,
+ pub content_type: String,
+ pub contents: Vec,
+}
+
+/// Represents different types of email events.
+#[derive(Debug, Clone)]
+pub enum EmailEvent {
+ Command {
+ request_id: Uuid,
+ email_address: String,
+ command: String,
+ account_code: Option,
+ subject: String,
+ body: String,
+ },
+ Ack {
+ email_addr: String,
+ command: String,
+ original_message_id: Option,
+ original_subject: String,
+ },
+ Completion {},
+ Error {
+ email_addr: String,
+ error: String,
+ original_subject: String,
+ original_message_id: Option,
+ },
+}
+
+/// Handles all possible email events and requests.
+///
+/// # Arguments
+///
+/// * `event` - The `EmailAuthEvent` to be handled.
+///
+/// # Returns
+///
+/// A `Result` indicating success or an `EmailError`.
+pub async fn handle_email_event(event: EmailEvent, relayer_state: RelayerState) -> Result<()> {
+ match event {
+ EmailEvent::Command {
+ request_id,
+ email_address,
+ command,
+ account_code,
+ subject,
+ body,
+ } => {
+ // Prepare the command with the account code if it exists
+ let command = if let Some(code) = account_code {
+ format!("{} Code {}", command, code)
+ } else {
+ command
+ };
+
+ // Create the plain text body
+ let body_plain = format!(
+ "ZK Email request. \
+ Your request ID is {}",
+ request_id
+ );
+
+ // Prepare data for HTML rendering
+ let render_data = serde_json::json!({
+ "userEmailAddr": email_address,
+ "body": body,
+ "requestId": request_id,
+ "command": command,
+ });
+ let body_html =
+ render_html("command_template.html", render_data, relayer_state.clone()).await?;
+
+ // Create and send the email
+ let email = EmailMessage {
+ to: email_address,
+ subject,
+ reference: None,
+ reply_to: None,
+ body_plain,
+ body_html,
+ body_attachments: None,
+ };
+
+ send_email(
+ email,
+ Some(ExpectsReply::new(request_id)),
+ relayer_state.clone(),
+ )
+ .await?;
+
+ update_request(&relayer_state.db, request_id, RequestStatus::EmailSent).await?;
+ }
+ EmailEvent::Ack {
+ email_addr,
+ command,
+ original_message_id,
+ original_subject,
+ } => todo!(),
+ EmailEvent::Completion {} => todo!(),
+ EmailEvent::Error {
+ email_addr,
+ error,
+ original_subject,
+ original_message_id,
+ } => todo!(), // EmailEvent::Ack {
+ // email_addr,
+ // command,
+ // original_message_id,
+ // original_subject,
+ // } => {
+ // let body_plain = format!(
+ // "Hi {}!\nYour email with the command {} is received.",
+ // email_addr, command
+ // );
+ // // Prepare data for HTML rendering
+ // let render_data = serde_json::json!({"userEmailAddr": email_addr, "request": command});
+ // let body_html = render_html("acknowledgement.html", render_data).await?;
+ // let subject = format!("Re: {}", original_subject);
+ // // Create and send the email
+ // let email = EmailMessage {
+ // to: email_addr,
+ // subject,
+ // body_plain,
+ // body_html,
+ // reference: original_message_id.clone(),
+ // reply_to: original_message_id,
+ // body_attachments: None,
+ // };
+ // send_email(email, None).await?;
+ // }
+ // EmailEvent::Completion {} => {}
+ // EmailEvent::Error {
+ // email_addr,
+ // error,
+ // original_subject,
+ // original_message_id,
+ // } => {
+ // let subject = format!("Re: {}", original_subject);
+
+ // let body_plain = format!(
+ // "An error occurred while processing your request. \
+ // Error: {}",
+ // error
+ // );
+
+ // // Prepare data for HTML rendering
+ // let render_data = serde_json::json!({
+ // "error": error,
+ // "userEmailAddr": email_addr,
+ // });
+ // let body_html = render_html("error.html", render_data).await?;
+
+ // // Create and send the email
+ // let email = EmailMessage {
+ // to: email_addr,
+ // subject,
+ // reference: original_message_id.clone(),
+ // reply_to: original_message_id,
+ // body_plain,
+ // body_html,
+ // body_attachments: None,
+ // };
+
+ // send_email(email, None).await?;
+ // }
+ }
+
+ Ok(())
+}
+
+/// Renders an HTML template with the given data.
+///
+/// # Arguments
+///
+/// * `template_name` - The name of the template file.
+/// * `render_data` - The data to be used in rendering the template.
+///
+/// # Returns
+///
+/// A `Result` containing the rendered HTML string or an `Error`.
+async fn render_html(
+ template_name: &str,
+ render_data: Value,
+ relayer_state: RelayerState,
+) -> Result {
+ // Construct the full path to the email template
+ let email_template_filename = PathBuf::new()
+ .join(relayer_state.config.path.email_templates)
+ .join(template_name);
+
+ // Read the email template file
+ let email_template = read_to_string(&email_template_filename).await?;
+
+ // Create a new Handlebars instance
+ let reg = Handlebars::new();
+
+ // Render the template with the provided data
+ let template = reg.render_template(&email_template, &render_data)?;
+ Ok(template)
+}
+
+/// Sends an email using the configured SMTP server.
+///
+/// # Arguments
+///
+/// * `email` - The `EmailMessage` to be sent.
+/// * `expects_reply` - An optional `ExpectsReply` struct indicating if a reply is expected.
+///
+/// # Returns
+///
+/// A `Result` indicating success or an `EmailError`.
+async fn send_email(
+ email: EmailMessage,
+ expects_reply: Option,
+ relayer_state: RelayerState,
+) -> Result<()> {
+ // Send POST request to email server
+ let response = relayer_state
+ .http_client
+ .post(format!("{}/api/sendEmail", relayer_state.config.smtp_url))
+ .json(&email)
+ .send()
+ .await?;
+
+ // Check if the email was sent successfully
+ if !response.status().is_success() {
+ return Err(anyhow::anyhow!(
+ "Failed to send email: {}",
+ response.text().await.unwrap_or_default()
+ ));
+ }
+
+ // Handle expected reply if necessary
+ if let Some(expects_reply) = expects_reply {
+ let response_body: EmailResponse = response.json().await?;
+
+ let message_id = response_body.message_id;
+ insert_expected_reply(&relayer_state.db, &message_id, expects_reply.request_id).await?;
+ }
+
+ Ok(())
+}
+
+/// Represents the response from the email server after sending an email.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+struct EmailResponse {
+ status: String,
+ message_id: String,
+}
+
+/// Represents an expectation of a reply to an email.
+pub struct ExpectsReply {
+ request_id: Option,
+}
+
+impl ExpectsReply {
+ /// Creates a new `ExpectsReply` instance with a request ID.
+ ///
+ /// # Arguments
+ ///
+ /// * `request_id` - The ID of the request expecting a reply.
+ fn new(request_id: Uuid) -> Self {
+ Self {
+ request_id: Some(request_id.to_string()),
+ }
+ }
+
+ /// Creates a new `ExpectsReply` instance without a request ID.
+ fn new_no_request_id() -> Self {
+ Self { request_id: None }
+ }
+}
+
+/// Checks if the email is a reply to a command that expects a reply.
+/// Will return false for duplicate replies.
+/// Will return true if the email is not a reply.
+///
+/// # Arguments
+///
+/// * `email` - The `ParsedEmail` to be checked.
+///
+/// # Returns
+///
+/// A `Result` containing a boolean indicating if the request is valid.
+pub async fn check_is_valid_request(email: &ParsedEmail, pool: &PgPool) -> Result {
+ // Check if the email is a reply by looking for the "In-Reply-To" header
+ let reply_message_id = match email
+ .headers
+ .get_header("In-Reply-To")
+ .and_then(|v| v.first().cloned())
+ {
+ Some(id) => id,
+ // Email is not a reply, so it's valid
+ None => return Ok(true),
+ };
+
+ // Check if the reply is valid (not a duplicate) using the database
+ let is_valid = is_valid_reply(pool, &reply_message_id).await?;
+ Ok(is_valid)
+}
diff --git a/packages/relayer/src/main.rs b/packages/relayer/src/main.rs
index 4b622f3f..ca490f21 100644
--- a/packages/relayer/src/main.rs
+++ b/packages/relayer/src/main.rs
@@ -1,7 +1,10 @@
mod config;
-mod db;
mod handler;
+mod mail;
+mod model;
mod route;
+mod schema;
+mod utils;
use std::sync::Arc;
@@ -11,6 +14,7 @@ use axum::http::{
Method,
};
use relayer_utils::LOG;
+use reqwest::Client;
use route::create_router;
use slog::info;
use sqlx::{postgres::PgPoolOptions, Pool, Postgres};
@@ -18,7 +22,9 @@ use tower_http::cors::CorsLayer;
use config::Config;
+#[derive(Debug, Clone)]
pub struct RelayerState {
+ http_client: Client,
config: Config,
db: Pool,
}
@@ -40,6 +46,7 @@ async fn main() -> Result<()> {
.allow_headers([AUTHORIZATION, ACCEPT, CONTENT_TYPE]);
let relayer = create_router(Arc::new(RelayerState {
+ http_client: Client::new(),
config: config.clone(),
db: pool.clone(),
}))
diff --git a/packages/relayer/src/model.rs b/packages/relayer/src/model.rs
new file mode 100644
index 00000000..3070c8a9
--- /dev/null
+++ b/packages/relayer/src/model.rs
@@ -0,0 +1,93 @@
+use anyhow::{Error, Ok, Result};
+use serde::{Deserialize, Serialize};
+use sqlx::{FromRow, PgPool, Row};
+use uuid::Uuid;
+
+#[derive(Debug, FromRow, Deserialize, Serialize)]
+#[allow(non_snake_case)]
+pub struct RequestModel {
+ pub id: Uuid,
+ pub status: String,
+ #[serde(rename = "updatedAt")]
+ pub updated_at: Option>,
+}
+
+#[derive(Debug, FromRow, Deserialize, Serialize)]
+#[allow(non_snake_case)]
+pub struct ExpectedReplyModel {
+ pub message_id: String,
+ pub request_id: Option,
+ pub has_reply: Option,
+ #[serde(rename = "createdAt")]
+ pub created_at: chrono::DateTime,
+}
+
+#[derive(Debug, Serialize, Deserialize, sqlx::Type)]
+#[sqlx(type_name = "status_enum")]
+pub enum RequestStatus {
+ #[sqlx(rename = "Request received")]
+ RequestReceived,
+ #[sqlx(rename = "Email sent")]
+ EmailSent,
+ #[sqlx(rename = "Email response received")]
+ EmailResponseReceived,
+ #[sqlx(rename = "Proving")]
+ Proving,
+ #[sqlx(rename = "Performing on chain transaction")]
+ PerformingOnChainTransaction,
+ #[sqlx(rename = "Finished")]
+ Finished,
+}
+
+pub async fn create_request(pool: &PgPool) -> Result {
+ let query_result = sqlx::query!("INSERT INTO requests DEFAULT VALUES RETURNING id")
+ .fetch_one(pool)
+ .await?;
+
+ Ok(query_result.id)
+}
+
+pub async fn update_request(pool: &PgPool, request_id: Uuid, status: RequestStatus) -> Result<()> {
+ sqlx::query!(
+ "UPDATE requests SET status = $1 WHERE id = $2",
+ status as RequestStatus,
+ request_id
+ )
+ .execute(pool)
+ .await
+ .map_err(|e| Error::msg(format!("Failed to update request: {}", e)))?;
+
+ Ok(())
+}
+
+pub async fn insert_expected_reply(
+ pool: &PgPool,
+ message_id: &str,
+ request_id: Option,
+) -> Result<()> {
+ sqlx::query!(
+ "INSERT INTO expected_replies (message_id, request_id) VALUES ($1, $2)",
+ message_id,
+ request_id
+ )
+ .execute(pool)
+ .await
+ .map_err(|e| Error::msg(format!("Failed to insert expected_reply: {}", e)))?;
+
+ Ok(())
+}
+
+pub async fn is_valid_reply(pool: &PgPool, message_id: &str) -> Result {
+ let query_result = sqlx::query!(
+ "UPDATE expected_replies
+ SET has_reply = true
+ WHERE message_id = $1 AND has_reply = false
+ RETURNING has_reply",
+ message_id
+ )
+ .fetch_one(pool)
+ .await
+ .map_err(|e| Error::msg(format!("Failed to validate reply: {}", e)))?;
+
+ Ok(query_result.has_reply.unwrap_or(false))
+}
diff --git a/packages/relayer/src/route.rs b/packages/relayer/src/route.rs
index ea13578e..0a6d8723 100644
--- a/packages/relayer/src/route.rs
+++ b/packages/relayer/src/route.rs
@@ -5,13 +5,17 @@ use axum::{
Router,
};
-use crate::{handler::health_checker_handler, RelayerState};
+use crate::{
+ handler::{health_checker_handler, receive_email_handler, submit_handler},
+ RelayerState,
+};
pub fn create_router(relayer_state: Arc) -> Router {
Router::new()
.route("/api/healthz", get(health_checker_handler))
+ .route("/api/submit", post(submit_handler))
+ .route("/api/receiveEmail", post(receive_email_handler))
// .route("/api/status/:id", get(get_status_handler))
- // .route("/api/submit/", post(submit_handler))
// .route("/api/addDKIMKey", post(add_dkim_key_handler))
.with_state(relayer_state)
}
diff --git a/packages/relayer/src/schema.rs b/packages/relayer/src/schema.rs
new file mode 100644
index 00000000..bb396c1d
--- /dev/null
+++ b/packages/relayer/src/schema.rs
@@ -0,0 +1,31 @@
+use std::collections::HashMap;
+
+use ethers::{abi::Item, types::Address};
+use relayer_utils::AccountCode;
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct EmailTxAuthSchema {
+ pub contract_address: Address,
+ pub email_auth_contract_address: Address,
+ pub account_code: AccountCode,
+ pub code_exists_in_email: bool,
+ pub function_abi: Item,
+ pub command_template: String,
+ pub command_params: HashMap,
+ pub remaining_args: HashMap,
+ pub email_address: String,
+ pub subject: String,
+ pub body: String,
+ pub chain: String,
+}
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct DKIMSchema {
+ dkim_contract_address: Address,
+ selector: String,
+ domain: String,
+ chain: String,
+}
diff --git a/packages/relayer/src/utils.rs b/packages/relayer/src/utils.rs
new file mode 100644
index 00000000..8ddadd18
--- /dev/null
+++ b/packages/relayer/src/utils.rs
@@ -0,0 +1,12 @@
+use std::collections::HashMap;
+
+pub fn parse_command_template(template: &str, params: &HashMap) -> String {
+ let mut parsed_string = template.to_string();
+
+ for (key, value) in params {
+ let placeholder = format!("${{{}}}", key);
+ parsed_string = parsed_string.replace(&placeholder, value);
+ }
+
+ parsed_string
+}