mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-26 00:58:44 +00:00
fix: scan fixes, add date, allow sending while scanning
This commit is contained in:
parent
b7c942ac4e
commit
8e5d997562
9 changed files with 190 additions and 214 deletions
|
@ -37,6 +37,7 @@ import 'package:cw_core/utils/file.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:cw_core/get_height_by_date.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
@ -359,7 +360,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
syncStatus = message.syncStatus;
|
syncStatus = message.syncStatus;
|
||||||
walletInfo.restoreHeight = message.height;
|
await walletInfo.updateRestoreHeight(message.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,6 +382,8 @@ abstract class ElectrumWalletBase
|
||||||
await updateBalance();
|
await updateBalance();
|
||||||
|
|
||||||
await updateFeeRates();
|
await updateFeeRates();
|
||||||
|
|
||||||
|
syncStatus = SyncedSyncStatus();
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
print(stacktrace);
|
print(stacktrace);
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
|
@ -1141,6 +1144,7 @@ abstract class ElectrumWalletBase
|
||||||
coin.isFrozen = coinInfo.isFrozen;
|
coin.isFrozen = coinInfo.isFrozen;
|
||||||
coin.isSending = coinInfo.isSending;
|
coin.isSending = coinInfo.isSending;
|
||||||
coin.note = coinInfo.note;
|
coin.note = coinInfo.note;
|
||||||
|
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
|
||||||
coin.bitcoinAddressRecord.balance += coinInfo.value;
|
coin.bitcoinAddressRecord.balance += coinInfo.value;
|
||||||
} else {
|
} else {
|
||||||
_addCoinInfo(coin);
|
_addCoinInfo(coin);
|
||||||
|
@ -1172,6 +1176,7 @@ abstract class ElectrumWalletBase
|
||||||
coin.isFrozen = coinInfo.isFrozen;
|
coin.isFrozen = coinInfo.isFrozen;
|
||||||
coin.isSending = coinInfo.isSending;
|
coin.isSending = coinInfo.isSending;
|
||||||
coin.note = coinInfo.note;
|
coin.note = coinInfo.note;
|
||||||
|
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
|
||||||
coin.bitcoinAddressRecord.balance += coinInfo.value;
|
coin.bitcoinAddressRecord.balance += coinInfo.value;
|
||||||
} else {
|
} else {
|
||||||
_addCoinInfo(coin);
|
_addCoinInfo(coin);
|
||||||
|
@ -1588,7 +1593,6 @@ abstract class ElectrumWalletBase
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
try {
|
try {
|
||||||
if (_isTransactionUpdating) {
|
if (_isTransactionUpdating) {
|
||||||
_isTransactionUpdating = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1734,7 +1738,7 @@ abstract class ElectrumWalletBase
|
||||||
_currentChainTip = height;
|
_currentChainTip = height;
|
||||||
|
|
||||||
if (_currentChainTip != null && _currentChainTip! > 0 && walletInfo.restoreHeight == 0) {
|
if (_currentChainTip != null && _currentChainTip! > 0 && walletInfo.restoreHeight == 0) {
|
||||||
walletInfo.restoreHeight = _currentChainTip!;
|
await walletInfo.updateRestoreHeight(_currentChainTip!);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1818,66 +1822,36 @@ class SyncResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> startRefresh(ScanData scanData) async {
|
Future<void> startRefresh(ScanData scanData) async {
|
||||||
Future<ElectrumClient> getElectrumConnection() async {
|
int syncHeight = scanData.height;
|
||||||
final electrumClient = scanData.electrumClient;
|
int initialSyncHeight = syncHeight;
|
||||||
if (!electrumClient.isConnected) {
|
|
||||||
final node = scanData.node;
|
|
||||||
await electrumClient.connectToUri(node.uri, useSSL: node.useSSL);
|
|
||||||
}
|
|
||||||
return electrumClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastKnownBlockHeight = 0;
|
|
||||||
var initialSyncHeight = 0;
|
|
||||||
|
|
||||||
var syncHeight = scanData.height;
|
|
||||||
var currentChainTip = scanData.chainTip;
|
|
||||||
|
|
||||||
if (syncHeight <= 0) {
|
|
||||||
syncHeight = currentChainTip;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initialSyncHeight <= 0) {
|
|
||||||
initialSyncHeight = syncHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastKnownBlockHeight == syncHeight) {
|
|
||||||
scanData.sendPort.send(SyncResponse(currentChainTip, SyncedSyncStatus()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BehaviorSubject<Object>? tweaksSubscription = null;
|
BehaviorSubject<Object>? tweaksSubscription = null;
|
||||||
|
|
||||||
lastKnownBlockHeight = syncHeight;
|
final syncingStatus = scanData.isSingleScan
|
||||||
|
? SyncingSyncStatus(1, 0)
|
||||||
SyncingSyncStatus syncingStatus;
|
: SyncingSyncStatus.fromHeightValues(scanData.chainTip, initialSyncHeight, syncHeight);
|
||||||
if (scanData.isSingleScan) {
|
|
||||||
syncingStatus = SyncingSyncStatus(1, 0);
|
|
||||||
} else {
|
|
||||||
syncingStatus =
|
|
||||||
SyncingSyncStatus.fromHeightValues(scanData.chainTip, initialSyncHeight, syncHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Initial status UI update, send how many blocks left to scan
|
||||||
scanData.sendPort.send(SyncResponse(syncHeight, syncingStatus));
|
scanData.sendPort.send(SyncResponse(syncHeight, syncingStatus));
|
||||||
|
|
||||||
if (syncingStatus.blocksLeft <= 0 || (scanData.isSingleScan && scanData.height != syncHeight)) {
|
final electrumClient = scanData.electrumClient;
|
||||||
scanData.sendPort.send(SyncResponse(scanData.chainTip, SyncedSyncStatus()));
|
await electrumClient.connectToUri(scanData.node.uri, useSSL: scanData.node.useSSL);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final electrumClient = await getElectrumConnection();
|
|
||||||
|
|
||||||
if (tweaksSubscription == null) {
|
if (tweaksSubscription == null) {
|
||||||
final count = scanData.isSingleScan ? 1 : TWEAKS_COUNT;
|
final count = scanData.isSingleScan ? 1 : TWEAKS_COUNT;
|
||||||
|
final receiver = Receiver(
|
||||||
|
scanData.silentAddress.b_scan.toHex(),
|
||||||
|
scanData.silentAddress.B_spend.toHex(),
|
||||||
|
scanData.network == BitcoinNetwork.testnet,
|
||||||
|
scanData.labelIndexes,
|
||||||
|
scanData.labelIndexes.length,
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
|
||||||
tweaksSubscription = await electrumClient.tweaksSubscribe(height: syncHeight, count: count);
|
tweaksSubscription = await electrumClient.tweaksSubscribe(height: syncHeight, count: count);
|
||||||
|
|
||||||
tweaksSubscription?.listen((t) async {
|
tweaksSubscription?.listen((t) async {
|
||||||
final tweaks = t as Map<String, dynamic>;
|
final tweaks = t as Map<String, dynamic>;
|
||||||
|
|
||||||
if (tweaks["message"] != null && !scanData.isSingleScan) {
|
if (tweaks["message"] != null) {
|
||||||
// re-subscribe to continue receiving messages
|
// re-subscribe to continue receiving messages
|
||||||
electrumClient.tweaksSubscribe(height: syncHeight, count: count);
|
electrumClient.tweaksSubscribe(height: syncHeight, count: count);
|
||||||
return;
|
return;
|
||||||
|
@ -1898,15 +1872,9 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
try {
|
try {
|
||||||
// scanOutputs called from rust here
|
// scanOutputs called from rust here
|
||||||
final addToWallet = scanOutputs(
|
final addToWallet = scanOutputs(
|
||||||
outputPubkeys.values.map((o) => o[0].toString()).toList(),
|
outputPubkeys.values.toList(),
|
||||||
tweak,
|
tweak,
|
||||||
Receiver(
|
receiver,
|
||||||
scanData.silentAddress.b_scan.toHex(),
|
|
||||||
scanData.silentAddress.B_spend.toHex(),
|
|
||||||
scanData.network == BitcoinNetwork.testnet,
|
|
||||||
scanData.labelIndexes,
|
|
||||||
scanData.labelIndexes.length,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (addToWallet.isEmpty) {
|
if (addToWallet.isEmpty) {
|
||||||
|
@ -1923,7 +1891,9 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
fee: 0,
|
fee: 0,
|
||||||
direction: TransactionDirection.incoming,
|
direction: TransactionDirection.incoming,
|
||||||
isPending: false,
|
isPending: false,
|
||||||
date: DateTime.now(),
|
date: scanData.network == BitcoinNetwork.mainnet
|
||||||
|
? getDateByBitcoinHeight(tweakHeight)
|
||||||
|
: DateTime.now(),
|
||||||
confirmations: scanData.chainTip - tweakHeight + 1,
|
confirmations: scanData.chainTip - tweakHeight + 1,
|
||||||
unspents: [],
|
unspents: [],
|
||||||
);
|
);
|
||||||
|
@ -1936,17 +1906,6 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
.toTaprootAddress(tweak: false)
|
.toTaprootAddress(tweak: false)
|
||||||
.toAddress(scanData.network);
|
.toAddress(scanData.network);
|
||||||
|
|
||||||
final receivedAddressRecord = BitcoinSilentPaymentAddressRecord(
|
|
||||||
receivingOutputAddress,
|
|
||||||
index: 0,
|
|
||||||
isHidden: false,
|
|
||||||
isUsed: true,
|
|
||||||
network: scanData.network,
|
|
||||||
silentPaymentTweak: t_k,
|
|
||||||
type: SegwitAddresType.p2tr,
|
|
||||||
txCount: 1,
|
|
||||||
);
|
|
||||||
|
|
||||||
int? amount;
|
int? amount;
|
||||||
int? pos;
|
int? pos;
|
||||||
outputPubkeys.entries.firstWhere((k) {
|
outputPubkeys.entries.firstWhere((k) {
|
||||||
|
@ -1959,6 +1918,18 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final receivedAddressRecord = BitcoinSilentPaymentAddressRecord(
|
||||||
|
receivingOutputAddress,
|
||||||
|
index: 0,
|
||||||
|
isHidden: false,
|
||||||
|
isUsed: true,
|
||||||
|
network: scanData.network,
|
||||||
|
silentPaymentTweak: t_k,
|
||||||
|
type: SegwitAddresType.p2tr,
|
||||||
|
txCount: 1,
|
||||||
|
balance: amount!,
|
||||||
|
);
|
||||||
|
|
||||||
final unspent = BitcoinSilentPaymentsUnspent(
|
final unspent = BitcoinSilentPaymentsUnspent(
|
||||||
receivedAddressRecord,
|
receivedAddressRecord,
|
||||||
txid,
|
txid,
|
||||||
|
@ -1983,25 +1954,18 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
SyncResponse(
|
SyncResponse(
|
||||||
syncHeight,
|
syncHeight,
|
||||||
SyncingSyncStatus.fromHeightValues(
|
SyncingSyncStatus.fromHeightValues(
|
||||||
currentChainTip,
|
scanData.chainTip,
|
||||||
initialSyncHeight,
|
initialSyncHeight,
|
||||||
syncHeight,
|
syncHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (int.parse(blockHeight) >= scanData.chainTip || scanData.isSingleScan) {
|
if (tweakHeight >= scanData.chainTip || scanData.isSingleScan) {
|
||||||
scanData.sendPort.send(SyncResponse(syncHeight, SyncedSyncStatus()));
|
scanData.sendPort.send(SyncResponse(syncHeight, SyncedSyncStatus()));
|
||||||
await tweaksSubscription!.close();
|
await tweaksSubscription!.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
|
||||||
if (e is RequestFailedTimeoutException) {
|
|
||||||
return scanData.sendPort.send(
|
|
||||||
SyncResponse(syncHeight, TimedOutSyncStatus()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tweaksSubscription == null) {
|
if (tweaksSubscription == null) {
|
||||||
|
@ -2009,12 +1973,6 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
SyncResponse(syncHeight, UnsupportedSyncStatus()),
|
SyncResponse(syncHeight, UnsupportedSyncStatus()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e, stacktrace) {
|
|
||||||
print(stacktrace);
|
|
||||||
print(e.toString());
|
|
||||||
|
|
||||||
scanData.sendPort.send(SyncResponse(syncHeight, NotConnectedSyncStatus()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EstimatedTxResult {
|
class EstimatedTxResult {
|
||||||
|
|
|
@ -794,7 +794,7 @@ packages:
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: master
|
ref: master
|
||||||
resolved-ref: a6b14bcc37ec16f56931e48afa8a8f8e6939431d
|
resolved-ref: "4977a0d31fc8614d27193b07d92c5992d163131e"
|
||||||
url: "https://github.com/rafael-xmr/sp_scanner"
|
url: "https://github.com/rafael-xmr/sp_scanner"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
|
|
@ -245,6 +245,7 @@ Future<int> getHavenCurrentHeight() async {
|
||||||
|
|
||||||
// Data taken from https://timechaincalendar.com/
|
// Data taken from https://timechaincalendar.com/
|
||||||
const bitcoinDates = {
|
const bitcoinDates = {
|
||||||
|
"2024-05": 841590,
|
||||||
"2024-04": 837182,
|
"2024-04": 837182,
|
||||||
"2024-03": 832623,
|
"2024-03": 832623,
|
||||||
"2024-02": 828319,
|
"2024-02": 828319,
|
||||||
|
@ -265,7 +266,9 @@ const bitcoinDates = {
|
||||||
|
|
||||||
int getBitcoinHeightByDate({required DateTime date}) {
|
int getBitcoinHeightByDate({required DateTime date}) {
|
||||||
String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}';
|
String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}';
|
||||||
int startBlock = bitcoinDates[dateKey] ?? bitcoinDates.values.last;
|
final closestKey = bitcoinDates.keys
|
||||||
|
.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => bitcoinDates.keys.last);
|
||||||
|
int startBlock = bitcoinDates[dateKey] ?? bitcoinDates[closestKey]!;
|
||||||
|
|
||||||
DateTime startOfMonth = DateTime(date.year, date.month);
|
DateTime startOfMonth = DateTime(date.year, date.month);
|
||||||
int daysDifference = date.difference(startOfMonth).inDays;
|
int daysDifference = date.difference(startOfMonth).inDays;
|
||||||
|
@ -275,3 +278,9 @@ int getBitcoinHeightByDate({required DateTime date}) {
|
||||||
|
|
||||||
return startBlock + estimatedBlocksSinceStartOfMonth;
|
return startBlock + estimatedBlocksSinceStartOfMonth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateTime getDateByBitcoinHeight(int height) {
|
||||||
|
final date = bitcoinDates.entries
|
||||||
|
.lastWhere((entry) => entry.value >= height, orElse: () => bitcoinDates.entries.last);
|
||||||
|
return formatMapKey(date.key);
|
||||||
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ class WalletInfo extends HiveObject {
|
||||||
this.showIntroCakePayCard,
|
this.showIntroCakePayCard,
|
||||||
this.derivationInfo,
|
this.derivationInfo,
|
||||||
this.hardwareWalletType,
|
this.hardwareWalletType,
|
||||||
): _yatLastUsedAddressController = StreamController<String>.broadcast();
|
) : _yatLastUsedAddressController = StreamController<String>.broadcast();
|
||||||
|
|
||||||
factory WalletInfo.external({
|
factory WalletInfo.external({
|
||||||
required String id,
|
required String id,
|
||||||
|
@ -207,4 +207,9 @@ class WalletInfo extends HiveObject {
|
||||||
Stream<String> get yatLastUsedAddressStream => _yatLastUsedAddressController.stream;
|
Stream<String> get yatLastUsedAddressStream => _yatLastUsedAddressController.stream;
|
||||||
|
|
||||||
StreamController<String> _yatLastUsedAddressController;
|
StreamController<String> _yatLastUsedAddressController;
|
||||||
|
|
||||||
|
Future<void> updateRestoreHeight(int height) async {
|
||||||
|
restoreHeight = height;
|
||||||
|
await save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ const cakeWalletBitcoinCashDefaultNodeUri = 'bitcoincash.stackwallet.com:50002';
|
||||||
const nanoDefaultNodeUri = 'rpc.nano.to';
|
const nanoDefaultNodeUri = 'rpc.nano.to';
|
||||||
const nanoDefaultPowNodeUri = 'rpc.nano.to';
|
const nanoDefaultPowNodeUri = 'rpc.nano.to';
|
||||||
const solanaDefaultNodeUri = 'rpc.ankr.com';
|
const solanaDefaultNodeUri = 'rpc.ankr.com';
|
||||||
const tronDefaultNodeUri = 'api.trongrid.io';
|
|
||||||
const tronDefaultNodeUri = 'tron-rpc.publicnode.com:443';
|
const tronDefaultNodeUri = 'tron-rpc.publicnode.com:443';
|
||||||
const newCakeWalletBitcoinUri = '198.58.111.154:50001';
|
const newCakeWalletBitcoinUri = '198.58.111.154:50001';
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,11 @@ import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
ReactionDisposer? _onWalletSyncStatusChangeReaction;
|
ReactionDisposer? _onWalletSyncStatusChangeReaction;
|
||||||
|
|
||||||
void startWalletSyncStatusChangeReaction(
|
void startWalletSyncStatusChangeReaction(
|
||||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet,
|
||||||
TransactionInfo> wallet,
|
|
||||||
FiatConversionStore fiatConversionStore) {
|
FiatConversionStore fiatConversionStore) {
|
||||||
_onWalletSyncStatusChangeReaction?.reaction.dispose();
|
_onWalletSyncStatusChangeReaction?.reaction.dispose();
|
||||||
_onWalletSyncStatusChangeReaction =
|
_onWalletSyncStatusChangeReaction = reaction((_) => wallet.syncStatus, (SyncStatus status) async {
|
||||||
reaction((_) => wallet.syncStatus, (SyncStatus status) async {
|
if (!(status is SyncingSyncStatus) || wallet.type != WalletType.bitcoin)
|
||||||
try {
|
try {
|
||||||
if (status is ConnectedSyncStatus) {
|
if (status is ConnectedSyncStatus) {
|
||||||
await wallet.startSync();
|
await wallet.startSync();
|
||||||
|
@ -32,7 +31,7 @@ void startWalletSyncStatusChangeReaction(
|
||||||
if (status is SyncedSyncStatus || status is FailedSyncStatus) {
|
if (status is SyncedSyncStatus || status is FailedSyncStatus) {
|
||||||
await WakelockPlus.disable();
|
await WakelockPlus.disable();
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -252,6 +252,7 @@ class CryptoBalanceWidget extends StatelessWidget {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
|
||||||
child: DashBoardRoundedCardWidget(
|
child: DashBoardRoundedCardWidget(
|
||||||
|
customBorder: 30,
|
||||||
title: S.of(context).silent_payments,
|
title: S.of(context).silent_payments,
|
||||||
subTitle: S.of(context).enable_silent_payments_scanning,
|
subTitle: S.of(context).enable_silent_payments_scanning,
|
||||||
hint: Column(
|
hint: Column(
|
||||||
|
|
|
@ -13,6 +13,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
|
||||||
this.svgPicture,
|
this.svgPicture,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.onClose,
|
this.onClose,
|
||||||
|
this.customBorder,
|
||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
|
@ -22,6 +23,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
|
||||||
final Widget? hint;
|
final Widget? hint;
|
||||||
final SvgPicture? svgPicture;
|
final SvgPicture? svgPicture;
|
||||||
final Icon? icon;
|
final Icon? icon;
|
||||||
|
final double? customBorder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -37,7 +39,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(customBorder ?? 20),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
|
color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
|
||||||
),
|
),
|
||||||
|
|
|
@ -218,7 +218,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||||
isFiatDisabled ? '' : pendingTransactionFeeFiatAmount + ' ' + fiat.title;
|
isFiatDisabled ? '' : pendingTransactionFeeFiatAmount + ' ' + fiat.title;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
bool get isReadyForSend => wallet.syncStatus is SyncedSyncStatus;
|
bool get isReadyForSend =>
|
||||||
|
wallet.syncStatus is SyncedSyncStatus ||
|
||||||
|
// If silent payments scanning, can still send payments
|
||||||
|
(wallet.type == WalletType.bitcoin && wallet.syncStatus is SyncingSyncStatus);
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
List<Template> get templates => sendTemplateViewModel.templates
|
List<Template> get templates => sendTemplateViewModel.templates
|
||||||
|
|
Loading…
Reference in a new issue