Merge branch 'staging' into desktop

This commit is contained in:
ryleedavis 2022-11-09 16:55:53 -07:00
commit 2159287326
9 changed files with 665 additions and 14 deletions

@ -1 +1 @@
Subproject commit 277d922c3b1d637c1ccda25f51395c618d293015 Subproject commit b9bc2dcc56e13f235a6c5b0fc02c0e543eb87758

View file

@ -8,6 +8,7 @@ import 'package:bip39/src/wordlists/english.dart' as bip39wordlist;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_libmonero/monero/monero.dart'; import 'package:flutter_libmonero/monero/monero.dart';
import 'package:flutter_libmonero/wownero/wownero.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart';
@ -156,6 +157,11 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
var moneroWordList = monero.getMoneroWordList("English"); var moneroWordList = monero.getMoneroWordList("English");
return moneroWordList.contains(word); return moneroWordList.contains(word);
} }
if (widget.coin == Coin.wownero) {
var wowneroWordList = wownero.getWowneroWordList("English",
seedWordsLength: widget.seedWordsLength);
return wowneroWordList.contains(word);
}
return _wordListHashSet.contains(word); return _wordListHashSet.contains(word);
} }
@ -181,6 +187,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
if (widget.coin == Coin.monero) { if (widget.coin == Coin.monero) {
height = monero.getHeigthByDate(date: widget.restoreFromDate); height = monero.getHeigthByDate(date: widget.restoreFromDate);
} else if (widget.coin == Coin.wownero) {
height = wownero.getHeightByDate(date: widget.restoreFromDate);
} }
// todo: wait until this implemented // todo: wait until this implemented
// else if (widget.coin == Coin.wownero) { // else if (widget.coin == Coin.wownero) {

View file

@ -699,7 +699,7 @@ class MoneroWallet extends CoinServiceAPI {
name: name, name: name,
type: WalletType.monero, type: WalletType.monero,
isRecovery: false, isRecovery: false,
restoreHeight: credentials.height ?? 0, restoreHeight: bufferedCreateHeight,
date: DateTime.now(), date: DateTime.now(),
path: path, path: path,
dirPath: dirPath, dirPath: dirPath,

View file

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_core/monero_transaction_priority.dart'; import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'package:cw_core/pending_transaction.dart'; import 'package:cw_core/pending_transaction.dart';
@ -647,7 +648,7 @@ class WowneroWallet extends CoinServiceAPI {
} }
//TODO: take in the default language when creating wallet. //TODO: take in the default language when creating wallet.
Future<void> _generateNewWallet() async { Future<void> _generateNewWallet({int seedWordsLength = 14}) async {
Logging.instance Logging.instance
.log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info);
// TODO: ping wownero server and make sure the genesis hash matches // TODO: ping wownero server and make sure the genesis hash matches
@ -685,9 +686,7 @@ class WowneroWallet extends CoinServiceAPI {
await pathForWalletDir(name: name, type: WalletType.wownero); await pathForWalletDir(name: name, type: WalletType.wownero);
final path = await pathForWallet(name: name, type: WalletType.wownero); final path = await pathForWallet(name: name, type: WalletType.wownero);
credentials = wownero.createWowneroNewWalletCredentials( credentials = wownero.createWowneroNewWalletCredentials(
name: name, name: name, language: "English", seedWordsLength: seedWordsLength);
language: "English",
);
walletInfo = WalletInfo.external( walletInfo = WalletInfo.external(
id: WalletBase.idFor(name, WalletType.wownero), id: WalletBase.idFor(name, WalletType.wownero),
@ -712,9 +711,12 @@ class WowneroWallet extends CoinServiceAPI {
// To restore from a seed // To restore from a seed
final wallet = await _walletCreationService?.create(credentials); final wallet = await _walletCreationService?.create(credentials);
// subtract a couple days to ensure we have a buffer for SWB final bufferedCreateHeight = (seedWordsLength == 14)
final bufferedCreateHeight = ? getSeedHeightSync(wallet?.seed.trim() as String)
getSeedHeightSync(wallet?.seed.trim() as String); : wownero.getHeightByDate(
date: DateTime.now().subtract(const Duration(
days:
2))); // subtract a couple days to ensure we have a buffer for SWB
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight); boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight);
@ -722,6 +724,7 @@ class WowneroWallet extends CoinServiceAPI {
await _secureStore.write( await _secureStore.write(
key: '${_walletId}_mnemonic', value: wallet?.seed.trim()); key: '${_walletId}_mnemonic', value: wallet?.seed.trim());
walletInfo.address = wallet?.walletAddresses.address; walletInfo.address = wallet?.walletAddresses.address;
await DB.instance await DB.instance
.add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo); .add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
@ -778,7 +781,7 @@ class WowneroWallet extends CoinServiceAPI {
@override @override
// TODO: implement initializeWallet // TODO: implement initializeWallet
Future<bool> initializeNew() async { Future<bool> initializeNew({int seedWordsLength = 14}) async {
await _prefs.init(); await _prefs.init();
// TODO: ping actual wownero network // TODO: ping actual wownero network
// try { // try {
@ -796,7 +799,7 @@ class WowneroWallet extends CoinServiceAPI {
prefs = await SharedPreferences.getInstance(); prefs = await SharedPreferences.getInstance();
keysStorage = KeyService(storage!); keysStorage = KeyService(storage!);
await _generateNewWallet(); await _generateNewWallet(seedWordsLength: seedWordsLength);
// var password; // var password;
// try { // try {
// password = // password =
@ -977,6 +980,14 @@ class WowneroWallet extends CoinServiceAPI {
// extract seed height from 14 word seed // extract seed height from 14 word seed
if (seedLength == 14) { if (seedLength == 14) {
height = getSeedHeightSync(mnemonic.trim()); height = getSeedHeightSync(mnemonic.trim());
} else {
// 25 word seed. TODO validate
if (height == 0) {
height = wownero.getHeightByDate(
date: DateTime.now().subtract(const Duration(
days:
2))); // subtract a couple days to ensure we have a buffer for SWB\
}
} }
await DB.instance await DB.instance

View file

@ -62,9 +62,7 @@ abstract class Constants {
values.addAll([25]); values.addAll([25]);
break; break;
case Coin.wownero: case Coin.wownero:
values.addAll([14]); values.addAll([14, 25]);
// todo: uncomment when wownero 25 word seeds implemented
// values.addAll([14, 25]);
break; break;
} }
return values; return values;

View file

@ -0,0 +1,227 @@
import 'dart:async';
import 'dart:core';
import 'dart:core' as core;
import 'dart:io';
import 'dart:math';
import 'package:flutter_test/flutter_test.dart';
import 'package:hive/hive.dart';
import 'package:hive_test/hive_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_monero/api/wallet.dart';
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
import 'package:cw_monero/pending_monero_transaction.dart';
import 'package:cw_monero/monero_wallet.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_libmonero/core/key_service.dart';
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
import 'package:flutter_libmonero/view_model/send/output.dart';
import 'package:flutter_libmonero/monero/monero.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/services/wallets.dart';
import 'dart:developer' as developer;
// TODO trim down to the minimum imports above
import 'monero_wallet_test_data.dart';
//FlutterSecureStorage? storage;
FakeSecureStorage? storage;
WalletService? walletService;
SharedPreferences? prefs;
KeyService? keysStorage;
MoneroWalletBase? walletBase;
late WalletCreationService _walletCreationService;
dynamic _walletInfoSource;
Wallets? walletsService;
String path = '';
String name = 'namee${Random().nextInt(10000000)}';
int nettype = 0;
WalletType type = WalletType.monero;
@GenerateMocks([])
void main() async {
storage = FakeSecureStorage();
prefs = await SharedPreferences.getInstance();
keysStorage = KeyService(storage!);
WalletInfo walletInfo = WalletInfo.external(
id: '',
name: '',
type: type,
isRecovery: false,
restoreHeight: 0,
date: DateTime.now(),
path: '',
address: '',
dirPath: '');
late WalletCredentials credentials;
WidgetsFlutterBinding.ensureInitialized();
Directory appDir = (await getApplicationDocumentsDirectory());
if (Platform.isIOS) {
appDir = (await getLibraryDirectory());
}
await Hive.close();
Hive.init(appDir.path);
Hive.registerAdapter(NodeAdapter());
Hive.registerAdapter(WalletInfoAdapter());
Hive.registerAdapter(WalletTypeAdapter());
Hive.registerAdapter(UnspentCoinsInfoAdapter());
monero.onStartup();
_walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
walletService = monero.createMoneroWalletService(_walletInfoSource);
group("Mainnet tests", () {
setUp(() async {
try {
// if (name?.isEmpty ?? true) {
// name = await generateName();
// }
final dirPath = await pathForWalletDir(name: name, type: type);
path = await pathForWallet(name: name, type: type);
credentials =
// // creating a new wallet
// monero.createMoneroNewWalletCredentials(
// name: name, language: "English");
// restoring a previous wallet
monero.createMoneroRestoreWalletFromSeedCredentials(
name: name, height: 2580000, mnemonic: testMnemonic);
walletInfo = WalletInfo.external(
id: WalletBase.idFor(name, type),
name: name,
type: type,
isRecovery: false,
restoreHeight: credentials.height ?? 0,
date: DateTime.now(),
path: path,
address: "",
dirPath: dirPath);
credentials.walletInfo = walletInfo;
_walletCreationService = WalletCreationService(
secureStorage: storage,
sharedPreferences: prefs,
walletService: walletService,
keyService: keysStorage,
);
_walletCreationService.changeWalletType();
} catch (e, s) {
print(e);
print(s);
}
});
test("Test mainnet address generation from seed", () async {
final wallet = await
// _walletCreationService.create(credentials);
_walletCreationService.restoreFromSeed(credentials);
walletInfo.address = wallet.walletAddresses.address;
//print(walletInfo.address);
await _walletInfoSource.add(walletInfo);
walletBase?.close();
walletBase = wallet as MoneroWalletBase;
//print("${walletBase?.seed}");
// print(walletBase);
// loggerPrint(walletBase.toString());
// loggerPrint("name: ${walletBase!.name} seed: ${walletBase!.seed} id: "
// "${walletBase!.id} walletinfo: ${toStringForinfo(walletBase!.walletInfo)} type: ${walletBase!.type} balance: "
// "${walletBase!.balance.entries.first.value.available} currency: ${walletBase!.currency}");
expect(walletInfo.address, mainnetTestData[0][0]);
expect(
await walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]);
expect(
await walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]);
expect(
await walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]);
expect(
await walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]);
expect(
await walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]);
expect(
await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
});
});
/*
// Not needed; only folder created, wallet files not saved yet. TODO test saving and deleting wallet files and make sure to clean up leftover folder afterwards
group("Mainnet wallet deletion test", () {
test("Test mainnet wallet existence", () {
expect(monero_wallet_manager.isWalletExistSync(path: path), true);
});
test("Test mainnet wallet deletion", () {
// Remove wallet from wallet service
walletService?.remove(name);
walletsService?.removeWallet(walletId: name);
expect(monero_wallet_manager.isWalletExistSync(path: path), false);
});
});
group("Mainnet node tests", () {
test("Test mainnet node connection", () async {
await walletBase?.connectToNode(
node: Node(
uri: "monero-stagenet.stackwallet.com:38081",
type: WalletType.moneroStageNet));
await walletBase!.rescan(
height:
credentials.height); // Probably shouldn't be rescanning from 0...
await walletBase!.getNodeHeight();
int height = await walletBase!.getNodeHeight();
print('height: $height');
bool connected = await walletBase!.isConnected();
print('connected: $connected');
//expect...
});
});
*/
// TODO test deletion of wallets ... and delete them
}
Future<String> pathForWalletDir(
{required String name, required WalletType type}) async {
Directory root = (await getApplicationDocumentsDirectory());
if (Platform.isIOS) {
root = (await getLibraryDirectory());
}
final prefix = walletTypeToString(type).toLowerCase();
final walletsDir = Directory('${root.path}/wallets');
final walletDire = Directory('${walletsDir.path}/$prefix/$name');
if (!walletDire.existsSync()) {
walletDire.createSync(recursive: true);
}
return walletDire.path;
}
Future<String> pathForWallet(
{required String name, required WalletType type}) async =>
await pathForWalletDir(name: name, type: type)
.then((path) => path + '/$name');

View file

@ -0,0 +1,14 @@
String testMnemonic =
'agreed aquarium wallets uptight karate wonders afoot guys itself nucleus reduce lamb fully fewest bimonthly dazed skulls magically mocked fugitive imbalance saga calamity dialect itself';
var mainnetTestData = [
[
'4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn',
'82WsoLmbZt3BPwJMF5PfT8GitThJzUq3FFoSQyr4fKfJdxZebgY3mHPcnAqTBA3FFwZRGxC4ZDwkfE1VVULPa55x3xXgCbj',
'84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'
],
[
'86SF44CsTBYU3vk1X7nGBbQnrUSknGbd6Uw8a9hUUgy3KBeXTDvk3pm8upMzZKw17m3mLPEzbcPp5WLpYVoHR5PKNVtFrHH',
'8Aa9LNGdBHwYUMsy6M9ZVXMEkTBZyEDT7aQmY32trCxbU6dwkZJSCSbcpyL7UiTB9QXXosomZtJYvUJ296vTNX5yQ81KaA2',
'85C5zZRcaD89PKmXEwjcYMVAUqoH5rrAXe3GokvSupXnDmccYvZagz5Qem7bQLteEw4iFEJ9oRk9BNfjTi4K2cyTJbTMMPT'
]
];

View file

@ -0,0 +1,371 @@
import 'dart:async';
import 'dart:core';
import 'dart:core' as core;
import 'dart:io';
import 'dart:math';
import 'package:flutter_test/flutter_test.dart';
import 'package:hive/hive.dart';
import 'package:hive_test/hive_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_wownero/api/wallet.dart';
import 'package:cw_wownero/pending_wownero_transaction.dart';
import 'package:cw_wownero/wownero_wallet.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_libmonero/core/key_service.dart';
import 'package:flutter_libmonero/core/wallet_creation_service.dart';
import 'package:flutter_libmonero/view_model/send/output.dart';
import 'package:flutter_libmonero/wownero/wownero.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'wownero_wallet_test_data.dart';
FakeSecureStorage? storage;
WalletService? walletService;
SharedPreferences? prefs;
KeyService? keysStorage;
WowneroWalletBase? walletBase;
late WalletCreationService _walletCreationService;
dynamic _walletInfoSource;
String path = '';
String name = '';
int nettype = 0;
WalletType type = WalletType.wownero;
@GenerateMocks([])
void main() async {
storage = FakeSecureStorage();
prefs = await SharedPreferences.getInstance();
keysStorage = KeyService(storage!);
WalletInfo walletInfo = WalletInfo.external(
id: '',
name: '',
type: type,
isRecovery: false,
restoreHeight: 0,
date: DateTime.now(),
path: '',
address: '',
dirPath: '');
late WalletCredentials credentials;
WidgetsFlutterBinding.ensureInitialized();
Directory appDir = (await getApplicationDocumentsDirectory());
if (Platform.isIOS) {
appDir = (await getLibraryDirectory());
}
await Hive.close();
Hive.init(appDir.path);
Hive.registerAdapter(NodeAdapter());
Hive.registerAdapter(WalletInfoAdapter());
Hive.registerAdapter(WalletTypeAdapter());
Hive.registerAdapter(UnspentCoinsInfoAdapter());
wownero.onStartup();
_walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
walletService = wownero.createWowneroWalletService(_walletInfoSource);
group("Wownero 14 word seed generation", () {
setUp(() async {
bool hasThrown = false;
try {
name = 'namee${Random().nextInt(10000000)}';
final dirPath = await pathForWalletDir(name: name, type: type);
path = await pathForWallet(name: name, type: type);
credentials = wownero.createWowneroNewWalletCredentials(
name: name,
language: "English",
seedWordsLength: 14); // TODO catch failure
walletInfo = WalletInfo.external(
id: WalletBase.idFor(name, type),
name: name,
type: type,
isRecovery: false,
restoreHeight: credentials.height ?? 0,
date: DateTime.now(),
path: path,
address: "",
dirPath: dirPath);
credentials.walletInfo = walletInfo;
_walletCreationService = WalletCreationService(
secureStorage: storage,
sharedPreferences: prefs,
walletService: walletService,
keyService: keysStorage,
);
_walletCreationService.changeWalletType();
} catch (e, s) {
print(e);
print(s);
hasThrown = true;
}
expect(hasThrown, false);
});
test("Wownero 14 word seed address generation", () async {
final wallet = await _walletCreationService.create(credentials);
// TODO validate mnemonic
walletInfo.address = wallet.walletAddresses.address;
bool hasThrown = false;
try {
await _walletInfoSource.add(walletInfo);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
// TODO validate
//expect(walletInfo.address, mainnetTestData14[0][0]);
} catch (_) {
hasThrown = true;
}
expect(hasThrown, false);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
});
// TODO delete left over wallet file with name: name
});
group("Wownero 14 word seed restoration", () {
setUp(() async {
bool hasThrown = false;
try {
name = 'namee${Random().nextInt(10000000)}';
final dirPath = await pathForWalletDir(name: name, type: type);
path = await pathForWallet(name: name, type: type);
credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
name: name,
height: 465760,
mnemonic: testMnemonic14); // TODO catch failure
walletInfo = WalletInfo.external(
id: WalletBase.idFor(name, type),
name: name,
type: type,
isRecovery: false,
restoreHeight: credentials.height ?? 0,
date: DateTime.now(),
path: path,
address: "",
dirPath: dirPath);
credentials.walletInfo = walletInfo;
_walletCreationService = WalletCreationService(
secureStorage: storage,
sharedPreferences: prefs,
walletService: walletService,
keyService: keysStorage,
);
_walletCreationService.changeWalletType();
} catch (e, s) {
print(e);
print(s);
hasThrown = true;
}
expect(hasThrown, false);
});
test("Wownero 14 word seed address generation", () async {
final wallet = await _walletCreationService.restoreFromSeed(credentials);
walletInfo.address = wallet.walletAddresses.address;
bool hasThrown = false;
try {
await _walletInfoSource.add(walletInfo);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
expect(walletInfo.address, mainnetTestData14[0][0]);
expect(await walletBase!.getTransactionAddress(0, 0),
mainnetTestData14[0][0]);
expect(await walletBase!.getTransactionAddress(0, 1),
mainnetTestData14[0][1]);
expect(await walletBase!.getTransactionAddress(0, 2),
mainnetTestData14[0][2]);
expect(await walletBase!.getTransactionAddress(1, 0),
mainnetTestData14[1][0]);
expect(await walletBase!.getTransactionAddress(1, 1),
mainnetTestData14[1][1]);
expect(await walletBase!.getTransactionAddress(1, 2),
mainnetTestData14[1][2]);
} catch (_) {
hasThrown = true;
}
expect(hasThrown, false);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
});
// TODO delete left over wallet file with name: name
});
group("Wownero 25 word seed generation", () {
setUp(() async {
bool hasThrown = false;
try {
name = 'namee${Random().nextInt(10000000)}';
final dirPath = await pathForWalletDir(name: name, type: type);
path = await pathForWallet(name: name, type: type);
credentials = wownero.createWowneroNewWalletCredentials(
name: name,
language: "English",
seedWordsLength: 25); // TODO catch failure
walletInfo = WalletInfo.external(
id: WalletBase.idFor(name, type),
name: name,
type: type,
isRecovery: false,
restoreHeight: credentials.height ?? 0,
date: DateTime.now(),
path: path,
address: "",
dirPath: dirPath);
credentials.walletInfo = walletInfo;
_walletCreationService = WalletCreationService(
secureStorage: storage,
sharedPreferences: prefs,
walletService: walletService,
keyService: keysStorage,
);
_walletCreationService.changeWalletType();
} catch (e, s) {
print(e);
print(s);
hasThrown = true;
}
expect(hasThrown, false);
});
test("Wownero 25 word seed address generation", () async {
final wallet = await _walletCreationService.create(credentials);
// TODO validate mnemonic
walletInfo.address = wallet.walletAddresses.address;
bool hasThrown = false;
try {
await _walletInfoSource.add(walletInfo);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
// TODO validate
//expect(walletInfo.address, mainnetTestData14[0][0]);
} catch (_) {
hasThrown = true;
}
expect(hasThrown, false);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
});
// TODO delete left over wallet file with name: name
});
group("Wownero 25 word seed restoration", () {
setUp(() async {
bool hasThrown = false;
try {
name = 'namee${Random().nextInt(10000000)}';
final dirPath = await pathForWalletDir(name: name, type: type);
path = await pathForWallet(name: name, type: type);
credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
name: name,
height: 465760,
mnemonic: testMnemonic25); // TODO catch failure
walletInfo = WalletInfo.external(
id: WalletBase.idFor(name, type),
name: name,
type: type,
isRecovery: false,
restoreHeight: credentials.height ?? 0,
date: DateTime.now(),
path: path,
address: "",
dirPath: dirPath);
credentials.walletInfo = walletInfo;
_walletCreationService = WalletCreationService(
secureStorage: storage,
sharedPreferences: prefs,
walletService: walletService,
keyService: keysStorage,
);
_walletCreationService.changeWalletType();
} catch (e, s) {
print(e);
print(s);
hasThrown = true;
}
expect(hasThrown, false);
});
test("Wownero 25 word seed address generation", () async {
final wallet = await _walletCreationService.restoreFromSeed(credentials);
walletInfo.address = wallet.walletAddresses.address;
bool hasThrown = false;
try {
await _walletInfoSource.add(walletInfo);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
expect(walletInfo.address, mainnetTestData25[0][0]);
} catch (_) {
hasThrown = true;
}
expect(hasThrown, false);
walletBase?.close();
walletBase = wallet as WowneroWalletBase;
});
// TODO delete left over wallet file with name: name
});
}
Future<String> pathForWalletDir(
{required String name, required WalletType type}) async {
Directory root = (await getApplicationDocumentsDirectory());
if (Platform.isIOS) {
root = (await getLibraryDirectory());
}
final prefix = walletTypeToString(type).toLowerCase();
final walletsDir = Directory('${root.path}/wallets');
final walletDire = Directory('${walletsDir.path}/$prefix/$name');
if (!walletDire.existsSync()) {
walletDire.createSync(recursive: true);
}
return walletDire.path;
}
Future<String> pathForWallet(
{required String name, required WalletType type}) async =>
await pathForWalletDir(name: name, type: type)
.then((path) => path + '/$name');

View file

@ -0,0 +1,22 @@
String testMnemonic14 =
'weather cruise school such silly profit clerk wage reduce obtain ill sand episode shadow';
var mainnetTestData14 = [
[
'Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi',
'WW3K54QzmMFB1uTZh3LVvgQYqANLmX1FkJHLJ4sU1E7BQmp8nGizyBnjNXSgsjCa4BQ3Rw3GG5jw1ByUkaUjSywm2KmHAbFvK',
'WW3e3F51KAojcSW2G5WimmE1WVFsbBHc6HppZFBa6dNiEn21cThXzdGGDbpv89aTKXSRSPSFaetK6HgCozYawaYz2knUi9Hmn'
],
[
'WW2nx7MFruyN2CcXnGnMbDdvqsyZUGQthLWKYPkQ4iM9XCE54RyWVjNjgopryUbyi9WKzYhHDai2wENbh1Jh1UHa28CL72TYt',
'WW34p57QBMoD6MEZVTu5u9R7G3KeYqvN4eYbvHLYsgbWXpLe992fBvVB7ANJNvaGmPg2uwY5oKjwKbpo4fDU6cGS231PmvXrZ',
'WW2KQLLt6gjC9gRsC4NGehbAZX6UPU7sK89UQFwSg3NKj3MXPwnjh5BiJVqYYNQb6JNsfa7oP7eDjLagtLa2H6YP11RhUNQqw'
]
];
String testMnemonic25 =
'myth byline benches sadness nylon tamper guide giving match angled lurk rally makeup alarms river soapy dolphin woven ticket maul examine public luggage mammal alarms';
var mainnetTestData25 = [
[
'Wo3piMnt1ztjLktFJNsfs9ce6N1tyHk7DB93cNqTGPJ7To3RS7W2q5DdxgQAG5E6RQXQhchQD7ip8WWL3fD8Ww5K2XmAXYxta'
]
];