import { ClipboardPasteIcon, InfoIcon } from "lucide-react"; import React from "react"; import { toast } from "sonner"; import { ExecuteCustomNodeCommandDialogContent } from "src/components/ExecuteCustomNodeCommandDialogContent"; import ExternalLink from "src/components/ExternalLink"; import { ResetRoutingDataDialogContent } from "src/components/ResetRoutingDataDialogContent"; import SettingsHeader from "src/components/SettingsHeader"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "src/components/ui/alert-dialog"; import { Button } from "src/components/ui/button"; import { Input } from "src/components/ui/input"; import { Label } from "src/components/ui/label"; import { RadioGroup, RadioGroupItem } from "src/components/ui/radio-group"; import { Textarea } from "src/components/ui/textarea"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "src/components/ui/tooltip"; import { useInfo } from "src/hooks/useInfo"; import { request } from "src/utils/request"; type Props = { apiRequest: ( endpoint: string, method: string, requestBody?: object ) => Promise; target?: string; }; function RefundSwapDialogContent() { const [swapId, setSwapId] = React.useState(""); const [address, setAddress] = React.useState(""); const [isInternal, setInternal] = React.useState(true); async function onConfirm() { try { const response = await request("/api/swaps/refund", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ swapId, ...(address ? { address } : {}), }), }); console.info("Processed refund", response); toast("Refund transaction broadcasted"); } catch (error) { console.error(error); toast.error("Failed to process refund", { description: "" + error, }); } setSwapId(""); } const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onConfirm(); }; const paste = async () => { const text = await navigator.clipboard.readText(); setAddress(text.trim()); }; return ( Refund Swap
Only On-chain {"->"} Lightning swaps need to be refunded
{ setSwapId(e.target.value.trim()); }} />
{ setAddress(""); setInternal(!isInternal); }} className="flex gap-4 flex-row" >
{!isInternal && (
setAddress(e.target.value)} required />
)}
Cancel Confirm
); } function GetLogsDialogContent({ apiRequest, target }: Props) { const [maxLen, setMaxLen] = React.useState(""); async function onConfirm() { await apiRequest(`/api/log/${target}?maxLen=${maxLen}`, "GET"); setMaxLen(""); } const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onConfirm(); }; return ( Get {target} Logs
{ setMaxLen(e.target.value.trim()); }} />
Cancel Confirm
); } function GetNetworkGraphDialogContent({ apiRequest }: Props) { const [nodeIds, setNodeIds] = React.useState(""); async function onConfirm() { await apiRequest(`/api/node/network-graph?nodeIds=${nodeIds}`, "GET"); setNodeIds(""); } const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onConfirm(); }; return ( Get Network Graph
{ setNodeIds(e.target.value.trim()); }} />
Cancel Confirm
); } export default function DebugTools() { const [apiResponse, setApiResponse] = React.useState(""); const [dialog, setDialog] = React.useState< | "refundSwap" | "getAppLogs" | "getNodeLogs" | "getNetworkGraph" | "resetRoutingData" | "customNodeCommand" >(); const { data: info, hasChannelManagement } = useInfo(); async function apiRequest( endpoint: string, method: string, requestBody?: object ) { try { const requestOptions: RequestInit = { method: method, headers: { "Content-Type": "application/json", }, }; if (requestBody) { requestOptions.body = JSON.stringify(requestBody); } const data = await request(endpoint, requestOptions); setApiResponse( (data as { logs: string }).logs || JSON.stringify(data, null, 2) ); } catch (error) { setApiResponse(JSON.stringify(error, Object.getOwnPropertyNames(error))); } } return (
{ if (!open) { setDialog(undefined); } }} > {hasChannelManagement && ( <> )} {(info?.backendType === "LDK" || info?.backendType === "CASHU") && ( )} {info?.backendType === "LDK" && ( )} {dialog === "refundSwap" && } {(dialog === "getAppLogs" || dialog === "getNodeLogs") && ( )} {dialog === "getNetworkGraph" && ( )} {dialog === "resetRoutingData" && } {dialog === "customNodeCommand" && ( )}
{apiResponse && (