NewSubwallet.tsx raw

   1  import { HelpCircleIcon } from "lucide-react";
   2  import React from "react";
   3  import { useNavigate } from "react-router";
   4  import { toast } from "sonner";
   5  import AppHeader from "src/components/AppHeader";
   6  import Loading from "src/components/Loading";
   7  import ResponsiveExternalLinkButton from "src/components/ResponsiveExternalLinkButton";
   8  import { LoadingButton } from "src/components/ui/custom/loading-button";
   9  import { Input } from "src/components/ui/input";
  10  import { Label } from "src/components/ui/label";
  11  import { MAX_FREE_SUBWALLETS, SUBWALLET_APPSTORE_APP_ID } from "src/constants";
  12  import { useAlbyMe } from "src/hooks/useAlbyMe";
  13  import { useApps } from "src/hooks/useApps";
  14  import { useInfo } from "src/hooks/useInfo";
  15  import { createApp } from "src/requests/createApp";
  16  import { CreateAppRequest } from "src/types";
  17  import { handleRequestError } from "src/utils/handleRequestError";
  18  
  19  export function NewSubwallet() {
  20    const navigate = useNavigate();
  21    const [name, setName] = React.useState("");
  22    const { data: subwalletAppsData } = useApps(undefined, undefined, {
  23      subWallets: true,
  24    });
  25    const { data: info } = useInfo();
  26    const { data: albyMe, error: albyMeError } = useAlbyMe();
  27  
  28    const [isLoading, setLoading] = React.useState(false);
  29  
  30    if (
  31      !info ||
  32      !subwalletAppsData ||
  33      (info.albyAccountConnected && !albyMe && !albyMeError)
  34    ) {
  35      return <Loading />;
  36    }
  37  
  38    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
  39      event.preventDefault();
  40      setLoading(true);
  41  
  42      try {
  43        if (
  44          !albyMe?.subscription.plan_code &&
  45          subwalletAppsData.totalCount >= MAX_FREE_SUBWALLETS
  46        ) {
  47          throw new Error(
  48            "Max limit reached. Please upgrade to Pro to create more sub-wallets."
  49          );
  50        }
  51        const createAppRequest: CreateAppRequest = {
  52          name,
  53          scopes: [
  54            "get_balance",
  55            "get_info",
  56            "list_transactions",
  57            "lookup_invoice",
  58            "make_invoice",
  59            "notifications",
  60            "pay_invoice",
  61          ],
  62          isolated: true,
  63          metadata: {
  64            app_store_app_id: SUBWALLET_APPSTORE_APP_ID,
  65          },
  66        };
  67  
  68        const createAppResponse = await createApp(createAppRequest);
  69  
  70        navigate("/sub-wallets/created", {
  71          state: createAppResponse,
  72        });
  73  
  74        toast("New sub-wallet created for " + name);
  75      } catch (error) {
  76        handleRequestError("Failed to create app", error);
  77      }
  78      setLoading(false);
  79    };
  80  
  81    return (
  82      <div className="grid gap-5">
  83        <AppHeader
  84          pageTitle="Create Sub-wallet"
  85          title="Create Sub-wallet"
  86          contentRight={
  87            <>
  88              <ResponsiveExternalLinkButton
  89                to="https://guides.getalby.com/user-guide/alby-hub/sub-wallets"
  90                icon={HelpCircleIcon}
  91                text="Help"
  92                variant="outline"
  93              />
  94            </>
  95          }
  96        />
  97        <form
  98          onSubmit={handleSubmit}
  99          className="flex flex-col items-start gap-3 max-w-lg"
 100        >
 101          <div className="w-full grid gap-1.5 mb-4">
 102            <Label htmlFor="name">Sub-wallet name</Label>
 103            <Input
 104              autoFocus
 105              type="text"
 106              name="name"
 107              value={name}
 108              id="name"
 109              onChange={(e) => setName(e.target.value)}
 110              required
 111              autoComplete="off"
 112            />
 113            <p className="text-muted-foreground text-sm">
 114              Name your friend, family member or coworker
 115            </p>
 116          </div>
 117          <LoadingButton loading={isLoading} type="submit">
 118            Create Sub-wallet
 119          </LoadingButton>
 120        </form>
 121      </div>
 122    );
 123  }
 124