Hey is a decentralized and permissionless social media app built with Lens Protocol 🌿

feat: integrate balance query and top-up functionality in Choose component for ENS username registration

yoginth.com ed385e57 5dea69c4

verified
+63 -28
+62 -28
apps/web/src/components/ENS/Choose.tsx
··· 7 7 NATIVE_TOKEN_SYMBOL, 8 8 STATIC_IMAGES_URL 9 9 } from "@hey/data/constants"; 10 - import { useCreateUsernameMutation, useUsernameQuery } from "@hey/indexer"; 10 + import { 11 + useBalancesBulkQuery, 12 + useCreateUsernameMutation, 13 + useUsernameQuery 14 + } from "@hey/indexer"; 11 15 import { useCallback, useState } from "react"; 12 16 import z from "zod"; 13 17 import NotLoggedIn from "@/components/Shared/NotLoggedIn"; ··· 16 20 import useHandleWrongNetwork from "@/hooks/useHandleWrongNetwork"; 17 21 import useTransactionLifecycle from "@/hooks/useTransactionLifecycle"; 18 22 import { useAccountStore } from "@/store/persisted/useAccountStore"; 23 + import TopUpButton from "../Shared/Account/TopUp/Button"; 19 24 import { 20 25 Button, 21 26 Card, 22 27 Form, 23 28 Image, 24 29 Input, 30 + Spinner, 25 31 Tooltip, 26 32 useZodForm 27 33 } from "../Shared/UI"; ··· 45 51 const handleTransactionLifecycle = useTransactionLifecycle(); 46 52 const form = useZodForm({ mode: "onChange", schema: ValidationSchema }); 47 53 54 + const { data: balance, loading: balanceLoading } = useBalancesBulkQuery({ 55 + fetchPolicy: "no-cache", 56 + pollInterval: 3000, 57 + skip: !currentAccount?.address, 58 + variables: { 59 + request: { 60 + address: currentAccount?.address, 61 + includeNative: true 62 + } 63 + } 64 + }); 65 + 48 66 const onCompleted = (hash: string) => { 49 67 setIsSubmitting(false); 50 68 setChosenUsername(username); ··· 89 107 const len = username?.length || 0; 90 108 const price = len > 4 ? 5 : (lengthPriceMap[len] ?? 0); 91 109 110 + const tokenBalance = 111 + balance?.balancesBulk[0].__typename === "NativeAmount" 112 + ? Number(balance.balancesBulk[0].value).toFixed(2) 113 + : 0; 114 + 115 + const canMint = Number(tokenBalance) >= price; 116 + 92 117 useUsernameQuery({ 93 118 fetchPolicy: "no-cache", 94 119 onCompleted: (data) => setIsAvailable(!data.username), ··· 106 131 const handleCreate = async ({ 107 132 username 108 133 }: z.infer<typeof ValidationSchema>) => { 109 - try { 110 - setIsSubmitting(true); 111 - await handleWrongNetwork(); 134 + setIsSubmitting(true); 135 + await handleWrongNetwork(); 112 136 113 - return await createUsername({ 114 - variables: { 115 - request: { 116 - autoAssign: true, 117 - username: { 118 - localName: username.toLowerCase(), 119 - namespace: HEY_ENS_NAMESPACE 120 - } 137 + return await createUsername({ 138 + variables: { 139 + request: { 140 + autoAssign: true, 141 + username: { 142 + localName: username.toLowerCase(), 143 + namespace: HEY_ENS_NAMESPACE 121 144 } 122 145 } 123 - }); 124 - } catch { 125 - onError(); 126 - } finally { 127 - setIsSubmitting(false); 128 - } 146 + } 147 + }); 129 148 }; 130 - 131 - const disabled = !canCheck || !isAvailable || isSubmitting || isInvalid; 132 149 133 150 if (!currentAccount) { 134 151 return <NotLoggedIn />; ··· 184 201 / once 185 202 </span> 186 203 </div> 187 - <Button 188 - className="w-full" 189 - disabled={disabled} 190 - loading={isSubmitting} 191 - type="submit" 192 - > 193 - Register Name 194 - </Button> 204 + {balanceLoading ? ( 205 + <Button 206 + className="w-full" 207 + disabled 208 + icon={<Spinner className="my-1" size="xs" />} 209 + /> 210 + ) : canMint ? ( 211 + <Button 212 + className="w-full" 213 + disabled={isSubmitting} 214 + loading={isSubmitting} 215 + type="submit" 216 + > 217 + Subscribe for ${price}/year 218 + </Button> 219 + ) : ( 220 + <TopUpButton 221 + amountToTopUp={ 222 + Math.ceil((price - Number(tokenBalance)) * 20) / 20 223 + } 224 + className="w-full" 225 + label={`Top-up ${price} ${NATIVE_TOKEN_SYMBOL} to your account`} 226 + outline 227 + /> 228 + )} 195 229 </Card> 196 230 ) : null 197 231 ) : canCheck && isInvalid ? (
+1
apps/web/src/components/Shared/Account/TopUp/Button.tsx
··· 32 32 } 33 33 outline={outline} 34 34 size={size} 35 + type="button" 35 36 > 36 37 {label} 37 38 </Button>