mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 11:59:30 +00:00
token transaction display fixes
This commit is contained in:
parent
90cc8ced9c
commit
46d454fad1
6 changed files with 115 additions and 55 deletions
|
@ -6,7 +6,6 @@ import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'
|
|||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/extensions/extensions.dart';
|
||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
|
||||
|
||||
|
@ -79,7 +78,7 @@ class TransactionV2 {
|
|||
return confirmations >= minimumConfirms;
|
||||
}
|
||||
|
||||
Amount getFee({required Coin coin}) {
|
||||
Amount getFee({required int fractionDigits}) {
|
||||
// check for override fee
|
||||
final fee = _getOverrideFee();
|
||||
if (fee != null) {
|
||||
|
@ -92,44 +91,47 @@ class TransactionV2 {
|
|||
.map((e) => e.value)
|
||||
.reduce((value, element) => value += element);
|
||||
|
||||
return Amount(rawValue: inSum - outSum, fractionDigits: coin.decimals);
|
||||
return Amount(rawValue: inSum - outSum, fractionDigits: fractionDigits);
|
||||
}
|
||||
|
||||
Amount getAmountReceivedInThisWallet({required Coin coin}) {
|
||||
Amount getAmountReceivedInThisWallet({required int fractionDigits}) {
|
||||
final outSum = outputs
|
||||
.where((e) => e.walletOwns)
|
||||
.fold(BigInt.zero, (p, e) => p + e.value);
|
||||
|
||||
return Amount(rawValue: outSum, fractionDigits: coin.decimals);
|
||||
return Amount(rawValue: outSum, fractionDigits: fractionDigits);
|
||||
}
|
||||
|
||||
Amount getAmountSparkSelfMinted({required Coin coin}) {
|
||||
Amount getAmountSparkSelfMinted({required int fractionDigits}) {
|
||||
final outSum = outputs.where((e) {
|
||||
final op = e.scriptPubKeyHex.substring(0, 2).toUint8ListFromHex.first;
|
||||
return e.walletOwns && (op == OP_SPARKMINT);
|
||||
}).fold(BigInt.zero, (p, e) => p + e.value);
|
||||
|
||||
return Amount(rawValue: outSum, fractionDigits: coin.decimals);
|
||||
return Amount(rawValue: outSum, fractionDigits: fractionDigits);
|
||||
}
|
||||
|
||||
Amount getAmountSentFromThisWallet({required Coin coin}) {
|
||||
Amount getAmountSentFromThisWallet({required int fractionDigits}) {
|
||||
final inSum = inputs
|
||||
.where((e) => e.walletOwns)
|
||||
.fold(BigInt.zero, (p, e) => p + e.value);
|
||||
|
||||
final amount = Amount(
|
||||
Amount amount = Amount(
|
||||
rawValue: inSum,
|
||||
fractionDigits: coin.decimals,
|
||||
fractionDigits: fractionDigits,
|
||||
) -
|
||||
getAmountReceivedInThisWallet(
|
||||
coin: coin,
|
||||
) -
|
||||
getFee(coin: coin);
|
||||
fractionDigits: fractionDigits,
|
||||
);
|
||||
|
||||
if (subType != TransactionSubType.ethToken) {
|
||||
amount = amount - getFee(fractionDigits: fractionDigits);
|
||||
}
|
||||
|
||||
// negative amounts are likely an error or can happen with coins such as eth
|
||||
// that don't use the btc style inputs/outputs
|
||||
if (amount.raw < BigInt.zero) {
|
||||
return Amount.zeroWith(fractionDigits: coin.decimals);
|
||||
return Amount.zeroWith(fractionDigits: fractionDigits);
|
||||
}
|
||||
|
||||
return amount;
|
||||
|
|
|
@ -843,6 +843,9 @@ class _DesktopTransactionCardRowState
|
|||
late final TransactionV2 _transaction;
|
||||
late final String walletId;
|
||||
late final int minConfirms;
|
||||
late final EthContract? ethContract;
|
||||
|
||||
bool get isTokenTx => ethContract != null;
|
||||
|
||||
String whatIsIt(TransactionV2 tx, int height) => tx.statusLabel(
|
||||
currentChainHeight: height,
|
||||
|
@ -858,6 +861,15 @@ class _DesktopTransactionCardRowState
|
|||
.cryptoCurrency
|
||||
.minConfirms;
|
||||
_transaction = widget.transaction;
|
||||
|
||||
if (_transaction.subType == TransactionSubType.ethToken) {
|
||||
ethContract = ref
|
||||
.read(mainDBProvider)
|
||||
.getEthContractSync(_transaction.contractAddress!);
|
||||
} else {
|
||||
ethContract == null;
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -892,19 +904,22 @@ class _DesktopTransactionCardRowState
|
|||
final currentHeight = ref.watch(pWalletChainHeight(walletId));
|
||||
|
||||
final Amount amount;
|
||||
|
||||
final fractionDigits = ethContract?.decimals ?? coin.decimals;
|
||||
if (_transaction.subType == TransactionSubType.cashFusion) {
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
} else {
|
||||
switch (_transaction.type) {
|
||||
case TransactionType.outgoing:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
break;
|
||||
|
||||
case TransactionType.incoming:
|
||||
case TransactionType.sentToSelf:
|
||||
if (_transaction.subType == TransactionSubType.sparkMint) {
|
||||
amount = _transaction.getAmountSparkSelfMinted(coin: coin);
|
||||
amount = _transaction.getAmountSparkSelfMinted(
|
||||
fractionDigits: fractionDigits);
|
||||
} else if (_transaction.subType == TransactionSubType.sparkSpend) {
|
||||
final changeAddress =
|
||||
(ref.watch(pWallets).getWallet(walletId) as SparkInterface)
|
||||
|
@ -917,12 +932,14 @@ class _DesktopTransactionCardRowState
|
|||
fractionDigits: coin.decimals,
|
||||
);
|
||||
} else {
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
}
|
||||
break;
|
||||
|
||||
case TransactionType.unknown:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1005,7 +1022,7 @@ class _DesktopTransactionCardRowState
|
|||
Expanded(
|
||||
flex: 6,
|
||||
child: Text(
|
||||
"$prefix${ref.watch(pAmountFormatter(coin)).format(amount)}",
|
||||
"$prefix${ref.watch(pAmountFormatter(coin)).format(amount, ethContract: ethContract)}",
|
||||
style:
|
||||
STextStyles.desktopTextExtraExtraSmall(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textDark,
|
||||
|
|
|
@ -112,18 +112,23 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> {
|
|||
|
||||
final Amount amount;
|
||||
|
||||
final fractionDigits = tokenContract?.decimals ?? coin.decimals;
|
||||
|
||||
if (_transaction.subType == TransactionSubType.cashFusion) {
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
} else {
|
||||
switch (_transaction.type) {
|
||||
case TransactionType.outgoing:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
break;
|
||||
|
||||
case TransactionType.incoming:
|
||||
case TransactionType.sentToSelf:
|
||||
if (_transaction.subType == TransactionSubType.sparkMint) {
|
||||
amount = _transaction.getAmountSparkSelfMinted(coin: coin);
|
||||
amount = _transaction.getAmountSparkSelfMinted(
|
||||
fractionDigits: fractionDigits);
|
||||
} else if (_transaction.subType == TransactionSubType.sparkSpend) {
|
||||
final changeAddress =
|
||||
(ref.watch(pWallets).getWallet(walletId) as SparkInterface)
|
||||
|
@ -136,12 +141,14 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> {
|
|||
fractionDigits: coin.decimals,
|
||||
);
|
||||
} else {
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
}
|
||||
break;
|
||||
|
||||
case TransactionType.unknown:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
|
@ -84,6 +86,9 @@ class _TransactionV2DetailsViewState
|
|||
late final String amountPrefix;
|
||||
late final String unit;
|
||||
late final int minConfirms;
|
||||
late final EthContract? ethContract;
|
||||
|
||||
bool get isTokenTx => ethContract != null;
|
||||
|
||||
late final List<({List<String> addresses, Amount amount})> data;
|
||||
|
||||
|
@ -96,10 +101,24 @@ class _TransactionV2DetailsViewState
|
|||
walletId = widget.walletId;
|
||||
|
||||
coin = widget.coin;
|
||||
|
||||
if (_transaction.subType == TransactionSubType.ethToken) {
|
||||
ethContract = ref
|
||||
.read(mainDBProvider)
|
||||
.getEthContractSync(_transaction.contractAddress!);
|
||||
|
||||
unit = ethContract!.symbol;
|
||||
} else {
|
||||
ethContract == null;
|
||||
unit = coin.ticker;
|
||||
}
|
||||
|
||||
minConfirms =
|
||||
ref.read(pWallets).getWallet(walletId).cryptoCurrency.minConfirms;
|
||||
|
||||
fee = _transaction.getFee(coin: coin);
|
||||
final fractionDigits = ethContract?.decimals ?? coin.decimals;
|
||||
|
||||
fee = _transaction.getFee(fractionDigits: fractionDigits);
|
||||
|
||||
if (_transaction.subType == TransactionSubType.cashFusion ||
|
||||
_transaction.type == TransactionType.sentToSelf) {
|
||||
|
@ -108,18 +127,18 @@ class _TransactionV2DetailsViewState
|
|||
amountPrefix = _transaction.type == TransactionType.outgoing ? "-" : "+";
|
||||
}
|
||||
|
||||
unit = coin.ticker;
|
||||
|
||||
if (_transaction.isEpiccashTransaction) {
|
||||
switch (_transaction.type) {
|
||||
case TransactionType.outgoing:
|
||||
case TransactionType.unknown:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
break;
|
||||
|
||||
case TransactionType.incoming:
|
||||
case TransactionType.sentToSelf:
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
break;
|
||||
}
|
||||
data = _transaction.outputs
|
||||
|
@ -129,7 +148,8 @@ class _TransactionV2DetailsViewState
|
|||
))
|
||||
.toList();
|
||||
} else if (_transaction.subType == TransactionSubType.cashFusion) {
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
data = _transaction.outputs
|
||||
.where((e) => e.walletOwns)
|
||||
.map((e) => (
|
||||
|
@ -140,7 +160,8 @@ class _TransactionV2DetailsViewState
|
|||
} else {
|
||||
switch (_transaction.type) {
|
||||
case TransactionType.outgoing:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
data = _transaction.outputs
|
||||
.where((e) => !e.walletOwns)
|
||||
.map((e) => (
|
||||
|
@ -154,7 +175,8 @@ class _TransactionV2DetailsViewState
|
|||
case TransactionType.incoming:
|
||||
case TransactionType.sentToSelf:
|
||||
if (_transaction.subType == TransactionSubType.sparkMint) {
|
||||
amount = _transaction.getAmountSparkSelfMinted(coin: coin);
|
||||
amount = _transaction.getAmountSparkSelfMinted(
|
||||
fractionDigits: fractionDigits);
|
||||
} else if (_transaction.subType == TransactionSubType.sparkSpend) {
|
||||
final changeAddress =
|
||||
(ref.read(pWallets).getWallet(walletId) as SparkInterface)
|
||||
|
@ -167,7 +189,8 @@ class _TransactionV2DetailsViewState
|
|||
fractionDigits: coin.decimals,
|
||||
);
|
||||
} else {
|
||||
amount = _transaction.getAmountReceivedInThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountReceivedInThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
}
|
||||
data = _transaction.outputs
|
||||
.where((e) => e.walletOwns)
|
||||
|
@ -180,7 +203,8 @@ class _TransactionV2DetailsViewState
|
|||
break;
|
||||
|
||||
case TransactionType.unknown:
|
||||
amount = _transaction.getAmountSentFromThisWallet(coin: coin);
|
||||
amount = _transaction.getAmountSentFromThisWallet(
|
||||
fractionDigits: fractionDigits);
|
||||
data = _transaction.inputs
|
||||
.where((e) => e.walletOwns)
|
||||
.map((e) => (
|
||||
|
@ -515,7 +539,7 @@ class _TransactionV2DetailsViewState
|
|||
: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SelectableText(
|
||||
"$amountPrefix${ref.watch(pAmountFormatter(coin)).format(amount)}",
|
||||
"$amountPrefix${ref.watch(pAmountFormatter(coin)).format(amount, ethContract: ethContract)}",
|
||||
style: isDesktop
|
||||
? STextStyles
|
||||
.desktopTextExtraExtraSmall(
|
||||
|
|
|
@ -105,21 +105,6 @@ class EthereumWallet extends Bip39Wallet with PrivateKeyInterface {
|
|||
await mainDB.updateOrPutAddresses([address]);
|
||||
}
|
||||
|
||||
// delete
|
||||
@override
|
||||
Future<Address> getCurrentReceivingAddress() async {
|
||||
return Address(
|
||||
walletId: walletId,
|
||||
value:
|
||||
checksumEthereumAddress("0x6Cc3006944070B32D80107D51d843a66EaC00686"),
|
||||
publicKey: [], // maybe store address bytes here? seems a waste of space though
|
||||
derivationIndex: 0,
|
||||
derivationPath: DerivationPath()..value = "$hdPathEthereum/0",
|
||||
type: AddressType.ethereum,
|
||||
subType: AddressSubType.receiving,
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== Overrides ============================================
|
||||
|
||||
@override
|
||||
|
|
|
@ -407,13 +407,17 @@ class EthTokenWallet extends Wallet {
|
|||
for (final tuple in data) {
|
||||
// ignore all non Transfer events (for now)
|
||||
if (tuple.tx.topics[0] == kTransferEventSignature) {
|
||||
final Amount txFee = tuple.extra.gasUsed * tuple.extra.gasPrice;
|
||||
|
||||
final amount = Amount(
|
||||
rawValue: tuple.tx.data.toBigIntFromHex,
|
||||
fractionDigits: tokenContract.decimals,
|
||||
);
|
||||
|
||||
if (amount.raw == BigInt.zero) {
|
||||
// probably don't need to show this
|
||||
continue;
|
||||
}
|
||||
|
||||
final Amount txFee = tuple.extra.gasUsed * tuple.extra.gasPrice;
|
||||
final addressFrom = _addressFromTopic(
|
||||
tuple.tx.topics[1],
|
||||
);
|
||||
|
@ -451,7 +455,28 @@ class EthTokenWallet extends Wallet {
|
|||
final List<OutputV2> outputs = [];
|
||||
final List<InputV2> inputs = [];
|
||||
|
||||
// TODO: ins outs
|
||||
OutputV2 output = OutputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptPubKeyHex: "00",
|
||||
valueStringSats: amount.raw.toString(),
|
||||
addresses: [
|
||||
addressTo,
|
||||
],
|
||||
walletOwns: addressTo == addressString,
|
||||
);
|
||||
InputV2 input = InputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptSigHex: null,
|
||||
sequence: null,
|
||||
outpoint: null,
|
||||
addresses: [addressFrom],
|
||||
valueStringSats: amount.raw.toString(),
|
||||
witness: null,
|
||||
innerRedeemScriptAsm: null,
|
||||
coinbase: null,
|
||||
walletOwns: addressFrom == addressString,
|
||||
);
|
||||
|
||||
outputs.add(output);
|
||||
inputs.add(input);
|
||||
|
||||
final txn = TransactionV2(
|
||||
walletId: walletId,
|
||||
|
|
Loading…
Reference in a new issue