Archipelago — open-source initial import
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Router;
|
||||
|
||||
/// TollGate provisioning parameters.
|
||||
///
|
||||
/// `mint_url` must be the externally-reachable URL of the Archy Cashu mint —
|
||||
/// TollGate customers connect from outside the Archy node's loopback, so
|
||||
/// localhost URLs will not work. Resolve this from the running mint app before
|
||||
/// calling `provision`.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TollGateConfig {
|
||||
/// SSID name for the pay-as-you-go network.
|
||||
pub ssid: String,
|
||||
/// Externally-reachable URL of the Archy Cashu mint.
|
||||
pub mint_url: String,
|
||||
/// Price in satoshis per `step_size` interval.
|
||||
pub price_sats: u64,
|
||||
/// Step size in milliseconds (default: 60000 = 1 minute).
|
||||
pub step_size_ms: u64,
|
||||
/// Minimum steps a customer must purchase at once.
|
||||
pub min_steps: u32,
|
||||
/// Whether the TollGate service should be running and enabled at boot.
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for TollGateConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ssid: "archipelago".to_string(),
|
||||
mint_url: String::new(), // must be set by caller from the running mint app
|
||||
price_sats: 10,
|
||||
step_size_ms: 60_000,
|
||||
min_steps: 1,
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write TollGate UCI configuration and commit.
|
||||
///
|
||||
/// `tollgate-wrt` never reads UCI — see `apply_daemon_config` below for the
|
||||
/// config it actually consumes. These `tollgate.main.*` keys exist only for
|
||||
/// this project's own status display / detection probes (`uci get
|
||||
/// tollgate.main.enabled` etc.); changing pricing or the mint here has no
|
||||
/// effect on what the daemon advertises or accepts.
|
||||
pub fn apply(router: &Router, cfg: &TollGateConfig) -> Result<()> {
|
||||
router.uci_apply(
|
||||
"tollgate",
|
||||
&[
|
||||
("tollgate.main", "tollgate"),
|
||||
("tollgate.main.enabled", if cfg.enabled { "1" } else { "0" }),
|
||||
("tollgate.main.metric", "milliseconds"),
|
||||
("tollgate.main.step_size", &cfg.step_size_ms.to_string()),
|
||||
("tollgate.main.min_steps", &cfg.min_steps.to_string()),
|
||||
("tollgate.main.price_per_step", &cfg.price_sats.to_string()),
|
||||
("tollgate.main.currency", "sat"),
|
||||
("tollgate.main.mint_url", &cfg.mint_url),
|
||||
],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write the config `tollgate-wrt` actually reads: `/etc/tollgate/config.json`
|
||||
/// (schema `v0.0.6`/`v0.0.7`, see `config_manager` in the upstream Go source).
|
||||
///
|
||||
/// Merges into whatever config.json already exists (the daemon writes a
|
||||
/// default on first boot) rather than overwriting it wholesale — fields this
|
||||
/// project doesn't manage (`profit_share`, `upstream_detector`,
|
||||
/// `upstream_session_manager`/`chandler`, `relays`, ...) must survive
|
||||
/// re-provisioning.
|
||||
///
|
||||
/// Must run before the daemon is (re)started — it only reads this file at
|
||||
/// startup, it does not hot-reload.
|
||||
pub fn apply_daemon_config(router: &Router, cfg: &TollGateConfig) -> Result<()> {
|
||||
let existing = router.run_ok("cat /etc/tollgate/config.json 2>/dev/null || echo '{}'")?;
|
||||
let mut doc: serde_json::Value =
|
||||
serde_json::from_str(existing.trim()).unwrap_or_else(|_| serde_json::json!({}));
|
||||
|
||||
doc["metric"] = serde_json::json!("milliseconds");
|
||||
doc["step_size"] = serde_json::json!(cfg.step_size_ms);
|
||||
doc["accepted_mints"] = serde_json::json!([{
|
||||
"url": cfg.mint_url,
|
||||
"min_balance": 64,
|
||||
"balance_tolerance_percent": 10,
|
||||
"payout_interval_seconds": 60,
|
||||
"min_payout_amount": 128,
|
||||
"price_per_step": cfg.price_sats,
|
||||
"price_unit": "sats",
|
||||
"purchase_min_steps": cfg.min_steps,
|
||||
}]);
|
||||
|
||||
let json_str = serde_json::to_string_pretty(&doc).context("serialize config.json")?;
|
||||
router
|
||||
.upload_file("/etc/tollgate/config.json", json_str.as_bytes())
|
||||
.context("upload /etc/tollgate/config.json")?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user