diff --git a/api/tronscan.py b/api/tronscan.py index f6f89a6..bba386f 100644 --- a/api/tronscan.py +++ b/api/tronscan.py @@ -16,14 +16,246 @@ class Tronscan: def accountv2(self, address): """ - - :param address: - :return: + Get account detail information + :param address: Account address + :return: Returns the detail information of an account. """ response = requests.get(f"https://apilist.tronscanapi.com/api/accountv2?address={address}", headers={'TRON-PRO-API-KEY': self.api_key}) return response.json() + def transactions(self, start=0, limit=10, start_timestamp=None, end_timestamp=None, + fromAddress=None, toAddress=None, tokens=None, block=None, + type=None, method=None): + """ + Get a list of transactions. + :param start: Start number. Default 0 + :param limit: Number of items per page. Default 10 + :param start_timestamp: Start time + :param end_timestamp: End time + :param fromAddress: Sender's address. + :param toAddress: Recipient's address. + :param tokens: Tokens involved + :param block: Block + :param type: Transaction type + :param method: Method called in a smart contract signature. Only one value can be specified each time. + :return: Getx a list of transactions. + """ + params = { + "sort": "-timestamp", + "count": "true", + "start": start, + "limit": limit, + } + + if start_timestamp is not None: + params["start_timestamp"] = start_timestamp + if end_timestamp is not None: + params["end_timestamp"] = end_timestamp + if fromAddress is not None: + params["fromAddress"] = fromAddress + if toAddress is not None: + params["toAddress"] = toAddress + if tokens is not None: + params["tokens"] = tokens + if block is not None: + params["block"] = block + if type is not None: + params["type"] = type + if method is not None: + params["method"] = method + + response = requests.get( + "https://apilist.tronscanapi.com/api/transaction", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params + ) + return response.json() + + def transaction_info(self, hash_): + """ + Get transaction detail information by transaction hash. + :param hash_: Transaction hash + :return: Get transaction information. + """ + params = { + "hash": hash_, + } + response = requests.get( + "https://apilist.tronscanapi.com/api/transaction-info", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params + ) + return response.json() + + def token_trc20_transfers(self, start=0, limit=10, contract_address=None, + start_timestamp=None, end_timestamp=None, confirm=True, + related_address=None, from_address=None, to_address=None): + """ + Get the transfer list of TRC20 and TRC721 tokens. + :param start: Start number. Default 0 + :param limit: Number of items per page. Default 10 + :param contract_address: Contract address + :param start_timestamp: Start time + :param end_timestamp: End time + :param confirm: Whether to return confirmed transfers only. Default: True + :param related_address: Account address + :param from_address: Sender's address + :param to_address: Recipient's address + :return: Get the transfer list of TRC20 and TRC721 tokens. + """ + params = { + "start": start, + "limit": limit, + "filterTokenValue": 1 + } + + if contract_address is not None: + params["contract_address"] = contract_address + if start_timestamp is not None: + params["start_timestamp"] = start_timestamp + if end_timestamp is not None: + params["end_timestamp"] = end_timestamp + if confirm is not None: + params["confirm"] = str(confirm).lower() + if related_address is not None: + params["relatedAddress"] = related_address + if from_address is not None: + params["fromAddress"] = from_address + if to_address is not None: + params["toAddress"] = to_address + + response = requests.get( + "https://apilist.tronscanapi.com/api/token_trc20/transfers", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params + ) + return response.json() + + def transfer(self, sort="-timestamp", start=0, limit=10, count="true", + address=None, from_address=None, to_address=None, tokens=None, block=None): + """ + Get account's transfer list. + :param sort: Sort type + :param start: Start index, default is 0 + :param limit: Number of transfers per page + :param count: Whether to return total transfer number. + :param address: Address, like contract address + :param from_address: Sender's address + :param to_address: Recipient's address + :param tokens: Specific tokens + :param block: Block number + :return: Get account's transfer list. + """ + params = { + "sort": sort, + "start": start, + "limit": limit, + "count": count, + "filterTokenValue": 1 + } + + if address is not None: + params["address"] = address + if from_address is not None: + params["fromAddress"] = from_address + if to_address is not None: + params["toAddress"] = to_address + if tokens is not None: + params["tokens"] = tokens + if block is not None: + params["block"] = block + + response = requests.get( + "https://apilist.tronscanapi.com/api/transfer", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params + ) + return response.json() + + def internal_transactions(self, start=0, limit=10, address=None, contract=None, block=None): + """ + Get internal transaction list for a specific address or block. + :param start: Start index, default is 0 + :param limit: Number of transfers per page + :param address: Specific address. At least one of address, block, or contract must be specified + :param contract: Sender's address + :param block: Block number + :return: Get the internal transaction list. + """ + params = { + "start": start, + "limit": limit + } + + if address is not None: + params["address"] = address + if contract is not None: + params["contract"] = contract + if block is not None: + params["block"] = block + + response = requests.get( + "https://apilist.tronscanapi.com/api/internal-transaction", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params + ) + return response.json() + + def token_trc20_transfers_with_status(self, start=0, limit=10, trc20Id=None, address=None, + direction=0, db_version=0, reverse="false"): + """ + Get account's transaction data. + :param start: Start index, default is 0 + :param limit: Number of transfers per page + :param trc20Id: TRC20 token address + :param address: Account address + :param direction: 0 for all, 1 for transfer-out, 2 for transfer-in + :param db_version: Whether to include approval transfers. 1 for include, 0 for exclude + :param reverse: Sort by creation time. Valid values: "true" or "false" + :return: Get account's transaction data. + """ + params = { + "start": start, + "limit": limit, + "direction": direction, + "db_version": db_version, + "reverse": reverse + } + + if trc20Id is not None: + params["trc20Id"] = trc20Id + if address is not None: + params["address"] = address + + response = requests.get( + "https://apilist.tronscanapi.com/api/token_trc20/transfers-with-status", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params + ) + return response.json() + + def search(self, term, type="token", start=0, limit=10): + """ + Search token/contract/account information + Note : The maximum value for limit is 50. + :param term: Search term + :param type: Search type, including "token", "address", "contract", "transaction" and "block" + :param start: Start number. Default: 0 + :param limit: Number of items per page. Default: 10 + :return: Returns account authorization change records. + """ + params = { + "term": term, + "type": type, + "start": start, + "limit": limit, + } + response = requests.get("https://apilist.tronscanapi.com/api/search/v2", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params) + return response.json() + def approve_change(self, contract_address, from_address, to_address, start=0, limit=20, show=3): """ Returns account authorization change records. @@ -44,16 +276,16 @@ class Tronscan: "show": show, "type": "approve", } - headers = {'TRON-PRO-API-KEY': self.api_key} response = requests.get("https://apilist.tronscanapi.com/api/account/approve/change", - headers=headers, params=params) + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params) return response.json() def transfer_trx(self, address, start_timestamp=None, end_timestamp=None, start=0, limit=20, direction=1, db_version=0, reverse=True, fee=False): """ - Returns the list of TRX transfers for a specific address. + Get the list of trx transfers related to a specific address Note : The value sum of start and limit must be less than or equal to 10000. :param address: Query address :param start_timestamp: Start timestamp @@ -64,7 +296,7 @@ class Tronscan: :param db_version: Default: 0, which indicates to filter transfers with invalid “to” or “from” addresses out. :param reverse: Sort the data in a descending order. Default: true :param fee: Whether to return data of TRX burning for resource consumption. Default: false - :return: + :return: Returns the list of TRX transfers for a specific address. """ params = { "address": address, @@ -77,15 +309,15 @@ class Tronscan: "reverse": reverse, "fee": fee, } - headers = {'TRON-PRO-API-KEY': self.api_key} response = requests.get("https://apilist.tronscanapi.com/api/transfer/trx", - headers=headers, params=params) + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params) return response.json() def transfer_token10(self, address, trc10Id, start_timestamp=None, end_timestamp=None, start=0, limit=20, direction=1, db_version=0, reverse=True): """ - Returns the transfer list of a TRC10 token for a specific account. + Get the transfer list of a specific TRC10 token for a certain address Note : The value sum of start and limit must be less than or equal to 10000. :param address: Query address :param trc10Id: TRC10 token ID @@ -96,7 +328,7 @@ class Tronscan: :param direction: Default: 1. 1 represents inbound transfers, 2 represents outbound transfers, and 0 represents both. :param db_version: Default: 0, which indicates to filter transfers with invalid “to” or “from” addresses out. :param reverse: Sort the data in a descending order. Default: true - :return: + :return: Returns the transfer list of a TRC10 token for a specific account. """ params = { "address": address, @@ -109,15 +341,15 @@ class Tronscan: "db_version": db_version, "reverse": reverse, } - headers = {'TRON-PRO-API-KEY': self.api_key} response = requests.get("https://apilist.tronscanapi.com/api/transfer/token10", - headers=headers, params=params) + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params) return response.json() def transfer_trc20(self, address, trc20Id, start_timestamp=None, end_timestamp=None, start=0, limit=20, direction=1, db_version=0, reverse=True): """ - Returns the transfer list of a TRC20 token for a specific account. + Get the transfer list of a specific TRC20 token for a certain address Note : The value sum of start and limit must be less than or equal to 10000. :param address: Query address :param trc20Id: TRC20 token ID @@ -128,7 +360,7 @@ class Tronscan: :param direction: Default: 1. 1 represents inbound transfers, 2 represents outbound transfers, and 0 represents both. :param db_version: Default: 0, which indicates to filter transfers with invalid “to” or “from” addresses out. :param reverse: Sort the data in a descending order. Default: true - :return: + :return: Returns the transfer list of a TRC20 token for a specific account. """ params = { "address": address, @@ -141,7 +373,29 @@ class Tronscan: "db_version": db_version, "reverse": reverse, } - headers = {'TRON-PRO-API-KEY': self.api_key} response = requests.get("https://apilist.tronscanapi.com/api/transfer/trc20", - headers=headers, params=params) + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params) return response.json() + + def account_wallet(self, address, asset_type=0): + """ + Get the information of tokens held and followed in the account's web wallet + :param address: Query address + :param asset_type: Asset types: 0 - All (default); 1 - Assets (TRX, TRC10, TRC20); 2 - Collectibles (TRC721 and TRC1155) + :return: Returns a list of tokens held and followed by an account. + """ + params = { + "address": address, + "asset_type": asset_type, + } + response = requests.get("https://apilist.tronscanapi.com/api/account/wallet", + headers={'TRON-PRO-API-KEY': self.api_key}, + params=params) + return response.json() + + +if __name__ == '__main__': + address = "TB592A5QwHvvcJoCmvALmzT3S9Pux91Gub" + tronscan = Tronscan(api_key='cc87d361-7cd6-4f69-a57b-f0a77a213355') + print(tronscan.transfer_trc20(address, trc20token_info["usdt"]["tokenId"])) diff --git a/tests/test_tronscan.py b/tests/test_tronscan.py new file mode 100644 index 0000000..f558fcd --- /dev/null +++ b/tests/test_tronscan.py @@ -0,0 +1,35 @@ +import unittest +from unittest.mock import patch + +from api import Tronscan + + +class TestExternalAPICalls(unittest.TestCase): + + def setUp(self): + # Setup code runs before every test method + self.tronscan = Tronscan(api_key='cc87d361-7cd6-4f69-a57b-f0a77a213355') + + @unittest.skip("Skipping this test temporarily") + @patch('requests.get') + def test_real_api_call(self, mock_get): + # Mocking API response + mock_response = { + "data": [{"name": "ExampleToken", "symbol": "ETK"}] + } + mock_get.return_value.status_code = 200 + mock_get.return_value.json.return_value = mock_response + + # Call the method + response = self.tronscan.search(term="example", type="token") + + # Assert the response + self.assertEqual(response, mock_response) + mock_get.assert_called_once_with( + "https://apilist.tronscanapi.com/api/search/v2", + headers={'TRON-PRO-API-KEY': self.api_key}, + params={"term": "example", "type": "token", "start": 0, "limit": 10} + ) + +if __name__ == "__main__": + unittest.main()