diff --git a/Cargo.lock b/Cargo.lock index b7d20f82..dad90cd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ dependencies = [ "matchit", "memchr", "mime", - "percent-encoding 2.1.0", + "percent-encoding", "pin-project-lite", "serde", "serde_json", @@ -551,8 +551,11 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ + "libc", "num-integer", "num-traits", + "time", + "winapi 0.3.9", ] [[package]] @@ -626,7 +629,7 @@ dependencies = [ "digest 0.9.0", "getrandom", "hmac 0.11.0", - "k256", + "k256 0.10.4", "lazy_static", "serde", "sha2 0.9.9", @@ -847,6 +850,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array 0.14.5", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.3.2" @@ -932,6 +947,12 @@ dependencies = [ "parking_lot_core 0.9.3", ] +[[package]] +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" + [[package]] name = "der" version = "0.5.1" @@ -966,29 +987,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "diesel" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" -dependencies = [ - "byteorder", - "diesel_derives", - "mysqlclient-sys", - "url 1.7.2", -] - -[[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "diff" version = "0.1.12" @@ -1057,14 +1055,26 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" +[[package]] +name = "ecdsa" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" +dependencies = [ + "der 0.4.5", + "elliptic-curve 0.10.6", + "hmac 0.11.0", + "signature", +] + [[package]] name = "ecdsa" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" dependencies = [ - "der", - "elliptic-curve", + "der 0.5.1", + "elliptic-curve 0.11.12", "rfc6979", "signature", ] @@ -1075,6 +1085,21 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "elliptic-curve" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" +dependencies = [ + "crypto-bigint 0.2.11", + "ff 0.10.1", + "generic-array 0.14.5", + "group 0.10.0", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.11.12" @@ -1082,11 +1107,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" dependencies = [ "base16ct", - "crypto-bigint", - "der", - "ff", + "crypto-bigint 0.3.2", + "der 0.5.1", + "ff 0.11.1", "generic-array 0.14.5", - "group", + "group 0.11.0", "rand_core", "sec1", "subtle", @@ -1245,7 +1270,7 @@ dependencies = [ "serde", "serde_json", "syn", - "url 2.2.2", + "url", "walkdir", ] @@ -1273,11 +1298,11 @@ dependencies = [ "cargo_metadata", "chrono", "convert_case 0.5.0", - "elliptic-curve", + "elliptic-curve 0.11.12", "ethabi", "generic-array 0.14.5", "hex", - "k256", + "k256 0.10.4", "once_cell", "proc-macro2", "rand", @@ -1329,7 +1354,7 @@ dependencies = [ "tokio", "tracing", "tracing-futures", - "url 2.2.2", + "url", ] [[package]] @@ -1359,7 +1384,7 @@ dependencies = [ "tokio-tungstenite", "tracing", "tracing-futures", - "url 2.2.2", + "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-timer", @@ -1375,7 +1400,7 @@ dependencies = [ "async-trait", "coins-bip32", "coins-bip39", - "elliptic-curve", + "elliptic-curve 0.11.12", "eth-keystore", "ethers-core", "hex", @@ -1449,6 +1474,16 @@ dependencies = [ "libc", ] +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "ff" version = "0.11.1" @@ -1515,7 +1550,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", - "percent-encoding 2.1.0", + "percent-encoding", ] [[package]] @@ -1739,13 +1774,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "ff 0.10.1", + "rand_core", + "subtle", +] + [[package]] name = "group" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ - "ff", + "ff 0.11.1", "rand_core", "subtle", ] @@ -1943,17 +1989,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.2.3" @@ -2078,6 +2113,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +[[package]] +name = "iri-string" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78" +dependencies = [ + "nom", +] + [[package]] name = "itertools" version = "0.10.3" @@ -2108,6 +2152,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903ae2481bcdfdb7b68e0a9baa4b7c9aff600b9ae2e8e5bb5833b8c91ab851ea" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.12.4", + "elliptic-curve 0.10.6", + "sha3 0.9.1", +] + [[package]] name = "k256" version = "0.10.4" @@ -2115,8 +2171,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" dependencies = [ "cfg-if 1.0.0", - "ecdsa", - "elliptic-curve", + "ecdsa 0.13.4", + "elliptic-curve 0.11.12", "sec1", "sha2 0.9.9", "sha3 0.9.1", @@ -2275,6 +2331,12 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.5.1" @@ -2339,16 +2401,6 @@ dependencies = [ "ws2_32-sys", ] -[[package]] -name = "mysqlclient-sys" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61b381528ba293005c42a409dd73d034508e273bf90481f17ec2e964a6e969b" -dependencies = [ - "pkg-config", - "vcpkg", -] - [[package]] name = "nanorand" version = "0.7.0" @@ -2375,6 +2427,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nonempty" version = "0.7.0" @@ -2660,12 +2722,6 @@ dependencies = [ "sha2 0.10.2", ] -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - [[package]] name = "percent-encoding" version = "2.1.0" @@ -2780,17 +2836,11 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ - "der", + "der 0.5.1", "spki", "zeroize", ] -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - [[package]] name = "plotters" version = "0.3.1" @@ -2991,11 +3041,11 @@ dependencies = [ "dtoa", "futures-util", "itoa 0.4.8", - "percent-encoding 2.1.0", + "percent-encoding", "pin-project-lite", "tokio", "tokio-util 0.6.10", - "url 2.2.2", + "url", ] [[package]] @@ -3082,7 +3132,7 @@ dependencies = [ "lazy_static", "log", "mime", - "percent-encoding 2.1.0", + "percent-encoding", "pin-project-lite", "rustls", "rustls-pemfile", @@ -3092,7 +3142,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "url 2.2.2", + "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -3106,7 +3156,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.3.2", "hmac 0.11.0", "zeroize", ] @@ -3271,7 +3321,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ - "der", + "der 0.5.1", "generic-array 0.14.5", "pkcs8", "subtle", @@ -3445,9 +3495,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", "rand_core", @@ -3459,6 +3509,22 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +[[package]] +name = "siwe" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f2d8ae2d4ae58df46e173aa496562ea857ac6a4f0d435ed30fcd19da0aaa79" +dependencies = [ + "chrono", + "hex", + "http", + "iri-string", + "k256 0.9.6", + "rand", + "sha3 0.9.1", + "thiserror", +] + [[package]] name = "slab" version = "0.4.6" @@ -3516,7 +3582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ "base64ct", - "der", + "der 0.5.1", ] [[package]] @@ -3598,7 +3664,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "url 2.2.2", + "url", ] [[package]] @@ -3723,6 +3789,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -4008,7 +4084,7 @@ dependencies = [ "rustls", "sha-1", "thiserror", - "url 2.2.2", + "url", "utf-8", "webpki", ] @@ -4076,17 +4152,6 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.2.2" @@ -4094,9 +4159,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", - "idna 0.2.3", + "idna", "matches", - "percent-encoding 2.1.0", + "percent-encoding", ] [[package]] @@ -4121,12 +4186,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" @@ -4257,20 +4316,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web3-backend" -version = "0.1.0" -dependencies = [ - "axum", - "diesel", - "serde", - "serde_json", - "tokio", - "toml", - "tracing", - "tracing-subscriber", -] - [[package]] name = "web3-proxy" version = "0.1.0" @@ -4299,13 +4344,14 @@ dependencies = [ "rustc-hash", "serde", "serde_json", + "siwe", "tokio", "tokio-stream", "toml", "tower", "tracing", "tracing-subscriber", - "url 2.2.2", + "url", ] [[package]] @@ -4461,6 +4507,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.5" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" diff --git a/Cargo.toml b/Cargo.toml index 5af76878..a3721e3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ members = [ "linkedhashmap", "redis-cell-client", - "web3-backend", "web3-proxy", ] diff --git a/TODO.md b/TODO.md index 0fef52ad..e5d53379 100644 --- a/TODO.md +++ b/TODO.md @@ -80,6 +80,27 @@ - send getTransaction rpc requests to the private rpc tier - [ ] don't "unwrap" anywhere. give proper errors +new endpoints for users: +- [ ] GET /user/login/$address + - returns a JSON string for the user to sign +- [ ] POST /user/login/$address + - returns a JSON string including the api key + - sets session cookie +- [ ] GET /user/$address + - checks for api key in session cookie or header + - returns a JSON string including user stats +- [ ] POST /user/$address + - opt-in link email address + - checks for api key in session cookie or header + - allows modifying user settings +- [ ] GET /$api_key + - proxies to web3 websocket +- [ ] POST /$api_key + - proxies to web3 +- [ ] GET /payment/$tx_hash + - checks a transaction to see if it modifies a user's balance + + ## V2 - [ ] ethers has a transactions_unsorted httprpc method that we should probably use. all rpcs probably don't support it, so make it okay for that to fail diff --git a/web3-backend/Cargo.toml b/web3-backend/Cargo.toml deleted file mode 100644 index 81856113..00000000 --- a/web3-backend/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "web3-backend" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -axum = { version = "0.5.12", features = ["serde_json"] } -diesel = { version = "1.4.8", features = ["mysql"] } -serde = { version = "1.0.139", features = ["derive"] } -serde_json = "1.0.82" -tokio = { version = "1.19.2", features = ["full", "tracing"] } -toml = "0.5.9" -tracing = "0.1.35" -tracing-subscriber = { version = "0.3.14", features = ["env-filter"] } diff --git a/web3-backend/src/main.rs b/web3-backend/src/main.rs deleted file mode 100644 index 3fe179b3..00000000 --- a/web3-backend/src/main.rs +++ /dev/null @@ -1,64 +0,0 @@ -use axum::{ - http::StatusCode, - response::IntoResponse, - routing::{get, post}, - Json, Router, -}; -use serde::{Deserialize, Serialize}; -use std::net::SocketAddr; - -#[tokio::main] -async fn main() { - // initialize tracing - tracing_subscriber::fmt::init(); - - // build our application with a route - let app = Router::new() - // `GET /` goes to `root` - .route("/", get(root)) - // `POST /users` goes to `create_user` - .route("/users", post(create_user)); - - // run our app with hyper - // `axum::Server` is a re-export of `hyper::Server` - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); - tracing::debug!("listening on {}", addr); - axum::Server::bind(&addr) - .serve(app.into_make_service()) - .await - .unwrap(); -} - -// basic handler that responds with a static string -async fn root() -> &'static str { - "Hello, World!" -} - -async fn create_user( - // this argument tells axum to parse the request body - // as JSON into a `CreateUser` type - Json(payload): Json, -) -> impl IntoResponse { - // insert your application logic here - let user = User { - id: 1337, - username: payload.username, - }; - - // this will be converted into a JSON response - // with a status code of `201 Created` - (StatusCode::CREATED, Json(user)) -} - -// the input to our `create_user` handler -#[derive(Deserialize)] -struct CreateUser { - username: String, -} - -// the output to our `create_user` handler -#[derive(Serialize)] -struct User { - id: u64, - username: String, -} diff --git a/web3-proxy/Cargo.toml b/web3-proxy/Cargo.toml index 2c75b8f1..978e09cf 100644 --- a/web3-proxy/Cargo.toml +++ b/web3-proxy/Cargo.toml @@ -34,6 +34,7 @@ proctitle = "0.1.1" regex = "1.6.0" reqwest = { version = "0.11.11", default-features = false, features = ["json", "tokio-rustls"] } rustc-hash = "1.1.0" +siwe = "0.3" serde = { version = "1.0.139", features = [] } serde_json = { version = "1.0.82", default-features = false, features = ["alloc", "raw_value"] } tokio = { version = "1.19.2", features = ["full", "tracing"] } diff --git a/web3-proxy/src/frontend/mod.rs b/web3-proxy/src/frontend/mod.rs index a9e1feb9..a8513421 100644 --- a/web3-proxy/src/frontend/mod.rs +++ b/web3-proxy/src/frontend/mod.rs @@ -2,6 +2,7 @@ mod errors; mod http; mod http_proxy; +mod users; mod ws_proxy; use axum::{ @@ -27,6 +28,8 @@ pub async fn run(port: u16, proxy_app: Arc) -> anyhow::Result<()> .route("/health", get(http::health)) // `GET /status` goes to `status` .route("/status", get(http::status)) + // `POST /users` goes to `create_user` + .route("/users", post(users::create_user)) .layer(Extension(proxy_app)); // 404 for any unknown routes diff --git a/web3-proxy/src/frontend/users.rs b/web3-proxy/src/frontend/users.rs new file mode 100644 index 00000000..339ba502 --- /dev/null +++ b/web3-proxy/src/frontend/users.rs @@ -0,0 +1,45 @@ +// So the API needs to show for any given user: +// - show balance in USD +// - show deposits history (currency, amounts, transaction id) +// - show number of requests used (so we can calculate average spending over a month, burn rate for a user etc, something like "Your balance will be depleted in xx days) +// - the email address of a user if he opted in to get contacted via email +// - all the monitoring and stats but that will come from someplace else if I understand corectly? +// I wonder how we handle payment +// probably have to do manual withdrawals + +use axum::{http::StatusCode, response::IntoResponse, Json}; +use ethers::prelude::{Address, Bytes}; +use serde::{Deserialize, Serialize}; + +pub async fn create_user( + // this argument tells axum to parse the request body + // as JSON into a `CreateUser` type + Json(payload): Json, +) -> impl IntoResponse { + // TODO: rate limit by ip + // TODO: insert your application logic here + let user = User { + id: 1337, + eth_address: payload.eth_address, + }; + + // this will be converted into a JSON response + // with a status code of `201 Created` + (StatusCode::CREATED, Json(user)) +} + +// the input to our `create_user` handler +#[derive(Deserialize)] +pub struct CreateUser { + eth_address: Address, + // TODO: validation + email: Option, + signature: Bytes, +} + +// the output to our `create_user` handler +#[derive(Serialize)] +struct User { + id: u64, + eth_address: Address, +}