chmod77 / dfuse-python

Python bindings for https://dfuse.io
MIT License
9 stars 1 forks source link
dfuse dfusepython eosio

dfuse is an open source library written in Python providing an easy to use wrapper around the dfuse.io API. This library has been tested with Python 3.6.x, 3.7.x, 3.8.x and 3.9.x.

Installation

From source use:

$ python setup.py install

or install from PyPi:

$ pipenv install dfuse

Prerequisites

To get up and rolling, create a .env or .ini file in the project folder, with contents copied from the example.env file. (as required by python decouple)

Make sure to substitute the predefined keys with the appropriate ones.

API_KEY = YOUR_API_KEY_HERE

EOS_BASE_URL = https://eos.dfuse.eosnation.io OR any of the REST Endpoints below

EOS_BLOCK_TIME_URL = /v0/block_id/by_time

EOS_TRX_URL = /v0/transactions

EOS_STATE_BASE_URL = /v0/state

*ENSURE NO trailing slash at the end of the BASE_URL**

Supported list of EOSIO Networks (Endpoints):

  1. EOS Mainnet

    Chain ID: aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906

    REST Endpoint: https://eos.dfuse.eosnation.io/

    Websocket: wss://eos.dfuse.eosnation.io/v1/stream

  2. EOSIO Testnet

    Chain ID: 0db13ab9b321c37c0ba8481cb4681c2788b622c3abfd1f12f0e5353d44ba6e72

    REST: https://testnet.eos.dfuse.io/

    Websocket: wss://testnet.eos.dfuse.io/v1/stream

    GraphQL: https://testnet.eos.dfuse.io/graphql

  3. CryptoKylin

    Chain ID: 5fff1dae8dc8e2fc4d5b23b2c7665c97f9e9d8edf2b6485a86ba311c25639191

    REST https://kylin.eos.dfuse.io/

    WebSocket wss://kylin.eos.dfuse.io/v1/stream

    GraphQL https://kylin.eos.dfuse.io/graphql

  4. WAX Mainnet

    Chain ID: 1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4

    REST https://mainnet.wax.dfuse.io/

    WebSocket wss://mainnet.wax.dfuse.io/v1/stream

    GraphQL https://mainnet.wax.dfuse.io/graphql

Use the REST endpoint values as your EOS_BASE_URL

You can also define these values as environment variables.

If the dfuse API is upgraded to another version, say v1, it is easier to switch to that with minimal changes. You only edit your .env file to match the changes.

JWT Caching

Short-time lived JWT Tokens are persisted on a local sqlite3 database, and are usable for upto 22 hours.

Example

An example Django + DRF example is on https://github.com/chmod77/dfuse-example

API Documentation:

This API can currently retrieve the following data from dfuse.io:

GET /v0/block_id/by_time/by_time?time=2019-03-04T10:36:14.5Z&comparator=gte

<dfuse.eosio.types.BlockTimeStampType at 0x7fcfc746abb0>

obj.data

{ 'block': { 'id': '095227fa85998bfefb6c474be42d8d6f1e890f152c7047570b8ababa73c12783', 'num': 156379130, 'time': '2020-12-07T10:37:15.5Z' } }


#### **`GET /v0/transactions/:id`**
- **`Description`**  

    Fetches the transaction lifecycle associated with the provided path parameter ```:id```.

- **`Types`** 

    - ```id``` - string

- **`Optional parameters:`**
    - None

```python
>>> from dfuse import Eosio
>>> eosio = Eosio()
>>> obj = eosio.get_transaction_lifecycle(id='1d5f57e9392d045ef4d1d19e6976803f06741e11089855b94efcdb42a1a41253')

>>> obj

   <dfuse.eosio.types.TransactionLifecycle at 0x7fcfc747c3d0>

>>> obj.data

    {
        'transaction_status': 'executed',
        'id': '1d5f57e9392d045ef4d1d19e6976803f06741e11089855b94efcdb42a1a41253',
        'transaction': {'expiration': '2019-04-16T14:36:11',
        'ref_block_num': 65222,
        'ref_block_prefix': 943310534,
        'max_net_usage_words': 0,
        'max_cpu_usage_ms': 0,
        'delay_sec': 0,
        'context_free_actions': [],
        'actions': [{
            'account': 'maouehmaoueh',
            'name': 'cfainline',
            'authorization': [{'actor': 'maouehmaoueh', 'permission': 'active'}],
            'hex_data': '03313233'}],
        'transaction_extensions': [],
        'signatures': ['SIG_K1_Jyv32XzrAGQepnk7p3YwXbRyNcp6Cztt8peR41GjfJ5hjDhjNfyf4ViubcShaDGd1BB9NEKGRrGjsQadzvwKrp7Wkjx9kh'],
        'context_free_data': []},
        'execution_trace': {'id': '1d5f57e9392d045ef4d1d19e6976803f06741e11089855b94efcdb42a1a41253',
        'block_num': 53280461,
        'block_time': '2019-04-16T14:35:41.5',
        'producer_block_id': '032cfecd63f2e42da2fb5b7f632acadbe5153756db615c5d28bbc99f9bd0976d',
        'receipt': {'status': 'executed',
        'cpu_usage_us': 1191,
        'net_usage_words': 12},
        'elapsed': 71934,
        'net_usage': 96,
        'scheduled': False,
        'action_traces': [{'receipt': {'receiver': 'maouehmaoueh',
            'act_digest': '5a2ffd1d0376049b5fcaa7d5f122723973c8fea40de9aba059bc439b4f77fd5e',
            'global_sequence': '6249291689',
            'auth_sequence': [['maouehmaoueh', 13]],
            'recv_sequence': 5,
            'code_sequence': 2,
            'abi_sequence': 1},
            'act': {'account': 'maouehmaoueh',
            'name': 'cfainline',
            'authorization': [{'actor': 'maouehmaoueh', 'permission': 'active'}],
            'data': {'data': '123'},
            'hex_data': '03313233'},
            'context_free': False,
            'elapsed': 71857,
            'console': '',
            'trx_id': '1d5f57e9392d045ef4d1d19e6976803f06741e11089855b94efcdb42a1a41253',
            'block_num': 53280461,
            'block_time': '2019-04-16T14:35:41.5',
            'producer_block_id': '032cfecd63f2e42da2fb5b7f632acadbe5153756db615c5d28bbc99f9bd0976d',
            'account_ram_deltas': None,
            'except': None,
            'inline_traces': [{'receipt': {'receiver': 'dfuseiohooks',
            'act_digest': '469d68d4e68c0adc6fd302ca60b4d27256400965b90baf7a5736c9e0ed0b3d0f',
            'global_sequence': '6249291690',
            'auth_sequence': [],
            'recv_sequence': 2,
            'code_sequence': 0,
            'abi_sequence': 1},
            'act': {'account': 'dfuseiohooks',
            'name': 'event',
            'data': {'data': 'testing=123', 'key': ''},
            'hex_data': '000b74657374696e673d313233'},
            'context_free': True,
            'elapsed': 11,
            'console': '',
            'trx_id': '1d5f57e9392d045ef4d1d19e6976803f06741e11089855b94efcdb42a1a41253',
            'block_num': 53280461,
            'block_time': '2019-04-16T14:35:41.5',
            'producer_block_id': '032cfecd63f2e42da2fb5b7f632acadbe5153756db615c5d28bbc99f9bd0976d',
            'account_ram_deltas': None,
            'except': None,
            'inline_traces': None}]}],
        'failed_dtrx_trace': None,
        'except': None},
        'execution_block_header': {'timestamp': '2019-04-16T14:35:41.5',
        'producer': 'bitfinexeos1',
        'confirmed': 0,
        'previous': '032cfeccf3b57dd793d3ff831adb381225fa7c2b4a998a3c16502c2774581e36',
        'transaction_mroot': 'a4317c9ce3c3925fac8bda2463a06d5b5876b37ea4b0b2af36bb42d028910a66',
        'action_mroot': '16187708fc3827f31d2fbe8ecf6c1877e2b5f0050e63f025edd01eeff4dec82f',
        'schedule_version': 773,
        'new_producers': None,
        'header_extensions': []},
        'dtrxops': None,
        'creation_tree': [],
        'dbops': None,
        'ramops': None,
        'tableops': None,
        'pub_keys': ['EOS8b3K9r6mLDykeL7GzGJCFt9Z5SRSHSXFT77yHz8e3z7en1tFwG'],
        'created_by': None,
        'canceled_by': None,
        'execution_irreversible': True,
        'creation_irreversible': True,
        'cancelation_irreversible': False
    }

 >>> obj.transaction_status

    'executed'

GET /v0/state/abi?account={account}&json={true/false}&block_num=int

>>> from dfuse import Eosio
>>> eosio = Eosio()
>>> obj = eosio.fetch_abi(account='arbarotokenn', block_num=57202657)

>>> obj

    <dfuse.eosio.types.ABIType at 0x7f54dc041828>

>>> obj.data

    {'block_num': 57202658,
    'account': 'arbarotokenn',
    'abi': {'version': 'eosio::abi/1.1',
    'structs': [{'name': 'account',
        'base': '',
        'fields': [{'name': 'balance', 'type': 'asset'},
        {'name': 'lastclaim', 'type': 'asset'}]},
    {'name': 'claim',
        'base': '',
        'fields': [{'name': 'owner', 'type': 'name'},
        {'name': 'tokensym', 'type': 'symbol'}]},
    {'name': 'close',
        'base': '',
        'fields': [{'name': 'owner', 'type': 'name'},
        {'name': 'symbol', 'type': 'symbol'}]},
    {'name': 'create',
        'base': '',
        'fields': [{'name': 'issuer', 'type': 'name'},
        {'name': 'maximum_supply', 'type': 'asset'}]},
    {'name': 'currency_stats',
        'base': '',
        'fields': [{'name': 'supply', 'type': 'asset'},
        {'name': 'max_supply', 'type': 'asset'},
        {'name': 'issuer', 'type': 'name'},
        {'name': 'totaldividends', 'type': 'asset'}]},
    {'name': 'issue',
        'base': '',
        'fields': [{'name': 'to', 'type': 'name'},
        {'name': 'quantity', 'type': 'asset'},
        {'name': 'memo', 'type': 'string'}]},
    {'name': 'open',
        'base': '',
        'fields': [{'name': 'owner', 'type': 'name'},
        {'name': 'symbol', 'type': 'symbol'},
        {'name': 'ram_payer', 'type': 'name'}]},
    {'name': 'retire',
        'base': '',
        'fields': [{'name': 'quantity', 'type': 'asset'},
        {'name': 'memo', 'type': 'string'}]},
    {'name': 'transfer',
        'base': '',
        'fields': [{'name': 'from', 'type': 'name'},
        {'name': 'to', 'type': 'name'},
        {'name': 'quantity', 'type': 'asset'},
        {'name': 'memo', 'type': 'string'}]}],
    'actions': [{'name': 'claim', 'type': 'claim', 'ricardian_contract': ''},
    {'name': 'close', 'type': 'close', 'ricardian_contract': ''},
    {'name': 'create', 'type': 'create', 'ricardian_contract': ''},
    {'name': 'issue', 'type': 'issue', 'ricardian_contract': ''},
    {'name': 'open', 'type': 'open', 'ricardian_contract': ''},
    {'name': 'retire', 'type': 'retire', 'ricardian_contract': ''},
    {'name': 'transfer', 'type': 'transfer', 'ricardian_contract': ''}],
    'tables': [{'name': 'accounts', 'index_type': 'i64', 'type': 'account'},
    {'name': 'stat', 'index_type': 'i64', 'type': 'currency_stats'}]}}

POST /v0/state/abi/bin_to_json

>>> from dfuse import Eosio
>>> eosio = Eosio()
>>> obj = eosio.bin_to_json(account='eosio.token', table='accounts',  hex_rows=["aa2c0b010000000004454f5300000000"], block_num=2600000)

>>> obj

    <dfuse.eosio.types.Bin2JSONType at 0x7f54c4763908>

>>> obj.data

    {
        'block_num': 181,
        'account': 'eosio.token',
        'table': 'accounts',
        'rows': [
            {
                'balance': '1750.9546 EOS'
            }
        ]
    }

>>> obj.account

    'eosio.token'

>>> obj.block_num

    181

GET /v0/state/key_accounts


>>> from dfuse import Eosio
>>> eosio = Eosio()
>>> obj = eosio.get_key_accounts(public_key='EOS744heXNxjLamUjLxaLpn6gREh3CVf5VvFESq9sG969VmcNYyq6')

>>> obj

    <dfuse.eosio.types.KeyAccountsType at 0x7f54c7169be0>

>>> obj.data

    {'block_num': 76752386, 'account_names': ['greenunicorn']}

>>> obj.block_num

    76752386

>>> obj.account_names

    ['greenunicorn']

GET /v0/state/permission_links

>>> from dfuse import Eosio
>>> eosio = Eosio()
>>> obj = eosio.get_permission_links(account='eoscanadacom', block_num=25000000)  

>>> obj

   <dfuse.eosio.types.PermissionLinkType at 0x7f54c7501c50>

>>> obj.data

    {'last_irreversible_block_id': '04931d68265c1fba52f772e031e67d2f16d898ed0ee0c60384db163345e7d0f1',
    'last_irreversible_block_num': 76750184,
    'linked_permissions': [{'contract': 'eosforumdapp',
    'action': 'post',
    'permission_name': 'day2day'},
    {'contract': 'eosforumdapp',
    'action': 'status',
    'permission_name': 'day2day'},
    {'contract': 'eosforumdapp',
    'action': 'unpost',
    'permission_name': 'day2day'},
    {'contract': 'eosio',
    'action': 'claimrewards',
    'permission_name': 'claimer'},
    {'contract': 'eosio', 'action': 'regproducer', 'permission_name': 'day2day'},
    {'contract': 'eosio', 'action': 'unregprod', 'permission_name': 'day2day'},
    {'contract': 'theblacklist',
    'action': 'sethash',
    'permission_name': 'blacklistops'}]}

>>> obj.last_irreversible_block_id

    '04931d68265c1fba52f772e031e67d2f16d898ed0ee0c60384db163345e7d0f1'

>>> obj.last_irreversible_block_num 

    76750184

GET/v0/state/table


>>> from dfuse import Eosio
>>> eosio = Eosio()
>>> obj = eosio.get_table(account='eosio.token', scope='greenunicorn', table='accounts', block_num=74000000) 

>>> obj

    <dfuse.eosio.types.StateType at 0x7f54c711f908>

>>> obj.data

    {'last_irreversible_block_id': '04932bcb8edd41317814654da379057d6a2f880aaf2e095a602b997eedc5c143',
        'last_irreversible_block_num': 76753867,
        'rows': [{'key': '........ehbo5',
        'payer': 'greenunicorn',
        'json': {'balance': '0.7585 EOS'}}
        ]
    }

>>> obj.obj.last_irreversible_block_id

    '04932bcb8edd41317814654da379057d6a2f880aaf2e095a602b997eedc5c143'

GET /v0/state/tables/accounts


>>> from dfuse import Eosio

>>> eosio = Eosio()

>>> obj = df.get_table_accounts(accounts="eosadddddddd|tokenbyeocat|ethsidechain|epraofficial|alibabapoole|hirevibeshvt|oo1122334455|irespotokens|publytoken11|parslseed123|trybenetwork|zkstokensr4u", scope="b1", table="accounts", block_num=45000000, json="true")

>>> obj

    <dfuse.eosio.types.MultiStateType at 0x7fe61111d820>

>>> obj.data

      {'last_irreversible_block_id': '',
        'last_irreversible_block_num': 0,
        'tables': [{'account': 'tokenbyeocat', 'scope': 'b1', 'rows': []},
        {'account': 'irespotokens', 'scope': 'b1', 'rows': []},
        {'account': 'parslseed123', 'scope': 'b1', 'rows': []},
        {'account': 'trybenetwork', 'scope': 'b1', 'rows': []},
        {'account': 'ethsidechain',
        'scope': 'b1',
        'rows': [{'key': '......2cel2o5',
            'payer': 'eos1kissgirl',
            'json': {'balance': '2000.0001 EETH'}}]},
        {'account': 'oo1122334455',
        'scope': 'b1',
   'rows': [{'key': '......2ndxc4d',
     'payer': 'guztemzzgyge',
     'json': {'balance': '4550.0000 IPOS'}}]},
     'tables': [{'account': 'tokenbyeocat', 'scope': 'b1', 'rows': []},
        {'account': 'irespotokens', 'scope': 'b1', 'rows': []},
        {'account': 'parslseed123', 'scope': 'b1', 'rows': []},
        {'account': 'trybenetwork', 'scope': 'b1', 'rows': []},
        {'account': 'ethsidechain',
        'scope': 'b1',
        'rows': [{'key': '......2cel2o5',
            'payer': 'eos1kissgirl',
            'json': {'balance': '2000.0001 EETH'}}]},
        {'account': 'oo1122334455',
        'scope': 'b1',
        'rows': [{'key': '......2ndxc4d',
            'payer': 'guztemzzgyge',
            'json': {'balance': '4550.0000 IPOS'}}]},

GET /v0/state/tables/scopes: Fetching snapshots of any table on the blockchain, at any block height, for a list of scopes for a given account (contract).

Buy me a coffee?

If you feel like buying me a coffee::

EOS : greenunicorn