diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..352a626 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.linkedProjects": [ + "./Cargo.toml" + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 378be7d..3a277dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,6 +80,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "binascii" version = "0.1.4" @@ -186,6 +192,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -356,6 +372,30 @@ 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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -601,6 +641,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.56" @@ -624,6 +677,16 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "ignore" version = "0.4.20" @@ -698,6 +761,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + [[package]] name = "is-terminal" version = "0.4.7" @@ -853,12 +922,33 @@ dependencies = [ "version_check", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nero-explore" version = "0.1.0" dependencies = [ + "reqwest", "rocket", "rocket_dyn_templates", + "serde", + "serde_derive", "serde_json", ] @@ -924,6 +1014,50 @@ version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +[[package]] +name = "openssl" +version = "0.10.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12df40a956736488b7b44fe79fe12d4f245bb5b3f5a1f6095e499760015be392" +dependencies = [ + "bitflags 1.3.2", + "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", +] + +[[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.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -1086,6 +1220,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1223,6 +1363,43 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rocket" version = "0.5.0-rc.3" @@ -1353,6 +1530,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1365,6 +1551,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "security-framework" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.163" @@ -1405,6 +1614,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha2" version = "0.10.6" @@ -1601,6 +1822,21 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.28.2" @@ -1630,6 +1866,16 @@ dependencies = [ "syn", ] +[[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]] name = "tokio-stream" version = "0.1.14" @@ -1844,24 +2090,56 @@ dependencies = [ "unic-common", ] +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + [[package]] name = "unicode-ident" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-xid" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "valuable" 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" @@ -1919,6 +2197,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.86" @@ -1948,6 +2238,16 @@ version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +[[package]] +name = "web-sys" +version = "0.3.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1988,6 +2288,21 @@ dependencies = [ "windows-targets 0.48.0", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -2129,6 +2444,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "yansi" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 3f5bfea..bbb9885 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde_json = { version = "1.0" } -rocket = { verion = "=0.5.0-rc.3", features = ["json"] } +serde = "1.0.0" +serde_json = "1.0.96" +serde_derive = "1.0.163" +reqwest = { version = "0.11.18", features = ["json"] } +rocket = { version = "=0.5.0-rc.3", features = ["json"] } rocket_dyn_templates = { version = "=0.1.0-rc.3", features = ["tera"] } \ No newline at end of file diff --git a/src/data/block.rs b/src/data/block.rs new file mode 100644 index 0000000..ea90400 --- /dev/null +++ b/src/data/block.rs @@ -0,0 +1,53 @@ +// request +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GetBlockRequest { + pub height: Option, + pub hash: Option +} + +// response +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GetBlockResponse { + pub block_header: BlockHeader, + pub status: String, + pub credits: u32, + pub miner_tx_hash: String, + pub top_hash: String, + pub untrusted: bool +} + +// data +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct BlockHeader { + pub block_size: u32, + pub block_weight: u32, + pub cumulative_difficulty: u32, + pub cumulative_difficulty_top64: u32, + pub depth: u32, + pub difficulty: u64, + pub difficulty_top64: u64, + pub hash: String, + pub height: u32, + pub long_term_weight: u32, + pub major_version: u8, + pub minor_version: u8, + pub miner_tx_hash: Option, + pub nonce: u32, + pub num_txes: u32, + pub orphan_status: bool, + pub pow_hash: String, + pub prev_hash: String, + pub reward: u64, + pub timestamp: i64, + pub wide_cumulative_difficulty: String, + pub wide_difficulty: String +} + +// #[derive(Serialize, Deserialize, Debug, Clone)] +// pub struct GetBlockResult { +// pub block_header: BlockHeader, +// pub credits: u8, +// pub miner_tx_hash: String, +// pub tx_hashes: Option>, +// } + diff --git a/src/data/mod.rs b/src/data/mod.rs new file mode 100644 index 0000000..c625b42 --- /dev/null +++ b/src/data/mod.rs @@ -0,0 +1,4 @@ +pub mod payload; +pub mod node; +pub mod block; +pub mod transaction; \ No newline at end of file diff --git a/src/data/node.rs b/src/data/node.rs new file mode 100644 index 0000000..ceb3ac4 --- /dev/null +++ b/src/data/node.rs @@ -0,0 +1,47 @@ +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GetInfoResponse { + pub adjusted_time: u64, + pub alt_blocks_count: u32, + pub block_size_limit: u32, + pub block_size_median: u32, + pub block_weight_limit: u32, + pub block_weight_median: u64, + pub bootstrap_daemon_address: String, + pub busy_syncing: bool, + pub credits: u32, + pub cumulative_difficulty: u64, + pub cumulative_difficulty_top64: u32, + pub database_size: u64, + pub donation_address: Option, + pub difficulty: u64, + pub difficulty_top64: u32, + pub free_space: u64, + pub grey_peerlist_size: u32, + pub height: u32, + pub height_without_bootstrap: u32, + pub incoming_connections_count: u32, + pub mainnet: bool, + pub nettype: String, + pub offline: bool, + pub restricted: bool, + pub outgoing_connections_count: u32, + pub rpc_connections_count: u32, + pub stagenet: bool, + pub start_time: u32, + pub status: String, + pub synchronized: bool, + pub target: u32, + pub target_height: u32, + pub testnet: bool, + pub top_block_hash: String, + pub top_hash: String, + pub tx_count: u32, + pub tx_pool_size: u32, + pub untrusted: bool, + pub update_available: bool, + pub version: String, + pub was_bootstrap_ever_used: bool, + pub white_peerlist_size: u32, + pub wide_cumulative_difficulty: String, + pub wide_difficulty: String +} diff --git a/src/data/payload.rs b/src/data/payload.rs new file mode 100644 index 0000000..f02e878 --- /dev/null +++ b/src/data/payload.rs @@ -0,0 +1,48 @@ +// mod node; + +use super::node::GetInfoResponse; +use super::block::GetBlockResponse; + +// Options for various response payloads +#[derive(Deserialize, Serialize, Debug, Clone)] +#[serde(untagged)] +pub enum RPCResponseOpt { + GetInfoResponse(GetInfoResponse), + GetBlockResponse(GetBlockResponse) +} + +// // Options for various request payloads +// #[derive(Deserialize, Serialize, Debug, Clone)] +// #[serde(untagged)] +// pub enum RPCRequestOpt { +// GetInfoResponse(GetInfoResponse) +// } + +// Default RPC response payload +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RPCResponse { + pub jsonrpc: Option, + pub id: Option, + pub result: Option +} + +// // Default RPC request payload +// #[derive(Serialize, Deserialize, Debug, Clone)] +// pub struct RPCRequest { +// pub jsonrpc: String, +// pub id: String, +// pub method: Option, +// pub params: Option +// } + +// impl Default for RPCRequest { +// fn default() -> RPCRequest { +// RPCRequest { +// jsonrpc: "2.0".to_string(), +// id: "0".to_string(), +// method: None, +// params: None +// } +// } +// } + diff --git a/src/data/transaction.rs b/src/data/transaction.rs new file mode 100644 index 0000000..0321788 --- /dev/null +++ b/src/data/transaction.rs @@ -0,0 +1,121 @@ +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RPCParams { + pub hash: Option, + pub txs_hashes: Option>, + pub height: Option +} + +impl Default for RPCParams { + fn default() -> RPCParams { + RPCParams { + hash: None, + txs_hashes: None, + height: None + } + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GetTransactionPool { + pub credits: u32, + pub spent_key_images: Option>, + pub status: String, + pub top_hash: String, + pub transactions: Option> +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct SpentKeyImages { + pub id_hash: String, + pub txs_hashes: Vec +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Transaction { + pub blob_size: u32, + pub do_not_relay: bool, + pub double_spend_seen: bool, + pub fee: u64, + pub id_hash: String, + pub kept_by_block: bool, + pub last_failed_height: u32, + pub last_failed_id_hash: String, + pub last_relayed_time: i64, + pub max_used_block_height: u32, + pub max_used_block_id_hash: String, + pub receive_time: i64, + pub relayed: bool, + pub tx_blob: String, + pub tx_json: String, + pub tx_json_full: Option, + pub weight: u32 +} + +impl Transaction { + pub fn process(&mut self) { + self.tx_json_full = Some(serde_json::from_str(&self.tx_json).unwrap()) + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct TransactionJSON { + pub version: u32, + pub unlock_time: u64, + pub vin: Option>, + pub vout: Vec, + pub extra: Vec, + pub rct_signatures: Option +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct TransactionInputs { + pub key: Option +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct PreviousTransactionKey { + pub amount: u64, + pub key_offsets: Vec, + pub k_image: String +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct TransactionOutputs { + pub amount: u64, + pub target: OutputStealthAddress +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct OutputStealthAddress { + pub key: Option +} + +#[allow(non_snake_case)] +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RingSignatures { + pub r#type: u32, + pub txnFee: Option, + pub outPk: Option> +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct QRData { + pub tx_amount: String, + pub tx_description: String, + pub recipient_name: String, + pub tx_payment_id: String +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct CheckTxKeyResponse { + pub jsonrpc: String, + pub id: u32, + pub result: Option +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct CheckTxKeyResult { + pub confirmations: u32, + pub in_pool: bool, + pub received: u64, +} \ No newline at end of file diff --git a/src/helpers.rs b/src/helpers.rs new file mode 100644 index 0000000..48f53bf --- /dev/null +++ b/src/helpers.rs @@ -0,0 +1,20 @@ +extern crate reqwest; + +use rocket::serde::json::{Value}; +use reqwest::{RequestBuilder, Client}; +use std::env; + +pub async fn build_rpc(method: &str, raw_data: Option, raw: bool) -> RequestBuilder { + let http_client = Client::new(); + let daemon_uri = env::var("DAEMON_URI").unwrap(); + let uri = if raw { + format!("{}/{}", &daemon_uri, &method) + } else { + format!("{}/json_rpc", &daemon_uri) + }; + if let None = raw_data { + http_client.post(&uri) + } else { + http_client.post(&uri).json(&raw_data) + } +} diff --git a/src/main.rs b/src/main.rs index 4c33b00..9f4304c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,30 @@ #[macro_use] extern crate rocket; +#[macro_use] extern crate serde_derive; +extern crate serde_json; +extern crate rocket_dyn_templates; + mod routes; -use routes::{block, transaction, address, search}; +mod helpers; +mod data; + +use std::{env, process}; +use routes::{block, transaction, address, search, home}; +use rocket_dyn_templates::Template; -#[get("/")] -fn index() -> &'static str { - "Hello, world!" -} #[launch] fn rocket() -> _ { + let node = env::var("DAEMON_URI"); + match node { + Ok(_) => println!("[+] Using node {:?}", node), + Err(_) => { + println!("[!] Provide a node via env DAEMON_URI"); + process::exit(1); + } + } rocket::build() - .mount("/", routes![index]) + .attach(Template::fairing()) + .mount("/", routes![home::home]) .mount("/block", routes![block::height, block::hash]) .mount("/transaction", routes![transaction::hash, transaction::receipt]) .mount("/address", routes![address::show]) diff --git a/src/routes/home.rs b/src/routes/home.rs new file mode 100644 index 0000000..c3c1ec2 --- /dev/null +++ b/src/routes/home.rs @@ -0,0 +1,35 @@ +use std::env; +use rocket_dyn_templates::{Template, context}; + +use crate::data::node::GetInfoResponse; +use crate::data::transaction::{GetTransactionPool, Transaction}; +use crate::helpers::build_rpc; + +#[get("/")] +pub async fn home() -> Template { + let daemon = env::var("DAEMON_URI").unwrap(); + let daemon_info: GetInfoResponse = build_rpc(&"get_info", None, true) + .await.send() + .await.unwrap().json() + .await.unwrap(); + + let tx_pool: GetTransactionPool = build_rpc(&"get_transaction_pool", None, true) + .await.send() + .await.unwrap().json() + .await.unwrap(); + + let mut pool_txs: Vec = tx_pool.transactions.unwrap_or(vec![]); + + for f in &mut pool_txs { + f.process(); + }; + + let context = context!{ + daemon_info: daemon_info, + tx_pool_txs: pool_txs, + daemon_uri: daemon + }; + + Template::render("home", context) + +} \ No newline at end of file diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 3ee19fa..aecbddc 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,3 +1,4 @@ +pub mod home; pub mod block; pub mod transaction; pub mod address; diff --git a/templates/base.html.tera b/templates/base.html.tera new file mode 100644 index 0000000..e077191 --- /dev/null +++ b/templates/base.html.tera @@ -0,0 +1,30 @@ + + + + + Block Explorer + + + + + +
+ {% block content %} + {% endblock content %} + +
+ + \ No newline at end of file diff --git a/templates/home.html.tera b/templates/home.html.tera new file mode 100644 index 0000000..cf034b0 --- /dev/null +++ b/templates/home.html.tera @@ -0,0 +1,126 @@ +{% extends "base" %} + +{% block content %} + +
+
+ +
+
+
+
+

Daemon Statistics

+

Address: {{ daemon_uri | default(value="?") }}

+
+
+
+
+
+

Version

+
+

{{ daemon_info.version | default(value="?") }}

+
+
+
+
+
+

Difficulty

+
+

{{ daemon_info.difficulty }}

+
+
+
+
+
+

Height

+
+

{{ daemon_info.height }}

+
+
+
+
+
+

Network

+
+

{{ daemon_info.nettype }}

+
+
+
+
+
+

Transaction Count

+
+

{{ daemon_info.tx_count }}

+
+
+
+
+
+

Database Size

+
+

{{ daemon_info.database_size / 1000000000 | default(value="?") }} GB

+
+
+
+
+
+

Connections

+
+

{{ daemon_info.incoming_connections_count }} in / {{ daemon_info.outgoing_connections_count }} out

+
+
+
+
+
+

Status

+
+

{{ daemon_info.status }}

+
+
+
+
+
+
+

+
+
+ + + {% if daemon_info.tx_pool_size > 0 %} + + + + + + + + {% for tx in tx_pool_txs %} + + + + + + + {% endfor %} + {% endif %} +
+

Transaction Pool ({{ daemon_info.tx_pool_size }})

+

Transactions that have yet to be mined into a block. This is where payments sit in a PENDING state.

+
Received TimeHashFeeInputs / OutputsRing Decoys
{{ tx.receive_time | date(format="%Y-%m-%d %H:%M") }}{{ tx.id_hash | truncate(length=8) }}{{ tx.fee / 10000000000 }} WOW{{ tx.tx_json_full.vin | length }} / {{ tx.tx_json_full.vout | length }}
+
+
+
+
+ +{% endblock content %} \ No newline at end of file