Skip to content

Commit aed6dcf

Browse files
committed
Add config saving to payjoin-cli
This Pr adds the ability to save config files for V2 to payjoin-cli . This is introduced via a set-config commandline arg that only works for v2 and when the right set of supporting args is present .
1 parent 069ad21 commit aed6dcf

File tree

6 files changed

+86
-0
lines changed

6 files changed

+86
-0
lines changed

Cargo-minimal.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,6 +2585,7 @@ dependencies = [
25852585
"tokio-rustls",
25862586
"tracing",
25872587
"tracing-subscriber",
2588+
"toml"
25882589
"url",
25892590
]
25902591

Cargo-recent.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,8 +2583,10 @@ dependencies = [
25832583
"tempfile",
25842584
"tokio",
25852585
"tokio-rustls",
2586+
<<<<<<< HEAD
25862587
"tracing",
25872588
"tracing-subscriber",
2589+
"toml",
25882590
"url",
25892591
]
25902592

payjoin-cli/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ url = { version = "2.5.4", features = ["serde"] }
5151
dirs = "6.0.0"
5252
tracing = "0.1.41"
5353
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
54+
toml = "0.5.11"
5455

5556
[dev-dependencies]
5657
nix = { version = "0.30.1", features = ["aio", "process", "signal"] }
5758
payjoin-test-utils = { version = "0.0.1" }
5859
tempfile = "3.20.0"
60+
61+

payjoin-cli/src/app/config.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,77 @@ impl Config {
204204
Ok(config)
205205
}
206206

207+
#[cfg(feature = "v2")]
208+
pub fn save_config(cli: &Cli) -> Result<(), anyhow::Error> {
209+
let version = Self::determine_version(cli)
210+
.map_err(|e| anyhow::anyhow!("Failed to determine version: {e}"))?;
211+
212+
if version != Version::Two {
213+
return Err(anyhow::anyhow!("--set-config is only available for bip77 (v2) mode"));
214+
}
215+
216+
// Ensure all required parameters are present
217+
if cli.rpcuser.is_none()
218+
|| cli.rpcpassword.is_none()
219+
|| cli.rpchost.is_none()
220+
|| cli.pj_directory.is_none()
221+
|| cli.ohttp_relays.is_none()
222+
{
223+
return Err(anyhow::anyhow!(
224+
"--set-config requires ALL of: \
225+
--rpcuser, --rpcpassword, --rpchost, \
226+
--pj-directory, --ohttp-relays"
227+
));
228+
}
229+
230+
// Build the TOML map , this feels a bit hacky but it works
231+
let mut toml_map = toml::map::Map::new();
232+
let mut bitcoind_map = toml::map::Map::new();
233+
234+
bitcoind_map.insert("rpcuser".into(), toml::Value::String(cli.rpcuser.clone().unwrap()));
235+
bitcoind_map
236+
.insert("rpcpassword".into(), toml::Value::String(cli.rpcpassword.clone().unwrap()));
237+
bitcoind_map.insert(
238+
"rpchost".into(),
239+
toml::Value::String(cli.rpchost.clone().unwrap().to_string()),
240+
);
241+
toml_map.insert("bitcoind".into(), toml::Value::Table(bitcoind_map));
242+
243+
let mut v2_map = toml::map::Map::new();
244+
v2_map.insert(
245+
"pj_directory".into(),
246+
toml::Value::String(cli.pj_directory.as_ref().unwrap().to_string()),
247+
);
248+
let relay_list: Vec<toml::Value> = cli
249+
.ohttp_relays
250+
.as_ref()
251+
.unwrap()
252+
.iter()
253+
.map(|url| toml::Value::String(url.to_string()))
254+
.collect();
255+
v2_map.insert("ohttp_relays".into(), toml::Value::Array(relay_list));
256+
toml_map.insert("v2".into(), toml::Value::Table(v2_map));
257+
258+
let toml_content = toml::Value::Table(toml_map);
259+
let toml_str = toml::to_string_pretty(&toml_content)?;
260+
261+
let config_path = std::env::current_dir()?.join("config.toml");
262+
let final_path = if !config_path.exists() {
263+
if let Some(config_dir) = dirs::config_dir() {
264+
let global_dir = config_dir.join(CONFIG_DIR);
265+
std::fs::create_dir_all(&global_dir)?;
266+
global_dir.join("config.toml")
267+
} else {
268+
config_path
269+
}
270+
} else {
271+
config_path
272+
};
273+
274+
std::fs::write(final_path, toml_str)?;
275+
Ok(())
276+
}
277+
207278
#[cfg(feature = "v1")]
208279
pub fn v1(&self) -> Result<&V1Config, anyhow::Error> {
209280
match &self.version {

payjoin-cli/src/cli/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ pub struct Cli {
7676
#[arg(long = "pj-directory", help = "The directory to store payjoin requests", value_parser = value_parser!(Url))]
7777
pub pj_directory: Option<Url>,
7878

79+
#[cfg(feature = "v2")]
80+
#[arg(long = "set-config", help = "Save current configuration parameters to config.toml", value_parser = value_parser!(bool))]
81+
pub set_config: bool,
82+
7983
#[cfg(feature = "_manual-tls")]
8084
#[arg(long = "root-certificate", help = "Specify a TLS certificate to be added as a root", value_parser = value_parser!(PathBuf))]
8185
pub root_certificate: Option<PathBuf>,

payjoin-cli/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ async fn main() -> Result<()> {
2020
tracing_subscriber::fmt().with_target(true).with_level(true).with_env_filter(env_filter).init();
2121

2222
let cli = Cli::parse();
23+
24+
#[cfg(feature = "v2")]
25+
if cli.set_config {
26+
Config::save_config(&cli)?;
27+
}
2328
let config = Config::new(&cli)?;
2429

2530
#[allow(clippy::if_same_then_else)]

0 commit comments

Comments
 (0)