One async-native client, usable from sync code through universalasync. AsyncTron and the other Async* names remain as aliases for compatibility, but aren't recommended: drop the prefix. See the migration notes
Breaking: requests is removed. Sync users catch httpx2 exceptions, HTTPProvider.sess is gone, TLS uses the OS trust store and redirects are no longer followed
Breaking: asyncio.run(client.method()) raises ValueError (TypeError on Python 3.14+) after the call has already run, so asyncio.run(tx.broadcast()) sends and then raises. Wrap it in async def main()
Breaking: sync-style calls inside a running event loop return a coroutine
Breaking: type checkers see the methods as async, so typed sync callers need cast or type: ignore
Breaking: custom providers need an async make_request
Breaking: Transaction(raw, client=c) no longer makes a network call, use Transaction.create. tronpy.tron.EMPTY is removed
Breaking: HTTPProvider arguments after timeout are keyword-only
Breaking: AsyncTron users now get ValueError when passing conf={"timeout": ...} along with a provider
HTTPProvider keeps one client per event loop, so Tron works across threads, repeated asyncio.run
Add HTTPProvider(client_factory=...) to use custom HTTP client settings on every event loop. A client passed with client= only applies to the event loop current when the provider is created
Fix broadcast raising KeyError in async code after sending, when a node omits txid
Breaking: the async client now uses httpx2 instead of httpx. Build AsyncHTTPProvider(client=...) clients and catch timeouts and other HTTP errors from httpx2. TLS verification now uses the OS trust store instead of certifi
Breaking: Tron and AsyncTron now raise ValueError on an unknown network, instead of silently connecting to mainnet or to TRONPY_HTTP_PROVIDER_URI
Move as_shielded_trc20 from ContractMethod, where it always raised TypeError, to Contract
Fix AsyncTron.get_contract_as_shielded_trc20 returning the sync wrapper, and AsyncShieldedTRC20 failing on mint, transfer and burn, or on a second read of trc20 or scale_factor
Tron.get_asset now raises ValueError when given both an id and an issuer, instead of returning the exception
is_note_spent now returns False instead of None when the node omits is_spent
Calling contract methods or printing them no longer raises AttributeError when their ABI has no stateMutability
Broadcasting or updating a transaction without a client now raises a clear TypeError instead of AttributeError
Signing a transaction that has no client and no known permission no longer raises TypeError
Report the actual number of arguments when contract methods and constructors get a wrong number of keyword arguments
BaseKey is now abstract. It could already only be built without arguments, and the result had no key data
Annotate the whole package, check it with mypy in CI, and ship a py.typed marker so type checkers use these annotations