Skip to content

Commit

Permalink
clean up code, add more struct types for responses and bump dependencies
Browse files Browse the repository at this point in the history
Signed-off-by: Nitesh Balusu <[email protected]>
  • Loading branch information
niteshbalusu11 committed Feb 28, 2024
1 parent 7feb1f0 commit 3f97423
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 137 deletions.
206 changes: 122 additions & 84 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustdress"
version = "0.4.13"
version = "0.4.14"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -11,7 +11,7 @@ chrono = "0.4.23"
dotenv = "0.15.0"
hex = "0.4.3"
hyper = "0.14.24"
lnd_grpc_rust = "2.3.0"
lnd_grpc_rust = "2.4.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
sha2 = "0.10.6"
Expand All @@ -21,4 +21,5 @@ tungstenite = "0.18"
tokio-tungstenite = { version = "0.18.0", features = ["native-tls"] }
futures-util = "0.3.26"
futures = "0.3.27"
rusted-nostr-tools = "0.1.3"
rusted-nostr-tools = "0.1.3"
anyhow = "1.0.80"
7 changes: 4 additions & 3 deletions src/credentials/get_lnd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ pub async fn get_lnd() -> LndClient {
return client;
}

pub async fn test_invoice(mut client: LndClient) {
pub async fn test_invoice(mut client: LndClient) -> Result<(), anyhow::Error> {
client
.lightning()
.add_invoice(Invoice {
value: 5,
expiry: 100,
..Default::default()
})
.await
.expect("FailedToConnectToLnd");
.await?;

Ok(())
}
12 changes: 7 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ mod credentials;
use dotenv::dotenv;

#[tokio::main]
async fn main() {
async fn main() -> Result<(), anyhow::Error> {
dotenv().ok();

// Check if username and domain exist

let domain = std::env::var(EnvVariables::DOMAIN).expect("ExpectedDomainNameAsEnvVariable");
let username = std::env::var(EnvVariables::USERNAME).expect("ExpectedUserNameAsEnvVariable");
let domain = std::env::var(EnvVariables::DOMAIN)?;
let username = std::env::var(EnvVariables::USERNAME)?;

let lnd = get_lnd().await;
test_invoice(lnd).await;

test_invoice(lnd).await?;

nip05_broadcast(domain, username).await;

start_server().await;

Ok(())
}
13 changes: 13 additions & 0 deletions src/server/constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ffi::OsStr;

use serde::{Deserialize, Serialize};

pub struct Constants {
pub max_comment_length: usize,
pub max_sendamount: i64,
Expand Down Expand Up @@ -65,3 +67,14 @@ impl AsRef<OsStr> for EnvVariables {
}
}
}

#[derive(Serialize, Deserialize)]
pub(crate) struct Nip05EventDetails {
pub content: String,
pub created_at: u64,
pub id: String,
pub kind: u16,
pub pubkey: String,
pub tags: Vec<String>,
pub sig: String,
}
75 changes: 61 additions & 14 deletions src/server/handle_request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::server::{constants::CONSTANTS, utils::bech32_encode};
use http::uri::Uri;
use hyper::{http, Body, Request, Response};
use serde::{Deserialize, Serialize};
use serde_json::json;

use super::{
Expand Down Expand Up @@ -31,6 +32,19 @@ pub async fn handle_request(req: Request<Body>) -> Result<Response<Body>, hyper:
}
}

#[derive(Serialize, Deserialize)]
struct Info {
title: String,
source: String,
}

#[derive(Serialize, Deserialize)]
struct DefaultPathResponse {
lnurl: String,
decoded_url: String,
info: Info,
}

fn handle_default_path() -> Result<Response<Body>, hyper::Error> {
let (domain, username) = get_identifiers();

Expand All @@ -39,7 +53,15 @@ fn handle_default_path() -> Result<Response<Body>, hyper::Error> {

match encoded {
Ok(s) => {
let response_body = json!({ "lnurl": s, "decoded_url": lnurl_url.clone(), "info": {"title": "RustDress: Lightning Address Personal Server", "source": "https://github.com/niteshbalusu11/rustdress"} });
let response_body = DefaultPathResponse {
lnurl: s,
decoded_url: lnurl_url.clone(),
info: Info {
title: "RustDress: Lightning Address Personal Server".to_string(),
source: "https://github.com/niteshbalusu11/rustdress".to_string(),
},
};

let response_body_string = serde_json::to_string(&response_body)
.expect("Failed to serialize response body to JSON");

Expand All @@ -49,15 +71,40 @@ fn handle_default_path() -> Result<Response<Body>, hyper::Error> {
}
}

#[derive(Serialize, Deserialize)]
struct UnknownPathResponse {
status: String,
reason: String,
}

fn handle_unknown_path() -> Result<Response<Body>, hyper::Error> {
let response_body = json!({ "status": "ERROR", "reason": "Invalid Path"});
let response_body = UnknownPathResponse {
status: "ERROR".to_string(),
reason: "Invalid Path".to_string(),
};

let response_body_string =
serde_json::to_string(&response_body).expect("Failed to serialize response body to JSON");

return handle_ok_request(response_body_string);
}

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct SuccessPathResponse {
disposable: bool,
pr: String,
routes: Vec<String>,
status: String,
success_action: SuccessAction,
}

#[derive(Serialize, Deserialize)]
struct SuccessAction {
tag: String,
message: String,
}

async fn handle_invoice_path(path: &str, uri: &Uri) -> Result<Response<Body>, hyper::Error> {
let username = path.rsplitn(2, '/').next();
let response_body_string = handle_response_body();
Expand Down Expand Up @@ -102,22 +149,23 @@ async fn handle_invoice_path(path: &str, uri: &Uri) -> Result<Response<Body>, hy
}

let pr = create_invoice(digest, comment, amount, parsed_nostr_query).await;

let success_response_body = json!({
"disposable": false,
"pr": pr,
"routes": [],
"status": "OK",
"successAction": { "tag": "message", "message": "Payment received!" },
});
let success_response_body = SuccessPathResponse {
disposable: false,
pr,
routes: vec![],
status: "OK".to_string(),
success_action: SuccessAction {
tag: "message".to_string(),
message: "Payment received!".to_string(),
},
};

let success_response_body_string = serde_json::to_string(&success_response_body)
.expect("Failed to serialize response body to JSON");

return handle_ok_request(success_response_body_string);
} else {
return handle_ok_request(response_body_string);
}
return handle_ok_request(response_body_string);
}
_ => return handle_bad_request("Username Not Found"),
}
Expand Down Expand Up @@ -181,7 +229,6 @@ async fn handle_nip05_path(uri: &Uri) -> Result<Response<Body>, hyper::Error> {
.expect("Failed to serialize response body to JSON");

return handle_ok_request(response_body_string);
} else {
return handle_ok_request(default_response_body_string);
}
return handle_ok_request(default_response_body_string);
}
12 changes: 1 addition & 11 deletions src/server/start_server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use dotenv::dotenv;
use hyper::service::{make_service_fn, service_fn};
use hyper::Server;
use std::net::Ipv4Addr;
Expand All @@ -10,8 +9,6 @@ pub async fn start_server() {
let default_host = "127.0.0.1".parse::<Ipv4Addr>().unwrap();
let default_port = 3000;

dotenv().ok();

let host = match std::env::var(EnvVariables::HOST) {
Ok(val) => {
if val.is_empty() {
Expand All @@ -35,14 +32,7 @@ pub async fn start_server() {
if val.is_empty() {
default_port
} else {
let res = val.to_string().parse::<u16>();
match res {
Ok(res) => res,
Err(_) => {
println!("Failed To Parse Port, Returning Default Port");
default_port
}
}
val.to_string().parse::<u16>().unwrap_or(default_port)
}
}
Err(_) => default_port,
Expand Down
33 changes: 16 additions & 17 deletions src/server/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ use rusted_nostr_tools::{
event_methods::{get_event_hash, sign_event, SignedEvent, UnsignedEvent},
GeneratePublicKey,
};
use serde_json::json;

use crate::{
credentials::get_lnd::get_lnd,
server::{constants::CONSTANTS, publish_to_relay::publish},
};

use super::{
constants::EnvVariables, parsing_functions::convert_key,
constants::{EnvVariables, Nip05EventDetails},
parsing_functions::convert_key,
publish_to_relay::publish_zap_to_relays,
};

Expand Down Expand Up @@ -182,21 +182,20 @@ pub async fn nip05_broadcast(domain: String, username: String) {
let id = get_event_hash(&event).expect("FailedToCalculateEventHash");
let signature = sign_event(&event, &privkey).expect("FailedToSignEvent");

let nip05_json = json!([
"EVENT",
{
"content": content,
"created_at": timestamp,
"id": id,
"kind": 0,
"pubkey": pubkey,
"tags": [],
"sig": signature.sig,
},
]);

let publish_message = serde_json::to_string(&nip05_json)
.expect("Failed to serialize response body to JSON");
let nip05_event_details = Nip05EventDetails {
content,
created_at: timestamp,
id,
kind: 0,
pubkey: pubkey.clone(),
tags: vec![],
sig: signature.sig,
};

let event = ("EVENT".to_string(), nip05_event_details);

let publish_message =
serde_json::to_string(&event).expect("Failed to serialize response body to JSON");

tokio::spawn(async move {
publish(relays, publish_message).await;
Expand Down

0 comments on commit 3f97423

Please sign in to comment.