GenerateNewAccount.tsx raw

   1  import { Button } from '@/components/ui/button'
   2  import { Input } from '@/components/ui/input'
   3  import { Label } from '@/components/ui/label'
   4  import { useNostr } from '@/providers/NostrProvider'
   5  import { Check, Copy, RefreshCcw } from 'lucide-react'
   6  import { generateSecretKey } from 'nostr-tools'
   7  import { nsecEncode } from 'nostr-tools/nip19'
   8  import { useState } from 'react'
   9  import { useTranslation } from 'react-i18next'
  10  
  11  export default function GenerateNewAccount({
  12    back,
  13    onLoginSuccess
  14  }: {
  15    back: () => void
  16    onLoginSuccess: () => void
  17  }) {
  18    const { t } = useTranslation()
  19    const { nsecLogin } = useNostr()
  20    const [nsec, setNsec] = useState(generateNsec())
  21    const [copied, setCopied] = useState(false)
  22    const [password, setPassword] = useState('')
  23  
  24    const handleLogin = () => {
  25      nsecLogin(nsec, password, true).then(() => onLoginSuccess())
  26    }
  27  
  28    return (
  29      <form
  30        className="space-y-4"
  31        onSubmit={(e) => {
  32          e.preventDefault()
  33          handleLogin()
  34        }}
  35      >
  36        <div className="text-orange-400">
  37          {t(
  38            'This is a private key. Do not share it with anyone. Keep it safe and secure. You will not be able to recover it if you lose it.'
  39          )}
  40        </div>
  41        <div className="grid gap-2">
  42          <Label>nsec</Label>
  43          <div className="flex gap-2">
  44            <Input value={nsec} />
  45            <Button type="button" variant="secondary" onClick={() => setNsec(generateNsec())}>
  46              <RefreshCcw />
  47            </Button>
  48            <Button
  49              type="button"
  50              onClick={() => {
  51                navigator.clipboard.writeText(nsec)
  52                setCopied(true)
  53                setTimeout(() => setCopied(false), 2000)
  54              }}
  55            >
  56              {copied ? <Check /> : <Copy />}
  57            </Button>
  58          </div>
  59        </div>
  60        <div className="grid gap-2">
  61          <Label htmlFor="password-input">{t('password')}</Label>
  62          <Input
  63            id="password-input"
  64            type="password"
  65            placeholder={t('optional: encrypt nsec')}
  66            value={password}
  67            onChange={(e) => setPassword(e.target.value)}
  68          />
  69        </div>
  70        <div className="flex gap-2">
  71          <Button className="w-fit px-8" variant="secondary" type="button" onClick={back}>
  72            {t('Back')}
  73          </Button>
  74          <Button className="flex-1" type="submit">
  75            {t('Login')}
  76          </Button>
  77        </div>
  78      </form>
  79    )
  80  }
  81  
  82  function generateNsec() {
  83    const sk = generateSecretKey()
  84    return nsecEncode(sk)
  85  }
  86