feat: add list addresses method to gui daemon interface

This commit is contained in:
Michael Mallan 2025-05-05 16:21:13 +01:00
parent 619ea6923f
commit 8b8b48142f
No known key found for this signature in database
GPG Key ID: 5177CDCEDB0EABEB
7 changed files with 124 additions and 7 deletions

View File

@ -13,7 +13,9 @@ use tracing::{error, info};
pub mod error;
pub mod jsonrpc;
use liana::miniscript::bitcoin::{address, psbt::Psbt, Address, Network, OutPoint, Txid};
use liana::miniscript::bitcoin::{
address, bip32::ChildNumber, psbt::Psbt, Address, Network, OutPoint, Txid,
};
use lianad::{
commands::{CoinStatus, CreateRecoveryResult, LabelItem},
config::Config,
@ -87,6 +89,24 @@ impl<C: Client + Send + Sync + Debug> Daemon for Lianad<C> {
self.call("getnewaddress", Option::<Request>::None)
}
async fn list_revealed_addresses(
&self,
is_change: bool,
exclude_used: bool,
limit: usize,
start_index: Option<ChildNumber>,
) -> Result<ListRevealedAddressesResult, DaemonError> {
self.call(
"listrevealedaddresses",
Some(vec![
json!(is_change),
json!(exclude_used),
json!(limit),
json!(start_index), // a `null` argument is parsed as `None` by the command
]),
)
}
async fn update_deriv_indexes(
&self,
receive: Option<u32>,

View File

@ -6,7 +6,9 @@ use tokio::sync::Mutex;
use super::{model::*, node, Daemon, DaemonBackend, DaemonError};
use crate::dir::LianaDirectory;
use async_trait::async_trait;
use liana::miniscript::bitcoin::{address, psbt::Psbt, Address, Network, OutPoint, Txid};
use liana::miniscript::bitcoin::{
address, bip32::ChildNumber, psbt::Psbt, Address, Network, OutPoint, Txid,
};
use lianad::{
commands::{CoinStatus, LabelItem},
config::Config,
@ -103,6 +105,21 @@ impl Daemon for EmbeddedDaemon {
self.command(|daemon| Ok(daemon.get_new_address())).await
}
async fn list_revealed_addresses(
&self,
is_change: bool,
exclude_used: bool,
limit: usize,
start_index: Option<ChildNumber>,
) -> Result<ListRevealedAddressesResult, DaemonError> {
self.command(|daemon| {
daemon
.list_revealed_addresses(is_change, exclude_used, limit, start_index)
.map_err(|e| DaemonError::Unexpected(e.to_string()))
})
.await
}
async fn update_deriv_indexes(
&self,
receive: Option<u32>,

View File

@ -11,7 +11,10 @@ use std::iter::FromIterator;
use async_trait::async_trait;
use liana::miniscript::bitcoin::{
address, bip32::Fingerprint, psbt::Psbt, secp256k1, Address, Network, OutPoint, Txid,
address,
bip32::{ChildNumber, Fingerprint},
psbt::Psbt,
secp256k1, Address, Network, OutPoint, Txid,
};
use lianad::bip329::Labels;
use lianad::commands::UpdateDerivIndexesResult;
@ -104,6 +107,13 @@ pub trait Daemon: Debug {
async fn stop(&self) -> Result<(), DaemonError>;
async fn get_info(&self) -> Result<model::GetInfoResult, DaemonError>;
async fn get_new_address(&self) -> Result<model::GetAddressResult, DaemonError>;
async fn list_revealed_addresses(
&self,
is_change: bool,
exclude_used: bool,
limit: usize,
start_index: Option<ChildNumber>,
) -> Result<model::ListRevealedAddressesResult, DaemonError>;
async fn update_deriv_indexes(
&self,
receive: Option<u32>,

View File

@ -12,7 +12,8 @@ pub use liana::{
};
pub use lianad::commands::{
CreateSpendResult, GetAddressResult, GetInfoResult, GetLabelsResult, LabelItem, ListCoinsEntry,
ListCoinsResult, ListSpendEntry, ListSpendResult, ListTransactionsResult, TransactionInfo,
ListCoinsResult, ListRevealedAddressesEntry, ListRevealedAddressesResult, ListSpendEntry,
ListSpendResult, ListTransactionsResult, TransactionInfo,
};
pub type Coin = ListCoinsEntry;

View File

@ -347,6 +347,21 @@ pub struct Address {
pub derivation_index: bip32::ChildNumber,
}
#[derive(Deserialize)]
pub struct RevealedAddress {
#[serde(deserialize_with = "deser_addr_assume_checked")]
pub address: bitcoin::Address,
pub derivation_index: bip32::ChildNumber,
pub label: Option<String>,
pub used_count: u32,
}
#[derive(Deserialize)]
pub struct ListRevealedAddresses {
pub addresses: Vec<RevealedAddress>,
pub continue_from: Option<bip32::ChildNumber>,
}
pub mod payload {
use liana::{descriptors::LianaDescriptor, miniscript::bitcoin};
use serde::{Serialize, Serializer};

View File

@ -9,7 +9,9 @@ use async_trait::async_trait;
use chrono::Utc;
use liana::{
descriptors::LianaDescriptor,
miniscript::bitcoin::{address, psbt::Psbt, Address, Network, OutPoint, Txid},
miniscript::bitcoin::{
address, bip32::ChildNumber, psbt::Psbt, Address, Network, OutPoint, Txid,
},
};
use lianad::{
bip329::Labels,
@ -610,6 +612,57 @@ impl Daemon for BackendWalletClient {
})
}
async fn list_revealed_addresses(
&self,
is_change: bool,
exclude_used: bool,
limit: usize,
start_index: Option<ChildNumber>,
) -> Result<ListRevealedAddressesResult, DaemonError> {
let mut query = Vec::<(&str, String)>::new();
query.push(("is_change_address", is_change.to_string()));
query.push(("exclude_used", exclude_used.to_string()));
query.push(("limit", limit.to_string()));
if let Some(start) = start_index {
query.push(("start_derivation_index", start.to_string()));
}
let response: Response = self
.inner
.request(
Method::GET,
&format!(
"{}/v1/wallets/{}/addresses",
self.inner.url, self.wallet_uuid
),
)
.await
.query(&query)
.send()
.await?;
if !response.status().is_success() {
return Err(DaemonError::Http(
Some(response.status().into()),
response.text().await?,
));
}
let res: api::ListRevealedAddresses = response.json().await?;
Ok(ListRevealedAddressesResult {
addresses: res
.addresses
.into_iter()
.map(|addr| ListRevealedAddressesEntry {
index: addr.derivation_index,
address: addr.address,
label: addr.label,
used_count: addr.used_count,
})
.collect(),
continue_from: res.continue_from,
})
}
async fn update_deriv_indexes(
&self,
_receive: Option<u32>,

View File

@ -1412,11 +1412,12 @@ impl ListAddressesResult {
}
/// A revealed address entry in the list returned by [`DaemonControl::list_revealed_addresses`].
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ListRevealedAddressesEntry {
/// The address's derivation index.
pub index: ChildNumber,
/// The address.
#[serde(deserialize_with = "deser_addr_assume_checked")]
pub address: bitcoin::Address,
/// Label assigned to the address, if any.
pub label: Option<String>,
@ -1428,7 +1429,7 @@ pub struct ListRevealedAddressesEntry {
}
/// Result of a [`DaemonControl::list_revealed_addresses`] request.
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ListRevealedAddressesResult {
/// Revealed addresses in order of descending derivation index.
pub addresses: Vec<ListRevealedAddressesEntry>,