Skip to content

Commit 5198a46

Browse files
authored
Merge pull request #29 from Ximik/listtransactions
CLI listtransactions command
2 parents f664298 + b8dada2 commit 5198a46

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

node/src/bin/space-cli.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ enum Commands {
196196
#[arg(long, short)]
197197
fee_rate: Option<u64>,
198198
},
199+
/// List last transactions
200+
#[command(name = "listtransactions")]
201+
ListTransactions {
202+
#[arg(default_value = "10")]
203+
count: usize,
204+
#[arg(default_value = "0")]
205+
skip: usize,
206+
},
199207
/// List won spaces including ones
200208
/// still in auction with a winning bid
201209
#[command(name = "listspaces")]
@@ -535,6 +543,13 @@ async fn handle_commands(
535543
let spaces = cli.client.wallet_list_bidouts(&cli.wallet).await?;
536544
println!("{}", serde_json::to_string_pretty(&spaces)?);
537545
}
546+
Commands::ListTransactions { count, skip } => {
547+
let txs = cli
548+
.client
549+
.wallet_list_transactions(&cli.wallet, count, skip)
550+
.await?;
551+
println!("{}", serde_json::to_string_pretty(&txs)?);
552+
}
538553
Commands::ListSpaces => {
539554
let spaces = cli.client.wallet_list_spaces(&cli.wallet).await?;
540555
println!("{}", serde_json::to_string_pretty(&spaces)?);

node/src/rpc.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ use crate::{
4444
source::BitcoinRpc,
4545
store::{ChainState, LiveSnapshot, RolloutEntry, Sha256},
4646
wallets::{
47-
AddressKind, Balance, RpcWallet, TxResponse, WalletCommand, WalletOutput, WalletResponse,
47+
AddressKind, Balance, RpcWallet, TxInfo, TxResponse, WalletCommand, WalletOutput,
48+
WalletResponse,
4849
},
4950
};
5051

@@ -168,6 +169,14 @@ pub trait Rpc {
168169
fee_rate: FeeRate,
169170
) -> Result<Vec<TxResponse>, ErrorObjectOwned>;
170171

172+
#[method(name = "walletlisttransactions")]
173+
async fn wallet_list_transactions(
174+
&self,
175+
wallet: &str,
176+
count: usize,
177+
skip: usize,
178+
) -> Result<Vec<TxInfo>, ErrorObjectOwned>;
179+
171180
#[method(name = "walletforcespend")]
172181
async fn wallet_force_spend(
173182
&self,
@@ -729,6 +738,19 @@ impl RpcServer for RpcServerImpl {
729738
.map_err(|error| ErrorObjectOwned::owned(-1, error.to_string(), None::<String>))
730739
}
731740

741+
async fn wallet_list_transactions(
742+
&self,
743+
wallet: &str,
744+
count: usize,
745+
skip: usize,
746+
) -> Result<Vec<TxInfo>, ErrorObjectOwned> {
747+
self.wallet(&wallet)
748+
.await?
749+
.send_list_transactions(count, skip)
750+
.await
751+
.map_err(|error| ErrorObjectOwned::owned(-1, error.to_string(), None::<String>))
752+
}
753+
732754
async fn wallet_force_spend(
733755
&self,
734756
wallet: &str,

node/src/wallets.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ pub struct TxResponse {
5656
pub raw: Option<String>,
5757
}
5858

59+
#[derive(Debug, Clone, Serialize, Deserialize)]
60+
pub struct TxInfo {
61+
pub txid: Txid,
62+
pub confirmed: bool,
63+
pub sent: Amount,
64+
pub received: Amount,
65+
pub fee: Option<Amount>,
66+
}
67+
5968
#[derive(Debug, Clone, Serialize, Deserialize)]
6069
pub struct WalletResponse {
6170
pub result: Vec<TxResponse>,
@@ -86,6 +95,11 @@ pub enum WalletCommand {
8695
fee_rate: FeeRate,
8796
resp: crate::rpc::Responder<anyhow::Result<Vec<TxResponse>>>,
8897
},
98+
ListTransactions {
99+
count: usize,
100+
skip: usize,
101+
resp: crate::rpc::Responder<anyhow::Result<Vec<TxInfo>>>,
102+
},
89103
ListSpaces {
90104
resp: crate::rpc::Responder<anyhow::Result<Vec<WalletOutput>>>,
91105
},
@@ -291,6 +305,10 @@ impl RpcWallet {
291305
WalletCommand::ListUnspent { resp } => {
292306
_ = resp.send(Self::list_unspent(wallet, state));
293307
}
308+
WalletCommand::ListTransactions { count, skip, resp } => {
309+
let transactions = Self::list_transactions(wallet, count, skip);
310+
_ = resp.send(transactions);
311+
}
294312
WalletCommand::ListSpaces { resp } => {
295313
let result = Self::list_unspent(wallet, state);
296314
match result {
@@ -448,6 +466,36 @@ impl RpcWallet {
448466
Ok(SpacesAwareCoinSelection::new(excluded, confirmed_only))
449467
}
450468

469+
fn list_transactions(
470+
wallet: &mut SpacesWallet,
471+
count: usize,
472+
skip: usize,
473+
) -> anyhow::Result<Vec<TxInfo>> {
474+
let mut transactions: Vec<_> = wallet.spaces.transactions().collect();
475+
transactions.sort();
476+
477+
Ok(transactions
478+
.iter()
479+
.rev()
480+
.skip(skip)
481+
.take(count)
482+
.map(|ctx| {
483+
let tx = ctx.tx_node.tx.clone();
484+
let txid = ctx.tx_node.txid.clone();
485+
let confirmed = ctx.chain_position.is_confirmed();
486+
let (sent, received) = wallet.spaces.sent_and_received(&tx);
487+
let fee = wallet.spaces.calculate_fee(&tx).ok();
488+
TxInfo {
489+
txid,
490+
confirmed,
491+
sent,
492+
received,
493+
fee,
494+
}
495+
})
496+
.collect())
497+
}
498+
451499
fn list_unspent(
452500
wallet: &mut SpacesWallet,
453501
store: &mut LiveSnapshot,
@@ -884,6 +932,18 @@ impl RpcWallet {
884932
resp_rx.await?
885933
}
886934

935+
pub async fn send_list_transactions(
936+
&self,
937+
count: usize,
938+
skip: usize,
939+
) -> anyhow::Result<Vec<TxInfo>> {
940+
let (resp, resp_rx) = oneshot::channel();
941+
self.sender
942+
.send(WalletCommand::ListTransactions { count, skip, resp })
943+
.await?;
944+
resp_rx.await?
945+
}
946+
887947
pub async fn send_force_spend(
888948
&self,
889949
outpoint: OutPoint,

wallet/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ impl SpacesWallet {
159159
}
160160

161161
pub fn get_info(&self) -> WalletInfo {
162-
let mut descriptors = Vec::with_capacity(4);
162+
let mut descriptors = Vec::with_capacity(2);
163163

164164
descriptors.push(DescriptorInfo {
165165
descriptor: self

0 commit comments

Comments
 (0)