Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON output for wallet commands #1359

Merged
merged 9 commits into from
Jan 25, 2023
Merged
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ mod rarity;
mod representation;
mod sat;
mod sat_point;
mod subcommand;
pub mod subcommand;
mod tally;
mod templates;

Expand Down
2 changes: 1 addition & 1 deletion src/sat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::*;

#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Ord, PartialOrd, Deserialize, Serialize)]
#[serde(transparent)]
pub(crate) struct Sat(pub(crate) u64);
pub struct Sat(pub(crate) u64);

impl Sat {
pub(crate) const LAST: Self = Self(Self::SUPPLY - 1);
Expand Down
9 changes: 9 additions & 0 deletions src/sat_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ impl Serialize for SatPoint {
}
}

impl<'de> Deserialize<'de> for SatPoint {
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(DeserializeFromStr::deserialize(deserializer)?.0)
}
}

impl FromStr for SatPoint {
type Err = Error;

Expand Down
2 changes: 1 addition & 1 deletion src/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod server;
mod subsidy;
mod supply;
mod traits;
pub(crate) mod wallet;
pub mod wallet;

fn print_json(output: impl Serialize) -> Result {
serde_json::to_writer_pretty(io::stdout(), &output)?;
Expand Down
14 changes: 7 additions & 7 deletions src/subcommand/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ use {
transaction_builder::TransactionBuilder,
};

mod balance;
pub mod balance;
pub(crate) mod create;
pub(crate) mod inscribe;
mod inscriptions;
mod outputs;
mod receive;
pub mod inscriptions;
pub mod outputs;
pub mod receive;
mod restore;
mod sats;
mod send;
pub mod sats;
pub mod send;
pub(crate) mod transaction_builder;
mod transactions;
pub mod transactions;

#[derive(Debug, Parser)]
pub(crate) enum Wallet {
Expand Down
7 changes: 6 additions & 1 deletion src/subcommand/wallet/balance.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use super::*;
use std::collections::BTreeSet;

#[derive(Serialize, Deserialize)]
pub struct Output {
pub balance: u64,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
}

pub(crate) fn run(options: Options) -> Result {
let index = Index::open(&options)?;
index.update()?;
Expand All @@ -18,7 +23,7 @@ pub(crate) fn run(options: Options) -> Result {
}
}

println!("{}", balance);
print_json(&Output { balance })?;
raphjaph marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
10 changes: 5 additions & 5 deletions src/subcommand/wallet/inscriptions.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use super::*;

#[derive(Serialize)]
struct Output {
inscription: InscriptionId,
location: SatPoint,
explorer: String,
#[derive(Serialize, Deserialize)]
pub struct Output {
pub inscription: InscriptionId,
pub location: SatPoint,
pub explorer: String,
}

pub(crate) fn run(options: Options) -> Result {
Expand Down
14 changes: 13 additions & 1 deletion src/subcommand/wallet/outputs.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
use super::*;

#[derive(Serialize, Deserialize)]
pub struct Output {
pub outpoint: OutPoint,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
pub amount: u64,
}

pub(crate) fn run(options: Options) -> Result {
let mut output = Vec::new();
for (outpoint, amount) in get_unspent_outputs(&options)? {
println!("{outpoint}\t{}", amount.to_sat());
output.push(Output {
outpoint,
amount: amount.to_sat(),
});
}

print_json(&output)?;
raphjaph marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
7 changes: 6 additions & 1 deletion src/subcommand/wallet/receive.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use super::*;

#[derive(Deserialize, Serialize)]
pub struct Output {
pub address: Address,
}

pub(crate) fn run(options: Options) -> Result {
let address = options
.bitcoin_rpc_client_for_wallet_command(false)?
.get_new_address(None, Some(bitcoincore_rpc::json::AddressType::Bech32m))?;

println!("{}", address);
print_json(&Output { address })?;
raphjaph marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
34 changes: 30 additions & 4 deletions src/subcommand/wallet/sats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ pub(crate) struct Sats {
tsv: Option<PathBuf>,
}

#[derive(Serialize, Deserialize)]
pub struct OutputExoticSats {
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
pub sat: String,
pub outpoint: OutPoint,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Serialize, Deserialize)]
pub struct OutputRareSats {
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
pub sat: Sat,
pub outpoint: OutPoint,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
pub offset: u64,
pub rarity: String,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
}

impl Sats {
pub(crate) fn run(&self, options: Options) -> Result {
let index = Index::open(&options)?;
Expand All @@ -17,17 +31,29 @@ impl Sats {
let utxos = get_unspent_output_ranges(&options, &index)?;

if let Some(path) = &self.tsv {
for (output, sat) in sats_from_tsv(
let mut output = Vec::new();
for (outpoint, sat) in sats_from_tsv(
utxos,
&fs::read_to_string(path)
.with_context(|| format!("I/O error reading `{}`", path.display()))?,
)? {
println!("{output}\t{sat}");
output.push(OutputExoticSats {
sat: sat.to_string(),
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
outpoint,
});
}
print_json(&output)?;
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
} else {
for (output, sat, offset, rarity) in rare_sats(utxos) {
println!("{output}\t{sat}\t{offset}\t{rarity}");
let mut output = Vec::new();
for (outpoint, sat, offset, rarity) in rare_sats(utxos) {
output.push(OutputRareSats {
sat,
outpoint,
offset,
rarity: rarity.to_string(),
});
}
print_json(&output)?;
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
}

Ok(())
Expand Down
7 changes: 6 additions & 1 deletion src/subcommand/wallet/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ pub(crate) struct Send {
fee_rate: FeeRate,
}

#[derive(Serialize, Deserialize)]
pub struct Output {
pub txid: Txid,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
}

impl Send {
pub(crate) fn run(self, options: Options) -> Result {
let client = options.bitcoin_rpc_client_for_wallet_command(false)?;
Expand Down Expand Up @@ -62,7 +67,7 @@ impl Send {
let txid =
client.send_to_address(&self.address, amount, None, None, None, None, None, None)?;

println!("{txid}");
print_json(&Output { txid })?;
raphjaph marked this conversation as resolved.
Show resolved Hide resolved

return Ok(());
}
Expand Down
14 changes: 13 additions & 1 deletion src/subcommand/wallet/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ pub(crate) struct Transactions {
limit: Option<u16>,
}

#[derive(Serialize, Deserialize)]
pub struct Output {
pub txid: Txid,
raphjaph marked this conversation as resolved.
Show resolved Hide resolved
pub confirmations: i32,
}

impl Transactions {
pub(crate) fn run(self, options: Options) -> Result {
let mut output = Vec::new();
for tx in options
.bitcoin_rpc_client_for_wallet_command(false)?
.list_transactions(
Expand All @@ -17,9 +24,14 @@ impl Transactions {
None,
)?
{
println!("{}\t{}", tx.info.txid, tx.info.confirmations);
output.push(Output {
txid: tx.info.txid,
confirmations: tx.info.confirmations,
});
}

print_json(&output)?;

Ok(())
}
}
2 changes: 1 addition & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use {
self::{command_builder::CommandBuilder, expected::Expected, test_server::TestServer},
bip39::Mnemonic,
bitcoin::{blockdata::constants::COIN_VALUE, Address, Network, OutPoint, Txid},
bitcoin::{blockdata::constants::COIN_VALUE, Network, OutPoint, Txid},
executable_path::executable_path,
pretty_assertions::assert_eq as pretty_assert_eq,
regex::Regex,
Expand Down
46 changes: 29 additions & 17 deletions tests/wallet/balance.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,49 @@
use super::*;
use {super::*, ord::subcommand::wallet::balance::Output};

#[test]
fn wallet_balance() {
let rpc_server = test_bitcoincore_rpc::spawn();
create_wallet(&rpc_server);

CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.expected_stdout("0\n")
.run();
assert_eq!(
CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.output::<Output>()
.balance,
0
);

rpc_server.mine_blocks(1);

CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.expected_stdout("5000000000\n")
.run();
assert_eq!(
CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.output::<Output>()
.balance,
50 * COIN_VALUE
);
}

#[test]
fn wallet_balance_only_counts_cardinal_utxos() {
let rpc_server = test_bitcoincore_rpc::spawn();
create_wallet(&rpc_server);

CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.expected_stdout("0\n")
.run();
assert_eq!(
CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.output::<Output>()
.balance,
0
);

inscribe(&rpc_server);

CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.expected_stdout(format!("{}\n", 100 * COIN_VALUE - 10_000))
.run();
assert_eq!(
CommandBuilder::new("wallet balance")
.rpc_server(&rpc_server)
.output::<Output>()
.balance,
100 * COIN_VALUE - 10_000
);
}
Loading