"use client"; /** * Restore mavi from an existing recovery phrase (12 or 24 words). */ import { countWords, isValidMnemonic, MAVI_MIN_PASSWORD_LENGTH, normalizeMnemonic, walletFromMnemonic, } from "@krypco/mavi-core"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { PasswordInput } from "@/components/ui/password-input"; import { MaviWalletLogo } from "@/components/wallet/wallet-logos"; import { Button, buttonVariants } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { ErrorBanner } from "@/components/ui/error-banner"; import { hasVault, saveNewVault, shortAddress, unlockVault, } from "@/lib/mavi/storage"; import { writeLastLoginMethod } from "@/lib/last-login"; import { cn } from "@/lib/utils"; type Step = "phrase" | "password" | "done"; export function ImportWalletFlow() { const router = useRouter(); const [step, setStep] = useState("phrase"); const [phrase, setPhrase] = useState(""); const [password, setPassword] = useState(""); const [password2, setPassword2] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [address, setAddress] = useState(null); const [wordCount, setWordCount] = useState<12 | 24 | null>(null); const wordsN = countWords(phrase); const phraseOk = (wordsN === 12 || wordsN === 24) && isValidMnemonic(phrase); function onPhraseContinue() { setError(null); const n = countWords(phrase); if (n !== 12 && n !== 24) { setError("Enter 12 or 24 recovery words (spaces between them)."); return; } if (!isValidMnemonic(phrase)) { setError( "That phrase is not valid. Check spelling and order, then try again.", ); return; } setWordCount(n === 24 ? 24 : 12); setStep("password"); } async function onImport() { setError(null); if (password.length < MAVI_MIN_PASSWORD_LENGTH) { setError( `Password must be at least ${MAVI_MIN_PASSWORD_LENGTH} characters.`, ); return; } if (password !== password2) { setError("Passwords do not match."); return; } if (hasVault()) { const ok = window.confirm( "A mavi wallet already exists on this browser. Replace it with the imported one? You will need the old recovery phrase to use the old wallet again.", ); if (!ok) return; } setBusy(true); try { const wallet = walletFromMnemonic(normalizeMnemonic(phrase)); await saveNewVault(password, wallet); await unlockVault(password); writeLastLoginMethod("mavi"); setAddress(wallet.address); setStep("done"); } catch (e) { setError(e instanceof Error ? e.message : "Import failed."); } finally { setBusy(false); } } return (
{error ? ( {error} ) : null} {step === "phrase" ? (
Import mavi wallet
Paste or type your secret recovery phrase. Words never leave this browser. Works with 12 or 24 words.