Skip to content

Commit 3c46a10

Browse files
committed
dcr: Always fetch the current dir path.
On ios devices the path will change between updates breaking decred. Never save the path and always check to ensure it is up to date. Previous wallets were also not creating a directory in the correct place. Move those when found.
1 parent 4448adb commit 3c46a10

File tree

2 files changed

+70
-38
lines changed

2 files changed

+70
-38
lines changed

cw_decred/lib/wallet.dart

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import 'dart:io';
44
import 'package:cw_core/exceptions.dart';
55
import 'package:cw_core/transaction_direction.dart';
66
import 'package:cw_core/utils/print_verbose.dart';
7+
import 'package:cw_core/pathForWallet.dart';
8+
import 'package:cw_core/wallet_type.dart';
79
import 'package:cw_decred/amount_format.dart';
810
import 'package:cw_decred/pending_transaction.dart';
911
import 'package:cw_decred/transaction_credentials.dart';
@@ -306,9 +308,10 @@ abstract class DecredWalletBase
306308
persistantPeer = addr;
307309
await _libwallet.closeWallet(walletInfo.name);
308310
final network = isTestnet ? "testnet" : "mainnet";
311+
final dirPath = await pathForWalletDir(name: walletInfo.name, type: WalletType.decred);
309312
final config = {
310313
"name": walletInfo.name,
311-
"datadir": walletInfo.dirPath,
314+
"datadir": dirPath,
312315
"net": network,
313316
"unsyncedaddrs": true,
314317
};
@@ -593,17 +596,7 @@ abstract class DecredWalletBase
593596
@override
594597
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => onError;
595598

596-
Future<void> renameWalletFiles(String newWalletName) async {
597-
final currentDirPath = await pathForWalletDir(name: walletInfo.name, type: type);
598-
599-
final newDirPath = await pathForWalletDir(name: newWalletName, type: type);
600-
601-
if (File(newDirPath).existsSync()) {
602-
throw "wallet already exists at $newDirPath";
603-
}
604-
605-
await Directory(currentDirPath).rename(newDirPath);
606-
}
599+
Future<void> renameWalletFiles(String newWalletName) async {}
607600

608601
@override
609602
Future<String> signMessage(String message, {String? address = null}) async {

cw_decred/lib/wallet_service.dart

Lines changed: 65 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:cw_core/wallet_service.dart';
88
import 'package:cw_core/pathForWallet.dart';
99
import 'package:cw_core/wallet_info.dart';
1010
import 'package:cw_core/wallet_type.dart';
11+
import 'package:path/path.dart';
1112
import 'package:hive/hive.dart';
1213
import 'package:collection/collection.dart';
1314
import 'package:cw_core/unspent_coins_info.dart';
@@ -57,42 +58,78 @@ class DecredWalletService extends WalletService<
5758
@override
5859
Future<DecredWallet> create(DecredNewWalletCredentials credentials, {bool? isTestnet}) async {
5960
await this.init();
61+
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
62+
final network = isTestnet == true ? testnet : mainnet;
6063
final config = {
6164
"name": credentials.walletInfo!.name,
62-
"datadir": credentials.walletInfo!.dirPath,
65+
"datadir": dirPath,
6366
"pass": credentials.password!,
64-
"net": isTestnet == true ? testnet : mainnet,
67+
"net": network,
6568
"unsyncedaddrs": true,
6669
};
6770
await libwallet!.createWallet(jsonEncode(config));
6871
final di = DerivationInfo(
6972
derivationPath: isTestnet == true ? seedRestorePathTestnet : seedRestorePath);
7073
credentials.walletInfo!.derivationInfo = di;
74+
credentials.walletInfo!.network = network;
75+
credentials.walletInfo!.dirPath = "";
7176
final wallet = DecredWallet(credentials.walletInfo!, credentials.password!,
7277
this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
7378
await wallet.init();
7479
return wallet;
7580
}
7681

82+
void copyDirectorySync(Directory source, Directory destination) {
83+
/// create destination folder if not exist
84+
if (!destination.existsSync()) {
85+
destination.createSync(recursive: true);
86+
}
87+
88+
/// get all files from source (recursive: false is important here)
89+
source.listSync(recursive: false).forEach((entity) {
90+
final newPath = destination.path + Platform.pathSeparator + basename(entity.path);
91+
if (entity is File) {
92+
entity.copySync(newPath);
93+
} else if (entity is Directory) {
94+
copyDirectorySync(entity, Directory(newPath));
95+
}
96+
});
97+
}
98+
99+
Future<void> moveWallet(String fromPath, String toPath) async {
100+
final oldWalletDir = new Directory(fromPath);
101+
final newWalletDir = new Directory(toPath);
102+
copyDirectorySync(oldWalletDir, newWalletDir);
103+
await oldWalletDir.delete(recursive: true);
104+
}
105+
77106
@override
78107
Future<DecredWallet> openWallet(String name, String password) async {
79108
final walletInfo = walletInfoSource.values
80109
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
81-
final network = walletInfo.derivationInfo?.derivationPath == seedRestorePathTestnet ||
82-
walletInfo.derivationInfo?.derivationPath == pubkeyRestorePathTestnet
83-
? testnet
84-
: mainnet;
85110

86111
await this.init();
87-
final walletDirExists = Directory(walletInfo.dirPath).existsSync();
88-
if (!walletDirExists) {
89-
walletInfo.dirPath = await pathForWalletDir(name: name, type: getType());
112+
113+
// Cake wallet version 4.27.0 and earlier gave a wallet dir that did not
114+
// match the name. Move those to the correct place.
115+
final dirPath = await pathForWalletDir(name: name, type: getType());
116+
if (walletInfo.dirPath != "" && walletInfo.dirPath != dirPath) {
117+
this.moveWallet(walletInfo.dirPath, dirPath);
118+
// Clear the path so this does not trigger again.
119+
walletInfo.dirPath = "";
120+
}
121+
122+
if (walletInfo.network == null || walletInfo.network == "") {
123+
walletInfo.network = walletInfo.derivationInfo?.derivationPath == seedRestorePathTestnet ||
124+
walletInfo.derivationInfo?.derivationPath == pubkeyRestorePathTestnet
125+
? testnet
126+
: mainnet;
90127
}
91128

92129
final config = {
93-
"name": walletInfo.name,
94-
"datadir": walletInfo.dirPath,
95-
"net": network,
130+
"name": name,
131+
"datadir": dirPath,
132+
"net": walletInfo.network,
96133
"unsyncedaddrs": true,
97134
};
98135
await libwallet!.loadWallet(jsonEncode(config));
@@ -114,21 +151,15 @@ class DecredWalletService extends WalletService<
114151
Future<void> rename(String currentName, String password, String newName) async {
115152
final currentWalletInfo = walletInfoSource.values
116153
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
117-
final network = currentWalletInfo.derivationInfo?.derivationPath == seedRestorePathTestnet ||
118-
currentWalletInfo.derivationInfo?.derivationPath == pubkeyRestorePathTestnet
119-
? testnet
120-
: mainnet;
121-
final currentWallet = DecredWallet(
122-
currentWalletInfo, password, this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
123-
124-
await currentWallet.renameWalletFiles(newName);
125154

155+
final currentDirPath = await pathForWalletDir(name: currentName, type: getType());
126156
final newDirPath = await pathForWalletDir(name: newName, type: getType());
157+
this.moveWallet(currentDirPath, newDirPath);
158+
127159
final newWalletInfo = currentWalletInfo;
128160
newWalletInfo.id = WalletBase.idFor(newName, getType());
129161
newWalletInfo.name = newName;
130-
newWalletInfo.dirPath = newDirPath;
131-
newWalletInfo.network = network;
162+
newWalletInfo.dirPath = "";
132163

133164
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
134165
}
@@ -137,18 +168,22 @@ class DecredWalletService extends WalletService<
137168
Future<DecredWallet> restoreFromSeed(DecredRestoreWalletFromSeedCredentials credentials,
138169
{bool? isTestnet}) async {
139170
await this.init();
171+
final network = isTestnet == true ? testnet : mainnet;
172+
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
140173
final config = {
141174
"name": credentials.walletInfo!.name,
142-
"datadir": credentials.walletInfo!.dirPath,
175+
"datadir": dirPath,
143176
"pass": credentials.password!,
144177
"mnemonic": credentials.mnemonic,
145-
"net": isTestnet == true ? testnet : mainnet,
178+
"net": network,
146179
"unsyncedaddrs": true,
147180
};
148181
await libwallet!.createWallet(jsonEncode(config));
149182
final di = DerivationInfo(
150183
derivationPath: isTestnet == true ? seedRestorePathTestnet : seedRestorePath);
151184
credentials.walletInfo!.derivationInfo = di;
185+
credentials.walletInfo!.network = network;
186+
credentials.walletInfo!.dirPath = "";
152187
final wallet = DecredWallet(credentials.walletInfo!, credentials.password!,
153188
this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
154189
await wallet.init();
@@ -161,17 +196,21 @@ class DecredWalletService extends WalletService<
161196
Future<DecredWallet> restoreFromKeys(DecredRestoreWalletFromPubkeyCredentials credentials,
162197
{bool? isTestnet}) async {
163198
await this.init();
199+
final network = isTestnet == true ? testnet : mainnet;
200+
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
164201
final config = {
165202
"name": credentials.walletInfo!.name,
166-
"datadir": credentials.walletInfo!.dirPath,
203+
"datadir": dirPath,
167204
"pubkey": credentials.pubkey,
168-
"net": isTestnet == true ? testnet : mainnet,
205+
"net": network,
169206
"unsyncedaddrs": true,
170207
};
171208
await libwallet!.createWatchOnlyWallet(jsonEncode(config));
172209
final di = DerivationInfo(
173210
derivationPath: isTestnet == true ? pubkeyRestorePathTestnet : pubkeyRestorePath);
174211
credentials.walletInfo!.derivationInfo = di;
212+
credentials.walletInfo!.network = network;
213+
credentials.walletInfo!.dirPath = "";
175214
final wallet = DecredWallet(credentials.walletInfo!, credentials.password!,
176215
this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
177216
await wallet.init();

0 commit comments

Comments
 (0)