mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
* feat(zcash): initial commit - initial work on cw_zcash - use single .db for everything zcash to speed up sync and scanning - implement silent autoshielding of non-orchard funds - use FFI for everything to fetch the data - add support for passphrase by adding extra word to seed phrase - enforce lints on CI for cw_zcash directory - use correct zcash name, and call transparent zcash tZEC - minor cleanups outsite of cw_zcash - gitmodules, gitignore - db debug - fix broken addressPageType in WalletInfo - enable debug options in kDebugMode and kProfileMode * feat: T address rotation (and cache) wip: minor fixes * wip: shield tx list * fix fiat amounts fix derrivation of rotation account addresses screen for zcash block height fix T address shields improvements Amount in disposable T shields UI improvements show pending outgoing tx in tx history * fix null check on passphrase page fix tx showing as pending rename auto shield txs fixed send all to include fee use rotating address in addressForExchange wrap all calls of WarpApi.getLatestHeight in try catch to prevent leaking errors other minor fixes from notion * wallet group debug cache sent tx address wallet T address rotation fixes automatically pick the fee for auto-shield * fix T address cache deserialization fix autoshield icon fix autoshield text getCachedDestinationAddress fix send address cache * address comments from review * wip: iOS fix * fix swap * Allow cakepay payment from zcash wallet * fix: ios (I'm stupid) fix: reorder addresses to make orchard default fix: send all balance * 5.6.6 bump fix: ios apple review add transport error to ignored exceptions * fix: leaving dust behind when sweeping all * Change wallets order * fix: reflect balance of pending out txs fix: restore height support * linux support (disabled) * fix: date picker for zcash on restore screen fix: build script for linux match WarpApi.warpSync args with upstream * fix: linter script * ensure all exchange providers support ZEC (#2802) * ensure all exchange providers support ZEC * remove zaddr and tzec currencies and refactor providers * Update lib/exchange/provider/near_Intents_exchange_provider.dart * add back old zcash currencies for backward compatibility, thanks Czarek * minor fix [skip ci] --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * Update android/app/src/main/AndroidManifestBase.xml [skip ci] * Update ios/Runner/InfoBase.plist [skip ci] * fix: remove unused code fix: macos fix: disable on linux and macos * update build numbers [skip ci] * Add zcash to birdpay --------- Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net> Co-authored-by: Serhii <borodenko.sv@gmail.com>
414 lines
15 KiB
Dart
414 lines
15 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:cake_wallet/entities/seed_type.dart';
|
|
import 'package:cake_wallet/reactions/wallet_utils.dart';
|
|
import 'package:cake_wallet/wallet_types.g.dart';
|
|
import 'package:cw_core/currency_for_wallet_type.dart';
|
|
import 'package:cw_core/wallet_type.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:cake_wallet/main.dart' as app;
|
|
|
|
import '../robots/create_pin_welcome_page_robot.dart';
|
|
import '../robots/new_wallet_page_robot.dart';
|
|
import '../robots/new_wallet_type_page_robot.dart';
|
|
import '../robots/pre_seed_page_robot.dart';
|
|
import '../robots/restore_from_seed_or_key_robot.dart';
|
|
import '../robots/restore_options_page_robot.dart';
|
|
import '../robots/seed_verification_page_robot.dart';
|
|
import '../robots/setup_pin_code_robot.dart';
|
|
import '../robots/wallet_group_description_page_robot.dart';
|
|
import '../robots/wallet_list_page_robot.dart';
|
|
import '../robots/wallet_seed_page_robot.dart';
|
|
import '../robots/welcome_page_robot.dart';
|
|
import 'common_test_cases.dart';
|
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
|
|
|
import 'common_test_constants.dart';
|
|
|
|
class CommonTestFlows {
|
|
CommonTestFlows(this._tester)
|
|
: _commonTestCases = CommonTestCases(_tester),
|
|
_welcomePageRobot = WelcomePageRobot(_tester),
|
|
_preSeedPageRobot = PreSeedPageRobot(_tester),
|
|
_setupPinCodeRobot = SetupPinCodeRobot(_tester),
|
|
_newWalletPageRobot = NewWalletPageRobot(_tester),
|
|
_walletSeedPageRobot = WalletSeedPageRobot(_tester),
|
|
_walletListPageRobot = WalletListPageRobot(_tester),
|
|
_newWalletTypePageRobot = NewWalletTypePageRobot(_tester),
|
|
_restoreOptionsPageRobot = RestoreOptionsPageRobot(_tester),
|
|
_seedVerificationPageRobot = SeedVerificationPageRobot(_tester),
|
|
_createPinWelcomePageRobot = CreatePinWelcomePageRobot(_tester),
|
|
_restoreFromSeedOrKeysPageRobot = RestoreFromSeedOrKeysPageRobot(_tester),
|
|
_walletGroupDescriptionPageRobot = WalletGroupDescriptionPageRobot(_tester);
|
|
|
|
final WidgetTester _tester;
|
|
final CommonTestCases _commonTestCases;
|
|
|
|
final WelcomePageRobot _welcomePageRobot;
|
|
final PreSeedPageRobot _preSeedPageRobot;
|
|
final SetupPinCodeRobot _setupPinCodeRobot;
|
|
final NewWalletPageRobot _newWalletPageRobot;
|
|
final WalletSeedPageRobot _walletSeedPageRobot;
|
|
final WalletListPageRobot _walletListPageRobot;
|
|
final NewWalletTypePageRobot _newWalletTypePageRobot;
|
|
final RestoreOptionsPageRobot _restoreOptionsPageRobot;
|
|
final CreatePinWelcomePageRobot _createPinWelcomePageRobot;
|
|
final SeedVerificationPageRobot _seedVerificationPageRobot;
|
|
final RestoreFromSeedOrKeysPageRobot _restoreFromSeedOrKeysPageRobot;
|
|
final WalletGroupDescriptionPageRobot _walletGroupDescriptionPageRobot;
|
|
|
|
//* ========== Handles flow to start the app afresh and accept disclaimer =============
|
|
Future<void> startAppFlow(Key key) async {
|
|
await app.main(topLevelKey: key);
|
|
|
|
await _tester.pump(Duration(seconds: 2));
|
|
|
|
// // --------- Disclaimer Page ------------
|
|
// // Tap checkbox to accept disclaimer
|
|
// await _disclaimerPageRobot.tapDisclaimerCheckbox();
|
|
|
|
// // Tap accept button
|
|
// await _disclaimerPageRobot.tapAcceptButton();
|
|
}
|
|
|
|
//* ========== Handles flow from welcome to creating a new wallet ===============
|
|
Future<void> welcomePageToCreateNewWalletFlow(
|
|
WalletType walletTypeToCreate,
|
|
List<int> walletPin,
|
|
) async {
|
|
await _welcomeToCreateWalletPath(walletTypeToCreate, walletPin);
|
|
|
|
await _generateNewWalletDetails();
|
|
|
|
await _confirmPreSeedInfo();
|
|
|
|
await _confirmWalletDetails();
|
|
|
|
await _verifyWalletSeed();
|
|
}
|
|
|
|
//* ========== Handles flow from welcome to restoring wallet from seeds ===============
|
|
Future<void> welcomePageToRestoreWalletThroughSeedsFlow(
|
|
WalletType walletTypeToRestore,
|
|
String walletSeed,
|
|
List<int> walletPin,
|
|
) async {
|
|
await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin);
|
|
await _restoreFromSeeds(walletTypeToRestore, walletSeed);
|
|
}
|
|
|
|
//* ========== Handles flow from welcome to restoring wallet from keys ===============
|
|
Future<void> welcomePageToRestoreWalletThroughKeysFlow(
|
|
WalletType walletTypeToRestore,
|
|
List<int> walletPin,
|
|
) async {
|
|
await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin);
|
|
await _restoreFromKeys();
|
|
}
|
|
|
|
void confirmAllAvailableWalletTypeIconsDisplayCorrectly() {
|
|
for (var walletType in availableWalletTypes) {
|
|
final imageUrl = walletTypeToCryptoCurrency(walletType).iconPath;
|
|
|
|
final walletIconFinder = find.image(
|
|
Image.asset(
|
|
imageUrl!,
|
|
width: 32,
|
|
height: 32,
|
|
).image,
|
|
);
|
|
|
|
expect(walletIconFinder, findsAny);
|
|
}
|
|
}
|
|
|
|
//* ========== Handles creating new wallet flow from wallet list/menu ===============
|
|
Future<void> createNewWalletFromWalletMenu(WalletType walletTypeToCreate) async {
|
|
_tester.printToConsole('Creating ${walletTypeToCreate.name} Wallet');
|
|
|
|
await _tester.pumpAndSettle(Duration(milliseconds: 1000));
|
|
|
|
await _walletListPageRobot.navigateToCreateNewWalletPage();
|
|
await _commonTestCases.defaultSleepTime();
|
|
|
|
await _selectWalletTypeForWallet(walletTypeToCreate);
|
|
await _commonTestCases.defaultSleepTime();
|
|
|
|
// ---- Wallet Group/New Seed Implementation Comes here
|
|
await _walletGroupDescriptionPageFlow(true, walletTypeToCreate);
|
|
|
|
await _generateNewWalletDetails();
|
|
|
|
await _confirmPreSeedInfo();
|
|
|
|
await _confirmWalletDetails();
|
|
|
|
await _verifyWalletSeed();
|
|
|
|
await _commonTestCases.defaultSleepTime();
|
|
}
|
|
|
|
Future<void> _walletGroupDescriptionPageFlow(bool isNewSeed, WalletType walletType) async {
|
|
if (!isBIP39Wallet(walletType)) return;
|
|
|
|
await _walletGroupDescriptionPageRobot.isWalletGroupDescriptionPage();
|
|
|
|
if (isNewSeed) {
|
|
await _walletGroupDescriptionPageRobot.navigateToCreateNewSeedPage();
|
|
} else {
|
|
await _walletGroupDescriptionPageRobot.navigateToChooseWalletGroup();
|
|
}
|
|
}
|
|
|
|
//* ========== Handles restore wallet flow from wallet list/menu ===============
|
|
Future<void> restoreWalletFromWalletMenu(WalletType walletType, String walletSeed) async {
|
|
_tester.printToConsole('Restoring ${walletType.name} Wallet');
|
|
await _walletListPageRobot.navigateToRestoreWalletOptionsPage();
|
|
await _commonTestCases.defaultSleepTime();
|
|
|
|
if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
|
|
if (!Platform.isLinux) await _commonTestCases.defaultSleepTime();
|
|
|
|
await _selectWalletTypeForWallet(walletType);
|
|
await _commonTestCases.defaultSleepTime();
|
|
|
|
await _restoreFromSeeds(walletType, walletSeed);
|
|
await _commonTestCases.defaultSleepTime();
|
|
}
|
|
|
|
//* ========== Handles setting up pin code for wallet on first install ===============
|
|
Future<void> setupPinCodeForWallet(List<int> pin) async {
|
|
if (Platform.isLinux) return;
|
|
// ----------- SetupPinCode Page -------------
|
|
// Confirm initial defaults - Widgets to be displayed etc
|
|
await _setupPinCodeRobot.isSetupPinCodePage();
|
|
|
|
await _setupPinCodeRobot.enterPinCode(pin);
|
|
await _setupPinCodeRobot.enterPinCode(pin);
|
|
await _setupPinCodeRobot.tapSuccessButton();
|
|
}
|
|
|
|
Future<void> _welcomeToCreateWalletPath(
|
|
WalletType walletTypeToCreate,
|
|
List<int> pin,
|
|
) async {
|
|
await _createPinWelcomePageRobot.tapSetAPinButton();
|
|
|
|
await setupPinCodeForWallet(pin);
|
|
|
|
await _welcomePageRobot.navigateToCreateNewWalletPage();
|
|
|
|
await _selectWalletTypeForWallet(walletTypeToCreate);
|
|
|
|
if (_welcomePageRobot.hasNewSingleSeedButton()) {
|
|
await _welcomePageRobot.tapNewSingleSeed();
|
|
}
|
|
}
|
|
|
|
Future<void> _welcomeToRestoreFromSeedsOrKeysPath(
|
|
WalletType walletTypeToRestore,
|
|
List<int> pin,
|
|
) async {
|
|
await _createPinWelcomePageRobot.tapSetAPinButton();
|
|
|
|
await setupPinCodeForWallet(pin);
|
|
|
|
await _welcomePageRobot.navigateToRestoreWalletPage();
|
|
|
|
if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
|
|
|
|
await _selectWalletTypeForWallet(walletTypeToRestore);
|
|
}
|
|
|
|
//* ============ Handles New Wallet Type Page ==================
|
|
Future<void> _selectWalletTypeForWallet(WalletType type) async {
|
|
// ----------- NewWalletType Page -------------
|
|
_tester.printToConsole('Selecting wallet type: ${type.name}');
|
|
|
|
await _tester.pumpAndSettle(Duration(milliseconds: 1000));
|
|
|
|
await _newWalletTypePageRobot.findParticularWalletTypeInScrollableList(type);
|
|
|
|
_tester.printToConsole('Tapping wallet type: ${type.name}');
|
|
await _newWalletTypePageRobot.selectWalletType(type);
|
|
await _tester.pumpAndSettle(Duration(milliseconds: 500));
|
|
|
|
_tester.printToConsole('Pressing next button');
|
|
await _newWalletTypePageRobot.onNextButtonPressed();
|
|
|
|
await _tester.pumpAndSettle(Duration(milliseconds: 2000));
|
|
|
|
_tester.printToConsole('Wallet type selection completed for: ${type.name}');
|
|
}
|
|
|
|
//* ============ Handles New Wallet Page ==================
|
|
Future<void> _generateNewWalletDetails() async {
|
|
_tester.printToConsole('Attempting to find NewWalletPage...');
|
|
|
|
await _tester.pumpAndSettle(Duration(milliseconds: 1000));
|
|
|
|
await _newWalletPageRobot.isNewWalletPage();
|
|
_tester.printToConsole('NewWalletPage found successfully');
|
|
|
|
await _newWalletPageRobot.generateWalletName();
|
|
|
|
if (Platform.isLinux) {
|
|
// manual pin input
|
|
await _restoreFromSeedOrKeysPageRobot
|
|
.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
|
|
await _restoreFromSeedOrKeysPageRobot
|
|
.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
|
|
}
|
|
|
|
await _newWalletPageRobot.onNextButtonPressed();
|
|
}
|
|
|
|
//* ============ Handles Pre Seed Page =====================
|
|
Future<void> _confirmPreSeedInfo() async {
|
|
await _preSeedPageRobot.isPreSeedPage();
|
|
|
|
await _preSeedPageRobot.onConfirmButtonPressed();
|
|
}
|
|
|
|
//* ============ Handles Wallet Seed Page ==================
|
|
Future<void> _confirmWalletDetails() async {
|
|
await _walletSeedPageRobot.isWalletSeedPage();
|
|
|
|
_walletSeedPageRobot.confirmWalletDetailsDisplayCorrectly();
|
|
|
|
_walletSeedPageRobot.confirmWalletSeedReminderDisplays();
|
|
|
|
// await _walletSeedPageRobot.onCopySeedsButtonPressed();
|
|
|
|
await _walletSeedPageRobot.onVerifySeedButtonPressed();
|
|
}
|
|
|
|
//* ============ Handles Wallet Seed Verification Page ==================
|
|
|
|
Future<void> _verifyWalletSeed() async {
|
|
await _seedVerificationPageRobot.isSeedVerificationPage();
|
|
|
|
_seedVerificationPageRobot.hasTitle();
|
|
|
|
await _seedVerificationPageRobot.verifyWalletSeeds();
|
|
}
|
|
|
|
//* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action
|
|
Future<void> _restoreFromSeeds(WalletType type, String walletSeed) async {
|
|
// ----------- RestoreFromSeedOrKeys Page -------------
|
|
|
|
await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions();
|
|
await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore(walletSeed);
|
|
|
|
final numberOfWords = walletSeed.split(' ').length;
|
|
|
|
if (numberOfWords == 25 && (type == WalletType.monero)) {
|
|
await _restoreFromSeedOrKeysPageRobot
|
|
.chooseSeedTypeForMoneroOrWowneroWallets(MoneroSeedType.legacy);
|
|
|
|
// Using a constant value of 2831400 for the blockheight as its the restore blockheight for our testing wallet
|
|
await _restoreFromSeedOrKeysPageRobot
|
|
.enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight);
|
|
}
|
|
|
|
if (Platform.isLinux) {
|
|
// manual pin input
|
|
await _restoreFromSeedOrKeysPageRobot
|
|
.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
|
|
await _restoreFromSeedOrKeysPageRobot
|
|
.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
|
|
}
|
|
|
|
await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
|
|
}
|
|
|
|
//* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Keys Action
|
|
Future<void> _restoreFromKeys() async {
|
|
await _commonTestCases.swipePage();
|
|
await _commonTestCases.defaultSleepTime();
|
|
|
|
await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions(
|
|
isSeedFormEntry: false,
|
|
);
|
|
|
|
await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore('');
|
|
await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
|
|
}
|
|
|
|
//* ====== Utility Function to get test wallet seeds for each wallet type ========
|
|
String getWalletSeedsByWalletType(WalletType walletType) {
|
|
switch (walletType) {
|
|
case WalletType.monero:
|
|
return secrets.moneroTestWalletSeeds;
|
|
case WalletType.bitcoin:
|
|
return secrets.bitcoinTestWalletSeeds;
|
|
case WalletType.ethereum:
|
|
return secrets.ethereumTestWalletSeeds;
|
|
case WalletType.litecoin:
|
|
return secrets.litecoinTestWalletSeeds;
|
|
case WalletType.bitcoinCash:
|
|
return secrets.bitcoinCashTestWalletSeeds;
|
|
case WalletType.polygon:
|
|
return secrets.polygonTestWalletSeeds;
|
|
case WalletType.solana:
|
|
return secrets.solanaTestWalletSeeds;
|
|
case WalletType.base:
|
|
return secrets.baseTestWalletSeeds;
|
|
case WalletType.arbitrum:
|
|
return secrets.arbitrumTestWalletSeeds;
|
|
case WalletType.tron:
|
|
return secrets.tronTestWalletSeeds;
|
|
case WalletType.nano:
|
|
return secrets.nanoTestWalletSeeds;
|
|
case WalletType.wownero:
|
|
return secrets.wowneroTestWalletSeeds;
|
|
case WalletType.zano:
|
|
return secrets.zanoTestWalletSeeds;
|
|
case WalletType.decred:
|
|
return secrets.decredTestWalletSeeds;
|
|
case WalletType.dogecoin:
|
|
return secrets.dogeTestWalletSeeds;
|
|
case WalletType.zcash:
|
|
return secrets.zcashTestWalletSeeds;
|
|
case WalletType.none:
|
|
case WalletType.haven:
|
|
case WalletType.banano:
|
|
throw Exception("Unable to get seeds for ${walletType}");
|
|
}
|
|
}
|
|
|
|
//* ====== Utility Function to get test receive address for each wallet type ========
|
|
String getReceiveAddressByWalletType(WalletType walletType) {
|
|
switch (walletType) {
|
|
case WalletType.monero:
|
|
return secrets.moneroTestWalletReceiveAddress;
|
|
case WalletType.bitcoin:
|
|
return secrets.bitcoinTestWalletReceiveAddress;
|
|
case WalletType.ethereum:
|
|
return secrets.ethereumTestWalletReceiveAddress;
|
|
case WalletType.litecoin:
|
|
return secrets.litecoinTestWalletReceiveAddress;
|
|
case WalletType.bitcoinCash:
|
|
return secrets.bitcoinCashTestWalletReceiveAddress;
|
|
case WalletType.polygon:
|
|
return secrets.polygonTestWalletReceiveAddress;
|
|
case WalletType.base:
|
|
return secrets.baseTestWalletReceiveAddress;
|
|
case WalletType.arbitrum:
|
|
return secrets.arbitrumTestWalletReceiveAddress;
|
|
case WalletType.solana:
|
|
return secrets.solanaTestWalletReceiveAddress;
|
|
case WalletType.tron:
|
|
return secrets.tronTestWalletReceiveAddress;
|
|
case WalletType.nano:
|
|
return secrets.nanoTestWalletReceiveAddress;
|
|
case WalletType.wownero:
|
|
return secrets.wowneroTestWalletReceiveAddress;
|
|
default:
|
|
return '';
|
|
}
|
|
}
|
|
}
|