Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"doneSafety": "Fast fertig... Sicherheitsüberprüfung",
"noProofsRestored": "Keine Beweise gefunden, um deine Wallet wiederherzustellen.",
"restoreErr": "Ein Fehler ist aufgetreten bei der Wiederherstellung Ihrer Wallet.",
"restoreSameSeed": "Diese Wiederherstellungsphrase wird bereits von dieser Wallet verwendet.",
"dontClose": "Bitte schließen Sie die App während des Vorgangs nicht.",
"recoveryHint": "Schreiben oder fügen Sie Ihren 12-Wort-Mnemonic in der richtigen Reihenfolge ein, getrennt durch Leerzeichen.",
"walletRecovery": "Wallet-Wiederherstellung",
Expand Down
1 change: 1 addition & 0 deletions assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"doneSafety": "Almost done... Safety check",
"noProofsRestored": "Found no proofs to restore your wallet.",
"restoreErr": "Something went wrong while restoring your wallet.",
"restoreSameSeed": "This recovery phrase is already in use on this wallet.",
"dontClose": "Please do not close the app during the process.",
"recoveryHint": "Write or paste your 12-word mnemonic in the right order, separated by blank spaces.",
"walletRecovery": "Wallet Recovery",
Expand Down
1 change: 1 addition & 0 deletions assets/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"counterIncreased": "¡Contadores incrementados en {{counterIncreased}}!",
"doneSafety": "Casi terminado... Verificación de seguridad",
"restoreErr": "Ocurrió un error al restaurar tu cartera.",
"restoreSameSeed": "Esta frase de recuperación ya está en uso en esta cartera.",
"noProofsRestored": "No se encontraron pruebas para restaurar la cartera.",
"dontClose": "Por favor, no cierre la aplicación durante el proceso.",
"recoveryHint": "Escribe o pega tu mnemotecnia de 12 palabras en el orden correcto, separadas por espacios en blanco.",
Expand Down
1 change: 1 addition & 0 deletions assets/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"doneSafety": "Processo quasi terminato... controllo di sicurezza",
"noProofsRestored": "Non ci sono prove utili per ripristinare il portafoglio.",
"restoreErr": "Qualcosa è andato storto durante il processo di ripristino del portafoglio.",
"restoreSameSeed": "Questa frase di recupero è già in uso in questo portafoglio.",
"dontClose": "Non chiudere l'applicazione durante il processo.",
"recoveryHint": "Scrivere o incollare la mnemonica di 12 parole, separate da uno spazio bianco.",
"walletRecovery": "Ripristino del portafoglio",
Expand Down
1 change: 1 addition & 0 deletions assets/translations/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"doneSafety": "Почти готово... Проверка безопасности",
"noProofsRestored": "Не найдено доказательств для восстановления вашего кошелька.",
"restoreErr": "Что-то пошло не так при восстановлении вашего кошелька.",
"restoreSameSeed": "Эта фраза восстановления уже используется в этом кошельке.",
"dontClose": "Пожалуйста, не закрывайте приложение во время процесса.",
"recoveryHint": "Напишите или вставьте мнемонику из 12 слов в правильном порядке, разделив их пробелами.",
"walletRecovery": "Восстановление кошелька",
Expand Down
1 change: 1 addition & 0 deletions assets/translations/th.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"doneSafety": "เกือบเสร็จละ... การตรวจสอบความปลอดภัย",
"noProofsRestored": "ไม่พบ proof เพื่อทำการกู้คืนกระเป๋าของคุณ",
"restoreErr": "เกิดข้อผิดพลาดบางอย่างขณะกู้คืนกระเป๋าของคุณ",
"restoreSameSeed": "วลีกู้คืนนี้ถูกใช้งานอยู่ในกระเป๋านี้แล้ว",
"dontClose": "กรุณาอย่าปิดแอปในระหว่างกระบวนการ",
"recoveryHint": "เขียนหรือวาง 12 คำตามลำดับที่ถูกต้อง โดยคั่นด้วยช่องว่าง",
"walletRecovery": "การกู้คืนกระเป๋า",
Expand Down
1 change: 1 addition & 0 deletions src/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import de from "@assets/translations/de.json";
import en from "@assets/translations/en.json";
import es from "@assets/translations/es.json";
import de from "@assets/translations/de.json";
import it from "@assets/translations/it.json";
import ru from "@assets/translations/ru.json";
import th from "@assets/translations/th.json";
Expand Down
14 changes: 13 additions & 1 deletion src/screens/Restore/Recover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { RecoverScreenProps } from "@src/nav/navTypes";
import { NS } from "@src/i18n";
import { useKnownMints } from "@src/context/KnownMints";
import { seedService } from "@src/services/SeedService";
import { usePromptContext } from "@src/context/Prompt";
import { getStrFromClipboard } from "@util";
import { createRef, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
Expand All @@ -20,6 +21,7 @@ export default function RecoverScreen({ navigation }: RecoverScreenProps) {
const { loading } = useLoading();
const inputRef = createRef<TextInput>();
const { knownMints } = useKnownMints();
const { openPromptAutoClose } = usePromptContext();

const handlePaste = async () => {
const clipboard = await getStrFromClipboard();
Expand All @@ -33,7 +35,17 @@ export default function RecoverScreen({ navigation }: RecoverScreenProps) {
if (loading || !input.length) {
return;
}
const seed = seedService.convertMnemonicToSeed(input);
if (await seedService.isSameMnemonic(input)) {
openPromptAutoClose({
msg: t("restoreSameSeed", {
defaultValue: "This recovery phrase is already in use on this wallet.",
}),
success: false,
});
return;
}

const seed = seedService.convertMnemonicToSeed(seedService.normalizeMnemonic(input));

navigation.navigate("Recovering", {
bip39seed: seed,
Expand Down
38 changes: 34 additions & 4 deletions src/services/SeedService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import { privateKeyFromSeedWords } from "nostr-tools/nip06";

class SeedService {
private _seed: Uint8Array | null = null;

static async getMnemonicFingerprint(mnemonic: string) {
const normalizedMnemonic = mnemonic.toLowerCase().trim();
return Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.MD5, normalizedMnemonic);
}

async createNewMnemonic(): Promise<{
mnemonic: string;
fingerprint: string;
Expand All @@ -14,7 +20,7 @@ class SeedService {
SecureStore.setItem("mnemonic", mnemonic);
const seed = bip39.mnemonicToSeedSync(mnemonic);
this._seed = seed;
const fingerprint = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.MD5, mnemonic);
const fingerprint = await SeedService.getMnemonicFingerprint(mnemonic);
return { mnemonic, fingerprint };
}

Expand All @@ -39,9 +45,9 @@ class SeedService {
if (!mnemonic) {
return null;
}
const fingerprint = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.MD5, mnemonic);
return fingerprint;
return SeedService.getMnemonicFingerprint(mnemonic);
}

async ensureMnemonicSet() {
const savedMnemonic = this.getMnemonic();
if (!savedMnemonic) {
Expand All @@ -62,8 +68,32 @@ class SeedService {
return seed;
}

async isSameSeed(seed: Uint8Array) {
try {
const currentSeed = this.getSeed();
if (currentSeed.length !== seed.length) {
return false;
}
return currentSeed.every((byte, index) => byte === seed[index]);
} catch {
return false;
}
}

async isSameMnemonic(mnemonic: string) {
const currentMnemonic = this.getMnemonic();
if (!currentMnemonic) {
return false;
}
const [currentFingerprint, inputFingerprint] = await Promise.all([
SeedService.getMnemonicFingerprint(currentMnemonic),
SeedService.getMnemonicFingerprint(mnemonic),
]);
return currentFingerprint === inputFingerprint;
}

async getNostrSk() {
const mnemonic = await this.getMnemonic();
const mnemonic = this.getMnemonic();
if (!mnemonic) {
throw new Error("No mnemonic found");
}
Expand Down