CakeWallet/lib/view_model/wallet_restore_view_model.dart
Omar Hatem a34cf24897
Remove haven (#2085)
* decred: Add decred. (#1322)

* multi: Add initial decred screens. (#1165)

Use a mock libwallet for now.

* cw_decred: add libdcrwallet dependency and link library for android, ios and macos (#1240)

* change cw_decred from package to plugin

* add libdcrwallet dependency and link library for android, ios and macos

* remove spvwallet, make some libdcrwallet fns async, light refactor

* libdcrwallet: use json payload returns

* use specific libwallet commit hash

* decred: fix Rename wallet.

---------

Co-authored-by: JoeGruff <joegruffins@gmail.com>

* decred: Add sync.

* decred: Add send transaction.

* decred: Fix fee estimation.

* decred: List transactions.

* decred: Add rescan.

* decred: Sign message.

* decred: Add new addr and addrs.

* decred: Add change wallet pass.

* decred: Add restore from seed.

* decred: Add watching only wallets.

* decred: Enable mainnet.

* decred: Allow using blank node address.

This allows a persistent peer to be unset, falling back to decred
seeders.

* decred: Rescan from wallet birthday.

* add and update macos build scripts, update build readme, gitignore macos project.pbxproj

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>

* multi: hide decred rescan page if it's not ready

-  move hasRescan method to WalletBase and implement for decred

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>

* cw_decred: fix bug where decred wallets are not loaded after app restart

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>

* add buy and sell for decred via onramp

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>

* bug-fix: account for other send outputs that are part of the same tx

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>

* decred: Return address with no peers.

* decred: Update pubspec.

* decred: Add verify message.

* upgrade hive_generator dep in cw_decred

* decred: Clean up code.

---------

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>
Co-authored-by: Wisdom Arerosuoghene <wisdom.arerosuoghene@gmail.com>
Co-authored-by: Philemon Ukane <ukanephilemon@gmail.com>

* fix extracted addresses not used
fix conflicts with main

* remove print [skip ci]

* minor formatting

* fix initial migration version

* add build decred script to workflow

* install go before build decred
fix switch cases

* trial 2 to fix decred build

* re-install go

* revert build script change

* refactor/clean nodes functions

* Fix address book issue
Fix send ALL (to be continued with the fees point)

* Fix transactions display issues
Add missing file

* Fix unconfirmed balance not displayed
Change Wallet order
Minor cleanup

* Fix workflow

* Fix workflow

* Fix workflow

* test

* hardcode path for now

* fix + cleanup decred build script to work on mac and linux

* Update decred build script

* Run actions on pull requests, extract commit message

* run after checkout

* add safe directory

* Get commit message from base.sha instead of last commit

* base -> head

* Do not merge main branch into pr

* [skip slack] [run tests] clone by sha

* Proper name for decred library in the build script

* Throw an error when ANDROID_HOME or ANDROID_NDK_VERSION is missing

* Fix conflicts with main

* minor code enhancement

* decred: Add used address history.  (#1941)

* decred: Update pubspec.

* decred testnet

* decred: Add used address history.

* decred: Remove default node list.

* populate transaction history before sync begins

* decred: Add some awaits.

* decred: Fix send all.

* decred: Add clang export to build script.

* decred: Update logo colors.

* cleanup cw_decred.dart

* make decred wallet addresses selectable in receive page

* decred: Always set default addr when used.

* decred: Add back default node list.

* decred: Allow creating addresses manually.

---------

Co-authored-by: Wisdom Arerosuoghene <wisdom.arerosuoghene@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* minor fixes and cleanup

* minor fix, feel free to test now

* - Fix transaction details
- Fix Nodes
- Add processing sync status

* Add decred info card

* push missing file

* Add missing text for decred info card

* minor: change docs link [skip ci]

* decred: Update derivation info. (#2013)

* decred: Update derivation info.

* decred: Allow unsynced unused addresses.

* decred: Update dcrwallet dep to 4.3.0.

* Merge main and fix conflicts

* Merge main and fix conflicts

* decred: Fix background sync panic. (#2080)

* decred: Run libwallet in isolate. (#2077)

* decred: Fix contact save inquiry. (#2083)

Also fix tx time and the fee shown on pending transactions.

* Disable send button in view only decred wallets

* - Fix frozen coins
- Add URI support
- Fix fees in tx details
- Handle empty coins send
- Handle wallets in address book

* Merge main

* remove print [skip ci]

* Fix restore from QR

* minor improvement for QR restore

* Remove Haven Wallet

* Remove haven scripts

* minor fixes [skip ci]

* decred: Get slip44 addrs before sync completes. (#2092)

* - Fix loading wallet more than one time
- Fix minor UI issue

* fix merge issue

* fix merge issue

---------

Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>
Co-authored-by: JoeGruffins <34998433+JoeGruffins@users.noreply.github.com>
Co-authored-by: Wisdom Arerosuoghene <wisdom.arerosuoghene@gmail.com>
Co-authored-by: Philemon Ukane <ukanephilemon@gmail.com>
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
2025-03-21 04:52:05 +02:00

301 lines
11 KiB
Dart

import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:cake_wallet/core/generate_wallet_password.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/decred/decred.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cake_wallet/zano/zano.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_type.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
part 'wallet_restore_view_model.g.dart';
class WalletRestoreViewModel = WalletRestoreViewModelBase with _$WalletRestoreViewModel;
abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource, SeedSettingsViewModel seedSettingsViewModel,
{required WalletType type, this.restoredWallet})
: hasSeedLanguageSelector =
type == WalletType.monero || type == WalletType.haven || type == WalletType.wownero,
hasBlockchainHeightLanguageSelector =
type == WalletType.monero || type == WalletType.haven || type == WalletType.wownero,
hasRestoreFromPrivateKey = type == WalletType.ethereum ||
type == WalletType.polygon ||
type == WalletType.nano ||
type == WalletType.banano ||
type == WalletType.solana ||
type == WalletType.tron,
isButtonEnabled = false,
mode = restoredWallet?.restoreMode ?? WalletRestoreMode.seed,
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
type: type, isRecovery: true) {
switch (type) {
case WalletType.monero:
availableModes = WalletRestoreMode.values;
break;
case WalletType.nano:
case WalletType.banano:
case WalletType.solana:
case WalletType.tron:
case WalletType.wownero:
case WalletType.haven:
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.decred:
availableModes = [WalletRestoreMode.seed, WalletRestoreMode.keys];
break;
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.bitcoinCash:
case WalletType.zano:
case WalletType.none:
availableModes = [WalletRestoreMode.seed];
break;
}
walletCreationService.changeWalletType(type: type);
if (restoredWallet != null) {
if(restoredWallet!.restoreMode == WalletRestoreMode.seed) {
seedSettingsViewModel.setPassphrase(restoredWallet!.passphrase);
}
}
}
static const moneroSeedMnemonicLength = 25;
static const decredSeedMnemonicLength = 15;
late List<WalletRestoreMode> availableModes;
final bool hasSeedLanguageSelector;
final bool hasBlockchainHeightLanguageSelector;
final bool hasRestoreFromPrivateKey;
final RestoredWallet? restoredWallet;
@observable
WalletRestoreMode mode;
@observable
bool isButtonEnabled;
@override
WalletCredentials getCredentials(dynamic options) {
final password = walletPassword ?? generateWalletPassword();
String? passphrase = options['passphrase'] as String?;
final height = options['height'] as int? ?? 0;
name = options['name'] as String;
DerivationInfo? derivationInfo = options["derivationInfo"] as DerivationInfo?;
if (mode == WalletRestoreMode.seed) {
final seed = options['seed'] as String;
switch (type) {
case WalletType.monero:
return monero!.createMoneroRestoreWalletFromSeedCredentials(
name: name, height: height, mnemonic: seed, password: password, passphrase: passphrase??'');
case WalletType.bitcoin:
case WalletType.litecoin:
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
derivationType: derivationInfo!.derivationType!,
derivationPath: derivationInfo.derivationPath!,
);
case WalletType.ethereum:
return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.bitcoinCash:
return bitcoinCash!.createBitcoinCashRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.nano:
case WalletType.banano:
return nano!.createNanoRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
derivationType: derivationInfo!.derivationType!,
passphrase: passphrase,
);
case WalletType.polygon:
return polygon!.createPolygonRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.solana:
return solana!.createSolanaRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.tron:
return tron!.createTronRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.wownero:
return wownero!.createWowneroRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase??'',
height: height,
);
case WalletType.zano:
return zano!.createZanoRestoreWalletFromSeedCredentials(
name: name,
password: password,
height: height,
passphrase: passphrase??'',
mnemonic: seed,
);
case WalletType.decred:
return decred!.createDecredRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
);
case WalletType.none:
case WalletType.haven:
break;
}
}
if (mode == WalletRestoreMode.keys) {
final viewKey = options['viewKey'] as String?;
final spendKey = options['spendKey'] as String?;
final address = options['address'] as String?;
switch (type) {
case WalletType.monero:
return monero!.createMoneroRestoreWalletFromKeysCredentials(
name: name,
height: height,
spendKey: spendKey!,
viewKey: viewKey!,
address: address!,
password: password,
language: 'English',
);
case WalletType.ethereum:
return ethereum!.createEthereumRestoreWalletFromPrivateKey(
name: name,
privateKey: options['private_key'] as String,
password: password,
);
case WalletType.nano:
return nano!.createNanoRestoreWalletFromKeysCredentials(
name: name,
password: password,
seedKey: options['private_key'] as String,
derivationType: derivationInfo!.derivationType!,
);
case WalletType.polygon:
return polygon!.createPolygonRestoreWalletFromPrivateKey(
name: name,
password: password,
privateKey: options['private_key'] as String,
);
case WalletType.solana:
return solana!.createSolanaRestoreWalletFromPrivateKey(
name: name,
password: password,
privateKey: options['private_key'] as String,
);
case WalletType.tron:
return tron!.createTronRestoreWalletFromPrivateKey(
name: name,
password: password,
privateKey: options['private_key'] as String,
);
case WalletType.wownero:
return wownero!.createWowneroRestoreWalletFromKeysCredentials(
name: name,
height: height,
spendKey: spendKey!,
viewKey: viewKey!,
address: address!,
password: password,
language: 'English',
);
case WalletType.decred:
return decred!.createDecredRestoreWalletFromPubkeyCredentials(
name: name,
password: password,
pubkey: viewKey!,
);
default:
break;
}
}
throw Exception('Unexpected type: ${type.toString()}');
}
Future<List<DerivationInfo>> getDerivationInfo(dynamic credentials) async {
var list = <DerivationInfo>[];
var walletType = credentials["walletType"] as WalletType;
var appStore = getIt.get<AppStore>();
var node = appStore.settingsStore.getCurrentNode(walletType);
switch (walletType) {
case WalletType.bitcoin:
case WalletType.litecoin:
String? mnemonic = credentials['seed'] as String?;
String? passphrase = credentials['passphrase'] as String?;
return bitcoin!.getDerivationsFromMnemonic(
mnemonic: mnemonic!,
node: node,
passphrase: passphrase,
);
case WalletType.nano:
String? mnemonic = credentials['seed'] as String?;
String? seedKey = credentials['private_key'] as String?;
return nanoUtil!.getDerivationsFromMnemonic(
mnemonic: mnemonic,
seedKey: seedKey,
node: node,
);
default:
break;
}
return list;
}
@override
Future<WalletBase> process(WalletCredentials credentials) async {
if (mode == WalletRestoreMode.keys) {
return walletCreationService.restoreFromKeys(credentials, isTestnet: useTestnet);
}
return walletCreationService.restoreFromSeed(credentials, isTestnet: useTestnet);
}
}