Skip to content

Commit

Permalink
donate screen and separate methods for on-chain / lighting send
Browse files Browse the repository at this point in the history
  • Loading branch information
futurepaul committed May 14, 2024
1 parent fd3f341 commit 86acd23
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 26 deletions.
13 changes: 12 additions & 1 deletion src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ use tokio::sync::mpsc;
#[derive(Debug, Clone)]
pub enum UICoreMsg {
SendLightning(Bolt11Invoice),
SendOnChain(SendOnChainDetails),
ReceiveLightning(Amount),
AddFederation(InviteCode),
Unlock(String),
}

#[derive(Debug, Clone, PartialEq)]
pub struct SendOnChainDetails {
pub amount: Amount,
pub address: String,
}

#[derive(Debug, Clone, PartialEq)]
pub enum SendSuccessMsg {
Lightning { preimage: [u8; 32] },
Expand Down Expand Up @@ -57,10 +64,14 @@ impl UIHandle {
self.ui_to_core_tx.send(msg).await.unwrap();
}

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

pub async fn send_onchain(&self, details: SendOnChainDetails) {
self.msg_send(UICoreMsg::SendOnChain(details)).await;
}

pub async fn receive(&self, amount: u64) {
self.msg_send(UICoreMsg::ReceiveLightning(Amount::from_sats(amount)))
.await;
Expand Down
2 changes: 2 additions & 0 deletions src/components/sidebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub fn sidebar(harbor: &HarborWallet) -> Element<Message> {
harbor.active_route
)
.on_press(Message::Navigate(Route::Settings)),
sidebar_button("Donate", SvgIcon::Heart, Route::Donate, harbor.active_route)
.on_press(Message::Navigate(Route::Donate)),
]
.spacing(8)
.align_items(Alignment::Start),
Expand Down
23 changes: 21 additions & 2 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ use iced::{
futures::{channel::mpsc::Sender, SinkExt},
subscription::{self, Subscription},
};
use log::error;
use log::{error, info};
use tokio::sync::RwLock;

use crate::{
bridge::{self, CoreUIMsg, UICoreMsg},
bridge::{self, CoreUIMsg, SendOnChainDetails, UICoreMsg},
conf::{self, get_mnemonic},
db::DBConnection,
Message,
Expand Down Expand Up @@ -99,6 +99,13 @@ impl HarborCore {
Ok(())
}

// TODO: actually send onchain
async fn send_onchain(&self, details: SendOnChainDetails) -> anyhow::Result<()> {
info!("{details:?}");
error!("BEN WTF YOU SAID ONCHAIN");
Ok(())
}

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 Down Expand Up @@ -242,6 +249,18 @@ pub fn run_core() -> Subscription<Message> {
if let Err(e) = core.send_lightning(invoice).await {
error!("Error sending: {e}");
core.msg(CoreUIMsg::SendFailure(e.to_string())).await;
} else {
info!("Successfully sent lightning");
}
}
UICoreMsg::SendOnChain(details) => {
log::info!("Got UICoreMsg::SendOnChain");
core.msg(CoreUIMsg::Sending).await;
if let Err(e) = core.send_onchain(details).await {
error!("Error sending: {e}");
core.msg(CoreUIMsg::SendFailure(e.to_string())).await;
} else {
info!("Successfully sent on-chain");
}
}
UICoreMsg::ReceiveLightning(amount) => {
Expand Down
71 changes: 50 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use routes::Route;
use std::str::FromStr;
use std::sync::Arc;

use bridge::CoreUIMsg;
use bridge::{CoreUIMsg, SendOnChainDetails};
use iced::subscription::Subscription;
use iced::widget::row;
use iced::Element;
Expand Down Expand Up @@ -66,6 +66,7 @@ pub struct HarborWallet {
receive_qr_data: Option<Data>,
mint_invite_code_str: String,
add_federation_failure_reason: Option<String>,
donate_amount_str: String,
}

impl Default for HarborWallet {
Expand Down Expand Up @@ -109,14 +110,15 @@ pub enum Message {
SendAmountInputChanged(String),
PasswordInputChanged(String),
MintInviteCodeInputChanged(String),
DonateAmountChanged(String),
CopyToClipboard(String),
// Async commands we fire from the UI to core
Noop,
Send(String),
Receive(u64),
GenerateInvoice,
Unlock(String),
AddFederation(String),
Donate,
// Core messages we get from core
CoreMessage(CoreUIMsg),
}
Expand All @@ -142,16 +144,31 @@ impl HarborWallet {
receive_qr_data: None,
mint_invite_code_str: String::new(),
add_federation_failure_reason: None,
donate_amount_str: String::new(),
}
}

fn subscription(&self) -> Subscription<Message> {
run_core()
}

async fn async_send(ui_handle: Option<Arc<bridge::UIHandle>>, invoice: Bolt11Invoice) {
async fn async_send_lightning(
ui_handle: Option<Arc<bridge::UIHandle>>,
invoice: Bolt11Invoice,
) {
if let Some(ui_handle) = ui_handle {
ui_handle.clone().send(invoice).await;
ui_handle.clone().send_lightning(invoice).await;
} else {
panic!("UI handle is None");
}
}

async fn async_send_onchain(
ui_handle: Option<Arc<bridge::UIHandle>>,
details: SendOnChainDetails,
) {
if let Some(ui_handle) = ui_handle {
ui_handle.clone().send_onchain(details).await;
} else {
panic!("UI handle is None");
}
Expand Down Expand Up @@ -222,30 +239,21 @@ impl HarborWallet {
self.mint_invite_code_str = input;
Command::none()
}
Message::DonateAmountChanged(input) => {
self.donate_amount_str = input;
Command::none()
}
// Async commands we fire from the UI to core
Message::Noop => Command::none(),
Message::Send(invoice_str) => match self.send_status {
SendStatus::Sending => Command::none(),
_ => {
self.send_failure_reason = None;
// todo get invoice from user
let invoice = Bolt11Invoice::from_str(&invoice_str).unwrap();
println!("Sending to invoice: {invoice}");
// let invoice = Bolt11Invoice::from_str(&invoice_str).unwrap();
Command::perform(Self::async_send(self.ui_handle.clone(), invoice), |_| {
// I don't know if this is the best way to do this but we don't really know anyting after we've fired the message
Message::Noop
})
}
},
Message::Receive(amount) => match self.send_status {
SendStatus::Sending => Command::none(),
_ => {
self.send_failure_reason = None;
Command::perform(Self::async_receive(self.ui_handle.clone(), amount), |_| {
// I don't know if this is the best way to do this but we don't really know anyting after we've fired the message
Message::Noop
})
Command::perform(
Self::async_send_lightning(self.ui_handle.clone(), invoice),
|_| Message::Noop,
)
}
},
Message::GenerateInvoice => match self.receive_status {
Expand All @@ -265,6 +273,26 @@ impl HarborWallet {
}
}
},
Message::Donate => match self.donate_amount_str.parse::<u64>() {
Ok(amount) => {
// TODO: don't hardcode this!
let hardcoded_donation_address = "tb1qd28npep0s8frcm3y7dxqajkcy2m40eysplyr9v";
let payload = SendOnChainDetails {
address: hardcoded_donation_address.to_string(),
amount: Amount::from_sats(amount),
};

Command::perform(
Self::async_send_onchain(self.ui_handle.clone(), payload),
|_| Message::Noop,
)
}
Err(e) => {
self.receive_amount_str = String::new();
eprintln!("Error parsing amount: {e}");
Command::none()
}
},
Message::Unlock(password) => match self.unlock_status {
UnlockStatus::Unlocking => Command::none(),
_ => {
Expand Down Expand Up @@ -372,6 +400,7 @@ impl HarborWallet {
Route::Receive => row![sidebar, crate::routes::receive(self)].into(),
Route::Send => row![sidebar, crate::routes::send(self)].into(),
Route::Mints => row![sidebar, crate::routes::mints(self)].into(),
Route::Donate => row![sidebar, crate::routes::donate(self)].into(),
_ => row![sidebar, crate::routes::home(self)].into(),
};

Expand Down
34 changes: 34 additions & 0 deletions src/routes/donate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use iced::widget::{column, container, scrollable};
use iced::Element;
use iced::{Length, Padding};

use crate::components::{h_button, h_header, h_input, SvgIcon};
use crate::{HarborWallet, Message};

pub fn donate(harbor: &HarborWallet) -> Element<Message> {
let header = h_header("Donate", "Support Harbor development.");

let donate_input = h_input(
"Amount",
"",
&harbor.donate_amount_str,
Message::DonateAmountChanged,
Message::Noop,
false,
None,
Some("sats"),
);

let donate_button = h_button("Donate", SvgIcon::Heart).on_press(Message::Donate);

let column = column![header, donate_input, donate_button].spacing(48);

container(scrollable(
column
.spacing(48)
.width(Length::Fill)
.max_width(512)
.padding(Padding::new(48.)),
))
.into()
}
1 change: 0 additions & 1 deletion src/routes/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use super::Route;
pub fn home(harbor: &HarborWallet) -> Element<Message> {
let balance = text(format!("{} sats", harbor.balance.sats_round_down())).size(64);
let send_button = h_button("Send", SvgIcon::UpRight).on_press(Message::Navigate(Route::Send));
// let receive_button = h_button("Receive", SvgIcon::DownLeft).on_press(Message::Receive(100));
let receive_button =
h_button("Receive", SvgIcon::DownLeft).on_press(Message::Navigate(Route::Receive));
let buttons = row![send_button, receive_button].spacing(32);
Expand Down
4 changes: 4 additions & 0 deletions src/routes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ pub use send::*;
pub mod unlock;
pub use unlock::*;

pub mod donate;
pub use donate::*;

#[derive(Default, PartialEq, Debug, Clone, Copy)]
pub enum Route {
#[default]
Expand All @@ -27,4 +30,5 @@ pub enum Route {
Settings,
Receive,
Send,
Donate,
}
1 change: 0 additions & 1 deletion src/routes/unlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use iced::{Alignment, Element, Length};
use crate::{HarborWallet, Message};

pub fn unlock(harbor: &HarborWallet) -> Element<Message> {
// let receive_button = h_button("Receive", SvgIcon::DownLeft).on_press(Message::Receive(100));
let unlock_button = h_button("Unlock", SvgIcon::DownLeft)
.on_press(Message::Unlock(harbor.password_input_str.clone()))
.width(Length::Fill);
Expand Down

0 comments on commit 86acd23

Please sign in to comment.