Revert "goblin: remove the Import identity option from onboarding"
This reverts commit b1baa14b85.
This commit is contained in:
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "Richte dein Wallet ein"
|
||||
create_new: "Neu erstellen"
|
||||
restore_from_seed: "Aus Seed wiederherstellen"
|
||||
import_identity: "Identität importieren"
|
||||
import_identity_hint: "Nach diesem Schritt bringst du deinen vorhandenen Schlüssel mit (eine .backup-Datei oder nsec)."
|
||||
name_hint: "Wallet-Name"
|
||||
password_hint: "Passwort"
|
||||
repeat_password_hint: "Passwort wiederholen"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "Freunde können dich jetzt per Namen bezahlen. Alles bereit — öffne dein Wallet."
|
||||
open_wallet: "Mein Wallet öffnen"
|
||||
skip_for_now: "Vorerst überspringen"
|
||||
import_existing: "Schon eine Goblin-Identität? Importieren"
|
||||
import_title: "Identität importieren"
|
||||
import_blurb: "Füge deinen nsec ein oder wähle eine .backup-Datei, um deinen vorhandenen Schlüssel und Benutzernamen zu behalten statt diesen neuen."
|
||||
errors:
|
||||
cant_open: "Wallet konnte nicht geöffnet werden: %{err}"
|
||||
cant_create: "Wallet konnte nicht erstellt werden: %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "Set up your wallet"
|
||||
create_new: "Create new"
|
||||
restore_from_seed: "Restore from seed"
|
||||
import_identity: "Import identity"
|
||||
import_identity_hint: "You'll bring in your existing key (a .backup file or nsec) after this step."
|
||||
name_hint: "Wallet name"
|
||||
password_hint: "Password"
|
||||
repeat_password_hint: "Repeat password"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "Friends can now pay you by name. You're all set — open your wallet."
|
||||
open_wallet: "Open my wallet"
|
||||
skip_for_now: "Skip for now"
|
||||
import_existing: "Already have a Goblin identity? Import it"
|
||||
import_title: "Import your identity"
|
||||
import_blurb: "Paste your nsec or pick a .backup file to keep your existing key and username instead of this new one."
|
||||
errors:
|
||||
cant_open: "Couldn't open the wallet: %{err}"
|
||||
cant_create: "Couldn't create the wallet: %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "Configura tu billetera"
|
||||
create_new: "Crear nueva"
|
||||
restore_from_seed: "Restaurar desde la frase semilla"
|
||||
import_identity: "Importar identidad"
|
||||
import_identity_hint: "Traerás tu clave existente (un archivo .backup o nsec) después de este paso."
|
||||
name_hint: "Nombre de la billetera"
|
||||
password_hint: "Contraseña"
|
||||
repeat_password_hint: "Repite la contraseña"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "Tus amigos ya pueden pagarte por nombre. Todo listo — abre tu billetera."
|
||||
open_wallet: "Abrir mi billetera"
|
||||
skip_for_now: "Saltar por ahora"
|
||||
import_existing: "¿Ya tienes una identidad de Goblin? Impórtala"
|
||||
import_title: "Importa tu identidad"
|
||||
import_blurb: "Pega tu nsec o elige un archivo .backup para conservar tu clave y nombre de usuario existentes en lugar de este nuevo."
|
||||
errors:
|
||||
cant_open: "No se pudo abrir la billetera: %{err}"
|
||||
cant_create: "No se pudo crear la billetera: %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "Configurez votre portefeuille"
|
||||
create_new: "Créer un nouveau"
|
||||
restore_from_seed: "Restaurer depuis la phrase"
|
||||
import_identity: "Importer une identité"
|
||||
import_identity_hint: "Vous importerez votre clé existante (un fichier .backup ou un nsec) après cette étape."
|
||||
name_hint: "Nom du portefeuille"
|
||||
password_hint: "Mot de passe"
|
||||
repeat_password_hint: "Répéter le mot de passe"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "Vos amis peuvent désormais vous payer par votre nom. Tout est prêt — ouvrez votre portefeuille."
|
||||
open_wallet: "Ouvrir mon portefeuille"
|
||||
skip_for_now: "Passer pour l'instant"
|
||||
import_existing: "Vous avez déjà une identité Goblin ? Importez-la"
|
||||
import_title: "Importer votre identité"
|
||||
import_blurb: "Collez votre nsec ou choisissez un fichier .backup pour conserver votre clé et votre nom existants au lieu de ce nouveau."
|
||||
errors:
|
||||
cant_open: "Impossible d'ouvrir le portefeuille : %{err}"
|
||||
cant_create: "Impossible de créer le portefeuille : %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "지갑을 설정하세요"
|
||||
create_new: "새로 만들기"
|
||||
restore_from_seed: "복구 문구로 복원"
|
||||
import_identity: "신원 가져오기"
|
||||
import_identity_hint: "이 단계 이후에 기존 키(.backup 파일 또는 nsec)를 가져오게 됩니다."
|
||||
name_hint: "지갑 이름"
|
||||
password_hint: "비밀번호"
|
||||
repeat_password_hint: "비밀번호 확인"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "이제 친구들이 이름으로 결제할 수 있습니다. 모든 준비가 끝났습니다 — 지갑을 열어 보세요."
|
||||
open_wallet: "내 지갑 열기"
|
||||
skip_for_now: "지금은 건너뛰기"
|
||||
import_existing: "이미 Goblin 신원이 있나요? 가져오기"
|
||||
import_title: "신원 가져오기"
|
||||
import_blurb: "nsec을 붙여넣거나 .backup 파일을 선택해서, 새 신원 대신 기존 키와 사용자 이름을 유지하세요."
|
||||
errors:
|
||||
cant_open: "지갑을 열 수 없습니다: %{err}"
|
||||
cant_create: "지갑을 만들 수 없습니다: %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "Настройте кошелёк"
|
||||
create_new: "Создать новый"
|
||||
restore_from_seed: "Восстановить из seed"
|
||||
import_identity: "Импорт личности"
|
||||
import_identity_hint: "После этого шага вы добавите свой существующий ключ (файл .backup или nsec)."
|
||||
name_hint: "Имя кошелька"
|
||||
password_hint: "Пароль"
|
||||
repeat_password_hint: "Повторите пароль"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "Друзья теперь могут платить вам по имени. Всё готово — откройте кошелёк."
|
||||
open_wallet: "Открыть кошелёк"
|
||||
skip_for_now: "Пропустить пока"
|
||||
import_existing: "Уже есть личность Goblin? Импортируйте её"
|
||||
import_title: "Импорт личности"
|
||||
import_blurb: "Вставьте свой nsec или выберите файл .backup, чтобы сохранить существующий ключ и имя вместо нового."
|
||||
errors:
|
||||
cant_open: "Не удалось открыть кошелёк: %{err}"
|
||||
cant_create: "Не удалось создать кошелёк: %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "Cüzdanını kur"
|
||||
create_new: "Yeni oluştur"
|
||||
restore_from_seed: "Tohumdan geri yükle"
|
||||
import_identity: "Kimliği içe aktar"
|
||||
import_identity_hint: "Bu adımdan sonra mevcut anahtarını (bir .backup dosyası veya nsec) getireceksin."
|
||||
name_hint: "Cüzdan adı"
|
||||
password_hint: "Parola"
|
||||
repeat_password_hint: "Parolayı tekrarla"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "Arkadaşların artık sana adınla ödeme yapabilir. Her şey hazır — cüzdanını aç."
|
||||
open_wallet: "Cüzdanımı aç"
|
||||
skip_for_now: "Şimdilik atla"
|
||||
import_existing: "Zaten bir Goblin kimliğin var mı? İçe aktar"
|
||||
import_title: "Kimliğini içe aktar"
|
||||
import_blurb: "Bu yeni anahtar yerine mevcut anahtarını ve kullanıcı adını korumak için nsec'ini yapıştır veya bir .backup dosyası seç."
|
||||
errors:
|
||||
cant_open: "Cüzdan açılamadı: %{err}"
|
||||
cant_create: "Cüzdan oluşturulamadı: %{err}"
|
||||
|
||||
@@ -820,6 +820,8 @@ goblin:
|
||||
title: "设置你的钱包"
|
||||
create_new: "新建"
|
||||
restore_from_seed: "从助记词恢复"
|
||||
import_identity: "导入身份"
|
||||
import_identity_hint: "此步骤之后,你将导入现有密钥(.backup 文件或 nsec)。"
|
||||
name_hint: "钱包名称"
|
||||
password_hint: "密码"
|
||||
repeat_password_hint: "重复密码"
|
||||
@@ -864,6 +866,9 @@ goblin:
|
||||
claimed_blurb: "朋友现在可以用你的用户名向你付款。一切就绪——打开钱包吧。"
|
||||
open_wallet: "打开我的钱包"
|
||||
skip_for_now: "暂时跳过"
|
||||
import_existing: "已有 Goblin 身份?导入它"
|
||||
import_title: "导入你的身份"
|
||||
import_blurb: "粘贴你的 nsec 或选择一个 .backup 文件,保留你现有的密钥和用户名,而不是这个新的。"
|
||||
errors:
|
||||
cant_open: "无法打开钱包:%{err}"
|
||||
cant_create: "无法创建钱包:%{err}"
|
||||
|
||||
@@ -28,6 +28,7 @@ use crate::gui::views::types::{ContentContainer, ModalPosition, QrScanResult};
|
||||
use crate::gui::views::wallets::creation::MnemonicSetup;
|
||||
use crate::gui::views::{CameraScanContent, Content, Modal, TextEdit, View};
|
||||
use crate::node::Node;
|
||||
use crate::nostr::NostrIdentity;
|
||||
use crate::wallet::types::{ConnectionMethod, PhraseMode, PhraseSize};
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection, Wallet, WalletList};
|
||||
|
||||
@@ -57,6 +58,11 @@ pub struct OnboardingContent {
|
||||
ext_url: String,
|
||||
/// Wallet setup inputs.
|
||||
restore: bool,
|
||||
/// The user chose "Import identity" on the wallet step: after the wallet is
|
||||
/// created the identity step opens the import panel straight away (bringing
|
||||
/// over an existing key from a `.backup` or nsec), instead of the fresh
|
||||
/// random key. Composes with either seed choice above it.
|
||||
want_import: bool,
|
||||
name: String,
|
||||
pass: String,
|
||||
pass2: String,
|
||||
@@ -70,10 +76,34 @@ pub struct OnboardingContent {
|
||||
wallet: Option<Wallet>,
|
||||
/// Optional username claim state (same machinery as Settings).
|
||||
claim: ClaimState,
|
||||
/// Optional "import an existing identity" sub-flow, opened from the identity
|
||||
/// step so a returning user can keep their old npub + username instead of the
|
||||
/// freshly-generated random key.
|
||||
import: Option<OnbImport>,
|
||||
/// Moment the recovery phrase was copied, for the transient "Copied" check.
|
||||
words_copied: Option<std::time::Instant>,
|
||||
}
|
||||
|
||||
/// Onboarding identity-import state. Reuses the wallet password the user just
|
||||
/// set, so it only needs the backup file / nsec (and the backup's own password
|
||||
/// when restoring a sealed `.backup`).
|
||||
#[derive(Default)]
|
||||
struct OnbImport {
|
||||
/// 0 = form, 1 = working, 2 = error.
|
||||
stage: u8,
|
||||
/// Pasted nsec or the read-in contents of a `.backup` / identity JSON file.
|
||||
nsec: String,
|
||||
/// Password the backup was sealed under (blank for a bare nsec, or when it
|
||||
/// matches this wallet's password).
|
||||
backup_password: String,
|
||||
/// Last import error, shown on stage 2.
|
||||
error: String,
|
||||
/// A native file pick is in flight (Android resolves the path asynchronously).
|
||||
picking: bool,
|
||||
/// Worker result: Ok(new npub) or Err(message).
|
||||
result: std::sync::Arc<std::sync::Mutex<Option<Result<String, String>>>>,
|
||||
}
|
||||
|
||||
impl Default for OnboardingContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -83,6 +113,7 @@ impl Default for OnboardingContent {
|
||||
integrated: false,
|
||||
ext_url: "https://grincoin.org".to_string(),
|
||||
restore: false,
|
||||
want_import: false,
|
||||
name: "Main wallet".to_string(),
|
||||
pass: String::new(),
|
||||
pass2: String::new(),
|
||||
@@ -91,6 +122,7 @@ impl Default for OnboardingContent {
|
||||
scan_modal: None,
|
||||
wallet: None,
|
||||
claim: ClaimState::default(),
|
||||
import: None,
|
||||
words_copied: None,
|
||||
}
|
||||
}
|
||||
@@ -388,6 +420,37 @@ impl OnboardingContent {
|
||||
ui.add_space(10.0);
|
||||
}
|
||||
});
|
||||
ui.add_space(10.0);
|
||||
|
||||
// First-class "Import identity" option, standing alongside Create/Restore:
|
||||
// bring an existing key over (from a .backup file or a bare nsec). It
|
||||
// composes with either seed choice above — the import panel itself opens
|
||||
// on the identity step, once the wallet exists.
|
||||
ui.scope_builder(
|
||||
egui::UiBuilder::new().max_rect(egui::Rect::from_min_size(
|
||||
ui.cursor().min,
|
||||
Vec2::new(ui.available_width(), 44.0),
|
||||
)),
|
||||
|ui| {
|
||||
if w::chip(
|
||||
ui,
|
||||
&t!("goblin.onboarding.wallet.import_identity"),
|
||||
self.want_import,
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.want_import = !self.want_import;
|
||||
}
|
||||
},
|
||||
);
|
||||
if self.want_import {
|
||||
ui.add_space(6.0);
|
||||
ui.label(
|
||||
RichText::new(t!("goblin.onboarding.wallet.import_identity_hint"))
|
||||
.font(FontId::new(12.5, fonts::regular()))
|
||||
.color(t.text_mute),
|
||||
);
|
||||
}
|
||||
ui.add_space(14.0);
|
||||
|
||||
w::field_well(ui, |ui| {
|
||||
@@ -838,7 +901,17 @@ impl OnboardingContent {
|
||||
.nostr_service()
|
||||
.map(|s| s.identity.read().nip05.is_some())
|
||||
.unwrap_or(false);
|
||||
if !registered {
|
||||
// Came in via the wallet step's "Import identity" button: open the import
|
||||
// panel straight away (offers both a .backup file and a bare nsec), rather
|
||||
// than the fresh-key claim card.
|
||||
if self.want_import && self.import.is_none() {
|
||||
self.import = Some(OnbImport::default());
|
||||
self.want_import = false;
|
||||
}
|
||||
if self.import.is_some() {
|
||||
// Returning user is swapping the random key for their existing identity.
|
||||
self.import_ui(ui, &wallet, cb);
|
||||
} else if !registered {
|
||||
w::card(ui, |ui| {
|
||||
ui.set_min_width(ui.available_width());
|
||||
ui.label(
|
||||
@@ -916,6 +989,14 @@ impl OnboardingContent {
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.add_space(10.0);
|
||||
// Returning user? A centered, first-class "Import identity" button
|
||||
// (was a left-aligned text link) restores their existing identity
|
||||
// from a .backup file or a bare nsec instead of the fresh random key.
|
||||
// The .backup-or-nsec choice lives behind it, in import_ui.
|
||||
if w::big_action(ui, &t!("goblin.onboarding.wallet.import_identity"), true).clicked() {
|
||||
self.import = Some(OnbImport::default());
|
||||
}
|
||||
ui.add_space(16.0);
|
||||
} else {
|
||||
// Claimed: show a clear success confirmation so the user knows the
|
||||
@@ -967,6 +1048,199 @@ impl OnboardingContent {
|
||||
None
|
||||
}
|
||||
|
||||
/// Onboarding identity-import sub-flow: paste an nsec or pick a `.backup`
|
||||
/// file to swap the freshly-generated random key for the user's existing
|
||||
/// identity (keeping their npub and any claimed username). Reuses the wallet
|
||||
/// password the user just set; a sealed `.backup` may carry its own password.
|
||||
fn import_ui(&mut self, ui: &mut egui::Ui, wallet: &Wallet, cb: &dyn PlatformCallbacks) {
|
||||
let t = theme::tokens();
|
||||
// Poll the worker first, WITHOUT holding a borrow across the reset below.
|
||||
if self.import.as_ref().map(|i| i.stage) == Some(1) {
|
||||
let res = self.import.as_ref().unwrap().result.lock().unwrap().take();
|
||||
if let Some(res) = res {
|
||||
match res {
|
||||
// Identity replaced: drop the sub-flow; the identity card and the
|
||||
// claim/success state re-render from the new service next frame.
|
||||
Ok(_) => {
|
||||
self.import = None;
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
let imp = self.import.as_mut().unwrap();
|
||||
imp.error = e;
|
||||
imp.stage = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let wallet_pass = self.pass.clone();
|
||||
let imp = self.import.as_mut().unwrap();
|
||||
let mut close = false;
|
||||
w::card(ui, |ui| {
|
||||
ui.set_min_width(ui.available_width());
|
||||
match imp.stage {
|
||||
1 => {
|
||||
ui.horizontal(|ui| {
|
||||
View::small_loading_spinner(ui);
|
||||
ui.add_space(8.0);
|
||||
ui.label(
|
||||
RichText::new(t!("goblin.settings.importing"))
|
||||
.font(FontId::new(13.0, fonts::regular()))
|
||||
.color(t.surface_text_dim),
|
||||
);
|
||||
});
|
||||
ui.ctx().request_repaint();
|
||||
}
|
||||
2 => {
|
||||
ui.label(
|
||||
RichText::new(t!("goblin.settings.import_failed"))
|
||||
.font(FontId::new(15.0, fonts::semibold()))
|
||||
.color(t.neg),
|
||||
);
|
||||
ui.add_space(4.0);
|
||||
ui.label(
|
||||
RichText::new(&imp.error)
|
||||
.font(FontId::new(13.0, fonts::regular()))
|
||||
.color(t.surface_text_dim),
|
||||
);
|
||||
ui.add_space(10.0);
|
||||
if w::big_action_on_card(ui, &t!("goblin.settings.close")).clicked() {
|
||||
close = true;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
ui.label(
|
||||
RichText::new(t!("goblin.onboarding.identity.import_title"))
|
||||
.font(FontId::new(15.0, fonts::semibold()))
|
||||
.color(t.surface_text),
|
||||
);
|
||||
ui.add_space(6.0);
|
||||
ui.label(
|
||||
RichText::new(t!("goblin.onboarding.identity.import_blurb"))
|
||||
.font(FontId::new(12.5, fonts::regular()))
|
||||
.color(t.surface_text_dim),
|
||||
);
|
||||
ui.add_space(10.0);
|
||||
// Native ".backup file" picker. Desktop returns the path now;
|
||||
// Android resolves it asynchronously (poll picked_file()).
|
||||
if imp.picking {
|
||||
if let Some(path) = cb.picked_file() {
|
||||
imp.picking = false;
|
||||
if !path.is_empty() {
|
||||
match std::fs::read_to_string(&path) {
|
||||
Ok(contents) => imp.nsec = contents.trim().to_string(),
|
||||
Err(_) => {
|
||||
imp.error =
|
||||
t!("goblin.settings.backup_read_failed").to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.ctx().request_repaint();
|
||||
}
|
||||
}
|
||||
if w::big_action_on_card(ui, &t!("goblin.settings.choose_backup_file"))
|
||||
.clicked()
|
||||
{
|
||||
imp.error.clear();
|
||||
match cb.pick_file() {
|
||||
Some(path) if !path.is_empty() => {
|
||||
match std::fs::read_to_string(&path) {
|
||||
Ok(contents) => imp.nsec = contents.trim().to_string(),
|
||||
Err(_) => {
|
||||
imp.error =
|
||||
t!("goblin.settings.backup_read_failed").to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Empty string = Android async pick in flight.
|
||||
Some(_) => imp.picking = true,
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
ui.add_space(8.0);
|
||||
w::field_well(ui, |ui| {
|
||||
TextEdit::new(egui::Id::from("onb_import_nsec"))
|
||||
.focus(false)
|
||||
.hint_text(t!("goblin.settings.import_nsec_hint"))
|
||||
.password()
|
||||
.text_color(t.surface_text)
|
||||
.body()
|
||||
.ui(ui, &mut imp.nsec, cb);
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
w::field_well(ui, |ui| {
|
||||
TextEdit::new(egui::Id::from("onb_import_bpw"))
|
||||
.focus(false)
|
||||
.hint_text(t!("goblin.settings.backup_password_hint"))
|
||||
.password()
|
||||
.text_color(t.surface_text)
|
||||
.body()
|
||||
.ui(ui, &mut imp.backup_password, cb);
|
||||
});
|
||||
if !imp.error.is_empty() {
|
||||
ui.add_space(6.0);
|
||||
ui.label(
|
||||
RichText::new(&imp.error)
|
||||
.font(FontId::new(12.5, fonts::regular()))
|
||||
.color(t.neg),
|
||||
);
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
let pasted = imp.nsec.trim();
|
||||
// Only an nsec paste or a sealed .backup file — nothing else.
|
||||
let armed =
|
||||
pasted.starts_with("nsec1") || NostrIdentity::is_encrypted_backup(pasted);
|
||||
ui.horizontal(|ui| {
|
||||
let half = (ui.available_width() - 10.0) / 2.0;
|
||||
ui.scope_builder(
|
||||
egui::UiBuilder::new().max_rect(egui::Rect::from_min_size(
|
||||
ui.cursor().min,
|
||||
Vec2::new(half, 44.0),
|
||||
)),
|
||||
|ui| {
|
||||
if w::big_action_on_card(ui, &t!("goblin.settings.cancel"))
|
||||
.clicked()
|
||||
{
|
||||
close = true;
|
||||
}
|
||||
},
|
||||
);
|
||||
ui.add_space(10.0);
|
||||
ui.scope_builder(
|
||||
egui::UiBuilder::new().max_rect(egui::Rect::from_min_size(
|
||||
ui.cursor().min,
|
||||
Vec2::new(half, 44.0),
|
||||
)),
|
||||
|ui| {
|
||||
ui.add_enabled_ui(armed, |ui| {
|
||||
if w::big_action(ui, &t!("goblin.settings.import_btn"), false)
|
||||
.clicked()
|
||||
{
|
||||
imp.stage = 1;
|
||||
let slot = imp.result.clone();
|
||||
let nsec = std::mem::take(&mut imp.nsec);
|
||||
let bpw = std::mem::take(&mut imp.backup_password);
|
||||
let bpw = if bpw.is_empty() { None } else { Some(bpw) };
|
||||
let wallet = wallet.clone();
|
||||
let pass = wallet_pass.clone();
|
||||
std::thread::spawn(move || {
|
||||
let res = wallet.import_nostr_identity(nsec, pass, bpw);
|
||||
*slot.lock().unwrap() = Some(res);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if close {
|
||||
self.import = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// Recovery-phrase QR scan modal content.
|
||||
fn scan_modal_ui(&mut self, ui: &mut egui::Ui, _: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
if let Some(content) = self.scan_modal.as_mut() {
|
||||
|
||||
Reference in New Issue
Block a user