blockchainpype 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. blockchainpype-0.1.0/LICENSE +21 -0
  2. blockchainpype-0.1.0/PKG-INFO +118 -0
  3. blockchainpype-0.1.0/README.md +102 -0
  4. blockchainpype-0.1.0/blockchainpype/__init__.py +5 -0
  5. blockchainpype-0.1.0/blockchainpype/evm/__init__.py +13 -0
  6. blockchainpype-0.1.0/blockchainpype/evm/asset.py +66 -0
  7. blockchainpype-0.1.0/blockchainpype/evm/blockchain/__init__.py +0 -0
  8. blockchainpype-0.1.0/blockchainpype/evm/blockchain/blockchain.py +319 -0
  9. blockchainpype-0.1.0/blockchainpype/evm/blockchain/configuration.py +92 -0
  10. blockchainpype-0.1.0/blockchainpype/evm/blockchain/gas.py +234 -0
  11. blockchainpype-0.1.0/blockchainpype/evm/blockchain/identifier.py +179 -0
  12. blockchainpype-0.1.0/blockchainpype/evm/blockchain/providers/__init__.py +4 -0
  13. blockchainpype-0.1.0/blockchainpype/evm/blockchain/providers/limited.py +20 -0
  14. blockchainpype-0.1.0/blockchainpype/evm/blockchain/providers/multiple.py +96 -0
  15. blockchainpype-0.1.0/blockchainpype/evm/dapp/__init__.py +5 -0
  16. blockchainpype-0.1.0/blockchainpype/evm/dapp/abi.py +98 -0
  17. blockchainpype-0.1.0/blockchainpype/evm/dapp/contract.py +143 -0
  18. blockchainpype-0.1.0/blockchainpype/evm/dapp/erc20.py +151 -0
  19. blockchainpype-0.1.0/blockchainpype/evm/explorer/__init__.py +8 -0
  20. blockchainpype-0.1.0/blockchainpype/evm/explorer/etherscan.py +71 -0
  21. blockchainpype-0.1.0/blockchainpype/evm/transaction.py +280 -0
  22. blockchainpype-0.1.0/blockchainpype/evm/wallet/__init__.py +0 -0
  23. blockchainpype-0.1.0/blockchainpype/evm/wallet/identifier.py +65 -0
  24. blockchainpype-0.1.0/blockchainpype/evm/wallet/signer.py +47 -0
  25. blockchainpype-0.1.0/blockchainpype/evm/wallet/wallet.py +386 -0
  26. blockchainpype-0.1.0/blockchainpype/factory.py +117 -0
  27. blockchainpype-0.1.0/blockchainpype/ipfs.py +6 -0
  28. blockchainpype-0.1.0/blockchainpype/solana/asset.py +63 -0
  29. blockchainpype-0.1.0/blockchainpype/solana/blockchain/__init__.py +0 -0
  30. blockchainpype-0.1.0/blockchainpype/solana/blockchain/blockchain.py +250 -0
  31. blockchainpype-0.1.0/blockchainpype/solana/blockchain/configuration.py +63 -0
  32. blockchainpype-0.1.0/blockchainpype/solana/blockchain/identifier.py +172 -0
  33. blockchainpype-0.1.0/blockchainpype/solana/dapp/__init__.py +22 -0
  34. blockchainpype-0.1.0/blockchainpype/solana/dapp/idl.py +98 -0
  35. blockchainpype-0.1.0/blockchainpype/solana/dapp/program.py +157 -0
  36. blockchainpype-0.1.0/blockchainpype/solana/dapp/token.py +166 -0
  37. blockchainpype-0.1.0/blockchainpype/solana/explorer/__init__.py +8 -0
  38. blockchainpype-0.1.0/blockchainpype/solana/explorer/solscan.py +52 -0
  39. blockchainpype-0.1.0/blockchainpype/solana/transaction.py +219 -0
  40. blockchainpype-0.1.0/blockchainpype/solana/wallet/identifier.py +65 -0
  41. blockchainpype-0.1.0/blockchainpype/solana/wallet/signer.py +47 -0
  42. blockchainpype-0.1.0/blockchainpype/solana/wallet/wallet.py +319 -0
  43. blockchainpype-0.1.0/pyproject.toml +77 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Gianluca Pagliara
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.1
2
+ Name: blockchainpype
3
+ Version: 0.1.0
4
+ Summary: BlockchainPype is a Python library for interacting with multiple blockchain networks.
5
+ Author: Gianluca Pagliara
6
+ Author-email: pagliara.gianluca@gmail.com
7
+ Requires-Python: >=3.13,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Requires-Dist: base58 (>=2.1.1,<3.0.0)
11
+ Requires-Dist: solana (>=0.36.3,<0.37.0)
12
+ Requires-Dist: solders (>=0.23.0,<0.24.0)
13
+ Requires-Dist: web3 (>=7.6.1,<8.0.0)
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Blockchain Pypeline
17
+
18
+ A powerful Python library for interacting with multiple blockchain networks, providing a unified interface for EVM-compatible chains and Solana. This library simplifies blockchain interactions, asset management, and transaction handling with a clean, type-safe API.
19
+
20
+ ## Overview
21
+
22
+ Blockchain Pypeline is designed to streamline blockchain development by providing:
23
+ - A unified interface for multiple blockchain networks
24
+ - Type-safe interactions with smart contracts and programs
25
+ - Simplified wallet and transaction management
26
+ - Comprehensive asset handling across different chains
27
+
28
+ ## Features
29
+
30
+ - **Multi-Chain Support**
31
+ - EVM-compatible chains (Ethereum, Polygon, BSC, etc.)
32
+ - Solana blockchain
33
+ - Extensible architecture for adding new chains
34
+
35
+ - **Wallet Management**
36
+ - Secure key management
37
+ - Transaction signing
38
+ - Multiple wallet support
39
+
40
+ - **Asset Operations**
41
+ - Token transfers and management
42
+ - NFT handling
43
+ - Dapps interactions (Smart contracts, Programs)
44
+
45
+ - **Transaction Handling**
46
+ - Transaction building and signing
47
+ - Gas estimation and optimization
48
+ - Transaction monitoring
49
+ - Block explorer integration
50
+
51
+
52
+ ## Installation
53
+
54
+ The package requires Python 3.13 or later. You can install it using Poetry:
55
+
56
+ ```bash
57
+ poetry add blockchainpype
58
+ ```
59
+
60
+ Or with pip:
61
+
62
+ ```bash
63
+ pip install blockchainpype
64
+ ```
65
+
66
+ ## Quick Start
67
+
68
+ Here's a simple example of how to use blockchainpype:
69
+
70
+ ```python
71
+ ...
72
+ ```
73
+
74
+ ## Development
75
+
76
+ ### Setup
77
+
78
+ 1. Clone the repository:
79
+ ```bash
80
+ git clone https://github.com/gianlucapagliara/blockchainpype.git
81
+ cd blockchainpype
82
+ ```
83
+
84
+ 2. Install dependencies with Poetry:
85
+ ```bash
86
+ poetry install
87
+ ```
88
+
89
+ 3. Set up pre-commit hooks:
90
+ ```bash
91
+ poetry run pre-commit install
92
+ ```
93
+
94
+ ### Testing
95
+
96
+ Run the test suite:
97
+
98
+ ```bash
99
+ poetry run pytest
100
+ ```
101
+
102
+ ### Code Quality
103
+
104
+ The project uses several tools to maintain code quality:
105
+ - Black for code formatting
106
+ - isort for import sorting
107
+ - mypy for static type checking
108
+ - ruff for linting
109
+ - pre-commit hooks for automated checks
110
+
111
+ ## License
112
+
113
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
114
+
115
+ ## Contributing
116
+
117
+ Contributions are welcome! Please feel free to submit a Pull Request.
118
+
@@ -0,0 +1,102 @@
1
+ # Blockchain Pypeline
2
+
3
+ A powerful Python library for interacting with multiple blockchain networks, providing a unified interface for EVM-compatible chains and Solana. This library simplifies blockchain interactions, asset management, and transaction handling with a clean, type-safe API.
4
+
5
+ ## Overview
6
+
7
+ Blockchain Pypeline is designed to streamline blockchain development by providing:
8
+ - A unified interface for multiple blockchain networks
9
+ - Type-safe interactions with smart contracts and programs
10
+ - Simplified wallet and transaction management
11
+ - Comprehensive asset handling across different chains
12
+
13
+ ## Features
14
+
15
+ - **Multi-Chain Support**
16
+ - EVM-compatible chains (Ethereum, Polygon, BSC, etc.)
17
+ - Solana blockchain
18
+ - Extensible architecture for adding new chains
19
+
20
+ - **Wallet Management**
21
+ - Secure key management
22
+ - Transaction signing
23
+ - Multiple wallet support
24
+
25
+ - **Asset Operations**
26
+ - Token transfers and management
27
+ - NFT handling
28
+ - Dapps interactions (Smart contracts, Programs)
29
+
30
+ - **Transaction Handling**
31
+ - Transaction building and signing
32
+ - Gas estimation and optimization
33
+ - Transaction monitoring
34
+ - Block explorer integration
35
+
36
+
37
+ ## Installation
38
+
39
+ The package requires Python 3.13 or later. You can install it using Poetry:
40
+
41
+ ```bash
42
+ poetry add blockchainpype
43
+ ```
44
+
45
+ Or with pip:
46
+
47
+ ```bash
48
+ pip install blockchainpype
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ Here's a simple example of how to use blockchainpype:
54
+
55
+ ```python
56
+ ...
57
+ ```
58
+
59
+ ## Development
60
+
61
+ ### Setup
62
+
63
+ 1. Clone the repository:
64
+ ```bash
65
+ git clone https://github.com/gianlucapagliara/blockchainpype.git
66
+ cd blockchainpype
67
+ ```
68
+
69
+ 2. Install dependencies with Poetry:
70
+ ```bash
71
+ poetry install
72
+ ```
73
+
74
+ 3. Set up pre-commit hooks:
75
+ ```bash
76
+ poetry run pre-commit install
77
+ ```
78
+
79
+ ### Testing
80
+
81
+ Run the test suite:
82
+
83
+ ```bash
84
+ poetry run pytest
85
+ ```
86
+
87
+ ### Code Quality
88
+
89
+ The project uses several tools to maintain code quality:
90
+ - Black for code formatting
91
+ - isort for import sorting
92
+ - mypy for static type checking
93
+ - ruff for linting
94
+ - pre-commit hooks for automated checks
95
+
96
+ ## License
97
+
98
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
99
+
100
+ ## Contributing
101
+
102
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,5 @@
1
+ import os
2
+
3
+ common_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "common")
4
+ common_abi_path = os.path.join(common_path, "abi")
5
+ common_idl_path = os.path.join(common_path, "idl")
@@ -0,0 +1,13 @@
1
+ """
2
+ This package provides a comprehensive framework for interacting with EVM-compatible blockchains.
3
+ It includes modules for:
4
+ - Transaction management and signing
5
+ - Asset handling (native and tokens)
6
+ - Smart contract interaction
7
+ - Wallet management
8
+ - Block explorer integration
9
+ - Gas fee estimation and optimization
10
+
11
+ The implementation supports both legacy and EIP-1559 transaction types, and includes
12
+ built-in support for common standards like ERC-20 tokens.
13
+ """
@@ -0,0 +1,66 @@
1
+ """
2
+ This module provides classes for handling Ethereum-based assets, including both native ETH
3
+ and ERC-20 tokens. It defines the data structures and relationships between different
4
+ types of Ethereum assets.
5
+ """
6
+
7
+ from financepype.assets.blockchain import BlockchainAsset, BlockchainAssetData
8
+ from pydantic import Field
9
+
10
+ from blockchainpype.evm.blockchain.identifier import (
11
+ EthereumAddress,
12
+ EthereumNullAddress,
13
+ )
14
+
15
+
16
+ class EthereumAssetData(BlockchainAssetData):
17
+ """
18
+ Data container for Ethereum asset information.
19
+
20
+ This class extends BlockchainAssetData to provide Ethereum-specific asset data handling.
21
+ It maintains compatibility with the general blockchain asset data structure while
22
+ allowing for future Ethereum-specific extensions.
23
+ """
24
+
25
+ pass
26
+
27
+
28
+ class EthereumAsset(BlockchainAsset):
29
+ """
30
+ Base class for all Ethereum-based assets.
31
+
32
+ This class represents any asset on the Ethereum blockchain, serving as a base for
33
+ both native ETH and ERC-20 tokens. It provides the foundation for asset management
34
+ and interaction within the Ethereum ecosystem.
35
+
36
+ Attributes:
37
+ data (EthereumAssetData): Asset-specific data including name, symbol, and decimals
38
+ """
39
+
40
+ data: EthereumAssetData
41
+
42
+
43
+ class EthereumNativeAsset(EthereumAsset):
44
+ """
45
+ Represents the native Ethereum asset (ETH).
46
+
47
+ This class specifically handles the native ETH token, with predefined properties
48
+ such as the null address identifier (since ETH doesn't have a contract address)
49
+ and standard ETH token data.
50
+
51
+ Attributes:
52
+ identifier (EthereumAddress): The null address, as ETH has no contract address
53
+ data (EthereumAssetData): Predefined ETH token data with name, symbol, and decimals
54
+ """
55
+
56
+ identifier: EthereumAddress = Field(
57
+ default_factory=lambda: EthereumNullAddress(),
58
+ init=False,
59
+ )
60
+ data: EthereumAssetData = Field(
61
+ default_factory=lambda: EthereumAssetData(
62
+ name="Ethereum",
63
+ symbol="ETH",
64
+ decimals=18,
65
+ ),
66
+ )
@@ -0,0 +1,319 @@
1
+ """
2
+ This module provides the core functionality for interacting with EVM-compatible blockchains.
3
+ It implements blockchain data retrieval, transaction management, and native asset operations
4
+ through Web3.py integration and optional block explorer support.
5
+ """
6
+
7
+ from decimal import Decimal
8
+ from typing import cast
9
+
10
+ from eth_account.datastructures import SignedTransaction
11
+ from eth_typing import BlockIdentifier
12
+ from financepype.operations.transactions.models import (
13
+ BlockchainTransactionState,
14
+ BlockchainTransactionUpdate,
15
+ )
16
+ from financepype.operators.blockchains.blockchain import Blockchain
17
+ from financepype.operators.blockchains.identifier import BlockchainIdentifier
18
+ from web3 import AsyncWeb3
19
+ from web3.types import BlockData
20
+
21
+ from blockchainpype.evm.asset import EthereumAssetData, EthereumNativeAsset
22
+ from blockchainpype.evm.blockchain.configuration import EthereumBlockchainConfiguration
23
+ from blockchainpype.evm.blockchain.identifier import (
24
+ EthereumAddress,
25
+ EthereumTransactionHash,
26
+ )
27
+ from blockchainpype.evm.explorer.etherscan import EtherscanExplorer
28
+ from blockchainpype.evm.transaction import (
29
+ EthereumRawTransaction,
30
+ EthereumTransaction,
31
+ EthereumTransactionReceipt,
32
+ )
33
+ from blockchainpype.evm.wallet.identifier import EthereumWalletIdentifier
34
+
35
+
36
+ class EthereumBlockchain(Blockchain):
37
+ """
38
+ Implementation of an EVM-compatible blockchain interface.
39
+
40
+ This class provides comprehensive functionality for interacting with Ethereum and
41
+ EVM-compatible blockchains, including:
42
+ - Web3 client management for both RPC and WebSocket connections
43
+ - Block and transaction data retrieval
44
+ - Native asset (ETH) operations
45
+ - Transaction sending and tracking
46
+ - Optional block explorer integration
47
+
48
+ Attributes:
49
+ web3 (AsyncWeb3): Asynchronous Web3 instance for blockchain interaction
50
+ explorer (EtherscanExplorer | None): Optional block explorer interface
51
+ native_asset (EthereumNativeAsset): Native blockchain asset (e.g., ETH)
52
+ """
53
+
54
+ def __init__(self, configuration: EthereumBlockchainConfiguration):
55
+ """
56
+ Initialize the blockchain interface with the provided configuration.
57
+
58
+ Args:
59
+ configuration (EthereumBlockchainConfiguration): Configuration including
60
+ connectivity settings, explorer settings, and native asset properties
61
+ """
62
+ super().__init__(configuration)
63
+
64
+ self.web3 = AsyncWeb3(
65
+ provider=configuration.connectivity.rpc_provider,
66
+ middleware=configuration.connectivity.middleware,
67
+ modules=configuration.connectivity.modules,
68
+ external_modules=configuration.connectivity.external_modules,
69
+ )
70
+
71
+ self.explorer = None
72
+ if configuration.explorer is not None:
73
+ self.explorer = EtherscanExplorer(configuration=configuration.explorer)
74
+
75
+ self.native_asset = EthereumNativeAsset(
76
+ platform=self.platform,
77
+ data=EthereumAssetData(
78
+ name=self.configuration.native_asset.name,
79
+ symbol=self.configuration.native_asset.symbol,
80
+ decimals=self.configuration.native_asset.decimals,
81
+ ),
82
+ )
83
+
84
+ @property
85
+ def configuration(self) -> EthereumBlockchainConfiguration:
86
+ """
87
+ Get the blockchain configuration.
88
+
89
+ Returns:
90
+ EthereumBlockchainConfiguration: The current blockchain configuration
91
+ """
92
+ return cast(EthereumBlockchainConfiguration, super().configuration)
93
+
94
+ # === Blockchain ===
95
+
96
+ async def fetch_block_data(self, block_number: BlockIdentifier) -> BlockData:
97
+ """
98
+ Fetch detailed data for a specific block.
99
+
100
+ Args:
101
+ block_number (BlockIdentifier): Block number or identifier (e.g., 'latest')
102
+
103
+ Returns:
104
+ BlockData: Detailed block information
105
+ """
106
+ return await self.web3.eth.get_block(block_number)
107
+
108
+ async def fetch_block_number(self) -> int:
109
+ """
110
+ Fetch the current block number.
111
+
112
+ Returns:
113
+ int: The latest block number
114
+ """
115
+ return await self.web3.eth.get_block_number()
116
+
117
+ async def fetch_block_timestamp(self, block_number: BlockIdentifier) -> int:
118
+ """
119
+ Fetch the timestamp of a specific block.
120
+
121
+ Args:
122
+ block_number (BlockIdentifier): Block number or identifier
123
+
124
+ Returns:
125
+ int: Block timestamp in Unix format
126
+
127
+ Raises:
128
+ ValueError: If the block has no timestamp
129
+ """
130
+ block_data = await self.fetch_block_data(block_number)
131
+ if "timestamp" not in block_data:
132
+ raise ValueError(f"Block {block_number} does not have a timestamp")
133
+
134
+ return block_data["timestamp"]
135
+
136
+ async def fetch_transaction_count(self, address: EthereumAddress) -> int:
137
+ """
138
+ Fetch the total number of transactions sent by an address (nonce).
139
+
140
+ Args:
141
+ address (EthereumAddress): The address to check
142
+
143
+ Returns:
144
+ int: The transaction count (nonce)
145
+ """
146
+ return await self.web3.eth.get_transaction_count(address.raw)
147
+
148
+ # === Native Asset ===
149
+
150
+ async def fetch_native_asset_balance(
151
+ self, address: EthereumAddress, block_number: BlockIdentifier | None = None
152
+ ) -> Decimal:
153
+ """
154
+ Fetch the native asset (ETH) balance for an address.
155
+
156
+ Args:
157
+ address (EthereumAddress): The address to check
158
+ block_number (BlockIdentifier | None): Optional block number for historical balance
159
+
160
+ Returns:
161
+ Decimal: The balance in ETH (not Wei)
162
+ """
163
+ raw_balance = await self.web3.eth.get_balance(
164
+ address.raw, block_identifier=block_number
165
+ )
166
+ balance = self.web3.from_wei(raw_balance, "ether")
167
+ return Decimal(str(balance))
168
+
169
+ # === Transactions ===
170
+
171
+ async def send_signed_transaction(
172
+ self, signed_tx: SignedTransaction
173
+ ) -> EthereumTransactionHash:
174
+ """
175
+ Send a signed transaction to the network.
176
+
177
+ Args:
178
+ signed_tx (SignedTransaction): The signed transaction to send
179
+
180
+ Returns:
181
+ EthereumTransactionHash: The transaction hash
182
+ """
183
+ raw_tx_hash = await self.web3.eth.send_raw_transaction(
184
+ signed_tx.raw_transaction
185
+ )
186
+ tx_hash = EthereumTransactionHash.from_raw(raw_tx_hash)
187
+ return tx_hash
188
+
189
+ async def send_transaction(
190
+ self, transaction: EthereumTransaction
191
+ ) -> BlockchainTransactionUpdate:
192
+ """
193
+ Send a transaction and create an update record.
194
+
195
+ This method broadcasts the transaction to the network and creates a
196
+ transaction update record with the result status.
197
+
198
+ Args:
199
+ transaction (EthereumTransaction): The transaction to send
200
+
201
+ Returns:
202
+ BlockchainTransactionUpdate: Transaction update record
203
+
204
+ Raises:
205
+ ValueError: If the transaction is not signed
206
+ """
207
+ if transaction.signed_transaction is None:
208
+ raise ValueError("Transaction is not signed")
209
+
210
+ try:
211
+ transaction_hash = await self.send_signed_transaction(
212
+ transaction.signed_transaction
213
+ )
214
+ transaction_update = BlockchainTransactionUpdate(
215
+ update_timestamp=self.current_timestamp,
216
+ client_transaction_id=transaction.client_operation_id,
217
+ transaction_id=transaction_hash,
218
+ new_state=BlockchainTransactionState.BROADCASTED,
219
+ receipt=None,
220
+ explorer_link=self.explorer.get_transaction_link(transaction_hash)
221
+ if self.explorer is not None
222
+ else None,
223
+ )
224
+ except Exception as e:
225
+ transaction_update = BlockchainTransactionUpdate(
226
+ update_timestamp=self.current_timestamp,
227
+ client_transaction_id=transaction.client_operation_id,
228
+ transaction_id=None,
229
+ new_state=BlockchainTransactionState.REJECTED,
230
+ receipt=None,
231
+ explorer_link=None,
232
+ other_data={"exception": e},
233
+ )
234
+ return transaction_update
235
+
236
+ async def fetch_transaction_receipt(
237
+ self, transaction_id: EthereumTransactionHash
238
+ ) -> EthereumTransactionReceipt | None:
239
+ """
240
+ Fetch the receipt for a transaction.
241
+
242
+ Args:
243
+ transaction_id (EthereumTransactionHash): Transaction hash
244
+
245
+ Returns:
246
+ EthereumTransactionReceipt | None: Transaction receipt if available
247
+ """
248
+ raw_receipt = await self.web3.eth.get_transaction_receipt(transaction_id.raw)
249
+ return EthereumTransactionReceipt.from_raw(raw_receipt)
250
+
251
+ async def fetch_raw_transaction(
252
+ self, transaction_id: EthereumTransactionHash
253
+ ) -> EthereumRawTransaction | None:
254
+ """
255
+ Fetch raw transaction data.
256
+
257
+ Args:
258
+ transaction_id (EthereumTransactionHash): Transaction hash
259
+
260
+ Returns:
261
+ EthereumRawTransaction | None: Raw transaction data if available
262
+ """
263
+ raw_transaction = await self.web3.eth.get_transaction(transaction_id.raw)
264
+ return EthereumRawTransaction.from_raw(raw_transaction)
265
+
266
+ async def fetch_transaction(
267
+ self, transaction_id: BlockchainIdentifier
268
+ ) -> EthereumTransaction | None:
269
+ """
270
+ Fetch complete transaction information.
271
+
272
+ This method retrieves all available information about a transaction,
273
+ including its raw data, receipt, and block information.
274
+
275
+ Args:
276
+ transaction_id (BlockchainIdentifier): Transaction identifier
277
+
278
+ Returns:
279
+ EthereumTransaction | None: Complete transaction information if available
280
+
281
+ Raises:
282
+ ValueError: If the transaction ID is invalid
283
+ """
284
+ if not isinstance(transaction_id, EthereumTransactionHash):
285
+ raise ValueError(f"Invalid transaction id: {transaction_id}")
286
+
287
+ raw_transaction = await self.fetch_raw_transaction(transaction_id)
288
+ if raw_transaction is None:
289
+ return None
290
+
291
+ block_data = await self.fetch_block_data(raw_transaction.block_number)
292
+ ts = block_data["timestamp"] if "timestamp" in block_data else 0
293
+
294
+ transaction_receipt = await self.fetch_transaction_receipt(transaction_id)
295
+ fee = None
296
+ # if transaction_receipt is not None:
297
+ # fee = BlockchainTransactionFee(
298
+ # amount=transaction_receipt.fee_amount,
299
+ # asset=...,
300
+ # )
301
+
302
+ transaction = EthereumTransaction(
303
+ client_operation_id=transaction_id.string,
304
+ operator_operation_id=transaction_id,
305
+ owner_identifier=EthereumWalletIdentifier(
306
+ platform=self.configuration.platform,
307
+ address=raw_transaction.sender,
308
+ ),
309
+ creation_timestamp=ts,
310
+ last_update_timestamp=ts,
311
+ current_state=BlockchainTransactionState.CONFIRMED,
312
+ raw_transaction=raw_transaction,
313
+ receipt=transaction_receipt,
314
+ fee=fee,
315
+ explorer_link=self.explorer.get_transaction_link(transaction_id)
316
+ if self.explorer is not None
317
+ else None,
318
+ )
319
+ return transaction