ConnectPeer.tsx raw
1 import React from "react";
2 import { useLocation, useNavigate } from "react-router";
3 import { toast } from "sonner";
4 import AppHeader from "src/components/AppHeader";
5 import { LoadingButton } from "src/components/ui/custom/loading-button";
6 import { Input } from "src/components/ui/input";
7 import { Label } from "src/components/ui/label";
8
9 import { splitSocketAddress } from "src/lib/utils";
10 import { ConnectPeerRequest } from "src/types";
11 import { request } from "src/utils/request";
12 import { safeReturnToUrl } from "src/utils/safeReturnToUrl";
13
14 export default function ConnectPeer() {
15 const navigate = useNavigate();
16 const location = useLocation();
17 const queryParams = new URLSearchParams(location.search);
18 const [isLoading, setLoading] = React.useState(false);
19 const [connectionString, setConnectionString] = React.useState(
20 queryParams.get("peer") ?? ""
21 );
22 const returnTo = safeReturnToUrl(queryParams.get("return_to")) ?? "";
23
24 const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
25 event.preventDefault();
26
27 try {
28 if (!connectionString) {
29 throw new Error("connection details missing");
30 }
31 const [pubkey, socketAddress] = connectionString.split("@");
32 const { address, port } = splitSocketAddress(socketAddress);
33 if (!pubkey || !address || !port) {
34 throw new Error("connection details missing");
35 }
36 console.info(`🔌 Peering with ${pubkey}`);
37 const connectPeerRequest: ConnectPeerRequest = {
38 pubkey,
39 address,
40 port: +port,
41 };
42
43 setLoading(true);
44 await request("/api/peers", {
45 method: "POST",
46 headers: {
47 "Content-Type": "application/json",
48 },
49 body: JSON.stringify(connectPeerRequest),
50 });
51 toast("Successfully connected with peer");
52 if (returnTo) {
53 window.location.href = returnTo;
54 return;
55 }
56 setConnectionString("");
57 navigate("/peers");
58 } catch (e) {
59 toast.error("Failed to connect peer", {
60 description: "" + e,
61 });
62 console.error(e);
63 }
64 setLoading(false);
65 };
66
67 return (
68 <div className="grid gap-5">
69 <AppHeader
70 pageTitle="Connect Peer"
71 title="Connect Peer"
72 description="Manually connect to a lightning network peer"
73 />
74 <div className="max-w-lg">
75 <form onSubmit={handleSubmit}>
76 <div className="grid gap-2">
77 <Label htmlFor="connectionString">Peer</Label>
78 <Input
79 id="connectionString"
80 type="text"
81 value={connectionString}
82 placeholder="pubkey@host:port"
83 onChange={(e) => {
84 setConnectionString(e.target.value.trim());
85 }}
86 />
87 </div>
88 {returnTo && (
89 <p className="text-xs text-muted-foreground mt-4">
90 You will automatically return to {returnTo}
91 </p>
92 )}
93 <div className="mt-4">
94 <LoadingButton
95 loading={isLoading}
96 type="submit"
97 disabled={!connectionString}
98 size="lg"
99 >
100 Connect
101 </LoadingButton>
102 </div>
103 </form>
104 </div>
105 </div>
106 );
107 }
108