From 69b4f6ecc9cf9b6208d495bbf6395c06d47239fb Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Fri, 22 Nov 2024 16:22:20 +0100 Subject: [PATCH 01/12] chore: setup lightning bot --- src/bin/super/state.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/bin/super/state.rs b/src/bin/super/state.rs index b351955b..e05e3554 100644 --- a/src/bin/super/state.rs +++ b/src/bin/super/state.rs @@ -13,6 +13,7 @@ pub struct Super { pub jwt_key: String, pub bots: Vec, pub ec2_limit: Ec2Limit, + pub lightning_bots: Vec, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Default)] @@ -52,6 +53,13 @@ pub struct InstanceFromAws { pub intance_type: String, } +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Default)] +pub struct LightningBot { + pub url: String, + pub token: String, + pub label: String, +} + impl Default for Super { fn default() -> Self { Self { @@ -60,6 +68,7 @@ impl Default for Super { jwt_key: secrets::random_word(16), bots: Vec::new(), ec2_limit: default_ec2_limit(), + lightning_bots: Vec::new(), } } } @@ -127,6 +136,7 @@ impl Super { count: 0, date: "".to_string(), }, + lightning_bots: vec![], } } From efd013966523c44db4d9afdb5e78624d40d8e0fa Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Fri, 22 Nov 2024 20:42:10 +0100 Subject: [PATCH 02/12] chore[superadmin-frontend]: setup lightning bot card --- src/bin/super/superapp/src/App.svelte | 29 ++++++++++++++++--- .../super/superapp/src/LightningBot.svelte | 25 ++++++++++++++++ .../src/components/LightningBotCard.svelte | 20 +++++++++++++ src/bin/super/superapp/src/store.ts | 4 ++- src/bin/super/superapp/src/types/types.ts | 7 +++++ 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/bin/super/superapp/src/LightningBot.svelte create mode 100644 src/bin/super/superapp/src/components/LightningBotCard.svelte diff --git a/src/bin/super/superapp/src/App.svelte b/src/bin/super/superapp/src/App.svelte index d2f8c16e..40faf9b1 100644 --- a/src/bin/super/superapp/src/App.svelte +++ b/src/bin/super/superapp/src/App.svelte @@ -3,9 +3,16 @@ import Login from "../../../../../app/src/auth/Login.svelte"; import { activeUser, saveUserToStore, logoutUser } from "./store"; import User from "carbon-icons-svelte/lib/User.svelte"; - import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte"; + import { + OverflowMenu, + OverflowMenuItem, + Tabs, + Tab, + TabContent, + } from "carbon-components-svelte"; import ChangePassword from "./ChangePassword.svelte"; import ViewNodes from "./ViewNodes.svelte"; + import LightningBot from "./LightningBot.svelte"; let page = "main"; async function backToMain() { @@ -43,10 +50,23 @@
{#if page === "change_password"} - {:else if page === "view_nodes"} - {:else} - + + + + + +
+ {#if page === "view_nodes"} + + {:else} + + {/if} +
+
+ +
+
{/if}
{/if} @@ -83,6 +103,7 @@ display: flex; height: calc(100vh - 4.2rem); width: 100%; + flex-direction: column; } .stack-title { color: white; diff --git a/src/bin/super/superapp/src/LightningBot.svelte b/src/bin/super/superapp/src/LightningBot.svelte new file mode 100644 index 00000000..71b62ff9 --- /dev/null +++ b/src/bin/super/superapp/src/LightningBot.svelte @@ -0,0 +1,25 @@ + + +
+
+ {#each $lightningBots as lightningBot} + + {/each} +
+
+ + diff --git a/src/bin/super/superapp/src/components/LightningBotCard.svelte b/src/bin/super/superapp/src/components/LightningBotCard.svelte new file mode 100644 index 00000000..6c752057 --- /dev/null +++ b/src/bin/super/superapp/src/components/LightningBotCard.svelte @@ -0,0 +1,20 @@ + + +
+ + diff --git a/src/bin/super/superapp/src/store.ts b/src/bin/super/superapp/src/store.ts index ed8a078b..84d804ff 100644 --- a/src/bin/super/superapp/src/store.ts +++ b/src/bin/super/superapp/src/store.ts @@ -2,7 +2,7 @@ import { writable } from "svelte/store"; import { userKey, type TokenData } from "../../../../../app/src/api/cmd"; import * as api from "../../../../../app/src/api"; import { decode } from "js-base64"; -import type { Tribe, Remote } from "./types/types"; +import type { Tribe, Remote, ILightningBot } from "./types/types"; export const remotes = writable([]); @@ -12,6 +12,8 @@ export const selectedNode = writable(); export const tribes = writable<{ [k: string]: Tribe[] }>({}); +export const lightningBots = writable([]); + export const saveUserToStore = async (user: string = "") => { if (user) { localStorage.setItem(userKey, user); diff --git a/src/bin/super/superapp/src/types/types.ts b/src/bin/super/superapp/src/types/types.ts index 7da07a9b..3ac50003 100644 --- a/src/bin/super/superapp/src/types/types.ts +++ b/src/bin/super/superapp/src/types/types.ts @@ -37,3 +37,10 @@ export interface Remote { default_host?: string; ec2_instance_id: string; } + +export interface ILightningBot { + balance: number; + label: string; + id: string; + pubkey: string; +} From a1092d1d6a19dfd02698a9f8f6efbd5755923fd4 Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Fri, 22 Nov 2024 23:50:16 +0100 Subject: [PATCH 03/12] chore[superadmin]: get lightning details --- app/src/api/cmd.ts | 3 +- app/src/api/swarm.ts | 5 + src/bin/super/cmd.rs | 13 ++ src/bin/super/lightning_bots.rs | 159 ++++++++++++++++++ src/bin/super/mod.rs | 6 + src/bin/super/state.rs | 11 ++ .../super/superapp/src/LightningBot.svelte | 5 +- src/bin/super/superapp/src/types/types.ts | 7 +- 8 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 src/bin/super/lightning_bots.rs diff --git a/app/src/api/cmd.ts b/app/src/api/cmd.ts index 0064717e..44548d9d 100644 --- a/app/src/api/cmd.ts +++ b/app/src/api/cmd.ts @@ -95,7 +95,8 @@ export type Cmd = | "GetInstanceType" | "GetAllImageActualVersion" | "GetSwarmChildImageVersions" - | "ChangeChildSwarmPassword"; + | "ChangeChildSwarmPassword" + | "GetLightningBotsDetails"; interface CmdData { cmd: Cmd; diff --git a/app/src/api/swarm.ts b/app/src/api/swarm.ts index 69e44974..e5362a94 100644 --- a/app/src/api/swarm.ts +++ b/app/src/api/swarm.ts @@ -378,3 +378,8 @@ export async function get_swarm_instance_type({ }) { return await swarmCmd("GetInstanceType", { instance_id }); } + +// GetLightningBotDetails +export async function get_lightning_bots_detail() { + return await swarmCmd("GetLightningBotsDetails"); +} diff --git a/src/bin/super/cmd.rs b/src/bin/super/cmd.rs index 8780daf9..e2080661 100644 --- a/src/bin/super/cmd.rs +++ b/src/bin/super/cmd.rs @@ -100,6 +100,7 @@ pub enum SwarmCmd { GetInstanceType(GetInstanceTypeByInstanceId), GetSwarmChildImageVersions(ChildSwarmIdentifier), ChangeChildSwarmPassword(ChangeUserPasswordBySuperAdminRequest), + GetLightningBotsDetails, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -153,3 +154,15 @@ pub struct GetInstanceTypeByInstanceId { pub struct GetInstanceTypeRes { pub instance_type: Option, } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct LightningBotAccountRes { + pub contact_info: String, + pub alias: String, + pub network: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct LightningBotBalanceRes { + pub msat: u64, +} diff --git a/src/bin/super/lightning_bots.rs b/src/bin/super/lightning_bots.rs new file mode 100644 index 00000000..26500be0 --- /dev/null +++ b/src/bin/super/lightning_bots.rs @@ -0,0 +1,159 @@ +use crate::{ + cmd::{LightningBotAccountRes, LightningBotBalanceRes, SuperSwarmResponse}, + state::{LightningBotsDetails, Super}, +}; +use anyhow::Error; +use reqwest::Response; +use sphinx_swarm::utils::make_reqwest_client; + +pub async fn get_lightning_bots_details(state: &Super) -> SuperSwarmResponse { + let mut lightning_bots_details: Vec = Vec::new(); + for bot in &state.lightning_bots { + // get bot details + let bot_details_res = match make_get_request_to_bot(&bot.url, &bot.token, "account").await { + Ok(res) => res, + Err(err) => { + log::error!("Error getting details: {}", err.to_string()); + lightning_bots_details.push(make_err_response( + format!( + "Error making get account details request: {}", + err.to_string() + ), + bot.label.clone(), + bot.url.clone(), + )); + continue; + } + }; + + if bot_details_res.status() != 200 { + let status_code = bot_details_res.status().clone(); + log::error!("Response body: {:?}", bot_details_res.text().await); + lightning_bots_details.push(make_err_response( + format!( + "Got this response code trying to get bot account details: {}", + status_code + ), + bot.label.clone(), + bot.url.clone(), + )); + continue; + } + + let bot_details: LightningBotAccountRes = match bot_details_res.json().await { + Ok(value) => value, + Err(err) => { + log::error!("Error parsing response details: {}", err.to_string()); + lightning_bots_details.push(make_err_response( + format!( + "Error parsing response details from get account: {}", + err.to_string() + ), + bot.label.clone(), + bot.url.clone(), + )); + continue; + } + }; + + // get bot balance + let bot_balance_res = match make_get_request_to_bot(&bot.url, &bot.token, "balance").await { + Ok(res) => res, + Err(err) => { + log::error!("Error getting balance: {}", err.to_string()); + lightning_bots_details.push(make_err_response( + format!("Error getting bot balance: {}", err.to_string()), + bot.label.clone(), + bot.url.clone(), + )); + continue; + } + }; + + if bot_balance_res.status() != 200 { + let status_code = bot_balance_res.status().clone(); + log::error!("Response body: {:?}", bot_balance_res.text().await); + lightning_bots_details.push(make_err_response( + format!( + "Got this response code trying to get bot balance: {}", + status_code + ), + bot.label.clone(), + bot.url.clone(), + )); + continue; + } + + let bot_balance: LightningBotBalanceRes = match bot_balance_res.json().await { + Ok(value) => value, + Err(err) => { + log::error!("Error parsing response details: {}", err.to_string()); + lightning_bots_details.push(make_err_response( + format!( + "Error parsing response details from getting bot balance: {}", + err.to_string() + ), + bot.label.clone(), + bot.url.clone(), + )); + continue; + } + }; + + lightning_bots_details.push(LightningBotsDetails { + balance_in_msat: bot_balance.msat, + contact_info: bot_details.contact_info, + alias: bot_details.alias, + error_message: "".to_string(), + network: bot_details.network, + id: bot.url.clone(), + label: bot.label.clone(), + }) + } + + let lightning_bots = match serde_json::to_value(&lightning_bots_details) { + Ok(json) => json, + Err(err) => { + log::error!("Error converting vec to Value: {}", err.to_string()); + return SuperSwarmResponse { + success: false, + message: format!("Error converting vec to Value: {}", err.to_string()), + data: None, + }; + } + }; + + SuperSwarmResponse { + success: true, + message: "lightning details".to_string(), + data: Some(lightning_bots), + } +} + +async fn make_get_request_to_bot( + host: &str, + token: &str, + endpoint: &str, +) -> Result { + let client = make_reqwest_client(); + + let res = client + .get(format!("https://{}/{}", host, endpoint)) + .header("x-admin-token", token) + .send() + .await?; + + Ok(res) +} + +fn make_err_response(err_msg: String, label: String, id: String) -> LightningBotsDetails { + LightningBotsDetails { + balance_in_msat: 0, + contact_info: "".to_string(), + alias: "".to_string(), + error_message: err_msg, + network: "".to_string(), + id: id, + label: label, + } +} diff --git a/src/bin/super/mod.rs b/src/bin/super/mod.rs index 0772da40..bb8e9324 100644 --- a/src/bin/super/mod.rs +++ b/src/bin/super/mod.rs @@ -3,6 +3,7 @@ mod aws_util; mod checker; mod cmd; mod ec2; +mod lightning_bots; mod route53; mod routes; mod state; @@ -10,6 +11,7 @@ mod util; use cmd::{AddSwarmResponse, SuperSwarmResponse}; use cmd::{Cmd, SwarmCmd}; +use lightning_bots::get_lightning_bots_details; use sphinx_swarm::utils::getenv; use state::RemoteStack; use state::Super; @@ -401,6 +403,10 @@ pub async fn super_handle( let res: SuperSwarmResponse = update_swarm_child_password(info, &state).await; Some(serde_json::to_string(&res)?) } + SwarmCmd::GetLightningBotsDetails => { + let res: SuperSwarmResponse = get_lightning_bots_details(&state).await; + Some(serde_json::to_string(&res)?) + } }, }; diff --git a/src/bin/super/state.rs b/src/bin/super/state.rs index e05e3554..4d6f56ab 100644 --- a/src/bin/super/state.rs +++ b/src/bin/super/state.rs @@ -60,6 +60,17 @@ pub struct LightningBot { pub label: String, } +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Default)] +pub struct LightningBotsDetails { + pub balance_in_msat: u64, + pub contact_info: String, + pub alias: String, + pub network: String, + pub error_message: String, + pub id: String, + pub label: String, +} + impl Default for Super { fn default() -> Self { Self { diff --git a/src/bin/super/superapp/src/LightningBot.svelte b/src/bin/super/superapp/src/LightningBot.svelte index 71b62ff9..16410b71 100644 --- a/src/bin/super/superapp/src/LightningBot.svelte +++ b/src/bin/super/superapp/src/LightningBot.svelte @@ -2,9 +2,12 @@ import { onMount } from "svelte"; import { lightningBots } from "./store"; import LightningBotCard from "./components/LightningBotCard.svelte"; + import { get_lightning_bots_detail } from "../../../../../app/src/api/swarm"; - onMount(() => { + onMount(async () => { // get all lightning bots + let res = await get_lightning_bots_detail(); + console.log(res); }); diff --git a/src/bin/super/superapp/src/types/types.ts b/src/bin/super/superapp/src/types/types.ts index 3ac50003..e3172632 100644 --- a/src/bin/super/superapp/src/types/types.ts +++ b/src/bin/super/superapp/src/types/types.ts @@ -39,8 +39,11 @@ export interface Remote { } export interface ILightningBot { - balance: number; + balance_in_msat: number; label: string; id: string; - pubkey: string; + contact_info: string; + network: string; + error_message: string; + alias: string; } From c2c5862faf1aa1d3d37ead2a0faef216dcb3fada Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Sat, 23 Nov 2024 00:29:05 +0100 Subject: [PATCH 04/12] chore[superadmin-frontend]: display lightning bot details properly --- app/src/components/input/input.svelte | 12 +--- app/src/helpers/swarm.ts | 10 ++++ .../super/superapp/src/LightningBot.svelte | 46 +++++++++++++-- .../src/components/LightningBotCard.svelte | 58 ++++++++++++++++++- 4 files changed, 108 insertions(+), 18 deletions(-) diff --git a/app/src/components/input/input.svelte b/app/src/components/input/input.svelte index c3ef6be8..8e1c8679 100644 --- a/app/src/components/input/input.svelte +++ b/app/src/components/input/input.svelte @@ -1,20 +1,12 @@
- {#each $lightningBots as lightningBot} - - {/each} + {#if loading} + + {/if} + {#if error_message} +
+ +
+ {:else} + {#each $lightningBots as lightningBot} + + {/each} + {/if}
@@ -25,4 +57,8 @@ flex-direction: column; padding: 1.5rem; } + + .success_toast_container { + margin-bottom: 2rem; + } diff --git a/src/bin/super/superapp/src/components/LightningBotCard.svelte b/src/bin/super/superapp/src/components/LightningBotCard.svelte index 6c752057..9432b920 100644 --- a/src/bin/super/superapp/src/components/LightningBotCard.svelte +++ b/src/bin/super/superapp/src/components/LightningBotCard.svelte @@ -1,4 +1,10 @@ -
+
+ {#if lightningBot.error_message} +
+ +
{:else} +
+

Label: {lightningBot.label}

+

+ Public Key: {splitPubkey(lightningBot.contact_info)} +

+

+ Balance : {formatSatsNumbers( + convertMillisatsToSats(lightningBot.balance_in_msat) + )} + Sats +

+

+ Network : {lightningBot.network} +

+

+ Alias : {lightningBot.alias} +

+
+ {/if} +
From 340858e86be284c22717643336510bfb7f9e7d83 Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Sat, 23 Nov 2024 00:53:59 +0100 Subject: [PATCH 05/12] chore:[superadmin-frontend]: function and Ui to handle change label --- app/src/api/cmd.ts | 3 +- app/src/api/swarm.ts | 12 ++- .../src/components/LightningBotCard.svelte | 90 +++++++++++++++++-- 3 files changed, 97 insertions(+), 8 deletions(-) diff --git a/app/src/api/cmd.ts b/app/src/api/cmd.ts index 44548d9d..809fc340 100644 --- a/app/src/api/cmd.ts +++ b/app/src/api/cmd.ts @@ -96,7 +96,8 @@ export type Cmd = | "GetAllImageActualVersion" | "GetSwarmChildImageVersions" | "ChangeChildSwarmPassword" - | "GetLightningBotsDetails"; + | "GetLightningBotsDetails" + | "ChangeLigthningBotLable"; interface CmdData { cmd: Cmd; diff --git a/app/src/api/swarm.ts b/app/src/api/swarm.ts index e5362a94..3d4893c1 100644 --- a/app/src/api/swarm.ts +++ b/app/src/api/swarm.ts @@ -379,7 +379,17 @@ export async function get_swarm_instance_type({ return await swarmCmd("GetInstanceType", { instance_id }); } -// GetLightningBotDetails export async function get_lightning_bots_detail() { return await swarmCmd("GetLightningBotsDetails"); } + +// ChangeLigthningBotLable +export async function change_lightning_bot_label({ + id, + new_label, +}: { + id: string; + new_label: string; +}) { + return await swarmCmd("ChangeLigthningBotLable", { id, new_label }); +} diff --git a/src/bin/super/superapp/src/components/LightningBotCard.svelte b/src/bin/super/superapp/src/components/LightningBotCard.svelte index 9432b920..f447c75f 100644 --- a/src/bin/super/superapp/src/components/LightningBotCard.svelte +++ b/src/bin/super/superapp/src/components/LightningBotCard.svelte @@ -1,17 +1,51 @@
@@ -46,8 +80,45 @@

Alias : {lightningBot.alias}

+
+ +
{/if} + + (open_change_label = false)} + on:open + on:close={handleOnCloseChangeBotLabel} + on:submit={handleChangeBotLabel} + > + {#if error_notification} + { + e.preventDefault(); + error_notification = false; + }} + /> + {/if} +
+ +
+
From 494ec6c2deccf837533f877c172e5e65b86ff866 Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Sat, 23 Nov 2024 01:16:19 +0100 Subject: [PATCH 06/12] chore[superadmin]: setup change label backend --- app/src/api/cmd.ts | 2 +- app/src/api/swarm.ts | 3 +-- src/bin/super/cmd.rs | 7 ++++++ src/bin/super/lightning_bots.rs | 40 ++++++++++++++++++++++++++++++++- src/bin/super/mod.rs | 7 +++++- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/app/src/api/cmd.ts b/app/src/api/cmd.ts index 809fc340..32eef7e4 100644 --- a/app/src/api/cmd.ts +++ b/app/src/api/cmd.ts @@ -97,7 +97,7 @@ export type Cmd = | "GetSwarmChildImageVersions" | "ChangeChildSwarmPassword" | "GetLightningBotsDetails" - | "ChangeLigthningBotLable"; + | "ChangeLigthningBotLabel"; interface CmdData { cmd: Cmd; diff --git a/app/src/api/swarm.ts b/app/src/api/swarm.ts index 3d4893c1..367895aa 100644 --- a/app/src/api/swarm.ts +++ b/app/src/api/swarm.ts @@ -383,7 +383,6 @@ export async function get_lightning_bots_detail() { return await swarmCmd("GetLightningBotsDetails"); } -// ChangeLigthningBotLable export async function change_lightning_bot_label({ id, new_label, @@ -391,5 +390,5 @@ export async function change_lightning_bot_label({ id: string; new_label: string; }) { - return await swarmCmd("ChangeLigthningBotLable", { id, new_label }); + return await swarmCmd("ChangeLigthningBotLabel", { id, new_label }); } diff --git a/src/bin/super/cmd.rs b/src/bin/super/cmd.rs index e2080661..0de9f399 100644 --- a/src/bin/super/cmd.rs +++ b/src/bin/super/cmd.rs @@ -101,6 +101,7 @@ pub enum SwarmCmd { GetSwarmChildImageVersions(ChildSwarmIdentifier), ChangeChildSwarmPassword(ChangeUserPasswordBySuperAdminRequest), GetLightningBotsDetails, + ChangeLigthningBotLabel(ChangeLigthningBotLabel), } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -166,3 +167,9 @@ pub struct LightningBotAccountRes { pub struct LightningBotBalanceRes { pub msat: u64, } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ChangeLigthningBotLabel { + pub id: String, + pub new_lable: String, +} diff --git a/src/bin/super/lightning_bots.rs b/src/bin/super/lightning_bots.rs index 26500be0..8437ea7a 100644 --- a/src/bin/super/lightning_bots.rs +++ b/src/bin/super/lightning_bots.rs @@ -1,5 +1,7 @@ use crate::{ - cmd::{LightningBotAccountRes, LightningBotBalanceRes, SuperSwarmResponse}, + cmd::{ + ChangeLigthningBotLabel, LightningBotAccountRes, LightningBotBalanceRes, SuperSwarmResponse, + }, state::{LightningBotsDetails, Super}, }; use anyhow::Error; @@ -157,3 +159,39 @@ fn make_err_response(err_msg: String, label: String, id: String) -> LightningBot label: label, } } + +pub async fn change_lightning_bot_label( + state: &mut Super, + must_save_stack: &mut bool, + info: ChangeLigthningBotLabel, +) -> SuperSwarmResponse { + if info.new_lable.is_empty() { + return SuperSwarmResponse { + success: false, + message: "Label cannot be empty".to_string(), + data: None, + }; + } + let bot_pos = &state + .lightning_bots + .iter() + .position(|bot| bot.url == info.id); + + if bot_pos.is_none() { + return SuperSwarmResponse { + success: false, + message: "Invalid bot".to_string(), + data: None, + }; + } + + let actual_bot_pos = bot_pos.unwrap(); + + state.lightning_bots[actual_bot_pos].label = info.new_lable; + *must_save_stack = true; + SuperSwarmResponse { + success: true, + message: "label updated successfully".to_string(), + data: None, + } +} diff --git a/src/bin/super/mod.rs b/src/bin/super/mod.rs index bb8e9324..2590fbf2 100644 --- a/src/bin/super/mod.rs +++ b/src/bin/super/mod.rs @@ -11,7 +11,7 @@ mod util; use cmd::{AddSwarmResponse, SuperSwarmResponse}; use cmd::{Cmd, SwarmCmd}; -use lightning_bots::get_lightning_bots_details; +use lightning_bots::{change_lightning_bot_label, get_lightning_bots_details}; use sphinx_swarm::utils::getenv; use state::RemoteStack; use state::Super; @@ -407,6 +407,11 @@ pub async fn super_handle( let res: SuperSwarmResponse = get_lightning_bots_details(&state).await; Some(serde_json::to_string(&res)?) } + SwarmCmd::ChangeLigthningBotLabel(info) => { + let res: SuperSwarmResponse = + change_lightning_bot_label(&mut state, &mut must_save_stack, info).await; + Some(serde_json::to_string(&res)?) + } }, }; From c63d6c3fea175ec74bff7ac6a3598a232d1f0e64 Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Sat, 23 Nov 2024 01:47:39 +0100 Subject: [PATCH 07/12] chore[superadmin-frontend]: change super admin label --- app/src/api/cmd.ts | 2 +- app/src/api/swarm.ts | 2 +- src/bin/super/cmd.rs | 6 ++-- src/bin/super/lightning_bots.rs | 10 +++--- src/bin/super/mod.rs | 2 +- .../src/components/LightningBotCard.svelte | 33 +++++++++++++++++++ src/bin/super/superapp/src/utils/index.ts | 27 +++++++++++++++ 7 files changed, 72 insertions(+), 10 deletions(-) diff --git a/app/src/api/cmd.ts b/app/src/api/cmd.ts index 32eef7e4..a5937b2c 100644 --- a/app/src/api/cmd.ts +++ b/app/src/api/cmd.ts @@ -97,7 +97,7 @@ export type Cmd = | "GetSwarmChildImageVersions" | "ChangeChildSwarmPassword" | "GetLightningBotsDetails" - | "ChangeLigthningBotLabel"; + | "ChangeLightningBotLabel"; interface CmdData { cmd: Cmd; diff --git a/app/src/api/swarm.ts b/app/src/api/swarm.ts index 367895aa..ce4f8602 100644 --- a/app/src/api/swarm.ts +++ b/app/src/api/swarm.ts @@ -390,5 +390,5 @@ export async function change_lightning_bot_label({ id: string; new_label: string; }) { - return await swarmCmd("ChangeLigthningBotLabel", { id, new_label }); + return await swarmCmd("ChangeLightningBotLabel", { id, new_label }); } diff --git a/src/bin/super/cmd.rs b/src/bin/super/cmd.rs index 0de9f399..124a2380 100644 --- a/src/bin/super/cmd.rs +++ b/src/bin/super/cmd.rs @@ -101,7 +101,7 @@ pub enum SwarmCmd { GetSwarmChildImageVersions(ChildSwarmIdentifier), ChangeChildSwarmPassword(ChangeUserPasswordBySuperAdminRequest), GetLightningBotsDetails, - ChangeLigthningBotLabel(ChangeLigthningBotLabel), + ChangeLightningBotLabel(ChangeLightningBotLabel), } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -169,7 +169,7 @@ pub struct LightningBotBalanceRes { } #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ChangeLigthningBotLabel { +pub struct ChangeLightningBotLabel { pub id: String, - pub new_lable: String, + pub new_label: String, } diff --git a/src/bin/super/lightning_bots.rs b/src/bin/super/lightning_bots.rs index 8437ea7a..8ce4756c 100644 --- a/src/bin/super/lightning_bots.rs +++ b/src/bin/super/lightning_bots.rs @@ -1,6 +1,6 @@ use crate::{ cmd::{ - ChangeLigthningBotLabel, LightningBotAccountRes, LightningBotBalanceRes, SuperSwarmResponse, + ChangeLightningBotLabel, LightningBotAccountRes, LightningBotBalanceRes, SuperSwarmResponse, }, state::{LightningBotsDetails, Super}, }; @@ -163,9 +163,9 @@ fn make_err_response(err_msg: String, label: String, id: String) -> LightningBot pub async fn change_lightning_bot_label( state: &mut Super, must_save_stack: &mut bool, - info: ChangeLigthningBotLabel, + info: ChangeLightningBotLabel, ) -> SuperSwarmResponse { - if info.new_lable.is_empty() { + if info.new_label.is_empty() { return SuperSwarmResponse { success: false, message: "Label cannot be empty".to_string(), @@ -187,8 +187,10 @@ pub async fn change_lightning_bot_label( let actual_bot_pos = bot_pos.unwrap(); - state.lightning_bots[actual_bot_pos].label = info.new_lable; + state.lightning_bots[actual_bot_pos].label = info.new_label; + *must_save_stack = true; + SuperSwarmResponse { success: true, message: "label updated successfully".to_string(), diff --git a/src/bin/super/mod.rs b/src/bin/super/mod.rs index 2590fbf2..197564b8 100644 --- a/src/bin/super/mod.rs +++ b/src/bin/super/mod.rs @@ -407,7 +407,7 @@ pub async fn super_handle( let res: SuperSwarmResponse = get_lightning_bots_details(&state).await; Some(serde_json::to_string(&res)?) } - SwarmCmd::ChangeLigthningBotLabel(info) => { + SwarmCmd::ChangeLightningBotLabel(info) => { let res: SuperSwarmResponse = change_lightning_bot_label(&mut state, &mut must_save_stack, info).await; Some(serde_json::to_string(&res)?) diff --git a/src/bin/super/superapp/src/components/LightningBotCard.svelte b/src/bin/super/superapp/src/components/LightningBotCard.svelte index f447c75f..a81724dc 100644 --- a/src/bin/super/superapp/src/components/LightningBotCard.svelte +++ b/src/bin/super/superapp/src/components/LightningBotCard.svelte @@ -13,6 +13,8 @@ import { splitPubkey } from "../../../../../../app/src/helpers/swarm"; import type { ILightningBot } from "../types/types"; import { change_lightning_bot_label } from "../../../../../../app/src/api/swarm"; + import { fectAndRefreshLightningBotDetails } from "../utils"; + import { lightningBots } from "../store"; export let lightningBot: ILightningBot; let open_change_label = false; @@ -20,6 +22,7 @@ let new_label = ""; let error_notification = false; let message = ""; + let show_notification = false; function handleOpenChangeBotLabelModal() { open_change_label = true; @@ -38,6 +41,20 @@ id: lightningBot.id, new_label, }); + message = res.message; + if (res.success) { + const refresh = await fectAndRefreshLightningBotDetails(lightningBots); + if (!refresh.success) { + message = refresh.message; + error_notification = true; + return; + } + show_notification = true; + open_change_label = false; + new_label = ""; + } else { + error_notification = true; + } } catch (error) { console.log("Error trying to change label: ", error); message = "Error trying to change label"; @@ -60,6 +77,22 @@ /> {:else}
+ {#if show_notification} +
+ { + e.preventDefault(); + show_notification = false; + }} + fullWidth={true} + /> +
+ {/if}

Label: {lightningBot.label}

Public Key: +): Promise<{ success: boolean; message: string }> { + try { + let res = await get_lightning_bots_detail(); + let message = res.message; + if (res.success) { + if (res.data) { + lightningBots.set(res.data); + } + return { success: true, message }; + } else { + return { success: false, message }; + } + } catch (error) { + console.log("error: ", error); + return { + success: false, + message: "Error occured while trying to get lightning bots details", + }; + } +} From cf159ca2cccfc760c1e54c5173c7f5a14b12de6f Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Sat, 23 Nov 2024 01:59:55 +0100 Subject: [PATCH 08/12] chore[superadmin-frontend]: handle empty state when lightning bots do not exist --- src/bin/super/superapp/src/LightningBot.svelte | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bin/super/superapp/src/LightningBot.svelte b/src/bin/super/superapp/src/LightningBot.svelte index 7e1645c8..d56890d0 100644 --- a/src/bin/super/superapp/src/LightningBot.svelte +++ b/src/bin/super/superapp/src/LightningBot.svelte @@ -43,10 +43,14 @@ fullWidth={true} />

- {:else} + {:else if $lightningBots.length > 0} {#each $lightningBots as lightningBot} {/each} + {:else} +
+

No Lightning Bot available, Contact Admin to add Lightning bot

+
{/if} @@ -61,4 +65,14 @@ .success_toast_container { margin-bottom: 2rem; } + + .empty_state_container { + display: flex; + justify-content: center; + align-items: center; + } + + .empty_state_container p { + font-size: 1.5rem; + } From 9ba6e7a4132b08dcaffe4d63f2d0fa0fb661b692 Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Sat, 23 Nov 2024 02:24:00 +0100 Subject: [PATCH 09/12] chore[superadminfrontend]: remove over flow from app.css --- src/bin/super/superapp/src/app.css | 92 ++++++++++++++---------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/src/bin/super/superapp/src/app.css b/src/bin/super/superapp/src/app.css index d7d21889..879c74de 100644 --- a/src/bin/super/superapp/src/app.css +++ b/src/bin/super/superapp/src/app.css @@ -1,100 +1,96 @@ -@import url('https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); -html, body { - position: relative; - width: 100%; - height: 100%; - color: white; +html, +body { + position: relative; + width: 100%; + height: 100%; + color: white; } body { - margin: 0; - padding: 0px; - box-sizing: border-box; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - overflow: hidden; + margin: 0; + padding: 0px; + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } - html { - font-size: 13px; + font-size: 13px; } @media only screen and (min-width: 400px) { - html { - font-size: 16px; - } + html { + font-size: 16px; + } } @media only screen and (min-width: 768px) { - html { - font-size: 19px; - } + html { + font-size: 19px; + } } .bx--assistive-text { - font-size: 0.75rem !important; + font-size: 0.75rem !important; } - .bx--btn--selected { - background: #618AFF !important; + background: #618aff !important; } .bx--btn--selected:focus { - border-color: transparent !important; - box-shadow: none !important; + border-color: transparent !important; + box-shadow: none !important; } .bx--btn--primary { - background: #618AFF !important; + background: #618aff !important; } - .bx--btn--primary:hover { - background: #4574f7 !important; + background: #4574f7 !important; } .bx--btn--primary:disabled { - background: #525252 !important; + background: #525252 !important; } - -.bx--toggle-input:checked+.bx--toggle-input__label>.bx--toggle__switch::before { - background: #618AFF !important; +.bx--toggle-input:checked + + .bx--toggle-input__label + > .bx--toggle__switch::before { + background: #618aff !important; } - - .bx--tab-content { - padding: 0; + padding: 0; } .bx--tabs { - display: flex; - justify-content: center; + display: flex; + justify-content: center; } - .bx--modal-footer .bx--btn { - max-height: 42px; - display: flex; - align-items: center; - justify-content: center; - padding: 0; + max-height: 42px; + display: flex; + align-items: center; + justify-content: center; + padding: 0; } .bx--modal-footer .bx--btn.bx--btn--primary { - background: #618AFF !important; - width: 40%; - margin-right: 2.5rem; + background: #618aff !important; + width: 40%; + margin-right: 2.5rem; } .bx--modal-footer .bx--btn.bx--btn--primary:disabled { - background: #525252 !important; + background: #525252 !important; } .bx--modal-footer .bx--btn.bx--btn--secondary { - width: 40%; - margin-left: 2.5rem; + width: 40%; + margin-left: 2.5rem; } From 6a34a9c1ce773d8f654cf3f2497accb13a89fe27 Mon Sep 17 00:00:00 2001 From: Oluwatobi Bamidele Date: Mon, 25 Nov 2024 16:42:26 +0100 Subject: [PATCH 10/12] chore[superadmin-frontend]: added create invoice ui --- app/src/api/cmd.ts | 3 +- app/src/api/swarm.ts | 4 ++ .../src/components/LightningBotCard.svelte | 58 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/app/src/api/cmd.ts b/app/src/api/cmd.ts index a5937b2c..321f164c 100644 --- a/app/src/api/cmd.ts +++ b/app/src/api/cmd.ts @@ -97,7 +97,8 @@ export type Cmd = | "GetSwarmChildImageVersions" | "ChangeChildSwarmPassword" | "GetLightningBotsDetails" - | "ChangeLightningBotLabel"; + | "ChangeLightningBotLabel" + | "CreateInvoiceForLightningBot"; interface CmdData { cmd: Cmd; diff --git a/app/src/api/swarm.ts b/app/src/api/swarm.ts index ce4f8602..27a273b3 100644 --- a/app/src/api/swarm.ts +++ b/app/src/api/swarm.ts @@ -392,3 +392,7 @@ export async function change_lightning_bot_label({ }) { return await swarmCmd("ChangeLightningBotLabel", { id, new_label }); } + +export async function create_invoice_for_lightning_bot({id, amt_msat}: {id: string, amt_msat: number}) { + return await swarmCmd("CreateInvoiceForLightningBot", {id, amt_msat}) +} diff --git a/src/bin/super/superapp/src/components/LightningBotCard.svelte b/src/bin/super/superapp/src/components/LightningBotCard.svelte index a81724dc..661a29a6 100644 --- a/src/bin/super/superapp/src/components/LightningBotCard.svelte +++ b/src/bin/super/superapp/src/components/LightningBotCard.svelte @@ -23,6 +23,10 @@ let error_notification = false; let message = ""; let show_notification = false; + let open_create_invoice = false; + let amount = 0 + let show_invoice_notification = false + let invoice_success = false; function handleOpenChangeBotLabelModal() { open_change_label = true; @@ -63,11 +67,27 @@ isSubmitting = false; } } + + function handleOpenCreateInvoice() { + open_create_invoice = true + amount = 0 + } + + function handleCreateInvoice() { + try { + //convert amount to number, convert to milisats and send to the backend + } catch (error) { + + } finally { + isSubmitting = false + } + }
{#if lightningBot.error_message}
+

Label: {lightningBot.label}

handleOpenChangeBotLabelModal()} >Change Bot Label + +
{/if} @@ -152,6 +176,40 @@ /> + + (open_create_invoice = false)} + on:open + on:close={handleOnCloseChangeBotLabel} + on:submit={handleCreateInvoice} +> +{#if show_invoice_notification} + { + e.preventDefault(); + show_invoice_notification = false; + }} +/> +{/if} +
+ +
+
diff --git a/src/bin/super/superapp/yarn.lock b/src/bin/super/superapp/yarn.lock index cd21b877..88a7fee6 100644 --- a/src/bin/super/superapp/yarn.lock +++ b/src/bin/super/superapp/yarn.lock @@ -567,6 +567,11 @@ postcss@^8.4.21: picocolors "^1.0.0" source-map-js "^1.0.2" +qrious@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/qrious/-/qrious-4.0.2.tgz#09c4d4079d2b961617f62c69cff3b9bb66a39693" + integrity sha512-xWPJIrK1zu5Ypn898fBp8RHkT/9ibquV2Kv24S/JY9VYEhMBMKur1gHVsOiNUh7PHP9uCgejjpZUHUIXXKoU/g== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -708,6 +713,13 @@ svelte-preprocess@^4.0.0: sorcery "^0.10.0" strip-indent "^3.0.0" +svelte-qrcode@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/svelte-qrcode/-/svelte-qrcode-1.0.1.tgz#bb3bd167fac59e7a7455e5eb678b6e2b0f934f58" + integrity sha512-l1RcxDWkQqtBWUkolYee/IHGVKSgm1I2PdF8yVoIRqzKCc3kXpCXSVsMfrMSavWW2/BXvKu5Orv+JGbrO5onsw== + dependencies: + qrious "^4.0.2" + svelte@^3.55.1: version "3.58.0" resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.58.0.tgz#d3e6f103efd6129e51c7d709225ad3b4c052b64e"