|
| 1 | +import 'dart:async'; |
| 2 | +import 'dart:core'; |
| 3 | +import 'dart:core' as core; |
| 4 | +import 'dart:io'; |
| 5 | +import 'dart:math'; |
| 6 | + |
| 7 | +import 'package:flutter_test/flutter_test.dart'; |
| 8 | +import 'package:hive/hive.dart'; |
| 9 | +import 'package:hive_test/hive_test.dart'; |
| 10 | +import 'package:mockito/annotations.dart'; |
| 11 | +import 'package:mockito/mockito.dart'; |
| 12 | + |
| 13 | +import 'package:cw_core/monero_amount_format.dart'; |
| 14 | +import 'package:cw_core/node.dart'; |
| 15 | +import 'package:cw_core/pending_transaction.dart'; |
| 16 | +import 'package:cw_core/unspent_coins_info.dart'; |
| 17 | +import 'package:cw_core/wallet_base.dart'; |
| 18 | +import 'package:cw_core/wallet_credentials.dart'; |
| 19 | +import 'package:cw_core/wallet_info.dart'; |
| 20 | +import 'package:cw_core/wallet_service.dart'; |
| 21 | +import 'package:cw_core/wallet_type.dart'; |
| 22 | +import 'package:cw_monero/api/wallet.dart'; |
| 23 | +import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager; |
| 24 | +import 'package:cw_monero/pending_monero_transaction.dart'; |
| 25 | +import 'package:cw_monero/monero_wallet.dart'; |
| 26 | +import 'package:flutter/material.dart'; |
| 27 | +import 'package:flutter/services.dart'; |
| 28 | +import 'package:flutter_libmonero/core/key_service.dart'; |
| 29 | +import 'package:flutter_libmonero/core/wallet_creation_service.dart'; |
| 30 | +import 'package:flutter_libmonero/view_model/send/output.dart'; |
| 31 | +import 'package:flutter_libmonero/monero/monero.dart'; |
| 32 | +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; |
| 33 | +import 'package:hive/hive.dart'; |
| 34 | +import 'package:path_provider/path_provider.dart'; |
| 35 | +import 'package:shared_preferences/shared_preferences.dart'; |
| 36 | +import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; |
| 37 | + |
| 38 | +import 'package:stackwallet/services/wallets.dart'; |
| 39 | + |
| 40 | +import 'dart:developer' as developer; |
| 41 | + |
| 42 | +// TODO trim down to the minimum imports above |
| 43 | + |
| 44 | +import 'monero_wallet_test_data.dart'; |
| 45 | + |
| 46 | +//FlutterSecureStorage? storage; |
| 47 | +FakeSecureStorage? storage; |
| 48 | +WalletService? walletService; |
| 49 | +SharedPreferences? prefs; |
| 50 | +KeyService? keysStorage; |
| 51 | +MoneroWalletBase? walletBase; |
| 52 | +late WalletCreationService _walletCreationService; |
| 53 | +dynamic _walletInfoSource; |
| 54 | +Wallets? walletsService; |
| 55 | + |
| 56 | +String path = ''; |
| 57 | + |
| 58 | +String name = 'namee${Random().nextInt(10000000)}'; |
| 59 | +int nettype = 0; |
| 60 | +WalletType type = WalletType.monero; |
| 61 | + |
| 62 | +@GenerateMocks([]) |
| 63 | +void main() async { |
| 64 | + storage = FakeSecureStorage(); |
| 65 | + prefs = await SharedPreferences.getInstance(); |
| 66 | + keysStorage = KeyService(storage!); |
| 67 | + WalletInfo walletInfo = WalletInfo.external( |
| 68 | + id: '', |
| 69 | + name: '', |
| 70 | + type: type, |
| 71 | + isRecovery: false, |
| 72 | + restoreHeight: 0, |
| 73 | + date: DateTime.now(), |
| 74 | + path: '', |
| 75 | + address: '', |
| 76 | + dirPath: ''); |
| 77 | + late WalletCredentials credentials; |
| 78 | + |
| 79 | + WidgetsFlutterBinding.ensureInitialized(); |
| 80 | + Directory appDir = (await getApplicationDocumentsDirectory()); |
| 81 | + if (Platform.isIOS) { |
| 82 | + appDir = (await getLibraryDirectory()); |
| 83 | + } |
| 84 | + await Hive.close(); |
| 85 | + Hive.init(appDir.path); |
| 86 | + Hive.registerAdapter(NodeAdapter()); |
| 87 | + Hive.registerAdapter(WalletInfoAdapter()); |
| 88 | + Hive.registerAdapter(WalletTypeAdapter()); |
| 89 | + Hive.registerAdapter(UnspentCoinsInfoAdapter()); |
| 90 | + |
| 91 | + monero.onStartup(); |
| 92 | + _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName); |
| 93 | + walletService = monero.createMoneroWalletService(_walletInfoSource); |
| 94 | + |
| 95 | + group("Mainnet tests", () { |
| 96 | + setUp(() async { |
| 97 | + try { |
| 98 | + // if (name?.isEmpty ?? true) { |
| 99 | + // name = await generateName(); |
| 100 | + // } |
| 101 | + final dirPath = await pathForWalletDir(name: name, type: type); |
| 102 | + path = await pathForWallet(name: name, type: type); |
| 103 | + credentials = |
| 104 | + // // creating a new wallet |
| 105 | + // monero.createMoneroNewWalletCredentials( |
| 106 | + // name: name, language: "English"); |
| 107 | + // restoring a previous wallet |
| 108 | + monero.createMoneroRestoreWalletFromSeedCredentials( |
| 109 | + name: name, height: 2580000, mnemonic: testMnemonic); |
| 110 | + |
| 111 | + walletInfo = WalletInfo.external( |
| 112 | + id: WalletBase.idFor(name, type), |
| 113 | + name: name, |
| 114 | + type: type, |
| 115 | + isRecovery: false, |
| 116 | + restoreHeight: credentials.height ?? 0, |
| 117 | + date: DateTime.now(), |
| 118 | + path: path, |
| 119 | + address: "", |
| 120 | + dirPath: dirPath); |
| 121 | + credentials.walletInfo = walletInfo; |
| 122 | + |
| 123 | + _walletCreationService = WalletCreationService( |
| 124 | + secureStorage: storage, |
| 125 | + sharedPreferences: prefs, |
| 126 | + walletService: walletService, |
| 127 | + keyService: keysStorage, |
| 128 | + ); |
| 129 | + _walletCreationService.changeWalletType(); |
| 130 | + } catch (e, s) { |
| 131 | + print(e); |
| 132 | + print(s); |
| 133 | + } |
| 134 | + }); |
| 135 | + |
| 136 | + test("Test mainnet address generation from seed", () async { |
| 137 | + final wallet = await |
| 138 | + // _walletCreationService.create(credentials); |
| 139 | + _walletCreationService.restoreFromSeed(credentials); |
| 140 | + walletInfo.address = wallet.walletAddresses.address; |
| 141 | + //print(walletInfo.address); |
| 142 | + |
| 143 | + await _walletInfoSource.add(walletInfo); |
| 144 | + walletBase?.close(); |
| 145 | + walletBase = wallet as MoneroWalletBase; |
| 146 | + //print("${walletBase?.seed}"); |
| 147 | + |
| 148 | + // print(walletBase); |
| 149 | + // loggerPrint(walletBase.toString()); |
| 150 | + // loggerPrint("name: ${walletBase!.name} seed: ${walletBase!.seed} id: " |
| 151 | + // "${walletBase!.id} walletinfo: ${toStringForinfo(walletBase!.walletInfo)} type: ${walletBase!.type} balance: " |
| 152 | + // "${walletBase!.balance.entries.first.value.available} currency: ${walletBase!.currency}"); |
| 153 | + |
| 154 | + expect(walletInfo.address, mainnetTestData[0][0]); |
| 155 | + expect( |
| 156 | + await walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]); |
| 157 | + expect( |
| 158 | + await walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]); |
| 159 | + expect( |
| 160 | + await walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]); |
| 161 | + expect( |
| 162 | + await walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]); |
| 163 | + expect( |
| 164 | + await walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]); |
| 165 | + expect( |
| 166 | + await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]); |
| 167 | + }); |
| 168 | + }); |
| 169 | + /* |
| 170 | + // 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 |
| 171 | + group("Mainnet wallet deletion test", () { |
| 172 | + test("Test mainnet wallet existence", () { |
| 173 | + expect(monero_wallet_manager.isWalletExistSync(path: path), true); |
| 174 | + }); |
| 175 | +
|
| 176 | + test("Test mainnet wallet deletion", () { |
| 177 | + // Remove wallet from wallet service |
| 178 | + walletService?.remove(name); |
| 179 | + walletsService?.removeWallet(walletId: name); |
| 180 | + expect(monero_wallet_manager.isWalletExistSync(path: path), false); |
| 181 | + }); |
| 182 | + }); |
| 183 | +
|
| 184 | + group("Mainnet node tests", () { |
| 185 | + test("Test mainnet node connection", () async { |
| 186 | + await walletBase?.connectToNode( |
| 187 | + node: Node( |
| 188 | + uri: "monero-stagenet.stackwallet.com:38081", |
| 189 | + type: WalletType.moneroStageNet)); |
| 190 | + await walletBase!.rescan( |
| 191 | + height: |
| 192 | + credentials.height); // Probably shouldn't be rescanning from 0... |
| 193 | + await walletBase!.getNodeHeight(); |
| 194 | + int height = await walletBase!.getNodeHeight(); |
| 195 | + print('height: $height'); |
| 196 | + bool connected = await walletBase!.isConnected(); |
| 197 | + print('connected: $connected'); |
| 198 | +
|
| 199 | + //expect... |
| 200 | + }); |
| 201 | + }); |
| 202 | + */ |
| 203 | + |
| 204 | + // TODO test deletion of wallets ... and delete them |
| 205 | +} |
| 206 | + |
| 207 | +Future<String> pathForWalletDir( |
| 208 | + {required String name, required WalletType type}) async { |
| 209 | + Directory root = (await getApplicationDocumentsDirectory()); |
| 210 | + if (Platform.isIOS) { |
| 211 | + root = (await getLibraryDirectory()); |
| 212 | + } |
| 213 | + final prefix = walletTypeToString(type).toLowerCase(); |
| 214 | + final walletsDir = Directory('${root.path}/wallets'); |
| 215 | + final walletDire = Directory('${walletsDir.path}/$prefix/$name'); |
| 216 | + |
| 217 | + if (!walletDire.existsSync()) { |
| 218 | + walletDire.createSync(recursive: true); |
| 219 | + } |
| 220 | + |
| 221 | + return walletDire.path; |
| 222 | +} |
| 223 | + |
| 224 | +Future<String> pathForWallet( |
| 225 | + {required String name, required WalletType type}) async => |
| 226 | + await pathForWalletDir(name: name, type: type) |
| 227 | + .then((path) => path + '/$name'); |
0 commit comments