depolymerization

wire gateway for Bitcoin/Ethereum
Log | Files | Refs | Submodules | README | LICENSE

commit cfb5da39f036a68aaeec0a0d3187718fc399b045
parent fb88a483473e5b3207ff6eac78faca149b4c8103
Author: Antoine A <>
Date:   Wed,  2 Feb 2022 22:12:49 +0100

wire-gateway: support eth and btc

Diffstat:
MCargo.lock | 1+
Mmakefile | 4++--
Mwire-gateway/Cargo.toml | 19+++++++++++++------
Mwire-gateway/src/main.rs | 34++++++++++++++++++++++++----------
4 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1979,6 +1979,7 @@ version = "0.1.0" dependencies = [ "bitcoin", "deadpool-postgres", + "ethereum-types", "hyper", "hyperlocal", "listenfd", diff --git a/makefile b/makefile @@ -22,4 +22,4 @@ test_btc: test_eth: test/eth/wire.sh -test: install test_gateway test_btc test_eth -\ No newline at end of file +test: install test_gateway test_eth test_btc +\ No newline at end of file diff --git a/wire-gateway/Cargo.toml b/wire-gateway/Cargo.toml @@ -4,9 +4,6 @@ version = "0.1.0" edition = "2021" license = "AGPL-3.0-or-later" -[features] -# Enable test admin endpoint -test = [] [dependencies] # Http library @@ -34,7 +31,17 @@ deadpool-postgres = "0.10.1" listenfd = "0.5.0" # Taler libs taler-common = { path = "../taler-common" } +# Bitcoin types +bitcoin = { version = "0.27.1", optional = true } +# Euthereum types +ethereum-types = { version = "0.12.1", default-features = false, optional = true } + -# TODO Put this behind a feature -# Bitcoin data structure -bitcoin = "0.27.1" +[features] +default = ["btc", "eth"] +# Enable test admin endpoint +test = [] +# Support btc-wire +btc = ["bitcoin"] +# Support eth-wire +eth = ["ethereum-types"] diff --git a/wire-gateway/src/main.rs b/wire-gateway/src/main.rs @@ -50,7 +50,7 @@ mod json; struct ServerState { pool: Pool, config: GatewayConfig, - domain: &'static str, + payto_check: fn(&Url) -> bool, notify: Notify, lifetime: Option<AtomicU32>, status: AtomicBool, @@ -122,9 +122,11 @@ async fn main() { let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap(); let state = ServerState { pool, - domain: match conf.core.currency.as_str() { - "BTC" => "bitcoin", - "ETH" => "ethereum", + payto_check: match conf.core.currency.as_str() { + #[cfg(feature = "btc")] + "BTC" => check_pay_to_btc, + #[cfg(feature = "eth")] + "ETH" => check_pay_to_eth, currency => unimplemented!("Unsupported currency {}", currency), }, config: conf.clone(), @@ -206,15 +208,27 @@ async fn main() { } /// Check if an url is a valid bitcoin payto url -fn check_pay_to(url: &Url, domain: &str) -> bool { - // TODO currency agnostic - return url.domain() == Some(domain) +#[cfg(feature = "btc")] +fn check_pay_to_btc(url: &Url) -> bool { + return url.domain() == Some("bitcoin") && url.scheme() == "payto" && url.username() == "" && url.password().is_none() && url.query().is_none() - && url.fragment().is_none(); - //&& bitcoin::Address::from_str(url.path().trim_start_matches('/')).is_ok(); + && url.fragment().is_none() + && bitcoin::Address::from_str(url.path().trim_start_matches('/')).is_ok(); +} + +/// Check if an url is a valid ethereum payto url +#[cfg(feature = "eth")] +fn check_pay_to_eth(url: &Url) -> bool { + return url.domain() == Some("ethereum") + && url.scheme() == "payto" + && url.username() == "" + && url.password().is_none() + && url.query().is_none() + && url.fragment().is_none() + && ethereum_types::H160::from_str(url.path().trim_start_matches('/')).is_ok(); } /// Assert request method match expected @@ -278,7 +292,7 @@ async fn router( StatusCode::BAD_REQUEST, ErrorCode::GENERIC_PARAMETER_MALFORMED, )?; - if !check_pay_to(&request.credit_account, state.domain) { + if !(state.payto_check)(&request.credit_account) { return Err(ServerError::code( StatusCode::BAD_REQUEST, ErrorCode::GENERIC_PAYTO_URI_MALFORMED,