Skip to content

Commit dabfc0b

Browse files
committed
Migrate legacy wallets
1 parent 74427ad commit dabfc0b

File tree

1 file changed

+81
-19
lines changed

1 file changed

+81
-19
lines changed

node/src/rpc.rs

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -316,41 +316,60 @@ impl WalletManager {
316316
&self,
317317
client: &reqwest::Client,
318318
name: String,
319+
) -> anyhow::Result<()> {
320+
let mnemonic: GeneratedKey<_, Tap> =
321+
Mnemonic::generate((WordCount::Words12, Language::English))
322+
.map_err(|_| anyhow!("Mnemonic generation error"))?;
323+
324+
let start_block = self.get_wallet_start_block(client).await?;
325+
self.setup_new_wallet(name.clone(), mnemonic.to_string(), start_block)?;
326+
self.load_wallet(client, name).await?;
327+
Ok(())
328+
}
329+
330+
fn setup_new_wallet(
331+
&self,
332+
name: String,
333+
mnemonic: String,
334+
start_block: BlockId,
319335
) -> anyhow::Result<()> {
320336
let wallet_path = self.data_dir.join(&name);
321337
if wallet_path.exists() {
322-
return Err(anyhow!("Wallet already exists"));
338+
return Err(anyhow!(format!("Wallet `{}` already exists", name)));
323339
}
324340

325-
let mnemonic: GeneratedKey<_, Tap> =
326-
Mnemonic::generate((WordCount::Words12, Language::English))
327-
.map_err(|_| anyhow!("Mnemonic generation error"))?;
341+
let export = self.wallet_from_mnemonic(name.clone(), mnemonic.to_string(), start_block)?;
342+
fs::create_dir_all(&wallet_path)?;
343+
let wallet_export_path = wallet_path.join("wallet.json");
344+
let mut file = fs::File::create(wallet_export_path)?;
345+
file.write_all(export.to_string().as_bytes())?;
346+
Ok(())
347+
}
328348

329-
let (network, _) = self.wallet_network();
349+
fn wallet_from_mnemonic(
350+
&self,
351+
name: String,
352+
mnemonic: String,
353+
start_block: BlockId,
354+
) -> anyhow::Result<WalletExport> {
355+
let (network, _) = self.fallback_network();
330356
let xpriv = Self::descriptor_from_mnemonic(network, &mnemonic.to_string())?;
331357

332358
let coins_descriptors = Self::default_coin_descriptors(xpriv);
333359
let space_descriptors = Self::default_spaces_descriptors(xpriv);
334360

335-
let start_block = self.get_wallet_start_block(client).await?;
336361
let export = WalletExport::from_descriptors(
337-
name.clone(),
362+
name,
338363
start_block.height,
339364
network,
340365
coins_descriptors.0,
341366
space_descriptors.0,
342367
)?;
343368

344-
fs::create_dir_all(&wallet_path)?;
345-
let wallet_export_path = wallet_path.join("wallet.json");
346-
let mut file = fs::File::create(wallet_export_path)?;
347-
file.write_all(export.to_string().as_bytes())?;
348-
349-
self.load_wallet(client, name).await?;
350-
Ok(())
369+
Ok(export)
351370
}
352371

353-
fn wallet_network(&self) -> (Network, Option<BlockHash>) {
372+
fn fallback_network(&self) -> (Network, Option<BlockHash>) {
354373
let mut genesis_hash = None;
355374

356375
let network = match self.network {
@@ -387,16 +406,59 @@ impl WalletManager {
387406
(network, genesis_hash)
388407
}
389408

409+
// TODO: remove in the next update
410+
pub async fn migrate_legacy_v0_0_1_wallet(
411+
&self,
412+
name: String,
413+
wallet_dir: PathBuf,
414+
) -> anyhow::Result<bool> {
415+
let legacy_secret = wallet_dir
416+
.join("insecure_secret")
417+
.to_str()
418+
.unwrap()
419+
.replace("/testnet/wallets/", "/test/wallets/");
420+
let legacy_secret = std::path::PathBuf::from(legacy_secret);
421+
422+
if !legacy_secret.exists() {
423+
return Ok(false);
424+
}
425+
426+
let mnemonic = fs::read_to_string(legacy_secret)?.trim().to_string();
427+
let start_block = match self.network {
428+
ExtendedNetwork::Testnet => ChainAnchor::TESTNET(),
429+
ExtendedNetwork::Testnet4 => ChainAnchor::TESTNET4(),
430+
ExtendedNetwork::Regtest => ChainAnchor::REGTEST(),
431+
_ => panic!("could not migrate legacy wallet: unsupported network"),
432+
};
433+
434+
self.setup_new_wallet(
435+
name,
436+
mnemonic,
437+
BlockId {
438+
height: start_block.height,
439+
hash: start_block.hash,
440+
},
441+
)?;
442+
443+
Ok(true)
444+
}
445+
390446
pub async fn load_wallet(&self, client: &reqwest::Client, name: String) -> anyhow::Result<()> {
391447
let wallet_dir = self.data_dir.join(name.clone());
392448
if !wallet_dir.exists() {
393-
return Err(anyhow!("Wallet does not exist"));
449+
if self
450+
.migrate_legacy_v0_0_1_wallet(name.clone(), wallet_dir.clone())
451+
.await?
452+
{
453+
info!("Migrated legacy wallet {}", name);
454+
} else {
455+
return Err(anyhow!("Wallet does not exist"));
456+
}
394457
}
395458

396459
let file = fs::File::open(wallet_dir.join("wallet.json"))?;
397460

398-
let (network, genesis_hash) = self.wallet_network();
399-
461+
let (network, genesis_hash) = self.fallback_network();
400462
let export: WalletExport = serde_json::from_reader(file)?;
401463

402464
let mut wallet = SpacesWallet::new(WalletConfig {
@@ -845,7 +907,7 @@ impl AsyncChainState {
845907
}
846908
}
847909

848-
info!("Shutting down database reader");
910+
info!("Shutting down chain state...");
849911
}
850912

851913
pub async fn estimate_bid(&self, target: usize) -> anyhow::Result<u64> {

0 commit comments

Comments
 (0)