--- /dev/null
+def main [host: string, destination: string, ssh_key: path] {
+    let ssh_args = [-i $ssh_key $host]
+    let scp_args = [-r -i $ssh_key]
+    let target = "x86_64-unknown-linux-musl"
+    let app_name = "staking_watchdog"
+    let build = "debug" # "debug" or "release".
+
+    def invoke_ssh [command: string] {
+        let args = $ssh_args ++ $command
+        print $"Executing: ssh ($args)"
+        ssh $args
+    }
+
+    def copy_ssh [source: string, destination: string] {
+        let args = $scp_args ++ [$source $"($host):($destination)"]
+        print $"Executing: scp ($args)"
+        scp $args
+    }
+
+    # Don't know how to dynamically pass variable arguments.
+    if $build == "release" {
+        cargo build --target $target --release
+    } else {
+        cargo build --target $target
+    }
+
+    # invoke_ssh [sudo systemctl stop $app_name]
+    copy_ssh ./target/($target)/($build)/($app_name) $destination
+    invoke_ssh $"chmod u+x ($destination)/($app_name)"
+    # invoke_ssh [sudo systemctl start $app_name]
+    print "Deployment finished"
+}
\ No newline at end of file
 
--- /dev/null
+/*
+ * API Reference: https://ethereum.github.io/beacon-APIs/
+ */
+
+#![cfg_attr(debug_assertions, allow(unused_variables, unused_imports, dead_code))]
+
+use std::{
+    fs,
+    net::{IpAddr, Ipv4Addr},
+    thread,
+    time::{self, Duration},
+};
+
+use anyhow::{Context, Result};
+use reqwest::StatusCode;
+use serde::Deserialize;
+use serde_json::{json, Value};
+
+use crate::config::Config;
+
+mod config;
+// mod error;
+
+const FILE_CONF: &str = "config.ron";
+const CHECK_PERIOD: Duration = Duration::from_secs(5); // 5s.
+const EMAIL_RESEND_PERIOD: Duration = Duration::from_secs(12 * 60 * 60); // 12h.
+const BASE_URI: &str = "http://localhost:5052/eth/v1/";
+
+fn main() -> Result<()> {
+    println!("Staking Watchdog");
+
+    let config = Config::read(FILE_CONF)?;
+
+    println!("Configuration: {:?}", config);
+
+    let mut time_last_email_send = time::Instant::now() - EMAIL_RESEND_PERIOD;
+
+    loop {
+        let time_beginning_loop = time::Instant::now();
+
+        if let Err(error) = check_validators(&config.pub_keys) {
+            println!("Error: {:?}", error);
+            if time::Instant::now() - time_last_email_send >= EMAIL_RESEND_PERIOD {
+                // Send e-mail.
+                println!("Sending email...");
+
+                time_last_email_send = time::Instant::now();
+            }
+        }
+
+        let elapsed = time::Instant::now() - time_beginning_loop;
+
+        if elapsed < CHECK_PERIOD {
+            let to_wait = CHECK_PERIOD - elapsed;
+            thread::sleep(to_wait);
+        }
+    }
+}
+
+#[derive(Debug)]
+enum CheckError {
+    HttpError(String),
+    NotSync,
+    InvalidSyncStatus,
+    NodeHavingIssues,
+    UnknownCodeFromHealthCheck(u16),
+    ReqwestError(reqwest::Error),
+    ValidatorError { pub_key: String, message: String },
+    ValidatorStatusError { pub_key: String, message: String },
+}
+
+impl From<reqwest::Error> for CheckError {
+    fn from(value: reqwest::Error) -> Self {
+        CheckError::ReqwestError(value)
+    }
+}
+
+#[derive(Deserialize, Debug)]
+struct JsonValidatorState {
+    data: JsonValidatorStateData,
+}
+
+#[derive(Deserialize, Debug)]
+struct JsonValidatorStateData {
+    status: String,
+}
+
+#[derive(Deserialize, Debug)]
+struct JsonError {
+    code: u16,
+    message: String,
+}
+
+fn check_validators(pub_keys: &[String]) -> std::result::Result<(), CheckError> {
+    let url = BASE_URI;
+    let client = reqwest::blocking::Client::new();
+
+    let request_health = client
+        .get(format!("{url}node/health"))
+        .header("accept", "application/json");
+    match request_health.send() {
+        Ok(resp) => {
+            println!("{resp:?}");
+            match resp.status().as_u16() {
+                200 => (),
+                206 => return Err(CheckError::NotSync),
+                400 => return Err(CheckError::InvalidSyncStatus),
+                503 => return Err(CheckError::NodeHavingIssues),
+                code => return Err(CheckError::UnknownCodeFromHealthCheck(code)),
+            }
+        }
+        Err(error) => {
+            println!("{error:?}");
+            return Err(CheckError::HttpError(error.to_string()));
+        }
+    }
+
+    return Err(CheckError::NotSync);
+
+    for pub_key in pub_keys {
+        let request = client
+            .get(format!("{url}beacon/states/head/validators/0x{pub_key}"))
+            .header("accept", "application/json");
+        match request.send() {
+            Ok(resp) => {
+                println!("{resp:?}");
+                match resp.status().as_u16() {
+                    200 => {
+                        let json: JsonValidatorState = resp.json()?;
+                        // println!("JSON:\n{:?}", json); // For Debug.
+                        if json.data.status != "active_ongoing" {
+                            return Err(CheckError::ValidatorStatusError {
+                                pub_key: pub_key.clone(),
+                                message: format!("Status: {}", json.data.status),
+                            });
+                        }
+                    }
+                    code => {
+                        let json: JsonError = resp.json()?;
+                        // println!("JSON:\n{:?}", json); // For Debug.
+                        return Err(CheckError::ValidatorError {
+                            pub_key: pub_key.clone(),
+                            message: format!(
+                                "Http error code: {}, message: {}",
+                                code, json.message
+                            ),
+                        });
+                    }
+                }
+            }
+            Err(error) => {
+                println!("{error:?}");
+                return Err(CheckError::ValidatorError {
+                    pub_key: pub_key.clone(),
+                    message: error.to_string(),
+                });
+            }
+        }
+    }
+
+    // match request_builder
+    //     .header("Authorization", format!("Apikey {}", api_key))
+    //     .send()
+    // {
+    //     Ok(resp) => {
+    //         if resp.status().is_success() {
+    //             let content = resp.text().unwrap();
+    //             Ok(serde_json::from_str(&content).unwrap())
+    //         } else {
+    //             Err(Box::new(Error {
+    //                 message: format!("Request unsuccessful to {}: {:#?}", &url, resp),
+    //             }))
+    //         }
+    //     }
+    //     Err(error) => Err(Box::new(Error {
+    //         message: format!("Error during request to {}: {:?}", &url, error),
+    //     })),
+    // }
+
+    // 1) Check health.
+
+    // 2) Check each validators.
+
+    Ok(())
+}