feat: per-network config with --network override#126
Conversation
Restructure both project (tari.config.toml) and global CLI configs to nest wallet-daemon URL, metadata-server URL, and template-address under [networks.<name>] sections, keyed by the Network enum from tari_ootle_common_types. Add a default-network setting and a global -n/--network flag that overrides it on any command. Resolution order for the active network: --network flag > project default-network > global default-network > Esmeralda. Wallet daemon URL, metadata server URL, and template address all look up the resolved network's section, with per-command URL flags still winning. Default project config now emits: default-network = "esmeralda" [networks.esmeralda] wallet-daemon-url = "http://127.0.0.1:5100/json_rpc" `tari config set` was generalised to arbitrary dotted-key depth so that `networks.<net>.wallet-daemon-url` works. No migration shim: existing flat `tari.config.toml` files will need `tari config init` or a manual edit.
There was a problem hiding this comment.
Code Review
This pull request introduces multi-network support to the Tari CLI, refactoring configuration structures to allow per-network settings for wallet daemon URLs, metadata server URLs, and published template addresses. It adds a global --network flag and implements a resolution hierarchy across CLI flags, project configurations, and global settings. Feedback focuses on the lack of validation between the CLI-resolved network and the network reported by the wallet daemon, which could lead to incorrect configuration updates. Additionally, there are concerns regarding code duplication between save_template_address and set_dotted_key, a regression in the global override mechanism for network-specific settings, and the preference for implicit tables in TOML generation to maintain a cleaner configuration file.
| let info = publisher | ||
| .get_wallet_info() | ||
| .await | ||
| .with_context(|| anyhow!("Failed to connect to the wallet at {}", wallet_daemon_url))?; | ||
| println!( | ||
| "🔗 Connected to wallet version {} (network: {})", | ||
| "🔗 Connected to wallet version {} (wallet network: {})", | ||
| info.version, info.network | ||
| ); |
There was a problem hiding this comment.
There is no validation that the network reported by the wallet daemon matches the network resolved by the CLI. This can lead to templates being published to a different network than intended (e.g., if the CLI is set to mainnet but the wallet is on esmeralda), while the CLI records the resulting address under the wrong network section in the configuration file. It is recommended to verify that info.network matches the resolved network before proceeding.
| let root = doc | ||
| .entry(head[0]) | ||
| .or_insert_with(|| toml_edit::Item::Table(toml_edit::Table::new())) | ||
| .as_table_mut() | ||
| .ok_or_else(|| anyhow!("'{}' is not a table", head[0]))?; | ||
|
|
||
| let mut table = root; | ||
| for part in &head[1..] { | ||
| let entry = table | ||
| .entry(part) | ||
| .or_insert_with(|| toml_edit::Item::Table(toml_edit::Table::new())); | ||
| table = entry | ||
| .as_table_mut() | ||
| .ok_or_else(|| anyhow!("'{part}' is not a table"))?; | ||
| } | ||
| table.insert(leaf, toml_edit::value(value)); |
There was a problem hiding this comment.
The current implementation of set_dotted_key creates intermediate tables as explicit tables, which can lead to a cluttered TOML file with multiple headers (e.g., [networks], [networks.esmeralda]). It is generally preferred to use implicit tables for nested structures. Additionally, the logic can be simplified by iterating over all parts of the 'head' using the root table of the document.
References
- Prefer implicit tables for nested TOML structures to maintain a clean configuration layout. (link)
| pub const VALID_OVERRIDE_KEYS: &[&str] = &[ | ||
| "template_repository.url", | ||
| "template_repository.branch", | ||
| "template_repository.folder", | ||
| "default_account", | ||
| "wallet_daemon_url", | ||
| "metadata_server_url", | ||
| "default_network", | ||
| ]; |
There was a problem hiding this comment.
Removing wallet_daemon_url and metadata_server_url from VALID_OVERRIDE_KEYS is a regression that breaks the ability to override these settings via the global -e flag. While command-specific flags exist, the -e flag was a useful catch-all. Furthermore, the -e flag logic in override_data remains flat and does not support the new nested configuration keys (e.g., networks.esmeralda.wallet-daemon-url), even though the tari config set command was generalized to support them. The global override mechanism should be updated to support the new structure or at least maintain backward compatibility for the old keys by mapping them to the default network.
| fn save_template_address(doc: &mut toml_edit::DocumentMut, network: Network, address: &str) { | ||
| let networks = doc | ||
| .entry("networks") | ||
| .or_insert_with(|| toml_edit::Item::Table(toml_edit::Table::new())); | ||
| let Some(networks_table) = networks.as_table_mut() else { | ||
| // Not a table — overwrite. | ||
| *networks = toml_edit::Item::Table(toml_edit::Table::new()); | ||
| return save_template_address(doc, network, address); | ||
| }; | ||
| networks_table.set_implicit(true); | ||
|
|
||
| let net_entry = networks_table | ||
| .entry(network.as_key_str()) | ||
| .or_insert_with(|| toml_edit::Item::Table(toml_edit::Table::new())); | ||
| let net_table = match net_entry.as_table_mut() { | ||
| Some(t) => t, | ||
| None => { | ||
| *net_entry = toml_edit::Item::Table(toml_edit::Table::new()); | ||
| net_entry.as_table_mut().unwrap() | ||
| }, | ||
| }; | ||
| net_table.insert("template-address", toml_edit::value(address.to_string())); | ||
| } |
There was a problem hiding this comment.
The save_template_address function duplicates much of the logic found in the generalized set_dotted_key function in crates/cli/src/cli/commands/config.rs. Consolidating this logic into a shared utility would improve maintainability and ensure that configuration file modifications (such as setting tables to implicit) are performed consistently across the CLI.
Default project and global configs now ship both [networks.esmeralda] and [networks.localnet] sections so users can switch with `--network localnet` without first editing the config. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Default project and global configs now write a metadata-server-url under each per-network section: esmeralda → https://ootle-templates-esme.tari.com/ localnet → http://localhost:3000 Both URLs are defined as single-source-of-truth constants in project/config.rs and reused by the in-memory fallback in util.rs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Validate wallet daemon network matches the CLI-resolved active network before publishing; abort with a clear error if they differ. - Restore -e overrides for nested keys: networks.<net>.wallet-daemon-url and networks.<net>.metadata-server-url. Switch the parser to split_once so values containing '=' are preserved. - Share set_dotted_key between `tari config set` and the post-publish template-address writer (drops the duplicated save_template_address). - Mark intermediate TOML tables implicit so nested structures render as `[networks.esmeralda]` instead of `[networks]\n[networks.esmeralda]`. - Update README and all docs (configuration-schema, cli-commands, workflow, project-configuration, deployment, faq, etc.) to the new per-network shape and document the --network flag. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
wallet-daemon-url,metadata-server-url, andtemplate-addressunder[networks.<name>]sections in both project (tari.config.toml) and global CLI config, keyed by theNetworkenum fromtari_ootle_common_types.default-networksetting (defaults toesmeralda) and a global-n/--network <NETWORK>flag that overrides it on any command.--networkflag → projectdefault-network→ globaldefault-network→Esmeralda. Wallet daemon URL, metadata server URL, and template address all look up the resolved network's section, with per-command URL flags still winning.http://127.0.0.1:5100/json_rpc(unchanged from the previous flat default).tari config setgeneralised to arbitrary dotted-key depth sonetworks.<net>.wallet-daemon-urlworks.Default project config now emits:
No backwards-compat shim — existing flat
tari.config.tomlfiles will needtari config initor a manual edit.Test plan
cargo test --workspacepasses (new roundtrip + per-network parse tests added).tari config initemits the new layout (verified locally).tari config set networks.localnet.wallet-daemon-url …/tari config get …round-trip through the deeper dotted-key setter.tari --network bogus publishrejects invalid networks via clap.--networkshows up in bothtari --helpandtari publish --help(global = true).tari publishagainst a running esmeralda wallet daemon (not run in CI).tari --network localnet publishwith a[networks.localnet]section in project config.🤖 Generated with Claude Code