lianad: add feature to dump labels in BIP-0329 format
This commit is contained in:
parent
158651ebe7
commit
38eed1b881
809
Cargo.lock
generated
809
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@ use std::iter::FromIterator;
|
||||
use std::path::Path;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use lianad::bip329::Labels;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
@ -205,6 +206,10 @@ impl<C: Client + Send + Sync + Debug> Daemon for Lianad<C> {
|
||||
let _res: serde_json::value::Value = self.call("updatelabels", Some(vec![labels]))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_labels_bip329(&self, _offset: u32, _limit: u32) -> Result<Labels, DaemonError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use lianad::bip329::Labels;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::Path;
|
||||
use tokio::sync::Mutex;
|
||||
@ -227,4 +228,9 @@ impl Daemon for EmbeddedDaemon {
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_labels_bip329(&self, offset: u32, limit: u32) -> Result<Labels, DaemonError> {
|
||||
self.command(|daemon| Ok(daemon.get_labels_bip329(offset, limit).labels))
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ use async_trait::async_trait;
|
||||
use liana::miniscript::bitcoin::{
|
||||
address, bip32::Fingerprint, psbt::Psbt, secp256k1, Address, Network, OutPoint, Txid,
|
||||
};
|
||||
use lianad::bip329::Labels;
|
||||
use lianad::{
|
||||
commands::{CoinStatus, LabelItem, TransactionInfo},
|
||||
config::Config,
|
||||
@ -125,6 +126,7 @@ pub trait Daemon: Debug {
|
||||
&self,
|
||||
labels: &HashMap<LabelItem, Option<String>>,
|
||||
) -> Result<(), DaemonError>;
|
||||
async fn get_labels_bip329(&self, offset: u32, limit: u32) -> Result<Labels, DaemonError>;
|
||||
async fn send_wallet_invitation(&self, _email: &str) -> Result<(), DaemonError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ use liana::{
|
||||
miniscript::bitcoin::{address, psbt::Psbt, Address, Network, OutPoint, Txid},
|
||||
};
|
||||
use lianad::{
|
||||
bip329::Labels,
|
||||
commands::{CoinStatus, GetInfoDescriptors, LCSpendInfo, LabelItem},
|
||||
config::Config,
|
||||
};
|
||||
@ -1115,6 +1116,11 @@ impl Daemon for BackendWalletClient {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_labels_bip329(&self, _offset: u32, _limit: u32) -> Result<Labels, DaemonError> {
|
||||
// TODO: add an endpoint on backend
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn history_tx_from_api(value: api::Transaction, network: Network) -> HistoryTransaction {
|
||||
|
||||
@ -55,3 +55,4 @@ rusqlite = { version = "0.30", features = ["bundled", "unlock_notify"] }
|
||||
|
||||
# To talk to bitcoind
|
||||
jsonrpc = { version = "0.17", features = ["minreq_http"], default-features = false }
|
||||
bip329 = {version = "0.1.1", default-features = false }
|
||||
|
||||
@ -687,6 +687,13 @@ impl DaemonControl {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_labels_bip329(&self, offset: u32, limit: u32) -> GetLabelsBip329Result {
|
||||
let mut db_conn = self.db.connection();
|
||||
GetLabelsBip329Result {
|
||||
labels: db_conn.get_labels_bip329(offset, limit),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn list_spend(
|
||||
&self,
|
||||
txids: Option<Vec<bitcoin::Txid>>,
|
||||
@ -1184,6 +1191,11 @@ pub struct GetLabelsResult {
|
||||
pub labels: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GetLabelsBip329Result {
|
||||
pub labels: crate::bip329::Labels,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
|
||||
pub struct AddressInfo {
|
||||
index: u32,
|
||||
|
||||
@ -20,6 +20,7 @@ use std::{
|
||||
sync,
|
||||
};
|
||||
|
||||
use bip329::Labels;
|
||||
use miniscript::bitcoin::{self, bip32, psbt::Psbt, secp256k1};
|
||||
|
||||
/// Information about the wallet.
|
||||
@ -190,6 +191,9 @@ pub trait DatabaseConnection {
|
||||
&mut self,
|
||||
txids: &[bitcoin::Txid],
|
||||
) -> Vec<(bitcoin::Transaction, Option<i32>, Option<u32>)>;
|
||||
|
||||
/// Dump all labels
|
||||
fn get_labels_bip329(&mut self, offset: u32, limit: u32) -> Labels;
|
||||
}
|
||||
|
||||
impl DatabaseConnection for SqliteConn {
|
||||
@ -367,6 +371,15 @@ impl DatabaseConnection for SqliteConn {
|
||||
HashMap::from_iter(labels.into_iter().map(|label| (label.item, label.value)))
|
||||
}
|
||||
|
||||
fn get_labels_bip329(&mut self, offset: u32, limit: u32) -> Labels {
|
||||
let labels = self
|
||||
.labels_bip329(offset, limit)
|
||||
.into_iter()
|
||||
.map(|l| l.into())
|
||||
.collect();
|
||||
Labels::new(labels)
|
||||
}
|
||||
|
||||
fn rollback_tip(&mut self, new_tip: &BlockChainTip) {
|
||||
self.rollback_tip(new_tip)
|
||||
}
|
||||
|
||||
@ -678,6 +678,18 @@ impl SqliteConn {
|
||||
.expect("Db must not fail")
|
||||
}
|
||||
|
||||
pub fn labels_bip329(&mut self, offset: u32, limit: u32) -> Vec<DbLabel> {
|
||||
db_query(
|
||||
&mut self.conn,
|
||||
"SELECT * FROM labels \
|
||||
ORDER BY id \
|
||||
LIMIT ?1 OFFSET ?2",
|
||||
rusqlite::params![limit, offset],
|
||||
|row| row.try_into(),
|
||||
)
|
||||
.expect("Db must not fail")
|
||||
}
|
||||
|
||||
/// Retrieves a limited and ordered list of transactions ids that happened during the given
|
||||
/// range.
|
||||
pub fn db_list_txids(&mut self, start: u32, end: u32, limit: u64) -> Vec<bitcoin::Txid> {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use bip329::Label;
|
||||
use liana::descriptors::LianaDescriptor;
|
||||
|
||||
use std::{convert::TryFrom, str::FromStr};
|
||||
@ -366,6 +367,31 @@ impl From<i64> for DbLabelledKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DbLabel> for Label {
|
||||
fn from(value: DbLabel) -> Self {
|
||||
let ref_ = value.item;
|
||||
let label = if value.value.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(value.value)
|
||||
};
|
||||
match value.item_kind {
|
||||
DbLabelledKind::Address => Label::Address(bip329::AddressRecord { ref_, label }),
|
||||
DbLabelledKind::OutPoint => Label::Output(bip329::OutputRecord {
|
||||
ref_,
|
||||
label,
|
||||
spendable: None,
|
||||
}),
|
||||
DbLabelledKind::Txid => Label::Transaction(bip329::TransactionRecord {
|
||||
ref_,
|
||||
label,
|
||||
// FIXME: "Optional key origin information referencing the wallet associated with the label"
|
||||
origin: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&rusqlite::Row<'_>> for DbLabel {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
|
||||
@ -364,6 +364,22 @@ fn get_labels(control: &DaemonControl, params: Params) -> Result<serde_json::Val
|
||||
Ok(serde_json::json!(control.get_labels(&items)))
|
||||
}
|
||||
|
||||
fn get_labels_bip329(control: &DaemonControl, params: Params) -> Result<serde_json::Value, Error> {
|
||||
let offset: u32 = params
|
||||
.get(0, "offset")
|
||||
.ok_or_else(|| Error::invalid_params("Missing 'offset' parameter."))?
|
||||
.as_u64()
|
||||
.and_then(|t| t.try_into().ok())
|
||||
.ok_or_else(|| Error::invalid_params("Invalid 'offset' parameter."))?;
|
||||
let limit: u32 = params
|
||||
.get(1, "limit")
|
||||
.ok_or_else(|| Error::invalid_params("Missing 'limit' parameter."))?
|
||||
.as_u64()
|
||||
.and_then(|t| t.try_into().ok())
|
||||
.ok_or_else(|| Error::invalid_params("Invalid 'limit' parameter."))?;
|
||||
Ok(serde_json::json!(control.get_labels_bip329(offset, limit)))
|
||||
}
|
||||
|
||||
/// Handle an incoming JSONRPC2 request.
|
||||
pub fn handle_request(control: &mut DaemonControl, req: Request) -> Result<Response, Error> {
|
||||
let result = match req.method.as_str() {
|
||||
@ -451,6 +467,12 @@ pub fn handle_request(control: &mut DaemonControl, req: Request) -> Result<Respo
|
||||
.ok_or_else(|| Error::invalid_params("Missing 'items' parameter."))?;
|
||||
get_labels(control, params)?
|
||||
}
|
||||
"getlabelsbip329" => {
|
||||
let params = req
|
||||
.params
|
||||
.ok_or_else(|| Error::invalid_params("Missing 'offset' and 'limit' parameters."))?;
|
||||
get_labels_bip329(control, params)?
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::method_not_found());
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ mod jsonrpc;
|
||||
mod testutils;
|
||||
|
||||
pub use bdk_electrum::electrum_client;
|
||||
pub use bip329;
|
||||
use bitcoin::electrum;
|
||||
pub use miniscript;
|
||||
|
||||
|
||||
@ -523,6 +523,10 @@ impl DatabaseConnection for DummyDatabase {
|
||||
}
|
||||
wallet_txs
|
||||
}
|
||||
|
||||
fn get_labels_bip329(&mut self, _offset: u32, _limit: u32) -> bip329::Labels {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyLiana {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user