blockapi 0.49.2__tar.gz → 0.49.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 (158) hide show
  1. {blockapi-0.49.2 → blockapi-0.49.4}/PKG-INFO +1 -1
  2. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_solana.py +57 -1
  3. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/solana.py +40 -9
  4. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/models.py +23 -3
  5. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/PKG-INFO +1 -1
  6. {blockapi-0.49.2 → blockapi-0.49.4}/setup.py +1 -1
  7. {blockapi-0.49.2 → blockapi-0.49.4}/LICENSE.md +0 -0
  8. {blockapi-0.49.2 → blockapi-0.49.4}/README.md +0 -0
  9. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/__init__.py +0 -0
  10. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/__init__.py +0 -0
  11. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/alethio.py +0 -0
  12. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/amberdata.py +0 -0
  13. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/binance.py +0 -0
  14. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockchaininfo.py +0 -0
  15. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockchainos.py +0 -0
  16. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockchair.py +0 -0
  17. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockcypher.py +0 -0
  18. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockonomics.py +0 -0
  19. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockscout.py +0 -0
  20. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/btc.py +0 -0
  21. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/cardanoexplorer.py +0 -0
  22. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/chainso.py +0 -0
  23. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/cosmos.py +0 -0
  24. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/cryptoid.py +0 -0
  25. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/dcrdata.py +0 -0
  26. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/digonchain.py +0 -0
  27. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/eospark.py +0 -0
  28. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/etherscan.py +0 -0
  29. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/ethplorer.py +0 -0
  30. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/greymass.py +0 -0
  31. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/insight.py +0 -0
  32. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/kyber.py +0 -0
  33. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/neoscan.py +0 -0
  34. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/ontology.py +0 -0
  35. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/solana.py +0 -0
  36. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/stellar.py +0 -0
  37. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/subscan.py +0 -0
  38. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/terra_money.py +0 -0
  39. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/trezor.py +0 -0
  40. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/tronscan.py +0 -0
  41. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/tzscan.py +0 -0
  42. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/tzstats.py +0 -0
  43. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/zchain.py +0 -0
  44. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/zensystem.py +0 -0
  45. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/services.py +0 -0
  46. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/__init__.py +0 -0
  47. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/__init__.py +0 -0
  48. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_amberdata.py +0 -0
  49. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_balances.py +0 -0
  50. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_binance.py +0 -0
  51. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_blockchainos.py +0 -0
  52. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_blockchair.py +0 -0
  53. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_blockscout.py +0 -0
  54. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_btc.py +0 -0
  55. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_cosmos.py +0 -0
  56. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_dcrdata.py +0 -0
  57. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_digonchain.py +0 -0
  58. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_insight.py +0 -0
  59. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_kyber.py +0 -0
  60. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_ontio.py +0 -0
  61. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_solana.py +0 -0
  62. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_subscan.py +0 -0
  63. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_terra_money.py +0 -0
  64. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_tronscan.py +0 -0
  65. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_tzscan.py +0 -0
  66. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_tzstats.py +0 -0
  67. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/test_blockapi.py +0 -0
  68. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/test_num.py +0 -0
  69. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/test_random_user_agent.py +0 -0
  70. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/__init__.py +0 -0
  71. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/__init__.py +0 -0
  72. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/conftest.py +0 -0
  73. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/covalenth/__init__.py +0 -0
  74. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/covalenth/test_ethereum.py +0 -0
  75. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/fake_sleep_provider.py +0 -0
  76. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/__init__.py +0 -0
  77. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/test_magic_eden.py +0 -0
  78. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/test_opensea.py +0 -0
  79. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/test_simple_hash.py +0 -0
  80. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/perpetual/__init__.py +0 -0
  81. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/perpetual/test_perpetual.py +0 -0
  82. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/synthetix/__init__.py +0 -0
  83. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/synthetix/test_synthetix.py +0 -0
  84. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchainos.py +0 -0
  85. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchair_btc.py +0 -0
  86. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchair_doge.py +0 -0
  87. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchair_ltc.py +0 -0
  88. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_cosmos.py +0 -0
  89. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_ethplorer.py +0 -0
  90. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_multisources.py +0 -0
  91. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_optimistic_etherscan.py +0 -0
  92. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_subscan_polkadot.py +0 -0
  93. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_sui.py +0 -0
  94. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_trezor_btc.py +0 -0
  95. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_base.py +0 -0
  96. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_blockchain_api.py +0 -0
  97. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_blockchain_mapping.py +0 -0
  98. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_data.py +0 -0
  99. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_enumerate_classes.py +0 -0
  100. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_generic.py +0 -0
  101. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_models.py +0 -0
  102. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test_data.py +0 -0
  103. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/__init__.py +0 -0
  104. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/address.py +0 -0
  105. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/datetime.py +0 -0
  106. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/ethereum.py +0 -0
  107. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/num.py +0 -0
  108. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/user_agent.py +0 -0
  109. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/__init__.py +0 -0
  110. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/__init__.py +0 -0
  111. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/blockchainos.py +0 -0
  112. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/blockchair.py +0 -0
  113. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/cosmos.py +0 -0
  114. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/__init__.py +0 -0
  115. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/arbitrum.py +0 -0
  116. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/astar.py +0 -0
  117. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/avalanche.py +0 -0
  118. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/axie.py +0 -0
  119. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/base.py +0 -0
  120. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/binance_smart_chain.py +0 -0
  121. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/ethereum.py +0 -0
  122. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/fantom.py +0 -0
  123. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/heco.py +0 -0
  124. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/iotex.py +0 -0
  125. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/klaytn.py +0 -0
  126. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/moonbeam.py +0 -0
  127. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/palm.py +0 -0
  128. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/polygon.py +0 -0
  129. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/rsk.py +0 -0
  130. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/debank.py +0 -0
  131. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/debank_maps.py +0 -0
  132. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/ethplorer.py +0 -0
  133. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/__init__.py +0 -0
  134. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/magic_eden.py +0 -0
  135. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/opensea.py +0 -0
  136. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/simple_hash.py +0 -0
  137. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/optimistic_etherscan.py +0 -0
  138. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/perpetual/__init__.py +0 -0
  139. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/perpetual/perp_abi.py +0 -0
  140. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/perpetual/perpetual.py +0 -0
  141. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/subscan.py +0 -0
  142. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/sui.py +0 -0
  143. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/synthetix/__init__.py +0 -0
  144. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/synthetix/synthetix.py +0 -0
  145. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/synthetix/synthetix_abi.py +0 -0
  146. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/terra.py +0 -0
  147. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/trezor.py +0 -0
  148. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/web3_utils.py +0 -0
  149. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/base.py +0 -0
  150. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/blockchain_mapping.py +0 -0
  151. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/coin_mapping.py +0 -0
  152. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/coins.py +0 -0
  153. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/SOURCES.txt +0 -0
  154. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/dependency_links.txt +0 -0
  155. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/requires.txt +0 -0
  156. {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/top_level.txt +0 -0
  157. {blockapi-0.49.2 → blockapi-0.49.4}/pyproject.toml +0 -0
  158. {blockapi-0.49.2 → blockapi-0.49.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: blockapi
3
- Version: 0.49.2
3
+ Version: 0.49.4
4
4
  Summary: BlockAPI library
5
5
  Home-page: UNKNOWN
6
6
  Author: Devmons s.r.o.
@@ -13,7 +13,14 @@ from blockapi.v2.api.solana import (
13
13
  SOL_TOKEN_LIST_URL,
14
14
  SONAR_TOKEN_LIST_URL,
15
15
  )
16
- from blockapi.v2.models import AssetType, BalanceItem, Blockchain, Coin, CoinInfo
16
+ from blockapi.v2.models import (
17
+ AssetType,
18
+ BalanceItem,
19
+ Blockchain,
20
+ Coin,
21
+ CoinContract,
22
+ CoinInfo,
23
+ )
17
24
 
18
25
 
19
26
  def test_merge_balances_with_different_coins(solana_api, balances_with_different_coins):
@@ -544,3 +551,52 @@ def metaplex_content():
544
551
  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
545
552
  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ=='
546
553
  )
554
+
555
+
556
+ def test_merge_balances_contract_merge(solana_api):
557
+ balances = [
558
+ BalanceItem(
559
+ **{
560
+ 'balance': Decimal('1'),
561
+ 'balance_raw': Decimal('1'),
562
+ 'coin': None,
563
+ 'coin_contract': CoinContract(
564
+ **{
565
+ 'blockchain': 'solana',
566
+ 'contract': 'HEL6KGUEvwYgTtcjenf9qeAb2Zg9Yr77usWPY9UZvoQj',
567
+ 'decimals': 0,
568
+ }
569
+ ),
570
+ 'raw': {},
571
+ 'asset_type': 'available',
572
+ 'last_updated': None,
573
+ 'protocol': None,
574
+ 'is_wallet': True,
575
+ 'pool_info': None,
576
+ }
577
+ ),
578
+ BalanceItem(
579
+ **{
580
+ 'balance': Decimal('11'),
581
+ 'balance_raw': Decimal('11'),
582
+ 'coin': None,
583
+ 'coin_contract': CoinContract(
584
+ **{
585
+ 'blockchain': 'solana',
586
+ 'contract': 'HEL6KGUEvwYgTtcjenf9qeAb2Zg9Yr77usWPY9UZvoQj',
587
+ 'decimals': 0,
588
+ }
589
+ ),
590
+ 'raw': {},
591
+ 'asset_type': 'available',
592
+ 'last_updated': None,
593
+ 'protocol': None,
594
+ 'is_wallet': True,
595
+ 'pool_info': None,
596
+ }
597
+ ),
598
+ ]
599
+
600
+ merged = solana_api.merge_balances_with_same_coin(balances)
601
+ assert len(merged) == 1
602
+ assert merged[0].coin_contract is not None
@@ -23,6 +23,7 @@ from blockapi.v2.models import (
23
23
  BalanceItem,
24
24
  Blockchain,
25
25
  Coin,
26
+ CoinContract,
26
27
  CoinInfo,
27
28
  FetchResult,
28
29
  ParseResult,
@@ -154,6 +155,13 @@ class SolanaApi(CustomizableBlockchainApi, BalanceMixin):
154
155
  ),
155
156
  )
156
157
 
158
+ def get_coin(self, fetch_params: tuple[str, int]) -> Coin:
159
+ contract, decimals = fetch_params
160
+ if contract not in self.tokens_map:
161
+ self.update_token_from_metaplex(contract, decimals=decimals, force=True)
162
+
163
+ return self.get_token_data(contract)
164
+
157
165
  def _fetch_staked_sol(self, address: str) -> dict:
158
166
  return self._request(
159
167
  method='getProgramAccounts',
@@ -218,7 +226,7 @@ class SolanaApi(CustomizableBlockchainApi, BalanceMixin):
218
226
  ) -> list[BalanceItem]:
219
227
  return list(
220
228
  reduceby(
221
- key=lambda b: b.coin.address,
229
+ key=lambda b: b.coin.address if b.coin else b.coin_contract.contract,
222
230
  binop=lambda v1, v2: v1 + v2,
223
231
  seq=token_balances,
224
232
  ).values()
@@ -288,19 +296,31 @@ class SolanaApi(CustomizableBlockchainApi, BalanceMixin):
288
296
  # token account
289
297
  # TODO move fetching tokens_map to fetch
290
298
  if address not in self.tokens_map:
291
- if not self.update_token_from_metaplex(
299
+ self.update_token_from_metaplex(
292
300
  address, decimals=info['tokenAmount']['decimals']
293
- ):
294
- return
301
+ )
302
+
303
+ coin = self.get_token_data(address)
304
+ contract = None
305
+ if not coin:
306
+ contract = CoinContract.from_api(
307
+ blockchain=Blockchain.SOLANA,
308
+ contract=address,
309
+ decimals=int(info['tokenAmount']['decimals']),
310
+ )
295
311
 
296
312
  return BalanceItem.from_api(
297
313
  balance_raw=info['tokenAmount']['amount'],
298
- coin=self.get_token_data(address),
314
+ coin=coin,
315
+ coin_contract=contract,
299
316
  raw=raw,
300
317
  )
301
318
 
302
- def get_token_data(self, address: str) -> Coin:
303
- raw_token = self.tokens_map[address]
319
+ def get_token_data(self, address: str) -> Optional[Coin]:
320
+ raw_token = self.tokens_map.get(address)
321
+ if not raw_token:
322
+ return None
323
+
304
324
  extensions = raw_token.get('extensions', {})
305
325
 
306
326
  return Coin(
@@ -319,8 +339,10 @@ class SolanaApi(CustomizableBlockchainApi, BalanceMixin):
319
339
  ),
320
340
  )
321
341
 
322
- def update_token_from_metaplex(self, address: str, decimals: int) -> bool:
323
- if not self.fetch_metaplex:
342
+ def update_token_from_metaplex(
343
+ self, address: str, decimals: int, force: bool = False
344
+ ) -> bool:
345
+ if not self.fetch_metaplex and not force:
324
346
  return False
325
347
 
326
348
  pda = self.get_metadata_pda(address)
@@ -455,3 +477,12 @@ class SolscanApi(BlockchainApi):
455
477
  last_updated=None,
456
478
  raw=response['data'],
457
479
  )
480
+
481
+
482
+ if __name__ == "__main__":
483
+ api = SolanaApi(
484
+ base_url="https://solemn-practical-tree.solana-mainnet.quiknode.pro/00205ae683fa5c6aab1bc6a47b9d6aa28c47e0fc/",
485
+ fetch_metaplex=False,
486
+ )
487
+ api.get_balance("FEeSRuEDk8ENZbpzXjn4uHPz3LQijbeKRzhqVr5zPSJ9")
488
+ x = 1
@@ -470,6 +470,17 @@ class CoinInfo:
470
470
  )
471
471
 
472
472
 
473
+ @attr.s(auto_attribs=True, slots=True, frozen=True)
474
+ class CoinContract:
475
+ blockchain: Blockchain
476
+ contract: str
477
+ decimals: int
478
+
479
+ @classmethod
480
+ def from_api(cls, *, blockchain: Blockchain, contract: str, decimals: int):
481
+ return cls(blockchain=blockchain, contract=contract, decimals=decimals)
482
+
483
+
473
484
  @attr.s(auto_attribs=True, slots=True, frozen=True)
474
485
  class Coin:
475
486
  symbol: str
@@ -583,7 +594,8 @@ class BalanceItem:
583
594
  balance: Decimal
584
595
  balance_raw: Decimal
585
596
  raw: Dict
586
- coin: Coin
597
+ coin: Optional[Coin] = attr.ib(default=None)
598
+ coin_contract: Optional[CoinContract] = attr.ib(default=None)
587
599
  asset_type: AssetType = AssetType.AVAILABLE
588
600
  last_updated: Optional[datetime] = attr.ib(default=None)
589
601
  protocol: Optional[Protocol] = attr.ib(default=None)
@@ -595,7 +607,8 @@ class BalanceItem:
595
607
  cls,
596
608
  *,
597
609
  balance_raw: Union[int, float, str, Decimal],
598
- coin: Coin,
610
+ coin: Optional[Coin] = None,
611
+ coin_contract: Optional[CoinContract] = None,
599
612
  asset_type: AssetType = AssetType.AVAILABLE,
600
613
  raw: Union[Dict, List[Dict]],
601
614
  last_updated: Optional[Union[int, str]] = None,
@@ -603,10 +616,16 @@ class BalanceItem:
603
616
  is_wallet: bool = True,
604
617
  pool_info: Optional[PoolInfo] = None,
605
618
  ) -> 'BalanceItem':
619
+ if coin is None and coin_contract is None:
620
+ raise ValueError('Either coin or coin_contract must be set')
621
+
606
622
  return cls(
607
623
  balance_raw=to_decimal(balance_raw),
608
- balance=raw_to_decimals(balance_raw, coin.decimals),
624
+ balance=raw_to_decimals(
625
+ balance_raw, coin.decimals if coin else coin_contract.decimals
626
+ ),
609
627
  coin=coin,
628
+ coin_contract=coin_contract,
610
629
  asset_type=asset_type,
611
630
  raw=raw,
612
631
  last_updated=(parse_dt(last_updated) if last_updated is not None else None),
@@ -623,6 +642,7 @@ class BalanceItem:
623
642
  balance_raw=self.balance_raw + other.balance_raw,
624
643
  balance=self.balance + other.balance,
625
644
  coin=self.coin,
645
+ coin_contract=self.coin_contract,
626
646
  asset_type=self.asset_type,
627
647
  raw=self._add_raw(other),
628
648
  last_updated=self.last_updated,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: blockapi
3
- Version: 0.49.2
3
+ Version: 0.49.4
4
4
  Summary: BlockAPI library
5
5
  Home-page: UNKNOWN
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__ = "0.49.2"
9
+ __version__ = "0.49.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