adding first wave of code
parent
49ee0d84e0
commit
7addf838ae
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "monero-blockchain-explorer"
|
||||
version = "0.1.0"
|
||||
authors = ["lalanza808 <lance@reciprocitylabs.com>"]
|
||||
edition = "2018"
|
||||
description = ""
|
||||
|
||||
# https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
[dependencies]
|
||||
rocket = "0.4.4"
|
||||
rocket_contrib = "0.4.4"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
serde_derive = "1.0"
|
||||
reqwest = { version = "0.10.4", features = ["blocking", "json"] }
|
@ -0,0 +1,12 @@
|
||||
# Monero Block Explorer
|
||||
|
||||
Building a very simple HTTP service to help learn Rust and get more familiar with the ecosystem.
|
||||
|
||||
## Running
|
||||
|
||||
```
|
||||
git clone https://github.com/lalanza808/monero-blockchain-explorer
|
||||
cd monero-blockchain-explorer
|
||||
rustup override set nightly
|
||||
cargo run
|
||||
```
|
@ -0,0 +1,97 @@
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RPCPayload {
|
||||
pub jsonrpc: String,
|
||||
pub id: String,
|
||||
pub method: String
|
||||
}
|
||||
|
||||
impl Default for RPCPayload {
|
||||
fn default() -> RPCPayload {
|
||||
RPCPayload {
|
||||
jsonrpc: "2.0".to_string(),
|
||||
id: "0".to_string(),
|
||||
method: "get_info".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GetInfo {
|
||||
pub jsonrpc: String,
|
||||
pub id: String,
|
||||
pub result: GetInfoResult
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GetInfoResult {
|
||||
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 credits: u32,
|
||||
pub cumulative_difficulty: u64,
|
||||
pub cumulative_difficulty_top64: u32,
|
||||
pub database_size: u64,
|
||||
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 outgoing_connections_count: u32,
|
||||
pub rpc_connections_count: u32,
|
||||
pub stagenet: bool,
|
||||
pub start_time: u32,
|
||||
pub status: String,
|
||||
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
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct BlockByHeaderHash {
|
||||
pub id: String,
|
||||
pub jsonrpc: String,
|
||||
pub result: BlockByHeaderHashResult
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct BlockByHeaderHashResult {
|
||||
pub status: String,
|
||||
pub untrusted: bool,
|
||||
pub block_header: BlockHeader
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct BlockHeader {
|
||||
pub block_size: u32,
|
||||
pub depth: u32,
|
||||
pub difficulty: u64,
|
||||
pub hash: String,
|
||||
pub height: u32,
|
||||
pub major_version: u8,
|
||||
pub minor_version: u8,
|
||||
pub nonce: u32,
|
||||
pub num_txes: u32,
|
||||
pub orphan_status: bool,
|
||||
pub prev_hash: String,
|
||||
pub reward: u64,
|
||||
pub timestamp: u64
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
#[macro_use] extern crate rocket;
|
||||
#[macro_use] extern crate rocket_contrib;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
extern crate reqwest;
|
||||
mod data_types;
|
||||
use rocket_contrib::json::{Json, JsonValue};
|
||||
use std::env;
|
||||
use data_types::*;
|
||||
|
||||
|
||||
|
||||
fn issue_rpc(method: &str) -> reqwest::blocking::RequestBuilder {
|
||||
let uri = env::var("DAEMON_URI").unwrap();
|
||||
let http_client = reqwest::blocking::Client::new();
|
||||
let post_data = RPCPayload {
|
||||
method: method.to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
return http_client.post(&uri).json(&post_data);
|
||||
}
|
||||
|
||||
#[catch(404)]
|
||||
fn not_found() -> JsonValue {
|
||||
json!({
|
||||
"status": "error",
|
||||
"reason": "Resource was not found."
|
||||
})
|
||||
}
|
||||
|
||||
#[get("/transaction/<hash>")]
|
||||
fn get_transaction(hash: String) -> Json<BlockHeader> {
|
||||
let res: BlockByHeaderHash = issue_rpc(&"get_block_header_by_hash")
|
||||
.send()
|
||||
.unwrap().json().unwrap();
|
||||
Json(res.result.block_header)
|
||||
}
|
||||
|
||||
#[get("/info")]
|
||||
fn get_daemon_info() -> Json<GetInfoResult> {
|
||||
let res: GetInfo = issue_rpc(&"get_info")
|
||||
.send()
|
||||
.unwrap().json().unwrap();
|
||||
Json(res.result)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let env_url = env::var("DAEMON_URI");
|
||||
match env_url {
|
||||
Ok(_) => {
|
||||
rocket::ignite()
|
||||
.mount("/", routes![
|
||||
get_daemon_info, get_transaction
|
||||
])
|
||||
.register(catchers![not_found])
|
||||
.launch();
|
||||
},
|
||||
Err(_) => panic!("Environment variable `DAEMON_URI` not provided.")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue