Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions blockapi/api/dcrdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ def get_txs(self, offset=None, limit=None, unconfirmed=False):
return [self.parse_tx(tx) for tx in txs]

def get_tx(self, tx_hash):
"""Despite the name this method is not returning single tx
but might result in the array of txs
"""
tx = self.request('get_transaction', tx_hash=tx_hash)
for parsed in self.parse_tx(tx):
return parsed[0]
return None
return self.parse_tx(tx)['result']

def parse_tx(self, tx):
kind = self.get_tx_kind(tx)

parsed = {
'transaction': self.parse_regular_tx,
'ticket': self.parse_ticket,
'vote': self.parse_vote,
'revocation': self.parse_revocation
}.get(kind)(tx)

parsed['kind'] = kind
return parsed
return {'kind': kind, 'result': parsed}

@staticmethod
def get_tx_kind(tx):
Expand All @@ -83,10 +83,14 @@ def parse_regular_tx(self, tx):
# Tx in decred could contain several addresses, filter only mine
ins = [v for v in tx['vin']
if self.address in v.get('prevOut', {}).get('addresses', [])]
outs = [o for o in tx['vout']
if self.address in o.get('scriptPubKey', {}).get('addresses', [])]
outs = [o for o in tx['vout'] if self.address
in o.get('scriptPubKey', {}).get('addresses', [])]

date = datetime.fromtimestamp(tx['time'], pytz.utc)
# get_txs has time attribute, get_tx has block.time attribute
if 'time' in tx:
date = datetime.fromtimestamp(tx['time'], pytz.utc)
else:
date = datetime.fromtimestamp(tx['block']['time'], pytz.utc)

parsed = []
for i in ins:
Expand Down Expand Up @@ -133,7 +137,8 @@ def parse_ticket(tx):
if v['scriptPubKey']['type'] == 'stakesubmission'),
0)

# pool fee is lower value then ticket cost, but not sure if it's correct
# pool fee is lower value then ticket cost,
# but not sure if it's correct
pool_fee = (min([v['amount_in'] for v in tx['vin']])
if len(tx['vin']) > 1
else 0)
Expand All @@ -155,7 +160,9 @@ def parse_ticket(tx):
@staticmethod
def get_ticket_status(tx):
# params for mainnet:
# https://github.com/decred/dcrd/blob/9da132b9823b20870122dc0bf795884cee99d922/chaincfg/mainnetparams.go#L321
# https://github.com/decred/dcrd/blob
# /9da132b9823b20870122dc0bf795884cee99d922
# /chaincfg/mainnetparams.go#L321
if tx['confirmations'] < 1:
return 'unmined'
elif tx['confirmations'] < 256:
Expand Down
58 changes: 58 additions & 0 deletions blockapi/test/api/cassettes/TestDcrdataAPI.test_get_balance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- python-requests/2.23.0
method: GET
uri: https://explorer.dcrdata.org/api/address/DsXt3he1A9KB2uL1g3MJvbAbXEB1CxN2rNF/totals
response:
body:
string: '{"address":"DsXt3he1A9KB2uL1g3MJvbAbXEB1CxN2rNF","blockhash":"00000000000000000081b3ca6f99e5c72603397e69f546d5f74263d7039bb783","blockheight":456630,"num_stxos":165,"num_utxos":2,"dcr_spent":7509.3490332,"dcr_unspent":135.0176}

'
headers:
Alt-Svc:
- clear
Content-Length:
- '228'
Content-Security-Policy-Report-Only:
- default-src 'self'; script-src 'self' 'sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb'
'sha256-8in1YfOPOMqtBgRhX5uaoR+Gb7WGEjhl6XqBqFHsTjI=' 'sha256-967sY4EvCS9bV1jFWgKgDeLOvpSpm2Sp9aCP537+BCA='
'sha256-ncTH9jyLor0RXzz2qH5UZEOpKBNwPyO/SrZW+vrYkA8=' 'sha384-e0qFAVkArN1dyymxMH35JdOyqaonxrxODNFAvMxThOhlG4XGCjfW92Y8GQmud8hK'
'sha384-eEQWQilDnDtUa8WKud8RTuw5eAoUbvrfoBjxyn1emDfDHoh8qXFpmy8IeP+2voml';
font-src 'self'; object-src 'none'; img-src 'self' data:; style-src 'self'
'unsafe-inline'; connect-src 'self' wss://*.dcrdata.org; manifest-src 'self';
frame-ancestors 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Mon, 08 Jun 2020 11:41:46 GMT
Referrer-Policy:
- same-origin
Server:
- nginx
Set-Cookie:
- GCLB=CPbn_86Ksuu3zAE; path=/; HttpOnly
Strict-Transport-Security:
- max-age=15552001
Vary:
- Origin
Via:
- 1.1 google
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-XSS-Protection:
- 1; mode=block
status:
code: 200
message: OK
version: 1
74 changes: 74 additions & 0 deletions blockapi/test/api/cassettes/TestDcrdataAPI.test_get_tx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- python-requests/2.23.0
method: GET
uri: https://explorer.dcrdata.org/api/tx/193b59d8926588181aad5a5bed672e1fccf443f4d05dc16a0cdaacf3b4b4ed7c?spends=true
response:
body:
string: !!binary |
H4sIAAAAAAAAA81VTW8bNxC991cYexaM4fDbN0eR6tip68ZNkDYIgiE5tBaOJUcrKVIM/ffOSlYK
1D0Y6aW6SLskZ96b9/j00CzWbWlOGhV1srGEiM6GoIIiKpZs4uI8sqo5V2N0NQVsycoR5EKUq04m
GS4+N4Oma79xc4IWB82K5107mzYnatB8nuXbRXsnSzBoeH3fzje7n6tW1j88HACY6qstUpsRrSOf
tcnSKDvH2mO1ynHyoEpxkGRBUdVWKwxUyPuQvABYzZaLXenFnPftOv6y5GmWB4PRRKES7aChu9ly
uujb66CPVdDRoQ6DJvVQJ9zeTKSM0YAKH1+208LrHZsuz9v7xXV705w8NNTdCXINxgKiAkhFQTEB
kMkZFbOPSifyxQVPKaakFehoM7EP5BUl9kkB2Zq8Y5RFqQJGMCJizlmkiJGUrsrFkBi59mNxGarV
2Rsj9b1TLE1qqFkFNM5zBHUEaGV8jgwiSy0ZmlRjnTByKUA+BquLHI9Bi1rB5ZKgCsRiGDMHApBh
TnrCjQn/N3aC5L/T224/HuwiDlzR52Xv3BiO5bDam2G6N+nByHCQ/mqZLnjzt/q/Xn16+fbqSL7O
Tq/PlIOjYpQSfla7YJyARhJy3kQoGiz3/tbiYgr9mdFvb09fvxu9eTX+o38cno2GF9evfv4+f+8o
KvPciiFQfxHn/EUM2u38utjcC7XmfplueTOhbiLrVMqcu45lx4fmZXd7PjKzOv5zQ+PL4dVw2r5b
/b4J9fJ8PX7zbf2VXPNxK+zveVp62rsi4gzjhGyNCD5yhQomyritqGdCDpQoZNmgUWySfNCBaxYT
iNClkkhgm10CfHq8WbDdDr4LEcyx9navgfoxDUwqkgshivEM9MkltxzFWyVaw9qw672oSnq+Bs+t
+GMavF/oCavTePECl6/Vjf7lfJVO0/vRCzVcX+L8cvyvGsTqnRYdktKmSJYlBslkKuIG8FyoilEk
02swoUCK3tSQLXgvQmStdXmigdyKPJvWdn5HCxm5gEMHeIjGvvM+I/ft4cknkACJIctQUOJb0qGa
/mI6waky1eoLxmoNJLRQm6eR6xCeRO7+z0NZMRGgd+5xwz9fb7c//QUwvECTzgYAAA==
headers:
Alt-Svc:
- clear
Content-Encoding:
- gzip
Content-Security-Policy-Report-Only:
- default-src 'self'; script-src 'self' 'sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb'
'sha256-8in1YfOPOMqtBgRhX5uaoR+Gb7WGEjhl6XqBqFHsTjI=' 'sha256-967sY4EvCS9bV1jFWgKgDeLOvpSpm2Sp9aCP537+BCA='
'sha256-ncTH9jyLor0RXzz2qH5UZEOpKBNwPyO/SrZW+vrYkA8=' 'sha384-e0qFAVkArN1dyymxMH35JdOyqaonxrxODNFAvMxThOhlG4XGCjfW92Y8GQmud8hK'
'sha384-eEQWQilDnDtUa8WKud8RTuw5eAoUbvrfoBjxyn1emDfDHoh8qXFpmy8IeP+2voml';
font-src 'self'; object-src 'none'; img-src 'self' data:; style-src 'self'
'unsafe-inline'; connect-src 'self' wss://*.dcrdata.org; manifest-src 'self';
frame-ancestors 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Mon, 08 Jun 2020 13:42:58 GMT
Referrer-Policy:
- same-origin
Server:
- nginx
Set-Cookie:
- GCLB=CMXAx6ObyODqFg; path=/; HttpOnly
Strict-Transport-Security:
- max-age=15552001
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
- Origin
Via:
- 1.1 google
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-XSS-Protection:
- 1; mode=block
status:
code: 200
message: OK
version: 1
83 changes: 83 additions & 0 deletions blockapi/test/api/cassettes/TestDcrdataAPI.test_get_txs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- python-requests/2.23.0
method: GET
uri: https://explorer.dcrdata.org/api/address/DsXt3he1A9KB2uL1g3MJvbAbXEB1CxN2rNF/count/2/skip/0/raw
response:
body:
string: !!binary |
H4sIAAAAAAAAA81X204cRxB9z1dY84xQVXX1jTfuGLCzNgKTWCjqSzW7xtx2Fwuw+PfUgMGxHSdr
nEjwAMzsTlfX6VPnnHn7sZuMrqVbIEtz3fRyVLuFLjbvDDvMaLiaYLJAKi1VUyt4qalRolhDCxwq
5Oi5hWLBezJYjDG1m+s+yHgyOj3pFnCue39ajqajYy0C+sFIb779eF8Ko8lW14rkbAgYMKVqk81S
nSfBVkpjNo0r2FrQJSg16V5M5sxSfelLnV5Mb+tMx3JXIx2fXpxM+0KB5423Ya7L/SaGMjoc6nfZ
gCP4dHN0UuXy9vlJGY/Opjujw27hY5cmx7o9A2yBCAEkWSvZpYS1xuZAGjcPujnbqkTrEKsp3HKq
zdgMwE0QmGwuLbZsSFdRhICaWKNdNEdNe9XrkgJxkQJJWqxk2YpvNnOpWpxcYeakhagmBnwGWgR1
wWZJMSCXULwJoXlJUq1IvzESVymFiBGKR5QcY+UATlIsJipiw77hjsNT60538vPt3cx1Z2P58GtP
Cj3GWscymchESdetTPanZii4GLeW6GIbD82LzQ95Me+vLuHy5Usav1zrDpRQ6f2FPHBH15vI+YWc
FL3HFDkqM6O9ObhnnpL5/gkzr1Q7ueP5/QDAPbEGF3lLrj5z69fBHyu7g2f6Z2NxZwMdPGuAoBPG
CSk7L5wKoYCNklwJhaQ4iy6Y1j+z+mp3cXtv9fXztd/6y+WN1eWtnefrD6frXYrIs64YQupHaSzn
Sv/J3TRdnWlL3dlFPpKrYZoM9fOv0DwZr50era1MGg2uNncOeaOuDXlbwsXy9HzTn19jd3BzM/cA
D8xbb71nf4sRPg6jFFMtxfvolEghlOiglWhjQGszOtOcNsQpz47RrCs+DqPDHTvNu3uTVy348eXe
0puj/bOdF5t7e+VsOJi8HMUeI+VSOT1po/Fxmiog/eJGZ+FetvqFFzr4+ieH3Niyjm5iZyA4n2vE
QJh7rY4p99ocsq9CnqAf/DsVRhu8i8Y496nA17f7M7tzBUb34Aq5CDuFIavsR5/IqiZggkSFrGvk
deybNSHpf44zep3Q5hTZHK2PXuIPuEIUj5KMTcET669K6gWiMqBGE4ECZxOyMyaq9KDKFNpqMlQx
Kkuo7vEvrsBxPn5jCSYyzmgJ3MudeqMvxid1sIYtFesy+8xVghpVIyxggsqnRxBFyYQqAgWLZa/X
qCTrJVP1U8GrKaqcWgFsEPSLRbmosLIiTSW2qvAlNUHHzYm6sQct25oJ7j82BP+0entadtCT5nte
MPfAXCoQkpZvmZSU2qnKSwZNNCGFJsn3pku5UQxSIbWkrstOdZhrrTp5n5kLf59nYF6ji3cevyUw
OIgzEviT65eosKkX21oxZQuqGjbouJYQQcWErdet6cmZAHoAlU1SHqgiOvBq3JhvjxkyZq/bB47C
lMlaG6QkCH2sI2VBEWGj2U1PJYZgM4FGDDAaHlwo/2OmeRrdPS0S/4U/P5BrjD7F6iGW4s/EGwEI
Rk+HjRov2UasfuVIZ4CMzo2zJut7gKmzW/esKz7Ouo8Hu4c7V0fr6/uTrfW0OzxZmgi/4zq4Nq/P
V/fT3pfxJqpA0M9EG7VsMd60qFAHRCOFIiJVTdWoPNF8ki0qv2fHZ9YVH4fPm5XpyK1fn4ffX22/
KVfJLXO+ajw4D+/2dsri6Pg70YYt0j9HG30xQGLvNDPpvGkPtRgBY4mo6dtJjpxFs4XRKw0gQF9E
G/IWIn8Tbe5u3xz88ifb5nWK8w4AAA==
headers:
Alt-Svc:
- clear
Content-Encoding:
- gzip
Content-Security-Policy-Report-Only:
- default-src 'self'; script-src 'self' 'sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb'
'sha256-8in1YfOPOMqtBgRhX5uaoR+Gb7WGEjhl6XqBqFHsTjI=' 'sha256-967sY4EvCS9bV1jFWgKgDeLOvpSpm2Sp9aCP537+BCA='
'sha256-ncTH9jyLor0RXzz2qH5UZEOpKBNwPyO/SrZW+vrYkA8=' 'sha384-e0qFAVkArN1dyymxMH35JdOyqaonxrxODNFAvMxThOhlG4XGCjfW92Y8GQmud8hK'
'sha384-eEQWQilDnDtUa8WKud8RTuw5eAoUbvrfoBjxyn1emDfDHoh8qXFpmy8IeP+2voml';
font-src 'self'; object-src 'none'; img-src 'self' data:; style-src 'self'
'unsafe-inline'; connect-src 'self' wss://*.dcrdata.org; manifest-src 'self';
frame-ancestors 'none'
Content-Type:
- application/json; charset=utf-8
Date:
- Mon, 08 Jun 2020 12:01:12 GMT
Referrer-Policy:
- same-origin
Server:
- nginx
Set-Cookie:
- GCLB=CKb55uHG9bv_DA; path=/; HttpOnly
Strict-Transport-Security:
- max-age=15552001
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
- Origin
Via:
- 1.1 google
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-XSS-Protection:
- 1; mode=block
status:
code: 200
message: OK
version: 1
15 changes: 7 additions & 8 deletions blockapi/test/api/test_cosmos.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from pytest import mark, raises

from blockapi.api.cosmos import CosmosAPI
from blockapi.services import InternalServerError, AddressNotExist
Expand All @@ -12,7 +12,6 @@ class TestCosmosAPI:

def test_init(self):
api = CosmosAPI(address=self.ADDRESS)

assert api

def test_process_error_response(self):
Expand All @@ -21,15 +20,15 @@ def test_process_error_response(self):
response.text = "Error"
response.status_code = 500

with pytest.raises(InternalServerError):
with raises(InternalServerError):
CosmosAPI(address=self.ADDRESS).process_error_response(response)

response.text = "Error decoding bech32 failed"

with pytest.raises(AddressNotExist):
with raises(AddressNotExist):
CosmosAPI(address=self.ADDRESS).process_error_response(response)

@pytest.mark.vcr()
@mark.vcr()
def test_get_info(self):
api = CosmosAPI(address=self.ADDRESS)
result = api.get_info()
Expand All @@ -44,22 +43,22 @@ def test_get_info(self):
assert "account_number" in result["result"]["value"]
assert "sequence" in result["result"]["value"]

@pytest.mark.vcr()
@mark.vcr()
def test_get_balance(self):
api = CosmosAPI(address=self.ADDRESS)
result = api.get_balance()

assert result["balances"] == [{"symbol": "ATOM", "amount": 0.005959}]
assert "height" in result

@pytest.mark.vcr()
@mark.vcr()
def test_get_incoming_txs(self):
api = CosmosAPI(address=self.ADDRESS)
api.get_incoming_txs()

# TODO: provider is no sending correct data

@pytest.mark.vcr()
@mark.vcr()
def test_get_outgoing_txs(self):
api = CosmosAPI(address=self.ADDRESS)
api.get_outgoing_txs()
Expand Down
Loading