diff --git a/mint-manager/src/components/channels.rs b/mint-manager/src/components/channels.rs index be68856..dc86bb1 100644 --- a/mint-manager/src/components/channels.rs +++ b/mint-manager/src/components/channels.rs @@ -1,6 +1,10 @@ +use std::collections::HashMap; + use anyhow::Result; +use bitcoin::secp256k1::PublicKey; use gloo_net::http::Request; use node_manager_types::responses::{self, ChannelInfo}; +use serde_json::Value; use url::Url; use yew::platform::spawn_local; use yew::prelude::*; @@ -36,7 +40,7 @@ enum View { pub struct Channels { view: View, channels: Vec, - peers: Vec, + peers: HashMap, } impl Component for Channels { @@ -51,7 +55,7 @@ impl Component for Channels { let url = ctx.props().url.clone(); spawn_local(async move { get_channels(&jwt, &url, channels_callback).await.ok(); - get_peers(&jwt, &url, peers_callback).await.ok(); + get_peers(&jwt, &url, peers_callback).await.unwrap(); }); Self::default() @@ -72,6 +76,10 @@ impl Component for Channels { true } Msg::FetechedPeers(peers) => { + let peers = peers.into_iter().fold(HashMap::new(), |mut acc, x| { + acc.insert(x.peer_pubkey, x); + acc + }); self.peers = peers; true } @@ -161,14 +169,16 @@ async fn get_peers( got_peers_cb: Callback>, ) -> Result<()> { let url = url.join("peers")?; - let fetched_channels: Vec = Request::get(url.as_str()) + let fetched_channels: Value = Request::get(url.as_str()) .header("Authorization", &format!("Bearer {}", jwt)) .send() .await? .json() .await?; - got_peers_cb.emit(fetched_channels); + let peers = serde_json::from_value(fetched_channels)?; + + got_peers_cb.emit(peers); Ok(()) } diff --git a/mint-manager/src/components/on_chain.rs b/mint-manager/src/components/on_chain.rs index 4ba27d1..0ae74dc 100644 --- a/mint-manager/src/components/on_chain.rs +++ b/mint-manager/src/components/on_chain.rs @@ -203,7 +203,7 @@ impl Component for OnChain { - + } } @@ -218,7 +218,7 @@ impl Component for OnChain { // - + } } diff --git a/mint-manager/src/components/open_channel.rs b/mint-manager/src/components/open_channel.rs index 1c26f50..0e2defb 100644 --- a/mint-manager/src/components/open_channel.rs +++ b/mint-manager/src/components/open_channel.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::str::FromStr; use anyhow::Result; @@ -54,7 +55,7 @@ async fn get_peers( pub struct Props { pub jwt: String, pub url: Url, - pub peers: Vec, + pub peers: HashMap, pub back_callback: Callback, } @@ -64,10 +65,16 @@ pub enum Msg { FetechedPeers(Vec), } +#[derive(Default)] +enum View { + #[default] + OpenChannel, + OpenedChannel, +} + #[derive(Default)] pub struct OpenChannel { - host_input_node_ref: NodeRef, - port_input_node_ref: NodeRef, + view: View, amount_input_node_ref: NodeRef, push_amount_input_node_ref: NodeRef, select_node_ref: NodeRef, @@ -83,7 +90,9 @@ impl Component for OpenChannel { let jwt = ctx.props().jwt.clone(); let url = ctx.props().url.clone(); spawn_local(async move { - get_peers(&jwt, &url, callback).await.unwrap(); + if let Err(err) = get_peers(&jwt, &url, callback).await { + warn!("Could not get peers: {:?}", err); + } }); Self::default() } @@ -98,16 +107,6 @@ impl Component for OpenChannel { .cast::() .map(|p| PublicKey::from_str(&p.value())); - let host = self - .host_input_node_ref - .cast::() - .map(|i| i.value()); - - let port = self - .port_input_node_ref - .cast::() - .map(|i| i.value().parse::()); - let amount = self .amount_input_node_ref .cast::() @@ -124,45 +123,52 @@ impl Component for OpenChannel { value.parse::() }); - if let ( - Some(Ok(public_key)), - Some(host), - Some(Ok(port)), - Some(Ok(amount)), - Some(Ok(push_amount)), - ) = (pubkey, host, port, amount, push_amount) + if let (Some(Ok(public_key)), Some(Ok(amount)), Some(Ok(push_amount))) = + (pubkey, amount, push_amount) { - let amount = Amount::from_sat(amount); - let push_amount = if push_amount > 0 { - Some(Amount::from_sat(push_amount)) + if let Some(peer) = ctx.props().peers.get(&public_key) { + let host = peer.host.clone(); + let port = peer.port; + + let amount = Amount::from_sat(amount); + let push_amount = if push_amount > 0 { + Some(Amount::from_sat(push_amount)) + } else { + None + }; + + let open_channel = OpenChannelRequest { + public_key, + host, + port, + amount, + push_amount, + }; + + let callback = ctx.link().callback(Msg::ChannelOpened); + let jwt = ctx.props().jwt.clone(); + let url = ctx.props().url.clone(); + + spawn_local(async move { + if let Err(err) = + post_open_channel(&jwt, &url, open_channel, callback).await + { + warn!("Failed to open channel: {:?}", err); + } + }); } else { - None - }; - - let open_channel = OpenChannelRequest { - public_key, - host, - port, - amount, - push_amount, - }; - - let callback = ctx.link().callback(Msg::ChannelOpened); - let jwt = ctx.props().jwt.clone(); - let url = ctx.props().url.clone(); - - spawn_local(async move { - post_open_channel(&jwt, &url, open_channel, callback) - .await - .ok(); - }); + warn!("Peer is missing"); + } } else { - warn!("Sommethitng is missing"); + warn!("Something is missing"); } false } - Msg::ChannelOpened(_response) => false, + Msg::ChannelOpened(_response) => { + self.view = View::OpenedChannel; + true + } Msg::FetechedPeers(peers) => { self.peers = peers; true @@ -174,47 +180,70 @@ impl Component for OpenChannel { let on_submit = ctx.link().callback(|_| Msg::Submit); html! { - - <> - - -
{ "Open Channel" }
-
-
-
-
-
- - -
- -
- - -
-
- - -
- - -
- - } + <> + +
{ "Open Channel" }
+ { + match self.view { + View::OpenChannel => { + html! { + <> +
+
+
+ +
+
+ + +
+
+ + +
+ + + + } + } + View::OpenedChannel => { + html! { + <> +
{ "Channel Opened" }
+ + + } + } + } + } +
+ + } } } diff --git a/mint/src/ln/cln.rs b/mint/src/ln/cln.rs index 3db899d..b197aaa 100644 --- a/mint/src/ln/cln.rs +++ b/mint/src/ln/cln.rs @@ -536,7 +536,7 @@ impl LnNodeManager for Cln { let cln_response = cln_client .call(cln_rpc::Request::Connect(cln_rpc::model::ConnectRequest { id: public_key.to_string(), - host: Some(host), + host: Some(host.clone()), port: Some(port), })) .await?; @@ -552,6 +552,8 @@ impl LnNodeManager for Cln { let peer_info = responses::PeerInfo { peer_pubkey: public_key, + host, + port, connected: true, }; @@ -622,8 +624,23 @@ fn from_peer_to_info(peer: &ListpeersPeers) -> Result = peer + .clone() + .netaddr + .ok_or(Error::Custom("No net address".to_string()))?[0] + .split(":") + .map(|s| s.to_string()) + .collect(); + + let host = remote_addr[0].to_string(); + let port = remote_addr[1].parse::()?; + Ok(responses::PeerInfo { peer_pubkey, + host, + port, connected, }) } diff --git a/mint/src/ln/error.rs b/mint/src/ln/error.rs index f1eb908..fa21655 100644 --- a/mint/src/ln/error.rs +++ b/mint/src/ln/error.rs @@ -120,6 +120,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: std::num::ParseIntError) -> Self { + Self::Custom(err.to_string()) + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct ErrorResponse { code: u16, diff --git a/mint/src/ln/ldk.rs b/mint/src/ln/ldk.rs index 36bb2e1..7a3155b 100644 --- a/mint/src/ln/ldk.rs +++ b/mint/src/ln/ldk.rs @@ -293,6 +293,8 @@ impl LnNodeManager for Ldk { let peer_info = responses::PeerInfo { peer_pubkey: public_key, + host: address, + port, connected: true, }; @@ -335,8 +337,12 @@ fn peer_info_from_details(details: &PeerDetails) -> Result().unwrap()) + .allow_headers([ + AUTHORIZATION, + CONTENT_TYPE, + ACCESS_CONTROL_ALLOW_CREDENTIALS, + ]), + ) .with_state(state); let ip = Ipv4Addr::from_str(&settings.info.listen_host)?; diff --git a/types/src/lib.rs b/types/src/lib.rs index 0155ee2..8bf4b38 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -106,6 +106,8 @@ pub mod responses { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct PeerInfo { pub peer_pubkey: PublicKey, + pub host: String, + pub port: u16, pub connected: bool, }