Repository: rotki/rotki

Issue:
Allow addition of per-user Covalent API key
## Abstract

This is a follow up after https://github.com/rotki/rotki/pull/3242.

In that PR the Covalent API was added for the first time and it comes with a free built-in key.

But just like with etherscan, beaconchain etc. it would be beneficial to allow the user to input their own api key for their local rotki instance as they may have better rate limits etc.

## Task

- Allow addition of a Covalent API key by the user
- If the user has given an API key then use that one instead of the built-in one.
Allow addition of per-user Covalent API key
## Abstract

This is a follow up after https://github.com/rotki/rotki/pull/3242.

In that PR the Covalent API was added for the first time and it comes with a free built-in key.

But just like with etherscan, beaconchain etc. it would be beneficial to allow the user to input their own api key for their local rotki instance as they may have better rate limits etc.

## Task

- Allow addition of a Covalent API key by the user
- If the user has given an API key then use that one instead of the built-in one.


Discussion:

Resolving patch:
diff --git a/rotkehlchen/externalapis/covalent.py b/rotkehlchen/externalapis/covalent.py
--- a/rotkehlchen/externalapis/covalent.py
+++ b/rotkehlchen/externalapis/covalent.py
@@ -5,10 +5,12 @@
 import requests
 
 from rotkehlchen.constants.timing import DEFAULT_TIMEOUT_TUPLE
+from rotkehlchen.db.dbhandler import DBHandler
 from rotkehlchen.errors import DeserializationError, RemoteError
+from rotkehlchen.externalapis.interface import ExternalServiceWithApiKey
 from rotkehlchen.externalapis.utils import read_integer
 from rotkehlchen.logging import RotkehlchenLogsAdapter
-from rotkehlchen.typing import ChecksumEthAddress, CovalentTransaction, Timestamp
+from rotkehlchen.typing import ChecksumEthAddress, CovalentTransaction, ExternalService, Timestamp
 from rotkehlchen.user_messages import MessagesAggregator
 from rotkehlchen.utils.misc import create_timestamp, ts_now
 
@@ -66,12 +68,14 @@ def convert_transaction_from_covalent(
         ) from e
 
 
-class Covalent():
+class Covalent(ExternalServiceWithApiKey):
     def __init__(
             self,
+            database: DBHandler,
             msg_aggregator: MessagesAggregator,
             chain_id: int,
     ) -> None:
+        super().__init__(database=database, service_name=ExternalService.COVALENT)
         self.session = requests.session()
         self.session.headers.update({'User-Agent': 'rotkehlchen'})
         self.msg_aggregator = msg_aggregator
@@ -96,7 +100,8 @@ def _query(
             query_str += f'/{address}'
         query_str += f'/{module}/'
 
-        query_str += f'?key={KEY}'
+        own_key = self._get_api_key()
+        query_str += f'?key={own_key if own_key else KEY}'
 
         if options:
             for name, value in options.items():
diff --git a/rotkehlchen/rotkehlchen.py b/rotkehlchen/rotkehlchen.py
--- a/rotkehlchen/rotkehlchen.py
+++ b/rotkehlchen/rotkehlchen.py
@@ -293,6 +293,7 @@ def unlock_user(
             own_rpc_endpoint=settings.dot_rpc_endpoint,
         )
         self.covalent_avalanche = Covalent(
+            database=self.data.db,
             msg_aggregator=self.msg_aggregator,
             chain_id=chains_id['avalanche'],
         )
diff --git a/rotkehlchen/typing.py b/rotkehlchen/typing.py
--- a/rotkehlchen/typing.py
+++ b/rotkehlchen/typing.py
@@ -92,6 +92,7 @@ class ExternalService(SerializableEnumMixin):
     BEACONCHAIN = 2
     LOOPRING = 3
     OPENSEA = 4
+    COVALENT = 5
 
 
 class ExternalServiceApiCredentials(NamedTuple):


Test patch:
diff --git a/rotkehlchen/tests/fixtures/blockchain.py b/rotkehlchen/tests/fixtures/blockchain.py
--- a/rotkehlchen/tests/fixtures/blockchain.py
+++ b/rotkehlchen/tests/fixtures/blockchain.py
@@ -100,8 +100,8 @@ def fixture_etherscan(database, messages_aggregator):
 
 
 @pytest.fixture(name='covalent_avalanche')
-def fixture_covalent_avalanche(messages_aggregator):
-    return Covalent(msg_aggregator=messages_aggregator, chain_id='43114')
+def fixture_covalent_avalanche(messages_aggregator, database):
+    return Covalent(database=database, msg_aggregator=messages_aggregator, chain_id='43114')
 
 
 @pytest.fixture(name='ethereum_manager')