Bip39 passphrase support (#1412)

* save

* passphrase working

* fix for when loading wallets + translation update

* minor fix

* Fix Nano

* minor fix [skip ci]

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
Matthew Fosse 2024-04-29 09:57:46 -07:00 committed by GitHub
parent d38ef8a9a8
commit 5ecc1a1db6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 174 additions and 63 deletions

View file

@ -54,7 +54,19 @@ Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = {
), ),
DerivationInfo( DerivationInfo(
derivationType: DerivationType.bip39, derivationType: DerivationType.bip39,
derivationPath: "m/44'|49'|84'/0'/0'", derivationPath: "m/44'/0'/0'",
description: "Samourai Deposit",
scriptType: "p2wpkh",
),
DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/49'/0'/0'",
description: "Samourai Deposit",
scriptType: "p2wpkh",
),
DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/84'/0'/0'",
description: "Samourai Deposit", description: "Samourai Deposit",
scriptType: "p2wpkh", scriptType: "p2wpkh",
), ),

View file

@ -31,8 +31,10 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
ElectrumBalance? initialBalance, ElectrumBalance? initialBalance,
Map<String, int>? initialRegularAddressIndex, Map<String, int>? initialRegularAddressIndex,
Map<String, int>? initialChangeAddressIndex, Map<String, int>? initialChangeAddressIndex,
String? passphrase,
}) : super( }) : super(
mnemonic: mnemonic, mnemonic: mnemonic,
passphrase: passphrase,
password: password, password: password,
walletInfo: walletInfo, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo, unspentCoinsInfo: unspentCoinsInfo,
@ -70,6 +72,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password, required String password,
required WalletInfo walletInfo, required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo, required Box<UnspentCoinsInfo> unspentCoinsInfo,
String? passphrase,
String? addressPageType, String? addressPageType,
BasedUtxoNetwork? network, BasedUtxoNetwork? network,
List<BitcoinAddressRecord>? initialAddresses, List<BitcoinAddressRecord>? initialAddresses,
@ -81,7 +84,10 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
switch (walletInfo.derivationInfo?.derivationType) { switch (walletInfo.derivationInfo?.derivationType) {
case DerivationType.bip39: case DerivationType.bip39:
seedBytes = await bip39.mnemonicToSeed(mnemonic); seedBytes = await bip39.mnemonicToSeed(
mnemonic,
passphrase: passphrase ?? "",
);
break; break;
case DerivationType.electrum: case DerivationType.electrum:
default: default:
@ -90,6 +96,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
} }
return BitcoinWallet( return BitcoinWallet(
mnemonic: mnemonic, mnemonic: mnemonic,
passphrase: passphrase ?? "",
password: password, password: password,
walletInfo: walletInfo, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo, unspentCoinsInfo: unspentCoinsInfo,
@ -130,13 +137,17 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
break; break;
case DerivationType.bip39: case DerivationType.bip39:
default: default:
seedBytes = await bip39.mnemonicToSeed(snp.mnemonic); seedBytes = await bip39.mnemonicToSeed(
snp.mnemonic,
passphrase: snp.passphrase ?? '',
);
break; break;
} }
return BitcoinWallet( return BitcoinWallet(
mnemonic: snp.mnemonic, mnemonic: snp.mnemonic,
password: password, password: password,
passphrase: snp.passphrase,
walletInfo: walletInfo, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo, unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: snp.addresses, initialAddresses: snp.addresses,

View file

@ -21,9 +21,11 @@ class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
WalletInfo? walletInfo, WalletInfo? walletInfo,
required DerivationType derivationType, required DerivationType derivationType,
required String derivationPath, required String derivationPath,
String? passphrase,
}) : super( }) : super(
name: name, name: name,
password: password, password: password,
passphrase: passphrase,
walletInfo: walletInfo, walletInfo: walletInfo,
derivationInfo: DerivationInfo( derivationInfo: DerivationInfo(
derivationType: derivationType, derivationType: derivationType,

View file

@ -3,7 +3,6 @@ import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart'; import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_service.dart';
@ -33,6 +32,7 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
final wallet = await BitcoinWalletBase.create( final wallet = await BitcoinWalletBase.create(
mnemonic: await generateElectrumMnemonic(), mnemonic: await generateElectrumMnemonic(),
password: credentials.password!, password: credentials.password!,
passphrase: credentials.passphrase,
walletInfo: credentials.walletInfo!, walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource, unspentCoinsInfo: unspentCoinsInfoSource,
network: network, network: network,
@ -116,6 +116,7 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
final wallet = await BitcoinWalletBase.create( final wallet = await BitcoinWalletBase.create(
password: credentials.password!, password: credentials.password!,
passphrase: credentials.passphrase,
mnemonic: credentials.mnemonic, mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!, walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource, unspentCoinsInfo: unspentCoinsInfoSource,
@ -125,8 +126,4 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
await wallet.init(); await wallet.init();
return wallet; return wallet;
} }
static Future<dynamic> getInfoFromSeed({required String seed, required Node node}) async {
throw UnimplementedError();
}
} }

View file

@ -55,6 +55,7 @@ abstract class ElectrumWalletBase
required this.networkType, required this.networkType,
required this.mnemonic, required this.mnemonic,
required Uint8List seedBytes, required Uint8List seedBytes,
this.passphrase,
List<BitcoinAddressRecord>? initialAddresses, List<BitcoinAddressRecord>? initialAddresses,
ElectrumClient? electrumClient, ElectrumClient? electrumClient,
ElectrumBalance? initialBalance, ElectrumBalance? initialBalance,
@ -93,6 +94,7 @@ abstract class ElectrumWalletBase
final bitcoin.HDWallet hd; final bitcoin.HDWallet hd;
final String mnemonic; final String mnemonic;
final String? passphrase;
@override @override
@observable @observable
@ -618,6 +620,7 @@ abstract class ElectrumWalletBase
String toJSON() => json.encode({ String toJSON() => json.encode({
'mnemonic': mnemonic, 'mnemonic': mnemonic,
'passphrase': passphrase ?? '',
'account_index': walletAddresses.currentReceiveAddressIndexByType, 'account_index': walletAddresses.currentReceiveAddressIndexByType,
'change_address_index': walletAddresses.currentChangeAddressIndexByType, 'change_address_index': walletAddresses.currentChangeAddressIndexByType,
'addresses': walletAddresses.allAddresses.map((addr) => addr.toJSON()).toList(), 'addresses': walletAddresses.allAddresses.map((addr) => addr.toJSON()).toList(),

View file

@ -18,6 +18,7 @@ class ElectrumWalletSnapshot {
required this.regularAddressIndex, required this.regularAddressIndex,
required this.changeAddressIndex, required this.changeAddressIndex,
required this.addressPageType, required this.addressPageType,
this.passphrase,
this.derivationType, this.derivationType,
this.derivationPath, this.derivationPath,
}); });
@ -32,6 +33,7 @@ class ElectrumWalletSnapshot {
ElectrumBalance balance; ElectrumBalance balance;
Map<String, int> regularAddressIndex; Map<String, int> regularAddressIndex;
Map<String, int> changeAddressIndex; Map<String, int> changeAddressIndex;
String? passphrase;
DerivationType? derivationType; DerivationType? derivationType;
String? derivationPath; String? derivationPath;
@ -42,6 +44,7 @@ class ElectrumWalletSnapshot {
final data = json.decode(jsonSource) as Map; final data = json.decode(jsonSource) as Map;
final addressesTmp = data['addresses'] as List? ?? <Object>[]; final addressesTmp = data['addresses'] as List? ?? <Object>[];
final mnemonic = data['mnemonic'] as String; final mnemonic = data['mnemonic'] as String;
final passphrase = data['passphrase'] as String? ?? '';
final addresses = addressesTmp final addresses = addressesTmp
.whereType<String>() .whereType<String>()
.map((addr) => BitcoinAddressRecord.fromJSON(addr, network)) .map((addr) => BitcoinAddressRecord.fromJSON(addr, network))
@ -74,6 +77,7 @@ class ElectrumWalletSnapshot {
name: name, name: name,
type: type, type: type,
password: password, password: password,
passphrase: passphrase,
mnemonic: mnemonic, mnemonic: mnemonic,
addresses: addresses, addresses: addresses,
balance: balance, balance: balance,

View file

@ -7,6 +7,7 @@ abstract class WalletCredentials {
this.seedPhraseLength, this.seedPhraseLength,
this.walletInfo, this.walletInfo,
this.password, this.password,
this.passphrase,
this.derivationInfo, this.derivationInfo,
}) { }) {
if (this.walletInfo != null && derivationInfo != null) { if (this.walletInfo != null && derivationInfo != null) {
@ -18,6 +19,7 @@ abstract class WalletCredentials {
final int? height; final int? height;
int? seedPhraseLength; int? seedPhraseLength;
String? password; String? password;
String? passphrase;
WalletInfo? walletInfo; WalletInfo? walletInfo;
DerivationInfo? derivationInfo; DerivationInfo? derivationInfo;
} }

View file

@ -19,6 +19,7 @@ enum DerivationType {
@HiveField(4) @HiveField(4)
electrum, electrum,
} }
@HiveType(typeId: DerivationInfo.typeId) @HiveType(typeId: DerivationInfo.typeId)
class DerivationInfo extends HiveObject { class DerivationInfo extends HiveObject {
DerivationInfo({ DerivationInfo({
@ -33,11 +34,10 @@ class DerivationInfo extends HiveObject {
static const typeId = DERIVATION_INFO_TYPE_ID; static const typeId = DERIVATION_INFO_TYPE_ID;
@HiveField(0, defaultValue: '')
@HiveField(0)
String address; String address;
@HiveField(1) @HiveField(1, defaultValue: '')
String balance; String balance;
@HiveField(2) @HiveField(2)
@ -90,19 +90,20 @@ class WalletInfo extends HiveObject {
DerivationInfo? derivationInfo, DerivationInfo? derivationInfo,
}) { }) {
return WalletInfo( return WalletInfo(
id, id,
name, name,
type, type,
isRecovery, isRecovery,
restoreHeight, restoreHeight,
date.millisecondsSinceEpoch, date.millisecondsSinceEpoch,
dirPath, dirPath,
path, path,
address, address,
yatEid, yatEid,
yatLastUsedAddressRaw, yatLastUsedAddressRaw,
showIntroCakePayCard, showIntroCakePayCard,
derivationInfo); derivationInfo,
);
} }
static const typeId = WALLET_INFO_TYPE_ID; static const typeId = WALLET_INFO_TYPE_ID;
@ -154,10 +155,10 @@ class WalletInfo extends HiveObject {
List<String>? usedAddresses; List<String>? usedAddresses;
@HiveField(16) @HiveField(16)
DerivationType? derivationType;// no longer used DerivationType? derivationType; // no longer used
@HiveField(17) @HiveField(17)
String? derivationPath;// no longer used String? derivationPath; // no longer used
@HiveField(18) @HiveField(18)
String? addressPageType; String? addressPageType;

View file

@ -7,13 +7,16 @@ class CWBitcoin extends Bitcoin {
required String password, required String password,
required DerivationType derivationType, required DerivationType derivationType,
required String derivationPath, required String derivationPath,
String? passphrase,
}) => }) =>
BitcoinRestoreWalletFromSeedCredentials( BitcoinRestoreWalletFromSeedCredentials(
name: name, name: name,
mnemonic: mnemonic, mnemonic: mnemonic,
password: password, password: password,
derivationType: derivationType, derivationType: derivationType,
derivationPath: derivationPath); derivationPath: derivationPath,
passphrase: passphrase,
);
@override @override
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials( WalletCredentials createBitcoinRestoreWalletFromWIFCredentials(
@ -277,8 +280,11 @@ class CWBitcoin extends Bitcoin {
} }
@override @override
Future<List<DerivationInfo>> getDerivationsFromMnemonic( Future<List<DerivationInfo>> getDerivationsFromMnemonic({
{required String mnemonic, required Node node}) async { required String mnemonic,
required Node node,
String? passphrase,
}) async {
List<DerivationInfo> list = []; List<DerivationInfo> list = [];
final electrumClient = ElectrumClient(); final electrumClient = ElectrumClient();
@ -303,7 +309,7 @@ class CWBitcoin extends Bitcoin {
if (dType == DerivationType.electrum) { if (dType == DerivationType.electrum) {
seedBytes = await mnemonicToSeedBytes(mnemonic); seedBytes = await mnemonicToSeedBytes(mnemonic);
} else if (dType == DerivationType.bip39) { } else if (dType == DerivationType.bip39) {
seedBytes = bip39.mnemonicToSeed(mnemonic); seedBytes = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
} }
for (DerivationInfo dInfo in bitcoin_derivations[dType]!) { for (DerivationInfo dInfo in bitcoin_derivations[dType]!) {

View file

@ -20,6 +20,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
{Key? key, {Key? key,
required this.displayLanguageSelector, required this.displayLanguageSelector,
required this.displayBlockHeightSelector, required this.displayBlockHeightSelector,
required this.displayPassphrase,
required this.type, required this.type,
required this.seedTypeViewModel, required this.seedTypeViewModel,
this.blockHeightFocusNode, this.blockHeightFocusNode,
@ -31,6 +32,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
final WalletType type; final WalletType type;
final bool displayLanguageSelector; final bool displayLanguageSelector;
final bool displayBlockHeightSelector; final bool displayBlockHeightSelector;
final bool displayPassphrase;
final SeedTypeViewModel seedTypeViewModel; final SeedTypeViewModel seedTypeViewModel;
final FocusNode? blockHeightFocusNode; final FocusNode? blockHeightFocusNode;
final Function(bool)? onHeightOrDateEntered; final Function(bool)? onHeightOrDateEntered;
@ -48,6 +50,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
formKey = GlobalKey<FormState>(), formKey = GlobalKey<FormState>(),
languageController = TextEditingController(), languageController = TextEditingController(),
nameTextEditingController = TextEditingController(), nameTextEditingController = TextEditingController(),
passphraseController = TextEditingController(),
seedTypeController = TextEditingController(); seedTypeController = TextEditingController();
final GlobalKey<SeedWidgetState> seedWidgetStateKey; final GlobalKey<SeedWidgetState> seedWidgetStateKey;
@ -55,6 +58,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
final TextEditingController languageController; final TextEditingController languageController;
final TextEditingController nameTextEditingController; final TextEditingController nameTextEditingController;
final TextEditingController seedTypeController; final TextEditingController seedTypeController;
final TextEditingController passphraseController;
final GlobalKey<FormState> formKey; final GlobalKey<FormState> formKey;
late ReactionDisposer moneroSeedTypeReaction; late ReactionDisposer moneroSeedTypeReaction;
String language; String language;
@ -194,6 +198,13 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
key: blockchainHeightKey, key: blockchainHeightKey,
onHeightOrDateEntered: widget.onHeightOrDateEntered, onHeightOrDateEntered: widget.onHeightOrDateEntered,
hasDatePicker: widget.type == WalletType.monero), hasDatePicker: widget.type == WalletType.monero),
if (widget.displayPassphrase) ...[
const SizedBox(height: 10),
BaseTextFormField(
hintText: S.current.passphrase,
controller: passphraseController,
),
]
])); ]));
} }

View file

@ -38,6 +38,7 @@ class WalletRestorePage extends BasePage {
displayBlockHeightSelector: displayBlockHeightSelector:
walletRestoreViewModel.hasBlockchainHeightLanguageSelector, walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector, displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
displayPassphrase: walletRestoreViewModel.hasPassphrase,
type: walletRestoreViewModel.type, type: walletRestoreViewModel.type,
key: walletRestoreFromSeedFormKey, key: walletRestoreFromSeedFormKey,
blockHeightFocusNode: _blockHeightFocusNode, blockHeightFocusNode: _blockHeightFocusNode,
@ -296,6 +297,11 @@ class WalletRestorePage extends BasePage {
-1; -1;
} }
if (walletRestoreViewModel.hasPassphrase) {
credentials['passphrase'] =
walletRestoreFromSeedFormKey.currentState!.passphraseController.text;
}
credentials['name'] = credentials['name'] =
walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text; walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
} else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) { } else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
@ -367,18 +373,16 @@ class WalletRestorePage extends BasePage {
} }
} }
// dInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation,
// arguments: derivations) as DerivationInfo?;
if (derivationsWithHistory > 1) { if (derivationsWithHistory > 1) {
dInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation, dInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation,
arguments: derivations) as DerivationInfo?; arguments: derivations) as DerivationInfo?;
} else if (derivationsWithHistory == 1) { } else if (derivationsWithHistory == 1) {
dInfo = derivations[derivationWithHistoryIndex]; dInfo = derivations[derivationWithHistoryIndex];
} else if (derivationsWithHistory == 0 && derivations.isNotEmpty) { } else {
dInfo = DerivationInfo( dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
derivationType: DerivationType.bip39,
derivationPath: "m/84'/0'/0'",
description: "Standard BIP84 native segwit",
scriptType: "p2wpkh",
);
} }
if (dInfo == null) { if (dInfo == null) {

View file

@ -343,7 +343,9 @@ class WalletListBodyState extends State<WalletListBody> {
}); });
} }
} catch (e) { } catch (e) {
changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString())); if (this.mounted) {
changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString()));
}
} }
}, },
conditionToDetermineIfToUse2FA: conditionToDetermineIfToUse2FA:

View file

@ -53,9 +53,11 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
WalletCredentials getCredentialsFromRestoredWallet( WalletCredentials getCredentialsFromRestoredWallet(
dynamic options, RestoredWallet restoreWallet) { dynamic options, RestoredWallet restoreWallet) {
final password = generateWalletPassword(); final password = generateWalletPassword();
String? passphrase;
DerivationInfo? derivationInfo; DerivationInfo? derivationInfo;
if (options != null) { if (options != null) {
derivationInfo = options["derivationInfo"] as DerivationInfo?; derivationInfo = options["derivationInfo"] as DerivationInfo?;
passphrase = options["passphrase"] as String?;
} }
derivationInfo ??= getDefaultDerivation(); derivationInfo ??= getDefaultDerivation();
@ -91,31 +93,37 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
switch (restoreWallet.type) { switch (restoreWallet.type) {
case WalletType.monero: case WalletType.monero:
return monero!.createMoneroRestoreWalletFromSeedCredentials( return monero!.createMoneroRestoreWalletFromSeedCredentials(
name: name, name: name,
height: restoreWallet.height ?? 0, height: restoreWallet.height ?? 0,
mnemonic: restoreWallet.mnemonicSeed ?? '', mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password); password: password,
);
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials( return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name, name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '', mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password, password: password,
passphrase: passphrase,
derivationType: derivationInfo!.derivationType!, derivationType: derivationInfo!.derivationType!,
derivationPath: derivationInfo.derivationPath!, derivationPath: derivationInfo.derivationPath!,
); );
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
return bitcoinCash!.createBitcoinCashRestoreWalletFromSeedCredentials( return bitcoinCash!.createBitcoinCashRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password); name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
);
case WalletType.ethereum: case WalletType.ethereum:
return ethereum!.createEthereumRestoreWalletFromSeedCredentials( return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password); name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
case WalletType.nano: case WalletType.nano:
return nano!.createNanoRestoreWalletFromSeedCredentials( return nano!.createNanoRestoreWalletFromSeedCredentials(
name: name, name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '', mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password, password: password,
derivationType: derivationInfo!.derivationType!); derivationType: derivationInfo!.derivationType!,
);
case WalletType.polygon: case WalletType.polygon:
return polygon!.createPolygonRestoreWalletFromSeedCredentials( return polygon!.createPolygonRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password); name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);

View file

@ -106,6 +106,25 @@ abstract class WalletCreationVMBase with Store {
} }
} }
DerivationInfo? getCommonRestoreDerivation() {
switch (this.type) {
case WalletType.nano:
return DerivationInfo(
derivationType: DerivationType.nano,
);
case WalletType.bitcoin:
case WalletType.litecoin:
return DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/84'/0'/0'/0",
description: "Standard BIP84 native segwit",
scriptType: "p2wpkh",
);
default:
return null;
}
}
WalletCredentials getCredentials(dynamic options) => throw UnimplementedError(); WalletCredentials getCredentials(dynamic options) => throw UnimplementedError();
Future<WalletBase> process(WalletCredentials credentials) => throw UnimplementedError(); Future<WalletBase> process(WalletCredentials credentials) => throw UnimplementedError();

View file

@ -67,6 +67,8 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
final bool hasBlockchainHeightLanguageSelector; final bool hasBlockchainHeightLanguageSelector;
final bool hasRestoreFromPrivateKey; final bool hasRestoreFromPrivateKey;
bool get hasPassphrase => [WalletType.bitcoin].contains(type);
@observable @observable
WalletRestoreMode mode; WalletRestoreMode mode;
@ -76,6 +78,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
@override @override
WalletCredentials getCredentials(dynamic options) { WalletCredentials getCredentials(dynamic options) {
final password = generateWalletPassword(); final password = generateWalletPassword();
String? passphrase = options['passphrase'] as String?;
final height = options['height'] as int? ?? 0; final height = options['height'] as int? ?? 0;
name = options['name'] as String; name = options['name'] as String;
DerivationInfo? derivationInfo = options["derivationInfo"] as DerivationInfo?; DerivationInfo? derivationInfo = options["derivationInfo"] as DerivationInfo?;
@ -87,18 +90,12 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
return monero!.createMoneroRestoreWalletFromSeedCredentials( return monero!.createMoneroRestoreWalletFromSeedCredentials(
name: name, height: height, mnemonic: seed, password: password); name: name, height: height, mnemonic: seed, password: password);
case WalletType.bitcoin: case WalletType.bitcoin:
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
derivationType: derivationInfo!.derivationType!,
derivationPath: derivationInfo.derivationPath!,
);
case WalletType.litecoin: case WalletType.litecoin:
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials( return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name, name: name,
mnemonic: seed, mnemonic: seed,
password: password, password: password,
passphrase: passphrase,
derivationType: derivationInfo!.derivationType!, derivationType: derivationInfo!.derivationType!,
derivationPath: derivationInfo.derivationPath!, derivationPath: derivationInfo.derivationPath!,
); );
@ -206,7 +203,12 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
String? mnemonic = credentials['seed'] as String?; String? mnemonic = credentials['seed'] as String?;
return bitcoin!.getDerivationsFromMnemonic(mnemonic: mnemonic!, node: node); String? passphrase = credentials['passphrase'] as String?;
return bitcoin!.getDerivationsFromMnemonic(
mnemonic: mnemonic!,
node: node,
passphrase: passphrase,
);
case WalletType.nano: case WalletType.nano:
String? mnemonic = credentials['seed'] as String?; String? mnemonic = credentials['seed'] as String?;
String? seedKey = credentials['private_key'] as String?; String? seedKey = credentials['private_key'] as String?;

View file

@ -411,6 +411,7 @@
"outputs": "المخرجات", "outputs": "المخرجات",
"overwrite_amount": "تغير المبلغ", "overwrite_amount": "تغير المبلغ",
"pairingInvalidEvent": "ﺢﻟﺎﺻ ﺮﻴﻏ ﺙﺪﺣ ﻥﺍﺮﻗﺇ", "pairingInvalidEvent": "ﺢﻟﺎﺻ ﺮﻴﻏ ﺙﺪﺣ ﻥﺍﺮﻗﺇ",
"passphrase": "عبارة الممر (اختياري)",
"password": "كلمة المرور", "password": "كلمة المرور",
"paste": "لصق", "paste": "لصق",
"pause_wallet_creation": ".ﺎﻴًﻟﺎﺣ ﺎﺘًﻗﺆﻣ ﺔﻔﻗﻮﺘﻣ Haven Wallet ءﺎﺸﻧﺇ ﻰﻠﻋ ﺓﺭﺪﻘﻟﺍ", "pause_wallet_creation": ".ﺎﻴًﻟﺎﺣ ﺎﺘًﻗﺆﻣ ﺔﻔﻗﻮﺘﻣ Haven Wallet ءﺎﺸﻧﺇ ﻰﻠﻋ ﺓﺭﺪﻘﻟﺍ",

View file

@ -411,6 +411,7 @@
"outputs": "Изходи", "outputs": "Изходи",
"overwrite_amount": "Промени сума", "overwrite_amount": "Промени сума",
"pairingInvalidEvent": "Невалидно събитие при сдвояване", "pairingInvalidEvent": "Невалидно събитие при сдвояване",
"passphrase": "Passphrase (по избор)",
"password": "Парола", "password": "Парола",
"paste": "Поставяне", "paste": "Поставяне",
"pause_wallet_creation": "Възможността за създаване на Haven Wallet в момента е на пауза.", "pause_wallet_creation": "Възможността за създаване на Haven Wallet в момента е на пауза.",

View file

@ -411,6 +411,7 @@
"outputs": "Výstupy", "outputs": "Výstupy",
"overwrite_amount": "Přepsat částku", "overwrite_amount": "Přepsat částku",
"pairingInvalidEvent": "Neplatná událost párování", "pairingInvalidEvent": "Neplatná událost párování",
"passphrase": "Passphrase (volitelné)",
"password": "Heslo", "password": "Heslo",
"paste": "Vložit", "paste": "Vložit",
"pause_wallet_creation": "Možnost vytvářet Haven Wallet je momentálně pozastavena.", "pause_wallet_creation": "Možnost vytvářet Haven Wallet je momentálně pozastavena.",

View file

@ -411,6 +411,7 @@
"outputs": "Ausgänge", "outputs": "Ausgänge",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Paarung ungültiges Ereignis", "pairingInvalidEvent": "Paarung ungültiges Ereignis",
"passphrase": "Passphrase (optional)",
"password": "Passwort", "password": "Passwort",
"paste": "Einfügen", "paste": "Einfügen",
"pause_wallet_creation": "Die Möglichkeit, Haven Wallet zu erstellen, ist derzeit pausiert.", "pause_wallet_creation": "Die Möglichkeit, Haven Wallet zu erstellen, ist derzeit pausiert.",
@ -425,8 +426,8 @@
"placeholder_transactions": "Ihre Transaktionen werden hier angezeigt", "placeholder_transactions": "Ihre Transaktionen werden hier angezeigt",
"please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist", "please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist",
"please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.", "please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.",
"Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.",
"please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.", "please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.",
"Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.",
"please_select": "Bitte auswählen:", "please_select": "Bitte auswählen:",
"please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.", "please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.",
"please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden", "please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden",
@ -822,4 +823,4 @@
"you_will_get": "Konvertieren zu", "you_will_get": "Konvertieren zu",
"you_will_send": "Konvertieren von", "you_will_send": "Konvertieren von",
"yy": "YY" "yy": "YY"
} }

View file

@ -411,6 +411,7 @@
"outputs": "Outputs", "outputs": "Outputs",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Pairing Invalid Event", "pairingInvalidEvent": "Pairing Invalid Event",
"passphrase": "Passphrase (Optional)",
"password": "Password", "password": "Password",
"paste": "Paste", "paste": "Paste",
"pause_wallet_creation": "Ability to create Haven Wallet is currently paused.", "pause_wallet_creation": "Ability to create Haven Wallet is currently paused.",

View file

@ -411,6 +411,7 @@
"outputs": "Salidas", "outputs": "Salidas",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Evento de emparejamiento no válido", "pairingInvalidEvent": "Evento de emparejamiento no válido",
"passphrase": "Passfrase (opcional)",
"password": "Contraseña", "password": "Contraseña",
"paste": "Pegar", "paste": "Pegar",
"pause_wallet_creation": "La capacidad para crear Haven Wallet está actualmente pausada.", "pause_wallet_creation": "La capacidad para crear Haven Wallet está actualmente pausada.",

View file

@ -411,6 +411,7 @@
"outputs": "Les sorties", "outputs": "Les sorties",
"overwrite_amount": "Remplacer le montant", "overwrite_amount": "Remplacer le montant",
"pairingInvalidEvent": "Événement de couplage non valide", "pairingInvalidEvent": "Événement de couplage non valide",
"passphrase": "Phrase de passe (facultative)",
"password": "Mot de passe", "password": "Mot de passe",
"paste": "Coller", "paste": "Coller",
"pause_wallet_creation": "La possibilité de créer Haven Wallet est actuellement suspendue.", "pause_wallet_creation": "La possibilité de créer Haven Wallet est actuellement suspendue.",

View file

@ -413,6 +413,7 @@
"outputs": "Abubuwan fashewa", "outputs": "Abubuwan fashewa",
"overwrite_amount": "Rubuta adadin", "overwrite_amount": "Rubuta adadin",
"pairingInvalidEvent": "Haɗa Lamarin mara inganci", "pairingInvalidEvent": "Haɗa Lamarin mara inganci",
"passphrase": "Passphrase (Zabi)",
"password": "Kalmar wucewa", "password": "Kalmar wucewa",
"paste": "Manna", "paste": "Manna",
"pause_wallet_creation": "A halin yanzu an dakatar da ikon ƙirƙirar Haven Wallet.", "pause_wallet_creation": "A halin yanzu an dakatar da ikon ƙirƙirar Haven Wallet.",

View file

@ -411,6 +411,7 @@
"outputs": "आउटपुट", "outputs": "आउटपुट",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "अमान्य ईवेंट युग्मित करना", "pairingInvalidEvent": "अमान्य ईवेंट युग्मित करना",
"passphrase": "पासफ्रेज़ (वैकल्पिक)",
"password": "पारण शब्द", "password": "पारण शब्द",
"paste": "पेस्ट करें", "paste": "पेस्ट करें",
"pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।", "pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।",

View file

@ -411,6 +411,7 @@
"outputs": "Izlazi", "outputs": "Izlazi",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Nevažeći događaj uparivanja", "pairingInvalidEvent": "Nevažeći događaj uparivanja",
"passphrase": "Prolaznica (neobavezno)",
"password": "Lozinka", "password": "Lozinka",
"paste": "Zalijepi", "paste": "Zalijepi",
"pause_wallet_creation": "Mogućnost stvaranja novčanika Haven trenutno je pauzirana.", "pause_wallet_creation": "Mogućnost stvaranja novčanika Haven trenutno je pauzirana.",

View file

@ -413,6 +413,7 @@
"outputs": "Output", "outputs": "Output",
"overwrite_amount": "Timpa jumlah", "overwrite_amount": "Timpa jumlah",
"pairingInvalidEvent": "Menyandingkan Acara Tidak Valid", "pairingInvalidEvent": "Menyandingkan Acara Tidak Valid",
"passphrase": "Frasa sandi (opsional)",
"password": "Kata Sandi", "password": "Kata Sandi",
"paste": "Tempel", "paste": "Tempel",
"pause_wallet_creation": "Kemampuan untuk membuat Haven Wallet saat ini dijeda.", "pause_wallet_creation": "Kemampuan untuk membuat Haven Wallet saat ini dijeda.",

View file

@ -413,6 +413,7 @@
"outputs": "Output", "outputs": "Output",
"overwrite_amount": "Sovrascrivi quantità", "overwrite_amount": "Sovrascrivi quantità",
"pairingInvalidEvent": "Associazione evento non valido", "pairingInvalidEvent": "Associazione evento non valido",
"passphrase": "Passphrase (opzionale)",
"password": "Password", "password": "Password",
"paste": "Incolla", "paste": "Incolla",
"pause_wallet_creation": "La possibilità di creare Haven Wallet è attualmente sospesa.", "pause_wallet_creation": "La possibilità di creare Haven Wallet è attualmente sospesa.",

View file

@ -412,6 +412,7 @@
"outputs": "出力", "outputs": "出力",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "ペアリング無効イベント", "pairingInvalidEvent": "ペアリング無効イベント",
"passphrase": "パスフレーズ(オプション)",
"password": "パスワード", "password": "パスワード",
"paste": "ペースト", "paste": "ペースト",
"pause_wallet_creation": "Haven Wallet を作成する機能は現在一時停止されています。", "pause_wallet_creation": "Haven Wallet を作成する機能は現在一時停止されています。",

View file

@ -411,6 +411,7 @@
"outputs": "출력", "outputs": "출력",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "잘못된 이벤트 페어링", "pairingInvalidEvent": "잘못된 이벤트 페어링",
"passphrase": "암호화 (선택 사항)",
"password": "암호", "password": "암호",
"paste": "풀", "paste": "풀",
"pause_wallet_creation": "Haven Wallet 생성 기능이 현재 일시 중지되었습니다.", "pause_wallet_creation": "Haven Wallet 생성 기능이 현재 일시 중지되었습니다.",
@ -425,8 +426,8 @@
"placeholder_transactions": "거래가 여기에 표시됩니다", "placeholder_transactions": "거래가 여기에 표시됩니다",
"please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.", "please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.",
"please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.", "please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.",
"please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.",
"Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.",
"please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.",
"please_select": "선택 해주세요:", "please_select": "선택 해주세요:",
"please_select_backup_file": "백업 파일을 선택하고 백업 암호를 입력하십시오.", "please_select_backup_file": "백업 파일을 선택하고 백업 암호를 입력하십시오.",
"please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오", "please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오",

View file

@ -411,6 +411,7 @@
"outputs": "ထုတ်လုပ်မှု", "outputs": "ထုတ်လုပ်မှု",
"overwrite_amount": "ပမာဏကို ထပ်ရေးပါ။", "overwrite_amount": "ပမာဏကို ထပ်ရေးပါ။",
"pairingInvalidEvent": "မမှန်ကန်သောဖြစ်ရပ်ကို တွဲချိတ်ခြင်း။", "pairingInvalidEvent": "မမှန်ကန်သောဖြစ်ရပ်ကို တွဲချိတ်ခြင်း။",
"passphrase": "passphrase (optional)",
"password": "စကားဝှက်", "password": "စကားဝှက်",
"paste": "ငါးပိ", "paste": "ငါးပိ",
"pause_wallet_creation": "Haven Wallet ဖန်တီးနိုင်မှုကို လောလောဆယ် ခေတ္တရပ်ထားသည်။", "pause_wallet_creation": "Haven Wallet ဖန်တီးနိုင်မှုကို လောလောဆယ် ခေတ္တရပ်ထားသည်။",

View file

@ -411,6 +411,7 @@
"outputs": "Uitgangen", "outputs": "Uitgangen",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Koppelen Ongeldige gebeurtenis", "pairingInvalidEvent": "Koppelen Ongeldige gebeurtenis",
"passphrase": "PassaspHRASE (optioneel)",
"password": "Wachtwoord", "password": "Wachtwoord",
"paste": "Plakken", "paste": "Plakken",
"pause_wallet_creation": "De mogelijkheid om Haven Wallet te maken is momenteel onderbroken.", "pause_wallet_creation": "De mogelijkheid om Haven Wallet te maken is momenteel onderbroken.",

View file

@ -411,6 +411,7 @@
"outputs": "Wyjścia", "outputs": "Wyjścia",
"overwrite_amount": "Nadpisz ilość", "overwrite_amount": "Nadpisz ilość",
"pairingInvalidEvent": "Nieprawidłowe zdarzenie parowania", "pairingInvalidEvent": "Nieprawidłowe zdarzenie parowania",
"passphrase": "PassPhraza (opcjonalnie)",
"password": "Hasło", "password": "Hasło",
"paste": "Wklej", "paste": "Wklej",
"pause_wallet_creation": "Możliwość utworzenia Portfela Haven jest obecnie wstrzymana.", "pause_wallet_creation": "Możliwość utworzenia Portfela Haven jest obecnie wstrzymana.",

View file

@ -413,6 +413,7 @@
"outputs": "Saídas", "outputs": "Saídas",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Emparelhamento de evento inválido", "pairingInvalidEvent": "Emparelhamento de evento inválido",
"passphrase": "Senha (opcional)",
"password": "Senha", "password": "Senha",
"paste": "Colar", "paste": "Colar",
"pause_wallet_creation": "A capacidade de criar a Haven Wallet está atualmente pausada.", "pause_wallet_creation": "A capacidade de criar a Haven Wallet está atualmente pausada.",

View file

@ -412,6 +412,7 @@
"outputs": "Выходы", "outputs": "Выходы",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Недействительное событие сопряжения", "pairingInvalidEvent": "Недействительное событие сопряжения",
"passphrase": "Passfrase (необязательно)",
"password": "Пароль", "password": "Пароль",
"paste": "Вставить", "paste": "Вставить",
"pause_wallet_creation": "Возможность создания Haven Wallet в настоящее время приостановлена.", "pause_wallet_creation": "Возможность создания Haven Wallet в настоящее время приостановлена.",

View file

@ -411,6 +411,7 @@
"outputs": "เอาต์พุต", "outputs": "เอาต์พุต",
"overwrite_amount": "เขียนทับจำนวน", "overwrite_amount": "เขียนทับจำนวน",
"pairingInvalidEvent": "การจับคู่เหตุการณ์ที่ไม่ถูกต้อง", "pairingInvalidEvent": "การจับคู่เหตุการณ์ที่ไม่ถูกต้อง",
"passphrase": "ข้อความรหัสผ่าน (ไม่บังคับ)",
"password": "รหัสผ่าน", "password": "รหัสผ่าน",
"paste": "วาง", "paste": "วาง",
"pause_wallet_creation": "ขณะนี้ความสามารถในการสร้าง Haven Wallet ถูกหยุดชั่วคราว", "pause_wallet_creation": "ขณะนี้ความสามารถในการสร้าง Haven Wallet ถูกหยุดชั่วคราว",

View file

@ -411,6 +411,7 @@
"outputs": "Mga output", "outputs": "Mga output",
"overwrite_amount": "Overwrite na halaga", "overwrite_amount": "Overwrite na halaga",
"pairingInvalidEvent": "Pagpares ng Di-wastong Kaganapan", "pairingInvalidEvent": "Pagpares ng Di-wastong Kaganapan",
"passphrase": "Passphrase (opsyonal)",
"password": "Password", "password": "Password",
"paste": "I -paste", "paste": "I -paste",
"pause_wallet_creation": "Kasalukuyang naka-pause ang kakayahang gumawa ng Haven Wallet.", "pause_wallet_creation": "Kasalukuyang naka-pause ang kakayahang gumawa ng Haven Wallet.",

View file

@ -411,6 +411,7 @@
"outputs": "çıktılar", "outputs": "çıktılar",
"overwrite_amount": "Miktarın üzerine yaz", "overwrite_amount": "Miktarın üzerine yaz",
"pairingInvalidEvent": "Geçersiz Etkinliği Eşleştirme", "pairingInvalidEvent": "Geçersiz Etkinliği Eşleştirme",
"passphrase": "Passfrase (isteğe bağlı)",
"password": "Parola", "password": "Parola",
"paste": "Yapıştır", "paste": "Yapıştır",
"pause_wallet_creation": "Haven Cüzdanı oluşturma yeteneği şu anda duraklatıldı.", "pause_wallet_creation": "Haven Cüzdanı oluşturma yeteneği şu anda duraklatıldı.",

View file

@ -411,6 +411,7 @@
"outputs": "Виходи", "outputs": "Виходи",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "Недійсна подія сполучення", "pairingInvalidEvent": "Недійсна подія сполучення",
"passphrase": "Пасофрази (необов’язково)",
"password": "Пароль", "password": "Пароль",
"paste": "Вставити", "paste": "Вставити",
"pause_wallet_creation": "Можливість створення гаманця Haven зараз призупинено.", "pause_wallet_creation": "Можливість створення гаманця Haven зараз призупинено.",

View file

@ -413,6 +413,7 @@
"outputs": "نتائج", "outputs": "نتائج",
"overwrite_amount": "رقم کو اوور رائٹ کریں۔", "overwrite_amount": "رقم کو اوور رائٹ کریں۔",
"pairingInvalidEvent": "ﭧﻧﻮﯾﺍ ﻂﻠﻏ ﺎﻧﺎﻨﺑ ﺍﮌﻮﺟ", "pairingInvalidEvent": "ﭧﻧﻮﯾﺍ ﻂﻠﻏ ﺎﻧﺎﻨﺑ ﺍﮌﻮﺟ",
"passphrase": "پاسفریز (اختیاری)",
"password": "پاس ورڈ", "password": "پاس ورڈ",
"paste": "چسپاں کریں۔", "paste": "چسپاں کریں۔",
"pause_wallet_creation": "Haven Wallet ۔ﮯﮨ ﻑﻮﻗﻮﻣ ﻝﺎﺤﻟﺍ ﯽﻓ ﺖﯿﻠﮨﺍ ﯽﮐ ﮯﻧﺎﻨﺑ", "pause_wallet_creation": "Haven Wallet ۔ﮯﮨ ﻑﻮﻗﻮﻣ ﻝﺎﺤﻟﺍ ﯽﻓ ﺖﯿﻠﮨﺍ ﯽﮐ ﮯﻧﺎﻨﺑ",

View file

@ -412,6 +412,7 @@
"outputs": "Awọn iṣan", "outputs": "Awọn iṣan",
"overwrite_amount": "Pààrọ̀ iye owó", "overwrite_amount": "Pààrọ̀ iye owó",
"pairingInvalidEvent": "Pipọpọ Iṣẹlẹ Ti ko tọ", "pairingInvalidEvent": "Pipọpọ Iṣẹlẹ Ti ko tọ",
"passphrase": "Ọrọ kukuru (iyan)",
"password": "Ọ̀rọ̀ aṣínà", "password": "Ọ̀rọ̀ aṣínà",
"paste": "Fikún ẹ̀dà yín", "paste": "Fikún ẹ̀dà yín",
"pause_wallet_creation": "Agbara lati ṣẹda Haven Wallet ti wa ni idaduro lọwọlọwọ.", "pause_wallet_creation": "Agbara lati ṣẹda Haven Wallet ti wa ni idaduro lọwọlọwọ.",

View file

@ -411,6 +411,7 @@
"outputs": "输出", "outputs": "输出",
"overwrite_amount": "Overwrite amount", "overwrite_amount": "Overwrite amount",
"pairingInvalidEvent": "配对无效事件", "pairingInvalidEvent": "配对无效事件",
"passphrase": "密码(可选)",
"password": "密码", "password": "密码",
"paste": "粘贴", "paste": "粘贴",
"pause_wallet_creation": "创建 Haven 钱包的功能当前已暂停。", "pause_wallet_creation": "创建 Haven 钱包的功能当前已暂停。",

View file

@ -130,6 +130,7 @@ abstract class Bitcoin {
required String password, required String password,
required DerivationType derivationType, required DerivationType derivationType,
required String derivationPath, required String derivationPath,
String? passphrase,
}); });
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo}); WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo}); WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo});
@ -168,7 +169,7 @@ abstract class Bitcoin {
Future<List<DerivationType>> compareDerivationMethods( Future<List<DerivationType>> compareDerivationMethods(
{required String mnemonic, required Node node}); {required String mnemonic, required Node node});
Future<List<DerivationInfo>> getDerivationsFromMnemonic( Future<List<DerivationInfo>> getDerivationsFromMnemonic(
{required String mnemonic, required Node node}); {required String mnemonic, required Node node, String? passphrase});
Future<void> setAddressType(Object wallet, dynamic option); Future<void> setAddressType(Object wallet, dynamic option);
ReceivePageOption getSelectedAddressType(Object wallet); ReceivePageOption getSelectedAddressType(Object wallet);
List<ReceivePageOption> getBitcoinReceivePageOptions(); List<ReceivePageOption> getBitcoinReceivePageOptions();