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