cdp-sdk 0.0.1__py3-none-any.whl
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.
- cdp/__init__.py +27 -0
- cdp/__version__.py +1 -0
- cdp/address.py +107 -0
- cdp/api_clients.py +148 -0
- cdp/asset.py +165 -0
- cdp/balance.py +79 -0
- cdp/balance_map.py +75 -0
- cdp/cdp.py +117 -0
- cdp/cdp_api_client.py +180 -0
- cdp/client/__init__.py +147 -0
- cdp/client/api/__init__.py +20 -0
- cdp/client/api/addresses_api.py +2476 -0
- cdp/client/api/assets_api.py +277 -0
- cdp/client/api/balance_history_api.py +357 -0
- cdp/client/api/contract_events_api.py +430 -0
- cdp/client/api/contract_invocations_api.py +1164 -0
- cdp/client/api/external_addresses_api.py +1127 -0
- cdp/client/api/networks_api.py +247 -0
- cdp/client/api/server_signers_api.py +1525 -0
- cdp/client/api/smart_contracts_api.py +1097 -0
- cdp/client/api/stake_api.py +1449 -0
- cdp/client/api/trades_api.py +1144 -0
- cdp/client/api/transfers_api.py +1144 -0
- cdp/client/api/users_api.py +232 -0
- cdp/client/api/validators_api.py +615 -0
- cdp/client/api/wallet_stake_api.py +856 -0
- cdp/client/api/wallets_api.py +1203 -0
- cdp/client/api/webhooks_api.py +988 -0
- cdp/client/api_client.py +694 -0
- cdp/client/api_response.py +21 -0
- cdp/client/configuration.py +457 -0
- cdp/client/exceptions.py +194 -0
- cdp/client/models/__init__.py +114 -0
- cdp/client/models/address.py +95 -0
- cdp/client/models/address_balance_list.py +100 -0
- cdp/client/models/address_historical_balance_list.py +98 -0
- cdp/client/models/address_list.py +100 -0
- cdp/client/models/address_transaction_list.py +98 -0
- cdp/client/models/asset.py +93 -0
- cdp/client/models/balance.py +88 -0
- cdp/client/models/broadcast_contract_invocation_request.py +79 -0
- cdp/client/models/broadcast_staking_operation_request.py +87 -0
- cdp/client/models/broadcast_trade_request.py +85 -0
- cdp/client/models/broadcast_transfer_request.py +77 -0
- cdp/client/models/build_staking_operation_request.py +97 -0
- cdp/client/models/contract_event.py +126 -0
- cdp/client/models/contract_event_list.py +98 -0
- cdp/client/models/contract_invocation.py +121 -0
- cdp/client/models/contract_invocation_list.py +102 -0
- cdp/client/models/create_address_request.py +92 -0
- cdp/client/models/create_contract_invocation_request.py +94 -0
- cdp/client/models/create_payload_signature_request.py +80 -0
- cdp/client/models/create_server_signer_request.py +89 -0
- cdp/client/models/create_smart_contract_request.py +91 -0
- cdp/client/models/create_staking_operation_request.py +87 -0
- cdp/client/models/create_trade_request.py +85 -0
- cdp/client/models/create_transfer_request.py +99 -0
- cdp/client/models/create_wallet_request.py +88 -0
- cdp/client/models/create_wallet_request_wallet.py +83 -0
- cdp/client/models/create_webhook_request.py +126 -0
- cdp/client/models/deploy_smart_contract_request.py +79 -0
- cdp/client/models/erc20_transfer_event.py +159 -0
- cdp/client/models/erc721_transfer_event.py +158 -0
- cdp/client/models/error.py +92 -0
- cdp/client/models/ethereum_transaction.py +186 -0
- cdp/client/models/ethereum_transaction_access.py +80 -0
- cdp/client/models/ethereum_transaction_access_list.py +94 -0
- cdp/client/models/ethereum_transaction_flattened_trace.py +137 -0
- cdp/client/models/ethereum_validator_metadata.py +127 -0
- cdp/client/models/faucet_transaction.py +87 -0
- cdp/client/models/feature_set.py +98 -0
- cdp/client/models/fetch_historical_staking_balances200_response.py +98 -0
- cdp/client/models/fetch_staking_rewards200_response.py +98 -0
- cdp/client/models/fetch_staking_rewards_request.py +107 -0
- cdp/client/models/get_staking_context_request.py +89 -0
- cdp/client/models/historical_balance.py +96 -0
- cdp/client/models/network.py +127 -0
- cdp/client/models/network_identifier.py +37 -0
- cdp/client/models/nft_contract_options.py +78 -0
- cdp/client/models/payload_signature.py +107 -0
- cdp/client/models/payload_signature_list.py +102 -0
- cdp/client/models/seed_creation_event.py +82 -0
- cdp/client/models/seed_creation_event_result.py +96 -0
- cdp/client/models/server_signer.py +87 -0
- cdp/client/models/server_signer_event.py +92 -0
- cdp/client/models/server_signer_event_event.py +147 -0
- cdp/client/models/server_signer_event_list.py +100 -0
- cdp/client/models/server_signer_list.py +102 -0
- cdp/client/models/signature_creation_event.py +112 -0
- cdp/client/models/signature_creation_event_result.py +102 -0
- cdp/client/models/signed_voluntary_exit_message_metadata.py +89 -0
- cdp/client/models/smart_contract.py +125 -0
- cdp/client/models/smart_contract_list.py +98 -0
- cdp/client/models/smart_contract_options.py +147 -0
- cdp/client/models/smart_contract_type.py +31 -0
- cdp/client/models/sponsored_send.py +119 -0
- cdp/client/models/staking_balance.py +112 -0
- cdp/client/models/staking_context.py +88 -0
- cdp/client/models/staking_context_context.py +106 -0
- cdp/client/models/staking_operation.py +133 -0
- cdp/client/models/staking_operation_metadata.py +141 -0
- cdp/client/models/staking_reward.py +120 -0
- cdp/client/models/staking_reward_format.py +31 -0
- cdp/client/models/staking_reward_usd_value.py +88 -0
- cdp/client/models/token_contract_options.py +87 -0
- cdp/client/models/trade.py +137 -0
- cdp/client/models/trade_list.py +102 -0
- cdp/client/models/transaction.py +147 -0
- cdp/client/models/transaction_content.py +133 -0
- cdp/client/models/transaction_type.py +30 -0
- cdp/client/models/transfer.py +162 -0
- cdp/client/models/transfer_list.py +102 -0
- cdp/client/models/update_webhook_request.py +107 -0
- cdp/client/models/user.py +78 -0
- cdp/client/models/validator.py +107 -0
- cdp/client/models/validator_details.py +135 -0
- cdp/client/models/validator_list.py +98 -0
- cdp/client/models/validator_status.py +42 -0
- cdp/client/models/wallet.py +120 -0
- cdp/client/models/wallet_list.py +100 -0
- cdp/client/models/webhook.py +142 -0
- cdp/client/models/webhook_event_filter.py +94 -0
- cdp/client/models/webhook_event_type.py +33 -0
- cdp/client/models/webhook_event_type_filter.py +135 -0
- cdp/client/models/webhook_list.py +101 -0
- cdp/client/models/webhook_wallet_activity_filter.py +84 -0
- cdp/client/py.typed +0 -0
- cdp/client/rest.py +222 -0
- cdp/errors.py +359 -0
- cdp/faucet_transaction.py +44 -0
- cdp/py.typed +0 -0
- cdp/sponsored_send.py +164 -0
- cdp/trade.py +266 -0
- cdp/transaction.py +181 -0
- cdp/transfer.py +325 -0
- cdp/wallet.py +622 -0
- cdp/wallet_address.py +191 -0
- cdp_sdk-0.0.1.dist-info/LICENSE.md +15 -0
- cdp_sdk-0.0.1.dist-info/METADATA +264 -0
- cdp_sdk-0.0.1.dist-info/RECORD +142 -0
- cdp_sdk-0.0.1.dist-info/WHEEL +5 -0
- cdp_sdk-0.0.1.dist-info/top_level.txt +1 -0
cdp/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from cdp.__version__ import __version__
|
|
2
|
+
from cdp.address import Address
|
|
3
|
+
from cdp.asset import Asset
|
|
4
|
+
from cdp.balance import Balance
|
|
5
|
+
from cdp.balance_map import BalanceMap
|
|
6
|
+
from cdp.cdp import Cdp
|
|
7
|
+
from cdp.faucet_transaction import FaucetTransaction
|
|
8
|
+
from cdp.sponsored_send import SponsoredSend
|
|
9
|
+
from cdp.trade import Trade
|
|
10
|
+
from cdp.transaction import Transaction
|
|
11
|
+
from cdp.transfer import Transfer
|
|
12
|
+
from cdp.wallet import Wallet
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"__version__",
|
|
16
|
+
"Cdp",
|
|
17
|
+
"Wallet",
|
|
18
|
+
"Asset",
|
|
19
|
+
"Transfer",
|
|
20
|
+
"Address",
|
|
21
|
+
"Transaction",
|
|
22
|
+
"Balance",
|
|
23
|
+
"BalanceMap",
|
|
24
|
+
"FaucetTransaction",
|
|
25
|
+
"Trade",
|
|
26
|
+
"SponsoredSend",
|
|
27
|
+
]
|
cdp/__version__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.1"
|
cdp/address.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
from cdp.asset import Asset
|
|
4
|
+
from cdp.balance import Balance
|
|
5
|
+
from cdp.balance_map import BalanceMap
|
|
6
|
+
from cdp.cdp import Cdp
|
|
7
|
+
from cdp.faucet_transaction import FaucetTransaction
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Address:
|
|
11
|
+
"""A class representing an address."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, network_id: str, address_id: str) -> None:
|
|
14
|
+
"""Initialize the Address class.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
network_id (str): The network ID.
|
|
18
|
+
address_id (str): The address ID.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
self._network_id = network_id
|
|
22
|
+
self._id = address_id
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def address_id(self) -> str:
|
|
26
|
+
"""Get the address ID.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
str: The address ID.
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
return self._id
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def network_id(self) -> str:
|
|
36
|
+
"""Get the network ID.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
str: The network ID.
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
return self._network_id
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def can_sign(self) -> bool:
|
|
46
|
+
"""Get whether the address can sign.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
bool: Whether the address can sign.
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
def faucet(self, asset_id=None) -> FaucetTransaction:
|
|
55
|
+
"""Request faucet funds.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
asset_id (str): The asset ID.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
FaucetTransaction: The faucet transaction object.
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
model = Cdp.api_clients.external_addresses.request_external_faucet_funds(
|
|
65
|
+
network_id=self.network_id, address_id=self.address_id, asset_id=asset_id
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return FaucetTransaction(model)
|
|
69
|
+
|
|
70
|
+
def balance(self, asset_id) -> Decimal:
|
|
71
|
+
"""Get the balance of the address.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
asset_id (str): The asset ID.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Decimal: The balance of the address.
|
|
78
|
+
|
|
79
|
+
"""
|
|
80
|
+
model = Cdp.api_clients.external_addresses.get_external_address_balance(
|
|
81
|
+
network_id=self.network_id,
|
|
82
|
+
address_id=self.address_id,
|
|
83
|
+
asset_id=Asset.primary_denomination(asset_id),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return Decimal(0) if model is None else Balance.from_model(model, asset_id).amount
|
|
87
|
+
|
|
88
|
+
def balances(self):
|
|
89
|
+
"""List balances of the address.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
BalanceMap: The balances of the address, keyed by asset ID. Ether balances are denominated in ETH.
|
|
93
|
+
|
|
94
|
+
"""
|
|
95
|
+
response = Cdp.api_clients.external_addresses.list_external_address_balances(
|
|
96
|
+
network_id=self.network_id, address_id=self.address_id
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return BalanceMap.from_models(response.data)
|
|
100
|
+
|
|
101
|
+
def __str__(self) -> str:
|
|
102
|
+
"""Return a string representation of the Address."""
|
|
103
|
+
return f"Address: (address_id: {self.address_id}, network_id: {self.network_id})"
|
|
104
|
+
|
|
105
|
+
def __repr__(self) -> str:
|
|
106
|
+
"""Return a string representation of the Address."""
|
|
107
|
+
return str(self)
|
cdp/api_clients.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from cdp.cdp_api_client import CdpApiClient
|
|
2
|
+
from cdp.client.api.addresses_api import AddressesApi
|
|
3
|
+
from cdp.client.api.assets_api import AssetsApi
|
|
4
|
+
from cdp.client.api.external_addresses_api import ExternalAddressesApi
|
|
5
|
+
from cdp.client.api.networks_api import NetworksApi
|
|
6
|
+
from cdp.client.api.trades_api import TradesApi
|
|
7
|
+
from cdp.client.api.transfers_api import TransfersApi
|
|
8
|
+
from cdp.client.api.wallets_api import WalletsApi
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ApiClients:
|
|
12
|
+
"""A container class for all API clients used in the Coinbase SDK.
|
|
13
|
+
|
|
14
|
+
This class provides lazy-loaded access to various API clients, ensuring
|
|
15
|
+
that each client is only instantiated when it's first accessed.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
_cdp_client (CdpApiClient): The CDP API client used to initialize individual API clients.
|
|
19
|
+
_wallets (Optional[WalletsApi]): The WalletsApi client instance.
|
|
20
|
+
_addresses (Optional[AddressesApi]): The AddressesApi client instance.
|
|
21
|
+
_external_addresses (Optional[ExternalAddressesApi]): The ExternalAddressesApi client instance.
|
|
22
|
+
_transfers (Optional[TransfersApi]): The TransfersApi client instance.
|
|
23
|
+
_networks (Optional[NetworksApi]): The NetworksApi client instance.
|
|
24
|
+
_assets (Optional[AssetsApi]): The AssetsApi client instance.
|
|
25
|
+
_trades (Optional[TradesApi]): The TradesApi client instance.
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, cdp_client: CdpApiClient) -> None:
|
|
30
|
+
"""Initialize the ApiClients instance.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
cdp_client (CdpApiClient): The CDP API client to use for initializing individual API clients.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
self._cdp_client: CdpApiClient = cdp_client
|
|
37
|
+
self._wallets: WalletsApi | None = None
|
|
38
|
+
self._addresses: AddressesApi | None = None
|
|
39
|
+
self._external_addresses: ExternalAddressesApi | None = None
|
|
40
|
+
self._transfers: TransfersApi | None = None
|
|
41
|
+
self._networks: NetworksApi | None = None
|
|
42
|
+
self._assets: AssetsApi | None = None
|
|
43
|
+
self._trades: TradesApi | None = None
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def wallets(self) -> WalletsApi:
|
|
47
|
+
"""Get the WalletsApi client instance.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
WalletsApi: The WalletsApi client instance.
|
|
51
|
+
|
|
52
|
+
Note:
|
|
53
|
+
This property lazily initializes the WalletsApi client on first access.
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
if self._wallets is None:
|
|
57
|
+
self._wallets = WalletsApi(api_client=self._cdp_client)
|
|
58
|
+
return self._wallets
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def addresses(self) -> AddressesApi:
|
|
62
|
+
"""Get the AddressesApi client instance.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
AddressesApi: The AddressesApi client instance.
|
|
66
|
+
|
|
67
|
+
Note:
|
|
68
|
+
This property lazily initializes the AddressesApi client on first access.
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
if self._addresses is None:
|
|
72
|
+
self._addresses = AddressesApi(api_client=self._cdp_client)
|
|
73
|
+
return self._addresses
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def external_addresses(self) -> ExternalAddressesApi:
|
|
77
|
+
"""Get the ExternalAddressesApi client instance.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
ExternalAddressesApi: The ExternalAddressesApi client instance.
|
|
81
|
+
|
|
82
|
+
Note:
|
|
83
|
+
This property lazily initializes the ExternalAddressesApi client on first access.
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
if self._external_addresses is None:
|
|
87
|
+
self._external_addresses = ExternalAddressesApi(api_client=self._cdp_client)
|
|
88
|
+
return self._external_addresses
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def transfers(self) -> TransfersApi:
|
|
92
|
+
"""Get the TransfersApi client instance.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
TransfersApi: The TransfersApi client instance.
|
|
96
|
+
|
|
97
|
+
Note:
|
|
98
|
+
This property lazily initializes the TransfersApi client on first access.
|
|
99
|
+
|
|
100
|
+
"""
|
|
101
|
+
if self._transfers is None:
|
|
102
|
+
self._transfers = TransfersApi(api_client=self._cdp_client)
|
|
103
|
+
return self._transfers
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def networks(self) -> NetworksApi:
|
|
107
|
+
"""Get the NetworksApi client instance.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
NetworksApi: The NetworksApi client instance.
|
|
111
|
+
|
|
112
|
+
Note:
|
|
113
|
+
This property lazily initializes the NetworksApi client on first access.
|
|
114
|
+
|
|
115
|
+
"""
|
|
116
|
+
if self._networks is None:
|
|
117
|
+
self._networks = NetworksApi(api_client=self._cdp_client)
|
|
118
|
+
return self._networks
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def assets(self) -> AssetsApi:
|
|
122
|
+
"""Get the AssetsApi client instance.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
AssetsApi: The AssetsApi client instance.
|
|
126
|
+
|
|
127
|
+
Note:
|
|
128
|
+
This property lazily initializes the AssetsApi client on first access.
|
|
129
|
+
|
|
130
|
+
"""
|
|
131
|
+
if self._assets is None:
|
|
132
|
+
self._assets = AssetsApi(api_client=self._cdp_client)
|
|
133
|
+
return self._assets
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def trades(self) -> TradesApi:
|
|
137
|
+
"""Get the TradesApi client instance.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
TradesApi: The TradesApi client instance.
|
|
141
|
+
|
|
142
|
+
Note:
|
|
143
|
+
This property lazily initializes the TradesApi client on first access.
|
|
144
|
+
|
|
145
|
+
"""
|
|
146
|
+
if self._trades is None:
|
|
147
|
+
self._trades = TradesApi(api_client=self._cdp_client)
|
|
148
|
+
return self._trades
|
cdp/asset.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
from cdp.cdp import Cdp
|
|
4
|
+
from cdp.client.models.asset import Asset as AssetModel
|
|
5
|
+
|
|
6
|
+
# TODO: Move to constants.py
|
|
7
|
+
GWEI_DECIMALS = 9
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Asset:
|
|
11
|
+
"""A class representing an asset."""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self, network_id: str, asset_id: str, contract_address: str, decimals: int
|
|
15
|
+
) -> None:
|
|
16
|
+
"""Initialize the Asset class.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
network_id (str): The network ID.
|
|
20
|
+
asset_id (str): The asset ID.
|
|
21
|
+
contract_address (str): The contract address.
|
|
22
|
+
decimals (int): The number of decimals.
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
self._network_id = network_id
|
|
26
|
+
self._asset_id = asset_id
|
|
27
|
+
self._contract_address = contract_address
|
|
28
|
+
self._decimals = decimals
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def from_model(cls, model: AssetModel, asset_id: str | None = None) -> "Asset":
|
|
32
|
+
"""Create an Asset instance from a model.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
model (AssetModel): The model representing the asset.
|
|
36
|
+
asset_id (Optional[str]): The asset ID.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Asset: The Asset instance.
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
decimals = model.decimals
|
|
43
|
+
|
|
44
|
+
if asset_id and asset_id != model.asset_id:
|
|
45
|
+
match asset_id:
|
|
46
|
+
case "gwei":
|
|
47
|
+
decimals = GWEI_DECIMALS
|
|
48
|
+
case "wei":
|
|
49
|
+
decimals = 0
|
|
50
|
+
case _:
|
|
51
|
+
raise ValueError(f"Unsupported asset ID: {asset_id}")
|
|
52
|
+
|
|
53
|
+
return cls(
|
|
54
|
+
network_id=model.network_id,
|
|
55
|
+
asset_id=model.asset_id,
|
|
56
|
+
contract_address=model.contract_address,
|
|
57
|
+
decimals=decimals,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def fetch(cls, network_id: str, asset_id: str) -> "Asset":
|
|
62
|
+
"""Fetch an asset from the API.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
network_id (str): The network ID.
|
|
66
|
+
asset_id (str): The asset ID.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Asset: The fetched Asset instance.
|
|
70
|
+
|
|
71
|
+
"""
|
|
72
|
+
primary_denomination_asset_id = cls.primary_denomination(asset_id)
|
|
73
|
+
|
|
74
|
+
model = Cdp.api_clients.assets.get_asset(
|
|
75
|
+
network_id=network_id, asset_id=primary_denomination_asset_id
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return cls.from_model(model, asset_id=asset_id)
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def primary_denomination(asset_id: str) -> str:
|
|
82
|
+
"""Get the primary denomination for a given asset ID.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
asset_id (str): The asset ID.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
str: The primary denomination of the asset.
|
|
89
|
+
|
|
90
|
+
"""
|
|
91
|
+
if asset_id in ["wei", "gwei"]:
|
|
92
|
+
return "eth"
|
|
93
|
+
return asset_id
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def decimals(self) -> int:
|
|
97
|
+
"""Get the number of decimals for the asset.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
int: The number of decimals.
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
return self._decimals
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def asset_id(self) -> str:
|
|
107
|
+
"""Get the asset ID.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
str: The asset ID.
|
|
111
|
+
|
|
112
|
+
"""
|
|
113
|
+
return self._asset_id
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def contract_address(self) -> str:
|
|
117
|
+
"""Get the contract address.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
str: The contract address.
|
|
121
|
+
|
|
122
|
+
"""
|
|
123
|
+
return self._contract_address
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def network_id(self) -> str:
|
|
127
|
+
"""Get the network ID.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
str: The network ID.
|
|
131
|
+
|
|
132
|
+
"""
|
|
133
|
+
return self._network_id
|
|
134
|
+
|
|
135
|
+
def from_atomic_amount(self, atomic_amount: Decimal) -> Decimal:
|
|
136
|
+
"""Convert an atomic amount to a whole amount.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
atomic_amount (Decimal): The atomic amount.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Decimal: The whole amount.
|
|
143
|
+
|
|
144
|
+
"""
|
|
145
|
+
return Decimal(atomic_amount) / Decimal(10) ** (self.decimals)
|
|
146
|
+
|
|
147
|
+
def to_atomic_amount(self, whole_amount: Decimal) -> Decimal:
|
|
148
|
+
"""Convert a whole amount to an atomic amount.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
whole_amount (Decimal): The whole amount.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
Decimal: The atomic amount.
|
|
155
|
+
|
|
156
|
+
"""
|
|
157
|
+
return whole_amount * Decimal(10) ** (self.decimals)
|
|
158
|
+
|
|
159
|
+
def __str__(self) -> str:
|
|
160
|
+
"""Return a string representation of the Asset."""
|
|
161
|
+
return f"Asset: (asset_id: {self.asset_id}, network_id: {self.network_id}, contract_address: {self.contract_address}, decimals: {self.decimals})"
|
|
162
|
+
|
|
163
|
+
def __repr__(self) -> str:
|
|
164
|
+
"""Return a string representation of the Asset."""
|
|
165
|
+
return str(self)
|
cdp/balance.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
from cdp.asset import Asset
|
|
4
|
+
from cdp.client.models.balance import Balance as BalanceModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Balance:
|
|
8
|
+
"""A class representing a balance."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, amount: Decimal, asset: Asset, asset_id: str | None = None):
|
|
11
|
+
"""Initialize the Balance class.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
amount (Decimal): The amount.
|
|
15
|
+
asset (Asset): The asset.
|
|
16
|
+
asset_id (Optional[str]): The asset ID.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
self._amount = amount
|
|
20
|
+
self._asset = asset
|
|
21
|
+
self._asset_id = asset_id if asset_id is not None else asset.asset_id
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def from_model(model: BalanceModel, asset_id: str | None = None) -> "Balance":
|
|
25
|
+
"""Create a Balance instance from a model.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
model (BalanceModel): The model representing the balance.
|
|
29
|
+
asset_id (Optional[str]): The asset ID.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Balance: The Balance instance.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
asset = Asset.from_model(model.asset, asset_id=asset_id)
|
|
36
|
+
|
|
37
|
+
return Balance(
|
|
38
|
+
amount=asset.from_atomic_amount(model.amount),
|
|
39
|
+
asset=asset,
|
|
40
|
+
asset_id=asset_id,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def amount(self) -> Decimal:
|
|
45
|
+
"""Get the amount.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Decimal: The amount.
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
return self._amount
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def asset(self) -> Asset:
|
|
55
|
+
"""Get the asset.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Asset: The asset.
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
return self._asset
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def asset_id(self) -> str:
|
|
65
|
+
"""Get the asset ID.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
str: The asset ID.
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
return self._asset_id
|
|
72
|
+
|
|
73
|
+
def __str__(self) -> str:
|
|
74
|
+
"""Return a string representation of the Balance."""
|
|
75
|
+
return f"Balance: (amount: {self.amount}, asset: {self.asset})"
|
|
76
|
+
|
|
77
|
+
def __repr__(self) -> str:
|
|
78
|
+
"""Return a string representation of the Balance."""
|
|
79
|
+
return str(self)
|
cdp/balance_map.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
|
|
4
|
+
from cdp.balance import Balance
|
|
5
|
+
from cdp.client.models.balance import Balance as BalanceModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BalanceMap(dict[str, Decimal]):
|
|
9
|
+
"""A class representing asset balances.
|
|
10
|
+
|
|
11
|
+
This class extends the built-in dict class, where keys are asset IDs (str)
|
|
12
|
+
and values are balance amounts (Decimal).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def from_models(cls, models: list[BalanceModel]) -> "BalanceMap":
|
|
17
|
+
"""Create a BalanceMap instance from a list of BalanceModel objects.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
models (List[BalanceModel]): A list of BalanceModel objects.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
BalanceMap: A new BalanceMap instance populated with the given models.
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
balance_map = cls()
|
|
27
|
+
|
|
28
|
+
for model in models:
|
|
29
|
+
balance = Balance.from_model(model)
|
|
30
|
+
balance_map.add(balance)
|
|
31
|
+
|
|
32
|
+
return balance_map
|
|
33
|
+
|
|
34
|
+
def add(self, balance: Balance) -> None:
|
|
35
|
+
"""Add a Balance object to the BalanceMap.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
balance (Balance): The Balance object to add.
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
ValueError: If the provided balance is not a Balance instance.
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
if not isinstance(balance, Balance):
|
|
45
|
+
raise ValueError("balance must be a Balance instance")
|
|
46
|
+
|
|
47
|
+
self[balance.asset_id] = balance.amount
|
|
48
|
+
|
|
49
|
+
def __str__(self) -> str:
|
|
50
|
+
"""Return a JSON string representation of the BalanceMap.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
str: A JSON string with asset IDs as keys and formatted balance amounts as values.
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
result: dict[str, str] = {}
|
|
57
|
+
|
|
58
|
+
for asset_id, amount in self.items():
|
|
59
|
+
amount_str = format(amount, "f")
|
|
60
|
+
|
|
61
|
+
if amount == amount.to_integral():
|
|
62
|
+
amount_str = str(int(amount))
|
|
63
|
+
|
|
64
|
+
result[asset_id] = amount_str
|
|
65
|
+
|
|
66
|
+
return json.dumps(result, separators=(",", ":"))
|
|
67
|
+
|
|
68
|
+
def __repr__(self) -> str:
|
|
69
|
+
"""Return a string representation of the BalanceMap.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
str: The string representation of the BalanceMap.
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
return str(self)
|