fedimint_gateway_ui/
mnemonic.rs

1use fedimint_gateway_common::MnemonicResponse;
2use maud::{Markup, html};
3
4use crate::DynGatewayApi;
5
6pub async fn render<E>(api: &DynGatewayApi<E>) -> Markup
7where
8    E: std::fmt::Display,
9{
10    let result = api.handle_mnemonic_msg().await;
11
12    match result {
13        Ok(MnemonicResponse { mnemonic, .. }) => {
14            html! {
15                div class="card h-100" {
16                    div class="card-header dashboard-header d-flex justify-content-between align-items-center" {
17                        span { "Gateway Secret Phrase" }
18
19                        // Toggle button
20                        button
21                            id="mnemonic-toggle-btn"
22                            class="btn btn-sm btn-secondary"
23                            type="button"
24                            onclick="toggleMnemonicVisibility()"
25                        {
26                            "Show"
27                        }
28                    }
29
30                    div class="card-body" {
31
32                        // Ordered list with redacted words
33                        ol id="mnemonic-list"
34                           style="column-count: 2; column-gap: 2rem; font-size: 1.1rem; padding-left: 1.4rem;"
35                        {
36                            @for word in &mnemonic {
37                                li class="mnemonic-word redacted" data-word=(word) {
38                                    "••••••••"
39                                }
40                            }
41                        }
42                    }
43                }
44
45                script {
46                    (maud::PreEscaped(r#"
47                        function toggleMnemonicVisibility() {
48                            const btn = document.getElementById("mnemonic-toggle-btn");
49                            const redacted = document.querySelectorAll(".mnemonic-word");
50
51                            const showing = btn.dataset.showing === "true";
52
53                            redacted.forEach(el => {
54                                if (showing) {
55                                    // Hide → show redaction
56                                    el.textContent = "••••••••";
57                                } else {
58                                    // Show → reveal actual word
59                                    el.textContent = el.dataset.word;
60                                }
61                            });
62
63                            btn.textContent = showing ? "Show" : "Hide";
64                            btn.dataset.showing = (!showing).toString();
65                        }
66                    "#))
67                }
68            }
69        }
70
71        Err(e) => {
72            html! {
73                div class="card h-100 border-danger" {
74                    div class="card-header dashboard-header bg-danger text-white" {
75                        "Gateway Secret Phrase"
76                    }
77                    div class="card-body" {
78                        div class="alert alert-danger mb-0" {
79                            strong { "Failed to fetch mnemonic: " }
80                            (e.to_string())
81                        }
82                    }
83                }
84            }
85        }
86    }
87}