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.
- {blockapi-0.49.2 → blockapi-0.49.4}/PKG-INFO +1 -1
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_solana.py +57 -1
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/solana.py +40 -9
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/models.py +23 -3
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/PKG-INFO +1 -1
- {blockapi-0.49.2 → blockapi-0.49.4}/setup.py +1 -1
- {blockapi-0.49.2 → blockapi-0.49.4}/LICENSE.md +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/README.md +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/alethio.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/amberdata.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/binance.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockchaininfo.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockchainos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockchair.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockcypher.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockonomics.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/blockscout.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/btc.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/cardanoexplorer.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/chainso.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/cosmos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/cryptoid.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/dcrdata.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/digonchain.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/eospark.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/etherscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/ethplorer.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/greymass.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/insight.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/kyber.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/neoscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/ontology.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/solana.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/stellar.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/subscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/terra_money.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/trezor.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/tronscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/tzscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/tzstats.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/zchain.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/api/zensystem.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/services.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_amberdata.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_balances.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_binance.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_blockchainos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_blockchair.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_blockscout.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_btc.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_cosmos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_dcrdata.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_digonchain.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_insight.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_kyber.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_ontio.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_solana.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_subscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_terra_money.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_tronscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_tzscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/api/test_tzstats.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/test_blockapi.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/test_num.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/test_random_user_agent.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/conftest.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/covalenth/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/covalenth/test_ethereum.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/fake_sleep_provider.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/test_magic_eden.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/test_opensea.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/nft/test_simple_hash.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/perpetual/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/perpetual/test_perpetual.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/synthetix/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/synthetix/test_synthetix.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchainos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchair_btc.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchair_doge.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_blockchair_ltc.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_cosmos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_ethplorer.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_multisources.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_optimistic_etherscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_subscan_polkadot.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_sui.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/api/test_trezor_btc.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_base.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_blockchain_api.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_blockchain_mapping.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_data.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_enumerate_classes.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_generic.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test/v2/test_models.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/test_data.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/address.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/datetime.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/ethereum.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/num.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/utils/user_agent.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/blockchainos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/blockchair.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/cosmos.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/arbitrum.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/astar.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/avalanche.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/axie.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/base.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/binance_smart_chain.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/ethereum.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/fantom.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/heco.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/iotex.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/klaytn.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/moonbeam.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/palm.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/polygon.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/covalenth/rsk.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/debank.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/debank_maps.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/ethplorer.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/magic_eden.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/opensea.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/nft/simple_hash.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/optimistic_etherscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/perpetual/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/perpetual/perp_abi.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/perpetual/perpetual.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/subscan.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/sui.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/synthetix/__init__.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/synthetix/synthetix.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/synthetix/synthetix_abi.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/terra.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/trezor.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/api/web3_utils.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/base.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/blockchain_mapping.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/coin_mapping.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi/v2/coins.py +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/SOURCES.txt +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/dependency_links.txt +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/requires.txt +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/blockapi.egg-info/top_level.txt +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/pyproject.toml +0 -0
- {blockapi-0.49.2 → blockapi-0.49.4}/setup.cfg +0 -0
|
@@ -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
|
|
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
|
-
|
|
299
|
+
self.update_token_from_metaplex(
|
|
292
300
|
address, decimals=info['tokenAmount']['decimals']
|
|
293
|
-
)
|
|
294
|
-
|
|
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=
|
|
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
|
|
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(
|
|
323
|
-
|
|
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(
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|