From 3036759f44694dd37891b5717496264b58ee832e Mon Sep 17 00:00:00 2001 From: benthecarman Date: Thu, 11 Jul 2024 18:52:23 -0500 Subject: [PATCH] Fedimint resync --- src/components/SetupErrorDisplay.tsx | 8 ++ src/components/layout/Misc.tsx | 6 +- src/routes/settings/ManageFederations.tsx | 93 ++++++++++++++++++++++- src/workers/walletWorker.ts | 23 +++++- 4 files changed, 124 insertions(+), 6 deletions(-) diff --git a/src/components/SetupErrorDisplay.tsx b/src/components/SetupErrorDisplay.tsx index b8f8697b..d0a96c26 100644 --- a/src/components/SetupErrorDisplay.tsx +++ b/src/components/SetupErrorDisplay.tsx @@ -221,6 +221,14 @@ export function SetupErrorDisplay(props: { )} + + {i18n.t("error.on_boot.loading_failed.in_the_meantime")}{" "} + + {" "} + {i18n.t("error.on_boot.loading_failed.safe_mode")} + + . + diff --git a/src/components/layout/Misc.tsx b/src/components/layout/Misc.tsx index f9025d6f..592b7b6c 100644 --- a/src/components/layout/Misc.tsx +++ b/src/components/layout/Misc.tsx @@ -349,10 +349,10 @@ export function ModalCloseButton() { ); } -const SIMPLE_OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-lg"; -const SIMPLE_DIALOG_POSITIONER = +export const SIMPLE_OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-lg"; +export const SIMPLE_DIALOG_POSITIONER = "fixed inset-0 z-50 flex items-center justify-center"; -const SIMPLE_DIALOG_CONTENT = +export const SIMPLE_DIALOG_CONTENT = "max-w-[500px] w-[90vw] max-h-device overflow-y-scroll disable-scrollbars mx-4 p-4 bg-neutral-800/90 rounded-xl border border-white/10"; export const SimpleDialog: ParentComponent<{ diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx index 87dfca6b..e3e07477 100644 --- a/src/routes/settings/ManageFederations.tsx +++ b/src/routes/settings/ManageFederations.tsx @@ -1,3 +1,4 @@ +import { Progress } from "@kobalte/core"; import { createForm, required, @@ -7,7 +8,14 @@ import { } from "@modular-forms/solid"; import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm"; import { A, useNavigate, useSearchParams } from "@solidjs/router"; -import { ArrowLeftRight, BadgeCheck, LogOut, Scan, Trash } from "lucide-solid"; +import { + ArrowLeftRight, + BadgeCheck, + LogOut, + RefreshCw, + Scan, + Trash +} from "lucide-solid"; import { createResource, createSignal, @@ -45,7 +53,7 @@ import { } from "~/components"; import { useI18n } from "~/i18n/context"; import { useMegaStore } from "~/state/megaStore"; -import { eify, timeAgo } from "~/utils"; +import { eify, timeAgo, timeout } from "~/utils"; type FederationForm = { federation_code: string; @@ -68,6 +76,12 @@ export type Metadata = { about?: string; }; +export type ResyncProgress = { + total: number; + complete: number; + done: boolean; +}; + export type DiscoveredFederation = { id: string; invite_codes: string[]; @@ -298,6 +312,22 @@ function RecommendButton(props: { fed: MutinyFederationIdentity }) { ); } +function ResyncLoadingBar(props: { value: number; max: number }) { + return ( + + + + + + + ); +} + function FederationListItem(props: { fed: MutinyFederationIdentity; balance?: bigint; @@ -317,10 +347,37 @@ function FederationListItem(props: { setConfirmLoading(false); } + async function resyncFederation() { + setResyncLoading(true); + try { + await sw.resync_federation(props.fed.federation_id); + + for (let i = 0; i < 60; i++) { + await timeout(1000); + const progress = await sw.get_federation_resync_progress( + props.fed.federation_id + ); + console.log("progress", progress); + if (progress?.total !== 0) { + setResyncProgress(progress); + setResyncOpen(false); + break; + } + } + } catch (e) { + console.error(e); + setResyncLoading(false); + } + } + async function confirmRemove() { setConfirmOpen(true); } + async function confirmResync() { + setResyncOpen(true); + } + const [transferDialogOpen, setTransferDialogOpen] = createSignal(false); async function transferFunds() { @@ -335,6 +392,13 @@ function FederationListItem(props: { const [confirmOpen, setConfirmOpen] = createSignal(false); const [confirmLoading, setConfirmLoading] = createSignal(false); + const [resyncOpen, setResyncOpen] = createSignal(false); + const [resyncLoading, setResyncLoading] = createSignal(false); + + const [resyncProgress, setResyncProgress] = createSignal< + ResyncProgress | undefined + >(undefined); + return ( <> @@ -404,6 +468,12 @@ function FederationListItem(props: { {i18n.t("settings.manage_federations.remove")} + + + + Resync + + + setResyncOpen(false)} + > + Are you sure you want to resync this federation? This will + rescan the federation for your ecash, this can take multiple + hours in some cases. If you stop the rescan it can cause your + wallet to be bricked. Please be sure you can run the rescan + before you start it. + + {/* todo put this in a dialog */} + + + ); } diff --git a/src/workers/walletWorker.ts b/src/workers/walletWorker.ts index 338b5102..0b0c86dd 100644 --- a/src/workers/walletWorker.ts +++ b/src/workers/walletWorker.ts @@ -25,7 +25,8 @@ import { MutinyWalletSettingStrings } from "~/logic/mutinyWalletSetup"; import { FakeDirectMessage, OnChainTx } from "~/routes"; import { DiscoveredFederation, - MutinyFederationIdentity + MutinyFederationIdentity, + ResyncProgress } from "~/routes/settings"; const RELEASE_VERSION = import.meta.env.__RELEASE_VERSION__; @@ -1201,6 +1202,26 @@ export async function remove_federation(federation_id: string): Promise { await wallet!.remove_federation(federation_id); } +/** + * Resyncs a federation + * @param {string} federation_id + * @returns {Promise} + */ +export async function resync_federation(federation_id: string): Promise { + await wallet!.resync_federation(federation_id); +} + +/** + * Gets the resync progress for a federation + * @param {string} federation_id + * @returns {Promise} + */ +export async function get_federation_resync_progress( + federation_id: string +): Promise { + return wallet!.get_federation_resync_progress(federation_id); +} + /** * Opens a channel from our selected node to the given pubkey. * The amount is in satoshis.