1010#![ doc( html_logo_url = "https://github.com/bitcoindevkit/bdk/raw/master/static/bdk.png" ) ]
1111#![ warn( missing_docs) ]
1212
13- mod backend ;
13+ mod client ;
1414mod commands;
1515mod config;
1616mod error;
@@ -22,14 +22,29 @@ mod handlers;
2222 feature = "rpc"
2323) ) ]
2424mod payjoin;
25+ mod persister;
2526mod utils;
26- mod wallet;
2727
28+ #[ cfg( feature = "redb" ) ]
29+ use bdk_redb:: Store as RedbStore ;
2830use bdk_wallet:: bitcoin:: Network ;
29- use log:: { debug, error , warn} ;
31+ use log:: { debug, warn} ;
3032
31- use crate :: commands:: CliOpts ;
32- use crate :: handlers:: handle_command;
33+ #[ cfg( any(
34+ feature = "electrum" ,
35+ feature = "esplora" ,
36+ feature = "rpc" ,
37+ feature = "cbf"
38+ ) ) ]
39+ use crate :: client:: new_blockchain_client;
40+ use crate :: commands:: { CliOpts , CliSubCommand , WalletSubCommand } ;
41+ use crate :: error:: BDKCliError as Error ;
42+ use crate :: handlers:: { AppCommand , AppContext } ;
43+ #[ cfg( any( feature = "sqlite" , feature = "redb" ) ) ]
44+ use crate :: persister:: { Persister , new_persisted_wallet} ;
45+ use crate :: utils:: output:: FormatOutput ;
46+ use crate :: utils:: prepare_wallet_db_dir;
47+ use crate :: utils:: { load_wallet_config, prepare_home_dir} ;
3348use clap:: Parser ;
3449
3550#[ tokio:: main]
@@ -45,11 +60,123 @@ async fn main() {
4560 )
4661 }
4762
48- match handle_command ( cli_opts) . await {
49- Ok ( result) => println ! ( "{result}" ) ,
50- Err ( e) => {
51- error ! ( "{e}" ) ;
52- std:: process:: exit ( 1 ) ;
53- }
63+ if let Err ( e) = run ( cli_opts) . await {
64+ eprintln ! ( "Error: {}" , e) ;
65+ std:: process:: exit ( 1 ) ;
5466 }
5567}
68+
69+ async fn run ( cli_opts : CliOpts ) -> Result < ( ) , Error > {
70+ let datadir = cli_opts. datadir . clone ( ) ;
71+ let home_dir = prepare_home_dir ( datadir) ?;
72+
73+ match cli_opts. subcommand . clone ( ) {
74+ CliSubCommand :: Wallet {
75+ wallet : wallet_name,
76+ subcommand,
77+ } => match subcommand {
78+ #[ cfg( any(
79+ feature = "electrum" ,
80+ feature = "esplora" ,
81+ feature = "rpc" ,
82+ feature = "cbf"
83+ ) ) ]
84+ WalletSubCommand :: OnlineWalletSubCommand ( online_cmd) => {
85+ let ( wallet_opts, network) = load_wallet_config ( & home_dir, & wallet_name) ?;
86+
87+ let database_path = prepare_wallet_db_dir ( & home_dir, & wallet_name) ?;
88+ #[ cfg( any( feature = "sqlite" , feature = "redb" ) ) ]
89+ let mut persister: Persister = match & wallet_opts. database_type {
90+ #[ cfg( feature = "sqlite" ) ]
91+ crate :: persister:: DatabaseType :: Sqlite => {
92+ let db_file = database_path. join ( "wallet.sqlite" ) ;
93+ let connection = bdk_wallet:: rusqlite:: Connection :: open ( db_file) ?;
94+ Persister :: Connection ( connection)
95+ }
96+ #[ cfg( feature = "redb" ) ]
97+ crate :: persister:: DatabaseType :: Redb => {
98+ use crate :: persister:: Persister ;
99+
100+ let db = std:: sync:: Arc :: new ( bdk_redb:: redb:: Database :: create (
101+ home_dir. join ( "wallet.redb" ) ,
102+ ) ?) ;
103+ let store = RedbStore :: new ( db, wallet_name) ?;
104+ log:: debug!( "Redb database opened successfully" ) ;
105+ Persister :: RedbStore ( store)
106+ }
107+ } ;
108+
109+ let mut wallet = new_persisted_wallet ( network, & mut persister, & wallet_opts) ?;
110+
111+ let client = new_blockchain_client ( & wallet_opts, & wallet, database_path) ?;
112+
113+ let mut ctx = AppContext :: new ( network, home_dir)
114+ . with_wallet ( & mut wallet)
115+ . with_client ( & client) ;
116+
117+ online_cmd. execute ( & mut ctx) . await ?;
118+ }
119+ WalletSubCommand :: OfflineWalletSubCommand ( offline_cmd) => {
120+ let ( wallet_opts, network) = load_wallet_config ( & home_dir, & wallet_name) ?;
121+
122+ let database_path = prepare_wallet_db_dir ( & home_dir, & wallet_name) ?;
123+
124+ #[ cfg( any( feature = "sqlite" , feature = "redb" ) ) ]
125+ let mut persister: Persister = match & wallet_opts. database_type {
126+ #[ cfg( feature = "sqlite" ) ]
127+ crate :: persister:: DatabaseType :: Sqlite => {
128+ let db_file = database_path. join ( "wallet.sqlite" ) ;
129+ let connection = bdk_wallet:: rusqlite:: Connection :: open ( db_file) ?;
130+ Persister :: Connection ( connection)
131+ }
132+ #[ cfg( feature = "redb" ) ]
133+ crate :: persister:: DatabaseType :: Redb => {
134+ use crate :: persister:: Persister ;
135+ let db = std:: sync:: Arc :: new ( bdk_redb:: redb:: Database :: create (
136+ home_dir. join ( "wallet.redb" ) ,
137+ ) ?) ;
138+ let store = RedbStore :: new ( db, wallet_name) ?;
139+ Persister :: RedbStore ( store)
140+ }
141+ } ;
142+
143+ let mut wallet = new_persisted_wallet ( network, & mut persister, & wallet_opts) ?;
144+
145+ let mut ctx = AppContext :: new ( network, home_dir) . with_wallet ( & mut wallet) ;
146+
147+ offline_cmd. execute ( & mut ctx) ?;
148+ }
149+ WalletSubCommand :: Config ( mut config_cmd) => {
150+ config_cmd. wallet_opts . wallet = Some ( wallet_name) ;
151+
152+ let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
153+
154+ config_cmd. execute ( & mut ctx) ?. print ( ) ?;
155+ }
156+ } ,
157+
158+ CliSubCommand :: Key { subcommand } => {
159+ let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
160+ subcommand. execute ( & mut ctx) ?;
161+ }
162+ CliSubCommand :: Descriptor ( descriptor_command) => {
163+ let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
164+ descriptor_command. execute ( & mut ctx) ?. print ( ) ?;
165+ }
166+ CliSubCommand :: Wallets ( cmd) => {
167+ let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
168+ cmd. execute ( & mut ctx) ?. print ( ) ?;
169+ }
170+ CliSubCommand :: Repl { wallet : _ } => todo ! ( ) ,
171+ CliSubCommand :: Completions { shell } => {
172+ shell;
173+ }
174+ #[ cfg( feature = "compiler" ) ]
175+ CliSubCommand :: Compile ( cmd) => {
176+ let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
177+ cmd. execute ( & mut ctx) ?. print ( ) ?;
178+ }
179+ } ;
180+
181+ Ok ( ( ) )
182+ }
0 commit comments