mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2025-12-30 04:14:25 +01:00
lint extravaganza
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { LoadingSpinner, NiceP, SmallAmount, SmallHeader } from "./layout"
|
||||
import { LoadingSpinner, NiceP } from "./layout"
|
||||
import {
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
createEffect,
|
||||
createMemo,
|
||||
@@ -11,9 +10,6 @@ import {
|
||||
} from "solid-js"
|
||||
import { useMegaStore } from "~/state/megaStore"
|
||||
import { MutinyInvoice } from "@mutinywallet/mutiny-wasm"
|
||||
import { JsonModal } from "~/components/JsonModal"
|
||||
import utxoIcon from "~/assets/icons/coin.svg"
|
||||
import { getRedshifted } from "~/utils/fakeLabels"
|
||||
import { ActivityItem } from "./ActivityItem"
|
||||
import { MutinyTagItem } from "~/utils/tags"
|
||||
import { Network } from "~/logic/mutinyWalletSetup"
|
||||
@@ -76,7 +72,7 @@ function OnChainItem(props: {
|
||||
}
|
||||
date={props.item.confirmation_time?.Confirmed?.time}
|
||||
positive={isReceive()}
|
||||
onClick={() => setOpen(!open())}
|
||||
onClick={() => setOpen(o => !o)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
@@ -96,52 +92,12 @@ function InvoiceItem(props: { item: MutinyInvoice; labels: MutinyTagItem[] }) {
|
||||
amount={props.item.amount_sats || 0n}
|
||||
date={props.item.last_updated}
|
||||
positive={!isSend()}
|
||||
onClick={() => setOpen(!open())}
|
||||
onClick={() => setOpen(o => !o)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function Utxo(props: { item: UtxoItem }) {
|
||||
const spent = createMemo(() => props.item.is_spent)
|
||||
|
||||
const [open, setOpen] = createSignal(false)
|
||||
|
||||
const redshifted = createMemo(() => getRedshifted(props.item.outpoint))
|
||||
|
||||
return (
|
||||
<>
|
||||
<JsonModal
|
||||
open={open()}
|
||||
data={props.item}
|
||||
title="Unspent Transaction Output"
|
||||
setOpen={setOpen}
|
||||
/>
|
||||
<div class={THREE_COLUMNS} onClick={() => setOpen(!open())}>
|
||||
<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}>Unknown</h2>}
|
||||
>
|
||||
<h2 class={REDSHIFT_LABEL}>Redshift</h2>
|
||||
</Show>
|
||||
</div>
|
||||
<SmallAmount amount={props.item.txout.value} />
|
||||
</div>
|
||||
<div class={RIGHT_COLUMN}>
|
||||
<SmallHeader class={spent() ? "text-m-red" : "text-m-green"}>
|
||||
{/* {spent() ? "SPENT" : "UNSPENT"} */}
|
||||
</SmallHeader>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
type ActivityItem = {
|
||||
type: "onchain" | "lightning"
|
||||
item: OnChainTx | MutinyInvoice
|
||||
|
||||
@@ -41,8 +41,8 @@ export const ActivityAmount: ParentComponent<{ amount: string, price: number, po
|
||||
function LabelCircle(props: { name?: string, contact: boolean }) {
|
||||
|
||||
// TODO: don't need to run this if it's not a contact
|
||||
const [gradient] = createResource(props.name, async (name: string) => {
|
||||
return generateGradient(name || "?")
|
||||
const [gradient] = createResource(async () => {
|
||||
return generateGradient(props.name || "?")
|
||||
})
|
||||
|
||||
const text = () => (props.contact && props.name && props.name.length) ? props.name[0] : (props.name && props.name.length) ? "≡" : "?"
|
||||
|
||||
@@ -57,10 +57,6 @@ function add(a: string, b?: string) {
|
||||
return Number(a || 0) + Number(b || 0);
|
||||
}
|
||||
|
||||
function subtract(a: string, b?: string) {
|
||||
return Number(a || 0) - Number(b || 0);
|
||||
}
|
||||
|
||||
export function AmountCard(props: {
|
||||
amountSats: string;
|
||||
fee?: string;
|
||||
|
||||
@@ -18,7 +18,7 @@ function SingleDigitButton(props: { character: string, onClick: (c: string) => v
|
||||
<Show when={props.fiat || !(props.character === ".")} fallback={<div />}>
|
||||
<button
|
||||
disabled={props.character === "."}
|
||||
class="disabled:opacity-50 p-2 rounded-lg hover:bg-white/10 active:bg-m-blue text-white text-4xl font-semi font-mono"
|
||||
class="disabled:opacity-50 p-2 rounded-lg md:hover:bg-white/10 active:bg-m-blue text-white text-4xl font-semi font-mono"
|
||||
onClick={() => props.onClick(props.character)}
|
||||
>
|
||||
{props.character}
|
||||
@@ -148,7 +148,7 @@ export const AmountEditable: ParentComponent<{ initialAmountSats: string, initia
|
||||
<Dialog.Content class={DIALOG_CONTENT} onEscapeKeyDown={() => setIsOpen(false)}>
|
||||
{/* TODO: figure out how to submit on enter */}
|
||||
<div class="w-full flex justify-end">
|
||||
<button tabindex="-1" onClick={() => setIsOpen(false)} class="hover:bg-white/10 rounded-lg active:bg-m-blue">
|
||||
<button onClick={() => setIsOpen(false)} class="hover:bg-white/10 rounded-lg active:bg-m-blue w-8 h-8">
|
||||
<img src={close} alt="Close" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import logo from '~/assets/icons/mutiny-logo.svg';
|
||||
import { DefaultMain, SafeArea, VStack, Card, LoadingSpinner } from "~/components/layout";
|
||||
import { DefaultMain, SafeArea, VStack, Card } from "~/components/layout";
|
||||
import BalanceBox, { LoadingShimmer } from "~/components/BalanceBox";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import ReloadPrompt from "~/components/Reload";
|
||||
@@ -18,7 +18,7 @@ export default function App() {
|
||||
<DefaultMain>
|
||||
<header class="w-full flex justify-between items-center mt-4 mb-2">
|
||||
<img src={logo} class="h-10" alt="logo" />
|
||||
<A class="md:hidden p-2 hover:bg-white/5 rounded-lg active:bg-m-blue" href="/activity"><img src={userClock} alt="Activity" /></A>
|
||||
<A class="md:hidden p-2 hover:bg-white/5 rounded-lg active:bg-m-blue" href="/activity"><img src={userClock} alt="Activity" class="h-8 w-8" /></A>
|
||||
</header>
|
||||
<Show when={!state.wallet_loading}>
|
||||
<OnboardWarning />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Show, Suspense } from "solid-js";
|
||||
import { Button, ButtonLink, FancyCard, Indicator } from "~/components/layout";
|
||||
import { Button, FancyCard, Indicator } from "~/components/layout";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Amount } from "./Amount";
|
||||
import { A, useNavigate } from "solid-start";
|
||||
@@ -15,10 +15,10 @@ function prettyPrintAmount(n?: number | bigint): string {
|
||||
export function LoadingShimmer() {
|
||||
return (<div class="flex flex-col gap-2 animate-pulse">
|
||||
<h1 class="text-4xl font-light">
|
||||
<div class="w-[12rem] rounded bg-neutral-700 h-[2.5rem]"></div>
|
||||
<div class="w-[12rem] rounded bg-neutral-700 h-[2.5rem]" />
|
||||
</h1>
|
||||
<h2 class="text-xl font-light text-white/70" >
|
||||
<div class="w-[8rem] rounded bg-neutral-700 h-[1.75rem]"></div>
|
||||
<div class="w-[8rem] rounded bg-neutral-700 h-[1.75rem]" />
|
||||
</h2>
|
||||
</div>)
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export function LoadingShimmer() {
|
||||
const STYLE = "px-2 py-1 rounded-xl border border-neutral-400 text-sm flex gap-2 items-center font-semibold"
|
||||
|
||||
export default function BalanceBox(props: { loading?: boolean }) {
|
||||
const [state, actions] = useMegaStore();
|
||||
const [state, _actions] = useMegaStore();
|
||||
|
||||
const emptyBalance = () => (state.balance?.confirmed || 0n) === 0n && (state.balance?.lightning || 0n) === 0n
|
||||
|
||||
@@ -46,7 +46,7 @@ export default function BalanceBox(props: { loading?: boolean }) {
|
||||
<Amount amountSats={state.balance?.confirmed} showFiat />
|
||||
<div class="self-end justify-self-end">
|
||||
<A href="/swap" class={STYLE}>
|
||||
<img src={shuffle} alt="swap" />
|
||||
<img src={shuffle} alt="swap" class="h-8 w-8" />
|
||||
</A>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,11 +8,10 @@ import {
|
||||
Switch,
|
||||
createMemo,
|
||||
} from "solid-js"
|
||||
import { Hr, TinyButton, VStack } from "~/components/layout"
|
||||
import { Hr, ModalCloseButton, TinyButton, VStack } from "~/components/layout"
|
||||
import { MutinyInvoice } from "@mutinywallet/mutiny-wasm"
|
||||
import { OnChainTx } from "./Activity"
|
||||
|
||||
import close from "~/assets/icons/close.svg"
|
||||
import bolt from "~/assets/icons/bolt-black.svg"
|
||||
import chain from "~/assets/icons/chain-black.svg"
|
||||
import copyIcon from "~/assets/icons/copy.svg"
|
||||
@@ -27,9 +26,9 @@ import mempoolTxUrl from "~/utils/mempoolTxUrl"
|
||||
import { Network } from "~/logic/mutinyWalletSetup"
|
||||
import { AmountSmall } from "./Amount"
|
||||
|
||||
const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||
const DIALOG_POSITIONER = "fixed inset-0 z-50 flex items-center justify-center"
|
||||
const DIALOG_CONTENT =
|
||||
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 }) {
|
||||
@@ -37,7 +36,7 @@ function LightningHeader(props: { info: MutinyInvoice }) {
|
||||
|
||||
const tags = createMemo(() => {
|
||||
if (props.info.labels.length) {
|
||||
let contact = state.mutiny_wallet?.get_contact(props.info.labels[0])
|
||||
const contact = state.mutiny_wallet?.get_contact(props.info.labels[0])
|
||||
if (contact) {
|
||||
return [tagToMutinyTag(contact)]
|
||||
} else {
|
||||
@@ -64,7 +63,9 @@ function LightningHeader(props: { info: MutinyInvoice }) {
|
||||
/>
|
||||
<For each={tags()}>
|
||||
{(tag) => (
|
||||
<TinyButton tag={tag} onClick={() => {}}>
|
||||
<TinyButton tag={tag} onClick={() => {
|
||||
// noop
|
||||
}}>
|
||||
{tag.name}
|
||||
</TinyButton>
|
||||
)}
|
||||
@@ -78,7 +79,7 @@ function OnchainHeader(props: { info: OnChainTx }) {
|
||||
|
||||
const tags = createMemo(() => {
|
||||
if (props.info.labels.length) {
|
||||
let contact = state.mutiny_wallet?.get_contact(props.info.labels[0])
|
||||
const contact = state.mutiny_wallet?.get_contact(props.info.labels[0])
|
||||
if (contact) {
|
||||
return [tagToMutinyTag(contact)]
|
||||
} else {
|
||||
@@ -117,7 +118,9 @@ function OnchainHeader(props: { info: OnChainTx }) {
|
||||
/>
|
||||
<For each={tags()}>
|
||||
{(tag) => (
|
||||
<TinyButton tag={tag} onClick={() => {}}>
|
||||
<TinyButton tag={tag} onClick={() => {
|
||||
// noop
|
||||
}}>
|
||||
{tag.name}
|
||||
</TinyButton>
|
||||
)}
|
||||
@@ -250,7 +253,7 @@ export function DetailsModal(props: {
|
||||
return (
|
||||
<Dialog.Root
|
||||
open={props.open}
|
||||
onOpenChange={(isOpen) => props.setOpen(isOpen)}
|
||||
onOpenChange={props.setOpen}
|
||||
>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay class={OVERLAY} />
|
||||
@@ -259,12 +262,7 @@ export function DetailsModal(props: {
|
||||
<div class="flex justify-between mb-2">
|
||||
<div />
|
||||
<Dialog.CloseButton>
|
||||
<button
|
||||
tabindex="-1"
|
||||
class="self-center hover:bg-white/10 rounded-lg active:bg-m-blue "
|
||||
>
|
||||
<img src={close} alt="Close" class="w-8 h-8" />
|
||||
</button>
|
||||
<ModalCloseButton />
|
||||
</Dialog.CloseButton>
|
||||
</div>
|
||||
<Dialog.Title>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Title } from "solid-start";
|
||||
import { Button, ButtonLink, DefaultMain, LargeHeader, SafeArea, SmallHeader } from "~/components/layout";
|
||||
import { Button, DefaultMain, LargeHeader, SafeArea, SmallHeader } from "~/components/layout";
|
||||
|
||||
export default function ErrorDisplay(props: { error: Error }) {
|
||||
return (
|
||||
|
||||
@@ -34,14 +34,16 @@ export function ImportExport() {
|
||||
reject(new Error("No text found in file"));
|
||||
}
|
||||
};
|
||||
fileReader.onerror = e => reject(new Error("File read error"));
|
||||
fileReader.onerror = _e => reject(new Error("File read error"));
|
||||
fileReader.readAsText(file, "UTF-8");
|
||||
});
|
||||
|
||||
// This should throw if there's a parse error, so we won't end up clearing
|
||||
JSON.parse(text);
|
||||
if (text) {
|
||||
JSON.parse(text);
|
||||
MutinyWallet.import_json(text);
|
||||
}
|
||||
|
||||
MutinyWallet.import_json(text);
|
||||
if (state.mutiny_wallet) {
|
||||
await state.mutiny_wallet.stop();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ParentComponent } from "solid-js";
|
||||
import { ButtonLink, SmallHeader } from "~/components/layout"
|
||||
import info from "~/assets/icons/info.svg"
|
||||
|
||||
export const InfoBox: ParentComponent<{ accent: "red" | "blue" | "green" | "white" }> = (props) => {
|
||||
|
||||
@@ -1,42 +1,36 @@
|
||||
import { Dialog } from "@kobalte/core";
|
||||
import { JSX, createMemo } from "solid-js";
|
||||
import { Button, SmallHeader } from "~/components/layout";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import { ModalCloseButton, SmallHeader } from "~/components/layout";
|
||||
import { DIALOG_CONTENT, DIALOG_POSITIONER, OVERLAY } from "~/components/DetailsModal";
|
||||
import { CopyButton } from "./ShareCard";
|
||||
|
||||
const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||
const DIALOG_POSITIONER = "fixed inset-0 z-50 flex items-center justify-center"
|
||||
const DIALOG_CONTENT = "max-w-[600px] max-h-full mx-4 p-4 bg-neutral-900/50 backdrop-blur-md shadow-xl rounded-xl border border-white/10"
|
||||
|
||||
export function JsonModal(props: { title: string, open: boolean, data?: unknown, setOpen: (open: boolean) => void, children?: JSX.Element }) {
|
||||
const json = createMemo(() => JSON.stringify(props.data, null, 2));
|
||||
|
||||
const [copy, copied] = useCopy({ copiedTimeout: 1000 });
|
||||
export function JsonModal(props: { title: string, open: boolean, plaintext?: string, data?: unknown, setOpen: (open: boolean) => void, children?: JSX.Element }) {
|
||||
const json = createMemo(() => props.plaintext ? props.plaintext : JSON.stringify(props.data, null, 2));
|
||||
|
||||
return (
|
||||
<Dialog.Root open={props.open} onOpenChange={(isOpen) => props.setOpen(isOpen)}>
|
||||
<Dialog.Root open={props.open} onOpenChange={props.setOpen}>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay class={OVERLAY} />
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
<div class="flex justify-between mb-2">
|
||||
<div class="flex justify-between mb-2 items-center">
|
||||
<Dialog.Title>
|
||||
<SmallHeader>
|
||||
{props.title}
|
||||
</SmallHeader>
|
||||
</Dialog.Title>
|
||||
<Dialog.CloseButton>
|
||||
<code>X</code>
|
||||
<ModalCloseButton />
|
||||
</Dialog.CloseButton>
|
||||
</div>
|
||||
<Dialog.Description class="flex flex-col gap-4">
|
||||
<div class="bg-white/10 rounded-xl max-h-[50vh] overflow-y-scroll disable-scrollbars p-4">
|
||||
<Dialog.Description class="flex flex-col gap-4 items-center">
|
||||
<div class="bg-white/5 rounded-xl max-h-[50vh] overflow-y-scroll disable-scrollbars p-4">
|
||||
<pre class="whitespace-pre-wrap break-all">
|
||||
{json()}
|
||||
</pre>
|
||||
</div>
|
||||
{props.children}
|
||||
<Button onClick={(_) => copy(json() ?? "")}>{copied() ? "Copied" : "Copy"}</Button>
|
||||
<Button onClick={(_) => props.setOpen(false)}>Close</Button>
|
||||
<CopyButton title="Copy" text={json()} />
|
||||
</Dialog.Description>
|
||||
</Dialog.Content>
|
||||
</div>
|
||||
|
||||
@@ -7,13 +7,15 @@ export default function Scanner(props: { onResult: (result: string) => void }) {
|
||||
// TODO: not sure it's appropriate to use a signal for this but it works!
|
||||
const [scanner, setScanner] = createSignal<QrScanner | null>(null);
|
||||
|
||||
const handleResult = (result: { data: string }) => {
|
||||
props.onResult(result.data);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (container) {
|
||||
const newScanner = new QrScanner(
|
||||
container,
|
||||
(result: { data: string }) => {
|
||||
props.onResult(result.data);
|
||||
},
|
||||
handleResult,
|
||||
{
|
||||
returnDetailedScanResult: true,
|
||||
}
|
||||
|
||||
@@ -2,26 +2,26 @@ 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'
|
||||
import { Button, Card } from '~/components/layout'
|
||||
|
||||
const ReloadPrompt: Component = () => {
|
||||
const {
|
||||
offlineReady: [offlineReady, setOfflineReady],
|
||||
needRefresh: [needRefresh, setNeedRefresh],
|
||||
updateServiceWorker,
|
||||
offlineReady: [offlineReady, _setOfflineReady],
|
||||
needRefresh: [needRefresh, _setNeedRefresh],
|
||||
updateServiceWorker: _update,
|
||||
} = useRegisterSW({
|
||||
onRegistered(r: ServiceWorkerRegistration) {
|
||||
console.log('SW Registered: ' + r.scope)
|
||||
immediate: true,
|
||||
onRegisteredSW(swUrl, r) {
|
||||
console.log('SW Registered: ' + r?.scope)
|
||||
},
|
||||
onRegisterError(error: Error) {
|
||||
console.log('SW registration error', error)
|
||||
},
|
||||
})
|
||||
|
||||
const close = () => {
|
||||
setOfflineReady(false)
|
||||
setNeedRefresh(false)
|
||||
}
|
||||
// const close = () => {
|
||||
// setOfflineReady(false)
|
||||
// setNeedRefresh(false)
|
||||
// }
|
||||
|
||||
return (
|
||||
<Show when={offlineReady() || needRefresh()}>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Button, Card, NiceP, VStack } from "~/components/layout";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { downloadTextFile } from "~/utils/download";
|
||||
|
||||
export function Restart() {
|
||||
const [state, _] = useMegaStore()
|
||||
|
||||
async function handleStop() {
|
||||
const result = await state.mutiny_wallet?.stop()
|
||||
await state.mutiny_wallet?.stop()
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ import eyeIcon from "~/assets/icons/eye.svg"
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { JsonModal } from "./JsonModal";
|
||||
|
||||
const STYLE = "px-4 py-2 rounded-xl border-2 border-white flex gap-2 items-center font-semibold"
|
||||
const STYLE = "px-4 py-2 rounded-xl border-2 border-white flex gap-2 items-center font-semibold hover:text-m-blue transition-colors"
|
||||
|
||||
export function ShareButton(props: { receiveString: string }) {
|
||||
async function share(receiveString: string) {
|
||||
@@ -34,7 +34,7 @@ export function StringShower(props: { text: string }) {
|
||||
const [open, setOpen] = createSignal(false);
|
||||
return (
|
||||
<>
|
||||
<JsonModal open={open()} data={props.text} title="Details" setOpen={setOpen} />
|
||||
<JsonModal open={open()} plaintext={props.text} title="Details" setOpen={setOpen} />
|
||||
<div class="w-full grid grid-cols-[minmax(0,_1fr)_auto]">
|
||||
<pre class="truncate text-neutral-400">{props.text}</pre>
|
||||
<button class="w-[2rem]" onClick={() => setOpen(true)}>
|
||||
|
||||
@@ -44,6 +44,11 @@ export function TagEditor(props: {
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: eslint is mad about reactivity
|
||||
const onTagTap = (tag: MutinyTagItem) => {
|
||||
props.setSelectedValues([...props.selectedValues!, tag]);
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="flex flex-col gap-2 flex-shrink flex-1" >
|
||||
<Select
|
||||
@@ -57,7 +62,8 @@ export function TagEditor(props: {
|
||||
<Show when={availableTags() && availableTags()!.length > 0}>
|
||||
<For each={availableTags()!.slice(0, 3)}>
|
||||
{(tag) => (
|
||||
<TinyButton tag={tag} onClick={() => props.setSelectedValues([...props.selectedValues!, tag])}>
|
||||
// eslint-disable-next-line solid/reactivity
|
||||
<TinyButton tag={tag} onClick={() => onTagTap(tag)}>
|
||||
{tag.name}
|
||||
</TinyButton>
|
||||
)}
|
||||
|
||||
@@ -15,8 +15,13 @@ type FullscreenModalProps = {
|
||||
}
|
||||
|
||||
export function FullscreenModal(props: FullscreenModalProps) {
|
||||
|
||||
const onNice = () => {
|
||||
props.onConfirm ? props.onConfirm() : props.setOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog.Root open={props.open} onOpenChange={(isOpen) => props.setOpen(isOpen)}>
|
||||
<Dialog.Root open={props.open} onOpenChange={props.setOpen}>
|
||||
<Dialog.Portal>
|
||||
<div class={DIALOG_POSITIONER}>
|
||||
<Dialog.Content class={DIALOG_CONTENT}>
|
||||
@@ -34,7 +39,7 @@ export function FullscreenModal(props: FullscreenModalProps) {
|
||||
{props.children}
|
||||
</Dialog.Description>
|
||||
<div class="w-full flex">
|
||||
<Button onClick={(_) => props.onConfirm ? props.onConfirm() : props.setOpen(false)}>{props.confirmText ?? "Nice"}</Button>
|
||||
<Button onClick={onNice}>{props.confirmText ?? "Nice"}</Button>
|
||||
</div>
|
||||
</Dialog.Content>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function Linkify(props: LinkifyProps): JSX.Element {
|
||||
links.push(beforeLink);
|
||||
}
|
||||
|
||||
links.push(<a href={href} target="_blank" rel="noopener noreferrer">{link}</a>);
|
||||
links.push(<a href={href} class="break-all" target="_blank" rel="noopener noreferrer">{link}</a>);
|
||||
}
|
||||
|
||||
const remainingText = text.slice(lastIndex);
|
||||
|
||||
@@ -7,7 +7,7 @@ type Choices = { value: string, label: string, caption: string }[]
|
||||
export function StyledRadioGroup(props: { value: string, choices: Choices, onValueChange: (value: string) => void, small?: boolean, accent?: "red" | "white" }) {
|
||||
return (
|
||||
// TODO: rewrite this with CVA, props are bad for tailwind
|
||||
<RadioGroup.Root value={props.value} onChange={(e) => props.onValueChange(e)}
|
||||
<RadioGroup.Root value={props.value} onChange={props.onValueChange}
|
||||
class={"grid w-full gap-4"}
|
||||
classList={{ "grid-cols-2": props.choices.length === 2, "grid-cols-3": props.choices.length === 3, "gap-2": props.small }}
|
||||
>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { JSX, ParentComponent, Show, Suspense, createResource, createSignal } from "solid-js"
|
||||
import { JSX, ParentComponent, Show, Suspense, createResource } from "solid-js"
|
||||
import Linkify from "./Linkify"
|
||||
import { Button, ButtonLink } from "./Button"
|
||||
import { Checkbox as KCheckbox, Separator } from "@kobalte/core"
|
||||
@@ -6,6 +6,7 @@ import { useMegaStore } from "~/state/megaStore"
|
||||
import check from "~/assets/icons/check.svg"
|
||||
import { MutinyTagItem } from "~/utils/tags"
|
||||
import { generateGradient } from "~/utils/gradientHash"
|
||||
import close from "~/assets/icons/close.svg"
|
||||
|
||||
export {
|
||||
Button,
|
||||
@@ -128,8 +129,8 @@ export const NiceP: ParentComponent = (props) => {
|
||||
|
||||
export const TinyButton: ParentComponent<{ onClick: () => void, tag?: MutinyTagItem }> = (props) => {
|
||||
// TODO: don't need to run this if it's not a contact
|
||||
const [gradient] = createResource(props.tag?.name, async (name: string) => {
|
||||
return generateGradient(name || "?")
|
||||
const [gradient] = createResource(async () => {
|
||||
return generateGradient(props.tag?.name || "?")
|
||||
})
|
||||
|
||||
const bg = () => (props.tag?.name && props.tag?.kind === "Contact") ? gradient() : "rgb(255 255 255 / 0.1)"
|
||||
@@ -161,4 +162,12 @@ export function Checkbox(props: { label: string, checked: boolean, onChange: (ch
|
||||
<KCheckbox.Label class="flex-1 text-xl font-light">{props.label}</KCheckbox.Label>
|
||||
</KCheckbox.Root>
|
||||
)
|
||||
}
|
||||
|
||||
export function ModalCloseButton() {
|
||||
return (<button
|
||||
class="self-center justify-self-center hover:bg-white/10 rounded-lg active:bg-m-blue"
|
||||
>
|
||||
<img src={close} alt="Close" class="w-8 h-8" />
|
||||
</button>)
|
||||
}
|
||||
@@ -35,12 +35,12 @@ export function WaitlistAlreadyIn() {
|
||||
const [posts] = createResource("", postsFetcher);
|
||||
|
||||
return (
|
||||
<main class='flex flex-col gap-2 sm:gap-4 py-8 px-4 max-w-xl mx-auto items-start drop-shadow-blue-glow'>
|
||||
<main class='flex flex-col gap-4 sm:gap-4 py-8 px-4 max-w-xl mx-auto items-start drop-shadow-blue-glow'>
|
||||
<a href="https://mutinywallet.com">
|
||||
<img src={logo} class="h-10" alt="logo" />
|
||||
</a>
|
||||
<h1 class="text-4xl font-bold">You're on a list!</h1>
|
||||
<h2 class="text-xl">
|
||||
<h2 class="text-xl pr-4">
|
||||
We'll message you when Mutiny Wallet is ready.
|
||||
</h2>
|
||||
<div class="px-4 sm:px-8 py-8 rounded-xl bg-half-black w-full">
|
||||
|
||||
@@ -19,9 +19,10 @@ function ContactRow() {
|
||||
const contacts = state.mutiny_wallet?.get_contacts();
|
||||
console.log(contacts)
|
||||
|
||||
let c: Contact[] = []
|
||||
// FIXME: this is just types shenanigans I believe
|
||||
const c: Contact[] = []
|
||||
if (contacts) {
|
||||
for (let contact in contacts) {
|
||||
for (const contact in contacts) {
|
||||
c.push(contacts[contact])
|
||||
}
|
||||
}
|
||||
@@ -37,7 +38,7 @@ function ContactRow() {
|
||||
}
|
||||
|
||||
//
|
||||
async function saveContact(contact: ContactFormValues) {
|
||||
async function saveContact(_contact: ContactFormValues) {
|
||||
showToast(new Error("Unimplemented"))
|
||||
// await editContact(contact)
|
||||
refetch();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Contact, MutinyBip21RawMaterials, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
import { createEffect, createMemo, createResource, createSignal, Match, onCleanup, onMount, Show, Switch } from "solid-js";
|
||||
import { createEffect, createMemo, createResource, createSignal, Match, onCleanup, Show, Switch } from "solid-js";
|
||||
import { QRCodeSVG } from "solid-qr-code";
|
||||
import { Button, Card, DefaultMain, Indicator, LargeHeader, MutinyWalletGuard, SafeArea } from "~/components/layout";
|
||||
import NavBar from "~/components/NavBar";
|
||||
@@ -51,7 +51,7 @@ type ReceiveState = "edit" | "show" | "paid"
|
||||
type PaidState = "lightning_paid" | "onchain_paid";
|
||||
|
||||
export default function Receive() {
|
||||
const [state, actions] = useMegaStore()
|
||||
const [state, _actions] = useMegaStore()
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [amount, setAmount] = createSignal("")
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import {
|
||||
Component,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createResource,
|
||||
createSignal,
|
||||
For,
|
||||
Match,
|
||||
onCleanup,
|
||||
onMount,
|
||||
ParentComponent,
|
||||
Show,
|
||||
@@ -53,8 +51,8 @@ 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 = any // Replace with the actual TypeScript type for RedshiftRecipient
|
||||
type PublicKey = any // Replace with the actual TypeScript type for PublicKey
|
||||
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
|
||||
@@ -96,52 +94,50 @@ function RedshiftReport(props: { redshift: RedshiftResult; utxo: UtxoItem }) {
|
||||
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)
|
||||
}
|
||||
// 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 [_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 inputUtxo = createMemo(() => {
|
||||
// console.log(utxos())
|
||||
// const foundUtxo = findUtxoByOutpoint(props.redshift.input_utxo, utxos())
|
||||
// console.log("Found utxo:", foundUtxo)
|
||||
// return foundUtxo
|
||||
// })
|
||||
|
||||
async function checkRedshift(id: string) {
|
||||
// const rs = redshiftItems[0] as RedshiftResult;
|
||||
console.log("Checking redshift", id)
|
||||
const redshift = await state.mutiny_wallet?.get_redshift(id)
|
||||
console.log(redshift)
|
||||
return redshift
|
||||
}
|
||||
const [redshiftResource, { refetch: _refetchRedshift }] = createResource(
|
||||
|
||||
const [redshiftResource, { refetch }] = createResource(
|
||||
props.redshift.id,
|
||||
checkRedshift
|
||||
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))
|
||||
// const interval = setInterval(() => {
|
||||
// if (redshiftResource()) refetch()
|
||||
// // if (sentAmount() === 200000) {
|
||||
// // clearInterval(interval)
|
||||
// // props.setShiftStage("success");
|
||||
// // // setSentAmount((0))
|
||||
|
||||
// } else {
|
||||
// setSentAmount((sentAmount() + 50000))
|
||||
// }
|
||||
}, 1000)
|
||||
// // } else {
|
||||
// // setSentAmount((sentAmount() + 50000))
|
||||
// // }
|
||||
// }, 1000)
|
||||
})
|
||||
|
||||
const outputUtxo = createMemo(() => {
|
||||
return findUtxoByOutpoint(redshiftResource()?.output_utxo, utxos())
|
||||
})
|
||||
|
||||
// const outputUtxo = createMemo(() => {
|
||||
// return findUtxoByOutpoint(redshiftResource()?.output_utxo, utxos())
|
||||
// })
|
||||
|
||||
createEffect(() => {
|
||||
setRedshifted(true, redshiftResource()?.output_utxo)
|
||||
@@ -170,23 +166,23 @@ function RedshiftReport(props: { redshift: RedshiftResult; utxo: UtxoItem }) {
|
||||
</Show>
|
||||
</KV> */}
|
||||
<KV key="Starting amount">
|
||||
<Amount amountSats={redshiftResource().amount_sats} />
|
||||
<Amount amountSats={redshiftResource()!.amount_sats} />
|
||||
</KV>
|
||||
<KV key="Fees paid">
|
||||
<Amount amountSats={redshiftResource().fees_paid} />
|
||||
<Amount amountSats={redshiftResource()!.fees_paid} />
|
||||
</KV>
|
||||
<KV key="Change">
|
||||
<Amount amountSats={redshiftResource().change_amt} />
|
||||
<Amount amountSats={redshiftResource()!.change_amt} />
|
||||
</KV>
|
||||
<KV key="Outbound channel">
|
||||
<VStack>
|
||||
<pre class="whitespace-pre-wrap break-all">
|
||||
{redshiftResource().introduction_channel}
|
||||
{redshiftResource()!.introduction_channel}
|
||||
</pre>
|
||||
<a
|
||||
class=""
|
||||
href={mempoolTxUrl(
|
||||
redshiftResource().introduction_channel?.split(":")[0],
|
||||
redshiftResource()!.introduction_channel?.split(":")[0],
|
||||
network
|
||||
)}
|
||||
target="_blank"
|
||||
@@ -196,16 +192,16 @@ function RedshiftReport(props: { redshift: RedshiftResult; utxo: UtxoItem }) {
|
||||
</a>
|
||||
</VStack>
|
||||
</KV>
|
||||
<Show when={redshiftResource().output_channel}>
|
||||
<Show when={redshiftResource()!.output_channel}>
|
||||
<KV key="Return channel">
|
||||
<VStack>
|
||||
<pre class="whitespace-pre-wrap break-all">
|
||||
{redshiftResource().output_channel}
|
||||
{redshiftResource()!.output_channel}
|
||||
</pre>
|
||||
<a
|
||||
class=""
|
||||
href={mempoolTxUrl(
|
||||
redshiftResource().output_channel?.split(":")[0],
|
||||
redshiftResource()!.output_channel?.split(":")[0],
|
||||
network
|
||||
)}
|
||||
target="_blank"
|
||||
@@ -219,7 +215,6 @@ function RedshiftReport(props: { redshift: RedshiftResult; utxo: UtxoItem }) {
|
||||
</VStack>
|
||||
</Card>
|
||||
</Show>
|
||||
<SmallHeader></SmallHeader>
|
||||
</VStack>
|
||||
</VStack>
|
||||
)
|
||||
@@ -238,7 +233,7 @@ export function Utxo(props: { item: UtxoItem; onClick?: () => void }) {
|
||||
const redshifted = createMemo(() => getRedshifted(props.item.outpoint))
|
||||
return (
|
||||
<>
|
||||
<div class={THREE_COLUMNS} onClick={props.onClick}>
|
||||
<div class={THREE_COLUMNS} onClick={() => props.onClick && props.onClick()}>
|
||||
<div class="flex items-center">
|
||||
<img src={utxoIcon} alt="coin" />
|
||||
</div>
|
||||
@@ -275,11 +270,11 @@ const FAKE_STATES = [
|
||||
|
||||
function ShiftObserver(props: {
|
||||
setShiftStage: (stage: ShiftStage) => void
|
||||
redshiftId: String
|
||||
redshiftId: string
|
||||
}) {
|
||||
const [state, _actions] = useMegaStore()
|
||||
const [_state, _actions] = useMegaStore()
|
||||
|
||||
const [fakeStage, setFakeStage] = createSignal(2)
|
||||
const [fakeStage, _setFakeStage] = createSignal(2)
|
||||
|
||||
const [sentAmount, setSentAmount] = createSignal(0)
|
||||
|
||||
@@ -295,17 +290,17 @@ function ShiftObserver(props: {
|
||||
}, 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
|
||||
}
|
||||
// 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
|
||||
)
|
||||
// const [redshiftResource, { refetch }] = createResource(
|
||||
// props.redshiftId,
|
||||
// checkRedshift
|
||||
// )
|
||||
|
||||
// onMount(() => {
|
||||
// const interval = setInterval(() => {
|
||||
@@ -377,7 +372,7 @@ export default function Redshift() {
|
||||
}
|
||||
|
||||
const [utxos, { refetch: _refetchUtxos }] = createResource(getUtXos)
|
||||
const [channels, { refetch: _refetchChannels }] = createResource(getChannels)
|
||||
const [_channels, { refetch: _refetchChannels }] = createResource(getChannels)
|
||||
|
||||
const redshiftedUtxos = createMemo(() => {
|
||||
return utxos()?.filter((utxo) => getRedshifted(utxo.outpoint))
|
||||
@@ -515,7 +510,7 @@ export default function Redshift() {
|
||||
<Match when={shiftStage() === "observe" && chosenUtxo()}>
|
||||
<ShiftObserver
|
||||
setShiftStage={setShiftStage}
|
||||
utxo={chosenUtxo()!}
|
||||
redshiftId="dummy-redshift"
|
||||
/>
|
||||
</Match>
|
||||
<Match when={shiftStage() === "success" && chosenUtxo()}>
|
||||
|
||||
@@ -32,6 +32,7 @@ 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";
|
||||
|
||||
export type SendSource = "lightning" | "onchain";
|
||||
|
||||
@@ -407,6 +408,8 @@ export default function Send() {
|
||||
const sendButtonDisabled = createMemo(() => {
|
||||
return !destination() || sending() || amountSats() === 0n;
|
||||
});
|
||||
|
||||
const network = state.mutiny_wallet?.get_network() as Network
|
||||
|
||||
return (
|
||||
<MutinyWalletGuard>
|
||||
@@ -441,7 +444,7 @@ export default function Send() {
|
||||
<Amount amountSats={sentDetails()?.amount} showFiat />
|
||||
<Show when={sentDetails()?.txid}>
|
||||
<a
|
||||
href={mempoolTxUrl(sentDetails()?.txid, state.mutiny_wallet?.get_network())}
|
||||
href={mempoolTxUrl(sentDetails()?.txid, network)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
||||
@@ -1,32 +1,12 @@
|
||||
import { Match, Show, Switch } from "solid-js";
|
||||
import { ActivityItem } from "~/components/ActivityItem";
|
||||
import { Amount } from "~/components/Amount";
|
||||
import { AmountCard } from "~/components/AmountCard";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import { OnboardWarning } from "~/components/OnboardWarning";
|
||||
import { ShareCard } from "~/components/ShareCard";
|
||||
import { Card, DefaultMain, LargeHeader, SafeArea, SmallHeader, VStack } from "~/components/layout";
|
||||
import { FullscreenModal } from "~/components/layout/FullscreenModal";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import megaex from "~/assets/icons/megaex.png";
|
||||
import megacheck from "~/assets/icons/megacheck.png";
|
||||
import { DefaultMain, LargeHeader, SafeArea, VStack } from "~/components/layout";
|
||||
|
||||
const SAMPLE =
|
||||
"bitcoin:tb1prqm8xtlgme0vmw5s30lgf0a4f5g4mkgsqundwmpu6thrg8zr6uvq2qrhzq?amount=0.001&lightning=lntbs1m1pj9n9xjsp5xgdrmvprtm67p7nq4neparalexlhlmtxx87zx6xeqthsplu842zspp546d6zd2seyaxpapaxx62m88yz3xueqtjmn9v6wj8y56np8weqsxqdqqnp4qdn2hj8tfknpuvdg6tz9yrf3e27ltrx9y58c24jh89lnm43yjwfc5xqrpwjcqpj9qrsgq5sdgh0m3ur5mu5hrmmag4mx9yvy86f83pd0x9ww80kgck6tac3thuzkj0mrtltaxwnlfea95h2re7tj4qsnwzxlvrdmyq2h9mgapnycpppz6k6";
|
||||
export default function Admin() {
|
||||
const channelOpenResult = () => {
|
||||
return {
|
||||
channel: {
|
||||
balance: 100000n,
|
||||
reserve: 1000n,
|
||||
outpoint: "123:0"
|
||||
},
|
||||
failure_reason: undefined
|
||||
};
|
||||
};
|
||||
|
||||
const setChannelOpenResult = (result: any) => {};
|
||||
|
||||
return (
|
||||
<SafeArea>
|
||||
<DefaultMain>
|
||||
@@ -35,64 +15,9 @@ export default function Admin() {
|
||||
<VStack>
|
||||
<AmountCard amountSats={"100000"} fee={"69"} />
|
||||
<ShareCard text={SAMPLE} />
|
||||
{/* <Card title="Activity">
|
||||
<ActivityItem kind="lightning" labels={["benthecarman"]} amount={100000} date={1683664966} />
|
||||
<ActivityItem kind="onchain" labels={["tony"]} amount={42000000} positive date={1683664966} />
|
||||
<ActivityItem kind="onchain" labels={["a fake name thati is too long"]} amount={42000000} date={1683664966} />
|
||||
<ActivityItem kind="onchain" labels={["a fake name thati is too long"]} amount={42000000} date={1683664966} />
|
||||
</Card> */}
|
||||
<FullscreenModal
|
||||
title={channelOpenResult()?.channel ? "Channel Opened" : "Channel Open Failed"}
|
||||
confirmText={channelOpenResult()?.channel ? "Nice" : "Too Bad"}
|
||||
open={!!channelOpenResult()}
|
||||
setOpen={(open: boolean) => {
|
||||
if (!open) setChannelOpenResult(undefined);
|
||||
}}
|
||||
onConfirm={() => {
|
||||
setChannelOpenResult(undefined);
|
||||
// navigate("/");
|
||||
}}
|
||||
>
|
||||
<div class="flex flex-col items-center gap-8 pb-8">
|
||||
<Switch>
|
||||
<Match when={channelOpenResult()?.failure_reason}>
|
||||
<img src={megaex} alt="fail" class="w-1/2 mx-auto max-w-[30vh] flex-shrink" />
|
||||
|
||||
<p class="text-xl font-light py-2 px-4 rounded-xl bg-white/10">
|
||||
{channelOpenResult()?.failure_reason?.message}
|
||||
</p>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<img
|
||||
src={megacheck}
|
||||
alt="success"
|
||||
class="w-1/2 mx-auto max-w-[30vh] flex-shrink"
|
||||
/>
|
||||
<AmountCard
|
||||
amountSats={channelOpenResult()?.channel?.balance.toString()}
|
||||
reserve={"1000"}
|
||||
/>
|
||||
<Show when={channelOpenResult()?.channel?.outpoint}>
|
||||
<a
|
||||
class=""
|
||||
href={mempoolTxUrl(
|
||||
channelOpenResult()?.channel?.outpoint?.split(":")[0],
|
||||
"signet"
|
||||
)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Mempool Link
|
||||
</a>
|
||||
</Show>
|
||||
{/* <pre>{JSON.stringify(channelOpenResult()?.channel?.value, null, 2)}</pre> */}
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
</FullscreenModal>
|
||||
</VStack>
|
||||
</DefaultMain>
|
||||
<NavBar activeTab="none" />
|
||||
</SafeArea>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
LargeHeader,
|
||||
MutinyWalletGuard,
|
||||
SafeArea,
|
||||
VStack
|
||||
VStack,
|
||||
} from "~/components/layout";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { TextField } from "~/components/layout/TextField";
|
||||
@@ -25,7 +25,6 @@ import { InfoBox } from "~/components/InfoBox";
|
||||
import { FullscreenModal } from "~/components/layout/FullscreenModal";
|
||||
import { useNavigate } from "solid-start";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
|
||||
const CHANNEL_FEE_ESTIMATE_ADDRESS =
|
||||
"bc1qf7546vg73ddsjznzq57z3e8jdn6gtw6au576j07kt6d9j7nz8mzsyn6lgf";
|
||||
@@ -40,7 +39,7 @@ type ChannelOpenDetails = {
|
||||
};
|
||||
|
||||
export default function Swap() {
|
||||
const [state, actions] = useMegaStore();
|
||||
const [state, _actions] = useMegaStore();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [source, setSource] = createSignal<SendSource>("onchain");
|
||||
@@ -166,8 +165,6 @@ export default function Swap() {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const network = state.mutiny_wallet?.get_network() as Network;
|
||||
|
||||
return (
|
||||
<MutinyWalletGuard>
|
||||
<SafeArea>
|
||||
|
||||
@@ -154,6 +154,7 @@ export const Provider: ParentComponent = (props) => {
|
||||
|
||||
// Fetch status from remote on load
|
||||
onMount(() => {
|
||||
// eslint-disable-next-line
|
||||
actions.fetchUserStatus().then(status => {
|
||||
setState({ user_status: status })
|
||||
|
||||
@@ -163,7 +164,7 @@ export const Provider: ParentComponent = (props) => {
|
||||
actions.setupMutinyWallet().then(() => console.log("node manager setup done"))
|
||||
|
||||
// Setup an event listener to stop the mutiny wallet when the page unloads
|
||||
window.onunload = async (e) => {
|
||||
window.onunload = async (_e) => {
|
||||
console.log("stopping mutiny_wallet")
|
||||
await state.mutiny_wallet?.stop();
|
||||
console.log("mutiny_wallet stopped")
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export const DIALOG_POSITIONER = "fixed inset-0 h-[100dvh] z-50"
|
||||
export const DIALOG_CONTENT = "h-[100dvh] flex flex-col justify-between px-4 pt-4 pb-8 bg-neutral-800/80 backdrop-blur-xl"
|
||||
export const DIALOG_CONTENT = "h-[100dvh] flex flex-col justify-between px-4 pt-4 pb-8 bg-neutral-800/80 backdrop-blur-xl touch-manipulation select-none"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// https://stackoverflow.com/questions/34156282/how-do-i-save-json-to-local-text-file
|
||||
|
||||
export function downloadTextFile(content: string, fileName: string, type: string) {
|
||||
export function downloadTextFile(content: string, fileName: string, type?: string) {
|
||||
const contentType = type ? type : "application/json";
|
||||
const a = document.createElement("a");
|
||||
const file = new Blob([content], { type: contentType });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Contact, TagItem } from "@mutinywallet/mutiny-wasm"
|
||||
import { TagItem } from "@mutinywallet/mutiny-wasm"
|
||||
|
||||
export type MutinyTagItem = {
|
||||
id: string,
|
||||
@@ -20,8 +20,7 @@ export function tagsToIds(tags?: MutinyTagItem[]): string[] {
|
||||
}
|
||||
|
||||
export function tagToMutinyTag(tag: TagItem): MutinyTagItem {
|
||||
// @ts-ignore
|
||||
// FIXME: make typescript less mad about this
|
||||
// @ts-expect-error: FIXME: make typescript less mad about this
|
||||
return tag as MutinyTagItem
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user