blockapi 2.3.3__tar.gz → 2.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {blockapi-2.3.3 → blockapi-2.3.4}/PKG-INFO +1 -1
  2. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/__init__.py +0 -1
  3. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/debank.py +30 -28
  4. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/coin_mapping.py +12 -0
  5. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/models.py +2 -81
  6. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi.egg-info/PKG-INFO +1 -1
  7. {blockapi-2.3.3 → blockapi-2.3.4}/setup.py +1 -1
  8. {blockapi-2.3.3 → blockapi-2.3.4}/LICENSE.md +0 -0
  9. {blockapi-2.3.3 → blockapi-2.3.4}/README.md +0 -0
  10. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/__init__.py +0 -0
  11. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/services.py +0 -0
  12. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/__init__.py +0 -0
  13. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/test_blockapi.py +0 -0
  14. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/test_num.py +0 -0
  15. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/test_random_user_agent.py +0 -0
  16. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/__init__.py +0 -0
  17. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/__init__.py +0 -0
  18. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/conftest.py +0 -0
  19. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/covalenth/__init__.py +0 -0
  20. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/covalenth/test_ethereum.py +0 -0
  21. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/fake_sleep_provider.py +0 -0
  22. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/nft/__init__.py +0 -0
  23. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/nft/test_magic_eden.py +0 -0
  24. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/nft/test_opensea.py +0 -0
  25. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/nft/test_simple_hash.py +0 -0
  26. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/nft/test_unisat.py +0 -0
  27. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/perpetual/__init__.py +0 -0
  28. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/perpetual/test_perpetual.py +0 -0
  29. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/synthetix/__init__.py +0 -0
  30. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/synthetix/test_synthetix.py +0 -0
  31. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_blockchainos.py +0 -0
  32. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_blockchair_btc.py +0 -0
  33. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_blockchair_doge.py +0 -0
  34. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_blockchair_ltc.py +0 -0
  35. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_cosmos.py +0 -0
  36. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_ethplorer.py +0 -0
  37. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_multisources.py +0 -0
  38. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_optimistic_etherscan.py +0 -0
  39. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_solana.py +0 -0
  40. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_subscan_polkadot.py +0 -0
  41. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_sui.py +0 -0
  42. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/api/test_trezor_btc.py +0 -0
  43. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_base.py +0 -0
  44. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_blockchain_api.py +0 -0
  45. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_blockchain_mapping.py +0 -0
  46. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_data.py +0 -0
  47. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_enumerate_classes.py +0 -0
  48. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_generic.py +0 -0
  49. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test/v2/test_models.py +0 -0
  50. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/test_data.py +0 -0
  51. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/utils/__init__.py +0 -0
  52. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/utils/address.py +0 -0
  53. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/utils/datetime.py +0 -0
  54. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/utils/num.py +0 -0
  55. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/utils/user_agent.py +0 -0
  56. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/__init__.py +0 -0
  57. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/blockchainos.py +0 -0
  58. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/blockchair.py +0 -0
  59. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/cosmos.py +0 -0
  60. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/__init__.py +0 -0
  61. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/arbitrum.py +0 -0
  62. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/astar.py +0 -0
  63. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/avalanche.py +0 -0
  64. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/axie.py +0 -0
  65. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/base.py +0 -0
  66. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/binance_smart_chain.py +0 -0
  67. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/ethereum.py +0 -0
  68. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/fantom.py +0 -0
  69. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/heco.py +0 -0
  70. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/iotex.py +0 -0
  71. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/klaytn.py +0 -0
  72. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/moonbeam.py +0 -0
  73. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/palm.py +0 -0
  74. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/polygon.py +0 -0
  75. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/covalenth/rsk.py +0 -0
  76. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/debank_maps.py +0 -0
  77. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/ethplorer.py +0 -0
  78. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/nft/__init__.py +0 -0
  79. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/nft/magic_eden.py +0 -0
  80. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/nft/opensea.py +0 -0
  81. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/nft/simple_hash.py +0 -0
  82. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/nft/unisat.py +0 -0
  83. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/optimistic_etherscan.py +0 -0
  84. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/perpetual/__init__.py +0 -0
  85. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/perpetual/perp_abi.py +0 -0
  86. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/perpetual/perpetual.py +0 -0
  87. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/solana.py +0 -0
  88. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/subscan.py +0 -0
  89. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/sui.py +0 -0
  90. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/synthetix/__init__.py +0 -0
  91. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/synthetix/synthetix.py +0 -0
  92. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/synthetix/synthetix_abi.py +0 -0
  93. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/terra.py +0 -0
  94. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/trezor.py +0 -0
  95. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/api/web3_utils.py +0 -0
  96. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/base.py +0 -0
  97. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/blockchain_mapping.py +0 -0
  98. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi/v2/coins.py +0 -0
  99. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi.egg-info/SOURCES.txt +0 -0
  100. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi.egg-info/dependency_links.txt +0 -0
  101. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi.egg-info/requires.txt +0 -0
  102. {blockapi-2.3.3 → blockapi-2.3.4}/blockapi.egg-info/top_level.txt +0 -0
  103. {blockapi-2.3.3 → blockapi-2.3.4}/pyproject.toml +0 -0
  104. {blockapi-2.3.3 → blockapi-2.3.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockapi
3
- Version: 2.3.3
3
+ Version: 2.3.4
4
4
  Summary: BlockAPI library
5
5
  Home-page: https://github.com/crypkit/blockapi
6
6
  Author: Devmons s.r.o.
@@ -8,7 +8,6 @@ from blockapi.v2.api.blockchair import (
8
8
  from blockapi.v2.api.debank import (
9
9
  DebankApi,
10
10
  DebankApp,
11
- DebankAppDeposit,
12
11
  DebankPrediction,
13
12
  )
14
13
  from blockapi.v2.api.ethplorer import EthplorerApi
@@ -5,7 +5,7 @@ from functools import lru_cache
5
5
  from typing import Dict, Iterable, List, Optional, Union
6
6
 
7
7
  import attr
8
- from pydantic import BaseModel, ValidationError, validator
8
+ from pydantic import BaseModel, validator
9
9
 
10
10
  from blockapi.utils.address import make_checksum_address
11
11
  from blockapi.utils.datetime import parse_dt
@@ -37,13 +37,12 @@ from blockapi.v2.models import (
37
37
  PoolInfo,
38
38
  Protocol,
39
39
  DebankApp,
40
- DebankAppDeposit,
41
40
  DebankPrediction,
42
41
  DebankModelAppPortfolioItem,
43
42
  DebankModelApp,
44
43
  DebankModelPredictionDetail,
45
- DebankDepositToken,
46
44
  )
45
+ from blockapi.v2.coin_mapping import symbol_to_coin_map
47
46
 
48
47
  logger = logging.getLogger(__name__)
49
48
 
@@ -601,10 +600,8 @@ class DebankPortfolioParser:
601
600
 
602
601
 
603
602
  class DebankAppParser:
604
- """Parser for Debank complex_app_list responses."""
605
603
 
606
604
  def parse(self, response: list) -> list[DebankApp]:
607
- """Parse the full response from get_complex_app_list."""
608
605
  if not response:
609
606
  return []
610
607
 
@@ -617,13 +614,17 @@ class DebankAppParser:
617
614
  return apps
618
615
 
619
616
  def _parse_app(self, raw_app: dict) -> Optional[DebankApp]:
620
- """Parse a single app from the response."""
621
617
  model = DebankModelApp(**raw_app)
622
618
 
623
619
  deposits = []
624
620
  predictions = []
625
621
 
626
622
  chain = DEBANK_APP_CHAIN_MAP.get(model.id)
623
+ if not chain:
624
+ logger.error(
625
+ f'No chain mapping found for app {model.id} ({model.name}). Skipping.'
626
+ )
627
+ return
627
628
 
628
629
  for portfolio_item in model.portfolio_item_list:
629
630
  detail_types = portfolio_item.detail_types
@@ -636,7 +637,7 @@ class DebankAppParser:
636
637
  # Parse as deposit (common, etc.)
637
638
  deposit = self._parse_deposit(portfolio_item, chain)
638
639
  if deposit:
639
- deposits.append(deposit)
640
+ deposits.extend(deposit)
640
641
 
641
642
  return DebankApp.from_api(
642
643
  app_id=model.id,
@@ -649,9 +650,8 @@ class DebankAppParser:
649
650
  )
650
651
 
651
652
  def _parse_prediction(
652
- self, item: DebankModelAppPortfolioItem, chain: Optional[Blockchain]
653
+ self, item: DebankModelAppPortfolioItem, chain: Blockchain
653
654
  ) -> Optional[DebankPrediction]:
654
- """Parse a prediction market position."""
655
655
  detail = DebankModelPredictionDetail(**item.detail)
656
656
 
657
657
  return DebankPrediction.from_api(
@@ -669,26 +669,28 @@ class DebankAppParser:
669
669
  )
670
670
 
671
671
  def _parse_deposit(
672
- self, item: DebankModelAppPortfolioItem, chain: Optional[Blockchain]
673
- ) -> Optional[DebankAppDeposit]:
674
- """Parse a deposit/common type portfolio item."""
675
- parsed_tokens = [
676
- self._parse_token(t.model_dump()) for t in item.asset_token_list or []
677
- ]
678
-
679
- return DebankAppDeposit.from_api(
680
- name=item.name,
681
- asset_usd_value=item.stats.asset_usd_value,
682
- debt_usd_value=item.stats.debt_usd_value,
683
- net_usd_value=item.stats.net_usd_value,
684
- tokens=[t for t in parsed_tokens if t is not None],
685
- chain=chain,
686
- position_index=item.position_index,
687
- update_at=item.update_at,
688
- )
672
+ self, item: DebankModelAppPortfolioItem, chain: Blockchain
673
+ ) -> list[BalanceItem]:
674
+ balances = []
675
+ for token in item.asset_token_list or []:
676
+ coin = symbol_to_coin_map.get(token.symbol)
677
+ if not coin:
678
+ logger.error(
679
+ f'No coin mapping found for app deposit token {token.symbol} in chain {chain}. Skipping.'
680
+ )
681
+ continue
682
+
683
+ balance = BalanceItem.from_api(
684
+ balance=Decimal(token.amount),
685
+ balance_raw=token.amount,
686
+ asset_type=AssetType.DEPOSITED,
687
+ coin=coin,
688
+ raw=token.model_dump(),
689
+ last_updated=int(item.update_at) if item.update_at else None,
690
+ )
691
+ balances.append(balance)
689
692
 
690
- def _parse_token(self, raw_token: dict) -> Optional[DebankDepositToken]:
691
- return DebankDepositToken.from_api(**raw_token)
693
+ return balances
692
694
 
693
695
 
694
696
  class DebankApi(CustomizableBlockchainApi, BalanceMixin, IPortfolio):
@@ -1,3 +1,6 @@
1
+ import inspect
2
+
3
+ from blockapi.v2 import coins as _coins_module
1
4
  from blockapi.v2.coins import (
2
5
  COIN_DAI,
3
6
  COIN_ETH,
@@ -8,6 +11,15 @@ from blockapi.v2.coins import (
8
11
  )
9
12
  from blockapi.v2.models import Blockchain, Coin
10
13
 
14
+ # Dynamically collect all COIN_* variables from coins module
15
+ coins: list[Coin] = [
16
+ obj
17
+ for name, obj in inspect.getmembers(_coins_module)
18
+ if name.startswith('COIN_') and isinstance(obj, Coin)
19
+ ]
20
+
21
+ symbol_to_coin_map: dict[str, Coin] = {coin.symbol: coin for coin in coins}
22
+
11
23
  OPENSEA_COINS: dict[str, Coin] = {
12
24
  'ETH': COIN_ETH,
13
25
  'USDC': COIN_USDC,
@@ -1282,85 +1282,6 @@ class DebankPrediction:
1282
1282
  )
1283
1283
 
1284
1284
 
1285
- @attr.s(auto_attribs=True, slots=True, frozen=True)
1286
- class DebankDepositToken:
1287
- id: str
1288
- symbol: str
1289
- name: str
1290
- amount: Decimal
1291
- decimals: int
1292
- app_id: str
1293
- price: Decimal
1294
- logo_url: Optional[str]
1295
-
1296
- @classmethod
1297
- def from_api(
1298
- cls,
1299
- *,
1300
- id: str,
1301
- symbol: str,
1302
- name: str,
1303
- amount: Union[str, float, int],
1304
- decimals: int,
1305
- app_id: str,
1306
- price: Union[str, float, int],
1307
- logo_url: Optional[str] = None,
1308
- ) -> 'DebankDepositToken':
1309
- return cls(
1310
- id=id,
1311
- symbol=symbol,
1312
- decimals=decimals,
1313
- name=name,
1314
- amount=to_decimal(amount),
1315
- app_id=app_id,
1316
- price=to_decimal(price),
1317
- logo_url=logo_url,
1318
- )
1319
-
1320
-
1321
- @attr.s(auto_attribs=True, slots=True, frozen=True)
1322
- class DebankAppDeposit:
1323
- """Represents a deposit/holding within a Debank App (e.g., Polymarket cash deposit)."""
1324
-
1325
- name: str
1326
- asset_usd_value: Decimal
1327
- debt_usd_value: Decimal
1328
- net_usd_value: Decimal
1329
- tokens: list[DebankDepositToken]
1330
- chain: Optional[Blockchain]
1331
- position_index: Optional[str]
1332
- update_at: Optional[datetime]
1333
-
1334
- @classmethod
1335
- def from_api(
1336
- cls,
1337
- *,
1338
- name: str,
1339
- asset_usd_value: Union[str, float, int],
1340
- debt_usd_value: Union[str, float, int],
1341
- net_usd_value: Union[str, float, int],
1342
- position_index: str,
1343
- tokens: Optional[list[DebankDepositToken]] = None,
1344
- chain: Optional[Blockchain] = None,
1345
- update_at: Optional[Union[int, float]] = None,
1346
- ) -> 'DebankAppDeposit':
1347
- return cls(
1348
- name=name,
1349
- asset_usd_value=to_decimal(asset_usd_value),
1350
- debt_usd_value=to_decimal(debt_usd_value),
1351
- net_usd_value=to_decimal(net_usd_value),
1352
- tokens=tokens or [],
1353
- chain=chain,
1354
- position_index=position_index,
1355
- update_at=parse_dt(update_at) if update_at else None,
1356
- )
1357
-
1358
- @property
1359
- def token_symbols(self) -> list[str]:
1360
- """Get list of token symbols in this deposit."""
1361
- return [t.symbol for t in self.tokens]
1362
-
1363
-
1364
1285
  @attr.s(auto_attribs=True, slots=True, frozen=True)
1365
1286
  class DebankApp:
1366
1287
  """Represents a Debank App with its deposits and predictions."""
@@ -1370,7 +1291,7 @@ class DebankApp:
1370
1291
  site_url: Optional[str]
1371
1292
  logo_url: Optional[str]
1372
1293
  has_supported_portfolio: bool
1373
- deposits: list[DebankAppDeposit]
1294
+ deposits: list[BalanceItem]
1374
1295
  predictions: list[DebankPrediction]
1375
1296
 
1376
1297
  @classmethod
@@ -1382,7 +1303,7 @@ class DebankApp:
1382
1303
  site_url: Optional[str] = None,
1383
1304
  logo_url: Optional[str] = None,
1384
1305
  has_supported_portfolio: bool = False,
1385
- deposits: Optional[list[DebankAppDeposit]] = None,
1306
+ deposits: Optional[list[BalanceItem]] = None,
1386
1307
  predictions: Optional[list[DebankPrediction]] = None,
1387
1308
  ) -> 'DebankApp':
1388
1309
  return cls(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockapi
3
- Version: 2.3.3
3
+ Version: 2.3.4
4
4
  Summary: BlockAPI library
5
5
  Home-page: https://github.com/crypkit/blockapi
6
6
  Author: Devmons s.r.o.
@@ -6,7 +6,7 @@ with open("README.md", "r") as f:
6
6
 
7
7
  PACKAGES = find_packages(where='.')
8
8
 
9
- __version__ = "2.3.3"
9
+ __version__ = "2.3.4"
10
10
 
11
11
  setuptools.setup(
12
12
  name='blockapi',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes