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