Skip to content

Commit

Permalink
Add wallet addresses (#4005)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Oct 25, 2024
1 parent 19a34e2 commit 6eebb11
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 4 deletions.
2 changes: 1 addition & 1 deletion crates/mockcore/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ impl Api for Server {
label: None,
redeem_script: None,
witness_script: None,
script_pub_key: ScriptBuf::new(),
script_pub_key: tx_out.script_pubkey.clone(),
amount,
confirmations: 0,
spendable: true,
Expand Down
4 changes: 4 additions & 0 deletions src/subcommand/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use {
shared_args::SharedArgs,
};

pub mod addresses;
pub mod balance;
mod batch_command;
pub mod burn;
Expand Down Expand Up @@ -43,6 +44,8 @@ pub(crate) struct WalletCommand {
#[derive(Debug, Parser)]
#[allow(clippy::large_enum_variant)]
pub(crate) enum Subcommand {
#[command(about = "Get wallet addresses")]
Addresses,
#[command(about = "Get wallet balance")]
Balance,
#[command(about = "Create inscriptions and runes")]
Expand Down Expand Up @@ -106,6 +109,7 @@ impl WalletCommand {
)?;

match self.subcommand {
Subcommand::Addresses => addresses::run(wallet),
Subcommand::Balance => balance::run(wallet),
Subcommand::Batch(batch) => batch.run(wallet),
Subcommand::Burn(burn) => burn.run(wallet),
Expand Down
59 changes: 59 additions & 0 deletions src/subcommand/wallet/addresses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use super::*;

#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub struct Output {
pub output: OutPoint,
pub amount: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub inscriptions: Option<Vec<InscriptionId>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub runes: Option<BTreeMap<SpacedRune, Decimal>>,
}

pub(crate) fn run(wallet: Wallet) -> SubcommandResult {
let mut addresses: BTreeMap<Address<NetworkUnchecked>, Vec<Output>> = BTreeMap::new();

for (output, txout) in wallet.utxos() {
let address = wallet.chain().address_from_script(&txout.script_pubkey)?;

let inscriptions = if wallet.has_inscription_index() {
Some(wallet.get_inscriptions_in_output(output))
} else {
None
};

let runes = if wallet.has_rune_index() {
Some(
wallet
.get_runes_balances_in_output(output)?
.iter()
.map(|(rune, pile)| {
(
*rune,
Decimal {
value: pile.amount,
scale: pile.divisibility,
},
)
})
.collect(),
)
} else {
None
};

let output = Output {
output: *output,
amount: txout.value.to_sat(),
inscriptions,
runes,
};

addresses
.entry(address.as_unchecked().clone())
.or_default()
.push(output);
}

Ok(Some(Box::new(addresses)))
}
1 change: 1 addition & 0 deletions tests/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;

mod addresses;
mod authentication;
mod balance;
mod batch_command;
Expand Down
76 changes: 76 additions & 0 deletions tests/wallet/addresses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use {super::*, ord::subcommand::wallet::addresses::Output};

#[test]
fn addresses() {
let core = mockcore::builder().network(Network::Regtest).build();

let ord = TestServer::spawn_with_server_args(&core, &["--regtest", "--index-runes"], &[]);

create_wallet(&core, &ord);

let rune = Rune(RUNE);

let etched = batch(
&core,
&ord,
batch::File {
etching: Some(batch::Etching {
divisibility: 3,
premine: "1.111".parse().unwrap(),
rune: SpacedRune { rune, spacers: 1 },
supply: "2.222".parse().unwrap(),
symbol: '¢',
terms: Some(batch::Terms {
amount: "1.111".parse().unwrap(),
cap: 1,
..default()
}),
turbo: false,
}),
inscriptions: vec![batch::Entry {
file: Some("inscription.jpeg".into()),
..default()
}],
..default()
},
);

let output = CommandBuilder::new("--regtest --index-runes wallet addresses")
.core(&core)
.ord(&ord)
.run_and_deserialize_output::<BTreeMap<Address<NetworkUnchecked>, Vec<Output>>>();

pretty_assert_eq!(
output
.get(&etched.output.rune.clone().unwrap().destination.unwrap())
.unwrap(),
&vec![Output {
output: etched.output.rune.unwrap().location.unwrap(),
amount: 10000,
inscriptions: Some(Vec::new()),
runes: Some(
vec![(
SpacedRune { rune, spacers: 1 },
ord::decimal::Decimal {
value: 1111,
scale: 3,
}
)]
.into_iter()
.collect()
),
}]
);

pretty_assert_eq!(
output
.get(&etched.output.inscriptions[0].destination)
.unwrap(),
&vec![Output {
output: etched.output.inscriptions[0].location.outpoint,
amount: 10000,
inscriptions: Some(vec![etched.output.inscriptions[0].id]),
runes: Some(BTreeMap::new()),
}]
);
}
6 changes: 3 additions & 3 deletions tests/wallet/outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ fn outputs_includes_runes_and_inscriptions() {
.run_and_deserialize_output::<Vec<Output>>();

assert!(output.contains(&Output {
output: etched.output.rune.unwrap().location.unwrap(),
address: None,
output: etched.output.rune.clone().unwrap().location.unwrap(),
address: etched.output.rune.unwrap().destination,
amount: 10000,
inscriptions: Some(Vec::new()),
runes: Some(
Expand All @@ -156,7 +156,7 @@ fn outputs_includes_runes_and_inscriptions() {

assert!(output.contains(&Output {
output: etched.output.inscriptions[0].location.outpoint,
address: None,
address: Some(etched.output.inscriptions[0].destination.clone()),
amount: 10000,
inscriptions: Some(vec![etched.output.inscriptions[0].id]),
runes: Some(BTreeMap::new()),
Expand Down

0 comments on commit 6eebb11

Please sign in to comment.