diff --git a/src/index.rs b/src/index.rs index 97ffad7b93..29d87d7694 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1522,6 +1522,23 @@ impl Index { ) } + pub fn get_inscriptions_for_outputs( + &self, + outpoints: &Vec, + ) -> Result> { + let mut inscriptions = Vec::new(); + for outpoint in outpoints { + inscriptions.extend( + self + .get_inscriptions_on_output_with_satpoints(*outpoint)? + .iter() + .map(|(_satpoint, inscription_id)| *inscription_id), + ); + } + + Ok(inscriptions) + } + pub fn get_transaction(&self, txid: Txid) -> Result> { if txid == self.genesis_block_coinbase_txid { return Ok(Some(self.genesis_block_coinbase_transaction.clone())); diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index ac47d929a8..d2ac36e0ed 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -864,6 +864,8 @@ impl Server { let sat_balance = index.get_sat_balances_for_outputs(&outputs)?; + let inscriptions = index.get_inscriptions_for_outputs(&outputs)?; + let runes_balances = index.get_aggregated_rune_balances_for_outputs(&outputs)?; Ok(if accept_json { @@ -872,6 +874,7 @@ impl Server { AddressHtml { address, outputs, + inscriptions, sat_balance, runes_balances, } diff --git a/src/templates/address.rs b/src/templates/address.rs index e55cfb1538..db4cd29003 100644 --- a/src/templates/address.rs +++ b/src/templates/address.rs @@ -4,6 +4,7 @@ use super::*; pub(crate) struct AddressHtml { pub(crate) address: Address, pub(crate) outputs: Vec, + pub(crate) inscriptions: Vec, pub(crate) sat_balance: u64, pub(crate) runes_balances: Vec<(SpacedRune, Decimal, Option)>, } @@ -25,6 +26,7 @@ mod tests { .require_network(Network::Bitcoin) .unwrap(), outputs: vec![outpoint(1), outpoint(2)], + inscriptions: vec![inscription_id(1)], sat_balance: 99, runes_balances: vec![ ( @@ -68,6 +70,13 @@ mod tests { assert_regex_match!(address_html, expected_pattern); } + #[test] + fn test_inscriptions_rendering() { + let address_html = setup(); + let expected_pattern = r#".*
inscriptions
\n\s*
.*.*
.*"#; + assert_regex_match!(address_html, expected_pattern); + } + #[test] fn test_runes_balances_rendering() { let address_html = setup(); diff --git a/templates/address.html b/templates/address.html index 08f4be235d..bca79fbf78 100644 --- a/templates/address.html +++ b/templates/address.html @@ -2,6 +2,14 @@

Address {{ self.address }}

sat balance
{{ self.sat_balance }}
+%% if !self.inscriptions.is_empty() { +
inscriptions
+
+%% for inscription in &self.inscriptions { + {{Iframe::thumbnail(*inscription)}} +%% } +
+%% }
runes balances
%% for (rune, decimal, symbol) in self.runes_balances.iter() { %% if let Some(symbol) = symbol { diff --git a/tests/server.rs b/tests/server.rs index 09067cc192..788bb8be70 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -177,6 +177,53 @@ fn address_page_shows_aggregated_runes_balance() { ); } +#[test] +fn address_page_shows_aggregated_inscriptions() { + let core = mockcore::builder().network(Network::Regtest).build(); + let ord = + TestServer::spawn_with_args(&core, &["--index-runes", "--index-addresses", "--regtest"]); + + create_wallet(&core, &ord); + + let (inscription_id_1, _reveal) = inscribe(&core, &ord); + + let address = "bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw"; + + CommandBuilder::new(format!( + "--chain regtest --index-runes wallet send --fee-rate 1 {address} {inscription_id_1}", + )) + .core(&core) + .ord(&ord) + .stdout_regex(".*") + .run_and_deserialize_output::(); + + core.mine_blocks(1); + + let (inscription_id_2, _reveal) = inscribe(&core, &ord); + + CommandBuilder::new(format!( + "--chain regtest --index-runes wallet send --fee-rate 1 {address} {inscription_id_2}", + )) + .core(&core) + .ord(&ord) + .stdout_regex(".*") + .run_and_deserialize_output::(); + + core.mine_blocks(1); + + ord.assert_response_regex( + format!("/address/{address}"), + r".* +
.* +
inscriptions
+
+ + +
.*" + , + ); +} + #[test] fn inscription_page() { let core = mockcore::spawn();