diff --git a/src/subcommand/wallet.rs b/src/subcommand/wallet.rs index bd15307786..914805d5af 100644 --- a/src/subcommand/wallet.rs +++ b/src/subcommand/wallet.rs @@ -15,6 +15,7 @@ use { }; pub mod balance; +pub mod cardinals; pub mod create; pub(crate) mod inscribe; pub mod inscriptions; @@ -46,8 +47,10 @@ pub(crate) enum Wallet { Send(send::Send), #[clap(about = "See wallet transactions")] Transactions(transactions::Transactions), - #[clap(about = "List wallet outputs")] + #[clap(about = "List all unspent outputs in wallet")] Outputs, + #[clap(about = "List unspent cardinal outputs in wallet")] + Cardinals, } impl Wallet { @@ -63,6 +66,7 @@ impl Wallet { Self::Send(send) => send.run(options), Self::Transactions(transactions) => transactions.run(options), Self::Outputs => outputs::run(options), + Self::Cardinals => cardinals::run(options), } } } diff --git a/src/subcommand/wallet/cardinals.rs b/src/subcommand/wallet/cardinals.rs new file mode 100644 index 0000000000..32076229a1 --- /dev/null +++ b/src/subcommand/wallet/cardinals.rs @@ -0,0 +1,37 @@ +use {super::*, crate::wallet::Wallet, std::collections::BTreeSet}; + +#[derive(Serialize, Deserialize)] +pub struct Cardinal { + pub output: OutPoint, + pub amount: u64, +} + +pub(crate) fn run(options: Options) -> Result { + let index = Index::open(&options)?; + index.update()?; + + let inscribed_utxos = index + .get_inscriptions(None)? + .keys() + .map(|satpoint| satpoint.outpoint) + .collect::>(); + + let cardinal_utxos = index + .get_unspent_outputs(Wallet::load(&options)?)? + .iter() + .filter_map(|(output, amount)| { + if inscribed_utxos.contains(output) { + None + } else { + Some(Cardinal { + output: *output, + amount: amount.to_sat(), + }) + } + }) + .collect::>(); + + print_json(cardinal_utxos)?; + + Ok(()) +} diff --git a/tests/wallet.rs b/tests/wallet.rs index 31dc1d96a0..3e04064183 100644 --- a/tests/wallet.rs +++ b/tests/wallet.rs @@ -1,6 +1,7 @@ use super::*; mod balance; +mod cardinals; mod create; mod inscribe; mod inscriptions; diff --git a/tests/wallet/cardinals.rs b/tests/wallet/cardinals.rs new file mode 100644 index 0000000000..19053f4389 --- /dev/null +++ b/tests/wallet/cardinals.rs @@ -0,0 +1,23 @@ +use { + super::*, + ord::subcommand::wallet::{cardinals::Cardinal, outputs::Output}, +}; + +#[test] +fn cardinals() { + let rpc_server = test_bitcoincore_rpc::spawn(); + create_wallet(&rpc_server); + + // this creates 2 more cardinal outputs and one inscribed output + inscribe(&rpc_server); + + let all_outputs = CommandBuilder::new("wallet outputs") + .rpc_server(&rpc_server) + .output::>(); + + let cardinal_outputs = CommandBuilder::new("wallet cardinals") + .rpc_server(&rpc_server) + .output::>(); + + assert_eq!(all_outputs.len() - cardinal_outputs.len(), 1); +}