tradehub.utils.Request.get()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nop 3
1
import base58
2
import binascii
3
import json
4
import math
5
import requests
6
from web3 import Web3
7
8
9
class TradehubApiException(Exception):
10
11
    def __init__(self, error_code, error_message, error):
12
        super(TradehubApiException, self).__init__(error_message)
13
        self.error_code = error_code
14
        self.error = error
15
16
17
class Request(object):
18
19
    def __init__(self, api_url='https://test-tradescan.switcheo.org', timeout=30):
20
        self.url = api_url.rstrip('/')
21
        self.timeout = timeout
22
23
    def get(self, path, params=None):
24
        """Perform GET request"""
25
        r = requests.get(url=self.url + path, params=params, timeout=self.timeout)
26
        r.raise_for_status()
27
        return r.json()
28
29
    def post(self, path, data=None, json_data=None, params=None):
30
        """Perform POST request"""
31
        r = requests.post(url=self.url + path, data=data, json=json_data, params=params, timeout=self.timeout)
32
        try:
33
            r.raise_for_status()
34
        except requests.exceptions.HTTPError:
35
            raise TradehubApiException(r.json().get('error_code'), r.json().get('error_message'), r.json().get('error'))
36
        return r.json()
37
38
    def status(self):
39
        return self.get(path='/get_status')
40
41
42
def sort_and_stringify_json(message):
43
    """
44
    Return a JSON message that is alphabetically sorted by the key name
45
    Args:
46
        message
47
    """
48
    return json.dumps(message, sort_keys=True, separators=(',', ':'))
49
50
51
def to_tradehub_asset_amount(amount: float, decimals: int = 8):
52
    return "{:.0f}".format(amount * math.pow(10, decimals))
53
54
55
def reverse_hex(message: str):
56
    return "".join([message[x:x + 2] for x in range(0, len(message), 2)][::-1])
57
58
59
def is_valid_neo_public_address(address: str) -> bool:
60
    """Check if address is a valid NEO address"""
61
    valid = False
62
63
    if len(address) == 34 and address[0] == 'A':
64
        try:
65
            base58.b58decode_check(address.encode())
66
            valid = True
67
        except ValueError:
68
            # checksum mismatch
69
            valid = False
70
71
    return valid
72
73
74
def neo_get_scripthash_from_address(address: str):
75
    hash_bytes = binascii.hexlify(base58.b58decode_check(address))
76
    return reverse_hex(hash_bytes[2:].decode('utf-8'))
77
78
79
def is_eth_contract(address: str, web3_uri: str):
80
    eth_w3 = Web3(provider=Web3.HTTPProvider(endpoint_uri=web3_uri))
81
    if len(eth_w3.eth.get_code(eth_w3.toChecksumAddress(value=address))) == 0:
82
        return False
83
    else:
84
        return True
85
86
87
def format_withdraw_address(address: str, blockchain: str, web3_uri: str = None):
88
    if blockchain.lower() in ['neo'] and is_valid_neo_public_address(address=address):
89
        return reverse_hex(neo_get_scripthash_from_address(address=address))
90
    elif blockchain.lower() in ['eth', 'ethereum'] and Web3.isAddress(value=address):
91
        if is_eth_contract(address=address, web3_uri=web3_uri):
92
            raise ValueError('Cannot withdraw to an Ethereum contract address.')
93
        else:
94
            print("In Web3")
95
            return Web3.toChecksumAddress(value=address)[2:]
96
    else:
97
        raise ValueError('Not a valid address OR blockchain not yet supported.')
98