Bitcoin   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 101
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 101
rs 10
c 0
b 0
f 0
wmc 19

11 Methods

Rating   Name   Duplication   Size   Complexity  
A convert_all() 0 4 1
A get_balance() 0 4 1
A get_spot_price() 0 4 1
A __init__() 0 3 1
B req() 0 26 5
A get_tx_from_addrs() 0 3 1
A noauth_req() 0 11 3
A get_tx_by_hash() 0 3 1
A get_new_address() 0 12 2
A get_block_height() 0 3 1
A convert() 0 9 2
1
2
import urllib
3
import urllib.error
4
import urllib.request
5
import time
6
import json
7
import hashlib
8
import hmac
9
from decimal import Decimal
10
11
12
class BTCException(Exception):
13
    pass
14
15
class Bitcoin(object):
16
17
    COINBASE_API_KEY = ""
18
    COINBASE_API_SECRET = ""
19
20
    HOSTNAME = ''
21
22
    def __init__(self, umid=None):
23
        self.umid = umid
24
        pass
25
26
    @staticmethod
27
    def req(url, body=None):
28
        try:
29
            opener = urllib.request.build_opener()
30
            nonce = int(time.time() * 1e6)
31
            message = str(nonce) + url + ('' if body is None else body)
32
            signature = hmac.new(bytes(Bitcoin.COINBASE_API_SECRET, "utf-8"),
33
                                 bytes(message, "utf-8"),
34
                                 hashlib.sha256).hexdigest()
35
            opener.addheaders = [('ACCESS_KEY', Bitcoin.COINBASE_API_KEY),
36
                                ('ACCESS_SIGNATURE', signature),
37
                                ('ACCESS_NONCE', nonce)]
38
39
            # is this really how you do this in this language?
40
            body_b = None
41
            if body is not None:
42
                body_b = bytes(body, "utf-8")
43
44
            res_s = opener.open(urllib.request.Request(url,
45
                body_b, {'Content-Type': 'application/json'})).read()
46
            return json.loads(str(res_s, 'utf-8'))
47
48
        except urllib.error.HTTPError as e:
49
            raise BTCException("Could not load HTTP url %s: %s, %s" % (url, str(e), e.read()))
50
        except urllib.error.URLError as e:
51
            raise BTCException("General urllib failure: %s" % (str(e)))
52
53
54
    @staticmethod
55
    def noauth_req(url):
56
        try:
57
            opener = urllib.request.build_opener()
58
            res_s = opener.open(urllib.request.Request(url,
59
                None, {'Content-Type': 'application/json'})).read()
60
            return json.loads(str(res_s, 'utf-8'))
61
        except urllib.error.HTTPError as e:
62
            raise BTCException("Could not load HTTP")
63
        except urllib.error.URLError as e:
64
            raise BTCException("General urllib failure")
65
66
    @staticmethod
67
    def get_new_address(umid, auth_key, cb_url='{}/terminal/bitcoin/deposit'):
68
69
        cb_url = cb_url.format(Bitcoin.HOSTNAME)
70
71
        obj = Bitcoin.req("https://api.coinbase.com/v1/addresses",
72
                      '{"address": {"callback_url": "%s/%s/%s", "label": "%s"}}' % (cb_url, umid, auth_key, umid))
73
74
        if not(obj['success']):
75
            raise BTCException("Could not get address: %s" % umid)
76
77
        return obj['address']
78
79
    @staticmethod
80
    def get_spot_price(currency="USD"):
81
        obj = Bitcoin.req("https://coinbase.com/api/v1/prices/spot_rate?currency=%s" % currency)
82
        return Decimal(obj['amount'])
83
84
    @staticmethod
85
    def get_balance():
86
        obj = Bitcoin.req("https://coinbase.com/api/v1/account/balance")
87
        return Decimal(obj['amount'])
88
89
    @staticmethod
90
    def get_tx_by_hash(txid):
91
        return Bitcoin.noauth_req("https://blockchain.info/rawtx/%s" % txid)
92
93
    @staticmethod
94
    def get_block_height():
95
        return Bitcoin.noauth_req("https://blockchain.info/latestblock")["height"]
96
97
    # | separated list (e.g. "14YD3or6jXZowg8PV5VfZo9jmer8TQZHFg|1AZiKMapdu2KibenF67FHFgNbxL9sG2jt5")
98
    @staticmethod
99
    def get_tx_from_addrs(addrs):
100
        return Bitcoin.noauth_req("https://blockchain.info/multiaddr?active=%s" % addrs )
101
102
    @staticmethod
103
    def convert(amount):
104
        obj = Bitcoin.req("https://coinbase.com/api/v1/sells",
105
                          '{"qty": %s}' % (amount))
106
107
        if not(obj['success']):
108
            raise BTCException("failure on BTC convert (%s)" % obj['errors'])
109
110
        return Decimal(obj['transfer']['total']['amount'])
111
112
    @staticmethod
113
    # Returns the amount in USD that the bitcoins were exchanged for
114
    def convert_all():
115
        return Bitcoin.get_balance()*Bitcoin.get_spot_price()*Decimal(0.99)
116
        #raise NotImplementedError()
117
118