ImportMnemonic.tsx raw

   1  import * as bip39 from "@scure/bip39";
   2  import { wordlist } from "@scure/bip39/wordlists/english.js";
   3  import { AlertTriangleIcon, LifeBuoyIcon, ShieldCheckIcon } from "lucide-react";
   4  import { useEffect, useState } from "react";
   5  import { useNavigate } from "react-router";
   6  
   7  import { toast } from "sonner";
   8  import MnemonicInputs from "src/components/mnemonic/MnemonicInputs";
   9  import TwoColumnLayoutHeader from "src/components/TwoColumnLayoutHeader";
  10  import { Alert, AlertDescription, AlertTitle } from "src/components/ui/alert";
  11  import { Button } from "src/components/ui/button";
  12  import useSetupStore from "src/state/SetupStore";
  13  
  14  export function ImportMnemonic() {
  15    const navigate = useNavigate();
  16    const setupStore = useSetupStore();
  17  
  18    useEffect(() => {
  19      // in case the user presses back, remove their last-saved mnemonic
  20      useSetupStore.getState().updateNodeInfo({
  21        mnemonic: undefined,
  22      });
  23    }, []);
  24    const [mnemonic, setMnemonic] = useState<string>("");
  25  
  26    async function onSubmit(e: React.FormEvent) {
  27      e.preventDefault();
  28      if (
  29        mnemonic.split(" ").length !== 12 ||
  30        !bip39.validateMnemonic(mnemonic, wordlist)
  31      ) {
  32        toast.error("Invalid recovery phrase");
  33        return;
  34      }
  35  
  36      const currentDate = new Date();
  37      const sixMonthsLater = new Date(
  38        currentDate.setMonth(currentDate.getMonth() + 6)
  39      );
  40  
  41      setupStore.updateNodeInfo({
  42        mnemonic,
  43        nextBackupReminder: sixMonthsLater.toISOString(),
  44      });
  45      setupStore.setHasImportedMnemonic(true);
  46  
  47      navigate(`/setup/node`);
  48    }
  49  
  50    return (
  51      <form
  52        onSubmit={onSubmit}
  53        className="flex flex-col gap-5 mx-auto max-w-md text-sm"
  54      >
  55        <TwoColumnLayoutHeader
  56          title="Import Recovery Phrase"
  57          pageTitle="Import Recovery Phrase"
  58          description="Enter your recovery phrase to import your Alby Hub."
  59        />
  60  
  61        <Alert variant="warning">
  62          <AlertTriangleIcon />
  63          <AlertTitle>Do not re-use the same key on multiple devices</AlertTitle>
  64          <AlertDescription className="inline">
  65            If you want to transfer your existing Hub to another machine please
  66            use the <b>migrate feature</b> from the Alby Hub settings.
  67          </AlertDescription>
  68        </Alert>
  69        <Alert className="grid-cols-none">
  70          <div className="flex flex-col gap-4">
  71            <div className="flex gap-2 items-center">
  72              <div className="shrink-0 text-muted-foreground">
  73                <LifeBuoyIcon className="size-6" />
  74              </div>
  75              <span className="text-muted-foreground">
  76                Your recovery phrase is a set of 12 words used to restore your
  77                on-chain balance from a backup.
  78              </span>
  79            </div>
  80            <div className="flex gap-2 items-center">
  81              <div className="shrink-0 text-muted-foreground">
  82                <ShieldCheckIcon className="size-6" />
  83              </div>
  84              <span className="text-muted-foreground">
  85                Keep it safe and private to ensure your funds remain secure.
  86              </span>
  87            </div>
  88          </div>
  89        </Alert>
  90  
  91        <MnemonicInputs mnemonic={mnemonic} setMnemonic={setMnemonic} />
  92  
  93        <Button>Next</Button>
  94      </form>
  95    );
  96  }
  97