feat(wallet): migrate-to-seed, Phase 1 — isolated seed-wallet creation
First, fund-safe step of "migrate a legacy wallet to a seed wallet": mint a brand-new BIP39 mnemonic wallet in an ISOLATED throwaway datadir so the user can later sweep funds into it. No funds move and the real wallet.dat / main daemon are never touched — the isolated node runs concurrently on its own port. - EmbeddedDaemon: one-shot isolated-datadir override (setNextStartOverride) consumed on the next start(); a skip-default-port-check for an isolated instance beside the main daemon; and a tcpPortInUse() probe. The datadir's basename must be the assetchain name (DRAGONX) and the daemon reads <datadir>/DRAGONX.conf itself, so no -conf is passed (both learned from live testing against the hd-transparent-keys daemon). - SeedWalletCreator (src/daemon): picks a free port, writes a throwaway conf, starts an isolated dragonxd with -usemnemonic=1 -connect=0, waits for RPC, calls z_exportmnemonic + z_getnewaddress (the sweep target), stops it, and keeps/scrubs the temp datadir. Off-thread; the seed is wiped after use. - App: beginCreateSeedWallet (background) -> pumpSeedMigration (main-thread handoff) -> renderSeedMigrationDialog (Intro -> Working -> Show seed -> Error), reusing the seed_display grid + clipboard auto-clear. - Settings: "Migrate to seed…" button (full-node gated) + persisted pending migration state (dest address + temp datadir) for Phase 2 to adopt. Validated end-to-end against the hd-transparent-keys daemon: the isolated node comes up in ~4s and returns a 24-word mnemonic + a shielded z-address. Requires that daemon (the bundled Jun-28 build lacks z_exportmnemonic). The migration modal uses English literals for now (as renderBackupDialog does); the whole flow gets translated once Phase 2 finalizes it. Phase 2 (sweep + adopt) is next. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -250,6 +250,15 @@ public:
|
||||
bool getSeedBackupReminded() const { return seed_backup_reminded_; }
|
||||
void setSeedBackupReminded(bool v) { seed_backup_reminded_ = v; }
|
||||
|
||||
// Pending "migrate to a seed wallet" state (Phase 1 created the wallet; a later sweep/adopt
|
||||
// step consumes it). dest = the new wallet's sweep-target z-address; tempDir = its datadir.
|
||||
bool getSeedMigrationPending() const { return seed_migration_pending_; }
|
||||
void setSeedMigrationPending(bool v) { seed_migration_pending_ = v; }
|
||||
std::string getSeedMigrationDest() const { return seed_migration_dest_; }
|
||||
void setSeedMigrationDest(const std::string& v) { seed_migration_dest_ = v; }
|
||||
std::string getSeedMigrationTempDir() const { return seed_migration_temp_dir_; }
|
||||
void setSeedMigrationTempDir(const std::string& v) { seed_migration_temp_dir_ = v; }
|
||||
|
||||
// Security — auto-lock timeout (seconds; 0 = disabled)
|
||||
int getAutoLockTimeout() const { return auto_lock_timeout_; }
|
||||
void setAutoLockTimeout(int seconds) { auto_lock_timeout_ = seconds; }
|
||||
@@ -449,6 +458,9 @@ private:
|
||||
std::map<std::string, AddressMeta> address_meta_;
|
||||
bool wizard_completed_ = false;
|
||||
bool seed_backup_reminded_ = false;
|
||||
bool seed_migration_pending_ = false;
|
||||
std::string seed_migration_dest_;
|
||||
std::string seed_migration_temp_dir_;
|
||||
int auto_lock_timeout_ = 900; // 15 minutes
|
||||
int unlock_duration_ = 600; // 10 minutes
|
||||
bool pin_enabled_ = false;
|
||||
|
||||
Reference in New Issue
Block a user