Skip to content

Commit

Permalink
Merge pull request #14 from MutinyWallet/refactor-ui-msgs
Browse files Browse the repository at this point in the history
Clean up UI <> Core messages
  • Loading branch information
benthecarman authored May 14, 2024
2 parents c353e67 + dc8f3ff commit 01bc9f5
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 70 deletions.
31 changes: 19 additions & 12 deletions src/bridge.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
use bitcoin::Txid;
use fedimint_core::api::InviteCode;
use fedimint_core::Amount;
use fedimint_ln_common::lightning_invoice::Bolt11Invoice;
use tokio::sync::mpsc;

#[derive(Debug, Clone)]
pub enum UICoreMsg {
Test(u64),
FakeSend(u64),
Send(Bolt11Invoice),
Receive(u64),
SendLightning(Bolt11Invoice),
ReceiveLightning(Amount),
AddFederation(InviteCode),
Unlock(String),
}

#[derive(Debug, Clone, PartialEq)]
pub enum SendSuccessMsg {
Lightning { preimage: [u8; 32] },
Onchain { txid: Txid },
}

#[derive(Debug, Clone, PartialEq)]
pub enum ReceiveSuccessMsg {
Lightning,
Onchain { txid: Txid },
}

#[derive(Debug, Clone)]
pub enum CoreUIMsg {
Sending,
SendSuccess,
SendSuccess(SendSuccessMsg),
SendFailure(String),
ReceiveInvoiceGenerating,
ReceiveInvoiceGenerated(Bolt11Invoice),
ReceiveSuccess,
ReceiveSuccess(ReceiveSuccessMsg),
ReceiveFailed(String),
BalanceUpdated(Amount),
AddFederationFailed(String),
Expand All @@ -45,16 +56,12 @@ impl UIHandle {
self.ui_to_core_tx.send(msg).await.unwrap();
}

pub async fn fake_send(&self, amount: u64) {
self.msg_send(UICoreMsg::FakeSend(amount)).await;
}

pub async fn send(&self, invoice: Bolt11Invoice) {
self.msg_send(UICoreMsg::Send(invoice)).await;
self.msg_send(UICoreMsg::SendLightning(invoice)).await;
}

pub async fn receive(&self, amount: u64) {
self.msg_send(UICoreMsg::Receive(amount)).await;
self.msg_send(UICoreMsg::ReceiveLightning(Amount::from_sats(amount))).await;
}

pub async fn unlock(&self, password: String) {
Expand Down
46 changes: 9 additions & 37 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ use std::collections::HashMap;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::atomic::AtomicBool;
use std::{sync::Arc, time::Duration};
use std::sync::Arc;

use iced::{
futures::{channel::mpsc::Sender, SinkExt},
subscription::{self, Subscription},
};
use log::error;
use tokio::sync::RwLock;
use tokio::time::sleep;

use crate::{
bridge::{self, CoreUIMsg, UICoreMsg},
Expand Down Expand Up @@ -64,32 +63,12 @@ impl HarborCore {
self.msg(CoreUIMsg::BalanceUpdated(self.balance)).await;
}

async fn fake_send(&mut self, amount: u64) {
self.msg(CoreUIMsg::Sending).await;
sleep(Duration::from_secs(1)).await;
println!("Sending {amount}");

let amount = Amount::from_sats(amount);
if amount > self.balance {
self.msg(CoreUIMsg::SendFailure("Insufficient funds".to_string()))
.await;
return;
}

// Save it in our struct
self.balance = self.balance.saturating_sub(amount);
// Tell the UI we did a good job
self.msg(CoreUIMsg::SendSuccess).await;
// Tell the UI the new balance
self.msg(CoreUIMsg::BalanceUpdated(self.balance)).await;
}

// todo for now just use the first client, but eventually we'll want to have a way to select a client
async fn get_client(&self) -> FedimintClient {
self.clients.read().await.values().next().unwrap().clone()
}

async fn send(&self, invoice: Bolt11Invoice) -> anyhow::Result<()> {
async fn send_lightning(&self, invoice: Bolt11Invoice) -> anyhow::Result<()> {
// todo go through all clients and select the first one that has enough balance
let client = self.get_client().await.fedimint_client;
let lightning_module = client.get_first_module::<LightningClientModule>();
Expand Down Expand Up @@ -118,7 +97,7 @@ impl HarborCore {
Ok(())
}

async fn receive(&self, amount: u64) -> anyhow::Result<Bolt11Invoice> {
async fn receive_lightning(&self, amount: Amount) -> anyhow::Result<Bolt11Invoice> {
let client = self.get_client().await.fedimint_client;
let lightning_module = client.get_first_module::<LightningClientModule>();

Expand All @@ -129,7 +108,7 @@ impl HarborCore {
let desc = Description::new(String::new()).expect("empty string is valid");
let (op_id, invoice, _) = lightning_module
.create_bolt11_invoice(
Amount::from_sats(amount),
amount,
Bolt11InvoiceDescription::Direct(&desc),
None,
(),
Expand Down Expand Up @@ -223,7 +202,7 @@ pub fn run_core() -> Subscription<Message> {
balance += client.fedimint_client.get_balance().await;
}

let mut core = HarborCore {
let core = HarborCore {
balance,
tx,
mnemonic,
Expand All @@ -248,24 +227,17 @@ pub fn run_core() -> Subscription<Message> {

if let Some(msg) = msg {
match msg {
UICoreMsg::Test(counter) => {
println!("{counter}");
}
UICoreMsg::FakeSend(amount) => {
core.fake_send(amount).await;
}
UICoreMsg::Send(invoice) => {
UICoreMsg::SendLightning(invoice) => {
log::info!("Got UICoreMsg::Send");
core.msg(CoreUIMsg::Sending).await;
if let Err(e) = core.send(invoice).await {
if let Err(e) = core.send_lightning(invoice).await {
error!("Error sending: {e}");
core.msg(CoreUIMsg::SendFailure(e.to_string())).await;
}
core.msg(CoreUIMsg::SendSuccess).await;
}
UICoreMsg::Receive(amount) => {
UICoreMsg::ReceiveLightning(amount) => {
core.msg(CoreUIMsg::ReceiveInvoiceGenerating).await;
match core.receive(amount).await {
match core.receive_lightning(amount).await {
Err(e) => {
core.msg(CoreUIMsg::ReceiveFailed(e.to_string())).await;
}
Expand Down
21 changes: 15 additions & 6 deletions src/fedimint_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::bridge::CoreUIMsg;
use crate::bridge::{CoreUIMsg, ReceiveSuccessMsg, SendSuccessMsg};
use crate::Message;
use bip39::Mnemonic;
use bitcoin::hashes::hex::FromHex;
use bitcoin::Network;
use fedimint_bip39::Bip39RootSecretStrategy;
use fedimint_client::oplog::UpdateStreamOrOutcome;
Expand Down Expand Up @@ -204,7 +205,9 @@ pub(crate) async fn spawn_invoice_receive_subscription(
LnReceiveState::Claimed => {
info!("Payment claimed");
sender
.send(Message::CoreMessage(CoreUIMsg::ReceiveSuccess))
.send(Message::CoreMessage(CoreUIMsg::ReceiveSuccess(
ReceiveSuccessMsg::Lightning,
)))
.await
.unwrap();

Expand Down Expand Up @@ -247,10 +250,13 @@ pub(crate) async fn spawn_invoice_payment_subscription(
.await
.unwrap();
}
LnPayState::Success { preimage: _ } => {
LnPayState::Success { preimage } => {
info!("Payment success");
let preimage: [u8; 32] =
FromHex::from_hex(&preimage).expect("Invalid preimage");
let params = SendSuccessMsg::Lightning { preimage };
sender
.send(Message::CoreMessage(CoreUIMsg::SendSuccess))
.send(Message::CoreMessage(CoreUIMsg::SendSuccess(params)))
.await
.unwrap();

Expand Down Expand Up @@ -293,10 +299,13 @@ pub(crate) async fn spawn_internal_payment_subscription(
.await
.unwrap();
}
InternalPayState::Preimage(_preimage) => {
InternalPayState::Preimage(preimage) => {
info!("Payment success");
let params = SendSuccessMsg::Lightning {
preimage: preimage.0,
};
sender
.send(Message::CoreMessage(CoreUIMsg::SendSuccess))
.send(Message::CoreMessage(CoreUIMsg::SendSuccess(params)))
.await
.unwrap();

Expand Down
25 changes: 10 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use iced::widget::row;
use iced::Element;
use iced::{clipboard, program, Color};
use iced::{Command, Font};
use log::info;

use crate::components::focus_input_id;

Expand Down Expand Up @@ -138,16 +139,6 @@ impl HarborWallet {
run_core()
}

// We can't use self in these async functions because lifetimes are hard
#[allow(dead_code)] // TODO: remove
async fn async_fake_send(ui_handle: Option<Arc<bridge::UIHandle>>, amount: u64) {
if let Some(ui_handle) = ui_handle {
ui_handle.clone().fake_send(amount).await;
} else {
panic!("UI handle is None");
}
}

async fn async_send(ui_handle: Option<Arc<bridge::UIHandle>>, invoice: Bolt11Invoice) {
println!("Got to async_send");
if let Some(ui_handle) = ui_handle {
Expand Down Expand Up @@ -273,7 +264,8 @@ impl HarborWallet {
self.send_status = SendStatus::Sending;
Command::none()
}
CoreUIMsg::SendSuccess => {
CoreUIMsg::SendSuccess(params) => {
info!("Send success: {params:?}");
self.send_status = SendStatus::Idle;
Command::none()
}
Expand All @@ -282,11 +274,14 @@ impl HarborWallet {
self.send_failure_reason = Some(reason);
Command::none()
}
CoreUIMsg::ReceiveSuccess => Command::none(),
CoreUIMsg::ReceiveSuccess(params) => {
info!("Receive success: {params:?}");
self.receive_status = ReceiveStatus::Idle;
Command::none()
},
CoreUIMsg::ReceiveFailed(reason) => {
// todo use receive failure reason
self.send_status = SendStatus::Idle;
self.send_failure_reason = Some(reason);
self.receive_status = ReceiveStatus::Idle;
self.receive_failure_reason = Some(reason);
Command::none()
}
CoreUIMsg::BalanceUpdated(balance) => {
Expand Down

0 comments on commit 01bc9f5

Please sign in to comment.