main.rs (3546B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use clap::Parser as _; 18 use taler_api::api::TalerRouter as _; 19 use taler_build::long_version; 20 use taler_common::{CommonArgs, cli::ConfigCmd, config::Config, taler_main}; 21 use taler_wise::{ 22 api, 23 config::ServeCfg, 24 constants::CONFIG_SOURCE, 25 db::{dbinit, pool}, 26 setup::{self}, 27 worker::run_worker, 28 }; 29 30 #[derive(clap::Parser, Debug)] 31 #[command(long_version = long_version(), about, long_about = None)] 32 struct Args { 33 #[clap(flatten)] 34 common: CommonArgs, 35 36 #[command(subcommand)] 37 cmd: Command, 38 } 39 40 #[derive(clap::Subcommand, Debug)] 41 enum Command { 42 /// Initialize taler-wise database 43 Dbinit { 44 /// Reset database (DANGEROUS: All existing data is lost) 45 #[arg(short, long)] 46 reset: bool, 47 }, 48 /// Check configuration and initialize balance state 49 Setup { 50 /// Reset all synchronization cursors and schedules to rescan from balance creation 51 #[arg(long)] 52 reset: bool, 53 }, 54 /// Run taler-wise worker 55 Worker { 56 /// Execute once and return 57 #[arg(short, long)] 58 transient: bool, 59 }, 60 /// Run taler-wise HTTP server 61 Serve { 62 /// Check whether an API is in use (if it's useful to start the HTTP 63 /// server). Exit with 0 if at least one API is enabled, otherwise 1 64 #[arg(long)] 65 check: bool, 66 }, 67 #[command(subcommand)] 68 Config(ConfigCmd), 69 } 70 71 async fn run(cmd: Command, cfg: &Config) -> anyhow::Result<()> { 72 match cmd { 73 Command::Dbinit { reset } => { 74 dbinit(cfg, reset).await?; 75 } 76 Command::Setup { reset } => { 77 let pool = pool(cfg).await?; 78 let client = http_client::client(); 79 setup::setup(cfg, &pool, &client, reset).await? 80 } 81 Command::Serve { check } => { 82 if check { 83 ServeCfg::parse(cfg)?; 84 } else { 85 let pool = pool(cfg).await?; 86 let cfg = ServeCfg::parse(cfg)?; 87 api::start( 88 pool, 89 &cfg.name, 90 cfg.balances, 91 cfg.api.public_key(), 92 cfg.profile_id, 93 &cfg.wire_gateway, 94 &cfg.revenue, 95 &cfg.observability, 96 ) 97 .await 98 .serve(&cfg.serve, None) 99 .await?; 100 } 101 } 102 Command::Worker { transient } => { 103 let pool = pool(cfg).await?; 104 let client = http_client::client(); 105 run_worker(cfg, &pool, &client, transient).await?; 106 } 107 Command::Config(cmd) => cmd.run(cfg)?, 108 } 109 Ok(()) 110 } 111 112 fn main() { 113 let args = Args::parse(); 114 taler_main(CONFIG_SOURCE, args.common, async |cfg| { 115 run(args.cmd, cfg).await 116 }); 117 }