Completed
Push — master ( e0dbd4...85d261 )
by
unknown
32s
created

bitpay.Client.pair_pos_client()   A

Complexity

Conditions 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 4
dl 0
loc 19
rs 9.2
1
from bitpay_exceptions import *
2
import bitpay_key_utils as key_utils
3
import requests
4
import json
5
import re
6
7
8
class Client:
9
10
    def __init__(self, api_uri="https://bitpay.com", insecure=False,
11
                 pem=key_utils.generate_pem(), tokens={}):
12
13
        self.uri = api_uri
14
        self.verify = not(insecure)
15
        self.pem = pem
16
        self.client_id = key_utils.get_sin_from_pem(pem)
17
        self.tokens = tokens
18
        self.user_agent = 'bitpay-python'
19
20
    def pair_pos_client(self, code):
21
        """
22
        POST /tokens
23
        https://bitpay.com/api#resource-Tokens
24
        """
25
        if re.match("^\w{7,7}$", code) is None:
26
            raise BitPayArgumentError("pairing code is not legal")
27
        payload = {'id': self.client_id, 'pairingCode': code}
28
        headers = {"content-type": "application/json",
29
                   "accept": "application/json", "X-accept-version": "2.0.0"}
30
        try:
31
            response = requests.post(self.uri + "/tokens", verify=self.verify,
32
                                     data=json.dumps(payload), headers=headers)
33
        except Exception:
34
            raise BitPayConnectionError('Connection refused')
35
        if response.ok:
36
            self.tokens = self.token_from_response(response.json())
37
            return self.tokens
38
        self.response_error(response)
39
40 View Code Duplication
    def create_token(self, facade):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
41
        """
42
        POST /tokens
43
        https://bitpay.com/api#resource-Tokens
44
        """
45
        payload = {'id': self.client_id, 'facade': facade}
46
        headers = {"content-type": "application/json",
47
                   "accept": "application/json", "X-accept-version": "2.0.0"}
48
        try:
49
            response = requests.post(self.uri + "/tokens", verify=self.verify,
50
                                     data=json.dumps(payload), headers=headers)
51
        except Exception:
52
            raise BitPayConnectionError('Connection refused')
53
        if response.ok:
54
            self.tokens = self.token_from_response(response.json())
55
            return response.json()['data'][0]['pairingCode']
56
        self.response_error(response)
57
58 View Code Duplication
    def create_invoice(self, params):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
59
        """
60
        POST /invoices
61
        https://bitpay.com/api#resource-Invoices
62
        """
63
        self.verify_invoice_params(params['price'], params['currency'])
64
        payload = json.dumps(params)
65
        uri = self.uri + "/invoices"
66
        xidentity = key_utils.get_compressed_public_key_from_pem(self.pem)
67
        xsignature = key_utils.sign(uri + payload, self.pem)
68
        headers = {"content-type": "application/json",
69
                   "accept": "application/json", "X-Identity": xidentity,
70
                   "X-Signature": xsignature, "X-accept-version": "2.0.0"}
71
        try:
72
            response = requests.post(uri, data=payload, headers=headers,
73
                                     verify=self.verify)
74
        except Exception as pro:
75
            raise BitPayConnectionError(pro.args)
76
        if response.ok:
77
            return response.json()['data']
78
        self.response_error(response)
79
80
    def get_invoice(self, invoice_id):
81
        """
82
        GET /invoices/:invoiceId
83
        https://bitpay.com/api#resource-Invoices
84
        """
85
        uri = self.uri + "/invoices/" + invoice_id
86
        try:
87
            response = requests.get(uri, verify=self.verify)
88
        except Exception as pro:
89
            raise BitPayConnectionError(pro.args)
90
        if response.ok:
91
            return response.json()['data']
92
        self.response_error(response)
93
94
    def verify_tokens(self):
95
        """
96
        GET /tokens
97
        https://bitpay.com/api#resource-Tokens
98
        """
99
        xidentity = key_utils.get_compressed_public_key_from_pem(self.pem)
100
        xsignature = key_utils.sign(self.uri + "/tokens", self.pem)
101
        headers = {"content-type": "application/json",
102
                   "accept": "application/json", "X-Identity": xidentity,
103
                   "X-Signature": xsignature, "X-accept-version": '2.0.0'}
104
        response = requests.get(self.uri + "/tokens", headers=headers,
105
                                verify=self.verify)
106
        if response.ok:
107
            allTokens = response.json()['data']
108
            selfKeys = self.tokens.keys()
109
            matchedTokens = [token for token in allTokens for key in selfKeys
110
                             if token.get(key) == self.tokens.get(key)]
111
        if not matchedTokens:
112
            return False
113
        return True
114
115
    def token_from_response(self, responseJson):
116
        token = responseJson['data'][0]['token']
117
        facade = responseJson['data'][0]['facade']
118
        return {facade: token}
119
        raise BitPayBitPayError(
120
            '%(code)d: %(message)s' % {'code': response.status_code,
121
                                       'message': response.json()['error']})
122
123
    def verify_invoice_params(self, price, currency):
124
        if re.match("^[A-Z]{3,3}$", currency) is None:
125
            raise BitPayArgumentError("Currency is invalid.")
126
        try:
127
            float(price)
128
        except:
129
            raise BitPayArgumentError("Price must be formatted as a float")
130
131
    def response_error(self, response):
132
        raise BitPayBitPayError(
133
            '%(code)d: %(message)s' % {'code': response.status_code,
134
                                       'message': response.json()['error']})
135