@@ -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,89 @@ 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.rename (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;
116
+ if (walletInfo.network == null || walletInfo.network == "" ) {
117
+ walletInfo.network = walletInfo.derivationInfo? .derivationPath == seedRestorePathTestnet ||
118
+ walletInfo.derivationInfo? .derivationPath == pubkeyRestorePathTestnet
119
+ ? testnet
120
+ : mainnet;
121
+ }
85
122
86
123
await this .init ();
87
- final walletDirExists = Directory (walletInfo.dirPath).existsSync ();
88
- if (! walletDirExists) {
89
- walletInfo.dirPath = await pathForWalletDir (name: name, type: getType ());
124
+
125
+ // Cake wallet version 4.27.0 and earlier gave a wallet dir that did not
126
+ // match the name. Move those to the correct place.
127
+ final dirPath = await pathForWalletDir (name: name, type: getType ());
128
+ if (walletInfo.dirPath != "" ) {
129
+ // On ios the stored dir no longer exists. We can only trust the basename.
130
+ final randomBasename = basename (walletInfo.dirPath);
131
+ final oldDir = await pathForWalletDir (name: randomBasename, type: getType ());
132
+ if (oldDir != dirPath) {
133
+ await this .moveWallet (oldDir, dirPath);
134
+ }
135
+ // Clear the path so this does not trigger again.
136
+ walletInfo.dirPath = "" ;
137
+ walletInfo.path = "" ;
90
138
}
91
139
92
140
final config = {
93
- "name" : walletInfo. name,
94
- "datadir" : walletInfo. dirPath,
95
- "net" : network,
141
+ "name" : name,
142
+ "datadir" : dirPath,
143
+ "net" : walletInfo. network,
96
144
"unsyncedaddrs" : true ,
97
145
};
98
146
await libwallet! .loadWallet (jsonEncode (config));
@@ -127,12 +175,11 @@ class DecredWalletService extends WalletService<
127
175
128
176
await currentWallet.renameWalletFiles (newName);
129
177
130
- final newDirPath = await pathForWalletDir (name: newName, type: getType ());
131
178
final newWalletInfo = currentWalletInfo;
132
179
newWalletInfo.id = WalletBase .idFor (newName, getType ());
133
180
newWalletInfo.name = newName;
134
- newWalletInfo.dirPath = newDirPath ;
135
- newWalletInfo.network = network ;
181
+ newWalletInfo.dirPath = "" ;
182
+ newWalletInfo.path = "" ;
136
183
137
184
await walletInfoSource.put (currentWalletInfo.key, newWalletInfo);
138
185
}
@@ -141,18 +188,23 @@ class DecredWalletService extends WalletService<
141
188
Future <DecredWallet > restoreFromSeed (DecredRestoreWalletFromSeedCredentials credentials,
142
189
{bool ? isTestnet}) async {
143
190
await this .init ();
191
+ final network = isTestnet == true ? testnet : mainnet;
192
+ final dirPath = await pathForWalletDir (name: credentials.walletInfo! .name, type: getType ());
144
193
final config = {
145
194
"name" : credentials.walletInfo! .name,
146
- "datadir" : credentials.walletInfo ! . dirPath,
195
+ "datadir" : dirPath,
147
196
"pass" : credentials.password! ,
148
197
"mnemonic" : credentials.mnemonic,
149
- "net" : isTestnet == true ? testnet : mainnet ,
198
+ "net" : network ,
150
199
"unsyncedaddrs" : true ,
151
200
};
152
201
await libwallet! .createWallet (jsonEncode (config));
153
202
final di = DerivationInfo (
154
203
derivationPath: isTestnet == true ? seedRestorePathTestnet : seedRestorePath);
155
204
credentials.walletInfo! .derivationInfo = di;
205
+ credentials.walletInfo! .network = network;
206
+ credentials.walletInfo! .dirPath = "" ;
207
+ credentials.walletInfo! .path = "" ;
156
208
final wallet = DecredWallet (credentials.walletInfo! , credentials.password! ,
157
209
this .unspentCoinsInfoSource, libwallet! , closeLibwallet);
158
210
await wallet.init ();
@@ -165,17 +217,22 @@ class DecredWalletService extends WalletService<
165
217
Future <DecredWallet > restoreFromKeys (DecredRestoreWalletFromPubkeyCredentials credentials,
166
218
{bool ? isTestnet}) async {
167
219
await this .init ();
220
+ final network = isTestnet == true ? testnet : mainnet;
221
+ final dirPath = await pathForWalletDir (name: credentials.walletInfo! .name, type: getType ());
168
222
final config = {
169
223
"name" : credentials.walletInfo! .name,
170
- "datadir" : credentials.walletInfo ! . dirPath,
224
+ "datadir" : dirPath,
171
225
"pubkey" : credentials.pubkey,
172
- "net" : isTestnet == true ? testnet : mainnet ,
226
+ "net" : network ,
173
227
"unsyncedaddrs" : true ,
174
228
};
175
229
await libwallet! .createWatchOnlyWallet (jsonEncode (config));
176
230
final di = DerivationInfo (
177
231
derivationPath: isTestnet == true ? pubkeyRestorePathTestnet : pubkeyRestorePath);
178
232
credentials.walletInfo! .derivationInfo = di;
233
+ credentials.walletInfo! .network = network;
234
+ credentials.walletInfo! .dirPath = "" ;
235
+ credentials.walletInfo! .path = "" ;
179
236
final wallet = DecredWallet (credentials.walletInfo! , credentials.password! ,
180
237
this .unspentCoinsInfoSource, libwallet! , closeLibwallet);
181
238
await wallet.init ();
0 commit comments