Skip to content

Commit cfc3f88

Browse files
committed
Fix substrate.subscan API key not being sent in requests
Subscan disabled unauthenticated access. The `api_key` config field existed but was never passed to HTTP requests. Now sends `X-API-Key` header when configured. Skip substrate init tests when SUBSCAN_API_KEY is not set.
1 parent a330a8e commit cfc3f88

8 files changed

Lines changed: 24 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Releases prior to 7.0 has been removed from this file to declutter search result
1212

1313
- database: Fix exception when creating connections with aiosqlite==0.22.0.
1414
- evm.node: Retry JSON-RPC requests on "invalid block range params" error.
15+
- substrate.subscan: Pass `X-API-Key` header when `api_key` is configured.
1516

1617
## [8.5.1] - 2025-11-03
1718

docs/3.datasources/9.substrate_subscan.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ To use this datasource, add the following section in config:
1414
datasources:
1515
subscan:
1616
kind: substrate.subscan
17-
url: ${ETHERSCAN_URL:-https://api.subscan.io/api}
18-
api_key: ${ETHERSCAN_API_KEY:-''}
17+
url: ${SUBSCAN_URL:-https://api.subscan.io/api}
18+
api_key: ${SUBSCAN_API_KEY:-''}
1919
```
2020
2121
During initialization, DipDup will use this datasource to fetch contract ABIs. If your config contains definitions for multiple networks, you can assign the datasource explicitly in `substrate.subsquid` index definitions:

src/demo_substrate_events/dipdup.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ datasources:
1313
subscan:
1414
kind: substrate.subscan
1515
url: https://assethub-polkadot.api.subscan.io/api
16+
api_key: ${SUBSCAN_API_KEY:-}
1617
node:
1718
kind: substrate.node
1819
url: https://statemint.api.onfinality.io/rpc?apikey=${ONFINALITY_API_KEY:-''}

src/dipdup/datasources/substrate_subscan.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,24 @@ async def get_abi(self, address: str) -> AbiJson:
1414
async def run(self) -> None:
1515
pass
1616

17+
def _api_key_headers(self) -> dict[str, str]:
18+
if self._config.api_key:
19+
return {'X-API-Key': self._config.api_key}
20+
return {}
21+
1722
async def get_runtime_list(self) -> list[dict[str, Any]]:
1823
res = await self.request(
1924
'post',
2025
'scan/runtime/list',
26+
headers=self._api_key_headers(),
2127
)
2228
return cast('list[dict[str, Any]]', res['data']['list'])
2329

2430
async def get_runtime_metadata(self, spec_version: int) -> list[dict[str, Any]]:
2531
res = await self.request(
2632
'post',
2733
'scan/runtime/metadata',
34+
headers=self._api_key_headers(),
2835
json={'spec': spec_version},
2936
)
3037
return cast('list[dict[str, Any]]', res['data']['info']['metadata'])

src/dipdup/projects/demo_substrate_events/dipdup.yaml.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ datasources:
1313
subscan:
1414
kind: substrate.subscan
1515
url: https://assethub-polkadot.api.subscan.io/api
16+
api_key: ${SUBSCAN_API_KEY:-}
1617
node:
1718
kind: substrate.node
1819
url: https://statemint.api.onfinality.io/rpc?apikey=${ONFINALITY_API_KEY:-''}

src/dipdup/test.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from shutil import which
1515
from typing import TYPE_CHECKING
1616
from typing import Any
17+
from typing import cast
1718

1819
from dipdup.config import DipDupConfig
1920
from dipdup.config import HasuraConfig
@@ -98,7 +99,10 @@ async def run_postgres_container() -> PostgresDatabaseConfig:
9899
)
99100
atexit.register(postgres_container.stop)
100101
postgres_container.reload()
101-
postgres_ip = postgres_container.attrs['NetworkSettings']['IPAddress']
102+
103+
network_settings = postgres_container.attrs['NetworkSettings']
104+
ip = network_settings.get('IPAddress') or next(iter(network_settings['Networks'].values()))['IPAddress']
105+
postgres_ip = cast('str', ip)
102106

103107
while not postgres_container.exec_run('pg_isready').exit_code == 0:
104108
await asyncio.sleep(0.1)
@@ -126,7 +130,10 @@ async def run_hasura_container(postgres_ip: str) -> HasuraConfig:
126130
)
127131
atexit.register(hasura_container.stop)
128132
hasura_container.reload()
129-
hasura_ip = hasura_container.attrs['NetworkSettings']['IPAddress']
133+
134+
network_settings = hasura_container.attrs['NetworkSettings']
135+
ip = network_settings.get('IPAddress') or next(iter(network_settings['Networks'].values()))['IPAddress']
136+
hasura_ip = cast('str', ip)
130137

131138
return HasuraConfig(
132139
url=f'http://{hasura_ip}:8080',

tests/configs/common_substrate.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ datasources:
55
subscan:
66
kind: substrate.subscan
77
url: https://assethub-polkadot.api.subscan.io/api
8+
api_key: ${SUBSCAN_API_KEY:-}
89
node:
910
kind: substrate.node
1011
url: https://statemint.api.onfinality.io/rpc?apikey=${ONFINALITY_API_KEY:-''}

tests/test_demos.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ async def test_run_init(
292292
pytest.skip('Starknet tests require ALCHEMY_API_KEY environment variable')
293293
if 'substrate' in config and not {'ONFINALITY_API_KEY'} <= set(os.environ):
294294
pytest.skip('Substrate tests require ONFINALITY_API_KEY environment variable')
295+
if 'substrate' in config and cmd == 'init' and not {'SUBSCAN_API_KEY'} <= set(os.environ):
296+
pytest.skip('Substrate init tests require SUBSCAN_API_KEY environment variable')
295297

296298
async with AsyncExitStack() as stack:
297299
tmp_package_path, env = await stack.enter_async_context(

0 commit comments

Comments
 (0)