blockchain-compare-py 1.0.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.
- blockchain_compare_py-1.0.0/PKG-INFO +71 -0
- blockchain_compare_py-1.0.0/README.md +58 -0
- blockchain_compare_py-1.0.0/pyproject.toml +17 -0
- blockchain_compare_py-1.0.0/setup.cfg +4 -0
- blockchain_compare_py-1.0.0/src/blockchain_compare_py/__init__.py +175 -0
- blockchain_compare_py-1.0.0/src/blockchain_compare_py.egg-info/PKG-INFO +71 -0
- blockchain_compare_py-1.0.0/src/blockchain_compare_py.egg-info/SOURCES.txt +8 -0
- blockchain_compare_py-1.0.0/src/blockchain_compare_py.egg-info/dependency_links.txt +1 -0
- blockchain_compare_py-1.0.0/src/blockchain_compare_py.egg-info/requires.txt +4 -0
- blockchain_compare_py-1.0.0/src/blockchain_compare_py.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blockchain-compare-py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: PyPI Package - blockchain-compare-py v4
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/worksOnMyFridge/blockchain-compare-py
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: matplotlib>=3.7
|
|
10
|
+
Requires-Dist: pandas>=2.0
|
|
11
|
+
Requires-Dist: aiohttp>=3.9
|
|
12
|
+
Requires-Dist: requests>=2.31
|
|
13
|
+
|
|
14
|
+
# blockchain-compare-py
|
|
15
|
+
|
|
16
|
+
Compare blockchain networks (NEAR, Ethereum, Solana) with latency measurement and visualization tools.
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Python 3.9+
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
pip install blockchain-compare-py
|
|
25
|
+
|
|
26
|
+
## Optional Dependencies
|
|
27
|
+
|
|
28
|
+
pip install pandas matplotlib
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
from blockchain_compare_py import BlockchainComparePyClient
|
|
33
|
+
|
|
34
|
+
client = BlockchainComparePyClient(timeout=10)
|
|
35
|
+
|
|
36
|
+
## Methods
|
|
37
|
+
|
|
38
|
+
| Method | Description |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `get_block_height(chain)` | Get current block height for a chain |
|
|
41
|
+
| `measure_latency(chain, samples)` | Measure RPC latency for a chain |
|
|
42
|
+
| `compare_latency()` | Compare latency across all chains |
|
|
43
|
+
| `get_metrics(chain)` | Get combined metrics for a chain |
|
|
44
|
+
| `compare_all()` | Compare all metrics across all chains |
|
|
45
|
+
| `to_dataframe()` | Export results as a pandas DataFrame |
|
|
46
|
+
| `plot_latency()` | Plot latency comparison chart |
|
|
47
|
+
| `plot_block_heights()` | Plot block height comparison chart |
|
|
48
|
+
|
|
49
|
+
## Supported Chains
|
|
50
|
+
|
|
51
|
+
- **NEAR** — `https://rpc.mainnet.near.org`
|
|
52
|
+
- **Ethereum** — `https://cloudflare-eth.com`
|
|
53
|
+
- **Solana** — `https://api.mainnet-beta.solana.com`
|
|
54
|
+
|
|
55
|
+
## Example
|
|
56
|
+
|
|
57
|
+
client = BlockchainComparePyClient()
|
|
58
|
+
|
|
59
|
+
# Compare latency across chains
|
|
60
|
+
results = client.compare_latency()
|
|
61
|
+
|
|
62
|
+
# Export to DataFrame (requires pandas)
|
|
63
|
+
df = client.to_dataframe()
|
|
64
|
+
|
|
65
|
+
# Visualize (requires matplotlib)
|
|
66
|
+
client.plot_latency()
|
|
67
|
+
client.plot_block_heights()
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# blockchain-compare-py
|
|
2
|
+
|
|
3
|
+
Compare blockchain networks (NEAR, Ethereum, Solana) with latency measurement and visualization tools.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Python 3.9+
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
pip install blockchain-compare-py
|
|
12
|
+
|
|
13
|
+
## Optional Dependencies
|
|
14
|
+
|
|
15
|
+
pip install pandas matplotlib
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
from blockchain_compare_py import BlockchainComparePyClient
|
|
20
|
+
|
|
21
|
+
client = BlockchainComparePyClient(timeout=10)
|
|
22
|
+
|
|
23
|
+
## Methods
|
|
24
|
+
|
|
25
|
+
| Method | Description |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `get_block_height(chain)` | Get current block height for a chain |
|
|
28
|
+
| `measure_latency(chain, samples)` | Measure RPC latency for a chain |
|
|
29
|
+
| `compare_latency()` | Compare latency across all chains |
|
|
30
|
+
| `get_metrics(chain)` | Get combined metrics for a chain |
|
|
31
|
+
| `compare_all()` | Compare all metrics across all chains |
|
|
32
|
+
| `to_dataframe()` | Export results as a pandas DataFrame |
|
|
33
|
+
| `plot_latency()` | Plot latency comparison chart |
|
|
34
|
+
| `plot_block_heights()` | Plot block height comparison chart |
|
|
35
|
+
|
|
36
|
+
## Supported Chains
|
|
37
|
+
|
|
38
|
+
- **NEAR** — `https://rpc.mainnet.near.org`
|
|
39
|
+
- **Ethereum** — `https://cloudflare-eth.com`
|
|
40
|
+
- **Solana** — `https://api.mainnet-beta.solana.com`
|
|
41
|
+
|
|
42
|
+
## Example
|
|
43
|
+
|
|
44
|
+
client = BlockchainComparePyClient()
|
|
45
|
+
|
|
46
|
+
# Compare latency across chains
|
|
47
|
+
results = client.compare_latency()
|
|
48
|
+
|
|
49
|
+
# Export to DataFrame (requires pandas)
|
|
50
|
+
df = client.to_dataframe()
|
|
51
|
+
|
|
52
|
+
# Visualize (requires matplotlib)
|
|
53
|
+
client.plot_latency()
|
|
54
|
+
client.plot_block_heights()
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "blockchain-compare-py"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "PyPI Package - blockchain-compare-py v4"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
dependencies = [
|
|
13
|
+
"matplotlib>=3.7",
|
|
14
|
+
"pandas>=2.0","aiohttp>=3.9", "requests>=2.31"]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Homepage = "https://github.com/worksOnMyFridge/blockchain-compare-py"
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""blockchain-compare-py: Compare blockchain networks with NEAR-inclusive analysis."""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.0.0"
|
|
4
|
+
__all__ = ["BlockchainComparePyClient"]
|
|
5
|
+
|
|
6
|
+
import time
|
|
7
|
+
import statistics
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import requests
|
|
12
|
+
HAS_REQUESTS = True
|
|
13
|
+
except ImportError:
|
|
14
|
+
HAS_REQUESTS = False
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import pandas as pd
|
|
18
|
+
HAS_PANDAS = True
|
|
19
|
+
except ImportError:
|
|
20
|
+
HAS_PANDAS = False
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import matplotlib.pyplot as plt
|
|
24
|
+
HAS_MATPLOTLIB = True
|
|
25
|
+
except ImportError:
|
|
26
|
+
HAS_MATPLOTLIB = False
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class BlockchainComparePyClient:
|
|
30
|
+
"""Client for comparing blockchain networks including NEAR, Ethereum, and Solana."""
|
|
31
|
+
|
|
32
|
+
CHAINS = ["near", "ethereum", "solana"]
|
|
33
|
+
|
|
34
|
+
RPC_ENDPOINTS = {
|
|
35
|
+
"near": "https://rpc.mainnet.near.org",
|
|
36
|
+
"ethereum": "https://cloudflare-eth.com",
|
|
37
|
+
"solana": "https://api.mainnet-beta.solana.com",
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
def __init__(self, timeout: int = 10):
|
|
41
|
+
"""Initialize with optional request timeout."""
|
|
42
|
+
self.timeout = timeout
|
|
43
|
+
self._session = requests.Session() if HAS_REQUESTS else None
|
|
44
|
+
|
|
45
|
+
# ── Internal RPC helpers ──────────────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
def _post(self, url: str, payload: dict) -> Optional[dict]:
|
|
48
|
+
"""Send JSON-RPC POST, return parsed response or None."""
|
|
49
|
+
if not HAS_REQUESTS:
|
|
50
|
+
return None
|
|
51
|
+
try:
|
|
52
|
+
r = self._session.post(url, json=payload, timeout=self.timeout)
|
|
53
|
+
r.raise_for_status()
|
|
54
|
+
return r.json()
|
|
55
|
+
except Exception:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
def _near_latest_block(self) -> Optional[dict]:
|
|
59
|
+
"""Fetch latest NEAR block via RPC."""
|
|
60
|
+
data = self._post(
|
|
61
|
+
self.RPC_ENDPOINTS["near"],
|
|
62
|
+
{"jsonrpc": "2.0", "id": "bc", "method": "block", "params": {"finality": "final"}},
|
|
63
|
+
)
|
|
64
|
+
return data.get("result") if data else None
|
|
65
|
+
|
|
66
|
+
def _eth_block_number(self) -> Optional[int]:
|
|
67
|
+
"""Fetch latest Ethereum block number."""
|
|
68
|
+
data = self._post(
|
|
69
|
+
self.RPC_ENDPOINTS["ethereum"],
|
|
70
|
+
{"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []},
|
|
71
|
+
)
|
|
72
|
+
if data and "result" in data:
|
|
73
|
+
return int(data["result"], 16)
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
def _sol_slot(self) -> Optional[int]:
|
|
77
|
+
"""Fetch latest Solana slot."""
|
|
78
|
+
data = self._post(
|
|
79
|
+
self.RPC_ENDPOINTS["solana"],
|
|
80
|
+
{"jsonrpc": "2.0", "id": 1, "method": "getSlot", "params": []},
|
|
81
|
+
)
|
|
82
|
+
return data.get("result") if data else None
|
|
83
|
+
|
|
84
|
+
# ── Public API ────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
def get_block_height(self, chain: str) -> Optional[int]:
|
|
87
|
+
"""Return current block height / slot for the given chain."""
|
|
88
|
+
chain = chain.lower()
|
|
89
|
+
if chain == "near":
|
|
90
|
+
block = self._near_latest_block()
|
|
91
|
+
return block["header"]["height"] if block else None
|
|
92
|
+
if chain == "ethereum":
|
|
93
|
+
return self._eth_block_number()
|
|
94
|
+
if chain == "solana":
|
|
95
|
+
return self._sol_slot()
|
|
96
|
+
raise ValueError(f"Unknown chain: {chain}. Choose from {self.CHAINS}")
|
|
97
|
+
|
|
98
|
+
def measure_latency(self, chain: str, samples: int = 3) -> dict:
|
|
99
|
+
"""Measure average RPC round-trip latency (seconds) over N samples."""
|
|
100
|
+
chain = chain.lower()
|
|
101
|
+
if chain not in self.CHAINS:
|
|
102
|
+
raise ValueError(f"Unknown chain: {chain}")
|
|
103
|
+
timings: list[float] = []
|
|
104
|
+
for _ in range(samples):
|
|
105
|
+
t0 = time.perf_counter()
|
|
106
|
+
self.get_block_height(chain)
|
|
107
|
+
timings.append(time.perf_counter() - t0)
|
|
108
|
+
return {
|
|
109
|
+
"chain": chain,
|
|
110
|
+
"samples": samples,
|
|
111
|
+
"avg_latency_s": round(statistics.mean(timings), 4),
|
|
112
|
+
"min_latency_s": round(min(timings), 4),
|
|
113
|
+
"max_latency_s": round(max(timings), 4),
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
def compare_latency(self, chains: Optional[list] = None, samples: int = 3) -> list[dict]:
|
|
117
|
+
"""Compare RPC latency across multiple chains."""
|
|
118
|
+
chains = chains or self.CHAINS
|
|
119
|
+
return [self.measure_latency(c, samples) for c in chains]
|
|
120
|
+
|
|
121
|
+
def get_metrics(self, chain: str) -> dict:
|
|
122
|
+
"""Return live-fetched metrics dict for a chain."""
|
|
123
|
+
chain = chain.lower()
|
|
124
|
+
height = self.get_block_height(chain)
|
|
125
|
+
latency = self.measure_latency(chain, samples=2)
|
|
126
|
+
return {
|
|
127
|
+
"chain": chain,
|
|
128
|
+
"block_height": height,
|
|
129
|
+
"avg_latency_s": latency["avg_latency_s"],
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
def compare_all(self, chains: Optional[list] = None) -> list[dict]:
|
|
133
|
+
"""Return metrics list for all (or specified) chains."""
|
|
134
|
+
chains = chains or self.CHAINS
|
|
135
|
+
return [self.get_metrics(c) for c in chains]
|
|
136
|
+
|
|
137
|
+
# ── Pandas integration ────────────────────────────────────────────────────
|
|
138
|
+
|
|
139
|
+
def to_dataframe(self, chains: Optional[list] = None):
|
|
140
|
+
"""Return a pandas DataFrame with chain metrics."""
|
|
141
|
+
if not HAS_PANDAS:
|
|
142
|
+
raise ImportError("pandas is required: pip install pandas")
|
|
143
|
+
rows = self.compare_all(chains)
|
|
144
|
+
return pd.DataFrame(rows).set_index("chain")
|
|
145
|
+
|
|
146
|
+
# ── Visualization ─────────────────────────────────────────────────────────
|
|
147
|
+
|
|
148
|
+
def plot_latency(self, chains: Optional[list] = None, samples: int = 3):
|
|
149
|
+
"""Bar chart of average RPC latency per chain."""
|
|
150
|
+
if not HAS_MATPLOTLIB:
|
|
151
|
+
raise ImportError("matplotlib is required: pip install matplotlib")
|
|
152
|
+
results = self.compare_latency(chains, samples)
|
|
153
|
+
labels = [r["chain"] for r in results]
|
|
154
|
+
values = [r["avg_latency_s"] for r in results]
|
|
155
|
+
colors = ["#00C08B" if l == "near" else "#627EEA" if l == "ethereum" else "#9945FF" for l in labels]
|
|
156
|
+
fig, ax = plt.subplots()
|
|
157
|
+
ax.bar(labels, values, color=colors)
|
|
158
|
+
ax.set_ylabel("Avg latency (s)")
|
|
159
|
+
ax.set_title("Blockchain RPC Latency Comparison")
|
|
160
|
+
plt.tight_layout()
|
|
161
|
+
return fig
|
|
162
|
+
|
|
163
|
+
def plot_block_heights(self, chains: Optional[list] = None):
|
|
164
|
+
"""Bar chart of current block heights per chain."""
|
|
165
|
+
if not HAS_MATPLOTLIB:
|
|
166
|
+
raise ImportError("matplotlib is required: pip install matplotlib")
|
|
167
|
+
chains = chains or self.CHAINS
|
|
168
|
+
heights = {c: (self.get_block_height(c) or 0) for c in chains}
|
|
169
|
+
colors = ["#00C08B" if c == "near" else "#627EEA" if c == "ethereum" else "#9945FF" for c in chains]
|
|
170
|
+
fig, ax = plt.subplots()
|
|
171
|
+
ax.bar(list(heights.keys()), list(heights.values()), color=colors)
|
|
172
|
+
ax.set_ylabel("Block height / slot")
|
|
173
|
+
ax.set_title("Blockchain Block Height Comparison")
|
|
174
|
+
plt.tight_layout()
|
|
175
|
+
return fig
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blockchain-compare-py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: PyPI Package - blockchain-compare-py v4
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/worksOnMyFridge/blockchain-compare-py
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: matplotlib>=3.7
|
|
10
|
+
Requires-Dist: pandas>=2.0
|
|
11
|
+
Requires-Dist: aiohttp>=3.9
|
|
12
|
+
Requires-Dist: requests>=2.31
|
|
13
|
+
|
|
14
|
+
# blockchain-compare-py
|
|
15
|
+
|
|
16
|
+
Compare blockchain networks (NEAR, Ethereum, Solana) with latency measurement and visualization tools.
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Python 3.9+
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
pip install blockchain-compare-py
|
|
25
|
+
|
|
26
|
+
## Optional Dependencies
|
|
27
|
+
|
|
28
|
+
pip install pandas matplotlib
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
from blockchain_compare_py import BlockchainComparePyClient
|
|
33
|
+
|
|
34
|
+
client = BlockchainComparePyClient(timeout=10)
|
|
35
|
+
|
|
36
|
+
## Methods
|
|
37
|
+
|
|
38
|
+
| Method | Description |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `get_block_height(chain)` | Get current block height for a chain |
|
|
41
|
+
| `measure_latency(chain, samples)` | Measure RPC latency for a chain |
|
|
42
|
+
| `compare_latency()` | Compare latency across all chains |
|
|
43
|
+
| `get_metrics(chain)` | Get combined metrics for a chain |
|
|
44
|
+
| `compare_all()` | Compare all metrics across all chains |
|
|
45
|
+
| `to_dataframe()` | Export results as a pandas DataFrame |
|
|
46
|
+
| `plot_latency()` | Plot latency comparison chart |
|
|
47
|
+
| `plot_block_heights()` | Plot block height comparison chart |
|
|
48
|
+
|
|
49
|
+
## Supported Chains
|
|
50
|
+
|
|
51
|
+
- **NEAR** — `https://rpc.mainnet.near.org`
|
|
52
|
+
- **Ethereum** — `https://cloudflare-eth.com`
|
|
53
|
+
- **Solana** — `https://api.mainnet-beta.solana.com`
|
|
54
|
+
|
|
55
|
+
## Example
|
|
56
|
+
|
|
57
|
+
client = BlockchainComparePyClient()
|
|
58
|
+
|
|
59
|
+
# Compare latency across chains
|
|
60
|
+
results = client.compare_latency()
|
|
61
|
+
|
|
62
|
+
# Export to DataFrame (requires pandas)
|
|
63
|
+
df = client.to_dataframe()
|
|
64
|
+
|
|
65
|
+
# Visualize (requires matplotlib)
|
|
66
|
+
client.plot_latency()
|
|
67
|
+
client.plot_block_heights()
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/blockchain_compare_py/__init__.py
|
|
4
|
+
src/blockchain_compare_py.egg-info/PKG-INFO
|
|
5
|
+
src/blockchain_compare_py.egg-info/SOURCES.txt
|
|
6
|
+
src/blockchain_compare_py.egg-info/dependency_links.txt
|
|
7
|
+
src/blockchain_compare_py.egg-info/requires.txt
|
|
8
|
+
src/blockchain_compare_py.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
blockchain_compare_py
|