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.
- blockchainpype-0.1.0/LICENSE +21 -0
- blockchainpype-0.1.0/PKG-INFO +118 -0
- blockchainpype-0.1.0/README.md +102 -0
- blockchainpype-0.1.0/blockchainpype/__init__.py +5 -0
- blockchainpype-0.1.0/blockchainpype/evm/__init__.py +13 -0
- blockchainpype-0.1.0/blockchainpype/evm/asset.py +66 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/__init__.py +0 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/blockchain.py +319 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/configuration.py +92 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/gas.py +234 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/identifier.py +179 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/providers/__init__.py +4 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/providers/limited.py +20 -0
- blockchainpype-0.1.0/blockchainpype/evm/blockchain/providers/multiple.py +96 -0
- blockchainpype-0.1.0/blockchainpype/evm/dapp/__init__.py +5 -0
- blockchainpype-0.1.0/blockchainpype/evm/dapp/abi.py +98 -0
- blockchainpype-0.1.0/blockchainpype/evm/dapp/contract.py +143 -0
- blockchainpype-0.1.0/blockchainpype/evm/dapp/erc20.py +151 -0
- blockchainpype-0.1.0/blockchainpype/evm/explorer/__init__.py +8 -0
- blockchainpype-0.1.0/blockchainpype/evm/explorer/etherscan.py +71 -0
- blockchainpype-0.1.0/blockchainpype/evm/transaction.py +280 -0
- blockchainpype-0.1.0/blockchainpype/evm/wallet/__init__.py +0 -0
- blockchainpype-0.1.0/blockchainpype/evm/wallet/identifier.py +65 -0
- blockchainpype-0.1.0/blockchainpype/evm/wallet/signer.py +47 -0
- blockchainpype-0.1.0/blockchainpype/evm/wallet/wallet.py +386 -0
- blockchainpype-0.1.0/blockchainpype/factory.py +117 -0
- blockchainpype-0.1.0/blockchainpype/ipfs.py +6 -0
- blockchainpype-0.1.0/blockchainpype/solana/asset.py +63 -0
- blockchainpype-0.1.0/blockchainpype/solana/blockchain/__init__.py +0 -0
- blockchainpype-0.1.0/blockchainpype/solana/blockchain/blockchain.py +250 -0
- blockchainpype-0.1.0/blockchainpype/solana/blockchain/configuration.py +63 -0
- blockchainpype-0.1.0/blockchainpype/solana/blockchain/identifier.py +172 -0
- blockchainpype-0.1.0/blockchainpype/solana/dapp/__init__.py +22 -0
- blockchainpype-0.1.0/blockchainpype/solana/dapp/idl.py +98 -0
- blockchainpype-0.1.0/blockchainpype/solana/dapp/program.py +157 -0
- blockchainpype-0.1.0/blockchainpype/solana/dapp/token.py +166 -0
- blockchainpype-0.1.0/blockchainpype/solana/explorer/__init__.py +8 -0
- blockchainpype-0.1.0/blockchainpype/solana/explorer/solscan.py +52 -0
- blockchainpype-0.1.0/blockchainpype/solana/transaction.py +219 -0
- blockchainpype-0.1.0/blockchainpype/solana/wallet/identifier.py +65 -0
- blockchainpype-0.1.0/blockchainpype/solana/wallet/signer.py +47 -0
- blockchainpype-0.1.0/blockchainpype/solana/wallet/wallet.py +319 -0
- 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,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
|
+
)
|
|
File without changes
|
|
@@ -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
|