From 33c469d459bbe05d1c9b800f57acee56c1e68f9d Mon Sep 17 00:00:00 2001 From: Aasim Khan Date: Wed, 21 Feb 2024 17:26:14 +0400 Subject: [PATCH] feat: Added `web3LoadTransactions` in `mirai_web3` to load user transactions on a specific token --- .../lib/action_parsers/action_parsers.dart | 1 + .../mirai_web3_load_transactions_parser.dart | 23 ++++++ .../lib/models/transaction_details.dart | 19 +++++ .../lib/services/web_modal_service.dart | 75 ++++++++++++++++++- packages/mirai_web3/pubspec.yaml | 1 + 5 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 packages/mirai_web3/lib/action_parsers/mirai_web3_load_transactions/mirai_web3_load_transactions_parser.dart create mode 100644 packages/mirai_web3/lib/models/transaction_details.dart diff --git a/packages/mirai_web3/lib/action_parsers/action_parsers.dart b/packages/mirai_web3/lib/action_parsers/action_parsers.dart index 397712a9..d8f0c081 100644 --- a/packages/mirai_web3/lib/action_parsers/action_parsers.dart +++ b/packages/mirai_web3/lib/action_parsers/action_parsers.dart @@ -7,3 +7,4 @@ export 'package:mirai_web3/action_parsers/mirai_web3_load_tokens/web3_load_token export 'package:mirai_web3/action_parsers/mirai_web3_validate_address/mirai_web3_validate_address_parser.dart'; export 'package:mirai_web3/action_parsers/mirai_web3_transfer_token/web3_transfer_token_parser.dart'; export 'package:mirai_web3/action_parsers/web3_sign_message/web3_sign_message_parser.dart'; +export 'package:mirai_web3/action_parsers/mirai_web3_load_transactions/mirai_web3_load_transactions_parser.dart'; diff --git a/packages/mirai_web3/lib/action_parsers/mirai_web3_load_transactions/mirai_web3_load_transactions_parser.dart b/packages/mirai_web3/lib/action_parsers/mirai_web3_load_transactions/mirai_web3_load_transactions_parser.dart new file mode 100644 index 00000000..0f4b70f9 --- /dev/null +++ b/packages/mirai_web3/lib/action_parsers/mirai_web3_load_transactions/mirai_web3_load_transactions_parser.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:mirai_framework/mirai_framework.dart'; +import 'package:mirai_web3/services/web_modal_service.dart'; + +class MiraiWeb3LoadTransactionsParser + extends MiraiActionParser> { + const MiraiWeb3LoadTransactionsParser(); + + @override + String get actionType => 'web3LoadTransactions'; + + @override + getModel(Map json) => json; + + @override + FutureOr onCall( + BuildContext context, Map model) async { + return await Web3ModalService.loadTransactions( + tokenAddress: model['token_address']); + } +} diff --git a/packages/mirai_web3/lib/models/transaction_details.dart b/packages/mirai_web3/lib/models/transaction_details.dart new file mode 100644 index 00000000..8ee5175c --- /dev/null +++ b/packages/mirai_web3/lib/models/transaction_details.dart @@ -0,0 +1,19 @@ +import 'package:mirai_web3/models/token.dart'; + +class TransactionDetails { + TransactionDetails({ + required this.senderAddress, + required this.receiverAddress, + required this.amount, + required this.received, + required this.tranHash, + required this.tranToken, + }); + + final String senderAddress; + final String receiverAddress; + final BigInt amount; + final bool received; + final String tranHash; + final Token tranToken; +} diff --git a/packages/mirai_web3/lib/services/web_modal_service.dart b/packages/mirai_web3/lib/services/web_modal_service.dart index 10668efd..bf1b9b3f 100644 --- a/packages/mirai_web3/lib/services/web_modal_service.dart +++ b/packages/mirai_web3/lib/services/web_modal_service.dart @@ -2,10 +2,11 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:mirai_web3/models/chain_details.dart'; - +import 'package:http/http.dart'; import 'package:mirai_web3/models/chain_meta_data.dart'; import 'package:mirai_web3/models/contract_details.dart'; import 'package:mirai_web3/models/token.dart'; +import 'package:mirai_web3/models/transaction_details.dart'; import 'package:web3modal_flutter/pages/select_network_page.dart'; import 'package:web3modal_flutter/web3modal_flutter.dart'; import 'package:web3modal_flutter/widgets/widget_stack/widget_stack_singleton.dart'; @@ -263,6 +264,78 @@ class Web3ModalService { return null; } + static Future> loadTransactions({ + required String tokenAddress, + int offset = 0, + }) async { + List transactions = []; + try { + final contract = + _contracts.firstWhere((contract) => contract.address == tokenAddress); + final contractToken = _contractTokens + .firstWhere((contract) => contract.address == tokenAddress); + + // Create DeployedContract object using contract's ABI and address + final deployedContract = DeployedContract( + ContractAbi.fromJson( + jsonEncode(contract.abi), + contract.name, + ), + EthereumAddress.fromHex( + contract.address, + ), + ); + + final client = Web3Client(contract.rpcUrl, Client()); + + final currentBlockNumber = await client.getBlockNumber(); + const int difference = 50000; + int blockNumber = currentBlockNumber - (difference * offset); + + final transferEvent = deployedContract.event('Transfer'); + final contractHex = bytesToHex(transferEvent.signature, + padToEvenLength: true, include0x: true); + + await client + .getLogs( + FilterOptions( + // events of a user wallet + fromBlock: BlockNum.exact(blockNumber - difference), + toBlock: BlockNum.exact(blockNumber), + address: EthereumAddress.fromHex(contract.address), + topics: [ + [ + contractHex, + ] + ]), + ) + .then((logs) { + for (FilterEvent l in logs) { + final result = transferEvent.decodeResults(l.topics!, l.data!); + + if (result + .contains(EthereumAddress.fromHex(connectedWalletAddress))) { + transactions.add( + TransactionDetails( + senderAddress: (result[0] as EthereumAddress).hex, + receiverAddress: (result[1] as EthereumAddress).hex, + amount: result[2] as BigInt, + received: (result[1] as EthereumAddress).hex == + connectedWalletAddress, + tranHash: l.transactionHash ?? '', + tranToken: contractToken, + ), + ); + } + } + }); + } catch (e) { + debugPrint(e.toString()); + } + + return transactions; + } + static Future disconnect() async { _service.closeModal(); await _service.disconnect(); diff --git a/packages/mirai_web3/pubspec.yaml b/packages/mirai_web3/pubspec.yaml index 70ee547e..25734e1a 100644 --- a/packages/mirai_web3/pubspec.yaml +++ b/packages/mirai_web3/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: flutter: sdk: flutter freezed_annotation: ^2.2.0 + http: ^1.2.0 json_annotation: ^4.8.1 mirai_framework: ^0.0.1 # intl: ^0.19.0