warn about bad dns federations

This commit is contained in:
Paul Miller
2024-07-01 16:54:25 -05:00
parent c1445dcdc2
commit 625c0f6de7
7 changed files with 101 additions and 58 deletions

View File

@@ -40,7 +40,10 @@
"just_me": "Just Me", "just_me": "Just Me",
"friends": "Friends", "friends": "Friends",
"requests": "Requests" "requests": "Requests"
} },
"federations_warn_generic": "Due to temporary issues with your current federation, we recommend you transfer your funds to a lightning channel or withdraw to another bitcoin wallet.",
"transfer_lightning": "Transfer to lightning",
"sent_to_another_wallet": "Send to another wallet"
}, },
"profile": { "profile": {
"profile": "Profile", "profile": "Profile",
@@ -49,6 +52,7 @@
"edit_profile": "Edit Profile", "edit_profile": "Edit Profile",
"join_federation": "Join a federation", "join_federation": "Join a federation",
"manage_federation": "Manage Federations", "manage_federation": "Manage Federations",
"leave_federation": "Leave Federation",
"federated_custody": "Federated Custody", "federated_custody": "Federated Custody",
"self_custody": "Self Custody", "self_custody": "Self Custody",
"social": "Social", "social": "Social",

View File

@@ -1,6 +1,6 @@
import { TagItem } from "@mutinywallet/mutiny-wasm"; import { TagItem } from "@mutinywallet/mutiny-wasm";
import { cache, createAsync, useNavigate } from "@solidjs/router"; import { cache, createAsync, useNavigate } from "@solidjs/router";
import { Plus, Save, Search, Shuffle, Users } from "lucide-solid"; import { Plus, Save, Search, Shuffle } from "lucide-solid";
import { import {
createEffect, createEffect,
createMemo, createMemo,

View File

@@ -1,8 +1,13 @@
import { useNavigate } from "@solidjs/router"; import { useNavigate } from "@solidjs/router";
import { Users } from "lucide-solid"; import { ArrowLeftRight, ArrowUpRight, Users } from "lucide-solid";
import { createSignal } from "solid-js"; import { createSignal, Show } from "solid-js";
import { ButtonCard, NiceP, SimpleDialog } from "~/components/layout"; import {
ButtonCard,
ExternalLink,
NiceP,
SimpleDialog
} from "~/components/layout";
import { useI18n } from "~/i18n/context"; import { useI18n } from "~/i18n/context";
import { useMegaStore } from "~/state/megaStore"; import { useMegaStore } from "~/state/megaStore";
@@ -16,9 +21,11 @@ export function FederationPopup() {
const i18n = useI18n(); const i18n = useI18n();
const navigate = useNavigate(); const navigate = useNavigate();
const name = state.expiration_warning?.federationName;
return ( return (
<SimpleDialog <SimpleDialog
title={`${i18n.t("activity.federation_message")}: ${state.expiration_warning?.federationName}`} title={`${i18n.t("activity.federation_message")} ${name ? `: ${name}` : ""}`}
open={showFederationExpirationWarning()} open={showFederationExpirationWarning()}
setOpen={(open: boolean) => { setOpen={(open: boolean) => {
if (!open) { if (!open) {
@@ -27,7 +34,41 @@ export function FederationPopup() {
} }
}} }}
> >
<NiceP>{state.expiration_warning?.expiresMessage}</NiceP> <NiceP>
{state.expiration_warning?.expiresMessage ||
i18n.t("home.federations_warn_generic")}
</NiceP>
<Show when={!name}>
<NiceP>
<ExternalLink href="https://x.com/MutinyWallet/status/1805346636660429021">
{i18n.t("settings.manage_federations.learn_more")}
</ExternalLink>
</NiceP>
</Show>
<ButtonCard
onClick={() => {
actions.clearExpirationWarning();
setShowFederationExpirationWarning(false);
navigate("/swaplightning");
}}
>
<div class="flex items-center gap-2">
<ArrowLeftRight class="inline-block text-m-red" />
<NiceP>{i18n.t("home.transfer_lightning")}</NiceP>
</div>
</ButtonCard>
<ButtonCard
onClick={() => {
actions.clearExpirationWarning();
setShowFederationExpirationWarning(false);
navigate("/send");
}}
>
<div class="flex items-center gap-2">
<ArrowUpRight class="inline-block text-m-red" />
<NiceP>{i18n.t("home.sent_to_another_wallet")}</NiceP>
</div>
</ButtonCard>
<ButtonCard <ButtonCard
onClick={() => { onClick={() => {
actions.clearExpirationWarning(); actions.clearExpirationWarning();
@@ -37,7 +78,7 @@ export function FederationPopup() {
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<Users class="inline-block text-m-red" /> <Users class="inline-block text-m-red" />
<NiceP>{i18n.t("profile.manage_federation")}</NiceP> <NiceP>{i18n.t("profile.leave_federation")}</NiceP>
</div> </div>
</ButtonCard> </ButtonCard>
</SimpleDialog> </SimpleDialog>

View File

@@ -7,7 +7,7 @@ import {
} from "@modular-forms/solid"; } from "@modular-forms/solid";
import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm"; import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm";
import { A, useNavigate, useSearchParams } from "@solidjs/router"; import { A, useNavigate, useSearchParams } from "@solidjs/router";
import { ArrowLeftRight, BadgeCheck, LogOut, Scan, Trash } from "lucide-solid"; import { BadgeCheck, LogOut, Scan, Trash } from "lucide-solid";
import { import {
createMemo, createMemo,
createResource, createResource,
@@ -168,6 +168,8 @@ export function AddFederationForm(props: {
setSuccess( setSuccess(
i18n.t("settings.manage_federations.federation_added_success") i18n.t("settings.manage_federations.federation_added_success")
); );
// Reset the expiration warning seen state
actions.resetExpirationWarning();
await actions.refreshFederations(); await actions.refreshFederations();
if (props.refetch) { if (props.refetch) {
await props.refetch(); await props.refetch();
@@ -435,8 +437,7 @@ function FederationListItem(props: {
balance?: bigint; balance?: bigint;
}) { }) {
const i18n = useI18n(); const i18n = useI18n();
const [state, actions, sw] = useMegaStore(); const [_state, actions, sw] = useMegaStore();
const navigate = useNavigate();
async function removeFederation() { async function removeFederation() {
setConfirmLoading(true); setConfirmLoading(true);
@@ -455,15 +456,6 @@ function FederationListItem(props: {
const [transferDialogOpen, setTransferDialogOpen] = createSignal(false); const [transferDialogOpen, setTransferDialogOpen] = createSignal(false);
async function transferFunds() {
// If there's only one federation we need to let them know to add another
if (state.federations?.length && state.federations.length < 2) {
setTransferDialogOpen(true);
} else {
navigate("/transfer?from=" + props.fed.federation_id);
}
}
const [confirmOpen, setConfirmOpen] = createSignal(false); const [confirmOpen, setConfirmOpen] = createSignal(false);
const [confirmLoading, setConfirmLoading] = createSignal(false); const [confirmLoading, setConfirmLoading] = createSignal(false);
@@ -525,10 +517,6 @@ function FederationListItem(props: {
inviteCode={props.fed.invite_code} inviteCode={props.fed.invite_code}
/> />
</KeyValue> </KeyValue>
<SubtleButton onClick={transferFunds}>
<ArrowLeftRight class="h-4 w-4" />
{i18n.t("settings.manage_federations.transfer_funds")}
</SubtleButton>
<Suspense> <Suspense>
<RecommendButton fed={props.fed} /> <RecommendButton fed={props.fed} />
</Suspense> </Suspense>

View File

@@ -28,6 +28,7 @@ import {
BTC_OPTION, BTC_OPTION,
Currency, Currency,
eify, eify,
federationWarning,
subscriptionValid, subscriptionValid,
USD_OPTION USD_OPTION
} from "~/utils"; } from "~/utils";
@@ -302,23 +303,7 @@ export const makeMegaStoreContext = () => {
// Get federations // Get federations
const federations = await sw.list_federations(); const federations = await sw.list_federations();
let expiration_warning: const expiration_warning = federationWarning(federations);
| {
expiresTimestamp: number;
expiresMessage: string;
federationName: string;
}
| undefined = undefined;
federations.forEach((f) => {
if (f.popup_countdown_message && f.popup_end_timestamp) {
expiration_warning = {
expiresTimestamp: f.popup_end_timestamp,
expiresMessage: f.popup_countdown_message,
federationName: f.federation_name
};
}
});
setState({ setState({
wallet_loading: false, wallet_loading: false,
@@ -576,23 +561,7 @@ export const makeMegaStoreContext = () => {
async refreshFederations() { async refreshFederations() {
const federations = await sw.list_federations(); const federations = await sw.list_federations();
let expiration_warning: const expiration_warning = federationWarning(federations);
| {
expiresTimestamp: number;
expiresMessage: string;
federationName: string;
}
| undefined = undefined;
federations.forEach((f) => {
if (f.popup_countdown_message && f.popup_end_timestamp) {
expiration_warning = {
expiresTimestamp: f.popup_end_timestamp,
expiresMessage: f.popup_countdown_message,
federationName: f.federation_name
};
}
});
setState({ federations, expiration_warning }); setState({ federations, expiration_warning });
}, },
@@ -638,6 +607,9 @@ export const makeMegaStoreContext = () => {
// Only show the expiration warning once per session // Only show the expiration warning once per session
clearExpirationWarning() { clearExpirationWarning() {
setState({ expiration_warning_seen: true }); setState({ expiration_warning_seen: true });
},
resetExpirationWarning() {
setState({ expiration_warning_seen: false });
} }
}; };

View File

@@ -0,0 +1,37 @@
import { MutinyFederationIdentity } from "~/routes/settings";
export function federationWarning(federations: MutinyFederationIdentity[]) {
const FEDERATIONS_WITH_WARNINGS = [
// Freedom One
"c944b2fd1e7fe04ca87f9a57d7894cb69116cec6264cb52faa71228f4ec54cd6",
// Bitcoin Principles
"b21068c84f5b12ca4fdf93f3e443d3bd7c27e8642d0d52ea2e4dce6fdbbee9df"
];
let expiration_warning:
| {
expiresTimestamp: number;
expiresMessage: string;
federationName: string;
}
| undefined = undefined;
federations.forEach((f) => {
if (f.popup_countdown_message && f.popup_end_timestamp) {
expiration_warning = {
expiresTimestamp: f.popup_end_timestamp,
expiresMessage: f.popup_countdown_message,
federationName: f.federation_name
};
} else if (FEDERATIONS_WITH_WARNINGS.includes(f.federation_id)) {
// If the federation has no expiration warning we'll do a generic one
expiration_warning = {
expiresTimestamp: 0,
expiresMessage: "",
federationName: ""
};
}
});
return expiration_warning;
}

View File

@@ -21,3 +21,4 @@ export * from "./bech32";
export * from "./keypad"; export * from "./keypad";
export * from "./debounce"; export * from "./debounce";
export * from "./blobToBase64"; export * from "./blobToBase64";
export * from "./federationWarning";