diff --git a/API_REFERENCE.md b/API_REFERENCE.md index c6f1dac..52a88b8 100644 --- a/API_REFERENCE.md +++ b/API_REFERENCE.md @@ -64,7 +64,7 @@ EVM methods support Ethereum, Polygon, BSC, Arbitrum, Optimism, Avalanche, Base, ### EVM Balances -#### `api.evm.balances(address, contract=None, limit=10, page=1, network=None)` +#### `api.evm.balances(address, contract=None, limit=10, page=1, network=None, chain=None)` Get ERC-20 token balances for a wallet address. @@ -74,6 +74,7 @@ Get ERC-20 token balances for a wallet address. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[Balance]`: List of balance objects with structured data access @@ -92,7 +93,7 @@ usdc_balance = await api.evm.balances( # Query different network polygon_balances = await api.evm.balances( "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", - network="matic" # or NetworkId.MATIC + chain="matic" # or NetworkId.MATIC ) # Access structured data with clean attribute syntax @@ -132,7 +133,7 @@ for balance in balances: ### EVM NFTs -#### `api.evm.nfts.ownerships(address, token_standard=None, limit=10, page=1, network=None)` +#### `api.evm.nfts.ownerships(address, token_standard=None, limit=10, page=1, network=None, chain=None)` Get NFT ownerships for a wallet address. @@ -142,6 +143,7 @@ Get NFT ownerships for a wallet address. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[NFTOwnership]`: List of NFT ownership objects with structured data access @@ -158,13 +160,14 @@ erc721_nfts = await api.evm.nfts.ownerships( ) ``` -#### `api.evm.nfts.collection(contract, network=None)` +#### `api.evm.nfts.collection(contract, network=None, chain=None)` Get NFT collection metadata by contract address. **Parameters:** - `contract` (str, required): NFT contract address - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `Optional[NFTCollection]`: Collection metadata object or None if not found @@ -177,7 +180,7 @@ print(f"Collection: {collection.name} ({collection.symbol})") print(f"Total Supply: {collection.total_supply}") ``` -#### `api.evm.nfts.activities(contract, from_address=None, to_address=None, any_address=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None)` +#### `api.evm.nfts.activities(contract, from_address=None, to_address=None, any_address=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None, chain=None)` Get NFT activities (transfers, mints, burns) for a contract. @@ -193,6 +196,7 @@ Get NFT activities (transfers, mints, burns) for a contract. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[NFTActivity]`: List of NFT activity objects with structured data access @@ -220,7 +224,7 @@ recent_activities = await api.evm.nfts.activities( ) ``` -#### `api.evm.nfts.item(contract, token_id, network=None)` +#### `api.evm.nfts.item(contract, token_id, network=None, chain=None)` Get specific NFT item metadata by contract and token ID. @@ -228,6 +232,7 @@ Get specific NFT item metadata by contract and token ID. - `contract` (str, required): NFT contract address - `token_id` (str, required): Token ID - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `Optional[NFTItem]`: NFT item metadata object or None if not found @@ -244,13 +249,14 @@ print(f"Owner: {nft_item.owner}") print(f"Attributes: {nft_item.attributes or []}") ``` -#### `api.evm.nfts.holders(contract, network=None)` +#### `api.evm.nfts.holders(contract, network=None, chain=None)` Get NFT holders for a contract address. **Parameters:** - `contract` (str, required): NFT contract address - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[NFTHolder]`: List of NFT holder objects with structured data access @@ -265,7 +271,7 @@ for holder in holders: print(f"Percentage: {holder.percentage:.2f}%") ``` -#### `api.evm.nfts.sales(contract=None, token_id=None, any_address=None, offerer=None, recipient=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None)` +#### `api.evm.nfts.sales(contract=None, token_id=None, any_address=None, offerer=None, recipient=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None, chain=None)` Get NFT marketplace sales data. @@ -282,6 +288,7 @@ Get NFT marketplace sales data. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[NFTSale]`: List of NFT sale objects with structured data access @@ -313,13 +320,14 @@ recent_sales = await api.evm.nfts.sales( ### EVM Tokens -#### `api.evm.token_info(contract, network=None)` +#### `api.evm.token_info(contract, network=None, chain=None)` Get token contract metadata and information. **Parameters:** - `contract` (str, required): Token contract address - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `Optional[Token]`: Token information object or None if not found @@ -333,7 +341,7 @@ print(f"Decimals: {token.decimals}") print(f"Price: ${token.price_usd}") ``` -#### `api.evm.token_holders(contract, limit=10, network=None)` +#### `api.evm.token_holders(contract, limit=10, network=None, chain=None)` Get token holder balances by contract address. @@ -341,6 +349,7 @@ Get token holder balances by contract address. - `contract` (str, required): Token contract address - `limit` (int, optional): Number of results to return (default: 10) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[TokenHolder]`: List of token holder objects with structured data access @@ -357,7 +366,7 @@ for holder in holders: ### EVM Transfers -#### `api.evm.transfers(from_address=None, to_address=None, contract=None, transaction_id=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None)` +#### `api.evm.transfers(from_address=None, to_address=None, contract=None, transaction_id=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None, chain=None)` Get ERC-20 token transfer events. @@ -373,6 +382,7 @@ Get ERC-20 token transfer events. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[Transfer]`: List of transfer objects with structured data access @@ -393,7 +403,7 @@ incoming = await api.evm.transfers(to_address="0xd8dA6BF26964aF9D7eEd9e03E53415D ### EVM Swaps -#### `api.evm.swaps(pool=None, caller=None, sender=None, recipient=None, protocol=None, transaction_id=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None)` +#### `api.evm.swaps(pool=None, caller=None, sender=None, recipient=None, protocol=None, transaction_id=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network=None, chain=None)` Get DEX swap transactions with filtering and time range support. @@ -411,6 +421,7 @@ Get DEX swap transactions with filtering and time range support. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[Swap]`: List of swap objects with structured data access @@ -427,7 +438,7 @@ v3_swaps = await api.evm.swaps(protocol="uniswap_v3") # or Protocol.UNISWAP_V3 pool_swaps = await api.evm.swaps(pool="0x3E456E2A71adafb6fe0AF8098334ee41ef53A7C6") ``` -#### `api.evm.swaps_advanced(...)` +#### `api.evm.swaps_advanced(..., network=None, chain=None)` Get DEX swap transactions with advanced filtering and time range support. @@ -444,6 +455,7 @@ Get DEX swap transactions with advanced filtering and time range support. - `order_direction` (OrderDirection, optional): Order direction (default: desc) - `limit` (int, optional): Number of results to return (default: 10) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[Swap]`: List of swap objects with structured data access @@ -468,7 +480,7 @@ recent_swaps = await api.evm.swaps_advanced( ### EVM Pools -#### `api.evm.pools(pool=None, factory=None, token=None, symbol=None, protocol=None, limit=10, page=1, network=None)` +#### `api.evm.pools(pool=None, factory=None, token=None, symbol=None, protocol=None, limit=10, page=1, network=None, chain=None)` Get DEX liquidity pool information. @@ -481,6 +493,7 @@ Get DEX liquidity pool information. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[Pool]`: List of pool objects with structured data access @@ -501,7 +514,7 @@ v3_pools = await api.evm.pools(protocol="uniswap_v3") # or Protocol.UNISWAP_V3 ### EVM Price Data -#### `api.evm.price_history(token, interval=Interval.ONE_HOUR, start_time=None, end_time=None, limit=24, page=1, network=None)` +#### `api.evm.price_history(token, interval=Interval.ONE_HOUR, start_time=None, end_time=None, limit=24, page=1, network=None, chain=None)` Get OHLC price data for a token. @@ -513,6 +526,7 @@ Get OHLC price data for a token. - `limit` (int, optional): Number of results to return (default: 24, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[PriceHistory]`: List of OHLC price objects with structured data access @@ -535,7 +549,7 @@ weekly_prices = await api.evm.price_history( ) ``` -#### `api.evm.pool_history(pool, interval=Interval.ONE_HOUR, start_time=None, end_time=None, limit=24, page=1, network=None)` +#### `api.evm.pool_history(pool, interval=Interval.ONE_HOUR, start_time=None, end_time=None, limit=24, page=1, network=None, chain=None)` Get OHLC data for a DEX pool. @@ -547,6 +561,7 @@ Get OHLC data for a DEX pool. - `limit` (int, optional): Number of results to return (default: 24, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[PoolHistory]`: List of OHLC pool data objects with structured data access @@ -565,7 +580,7 @@ pool_data = await api.evm.pool_history( ### EVM Historical Balances -#### `api.evm.historical_balances(address, interval=Interval.ONE_HOUR, contracts=None, start_time=None, end_time=None, limit=10, page=1, network=None)` +#### `api.evm.historical_balances(address, interval=Interval.ONE_HOUR, contracts=None, start_time=None, end_time=None, limit=10, page=1, network=None, chain=None)` Get historical ERC-20 & Native balances by wallet address with time intervals. @@ -578,6 +593,7 @@ Get historical ERC-20 & Native balances by wallet address with time intervals. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (NetworkId, optional): Network to query (default: mainnet) +- `chain` (NetworkId, optional): Alias for `network` **Returns:** - `List[HistoricalBalance]`: List of historical balance objects with structured data access @@ -677,7 +693,7 @@ SVM methods support Solana mainnet with SPL tokens and Solana DEXs. ### SVM Balances -#### `api.svm.balances(token_account=None, mint=None, program_id=None, limit=10, page=1, network="solana")` +#### `api.svm.balances(token_account=None, mint=None, program_id=None, limit=10, page=1, network="solana", chain=None)` Get Solana SPL token balances. @@ -688,6 +704,7 @@ Get Solana SPL token balances. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (SolanaNetworkId, optional): Solana network (default: solana) +- `chain` (SolanaNetworkId, optional): Alias for `network` **Returns:** - `List[SolanaBalance]`: List of Solana balance objects with structured data access @@ -735,7 +752,7 @@ token_2022_balances = await api.svm.balances( ### SVM Transfers -#### `api.svm.transfers(signature=None, program_id=None, mint=None, authority=None, source=None, destination=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network="solana")` +#### `api.svm.transfers(signature=None, program_id=None, mint=None, authority=None, source=None, destination=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network="solana", chain=None)` Get Solana SPL token transfer events. @@ -753,6 +770,7 @@ Get Solana SPL token transfer events. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (SolanaNetworkId, optional): Solana network (default: solana) +- `chain` (SolanaNetworkId, optional): Alias for `network` **Returns:** - `List[SolanaTransfer]`: List of Solana transfer objects with structured data access @@ -782,7 +800,7 @@ token_transfers = await api.svm.transfers( ### SVM Swaps -#### `api.svm.swaps(program_id, amm=None, amm_pool=None, user=None, input_mint=None, output_mint=None, signature=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network="solana")` +#### `api.svm.swaps(program_id, amm=None, amm_pool=None, user=None, input_mint=None, output_mint=None, signature=None, start_time=None, end_time=None, order_by=None, order_direction=None, limit=10, page=1, network="solana", chain=None)` Get Solana DEX swap transactions with time filtering support. @@ -801,6 +819,7 @@ Get Solana DEX swap transactions with time filtering support. - `limit` (int, optional): Number of results to return (default: 10, max: 1000) - `page` (int, optional): Page number for pagination (default: 1) - `network` (SolanaNetworkId, optional): Solana network (default: solana) +- `chain` (SolanaNetworkId, optional): Alias for `network` **Returns:** - `List[SolanaSwap]`: List of Solana swap objects with structured data access diff --git a/README.md b/README.md index 86297fc..5fbfe11 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,11 @@ async def main(): eth_nfts = await api.evm.nfts.ownerships("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045") eth_swaps = await api.evm.swaps(protocol=Protocol.UNISWAP_V3, limit=10) + # Override chain per call + polygon_balances = await api.evm.balances( + "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", chain="polygon" + ) + # SVM (Solana) sol_balances = await api.svm.balances(mint="So11111111111111111111111111111111111111112") sol_swaps = await api.svm.swaps(program_id=SwapPrograms.RAYDIUM, limit=10) @@ -54,6 +59,7 @@ Get your free API key at: [thegraph.market](https://thegraph.market) (click "Get - šŸ“¦ **Type Safety**: Full type hints and runtime validation - šŸš€ **Async/Await**: Built for modern Python async patterns - šŸ”„ **Auto Environment**: Loads API keys from `.env` automatically +- 🌐 **Chain Override**: Pass `chain="polygon"` to override the default ## API Structure diff --git a/examples/endpoints/evm/balances.py b/examples/endpoints/evm/balances.py index 5300914..cc6033e 100644 --- a/examples/endpoints/evm/balances.py +++ b/examples/endpoints/evm/balances.py @@ -36,6 +36,10 @@ async def main(): print("\nšŸŽÆ Specific Token:") imagine = await api.evm.balances(wallet, contract="0x6A1B2AE3a55B5661b40d86c2bF805f7DAdB16978", limit=1) + # Query Polygon instead of default chain + polygon = await api.evm.balances(wallet, limit=3, chain="polygon") + print(f"\nšŸ”€ Polygon Top Tokens: {len(polygon)} items") + if imagine: token = imagine[0] print(f" {token.symbol or 'TOKEN'}: {format_amount(token.value)}") diff --git a/examples/endpoints/svm/balances.py b/examples/endpoints/svm/balances.py index 84c7159..da58b2a 100644 --- a/examples/endpoints/svm/balances.py +++ b/examples/endpoints/svm/balances.py @@ -17,6 +17,10 @@ async def main(): print("\nSPL Token Balances:") balances = await api.svm.balances(limit=6) + # Query devnet for comparison + devnet = await api.svm.balances(limit=2, chain="solana-devnet") + print(f"\n🌐 Devnet Balances: {len(devnet)} items") + for i, balance in enumerate(balances, 1): mint = balance.mint[:10] + "..." amount = balance.amount diff --git a/src/thegraph_token_api/simple.py b/src/thegraph_token_api/simple.py index a6076f9..5ea388d 100644 --- a/src/thegraph_token_api/simple.py +++ b/src/thegraph_token_api/simple.py @@ -64,14 +64,22 @@ async def ownerships( token_standard: TokenStandard | str | None = None, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[NFTOwnership]: """Get NFT ownerships for an address.""" - data = await self._api._evm_nfts(address=address, token_standard=token_standard, limit=limit, network=network) + net = chain or network + data = await self._api._evm_nfts(address=address, token_standard=token_standard, limit=limit, network=net) return convert_list_to_models(data, NFTOwnership) - async def collection(self, contract: str, network: NetworkId | str | None = None) -> NFTCollection | None: + async def collection( + self, + contract: str, + network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, + ) -> NFTCollection | None: """Get NFT collection metadata by contract address.""" - data = await self._api._evm_nft_collection(contract=contract, network=network) + net = chain or network + data = await self._api._evm_nft_collection(contract=contract, network=net) return convert_to_model(data, NFTCollection) if data else None async def activities( @@ -81,21 +89,36 @@ async def activities( to_address: str | None = None, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[NFTActivity]: """Get NFT activities (transfers, mints, burns) for a contract.""" + net = chain or network data = await self._api._evm_nft_activities( - contract=contract, from_address=from_address, to_address=to_address, limit=limit, network=network + contract=contract, from_address=from_address, to_address=to_address, limit=limit, network=net ) return convert_list_to_models(data, NFTActivity) - async def item(self, contract: str, token_id: str, network: NetworkId | str | None = None) -> list[dict[str, Any]]: + async def item( + self, + contract: str, + token_id: str, + network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, + ) -> list[dict[str, Any]]: """Get specific NFT item metadata by contract and token ID.""" - data = await self._api._evm_nft_item(contract=contract, token_id=token_id, network=network) + net = chain or network + data = await self._api._evm_nft_item(contract=contract, token_id=token_id, network=net) return data.get("items", []) if data else [] - async def holders(self, contract: str, network: NetworkId | str | None = None) -> list[dict[str, Any]]: + async def holders( + self, + contract: str, + network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, + ) -> list[dict[str, Any]]: """Get NFT holders for a contract.""" - data = await self._api._evm_nft_holders(contract=contract, network=network) + net = chain or network + data = await self._api._evm_nft_holders(contract=contract, network=net) return data.get("holders", []) if data else [] async def sales( @@ -104,9 +127,11 @@ async def sales( token_id: str | None = None, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[dict[str, Any]]: """Get NFT marketplace sales.""" - data = await self._api._evm_nft_sales(contract=contract, token_id=token_id, limit=limit, network=network) + net = chain or network + data = await self._api._evm_nft_sales(contract=contract, token_id=token_id, limit=limit, network=net) return data.get("sales", []) if data else [] @@ -120,10 +145,16 @@ def __init__(self, api_instance): self.nfts = NFTWrapper(api_instance) async def balances( - self, address: str, contract: str | None = None, limit: int = 10, network: NetworkId | str | None = None + self, + address: str, + contract: str | None = None, + limit: int = 10, + network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[Balance]: """Get EVM token balances for an address.""" - data = await self._api._evm_balances(address=address, contract=contract, limit=limit, network=network) + net = chain or network + data = await self._api._evm_balances(address=address, contract=contract, limit=limit, network=net) return convert_list_to_models(data, Balance) async def historical_balances( @@ -133,16 +164,24 @@ async def historical_balances( interval: Interval | str = Interval.ONE_HOUR, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[dict[str, Any]]: """Get historical balance data for EVM addresses.""" + net = chain or network data = await self._api._evm_historical_balances( - address=address, contracts=contracts, interval=interval, limit=limit, network=network + address=address, contracts=contracts, interval=interval, limit=limit, network=net ) return data.get("balances", []) if data else [] - async def token_info(self, contract: str, network: NetworkId | str | None = None) -> Token | None: + async def token_info( + self, + contract: str, + network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, + ) -> Token | None: """Get EVM token contract information.""" - data = await self._api._evm_token_info(contract=contract, network=network) + net = chain or network + data = await self._api._evm_token_info(contract=contract, network=net) return convert_to_model(data, Token) if data else None async def transfers( @@ -152,10 +191,12 @@ async def transfers( contract: str | None = None, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[Transfer]: """Get EVM token transfer events.""" + net = chain or network data = await self._api._evm_transfers( - from_address=from_address, to_address=to_address, contract=contract, limit=limit, network=network + from_address=from_address, to_address=to_address, contract=contract, limit=limit, network=net ) return convert_list_to_models(data, Transfer) @@ -165,9 +206,11 @@ async def swaps( protocol: Protocol | str | None = None, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[Swap]: """Get EVM DEX swap transactions.""" - data = await self._api._evm_swaps(pool=pool, protocol=protocol, limit=limit, network=network) + net = chain or network + data = await self._api._evm_swaps(pool=pool, protocol=protocol, limit=limit, network=net) return convert_list_to_models(data, Swap) async def swaps_advanced( @@ -184,8 +227,10 @@ async def swaps_advanced( order_direction: OrderDirection | str = OrderDirection.DESC, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[Swap]: """Get EVM DEX swap transactions with advanced filtering.""" + net = chain or network data = await self._api._evm_swaps_advanced( pool=pool, caller=caller, @@ -198,7 +243,7 @@ async def swaps_advanced( order_by=order_by, order_direction=order_direction, limit=limit, - network=network, + network=net, ) return convert_list_to_models(data, Swap) @@ -209,9 +254,11 @@ async def pools( protocol: Protocol | str | None = None, limit: int = 10, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[Pool]: """Get EVM DEX liquidity pools.""" - data = await self._api._evm_pools(pool=pool, token=token, protocol=protocol, limit=limit, network=network) + net = chain or network + data = await self._api._evm_pools(pool=pool, token=token, protocol=protocol, limit=limit, network=net) return convert_list_to_models(data, Pool) async def price_history( @@ -221,10 +268,12 @@ async def price_history( days: int = 1, limit: int = 24, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[OHLC]: """Get EVM OHLC price data for a token.""" + net = chain or network data = await self._api._evm_price_history( - token=token, interval=interval, days=days, limit=limit, network=network + token=token, interval=interval, days=days, limit=limit, network=net ) return convert_list_to_models(data, OHLC) @@ -235,16 +284,23 @@ async def pool_history( days: int = 1, limit: int = 24, network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[OHLC]: """Get EVM OHLC data for a DEX pool.""" - data = await self._api._evm_pool_history(pool=pool, interval=interval, days=days, limit=limit, network=network) + net = chain or network + data = await self._api._evm_pool_history(pool=pool, interval=interval, days=days, limit=limit, network=net) return convert_list_to_models(data, OHLC) async def token_holders( - self, contract: str, limit: int = 10, network: NetworkId | str | None = None + self, + contract: str, + limit: int = 10, + network: NetworkId | str | None = None, + chain: NetworkId | str | None = None, ) -> list[TokenHolder]: """Get EVM token holder balances by contract address.""" - data = await self._api._evm_token_holders(contract=contract, limit=limit, network=network) + net = chain or network + data = await self._api._evm_token_holders(contract=contract, limit=limit, network=net) return convert_list_to_models(data, TokenHolder) @@ -267,8 +323,10 @@ async def swaps( end_time: int | None = None, limit: int = 10, network: SolanaNetworkId | str = SolanaNetworkId.SOLANA, + chain: SolanaNetworkId | str | None = None, ) -> list[SolanaSwap]: """Get SVM DEX swap transactions.""" + net = chain or network data = await self._api._svm_swaps( program_id=program_id, amm=amm, @@ -280,7 +338,7 @@ async def swaps( start_time=start_time, end_time=end_time, limit=limit, - network=network, + network=net, ) return convert_list_to_models(data, SolanaSwap) @@ -291,10 +349,12 @@ async def balances( program_id: SolanaPrograms | str | None = None, limit: int = 10, network: SolanaNetworkId | str = SolanaNetworkId.SOLANA, + chain: SolanaNetworkId | str | None = None, ) -> list[SolanaBalance]: """Get SVM token balances.""" + net = chain or network data = await self._api._svm_balances( - token_account=token_account, mint=mint, program_id=program_id, limit=limit, network=network + token_account=token_account, mint=mint, program_id=program_id, limit=limit, network=net ) return convert_list_to_models(data, SolanaBalance) @@ -308,8 +368,10 @@ async def transfers( destination: str | None = None, limit: int = 10, network: SolanaNetworkId | str = SolanaNetworkId.SOLANA, + chain: SolanaNetworkId | str | None = None, ) -> list[SolanaTransfer]: """Get SVM token transfers.""" + net = chain or network data = await self._api._svm_transfers( signature=signature, program_id=program_id, @@ -318,7 +380,7 @@ async def transfers( source=source, destination=destination, limit=limit, - network=network, + network=net, ) return convert_list_to_models(data, SolanaTransfer) diff --git a/tests/test_simple_api.py b/tests/test_simple_api.py index 1ebbcff..66e56a6 100644 --- a/tests/test_simple_api.py +++ b/tests/test_simple_api.py @@ -603,6 +603,16 @@ async def test_evm_wrapper_balances(self): assert result == ["balance"] + @pytest.mark.anyio + async def test_evm_wrapper_balances_chain_override(self): + """Chain parameter overrides default network.""" + api = TokenAPI(api_key="test_key", auto_load_env=False) + + with patch.object(api, "_evm_balances") as mock_balances: + mock_balances.return_value = [] + await api.evm.balances(address="0xtest", chain="polygon") + mock_balances.assert_called_with(address="0xtest", contract=None, limit=10, network="polygon") + @pytest.mark.anyio async def test_evm_wrapper_token_info_with_data(self): """Test EVMWrapper.token_info method with data.""" @@ -649,6 +659,22 @@ async def test_svm_wrapper_balances(self): assert result == ["solana_balance"] + @pytest.mark.anyio + async def test_svm_wrapper_balances_chain(self): + """Chain parameter forwards to network.""" + api = TokenAPI(api_key="test_key", auto_load_env=False) + + with patch.object(api, "_svm_balances") as mock_balances: + mock_balances.return_value = [] + await api.svm.balances(chain="solana-devnet") + mock_balances.assert_called_with( + token_account=None, + mint=None, + program_id=None, + limit=10, + network="solana-devnet", + ) + @pytest.mark.anyio async def test_svm_wrapper_swaps(self): """Test SVMWrapper.swaps method."""