Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 130 lines 4.1 kB view raw
1import { ERRORS } from "@hey/data/errors"; 2import { useAuthenticateMutation, useChallengeMutation } from "@hey/indexer"; 3import type { ApolloClientError } from "@hey/types/errors"; 4import { useCallback, useState } from "react"; 5import { toast } from "sonner"; 6import { useAccount, useSignMessage } from "wagmi"; 7import BackButton from "@/components/Shared/BackButton"; 8import { Button, Card, CardHeader, H6 } from "@/components/Shared/UI"; 9import errorToast from "@/helpers/errorToast"; 10import useCopyToClipboard from "@/hooks/useCopyToClipboard"; 11import useHandleWrongNetwork from "@/hooks/useHandleWrongNetwork"; 12import { hydrateAuthTokens } from "@/store/persisted/useAuthStore"; 13 14const Tokens = () => { 15 const { accessToken, refreshToken } = hydrateAuthTokens(); 16 const [builderToken, setBuilderToken] = useState<string | null>(null); 17 const [isSubmitting, setIsSubmitting] = useState(false); 18 19 const copyAccessToken = useCopyToClipboard( 20 accessToken as string, 21 "Copied to clipboard" 22 ); 23 const copyRefreshToken = useCopyToClipboard( 24 refreshToken as string, 25 "Copied to clipboard" 26 ); 27 const copyBuilderToken = useCopyToClipboard( 28 builderToken ?? "", 29 "Copied to clipboard" 30 ); 31 32 const { address } = useAccount(); 33 const handleWrongNetwork = useHandleWrongNetwork(); 34 35 const onError = useCallback((error: ApolloClientError) => { 36 setIsSubmitting(false); 37 errorToast(error); 38 }, []); 39 40 const { signMessageAsync } = useSignMessage({ 41 mutation: { onError } 42 }); 43 const [loadChallenge] = useChallengeMutation(); 44 const [authenticate] = useAuthenticateMutation(); 45 46 const handleGenerateBuilderToken = async () => { 47 try { 48 setIsSubmitting(true); 49 await handleWrongNetwork(); 50 51 const challenge = await loadChallenge({ 52 variables: { request: { builder: { address } } } 53 }); 54 55 if (!challenge?.data?.challenge?.text) { 56 return toast.error(ERRORS.SomethingWentWrong); 57 } 58 59 // Get signature 60 const signature = await signMessageAsync({ 61 message: challenge?.data?.challenge?.text 62 }); 63 64 // Auth account 65 const auth = await authenticate({ 66 variables: { request: { id: challenge.data.challenge.id, signature } } 67 }); 68 69 if (auth.data?.authenticate.__typename === "AuthenticationTokens") { 70 setBuilderToken(auth.data?.authenticate.accessToken); 71 } 72 } catch (error) { 73 errorToast(error); 74 } finally { 75 setIsSubmitting(false); 76 } 77 }; 78 79 return ( 80 <Card> 81 <CardHeader 82 icon={<BackButton path="/settings" />} 83 title="Your temporary access token" 84 /> 85 <div className="m-5 space-y-5"> 86 <div className="flex flex-col gap-y-3"> 87 <b>Your temporary access token</b> 88 <button 89 className="cursor-pointer break-all rounded-md bg-gray-300 p-2 px-3 text-left dark:bg-gray-600" 90 onClick={copyAccessToken} 91 type="button" 92 > 93 <H6>{accessToken}</H6> 94 </button> 95 </div> 96 <div className="flex flex-col gap-y-3"> 97 <b>Your temporary refresh token</b> 98 <button 99 className="cursor-pointer break-all rounded-md bg-gray-300 p-2 px-3 text-left dark:bg-gray-600" 100 onClick={copyRefreshToken} 101 type="button" 102 > 103 <H6>{refreshToken}</H6> 104 </button> 105 </div> 106 <div className="flex flex-col gap-y-3"> 107 <b>Your temporary builder token</b> 108 <Button 109 disabled={isSubmitting} 110 loading={isSubmitting} 111 onClick={handleGenerateBuilderToken} 112 > 113 Generate builder token 114 </Button> 115 {builderToken && ( 116 <button 117 className="mt-5 cursor-pointer break-all rounded-md bg-gray-300 p-2 px-3 text-left dark:bg-gray-600" 118 onClick={copyBuilderToken} 119 type="button" 120 > 121 <H6>{builderToken}</H6> 122 </button> 123 )} 124 </div> 125 </div> 126 </Card> 127 ); 128}; 129 130export default Tokens;