diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 21590c8..5eac568 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -15,7 +15,7 @@ jobs: #---------------------------------------------- # load pip cache if cache exists #---------------------------------------------- - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip @@ -35,7 +35,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: [ "3.8", "3.9", "3.10", "3.11" ] + python-version: [ "3.9", "3.10", "3.11" ] runs-on: "ubuntu-latest" steps: #---------------------------------------------- @@ -61,7 +61,7 @@ jobs: #---------------------------------------------- - name: Load cached venv id: cached-poetry-dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: .venv key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} diff --git a/README.md b/README.md index 0243148..04106ad 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Mainnet - Flare: `"flare"` - Gnosis Chain: `"gnosis"` - Scroll: `"scroll"` +- Stellar: `"stellar"` - Linea: `"linea"` - Xai: `"xai"` - Xlayer: `"xlayer"` @@ -118,19 +119,15 @@ Testnet - Ethereum Holesky: `"eth_holesky"` - Avalanche Fuji: `"avalanche_fuji"` - Polygon Amoy: `"polygon_amoy"` -- Optimism Testnet: `"optimism_testnet"` +- Optimism Sepolia: `"optimism_sepolia"` - Base Sepolia: `"base_sepolia"` - -Appchain - -- META Apes: `"bas_metaapes"` +- Neura Devnet `"neura_devnet"` +- Neura Testnet `"neura_testnet_v1"` Appchain Testnet -- META Apes Testnet: `"bas_metaapes_testnet"` -- Neura Devnet `"neura_devnet"` -- Neura Testnet `"neura_testnet_v1"` -- Incentiv Devnet `"incentiv_devnet"` +- Incentiv Devnet `"incentiv_devnet_v3"` +- Incentiv Testnet `"incentiv_testnet"` When passing blockchain, you can use one available from `types.py` (preferred) or just a string value. @@ -141,9 +138,6 @@ When passing blockchain, you can use one available from `types.py` (preferred) o Early Access - [`get_token_price_history`](#gettokenpricehistory--gettokenpricehistoryraw) -- [`get_account_balance_historical`](#getaccountbalancehistorical--getaccountbalancehistoricalraw) -- [`get_internal_transactions_by_block_number`](#getinternaltransactionsbyblocknumber--getinternaltransactionsbyblocknumberraw) -- [`get_internal_transactions_by_parent_hash`](#getinternaltransactionsbyparenthash--getinternaltransactionsbyparenthashraw) Token API @@ -208,68 +202,6 @@ result = advancedAPI.get_token_price_history( print(result) ``` -#### `get_account_balance_historical` / `get_account_balance_historical_raw` - -Get the coin and token balances of the wallet at specified block. - -```python3 -from ankr import AnkrAdvancedAPI -from ankr.types import Blockchain, GetAccountBalanceHistoricalRequest - -advancedAPI = AnkrAdvancedAPI("YOUR-TOKEN") - -result = advancedAPI.get_account_balance_historical( - request=GetAccountBalanceHistoricalRequest( - blockchain=Blockchain.Eth, - walletAddress='vitalik.eth', - onlyWhitelisted=False, - blockHeight=17967813, - ) -) -print(result) -``` - -#### `get_internal_transactions_by_block_number` / `get_internal_transactions_by_block_number_raw` - -Get a list of internal transactions in the block. - -```python3 -from ankr import AnkrAdvancedAPI -from ankr.types import Blockchain, GetInternalTransactionsByBlockNumberRequest - -advancedAPI = AnkrAdvancedAPI("YOUR-TOKEN") - -result = advancedAPI.get_internal_transactions_by_block_number( - request=GetInternalTransactionsByBlockNumberRequest( - blockchain=Blockchain.Eth, - blockNumber=10000000, - onlyWithValue=True, - ) -) -for transaction in result: - print(transaction) -``` - -#### `get_internal_transactions_by_parent_hash` / `get_internal_transactions_by_parent_hash_raw` - -Get a list of internal transactions in the transaction. - -```python3 -from ankr import AnkrAdvancedAPI -from ankr.types import Blockchain, GetInternalTransactionsByParentHashRequest - -advancedAPI = AnkrAdvancedAPI("YOUR-TOKEN") - -result = advancedAPI.get_internal_transactions_by_parent_hash( - request=GetInternalTransactionsByParentHashRequest( - blockchain=Blockchain.Eth, - parentTransactionHash='0xa50f8744e65cb76f66f9d54499d5401866a75d93db2e784952f55205afc3acc5', - onlyWithValue=True, - ) -) -for transaction in result: - print(transaction) -``` ### Token API diff --git a/ankr/advanced_apis.py b/ankr/advanced_apis.py index d08d388..5751917 100644 --- a/ankr/advanced_apis.py +++ b/ankr/advanced_apis.py @@ -44,87 +44,6 @@ def get_token_price_history_raw( return reply - def get_account_balance_historical( - self, - request: types.GetAccountBalanceHistoricalRequest, - limit: Optional[int] = None, - ) -> Iterable[types.Balance]: - for asset in self.provider.call_method_paginated( - rpc="ankr_getAccountBalanceHistorical", - request=request, - reply=types.GetAccountBalanceHistoricalReply, - iterable_name="assets", - iterable_type=types.Balance, - limit=limit, - ): - yield asset - - def get_account_balance_historical_raw( - self, - request: types.GetAccountBalanceHistoricalRequest, - ) -> types.GetAccountBalanceHistoricalReply: - reply = self.provider.call_method( - rpc="ankr_getAccountBalanceHistorical", - request=request, - reply=types.GetAccountBalanceReply, - ) - - return reply - - def get_internal_transactions_by_block_number( - self, - request: types.GetInternalTransactionsByBlockNumberRequest, - limit: Optional[int] = None, - ) -> Iterable[types.InternalTransaction]: - for asset in self.provider.call_method_paginated( - rpc="ankr_getInternalTransactionsByBlockNumber", - request=request, - reply=types.GetInternalTransactionsReply, - iterable_name="internalTransactions", - iterable_type=types.InternalTransaction, - limit=limit, - ): - yield asset - - def get_internal_transactions_by_block_number_raw( - self, - request: types.GetInternalTransactionsByBlockNumberRequest, - ) -> types.GetInternalTransactionsReply: - reply = self.provider.call_method( - rpc="ankr_getInternalTransactionsByBlockNumber", - request=request, - reply=types.GetInternalTransactionsReply, - ) - - return reply - - def get_internal_transactions_by_parent_hash( - self, - request: types.GetInternalTransactionsByParentHashRequest, - limit: Optional[int] = None, - ) -> Iterable[types.InternalTransaction]: - for asset in self.provider.call_method_paginated( - rpc="ankr_getInternalTransactionsByParentHash", - request=request, - reply=types.GetInternalTransactionsReply, - iterable_name="internalTransactions", - iterable_type=types.InternalTransaction, - limit=limit, - ): - yield asset - - def get_internal_transactions_by_parent_hash_raw( - self, - request: types.GetInternalTransactionsByBlockNumberRequest, - ) -> types.GetInternalTransactionsReply: - reply = self.provider.call_method( - rpc="ankr_getInternalTransactionsByParentHash", - request=request, - reply=types.GetInternalTransactionsReply, - ) - - return reply - class AnkrQueryAPI(AnkrMultichainAPI): def get_logs( diff --git a/ankr/types.py b/ankr/types.py index b20d0a2..b16028b 100644 --- a/ankr/types.py +++ b/ankr/types.py @@ -2013,238 +2013,6 @@ def from_dict(cls, **data): ) -class GetInternalTransactionsByParentHashRequest: - def __init__( - self, - blockchain: Blockchain, - onlyWithValue: bool, - parentTransactionHash: str, - syncCheck: bool = None, - ): - self.blockchain = blockchain - self.onlyWithValue = onlyWithValue - self.parentTransactionHash = parentTransactionHash - self.syncCheck = syncCheck - - def to_dict(self): - if isinstance(self.blockchain, str): - blockchain_value = self.blockchain - elif isinstance(self.blockchain, list): - blockchain_value = [ - block.value if isinstance(block, Blockchain) else block - for block in self.blockchain - ] - elif self.blockchain is not None: - blockchain_value = self.blockchain.value - else: - blockchain_value = None - return { - "blockchain": blockchain_value, - "onlyWithValue": self.onlyWithValue, - "parentTransactionHash": self.parentTransactionHash, - "syncCheck": self.syncCheck, - } - - -class GetInternalTransactionsByBlockNumberRequest: - def __init__( - self, - blockNumber: float, - blockchain: Blockchain, - onlyWithValue: bool, - syncCheck: bool = None, - ): - self.blockNumber = blockNumber - self.blockchain = blockchain - self.onlyWithValue = onlyWithValue - self.syncCheck = syncCheck - - def to_dict(self): - if isinstance(self.blockchain, str): - blockchain_value = self.blockchain - elif isinstance(self.blockchain, list): - blockchain_value = [ - block.value if isinstance(block, Blockchain) else block - for block in self.blockchain - ] - elif self.blockchain is not None: - blockchain_value = self.blockchain.value - else: - blockchain_value = None - return { - "blockNumber": self.blockNumber, - "blockchain": blockchain_value, - "onlyWithValue": self.onlyWithValue, - "syncCheck": self.syncCheck, - } - - -class InternalTransaction: - def __init__( - self, - blockHash: str, - blockHeight: float, - blockchain: Blockchain, - callType: str, - fromAddress: str, - gas: float, - gasUsed: float, - input: str, - output: str, - timestamp: str, - toAddress: str, - transactionHash: str, - transactionIndex: float, - value: str, - callPath: str = None, - callStack: List[float] = None, - error: str = None, - contractAddress: str = None, - ): - self.blockHash = blockHash - self.blockHeight = blockHeight - self.blockchain = blockchain - self.callType = callType - self.fromAddress = fromAddress - self.gas = gas - self.gasUsed = gasUsed - self.input = input - self.output = output - self.timestamp = timestamp - self.toAddress = toAddress - self.transactionHash = transactionHash - self.transactionIndex = transactionIndex - self.value = value - self.callPath = callPath - self.callStack = callStack - self.error = error - self.contractAddress = contractAddress - - @classmethod - def from_dict(cls, **data): - return cls( - blockHash=data.get("blockHash"), - blockHeight=data.get("blockHeight"), - blockchain=Blockchain(data.get("blockchain")), - callType=data.get("callType"), - fromAddress=data.get("fromAddress"), - gas=data.get("gas"), - gasUsed=data.get("gasUsed"), - input=data.get("input"), - output=data.get("output"), - timestamp=data.get("timestamp"), - toAddress=data.get("toAddress"), - transactionHash=data.get("transactionHash"), - transactionIndex=data.get("transactionIndex"), - value=data.get("value"), - callPath=data.get("callPath"), - callStack=data.get("callStack"), - error=data.get("error"), - contractAddress=data.get("contractAddress"), - ) - - -class GetInternalTransactionsReply: - def __init__( - self, internalTransactions: List[InternalTransaction], nextPageToken: str = None - ): - self.internalTransactions = internalTransactions - self.nextPageToken = nextPageToken - - @classmethod - def from_dict(cls, **data): - return cls( - internalTransactions=[ - InternalTransaction.from_dict(**internaltransaction_data) - for internaltransaction_data in data.get("internalTransactions", []) - ], - nextPageToken=data.get("nextPageToken"), - ) - - -class GetAccountBalanceHistoricalRequest: - def __init__( - self, - walletAddress: str, - blockchain: Blockchain | List[Blockchain] = None, - onlyWhitelisted: bool = None, - nativeFirst: bool = None, - pageToken: str = None, - pageSize: float = None, - blockHeight: float - | Literal[Literal["latest"]] - | Literal[Literal["earliest"]] = None, - syncCheck: bool = None, - ): - self.walletAddress = walletAddress - self.blockchain = blockchain - self.onlyWhitelisted = onlyWhitelisted - self.nativeFirst = nativeFirst - self.pageToken = pageToken - self.pageSize = pageSize - self.blockHeight = blockHeight - self.syncCheck = syncCheck - - def to_dict(self): - if isinstance(self.blockchain, str): - blockchain_value = self.blockchain - elif isinstance(self.blockchain, list): - blockchain_value = [ - block.value if isinstance(block, Blockchain) else block - for block in self.blockchain - ] - elif self.blockchain is not None: - blockchain_value = self.blockchain.value - else: - blockchain_value = None - return { - "walletAddress": self.walletAddress, - "blockchain": blockchain_value, - "onlyWhitelisted": self.onlyWhitelisted, - "nativeFirst": self.nativeFirst, - "pageToken": self.pageToken, - "pageSize": self.pageSize, - "blockHeight": self.blockHeight, - "syncCheck": self.syncCheck, - } - - -class GetAccountBalanceHistoricalReply: - def __init__( - self, - assets: List[Balance], - totalBalanceUsd: str, - totalCount: float, - nextPageToken: str = None, - syncStatus: SyncStatus = None, - blockHeight: float - | Literal[Literal["latest"]] - | Literal[Literal["earliest"]] = None, - ): - self.assets = assets - self.totalBalanceUsd = totalBalanceUsd - self.totalCount = totalCount - self.nextPageToken = nextPageToken - self.syncStatus = syncStatus - self.blockHeight = blockHeight - - @classmethod - def from_dict(cls, **data): - return cls( - assets=[ - Balance.from_dict(**balance_data) - for balance_data in data.get("assets", []) - ], - totalBalanceUsd=data.get("totalBalanceUsd"), - totalCount=data.get("totalCount"), - nextPageToken=data.get("nextPageToken"), - syncStatus=SyncStatus.from_dict(**data.get("syncStatus")) - if data.get("syncStatus") is not None - else None, - blockHeight=data.get("blockHeight"), - ) - - class Blockchain(Enum): Arbitrum = "arbitrum" Avalanche = "avalanche" @@ -2258,17 +2026,19 @@ class Blockchain(Enum): Fantom = "fantom" Flare = "flare" Gnosis = "gnosis" - Incentiv_devnet = "incentiv_devnet" + Incentiv_devnet_v3 = "incentiv_devnet_v3" + Incentiv_testnet = "incentiv_testnet" Linea = "linea" Neura_devnet = "neura_devnet" Neura_testnet_v1 = "neura_testnet_v1" Optimism = "optimism" - Optimism_testnet = "optimism_testnet" + Optimism_sepolia = "optimism_sepolia" Polygon = "polygon" Polygon_amoy = "polygon_amoy" Polygon_zkevm = "polygon_zkevm" Rollux = "rollux" Scroll = "scroll" + Stellar = "stellar" Syscoin = "syscoin" Telos = "telos" Xai = "xai" diff --git a/tests/test_client.py b/tests/test_client.py index cd10d19..bfd5bff 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -246,15 +246,3 @@ def test_get_token_price(client: AnkrAdvancedAPI) -> None: assert price assert float(price) > 0 - - -@pytest.mark.webtest -def test_get_token_price__no_price(client: AnkrAdvancedAPI) -> None: - price = client.get_token_price( - request=GetTokenPriceRequest( - contractAddress="0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - blockchain=Blockchain.Eth, - ) - ) - - assert price == "0"