Skip to content

The Async API

TronPy offers a standard synchronous API by default, but also introduces an async client via httpx.

The async client is AsyncTron. It almost uses the same API as the synchronous client Tron.

import asyncio

from tronpy import AsyncTron
from tronpy.keys import PrivateKey

# private key of TMisHYBVvFHwKXHPYTqo8DhrRPTbWeAM6z
priv_key = PrivateKey(bytes.fromhex("8888888888888888888888888888888888888888888888888888888888888888"))


async def transfer():
    async with AsyncTron(network="nile") as client:
        print(client)

        txb = (
            client.trx.transfer("TJzXt1sZautjqXnpjQT4xSCBHNSYgBkDr3", "TVjsyZ7fYF3qLF6BQgPmTEZy1xrNNyVAAA", 1_000)
            .memo("test memo")
            .fee_limit(100_000_000)
        )
        txn = await txb.build()
        print(txn)
        txn_ret = await txn.sign(priv_key).broadcast()
        print(txn_ret)
        # > {'result': True, 'txid': 'edc2a625752b9c71fdd0d68117802860c6adb1a45c19fd631a41757fa334d72b'}
        print(await txn_ret.wait())
        # > {'id': 'edc2a625752b9c71fdd0d68117802860c6adb1a45c19fd631a41757fa334d72b', 'blockNumber': 10163821,
        # > 'blockTimeStamp': 1603368072000, 'contractResult': [''], 'receipt': {'net_usage': 283}}


if __name__ == "__main__":
    asyncio.run(transfer())

API reference

AsyncTron

AsyncTron(
    provider: AsyncHTTPProvider = None, *, network: str = "mainnet", conf: dict = None
)

The Async TRON API Client.

Parameters:

  • provider

    (AsyncHTTPProvider, default: None ) –

    An HTTPProvider object, can be configured to use private node

  • network

    (str, default: 'mainnet' ) –

    Which network to connect, one of "mainnet", "shasta", "nile", or "tronex"

Methods:

Attributes:

Source code in tronpy/async_tron.py
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
def __init__(self, provider: AsyncHTTPProvider = None, *, network: str = "mainnet", conf: dict = None):
    self.conf = DEFAULT_CONF
    """The config dict."""

    if conf is not None:
        self.conf = dict(DEFAULT_CONF, **conf)

    if provider is None:
        self.provider = AsyncHTTPProvider(conf_for_name(network), self.conf["timeout"])
    elif isinstance(provider, (AsyncHTTPProvider,)):
        self.provider = provider
    else:
        raise TypeError("provider is not a HTTPProvider")

    self._trx = AsyncTrx(self)

conf instance-attribute

conf = DEFAULT_CONF

The config dict.

is_address class-attribute instance-attribute

is_address = staticmethod(keys.is_address)

Is object a TRON address, both hex format and base58check format.

is_base58check_address class-attribute instance-attribute

is_base58check_address = staticmethod(keys.is_base58check_address)

Is object an address in base58check format.

is_hex_address class-attribute instance-attribute

is_hex_address = staticmethod(keys.is_hex_address)

Is object an address in hex str format.

to_base58check_address class-attribute instance-attribute

to_base58check_address = staticmethod(keys.to_base58check_address)

Convert address of any format to a base58check format.

to_canonical_address class-attribute instance-attribute

to_canonical_address = staticmethod(keys.to_base58check_address)

Convert address of any format to a base58check format.

to_hex_address class-attribute instance-attribute

to_hex_address = staticmethod(keys.to_hex_address)

Convert address of any format to a hex format.

trx property

trx: AsyncTrx

Helper object to send various transactions.

generate_address

generate_address(priv_key=None) -> dict

Generate a random address.

Source code in tronpy/async_tron.py
644
645
646
647
648
649
650
651
652
653
def generate_address(self, priv_key=None) -> dict:
    """Generate a random address."""
    if priv_key is None:
        priv_key = PrivateKey.random()
    return {
        "base58check_address": priv_key.public_key.to_base58check_address(),
        "hex_address": priv_key.public_key.to_hex_address(),
        "private_key": priv_key.hex(),
        "public_key": priv_key.public_key.hex(),
    }

generate_address_from_mnemonic

generate_address_from_mnemonic(
    mnemonic: str, passphrase: str = "", account_path: str = TRON_DEFAULT_PATH
)

Generate address from a mnemonic.

Parameters:

  • mnemonic

    (str) –

    space-separated list of BIP39 mnemonic seed words

  • passphrase

    (str, default: '' ) –

    Optional passphrase used to encrypt the mnemonic

  • account_path

    (str, default: TRON_DEFAULT_PATH ) –

    Specify an alternate HD path for deriving the seed using BIP32 HD wallet key derivation.

Source code in tronpy/async_tron.py
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
def generate_address_from_mnemonic(self, mnemonic: str, passphrase: str = "", account_path: str = TRON_DEFAULT_PATH):
    """
    Generate address from a mnemonic.

    :param str mnemonic: space-separated list of BIP39 mnemonic seed words
    :param str passphrase: Optional passphrase used to encrypt the mnemonic
    :param str account_path: Specify an alternate HD path for deriving the seed using
        BIP32 HD wallet key derivation.
    """
    seed = seed_from_mnemonic(mnemonic, passphrase)
    key = key_from_seed(seed, account_path)
    priv_key = PrivateKey(key)
    return {
        "base58check_address": priv_key.public_key.to_base58check_address(),
        "hex_address": priv_key.public_key.to_hex_address(),
        "private_key": priv_key.hex(),
        "public_key": priv_key.public_key.hex(),
    }

generate_address_with_mnemonic

generate_address_with_mnemonic(
    passphrase: str = "",
    num_words: int = 12,
    language: str = "english",
    account_path: str = TRON_DEFAULT_PATH,
)

Create a new address and related mnemonic.

Creates a new address, and returns it alongside the mnemonic that can be used to regenerate it using any BIP39-compatible wallet.

Parameters:

  • passphrase

    (str, default: '' ) –

    Extra passphrase to encrypt the seed phrase

  • num_words

    (int, default: 12 ) –

    Number of words to use with seed phrase. Default is 12 words. Must be one of [12, 15, 18, 21, 24].

  • language

    (str, default: 'english' ) –

    Language to use for BIP39 mnemonic seed phrase.

  • account_path

    (str, default: TRON_DEFAULT_PATH ) –

    Specify an alternate HD path for deriving the seed using BIP32 HD wallet key derivation.

Source code in tronpy/async_tron.py
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
def generate_address_with_mnemonic(
    self, passphrase: str = "", num_words: int = 12, language: str = "english", account_path: str = TRON_DEFAULT_PATH
):
    r"""
    Create a new address and related mnemonic.

    Creates a new address, and returns it alongside the mnemonic that can be used to regenerate it using any BIP39-compatible wallet.

    :param str passphrase: Extra passphrase to encrypt the seed phrase
    :param int num_words: Number of words to use with seed phrase. Default is 12 words.
                          Must be one of [12, 15, 18, 21, 24].
    :param str language: Language to use for BIP39 mnemonic seed phrase.
    :param str account_path: Specify an alternate HD path for deriving the seed using
        BIP32 HD wallet key derivation.
    """  # noqa: E501
    mnemonic = generate_mnemonic(num_words, language)
    return self.generate_address_from_mnemonic(mnemonic, passphrase, account_path), mnemonic

generate_zkey async

generate_zkey() -> dict

Generate a random shielded address.

Source code in tronpy/async_tron.py
697
698
699
async def generate_zkey(self) -> dict:
    """Generate a random shielded address."""
    return await self.provider.make_request("wallet/getnewshieldedaddress")

get_account async

get_account(addr: TAddress) -> dict

Get account info from an address.

Source code in tronpy/async_tron.py
738
739
740
741
742
743
744
745
746
async def get_account(self, addr: TAddress) -> dict:
    """Get account info from an address."""

    ret = await self.provider.make_request(
        "wallet/getaccount", {"address": keys.to_base58check_address(addr), "visible": True}
    )
    if ret:
        return ret
    raise AddressNotFound("account not found on-chain")

get_account_asset_balance async

get_account_asset_balance(addr: TAddress, token_id: int | str) -> int

Get TRC10 token balance of an account. Result is in raw amount.

Source code in tronpy/async_tron.py
789
790
791
792
793
794
795
async def get_account_asset_balance(self, addr: TAddress, token_id: int | str) -> int:
    """Get TRC10 token balance of an account. Result is in raw amount."""
    if int(token_id) < 1000000 or int(token_id) > 1999999:
        raise ValueError("invalid token_id range")

    balances = await self.get_account_asset_balances(addr)
    return balances.get(str(token_id), 0)

get_account_asset_balances async

get_account_asset_balances(addr: TAddress) -> dict

Get all TRC10 token balances of an account.

Source code in tronpy/async_tron.py
784
785
786
787
async def get_account_asset_balances(self, addr: TAddress) -> dict:
    """Get all TRC10 token balances of an account."""
    info = await self.get_account(addr)
    return {p["key"]: p["value"] for p in info.get("assetV2", {}) if p["value"] > 0}

get_account_balance async

get_account_balance(addr: TAddress) -> Decimal

Get TRX balance of an account. Result in TRX.

Source code in tronpy/async_tron.py
778
779
780
781
782
async def get_account_balance(self, addr: TAddress) -> Decimal:
    """Get TRX balance of an account. Result in `TRX`."""

    info = await self.get_account(addr)
    return Decimal(info.get("balance", 0)) / 1_000_000

get_account_permission async

get_account_permission(addr: TAddress) -> dict

Get account's permission info from an address. Can be used in account_permission_update.

Source code in tronpy/async_tron.py
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
async def get_account_permission(self, addr: TAddress) -> dict:
    """Get account's permission info from an address. Can be used in `account_permission_update`."""

    addr = keys.to_base58check_address(addr)
    # will check account existence
    info = await self.get_account(addr)
    # For old accounts prior to AccountPermissionUpdate, these fields are not set.
    # So default permission is for backward compatibility.
    default_witness = None
    if info.get("is_witness", None):
        default_witness = {
            "type": "Witness",
            "id": 1,
            "permission_name": "witness",
            "threshold": 1,
            "keys": [{"address": addr, "weight": 1}],
        }
    return {
        "owner": info.get(
            "owner_permission",
            {"permission_name": "owner", "threshold": 1, "keys": [{"address": addr, "weight": 1}]},
        ),
        "actives": info.get(
            "active_permission",
            [
                {
                    "type": "Active",
                    "id": 2,
                    "permission_name": "active",
                    "threshold": 1,
                    "operations": "7fff1fc0033e0100000000000000000000000000000000000000000000000000",
                    "keys": [{"address": addr, "weight": 1}],
                }
            ],
        ),
        "witness": info.get("witness_permission", default_witness),
    }

get_account_resource async

get_account_resource(addr: TAddress) -> dict

Get resource info of an account.

Source code in tronpy/async_tron.py
767
768
769
770
771
772
773
774
775
776
async def get_account_resource(self, addr: TAddress) -> dict:
    """Get resource info of an account."""

    ret = await self.provider.make_request(
        "wallet/getaccountresource",
        {"address": keys.to_base58check_address(addr), "visible": True},
    )
    if ret:
        return ret
    raise AddressNotFound("account not found on-chain")

get_address_from_passphrase

get_address_from_passphrase(passphrase: str) -> dict

Get an address from a passphrase, compatiable with wallet/createaddress.

Source code in tronpy/async_tron.py
692
693
694
695
def get_address_from_passphrase(self, passphrase: str) -> dict:
    """Get an address from a passphrase, compatiable with `wallet/createaddress`."""
    priv_key = PrivateKey.from_passphrase(passphrase.encode())
    return self.generate_address(priv_key)

get_asset async

get_asset(asset_id: int = None, issuer: TAddress = None) -> dict

Get TRC10(asset) info by asset's id or issuer.

Source code in tronpy/async_tron.py
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
async def get_asset(self, asset_id: int = None, issuer: TAddress = None) -> dict:
    """Get TRC10(asset) info by asset's id or issuer."""
    if asset_id and issuer:
        raise ValueError("either query by id or issuer")
    if asset_id:
        return await self.provider.make_request("wallet/getassetissuebyid", {"value": asset_id, "visible": True})
    return await self.provider.make_request(
        "wallet/getassetissuebyaccount",
        {"address": keys.to_base58check_address(issuer), "visible": True},
    )

get_asset_from_name async

get_asset_from_name(name: str) -> dict

Get asset info from its abbr name, might fail if there're duplicates.

Source code in tronpy/async_tron.py
1022
1023
1024
1025
1026
1027
1028
1029
async def get_asset_from_name(self, name: str) -> dict:
    """Get asset info from its abbr name, might fail if there're duplicates."""
    assets = [asset for asset in await self.list_assets() if asset["abbr"] == name]
    if assets:
        if len(assets) == 1:
            return assets[0]
        raise ValueError("duplicated assets with the same name", [asset["id"] for asset in assets])
    raise AssetNotFound

get_bandwidth async

get_bandwidth(addr: TAddress) -> int

Query the bandwidth of the account

Source code in tronpy/async_tron.py
749
750
751
752
753
754
755
756
757
758
async def get_bandwidth(self, addr: TAddress) -> int:
    """Query the bandwidth of the account"""

    ret = await self.provider.make_request(
        "wallet/getaccountnet", {"address": keys.to_base58check_address(addr), "visible": True}
    )
    if ret:
        # (freeNetLimit - freeNetUsed) + (NetLimit - NetUsed)
        return ret["freeNetLimit"] - ret.get("freeNetUsed", 0) + ret.get("NetLimit", 0) - ret.get("NetUsed", 0)
    raise AddressNotFound("account not found on-chain")

get_block async

get_block(id_or_num: None | str | int = None, *, visible: bool = True) -> dict

Get block from a block id or block number.

Parameters:

  • id_or_num

    (None | str | int, default: None ) –

    Block number, or Block hash(id), or None (default) to get the latest block.

  • visible

    (bool, default: True ) –

    Use visible=False to get non-base58check addresses and strings instead of hex strings.

Source code in tronpy/async_tron.py
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
async def get_block(self, id_or_num: None | str | int = None, *, visible: bool = True) -> dict:
    """Get block from a block id or block number.

    :param id_or_num: Block number, or Block hash(id), or ``None`` (default) to get the latest block.
    :param visible: Use ``visible=False`` to get non-base58check addresses and strings instead of hex strings.
    """

    if isinstance(id_or_num, (int,)):
        block = await self.provider.make_request("wallet/getblockbynum", {"num": id_or_num, "visible": visible})
    elif isinstance(id_or_num, (str,)):
        block = await self.provider.make_request("wallet/getblockbyid", {"value": id_or_num, "visible": visible})
    elif id_or_num is None:
        block = await self.provider.make_request("wallet/getnowblock", {"visible": visible})
    else:
        raise TypeError(f"can not infer type of {id_or_num}")

    if "Error" in (block or {}):
        raise BugInJavaTron(block)
    if block:
        return block
    raise BlockNotFound

get_can_delegated_max_size async

get_can_delegated_max_size(address: TAddress, resource: str = 'ENERGY') -> dict

Query the amount of delegatable resources share of the specified resource type for an address

Args: address (TAddress): resource (str, optional): Resource type, can be "ENERGY" or "BANDWIDTH". Defaults to "ENERGY".

Returns: dict: Response data

Source code in tronpy/async_tron.py
846
847
848
849
850
851
852
853
854
855
856
857
858
859
async def get_can_delegated_max_size(self, address: TAddress, resource: str = "ENERGY") -> dict:
    """Query the amount of delegatable resources share of the specified resource type for an address

    Args:
        address (TAddress):
        resource (str, optional): Resource type, can be ``"ENERGY"`` or ``"BANDWIDTH"``. Defaults to "ENERGY".

    Returns:
        dict: Response data
    """
    return await self.provider.make_request(
        "wallet/getcandelegatedmaxsize",
        {"owner_address": keys.to_base58check_address(address), "type": 1 if resource == "ENERGY" else 0, "visible": True},
    )

get_chain_parameters async

get_chain_parameters() -> dict

List all chain parameters, values that can be changed via proposal.

Source code in tronpy/async_tron.py
1004
1005
1006
1007
async def get_chain_parameters(self) -> dict:
    """List all chain parameters, values that can be changed via proposal."""
    params = await self.provider.make_request("wallet/getchainparameters", {"visible": True})
    return params.get("chainParameter", [])

get_contract async

get_contract(addr: TAddress) -> AsyncContract

Get a contract object.

Source code in tronpy/async_tron.py
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
async def get_contract(self, addr: TAddress) -> AsyncContract:
    """Get a contract object."""
    addr = keys.to_base58check_address(addr)
    info = await self.provider.make_request("wallet/getcontract", {"value": addr, "visible": True})

    try:
        self._handle_api_error(info)
    except ApiError as e:
        # your java's null pointer exception sucks
        raise AddressNotFound("contract address not found") from e

    return AsyncContract(
        addr=addr,
        bytecode=info.get("bytecode", ""),
        name=info.get("name", ""),
        abi=info.get("abi", {}).get("entrys", []),
        origin_energy_limit=info.get("origin_energy_limit", 0),
        user_resource_percent=info.get("consume_user_resource_percent", 100),
        origin_address=info.get("origin_address", ""),
        code_hash=info.get("code_hash", ""),
        client=self,
    )

get_contract_as_shielded_trc20 async

get_contract_as_shielded_trc20(addr: TAddress) -> ShieldedTRC20

Get a Shielded TRC20 Contract object.

Source code in tronpy/async_tron.py
1087
1088
1089
1090
async def get_contract_as_shielded_trc20(self, addr: TAddress) -> ShieldedTRC20:
    """Get a Shielded TRC20 Contract object."""
    contract = await self.get_contract(addr)
    return ShieldedTRC20(contract)

get_contract_info async

get_contract_info(addr: TAddress) -> dict

Queries a contract's information from the blockchain

Source code in tronpy/async_tron.py
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
async def get_contract_info(self, addr: TAddress) -> dict:
    """Queries a contract's information from the blockchain"""
    addr = keys.to_base58check_address(addr)
    info = await self.provider.make_request("wallet/getcontractinfo", {"value": addr, "visible": True})

    try:
        self._handle_api_error(info)
    except ApiError as e:
        raise AddressNotFound("contract address not found") from e

    return info

get_delegated_resource_account_index_v2 async

get_delegated_resource_account_index_v2(addr: TAddress) -> dict

Query the resource delegation index by an account

Source code in tronpy/async_tron.py
861
862
863
864
865
866
867
868
869
async def get_delegated_resource_account_index_v2(self, addr: TAddress) -> dict:
    """Query the resource delegation index by an account"""
    return await self.provider.make_request(
        "wallet/getdelegatedresourceaccountindexv2",
        {
            "value": keys.to_base58check_address(addr),
            "visible": True,
        },
    )

get_delegated_resource_v2 async

get_delegated_resource_v2(fromAddr: TAddress, toAddr: TAddress) -> dict

Query the amount of delegatable resources share of the specified resource type for an address

Source code in tronpy/async_tron.py
835
836
837
838
839
840
841
842
843
844
async def get_delegated_resource_v2(self, fromAddr: TAddress, toAddr: TAddress) -> dict:
    """Query the amount of delegatable resources share of the specified resource type for an address"""
    return await self.provider.make_request(
        "wallet/getdelegatedresourcev2",
        {
            "fromAddress": keys.to_base58check_address(fromAddr),
            "toAddress": keys.to_base58check_address(toAddr),
            "visible": True,
        },
    )

get_energy async

get_energy(address: str) -> int

Query the energy of the account

Source code in tronpy/async_tron.py
760
761
762
763
764
765
async def get_energy(self, address: str) -> int:
    """Query the energy of the account"""
    account_info = await self.get_account_resource(address)
    energy_limit = account_info.get("EnergyLimit", 0)
    energy_used = account_info.get("EnergyUsed", 0)
    return energy_limit - energy_used

get_estimated_energy async

get_estimated_energy(
    owner_address: TAddress,
    contract_address: TAddress,
    function_selector: str,
    parameter: str,
) -> int

Returns an estimated energy of calling a contract from the chain.

Source code in tronpy/async_tron.py
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
async def get_estimated_energy(
    self,
    owner_address: TAddress,
    contract_address: TAddress,
    function_selector: str,
    parameter: str,
) -> int:
    """Returns an estimated energy of calling a contract from the chain."""
    params = {
        "owner_address": keys.to_base58check_address(owner_address),
        "contract_address": keys.to_base58check_address(contract_address),
        "function_selector": function_selector,
        "parameter": parameter,
        "visible": True,
    }
    ret = await self.provider.make_request("wallet/estimateenergy", params)
    self._handle_api_error(ret)
    return ret["energy_required"]

get_latest_block async

get_latest_block() -> dict

Get latest block.

Source code in tronpy/async_tron.py
892
893
894
async def get_latest_block(self) -> dict:
    """Get latest block."""
    return await self.provider.make_request("wallet/getnowblock", {"visible": True})

get_latest_block_id async

get_latest_block_id() -> str

Get latest block id in hex.

Source code in tronpy/async_tron.py
896
897
898
899
900
async def get_latest_block_id(self) -> str:
    """Get latest block id in hex."""

    info = await self.provider.make_request("wallet/getnodeinfo")
    return info["block"].split(",ID:", 1)[-1]

get_latest_block_number async

get_latest_block_number() -> int

Get latest block number. Implemented via wallet/getnodeinfo, which is faster than wallet/getnowblock.

Source code in tronpy/async_tron.py
902
903
904
905
906
async def get_latest_block_number(self) -> int:
    """Get latest block number. Implemented via `wallet/getnodeinfo`, which is faster than `wallet/getnowblock`."""

    info = await self.provider.make_request("wallet/getnodeinfo")
    return int(info["block"].split(",ID:", 1)[0].replace("Num:", "", 1))

get_latest_solid_block_id async

get_latest_solid_block_id() -> str

Get latest solid block id in hex.

Source code in tronpy/async_tron.py
876
877
878
879
880
881
882
883
884
async def get_latest_solid_block_id(self) -> str:
    """Get latest solid block id in hex."""

    try:
        info = await self.provider.make_request("wallet/getnodeinfo")
        return info["solidityBlock"].split(",ID:", 1)[-1]
    except Exception:
        info = await self.get_latest_solid_block()
        return info["blockID"]

get_latest_solid_block_number async

get_latest_solid_block_number() -> int

Get latest solid block number. Implemented via wallet/getnodeinfo, which is faster than walletsolidity/getnowblock.

Source code in tronpy/async_tron.py
886
887
888
889
890
async def get_latest_solid_block_number(self) -> int:
    """Get latest solid block number. Implemented via `wallet/getnodeinfo`,
    which is faster than `walletsolidity/getnowblock`."""
    info = await self.provider.make_request("wallet/getnodeinfo")
    return int(info["solidityBlock"].split(",ID:", 1)[0].replace("Num:", "", 1))

get_node_info async

get_node_info() -> dict

Get current API node' info.

Source code in tronpy/async_tron.py
 999
1000
1001
1002
async def get_node_info(self) -> dict:
    """Get current API node' info."""

    return await self.provider.make_request("wallet/getnodeinfo", {"visible": True})

get_solid_transaction async

get_solid_transaction(txn_id: str) -> dict

Get transaction from a transaction id, must be in solid block.

Source code in tronpy/async_tron.py
942
943
944
945
946
947
948
949
950
951
952
async def get_solid_transaction(self, txn_id: str) -> dict:
    """Get transaction from a transaction id, must be in solid block."""

    if len(txn_id) != 64:
        raise BadHash("wrong transaction hash length")

    ret = await self.provider.make_request("walletsolidity/gettransactionbyid", {"value": txn_id, "visible": True})
    self._handle_api_error(ret)
    if ret:
        return ret
    raise TransactionNotFound

get_solid_transaction_info async

get_solid_transaction_info(txn_id: str) -> dict

Get transaction receipt info from a transaction id, must be in solid block.

Source code in tronpy/async_tron.py
966
967
968
969
970
971
972
973
974
975
976
async def get_solid_transaction_info(self, txn_id: str) -> dict:
    """Get transaction receipt info from a transaction id, must be in solid block."""

    if len(txn_id) != 64:
        raise BadHash("wrong transaction hash length")

    ret = await self.provider.make_request("walletsolidity/gettransactioninfobyid", {"value": txn_id, "visible": True})
    self._handle_api_error(ret)
    if ret:
        return ret
    raise TransactionNotFound

get_transaction async

get_transaction(txn_id: str) -> dict

Get transaction from a transaction id.

Source code in tronpy/async_tron.py
930
931
932
933
934
935
936
937
938
939
940
async def get_transaction(self, txn_id: str) -> dict:
    """Get transaction from a transaction id."""

    if len(txn_id) != 64:
        raise BadHash("wrong transaction hash length")

    ret = await self.provider.make_request("wallet/gettransactionbyid", {"value": txn_id, "visible": True})
    self._handle_api_error(ret)
    if ret:
        return ret
    raise TransactionNotFound

get_transaction_info async

get_transaction_info(txn_id: str) -> dict

Get transaction receipt info from a transaction id.

Source code in tronpy/async_tron.py
954
955
956
957
958
959
960
961
962
963
964
async def get_transaction_info(self, txn_id: str) -> dict:
    """Get transaction receipt info from a transaction id."""

    if len(txn_id) != 64:
        raise BadHash("wrong transaction hash length")

    ret = await self.provider.make_request("wallet/gettransactioninfobyid", {"value": txn_id, "visible": True})
    self._handle_api_error(ret)
    if ret:
        return ret
    raise TransactionNotFound

get_zkey_from_sk async

get_zkey_from_sk(sk: str, d: str = None) -> dict

Get the shielded address from sk(spending key) and d(diversifier).

Source code in tronpy/async_tron.py
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
async def get_zkey_from_sk(self, sk: str, d: str = None) -> dict:
    """Get the shielded address from sk(spending key) and d(diversifier)."""
    if len(sk) != 64:
        raise BadKey("32 byte sk required")
    if d and len(d) != 22:
        raise BadKey("11 byte d required")

    esk = await self.provider.make_request("wallet/getexpandedspendingkey", {"value": sk})
    ask = esk["ask"]
    nsk = esk["nsk"]
    ovk = esk["ovk"]
    ak = (await self.provider.make_request("wallet/getakfromask", {"value": ask}))["value"]
    nk = (await self.provider.make_request("wallet/getnkfromnsk", {"value": nsk}))["value"]

    ivk = (await self.provider.make_request("wallet/getincomingviewingkey", {"ak": ak, "nk": nk}))["ivk"]

    if d is None:
        d = (await self.provider.make_request("wallet/getdiversifier"))["d"]

    ret = await self.provider.make_request("wallet/getzenpaymentaddress", {"ivk": ivk, "d": d})
    pkD = ret["pkD"]
    payment_address = ret["payment_address"]

    return {
        "sk": sk,
        "ask": ask,
        "nsk": nsk,
        "ovk": ovk,
        "ak": ak,
        "nk": nk,
        "ivk": ivk,
        "d": d,
        "pkD": pkD,
        "payment_address": payment_address,
    }

list_assets async

list_assets() -> list

List all TRC10 tokens(assets).

Source code in tronpy/async_tron.py
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
async def list_assets(self) -> list:
    """List all TRC10 tokens(assets)."""
    ret = await self.provider.make_request("wallet/getassetissuelist", {"visible": True})
    assets = ret["assetIssue"]
    for asset in assets:
        asset["id"] = int(asset["id"])
        asset["owner_address"] = keys.to_base58check_address(asset["owner_address"])
        asset["name"] = bytes.fromhex(asset["name"]).decode()
        if "abbr" in asset:
            asset["abbr"] = bytes.fromhex(asset["abbr"]).decode()
        else:
            asset["abbr"] = ""
        if "description" in asset:
            asset["description"] = bytes.fromhex(asset["description"]).decode("utf8", "replace")
        else:
            asset["description"] = ""
        asset["url"] = bytes.fromhex(asset["url"]).decode()
    return assets

list_nodes async

list_nodes() -> list

List all nodes that current API node is connected to.

Source code in tronpy/async_tron.py
990
991
992
993
994
995
996
997
async def list_nodes(self) -> list:
    """List all nodes that current API node is connected to."""
    # NOTE: visible parameter is ignored
    ret = await self.provider.make_request("wallet/listnodes", {"visible": True})
    nodes = ret.get("nodes", [])
    for node in nodes:
        node["address"]["host"] = bytes.fromhex(node["address"]["host"]).decode()
    return nodes

list_witnesses async

list_witnesses() -> list

List all witnesses, including SR, SRP, and SRC.

Source code in tronpy/async_tron.py
980
981
982
983
984
985
986
987
988
async def list_witnesses(self) -> list:
    """List all witnesses, including SR, SRP, and SRC."""
    # NOTE: visible parameter is ignored
    ret = await self.provider.make_request("wallet/listwitnesses", {"visible": True})
    witnesses = ret.get("witnesses", [])
    for witness in witnesses:
        witness["address"] = keys.to_base58check_address(witness["address"])

    return witnesses

AsyncTrx

AsyncTrx(tron)

The Trx(transaction) API.

Methods:

Source code in tronpy/async_tron.py
315
316
def __init__(self, tron):
    self._tron = tron

account_permission_update

account_permission_update(owner: TAddress, perm: dict) -> AsyncTransactionBuilder

Update account permission.

Parameters:

Source code in tronpy/async_tron.py
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
def account_permission_update(self, owner: TAddress, perm: dict) -> "AsyncTransactionBuilder":
    """Update account permission.

    :param owner: Address of owner
    :param perm: Permission dict from [`get_account_permission`][tronpy.Tron.get_account_permission]
    """

    if "owner" in perm:
        for key in perm["owner"]["keys"]:
            key["address"] = keys.to_hex_address(key["address"])
    if "actives" in perm:
        for act in perm["actives"]:
            for key in act["keys"]:
                key["address"] = keys.to_hex_address(key["address"])
    if perm.get("witness"):
        for key in perm["witness"]["keys"]:
            key["address"] = keys.to_hex_address(key["address"])

    return self._build_transaction(
        "AccountPermissionUpdateContract",
        dict(owner_address=keys.to_hex_address(owner), **perm),
    )

account_update

account_update(owner: TAddress, name: str) -> AsyncTransactionBuilder

Update account name. An account can only set name once.

Source code in tronpy/async_tron.py
431
432
433
434
435
436
def account_update(self, owner: TAddress, name: str) -> "AsyncTransactionBuilder":
    """Update account name. An account can only set name once."""
    return self._build_transaction(
        "UpdateAccountContract",
        {"owner_address": keys.to_hex_address(owner), "account_name": name.encode().hex()},
    )

asset_issue

asset_issue(
    owner: TAddress,
    abbr: str,
    total_supply: int,
    *,
    url: str,
    name: str = None,
    description: str = "",
    start_time: int = None,
    end_time: int = None,
    precision: int = 6,
    frozen_supply: list = None,
    trx_num: int = 1,
    num: int = 1,
) -> AsyncTransactionBuilder

Issue a TRC10 token.

Almost all parameters have resonable defaults.

Source code in tronpy/async_tron.py
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
def asset_issue(
    self,
    owner: TAddress,
    abbr: str,
    total_supply: int,
    *,
    url: str,
    name: str = None,
    description: str = "",
    start_time: int = None,
    end_time: int = None,
    precision: int = 6,
    frozen_supply: list = None,
    trx_num: int = 1,
    num: int = 1,
) -> AsyncTransactionBuilder:
    """Issue a TRC10 token.

    Almost all parameters have resonable defaults.
    """
    if name is None:
        name = abbr

    if start_time is None:
        # use default expiration
        start_time = current_timestamp() + 60_000

    if end_time is None:
        # use default expiration
        end_time = current_timestamp() + 60_000 + 1

    if frozen_supply is None:
        frozen_supply = []

    return self._build_transaction(
        "AssetIssueContract",
        {
            "owner_address": keys.to_hex_address(owner),
            "abbr": abbr.encode().hex(),
            "name": name.encode().hex(),
            "total_supply": total_supply,
            "precision": precision,
            "url": url.encode().hex(),
            "description": description.encode().hex(),
            "start_time": start_time,
            "end_time": end_time,
            "frozen_supply": frozen_supply,
            "trx_num": trx_num,
            "num": num,
            "public_free_asset_net_limit": 0,
            "free_asset_net_limit": 0,
        },
    )

asset_transfer

asset_transfer(
    from_: TAddress, to: TAddress, amount: int, token_id: int
) -> AsyncTransactionBuilder

Transfer TRC10 tokens.

Source code in tronpy/async_tron.py
340
341
342
343
344
345
346
347
348
349
350
def asset_transfer(self, from_: TAddress, to: TAddress, amount: int, token_id: int) -> AsyncTransactionBuilder:
    """Transfer TRC10 tokens."""
    return self._build_transaction(
        "TransferAssetContract",
        {
            "owner_address": keys.to_hex_address(from_),
            "to_address": keys.to_hex_address(to),
            "amount": amount,
            "asset_name": str(token_id).encode().hex(),
        },
    )

create_witness

create_witness(owner: TAddress, url: str) -> AsyncTransactionBuilder

Create a new witness, will consume 1_000 TRX.

Source code in tronpy/async_tron.py
542
543
544
545
def create_witness(self, owner: TAddress, url: str) -> "AsyncTransactionBuilder":
    """Create a new witness, will consume 1_000 TRX."""
    payload = {"owner_address": keys.to_hex_address(owner), "url": url.encode().hex()}
    return self._build_transaction("WitnessCreateContract", payload)

delegate_resource

delegate_resource(
    owner: TAddress,
    receiver: TAddress,
    balance: int,
    resource: str = "BANDWIDTH",
    lock: bool = False,
    lock_period: int = None,
) -> AsyncTransactionBuilder

Delegate bandwidth or energy resources to other accounts in Stake2.0.

Parameters:

  • owner

    (TAddress) –
  • receiver

    (TAddress) –
  • balance

    (int) –
  • resource

    (str, default: 'BANDWIDTH' ) –

    Resource type, can be "ENERGY" or "BANDWIDTH"

  • lock

    (bool, default: False ) –

    Optionally lock delegated resources for 3 days.

  • lock_period

    (int, default: None ) –

    Optionally lock delegated resources for a specific period. Default: 3 days.

Source code in tronpy/async_tron.py
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
def delegate_resource(
    self,
    owner: TAddress,
    receiver: TAddress,
    balance: int,
    resource: str = "BANDWIDTH",
    lock: bool = False,
    lock_period: int = None,
) -> "AsyncTransactionBuilder":
    """Delegate bandwidth or energy resources to other accounts in Stake2.0.

    :param owner:
    :param receiver:
    :param balance:
    :param resource: Resource type, can be ``"ENERGY"`` or ``"BANDWIDTH"``
    :param lock: Optionally lock delegated resources for 3 days.
    :param lock_period: Optionally lock delegated resources for a specific period. Default: 3 days.
    """

    payload = {
        "owner_address": keys.to_hex_address(owner),
        "receiver_address": keys.to_hex_address(receiver),
        "balance": balance,
        "resource": resource,
        "lock": lock,
    }
    if lock_period is not None:
        payload["lock_period"] = lock_period

    return self._build_transaction("DelegateResourceContract", payload)

deploy_contract

deploy_contract(owner: TAddress, contract: AsyncContract) -> AsyncTransactionBuilder

Deploy a new contract on chain.

Source code in tronpy/async_tron.py
560
561
562
563
564
565
566
567
def deploy_contract(self, owner: TAddress, contract: AsyncContract) -> "AsyncTransactionBuilder":
    """Deploy a new contract on chain."""
    contract._client = self.client
    contract.owner_address = owner
    contract.origin_address = owner
    contract.contract_address = None

    return contract.deploy()

freeze_balance

freeze_balance(
    owner: TAddress, amount: int, resource: str = "ENERGY"
) -> AsyncTransactionBuilder

Freeze balance to get energy or bandwidth, for 3 days.

Parameters:

  • resource

    (str, default: 'ENERGY' ) –

    Resource type, can be "ENERGY" or "BANDWIDTH"

Source code in tronpy/async_tron.py
438
439
440
441
442
443
444
445
446
447
448
def freeze_balance(self, owner: TAddress, amount: int, resource: str = "ENERGY") -> "AsyncTransactionBuilder":
    """Freeze balance to get energy or bandwidth, for 3 days.

    :param resource: Resource type, can be ``"ENERGY"`` or ``"BANDWIDTH"``
    """
    payload = {
        "owner_address": keys.to_hex_address(owner),
        "frozen_balance": amount,
        "resource": resource,
    }
    return self._build_transaction("FreezeBalanceV2Contract", payload)

transfer

transfer(from_: TAddress, to: TAddress, amount: int) -> AsyncTransactionBuilder

Transfer TRX. amount in SUN.

Source code in tronpy/async_tron.py
331
332
333
334
335
336
def transfer(self, from_: TAddress, to: TAddress, amount: int) -> AsyncTransactionBuilder:
    """Transfer TRX. ``amount`` in `SUN`."""
    return self._build_transaction(
        "TransferContract",
        {"owner_address": keys.to_hex_address(from_), "to_address": keys.to_hex_address(to), "amount": amount},
    )

undelegate_resource

undelegate_resource(
    owner: TAddress, receiver: TAddress, balance: int, resource: str = "BANDWIDTH"
) -> AsyncTransactionBuilder

Cancel the delegation of bandwidth or energy resources to other accounts in Stake2.0

Parameters:

  • owner

    (TAddress) –
  • receiver

    (TAddress) –
  • balance

    (int) –
  • resource

    (str, default: 'BANDWIDTH' ) –

    Resource type, can be "ENERGY" or "BANDWIDTH"

Source code in tronpy/async_tron.py
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
def undelegate_resource(
    self, owner: TAddress, receiver: TAddress, balance: int, resource: str = "BANDWIDTH"
) -> "AsyncTransactionBuilder":
    """Cancel the delegation of bandwidth or energy resources to other accounts in Stake2.0

    :param owner:
    :param receiver:
    :param balance:
    :param resource: Resource type, can be ``"ENERGY"`` or ``"BANDWIDTH"``
    """

    payload = {
        "owner_address": keys.to_hex_address(owner),
        "receiver_address": keys.to_hex_address(receiver),
        "balance": balance,
        "resource": resource,
    }

    return self._build_transaction("UnDelegateResourceContract", payload)

unfreeze_balance

unfreeze_balance(
    owner: TAddress, resource: str = "ENERGY", *, unfreeze_balance: int
) -> AsyncTransactionBuilder

Unfreeze balance to get TRX back.

Parameters:

  • resource

    (str, default: 'ENERGY' ) –

    Resource type, can be "ENERGY" or "BANDWIDTH"

Source code in tronpy/async_tron.py
460
461
462
463
464
465
466
467
468
469
470
471
472
def unfreeze_balance(
    self, owner: TAddress, resource: str = "ENERGY", *, unfreeze_balance: int
) -> "AsyncTransactionBuilder":
    """Unfreeze balance to get TRX back.

    :param resource: Resource type, can be ``"ENERGY"`` or ``"BANDWIDTH"``
    """
    payload = {
        "owner_address": keys.to_hex_address(owner),
        "unfreeze_balance": unfreeze_balance,
        "resource": resource,
    }
    return self._build_transaction("UnfreezeBalanceV2Contract", payload)

unfreeze_balance_legacy

unfreeze_balance_legacy(
    owner: TAddress, resource: str = "ENERGY", receiver: TAddress = None
) -> AsyncTransactionBuilder

Unfreeze balance to get TRX back.

Parameters:

  • resource

    (str, default: 'ENERGY' ) –

    Resource type, can be "ENERGY" or "BANDWIDTH"

Source code in tronpy/async_tron.py
474
475
476
477
478
479
480
481
482
483
484
485
486
487
def unfreeze_balance_legacy(
    self, owner: TAddress, resource: str = "ENERGY", receiver: TAddress = None
) -> "AsyncTransactionBuilder":
    """Unfreeze balance to get TRX back.

    :param resource: Resource type, can be ``"ENERGY"`` or ``"BANDWIDTH"``
    """
    payload = {
        "owner_address": keys.to_hex_address(owner),
        "resource": resource,
    }
    if receiver is not None:
        payload["receiver_address"] = keys.to_hex_address(receiver)
    return self._build_transaction("UnfreezeBalanceContract", payload)

vote_witness

vote_witness(owner: TAddress, *votes: tuple[TAddress, int]) -> AsyncTransactionBuilder

Vote for witnesses. Empty votes to clean voted.

Source code in tronpy/async_tron.py
547
548
549
550
551
def vote_witness(self, owner: TAddress, *votes: tuple[TAddress, int]) -> "AsyncTransactionBuilder":
    """Vote for witnesses. Empty ``votes`` to clean voted."""
    votes = [{"vote_address": keys.to_hex_address(addr), "vote_count": count} for addr, count in votes]
    payload = {"owner_address": keys.to_hex_address(owner), "votes": votes}
    return self._build_transaction("VoteWitnessContract", payload)

withdraw_rewards

withdraw_rewards(owner: TAddress) -> AsyncTransactionBuilder

Withdraw voting rewards.

Source code in tronpy/async_tron.py
553
554
555
556
def withdraw_rewards(self, owner: TAddress) -> "AsyncTransactionBuilder":
    """Withdraw voting rewards."""
    payload = {"owner_address": keys.to_hex_address(owner)}
    return self._build_transaction("WithdrawBalanceContract", payload)

withdraw_stake_balance

withdraw_stake_balance(owner: TAddress) -> AsyncTransactionBuilder

Withdraw all stake v2 balance after waiting for 14 days since unfreeze_balance call.

Parameters:

  • owner

    (TAddress) –
Source code in tronpy/async_tron.py
450
451
452
453
454
455
456
457
458
def withdraw_stake_balance(self, owner: TAddress) -> "AsyncTransactionBuilder":
    """Withdraw all stake v2 balance after waiting for 14 days since unfreeze_balance call.

    :param owner:
    """
    payload = {
        "owner_address": keys.to_hex_address(owner),
    }
    return self._build_transaction("WithdrawExpireUnfreezeContract", payload)