mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-22 06:28:39 +02:00
Add decred (#1938)
* 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 * minor fixes [skip ci] * decred: Get slip44 addrs before sync completes. (#2092) * - Fix loading wallet more than one time - Fix minor UI 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>
This commit is contained in:
co-authored by
JoeGruffins
Wisdom Arerosuoghene
Philemon Ukane
Czarek Nakamoto
parent
52a39e29d4
commit
0ba54fa602
@@ -55,6 +55,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
||||
case WalletType.none:
|
||||
case WalletType.haven:
|
||||
case WalletType.zano:
|
||||
case WalletType.decred:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:cake_wallet/entities/wallet_list_order_types.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
@@ -43,7 +42,8 @@ abstract class ContactListViewModelBase with Store {
|
||||
}
|
||||
}
|
||||
} else if (info.addresses?.isNotEmpty == true && info.addresses!.length > 1) {
|
||||
if ([WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type)) {
|
||||
if ([WalletType.monero, WalletType.wownero, WalletType.haven, WalletType.decred]
|
||||
.contains(info.type)) {
|
||||
final address = info.address;
|
||||
final name = _createName(info.name, "", key: 0);
|
||||
walletContacts.add(WalletContact(
|
||||
@@ -129,11 +129,9 @@ abstract class ContactListViewModelBase with Store {
|
||||
(element.type == CryptoCurrency.btc || element.type == CryptoCurrency.ltc)) return false;
|
||||
|
||||
return element.type == _currency ||
|
||||
(element.type.tag != null &&
|
||||
_currency?.tag != null &&
|
||||
element.type.tag == _currency?.tag) ||
|
||||
_currency?.toString() == element.type.tag ||
|
||||
_currency?.tag == element.type.toString();
|
||||
(element.type.tag != null && _currency.tag != null && element.type.tag == _currency.tag) ||
|
||||
_currency.toString() == element.type.tag ||
|
||||
_currency.tag == element.type.toString();
|
||||
}
|
||||
|
||||
void dispose() => _subscription?.cancel();
|
||||
|
||||
@@ -62,12 +62,12 @@ abstract class ContactViewModelBase with Store {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_contact != null && _contact!.original.isInBox) {
|
||||
_contact?.name = name;
|
||||
_contact?.address = address;
|
||||
_contact?.type = currency!;
|
||||
_contact?.lastChange = now;
|
||||
await _contact?.save();
|
||||
if (_contact != null && _contact.original.isInBox) {
|
||||
_contact.name = name;
|
||||
_contact.address = address;
|
||||
_contact.type = currency!;
|
||||
_contact.lastChange = now;
|
||||
await _contact.save();
|
||||
} else {
|
||||
await _contacts
|
||||
.add(Contact(name: name, address: address, type: currency!, lastChange: now));
|
||||
|
||||
@@ -306,6 +306,7 @@ abstract class BalanceViewModelBase with Store {
|
||||
case WalletType.monero:
|
||||
case WalletType.wownero:
|
||||
case WalletType.zano:
|
||||
case WalletType.decred:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -23,7 +23,6 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
|
||||
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
@@ -169,6 +168,9 @@ abstract class DashboardViewModelBase with Store {
|
||||
type = appStore.wallet!.type,
|
||||
transactions = ObservableList<TransactionListItem>(),
|
||||
wallet = appStore.wallet! {
|
||||
showDecredInfoCard = wallet.type == WalletType.decred &&
|
||||
(sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) ?? true);
|
||||
|
||||
name = wallet.name;
|
||||
type = wallet.type;
|
||||
isShowFirstYatIntroduction = false;
|
||||
@@ -261,6 +263,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
reaction((_) => appStore.wallet, (wallet) {
|
||||
_onWalletChange(wallet);
|
||||
_checkMweb();
|
||||
showDecredInfoCard = wallet?.type == WalletType.decred;
|
||||
});
|
||||
|
||||
_transactionDisposer?.reaction.dispose();
|
||||
@@ -350,6 +353,10 @@ abstract class DashboardViewModelBase with Store {
|
||||
statusText = S.current.please_try_to_connect_to_another_node;
|
||||
}
|
||||
|
||||
if (status is ProcessingSyncStatus) {
|
||||
statusText = (status as ProcessingSyncStatus).message ?? S.current.processing;
|
||||
}
|
||||
|
||||
return statusText;
|
||||
}
|
||||
|
||||
@@ -399,13 +406,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
bool get isTestnet => wallet.type == WalletType.bitcoin && bitcoin!.isTestnet(wallet);
|
||||
|
||||
@computed
|
||||
bool get hasRescan => [
|
||||
WalletType.bitcoin,
|
||||
WalletType.monero,
|
||||
WalletType.litecoin,
|
||||
WalletType.wownero,
|
||||
WalletType.haven
|
||||
].contains(wallet.type);
|
||||
bool get hasRescan => wallet.hasRescan;
|
||||
|
||||
@computed
|
||||
bool get isMoneroViewOnly {
|
||||
@@ -490,6 +491,9 @@ abstract class DashboardViewModelBase with Store {
|
||||
@observable
|
||||
bool mwebEnabled = false;
|
||||
|
||||
@observable
|
||||
late bool showDecredInfoCard;
|
||||
|
||||
@computed
|
||||
bool get hasEnabledMwebBefore => settingsStore.hasEnabledMwebBefore;
|
||||
|
||||
@@ -543,6 +547,12 @@ abstract class DashboardViewModelBase with Store {
|
||||
bitcoin!.setMwebEnabled(wallet, false);
|
||||
}
|
||||
|
||||
@action
|
||||
void dismissDecredInfoCard() {
|
||||
showDecredInfoCard = false;
|
||||
sharedPreferences.setBool(PreferencesKey.showDecredInfoCard, false);
|
||||
}
|
||||
|
||||
BalanceViewModel balanceViewModel;
|
||||
|
||||
AppStore appStore;
|
||||
@@ -573,6 +583,9 @@ abstract class DashboardViewModelBase with Store {
|
||||
@computed
|
||||
bool get isEnabledSwapAction => settingsStore.exchangeStatus != ExchangeApiMode.disabled;
|
||||
|
||||
@computed
|
||||
bool get canSend => wallet.canSend();
|
||||
|
||||
@observable
|
||||
bool hasSwapAction;
|
||||
|
||||
@@ -596,21 +609,28 @@ abstract class DashboardViewModelBase with Store {
|
||||
|
||||
@computed
|
||||
bool get hasSignMessages {
|
||||
if (wallet.isHardwareWallet) return false;
|
||||
|
||||
return [
|
||||
WalletType.monero,
|
||||
WalletType.litecoin,
|
||||
WalletType.bitcoin,
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.ethereum,
|
||||
WalletType.polygon,
|
||||
WalletType.solana,
|
||||
WalletType.nano,
|
||||
WalletType.banano,
|
||||
WalletType.tron,
|
||||
WalletType.wownero
|
||||
].contains(wallet.type);
|
||||
if (wallet.isHardwareWallet) {
|
||||
return false;
|
||||
}
|
||||
switch (wallet.type) {
|
||||
case WalletType.monero:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.ethereum:
|
||||
case WalletType.polygon:
|
||||
case WalletType.solana:
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
case WalletType.tron:
|
||||
case WalletType.wownero:
|
||||
case WalletType.decred:
|
||||
return true;
|
||||
case WalletType.zano:
|
||||
case WalletType.haven:
|
||||
case WalletType.none:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool get showRepWarning {
|
||||
|
||||
@@ -214,6 +214,7 @@ abstract class HomeSettingsViewModelBase with Store {
|
||||
case WalletType.nano:
|
||||
case WalletType.wownero:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.decred:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ abstract class ReceiveOptionViewModelBase with Store {
|
||||
(_wallet.type == WalletType.bitcoin ||
|
||||
_wallet.type == WalletType.litecoin
|
||||
? bitcoin!.getSelectedAddressType(_wallet)
|
||||
: ReceivePageOption.mainnet),
|
||||
: (_wallet.type == WalletType.decred && _wallet.isTestnet)
|
||||
? ReceivePageOption.testnet
|
||||
: ReceivePageOption.mainnet),
|
||||
_options = [] {
|
||||
final walletType = _wallet.type;
|
||||
switch (walletType) {
|
||||
@@ -33,6 +35,17 @@ abstract class ReceiveOptionViewModelBase with Store {
|
||||
case WalletType.haven:
|
||||
_options = [ReceivePageOption.mainnet];
|
||||
break;
|
||||
case WalletType.decred:
|
||||
if (_wallet.isTestnet) {
|
||||
_options = [
|
||||
ReceivePageOption.testnet,
|
||||
...ReceivePageOptions.where(
|
||||
(element) => element != ReceivePageOption.mainnet)
|
||||
];
|
||||
} else {
|
||||
_options = ReceivePageOptions;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_options = ReceivePageOptions;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
@@ -82,7 +83,9 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
if (transaction.confirmations <= 0) {
|
||||
str = S.current.pending;
|
||||
}
|
||||
if ((isPegOut || fromPegOut) && transaction.confirmations >= 0 && transaction.confirmations < 6) {
|
||||
if ((isPegOut || fromPegOut) &&
|
||||
transaction.confirmations >= 0 &&
|
||||
transaction.confirmations < 6) {
|
||||
str = " (${transaction.confirmations}/6)";
|
||||
}
|
||||
if (isPegIn) {
|
||||
@@ -224,7 +227,13 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
cryptoAmount: zano!.formatterIntAmountToDouble(amount: transaction.amount, currency: asset, forFee: false),
|
||||
price: price);
|
||||
break;
|
||||
default:
|
||||
case WalletType.decred:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: decred!.formatterDecredAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
break;
|
||||
case WalletType.none:
|
||||
case WalletType.banano:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
@@ -167,7 +169,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
wallet.type == WalletType.bitcoinCash;
|
||||
|
||||
bool get hideAddressAfterExchange =>
|
||||
wallet.type == WalletType.monero || wallet.type == WalletType.wownero;
|
||||
wallet.type == WalletType.monero ||
|
||||
wallet.type == WalletType.wownero;
|
||||
|
||||
bool _useTorOnly;
|
||||
final Box<Trade> trades;
|
||||
@@ -316,8 +319,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
|
||||
bool get isMoneroWallet => wallet.type == WalletType.monero;
|
||||
|
||||
|
||||
|
||||
List<CryptoCurrency> receiveCurrencies;
|
||||
|
||||
List<CryptoCurrency> depositCurrencies;
|
||||
@@ -778,6 +779,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
depositCurrency = CryptoCurrency.zano;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.decred:
|
||||
depositCurrency = CryptoCurrency.dcr;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.none:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -63,13 +63,13 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
String socksProxyAddress;
|
||||
|
||||
@computed
|
||||
bool get isReady => address.isNotEmpty && port.isNotEmpty;
|
||||
bool get isReady =>
|
||||
(address.isNotEmpty && port.isNotEmpty) ||
|
||||
_walletType == WalletType.decred; // Allow an empty address.
|
||||
|
||||
bool get hasAuthCredentials =>
|
||||
_walletType == WalletType.monero || _walletType == WalletType.wownero || _walletType == WalletType.haven;
|
||||
|
||||
bool get hasTestnetSupport => _walletType == WalletType.bitcoin;
|
||||
|
||||
bool get hasPathSupport {
|
||||
switch (_walletType) {
|
||||
case WalletType.ethereum:
|
||||
@@ -87,6 +87,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.zano:
|
||||
case WalletType.decred:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,50 +49,10 @@ abstract class NodeListViewModelBase with Store {
|
||||
await resetToDefault(_nodeSource);
|
||||
|
||||
Node node;
|
||||
|
||||
switch (_appStore.wallet!.type) {
|
||||
case WalletType.bitcoin:
|
||||
if (_appStore.wallet!.isTestnet) {
|
||||
node = getBitcoinTestnetDefaultElectrumServer(nodes: _nodeSource)!;
|
||||
} else {
|
||||
node = getBitcoinDefaultElectrumServer(nodes: _nodeSource)!;
|
||||
}
|
||||
break;
|
||||
case WalletType.monero:
|
||||
node = getMoneroDefaultNode(nodes: _nodeSource);
|
||||
break;
|
||||
case WalletType.litecoin:
|
||||
node = getLitecoinDefaultElectrumServer(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.haven:
|
||||
node = getHavenDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.ethereum:
|
||||
node = getEthereumDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.bitcoinCash:
|
||||
node = getBitcoinCashDefaultElectrumServer(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.nano:
|
||||
node = getNanoDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.polygon:
|
||||
node = getPolygonDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.solana:
|
||||
node = getSolanaDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.tron:
|
||||
node = getTronDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
case WalletType.wownero:
|
||||
node = getWowneroDefaultNode(nodes: _nodeSource);
|
||||
break;
|
||||
case WalletType.zano:
|
||||
node = getZanoDefaultNode(nodes: _nodeSource)!;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.type}');
|
||||
if (_appStore.wallet!.type == WalletType.bitcoin && _appStore.wallet!.isTestnet) {
|
||||
node = getBitcoinTestnetDefaultElectrumServer(nodes: _nodeSource)!;
|
||||
} else {
|
||||
node = getDefaultNode(nodes: _nodeSource, type: _appStore.wallet!.type)!;
|
||||
}
|
||||
|
||||
await setAsCurrent(node);
|
||||
|
||||
@@ -44,6 +44,9 @@ class WalletRestoreFromQRCode {
|
||||
'zano': WalletType.zano,
|
||||
'zano-wallet': WalletType.zano,
|
||||
'zano_wallet': WalletType.zano,
|
||||
'decred': WalletType.decred,
|
||||
'decred-wallet': WalletType.decred,
|
||||
'decred_wallet': WalletType.decred,
|
||||
};
|
||||
|
||||
static WalletType? _extractWalletType(String code) {
|
||||
@@ -69,8 +72,12 @@ class WalletRestoreFromQRCode {
|
||||
}
|
||||
|
||||
static String? _extractAddressFromUrl(String rawString, WalletType type) {
|
||||
return AddressResolver.extractAddressByType(
|
||||
raw: rawString, type: walletTypeToCryptoCurrency(type));
|
||||
try {
|
||||
return AddressResolver.extractAddressByType(
|
||||
raw: rawString, type: walletTypeToCryptoCurrency(type));
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static String? _extractSeedPhraseFromUrl(String rawString, WalletType walletType) {
|
||||
@@ -122,7 +129,6 @@ class WalletRestoreFromQRCode {
|
||||
}
|
||||
if (queryParameters['address'] == null) {
|
||||
queryParameters['address'] = _extractAddressFromUrl(code, walletType);
|
||||
|
||||
}
|
||||
|
||||
Map<String, dynamic> credentials = {'type': walletType, ...queryParameters, 'raw_qr': code};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
||||
import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
@@ -88,7 +89,13 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
return transactionPriority == bitcoinCash!.getBitcoinCashTransactionPrioritySlow();
|
||||
case WalletType.polygon:
|
||||
return transactionPriority == polygon!.getPolygonTransactionPrioritySlow();
|
||||
default:
|
||||
case WalletType.decred:
|
||||
return transactionPriority == decred!.getDecredTransactionPrioritySlow();
|
||||
case WalletType.none:
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
@@ -101,6 +102,9 @@ abstract class OutputBase with Store {
|
||||
case WalletType.bitcoinCash:
|
||||
_amount = bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
|
||||
break;
|
||||
case WalletType.decred:
|
||||
_amount = decred!.formatterStringDoubleToDecredAmount(_cryptoAmount);
|
||||
break;
|
||||
case WalletType.haven:
|
||||
_amount = haven!.formatterMoneroParseAmount(amount: _cryptoAmount);
|
||||
break;
|
||||
@@ -188,6 +192,10 @@ abstract class OutputBase with Store {
|
||||
if (_wallet.type == WalletType.zano) {
|
||||
return zano!.formatterIntAmountToDouble(amount: fee, currency: cryptoCurrencyHandler(), forFee: true);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.decred) {
|
||||
return decred!.formatterDecredAmountToDouble(amount: fee);
|
||||
}
|
||||
} catch (e) {
|
||||
printV(e.toString());
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
|
||||
import 'package:cake_wallet/entities/contact_record.dart';
|
||||
import 'package:cake_wallet/entities/wallet_contact.dart';
|
||||
@@ -251,6 +252,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
wallet.type == WalletType.litecoin ||
|
||||
wallet.type == WalletType.monero ||
|
||||
wallet.type == WalletType.wownero ||
|
||||
wallet.type == WalletType.decred ||
|
||||
wallet.type == WalletType.bitcoinCash;
|
||||
|
||||
@computed
|
||||
@@ -539,6 +541,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
case WalletType.zano:
|
||||
return zano!.createZanoTransactionCredentials(
|
||||
outputs: outputs, priority: priority!, currency: selectedCryptoCurrency);
|
||||
case WalletType.decred:
|
||||
this.coinTypeToSpendFrom = UnspentCoinType.any;
|
||||
return decred!.createDecredTransactionCredentials(outputs, priority!);
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${wallet.type}');
|
||||
}
|
||||
@@ -681,55 +686,51 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
}
|
||||
}
|
||||
|
||||
if (walletType == WalletType.bitcoin ||
|
||||
walletType == WalletType.litecoin ||
|
||||
walletType == WalletType.bitcoinCash) {
|
||||
if (error is TransactionWrongBalanceException) {
|
||||
if (error.amount != null)
|
||||
return S.current
|
||||
.tx_wrong_balance_with_amount_exception(currency.toString(), error.amount.toString());
|
||||
if (error is TransactionWrongBalanceException) {
|
||||
if (error.amount != null)
|
||||
return S.current
|
||||
.tx_wrong_balance_with_amount_exception(currency.toString(), error.amount.toString());
|
||||
|
||||
return S.current.tx_wrong_balance_exception(currency.toString());
|
||||
}
|
||||
if (error is TransactionNoInputsException) {
|
||||
return S.current.tx_not_enough_inputs_exception;
|
||||
}
|
||||
if (error is TransactionNoFeeException) {
|
||||
return S.current.tx_zero_fee_exception;
|
||||
}
|
||||
if (error is TransactionNoDustException) {
|
||||
return S.current.tx_no_dust_exception;
|
||||
}
|
||||
if (error is TransactionCommitFailed) {
|
||||
if (error.errorMessage != null && error.errorMessage!.contains("no peers replied")) {
|
||||
return S.current.tx_commit_failed_no_peers;
|
||||
}
|
||||
return "${S.current.tx_commit_failed}${error.errorMessage != null ? "\n\n${error.errorMessage}" : ""}";
|
||||
}
|
||||
if (error is TransactionCommitFailedDustChange) {
|
||||
return S.current.tx_rejected_dust_change;
|
||||
}
|
||||
if (error is TransactionCommitFailedDustOutput) {
|
||||
return S.current.tx_rejected_dust_output;
|
||||
}
|
||||
if (error is TransactionCommitFailedDustOutputSendAll) {
|
||||
return S.current.tx_rejected_dust_output_send_all;
|
||||
}
|
||||
if (error is TransactionCommitFailedVoutNegative) {
|
||||
return S.current.tx_rejected_vout_negative;
|
||||
}
|
||||
if (error is TransactionCommitFailedBIP68Final) {
|
||||
return S.current.tx_rejected_bip68_final;
|
||||
}
|
||||
if (error is TransactionCommitFailedLessThanMin) {
|
||||
return S.current.fee_less_than_min;
|
||||
}
|
||||
if (error is TransactionNoDustOnChangeException) {
|
||||
return S.current.tx_commit_exception_no_dust_on_change(error.min, error.max);
|
||||
}
|
||||
if (error is TransactionInputNotSupported) {
|
||||
return S.current.tx_invalid_input;
|
||||
return S.current.tx_wrong_balance_exception(currency.toString());
|
||||
}
|
||||
if (error is TransactionNoInputsException) {
|
||||
return S.current.tx_not_enough_inputs_exception;
|
||||
}
|
||||
if (error is TransactionNoFeeException) {
|
||||
return S.current.tx_zero_fee_exception;
|
||||
}
|
||||
if (error is TransactionNoDustException) {
|
||||
return S.current.tx_no_dust_exception;
|
||||
}
|
||||
if (error is TransactionCommitFailed) {
|
||||
if (error.errorMessage != null && error.errorMessage!.contains("no peers replied")) {
|
||||
return S.current.tx_commit_failed_no_peers;
|
||||
}
|
||||
return "${S.current.tx_commit_failed}${error.errorMessage != null ? "\n\n${error.errorMessage}" : ""}";
|
||||
}
|
||||
if (error is TransactionCommitFailedDustChange) {
|
||||
return S.current.tx_rejected_dust_change;
|
||||
}
|
||||
if (error is TransactionCommitFailedDustOutput) {
|
||||
return S.current.tx_rejected_dust_output;
|
||||
}
|
||||
if (error is TransactionCommitFailedDustOutputSendAll) {
|
||||
return S.current.tx_rejected_dust_output_send_all;
|
||||
}
|
||||
if (error is TransactionCommitFailedVoutNegative) {
|
||||
return S.current.tx_rejected_vout_negative;
|
||||
}
|
||||
if (error is TransactionCommitFailedBIP68Final) {
|
||||
return S.current.tx_rejected_bip68_final;
|
||||
}
|
||||
if (error is TransactionCommitFailedLessThanMin) {
|
||||
return S.current.fee_less_than_min;
|
||||
}
|
||||
if (error is TransactionNoDustOnChangeException) {
|
||||
return S.current.tx_commit_exception_no_dust_on_change(error.min, error.max);
|
||||
}
|
||||
if (error is TransactionInputNotSupported) {
|
||||
return S.current.tx_invalid_input;
|
||||
}
|
||||
|
||||
return errorMessage;
|
||||
|
||||
@@ -44,7 +44,8 @@ abstract class PrivacySettingsViewModelBase with Store {
|
||||
_wallet.type == WalletType.wownero ||
|
||||
_wallet.type == WalletType.bitcoin ||
|
||||
_wallet.type == WalletType.litecoin ||
|
||||
_wallet.type == WalletType.bitcoinCash;
|
||||
_wallet.type == WalletType.bitcoinCash ||
|
||||
_wallet.type == WalletType.decred;
|
||||
|
||||
bool get isMoneroWallet => _wallet.type == WalletType.monero;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
final dateFormat = DateFormatter.withCurrentLocal();
|
||||
final tx = transactionInfo;
|
||||
|
||||
// TODO: can be cleaned further
|
||||
switch (wallet.type) {
|
||||
case WalletType.monero:
|
||||
_addMoneroListItems(tx, dateFormat);
|
||||
@@ -84,8 +85,12 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
case WalletType.zano:
|
||||
_addZanoListItems(tx, dateFormat);
|
||||
break;
|
||||
default:
|
||||
case WalletType.decred:
|
||||
_addDecredListItems(tx, dateFormat);
|
||||
break;
|
||||
case WalletType.none:
|
||||
case WalletType.banano:
|
||||
break;
|
||||
}
|
||||
|
||||
final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
|
||||
@@ -186,6 +191,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return 'https://explore.wownero.com/tx/${txId}';
|
||||
case WalletType.zano:
|
||||
return 'https://explorer.zano.org/transaction/${txId}';
|
||||
case WalletType.decred:
|
||||
return 'https://${wallet.isTestnet ? "testnet" : "dcrdata"}.decred.org/tx/${txId.split(':')[0]}';
|
||||
case WalletType.none:
|
||||
return '';
|
||||
}
|
||||
@@ -218,6 +225,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return S.current.view_transaction_on + 'Wownero.com';
|
||||
case WalletType.zano:
|
||||
return S.current.view_transaction_on + 'explorer.zano.org';
|
||||
case WalletType.decred:
|
||||
return S.current.view_transaction_on + 'dcrdata.decred.org';
|
||||
case WalletType.none:
|
||||
return '';
|
||||
}
|
||||
@@ -672,6 +681,51 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
void _addDecredListItems(TransactionInfo tx, DateFormat dateFormat) {
|
||||
final _items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id,
|
||||
value: tx.txHash,
|
||||
key: ValueKey('standard_list_item_transaction_details_id_key'),
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date),
|
||||
key: ValueKey('standard_list_item_transaction_details_date_key'),
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height,
|
||||
value: '${tx.height}',
|
||||
key: ValueKey('standard_list_item_transaction_details_height_key'),
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted(),
|
||||
key: ValueKey('standard_list_item_transaction_details_amount_key'),
|
||||
),
|
||||
if (tx.feeFormatted()?.isNotEmpty ?? false)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_fee,
|
||||
value: tx.feeFormatted()!,
|
||||
key: ValueKey('standard_list_item_transaction_details_fee_key'),
|
||||
),
|
||||
if (showRecipientAddress && tx.to != null)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: tx.to!,
|
||||
key: ValueKey('standard_list_item_transaction_details_recipient_address_key'),
|
||||
),
|
||||
if (tx.from != null)
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_source_address,
|
||||
value: tx.from!,
|
||||
key: ValueKey('standard_list_item_transaction_details_source_address_key'),
|
||||
),
|
||||
];
|
||||
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> _checkForRBF(TransactionInfo tx) async {
|
||||
if (wallet.type == WalletType.bitcoin &&
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
|
||||
import 'package:cake_wallet/wownero/wownero.dart';
|
||||
import 'package:cw_core/unspent_coin_type.dart';
|
||||
@@ -92,6 +93,8 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
return wownero!.formatterWowneroAmountToString(amount: fullBalance);
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type))
|
||||
return bitcoin!.formatterBitcoinAmountToString(amount: fullBalance);
|
||||
if (wallet.type == WalletType.decred)
|
||||
return decred!.formatterDecredAmountToString(amount: fullBalance);
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -105,7 +108,9 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type)) {
|
||||
await bitcoin!.updateUnspents(wallet);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.decred) {
|
||||
decred!.updateUnspents(wallet);
|
||||
}
|
||||
_updateUnspentCoinsInfo();
|
||||
}
|
||||
|
||||
@@ -119,6 +124,8 @@ abstract class UnspentCoinsListViewModelBase with Store {
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: coinTypeToSpendFrom);
|
||||
case WalletType.decred:
|
||||
return decred!.getUnspents(wallet);
|
||||
default:
|
||||
return List.empty();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
part 'wallet_address_edit_or_create_view_model.g.dart';
|
||||
@@ -27,13 +28,12 @@ class AddressEditOrCreateStateFailure extends AddressEditOrCreateState {
|
||||
}
|
||||
|
||||
abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
WalletAddressEditOrCreateViewModelBase(
|
||||
{required WalletBase wallet, WalletAddressListItem? item})
|
||||
WalletAddressEditOrCreateViewModelBase({required WalletBase wallet, WalletAddressListItem? item})
|
||||
: isEdit = item != null,
|
||||
state = AddressEditOrCreateStateInitial(),
|
||||
label = item?.name ?? '',
|
||||
_item = item,
|
||||
_wallet = wallet;
|
||||
_wallet = wallet;
|
||||
|
||||
@observable
|
||||
AddressEditOrCreateState state;
|
||||
@@ -46,7 +46,8 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
final WalletAddressListItem? _item;
|
||||
final WalletBase _wallet;
|
||||
|
||||
bool get isElectrum => _wallet.type == WalletType.bitcoin ||
|
||||
bool get isElectrum =>
|
||||
_wallet.type == WalletType.bitcoin ||
|
||||
_wallet.type == WalletType.bitcoinCash ||
|
||||
_wallet.type == WalletType.litecoin;
|
||||
|
||||
@@ -69,39 +70,46 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
Future<void> _createNew() async {
|
||||
final wallet = _wallet;
|
||||
|
||||
if (isElectrum) await bitcoin!.generateNewAddress(wallet, label);
|
||||
if (isElectrum) {
|
||||
await bitcoin!.generateNewAddress(wallet, label);
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.decred) {
|
||||
await decred!.generateNewAddress(wallet, label);
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
await monero
|
||||
!.getSubaddressList(wallet)
|
||||
.addSubaddress(
|
||||
wallet,
|
||||
accountIndex: monero!.getCurrentAccount(wallet).id,
|
||||
label: label);
|
||||
final addr = await monero!.getSubaddressList(wallet).subaddresses.first.address; // first because the order is reversed
|
||||
await monero!
|
||||
.getSubaddressList(wallet)
|
||||
.addSubaddress(wallet, accountIndex: monero!.getCurrentAccount(wallet).id, label: label);
|
||||
final addr = await monero!
|
||||
.getSubaddressList(wallet)
|
||||
.subaddresses
|
||||
.first
|
||||
.address; // first because the order is reversed
|
||||
wallet.walletAddresses.manualAddresses.add(addr);
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.wownero) {
|
||||
await wownero
|
||||
!.getSubaddressList(wallet)
|
||||
.addSubaddress(
|
||||
wallet,
|
||||
accountIndex: wownero!.getCurrentAccount(wallet).id,
|
||||
label: label);
|
||||
final addr = await wownero!.getSubaddressList(wallet).subaddresses.first.address; // first because the order is reversed
|
||||
await wownero!
|
||||
.getSubaddressList(wallet)
|
||||
.addSubaddress(wallet, accountIndex: wownero!.getCurrentAccount(wallet).id, label: label);
|
||||
final addr = await wownero!
|
||||
.getSubaddressList(wallet)
|
||||
.subaddresses
|
||||
.first
|
||||
.address; // first because the order is reversed
|
||||
wallet.walletAddresses.manualAddresses.add(addr);
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
await haven
|
||||
!.getSubaddressList(wallet)
|
||||
.addSubaddress(
|
||||
wallet,
|
||||
accountIndex: haven!.getCurrentAccount(wallet).id,
|
||||
label: label);
|
||||
await haven!
|
||||
.getSubaddressList(wallet)
|
||||
.addSubaddress(wallet, accountIndex: haven!.getCurrentAccount(wallet).id, label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
}
|
||||
@@ -111,6 +119,12 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
|
||||
if (isElectrum) await bitcoin!.updateAddress(wallet, _item!.address, label);
|
||||
|
||||
if (wallet.type == WalletType.decred) {
|
||||
await decred!.updateAddress(wallet, _item!.address, label);
|
||||
await wallet.save();
|
||||
return;
|
||||
}
|
||||
|
||||
final index = _item?.id;
|
||||
if (index != null) {
|
||||
if (wallet.type == WalletType.monero) {
|
||||
@@ -125,9 +139,7 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
}
|
||||
if (wallet.type == WalletType.haven) {
|
||||
await haven!.getSubaddressList(wallet).setLabelSubaddress(wallet,
|
||||
accountIndex: haven!.getCurrentAccount(wallet).id,
|
||||
addressIndex: index,
|
||||
label: label);
|
||||
accountIndex: haven!.getCurrentAccount(wallet).id, addressIndex: index, label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/polygon/polygon.dart';
|
||||
import 'package:cake_wallet/solana/solana.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
@@ -222,6 +223,22 @@ class ZanoURI extends PaymentURI {
|
||||
}
|
||||
}
|
||||
|
||||
class DecredURI extends PaymentURI {
|
||||
DecredURI({required String amount, required String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var base = 'decred:' + address;
|
||||
|
||||
if (amount.isNotEmpty) {
|
||||
base += '?amount=${amount.replaceAll(',', '.')}';
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewModel with Store {
|
||||
WalletAddressListViewModelBase({
|
||||
required AppStore appStore,
|
||||
@@ -313,7 +330,9 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
case WalletType.wownero:
|
||||
return WowneroURI(amount: amount, address: address.address);
|
||||
case WalletType.zano:
|
||||
return ZanoURI(amount: amount, address: address.address);
|
||||
return ZanoURI(amount: amount, address: address.address);
|
||||
case WalletType.decred:
|
||||
return DecredURI(amount: amount, address: address.address);
|
||||
case WalletType.none:
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
@@ -468,6 +487,14 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.decred) {
|
||||
final addrInfos = decred!.getAddressInfos(wallet);
|
||||
addrInfos.forEach((info) {
|
||||
addressList.add(new WalletAddressListItem(isPrimary: false, address: info.address,
|
||||
name: info.label));
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < addressList.length; i++) {
|
||||
if (!(addressList[i] is WalletAddressListItem)) continue;
|
||||
(addressList[i] as WalletAddressListItem).isHidden = wallet.walletAddresses.hiddenAddresses
|
||||
@@ -561,7 +588,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
WalletType.haven,
|
||||
WalletType.bitcoinCash,
|
||||
WalletType.bitcoin,
|
||||
WalletType.litecoin
|
||||
WalletType.litecoin,
|
||||
WalletType.decred
|
||||
].contains(wallet.type);
|
||||
|
||||
@computed
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/decred/decred.dart';
|
||||
import 'package:polyseed/polyseed.dart';
|
||||
|
||||
part 'wallet_keys_view_model.g.dart';
|
||||
@@ -155,6 +156,12 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
),
|
||||
]);
|
||||
break;
|
||||
case WalletType.decred:
|
||||
final pubkey = decred!.pubkey(_appStore.wallet!);
|
||||
items.addAll([
|
||||
StandartListItem(title: S.current.view_key_public, value: pubkey),
|
||||
]);
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
@@ -248,6 +255,8 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
return 'wownero-wallet';
|
||||
case WalletType.zano:
|
||||
return 'zano-wallet';
|
||||
case WalletType.decred:
|
||||
return 'decred-wallet';
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_wallet.type.toString()}');
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import 'package:cake_wallet/tron/tron.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/decred/decred.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
@@ -83,6 +84,8 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
return 25;
|
||||
case WalletType.zano:
|
||||
return 26;
|
||||
case WalletType.decred:
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +173,8 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
password: walletPassword,
|
||||
passphrase: passphrase,
|
||||
);
|
||||
case WalletType.decred:
|
||||
return decred!.createDecredNewWalletCredentials(name: name);
|
||||
case WalletType.none:
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ 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';
|
||||
@@ -58,6 +59,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
case WalletType.haven:
|
||||
case WalletType.ethereum:
|
||||
case WalletType.polygon:
|
||||
case WalletType.decred:
|
||||
availableModes = [WalletRestoreMode.seed, WalletRestoreMode.keys];
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
@@ -77,6 +79,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
}
|
||||
|
||||
static const moneroSeedMnemonicLength = 25;
|
||||
static const decredSeedMnemonicLength = 15;
|
||||
|
||||
late List<WalletRestoreMode> availableModes;
|
||||
final bool hasSeedLanguageSelector;
|
||||
@@ -171,11 +174,18 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
);
|
||||
case WalletType.zano:
|
||||
return zano!.createZanoRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
height: height,
|
||||
name: name,
|
||||
password: password,
|
||||
height: height,
|
||||
passphrase: passphrase??'',
|
||||
mnemonic: seed);
|
||||
mnemonic: seed,
|
||||
);
|
||||
case WalletType.decred:
|
||||
return decred!.createDecredRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
);
|
||||
case WalletType.none:
|
||||
break;
|
||||
}
|
||||
@@ -251,6 +261,12 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
password: password,
|
||||
language: 'English',
|
||||
);
|
||||
case WalletType.decred:
|
||||
return decred!.createDecredRestoreWalletFromPubkeyCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
pubkey: viewKey!,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user