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
6 changes: 5 additions & 1 deletion blockfrost/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def root(self, **kwargs):
block_epoch_slot, \
blocks_next, \
blocks_previous, \
block_transactions
block_transactions, \
blocks_addresses
from .cardano.epochs import \
epoch_latest, \
epoch_latest_parameters, \
Expand All @@ -96,6 +97,7 @@ def root(self, **kwargs):
network
from .cardano.pools import \
pools, \
pools_extended, \
pools_retired, \
pools_retiring, \
pool, \
Expand Down Expand Up @@ -125,3 +127,5 @@ def root(self, **kwargs):
script_cbor, \
script_redeemers, \
script_datum
from .cardano.utils import \
utils_addresses_xpub
29 changes: 29 additions & 0 deletions blockfrost/api/cardano/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,32 @@ def block_transactions(self, hash_or_number: str, **kwargs):
params=self.query_parameters(kwargs),
headers=self.default_headers
)


@list_request_wrapper
def blocks_addresses(self, hash_or_number: str, **kwargs):
"""
Return list of addresses affected in the specified block with additional information, sorted by the bech32 address, ascending.

https://docs.blockfrost.io/#tag/Cardano-Blocks/paths/~1blocks~1{hash_or_number}~1addresses/get

:param hash_or_number: Hash or number of the requested block.
:type hash_or_number: str
:param return_type: Optional. "object", "json" or "pandas". Default: "object".
:type return_type: str
:param gather_pages: Optional. Default: false. Will collect all pages into one return
:type gather_pages: bool
:param count: Optional. Default: 100. The number of results displayed on one page.
:type count: int
:param page: Optional. The page number for listing the results.
:type page: int
:returns A list of objects.
:rtype [Namespace]
:raises ApiError: If API fails
:raises Exception: If the API response is somehow malformed.
"""
return requests.get(
url=f"{self.url}/blocks/{hash_or_number}/addresses",
params=self.query_parameters(kwargs),
headers=self.default_headers
)
27 changes: 27 additions & 0 deletions blockfrost/api/cardano/pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,33 @@ def pools(self, **kwargs):
)


@list_request_wrapper
def pools_extended(self, **kwargs):
"""
List of registered stake pools with additional information.

https://docs.blockfrost.io/#tag/Cardano-Pools/paths/~1pools~1extended/get

:param gather_pages: Optional. Default: false. Will collect all pages into one return
:type gather_pages: bool
:param count: Optional. Default: 100. The number of results displayed on one page.
:type count: int
:param page: Optional. The page number for listing the results.
:type page: int
:param order: Optional. "asc" or "desc". Default: "asc".
:type order: str
:returns A list of objects.
:rtype [Namespace]
:raises ApiError: If API fails
:raises Exception: If the API response is somehow malformed.
"""
return requests.get(
url=f"{self.url}/pools/extended",
params=self.query_parameters(kwargs),
headers=self.default_headers
)


@list_request_wrapper
def pools_retired(self, **kwargs):
"""
Expand Down
37 changes: 37 additions & 0 deletions blockfrost/api/cardano/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import requests
from blockfrost.utils import request_wrapper, list_request_wrapper


@list_request_wrapper
def utils_addresses_xpub(self, xpub: str, role: int, index: int, **kwargs):
"""
Derive Shelley address from an xpub

https://docs.blockfrost.io/#tag/Cardano-Utilities/paths/~1utils~1addresses~1xpub~1{xpub}~1{role}~1{index}/get

:param xpub: Hex xpub.
:type xpub: str
:param role: Account role.
:type role: int
:param index: Address index.
:type index: int
:param return_type: Optional. "object", "json" or "pandas". Default: "object".
:type return_type: str
:param gather_pages: Optional. Default: false. Will collect all pages into one return
:type gather_pages: bool
:param count: Optional. Default: 100. The number of results displayed on one page.
:type count: int
:param page: Optional. The page number for listing the results.
:type page: int
:param order: Optional. "asc" or "desc". Default: "asc".
:type order: str
:returns A list of objects.
:rtype [Namespace]
:raises ApiError: If API fails
:raises Exception: If the API response is somehow malformed.
"""
return requests.get(
url=f"{self.url}/utils/addresses/xpub/{xpub}/{role}/{index}",
params=self.query_parameters(kwargs),
headers=self.default_headers
)
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

setup(
name='blockfrost-python',
version='0.4.0',
description='The official Python SDK for Blockfrost API v0.1.33',
version='0.4.1',
description='The official Python SDK for Blockfrost API v0.1.35',
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/blockfrost/blockfrost-python',
Expand Down
2 changes: 0 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,3 @@ def test_integration_root():
def test_integration_root():
if os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'):
assert True
else:
assert False
2 changes: 1 addition & 1 deletion tests/test_cardano_addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def test_address_utxos(requests_mock):
def test_integration_address_utxos():
if os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'):
api = BlockFrostApi(project_id=os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'))
assert api.address_utxos(address=address)
assert api.address_utxos(address=address) == []


def test_address_utxos_asset(requests_mock):
Expand Down
30 changes: 30 additions & 0 deletions tests/test_cardano_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,33 @@ def test_integration_block_transactions():
if os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'):
api = BlockFrostApi(project_id=os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'))
assert api.block_transactions(hash_or_number=hash)


def test_blocks_blocks_addresses(requests_mock):
api = BlockFrostApi()
mock_data = [
{
"address": "addr1q9ld26v2lv8wvrxxmvg90pn8n8n5k6tdst06q2s856rwmvnueldzuuqmnsye359fqrk8hwvenjnqultn7djtrlft7jnq7dy7wv",
"transactions": [
{
"tx_hash": "1a0570af966fb355a7160e4f82d5a80b8681b7955f5d44bec0dce628516157f0"
}
]
},
{
"address": "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz",
"transactions": [
{
"tx_hash": "1a0570af966fb355a7160e4f82d5a80b8681b7955f5d44bec0dce628516157d0"
}
]
}
]
requests_mock.get(f"{api.url}/blocks/{hash}/addresses", json=mock_data)
assert api.blocks_addresses(hash_or_number=hash) == convert_json_to_object(mock_data)


def test_integration_blocks_addresses():
if os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'):
api = BlockFrostApi(project_id=os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'))
assert api.blocks_addresses(hash_or_number=hash)
29 changes: 29 additions & 0 deletions tests/test_cardano_pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,35 @@ def test_integration_pools():
assert api.pools()


def test_pools_extended(requests_mock):
api = BlockFrostApi()
mock_data = [
{
"pool_id": "pool19u64770wqp6s95gkajc8udheske5e6ljmpq33awxk326zjaza0q",
"active_stake": "1541200000",
"live_stake": "1541400000"
},
{
"pool_id": "pool1dvla4zq98hpvacv20snndupjrqhuc79zl6gjap565nku6et5zdx",
"active_stake": "22200000",
"live_stake": "48955550"
},
{
"pool_id": "pool1wvccajt4eugjtf3k0ja3exjqdj7t8egsujwhcw4tzj4rzsxzw5w",
"active_stake": "9989541215",
"live_stake": "168445464878"
}
]
requests_mock.get(f"{api.url}/pools/extended", json=mock_data)
assert api.pools_extended() == convert_json_to_object(mock_data)


def test_integration_pools_extended():
if os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'):
api = BlockFrostApi(project_id=os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'))
assert api.pools_extended()


def test_pools_retired(requests_mock):
api = BlockFrostApi()
mock_data = [
Expand Down
27 changes: 27 additions & 0 deletions tests/test_cardano_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os, json
from blockfrost import BlockFrostApi, ApiError
from blockfrost.utils import convert_json_to_object

xpub = "d507c8f866691bd96e131334c355188b1a1d0b2fa0ab11545075aab332d77d9eb19657ad13ee581b56b0f8d744d66ca356b93d42fe176b3de007d53e9c4c4e7a"
role = 0
index = 0


def test_utils_addresses_xpub(requests_mock):
api = BlockFrostApi()
mock_data = [
{
"xpub": "d507c8f866691bd96e131334c355188b1a1d0b2fa0ab11545075aab332d77d9eb19657ad13ee581b56b0f8d744d66ca356b93d42fe176b3de007d53e9c4c4e7a",
"role": 0,
"index": 0,
"address": "addr1q90sqnljxky88s0jsnps48jd872p7znzwym0jpzqnax6qs5nfrlkaatu28n0qzmqh7f2cpksxhpc9jefx3wrl0a2wu8q5amen7"
}
]
requests_mock.get(f"{api.url}/utils/addresses/xpub/{xpub}/{role}/{index}", json=mock_data)
assert api.utils_addresses_xpub(xpub, role, index) == convert_json_to_object(mock_data)


def test_integration_utils_addresses_xpub():
if os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'):
api = BlockFrostApi(project_id=os.getenv('BLOCKFROST_PROJECT_ID_MAINNET'))
assert api.utils_addresses_xpub(xpub, role, index)