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 { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat, AmountSats } from "~/components/Amount";
|
||||
import { AmountFiat, AmountSats } from "~/components";
|
||||
|
||||
export const ActivityAmount: ParentComponent<{
|
||||
amount: string;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
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 { satsToUsd } from "~/utils/conversions";
|
||||
import { AmountEditable } from "./AmountEditable";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
const noop = () => {
|
||||
|
||||
@@ -9,18 +9,15 @@ import {
|
||||
Switch,
|
||||
Match
|
||||
} from "solid-js";
|
||||
import { Button } from "~/components/layout";
|
||||
import { Button, InlineAmount, InfoBox, FeesModal } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { satsToUsd, usdToSats } from "~/utils/conversions";
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import pencil from "~/assets/icons/pencil.svg";
|
||||
import currencySwap from "~/assets/icons/currency-swap.svg";
|
||||
import { InlineAmount } from "./AmountCard";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { FeesModal } from "./MoreInfoModal";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useNavigate } from "solid-start";
|
||||
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
import { DefaultMain, SafeArea, VStack, Card } from "~/components/layout";
|
||||
import BalanceBox, { LoadingShimmer } from "~/components/BalanceBox";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import ReloadPrompt from "~/components/Reload";
|
||||
import {
|
||||
DefaultMain,
|
||||
SafeArea,
|
||||
VStack,
|
||||
Card,
|
||||
LoadingShimmer,
|
||||
BalanceBox,
|
||||
ReloadPrompt,
|
||||
NavBar,
|
||||
OnboardWarning,
|
||||
CombinedActivity,
|
||||
BetaWarningModal,
|
||||
PendingNwc,
|
||||
DecryptDialog,
|
||||
LoadingIndicator
|
||||
} from "~/components";
|
||||
import { A } from "solid-start";
|
||||
import { OnboardWarning } from "~/components/OnboardWarning";
|
||||
import { CombinedActivity } from "./Activity";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Match, Show, Suspense, Switch } from "solid-js";
|
||||
import { BetaWarningModal } from "~/components/BetaWarningModal";
|
||||
import settings from "~/assets/icons/settings.svg";
|
||||
import pixelLogo from "~/assets/mutiny-pixel-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 { useI18n } from "~/i18n/context";
|
||||
|
||||
export default function App() {
|
||||
export function App() {
|
||||
const i18n = useI18n();
|
||||
const [state, _actions] = useMegaStore();
|
||||
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
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 { AmountSats, AmountFiat } from "./Amount";
|
||||
import { A, useNavigate } from "solid-start";
|
||||
import shuffle from "~/assets/icons/shuffle.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
|
||||
export function LoadingShimmer() {
|
||||
return (
|
||||
@@ -23,7 +28,7 @@ export function LoadingShimmer() {
|
||||
const STYLE =
|
||||
"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 i18n = useI18n();
|
||||
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { ParentComponent, createSignal } from "solid-js";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER, OVERLAY } from "./DetailsModal";
|
||||
import { ModalCloseButton, SmallHeader } from "./layout";
|
||||
import {
|
||||
DIALOG_CONTENT,
|
||||
DIALOG_POSITIONER,
|
||||
OVERLAY,
|
||||
ModalCloseButton,
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Match, Switch, createSignal } from "solid-js";
|
||||
import { SmallHeader, TinyButton } from "~/components/layout";
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { SubmitHandler } from "@modular-forms/solid";
|
||||
import { ContactForm } from "./ContactForm";
|
||||
import { ContactFormValues } from "./ContactViewer";
|
||||
import {
|
||||
ContactFormValues,
|
||||
ContactForm,
|
||||
SmallHeader,
|
||||
TinyButton
|
||||
} from "~/components";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { SubmitHandler, createForm, required } from "@modular-forms/solid";
|
||||
import { Button, LargeHeader, VStack } from "~/components/layout";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
import { ContactFormValues } from "./ContactViewer";
|
||||
import {
|
||||
Button,
|
||||
LargeHeader,
|
||||
VStack,
|
||||
TextField,
|
||||
ContactFormValues
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function ContactForm(props: {
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
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 close from "~/assets/icons/close.svg";
|
||||
import { SubmitHandler } from "@modular-forms/solid";
|
||||
import { ContactForm } from "./ContactForm";
|
||||
import { showToast } from "./Toaster";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { Button, SimpleDialog } from "~/components/layout";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
import { InfoBox } from "~/components/InfoBox";
|
||||
import { Button, SimpleDialog, TextField, InfoBox } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import { A } from "solid-start";
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { createSignal } from "solid-js";
|
||||
import { ConfirmDialog } from "~/components/Dialog";
|
||||
import { Button } from "~/components/layout";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import { ConfirmDialog, Button, showToast } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
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 { ParentComponent } from "solid-js";
|
||||
import { Button, SmallHeader } from "./layout";
|
||||
import { Button, SmallHeader } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export default function ErrorDisplay(props: { error: Error }) {
|
||||
export function ErrorDisplay(props: { error: Error }) {
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<SafeArea>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat, AmountSats } from "~/components/Amount";
|
||||
import { FeesModal } from "~/components/MoreInfoModal";
|
||||
import { AmountFiat, AmountSats, FeesModal } from "~/components";
|
||||
|
||||
export function Fee(props: { amountSats?: bigint | number }) {
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ParentComponent, Show, createResource } from "solid-js";
|
||||
import { I18nContext } from "../i18n/context";
|
||||
import { I18nContext } from "~/i18n/context";
|
||||
import i18next from "i18next";
|
||||
import i18nConfig from "~/i18n/config";
|
||||
|
||||
|
||||
@@ -4,17 +4,17 @@ import {
|
||||
InnerCard,
|
||||
NiceP,
|
||||
SimpleDialog,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
VStack,
|
||||
ConfirmDialog,
|
||||
showToast,
|
||||
InfoBox,
|
||||
TextField
|
||||
} from "~/components";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import eify from "~/utils/eify";
|
||||
import { showToast } from "./Toaster";
|
||||
import { downloadTextFile } from "~/utils/download";
|
||||
import { createFileUploader } from "@solid-primitives/upload";
|
||||
import { ConfirmDialog } from "./Dialog";
|
||||
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import { TextField } from "./layout/TextField";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function ImportExport(props: { emergency?: boolean }) {
|
||||
|
||||
@@ -2,8 +2,7 @@ import { Match, Show, Switch } from "solid-js";
|
||||
import { QRCodeSVG } from "solid-qr-code";
|
||||
import { ReceiveFlavor } from "~/routes/Receive";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import { AmountSats, AmountFiat } from "./Amount";
|
||||
import { TruncateMiddle } from "./ShareCard";
|
||||
import { AmountSats, AmountFiat, TruncateMiddle } from "~/components";
|
||||
import copyBlack from "~/assets/icons/copy-black.svg";
|
||||
import shareBlack from "~/assets/icons/share-black.svg";
|
||||
import chainBlack from "~/assets/icons/chain-black.svg";
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { JSX, createMemo } from "solid-js";
|
||||
import { ModalCloseButton, SmallHeader } from "~/components/layout";
|
||||
import {
|
||||
ModalCloseButton,
|
||||
SmallHeader,
|
||||
DIALOG_CONTENT,
|
||||
DIALOG_POSITIONER,
|
||||
OVERLAY
|
||||
} from "~/components/DetailsModal";
|
||||
import { CopyButton } from "./ShareCard";
|
||||
OVERLAY,
|
||||
CopyButton
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export function JsonModal(props: {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Hr, Button, InnerCard, VStack } from "~/components/layout";
|
||||
import {
|
||||
For,
|
||||
Match,
|
||||
@@ -13,14 +12,20 @@ import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
|
||||
import { Collapsible, TextField } from "@kobalte/core";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import eify from "~/utils/eify";
|
||||
import { ConfirmDialog } from "~/components/Dialog";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import {
|
||||
ConfirmDialog,
|
||||
Hr,
|
||||
Button,
|
||||
InnerCard,
|
||||
VStack,
|
||||
showToast,
|
||||
Restart,
|
||||
ResyncOnchain,
|
||||
ResetRouter,
|
||||
MiniStringShower
|
||||
} from "~/components";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
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";
|
||||
|
||||
// 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 (
|
||||
<>
|
||||
<ListNodes />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { downloadTextFile } from "~/utils/download";
|
||||
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { ParentComponent, createSignal, JSXElement } from "solid-js";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER, OVERLAY } from "./DetailsModal";
|
||||
import { ModalCloseButton, SmallHeader } from "./layout";
|
||||
import {
|
||||
DIALOG_CONTENT,
|
||||
DIALOG_POSITIONER,
|
||||
OVERLAY,
|
||||
ModalCloseButton,
|
||||
SmallHeader
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import help from "~/assets/icons/help.svg";
|
||||
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 (
|
||||
<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">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Show } from "solid-js";
|
||||
import { ButtonLink, SmallHeader } from "./layout";
|
||||
import { ButtonLink, SmallHeader } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import save from "~/assets/icons/save.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
||||
import { formatExpiration } from "~/utils/prettyPrintTime";
|
||||
import { Card, VStack } from "./layout";
|
||||
import { Card, VStack, ActivityAmount, InfoBox } from "~/components";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import bolt from "~/assets/icons/bolt.svg";
|
||||
import {
|
||||
@@ -16,8 +16,6 @@ import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
import greenCheck from "~/assets/icons/green-check.svg";
|
||||
import redClose from "~/assets/icons/red-close.svg";
|
||||
import { ActivityAmount } from "./ActivityItem";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import eify from "~/utils/eify";
|
||||
import { A } from "solid-start";
|
||||
import { createDeepSignal } from "~/utils/deepSignal";
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import QrScanner from "qr-scanner";
|
||||
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 scanner: QrScanner | undefined;
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { Component } from "solid-js";
|
||||
import { Show } from "solid-js";
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { useRegisterSW } from "virtual:pwa-register/solid";
|
||||
|
||||
const ReloadPrompt: Component = () => {
|
||||
export function ReloadPrompt() {
|
||||
const {
|
||||
offlineReady: [offlineReady, _setOfflineReady],
|
||||
needRefresh: [needRefresh, _setNeedRefresh],
|
||||
@@ -41,6 +40,4 @@ const ReloadPrompt: Component = () => {
|
||||
</Card> */}
|
||||
</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 { useI18n } from "~/i18n/context";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { 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 { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@ import {
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader
|
||||
} from "~/components/layout";
|
||||
SmallHeader,
|
||||
ImportExport,
|
||||
Logs,
|
||||
DeleteEverything
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { Match, Switch } from "solid-js";
|
||||
import { ImportExport } from "./ImportExport";
|
||||
import { Logs } from "./Logs";
|
||||
import { DeleteEverything } from "./DeleteEverything";
|
||||
import { FeedbackLink } from "~/routes/Feedback";
|
||||
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
|
||||
const i18n = useI18n();
|
||||
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 copyIcon from "~/assets/icons/copy.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 eyeIcon from "~/assets/icons/eye.svg";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { JsonModal } from "./JsonModal";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
const STYLE =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Select, createOptions } from "@thisbeyond/solid-select";
|
||||
import "~/styles/solid-select.css";
|
||||
import { For, Show, createMemo, createSignal, onMount } from "solid-js";
|
||||
import { TinyButton } from "./layout";
|
||||
import { TinyButton } from "~/components";
|
||||
import { MutinyTagItem, sortByLastUsed } from "~/utils/tags";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Toast, toaster } from "@kobalte/core";
|
||||
import { Portal } from "solid-js/web";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { SmallHeader } from "./layout";
|
||||
import { SmallHeader } from "~/components";
|
||||
|
||||
export function Toaster() {
|
||||
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 { BackButton } from "./BackButton";
|
||||
import { BackButton } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
type StateWithPrevious = {
|
||||
|
||||
@@ -4,7 +4,7 @@ interface LinkifyProps {
|
||||
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
|
||||
const text = props.initialText;
|
||||
const links: (string | JSX.Element)[] = [];
|
||||
|
||||
@@ -8,8 +8,6 @@ import {
|
||||
createResource,
|
||||
createSignal
|
||||
} from "solid-js";
|
||||
import Linkify from "./Linkify";
|
||||
import { Button, ButtonLink } from "./Button";
|
||||
import {
|
||||
Collapsible,
|
||||
Checkbox as KCheckbox,
|
||||
@@ -23,13 +21,10 @@ import { generateGradient } from "~/utils/gradientHash";
|
||||
import close from "~/assets/icons/close.svg";
|
||||
import { A } from "solid-start";
|
||||
import down from "~/assets/icons/down.svg";
|
||||
import { DecryptDialog } from "../DecryptDialog";
|
||||
import { LoadingIndicator } from "~/components/LoadingIndicator";
|
||||
import { LoadingIndicator, DecryptDialog } from "~/components";
|
||||
import { LoadingSpinner } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export { Button, ButtonLink, Linkify };
|
||||
|
||||
export const SmallHeader: ParentComponent<{ class?: string }> = (props) => {
|
||||
return (
|
||||
<header class={`text-sm font-semibold uppercase ${props.class}`}>
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Progress } from "@kobalte/core";
|
||||
import { SmallHeader } from ".";
|
||||
import { SmallHeader } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export default function formatNumber(num: number) {
|
||||
export function formatNumber(num: number) {
|
||||
const map = [
|
||||
{ suffix: "T", threshold: 1e12 },
|
||||
{ suffix: "B", threshold: 1e9 },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { TextField as KTextField } from "@kobalte/core";
|
||||
import { type JSX, Show, splitProps } from "solid-js";
|
||||
import { TinyText } from ".";
|
||||
import { TinyText } from "~/components";
|
||||
|
||||
export type TextFieldProps = {
|
||||
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 { JSX } from "solid-js";
|
||||
import { Button } from "~/components/layout";
|
||||
import { Button } from "~/components";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER } from "~/styles/dialogs";
|
||||
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
|
||||
import "@mutinywallet/ui/style.css";
|
||||
import { Provider as MegaStoreProvider } from "~/state/megaStore";
|
||||
import { Toaster } from "~/components/Toaster";
|
||||
import ErrorDisplay from "./components/ErrorDisplay";
|
||||
import { I18nProvider } from "./components/I18nProvider";
|
||||
import { Toaster, ErrorDisplay, I18nProvider } from "~/components";
|
||||
|
||||
export default function Root() {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { For, Show, Suspense, createResource } from "solid-js";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@@ -8,18 +7,20 @@ import {
|
||||
NiceP,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { CombinedActivity } from "~/components/Activity";
|
||||
VStack,
|
||||
NavBar,
|
||||
BackLink,
|
||||
CombinedActivity,
|
||||
ContactEditor,
|
||||
ContactFormValues,
|
||||
ContactViewer,
|
||||
showToast,
|
||||
LoadingShimmer
|
||||
} from "~/components";
|
||||
import { Tabs } from "@kobalte/core";
|
||||
import { gradientsPerContact } from "~/utils/gradientHash";
|
||||
import { ContactEditor } from "~/components/ContactEditor";
|
||||
import { ContactFormValues, ContactViewer } from "~/components/ContactViewer";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import { LoadingShimmer } from "~/components/BalanceBox";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
function ContactRow() {
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
} from "@modular-forms/solid";
|
||||
import { Match, Show, Switch, createSignal } from "solid-js";
|
||||
import { A, useLocation } from "solid-start";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
Button,
|
||||
ButtonLink,
|
||||
@@ -17,17 +16,16 @@ import {
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
VStack
|
||||
VStack,
|
||||
BackPop,
|
||||
StyledRadioGroup,
|
||||
TextField
|
||||
} from "~/components/layout";
|
||||
import { BackPop } from "~/components/layout/BackPop";
|
||||
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 { InfoBox } from "~/components/InfoBox";
|
||||
import eify from "~/utils/eify";
|
||||
import { MegaCheck } from "~/components/successfail/MegaCheck";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { InfoBox, MegaCheck, NavBar } from "~/components";
|
||||
|
||||
const FEEDBACK_API = import.meta.env.VITE_FEEDBACK;
|
||||
|
||||
|
||||
@@ -13,7 +13,12 @@ import {
|
||||
Show,
|
||||
Switch
|
||||
} from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { objectToSearchParams } from "~/utils/objectToSearchParams";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { useNavigate } from "solid-start";
|
||||
import {
|
||||
Fee,
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
@@ -21,33 +26,29 @@ import {
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
SimpleDialog
|
||||
} from "~/components/layout";
|
||||
SimpleDialog,
|
||||
NavBar,
|
||||
AmountSats,
|
||||
AmountFiat,
|
||||
BackLink,
|
||||
TagEditor,
|
||||
StyledRadioGroup,
|
||||
showToast,
|
||||
AmountCard,
|
||||
BackButton,
|
||||
SuccessModal,
|
||||
MegaCheck,
|
||||
InfoBox,
|
||||
FeesModal,
|
||||
IntegratedQr
|
||||
} from "~/components";
|
||||
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 { 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 eify from "~/utils/eify";
|
||||
import { matchError } from "~/logic/errorDispatch";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { Fee } from "~/components/Fee";
|
||||
|
||||
type OnChainTx = {
|
||||
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 { useNavigate } from "solid-start";
|
||||
import { Button } from "~/components/layout";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import { Button, Scanner as Reader, showToast } from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { toParsedParams } from "~/logic/waila";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
|
||||
@@ -7,9 +7,10 @@ import {
|
||||
createSignal,
|
||||
onMount
|
||||
} from "solid-js";
|
||||
import { AmountSats, AmountFiat } from "~/components/Amount";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
NavBar,
|
||||
AmountSats,
|
||||
AmountFiat,
|
||||
Button,
|
||||
ButtonLink,
|
||||
Card,
|
||||
@@ -19,35 +20,35 @@ import {
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
VStack,
|
||||
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 { Scan } from "~/assets/svg/Scan";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
import { StyledRadioGroup } from "~/components/layout/Radio";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import eify from "~/utils/eify";
|
||||
import { MegaCheck } from "~/components/successfail/MegaCheck";
|
||||
import { MegaEx } from "~/components/successfail/MegaEx";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
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 { BackButton } from "~/components/layout/BackButton";
|
||||
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 { ParsedParams, toParsedParams } from "~/logic/waila";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { FeedbackLink } from "./Feedback";
|
||||
import { Fee } from "~/components/Fee";
|
||||
|
||||
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 {
|
||||
AmountCard,
|
||||
Fee,
|
||||
NavBar,
|
||||
OnboardWarning,
|
||||
Button,
|
||||
DefaultMain,
|
||||
ShareCard,
|
||||
LargeHeader,
|
||||
SafeArea,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
} from "~/components";
|
||||
|
||||
const SAMPLE =
|
||||
"bitcoin:tb1prqm8xtlgme0vmw5s30lgf0a4f5g4mkgsqundwmpu6thrg8zr6uvq2qrhzq?amount=0.001&lightning=lntbs1m1pj9n9xjsp5xgdrmvprtm67p7nq4neparalexlhlmtxx87zx6xeqthsplu842zspp546d6zd2seyaxpapaxx62m88yz3xueqtjmn9v6wj8y56np8weqsxqdqqnp4qdn2hj8tfknpuvdg6tz9yrf3e27ltrx9y58c24jh89lnm43yjwfc5xqrpwjcqpj9qrsgq5sdgh0m3ur5mu5hrmmag4mx9yvy86f83pd0x9ww80kgck6tac3thuzkj0mrtltaxwnlfea95h2re7tj4qsnwzxlvrdmyq2h9mgapnycpppz6k6";
|
||||
|
||||
@@ -9,33 +9,33 @@ import {
|
||||
createResource,
|
||||
createSignal
|
||||
} from "solid-js";
|
||||
import { AmountCard } from "~/components/AmountCard";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import {
|
||||
AmountCard,
|
||||
NavBar,
|
||||
showToast,
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
BackLink,
|
||||
TextField,
|
||||
VStack,
|
||||
MegaCheck,
|
||||
MegaEx,
|
||||
InfoBox,
|
||||
SuccessModal,
|
||||
AmountFiat
|
||||
} from "~/components";
|
||||
import { MethodChooser, SendSource } from "~/routes/Send";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
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 mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { SuccessModal } from "~/components/successfail/SuccessModal";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat } from "~/components/Amount";
|
||||
|
||||
const CHANNEL_FEE_ESTIMATE_ADDRESS =
|
||||
"bc1qf7546vg73ddsjznzq57z3e8jdn6gtw6au576j07kt6d9j7nz8mzsyn6lgf";
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { Title } from "solid-start";
|
||||
import { HttpStatusCode } from "solid-start/server";
|
||||
import {
|
||||
ButtonLink,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
SafeArea
|
||||
} from "~/components/layout";
|
||||
import { ButtonLink, DefaultMain, LargeHeader, SafeArea } from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export default function NotFound() {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import App from "~/components/App";
|
||||
import { Switch, Match } from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { FullscreenLoader } from "~/components/layout";
|
||||
import SetupErrorDisplay from "~/components/SetupErrorDisplay";
|
||||
import { App, FullscreenLoader, SetupErrorDisplay } from "~/components";
|
||||
|
||||
export default function Home() {
|
||||
const [state, _] = useMegaStore();
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { DeleteEverything } from "~/components/DeleteEverything";
|
||||
import KitchenSink from "~/components/KitchenSink";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
DeleteEverything,
|
||||
KitchenSink,
|
||||
NavBar,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
VStack,
|
||||
BackLink
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
export default function Admin() {
|
||||
|
||||
@@ -6,14 +6,14 @@ import {
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack,
|
||||
Checkbox
|
||||
} from "~/components/layout";
|
||||
import NavBar from "~/components/NavBar";
|
||||
Checkbox,
|
||||
NavBar,
|
||||
SeedWords,
|
||||
BackLink
|
||||
} from "~/components";
|
||||
import { useNavigate } from "solid-start";
|
||||
import { SeedWords } from "~/components/SeedWords";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Show, createEffect, createSignal } from "solid-js";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
function Quiz(props: { setHasCheckedAll: (hasChecked: boolean) => void }) {
|
||||
|
||||
@@ -9,11 +9,11 @@ import {
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
TinyText,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { AmountSmall } from "~/components/Amount";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import NavBar from "~/components/NavBar";
|
||||
VStack,
|
||||
AmountSmall,
|
||||
BackLink,
|
||||
NavBar
|
||||
} from "~/components";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
function BalanceBar(props: { inbound: number; outbound: number }) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { NwcProfile } from "@mutinywallet/mutiny-wasm";
|
||||
import { For, Show, createResource, createSignal } from "solid-js";
|
||||
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 {
|
||||
KeyValue,
|
||||
MiniStringShower,
|
||||
InfoBox,
|
||||
NavBar,
|
||||
ShareCard,
|
||||
Button,
|
||||
Collapser,
|
||||
DefaultMain,
|
||||
@@ -15,10 +16,10 @@ import {
|
||||
SafeArea,
|
||||
SettingsCard,
|
||||
SimpleDialog,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
VStack,
|
||||
BackLink,
|
||||
TextField
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
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 {
|
||||
DeleteEverything,
|
||||
ImportExport,
|
||||
LoadingIndicator,
|
||||
Logs,
|
||||
NavBar,
|
||||
DefaultMain,
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
SmallHeader,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
VStack,
|
||||
BackLink
|
||||
} from "~/components";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
|
||||
@@ -6,17 +6,17 @@ import {
|
||||
NiceP,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import NavBar from "~/components/NavBar";
|
||||
VStack,
|
||||
NavBar,
|
||||
BackLink,
|
||||
TextField,
|
||||
InfoBox
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { createForm } from "@modular-forms/solid";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
import { timeout } from "~/utils/timeout";
|
||||
import eify from "~/utils/eify";
|
||||
import { InfoBox } from "~/components/InfoBox";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
type EncryptPasswordForm = {
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { TextField } from "@kobalte/core";
|
||||
import { createSignal } from "solid-js";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
Button,
|
||||
NavBar,
|
||||
DefaultMain,
|
||||
InnerCard,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
SafeArea,
|
||||
BackLink
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
createSignal
|
||||
} from "solid-js";
|
||||
import { A } from "solid-start";
|
||||
import { ConfirmDialog } from "~/components/Dialog";
|
||||
import { InfoBox } from "~/components/InfoBox";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
ConfirmDialog,
|
||||
InfoBox,
|
||||
NavBar,
|
||||
Button,
|
||||
DefaultMain,
|
||||
FancyCard,
|
||||
@@ -19,13 +19,13 @@ import {
|
||||
NiceP,
|
||||
SafeArea,
|
||||
TinyText,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
VStack,
|
||||
BackLink,
|
||||
LoadingShimmer
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import eify from "~/utils/eify";
|
||||
import party from "~/assets/party.gif";
|
||||
import { LoadingShimmer } from "~/components/BalanceBox";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { subscriptionValid } from "~/utils/subscriptions";
|
||||
|
||||
|
||||
@@ -4,10 +4,14 @@ import {
|
||||
LargeHeader,
|
||||
NiceP,
|
||||
SafeArea,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import NavBar from "~/components/NavBar";
|
||||
VStack,
|
||||
BackLink,
|
||||
NavBar,
|
||||
TextFieldProps,
|
||||
showToast,
|
||||
ConfirmDialog,
|
||||
InfoBox
|
||||
} from "~/components";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { For, Show, createSignal, splitProps } from "solid-js";
|
||||
import pasteIcon from "~/assets/icons/paste.svg";
|
||||
@@ -20,13 +24,9 @@ import {
|
||||
validate
|
||||
} from "@modular-forms/solid";
|
||||
import { TextField as KTextField } from "@kobalte/core";
|
||||
import { TextFieldProps } from "~/components/layout/TextField";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import eify from "~/utils/eify";
|
||||
import { ConfirmDialog } from "~/components/Dialog";
|
||||
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
|
||||
import { WORDS_EN } from "~/utils/words";
|
||||
import { InfoBox } from "~/components/InfoBox";
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { createForm, url } from "@modular-forms/solid";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
import {
|
||||
MutinyWalletSettingStrings,
|
||||
setSettings
|
||||
@@ -8,16 +7,17 @@ import {
|
||||
Button,
|
||||
Card,
|
||||
DefaultMain,
|
||||
TextField,
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
NiceP,
|
||||
SafeArea
|
||||
} from "~/components/layout";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
SafeArea,
|
||||
showToast,
|
||||
BackLink,
|
||||
NavBar
|
||||
} from "~/components";
|
||||
import eify from "~/utils/eify";
|
||||
import { ExternalLink } from "@mutinywallet/ui";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ import {
|
||||
LargeHeader,
|
||||
SafeArea,
|
||||
SettingsCard,
|
||||
VStack
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import NavBar from "~/components/NavBar";
|
||||
VStack,
|
||||
BackLink,
|
||||
NavBar
|
||||
} from "~/components";
|
||||
import { A } from "solid-start";
|
||||
import { For, Show } from "solid-js";
|
||||
import forward from "~/assets/icons/forward.svg";
|
||||
|
||||
Reference in New Issue
Block a user