diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart index d56417d36..bb7c5514d 100644 --- a/cw_core/lib/wallet_base.dart +++ b/cw_core/lib/wallet_base.dart @@ -46,7 +46,7 @@ abstract class WalletBase null; - String get passphrase => ""; + String? get passphrase => null; Object get keys; diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index c4d62d654..9cfddbf48 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -34,16 +34,22 @@ String getSeed() { final cakepolyseed = monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed"); final cakepassphrase = getPassphrase(); - if (cakepassphrase != "") { - final lang = PolyseedLang.getByPhrase(cakepassphrase); - final coin = PolyseedCoin.POLYSEED_MONERO; - final ps = Polyseed.decode(cakepolyseed, lang, coin); - if (ps.isEncrypted) return ps.encode(lang, coin); - } + + final weirdPolyseed = monero.Wallet_getPolyseed(wptr!, passphrase: cakepassphrase); + if (weirdPolyseed != "") return weirdPolyseed; + if (cakepolyseed != "") { + if (cakepassphrase != "") { + final lang = PolyseedLang.getByPhrase(cakepassphrase); + final coin = PolyseedCoin.POLYSEED_MONERO; + final ps = Polyseed.decode(cakepolyseed, lang, coin); + if (ps.isEncrypted) return ps.encode(lang, coin); + ps.crypt(getPassphrase()); + return ps.encode(lang, coin); + } return cakepolyseed; } - final legacy = getSeedLegacy("English"); + final legacy = getSeedLegacy(null); return legacy; } diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index 881ae420b..9e70d87d3 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -157,6 +157,47 @@ void restoreWalletFromKeysSync( openedWalletsByPath[path] = wptr!; } + +// English only, because normalization. +void restoreWalletFromPolyseedWithOffset( + {required String path, + required String password, + required String seed, + required String seedOffset, + required String language, + int nettype = 0}) { + + txhistory = null; + final newWptr = monero.WalletManager_createWalletFromPolyseed( + wmPtr, + path: path, + password: password, + networkType: nettype, + mnemonic: seed, + seedOffset: seedOffset, + newWallet: true, // safe to remove + restoreHeight: 0, + kdfRounds: 1, + ); + + final status = monero.Wallet_status(newWptr); + + if (status != 0) { + final err = monero.Wallet_errorString(newWptr); + print("err: $err"); + throw WalletRestoreFromKeysException(message: err); + } + + wptr = newWptr; + + monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); + + storeSync(); + + openedWalletsByPath[path] = wptr!; +} + + void restoreWalletFromSpendKeySync( {required String path, required String password, diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index 93fb0d334..685ed66a5 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -332,6 +332,28 @@ class MoneroWalletService extends WalletService< {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight, String? passphrase}) async { + + if (polyseed.isEncrypted == false && + (passphrase??'') != "") { + // Fallback to the different passphrase offset method, when a passphrase + // was provided but the polyseed is not encrypted. + monero_wallet_manager.restoreWalletFromPolyseedWithOffset( + path: path, + password: password, + seed: polyseed.encode(lang, coin), + seedOffset: passphrase??'', + language: "English"); + + final wallet = MoneroWallet( + walletInfo: walletInfo, + unspentCoinsInfo: unspentCoinsInfoSource, + password: password, + ); + await wallet.init(); + + return wallet; + } + if (polyseed.isEncrypted) polyseed.crypt(passphrase ?? ''); final height = overrideHeight ?? diff --git a/cw_wownero/lib/api/wallet.dart b/cw_wownero/lib/api/wallet.dart index f99be43ea..cb94a9100 100644 --- a/cw_wownero/lib/api/wallet.dart +++ b/cw_wownero/lib/api/wallet.dart @@ -6,6 +6,7 @@ import 'package:cw_wownero/api/account_list.dart'; import 'package:cw_wownero/api/exceptions/setup_wallet_exception.dart'; import 'package:monero/wownero.dart' as wownero; import 'package:mutex/mutex.dart'; +import 'package:polyseed/polyseed.dart'; int getSyncingHeight() { // final height = wownero.WOWNERO_cw_WalletListener_height(getWlptr()); @@ -31,10 +32,23 @@ bool isNewTransactionExist() { String getFilename() => wownero.Wallet_filename(wptr!); String getSeed() { - // wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); + // monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); final cakepolyseed = wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed"); + final cakepassphrase = getPassphrase(); + + final weirdPolyseed = wownero.Wallet_getPolyseed(wptr!, passphrase: cakepassphrase); + if (weirdPolyseed != "") return weirdPolyseed; + if (cakepolyseed != "") { + if (cakepassphrase != "") { + final lang = PolyseedLang.getByPhrase(cakepassphrase); + final coin = PolyseedCoin.POLYSEED_MONERO; + final ps = Polyseed.decode(cakepolyseed, lang, coin); + if (ps.isEncrypted) return ps.encode(lang, coin); + ps.crypt(getPassphrase()); + return ps.encode(lang, coin); + } return cakepolyseed; } final legacy = getSeedLegacy(null); diff --git a/cw_wownero/lib/api/wallet_manager.dart b/cw_wownero/lib/api/wallet_manager.dart index fbe4250e6..ca4258a6b 100644 --- a/cw_wownero/lib/api/wallet_manager.dart +++ b/cw_wownero/lib/api/wallet_manager.dart @@ -175,6 +175,47 @@ void restoreWalletFromKeysSync( openedWalletsByPath[path] = wptr!; } + + +// English only, because normalization. +void restoreWalletFromPolyseedWithOffset( + {required String path, + required String password, + required String seed, + required String seedOffset, + required String language, + int nettype = 0}) { + + txhistory = null; + final newWptr = wownero.WalletManager_createWalletFromPolyseed( + wmPtr, + path: path, + password: password, + networkType: nettype, + mnemonic: seed, + seedOffset: seedOffset, + newWallet: true, // safe to remove + restoreHeight: 0, + kdfRounds: 1, + ); + + final status = wownero.Wallet_status(newWptr); + + if (status != 0) { + final err = wownero.Wallet_errorString(newWptr); + print("err: $err"); + throw WalletRestoreFromKeysException(message: err); + } + + wptr = newWptr; + + wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed); + + storeSync(); + + openedWalletsByPath[path] = wptr!; +} + void restoreWalletFromSpendKeySync( {required String path, required String password, diff --git a/cw_wownero/lib/wownero_wallet.dart b/cw_wownero/lib/wownero_wallet.dart index 63569bc21..38fcb3bff 100644 --- a/cw_wownero/lib/wownero_wallet.dart +++ b/cw_wownero/lib/wownero_wallet.dart @@ -112,9 +112,8 @@ abstract class WowneroWalletBase String get password => _password; - String? passphrase() { - return wownero_wallet.getPassphrase(); - } + @override + String get passphrase => wownero_wallet.getPassphrase(); String _password; diff --git a/cw_wownero/lib/wownero_wallet_service.dart b/cw_wownero/lib/wownero_wallet_service.dart index 7c986ffea..9576bf2f1 100644 --- a/cw_wownero/lib/wownero_wallet_service.dart +++ b/cw_wownero/lib/wownero_wallet_service.dart @@ -303,6 +303,29 @@ class WowneroWalletService extends WalletService< Future _restoreFromPolyseed( String path, String password, Polyseed polyseed, WalletInfo walletInfo, PolyseedLang lang, {PolyseedCoin coin = PolyseedCoin.POLYSEED_WOWNERO, int? overrideHeight, String? passphrase}) async { + + + if (polyseed.isEncrypted == false && + (passphrase??'') != "") { + // Fallback to the different passphrase offset method, when a passphrase + // was provided but the polyseed is not encrypted. + wownero_wallet_manager.restoreWalletFromPolyseedWithOffset( + path: path, + password: password, + seed: polyseed.encode(lang, coin), + seedOffset: passphrase??'', + language: "English"); + + final wallet = WowneroWallet( + walletInfo: walletInfo, + unspentCoinsInfo: unspentCoinsInfoSource, + password: password, + ); + await wallet.init(); + + return wallet; + } + if (polyseed.isEncrypted) polyseed.crypt(passphrase ?? ''); final height = overrideHeight ?? diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart index 2a650c337..41303a749 100644 --- a/lib/view_model/wallet_keys_view_model.dart +++ b/lib/view_model/wallet_keys_view_model.dart @@ -167,7 +167,7 @@ abstract class WalletKeysViewModelBase with Store { value: wownero!.getLegacySeed(_appStore.wallet!, lang.nameEnglish))); } - final passphrase = (_appStore.wallet as WowneroWalletBase).passphrase(); + final passphrase = _appStore.wallet?.passphrase; if (passphrase != null && passphrase != "") { items.add(StandartListItem( title: S.current.passphrase_view_keys,