Skip to content

Commit

Permalink
Get the on chain and off chain balance
Browse files Browse the repository at this point in the history
  • Loading branch information
ademar111190 committed Jul 7, 2023
1 parent b7e4a9e commit 2408dd6
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 58 deletions.
38 changes: 19 additions & 19 deletions libs/sdk-core/src/breez_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,50 @@ use std::time::{SystemTime, UNIX_EPOCH};

use anyhow::{anyhow, Result};
use bip39::*;
use bitcoin::hashes::{Hash, sha256};
use bitcoin::hashes::{sha256, Hash};
use bitcoin::util::bip32::ChildNumber;
use tokio::runtime::Runtime;
use tokio::sync::{mpsc, Mutex, RwLock, watch};
use tokio::time::{Duration, sleep};
use tonic::{Request, Status};
use tokio::sync::{mpsc, watch, Mutex, RwLock};
use tokio::time::{sleep, Duration};
use tonic::codegen::InterceptedService;
use tonic::metadata::{Ascii, MetadataValue};
use tonic::service::Interceptor;
use tonic::transport::{Channel, Uri};
use tonic::{Request, Status};

use crate::*;
use crate::{BuyBitcoinProvider, LnUrlAuthRequestData, LnUrlWithdrawRequestData, PaymentResponse};
use crate::backup::{BackupRequest, BackupTransport, BackupWatcher};
use crate::boltzswap::BoltzApi;
use crate::BuyBitcoinProvider::Moonpay;
use crate::chain::{ChainService, MempoolSpace, RecommendedFees};
use crate::fiat::{FiatCurrency, Rate};
use crate::greenlight::{GLBackupTransport, Greenlight};
use crate::grpc::channel_opener_client::ChannelOpenerClient;
use crate::grpc::fund_manager_client::FundManagerClient;
use crate::grpc::information_client::InformationClient;
use crate::grpc::PaymentInformation;
use crate::grpc::signer_client::SignerClient;
use crate::grpc::PaymentInformation;
use crate::input_parser::LnUrlPayRequestData;
use crate::invoice::{add_lsp_routing_hints, LNInvoice, parse_invoice, RouteHint, RouteHintHop};
use crate::invoice::{add_lsp_routing_hints, parse_invoice, LNInvoice, RouteHint, RouteHintHop};
use crate::lnurl::auth::perform_lnurl_auth;
use crate::lnurl::pay::model::SuccessAction::Aes;
use crate::lnurl::pay::model::{
LnUrlPayResult, SuccessAction, SuccessActionProcessed, ValidatedCallbackResponse,
};
use crate::lnurl::pay::model::SuccessAction::Aes;
use crate::lnurl::pay::validate_lnurl_pay;
use crate::lnurl::withdraw::validate_lnurl_withdraw;
use crate::lsp::LspInformation;
use crate::models::{
ChannelState, ClosedChannelPaymentDetails, Config, EnvironmentType, FiatAPI,
GreenlightCredentials, LnUrlCallbackStatus, LspAPI, Network, NodeAPI, NodeState, parse_short_channel_id,
parse_short_channel_id, ChannelState, ClosedChannelPaymentDetails, Config, EnvironmentType,
FiatAPI, GreenlightCredentials, LnUrlCallbackStatus, LspAPI, Network, NodeAPI, NodeState,
Payment, PaymentDetails, PaymentType, PaymentTypeFilter, ReverseSwapPairInfo,
ReverseSwapperAPI, SwapInfo, SwapperAPI,
};
use crate::moonpay::MoonPayApi;
use crate::persist::db::SqliteStorage;
use crate::reverseswap::BTCSendSwap;
use crate::swap::BTCReceiveSwap;
use crate::BuyBitcoinProvider::Moonpay;
use crate::*;
use crate::{BuyBitcoinProvider, LnUrlAuthRequestData, LnUrlWithdrawRequestData, PaymentResponse};

/// Trait that can be used to react to various [BreezEvent]s emitted by the SDK.
pub trait EventListener: Send + Sync {
Expand Down Expand Up @@ -207,7 +207,7 @@ impl BreezServices {
Some(parsed_invoice),
payment_res,
)
.await
.await
}

/// Pay directly to a node id using keysend
Expand Down Expand Up @@ -620,7 +620,7 @@ impl BreezServices {
invoice,
},
})
.await?;
.await?;
return Err(payment_res.err().unwrap());
}
let payment = payment_res.unwrap();
Expand Down Expand Up @@ -1067,7 +1067,7 @@ impl BreezServicesBuilder {
self.seed.clone().unwrap(),
self.creds.clone().unwrap(),
)
.await?;
.await?;
let gl_arc = Arc::new(greenlight);
node_api = Some(gl_arc.clone());
if backup_transport.is_none() {
Expand Down Expand Up @@ -1440,15 +1440,15 @@ pub(crate) mod tests {
use regex::Regex;
use reqwest::Url;

use crate::{
BuyBitcoinProvider, input_parser, InputType, parse_short_channel_id, test_utils::*,
};
use crate::{NodeAPI, PaymentType};
use crate::breez_services::{BreezServices, BreezServicesBuilder};
use crate::fiat::Rate;
use crate::lnurl::pay::model::MessageSuccessActionData;
use crate::lnurl::pay::model::SuccessActionProcessed;
use crate::models::{LnPaymentDetails, NodeState, Payment, PaymentDetails, PaymentTypeFilter};
use crate::{
input_parser, parse_short_channel_id, test_utils::*, BuyBitcoinProvider, InputType,
};
use crate::{NodeAPI, PaymentType};

use super::{PaymentReceiver, Receiver};

Expand Down
128 changes: 93 additions & 35 deletions libs/sdk-core/src/greenlight/node_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use gl_client::pb::cln::{
ListpeerchannelsRequest,
};
use gl_client::pb::{
Amount, Invoice, InvoiceRequest, InvoiceStatus, OffChainPayment, PayStatus, WithdrawResponse,
Amount, Invoice, InvoiceRequest, InvoiceStatus, ListPeersResponse, OffChainPayment, PayStatus,
WithdrawResponse,
};
use gl_client::pb::{ListFundsResponse, Peer};
use gl_client::scheduler::Scheduler;
Expand Down Expand Up @@ -168,12 +169,6 @@ impl NodeAPI for Greenlight {
let mut client = self.get_client().await?;
let mut node_client = self.get_node_client().await?;

// list all peers
let peers = client
.list_peers(pb::ListPeersRequest::default())
.await?
.into_inner();

// get node info
let node_info = client
.get_info(pb::GetInfoRequest::default())
Expand All @@ -182,30 +177,19 @@ impl NodeAPI for Greenlight {

// list both off chain funds and on chain fudns
let funds = self.list_funds().await?;
let offchain_funds = funds.channels;
let onchain_funds = funds.outputs;

// list all peers
let peers = self.peers().await?;

// filter only connected peers
let connected_peers: Vec<String> = peers
.peers
.clone()
.iter()
.filter(|p| p.connected)
.map(|p| hex::encode(p.id.clone()))
.collect();
let connected_peers = self.connected_peers(Some(&peers)).await?;

// make a vector of all channels by searching in peers
let all_channels: &mut Vec<pb::Channel> = &mut Vec::new();
peers.peers.clone().iter().for_each(|p| {
let peer_channels = &mut p.channels.clone();
all_channels.append(peer_channels);
});
let all_channels = self.all_channels(Some(&peers)).await?;

// filter only opened channels
let opened_channels: &mut Vec<&pb::Channel> = &mut all_channels
.iter()
.filter(|c| c.state == *"CHANNELD_NORMAL")
.collect();
let opened_channels = self.opened_channels(Some(&all_channels)).await?;

// Fetch closed channels from greenlight
let closed_channels = match node_client
Expand Down Expand Up @@ -235,16 +219,12 @@ impl NodeAPI for Greenlight {
all_channel_models.extend(forgotten_closed_channels?);

// calculate channels balance only from opened channels
let channels_balance = offchain_funds.iter().fold(0, |a, b| {
let hex_txid = hex::encode(b.funding_txid.clone());
if opened_channels.iter().any(|c| c.funding_txid == hex_txid) {
return a + b.our_amount_msat;
}
a
});
let channels_balance = self
.off_chain_balance(Some(&funds), Some(&opened_channels))
.await?;

// calculate onchain balance
let onchain_balance = self.on_chain_balance().await?;
let onchain_balance = self.on_chain_balance(Some(&funds)).await?;

// Collect utxos from onchain funds
let utxos = onchain_funds
Expand Down Expand Up @@ -396,7 +376,7 @@ impl NodeAPI for Greenlight {
outputs: vec![cln::OutputDesc {
address: to_address,
amount: Some(cln::Amount {
msat: self.on_chain_balance().await?,
msat: self.off_chain_balance(None, None).await?,
}),
}],
feerate: Some(cln::Feerate {
Expand Down Expand Up @@ -616,8 +596,11 @@ impl NodeAPI for Greenlight {
return Ok(funds);
}

async fn on_chain_balance(&self) -> Result<u64> {
let funds = self.list_funds().await?;
async fn on_chain_balance(&self, funds: Option<&ListFundsResponse>) -> Result<u64> {
let funds = match funds {
Some(f) => f,
None => &self.list_funds().await?,
};
let on_chain_balance = funds.outputs.iter().fold(0, |a, b| {
if b.reserved {
return a;
Expand All @@ -626,6 +609,81 @@ impl NodeAPI for Greenlight {
});
return Ok(on_chain_balance);
}

async fn off_chain_balance(
&self,
funds: Option<&ListFundsResponse>,
opened_channels: Option<&Vec<&pb::Channel>>,
) -> Result<u64> {
let funds = match funds {
Some(f) => f,
None => &self.list_funds().await?,
};
let opened_channels = match opened_channels {
Some(c) => c,
None => &self.opened_channels(None).await?,
};
let off_chain_balance = funds.channels.iter().fold(0, |a, b| {
let hex_txid = hex::encode(b.funding_txid.clone());
if opened_channels.iter().any(|c| c.funding_txid == hex_txid) {
return a + b.our_amount_msat;
}
a
});
return Ok(off_chain_balance);
}

async fn peers(&self) -> Result<ListPeersResponse> {
let mut client = self.get_client().await?;
let peers = client
.list_peers(pb::ListPeersRequest::default())
.await?
.into_inner();
return Ok(peers);
}

async fn connected_peers(&self, peers: Option<&ListPeersResponse>) -> Result<Vec<String>> {
let peers = match peers {
Some(p) => p,
None => &self.peers().await?,
};
let connected_peers = peers
.peers
.clone()
.iter()
.filter(|p| p.connected)
.map(|p| hex::encode(p.id.clone()))
.collect();
return Ok(connected_peers);
}

async fn all_channels(&self, peers: Option<&ListPeersResponse>) -> Result<Vec<pb::Channel>> {
let peers = match peers {
Some(p) => p,
None => &self.peers().await?,
};
let all_channels: &mut Vec<pb::Channel> = &mut Vec::new();
peers.peers.clone().iter().for_each(|p| {
let peer_channels = &mut p.channels.clone();
all_channels.append(peer_channels);
});
return Ok(all_channels.clone());
}

async fn opened_channels(
&self,
all_channels: Option<&Vec<pb::Channel>>,
) -> Result<Vec<&pb::Channel>> {
let all_channels = match all_channels {
Some(c) => c,
None => &self.all_channels(None).await?,
};
let opened_channels: &mut Vec<&pb::Channel> = &mut all_channels
.iter()
.filter(|c| c.state == *"CHANNELD_NORMAL")
.collect();
return Ok(opened_channels.clone());
}
}

#[derive(Clone, PartialEq, Eq, Debug, EnumString, Display, Deserialize, Serialize)]
Expand Down
19 changes: 17 additions & 2 deletions libs/sdk-core/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey};
use bitcoin::{Address, Script};
use gl_client::pb::Peer;
use gl_client::pb::WithdrawResponse;
use gl_client::pb::{Invoice, ListFundsResponse};
use gl_client::pb::{Invoice, ListFundsResponse, ListPeersResponse};
use lightning_invoice::RawInvoice;
use ripemd::Digest;
use ripemd::Ripemd160;
Expand Down Expand Up @@ -79,7 +79,22 @@ pub trait NodeAPI: Send + Sync {
/// Gets the private key at the path specified
fn derive_bip32_key(&self, path: Vec<ChildNumber>) -> Result<ExtendedPrivKey>;
async fn list_funds(&self) -> Result<ListFundsResponse>;
async fn on_chain_balance(&self) -> Result<u64>;
async fn on_chain_balance(&self, funds: Option<&ListFundsResponse>) -> Result<u64>;
async fn off_chain_balance(
&self,
funds: Option<&ListFundsResponse>,
opened_channels: Option<&Vec<&gl_client::pb::Channel>>,
) -> Result<u64>;
async fn peers(&self) -> Result<ListPeersResponse>;
async fn connected_peers(&self, peers: Option<&ListPeersResponse>) -> Result<Vec<String>>;
async fn all_channels(
&self,
peers: Option<&ListPeersResponse>,
) -> Result<Vec<gl_client::pb::Channel>>;
async fn opened_channels(
&self,
all_channels: Option<&Vec<gl_client::pb::Channel>>,
) -> Result<Vec<&gl_client::pb::Channel>>;
}

/// Trait covering LSP-related functionality
Expand Down
30 changes: 28 additions & 2 deletions libs/sdk-core/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey};
use bitcoin::Network;
use gl_client::pb::amount::Unit;
use gl_client::pb::{Amount, Invoice, ListFundsResponse, Peer, WithdrawResponse};
use gl_client::pb::{
Amount, Channel, Invoice, ListFundsResponse, ListPeersResponse, Peer, WithdrawResponse,
};
use lightning::ln::PaymentSecret;
use lightning_invoice::{Currency, InvoiceBuilder, RawInvoice};
use rand::distributions::{Alphanumeric, DistString, Standard};
Expand Down Expand Up @@ -361,7 +363,31 @@ impl NodeAPI for MockNodeAPI {
Err(anyhow!("Not implemented"))
}

async fn on_chain_balance(&self) -> Result<u64> {
async fn on_chain_balance(&self, funds: Option<&ListFundsResponse>) -> Result<u64> {
Err(anyhow!("Not implemented"))
}

async fn off_chain_balance(
&self,
funds: Option<&ListFundsResponse>,
opened_channels: Option<&Vec<&Channel>>,
) -> Result<u64> {
Err(anyhow!("Not implemented"))
}

async fn peers(&self) -> Result<ListPeersResponse> {
Err(anyhow!("Not implemented"))
}

async fn connected_peers(&self, peers: Option<&ListPeersResponse>) -> Result<Vec<String>> {
Err(anyhow!("Not implemented"))
}

async fn all_channels(&self, peers: Option<&ListPeersResponse>) -> Result<Vec<Channel>> {
Err(anyhow!("Not implemented"))
}

async fn opened_channels(&self, all_channels: Option<&Vec<Channel>>) -> Result<Vec<&Channel>> {
Err(anyhow!("Not implemented"))
}
}
Expand Down

0 comments on commit 2408dd6

Please sign in to comment.