@@ -30,21 +30,12 @@ use bdk_redb::Store as RedbStore;
3030use bdk_wallet:: bitcoin:: Network ;
3131use log:: { debug, warn} ;
3232
33- #[ cfg( any(
34- feature = "electrum" ,
35- feature = "esplora" ,
36- feature = "rpc" ,
37- feature = "cbf"
38- ) ) ]
39- use crate :: client:: new_blockchain_client;
4033use crate :: commands:: { CliOpts , CliSubCommand , WalletSubCommand } ;
4134use crate :: error:: BDKCliError as Error ;
4235use crate :: handlers:: { AppCommand , AppContext } ;
43- #[ cfg( any( feature = "sqlite" , feature = "redb" ) ) ]
44- use crate :: persister:: { Persister , new_persisted_wallet} ;
4536use crate :: utils:: output:: FormatOutput ;
46- use crate :: utils:: prepare_wallet_db_dir ;
47- use crate :: utils:: { load_wallet_config , prepare_home_dir} ;
37+ use crate :: utils:: runtime :: WalletRuntime ;
38+ use crate :: utils:: { command_requires_db , prepare_home_dir} ;
4839use clap:: Parser ;
4940
5041#[ tokio:: main]
@@ -81,70 +72,36 @@ async fn run(cli_opts: CliOpts) -> Result<(), Error> {
8172 feature = "rpc" ,
8273 feature = "cbf"
8374 ) ) ]
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- } ;
75+ WalletSubCommand :: OnlineWalletSubCommand ( cmd) => {
76+ let runtime = WalletRuntime :: load ( & home_dir, & wallet_name) ?;
10877
109- let mut wallet = new_persisted_wallet ( network, & mut persister, & wallet_opts) ?;
78+ let mut wallet = runtime. build_wallet ( true ) ?;
79+ let client = runtime. build_client ( & wallet) ?;
11080
111- let client = new_blockchain_client ( & wallet_opts, & wallet, database_path) ?;
112-
113- let mut ctx =
114- AppContext :: new_online_wallet ( network, home_dir, & mut wallet, & client) ;
81+ let mut ctx = AppContext :: new_online_wallet (
82+ runtime. network ,
83+ runtime. home_dir . clone ( ) ,
84+ & mut wallet,
85+ & client,
86+ ) ;
11587
116- online_cmd . execute ( & mut ctx) . await ?;
88+ cmd . execute ( & mut ctx) . await ?;
11789 }
118- WalletSubCommand :: OfflineWalletSubCommand ( offline_cmd) => {
119- let ( wallet_opts, network) = load_wallet_config ( & home_dir, & wallet_name) ?;
120-
121- let database_path = prepare_wallet_db_dir ( & home_dir, & wallet_name) ?;
122-
123- #[ cfg( any( feature = "sqlite" , feature = "redb" ) ) ]
124- let mut persister: Persister = match & wallet_opts. database_type {
125- #[ cfg( feature = "sqlite" ) ]
126- crate :: persister:: DatabaseType :: Sqlite => {
127- let db_file = database_path. join ( "wallet.sqlite" ) ;
128- let connection = bdk_wallet:: rusqlite:: Connection :: open ( db_file) ?;
129- Persister :: Connection ( connection)
130- }
131- #[ cfg( feature = "redb" ) ]
132- crate :: persister:: DatabaseType :: Redb => {
133- use crate :: persister:: Persister ;
134- let db = std:: sync:: Arc :: new ( bdk_redb:: redb:: Database :: create (
135- home_dir. join ( "wallet.redb" ) ,
136- ) ?) ;
137- let store = RedbStore :: new ( db, wallet_name) ?;
138- Persister :: RedbStore ( store)
139- }
140- } ;
14190
142- let mut wallet = new_persisted_wallet ( network, & mut persister, & wallet_opts) ?;
91+ WalletSubCommand :: OfflineWalletSubCommand ( cmd) => {
92+ let runtime = WalletRuntime :: load ( & home_dir, & wallet_name) ?;
14393
144- let mut ctx = AppContext :: new_offline_wallet ( network, home_dir, & mut wallet) ;
94+ let mut wallet = runtime. build_wallet ( command_requires_db ( & cmd) ) ?;
95+
96+ let mut ctx = AppContext :: new_offline_wallet (
97+ runtime. network ,
98+ runtime. home_dir . clone ( ) ,
99+ & mut wallet,
100+ ) ;
145101
146- offline_cmd . execute ( & mut ctx) ?;
102+ cmd . execute ( & mut ctx) ?;
147103 }
104+
148105 WalletSubCommand :: Config ( mut config_cmd) => {
149106 config_cmd. wallet_opts . wallet = Some ( wallet_name) ;
150107
@@ -156,107 +113,87 @@ async fn run(cli_opts: CliOpts) -> Result<(), Error> {
156113
157114 CliSubCommand :: Key { subcommand } => {
158115 let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
116+
159117 subcommand. execute ( & mut ctx) ?;
160118 }
161- CliSubCommand :: Descriptor ( descriptor_command) => {
119+
120+ CliSubCommand :: Descriptor ( cmd) => {
162121 let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
163- descriptor_command
164- . execute ( & mut ctx) ?
165- . write_out ( std:: io:: stdout ( ) ) ?;
122+
123+ cmd. execute ( & mut ctx) ?. write_out ( std:: io:: stdout ( ) ) ?;
166124 }
125+
167126 CliSubCommand :: Wallets ( cmd) => {
168127 let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
128+
169129 cmd. execute ( & mut ctx) ?. write_out ( std:: io:: stdout ( ) ) ?;
170130 }
131+
171132 CliSubCommand :: Repl {
172133 wallet : wallet_name,
173134 } => {
174135 #[ cfg( feature = "repl" ) ]
175136 {
176- let ( wallet_opts, network) = load_wallet_config ( & home_dir, & wallet_name) ?;
177- let database_path = prepare_wallet_db_dir ( & home_dir, & wallet_name) ?;
178-
179- #[ cfg( any( feature = "sqlite" , feature = "redb" ) ) ]
180- let mut persister: Persister = match & wallet_opts. database_type {
181- #[ cfg( feature = "sqlite" ) ]
182- crate :: persister:: DatabaseType :: Sqlite => {
183- let db_file = database_path. join ( "wallet.sqlite" ) ;
184- let connection = bdk_wallet:: rusqlite:: Connection :: open ( db_file) ?;
185- Persister :: Connection ( connection)
186- }
187- #[ cfg( feature = "redb" ) ]
188- crate :: persister:: DatabaseType :: Redb => {
189- use crate :: persister:: Persister ;
190- let db = std:: sync:: Arc :: new ( bdk_redb:: redb:: Database :: create (
191- home_dir. join ( "wallet.redb" ) ,
192- ) ?) ;
193- let store = RedbStore :: new ( db, wallet_name. clone ( ) ) ?;
194- Persister :: RedbStore ( store)
195- }
196- } ;
137+ let runtime = WalletRuntime :: load ( & home_dir, & wallet_name) ?;
197138
198- let mut wallet = new_persisted_wallet ( network , & mut persister , & wallet_opts ) ?;
139+ let mut wallet = runtime . build_wallet ( true ) ?;
199140
200141 #[ cfg( any(
201142 feature = "electrum" ,
202143 feature = "esplora" ,
203144 feature = "rpc" ,
204145 feature = "cbf"
205146 ) ) ]
206- let client = Some ( new_blockchain_client ( & wallet_opts , & wallet, database_path ) ? ) ;
147+ let client = runtime . build_client ( & wallet) . ok ( ) ;
207148
208149 println ! (
209- "Entering REPL mode for wallet '{}'. Type 'exit' to quit." ,
150+ "Entering REPL mode for wallet '{}'. \
151+ Type 'exit' to quit.",
210152 wallet_name
211153 ) ;
212154
213155 loop {
214156 let line = crate :: handlers:: repl:: readline ( ) ?;
157+
215158 if line. trim ( ) . is_empty ( ) {
216159 continue ;
217160 }
218161
219- // Pass it to our newly refactored respond function
220162 let should_exit = crate :: handlers:: repl:: respond (
221- network,
163+ runtime . network ,
222164 & mut wallet,
223165 #[ cfg( any(
224166 feature = "electrum" ,
225167 feature = "esplora" ,
226168 feature = "rpc" ,
227169 feature = "cbf"
228170 ) ) ]
229- client. as_ref ( ) ,
171+ client. as_ref ( ) ,
230172 & line,
231- home_dir. clone ( ) ,
173+ runtime . home_dir . clone ( ) ,
232174 & cli_opts,
233175 )
234176 . await
235- . map_err ( Error :: Generic ) ?;
177+ . map_err ( Error :: Generic ) ?;
236178
237- // Break the loop if the user typed `exit`
238179 if should_exit {
239180 break ;
240181 }
241182 }
242183 }
243-
244- #[ cfg( not( feature = "repl" ) ) ]
245- {
246- return Err ( Error :: Generic (
247- "The 'repl' feature is not enabled in this build." . into ( ) ,
248- ) ) ;
249- }
250184 }
185+
251186 CliSubCommand :: Completions { shell } => {
252187 shell;
253188 }
189+
254190 #[ cfg( feature = "compiler" ) ]
255191 CliSubCommand :: Compile ( cmd) => {
256192 let mut ctx = AppContext :: new ( cli_opts. network , home_dir) ;
193+
257194 cmd. execute ( & mut ctx) ?. write_out ( std:: io:: stdout ( ) ) ?;
258195 }
259- } ;
196+ }
260197
261198 Ok ( ( ) )
262199}
0 commit comments