diff --git a/src/subcommand/wallet.rs b/src/subcommand/wallet.rs index a7ad5ad9b3..3180b4d6bc 100644 --- a/src/subcommand/wallet.rs +++ b/src/subcommand/wallet.rs @@ -15,6 +15,7 @@ pub mod inscriptions; mod label; pub mod mint; pub mod outputs; +pub mod pending; pub mod receive; pub mod restore; pub mod resume; @@ -48,8 +49,6 @@ pub(crate) enum Subcommand { Batch(batch_command::Batch), #[command(about = "List unspent cardinal outputs in wallet")] Cardinals, - #[command(about = "List unspent runic outputs in wallet")] - Runics, #[command(about = "Create new wallet")] Create(create::Create), #[command(about = "Dump wallet descriptors")] @@ -64,12 +63,16 @@ pub(crate) enum Subcommand { Mint(mint::Mint), #[command(about = "List all unspent outputs in wallet")] Outputs, + #[command(about = "List pending etchings")] + Pending(pending::Pending), #[command(about = "Generate receive address")] Receive(receive::Receive), #[command(about = "Restore wallet")] Restore(restore::Restore), #[command(about = "Resume pending etchings")] Resume(resume::Resume), + #[command(about = "List unspent runic outputs in wallet")] + Runics, #[command(about = "List wallet satoshis")] Sats(sats::Sats), #[command(about = "Send sat or inscription")] @@ -104,7 +107,6 @@ impl WalletCommand { Subcommand::Balance => balance::run(wallet), Subcommand::Batch(batch) => batch.run(wallet), Subcommand::Cardinals => cardinals::run(wallet), - Subcommand::Runics => runics::run(wallet), Subcommand::Create(_) | Subcommand::Restore(_) => unreachable!(), Subcommand::Dump => dump::run(wallet), Subcommand::Inscribe(inscribe) => inscribe.run(wallet), @@ -112,8 +114,10 @@ impl WalletCommand { Subcommand::Label => label::run(wallet), Subcommand::Mint(mint) => mint.run(wallet), Subcommand::Outputs => outputs::run(wallet), + Subcommand::Pending(pending) => pending.run(wallet), Subcommand::Receive(receive) => receive.run(wallet), Subcommand::Resume(resume) => resume.run(wallet), + Subcommand::Runics => runics::run(wallet), Subcommand::Sats(sats) => sats.run(wallet), Subcommand::Send(send) => send.run(wallet), Subcommand::Transactions(transactions) => transactions.run(wallet), diff --git a/src/subcommand/wallet/pending.rs b/src/subcommand/wallet/pending.rs new file mode 100644 index 0000000000..5eeeaa7e88 --- /dev/null +++ b/src/subcommand/wallet/pending.rs @@ -0,0 +1,28 @@ +use super::*; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +pub struct PendingOutput { + pub commit: Txid, + pub rune: SpacedRune, +} +#[derive(Debug, Parser)] +pub(crate) struct Pending {} + +impl Pending { + pub(crate) fn run(self, wallet: Wallet) -> SubcommandResult { + let etchings = wallet + .pending_etchings()? + .into_iter() + .map(|(_, entry)| { + let spaced_rune = entry.output.rune.unwrap().rune; + + PendingOutput { + rune: spaced_rune, + commit: entry.commit.txid(), + } + }) + .collect::>(); + + Ok(Some(Box::new(etchings) as Box)) + } +} diff --git a/tests/wallet.rs b/tests/wallet.rs index a77e7ba92e..efa75d628e 100644 --- a/tests/wallet.rs +++ b/tests/wallet.rs @@ -11,6 +11,8 @@ mod inscriptions; mod label; mod mint; mod outputs; +#[cfg(unix)] +mod pending; mod receive; mod restore; #[cfg(unix)] diff --git a/tests/wallet/pending.rs b/tests/wallet/pending.rs new file mode 100644 index 0000000000..24f5f6965b --- /dev/null +++ b/tests/wallet/pending.rs @@ -0,0 +1,90 @@ +use { + super::*, + nix::{ + sys::signal::{self, Signal}, + unistd::Pid, + }, +}; + +#[test] +fn wallet_pending() { + let core = mockcore::builder().network(Network::Regtest).build(); + let ord = TestServer::spawn_with_server_args(&core, &["--regtest", "--index-runes"], &[]); + + create_wallet(&core, &ord); + + core.mine_blocks(1); + + let batchfile = batch::File { + etching: Some(batch::Etching { + divisibility: 0, + rune: SpacedRune { + rune: Rune(RUNE), + spacers: 0, + }, + supply: "1000".parse().unwrap(), + premine: "1000".parse().unwrap(), + symbol: '¢', + ..default() + }), + inscriptions: vec![batch::Entry { + file: Some("inscription.jpeg".into()), + ..default() + }], + ..default() + }; + + let tempdir = Arc::new(TempDir::new().unwrap()); + + { + let mut spawn = + CommandBuilder::new("--regtest --index-runes wallet batch --fee-rate 0 --batch batch.yaml") + .temp_dir(tempdir.clone()) + .write("batch.yaml", serde_yaml::to_string(&batchfile).unwrap()) + .write("inscription.jpeg", "inscription") + .core(&core) + .ord(&ord) + .expected_exit_code(1) + .spawn(); + + let mut buffer = String::new(); + + BufReader::new(spawn.child.stderr.as_mut().unwrap()) + .read_line(&mut buffer) + .unwrap(); + + assert_regex_match!( + buffer, + "Waiting for rune AAAAAAAAAAAAA commitment [[:xdigit:]]{64} to mature…\n" + ); + + core.mine_blocks(1); + + signal::kill( + Pid::from_raw(spawn.child.id().try_into().unwrap()), + Signal::SIGINT, + ) + .unwrap(); + + buffer.clear(); + + BufReader::new(spawn.child.stderr.as_mut().unwrap()) + .read_line(&mut buffer) + .unwrap(); + + assert_eq!( + buffer, + "Shutting down gracefully. Press again to shutdown immediately.\n" + ); + + spawn.child.wait().unwrap(); + } + + let output = CommandBuilder::new("--regtest --index-runes wallet pending") + .temp_dir(tempdir) + .core(&core) + .ord(&ord) + .run_and_deserialize_output::>(); + + assert_eq!(output.first().unwrap().rune.rune, Rune(RUNE)); +}