@@ -8,6 +8,7 @@ import 'package:cw_core/wallet_service.dart';
8
8
import 'package:cw_core/pathForWallet.dart' ;
9
9
import 'package:cw_core/wallet_info.dart' ;
10
10
import 'package:cw_core/wallet_type.dart' ;
11
+ import 'package:path/path.dart' ;
11
12
import 'package:hive/hive.dart' ;
12
13
import 'package:collection/collection.dart' ;
13
14
import 'package:cw_core/unspent_coins_info.dart' ;
@@ -57,42 +58,90 @@ class DecredWalletService extends WalletService<
57
58
@override
58
59
Future <DecredWallet > create (DecredNewWalletCredentials credentials, {bool ? isTestnet}) async {
59
60
await this .init ();
61
+ final dirPath = await pathForWalletDir (name: credentials.walletInfo! .name, type: getType ());
62
+ final network = isTestnet == true ? testnet : mainnet;
60
63
final config = {
61
64
"name" : credentials.walletInfo! .name,
62
- "datadir" : credentials.walletInfo ! . dirPath,
65
+ "datadir" : dirPath,
63
66
"pass" : credentials.password! ,
64
- "net" : isTestnet == true ? testnet : mainnet ,
67
+ "net" : network ,
65
68
"unsyncedaddrs" : true ,
66
69
};
67
70
await libwallet! .createWallet (jsonEncode (config));
68
71
final di = DerivationInfo (
69
72
derivationPath: isTestnet == true ? seedRestorePathTestnet : seedRestorePath);
70
73
credentials.walletInfo! .derivationInfo = di;
74
+ credentials.walletInfo! .network = network;
75
+ // ios will move our wallet directory when updating. Since we must
76
+ // recalculate the new path every time we open the wallet, ensure this path
77
+ // is not used. An older wallet will have a directory here which is a
78
+ // condition for moving the wallet when opening, so this must be kept blank
79
+ // going forward.
80
+ credentials.walletInfo! .dirPath = "" ;
81
+ credentials.walletInfo! .path = "" ;
71
82
final wallet = DecredWallet (credentials.walletInfo! , credentials.password! ,
72
83
this .unspentCoinsInfoSource, libwallet! , closeLibwallet);
73
84
await wallet.init ();
74
85
return wallet;
75
86
}
76
87
88
+ void copyDirectorySync (Directory source, Directory destination) {
89
+ /// create destination folder if not exist
90
+ if (! destination.existsSync ()) {
91
+ destination.createSync (recursive: true );
92
+ }
93
+
94
+ /// get all files from source (recursive: false is important here)
95
+ source.listSync (recursive: false ).forEach ((entity) {
96
+ final newPath = destination.path + Platform .pathSeparator + basename (entity.path);
97
+ if (entity is File ) {
98
+ entity.copySync (newPath);
99
+ } else if (entity is Directory ) {
100
+ copyDirectorySync (entity, Directory (newPath));
101
+ }
102
+ });
103
+ }
104
+
105
+ Future <void > moveWallet (String fromPath, String toPath) async {
106
+ final oldWalletDir = new Directory (fromPath);
107
+ final newWalletDir = new Directory (toPath);
108
+ copyDirectorySync (oldWalletDir, newWalletDir);
109
+ await oldWalletDir.delete (recursive: true );
110
+ }
111
+
77
112
@override
78
113
Future <DecredWallet > openWallet (String name, String password) async {
79
114
final walletInfo = walletInfoSource.values
80
115
.firstWhereOrNull ((info) => info.id == WalletBase .idFor (name, getType ()))! ;
81
- final network = walletInfo.derivationInfo? .derivationPath == seedRestorePathTestnet ||
82
- walletInfo.derivationInfo? .derivationPath == pubkeyRestorePathTestnet
83
- ? testnet
84
- : mainnet;
85
116
86
117
await this .init ();
87
- final walletDirExists = Directory (walletInfo.dirPath).existsSync ();
88
- if (! walletDirExists) {
89
- walletInfo.dirPath = await pathForWalletDir (name: name, type: getType ());
118
+
119
+ // Cake wallet version 4.27.0 and earlier gave a wallet dir that did not
120
+ // match the name. Move those to the correct place.
121
+ final dirPath = await pathForWalletDir (name: name, type: getType ());
122
+ if (walletInfo.dirPath != "" ) {
123
+ // On ios the stored dir no longer exists. We can only trust the basename.
124
+ final randomBasename = basename (walletInfo.dirPath);
125
+ final oldDir = await pathForWalletDir (name: randomBasename, type: getType ());
126
+ if (oldDir != dirPath) {
127
+ await this .moveWallet (oldDir, dirPath);
128
+ }
129
+ // Clear the path so this does not trigger again.
130
+ walletInfo.dirPath = "" ;
131
+ walletInfo.path = "" ;
132
+ }
133
+
134
+ if (walletInfo.network == null || walletInfo.network == "" ) {
135
+ walletInfo.network = walletInfo.derivationInfo? .derivationPath == seedRestorePathTestnet ||
136
+ walletInfo.derivationInfo? .derivationPath == pubkeyRestorePathTestnet
137
+ ? testnet
138
+ : mainnet;
90
139
}
91
140
92
141
final config = {
93
- "name" : walletInfo. name,
94
- "datadir" : walletInfo. dirPath,
95
- "net" : network,
142
+ "name" : name,
143
+ "datadir" : dirPath,
144
+ "net" : walletInfo. network,
96
145
"unsyncedaddrs" : true ,
97
146
};
98
147
await libwallet! .loadWallet (jsonEncode (config));
@@ -114,21 +163,16 @@ class DecredWalletService extends WalletService<
114
163
Future <void > rename (String currentName, String password, String newName) async {
115
164
final currentWalletInfo = walletInfoSource.values
116
165
.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);
125
166
167
+ final currentDirPath = await pathForWalletDir (name: currentName, type: getType ());
126
168
final newDirPath = await pathForWalletDir (name: newName, type: getType ());
169
+ await this .moveWallet (currentDirPath, newDirPath);
170
+
127
171
final newWalletInfo = currentWalletInfo;
128
172
newWalletInfo.id = WalletBase .idFor (newName, getType ());
129
173
newWalletInfo.name = newName;
130
- newWalletInfo.dirPath = newDirPath ;
131
- newWalletInfo.network = network ;
174
+ newWalletInfo.dirPath = "" ;
175
+ newWalletInfo.path = "" ;
132
176
133
177
await walletInfoSource.put (currentWalletInfo.key, newWalletInfo);
134
178
}
@@ -137,18 +181,23 @@ class DecredWalletService extends WalletService<
137
181
Future <DecredWallet > restoreFromSeed (DecredRestoreWalletFromSeedCredentials credentials,
138
182
{bool ? isTestnet}) async {
139
183
await this .init ();
184
+ final network = isTestnet == true ? testnet : mainnet;
185
+ final dirPath = await pathForWalletDir (name: credentials.walletInfo! .name, type: getType ());
140
186
final config = {
141
187
"name" : credentials.walletInfo! .name,
142
- "datadir" : credentials.walletInfo ! . dirPath,
188
+ "datadir" : dirPath,
143
189
"pass" : credentials.password! ,
144
190
"mnemonic" : credentials.mnemonic,
145
- "net" : isTestnet == true ? testnet : mainnet ,
191
+ "net" : network ,
146
192
"unsyncedaddrs" : true ,
147
193
};
148
194
await libwallet! .createWallet (jsonEncode (config));
149
195
final di = DerivationInfo (
150
196
derivationPath: isTestnet == true ? seedRestorePathTestnet : seedRestorePath);
151
197
credentials.walletInfo! .derivationInfo = di;
198
+ credentials.walletInfo! .network = network;
199
+ credentials.walletInfo! .dirPath = "" ;
200
+ credentials.walletInfo! .path = "" ;
152
201
final wallet = DecredWallet (credentials.walletInfo! , credentials.password! ,
153
202
this .unspentCoinsInfoSource, libwallet! , closeLibwallet);
154
203
await wallet.init ();
@@ -161,17 +210,22 @@ class DecredWalletService extends WalletService<
161
210
Future <DecredWallet > restoreFromKeys (DecredRestoreWalletFromPubkeyCredentials credentials,
162
211
{bool ? isTestnet}) async {
163
212
await this .init ();
213
+ final network = isTestnet == true ? testnet : mainnet;
214
+ final dirPath = await pathForWalletDir (name: credentials.walletInfo! .name, type: getType ());
164
215
final config = {
165
216
"name" : credentials.walletInfo! .name,
166
- "datadir" : credentials.walletInfo ! . dirPath,
217
+ "datadir" : dirPath,
167
218
"pubkey" : credentials.pubkey,
168
- "net" : isTestnet == true ? testnet : mainnet ,
219
+ "net" : network ,
169
220
"unsyncedaddrs" : true ,
170
221
};
171
222
await libwallet! .createWatchOnlyWallet (jsonEncode (config));
172
223
final di = DerivationInfo (
173
224
derivationPath: isTestnet == true ? pubkeyRestorePathTestnet : pubkeyRestorePath);
174
225
credentials.walletInfo! .derivationInfo = di;
226
+ credentials.walletInfo! .network = network;
227
+ credentials.walletInfo! .dirPath = "" ;
228
+ credentials.walletInfo! .path = "" ;
175
229
final wallet = DecredWallet (credentials.walletInfo! , credentials.password! ,
176
230
this .unspentCoinsInfoSource, libwallet! , closeLibwallet);
177
231
await wallet.init ();
0 commit comments