This commit is contained in:
M 2020-12-17 15:39:21 +02:00
parent 1188edd5b7
commit 4a2f1e48ff
7 changed files with 65 additions and 43 deletions

View file

@ -7,7 +7,10 @@ import 'package:cake_wallet/entities/balance.dart';
class BitcoinBalance extends Balance { class BitcoinBalance extends Balance {
const BitcoinBalance({@required this.confirmed, @required this.unconfirmed}) const BitcoinBalance({@required this.confirmed, @required this.unconfirmed})
: super(const [BalanceDisplayMode.availableBalance]); : super(const [
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.fullBalance
]);
factory BitcoinBalance.fromJSON(String jsonSource) { factory BitcoinBalance.fromJSON(String jsonSource) {
if (jsonSource == null) { if (jsonSource == null) {
@ -38,7 +41,7 @@ class BitcoinBalance extends Balance {
case BalanceDisplayMode.fullBalance: case BalanceDisplayMode.fullBalance:
return totalFormatted; return totalFormatted;
case BalanceDisplayMode.availableBalance: case BalanceDisplayMode.availableBalance:
return totalFormatted; return confirmedFormatted;
default: default:
return null; return null;
} }

View file

@ -12,6 +12,7 @@ class BitcoinTransactionInfo extends TransactionInfo {
{@required String id, {@required String id,
@required int height, @required int height,
@required int amount, @required int amount,
@required int fee,
@required TransactionDirection direction, @required TransactionDirection direction,
@required bool isPending, @required bool isPending,
@required DateTime date, @required DateTime date,
@ -19,6 +20,7 @@ class BitcoinTransactionInfo extends TransactionInfo {
this.id = id; this.id = id;
this.height = height; this.height = height;
this.amount = amount; this.amount = amount;
this.fee = fee;
this.direction = direction; this.direction = direction;
this.date = date; this.date = date;
this.isPending = isPending; this.isPending = isPending;
@ -36,37 +38,42 @@ class BitcoinTransactionInfo extends TransactionInfo {
: DateTime.now(); : DateTime.now();
final confirmations = obj['confirmations'] as int ?? 0; final confirmations = obj['confirmations'] as int ?? 0;
var direction = TransactionDirection.incoming; var direction = TransactionDirection.incoming;
var inputsAmount = 0;
var amount = 0;
var totalOutAmount = 0;
for (dynamic vin in vins) { for (dynamic vin in vins) {
final vout = vin['vout'] as int; final vout = vin['vout'] as int;
final out = vin['tx']['vout'][vout] as Map; final out = vin['tx']['vout'][vout] as Map;
final outAddresses = final outAddresses =
(out['scriptPubKey']['addresses'] as List<Object>)?.toSet(); (out['scriptPubKey']['addresses'] as List<Object>)?.toSet();
inputsAmount += doubleToBitcoinAmount(out['value'] as double ?? 0);
if (outAddresses?.intersection(addressesSet)?.isNotEmpty ?? false) { if (outAddresses?.intersection(addressesSet)?.isNotEmpty ?? false) {
direction = TransactionDirection.outgoing; direction = TransactionDirection.outgoing;
break;
} }
} }
final amount = vout.fold(0, (int acc, dynamic out) { for (dynamic out in vout) {
final outAddresses = final outAddresses =
out['scriptPubKey']['addresses'] as List<Object> ?? []; out['scriptPubKey']['addresses'] as List<Object> ?? [];
final ntrs = outAddresses.toSet().intersection(addressesSet); final ntrs = outAddresses.toSet().intersection(addressesSet);
var amount = acc; final value = doubleToBitcoinAmount(out['value'] as double ?? 0.0);
totalOutAmount += value;
if ((direction == TransactionDirection.incoming && ntrs.isNotEmpty) || if ((direction == TransactionDirection.incoming && ntrs.isNotEmpty) ||
(direction == TransactionDirection.outgoing && ntrs.isEmpty)) { (direction == TransactionDirection.outgoing && ntrs.isEmpty)) {
amount += doubleToBitcoinAmount(out['value'] as double ?? 0.0); amount += value;
} }
}
return amount; final fee = inputsAmount - totalOutAmount;
});
return BitcoinTransactionInfo( return BitcoinTransactionInfo(
id: id, id: id,
height: height, height: height,
isPending: false, isPending: false,
fee: fee,
direction: direction, direction: direction,
amount: amount, amount: amount,
date: date, date: date,
@ -101,6 +108,7 @@ class BitcoinTransactionInfo extends TransactionInfo {
id: tx.getId(), id: tx.getId(),
height: height, height: height,
isPending: false, isPending: false,
fee: null,
direction: TransactionDirection.incoming, direction: TransactionDirection.incoming,
amount: amount, amount: amount,
date: date, date: date,
@ -112,6 +120,7 @@ class BitcoinTransactionInfo extends TransactionInfo {
id: data['id'] as String, id: data['id'] as String,
height: data['height'] as int, height: data['height'] as int,
amount: data['amount'] as int, amount: data['amount'] as int,
fee: data['fee'] as int,
direction: parseTransactionDirectionFromInt(data['direction'] as int), direction: parseTransactionDirectionFromInt(data['direction'] as int),
date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int), date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int),
isPending: data['isPending'] as bool, isPending: data['isPending'] as bool,
@ -124,6 +133,11 @@ class BitcoinTransactionInfo extends TransactionInfo {
String amountFormatted() => String amountFormatted() =>
'${formatAmount(bitcoinAmountToString(amount: amount))} BTC'; '${formatAmount(bitcoinAmountToString(amount: amount))} BTC';
@override
String feeFormatted() => fee != null
? '${formatAmount(bitcoinAmountToString(amount: fee))} BTC'
: '';
@override @override
String fiatAmount() => _fiatAmount ?? ''; String fiatAmount() => _fiatAmount ?? '';
@ -135,6 +149,7 @@ class BitcoinTransactionInfo extends TransactionInfo {
id: id, id: id,
height: info.height, height: info.height,
amount: info.amount, amount: info.amount,
fee: info.fee,
direction: direction ?? info.direction, direction: direction ?? info.direction,
date: date ?? info.date, date: date ?? info.date,
isPending: isPending ?? info.isPending, isPending: isPending ?? info.isPending,
@ -150,6 +165,7 @@ class BitcoinTransactionInfo extends TransactionInfo {
m['date'] = date.millisecondsSinceEpoch; m['date'] = date.millisecondsSinceEpoch;
m['isPending'] = isPending; m['isPending'] = isPending;
m['confirmations'] = confirmations; m['confirmations'] = confirmations;
m['fee'] = fee;
return m; return m;
} }
} }

View file

@ -4,6 +4,7 @@ import 'package:cake_wallet/utils/mobx.dart';
abstract class TransactionInfo extends Object with Keyable { abstract class TransactionInfo extends Object with Keyable {
String id; String id;
int amount; int amount;
int fee;
TransactionDirection direction; TransactionDirection direction;
bool isPending; bool isPending;
DateTime date; DateTime date;
@ -11,6 +12,7 @@ abstract class TransactionInfo extends Object with Keyable {
int confirmations; int confirmations;
String amountFormatted(); String amountFormatted();
String fiatAmount(); String fiatAmount();
String feeFormatted();
void changeFiatAmount(String amount); void changeFiatAmount(String amount);
@override @override

View file

@ -208,7 +208,7 @@ class S implements WidgetsLocalizations {
String get send_error_currency => "Currency can only contain numbers"; String get send_error_currency => "Currency can only contain numbers";
String get send_error_minimum_value => "Minimum value of amount is 0.01"; String get send_error_minimum_value => "Minimum value of amount is 0.01";
String get send_estimated_fee => "Estimated fee:"; String get send_estimated_fee => "Estimated fee:";
String get send_fee => "Fee:"; String get send_fee => "Fee";
String get send_got_it => "Got it"; String get send_got_it => "Got it";
String get send_name => "Name"; String get send_name => "Name";
String get send_new => "New"; String get send_new => "New";
@ -396,7 +396,7 @@ class $de extends S {
@override @override
String get transaction_sent => "Transaktion gesendet!"; String get transaction_sent => "Transaktion gesendet!";
@override @override
String get send_fee => "Gebühr:"; String get send_fee => "Gebühr";
@override @override
String get password => "Passwort"; String get password => "Passwort";
@override @override
@ -1780,7 +1780,7 @@ class $ru extends S {
@override @override
String get transaction_sent => "Tранзакция отправлена!"; String get transaction_sent => "Tранзакция отправлена!";
@override @override
String get send_fee => "Комиссия:"; String get send_fee => "Комиссия";
@override @override
String get password => "Пароль"; String get password => "Пароль";
@override @override
@ -2472,7 +2472,7 @@ class $ko extends S {
@override @override
String get transaction_sent => "거래가 전송되었습니다!"; String get transaction_sent => "거래가 전송되었습니다!";
@override @override
String get send_fee => "회비:"; String get send_fee => "회비";
@override @override
String get password => "암호"; String get password => "암호";
@override @override
@ -3164,7 +3164,7 @@ class $pt extends S {
@override @override
String get transaction_sent => "Transação enviada!"; String get transaction_sent => "Transação enviada!";
@override @override
String get send_fee => "Taxa:"; String get send_fee => "Taxa";
@override @override
String get password => "Senha"; String get password => "Senha";
@override @override
@ -3856,7 +3856,7 @@ class $uk extends S {
@override @override
String get transaction_sent => "Tранзакцію відправлено!"; String get transaction_sent => "Tранзакцію відправлено!";
@override @override
String get send_fee => "Комісія:"; String get send_fee => "Комісія";
@override @override
String get password => "Пароль"; String get password => "Пароль";
@override @override
@ -4548,7 +4548,7 @@ class $ja extends S {
@override @override
String get transaction_sent => "トランザクションが送信されました!"; String get transaction_sent => "トランザクションが送信されました!";
@override @override
String get send_fee => "費用"; String get send_fee => "費用";
@override @override
String get password => "パスワード"; String get password => "パスワード";
@override @override
@ -5244,7 +5244,7 @@ class $pl extends S {
@override @override
String get transaction_sent => "Transakcja wysłana!"; String get transaction_sent => "Transakcja wysłana!";
@override @override
String get send_fee => "Opłata:"; String get send_fee => "Opłata";
@override @override
String get password => "Hasło"; String get password => "Hasło";
@override @override
@ -5936,7 +5936,7 @@ class $es extends S {
@override @override
String get transaction_sent => "Transacción enviada!"; String get transaction_sent => "Transacción enviada!";
@override @override
String get send_fee => "Cuota:"; String get send_fee => "Cuota";
@override @override
String get password => "Contraseña"; String get password => "Contraseña";
@override @override
@ -6628,7 +6628,7 @@ class $nl extends S {
@override @override
String get transaction_sent => "Transactie verzonden!"; String get transaction_sent => "Transactie verzonden!";
@override @override
String get send_fee => "Vergoeding:"; String get send_fee => "Vergoeding";
@override @override
String get password => "Wachtwoord"; String get password => "Wachtwoord";
@override @override
@ -7320,7 +7320,7 @@ class $zh extends S {
@override @override
String get transaction_sent => "交易已发送"; String get transaction_sent => "交易已发送";
@override @override
String get send_fee => "費用:"; String get send_fee => "費用";
@override @override
String get password => "密码"; String get password => "密码";
@override @override

View file

@ -16,10 +16,9 @@ class AddressPage extends StatelessWidget {
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: Center( child: Center(
child: QRWidget(addressListViewModel: addressListViewModel), child: QRWidget(addressListViewModel: addressListViewModel),
) )),
),
GestureDetector( GestureDetector(
onTap: () => Navigator.of(context).pushNamed(Routes.receive), onTap: () => Navigator.of(context).pushNamed(Routes.receive),
child: Container( child: Container(
@ -27,24 +26,23 @@ class AddressPage extends StatelessWidget {
padding: EdgeInsets.only(left: 24, right: 12), padding: EdgeInsets.only(left: 24, right: 12),
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(25)), borderRadius: BorderRadius.all(Radius.circular(25)),
border: Border.all( border: Border.all(
color: Theme.of(context).textTheme.subhead.color, color: Theme.of(context).textTheme.subhead.color,
width: 1 width: 1),
), color: Theme.of(context).buttonColor),
color: Theme.of(context).buttonColor
),
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Text( Text(
S.of(context).accounts_subaddresses, addressListViewModel.hasAccounts
? S.of(context).accounts_subaddresses
: S.of(context).addresses,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Colors.white color: Colors.white),
),
), ),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
@ -59,4 +57,4 @@ class AddressPage extends StatelessWidget {
), ),
); );
} }
} }

View file

@ -13,7 +13,8 @@ import 'package:cake_wallet/utils/date_formatter.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
class TransactionDetailsPage extends BasePage { class TransactionDetailsPage extends BasePage {
TransactionDetailsPage(this.transactionInfo, bool showRecipientAddress, Box<TransactionDescription> transactionDescriptionBox) TransactionDetailsPage(this.transactionInfo, bool showRecipientAddress,
Box<TransactionDescription> transactionDescriptionBox)
: _items = [] { : _items = [] {
final dateFormat = DateFormatter.withCurrentLocal(); final dateFormat = DateFormatter.withCurrentLocal();
final tx = transactionInfo; final tx = transactionInfo;
@ -30,9 +31,7 @@ class TransactionDetailsPage extends BasePage {
StandartListItem( StandartListItem(
title: S.current.transaction_details_amount, title: S.current.transaction_details_amount,
value: tx.amountFormatted()), value: tx.amountFormatted()),
StandartListItem( StandartListItem(title: S.current.send_fee, value: tx.feeFormatted())
title: S.current.send_fee,
value: tx.feeFormatted())
]; ];
if (tx.key?.isNotEmpty ?? null) { if (tx.key?.isNotEmpty ?? null) {
@ -56,14 +55,18 @@ class TransactionDetailsPage extends BasePage {
title: S.current.transaction_details_height, value: '${tx.height}'), title: S.current.transaction_details_height, value: '${tx.height}'),
StandartListItem( StandartListItem(
title: S.current.transaction_details_amount, title: S.current.transaction_details_amount,
value: tx.amountFormatted()) value: tx.amountFormatted()),
if (tx.feeFormatted()?.isNotEmpty)
StandartListItem(title: S.current.send_fee, value: tx.feeFormatted())
]; ];
_items.addAll(items); _items.addAll(items);
} }
if (showRecipientAddress) { if (showRecipientAddress) {
final recipientAddress = transactionDescriptionBox.values.firstWhere((val) => val.id == transactionInfo.id, orElse: () => null)?.recipientAddress; final recipientAddress = transactionDescriptionBox.values
.firstWhere((val) => val.id == transactionInfo.id, orElse: () => null)
?.recipientAddress;
if (recipientAddress?.isNotEmpty ?? false) { if (recipientAddress?.isNotEmpty ?? false) {
_items.add(StandartListItem( _items.add(StandartListItem(

View file

@ -95,7 +95,7 @@ abstract class BalanceViewModelBase with Store {
if (_wallet is BitcoinWallet) { if (_wallet is BitcoinWallet) {
return WalletBalance( return WalletBalance(
unlockedBalance: _wallet.balance.totalFormatted, unlockedBalance: _wallet.balance.confirmedFormatted,
totalBalance: _wallet.balance.totalFormatted); totalBalance: _wallet.balance.totalFormatted);
} }