mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2025-12-18 14:54:26 +01:00
export * from ~/components
This commit is contained in:
@@ -1,183 +0,0 @@
|
|||||||
import { NiceP } from "./layout";
|
|
||||||
import {
|
|
||||||
For,
|
|
||||||
Match,
|
|
||||||
Show,
|
|
||||||
Switch,
|
|
||||||
createEffect,
|
|
||||||
createResource,
|
|
||||||
createSignal
|
|
||||||
} from "solid-js";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
|
||||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
|
||||||
import { ActivityItem, HackActivityType } from "./ActivityItem";
|
|
||||||
import { DetailsIdModal } from "./DetailsModal";
|
|
||||||
import { A } from "solid-start";
|
|
||||||
import { LoadingShimmer } from "./BalanceBox";
|
|
||||||
import { createDeepSignal } from "~/utils/deepSignal";
|
|
||||||
|
|
||||||
export const THREE_COLUMNS =
|
|
||||||
"grid grid-cols-[auto,1fr,auto] gap-4 py-2 px-2 border-b border-neutral-800 last:border-b-0";
|
|
||||||
export const CENTER_COLUMN = "min-w-0 overflow-hidden max-w-full";
|
|
||||||
export const MISSING_LABEL =
|
|
||||||
"py-1 px-2 bg-white/10 rounded inline-block text-sm";
|
|
||||||
export const REDSHIFT_LABEL =
|
|
||||||
"py-1 px-2 bg-white text-m-red rounded inline-block text-sm";
|
|
||||||
export const RIGHT_COLUMN = "flex flex-col items-right text-right max-w-[8rem]";
|
|
||||||
|
|
||||||
export type OnChainTx = {
|
|
||||||
txid: string;
|
|
||||||
received: number;
|
|
||||||
sent: number;
|
|
||||||
fee?: number;
|
|
||||||
confirmation_time?: {
|
|
||||||
Confirmed?: {
|
|
||||||
height: number;
|
|
||||||
time: number;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
labels: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UtxoItem = {
|
|
||||||
outpoint: string;
|
|
||||||
txout: {
|
|
||||||
value: number;
|
|
||||||
script_pubkey: string;
|
|
||||||
};
|
|
||||||
keychain: string;
|
|
||||||
is_spent: boolean;
|
|
||||||
redshifted?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ActivityItem = {
|
|
||||||
kind: HackActivityType;
|
|
||||||
id: string;
|
|
||||||
amount_sats: number;
|
|
||||||
inbound: boolean;
|
|
||||||
labels: string[];
|
|
||||||
contacts: Contact[];
|
|
||||||
last_updated: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
function UnifiedActivityItem(props: {
|
|
||||||
item: ActivityItem;
|
|
||||||
onClick: (id: string, kind: HackActivityType) => void;
|
|
||||||
}) {
|
|
||||||
const click = () => {
|
|
||||||
props.onClick(
|
|
||||||
props.item.id,
|
|
||||||
props.item.kind as unknown as HackActivityType
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ActivityItem
|
|
||||||
// This is actually the ActivityType enum but wasm is hard
|
|
||||||
kind={props.item.kind as unknown as HackActivityType}
|
|
||||||
labels={props.item.labels}
|
|
||||||
contacts={props.item.contacts}
|
|
||||||
// FIXME: is this something we can put into node logic?
|
|
||||||
amount={props.item.amount_sats || 0}
|
|
||||||
date={props.item.last_updated}
|
|
||||||
positive={props.item.inbound}
|
|
||||||
onClick={click}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function CombinedActivity(props: { limit?: number }) {
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
const i18n = useI18n();
|
|
||||||
|
|
||||||
const [detailsOpen, setDetailsOpen] = createSignal(false);
|
|
||||||
const [detailsKind, setDetailsKind] = createSignal<HackActivityType>();
|
|
||||||
const [detailsId, setDetailsId] = createSignal("");
|
|
||||||
|
|
||||||
function openDetailsModal(id: string, kind: HackActivityType) {
|
|
||||||
console.log("Opening details modal: ", id, kind);
|
|
||||||
|
|
||||||
// Some old channels don't have a channel id in the activity list
|
|
||||||
if (!id) {
|
|
||||||
console.warn("No id provided to openDetailsModal");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDetailsId(id);
|
|
||||||
setDetailsKind(kind);
|
|
||||||
setDetailsOpen(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchActivity() {
|
|
||||||
return await state.mutiny_wallet?.get_activity();
|
|
||||||
}
|
|
||||||
|
|
||||||
const [activity, { refetch }] = createResource(fetchActivity, {
|
|
||||||
storage: createDeepSignal
|
|
||||||
});
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
// Should re-run after every sync
|
|
||||||
if (!state.is_syncing) {
|
|
||||||
refetch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Show
|
|
||||||
when={activity.state === "ready" || activity.state === "refreshing"}
|
|
||||||
fallback={<LoadingShimmer />}
|
|
||||||
>
|
|
||||||
<Show when={detailsId() && detailsKind()}>
|
|
||||||
<DetailsIdModal
|
|
||||||
open={detailsOpen()}
|
|
||||||
kind={detailsKind()}
|
|
||||||
id={detailsId()}
|
|
||||||
setOpen={setDetailsOpen}
|
|
||||||
/>
|
|
||||||
</Show>
|
|
||||||
<Switch>
|
|
||||||
<Match when={activity.latest.length === 0}>
|
|
||||||
<div class="w-full text-center pb-4">
|
|
||||||
<NiceP>
|
|
||||||
{i18n.t(
|
|
||||||
"activity.receive_some_sats_to_get_started"
|
|
||||||
)}
|
|
||||||
</NiceP>
|
|
||||||
</div>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={props.limit && activity.latest.length > props.limit}
|
|
||||||
>
|
|
||||||
<For each={activity.latest.slice(0, props.limit)}>
|
|
||||||
{(activityItem) => (
|
|
||||||
<UnifiedActivityItem
|
|
||||||
item={activityItem}
|
|
||||||
onClick={openDetailsModal}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</Match>
|
|
||||||
<Match when={activity.latest.length >= 0}>
|
|
||||||
<For each={activity.latest}>
|
|
||||||
{(activityItem) => (
|
|
||||||
<UnifiedActivityItem
|
|
||||||
item={activityItem}
|
|
||||||
onClick={openDetailsModal}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
<Show when={props.limit && activity.latest.length > 0}>
|
|
||||||
<A
|
|
||||||
href="/activity"
|
|
||||||
class="text-m-red active:text-m-red/80 font-semibold no-underline self-center"
|
|
||||||
>
|
|
||||||
{i18n.t("activity.view_all")}
|
|
||||||
</A>
|
|
||||||
</Show>
|
|
||||||
</Show>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ import { generateGradient } from "~/utils/gradientHash";
|
|||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { AmountFiat, AmountSats } from "~/components/Amount";
|
import { AmountFiat, AmountSats } from "~/components";
|
||||||
|
|
||||||
export const ActivityAmount: ParentComponent<{
|
export const ActivityAmount: ParentComponent<{
|
||||||
amount: string;
|
amount: string;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { Match, ParentComponent, Show, Switch, createMemo } from "solid-js";
|
import { Match, ParentComponent, Show, Switch, createMemo } from "solid-js";
|
||||||
import { Card, VStack } from "~/components/layout";
|
import { Card, VStack, AmountEditable } from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { satsToUsd } from "~/utils/conversions";
|
import { satsToUsd } from "~/utils/conversions";
|
||||||
import { AmountEditable } from "./AmountEditable";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
const noop = () => {
|
const noop = () => {
|
||||||
|
|||||||
@@ -9,18 +9,15 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Match
|
Match
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { Button } from "~/components/layout";
|
import { Button, InlineAmount, InfoBox, FeesModal } from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { satsToUsd, usdToSats } from "~/utils/conversions";
|
import { satsToUsd, usdToSats } from "~/utils/conversions";
|
||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import close from "~/assets/icons/close.svg";
|
import close from "~/assets/icons/close.svg";
|
||||||
import pencil from "~/assets/icons/pencil.svg";
|
import pencil from "~/assets/icons/pencil.svg";
|
||||||
import currencySwap from "~/assets/icons/currency-swap.svg";
|
import currencySwap from "~/assets/icons/currency-swap.svg";
|
||||||
import { InlineAmount } from "./AmountCard";
|
|
||||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||||
import { InfoBox } from "./InfoBox";
|
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
import { Network } from "~/logic/mutinyWalletSetup";
|
||||||
import { FeesModal } from "./MoreInfoModal";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { useNavigate } from "solid-start";
|
import { useNavigate } from "solid-start";
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
import { DefaultMain, SafeArea, VStack, Card } from "~/components/layout";
|
import {
|
||||||
import BalanceBox, { LoadingShimmer } from "~/components/BalanceBox";
|
DefaultMain,
|
||||||
import NavBar from "~/components/NavBar";
|
SafeArea,
|
||||||
import ReloadPrompt from "~/components/Reload";
|
VStack,
|
||||||
|
Card,
|
||||||
|
LoadingShimmer,
|
||||||
|
BalanceBox,
|
||||||
|
ReloadPrompt,
|
||||||
|
NavBar,
|
||||||
|
OnboardWarning,
|
||||||
|
CombinedActivity,
|
||||||
|
BetaWarningModal,
|
||||||
|
PendingNwc,
|
||||||
|
DecryptDialog,
|
||||||
|
LoadingIndicator
|
||||||
|
} from "~/components";
|
||||||
import { A } from "solid-start";
|
import { A } from "solid-start";
|
||||||
import { OnboardWarning } from "~/components/OnboardWarning";
|
|
||||||
import { CombinedActivity } from "./Activity";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Match, Show, Suspense, Switch } from "solid-js";
|
import { Match, Show, Suspense, Switch } from "solid-js";
|
||||||
import { BetaWarningModal } from "~/components/BetaWarningModal";
|
|
||||||
import settings from "~/assets/icons/settings.svg";
|
import settings from "~/assets/icons/settings.svg";
|
||||||
import pixelLogo from "~/assets/mutiny-pixel-logo.png";
|
import pixelLogo from "~/assets/mutiny-pixel-logo.png";
|
||||||
import plusLogo from "~/assets/mutiny-plus-logo.png";
|
import plusLogo from "~/assets/mutiny-plus-logo.png";
|
||||||
import { PendingNwc } from "./PendingNwc";
|
|
||||||
import { DecryptDialog } from "./DecryptDialog";
|
|
||||||
import { LoadingIndicator } from "./LoadingIndicator";
|
|
||||||
import { FeedbackLink } from "~/routes/Feedback";
|
import { FeedbackLink } from "~/routes/Feedback";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export default function App() {
|
export function App() {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const [state, _actions] = useMegaStore();
|
const [state, _actions] = useMegaStore();
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
import { Match, Show, Switch } from "solid-js";
|
import { Match, Show, Switch } from "solid-js";
|
||||||
import { Button, FancyCard, Indicator } from "~/components/layout";
|
import {
|
||||||
|
Button,
|
||||||
|
FancyCard,
|
||||||
|
Indicator,
|
||||||
|
AmountSats,
|
||||||
|
AmountFiat,
|
||||||
|
InfoBox
|
||||||
|
} from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { AmountSats, AmountFiat } from "./Amount";
|
|
||||||
import { A, useNavigate } from "solid-start";
|
import { A, useNavigate } from "solid-start";
|
||||||
import shuffle from "~/assets/icons/shuffle.svg";
|
import shuffle from "~/assets/icons/shuffle.svg";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { InfoBox } from "./InfoBox";
|
|
||||||
|
|
||||||
export function LoadingShimmer() {
|
export function LoadingShimmer() {
|
||||||
return (
|
return (
|
||||||
@@ -23,7 +28,7 @@ export function LoadingShimmer() {
|
|||||||
const STYLE =
|
const STYLE =
|
||||||
"px-2 py-1 rounded-xl text-sm flex gap-2 items-center font-semibold";
|
"px-2 py-1 rounded-xl text-sm flex gap-2 items-center font-semibold";
|
||||||
|
|
||||||
export default function BalanceBox(props: { loading?: boolean }) {
|
export function BalanceBox(props: { loading?: boolean }) {
|
||||||
const [state, _actions] = useMegaStore();
|
const [state, _actions] = useMegaStore();
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import { ParentComponent, createSignal } from "solid-js";
|
import { ParentComponent, createSignal } from "solid-js";
|
||||||
import { DIALOG_CONTENT, DIALOG_POSITIONER, OVERLAY } from "./DetailsModal";
|
import {
|
||||||
import { ModalCloseButton, SmallHeader } from "./layout";
|
DIALOG_CONTENT,
|
||||||
|
DIALOG_POSITIONER,
|
||||||
|
OVERLAY,
|
||||||
|
ModalCloseButton,
|
||||||
|
SmallHeader
|
||||||
|
} from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { Match, Switch, createSignal } from "solid-js";
|
import { Match, Switch, createSignal } from "solid-js";
|
||||||
import { SmallHeader, TinyButton } from "~/components/layout";
|
|
||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import close from "~/assets/icons/close.svg";
|
import close from "~/assets/icons/close.svg";
|
||||||
import { SubmitHandler } from "@modular-forms/solid";
|
import { SubmitHandler } from "@modular-forms/solid";
|
||||||
import { ContactForm } from "./ContactForm";
|
import {
|
||||||
import { ContactFormValues } from "./ContactViewer";
|
ContactFormValues,
|
||||||
|
ContactForm,
|
||||||
|
SmallHeader,
|
||||||
|
TinyButton
|
||||||
|
} from "~/components";
|
||||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { SubmitHandler, createForm, required } from "@modular-forms/solid";
|
import { SubmitHandler, createForm, required } from "@modular-forms/solid";
|
||||||
import { Button, LargeHeader, VStack } from "~/components/layout";
|
import {
|
||||||
import { TextField } from "~/components/layout/TextField";
|
Button,
|
||||||
import { ContactFormValues } from "./ContactViewer";
|
LargeHeader,
|
||||||
|
VStack,
|
||||||
|
TextField,
|
||||||
|
ContactFormValues
|
||||||
|
} from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export function ContactForm(props: {
|
export function ContactForm(props: {
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
import { Match, Switch, createSignal } from "solid-js";
|
import { Match, Switch, createSignal } from "solid-js";
|
||||||
import { Button, Card, NiceP, SmallHeader } from "~/components/layout";
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
NiceP,
|
||||||
|
SmallHeader,
|
||||||
|
ContactForm,
|
||||||
|
showToast
|
||||||
|
} from "~/components";
|
||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import close from "~/assets/icons/close.svg";
|
import close from "~/assets/icons/close.svg";
|
||||||
import { SubmitHandler } from "@modular-forms/solid";
|
import { SubmitHandler } from "@modular-forms/solid";
|
||||||
import { ContactForm } from "./ContactForm";
|
|
||||||
import { showToast } from "./Toaster";
|
|
||||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { Show, createSignal } from "solid-js";
|
import { Show, createSignal } from "solid-js";
|
||||||
import { Button, SimpleDialog } from "~/components/layout";
|
import { Button, SimpleDialog, TextField, InfoBox } from "~/components";
|
||||||
import { TextField } from "~/components/layout/TextField";
|
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { A } from "solid-start";
|
import { A } from "solid-start";
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||||
import { createSignal } from "solid-js";
|
import { createSignal } from "solid-js";
|
||||||
import { ConfirmDialog } from "~/components/Dialog";
|
import { ConfirmDialog, Button, showToast } from "~/components";
|
||||||
import { Button } from "~/components/layout";
|
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
|
|||||||
@@ -1,510 +0,0 @@
|
|||||||
import { Dialog } from "@kobalte/core";
|
|
||||||
import {
|
|
||||||
For,
|
|
||||||
Match,
|
|
||||||
ParentComponent,
|
|
||||||
Show,
|
|
||||||
Suspense,
|
|
||||||
Switch,
|
|
||||||
createEffect,
|
|
||||||
createMemo,
|
|
||||||
createResource
|
|
||||||
} from "solid-js";
|
|
||||||
import { Hr, ModalCloseButton, TinyButton, VStack } from "~/components/layout";
|
|
||||||
import { MutinyChannel, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
|
||||||
import { OnChainTx } from "./Activity";
|
|
||||||
|
|
||||||
import bolt from "~/assets/icons/bolt-black.svg";
|
|
||||||
import chain from "~/assets/icons/chain-black.svg";
|
|
||||||
import copyIcon from "~/assets/icons/copy.svg";
|
|
||||||
import shuffle from "~/assets/icons/shuffle-black.svg";
|
|
||||||
|
|
||||||
import { ActivityAmount, HackActivityType } from "./ActivityItem";
|
|
||||||
import { CopyButton, TruncateMiddle } from "./ShareCard";
|
|
||||||
import { prettyPrintTime } from "~/utils/prettyPrintTime";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
|
||||||
import { MutinyTagItem, tagToMutinyTag } from "~/utils/tags";
|
|
||||||
import { useCopy } from "~/utils/useCopy";
|
|
||||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
|
||||||
import { AmountSmall } from "./Amount";
|
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
|
||||||
import { InfoBox } from "./InfoBox";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
|
||||||
|
|
||||||
type ChannelClosure = {
|
|
||||||
channel_id: string;
|
|
||||||
node_id: string;
|
|
||||||
reason: string;
|
|
||||||
timestamp: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
|
|
||||||
export const DIALOG_POSITIONER =
|
|
||||||
"fixed inset-0 z-50 flex items-center justify-center";
|
|
||||||
export const DIALOG_CONTENT =
|
|
||||||
"max-w-[500px] w-[90vw] max-h-[100dvh] overflow-y-scroll disable-scrollbars mx-4 p-4 bg-neutral-800/80 backdrop-blur-md shadow-xl rounded-xl border border-white/10";
|
|
||||||
|
|
||||||
function LightningHeader(props: {
|
|
||||||
info: MutinyInvoice;
|
|
||||||
tags: MutinyTagItem[];
|
|
||||||
}) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="flex flex-col items-center gap-4">
|
|
||||||
<div class="p-4 bg-neutral-100 rounded-full">
|
|
||||||
<img src={bolt} alt="lightning bolt" class="w-8 h-8" />
|
|
||||||
</div>
|
|
||||||
<h1 class="uppercase font-semibold">
|
|
||||||
{props.info.inbound
|
|
||||||
? i18n.t("modals.transaction_details.lightning_receive")
|
|
||||||
: i18n.t("modals.transaction_details.lightning_send")}
|
|
||||||
</h1>
|
|
||||||
<ActivityAmount
|
|
||||||
center
|
|
||||||
amount={props.info.amount_sats?.toString() ?? "0"}
|
|
||||||
price={state.price}
|
|
||||||
positive={props.info.inbound}
|
|
||||||
/>
|
|
||||||
<For each={props.tags}>
|
|
||||||
{(tag) => (
|
|
||||||
<TinyButton
|
|
||||||
tag={tag}
|
|
||||||
onClick={() => {
|
|
||||||
// noop
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{tag.name}
|
|
||||||
</TinyButton>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function OnchainHeader(props: {
|
|
||||||
info: OnChainTx;
|
|
||||||
tags: MutinyTagItem[];
|
|
||||||
kind?: HackActivityType;
|
|
||||||
}) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
const isSend = () => {
|
|
||||||
return props.info.sent > props.info.received;
|
|
||||||
};
|
|
||||||
|
|
||||||
const amount = () => {
|
|
||||||
if (isSend()) {
|
|
||||||
return (props.info.sent - props.info.received).toString();
|
|
||||||
} else {
|
|
||||||
return (props.info.received - props.info.sent).toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="flex flex-col items-center gap-4">
|
|
||||||
<div class="p-4 bg-neutral-100 rounded-full">
|
|
||||||
<Switch>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
props.kind === "ChannelOpen" ||
|
|
||||||
props.kind === "ChannelClose"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<img src={shuffle} alt="swap" class="w-8 h-8" />
|
|
||||||
</Match>
|
|
||||||
<Match when={true}>
|
|
||||||
<img src={chain} alt="blockchain" class="w-8 h-8" />
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</div>
|
|
||||||
<h1 class="uppercase font-semibold">
|
|
||||||
{props.kind === "ChannelOpen"
|
|
||||||
? i18n.t("modals.transaction_details.channel_open")
|
|
||||||
: props.kind === "ChannelClose"
|
|
||||||
? i18n.t("modals.transaction_details.channel_close")
|
|
||||||
: isSend()
|
|
||||||
? i18n.t("modals.transaction_details.onchain_send")
|
|
||||||
: i18n.t("modals.transaction_details.onchain_receive")}
|
|
||||||
</h1>
|
|
||||||
<Show when={props.kind !== "ChannelClose"}>
|
|
||||||
<ActivityAmount
|
|
||||||
center
|
|
||||||
amount={amount() ?? "0"}
|
|
||||||
price={state.price}
|
|
||||||
positive={!isSend()}
|
|
||||||
/>
|
|
||||||
</Show>
|
|
||||||
<For each={props.tags}>
|
|
||||||
{(tag) => (
|
|
||||||
<TinyButton
|
|
||||||
tag={tag}
|
|
||||||
onClick={() => {
|
|
||||||
// noop
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{tag.name}
|
|
||||||
</TinyButton>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const KeyValue: ParentComponent<{ key: string }> = (props) => {
|
|
||||||
return (
|
|
||||||
<li class="flex justify-between items-center gap-4">
|
|
||||||
<span class="uppercase font-semibold whitespace-nowrap text-sm">
|
|
||||||
{props.key}
|
|
||||||
</span>
|
|
||||||
<span class="font-light">{props.children}</span>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function MiniStringShower(props: { text: string }) {
|
|
||||||
const [copy, copied] = useCopy({ copiedTimeout: 1000 });
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="w-full grid gap-1 grid-cols-[minmax(0,_1fr)_auto]">
|
|
||||||
<TruncateMiddle text={props.text} />
|
|
||||||
{/* <pre class="truncate text-neutral-300 font-light">{props.text}</pre> */}
|
|
||||||
<button
|
|
||||||
class="w-[1.5rem] p-1"
|
|
||||||
classList={{ "bg-m-green rounded": copied() }}
|
|
||||||
onClick={() => copy(props.text)}
|
|
||||||
>
|
|
||||||
<img src={copyIcon} alt="copy" class="w-4 h-4" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function LightningDetails(props: { info: MutinyInvoice }) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
return (
|
|
||||||
<VStack>
|
|
||||||
<ul class="flex flex-col gap-4">
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.status")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
{props.info.paid
|
|
||||||
? i18n.t("modals.transaction_details.paid")
|
|
||||||
: i18n.t("modals.transaction_details.unpaid")}
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.when")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
{prettyPrintTime(Number(props.info.last_updated))}
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
<Show when={props.info.description}>
|
|
||||||
<KeyValue
|
|
||||||
key={i18n.t("modals.transaction_details.description")}
|
|
||||||
>
|
|
||||||
<span class="text-neutral-300 truncate">
|
|
||||||
{props.info.description}
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
</Show>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.fees")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
<AmountSmall amountSats={props.info.fees_paid} />
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.bolt11")}>
|
|
||||||
<MiniStringShower text={props.info.bolt11 ?? ""} />
|
|
||||||
</KeyValue>
|
|
||||||
<KeyValue
|
|
||||||
key={i18n.t("modals.transaction_details.payment_hash")}
|
|
||||||
>
|
|
||||||
<MiniStringShower text={props.info.payment_hash ?? ""} />
|
|
||||||
</KeyValue>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.preimage")}>
|
|
||||||
<MiniStringShower text={props.info.preimage ?? ""} />
|
|
||||||
</KeyValue>
|
|
||||||
</ul>
|
|
||||||
</VStack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function OnchainDetails(props: { info: OnChainTx; kind?: HackActivityType }) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
const confirmationTime = () => {
|
|
||||||
return props.info.confirmation_time?.Confirmed?.time;
|
|
||||||
};
|
|
||||||
|
|
||||||
const network = state.mutiny_wallet?.get_network() as Network;
|
|
||||||
|
|
||||||
// Can return nothing if the channel is already closed
|
|
||||||
const [channelInfo] = createResource(async () => {
|
|
||||||
if (props.kind === "ChannelOpen") {
|
|
||||||
try {
|
|
||||||
const channels =
|
|
||||||
await (state.mutiny_wallet?.list_channels() as Promise<
|
|
||||||
MutinyChannel[]
|
|
||||||
>);
|
|
||||||
const channel = channels.find((channel) =>
|
|
||||||
channel.outpoint?.startsWith(props.info.txid)
|
|
||||||
);
|
|
||||||
return channel;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<VStack>
|
|
||||||
{/* <pre>{JSON.stringify(channelInfo() || "", null, 2)}</pre> */}
|
|
||||||
<ul class="flex flex-col gap-4">
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.status")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
{confirmationTime()
|
|
||||||
? i18n.t("modals.transaction_details.confirmed")
|
|
||||||
: i18n.t("modals.transaction_details.unconfirmed")}
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
<Show when={confirmationTime()}>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.when")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
{confirmationTime()
|
|
||||||
? prettyPrintTime(Number(confirmationTime()))
|
|
||||||
: "Pending"}
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
</Show>
|
|
||||||
<Show when={props.info.fee && props.info.fee > 0}>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.fee")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
<AmountSmall amountSats={props.info.fee} />
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
</Show>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.txid")}>
|
|
||||||
<MiniStringShower text={props.info.txid ?? ""} />
|
|
||||||
</KeyValue>
|
|
||||||
<Switch>
|
|
||||||
<Match when={props.kind === "ChannelOpen" && channelInfo()}>
|
|
||||||
<KeyValue
|
|
||||||
key={i18n.t("modals.transaction_details.balance")}
|
|
||||||
>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
<AmountSmall
|
|
||||||
amountSats={channelInfo()?.balance}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
<KeyValue
|
|
||||||
key={i18n.t("modals.transaction_details.reserve")}
|
|
||||||
>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
<AmountSmall
|
|
||||||
amountSats={channelInfo()?.reserve}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
<KeyValue
|
|
||||||
key={i18n.t("modals.transaction_details.peer")}
|
|
||||||
>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
<MiniStringShower
|
|
||||||
text={channelInfo()?.peer ?? ""}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
</Match>
|
|
||||||
<Match when={props.kind === "ChannelOpen"}>
|
|
||||||
<InfoBox accent="blue">
|
|
||||||
{i18n.t("modals.transaction_details.no_details")}
|
|
||||||
</InfoBox>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</ul>
|
|
||||||
<div class="text-center">
|
|
||||||
<ExternalLink href={mempoolTxUrl(props.info.txid, network)}>
|
|
||||||
{i18n.t("common.view_transaction")}
|
|
||||||
</ExternalLink>
|
|
||||||
</div>
|
|
||||||
</VStack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ChannelCloseDetails(props: { info: ChannelClosure }) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
return (
|
|
||||||
<VStack>
|
|
||||||
{/* <pre>{JSON.stringify(props.info.value, null, 2)}</pre> */}
|
|
||||||
<ul class="flex flex-col gap-4">
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.channel_id")}>
|
|
||||||
<MiniStringShower text={props.info.channel_id ?? ""} />
|
|
||||||
</KeyValue>
|
|
||||||
<Show when={props.info.timestamp}>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.when")}>
|
|
||||||
<span class="text-neutral-300">
|
|
||||||
{props.info.timestamp
|
|
||||||
? prettyPrintTime(Number(props.info.timestamp))
|
|
||||||
: i18n.t("common.pending")}
|
|
||||||
</span>
|
|
||||||
</KeyValue>
|
|
||||||
</Show>
|
|
||||||
<KeyValue key={i18n.t("modals.transaction_details.reason")}>
|
|
||||||
<p class="text-neutral-300 text-right">
|
|
||||||
{props.info.reason ?? ""}
|
|
||||||
</p>
|
|
||||||
</KeyValue>
|
|
||||||
</ul>
|
|
||||||
</VStack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DetailsIdModal(props: {
|
|
||||||
open: boolean;
|
|
||||||
kind?: HackActivityType;
|
|
||||||
id: string;
|
|
||||||
setOpen: (open: boolean) => void;
|
|
||||||
}) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
const id = () => props.id;
|
|
||||||
const kind = () => props.kind;
|
|
||||||
|
|
||||||
// TODO: is there a cleaner way to do refetch when id changes?
|
|
||||||
const [data, { refetch }] = createResource(async () => {
|
|
||||||
try {
|
|
||||||
if (kind() === "Lightning") {
|
|
||||||
console.debug("reading invoice: ", id());
|
|
||||||
const invoice = await state.mutiny_wallet?.get_invoice_by_hash(
|
|
||||||
id()
|
|
||||||
);
|
|
||||||
return invoice;
|
|
||||||
} else if (kind() === "ChannelClose") {
|
|
||||||
console.debug("reading channel close: ", id());
|
|
||||||
const closeItem =
|
|
||||||
await state.mutiny_wallet?.get_channel_closure(id());
|
|
||||||
|
|
||||||
return closeItem;
|
|
||||||
} else {
|
|
||||||
console.debug("reading tx: ", id());
|
|
||||||
const tx = await state.mutiny_wallet?.get_transaction(id());
|
|
||||||
|
|
||||||
return tx;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const tags = createMemo(() => {
|
|
||||||
if (data() && data().labels && data().labels.length > 0) {
|
|
||||||
try {
|
|
||||||
const contact = state.mutiny_wallet?.get_contact(
|
|
||||||
data().labels[0]
|
|
||||||
);
|
|
||||||
if (contact) {
|
|
||||||
return [tagToMutinyTag(contact)];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
if (props.id && props.kind && props.open) {
|
|
||||||
refetch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const json = createMemo(() => JSON.stringify(data() || "", null, 2));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog.Root open={props.open} onOpenChange={props.setOpen}>
|
|
||||||
<Dialog.Portal>
|
|
||||||
<Dialog.Overlay class={OVERLAY} />
|
|
||||||
<div class={DIALOG_POSITIONER}>
|
|
||||||
<Dialog.Content class={DIALOG_CONTENT}>
|
|
||||||
<Suspense>
|
|
||||||
<div class="flex justify-between mb-2">
|
|
||||||
<div />
|
|
||||||
<Dialog.CloseButton>
|
|
||||||
<ModalCloseButton />
|
|
||||||
</Dialog.CloseButton>
|
|
||||||
</div>
|
|
||||||
<Dialog.Title>
|
|
||||||
<Switch>
|
|
||||||
<Match when={props.kind === "Lightning"}>
|
|
||||||
<LightningHeader
|
|
||||||
info={data() as MutinyInvoice}
|
|
||||||
tags={tags()}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
props.kind === "OnChain" ||
|
|
||||||
props.kind === "ChannelOpen" ||
|
|
||||||
props.kind === "ChannelClose"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<OnchainHeader
|
|
||||||
info={data() as OnChainTx}
|
|
||||||
tags={tags()}
|
|
||||||
kind={props.kind}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</Dialog.Title>
|
|
||||||
<Hr />
|
|
||||||
<Dialog.Description class="flex flex-col gap-4">
|
|
||||||
<Switch>
|
|
||||||
<Match when={props.kind === "Lightning"}>
|
|
||||||
<LightningDetails
|
|
||||||
info={data() as MutinyInvoice}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
props.kind === "OnChain" ||
|
|
||||||
props.kind === "ChannelOpen"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<OnchainDetails
|
|
||||||
info={data() as OnChainTx}
|
|
||||||
kind={props.kind}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
<Match when={props.kind === "ChannelClose"}>
|
|
||||||
<ChannelCloseDetails
|
|
||||||
info={data() as ChannelClosure}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
<Show when={props.kind !== "ChannelClose"}>
|
|
||||||
<div class="flex justify-center">
|
|
||||||
<CopyButton
|
|
||||||
title={i18n.t("common.copy")}
|
|
||||||
text={json()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
</Dialog.Description>
|
|
||||||
</Suspense>
|
|
||||||
</Dialog.Content>
|
|
||||||
</div>
|
|
||||||
</Dialog.Portal>
|
|
||||||
</Dialog.Root>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import { ParentComponent } from "solid-js";
|
import { ParentComponent } from "solid-js";
|
||||||
import { Button, SmallHeader } from "./layout";
|
import { Button, SmallHeader } from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
|
const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export default function ErrorDisplay(props: { error: Error }) {
|
export function ErrorDisplay(props: { error: Error }) {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
return (
|
return (
|
||||||
<SafeArea>
|
<SafeArea>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { AmountFiat, AmountSats } from "~/components/Amount";
|
import { AmountFiat, AmountSats, FeesModal } from "~/components";
|
||||||
import { FeesModal } from "~/components/MoreInfoModal";
|
|
||||||
|
|
||||||
export function Fee(props: { amountSats?: bigint | number }) {
|
export function Fee(props: { amountSats?: bigint | number }) {
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ParentComponent, Show, createResource } from "solid-js";
|
import { ParentComponent, Show, createResource } from "solid-js";
|
||||||
import { I18nContext } from "../i18n/context";
|
import { I18nContext } from "~/i18n/context";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import i18nConfig from "~/i18n/config";
|
import i18nConfig from "~/i18n/config";
|
||||||
|
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ import {
|
|||||||
InnerCard,
|
InnerCard,
|
||||||
NiceP,
|
NiceP,
|
||||||
SimpleDialog,
|
SimpleDialog,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
ConfirmDialog,
|
||||||
|
showToast,
|
||||||
|
InfoBox,
|
||||||
|
TextField
|
||||||
|
} from "~/components";
|
||||||
import { Show, createSignal } from "solid-js";
|
import { Show, createSignal } from "solid-js";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { showToast } from "./Toaster";
|
|
||||||
import { downloadTextFile } from "~/utils/download";
|
import { downloadTextFile } from "~/utils/download";
|
||||||
import { createFileUploader } from "@solid-primitives/upload";
|
import { createFileUploader } from "@solid-primitives/upload";
|
||||||
import { ConfirmDialog } from "./Dialog";
|
|
||||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||||
import { InfoBox } from "./InfoBox";
|
|
||||||
import { TextField } from "./layout/TextField";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export function ImportExport(props: { emergency?: boolean }) {
|
export function ImportExport(props: { emergency?: boolean }) {
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import { Match, Show, Switch } from "solid-js";
|
|||||||
import { QRCodeSVG } from "solid-qr-code";
|
import { QRCodeSVG } from "solid-qr-code";
|
||||||
import { ReceiveFlavor } from "~/routes/Receive";
|
import { ReceiveFlavor } from "~/routes/Receive";
|
||||||
import { useCopy } from "~/utils/useCopy";
|
import { useCopy } from "~/utils/useCopy";
|
||||||
import { AmountSats, AmountFiat } from "./Amount";
|
import { AmountSats, AmountFiat, TruncateMiddle } from "~/components";
|
||||||
import { TruncateMiddle } from "./ShareCard";
|
|
||||||
import copyBlack from "~/assets/icons/copy-black.svg";
|
import copyBlack from "~/assets/icons/copy-black.svg";
|
||||||
import shareBlack from "~/assets/icons/share-black.svg";
|
import shareBlack from "~/assets/icons/share-black.svg";
|
||||||
import chainBlack from "~/assets/icons/chain-black.svg";
|
import chainBlack from "~/assets/icons/chain-black.svg";
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import { JSX, createMemo } from "solid-js";
|
import { JSX, createMemo } from "solid-js";
|
||||||
import { ModalCloseButton, SmallHeader } from "~/components/layout";
|
|
||||||
import {
|
import {
|
||||||
|
ModalCloseButton,
|
||||||
|
SmallHeader,
|
||||||
DIALOG_CONTENT,
|
DIALOG_CONTENT,
|
||||||
DIALOG_POSITIONER,
|
DIALOG_POSITIONER,
|
||||||
OVERLAY
|
OVERLAY,
|
||||||
} from "~/components/DetailsModal";
|
CopyButton
|
||||||
import { CopyButton } from "./ShareCard";
|
} from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export function JsonModal(props: {
|
export function JsonModal(props: {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Hr, Button, InnerCard, VStack } from "~/components/layout";
|
|
||||||
import {
|
import {
|
||||||
For,
|
For,
|
||||||
Match,
|
Match,
|
||||||
@@ -13,14 +12,20 @@ import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
|
|||||||
import { Collapsible, TextField } from "@kobalte/core";
|
import { Collapsible, TextField } from "@kobalte/core";
|
||||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { ConfirmDialog } from "~/components/Dialog";
|
import {
|
||||||
import { showToast } from "~/components/Toaster";
|
ConfirmDialog,
|
||||||
|
Hr,
|
||||||
|
Button,
|
||||||
|
InnerCard,
|
||||||
|
VStack,
|
||||||
|
showToast,
|
||||||
|
Restart,
|
||||||
|
ResyncOnchain,
|
||||||
|
ResetRouter,
|
||||||
|
MiniStringShower
|
||||||
|
} from "~/components";
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
import { Network } from "~/logic/mutinyWalletSetup";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { Restart } from "./Restart";
|
|
||||||
import { ResyncOnchain } from "./ResyncOnchain";
|
|
||||||
import { ResetRouter } from "./ResetRouter";
|
|
||||||
import { MiniStringShower } from "./DetailsModal";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
// TODO: hopefully I don't have to maintain this type forever but I don't know how to pass it around otherwise
|
// TODO: hopefully I don't have to maintain this type forever but I don't know how to pass it around otherwise
|
||||||
@@ -451,7 +456,7 @@ function ListNodes() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function KitchenSink() {
|
export function KitchenSink() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ListNodes />
|
<ListNodes />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||||
import { InnerCard, NiceP, VStack, Button } from "~/components/layout";
|
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { downloadTextFile } from "~/utils/download";
|
import { downloadTextFile } from "~/utils/download";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import { ParentComponent, createSignal, JSXElement } from "solid-js";
|
import { ParentComponent, createSignal, JSXElement } from "solid-js";
|
||||||
import { DIALOG_CONTENT, DIALOG_POSITIONER, OVERLAY } from "./DetailsModal";
|
import {
|
||||||
import { ModalCloseButton, SmallHeader } from "./layout";
|
DIALOG_CONTENT,
|
||||||
|
DIALOG_POSITIONER,
|
||||||
|
OVERLAY,
|
||||||
|
ModalCloseButton,
|
||||||
|
SmallHeader
|
||||||
|
} from "~/components";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import help from "~/assets/icons/help.svg";
|
import help from "~/assets/icons/help.svg";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ function NavBarItem(props: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function NavBar(props: { activeTab: ActiveTab }) {
|
export function NavBar(props: { activeTab: ActiveTab }) {
|
||||||
return (
|
return (
|
||||||
<nav class="hidden md:block fixed shadow-none z-40 safe-bottom top-0 bottom-auto left-0 h-full">
|
<nav class="hidden md:block fixed shadow-none z-40 safe-bottom top-0 bottom-auto left-0 h-full">
|
||||||
<ul class="flex flex-col justify-start gap-4 px-4 mt-4">
|
<ul class="flex flex-col justify-start gap-4 px-4 mt-4">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Show } from "solid-js";
|
import { Show } from "solid-js";
|
||||||
import { ButtonLink, SmallHeader } from "./layout";
|
import { ButtonLink, SmallHeader } from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import save from "~/assets/icons/save.svg";
|
import save from "~/assets/icons/save.svg";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
||||||
import { formatExpiration } from "~/utils/prettyPrintTime";
|
import { formatExpiration } from "~/utils/prettyPrintTime";
|
||||||
import { Card, VStack } from "./layout";
|
import { Card, VStack, ActivityAmount, InfoBox } from "~/components";
|
||||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||||
import bolt from "~/assets/icons/bolt.svg";
|
import bolt from "~/assets/icons/bolt.svg";
|
||||||
import {
|
import {
|
||||||
@@ -16,8 +16,6 @@ import { useMegaStore } from "~/state/megaStore";
|
|||||||
|
|
||||||
import greenCheck from "~/assets/icons/green-check.svg";
|
import greenCheck from "~/assets/icons/green-check.svg";
|
||||||
import redClose from "~/assets/icons/red-close.svg";
|
import redClose from "~/assets/icons/red-close.svg";
|
||||||
import { ActivityAmount } from "./ActivityItem";
|
|
||||||
import { InfoBox } from "./InfoBox";
|
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { A } from "solid-start";
|
import { A } from "solid-start";
|
||||||
import { createDeepSignal } from "~/utils/deepSignal";
|
import { createDeepSignal } from "~/utils/deepSignal";
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
import QrScanner from "qr-scanner";
|
import QrScanner from "qr-scanner";
|
||||||
import { Capacitor } from "@capacitor/core";
|
import { Capacitor } from "@capacitor/core";
|
||||||
|
|
||||||
export default function Scanner(props: { onResult: (result: string) => void }) {
|
export function Scanner(props: { onResult: (result: string) => void }) {
|
||||||
let container: HTMLVideoElement | undefined;
|
let container: HTMLVideoElement | undefined;
|
||||||
let scanner: QrScanner | undefined;
|
let scanner: QrScanner | undefined;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import type { Component } from "solid-js";
|
|
||||||
import { Show } from "solid-js";
|
import { Show } from "solid-js";
|
||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import { useRegisterSW } from "virtual:pwa-register/solid";
|
import { useRegisterSW } from "virtual:pwa-register/solid";
|
||||||
|
|
||||||
const ReloadPrompt: Component = () => {
|
export function ReloadPrompt() {
|
||||||
const {
|
const {
|
||||||
offlineReady: [offlineReady, _setOfflineReady],
|
offlineReady: [offlineReady, _setOfflineReady],
|
||||||
needRefresh: [needRefresh, _setNeedRefresh],
|
needRefresh: [needRefresh, _setNeedRefresh],
|
||||||
@@ -41,6 +40,4 @@ const ReloadPrompt: Component = () => {
|
|||||||
</Card> */}
|
</Card> */}
|
||||||
</Show>
|
</Show>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default ReloadPrompt;
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Button, InnerCard, NiceP, VStack } from "~/components/layout";
|
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createSignal } from "solid-js";
|
import { createSignal } from "solid-js";
|
||||||
import { Button, InnerCard, NiceP, VStack } from "~/components/layout";
|
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Button, InnerCard, NiceP, VStack } from "~/components/layout";
|
import { Button, InnerCard, NiceP, VStack } from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import {
|
|||||||
LargeHeader,
|
LargeHeader,
|
||||||
NiceP,
|
NiceP,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
SmallHeader
|
SmallHeader,
|
||||||
} from "~/components/layout";
|
ImportExport,
|
||||||
|
Logs,
|
||||||
|
DeleteEverything
|
||||||
|
} from "~/components";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { Match, Switch } from "solid-js";
|
import { Match, Switch } from "solid-js";
|
||||||
import { ImportExport } from "./ImportExport";
|
|
||||||
import { Logs } from "./Logs";
|
|
||||||
import { DeleteEverything } from "./DeleteEverything";
|
|
||||||
import { FeedbackLink } from "~/routes/Feedback";
|
import { FeedbackLink } from "~/routes/Feedback";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ function ErrorFooter() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SetupErrorDisplay(props: { initialError: Error }) {
|
export function SetupErrorDisplay(props: { initialError: Error }) {
|
||||||
// Error shouldn't be reactive, so we assign to it so it just gets rendered with the first value
|
// Error shouldn't be reactive, so we assign to it so it just gets rendered with the first value
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const error = props.initialError;
|
const error = props.initialError;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Card, VStack } from "~/components/layout";
|
import { Card, VStack, JsonModal } from "~/components";
|
||||||
import { useCopy } from "~/utils/useCopy";
|
import { useCopy } from "~/utils/useCopy";
|
||||||
import copyIcon from "~/assets/icons/copy.svg";
|
import copyIcon from "~/assets/icons/copy.svg";
|
||||||
import copyBlack from "~/assets/icons/copy-black.svg";
|
import copyBlack from "~/assets/icons/copy-black.svg";
|
||||||
@@ -6,7 +6,6 @@ import shareIcon from "~/assets/icons/share.svg";
|
|||||||
import shareBlack from "~/assets/icons/share-black.svg";
|
import shareBlack from "~/assets/icons/share-black.svg";
|
||||||
import eyeIcon from "~/assets/icons/eye.svg";
|
import eyeIcon from "~/assets/icons/eye.svg";
|
||||||
import { Show, createSignal } from "solid-js";
|
import { Show, createSignal } from "solid-js";
|
||||||
import { JsonModal } from "./JsonModal";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
const STYLE =
|
const STYLE =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Select, createOptions } from "@thisbeyond/solid-select";
|
import { Select, createOptions } from "@thisbeyond/solid-select";
|
||||||
import "~/styles/solid-select.css";
|
import "~/styles/solid-select.css";
|
||||||
import { For, Show, createMemo, createSignal, onMount } from "solid-js";
|
import { For, Show, createMemo, createSignal, onMount } from "solid-js";
|
||||||
import { TinyButton } from "./layout";
|
import { TinyButton } from "~/components";
|
||||||
import { MutinyTagItem, sortByLastUsed } from "~/utils/tags";
|
import { MutinyTagItem, sortByLastUsed } from "~/utils/tags";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Toast, toaster } from "@kobalte/core";
|
import { Toast, toaster } from "@kobalte/core";
|
||||||
import { Portal } from "solid-js/web";
|
import { Portal } from "solid-js/web";
|
||||||
import close from "~/assets/icons/close.svg";
|
import close from "~/assets/icons/close.svg";
|
||||||
import { SmallHeader } from "./layout";
|
import { SmallHeader } from "~/components";
|
||||||
|
|
||||||
export function Toaster() {
|
export function Toaster() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
43
src/components/index.ts
Normal file
43
src/components/index.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
export * from "./layout";
|
||||||
|
export * from "./successfail";
|
||||||
|
|
||||||
|
export * from "./Activity";
|
||||||
|
export * from "./ActivityItem";
|
||||||
|
export * from "./Amount";
|
||||||
|
export * from "./AmountCard";
|
||||||
|
export * from "./AmountEditable";
|
||||||
|
export * from "./App";
|
||||||
|
export * from "./BalanceBox";
|
||||||
|
export * from "./BetaWarningModal";
|
||||||
|
export * from "./ContactEditor";
|
||||||
|
export * from "./ContactForm";
|
||||||
|
export * from "./ContactViewer";
|
||||||
|
export * from "./CopyableQR";
|
||||||
|
export * from "./DecryptDialog";
|
||||||
|
export * from "./DeleteEverything";
|
||||||
|
export * from "./DetailsModal";
|
||||||
|
export * from "./Dialog";
|
||||||
|
export * from "./ErrorDisplay";
|
||||||
|
export * from "./Fee";
|
||||||
|
export * from "./I18nProvider";
|
||||||
|
export * from "./ImportExport";
|
||||||
|
export * from "./InfoBox";
|
||||||
|
export * from "./IntegratedQR";
|
||||||
|
export * from "./JsonModal";
|
||||||
|
export * from "./KitchenSink";
|
||||||
|
export * from "./LoadingIndicator";
|
||||||
|
export * from "./Logs";
|
||||||
|
export * from "./MoreInfoModal";
|
||||||
|
export * from "./NavBar";
|
||||||
|
export * from "./OnboardWarning";
|
||||||
|
export * from "./PendingNwc";
|
||||||
|
export * from "./Reader";
|
||||||
|
export * from "./Reload";
|
||||||
|
export * from "./ResetRouter";
|
||||||
|
export * from "./Restart";
|
||||||
|
export * from "./ResyncOnchain";
|
||||||
|
export * from "./SeedWords";
|
||||||
|
export * from "./SetupErrorDisplay";
|
||||||
|
export * from "./ShareCard";
|
||||||
|
export * from "./TagEditor";
|
||||||
|
export * from "./Toaster";
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useLocation, useNavigate } from "solid-start";
|
import { useLocation, useNavigate } from "solid-start";
|
||||||
import { BackButton } from "./BackButton";
|
import { BackButton } from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
type StateWithPrevious = {
|
type StateWithPrevious = {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ interface LinkifyProps {
|
|||||||
initialText: string;
|
initialText: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Linkify(props: LinkifyProps): JSX.Element {
|
export function Linkify(props: LinkifyProps): JSX.Element {
|
||||||
// By naming this "initialText" we can prove to eslint that the props won't change
|
// By naming this "initialText" we can prove to eslint that the props won't change
|
||||||
const text = props.initialText;
|
const text = props.initialText;
|
||||||
const links: (string | JSX.Element)[] = [];
|
const links: (string | JSX.Element)[] = [];
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import {
|
|||||||
createResource,
|
createResource,
|
||||||
createSignal
|
createSignal
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import Linkify from "./Linkify";
|
|
||||||
import { Button, ButtonLink } from "./Button";
|
|
||||||
import {
|
import {
|
||||||
Collapsible,
|
Collapsible,
|
||||||
Checkbox as KCheckbox,
|
Checkbox as KCheckbox,
|
||||||
@@ -23,13 +21,10 @@ import { generateGradient } from "~/utils/gradientHash";
|
|||||||
import close from "~/assets/icons/close.svg";
|
import close from "~/assets/icons/close.svg";
|
||||||
import { A } from "solid-start";
|
import { A } from "solid-start";
|
||||||
import down from "~/assets/icons/down.svg";
|
import down from "~/assets/icons/down.svg";
|
||||||
import { DecryptDialog } from "../DecryptDialog";
|
import { LoadingIndicator, DecryptDialog } from "~/components";
|
||||||
import { LoadingIndicator } from "~/components/LoadingIndicator";
|
|
||||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export { Button, ButtonLink, Linkify };
|
|
||||||
|
|
||||||
export const SmallHeader: ParentComponent<{ class?: string }> = (props) => {
|
export const SmallHeader: ParentComponent<{ class?: string }> = (props) => {
|
||||||
return (
|
return (
|
||||||
<header class={`text-sm font-semibold uppercase ${props.class}`}>
|
<header class={`text-sm font-semibold uppercase ${props.class}`}>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Progress } from "@kobalte/core";
|
import { Progress } from "@kobalte/core";
|
||||||
import { SmallHeader } from ".";
|
import { SmallHeader } from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export default function formatNumber(num: number) {
|
export function formatNumber(num: number) {
|
||||||
const map = [
|
const map = [
|
||||||
{ suffix: "T", threshold: 1e12 },
|
{ suffix: "T", threshold: 1e12 },
|
||||||
{ suffix: "B", threshold: 1e9 },
|
{ suffix: "B", threshold: 1e9 },
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { TextField as KTextField } from "@kobalte/core";
|
import { TextField as KTextField } from "@kobalte/core";
|
||||||
import { type JSX, Show, splitProps } from "solid-js";
|
import { type JSX, Show, splitProps } from "solid-js";
|
||||||
import { TinyText } from ".";
|
import { TinyText } from "~/components";
|
||||||
|
|
||||||
export type TextFieldProps = {
|
export type TextFieldProps = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
9
src/components/layout/index.ts
Normal file
9
src/components/layout/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export * from "./BackButton";
|
||||||
|
export * from "./BackLink";
|
||||||
|
export * from "./BackPop";
|
||||||
|
export * from "./Button";
|
||||||
|
export * from "./Linkify";
|
||||||
|
export * from "./Misc";
|
||||||
|
export * from "./ProgressBar";
|
||||||
|
export * from "./Radio";
|
||||||
|
export * from "./TextField";
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Dialog } from "@kobalte/core";
|
import { Dialog } from "@kobalte/core";
|
||||||
import { JSX } from "solid-js";
|
import { JSX } from "solid-js";
|
||||||
import { Button } from "~/components/layout";
|
import { Button } from "~/components";
|
||||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
|
|||||||
3
src/components/successfail/index.ts
Normal file
3
src/components/successfail/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./MegaCheck";
|
||||||
|
export * from "./MegaEx";
|
||||||
|
export * from "./SuccessModal";
|
||||||
@@ -15,9 +15,7 @@ import {
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
import "@mutinywallet/ui/style.css";
|
import "@mutinywallet/ui/style.css";
|
||||||
import { Provider as MegaStoreProvider } from "~/state/megaStore";
|
import { Provider as MegaStoreProvider } from "~/state/megaStore";
|
||||||
import { Toaster } from "~/components/Toaster";
|
import { Toaster, ErrorDisplay, I18nProvider } from "~/components";
|
||||||
import ErrorDisplay from "./components/ErrorDisplay";
|
|
||||||
import { I18nProvider } from "./components/I18nProvider";
|
|
||||||
|
|
||||||
export default function Root() {
|
export default function Root() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { For, Show, Suspense, createResource } from "solid-js";
|
import { For, Show, Suspense, createResource } from "solid-js";
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -8,18 +7,20 @@ import {
|
|||||||
NiceP,
|
NiceP,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
NavBar,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
BackLink,
|
||||||
import { CombinedActivity } from "~/components/Activity";
|
CombinedActivity,
|
||||||
|
ContactEditor,
|
||||||
|
ContactFormValues,
|
||||||
|
ContactViewer,
|
||||||
|
showToast,
|
||||||
|
LoadingShimmer
|
||||||
|
} from "~/components";
|
||||||
import { Tabs } from "@kobalte/core";
|
import { Tabs } from "@kobalte/core";
|
||||||
import { gradientsPerContact } from "~/utils/gradientHash";
|
import { gradientsPerContact } from "~/utils/gradientHash";
|
||||||
import { ContactEditor } from "~/components/ContactEditor";
|
|
||||||
import { ContactFormValues, ContactViewer } from "~/components/ContactViewer";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import { LoadingShimmer } from "~/components/BalanceBox";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
function ContactRow() {
|
function ContactRow() {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
} from "@modular-forms/solid";
|
} from "@modular-forms/solid";
|
||||||
import { Match, Show, Switch, createSignal } from "solid-js";
|
import { Match, Show, Switch, createSignal } from "solid-js";
|
||||||
import { A, useLocation } from "solid-start";
|
import { A, useLocation } from "solid-start";
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
ButtonLink,
|
ButtonLink,
|
||||||
@@ -17,17 +16,16 @@ import {
|
|||||||
LargeHeader,
|
LargeHeader,
|
||||||
NiceP,
|
NiceP,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack
|
VStack,
|
||||||
|
BackPop,
|
||||||
|
StyledRadioGroup,
|
||||||
|
TextField
|
||||||
} from "~/components/layout";
|
} from "~/components/layout";
|
||||||
import { BackPop } from "~/components/layout/BackPop";
|
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { StyledRadioGroup } from "~/components/layout/Radio";
|
|
||||||
import { TextField } from "~/components/layout/TextField";
|
|
||||||
import feedback from "~/assets/icons/feedback.svg";
|
import feedback from "~/assets/icons/feedback.svg";
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { MegaCheck } from "~/components/successfail/MegaCheck";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
import { InfoBox, MegaCheck, NavBar } from "~/components";
|
||||||
|
|
||||||
const FEEDBACK_API = import.meta.env.VITE_FEEDBACK;
|
const FEEDBACK_API = import.meta.env.VITE_FEEDBACK;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ import {
|
|||||||
Show,
|
Show,
|
||||||
Switch
|
Switch
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
|
import { objectToSearchParams } from "~/utils/objectToSearchParams";
|
||||||
|
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||||
|
import { useNavigate } from "solid-start";
|
||||||
import {
|
import {
|
||||||
|
Fee,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
@@ -21,33 +26,29 @@ import {
|
|||||||
LargeHeader,
|
LargeHeader,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
SimpleDialog
|
SimpleDialog,
|
||||||
} from "~/components/layout";
|
NavBar,
|
||||||
|
AmountSats,
|
||||||
|
AmountFiat,
|
||||||
|
BackLink,
|
||||||
|
TagEditor,
|
||||||
|
StyledRadioGroup,
|
||||||
|
showToast,
|
||||||
|
AmountCard,
|
||||||
|
BackButton,
|
||||||
|
SuccessModal,
|
||||||
|
MegaCheck,
|
||||||
|
InfoBox,
|
||||||
|
FeesModal,
|
||||||
|
IntegratedQr
|
||||||
|
} from "~/components";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
|
||||||
import { objectToSearchParams } from "~/utils/objectToSearchParams";
|
|
||||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
|
||||||
import { AmountSats, AmountFiat } from "~/components/Amount";
|
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
|
||||||
import { TagEditor } from "~/components/TagEditor";
|
|
||||||
import { StyledRadioGroup } from "~/components/layout/Radio";
|
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import { useNavigate } from "solid-start";
|
|
||||||
import { AmountCard } from "~/components/AmountCard";
|
|
||||||
import { BackButton } from "~/components/layout/BackButton";
|
|
||||||
import { MutinyTagItem } from "~/utils/tags";
|
import { MutinyTagItem } from "~/utils/tags";
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
import { Network } from "~/logic/mutinyWalletSetup";
|
||||||
import { SuccessModal } from "~/components/successfail/SuccessModal";
|
|
||||||
import { MegaCheck } from "~/components/successfail/MegaCheck";
|
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import { FeesModal } from "~/components/MoreInfoModal";
|
|
||||||
import { IntegratedQr } from "~/components/IntegratedQR";
|
|
||||||
import side2side from "~/assets/icons/side-to-side.svg";
|
import side2side from "~/assets/icons/side-to-side.svg";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { matchError } from "~/logic/errorDispatch";
|
import { matchError } from "~/logic/errorDispatch";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { Fee } from "~/components/Fee";
|
|
||||||
|
|
||||||
type OnChainTx = {
|
type OnChainTx = {
|
||||||
transaction: {
|
transaction: {
|
||||||
|
|||||||
@@ -1,644 +0,0 @@
|
|||||||
import {
|
|
||||||
createEffect,
|
|
||||||
createMemo,
|
|
||||||
createResource,
|
|
||||||
createSignal,
|
|
||||||
For,
|
|
||||||
Match,
|
|
||||||
onMount,
|
|
||||||
ParentComponent,
|
|
||||||
Show,
|
|
||||||
Suspense,
|
|
||||||
Switch
|
|
||||||
} from "solid-js";
|
|
||||||
import {
|
|
||||||
CENTER_COLUMN,
|
|
||||||
MISSING_LABEL,
|
|
||||||
REDSHIFT_LABEL,
|
|
||||||
RIGHT_COLUMN,
|
|
||||||
THREE_COLUMNS,
|
|
||||||
UtxoItem
|
|
||||||
} from "~/components/Activity";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
DefaultMain,
|
|
||||||
LargeHeader,
|
|
||||||
NiceP,
|
|
||||||
MutinyWalletGuard,
|
|
||||||
SafeArea,
|
|
||||||
SmallAmount,
|
|
||||||
SmallHeader,
|
|
||||||
VStack
|
|
||||||
} from "~/components/layout";
|
|
||||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
|
||||||
import { StyledRadioGroup } from "~/components/layout/Radio";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
|
||||||
import wave from "~/assets/wave.gif";
|
|
||||||
import utxoIcon from "~/assets/icons/coin.svg";
|
|
||||||
import { ProgressBar } from "~/components/layout/ProgressBar";
|
|
||||||
import { MutinyChannel } from "@mutinywallet/mutiny-wasm";
|
|
||||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
|
||||||
import { AmountSats } from "~/components/Amount";
|
|
||||||
import { getRedshifted, setRedshifted } from "~/utils/fakeLabels";
|
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
|
||||||
|
|
||||||
type ShiftOption = "utxo" | "lightning";
|
|
||||||
|
|
||||||
type ShiftStage = "choose" | "observe" | "success" | "failure";
|
|
||||||
|
|
||||||
type OutPoint = string; // Replace with the actual TypeScript type for OutPoint
|
|
||||||
type RedshiftStatus = string; // Replace with the actual TypeScript type for RedshiftStatus
|
|
||||||
type RedshiftRecipient = unknown; // Replace with the actual TypeScript type for RedshiftRecipient
|
|
||||||
type PublicKey = unknown; // Replace with the actual TypeScript type for PublicKey
|
|
||||||
|
|
||||||
interface RedshiftResult {
|
|
||||||
id: string;
|
|
||||||
input_utxo: OutPoint;
|
|
||||||
status: RedshiftStatus;
|
|
||||||
recipient: RedshiftRecipient;
|
|
||||||
output_utxo?: OutPoint;
|
|
||||||
introduction_channel?: OutPoint;
|
|
||||||
output_channel?: OutPoint;
|
|
||||||
introduction_node: PublicKey;
|
|
||||||
amount_sats: bigint;
|
|
||||||
change_amt?: bigint;
|
|
||||||
fees_paid: bigint;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dummyRedshift: RedshiftResult = {
|
|
||||||
id: "44036599c37d590899e8d5d920860286",
|
|
||||||
input_utxo:
|
|
||||||
"44036599c37d590899e8d5d92086028695d2c2966fdc354ce1da9a9eac610a53:1",
|
|
||||||
status: "Completed", // Replace with a dummy value for RedshiftStatus
|
|
||||||
recipient: {}, // Replace with a dummy value for RedshiftRecipient
|
|
||||||
output_utxo:
|
|
||||||
"44036599c37d590899e8d5d92086028695d2c2966fdc354ce1da9a9eac610a53:1",
|
|
||||||
introduction_channel:
|
|
||||||
"a7773e57f8595848a635e9af105927cac9ecaf292d71a76456ae0455bd3c9c64:0",
|
|
||||||
output_channel:
|
|
||||||
"a7773e57f8595848a635e9af105927cac9ecaf292d71a76456ae0455bd3c9c64:0",
|
|
||||||
introduction_node: {}, // Replace with a dummy value for PublicKey
|
|
||||||
amount_sats: BigInt(1000000),
|
|
||||||
change_amt: BigInt(12345),
|
|
||||||
fees_paid: BigInt(2500)
|
|
||||||
};
|
|
||||||
|
|
||||||
function RedshiftReport(props: { redshift: RedshiftResult; utxo: UtxoItem }) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
const getUtXos = async () => {
|
|
||||||
console.log("Getting utxos");
|
|
||||||
return (await state.mutiny_wallet?.list_utxos()) as UtxoItem[];
|
|
||||||
};
|
|
||||||
|
|
||||||
// function findUtxoByOutpoint(
|
|
||||||
// outpoint?: string,
|
|
||||||
// utxos: UtxoItem[] = []
|
|
||||||
// ): UtxoItem | undefined {
|
|
||||||
// if (!outpoint) return undefined
|
|
||||||
// return utxos.find((utxo) => utxo.outpoint === outpoint)
|
|
||||||
// }
|
|
||||||
|
|
||||||
const [_utxos, { refetch: _refetchUtxos }] = createResource(getUtXos);
|
|
||||||
|
|
||||||
// const inputUtxo = createMemo(() => {
|
|
||||||
// console.log(utxos())
|
|
||||||
// const foundUtxo = findUtxoByOutpoint(props.redshift.input_utxo, utxos())
|
|
||||||
// console.log("Found utxo:", foundUtxo)
|
|
||||||
// return foundUtxo
|
|
||||||
// })
|
|
||||||
|
|
||||||
const [redshiftResource, { refetch: _refetchRedshift }] = createResource(
|
|
||||||
async () => {
|
|
||||||
console.log("Checking redshift", props.redshift.id);
|
|
||||||
const redshift = await state.mutiny_wallet?.get_redshift(
|
|
||||||
props.redshift.id
|
|
||||||
);
|
|
||||||
console.log(redshift);
|
|
||||||
return redshift;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
onMount(() => {
|
|
||||||
// const interval = setInterval(() => {
|
|
||||||
// if (redshiftResource()) refetch()
|
|
||||||
// // if (sentAmount() === 200000) {
|
|
||||||
// // clearInterval(interval)
|
|
||||||
// // props.setShiftStage("success");
|
|
||||||
// // // setSentAmount((0))
|
|
||||||
// // } else {
|
|
||||||
// // setSentAmount((sentAmount() + 50000))
|
|
||||||
// // }
|
|
||||||
// }, 1000)
|
|
||||||
});
|
|
||||||
|
|
||||||
// const outputUtxo = createMemo(() => {
|
|
||||||
// return findUtxoByOutpoint(redshiftResource()?.output_utxo, utxos())
|
|
||||||
// })
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
setRedshifted(true, redshiftResource()?.output_utxo);
|
|
||||||
});
|
|
||||||
|
|
||||||
const network = state.mutiny_wallet?.get_network() as Network;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<VStack biggap>
|
|
||||||
{/* <VStack>
|
|
||||||
<NiceP>We did it. Here's your new UTXO:</NiceP>
|
|
||||||
<Show when={utxos() && outputUtxo()}>
|
|
||||||
<Card>
|
|
||||||
<Utxo item={outputUtxo()!} />
|
|
||||||
</Card>
|
|
||||||
</Show>
|
|
||||||
</VStack> */}
|
|
||||||
<VStack>
|
|
||||||
<NiceP>{i18n.t("redshift.what_happened")}</NiceP>
|
|
||||||
<Show when={redshiftResource()}>
|
|
||||||
<Card>
|
|
||||||
<VStack biggap>
|
|
||||||
{/* <KV key="Input utxo">
|
|
||||||
<Show when={utxos() && inputUtxo()}>
|
|
||||||
<Utxo item={inputUtxo()!} />
|
|
||||||
</Show>
|
|
||||||
</KV> */}
|
|
||||||
<KV key={i18n.t("redshift.starting_amount")}>
|
|
||||||
<AmountSats
|
|
||||||
amountSats={redshiftResource()!.amount_sats}
|
|
||||||
/>
|
|
||||||
</KV>
|
|
||||||
<KV key={i18n.t("redshift.fees_paid")}>
|
|
||||||
<AmountSats
|
|
||||||
amountSats={redshiftResource()!.fees_paid}
|
|
||||||
/>
|
|
||||||
</KV>
|
|
||||||
<KV key={i18n.t("redshift.change")}>
|
|
||||||
<AmountSats
|
|
||||||
amountSats={redshiftResource()!.change_amt}
|
|
||||||
/>
|
|
||||||
</KV>
|
|
||||||
<KV key={i18n.t("redshift.outbound_channel")}>
|
|
||||||
<VStack>
|
|
||||||
<pre class="whitespace-pre-wrap break-all">
|
|
||||||
{
|
|
||||||
redshiftResource()!
|
|
||||||
.introduction_channel
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href={mempoolTxUrl(
|
|
||||||
redshiftResource()!.introduction_channel?.split(
|
|
||||||
":"
|
|
||||||
)[0],
|
|
||||||
network
|
|
||||||
)}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{i18n.t("common.view_transaction")}
|
|
||||||
</a>
|
|
||||||
</VStack>
|
|
||||||
</KV>
|
|
||||||
<Show when={redshiftResource()!.output_channel}>
|
|
||||||
<KV key={i18n.t("redshift.return_channel")}>
|
|
||||||
<VStack>
|
|
||||||
<pre class="whitespace-pre-wrap break-all">
|
|
||||||
{redshiftResource()!.output_channel}
|
|
||||||
</pre>
|
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href={mempoolTxUrl(
|
|
||||||
redshiftResource()!.output_channel?.split(
|
|
||||||
":"
|
|
||||||
)[0],
|
|
||||||
network
|
|
||||||
)}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{i18n.t("common.view_transaction")}
|
|
||||||
</a>
|
|
||||||
</VStack>
|
|
||||||
</KV>
|
|
||||||
</Show>
|
|
||||||
</VStack>
|
|
||||||
</Card>
|
|
||||||
</Show>
|
|
||||||
</VStack>
|
|
||||||
</VStack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Utxo(props: { item: UtxoItem; onClick?: () => void }) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const redshifted = createMemo(() => getRedshifted(props.item.outpoint));
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div
|
|
||||||
class={THREE_COLUMNS}
|
|
||||||
onClick={() => props.onClick && props.onClick()}
|
|
||||||
>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<img src={utxoIcon} alt="coin" />
|
|
||||||
</div>
|
|
||||||
<div class={CENTER_COLUMN}>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<Show
|
|
||||||
when={redshifted()}
|
|
||||||
fallback={
|
|
||||||
<h2 class={MISSING_LABEL}>
|
|
||||||
{i18n.t("redshift.unknown")}
|
|
||||||
</h2>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<h2 class={REDSHIFT_LABEL}>
|
|
||||||
{i18n.t("redshift.title")}
|
|
||||||
</h2>
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
<SmallAmount amount={props.item.txout.value} />
|
|
||||||
</div>
|
|
||||||
<div class={RIGHT_COLUMN}>
|
|
||||||
<SmallHeader
|
|
||||||
class={
|
|
||||||
props.item?.is_spent ? "text-m-red" : "text-m-green"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{/* {props.item?.is_spent ? "SPENT" : "UNSPENT"} */}
|
|
||||||
</SmallHeader>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const FAKE_STATES = [
|
|
||||||
"Creating a new node",
|
|
||||||
"Opening a channel",
|
|
||||||
"Sending funds through",
|
|
||||||
"Closing the channel",
|
|
||||||
"Redshift complete"
|
|
||||||
];
|
|
||||||
|
|
||||||
function ShiftObserver(props: {
|
|
||||||
setShiftStage: (stage: ShiftStage) => void;
|
|
||||||
redshiftId: string;
|
|
||||||
}) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [_state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
const [fakeStage, _setFakeStage] = createSignal(2);
|
|
||||||
|
|
||||||
const [sentAmount, setSentAmount] = createSignal(0);
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
if (sentAmount() === 200000) {
|
|
||||||
clearInterval(interval);
|
|
||||||
props.setShiftStage("success");
|
|
||||||
// setSentAmount((0))
|
|
||||||
} else {
|
|
||||||
setSentAmount(sentAmount() + 50000);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
// async function checkRedshift(id: string) {
|
|
||||||
// console.log("Checking redshift", id)
|
|
||||||
// const redshift = await state.mutiny_wallet?.get_redshift(id)
|
|
||||||
// console.log(redshift)
|
|
||||||
// return redshift
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const [redshiftResource, { refetch }] = createResource(
|
|
||||||
// props.redshiftId,
|
|
||||||
// checkRedshift
|
|
||||||
// )
|
|
||||||
|
|
||||||
// onMount(() => {
|
|
||||||
// const interval = setInterval(() => {
|
|
||||||
// if (redshiftResource()) refetch();
|
|
||||||
// // if (sentAmount() === 200000) {
|
|
||||||
// // clearInterval(interval)
|
|
||||||
// // props.setShiftStage("success");
|
|
||||||
// // // setSentAmount((0))
|
|
||||||
|
|
||||||
// // } else {
|
|
||||||
// // setSentAmount((sentAmount() + 50000))
|
|
||||||
// // }
|
|
||||||
// }, 1000)
|
|
||||||
// })
|
|
||||||
|
|
||||||
// createEffect(() => {
|
|
||||||
// const interval = setInterval(() => {
|
|
||||||
// if (chosenUtxo()) refetch();
|
|
||||||
// }, 1000); // Poll every second
|
|
||||||
// onCleanup(() => {
|
|
||||||
// clearInterval(interval);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<NiceP>{i18n.t("redshift.watch_it_go")}</NiceP>
|
|
||||||
<Card>
|
|
||||||
<VStack>
|
|
||||||
<pre class="self-center">{FAKE_STATES[fakeStage()]}</pre>
|
|
||||||
<ProgressBar value={sentAmount()} max={200000} />
|
|
||||||
<img src={wave} class="h-4 self-center" alt="sine wave" />
|
|
||||||
</VStack>
|
|
||||||
</Card>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const KV: ParentComponent<{ key: string }> = (props) => {
|
|
||||||
return (
|
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
<p class="text-sm font-semibold uppercase">{props.key}</p>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Redshift() {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const [state, _actions] = useMegaStore();
|
|
||||||
|
|
||||||
const [shiftStage, setShiftStage] = createSignal<ShiftStage>("choose");
|
|
||||||
const [shiftType, setShiftType] = createSignal<ShiftOption>("utxo");
|
|
||||||
|
|
||||||
const [chosenUtxo, setChosenUtxo] = createSignal<UtxoItem>();
|
|
||||||
|
|
||||||
const SHIFT_OPTIONS = [
|
|
||||||
{
|
|
||||||
value: "utxo",
|
|
||||||
label: i18n.t("redshift.utxo_label"),
|
|
||||||
caption: i18n.t("redshift.utxo_caption")
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "lightning",
|
|
||||||
label: i18n.t("redshift.lightning_label"),
|
|
||||||
caption: i18n.t("redshift.lightning_caption")
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const getUtXos = async () => {
|
|
||||||
console.log("Getting utxos");
|
|
||||||
return (await state.mutiny_wallet?.list_utxos()) as UtxoItem[];
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: FIXME: this is old code needs to be revisited!
|
|
||||||
const getChannels = async () => {
|
|
||||||
console.log("Getting channels");
|
|
||||||
// await state.mutiny_wallet?.sync();
|
|
||||||
const channels =
|
|
||||||
(await state.mutiny_wallet?.list_channels()) as Promise<
|
|
||||||
MutinyChannel[]
|
|
||||||
>;
|
|
||||||
console.log(channels);
|
|
||||||
return channels;
|
|
||||||
};
|
|
||||||
|
|
||||||
const [utxos, { refetch: _refetchUtxos }] = createResource(getUtXos);
|
|
||||||
const [_channels, { refetch: _refetchChannels }] =
|
|
||||||
createResource(getChannels);
|
|
||||||
|
|
||||||
const redshiftedUtxos = createMemo(() => {
|
|
||||||
return utxos()?.filter((utxo) => getRedshifted(utxo.outpoint));
|
|
||||||
});
|
|
||||||
|
|
||||||
const unredshiftedUtxos = createMemo(() => {
|
|
||||||
return utxos()?.filter((utxo) => !getRedshifted(utxo.outpoint));
|
|
||||||
});
|
|
||||||
|
|
||||||
function resetState() {
|
|
||||||
setShiftStage("choose");
|
|
||||||
setShiftType("utxo");
|
|
||||||
setChosenUtxo(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function redshiftUtxo(utxo: UtxoItem) {
|
|
||||||
console.log("Redshifting utxo", utxo.outpoint);
|
|
||||||
const redshift = await state.mutiny_wallet?.init_redshift(
|
|
||||||
utxo.outpoint
|
|
||||||
);
|
|
||||||
console.log("Redshift initialized:");
|
|
||||||
console.log(redshift);
|
|
||||||
return redshift;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [initializedRedshift, { refetch: _refetchRedshift }] = createResource(
|
|
||||||
chosenUtxo,
|
|
||||||
redshiftUtxo
|
|
||||||
);
|
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
if (chosenUtxo() && initializedRedshift()) {
|
|
||||||
// window.location.href = "/"
|
|
||||||
setShiftStage("observe");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MutinyWalletGuard>
|
|
||||||
<SafeArea>
|
|
||||||
<DefaultMain>
|
|
||||||
<BackLink />
|
|
||||||
<LargeHeader>
|
|
||||||
{i18n.t("redshift.title")}{" "}
|
|
||||||
{i18n.t("common.coming_soon")}
|
|
||||||
</LargeHeader>
|
|
||||||
<div class="relative filter grayscale pointer-events-none opacity-75">
|
|
||||||
<VStack biggap>
|
|
||||||
{/* <pre>{JSON.stringify(redshiftResource(), null, 2)}</pre> */}
|
|
||||||
<Switch>
|
|
||||||
<Match when={shiftStage() === "choose"}>
|
|
||||||
<VStack>
|
|
||||||
<NiceP>
|
|
||||||
{i18n.t("redshift.where_this_goes")}
|
|
||||||
</NiceP>
|
|
||||||
<StyledRadioGroup
|
|
||||||
accent="red"
|
|
||||||
value={shiftType()}
|
|
||||||
onValueChange={(newValue) =>
|
|
||||||
setShiftType(
|
|
||||||
newValue as ShiftOption
|
|
||||||
)
|
|
||||||
}
|
|
||||||
choices={SHIFT_OPTIONS}
|
|
||||||
/>
|
|
||||||
</VStack>
|
|
||||||
<VStack>
|
|
||||||
<NiceP>
|
|
||||||
{i18n.t("redshift.choose_your")}{" "}
|
|
||||||
<span class="inline-block">
|
|
||||||
<img
|
|
||||||
class="h-4"
|
|
||||||
src={wave}
|
|
||||||
alt="sine wave"
|
|
||||||
/>
|
|
||||||
</span>{" "}
|
|
||||||
{i18n.t("redshift.utxo_to_begin")}
|
|
||||||
</NiceP>
|
|
||||||
<Suspense>
|
|
||||||
<Card
|
|
||||||
title={i18n.t(
|
|
||||||
"redshift.unshifted_utxo"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Switch>
|
|
||||||
<Match when={utxos.loading}>
|
|
||||||
<LoadingSpinner wide />
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
utxos.state ===
|
|
||||||
"ready" &&
|
|
||||||
unredshiftedUtxos()
|
|
||||||
?.length === 0
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<code>
|
|
||||||
{i18n.t(
|
|
||||||
"redshift.no_utxos_empty_state"
|
|
||||||
)}
|
|
||||||
</code>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
utxos.state ===
|
|
||||||
"ready" &&
|
|
||||||
unredshiftedUtxos() &&
|
|
||||||
unredshiftedUtxos()!
|
|
||||||
.length >= 0
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<For
|
|
||||||
each={unredshiftedUtxos()}
|
|
||||||
>
|
|
||||||
{(utxo) => (
|
|
||||||
<Utxo
|
|
||||||
item={utxo}
|
|
||||||
onClick={() =>
|
|
||||||
setChosenUtxo(
|
|
||||||
utxo
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</Card>
|
|
||||||
</Suspense>
|
|
||||||
<Suspense>
|
|
||||||
<Card
|
|
||||||
titleElement={
|
|
||||||
<SmallHeader>
|
|
||||||
<span class="text-m-red">
|
|
||||||
{i18n.t(
|
|
||||||
"redshift.redshifted"
|
|
||||||
)}{" "}
|
|
||||||
</span>
|
|
||||||
{i18n.t(
|
|
||||||
"redshift.utxos"
|
|
||||||
)}
|
|
||||||
</SmallHeader>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Switch>
|
|
||||||
<Match when={utxos.loading}>
|
|
||||||
<LoadingSpinner wide />
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
utxos.state ===
|
|
||||||
"ready" &&
|
|
||||||
redshiftedUtxos()
|
|
||||||
?.length === 0
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<code>
|
|
||||||
{i18n.t(
|
|
||||||
"redshift.no_utxos_empty_state"
|
|
||||||
)}
|
|
||||||
</code>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
utxos.state ===
|
|
||||||
"ready" &&
|
|
||||||
redshiftedUtxos() &&
|
|
||||||
redshiftedUtxos()!
|
|
||||||
.length >= 0
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<For
|
|
||||||
each={redshiftedUtxos()}
|
|
||||||
>
|
|
||||||
{(utxo) => (
|
|
||||||
<Utxo
|
|
||||||
item={utxo}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</Card>
|
|
||||||
</Suspense>
|
|
||||||
</VStack>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
shiftStage() === "observe" &&
|
|
||||||
chosenUtxo()
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ShiftObserver
|
|
||||||
setShiftStage={setShiftStage}
|
|
||||||
redshiftId="dummy-redshift"
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
shiftStage() === "success" &&
|
|
||||||
chosenUtxo()
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<VStack biggap>
|
|
||||||
<RedshiftReport
|
|
||||||
redshift={dummyRedshift}
|
|
||||||
utxo={chosenUtxo()!}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
intent="red"
|
|
||||||
onClick={resetState}
|
|
||||||
>
|
|
||||||
{i18n.t("common.nice")}
|
|
||||||
</Button>
|
|
||||||
</VStack>
|
|
||||||
</Match>
|
|
||||||
<Match when={shiftStage() === "failure"}>
|
|
||||||
<NiceP>{i18n.t("redshift.oh_dear")}</NiceP>
|
|
||||||
<NiceP>
|
|
||||||
{i18n.t("redshift.here_is_error")}
|
|
||||||
</NiceP>
|
|
||||||
<Button intent="red" onClick={resetState}>
|
|
||||||
{i18n.t("common.dangit")}
|
|
||||||
</Button>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
</VStack>
|
|
||||||
</div>
|
|
||||||
</DefaultMain>
|
|
||||||
<NavBar activeTab="redshift" />
|
|
||||||
</SafeArea>
|
|
||||||
</MutinyWalletGuard>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
import Reader from "~/components/Reader";
|
|
||||||
import { createEffect, createSignal } from "solid-js";
|
import { createEffect, createSignal } from "solid-js";
|
||||||
import { useNavigate } from "solid-start";
|
import { useNavigate } from "solid-start";
|
||||||
import { Button } from "~/components/layout";
|
import { Button, Scanner as Reader, showToast } from "~/components";
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { toParsedParams } from "~/logic/waila";
|
import { toParsedParams } from "~/logic/waila";
|
||||||
import { Clipboard } from "@capacitor/clipboard";
|
import { Clipboard } from "@capacitor/clipboard";
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import {
|
|||||||
createSignal,
|
createSignal,
|
||||||
onMount
|
onMount
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { AmountSats, AmountFiat } from "~/components/Amount";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
|
NavBar,
|
||||||
|
AmountSats,
|
||||||
|
AmountFiat,
|
||||||
Button,
|
Button,
|
||||||
ButtonLink,
|
ButtonLink,
|
||||||
Card,
|
Card,
|
||||||
@@ -19,35 +20,35 @@ import {
|
|||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
SmallHeader,
|
SmallHeader,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
StyledRadioGroup,
|
||||||
|
showToast,
|
||||||
|
MegaCheck,
|
||||||
|
MegaEx,
|
||||||
|
BackLink,
|
||||||
|
TagEditor,
|
||||||
|
StringShower,
|
||||||
|
AmountCard,
|
||||||
|
BackButton,
|
||||||
|
SuccessModal,
|
||||||
|
InfoBox,
|
||||||
|
Fee
|
||||||
|
} from "~/components";
|
||||||
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { Paste } from "~/assets/svg/Paste";
|
import { Paste } from "~/assets/svg/Paste";
|
||||||
import { Scan } from "~/assets/svg/Scan";
|
import { Scan } from "~/assets/svg/Scan";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Contact, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
import { Contact, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||||
import { StyledRadioGroup } from "~/components/layout/Radio";
|
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { MegaCheck } from "~/components/successfail/MegaCheck";
|
|
||||||
import { MegaEx } from "~/components/successfail/MegaEx";
|
|
||||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
|
||||||
import { useNavigate } from "solid-start";
|
import { useNavigate } from "solid-start";
|
||||||
import { TagEditor } from "~/components/TagEditor";
|
|
||||||
import { StringShower } from "~/components/ShareCard";
|
|
||||||
import { AmountCard } from "~/components/AmountCard";
|
|
||||||
import { MutinyTagItem } from "~/utils/tags";
|
import { MutinyTagItem } from "~/utils/tags";
|
||||||
import { BackButton } from "~/components/layout/BackButton";
|
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
import { Network } from "~/logic/mutinyWalletSetup";
|
||||||
import { SuccessModal } from "~/components/successfail/SuccessModal";
|
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { ParsedParams, toParsedParams } from "~/logic/waila";
|
import { ParsedParams, toParsedParams } from "~/logic/waila";
|
||||||
import { Clipboard } from "@capacitor/clipboard";
|
import { Clipboard } from "@capacitor/clipboard";
|
||||||
import { Capacitor } from "@capacitor/core";
|
import { Capacitor } from "@capacitor/core";
|
||||||
import { FeedbackLink } from "./Feedback";
|
import { FeedbackLink } from "./Feedback";
|
||||||
import { Fee } from "~/components/Fee";
|
|
||||||
|
|
||||||
export type SendSource = "lightning" | "onchain";
|
export type SendSource = "lightning" | "onchain";
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { AmountCard } from "~/components/AmountCard";
|
|
||||||
import { Fee } from "~/components/Fee";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import { OnboardWarning } from "~/components/OnboardWarning";
|
|
||||||
import { ShareCard } from "~/components/ShareCard";
|
|
||||||
import {
|
import {
|
||||||
|
AmountCard,
|
||||||
|
Fee,
|
||||||
|
NavBar,
|
||||||
|
OnboardWarning,
|
||||||
Button,
|
Button,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
|
ShareCard,
|
||||||
LargeHeader,
|
LargeHeader,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack
|
VStack
|
||||||
} from "~/components/layout";
|
} from "~/components";
|
||||||
|
|
||||||
const SAMPLE =
|
const SAMPLE =
|
||||||
"bitcoin:tb1prqm8xtlgme0vmw5s30lgf0a4f5g4mkgsqundwmpu6thrg8zr6uvq2qrhzq?amount=0.001&lightning=lntbs1m1pj9n9xjsp5xgdrmvprtm67p7nq4neparalexlhlmtxx87zx6xeqthsplu842zspp546d6zd2seyaxpapaxx62m88yz3xueqtjmn9v6wj8y56np8weqsxqdqqnp4qdn2hj8tfknpuvdg6tz9yrf3e27ltrx9y58c24jh89lnm43yjwfc5xqrpwjcqpj9qrsgq5sdgh0m3ur5mu5hrmmag4mx9yvy86f83pd0x9ww80kgck6tac3thuzkj0mrtltaxwnlfea95h2re7tj4qsnwzxlvrdmyq2h9mgapnycpppz6k6";
|
"bitcoin:tb1prqm8xtlgme0vmw5s30lgf0a4f5g4mkgsqundwmpu6thrg8zr6uvq2qrhzq?amount=0.001&lightning=lntbs1m1pj9n9xjsp5xgdrmvprtm67p7nq4neparalexlhlmtxx87zx6xeqthsplu842zspp546d6zd2seyaxpapaxx62m88yz3xueqtjmn9v6wj8y56np8weqsxqdqqnp4qdn2hj8tfknpuvdg6tz9yrf3e27ltrx9y58c24jh89lnm43yjwfc5xqrpwjcqpj9qrsgq5sdgh0m3ur5mu5hrmmag4mx9yvy86f83pd0x9ww80kgck6tac3thuzkj0mrtltaxwnlfea95h2re7tj4qsnwzxlvrdmyq2h9mgapnycpppz6k6";
|
||||||
|
|||||||
@@ -9,33 +9,33 @@ import {
|
|||||||
createResource,
|
createResource,
|
||||||
createSignal
|
createSignal
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { AmountCard } from "~/components/AmountCard";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import {
|
import {
|
||||||
|
AmountCard,
|
||||||
|
NavBar,
|
||||||
|
showToast,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
LargeHeader,
|
LargeHeader,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack
|
BackLink,
|
||||||
} from "~/components/layout";
|
TextField,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
VStack,
|
||||||
import { TextField } from "~/components/layout/TextField";
|
MegaCheck,
|
||||||
|
MegaEx,
|
||||||
|
InfoBox,
|
||||||
|
SuccessModal,
|
||||||
|
AmountFiat
|
||||||
|
} from "~/components";
|
||||||
import { MethodChooser, SendSource } from "~/routes/Send";
|
import { MethodChooser, SendSource } from "~/routes/Send";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { MegaCheck } from "~/components/successfail/MegaCheck";
|
|
||||||
import { MegaEx } from "~/components/successfail/MegaEx";
|
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import { useNavigate } from "solid-start";
|
import { useNavigate } from "solid-start";
|
||||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||||
import { SuccessModal } from "~/components/successfail/SuccessModal";
|
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { Network } from "~/logic/mutinyWalletSetup";
|
import { Network } from "~/logic/mutinyWalletSetup";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { AmountFiat } from "~/components/Amount";
|
|
||||||
|
|
||||||
const CHANNEL_FEE_ESTIMATE_ADDRESS =
|
const CHANNEL_FEE_ESTIMATE_ADDRESS =
|
||||||
"bc1qf7546vg73ddsjznzq57z3e8jdn6gtw6au576j07kt6d9j7nz8mzsyn6lgf";
|
"bc1qf7546vg73ddsjznzq57z3e8jdn6gtw6au576j07kt6d9j7nz8mzsyn6lgf";
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import { Title } from "solid-start";
|
import { Title } from "solid-start";
|
||||||
import { HttpStatusCode } from "solid-start/server";
|
import { HttpStatusCode } from "solid-start/server";
|
||||||
import {
|
import { ButtonLink, DefaultMain, LargeHeader, SafeArea } from "~/components";
|
||||||
ButtonLink,
|
|
||||||
DefaultMain,
|
|
||||||
LargeHeader,
|
|
||||||
SafeArea
|
|
||||||
} from "~/components/layout";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export default function NotFound() {
|
export default function NotFound() {
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import App from "~/components/App";
|
|
||||||
import { Switch, Match } from "solid-js";
|
import { Switch, Match } from "solid-js";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { FullscreenLoader } from "~/components/layout";
|
import { App, FullscreenLoader, SetupErrorDisplay } from "~/components";
|
||||||
import SetupErrorDisplay from "~/components/SetupErrorDisplay";
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [state, _] = useMegaStore();
|
const [state, _] = useMegaStore();
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { DeleteEverything } from "~/components/DeleteEverything";
|
|
||||||
import KitchenSink from "~/components/KitchenSink";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
|
DeleteEverything,
|
||||||
|
KitchenSink,
|
||||||
|
NavBar,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
LargeHeader,
|
LargeHeader,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
NiceP,
|
NiceP,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
SmallHeader,
|
SmallHeader,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
BackLink
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
} from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
export default function Admin() {
|
export default function Admin() {
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import {
|
|||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack,
|
VStack,
|
||||||
Checkbox
|
Checkbox,
|
||||||
} from "~/components/layout";
|
NavBar,
|
||||||
import NavBar from "~/components/NavBar";
|
SeedWords,
|
||||||
|
BackLink
|
||||||
|
} from "~/components";
|
||||||
import { useNavigate } from "solid-start";
|
import { useNavigate } from "solid-start";
|
||||||
import { SeedWords } from "~/components/SeedWords";
|
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Show, createEffect, createSignal } from "solid-js";
|
import { Show, createEffect, createSignal } from "solid-js";
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
function Quiz(props: { setHasCheckedAll: (hasChecked: boolean) => void }) {
|
function Quiz(props: { setHasCheckedAll: (hasChecked: boolean) => void }) {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import {
|
|||||||
SafeArea,
|
SafeArea,
|
||||||
SmallHeader,
|
SmallHeader,
|
||||||
TinyText,
|
TinyText,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
AmountSmall,
|
||||||
import { AmountSmall } from "~/components/Amount";
|
BackLink,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
NavBar
|
||||||
import NavBar from "~/components/NavBar";
|
} from "~/components";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
function BalanceBar(props: { inbound: number; outbound: number }) {
|
function BalanceBar(props: { inbound: number; outbound: number }) {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
||||||
import { For, Show, createResource, createSignal } from "solid-js";
|
import { For, Show, createResource, createSignal } from "solid-js";
|
||||||
import { QRCodeSVG } from "solid-qr-code";
|
import { QRCodeSVG } from "solid-qr-code";
|
||||||
import { KeyValue, MiniStringShower } from "~/components/DetailsModal";
|
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import { ShareCard } from "~/components/ShareCard";
|
|
||||||
import {
|
import {
|
||||||
|
KeyValue,
|
||||||
|
MiniStringShower,
|
||||||
|
InfoBox,
|
||||||
|
NavBar,
|
||||||
|
ShareCard,
|
||||||
Button,
|
Button,
|
||||||
Collapser,
|
Collapser,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
@@ -15,10 +16,10 @@ import {
|
|||||||
SafeArea,
|
SafeArea,
|
||||||
SettingsCard,
|
SettingsCard,
|
||||||
SimpleDialog,
|
SimpleDialog,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
BackLink,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
TextField
|
||||||
import { TextField } from "~/components/layout/TextField";
|
} from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { DeleteEverything } from "~/components/DeleteEverything";
|
|
||||||
import { ImportExport } from "~/components/ImportExport";
|
|
||||||
import { LoadingIndicator } from "~/components/LoadingIndicator";
|
|
||||||
import { Logs } from "~/components/Logs";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
|
DeleteEverything,
|
||||||
|
ImportExport,
|
||||||
|
LoadingIndicator,
|
||||||
|
Logs,
|
||||||
|
NavBar,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
LargeHeader,
|
LargeHeader,
|
||||||
NiceP,
|
NiceP,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
SmallHeader,
|
SmallHeader,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
BackLink
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
} from "~/components";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import {
|
|||||||
NiceP,
|
NiceP,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
NavBar,
|
||||||
import NavBar from "~/components/NavBar";
|
BackLink,
|
||||||
|
TextField,
|
||||||
|
InfoBox
|
||||||
|
} from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { Show, createSignal } from "solid-js";
|
import { Show, createSignal } from "solid-js";
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
|
||||||
import { createForm } from "@modular-forms/solid";
|
import { createForm } from "@modular-forms/solid";
|
||||||
import { TextField } from "~/components/layout/TextField";
|
|
||||||
import { timeout } from "~/utils/timeout";
|
import { timeout } from "~/utils/timeout";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
type EncryptPasswordForm = {
|
type EncryptPasswordForm = {
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { TextField } from "@kobalte/core";
|
import { TextField } from "@kobalte/core";
|
||||||
import { createSignal } from "solid-js";
|
import { createSignal } from "solid-js";
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
NavBar,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
InnerCard,
|
InnerCard,
|
||||||
LargeHeader,
|
LargeHeader,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
SafeArea
|
SafeArea,
|
||||||
} from "~/components/layout";
|
BackLink
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
} from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import {
|
|||||||
createSignal
|
createSignal
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import { A } from "solid-start";
|
import { A } from "solid-start";
|
||||||
import { ConfirmDialog } from "~/components/Dialog";
|
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import {
|
import {
|
||||||
|
ConfirmDialog,
|
||||||
|
InfoBox,
|
||||||
|
NavBar,
|
||||||
Button,
|
Button,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
FancyCard,
|
FancyCard,
|
||||||
@@ -19,13 +19,13 @@ import {
|
|||||||
NiceP,
|
NiceP,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
TinyText,
|
TinyText,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
BackLink,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
LoadingShimmer
|
||||||
|
} from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import party from "~/assets/party.gif";
|
import party from "~/assets/party.gif";
|
||||||
import { LoadingShimmer } from "~/components/BalanceBox";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { subscriptionValid } from "~/utils/subscriptions";
|
import { subscriptionValid } from "~/utils/subscriptions";
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,14 @@ import {
|
|||||||
LargeHeader,
|
LargeHeader,
|
||||||
NiceP,
|
NiceP,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
BackLink,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
NavBar,
|
||||||
import NavBar from "~/components/NavBar";
|
TextFieldProps,
|
||||||
|
showToast,
|
||||||
|
ConfirmDialog,
|
||||||
|
InfoBox
|
||||||
|
} from "~/components";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
import { For, Show, createSignal, splitProps } from "solid-js";
|
import { For, Show, createSignal, splitProps } from "solid-js";
|
||||||
import pasteIcon from "~/assets/icons/paste.svg";
|
import pasteIcon from "~/assets/icons/paste.svg";
|
||||||
@@ -20,13 +24,9 @@ import {
|
|||||||
validate
|
validate
|
||||||
} from "@modular-forms/solid";
|
} from "@modular-forms/solid";
|
||||||
import { TextField as KTextField } from "@kobalte/core";
|
import { TextField as KTextField } from "@kobalte/core";
|
||||||
import { TextFieldProps } from "~/components/layout/TextField";
|
|
||||||
import { showToast } from "~/components/Toaster";
|
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { ConfirmDialog } from "~/components/Dialog";
|
|
||||||
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||||
import { WORDS_EN } from "~/utils/words";
|
import { WORDS_EN } from "~/utils/words";
|
||||||
import { InfoBox } from "~/components/InfoBox";
|
|
||||||
import { Clipboard } from "@capacitor/clipboard";
|
import { Clipboard } from "@capacitor/clipboard";
|
||||||
import { Capacitor } from "@capacitor/core";
|
import { Capacitor } from "@capacitor/core";
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { createForm, url } from "@modular-forms/solid";
|
import { createForm, url } from "@modular-forms/solid";
|
||||||
import { TextField } from "~/components/layout/TextField";
|
|
||||||
import {
|
import {
|
||||||
MutinyWalletSettingStrings,
|
MutinyWalletSettingStrings,
|
||||||
setSettings
|
setSettings
|
||||||
@@ -8,16 +7,17 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
DefaultMain,
|
DefaultMain,
|
||||||
|
TextField,
|
||||||
LargeHeader,
|
LargeHeader,
|
||||||
MutinyWalletGuard,
|
MutinyWalletGuard,
|
||||||
NiceP,
|
NiceP,
|
||||||
SafeArea
|
SafeArea,
|
||||||
} from "~/components/layout";
|
showToast,
|
||||||
import { showToast } from "~/components/Toaster";
|
BackLink,
|
||||||
|
NavBar
|
||||||
|
} from "~/components";
|
||||||
import eify from "~/utils/eify";
|
import eify from "~/utils/eify";
|
||||||
import { ExternalLink } from "@mutinywallet/ui";
|
import { ExternalLink } from "@mutinywallet/ui";
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
|
||||||
import NavBar from "~/components/NavBar";
|
|
||||||
import { useI18n } from "~/i18n/context";
|
import { useI18n } from "~/i18n/context";
|
||||||
import { useMegaStore } from "~/state/megaStore";
|
import { useMegaStore } from "~/state/megaStore";
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import {
|
|||||||
LargeHeader,
|
LargeHeader,
|
||||||
SafeArea,
|
SafeArea,
|
||||||
SettingsCard,
|
SettingsCard,
|
||||||
VStack
|
VStack,
|
||||||
} from "~/components/layout";
|
BackLink,
|
||||||
import { BackLink } from "~/components/layout/BackLink";
|
NavBar
|
||||||
import NavBar from "~/components/NavBar";
|
} from "~/components";
|
||||||
import { A } from "solid-start";
|
import { A } from "solid-start";
|
||||||
import { For, Show } from "solid-js";
|
import { For, Show } from "solid-js";
|
||||||
import forward from "~/assets/icons/forward.svg";
|
import forward from "~/assets/icons/forward.svg";
|
||||||
|
|||||||
Reference in New Issue
Block a user