use crate::commands::WalletOpts;
use crate::config::{WalletConfig, WalletConfigInner};
use crate::error::BDKCliError as Error;
+use crate::handlers::Init;
use crate::handlers::{AppCommand, AppContext};
#[cfg(feature = "sqlite")]
use crate::persister::DatabaseType;
pub(crate) wallet_opts: WalletOpts,
}
-impl AppCommand for SaveConfigCommand {
+impl AppCommand<AppContext<Init>> for SaveConfigCommand {
type Output = StatusResult;
- fn execute(&self, ctx: &mut AppContext<'_>) -> Result<Self::Output, Error> {
+ fn execute(&self, ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
if ctx.network == Network::Bitcoin {
eprintln!("WARNING: Configuring for Bitcoin MAINNET. Experimental software!");
}
#[derive(Args, Debug, Clone, PartialEq)]
pub struct ListWalletsCommand {}
-impl AppCommand for ListWalletsCommand {
+impl AppCommand<AppContext<Init>> for ListWalletsCommand {
type Output = WalletsListResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
let config = match WalletConfig::load(&ctx.datadir)? {
Some(cfg) => cfg,
None => return Err(Error::Generic("No wallets configured yet.".into())),
+use crate::handlers::Init;
use crate::utils::types::DescriptorResult;
use crate::{
error::BDKCliError as Error,
/// Optional key: xprv, xpub, or mnemonic phrase
key: Option<String>,
}
-impl AppCommand for DescriptorCommand {
+impl AppCommand<AppContext<Init>> for DescriptorCommand {
type Output = DescriptorResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
match &self.key {
Some(key) => {
if is_mnemonic(key) {
}
#[cfg(feature = "compiler")]
-impl AppCommand for CompileCommand {
+impl AppCommand<AppContext<Init>> for CompileCommand {
type Output = DescriptorResult;
- fn execute(&self, _ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, _ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
let policy: Concrete<String> = Concrete::from_str(&self.policy)
.map_err(|e| Error::Generic(format!("Invalid policy: {e}")))?;
use crate::commands::KeySubCommand;
use crate::error::BDKCliError as Error;
+use crate::handlers::Init;
use crate::handlers::{AppCommand, AppContext};
use crate::utils::output::FormatOutput;
use crate::utils::types::KeyResult;
use clap::Parser;
impl KeySubCommand {
- pub fn execute(&self, ctx: &mut AppContext) -> Result<(), Error> {
+ pub fn execute(&self, ctx: &mut AppContext<Init>) -> Result<(), Error> {
match self {
KeySubCommand::Generate(generate_key_command) => generate_key_command
.execute(ctx)?
password: Option<String>,
}
-impl AppCommand for GenerateKeyCommand {
+impl AppCommand<AppContext<Init>> for GenerateKeyCommand {
type Output = KeyResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
let secp = Secp256k1::new();
let mnemonic_type = match self.word_count {
12 => WordCount::Words12,
path: DerivationPath,
}
-impl AppCommand for DeriveKeyCommand {
+impl AppCommand<AppContext<Init>> for DeriveKeyCommand {
type Output = KeyResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
let secp = Secp256k1::new();
let derived_xprv = &self.xprv.derive_priv(&secp, &self.path)?;
password: Option<String>,
}
-impl AppCommand for RestoreKeyCommand {
+impl AppCommand<AppContext<Init>> for RestoreKeyCommand {
type Output = KeyResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, ctx: &mut AppContext<Init>) -> Result<Self::Output, Error> {
let secp = Secp256k1::new();
let mnemonic = Mnemonic::parse_in(Language::English, &self.mnemonic)?;
use crate::commands::OfflineWalletSubCommand;
use crate::error::BDKCliError as Error;
-use crate::handlers::{AppCommand, AppContext};
+use crate::handlers::{AppCommand, AppContext, OfflineOperations};
use crate::utils::output::{FormatOutput, ListResult};
use crate::utils::parse_address;
use crate::utils::types::{
};
impl OfflineWalletSubCommand {
- pub fn execute(&self, ctx: &mut AppContext<'_>) -> Result<(), Error> {
+ pub fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<(), Error> {
match self {
Self::NewAddress(new_address) => new_address.execute(ctx)?.write_out(std::io::stdout()),
Self::Balance(balance) => balance.execute(ctx)?.write_out(std::io::stdout()),
#[derive(Parser, Debug, Clone, PartialEq)]
pub struct NewAddressCommand {}
-impl AppCommand for NewAddressCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for NewAddressCommand {
type Output = AddressResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".to_string()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let address_info = wallet.reveal_next_address(KeychainKind::External);
Ok(AddressResult::from(address_info))
}
#[derive(Parser, Debug, PartialEq, Clone)]
pub struct UnusedAddressCommand {}
-impl AppCommand for UnusedAddressCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for UnusedAddressCommand {
type Output = AddressResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("wallet is required".to_string()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let address_info = wallet.next_unused_address(KeychainKind::External);
Ok(AddressResult::from(address_info))
}
#[derive(Parser, Debug, PartialEq, Clone)]
pub struct UnspentCommand {}
-impl AppCommand for UnspentCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for UnspentCommand {
type Output = ListResult<UnspentDetails>;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet is required".to_string()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let utxos = wallet
.list_unspent()
.map(|utxo| UnspentDetails::from_local_output(&utxo, ctx.network))
#[derive(Parser, Debug, PartialEq, Clone)]
pub struct TransactionsCommand {}
-impl AppCommand for TransactionsCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for TransactionsCommand {
type Output = ListResult<TransactionDetails>;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("wallet required".to_string()))?;
-
- let transactions = wallet.transactions();
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let transactions = &mut ctx.state.wallet.transactions();
let txns: Vec<TransactionDetails> = transactions
.map(|tx| {
#[derive(Parser, Debug, PartialEq, Clone)]
pub struct BalanceCommand {}
-impl AppCommand for BalanceCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for BalanceCommand {
type Output = BalanceResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or_else(|| Error::Generic("Wallet required".into()))?;
- let balance = wallet.balance();
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let balance = ctx.state.wallet.balance();
Ok(BalanceResult::from(balance))
}
}
pub add_data: Option<String>,
}
-impl AppCommand for CreateTxCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for CreateTxCommand {
type Output = PsbtResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or_else(|| Error::Generic("Wallet required".into()))?;
-
- let mut tx_builder = wallet.build_tx();
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let mut tx_builder = ctx.state.wallet.build_tx();
if self.send_all {
tx_builder
pub fee_rate: f32,
}
-impl AppCommand for BumpFeeCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for BumpFeeCommand {
type Output = PsbtResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or_else(|| Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let txid = Txid::from_str(self.txid.as_str())?;
#[derive(Parser, Debug, PartialEq, Clone)]
pub struct PoliciesCommand {}
-impl AppCommand for PoliciesCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for PoliciesCommand {
type Output = KeychainPair<serde_json::Value>;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let external_policy = wallet.policies(KeychainKind::External)?;
let internal_policy = wallet.policies(KeychainKind::Internal)?;
#[derive(Parser, Debug, PartialEq, Clone)]
pub struct PublicDescriptorCommand {}
-impl AppCommand for PublicDescriptorCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for PublicDescriptorCommand {
type Output = KeychainPair<String>;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
Ok(KeychainPair {
external: wallet.public_descriptor(KeychainKind::External).to_string(),
internal: wallet.public_descriptor(KeychainKind::Internal).to_string(),
pub trust_witness_utxo: Option<bool>,
}
-impl AppCommand for SignCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for SignCommand {
type Output = PsbtResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let psbt_bytes = BASE64_STANDARD
.decode(&self.psbt)
.map_err(|e| Error::Generic(e.to_string()))?;
pub psbt: String,
}
-impl AppCommand for ExtractPsbtCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for ExtractPsbtCommand {
type Output = RawPsbt;
- fn execute(&self, _ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, _ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
let psbt_serialized = BASE64_STANDARD.decode(self.psbt.clone())?;
let psbt = Psbt::deserialize(&psbt_serialized)?;
let raw_tx = psbt.extract_tx()?;
pub trust_witness_utxo: Option<bool>,
}
-impl AppCommand for FinalizePsbtCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for FinalizePsbtCommand {
type Output = PsbtResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let psbt_bytes = BASE64_STANDARD
.decode(&self.psbt)
.map_err(|e| Error::Generic(e.to_string()))?;
pub psbt: Vec<String>,
}
-impl AppCommand for CombinePsbtCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for CombinePsbtCommand {
type Output = PsbtResult;
- fn execute(&self, _ctx: &mut AppContext) -> Result<Self::Output, Error> {
+ fn execute(&self, _ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
let mut psbts = self
.psbt
.iter()
}
}
-#[cfg(feature = "bip322")]
+// #[cfg(feature = "bip322")]
#[derive(Debug, Parser, Clone, PartialEq)]
pub struct SignMessageCommand {
/// The message to sign
}
#[cfg(feature = "bip322")]
-impl AppCommand for SignMessageCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for SignMessageCommand {
type Output = MessageResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
let address: Address = parse_address(&self.address)?;
let signature_format = parse_signature_format(&self.signature_type)?;
}
#[cfg(feature = "bip322")]
-impl AppCommand for VerifyMessageCommand {
+impl AppCommand<AppContext<OfflineOperations<'_>>> for VerifyMessageCommand {
type Output = MessageResult;
- fn execute(&self, ctx: &mut AppContext) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
+ fn execute(&self, ctx: &mut AppContext<OfflineOperations<'_>>) -> Result<Self::Output, Error> {
+ let wallet = &ctx.state.wallet;
let address: Address = parse_address(&self.address)?;
use {
crate::commands::OnlineWalletSubCommand,
crate::error::BDKCliError as Error,
- crate::handlers::{AppContext, AsyncCommand},
+ crate::handlers::{AppContext, AsyncAppCommand, OnlineOperations},
crate::payjoin::{PayjoinManager, ohttp::RelayManager},
crate::utils::is_final,
crate::utils::output::FormatOutput,
crate::utils::types::{StatusResult, TransactionResult},
bdk_wallet::bitcoin::{
- Psbt, Transaction, base64::Engine, base64::prelude::BASE64_STANDARD, consensus::Decodable,
- hex::FromHex,
+ Psbt, Transaction, Txid, base64::Engine, base64::prelude::BASE64_STANDARD,
+ consensus::Decodable, hex::FromHex,
},
std::sync::{Arc, Mutex},
};
feature = "rpc"
))]
impl OnlineWalletSubCommand {
- pub async fn execute(&self, ctx: &mut AppContext<'_>) -> Result<(), Error> {
+ pub async fn execute(&self, ctx: &mut AppContext<OnlineOperations<'_>>) -> Result<(), Error> {
match self {
OnlineWalletSubCommand::FullScan(full_scan_command) => {
let response: StatusResult = full_scan_command.execute(ctx).await?;
feature = "cbf",
feature = "rpc"
))]
-impl AsyncCommand for FullScanCommand {
+impl AsyncAppCommand<AppContext<OnlineOperations<'_>>> for FullScanCommand {
type Output = StatusResult;
- async fn execute(&self, ctx: &mut AppContext<'_>) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
- let client = ctx
- .client
- .ok_or(Error::Generic("Online client required".into()))?;
+ async fn execute(
+ &self,
+ ctx: &mut AppContext<OnlineOperations<'_>>,
+ ) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
+ let client = ctx.state.client;
#[cfg(any(feature = "electrum", feature = "esplora"))]
let request = wallet.start_full_scan().inspect({
feature = "cbf",
feature = "rpc"
))]
-impl AsyncCommand for SyncCommand {
+impl AsyncAppCommand<AppContext<OnlineOperations<'_>>> for SyncCommand {
type Output = StatusResult;
- async fn execute(&self, ctx: &mut AppContext<'_>) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".to_string()))?;
- let client = ctx
- .client
- .ok_or(Error::Generic("Client is required".to_string()))?;
+ async fn execute(
+ &self,
+ ctx: &mut AppContext<OnlineOperations<'_>>,
+ ) -> Result<Self::Output, Error> {
+ let mut wallet = &mut ctx.state.wallet;
+ let client = ctx.state.client;
#[cfg(any(feature = "electrum", feature = "esplora"))]
let request = wallet
.start_sync_with_revealed_spks()
let mempool_txs = emitter.mempool()?;
wallet.apply_unconfirmed_txs(mempool_txs.update);
}
- #[cfg(feature = "cbf")]
- KyotoClient { client } => sync_kyoto_client(wallet, client)
+ // #[cfg(feature = "cbf")]
+ KyotoClient { client } => sync_kyoto_client(&mut wallet, client)
.await
.map_err(|e| Error::Generic(e.to_string()))?,
}
feature = "cbf",
feature = "rpc"
))]
-impl AsyncCommand for BroadcastCommand {
+impl AsyncAppCommand<AppContext<OnlineOperations<'_>>> for BroadcastCommand {
type Output = TransactionResult;
- async fn execute(&self, ctx: &mut AppContext<'_>) -> Result<Self::Output, Error> {
- let client = ctx
- .client
- .ok_or(Error::Generic("Online client required".into()))?;
+ async fn execute(
+ &self,
+ ctx: &mut AppContext<OnlineOperations<'_>>,
+ ) -> Result<Self::Output, Error> {
+ let client = ctx.state.client;
let tx = match (&self.psbt, &self.tx) {
(Some(psbt), None) => {
}
};
- let txid = client.broadcast(tx).await?;
+ let txid: Txid = client.broadcast(tx).await?;
Ok(TransactionResult {
txid: txid.to_string(),
#[derive(Parser, Debug, Clone, PartialEq, Eq)]
pub struct ReceivePayjoinCommand {
- // /// The amount to receive in satoshis.
- // pub amount: u64,
-
- // /// The payjoin directory URL.
- // #[clap(long)]
- // pub directory: String,
-
- // /// Optional OHTTP relay URLs for privacy.
- // #[clap(long)]
- // pub ohttp_relays: Vec<String>,
-
- // /// Maximum fee rate in sat/vB to pay for the payjoin transaction.
- // #[clap(long)]
- // pub max_fee_rate: u64,
/// Amount to be received in sats.
#[arg(env = "PAYJOIN_AMOUNT", long = "amount", required = true)]
amount: u64,
feature = "cbf",
feature = "rpc"
))]
-impl AsyncCommand for ReceivePayjoinCommand {
+impl AsyncAppCommand<AppContext<OnlineOperations<'_>>> for ReceivePayjoinCommand {
type Output = StatusResult;
- async fn execute(&self, ctx: &mut AppContext<'_>) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
- let client = ctx
- .client
- .ok_or(Error::Generic("Online client required".into()))?;
+ async fn execute(
+ &self,
+ ctx: &mut AppContext<OnlineOperations<'_>>,
+ ) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
+ let client = ctx.state.client;
let relay_manager = Arc::new(Mutex::new(RelayManager::new()));
let mut payjoin_manager = PayjoinManager::new(wallet, relay_manager);
#[derive(Parser, Debug, Clone, PartialEq, Eq)]
pub struct SendPayjoinCommand {
- // /// The Payjoin URI string to send to.
- // pub uri: String,
-
- // /// Optional OHTTP relay URLs for privacy.
- // #[clap(long)]
- // pub ohttp_relays: Vec<String>,
-
- // /// Fee rate in sat/vB for the transaction.
- // #[clap(long, short)]
- // pub fee_rate: u64,
/// BIP 21 URI for the Payjoin.
#[arg(env = "PAYJOIN_URI", long = "uri", required = true)]
uri: String,
feature = "cbf",
feature = "rpc"
))]
-impl AsyncCommand for SendPayjoinCommand {
+impl AsyncAppCommand<AppContext<OnlineOperations<'_>>> for SendPayjoinCommand {
type Output = StatusResult;
- async fn execute(&self, ctx: &mut AppContext<'_>) -> Result<Self::Output, Error> {
- let wallet = ctx
- .wallet
- .as_deref_mut()
- .ok_or(Error::Generic("Wallet required".into()))?;
- let client = ctx.client.ok_or(Error::Generic("client required".into()))?;
+ async fn execute(
+ &self,
+ ctx: &mut AppContext<OnlineOperations<'_>>,
+ ) -> Result<Self::Output, Error> {
+ let wallet = &mut ctx.state.wallet;
+ let client = ctx.state.client;
let relay_manager = Arc::new(Mutex::new(RelayManager::new()));
let mut payjoin_manager = PayjoinManager::new(wallet, relay_manager);
use bdk_wallet::{Wallet, bitcoin::Network};
#[cfg(feature = "repl")]
-use crate::handlers::{AppCommand, AppContext};
-use crate::utils::output::FormatOutput;
+use crate::handlers::AppCommand;
+#[cfg(feature = "repl")]
+use crate::{handlers::AppContext, utils::output::FormatOutput};
-#[cfg(feature = "sqlite")]
+#[cfg(feature = "repl")]
use crate::commands::ReplSubCommand;
use clap::Parser;
+
+#[cfg(any(
+ feature = "electrum",
+ feature = "esplora",
+ feature = "rpc",
+ feature = "cbf"
+))]
+use crate::client::BlockchainClient;
#[cfg(feature = "repl")]
use std::io::Write;
use {
pub(crate) async fn respond(
network: Network,
wallet: &mut Wallet,
+ #[cfg(any(
+ feature = "electrum",
+ feature = "esplora",
+ feature = "rpc",
+ feature = "cbf"
+ ))]
+ client: Option<&BlockchainClient>,
line: &str,
datadir: std::path::PathBuf,
- cli_opts: &CliOpts,
+ _cli_opts: &CliOpts,
) -> Result<bool, String> {
let args = shlex::split(line).ok_or("error: Invalid quoting".to_string())?;
}
};
- let mut ctx = AppContext::new(network, datadir.clone()).with_wallet(&mut *wallet);
-
let response = match repl_subcommand {
ReplSubCommand::Wallet { subcommand } => match subcommand {
WalletSubCommand::OfflineWalletSubCommand(cmd) => {
- cmd.execute(&mut ctx).map_err(|e| e.to_string())?;
+ let mut ctx = AppContext::new_offline_wallet(network, datadir, wallet);
+ cmd.execute(&mut ctx)
+ .map_err(|e| e.to_string())?
+ .write_out(std::io::stdout())
+ .map_err(|e| e.to_string())?;
Some(())
}
#[cfg(any(
feature = "rpc"
))]
WalletSubCommand::OnlineWalletSubCommand(cmd) => {
- let value = cmd.execute(&mut ctx).await.map_err(|e| e.to_string())?;
+ let client_ref = client.ok_or("Online commands require a client.".to_string())?;
+ let mut ctx = AppContext::new_online_wallet(network, datadir, wallet, client_ref);
+
+ cmd.execute(&mut ctx)
+ .await
+ .map_err(|e| e.to_string())?
+ .write_out(std::io::stdout())
+ .map_err(|e| e.to_string())?;
Some(())
- // Some(value)
}
WalletSubCommand::Config(config_cmd) => {
let mut ctx = AppContext::new(network, datadir);
- let _ = config_cmd
+ config_cmd
.execute(&mut ctx)
.map_err(|e| e.to_string())?
- .write_out(std::io::stdout());
+ .write_out(std::io::stdout())
+ .map_err(|e| e.to_string())?;
Some(())
}
},
- // Assuming your REPL Descriptor command is an inline struct based on commands.rs
ReplSubCommand::Descriptor(cmd) => {
- let value = cmd
- .execute(&mut ctx)
+ let mut ctx = AppContext::new(network, datadir);
+ cmd.execute(&mut ctx)
.map_err(|e| e.to_string())?
- .write_out(std::io::stdout());
+ .write_out(std::io::stdout())
+ .map_err(|e| e.to_string())?;
+ Some(())
+ }
+
+ ReplSubCommand::Key { subcommand } => {
+ let mut ctx = AppContext::new(network, datadir);
+ subcommand.execute(&mut ctx).map_err(|e| e.to_string())?;
Some(())
}
ReplSubCommand::Exit => None,
- _ => todo!(),
+ // _ => todo!(), // Handled specifically depending on your ReplSubCommand definitions
};
- if let Some(value) = response {
- // writeln!(std::io::stdout(), "{value}").map_err(|e| e.to_string())?;
+ if response.is_some() {
std::io::stdout().flush().map_err(|e| e.to_string())?;
Ok(false)
} else {