Skip to content

plargohq/ubiquity-python-client

Repository files navigation

Ubiquity Python client

A Python client to the Ubiquity service of blockdaemon.com.

Requirements

Python 3.7.2 or newer.

Installation

To install in your global Python installation with pip, run the following from the repository's root:

$ pip install -e .

To install using a virtual environment called testenv:

$ python -m venv testenv
$ source testenv/bin/activate
$ pip install -r requirements.txt
$ pip install -e .

Testing

To run the test suite first install the test dependencies with pip then run pytest at the repository's root:

$ pip install -r test-requirements.txt
$ make test

Usage

Basic

import ubiquity
from ubiquity.api import blocks_api

conf = ubiquity.Configuration(
    access_token="<token>"
)

with ubiquity.ApiClient(conf) as client:
    blocks_api_instance = blocks_api.BlocksApi(client)
    platform = "ethereum"
    network = "mainnet"

    block = blocks_api_instance.get_block(platform, network, "current")

An API URL may also be specified if you have a personal Ubiquity endpoint:

import ubiquity
from ubiquity.api import blocks_api

conf = ubiquity.Configuration(
    host="<url>",
    access_token="<token>"
)

with ubiquity.ApiClient(conf) as client:
    blocks_api_instance = blocks_api.BlocksApi(client)
    platform = "ethereum"
    network = "mainnet"

    block = blocks_api_instance.get_block(platform, network, "current")

Paginated APIs

Certain resources contain more data than can be practically returned in a single request. In these resources the data is split across multiple responses where each response returns a subset of the items requested and a continuation token.

Requests for the first page of data should not contain a continuation token. To get the next batch of items, the continuation token should be passed with the subsequent request. If no continuation token is returned, all of the available data has been returned.

Initial request to paged APIs should not include a continuation. If no limit is supplied, the default of 25 will be applied.

import ubiquity
from ubiquity.api import transactions_api

conf = ubiquity.Configuration(
    host="url",
    access_token="token"
)

with ubiquity.ApiClient(conf) as client:
    platform = "bitcoin"
    network = "mainnet"

    txs_api_instance = transactions_api.TransactionsApi(client)

    order = "desc"
    limit = 10

    txPage1 = txs_api_instance.get_txs(platform, network, order=order, limit=limit);
    continuation = txPage1['continuation']

    txPage2 = txs_api_instance.get_txs(platform, network, order=order, limit=limit, continuation=continuation);

To continue through the pages of transactions, the continuation from the previous page must be supplied to the next request:

with ubiquity.ApiClient(conf) as client:
    platform = "bitcoin"
    network = "mainnet"

    txs_api_instance = transactions_api.TransactionsApi(client)

    order = "desc"
    limit = 10

    txPage1 = txs_api_instance.get_txs(platform, network, order=order, limit=limit);
    continuation = txPage1['continuation']

    txPage2 = txs_api_instance.get_txs(platform, network, order=order, limit=limit, continuation=continuation);

Working with transactions

Creating and signing transactions

Transactions can be created and signed directly from the SDK. Currently supported platforms are Bitcoin and Ethereum.

To create and sign a transaction that sends 0.0001 BTC (10000 satoshis) with a 0.00001 BTC (1000 satoshis) fee from an account to another:

import ubiquity.transaction as tx

key = "<key>"

from_ = [{
    "address": "<input transaction>",
    "index": 0
}]
to = [
    {
        "address": "<destination address>",
        "amount": 10000
    }
]
fee = 1000

platform = "bitcoin"
network = "testnet" # can be "mainnet" or "testnet"

signed_tx = tx.create_and_sign(from_, to, key, { "network": network, "platform": platform })

For Bitcoin an unsigned transaction can also be created with the function ubiquity.transaction.create.

To create and sign a transaction that sends 1 ETH and pays 21000 gas as fee from an account to another:

import ubiquity
import ubiquity.transaction as tx
from ubiquity.api import ApiClient

platform = "ethereum"
network = "ropsten" # can be "mainnet" or "testnet"

key = "<key>"

# Note: Ethereum transactions don't contain an input address
from_ = [{
    "index": 3 # nonce
}]
to = [{
    "address": "<destination address>",
    "amount": 10 ** 18 # 1 ETH in smallest possible units (wei)
}]
fee = 21000

api_client = ApiClient(ubiquity.Configuration(
    host="<url>",
    access_token="<token>"
))

# An ApiClient object has to be passed to create_and_sign
#   for Ethereum because the gas price needs to be
#   fetched from the ethereum network
signed_tx = tx.create_and_sign(from_, to, key, {
    "api_client": api_client,
    "platform": platform,
    "network": network,
    "fee": fee
})

api_client.close()
print('signed: ', signed_tx)

For Ethereum only transactions with a single output are currently supported.

Broadcasting signed transactions

After a transaction is created and signed, it can be broadcasted through Ubiquity's /tx/send endpoint, which is interfaced through the tx_send method:

conf = ubiquity.Configuration(
    host="url",
    access_token="token"
)

with ubiquity.ApiClient(conf) as api_client:
    api_instance = ubiquity.api.transactions_api.TransactionsApi(api_client)
    try:
        # Submit a signed transaction
        print("Sending signed transaction...")
        api_response = api_instance.tx_send(platform, network, signed_tx)
        print(api_response)
        print("Transaction sent successfully with id:", api_response.id)
    except ubiquity.ubiquity_openapi_client.ApiException as e:
        print("Exception when calling TransactionsApi->tx_send: %s\n" % e)

Estimating fees

Ubiquity's /tx/estimate_fee endpoint returns an estimation of the fee value required for transactions to be pushed to the network.

It can be used through the TransactionsApi.estimate_fee method:

with ubiquity.ApiClient(config) as api_client:
    api_instance = ubiquity.api.transactions_api.TransactionsApi(api_client)
    try:
        # For bitcoin, the 'confirmed_within_blocks' parameter (defaults to 10) specifies
        #   the number of blocks the transaction would be processed within, which
        #   reflects in different fee values
        api_response = api_instance.estimate_fee("bitcoin", "testnet", confirmed_within_blocks=15)
        print("Fee value:", api_response)
    except ubiquity.ubiquity_openapi_client.ApiException as e:
        print("Exception when calling TransactionsApi->estimate_fee: %s\n" % e)

Websockets support

Ubiquity also supports websockets connections (see docs).

A client can communicate with this service to get notifications about new data from the network.

See the following example to subscribe to events for new transactions added to the network:

import asyncio

from ubiquity import websockets as ws
from ubiquity import Configuration

async def run_client():
    conf = Configuration(
        host="<ws_url>",
        access_token="<token>"
    )

    # The class TxsWebsocketConnection has the 'subscribe_txs' method
    #   to interface the connection to the "ubiquity.txs" channel:
    txs_ws_connection = ws.TxsWebsocketConnection()
    conn = txs_ws_connection.connect(conf)

    # The function passed as callback is called when a new event is sent by the server
    #   in this example this function just prints the new tx's id
    await txs_ws_connection.subscribe_txs(
        conn,
        1,
        lambda blk: print(blk['content']['id'])
    )


asyncio.get_event_loop().run_until_complete(run_client())

The following table lists the classes and methods used to handle each websocket channel exposed by Ubiquity:

Channel Class Method
ubiquity.block_identifiers BlockIdsWebsocketConnection subscribe_block_ids
ubiquity.txs TxsWebsocketConnection subscribe_txs

Docs

Additional documentation and examples can be found in the docs directory.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors