Skip to content

Commit c25c5cc

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 c25c5cc

File tree

2 files changed

+66
-38
lines changed

2 files changed

+66
-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: 61 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,77 @@ 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;
7175
final wallet = DecredWallet(credentials.walletInfo!, credentials.password!,
7276
this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
7377
await wallet.init();
7478
return wallet;
7579
}
7680

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

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

92128
final config = {
93-
"name": walletInfo.name,
94-
"datadir": walletInfo.dirPath,
95-
"net": network,
129+
"name": name,
130+
"datadir": dirPath,
131+
"net": walletInfo.network,
96132
"unsyncedaddrs": true,
97133
};
98134
await libwallet!.loadWallet(jsonEncode(config));
@@ -114,21 +150,14 @@ class DecredWalletService extends WalletService<
114150
Future<void> rename(String currentName, String password, String newName) async {
115151
final currentWalletInfo = walletInfoSource.values
116152
.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);
125153

154+
final currentDirPath = await pathForWalletDir(name: currentName, type: getType());
126155
final newDirPath = await pathForWalletDir(name: newName, type: getType());
156+
this.moveWallet(currentDirPath, newDirPath);
157+
127158
final newWalletInfo = currentWalletInfo;
128159
newWalletInfo.id = WalletBase.idFor(newName, getType());
129160
newWalletInfo.name = newName;
130-
newWalletInfo.dirPath = newDirPath;
131-
newWalletInfo.network = network;
132161

133162
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
134163
}
@@ -137,18 +166,21 @@ class DecredWalletService extends WalletService<
137166
Future<DecredWallet> restoreFromSeed(DecredRestoreWalletFromSeedCredentials credentials,
138167
{bool? isTestnet}) async {
139168
await this.init();
169+
final network = isTestnet == true ? testnet : mainnet;
170+
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
140171
final config = {
141172
"name": credentials.walletInfo!.name,
142-
"datadir": credentials.walletInfo!.dirPath,
173+
"datadir": dirPath,
143174
"pass": credentials.password!,
144175
"mnemonic": credentials.mnemonic,
145-
"net": isTestnet == true ? testnet : mainnet,
176+
"net": network,
146177
"unsyncedaddrs": true,
147178
};
148179
await libwallet!.createWallet(jsonEncode(config));
149180
final di = DerivationInfo(
150181
derivationPath: isTestnet == true ? seedRestorePathTestnet : seedRestorePath);
151182
credentials.walletInfo!.derivationInfo = di;
183+
credentials.walletInfo!.network = network;
152184
final wallet = DecredWallet(credentials.walletInfo!, credentials.password!,
153185
this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
154186
await wallet.init();
@@ -161,17 +193,20 @@ class DecredWalletService extends WalletService<
161193
Future<DecredWallet> restoreFromKeys(DecredRestoreWalletFromPubkeyCredentials credentials,
162194
{bool? isTestnet}) async {
163195
await this.init();
196+
final network = isTestnet == true ? testnet : mainnet;
197+
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
164198
final config = {
165199
"name": credentials.walletInfo!.name,
166-
"datadir": credentials.walletInfo!.dirPath,
200+
"datadir": dirPath,
167201
"pubkey": credentials.pubkey,
168-
"net": isTestnet == true ? testnet : mainnet,
202+
"net": network,
169203
"unsyncedaddrs": true,
170204
};
171205
await libwallet!.createWatchOnlyWallet(jsonEncode(config));
172206
final di = DerivationInfo(
173207
derivationPath: isTestnet == true ? pubkeyRestorePathTestnet : pubkeyRestorePath);
174208
credentials.walletInfo!.derivationInfo = di;
209+
credentials.walletInfo!.network = network;
175210
final wallet = DecredWallet(credentials.walletInfo!, credentials.password!,
176211
this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
177212
await wallet.init();

0 commit comments

Comments
 (0)