Skip to content
This repository was archived by the owner on Feb 17, 2024. It is now read-only.

Commit f212cd9

Browse files
committed
initial commit
1 parent 3150919 commit f212cd9

File tree

12 files changed

+262
-1
lines changed

12 files changed

+262
-1
lines changed

CHANGELOG.md

Whitespace-only changes.

CONTRIBUTING.md

Whitespace-only changes.

README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,40 @@
11
# alchemy_sdk_py
2-
An SDK to use the Alchemy API
2+
An SDK to use the [Alchemy API](https://www.alchemy.com/)
3+
4+
5+
# Getting Started
6+
7+
## Requirements
8+
9+
- [Python](https://www.python.org/downloads/) 3.7 or higher
10+
- You'll know you've done it right if you can run `python3 --version` in your terminal and see something like `Python 3.10.6`
11+
12+
## Installation
13+
14+
```bash
15+
pip3 install alchemy_sdk_py
16+
```
17+
18+
## Quickstart
19+
20+
### Get an API Key
21+
After [installing](#installation), you'll need to sign up for an API key and set it as an `ALCHEMY_API_KEY` environment variable.
22+
23+
If you're unfamiliar with environment variables, you can use the API to set the key directly using the SDK - please don't do this in production code.
24+
25+
```python
26+
import alchemy_sdk_py
27+
28+
alchemy_sdk_py.set_api_key("YOUR_API_KEY")
29+
```
30+
31+
This will make the key availible for the duration of your script.
32+
33+
### Useage
34+
35+
```python
36+
import alchemy_sdk_py as alchemy
37+
38+
current_block = alchemy.get_current_block()
39+
print(current_block)
40+
```

alchemy_sdk_py/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from .api import (
2+
get_current_block,
3+
get_asset_transfers,
4+
get_transaction_receipt,
5+
get_events,
6+
get_block_datetime,
7+
set_api_key,
8+
)

alchemy_sdk_py/__version__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
__title__ = "alchemy_sdk_py"
2+
__description__ = "Python SDK for working with the Alchemy API."
3+
__version__ = "0.0.1"
4+
__author__ = "Alpha Chain"
5+
__license__ = "MIT"
6+
__copyright__ = "Copyright 2022 Alpha Chain"

alchemy_sdk_py/api.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import os
2+
import requests
3+
import json
4+
from decimal import Decimal
5+
from datetime import datetime
6+
7+
API_KEY = os.getenv("ALCHEMY_API_KEY")
8+
BASE_URL = f"https://eth-mainnet.g.alchemy.com/v2/{API_KEY}"
9+
HEADERS = {"accept": "application/json", "content-type": "application/json"}
10+
11+
12+
def set_api_key(key: str):
13+
"""
14+
params:
15+
key: API key
16+
returns:
17+
None
18+
"""
19+
os.environ["ALCHEMY_API_KEY"] = key
20+
21+
22+
def get_current_block() -> int:
23+
"""
24+
params:
25+
None
26+
returns:
27+
the current max block (INT)
28+
"""
29+
payload = {"id": 1, "jsonrpc": "2.0", "method": "eth_blockNumber"}
30+
response = requests.post(BASE_URL, json=payload, headers=HEADERS)
31+
response = json.loads(response.text)
32+
result = int(response["result"], 16)
33+
return result
34+
35+
36+
def get_asset_transfers(node_address: str, block_start: int, block_end: int) -> list:
37+
"""
38+
params:
39+
node_address: wallet address associated with the OCR node
40+
block_start: INT
41+
block_end: INT
42+
returns: A dictionary, internal/external asset transfers for the address
43+
"""
44+
from_block = str(hex(block_start))
45+
to_block = str(hex(block_end))
46+
address = node_address.lower()
47+
payload = {
48+
"id": 1,
49+
"jsonrpc": "2.0",
50+
"method": "alchemy_getAssetTransfers",
51+
"params": [
52+
{
53+
"fromBlock": from_block,
54+
"toBlock": to_block,
55+
"fromAddress": address,
56+
"category": ["external", "internal"],
57+
"excludeZeroValue": False,
58+
}
59+
],
60+
}
61+
response = requests.post(BASE_URL, json=payload, headers=HEADERS)
62+
response = json.loads(response.text)
63+
result = response["result"]
64+
transfers = result["transfers"]
65+
return transfers
66+
67+
68+
def get_transaction_receipt(transaction_hash: str):
69+
"""
70+
params:
71+
transaction_hash: transaction hash to search for
72+
returns:
73+
transaction receipt data
74+
"""
75+
payload = {
76+
"id": 1,
77+
"jsonrpc": "2.0",
78+
"method": "eth_getTransactionReceipt",
79+
"params": [transaction_hash],
80+
}
81+
response = requests.post(BASE_URL, json=payload, headers=HEADERS)
82+
response = json.loads(response.text)
83+
result = response["result"]
84+
return result
85+
86+
87+
def get_events(contract_address, event_signature, block_start, block_end) -> dict:
88+
"""
89+
params:
90+
contract_address: LIST off addresses for which to search for events
91+
event_signature: signature of the event to search for (TOPIC 0)
92+
block_start: INT
93+
block_end: INT
94+
returns: A dictionary, result[block] = block_date
95+
"""
96+
from_block = str(hex(block_start))
97+
to_block = str(hex(block_end))
98+
payload = {
99+
"id": 1,
100+
"jsonrpc": "2.0",
101+
"method": "eth_getLogs",
102+
"params": [
103+
{
104+
"address": contract_address,
105+
"fromBlock": from_block,
106+
"toBlock": to_block,
107+
"topics": [event_signature],
108+
}
109+
],
110+
}
111+
response = requests.post(BASE_URL, json=payload, headers=HEADERS)
112+
response = json.loads(response.text)
113+
result = response.get("result")
114+
return result
115+
116+
117+
def get_block_datetime(blocks=None, block_start=None, block_end=None) -> dict:
118+
"""
119+
params:
120+
block_start as an INT
121+
block_end as an INT
122+
returns:
123+
A dictionary, result[block] = block_date
124+
"""
125+
blocks = list(range(block_start, block_end)) if blocks is None else blocks
126+
result = {}
127+
for block in blocks:
128+
payload = {
129+
"id": 1,
130+
"jsonrpc": "2.0",
131+
"method": "eth_getBlockByNumber",
132+
"params": [hex(block), False],
133+
}
134+
response = requests.post(BASE_URL, json=payload, headers=HEADERS)
135+
result_raw = json.loads(response.text)["result"]
136+
block = int(result_raw["number"], 16)
137+
block_date = datetime.fromtimestamp(int(result_raw["timestamp"], 16))
138+
result[block] = block_date
139+
return result

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["setuptools"]
3+
build-backend = "setuptools.build_meta"

requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
certifi==2022.12.7
2+
charset-normalizer==2.1.1
3+
idna==3.4
4+
requests==2.28.1
5+
urllib3==1.26.13

setup.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[metadata]
2+
license_file = LICENSE
3+
description-file = README.md

setup.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from setuptools import setup
2+
import os
3+
4+
5+
here = os.path.abspath(os.path.dirname(__file__))
6+
with open("README.md", "r", "utf-8") as f:
7+
readme = f.read()
8+
9+
about = {}
10+
with open(os.path.join(here, "alchemy_sdk_py", "__version__.py"), "r", "utf-8") as f:
11+
exec(f.read(), about)
12+
13+
setup(
14+
name=about["__title__"],
15+
version=about["__version__"],
16+
author=about["__author__"],
17+
license=about["__license__"],
18+
install_requires=[
19+
"certifi",
20+
"charset-normalizer",
21+
"idna",
22+
"requests",
23+
"urllib3",
24+
],
25+
packages=[about["__title__"]],
26+
python_requires=">=3.7, <4",
27+
url="https://github.com/alphachainio/alchemy_sdk_py",
28+
long_description=readme,
29+
long_description_content_type="text/markdown",
30+
classifiers=[
31+
"Development Status :: 2 - Pre-Alpha",
32+
"Intended Audience :: Developers",
33+
"License :: OSI Approved :: MIT License",
34+
"Programming Language :: Python :: 3.7",
35+
"Programming Language :: Python :: 3.8",
36+
"Programming Language :: Python :: 3.9",
37+
"Programming Language :: Python :: 3.10",
38+
],
39+
packages=["alchemy_sdk_py"],
40+
)

0 commit comments

Comments
 (0)