#![doc = include_str!("../README.md")]
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![cfg_attr(any(), deny(clippy::unwrap_used))]
use std::time::Duration;
use anyhow::Result;
use http_relay::HttpRelay;
use pubky::{ClientBuilder, Keypair};
use pubky_common::timestamp::Timestamp;
use pubky_homeserver::Homeserver;
use url::Url;
pub struct Testnet {
dht: mainline::Testnet,
relays: Vec<pkarr_relay::Relay>,
}
impl Testnet {
pub async fn run() -> Result<Self> {
let dht = mainline::Testnet::new(3)?;
let mut testnet = Self {
dht,
relays: vec![],
};
testnet.run_pkarr_relay().await?;
Ok(testnet)
}
pub async fn run_with_hardcoded_configurations() -> Result<Self> {
let dht = mainline::Testnet::new(3)?;
dht.leak();
let storage = std::env::temp_dir().join(Timestamp::now().to_string());
let mut builder = pkarr_relay::Relay::builder();
builder
.http_port(15411)
.storage(storage.clone())
.disable_rate_limiter()
.pkarr(|pkarr| {
pkarr
.request_timeout(Duration::from_millis(100))
.bootstrap(&dht.bootstrap)
.dht(|builder| {
if !dht.bootstrap.first().unwrap().contains("6881") {
builder.server_mode().port(6881);
}
builder
.bootstrap(&dht.bootstrap)
.request_timeout(Duration::from_millis(200))
})
});
let relay = unsafe { builder.run() }.await?;
let mut builder = Homeserver::builder();
builder
.keypair(Keypair::from_secret_key(&[0; 32]))
.storage(storage)
.bootstrap(&dht.bootstrap)
.relays(&[relay.local_url()])
.domain("localhost")
.close_signups()
.admin_password("admin".to_string());
unsafe { builder.run().await }?;
HttpRelay::builder().http_port(15412).run().await?;
let testnet = Self {
dht,
relays: vec![relay],
};
Ok(testnet)
}
pub fn bootstrap(&self) -> &[String] {
&self.dht.bootstrap
}
pub fn relays(&self) -> Box<[Url]> {
self.relays.iter().map(|r| r.local_url()).collect()
}
pub async fn run_homeserver(&self) -> Result<Homeserver> {
Homeserver::run_test(&self.dht.bootstrap).await
}
pub async fn run_homeserver_with_signup_tokens(&self) -> Result<Homeserver> {
Homeserver::run_test_with_signup_tokens(&self.dht.bootstrap).await
}
pub async fn run_http_relay(&self) -> Result<HttpRelay> {
HttpRelay::builder().run().await
}
pub fn client_builder(&self) -> ClientBuilder {
let bootstrap = self.bootstrap();
let relays = self.relays();
let mut builder = pubky::Client::builder();
builder.pkarr(|builder| {
builder
.bootstrap(bootstrap)
.relays(&relays)
.expect("testnet relays should be valid urls")
});
builder
}
pub async fn run_pkarr_relay(&mut self) -> Result<Url> {
let relay = pkarr_relay::Relay::run_test(&self.dht).await?;
let url = relay.local_url();
self.relays.push(relay);
Ok(url)
}
}