turtlecoin-python

https://img.shields.io/pypi/v/turtlecoin.svg https://img.shields.io/pypi/pyversions/turtlecoin.svg https://img.shields.io/pypi/l/turtlecoin.svg

turtlecoin-python is a Python wrapper for the TurtleCoin JSON-RPC API. It integrates with Walletd and Turtlecoind.

Source Code

You can find the source code at GitHub: https://github.com/arthurk/turtlecoin-python

Requirements

Installation

You can install the latest version with pip:

$ pip install turtlecoin

Contents

Walletd

This document shows examples for the walletd JSON-RPC API.

Before you start using the Python integration, make sure that you have walletd running with the rpc-password argument set:

./walletd -w test.wallet -p my_wallet_password --local --rpc-password test

Once it’s running make sure that the blockchain is synchronized. The console log will show an info message when it’s done:

Wallet loading is finished.

The python integration can now be used.

Usage

For all available methods see the full API documentation.

Each response has the following format: {‘id’: 0, ‘jsonrpc’: ‘2.0’, ‘result’: …}. In all examples below only the result is included.

Let’s start by instantiating the Walletd class and printing the wallet address as well as the balance.

from turtlecoin import Walletd

wallet = Wallet(password='test')
wallet.get_address()
'TRTLuxBjcKs5Ubbopcwc...'
wallet.get_balance()
{'availableBalance': 1000, 'lockedAmount': 0}

Internally all amounts are represented as integers. To get the correct amount you have to divide it by 100. For convenience you can use the format_amount helper from the utils package:

from turtlecoin.utils import format_amount

balance = wallet.get_balance()
format_amount(balance['availableBalance'])
100.00

Let’s create a second address and transfer some funds to it. You can either multiply the value by 100 or use the parse_amount utility to convert the amount of TRLT into the internal integer representation:

sender_address = wallet.get_address()
receiver_address = wallet.create_address()

amount = parse_amount(100.00)
transfers = [{'address': receiver_address, 'amount': amount}]
tx_hash = wallet.send_transaction(transfers, change_address=sender_address)

wallet.get_balance(sender_address)
{'availableBalance': 0, 'lockedAmount': 0}
wallet.get_balance(receiver_address)
{'availableBalance': 1000, 'lockedAmount': 0}

Turtlecoind

This document shows how to use the TurtleCoind JSON-RPC API.

Running Turtlecoind

Before you start using the Python integration, make sure that you are running TurtleCoind with the enable_blockexplorer argument set:

./TurtleCoind --enable_blockexplorer

After starting it make sure the blockchain is synchronized. This might take a while. The console log will show a message when it’s done:

Successfully synchronized with the TurtleCoin Network

The python integration can now be used.

Usage

For all available methods see the full API documentation.

To print the current block-height:

from turtlecoin import Turtlecoind

turtle = TurtleCoind()
turtle.getblockcount()['count']
286373

The API Documentation / Guide

If you are looking for information on a specific function, class, or method, this part of the documentation is for you.

Walletd API Reference

class turtlecoin.Walletd(password, host='127.0.0.1', port=8070)

Integrates with Walletd RPC interface.

Run Walletd like this:

$ walletd -w test.wallet -p mypw --local --rpc-password test
create_address(spend_secret_key='', spend_public_key='')

Create a new address

Parameters:
  • spend_secret_key (str) –
  • spend_public_key (str) –
Returns:

the hash of the new address

Return type:

str

create_integrated_address(address, payment_id)

Creates a unique 236 char long address which corresponds to given address and paymentID

Parameters:
  • address (str) – valid TRTL address
  • payment_id (str) – valid payment id
Returns:

integrated address

Return type:

str

delete_address(address)

Delete address from wallet

Parameters:address (str) – the address to delete
Returns:True if successful
Return type:bool
delete_delayed_transaction(transaction_hash)

Delete a delayed transaction

Example

>>> wallet.delete_delayed_transaction('8dea3....')
estimate_fusion(threshold, addresses=[])

Counts the number of unspent outputs of the specified addresses and returns how many of those outputs can be optimized.

get_balance(address='')

Returns the balance of an address

Note

Amount needs to be divided by 100 to get decimal places. If balance returned is 1000 it means 10.00 TRTL

Parameters:address (str) – (optional) The address for which to return the balance. Must exist in this wallet.
Returns:available balance (int) and locked amount (int):
{
    'availableBalance': 1000,
    'lockedAmount': 0
}
Return type:dict
get_delayed_transaction_hashes()

Returns a list of delayed transaction hashes

get_fee_info()

Gets the fee address and amount (if any) from the node that the turtle-service instance is currently connected to. This fee will be automatically sent to the address on every sendTransaction() and sendDelayedTransaction() request. Note that it does not apply to sendFusionTransaction().

Returns:address int: amount
Return type:str
get_mnemonic_seed(address)

Returns the mnemonic seed for the given address

Parameters:address (str) – Valid and existing in this container address
Returns:mnemonic seed
Return type:str
get_spend_keys(address)

Returns spend keys

Parameters:address (str) – Valid and existing in this container address
Returns:A dictionary with the secret and public spend keys:
{
    'spendPublicKey': '3550a41b004520030941183b7f3e5ec075042cdde492044ea5064e4a1d99a3ba',
    'spendSecretKey': 'f66997b99f9a8444417f09b4bca710e7afe9285d581a5aa641cd4ac0b29f5d00'
}
Return type:dict
get_transaction(transaction_hash)

Returns information about a particular transaction

Parameters:transaction_hash (str) – Hash of the requested transaction
Returns:information about the transaction:
{'amount': -110,
 'blockIndex': 274123,
 'extra': '013ffd7e8481121a427a01e034cc9f4604d7b474412186ddd9fc56361dc0eafb72',
 'fee': 10,
 'isBase': False,
 'paymentId': '',
 'state': 0,
 'timestamp': 1521641265,
 'transactionHash': 'dc1221181e5745b9016fed2970bf002d14fe2ad8c90d7a55456d0eb459c7c2b8',
 'transfers': [{'address': 'TRTLuxBjcKs5Ubbopcwc9N6yV62781VdDCS4ZVFupFdWBm3UZrAabVFKwc6yLWQVV3agCBxYzGQhGJsHZokixfufgxZ7EK3d33A',
                'amount': 100,
                'type': 0},
               {'address': 'TRTLuxqgEUr24bw6dWKEJnNHRWk8SfbpgfERJUX43Dys5xACTU22zTZBR32BFi8TavSNei6cU9ym6DPECaTrqQaaaFRgF3xKE73',
                'amount': 790,
                'type': 2},
               {'address': 'TRTLuxqgEUr01cw61WKfJnNHRWk7SgbpgfERJUX4WDys5xACTU123TZBR32BFi8TavSNei6cU9ym6DPECaTrqQaaaFRgF3xKE73',
                'amount': -900,
                'type': 0}],
 'unlockTime': 0}
Return type:dict
get_unconfirmed_transaction_hashes(addresses=[])

Returns the current unconfirmed transaction pool for addresses

Parameters:addresses (list) – (optional) List of addresses. If not set, all addresses of this wallet will be used.
Returns:Hashes of unconfirmed transactions
Return type:list
get_view_key()

Returns the view key

Returns:Private view key
Return type:str
reset(view_secret_key)

Re-syncs the wallet

Note

If the view_secret_key parameter is not specified, the reset() method resets the wallet and re-syncs it. If the view_secret_key argument is specified, reset() method substitutes the existing wallet with a new one with a specified view_secret_key and creates an address for it.

save()

Save the wallet

send_delayed_transaction(transaction_hash)

Send a delayed transaction

Example:

>>> wallet.send_delayed_transaction('8dea3...')
Raises:
  • ValueError – { ‘code’: -32000, ‘data’: {‘application_code’: 15}, ‘message’: ‘Transaction transfer impossible’
  • }
send_fusion_transaction(threshold, anonymity, addresses, destination_address)

Send a fusion transaction, by taking funds from selected addresses and transferring them to the destination address.

Returns:hash of the sent transaction
Return type:str
send_transaction(transfers, anonymity=3, fee=10, addresses='', change_address='', extra='', payment_id='', unlock_time=0)

Send a transaction to one or multiple addresses.

Note

The amount/fee need to be multiplied by 100 to get TRTL amount.

If you want to transfer 10 TRTL with a fee of 0.1 TRLT you should set transfer amount to 1000 and fee to 10

Params:
anonymity: mixin amount transfers: address where to send the funds to. (address, amount) fee: transaction fee (default 100 (0.1 TRTL)) source_addresses: addresses from which to take the funds from. change_address: address where to send the change to. extra (bytes): extra data to include payment_id: can be given to receiver to identify transaction unlock_time (int)

Example:

>>> wallet.send_transaction(
    anonymity=3,
    transfers=[
        {'address': 'TRTL...',
         'amount': 500}],
    fee=10
)
{'transactionHash': '1b87a........'}

Turtlecoind API Reference

class turtlecoin.TurtleCoind(host='127.0.0.1', port=11898)

Integrates with JSON-RPC interface of TurtleCoind.

get_block(block_hash)

Returns information on a single block

Parameters:block_hash – Block hash of the block you wish to retrieve
Returns:dict:
{
    "block": {
        "alreadyGeneratedCoins": "1484230931125",
        "alreadyGeneratedTransactions": 974921,
        "baseReward": 2935998,
        "blockSize": 48846,
        "depth": 0,
        "difficulty": 358164537,
        "effectiveSizeMedian": 100000,
        "hash": "f11580d74134ac34673c74f8da458080aacbe1eccea05b197e9d10bde05139f5",
        "height": 501854,
        "major_version": 4,
        "minor_version": 0,
        "nonce": 214748383,
        "orphan_status": false,
        "penalty": 0,
        "prev_hash": "674046ea53a8673c630bd34655c4723199e69fdcfd518503f4c714e16a7121b5",
        "reward": 2936608,
        "sizeMedian": 231,
        "timestamp": 1527891820,
        "totalFeeAmount": 610,
        "transactions": [
            {
                "amount_out": 2936608,
                "fee": 0,
                "hash": "61b29d7a3fe931928388f14cffb5e705a68db219e1df6b4e15aee39d1c2a16e8",
                "size": 266
            },
            .....,
            .....,
        ],
        "transactionsCumulativeSize": 48535
    },
    "status": "OK"
}
get_block_count()

Returns current chain height.

Returns:dict:
{
    "jsonrpc":"2.0",
    "result":{
        "count":560915,
        "status":"OK"
    }
}
get_block_hash(block_hash)

Returns block hash for a given height off by one

Parameters:height – 123456
Returns:dict:: result
{
“jsonrpc”: “2.0”, “result”: “4bd7dd9649a006660e113efe49691e0739d9838d044774f18732111b145347c8”

}

get_block_header_by_hash(hash)

Returns last block header by given hash.

Parameters:hash (str) – a valid block hash
Returns:See getlastblockheader
Return type:dict
get_block_header_by_height(height)

Returns last block header by given hash.

Parameters:hash (int) – a valid block height
Returns:See getlastblockheader
Return type:dict
get_block_template(reserve_size, wallet_address)

Returns blocktemplate with an empty “hole” for nonce.

Parameters:
  • reserve_size (int) – 123
  • wallet_address (str) – a valid wallet address
Returns:

the block template:

{
    "blocktemplate_blob": "0300f29a5cddd1a88f9b95...",
    "difficulty": 273666101,
    "height": 286393,
    "reserved_offset": 412,
    "status": "OK"
}

Return type:

dict

get_blocks(height)

Returns information on the last 30 blocks before height (inclusive)

Parameters:height – the height of the blockchain to start at
Returns:dict:
{
    "jsonrpc": "2.0",
    "result": {
        'blocks':[
            {
                "cumul_size": 22041,
                "difficulty": 285124963,
                "hash": "62f0058453292af5e1aa070f8526f7642ab6974c6af2c17088c21b31679c813d",
                "height": 500000,
                "timestamp": 1527834137,
                "tx_count": 4
            },
            .....,
            .....,
        ],
        "status": "OK"
    }
}
get_currency_id()

Returns unique currency identifier.

Returns:dict:
{'currency_id_blob': '7fb97df81221dd1366051b2...'}
get_fee_info()

Returns information on fee set by remote node

Returns:
dict::
{
‘address’: ‘’, ‘amount’: 0, ‘status’: “Node’s fee address is not set”

}

get_height()

Returns current chain height

Returns:dict:
{
    'height': 613945,
    'network_height': 613945,
    'status': 'OK'
}
get_info()

Returns information of network and connection

Returns:
dict::
{
‘alt_blocks_count’: 7, ‘difficulty’: 162204943, ‘grey_peerlist_size’: 736, ‘hashrate’: 5406831, ‘height’: 613945, ‘incoming_connections_count’: 0, ‘last_known_block_index’: 613942, ‘major_version’: 4, ‘minor_version’: 0, ‘network_height’: 613945, ‘outgoing_connections_count’: 8, ‘start_time’: 1531374018, ‘status’: ‘OK’, ‘supported_height’: 620000, ‘synced’: True, ‘testnet’: False, ‘tx_count’: 719763, ‘tx_pool_size’: 0, ‘upgrade_heights’: [
187000, 350000, 440000, 620000, …

], ‘version’: ‘0.6.4’, ‘white_peerlist_size’: 52

}

get_last_block_header()

Returns last block header.

Returns:information about the last block header:
{
    'block_header': {
        'depth': 0,
        'difficulty': 226559499,
        'hash': '34aa8777302f4856e360fef49a0a7b6c78cc8eff999c0c716bad234837917986',
        'height': 286397,
        'major_version': 3,
        'minor_version': 0,
        'nonce': 18205,
        'orphan_status': False,
        'prev_hash': '522f53dae525f0a66064377c41bc1f78c6eb4eea2b3e7630efccd395bb17f43f',
        'reward': 2954906,
        'timestamp': 1521732086
    },
    'status': 'OK'
}
Return type:dict
get_peers()

Returns array of peers connected to the daemon

Returns:
dict::
{
‘peers’: [
142.44.212.51:11897, 45.55.33.219:11897. …

], ‘status’: ‘OK

}

get_transaction(transaction_hash)

Gets information on the single transaction

Parameters:transaction_hash – (str) The transaction hash
Returns:dict:
{
    "block": {
        "cumul_size": 22041,
        "difficulty": 103205633,
        "hash": "62f0058453292af5e1aa070f8526f7642ab6974c6af2c17088c21b31679c813d",
        "height": 500000,
        "timestamp": 1527834137,
        "tx_count": 4
    },
    "status": "OK",
    "tx": {
        "extra": "019e430ecdd501714900c71cb45fd49b4fa77ebd4a68d967cc2419ccd4e72378e3020800000000956710b6",
        "unlock_time": 500040,
        "version": 1,
        "vin": [
            {
                "type": "ff",
                "value": {
                    "height": 500000
                }
            }
        ],
        "vout": [
            {
                "amount": 80,
                "target": {
                    "data": {
                        "key": "5ce69a87940df7ae8443261ff610861d2e4207a7556ef1aa35878c0a5e7e382d"
                    },
                "type": "02"
                }
            },
            .....,
            .....,
        ]
    },
    "txDetails": {
        "amount_out": 2936280,
        "fee": 0,
        "hash": "702ad5bd04b9eff14b080d508f69a320da1909e989d6c163c18f80ae7a5ab832",
        "mixin": 0,
        "paymentId": "",
        "size": 266
    }
}
get_transaction_pool()

Gets the list of transaction hashs in the mempool.

Returns:dict:
{
    "jsonrpc": "2.0"
    "transactions": [
        {
            "amount_out": 1660000,
            "fee": 0,
            "hash": "721ae50994d5446d5683ca79d6fa97dce321a39e88e1df70ae433dc67573841b",
            "size": 13046
        },
        .....,
        .....,
    ]
}
get_transactions()

Returns array of missed transactions

Returns:
dict::
{
‘missed_tx’: [], ‘status’: ‘OK’, ‘txs_as_hex’: []

}

submit_block(block_blob)

Submits a block

Parameters:block_blob (str) – a valid block blob …
Returns:dict:
{
    "jsonrpc": "2.0"
    "result": {
        "status": "OK"
    }
}

Development

If you plan to work on the turtlecoin-python itself, it is useful to have DEBUG logging enabled. You can do this with the following code snippet:

import logging

logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

Enabling this will let you see more detailed data for the request that is being sent to the JSON-RPC interface:

2018-04-05 16:20:09,193 DEBUG    {
    "jsonrpc": "2.0",
    "method": "getlastblockheader",
    "params": {},
    "password": ""
}
2018-04-05 16:20:09,204 DEBUG    Starting new HTTP connection (1): 127.0.0.1
2018-04-05 16:20:09,206 DEBUG    http://127.0.0.1:11898 "POST /json_rpc HTTP/1.1" 200 406