-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
f Allow node runner to accepts HTTP request on /payjoin endpoint
- Loading branch information
Showing
6 changed files
with
144 additions
and
255 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use bitcoin::address::NetworkChecked; | ||
use hyper::HeaderMap; | ||
use payjoin::bitcoin::{self, Amount}; | ||
use payjoin::Uri; | ||
use std::str::FromStr; | ||
|
||
struct Headers(HeaderMap); | ||
|
||
impl payjoin::receive::Headers for Headers { | ||
fn get_header(&self, key: &str) -> Option<&str> { | ||
self.0.get(key).and_then(|v| v.to_str().ok()) | ||
} | ||
} | ||
|
||
pub struct Receiver; | ||
|
||
impl Receiver { | ||
pub async fn start() -> Result<(), Box<dyn std::error::Error>> { | ||
http_server::start().await.unwrap(); | ||
Ok(()) | ||
} | ||
|
||
fn _build_pj_uri( | ||
address: bitcoin::Address, amount: Amount, pj: &'static str, | ||
) -> Result<Uri<'static, NetworkChecked>, Box<dyn std::error::Error>> { | ||
let pj_uri_string = format!("{}?amount={}&pj={}", address.to_qr_uri(), amount.to_btc(), pj); | ||
let pj_uri = Uri::from_str(&pj_uri_string).map_err(|e| e.to_string())?; | ||
Ok(pj_uri.assume_checked()) | ||
} | ||
} | ||
|
||
mod http_server { | ||
use bytes::Bytes; | ||
use http_body_util::{combinators::BoxBody, BodyExt, Empty, Full}; | ||
use hyper::server::conn::http1; | ||
use hyper::service::service_fn; | ||
use hyper::{Method, Request, Response, StatusCode}; | ||
use hyper_util::rt::TokioIo; | ||
use std::net::SocketAddr; | ||
use tokio::net::TcpListener; | ||
|
||
pub async fn start() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
let addr = SocketAddr::from(([127, 0, 0, 1], 3227)); | ||
let listener = TcpListener::bind(addr).await?; | ||
println!("Listening on http://{}", addr); | ||
loop { | ||
let (stream, _) = listener.accept().await?; | ||
let io = TokioIo::new(stream); | ||
|
||
tokio::task::spawn(async move { | ||
if let Err(err) = | ||
http1::Builder::new().serve_connection(io, service_fn(request_handler)).await | ||
{ | ||
println!("Error serving connection: {:?}", err); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
async fn request_handler( | ||
req: Request<hyper::body::Incoming>, | ||
) -> Result<Response<BoxBody<Bytes, hyper::Error>>, hyper::Error> { | ||
match (req.method(), req.uri().path()) { | ||
// Serve some instructions at / | ||
(&Method::GET, "/") => Ok(Response::new(full( | ||
"Try POSTing data to /request_handler such as: `curl localhost:3000/request_handler -XPOST -d \"PAYJOIN ME\"`", | ||
))), | ||
|
||
// Simply echo the body back to the client. | ||
(&Method::POST, "/payjoin") => Ok(Response::new(req.into_body().boxed())), | ||
|
||
// Return the 404 Not Found for other routes. | ||
_ => { | ||
let mut not_found = Response::new( | ||
Empty::<Bytes>::new() | ||
.map_err(|never| match never {}) | ||
.boxed() | ||
); | ||
*not_found.status_mut() = StatusCode::NOT_FOUND; | ||
Ok(not_found) | ||
} | ||
} | ||
} | ||
|
||
fn full<T: Into<Bytes>>(chunk: T) -> BoxBody<Bytes, hyper::Error> { | ||
Full::new(chunk.into()).map_err(|never| match never {}).boxed() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.