gm_lib/tui/app/pages/
sign_message.rs1use std::sync::{atomic::AtomicBool, mpsc, Arc};
2
3use alloy::signers::SignerSync;
4use ratatui::{buffer::Buffer, layout::Rect};
5use strum::EnumIter;
6
7use crate::{
8 tui::{
9 app::{
10 widgets::form::{Form, FormItemIndex, FormWidget},
11 SharedState,
12 },
13 events::Event,
14 traits::{Component, HandleResult},
15 },
16 utils::account::AccountManager,
17};
18
19#[derive(EnumIter, PartialEq)]
20pub enum FormItem {
21 Heading,
22 Message,
23 SignMessageButton,
24 Signature,
25}
26
27pub struct SignMessagePage {
28 form: Form<FormItem>,
29}
30impl FormItemIndex for FormItem {
31 fn index(self) -> usize {
32 self as usize
33 }
34}
35impl TryFrom<FormItem> for FormWidget {
36 type Error = crate::Error;
37 fn try_from(value: FormItem) -> crate::Result<Self> {
38 let widget = match value {
39 FormItem::Heading => FormWidget::Heading("Sign a Message"),
40 FormItem::Message => FormWidget::InputBox {
41 label: "Message",
42 text: String::new(),
43 empty_text: Some("Type message to sign"),
44 currency: None,
45 },
46 FormItem::SignMessageButton => FormWidget::Button {
47 label: "Sign Message",
48 },
49 FormItem::Signature => FormWidget::DisplayText(String::new()),
50 };
51 Ok(widget)
52 }
53}
54
55impl SignMessagePage {
56 pub fn new() -> crate::Result<Self> {
57 Ok(Self {
58 form: Form::init(|_| Ok(()))?,
59 })
60 }
61}
62
63impl Component for SignMessagePage {
64 fn set_focus(&mut self, focus: bool) {
65 self.form.set_form_focus(focus);
66 }
67
68 fn handle_event(
69 &mut self,
70 event: &Event,
71 _area: Rect,
72 _transmitter: &mpsc::Sender<Event>,
73 _shutdown_signal: &Arc<AtomicBool>,
74 shared_state: &SharedState,
75 ) -> crate::Result<HandleResult> {
76 self.form.handle_event(
77 event,
78 |_, _| Ok(()),
79 |item, form| {
80 if item == FormItem::SignMessageButton
81 && form.get_text(FormItem::Signature).is_empty()
82 {
83 let message = form.get_text(FormItem::Message);
84
85 let wallet_address = shared_state.try_current_account()?;
86 let wallet = AccountManager::load_wallet(&wallet_address)?;
87 let signature = wallet.sign_message_sync(message.as_bytes())?;
88 *form.get_text_mut(FormItem::Signature) = format!("Signature:\n{signature}");
89 }
90 Ok(())
91 },
92 )?;
93 Ok(HandleResult::default())
94 }
95
96 fn render_component(&self, area: Rect, buf: &mut Buffer, ss: &SharedState) -> Rect
97 where
98 Self: Sized,
99 {
100 self.form.render(area, buf, &ss.theme);
101
102 area
103 }
104}