add transaction filter for custom queries based on wallet type

This commit is contained in:
julian 2024-01-15 14:48:57 -06:00
parent 62e1afb6cc
commit b70974b050
8 changed files with 118 additions and 48 deletions

View file

@ -13,8 +13,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/db/isar/main_db.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/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/pages/receive_view/addresses/address_tag.dart'; import 'package:stackwallet/pages/receive_view/addresses/address_tag.dart';
@ -485,17 +483,42 @@ class _AddressDetailsTxV2List extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final query = ref final walletTxFilter =
.watch(mainDBProvider) ref.watch(pWallets).getWallet(walletId).transactionFilterOperation;
.isar
.transactionV2s final query =
.where() ref.watch(mainDBProvider).isar.transactionV2s.buildQuery<TransactionV2>(
.walletIdEqualTo(walletId) whereClauses: [
.filter() IndexWhereClause.equalTo(
.inputsElement((q) => q.addressesElementContains(address.value)) indexName: 'walletId',
.or() value: [walletId],
.outputsElement((q) => q.addressesElementContains(address.value)) )
.sortByTimestampDesc(); ],
filter: FilterGroup.and([
if (walletTxFilter != null) walletTxFilter,
FilterGroup.or([
ObjectFilter(
property: 'inputs',
filter: FilterCondition.contains(
property: "addresses",
value: address.value,
),
),
ObjectFilter(
property: 'outputs',
filter: FilterCondition.contains(
property: "addresses",
value: address.value,
),
)
]),
]),
sortBy: [
const SortProperty(
property: "timestamp",
sort: Sort.desc,
),
]);
final count = query.countSync(); final count = query.countSync();

View file

@ -13,7 +13,6 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.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/blockchain_data/v2/transaction_v2.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart';
@ -45,7 +44,7 @@ class _TransactionsListState extends ConsumerState<TokenTransactionsList> {
List<TransactionV2> _transactions = []; List<TransactionV2> _transactions = [];
late final StreamSubscription<List<TransactionV2>> _subscription; late final StreamSubscription<List<TransactionV2>> _subscription;
late final QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> _query; late final Query<TransactionV2> _query;
BorderRadius get _borderRadiusFirst { BorderRadius get _borderRadiusFirst {
return BorderRadius.only( return BorderRadius.only(
@ -76,19 +75,22 @@ class _TransactionsListState extends ConsumerState<TokenTransactionsList> {
.getWallet(widget.walletId) .getWallet(widget.walletId)
.cryptoCurrency .cryptoCurrency
.minConfirms; .minConfirms;
_query =
_query = ref ref.read(mainDBProvider).isar.transactionV2s.buildQuery<TransactionV2>(
.read(mainDBProvider) whereClauses: [
.isar IndexWhereClause.equalTo(
.transactionV2s indexName: 'walletId',
.where() value: [widget.walletId],
.walletIdEqualTo(widget.walletId) )
.filter() ],
.subTypeEqualTo(TransactionSubType.ethToken) filter: ref.read(pCurrentTokenWallet)!.transactionFilterOperation,
.and() sortBy: [
.contractAddressEqualTo( const SortProperty(
ref.read(pCurrentTokenWallet)!.tokenContract.address) property: "timestamp",
.sortByTimestampDesc(); sort: Sort.desc,
),
],
);
_subscription = _query.watch().listen((event) { _subscription = _query.watch().listen((event) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {

View file

@ -36,6 +36,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart'; import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/conditional_parent.dart';
@ -499,19 +500,14 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
value: [widget.walletId], value: [widget.walletId],
) )
], ],
// TODO: [prio=med] add filters to wallet or cryptocurrency class filter: widget.contractAddress == null
filter: widget.contractAddress != null ? ref
? FilterGroup.and([ .watch(pWallets)
FilterCondition.equalTo( .getWallet(widget.walletId)
property: r"contractAddress", .transactionFilterOperation
value: widget.contractAddress!, : ref
), .read(pCurrentTokenWallet)!
const FilterCondition.equalTo( .transactionFilterOperation,
property: r"subType",
value: TransactionSubType.ethToken,
),
])
: null,
sortBy: [ sortBy: [
const SortProperty( const SortProperty(
property: "timestamp", property: "timestamp",

View file

@ -43,7 +43,7 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> {
List<TransactionV2> _transactions = []; List<TransactionV2> _transactions = [];
late final StreamSubscription<List<TransactionV2>> _subscription; late final StreamSubscription<List<TransactionV2>> _subscription;
late final QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> _query; late final Query<TransactionV2> _query;
BorderRadius get _borderRadiusFirst { BorderRadius get _borderRadiusFirst {
return BorderRadius.only( return BorderRadius.only(
@ -73,12 +73,23 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> {
.read(mainDBProvider) .read(mainDBProvider)
.isar .isar
.transactionV2s .transactionV2s
.where() .buildQuery<TransactionV2>(
.walletIdEqualTo(widget.walletId) whereClauses: [
.filter() IndexWhereClause.equalTo(
.not() indexName: 'walletId',
.subTypeEqualTo(TransactionSubType.ethToken) value: [widget.walletId],
.sortByTimestampDesc(); )
],
filter: ref
.read(pWallets)
.getWallet(widget.walletId)
.transactionFilterOperation,
sortBy: [
const SortProperty(
property: "timestamp",
sort: Sort.desc,
),
]);
_subscription = _query.watch().listen((event) { _subscription = _query.watch().listen((event) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {

View file

@ -107,6 +107,14 @@ class EthereumWallet extends Bip39Wallet with PrivateKeyInterface {
// ==================== Overrides ============================================ // ==================== Overrides ============================================
@override
FilterOperation? get transactionFilterOperation => FilterGroup.not(
const FilterCondition.equalTo(
property: r"subType",
value: TransactionSubType.ethToken,
),
);
@override @override
FilterOperation? get changeAddressFilterOperation => FilterOperation? get changeAddressFilterOperation =>
FilterGroup.and(standardChangeAddressFilters); FilterGroup.and(standardChangeAddressFilters);

View file

@ -515,4 +515,16 @@ class EthTokenWallet extends Wallet {
Future<bool> updateUTXOs() async { Future<bool> updateUTXOs() async {
return await ethWallet.updateUTXOs(); return await ethWallet.updateUTXOs();
} }
@override
FilterOperation? get transactionFilterOperation => FilterGroup.and([
FilterCondition.equalTo(
property: r"contractAddress",
value: tokenContract.address,
),
const FilterCondition.equalTo(
property: r"subType",
value: TransactionSubType.ethToken,
),
]);
} }

View file

@ -614,6 +614,8 @@ abstract class Wallet<T extends CryptoCurrency> {
// =========================================================================== // ===========================================================================
FilterOperation? get transactionFilterOperation => null;
FilterOperation? get receivingAddressFilterOperation; FilterOperation? get receivingAddressFilterOperation;
FilterOperation? get changeAddressFilterOperation; FilterOperation? get changeAddressFilterOperation;

View file

@ -1749,4 +1749,20 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
utxoLabel: utxoLabel utxoLabel: utxoLabel
); );
} }
@override
FilterOperation? get transactionFilterOperation => FilterGroup.not(
const FilterGroup.and(
[
FilterCondition.equalTo(
property: r"subType",
value: TransactionSubType.bip47Notification,
),
FilterCondition.equalTo(
property: r"type",
value: TransactionType.incoming,
),
],
),
);
} }