mirror of
https://github.com/FlipsideCrypto/chainwalkers-utils.git
synced 2026-02-06 10:06:43 +00:00
Add eth utils and readme
This commit is contained in:
parent
19263bba9e
commit
c011a12b48
17
README.md
Normal file
17
README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Chainwalker Utilities
|
||||||
|
|
||||||
|
This repo is home to Flipsides chainwalkers python utilities package. A central repo that packeges up various python modules that can be used across chainwalkers projects.
|
||||||
|
|
||||||
|
## Modules
|
||||||
|
|
||||||
|
### Tendermint Utils
|
||||||
|
|
||||||
|
Collection of common methods used to interact with tendermint based chains (Cosmos, Kava, Binance)
|
||||||
|
|
||||||
|
### Eth utils
|
||||||
|
|
||||||
|
Collection of common methods used across eth based chains
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
`pip install git+ssh://git@github.com/FlipsideCrypto/chainwalkers-utils.git`
|
||||||
1
build/lib/eth_utils/__init__.py
Normal file
1
build/lib/eth_utils/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from eth_utils.jsonrpc import JsonRpcCaller
|
||||||
7
build/lib/eth_utils/decimals.py
Normal file
7
build/lib/eth_utils/decimals.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
def hex_to_decimal(hex_value):
|
||||||
|
if hex_value == '0x':
|
||||||
|
return 0
|
||||||
|
return int(hex_value, 16)
|
||||||
|
|
||||||
|
def decimal_to_hex(decimal):
|
||||||
|
return hex(decimal)
|
||||||
62
build/lib/eth_utils/jsonrpc.py
Normal file
62
build/lib/eth_utils/jsonrpc.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import time
|
||||||
|
|
||||||
|
class RpcCallFailedException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class JsonRpcCaller(object):
|
||||||
|
|
||||||
|
def __init__(self, node_url, user=None, password=None, tls=False, tlsVerify=False):
|
||||||
|
self.url = node_url
|
||||||
|
self.user = user
|
||||||
|
self.password = password
|
||||||
|
self.tls = tls
|
||||||
|
self.tlsVerify = tlsVerify
|
||||||
|
|
||||||
|
def _make_rpc_call(self, headers, payload, json):
|
||||||
|
try:
|
||||||
|
response = requests.post(
|
||||||
|
self.url,
|
||||||
|
headers=headers,
|
||||||
|
data=payload,
|
||||||
|
json=json,
|
||||||
|
verify=(self.tls and self.tlsVerify)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise RpcCallFailedException(e)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise RpcCallFailedException("Invalid status code: %s" % response.status_code)
|
||||||
|
|
||||||
|
responseJson = response.json(parse_float=lambda f: f)
|
||||||
|
|
||||||
|
if type(responseJson) != list:
|
||||||
|
if "error" in responseJson and responseJson["error"] is not None:
|
||||||
|
raise RpcCallFailedException("RPC call error: %s" % responseJson["error"])
|
||||||
|
else:
|
||||||
|
return responseJson.get('result')
|
||||||
|
else:
|
||||||
|
result = []
|
||||||
|
for subResult in responseJson:
|
||||||
|
if "error" in subResult and subResult["error"] is not None:
|
||||||
|
raise RpcCallFailedException("RPC call error: %s" % subResult["error"])
|
||||||
|
else:
|
||||||
|
result.append(subResult["result"])
|
||||||
|
return result
|
||||||
|
|
||||||
|
def call(self, method, params=None, query=None):
|
||||||
|
if params is None:
|
||||||
|
params = []
|
||||||
|
headers = {'content-type': 'application/json'}
|
||||||
|
payload = json.dumps({"jsonrpc": "2.0", "id": "0", "method": method, "params": params})
|
||||||
|
if query: # GQL Hack
|
||||||
|
return self._make_rpc_call(headers, payload=None, json={'query': query})
|
||||||
|
return self._make_rpc_call(headers, payload, json=None)
|
||||||
|
|
||||||
|
def bulk_call(self, methodParamsTuples):
|
||||||
|
headers = {'content-type': 'application/json'}
|
||||||
|
payload = json.dumps([{"jsonrpc": "2.0", "id": "0", "method": method, "params": params}
|
||||||
|
for method, params in methodParamsTuples])
|
||||||
|
return self._make_rpc_call(headers, payload)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
Metadata-Version: 1.0
|
Metadata-Version: 2.1
|
||||||
Name: chainwalkers-utils
|
Name: chainwalkers-utils
|
||||||
Version: 0.0.4
|
Version: 0.0.4
|
||||||
Summary: Collection of utilities to be used across chainwalkers repos
|
Summary: Collection of utilities to be used across chainwalkers repos
|
||||||
@ -6,5 +6,22 @@ Home-page: git@github.com:FlipsideCrypto/chainwalkers-utils.git
|
|||||||
Author: Brian Ford
|
Author: Brian Ford
|
||||||
Author-email: brian@flipsidecrypto.com
|
Author-email: brian@flipsidecrypto.com
|
||||||
License: unlicense
|
License: unlicense
|
||||||
Description: UNKNOWN
|
Description: # Chainwalker Utilities
|
||||||
|
|
||||||
|
This repo is home to Flipsides chainwalkers python utilities package. A central repo that packeges up various python modules that can be used across chainwalkers projects.
|
||||||
|
|
||||||
|
## Modules
|
||||||
|
|
||||||
|
### Tendermint Utils
|
||||||
|
|
||||||
|
Collection of common methods used to interact with tendermint based chains (Cosmos, Kava, Binance)
|
||||||
|
|
||||||
|
### Eth utils
|
||||||
|
|
||||||
|
Collection of common methods used across eth based chains
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
`pip install git+ssh://git@github.com/FlipsideCrypto/chainwalkers-utils.git`
|
||||||
Platform: UNKNOWN
|
Platform: UNKNOWN
|
||||||
|
Description-Content-Type: text/markdown
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
|
README.md
|
||||||
setup.py
|
setup.py
|
||||||
chainwalkers_utils.egg-info/PKG-INFO
|
chainwalkers_utils.egg-info/PKG-INFO
|
||||||
chainwalkers_utils.egg-info/SOURCES.txt
|
chainwalkers_utils.egg-info/SOURCES.txt
|
||||||
chainwalkers_utils.egg-info/dependency_links.txt
|
chainwalkers_utils.egg-info/dependency_links.txt
|
||||||
chainwalkers_utils.egg-info/not-zip-safe
|
chainwalkers_utils.egg-info/not-zip-safe
|
||||||
chainwalkers_utils.egg-info/top_level.txt
|
chainwalkers_utils.egg-info/top_level.txt
|
||||||
tendermint/__init__.py
|
eth_utils/__init__.py
|
||||||
tendermint/rpc.py
|
eth_utils/decimals.py
|
||||||
|
eth_utils/jsonrpc.py
|
||||||
|
tendermint_utils/__init__.py
|
||||||
|
tendermint_utils/rpc.py
|
||||||
@ -1 +1,2 @@
|
|||||||
tendermint
|
eth_utils
|
||||||
|
tendermint_utils
|
||||||
|
|||||||
BIN
dist/chainwalkers_utils-0.0.4-py3.7.egg
vendored
BIN
dist/chainwalkers_utils-0.0.4-py3.7.egg
vendored
Binary file not shown.
1
eth_utils/__init__.py
Normal file
1
eth_utils/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from eth_utils.jsonrpc import JsonRpcCaller
|
||||||
7
eth_utils/decimals.py
Normal file
7
eth_utils/decimals.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
def hex_to_decimal(hex_value):
|
||||||
|
if hex_value == '0x':
|
||||||
|
return 0
|
||||||
|
return int(hex_value, 16)
|
||||||
|
|
||||||
|
def decimal_to_hex(decimal):
|
||||||
|
return hex(decimal)
|
||||||
62
eth_utils/jsonrpc.py
Normal file
62
eth_utils/jsonrpc.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import time
|
||||||
|
|
||||||
|
class RpcCallFailedException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class JsonRpcCaller(object):
|
||||||
|
|
||||||
|
def __init__(self, node_url, user=None, password=None, tls=False, tlsVerify=False):
|
||||||
|
self.url = node_url
|
||||||
|
self.user = user
|
||||||
|
self.password = password
|
||||||
|
self.tls = tls
|
||||||
|
self.tlsVerify = tlsVerify
|
||||||
|
|
||||||
|
def _make_rpc_call(self, headers, payload, json):
|
||||||
|
try:
|
||||||
|
response = requests.post(
|
||||||
|
self.url,
|
||||||
|
headers=headers,
|
||||||
|
data=payload,
|
||||||
|
json=json,
|
||||||
|
verify=(self.tls and self.tlsVerify)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise RpcCallFailedException(e)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise RpcCallFailedException("Invalid status code: %s" % response.status_code)
|
||||||
|
|
||||||
|
responseJson = response.json(parse_float=lambda f: f)
|
||||||
|
|
||||||
|
if type(responseJson) != list:
|
||||||
|
if "error" in responseJson and responseJson["error"] is not None:
|
||||||
|
raise RpcCallFailedException("RPC call error: %s" % responseJson["error"])
|
||||||
|
else:
|
||||||
|
return responseJson.get('result')
|
||||||
|
else:
|
||||||
|
result = []
|
||||||
|
for subResult in responseJson:
|
||||||
|
if "error" in subResult and subResult["error"] is not None:
|
||||||
|
raise RpcCallFailedException("RPC call error: %s" % subResult["error"])
|
||||||
|
else:
|
||||||
|
result.append(subResult["result"])
|
||||||
|
return result
|
||||||
|
|
||||||
|
def call(self, method, params=None, query=None):
|
||||||
|
if params is None:
|
||||||
|
params = []
|
||||||
|
headers = {'content-type': 'application/json'}
|
||||||
|
payload = json.dumps({"jsonrpc": "2.0", "id": "0", "method": method, "params": params})
|
||||||
|
if query: # GQL Hack
|
||||||
|
return self._make_rpc_call(headers, payload=None, json={'query': query})
|
||||||
|
return self._make_rpc_call(headers, payload, json=None)
|
||||||
|
|
||||||
|
def bulk_call(self, methodParamsTuples):
|
||||||
|
headers = {'content-type': 'application/json'}
|
||||||
|
payload = json.dumps([{"jsonrpc": "2.0", "id": "0", "method": method, "params": params}
|
||||||
|
for method, params in methodParamsTuples])
|
||||||
|
return self._make_rpc_call(headers, payload)
|
||||||
5
setup.py
5
setup.py
@ -1,9 +1,14 @@
|
|||||||
import setuptools
|
import setuptools
|
||||||
|
|
||||||
|
with open("README.md", "r") as fh:
|
||||||
|
long_description = fh.read()
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name='chainwalkers_utils',
|
name='chainwalkers_utils',
|
||||||
version='0.0.4',
|
version='0.0.4',
|
||||||
description='Collection of utilities to be used across chainwalkers repos',
|
description='Collection of utilities to be used across chainwalkers repos',
|
||||||
|
long_description=long_description,
|
||||||
|
long_description_content_type="text/markdown",
|
||||||
url='git@github.com:FlipsideCrypto/chainwalkers-utils.git',
|
url='git@github.com:FlipsideCrypto/chainwalkers-utils.git',
|
||||||
author='Brian Ford',
|
author='Brian Ford',
|
||||||
author_email='brian@flipsidecrypto.com',
|
author_email='brian@flipsidecrypto.com',
|
||||||
|
|||||||
1
tendermint_utils/__init__.py
Normal file
1
tendermint_utils/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from tendermint.rpc import TendermintRPC
|
||||||
85
tendermint_utils/rpc.py
Normal file
85
tendermint_utils/rpc.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import json
|
||||||
|
import requests
|
||||||
|
|
||||||
|
class TendermintRPC:
|
||||||
|
|
||||||
|
def __init__(self, node_url):
|
||||||
|
self.node_url = node_url
|
||||||
|
|
||||||
|
def get_block_height(self):
|
||||||
|
try:
|
||||||
|
response = requests.get(self.node_url+ '/abci_info?')
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
return data['result']['response']['last_block_height']
|
||||||
|
except Exception as err:
|
||||||
|
print(f'An error occured retrieving the latest block height: {err}')
|
||||||
|
|
||||||
|
def get_block(self, height):
|
||||||
|
try:
|
||||||
|
response = requests.get(self.node_url + '/block?height=' + str(height))
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
block = self.init_block(data['result'])
|
||||||
|
|
||||||
|
block_results = self.get_block_results(height)
|
||||||
|
|
||||||
|
# Capture transactions and underlying events
|
||||||
|
block_transactions = self.get_transactions_by_block(height)
|
||||||
|
if block_transactions['txs']:
|
||||||
|
for tx in block_transactions['txs']:
|
||||||
|
block_tx = self.get_transactions_by_hash(tx['hash'])
|
||||||
|
block.add_transaction(block_tx)
|
||||||
|
|
||||||
|
# Capture begin block events ()
|
||||||
|
if block_results['results']['begin_block']:
|
||||||
|
for event in block_results['results']['begin_block']['events']:
|
||||||
|
block.begin_block.append(event)
|
||||||
|
|
||||||
|
block.end_block = block_results['results']['end_block']
|
||||||
|
|
||||||
|
block_validators = self.get_block_validators(height)
|
||||||
|
for validator in block_validators['validators']:
|
||||||
|
block.validators.append(validator)
|
||||||
|
|
||||||
|
return block
|
||||||
|
except Exception as err:
|
||||||
|
print(f'An error occured retrieving block: {err}')
|
||||||
|
|
||||||
|
def get_block_results(self, height):
|
||||||
|
try:
|
||||||
|
response = requests.get(self.node_url + '/block_results?height=' + str(height))
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
return data['result']
|
||||||
|
except Exception as err:
|
||||||
|
print(f'An error occured retrieving the results of block height: {err}')
|
||||||
|
|
||||||
|
# Need ANKR to turn on indexing at node level for this call to work properly
|
||||||
|
def get_transactions_by_block(self, height):
|
||||||
|
try:
|
||||||
|
response = requests.get(self.node_url + '/tx_search?query=\"tx.height=' + str(height) + '\"&prove=true')
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
return data['result']
|
||||||
|
except Exception as err:
|
||||||
|
print(f'An error occured retrieving the transactions in block: {err}')
|
||||||
|
|
||||||
|
def get_transactions_by_hash(self, tx_hash):
|
||||||
|
try:
|
||||||
|
response = requests.get(self.node_url + '/tx?hash=' + tx_hash)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
return data
|
||||||
|
except Exception as err:
|
||||||
|
print(f'An error occured retrieving the transaction by hash: {err}')
|
||||||
|
|
||||||
|
# Currently returning the following response "Height must be less than or equal to the current blockchain height"
|
||||||
|
def get_block_validators(self, height):
|
||||||
|
try:
|
||||||
|
response = requests.get(self.node_url + '/validators?height=' + str(height))
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
return data['result']
|
||||||
|
except Exception as err:
|
||||||
|
print(f'An error occured retrieving the validators for block height: {err}')
|
||||||
Loading…
Reference in New Issue
Block a user