diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 0c3c244..183496f 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_ios","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_ios-2.1.0/","native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_android-2.0.11/","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-2.0.3/","native_build":true,"dependencies":[]},{"name":"window_size","path":"/usr/lib/flutter/.pub-cache/git/flutter-desktop-embedding-89c350f787e1d7bff12b3517e5671146211ee70e/plugins/window_size/","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.5/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_linux-2.1.0/","native_build":false,"dependencies":["path_provider_linux"]},{"name":"window_size","path":"/usr/lib/flutter/.pub-cache/git/flutter-desktop-embedding-89c350f787e1d7bff12b3517e5671146211ee70e/plugins/window_size/","native_build":true,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.0.5/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_windows-2.1.0/","native_build":false,"dependencies":["path_provider_windows"]},{"name":"window_size","path":"/usr/lib/flutter/.pub-cache/git/flutter-desktop-embedding-89c350f787e1d7bff12b3517e5671146211ee70e/plugins/window_size/","native_build":true,"dependencies":[]}],"web":[{"name":"shared_preferences_web","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-2.0.3/","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_ios","shared_preferences_linux","shared_preferences_macos","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_ios","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"window_size","dependencies":[]}],"date_created":"2022-06-04 17:36:04.435418","version":"3.1.0-0.0.pre.1101"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences_ios","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_ios-2.1.0/","native_build":true,"dependencies":[]}],"android":[{"name":"shared_preferences_android","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_android-2.0.11/","native_build":true,"dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-2.0.3/","native_build":true,"dependencies":[]},{"name":"window_size","path":"/usr/lib/flutter/.pub-cache/git/flutter-desktop-embedding-89c350f787e1d7bff12b3517e5671146211ee70e/plugins/window_size/","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.5/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_linux-2.1.0/","native_build":false,"dependencies":["path_provider_linux"]},{"name":"window_size","path":"/usr/lib/flutter/.pub-cache/git/flutter-desktop-embedding-89c350f787e1d7bff12b3517e5671146211ee70e/plugins/window_size/","native_build":true,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.0.5/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_windows-2.1.0/","native_build":false,"dependencies":["path_provider_windows"]},{"name":"window_size","path":"/usr/lib/flutter/.pub-cache/git/flutter-desktop-embedding-89c350f787e1d7bff12b3517e5671146211ee70e/plugins/window_size/","native_build":true,"dependencies":[]}],"web":[{"name":"shared_preferences_web","path":"/usr/lib/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-2.0.3/","dependencies":[]}]},"dependencyGraph":[{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_ios","shared_preferences_linux","shared_preferences_macos","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_ios","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"window_size","dependencies":[]}],"date_created":"2022-06-06 08:38:49.429855","version":"3.1.0-0.0.pre.1109"} \ No newline at end of file diff --git a/lib/easy_wallet.dart b/lib/easy_wallet.dart index 2d1cf63..e338a69 100644 --- a/lib/easy_wallet.dart +++ b/lib/easy_wallet.dart @@ -6,6 +6,8 @@ class EasyWallet { final String address; BigDecimal balance; + String privateKey = ""; + String mnemonic = ""; EasyWallet(this.address) : balance = BigDecimal.parse("0.0"); diff --git a/lib/preferences.dart b/lib/preferences.dart index 5df23b6..a482a1f 100644 --- a/lib/preferences.dart +++ b/lib/preferences.dart @@ -4,15 +4,17 @@ import 'package:easy_wallet/resources/constants.dart'; import 'easy_wallet.dart'; class _WalletPrefereces { - late String address; + late Map wallet; _WalletPrefereces(EasyWallet w) { - address = w.address; + wallet = { + KEY_CFG_WALLET_ADDRESS: w.address, + KEY_CFG_WALLET_PRIVATE_KEY: w.privateKey, + KEY_CFG_WALLET_MNEMONIC: w.mnemonic + }; } - Map toJson() => { - "address": address - }; + Map toJson() => wallet; } class Preferences { @@ -35,7 +37,10 @@ class Preferences { p.appkey = jsonMap[KEY_CFG_APPKEY] ?? ""; p.wallets = []; for (Map w in jsonMap[KEY_CFG_WALLETS] ?? {}) { - p.wallets.add(EasyWallet(w[KEY_CFG_WALLET_ADDRESS])); + EasyWallet wallet = EasyWallet(w[KEY_CFG_WALLET_ADDRESS]); + wallet.privateKey = w[KEY_CFG_WALLET_PRIVATE_KEY] ?? ""; + wallet.mnemonic = w[KEY_CFG_WALLET_MNEMONIC] ?? ""; + p.wallets.add(wallet); } return p; @@ -52,7 +57,7 @@ class Preferences { for(EasyWallet w in wallets) { list.add(_WalletPrefereces(w)); }; - json["wallets"] = list; + json[KEY_CFG_WALLETS] = list; return json; } diff --git a/lib/resources/constants.dart b/lib/resources/constants.dart index 804b1a4..1fce43e 100644 --- a/lib/resources/constants.dart +++ b/lib/resources/constants.dart @@ -12,6 +12,8 @@ const String KEY_CFG_ENDPOINT = "endpoint"; const String KEY_CFG_APPKEY = "appkey"; const String KEY_CFG_WALLETS = "wallets"; const String KEY_CFG_WALLET_ADDRESS = "address"; +const String KEY_CFG_WALLET_PRIVATE_KEY = "privateKey"; +const String KEY_CFG_WALLET_MNEMONIC = "mnemonicPhrase"; const String LABEL_ADDRESS = "Insert the 20 hex bytes public address:"; const String LABEL_ADDRESS_HINT = "eg: 00000000219ab540356cBB839Cbe05303d7705Fa"; diff --git a/lib/ui/edit_private_key_dialog.dart b/lib/ui/edit_private_key_dialog.dart index ac831b3..d597427 100644 --- a/lib/ui/edit_private_key_dialog.dart +++ b/lib/ui/edit_private_key_dialog.dart @@ -17,7 +17,7 @@ class EditPrivateKeyDialog extends StatefulWidget { class _EditPrivateKeyDialogState extends State { final EasyWallet wallet; final WalletEditingController keyController = WalletEditingController(); - final MnemonicEditingController passphraseController = MnemonicEditingController(); + final MnemonicEditingController mnemonicController = MnemonicEditingController(); _EditPrivateKeyDialogState(this.wallet); @@ -25,14 +25,14 @@ class _EditPrivateKeyDialogState extends State { void initState() { super.initState(); keyController.clear(); - passphraseController.clear(); + mnemonicController.clear(); } @override void dispose() { super.dispose(); keyController.dispose(); - passphraseController.dispose(); + mnemonicController.dispose(); } @override @@ -46,7 +46,7 @@ class _EditPrivateKeyDialogState extends State { Text(LABEL_MNEMONIC_PHRASE), TextField( key: KEY_MNEMONIC_PHRASE, - controller: passphraseController, + controller: mnemonicController, onChanged: (value) { _setPrivateKeyIfValidPassphrase(value); setState(() {}); @@ -89,6 +89,8 @@ class _EditPrivateKeyDialogState extends State { TextButton( child: const Text('OK'), onPressed: !_validate() ? null : () { + wallet.privateKey = keyController.text; + wallet.mnemonic = mnemonicController.text; Navigator.pop(context, ""); } ) @@ -102,16 +104,15 @@ class _EditPrivateKeyDialogState extends State { // // If the key is invalid key2adress returns an empty address... // - print("${wallet.address} == " + keyController.key2address()); return wallet.address == keyController.key2address(); } bool _isPrivateKeyEnabled() { - return passphraseController.value.text.isEmpty; + return mnemonicController.value.text.isEmpty; } void _setPrivateKeyIfValidPassphrase(value) { - keyController.text = passphraseController.privateKey(wallet.address); + keyController.text = mnemonicController.privateKey(wallet.address); } } \ No newline at end of file diff --git a/lib/ui/wallet_app.dart b/lib/ui/wallet_app.dart index a675e1e..209d41d 100644 --- a/lib/ui/wallet_app.dart +++ b/lib/ui/wallet_app.dart @@ -126,9 +126,13 @@ class _EasyWalletState extends State { for (var wallet in controller.value) { cards.add( - WalletCard(wallet, () { - controller - wallet.address; - setState(() {}); + WalletCard(wallet, (WalletAction action) { + if (action == WalletAction.delete) { + controller - wallet.address; + setState(() {}); + } else if (action == WalletAction.update) { + controller.updateWallet(wallet); + } }) ); } diff --git a/lib/ui/wallet_card.dart b/lib/ui/wallet_card.dart index 34b2801..51d84b6 100644 --- a/lib/ui/wallet_card.dart +++ b/lib/ui/wallet_card.dart @@ -4,13 +4,15 @@ import "package:crypto_font_icons/crypto_font_icons.dart"; import 'package:easy_wallet/easy_wallet.dart'; import 'package:easy_wallet/ui/edit_private_key_dialog.dart'; +enum WalletAction { delete, update } + class WalletCard extends StatelessWidget { final EasyWallet wallet; - final Function onDelete; + final Function onUpdate; - WalletCard(this.wallet, this.onDelete) : super ( + WalletCard(this.wallet, this.onUpdate) : super ( key: Key(wallet.address), ) { } @@ -72,7 +74,7 @@ class WalletCard extends StatelessWidget { child: const Icon(Icons.delete), ), onTap: () { - onDelete(); + onUpdate(WalletAction.delete); }, ), ] @@ -166,6 +168,8 @@ class WalletCard extends StatelessWidget { return EditPrivateKeyDialog(wallet); }); + onUpdate(WalletAction.update); + return result; } diff --git a/lib/ui/wallet_list_controller.dart b/lib/ui/wallet_list_controller.dart index 220e0c4..c03df68 100644 --- a/lib/ui/wallet_list_controller.dart +++ b/lib/ui/wallet_list_controller.dart @@ -17,7 +17,7 @@ class WalletListController extends ValueNotifier> { WalletListController operator +(EasyWallet wallet) { value.add(wallet); - walletManager.balance(wallet).whenComplete(() => notifyListeners()); + walletManager.balance(wallet).whenComplete(() => notifyListeners()); // TODO: remove notifyListener _savePreferences(); @@ -25,21 +25,31 @@ class WalletListController extends ValueNotifier> { } WalletListController operator -(String address) { - final int l = value.length; + final int len = value.length; value.removeWhere((e) { return (e.address == address); }); - if (value.length != l) { + if (value.length != len) { _savePreferences(); } return this; } + void updateWallet(EasyWallet wallet) { + for (int i=0; i retrieveBalance() async { for (EasyWallet w in value) { - await walletManager.balance(w); notifyListeners(); + await walletManager.balance(w); notifyListeners(); // TODO: remove notifyListener } } diff --git a/test/preferences_test.dart b/test/preferences_test.dart index 5ef5ab7..8c36dc0 100644 --- a/test/preferences_test.dart +++ b/test/preferences_test.dart @@ -25,14 +25,17 @@ void main() { p.endpoint = "endpoint"; p.appkey = "appkey"; - + p.wallets = [ EasyWallet("wallet1") ]; - expect(json.encoder.convert(p), '{"endpoint":"endpoint","appkey":"appkey","wallets":[{"address":"wallet1"}]}'); + p.wallets[0].privateKey = "privatekey1"; + expect(json.encoder.convert(p), '{"endpoint":"endpoint","appkey":"appkey","wallets":[{"address":"wallet1","privateKey":"privatekey1","mnemonicPhrase":""}]}'); p.wallets.add(EasyWallet("wallet2")); - expect(json.encoder.convert(p), '{"endpoint":"endpoint","appkey":"appkey","wallets":[{"address":"wallet1"},{"address":"wallet2"}]}'); + p.wallets[1].privateKey = "privatekey2"; + p.wallets[1].mnemonic = "mnemonic2"; + expect(json.encoder.convert(p), '{"endpoint":"endpoint","appkey":"appkey","wallets":[{"address":"wallet1","privateKey":"privatekey1","mnemonicPhrase":""},{"address":"wallet2","privateKey":"privatekey2","mnemonicPhrase":"mnemonic2"}]}'); }); test('deserialize preferences', () { @@ -47,10 +50,33 @@ void main() { // // some values // - p = Preferences.fromJson('{"endpoint":"an endpoint","appkey":"an appkey","wallets":[{"address":"a wallet"}]}'); + p = Preferences.fromJson('{"endpoint":"an endpoint","appkey":"an appkey","wallets":[{"address":"a wallet","privateKey":"privatekey","mnemonicPhrase":"mnemonicphrase"}]}'); + expect(p.endpoint, "an endpoint"); + expect(p.appkey, "an appkey"); + expect(p.wallets.length, 1); + expect(p.wallets[0].address, "a wallet"); + expect(p.wallets[0].privateKey, "privatekey"); + expect(p.wallets[0].mnemonic, "mnemonicphrase"); + + // + // empty private key, missing mnemonic + // + p = Preferences.fromJson('{"endpoint":"an endpoint","appkey":"an appkey","wallets":[{"address":"a wallet","privateKey":""}]}'); + expect(p.endpoint, "an endpoint"); + expect(p.appkey, "an appkey"); + expect(p.wallets[0].address, "a wallet"); + expect(p.wallets[0].privateKey, ""); + expect(p.wallets[0].mnemonic, ""); + + // + // missing private key, empty mnemonic + // + p = Preferences.fromJson('{"endpoint":"an endpoint","appkey":"an appkey","wallets":[{"address":"a wallet","mnemonic":""}]}'); expect(p.endpoint, "an endpoint"); expect(p.appkey, "an appkey"); - expect(p.wallets.length, 1); expect(p.wallets[0].address, "a wallet"); + expect(p.wallets[0].address, "a wallet"); + expect(p.wallets[0].privateKey, ""); + expect(p.wallets[0].mnemonic, ""); }); test('deserialize preferences with missing values', () { diff --git a/test/testing_constants.dart b/test/testing_constants.dart index 3de7771..18d4977 100644 --- a/test/testing_constants.dart +++ b/test/testing_constants.dart @@ -9,15 +9,20 @@ const String WALLET2 = "0123456789012345678901234567890123456789"; // print(bytesToHex(random.privateKey)); // print((await random.extractAddress()).hex); // -const String PRIVATE_KEY1 = "008a2b2d41febc2bef749ecec009b86e5fa18753439b28789658eb7b411397abb6"; +const String PRIVATE_KEY1 = "8a2b2d41febc2bef749ecec009b86e5fa18753439b28789658eb7b411397abb6"; const String PRIVATE_KEY2 = "436804c64fea7474fc184d88f8219a3a72c6a9c26321e53babd3c4a8775ed88f"; // // Derived by mnemonic phrase "alert record income curve mercy tree heavy loan hen recycle mean devote" // const String PRIVATE_KEY3 = "c8f12c80b8c0325bb15aa8546f7b0bea133c884da3cfb6f2096368d94192cb37"; +// +// Derived by mnemonic phrase "alert record income curve mercy tree heavy loan hen recycle mean devote" #1 +// +const String PRIVATE_KEY6 = "82b4cd6699cc1aee53b492598def7833a5ca8aae948f817c325548cb3e62c610"; const String ADDRESS1 = "0xc2a6927e5e2f27e5fc7d2611cb0246fb3151f034"; const String ADDRESS2 = "0x496ef9de509d5d4b3f48f33eb75e55c4b3005dc7"; const String ADDRESS3 = "0x1489a7dd02ca2294ed999cfc175050c852851dec"; // associated to PRIVATE_KEY3 const String ADDRESS4 = "0x00000000219ab540356cbb839cbe05303d7705fa"; const String ADDRESS5 = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"; +const String ADDRESS6 = "0xb24f4ad87c027f05c58a71eed50193364c1c4a22"; // associated to PRIVATE_KEY6 diff --git a/test/ui/add_wallet_dialog_test.dart b/test/ui/add_wallet_dialog_test.dart index 4f751fc..860d6f5 100644 --- a/test/ui/add_wallet_dialog_test.dart +++ b/test/ui/add_wallet_dialog_test.dart @@ -96,7 +96,7 @@ void main() { expect(find.text(LABEL_PRIVATE_KEY_HINT), findsNothing); }); - testWidgets('close add wallet dialog by cancel', (WidgetTester tester) async { + testWidgets('cancel closes add wallet dialog', (WidgetTester tester) async { await _showDialog(tester); expect(find.byType(Dialog), findsOneWidget); await tester.tap(find.descendant( diff --git a/test/ui/edit_private_key_dialog_test.dart b/test/ui/edit_private_key_dialog_test.dart index b3d9825..6e33b93 100644 --- a/test/ui/edit_private_key_dialog_test.dart +++ b/test/ui/edit_private_key_dialog_test.dart @@ -23,10 +23,9 @@ void main() { home.state.controller + wallet; tester.state(find.byType(EasyWalletHomePage)).setState(() {}); await tester.pump(); - var button = find.descendant(of: find.byKey(Key(ADDRESS3.substring(2))), matching: find.byIcon(Icons.lock_open)); - - await tester.tap(button); - await tester.pumpAndSettle(); + await tester.tap( + find.descendant(of: find.byKey(Key(ADDRESS3.substring(2))), matching: find.byIcon(Icons.lock_open)) + ); await tester.pumpAndSettle(); return find.byType(Dialog); } @@ -85,6 +84,18 @@ void main() { expect(btnok.enabled, isTrue); }); + testWidgets('valid mnemonic phrase derives the proper private key', (WidgetTester tester) async { + var dialog = await _showDialog(tester); + + var textField = find.descendant(of: dialog, matching: find.byKey(KEY_MNEMONIC_PHRASE)); + await tester.enterText( + textField, + LABEL_MNEMONIC_PHRASE_HINT + ); + await tester.pumpAndSettle(); + + expect(find.descendant(of: dialog, matching: find.textContaining(PRIVATE_KEY3)), findsOneWidget); + }); testWidgets('close the dialog when pressing ok', (WidgetTester tester) async { var dialog = await _showDialog(tester); diff --git a/test/ui/wallet_app_test.dart b/test/ui/wallet_app_test.dart index c8a5823..c04dbd1 100644 --- a/test/ui/wallet_app_test.dart +++ b/test/ui/wallet_app_test.dart @@ -36,7 +36,7 @@ void main() { }); - testWidgets('show add wallet dialog', (WidgetTester tester) async { + testWidgets('tapping + shows add wallet dialog', (WidgetTester tester) async { await tester.pumpWidget(EasyWalletApp()); var button = find.byKey(KEY_ADD_WALLET); @@ -135,5 +135,72 @@ void main() { expect(config["wallets"].length, 1); expect(config["wallets"][0]["address"], WALLET1); }); + + testWidgets('setting the private key updates the configuration', (WidgetTester tester) async { + EasyWalletHomePage home = await givenWlalletManagerStub(tester); + home.state.controller + EasyWallet(ADDRESS1.substring(2)); + tester.state(find.byType(EasyWalletHomePage)).setState(() {}); await tester.pumpAndSettle(); + + // + // open the edit private key dialog + // + await tester.tap( + find.descendant(of: find.byKey(Key(ADDRESS1.substring(2))), matching: find.byIcon(Icons.lock_open)) + ); await tester.pumpAndSettle(); + + // + // Edit the private key + // + await tester.enterText(find.byKey(KEY_PRIVATE_KEY), PRIVATE_KEY1); + await tester.pump(); + + // + // press OK + // + await tester.tap( + find.descendant(of: find.byType(Dialog), matching: find.text("OK")) + ); await tester.pumpAndSettle(); + + ew.readPreferences(); + expect(ew.preferences.wallets.length, 1); + expect(ew.preferences.wallets[0].address, ADDRESS1.substring(2)); + expect(ew.preferences.wallets[0].privateKey, PRIVATE_KEY1); + expect(ew.preferences.wallets[0].mnemonic, ""); + }); + + testWidgets('setting the mnemonic phrase key updates the configuration', (WidgetTester tester) async { + EasyWalletHomePage home = await givenWlalletManagerStub(tester); + home.state.controller + EasyWallet(ADDRESS3.substring(2)); + tester.state(find.byType(EasyWalletHomePage)).setState(() {}); await tester.pumpAndSettle(); + + // + // open the edit private key dialog + // + await tester.tap( + find.descendant(of: find.byKey(Key(ADDRESS3.substring(2))), matching: find.byIcon(Icons.lock_open)) + ); await tester.pumpAndSettle(); + + // + // Edit the mnemonic phrase + // + await tester.enterText( + find.byKey(KEY_MNEMONIC_PHRASE), + LABEL_MNEMONIC_PHRASE_HINT + ); + await tester.pumpAndSettle(); + + // + // press OK + // + await tester.tap( + find.descendant(of: find.byType(Dialog), matching: find.text("OK")) + ); await tester.pumpAndSettle(); + + ew.readPreferences(); + expect(ew.preferences.wallets.length, 1); + expect(ew.preferences.wallets[0].address, ADDRESS3.substring(2)); + expect(ew.preferences.wallets[0].privateKey, PRIVATE_KEY3); + expect(ew.preferences.wallets[0].mnemonic, LABEL_MNEMONIC_PHRASE_HINT); + }); }