feat: bip39 decred (#3348)
What changed, and why it matters
This commit adds BIP39 seed phrase support for Decred wallets in Cake Wallet. It changes how Decred wallets are created, restored, and saved, including storing an encrypted backup of the seed/passphrase and switching the underlying Decred library call used to build transactions. There is no explicit security bug in the diff, but the change touches sensitive wallet-key handling and transaction creation code, so it warrants careful review.
Review the new key-file backup implementation for Decred to ensure encryption and storage follow the same hardened path as other BIP39 wallets. Verify that the `createTransaction` FFI change in libdcrwallet still produces signed transactions correctly and does not introduce unsigned-tx exposure. Confirm the bumped libwallet version does not contain unrelated security changes. No immediate patch is indicated by the diff alone.
Security signals we found
New encrypted key backup path introduced for Decred (WalletKeysData/saveKeysFile)
Transaction construction FFI call renamed and request payload changed (createSignedTransaction -> createTransaction + sign: true)
Passphrase now accepted and persisted for Decred wallets
Mnemonic validation added but only checks word count for native 15-word Decred seeds, not checksum
Wallet rename now also renames .keys/.keys.backup files, reducing risk of orphaned key material
Evidence from the diff
The patch migrates Decred wallet handling from a native Decred-only seed model to a BIP39-compatible model. Key changes: (1) adds bip39 mnemonic generation/validation and accepts 12/15/24-word seeds; (2) introduces passphrase support and persists WalletKeysData(mnemonic, passphrase) via saveKeysFile; (3) renames key backup files during wallet rename; (4) updates isBIP39Wallet and related UI/derivation logic to include Decred; (5) changes the libdcrwallet FFI call from createSignedTransaction to createTransaction with a new "sign": true field in the request; and (6) bumps the libwallet dependency version in build scripts.
Changed components
cw_decred/lib/api/libdcrwallet.dartcw_decred/lib/wallet.dartcw_decred/lib/wallet_service.dartcw_decred/lib/wallet_creation_credentials.dartcw_decred/lib/mnemonic_validation.dartlib/decred/cw_decred.dartlib/di.dartlib/view_model/wallet_new_vm.dartlib/view_model/wallet_restore_view_model.dartscripts/android/build_decred.shscripts/ios/build_decred.shInspect captured patch +208 / −43
diff --git a/cw_decred/lib/api/libdcrwallet.dart b/cw_decred/lib/api/libdcrwallet.dart
index a6d1e10..f1de723 100644
--- a/cw_decred/lib/api/libdcrwallet.dart
+++ b/cw_decred/lib/api/libdcrwallet.dart
@@ -182,7 +182,7 @@ class Libwallet {
final cName = name.toCString();
final cSignReq = signReq.toCString();
res = executePayloadFn(
- fn: () => dcrwalletApi.createSignedTransaction(cName, cSignReq),
+ fn: () => dcrwalletApi.createTransaction(cName, cSignReq),
ptrsToFree: [cName, cSignReq],
);
break;
diff --git a/cw_decred/lib/mnemonic_validation.dart b/cw_decred/lib/mnemonic_validation.dart
new file mode 100644
index 0000000..96cb26f
--- /dev/null
+++ b/cw_decred/lib/mnemonic_validation.dart
@@ -0,0 +1,24 @@
+import "package:bip39/bip39.dart" as bip39;
+
+class DecredMnemonicIsIncorrectException implements Exception {
+ @override
+ String toString() =>
+ "Decred mnemonic has incorrect format. Mnemonic should be a valid BIP39 seed (12 or 24 words) or a native Decred seed (15 words).";
+}
+
+bool isValidDecredMnemonic(String mnemonic, {bool allowNativeSeed = true}) {
+ if (bip39.validateMnemonic(mnemonic)) {
+ return true;
+ }
+ if (!allowNativeSeed) {
+ return false;
+ }
+ final wordCount = mnemonic.trim().split(RegExp(r"\s+")).where((word) => word.isNotEmpty).length;
+ return wordCount == 15;
+}
+
+void validateDecredMnemonic(String mnemonic, {bool allowNativeSeed = true}) {
+ if (!isValidDecredMnemonic(mnemonic, allowNativeSeed: allowNativeSeed)) {
+ throw DecredMnemonicIsIncorrectException();
+ }
+}
diff --git a/cw_decred/lib/wallet.dart b/cw_decred/lib/wallet.dart
index 831390b..9bb7664 100644
--- a/cw_decred/lib/wallet.dart
+++ b/cw_decred/lib/wallet.dart
@@ -22,8 +22,10 @@ import 'package:cw_decred/wallet_service.dart';
import 'package:cw_decred/balance.dart';
import 'package:cw_decred/transaction_info.dart';
import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_keys_file.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/sync_status.dart';
@@ -36,9 +38,11 @@ part 'wallet.g.dart';
class DecredWallet = DecredWalletBase with _$DecredWallet;
abstract class DecredWalletBase
- extends WalletBase<DecredBalance, DecredTransactionHistory, DecredTransactionInfo> with Store {
+ extends WalletBase<DecredBalance, DecredTransactionHistory, DecredTransactionInfo>
+ with Store, WalletKeysFile {
DecredWalletBase(WalletInfo walletInfo, DerivationInfo derivationInfo, String password,
- Box<UnspentCoinsInfo> unspentCoinsInfo, Libwallet libwallet, Function() closeLibwallet)
+ Box<UnspentCoinsInfo> unspentCoinsInfo, Libwallet libwallet, Function() closeLibwallet,
+ {this.passphrase, required this.encryptionFileUtils})
: _password = password,
_libwallet = libwallet,
_closeLibwallet = closeLibwallet,
@@ -113,6 +117,17 @@ abstract class DecredWalletBase
return _seed;
}
+ @override
+ final String? passphrase;
+
+ final EncryptionFileUtils encryptionFileUtils;
+
+ @override
+ WalletKeysData get walletKeysData => WalletKeysData(
+ mnemonic: seed,
+ passphrase: passphrase,
+ );
+
@override
Object get keys => {};
@@ -402,11 +417,11 @@ abstract class DecredWalletBase
"feerate": creds.feeRate ?? defaultFeeRate,
"password": _password,
"sendall": sendAll,
+ "sign": true,
};
final res = await _libwallet.createSignedTransaction(walletInfo.name, jsonEncode(signReq));
final decoded = json.decode(res);
- final signedHex = decoded["signedhex"];
-
+ final signedHex = decoded["hex"];
final send = () async {
await _libwallet.sendRawTransaction(walletInfo.name, signedHex);
await updateBalance();
@@ -518,7 +533,12 @@ abstract class DecredWalletBase
String uniqueTxID(String id, int vout) => "$id:$vout";
@override
- Future<void> save() async {}
+ Future<void> save() async {
+ if (watchingOnly) {
+ return;
+ }
+ await saveKeysFile(_password, encryptionFileUtils);
+ }
@override
bool get hasRescan => walletBirthdayBlockHeight() != -1;
@@ -620,6 +640,13 @@ abstract class DecredWalletBase
}
await sourceDir.delete(recursive: true);
+
+ for (final suffix in const ['.keys', '.keys.backup']) {
+ final file = File(p.join(newDirPath, '${walletInfo.name}$suffix'));
+ if (file.existsSync()) {
+ await file.rename(p.join(newDirPath, '$newWalletName$suffix'));
+ }
+ }
}
@override
diff --git a/cw_decred/lib/wallet_creation_credentials.dart b/cw_decred/lib/wallet_creation_credentials.dart
index ca04514..80557bc 100644
--- a/cw_decred/lib/wallet_creation_credentials.dart
+++ b/cw_decred/lib/wallet_creation_credentials.dart
@@ -3,8 +3,15 @@ import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/hardware/hardware_account_data.dart';
class DecredNewWalletCredentials extends WalletCredentials {
- DecredNewWalletCredentials({required String name, WalletInfo? walletInfo})
- : super(name: name, walletInfo: walletInfo);
+ DecredNewWalletCredentials(
+ {required String name,
+ String? password,
+ String? passphrase,
+ this.mnemonic,
+ WalletInfo? walletInfo})
+ : super(name: name, password: password, passphrase: passphrase, walletInfo: walletInfo);
+
+ final String? mnemonic;
}
class DecredRestoreWalletFromSeedCredentials extends WalletCredentials {
@@ -12,8 +19,9 @@ class DecredRestoreWalletFromSeedCredentials extends WalletCredentials {
{required String name,
required String password,
required this.mnemonic,
+ String? passphrase,
WalletInfo? walletInfo})
- : super(name: name, password: password, walletInfo: walletInfo);
+ : super(name: name, password: password, passphrase: passphrase, walletInfo: walletInfo);
final String mnemonic;
}
diff --git a/cw_decred/lib/wallet_service.dart b/cw_decred/lib/wallet_service.dart
index 46f9807..a0385b0 100644
--- a/cw_decred/lib/wallet_service.dart
+++ b/cw_decred/lib/wallet_service.dart
@@ -1,6 +1,10 @@
import 'dart:convert';
import 'dart:io';
+import 'package:bip39/bip39.dart' as bip39;
+import 'package:cw_core/encryption_file_utils.dart';
+import 'package:cw_core/wallet_keys_file.dart';
import 'package:cw_decred/api/libdcrwallet.dart';
+import 'package:cw_decred/mnemonic_validation.dart';
import 'package:cw_decred/wallet_creation_credentials.dart';
import 'package:cw_decred/wallet.dart';
import 'package:cw_core/wallet_base.dart';
@@ -17,9 +21,10 @@ class DecredWalletService extends WalletService<
DecredRestoreWalletFromSeedCredentials,
DecredRestoreWalletFromPubkeyCredentials,
DecredRestoreWalletFromHardwareCredentials> {
- DecredWalletService(this.unspentCoinsInfoSource);
+ DecredWalletService(this.unspentCoinsInfoSource, this.isDirect);
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
+ final bool isDirect;
final seedRestorePath = "m/44'/42'";
static final seedRestorePathTestnet = "m/44'/1'";
static final pubkeyRestorePath = "m/44'/42'/0'";
@@ -55,6 +60,11 @@ class DecredWalletService extends WalletService<
@override
Future<DecredWallet> create(DecredNewWalletCredentials credentials, {bool? isTestnet}) async {
+ final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
+ final mnemonic = (credentials.mnemonic?.isNotEmpty == true)
+ ? credentials.mnemonic!
+ : bip39.generateMnemonic(strength: strength);
+ validateDecredMnemonic(mnemonic, allowNativeSeed: false);
await this.init();
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
final network = isTestnet == true ? testnet : mainnet;
@@ -62,12 +72,16 @@ class DecredWalletService extends WalletService<
"name": credentials.walletInfo!.name,
"datadir": dirPath,
"pass": credentials.password!,
+ "mnemonic": mnemonic,
+ "seedpass": credentials.passphrase ?? "",
+ "birthday": DateTime.now().millisecondsSinceEpoch ~/ 1000,
"net": network,
"unsyncedaddrs": true,
};
await libwallet!.createWallet(jsonEncode(config));
final di = await credentials.walletInfo!.getDerivationInfo();
di.derivationPath = isTestnet == true ? seedRestorePathTestnet : seedRestorePath;
+ di.derivationType = DerivationType.bip39;
await di.save();
credentials.walletInfo!.save();
credentials.walletInfo!.network = network;
@@ -78,9 +92,14 @@ class DecredWalletService extends WalletService<
// going forward.
credentials.walletInfo!.dirPath = "";
credentials.walletInfo!.path = "";
- final wallet = DecredWallet(credentials.walletInfo!, di, credentials.password!,
- this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
+ final wallet = _createWalletInstance(
+ credentials.walletInfo!,
+ di,
+ credentials.password!,
+ passphrase: credentials.passphrase,
+ );
await wallet.init();
+ await wallet.save();
return wallet;
}
@@ -151,9 +170,10 @@ class DecredWalletService extends WalletService<
"unsyncedaddrs": true,
};
await libwallet!.loadWallet(jsonEncode(config));
- final wallet = DecredWallet(
- walletInfo, di, password, this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
+ final passphrase = await _loadPassphrase(name, password);
+ final wallet = _createWalletInstance(walletInfo, di, password, passphrase: passphrase);
await wallet.init();
+ await _persistSeedDerivationType(wallet);
return wallet;
}
@@ -184,8 +204,7 @@ class DecredWalletService extends WalletService<
libwallet = await Libwallet.spawn();
libwallet!.initLibdcrwallet("", "err");
}
- final currentWallet = DecredWallet(
- currentWalletInfo, di, password, this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
+ final currentWallet = _createWalletInstance(currentWalletInfo, di, password);
await currentWallet.renameWalletFiles(newName);
@@ -201,6 +220,7 @@ class DecredWalletService extends WalletService<
@override
Future<DecredWallet> restoreFromSeed(DecredRestoreWalletFromSeedCredentials credentials,
{bool? isTestnet}) async {
+ validateDecredMnemonic(credentials.mnemonic);
await this.init();
final network = isTestnet == true ? testnet : mainnet;
final dirPath = await pathForWalletDir(name: credentials.walletInfo!.name, type: getType());
@@ -209,22 +229,81 @@ class DecredWalletService extends WalletService<
"datadir": dirPath,
"pass": credentials.password!,
"mnemonic": credentials.mnemonic,
+ "seedpass": credentials.passphrase ?? "",
"net": network,
"unsyncedaddrs": true,
};
await libwallet!.createWallet(jsonEncode(config));
final di = await credentials.walletInfo!.getDerivationInfo();
di.derivationPath = isTestnet == true ? seedRestorePathTestnet : seedRestorePath;
+ di.derivationType =
+ bip39.validateMnemonic(credentials.mnemonic) ? DerivationType.bip39 : DerivationType.def;
await di.save();
credentials.walletInfo!.network = network;
credentials.walletInfo!.dirPath = "";
credentials.walletInfo!.path = "";
- final wallet = DecredWallet(credentials.walletInfo!, di, credentials.password!,
- this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
+ final wallet = _createWalletInstance(
+ credentials.walletInfo!,
+ di,
+ credentials.password!,
+ passphrase: credentials.passphrase,
+ );
await wallet.init();
+ await wallet.save();
return wallet;
}
+ EncryptionFileUtils get _encryptionFileUtils => encryptionFileUtilsFor(isDirect);
+
+ DecredWallet _createWalletInstance(
+ WalletInfo walletInfo,
+ DerivationInfo di,
+ String password, {
+ String? passphrase,
+ }) {
+ return DecredWallet(
+ walletInfo,
+ di,
+ password,
+ unspentCoinsInfoSource,
+ libwallet!,
+ closeLibwallet,
+ passphrase: passphrase,
+ encryptionFileUtils: _encryptionFileUtils,
+ );
+ }
+
+ Future<String?> _loadPassphrase(String name, String password) async {
+ if (!await WalletKeysFile.hasKeysFile(name, getType())) {
+ return null;
+ }
+ try {
+ final keys = await WalletKeysFile.readKeysFile(
+ name,
+ getType(),
+ password,
+ _encryptionFileUtils,
+ );
+ return keys.passphrase;
+ } catch (_) {
+ return null;
+ }
+ }
+
+ Future<void> _persistSeedDerivationType(DecredWallet wallet) async {
+ final seed = wallet.seed;
+ if (seed == null || seed.isEmpty) {
+ return;
+ }
+ final expected =
+ bip39.validateMnemonic(seed) ? DerivationType.bip39 : DerivationType.def;
+ if (wallet.derivationInfo.derivationType == expected) {
+ return;
+ }
+ wallet.derivationInfo.derivationType = expected;
+ await wallet.derivationInfo.save();
+ }
+
// restoreFromKeys only supports restoring a watch only wallet from an account
// pubkey.
@override
@@ -247,8 +326,7 @@ class DecredWalletService extends WalletService<
credentials.walletInfo!.network = network;
credentials.walletInfo!.dirPath = "";
credentials.walletInfo!.path = "";
- final wallet = DecredWallet(credentials.walletInfo!, di, credentials.password!,
- this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
+ final wallet = _createWalletInstance(credentials.walletInfo!, di, credentials.password!);
await wallet.init();
return wallet;
}
diff --git a/cw_decred/pubspec.yaml b/cw_decred/pubspec.yaml
index 1b808e2..7a41bc0 100644
--- a/cw_decred/pubspec.yaml
+++ b/cw_decred/pubspec.yaml
@@ -12,6 +12,7 @@ environment:
dependencies:
flutter:
sdk: flutter
+ bip39: ^1.0.6
cw_core:
path: ../cw_core
diff --git a/lib/core/wallet_creation_service.dart b/lib/core/wallet_creation_service.dart
index c40b810..d627c1a 100644
--- a/lib/core/wallet_creation_service.dart
+++ b/lib/core/wallet_creation_service.dart
@@ -86,6 +86,7 @@ class WalletCreationService {
case WalletType.dogecoin:
case WalletType.nano:
case WalletType.zcash:
+ case WalletType.decred:
return true;
case WalletType.monero:
case WalletType.wownero:
@@ -93,7 +94,6 @@ class WalletCreationService {
case WalletType.haven:
case WalletType.banano:
case WalletType.zano:
- case WalletType.decred:
return false;
}
}
diff --git a/lib/decred/cw_decred.dart b/lib/decred/cw_decred.dart
index 18b955a..958a544 100644
--- a/lib/decred/cw_decred.dart
+++ b/lib/decred/cw_decred.dart
@@ -5,13 +5,26 @@ class CWDecred extends Decred {
@override
WalletCredentials createDecredNewWalletCredentials(
- {required String name, WalletInfo? walletInfo}) =>
- DecredNewWalletCredentials(name: name, walletInfo: walletInfo);
+ {required String name,
+ String? password,
+ String? passphrase,
+ String? mnemonic,
+ WalletInfo? walletInfo}) =>
+ DecredNewWalletCredentials(
+ name: name,
+ password: password,
+ passphrase: passphrase,
+ mnemonic: mnemonic,
+ walletInfo: walletInfo);
@override
WalletCredentials createDecredRestoreWalletFromSeedCredentials(
- {required String name, required String mnemonic, required String password}) =>
- DecredRestoreWalletFromSeedCredentials(name: name, mnemonic: mnemonic, password: password);
+ {required String name,
+ required String mnemonic,
+ required String password,
+ String? passphrase}) =>
+ DecredRestoreWalletFromSeedCredentials(
+ name: name, mnemonic: mnemonic, password: password, passphrase: passphrase);
@override
WalletCredentials createDecredRestoreWalletFromPubkeyCredentials(
@@ -19,8 +32,8 @@ class CWDecred extends Decred {
DecredRestoreWalletFromPubkeyCredentials(name: name, pubkey: pubkey, password: password);
@override
- WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource) =>
- DecredWalletService(unspentCoinSource);
+ WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) =>
+ DecredWalletService(unspentCoinSource, isDirect);
@override
List<TransactionPriority> getTransactionPriorities() => DecredTransactionPriority.all;
diff --git a/lib/di.dart b/lib/di.dart
index cd27c53..147f190 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -1343,7 +1343,8 @@ Future<void> setup({
case WalletType.zano:
return zano!.createZanoWalletService();
case WalletType.decred:
- return decred!.createDecredWalletService(_unspentCoinsInfoSource);
+ return decred!.createDecredWalletService(
+ _unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
case WalletType.haven:
return HavenWalletService();
case WalletType.zcash:
diff --git a/lib/reactions/wallet_utils.dart b/lib/reactions/wallet_utils.dart
index 2e94fa9..56bf208 100644
--- a/lib/reactions/wallet_utils.dart
+++ b/lib/reactions/wallet_utils.dart
@@ -17,11 +17,11 @@ bool isBIP39Wallet(WalletType walletType) {
case WalletType.monero:
case WalletType.dogecoin:
case WalletType.zcash:
+ case WalletType.decred:
return true;
case WalletType.wownero:
case WalletType.haven:
case WalletType.zano:
- case WalletType.decred:
case WalletType.none:
return false;
}
diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart
index 3e5ed20..1a0db8d 100644
--- a/lib/src/screens/restore/wallet_restore_page.dart
+++ b/lib/src/screens/restore/wallet_restore_page.dart
@@ -630,7 +630,7 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
}
if ((walletRestoreViewModel.type == WalletType.decred) &&
- seedWords.length != WalletRestoreViewModelBase.decredSeedMnemonicLength) {
+ ![12, 15, 24].contains(seedWords.length)) {
return false;
}
diff --git a/lib/view_model/advanced_privacy_settings_view_model.dart b/lib/view_model/advanced_privacy_settings_view_model.dart
index d594f08..39e9346 100644
--- a/lib/view_model/advanced_privacy_settings_view_model.dart
+++ b/lib/view_model/advanced_privacy_settings_view_model.dart
@@ -59,6 +59,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
case WalletType.solana:
case WalletType.tron:
case WalletType.zcash:
+ case WalletType.decred:
return true;
case WalletType.bitcoin:
@@ -74,7 +75,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
case WalletType.none:
case WalletType.haven:
case WalletType.zano:
- case WalletType.decred:
return false;
}
}
@@ -107,7 +107,8 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
WalletType.zano,
WalletType.dogecoin,
WalletType.zcash,
- ].contains(type);
+ WalletType.decred,
+ ].contains(type);
@computed
bool get addCustomNode => _addCustomNode;
diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart
index eeb2bd4..5a94bbd 100644
--- a/lib/view_model/wallet_creation_vm.dart
+++ b/lib/view_model/wallet_creation_vm.dart
@@ -179,6 +179,8 @@ abstract class WalletCreationVMBase with Store {
);
}
return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
+ case WalletType.decred:
+ return DerivationInfo(derivationType: DerivationType.bip39);
default:
return DerivationInfo(derivationType: DerivationType.unknown);
}
diff --git a/lib/view_model/wallet_groups_display_view_model.dart b/lib/view_model/wallet_groups_display_view_model.dart
index 5be1d29..fd8fdc2 100644
--- a/lib/view_model/wallet_groups_display_view_model.dart
+++ b/lib/view_model/wallet_groups_display_view_model.dart
@@ -131,6 +131,10 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
bool isNotMoneroBip39Wallet =
wallet.type == WalletType.monero && di.derivationType != DerivationType.bip39;
+ bool isNotDecredBip39Wallet = wallet.type == WalletType.decred &&
+ di.derivationType != DerivationType.bip39 &&
+ di.derivationType != DerivationType.unknown;
+
// Exclude if any of these conditions are true
shouldExcludeGroup = shouldExcludeGroup ||
isNonBIP39Wallet ||
@@ -138,7 +142,8 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
isElectrumDerivationType ||
isSameTypeAsSelectedWallet ||
isNonSeedWallet ||
- isNotMoneroBip39Wallet;
+ isNotMoneroBip39Wallet ||
+ isNotDecredBip39Wallet;
}
if (shouldExcludeGroup) continue;
diff --git a/lib/view_model/wallet_new_vm.dart b/lib/view_model/wallet_new_vm.dart
index f7fa7c7..e313ca0 100644
--- a/lib/view_model/wallet_new_vm.dart
+++ b/lib/view_model/wallet_new_vm.dart
@@ -149,7 +149,11 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
network: zcashNetwork,
);
case WalletType.decred:
- return decred!.createDecredNewWalletCredentials(name: name);
+ return decred!.createDecredNewWalletCredentials(
+ name: name,
+ password: walletPassword,
+ passphrase: passphrase,
+ mnemonic: newWalletArguments!.mnemonic);
case WalletType.none:
case WalletType.haven:
throw Exception('Unexpected type: ${type.toString()}');
diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart
index 467ad06..16767a6 100644
--- a/lib/view_model/wallet_restore_view_model.dart
+++ b/lib/view_model/wallet_restore_view_model.dart
@@ -216,6 +216,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
name: name,
mnemonic: seed,
password: password,
+ passphrase: passphrase,
);
case WalletType.zcash:
return zcash!.createZcashRestoreWalletFromSeedCredentials(
diff --git a/pubspec.lock b/pubspec.lock
index f0277a2..83f7563 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1871,8 +1871,8 @@ packages:
dependency: "direct overridden"
description:
path: "."
- ref: 40af7c48cf34211ba3cc9e87dd05ed1af8a429a2
- resolved-ref: 40af7c48cf34211ba3cc9e87dd05ed1af8a429a2
+ ref: "40af7c48cf34211ba3cc9e87dd05ed1af8a429a2"
+ resolved-ref: "40af7c48cf34211ba3cc9e87dd05ed1af8a429a2"
url: "https://github.com/cake-tech/ledger-usb-plus"
source: git
version: "1.0.8"
@@ -3161,8 +3161,8 @@ packages:
dependency: "direct overridden"
description:
path: "."
- ref: 6735c1bdf7f42c501d51c20564eb957c3a12b981
- resolved-ref: 6735c1bdf7f42c501d51c20564eb957c3a12b981
+ ref: "6735c1bdf7f42c501d51c20564eb957c3a12b981"
+ resolved-ref: "6735c1bdf7f42c501d51c20564eb957c3a12b981"
url: "https://github.com/cake-tech/universal_ble.git"
source: git
version: "2.0.0"
diff --git a/scripts/android/build_decred.sh b/scripts/android/build_decred.sh
index 1ade0f8..cabf11f 100755
--- a/scripts/android/build_decred.sh
+++ b/scripts/android/build_decred.sh
@@ -7,7 +7,7 @@ cd "$(dirname "$0")"
CW_DECRED_DIR=$(realpath ../..)/cw_decred
LIBWALLET_PATH="${PWD}/decred/libwallet"
LIBWALLET_URL="https://github.com/decred/libwallet.git"
-LIBWALLET_VERSION="05f8d7374999400fe4d525eb365c39b77d307b14"
+LIBWALLET_VERSION="ecc4a5fb9594368777848de42d7e072d62406507"
if [[ -e $LIBWALLET_PATH ]]; then
rm -fr $LIBWALLET_PATH || true
diff --git a/scripts/ios/build_decred.sh b/scripts/ios/build_decred.sh
index 37384f4..5e92cc6 100755
--- a/scripts/ios/build_decred.sh
+++ b/scripts/ios/build_decred.sh
@@ -3,7 +3,7 @@ set -e
. ./config.sh
LIBWALLET_PATH="${EXTERNAL_IOS_SOURCE_DIR}/libwallet"
LIBWALLET_URL="https://github.com/decred/libwallet.git"
-LIBWALLET_VERSION="05f8d7374999400fe4d525eb365c39b77d307b14"
+LIBWALLET_VERSION="ecc4a5fb9594368777848de42d7e072d62406507"
if [[ -e $LIBWALLET_PATH ]]; then
rm -fr $LIBWALLET_PATH
diff --git a/tool/configure.dart b/tool/configure.dart
index b0a8849..e3f5f38 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -1259,12 +1259,12 @@ import 'package:cw_decred/mnemonic.dart';
abstract class Decred {
WalletCredentials createDecredNewWalletCredentials(
- {required String name, WalletInfo? walletInfo});
+ {required String name, String? password, String? passphrase, String? mnemonic, WalletInfo? walletInfo});
WalletCredentials createDecredRestoreWalletFromSeedCredentials(
- {required String name, required String mnemonic, required String password});
+ {required String name, required String mnemonic, required String password, String? passphrase});
WalletCredentials createDecredRestoreWalletFromPubkeyCredentials(
{required String name, required String pubkey, required String password});
- WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource);
+ WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
List<TransactionPriority> getTransactionPriorities();
TransactionPriority getDecredTransactionPriorityMedium();
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.