pccontext 0.1.0__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.
- pccontext-0.1.0/PKG-INFO +110 -0
- pccontext-0.1.0/README.md +80 -0
- pccontext-0.1.0/pccontext/__init__.py +8 -0
- pccontext-0.1.0/pccontext/backend/__init__.py +9 -0
- pccontext-0.1.0/pccontext/backend/blockfrost.py +296 -0
- pccontext-0.1.0/pccontext/backend/cardano_cli.py +471 -0
- pccontext-0.1.0/pccontext/backend/koios.py +297 -0
- pccontext-0.1.0/pccontext/backend/kupo.py +267 -0
- pccontext-0.1.0/pccontext/backend/offline_transfer_file.py +216 -0
- pccontext-0.1.0/pccontext/backend/ogmios.py +518 -0
- pccontext-0.1.0/pccontext/backend/yaci_devkit.py +307 -0
- pccontext-0.1.0/pccontext/enums/__init__.py +5 -0
- pccontext-0.1.0/pccontext/enums/address_type_enum.py +12 -0
- pccontext-0.1.0/pccontext/enums/era_enum.py +17 -0
- pccontext-0.1.0/pccontext/enums/history_type_enum.py +108 -0
- pccontext-0.1.0/pccontext/enums/network_enum.py +20 -0
- pccontext-0.1.0/pccontext/enums/transaction_type_enum.py +20 -0
- pccontext-0.1.0/pccontext/exceptions.py +113 -0
- pccontext-0.1.0/pccontext/logging.py +18 -0
- pccontext-0.1.0/pccontext/models/__init__.py +8 -0
- pccontext-0.1.0/pccontext/models/address_info_model.py +227 -0
- pccontext-0.1.0/pccontext/models/base_model.py +186 -0
- pccontext-0.1.0/pccontext/models/genesis_parameters_model.py +97 -0
- pccontext-0.1.0/pccontext/models/offline_transfer_model.py +292 -0
- pccontext-0.1.0/pccontext/models/protocol_parameters_model.py +1105 -0
- pccontext-0.1.0/pccontext/models/stake_address_info_model.py +49 -0
- pccontext-0.1.0/pccontext/models/token_metadata_model.py +32 -0
- pccontext-0.1.0/pccontext/utils/__init__.py +10 -0
- pccontext-0.1.0/pccontext/utils/file_utils.py +158 -0
- pccontext-0.1.0/pccontext/utils/formatters.py +21 -0
- pccontext-0.1.0/pccontext/utils/validators.py +22 -0
- pccontext-0.1.0/pyproject.toml +102 -0
pccontext-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pccontext
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Chain Contexts for PyCardano library
|
|
5
|
+
Home-page: https://github.com/Python-Cardano/pycardano
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: python,cardano,blockchain,crypto
|
|
8
|
+
Author: Hareem Adderley
|
|
9
|
+
Author-email: haddderley@kingpinapps.com
|
|
10
|
+
Requires-Python: >=3.8.1,<4.0.0
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Natural Language :: English
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Requires-Dist: cachetools (>=5.5.0,<6.0.0)
|
|
21
|
+
Requires-Dist: koios-python (>=2.0.0,<3.0.0)
|
|
22
|
+
Requires-Dist: ogmios (>=1.2.1,<2.0.0)
|
|
23
|
+
Requires-Dist: pycardano (>=0.12.0,<0.13.0)
|
|
24
|
+
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
25
|
+
Requires-Dist: yaci-client (>=1.0,<2.0)
|
|
26
|
+
Project-URL: Documentation, https://pycardano.readthedocs.io/en/latest/
|
|
27
|
+
Project-URL: Repository, https://github.com/KINGH242/pccontext.git
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
## PyCardano Chain Contexts
|
|
31
|
+
|
|
32
|
+
This library contains the various Chain Contexts to use with the PyCardano library.
|
|
33
|
+
|
|
34
|
+
### Basic Usage
|
|
35
|
+
|
|
36
|
+
#### Blockfrost
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from pccontext import BlockFrostChainContext
|
|
40
|
+
from blockfrost import ApiUrls
|
|
41
|
+
|
|
42
|
+
chain_context = BlockFrostChainContext(
|
|
43
|
+
project_id="your_project_id",
|
|
44
|
+
base_url=ApiUrls.mainnet.value
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### Cardano-CLI
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from pccontext import CardanoCliChainContext, CardanoCliNetwork
|
|
53
|
+
from pathlib import Path
|
|
54
|
+
|
|
55
|
+
chain_context = CardanoCliChainContext(
|
|
56
|
+
binary=Path("cardano-cli"),
|
|
57
|
+
socket=Path("node.socket"),
|
|
58
|
+
config_file=Path("config.json"),
|
|
59
|
+
network=CardanoCliNetwork.MAINNET,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Koios
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from pccontext import KoiosChainContext
|
|
68
|
+
|
|
69
|
+
chain_context = KoiosChainContext(api_key="api_key")
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Ogmios
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pccontext import OgmiosChainContext
|
|
77
|
+
|
|
78
|
+
chain_context = OgmiosChainContext(host="localhost", port=1337)
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### Kupo
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from pccontext import OgmiosChainContext, KupoChainContextExtension
|
|
86
|
+
|
|
87
|
+
ogmios_chain_context = OgmiosChainContext(host="localhost", port=1337)
|
|
88
|
+
chain_context = KupoChainContextExtension(wrapped_backend=ogmios_chain_context)
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Offline Transfer File
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from pathlib import Path
|
|
96
|
+
from pccontext import OfflineTransferFileContext
|
|
97
|
+
|
|
98
|
+
chain_context = OfflineTransferFileContext(offline_transfer_file=Path("offline-transfer.json"))
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Yaci Devkit
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from pccontext import YaciDevkitChainContext
|
|
106
|
+
|
|
107
|
+
chain_context = YaciDevkitChainContext(api_url="http://localhost:8080")
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
## PyCardano Chain Contexts
|
|
2
|
+
|
|
3
|
+
This library contains the various Chain Contexts to use with the PyCardano library.
|
|
4
|
+
|
|
5
|
+
### Basic Usage
|
|
6
|
+
|
|
7
|
+
#### Blockfrost
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from pccontext import BlockFrostChainContext
|
|
11
|
+
from blockfrost import ApiUrls
|
|
12
|
+
|
|
13
|
+
chain_context = BlockFrostChainContext(
|
|
14
|
+
project_id="your_project_id",
|
|
15
|
+
base_url=ApiUrls.mainnet.value
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
#### Cardano-CLI
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from pccontext import CardanoCliChainContext, CardanoCliNetwork
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
chain_context = CardanoCliChainContext(
|
|
27
|
+
binary=Path("cardano-cli"),
|
|
28
|
+
socket=Path("node.socket"),
|
|
29
|
+
config_file=Path("config.json"),
|
|
30
|
+
network=CardanoCliNetwork.MAINNET,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### Koios
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from pccontext import KoiosChainContext
|
|
39
|
+
|
|
40
|
+
chain_context = KoiosChainContext(api_key="api_key")
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Ogmios
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from pccontext import OgmiosChainContext
|
|
48
|
+
|
|
49
|
+
chain_context = OgmiosChainContext(host="localhost", port=1337)
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Kupo
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from pccontext import OgmiosChainContext, KupoChainContextExtension
|
|
57
|
+
|
|
58
|
+
ogmios_chain_context = OgmiosChainContext(host="localhost", port=1337)
|
|
59
|
+
chain_context = KupoChainContextExtension(wrapped_backend=ogmios_chain_context)
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Offline Transfer File
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from pathlib import Path
|
|
67
|
+
from pccontext import OfflineTransferFileContext
|
|
68
|
+
|
|
69
|
+
chain_context = OfflineTransferFileContext(offline_transfer_file=Path("offline-transfer.json"))
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Yaci Devkit
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pccontext import YaciDevkitChainContext
|
|
77
|
+
|
|
78
|
+
chain_context = YaciDevkitChainContext(api_url="http://localhost:8080")
|
|
79
|
+
|
|
80
|
+
```
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import tempfile
|
|
3
|
+
import time
|
|
4
|
+
import warnings
|
|
5
|
+
from typing import Dict, List, Optional, Union
|
|
6
|
+
|
|
7
|
+
import cbor2
|
|
8
|
+
from blockfrost import ApiError, ApiUrls, BlockFrostApi
|
|
9
|
+
from blockfrost.utils import Namespace
|
|
10
|
+
from pycardano.address import Address
|
|
11
|
+
from pycardano.backend.base import ChainContext
|
|
12
|
+
from pycardano.backend.base import ProtocolParameters as PyCardanoProtocolParameters
|
|
13
|
+
from pycardano.exception import TransactionFailedException
|
|
14
|
+
from pycardano.hash import SCRIPT_HASH_SIZE, DatumHash, ScriptHash
|
|
15
|
+
from pycardano.nativescript import NativeScript
|
|
16
|
+
from pycardano.network import Network
|
|
17
|
+
from pycardano.plutus import (
|
|
18
|
+
ExecutionUnits,
|
|
19
|
+
PlutusV1Script,
|
|
20
|
+
PlutusV2Script,
|
|
21
|
+
PlutusV3Script,
|
|
22
|
+
script_hash,
|
|
23
|
+
)
|
|
24
|
+
from pycardano.serialization import RawCBOR
|
|
25
|
+
from pycardano.transaction import (
|
|
26
|
+
Asset,
|
|
27
|
+
AssetName,
|
|
28
|
+
MultiAsset,
|
|
29
|
+
TransactionInput,
|
|
30
|
+
TransactionOutput,
|
|
31
|
+
UTxO,
|
|
32
|
+
Value,
|
|
33
|
+
)
|
|
34
|
+
from pycardano.types import JsonDict
|
|
35
|
+
|
|
36
|
+
from pccontext.models import GenesisParameters, ProtocolParameters, StakeAddressInfo
|
|
37
|
+
|
|
38
|
+
__all__ = ["BlockFrostChainContext"]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _try_fix_script(
|
|
42
|
+
scripth: str, script: Union[PlutusV1Script, PlutusV2Script, PlutusV3Script]
|
|
43
|
+
) -> Union[PlutusV1Script, PlutusV2Script, PlutusV3Script]:
|
|
44
|
+
if str(script_hash(script)) == scripth:
|
|
45
|
+
return script
|
|
46
|
+
new_script = script.__class__(cbor2.loads(script))
|
|
47
|
+
if str(script_hash(new_script)) == scripth:
|
|
48
|
+
return new_script
|
|
49
|
+
else:
|
|
50
|
+
raise ValueError("Cannot recover script from hash.")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class BlockFrostChainContext(ChainContext):
|
|
54
|
+
"""A `BlockFrost <https://blockfrost.io/>`_ API wrapper for the client code to interact with.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
project_id (str): A BlockFrost project ID obtained from https://blockfrost.io.
|
|
58
|
+
network (Network): Network to use.
|
|
59
|
+
base_url (str): Base URL for the BlockFrost API. Defaults to the preprod url.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
api: BlockFrostApi
|
|
63
|
+
_epoch_info: Namespace
|
|
64
|
+
_epoch: Optional[int] = None
|
|
65
|
+
_genesis_param: Optional[GenesisParameters] = None
|
|
66
|
+
_protocol_param: Optional[ProtocolParameters] = None
|
|
67
|
+
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
project_id: str,
|
|
71
|
+
network: Optional[Network] = None,
|
|
72
|
+
base_url: Optional[str] = None,
|
|
73
|
+
):
|
|
74
|
+
if network is not None:
|
|
75
|
+
warnings.warn(
|
|
76
|
+
"`network` argument will be deprecated in the future. Directly passing `base_url` is recommended."
|
|
77
|
+
)
|
|
78
|
+
self._network = network
|
|
79
|
+
else:
|
|
80
|
+
self._network = Network.TESTNET
|
|
81
|
+
|
|
82
|
+
self._project_id = project_id
|
|
83
|
+
self._base_url = base_url or (
|
|
84
|
+
ApiUrls.preprod.value
|
|
85
|
+
if self.network == Network.TESTNET
|
|
86
|
+
else ApiUrls.mainnet.value
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Set network value to mainnet if base_url contains "mainnet".
|
|
90
|
+
if "mainnet" in self._base_url:
|
|
91
|
+
self._network = Network.MAINNET
|
|
92
|
+
|
|
93
|
+
self.api = BlockFrostApi(project_id=self._project_id, base_url=self._base_url)
|
|
94
|
+
self._epoch_info = self.api.epoch_latest()
|
|
95
|
+
self._epoch = None
|
|
96
|
+
self._genesis_param = None
|
|
97
|
+
self._protocol_param = None
|
|
98
|
+
|
|
99
|
+
def _check_epoch_and_update(self):
|
|
100
|
+
if int(time.time()) < self._epoch_info.end_time:
|
|
101
|
+
return False
|
|
102
|
+
self._epoch_info = self.api.epoch_latest()
|
|
103
|
+
return True
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def network(self) -> Network:
|
|
107
|
+
return self._network
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def epoch(self) -> int:
|
|
111
|
+
if not self._epoch or self._check_epoch_and_update():
|
|
112
|
+
new_epoch: int = self.api.epoch_latest().epoch
|
|
113
|
+
self._epoch = new_epoch
|
|
114
|
+
return self._epoch
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def last_block_slot(self) -> int:
|
|
118
|
+
block = self.api.block_latest()
|
|
119
|
+
return block.slot
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def genesis_param(self) -> GenesisParameters:
|
|
123
|
+
if not self._genesis_param or self._check_epoch_and_update():
|
|
124
|
+
params = self.api.genesis(return_type="json")
|
|
125
|
+
self._genesis_param = GenesisParameters.from_json(params)
|
|
126
|
+
return self._genesis_param
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def protocol_param(self) -> PyCardanoProtocolParameters:
|
|
130
|
+
if not self._protocol_param or self._check_epoch_and_update():
|
|
131
|
+
params = self.api.epoch_latest_parameters(return_type="json")
|
|
132
|
+
self._protocol_param = ProtocolParameters.from_json(params)
|
|
133
|
+
return self._protocol_param.to_pycardano()
|
|
134
|
+
|
|
135
|
+
def _get_script(
|
|
136
|
+
self, script_hash: str
|
|
137
|
+
) -> Union[PlutusV1Script, PlutusV2Script, PlutusV3Script, NativeScript]:
|
|
138
|
+
script_type = self.api.script(script_hash).type
|
|
139
|
+
if script_type == "plutusV1":
|
|
140
|
+
v1script = PlutusV1Script(
|
|
141
|
+
bytes.fromhex(self.api.script_cbor(script_hash).cbor)
|
|
142
|
+
)
|
|
143
|
+
return _try_fix_script(script_hash, v1script)
|
|
144
|
+
elif script_type == "plutusV2":
|
|
145
|
+
v2script = PlutusV2Script(
|
|
146
|
+
bytes.fromhex(self.api.script_cbor(script_hash).cbor)
|
|
147
|
+
)
|
|
148
|
+
return _try_fix_script(script_hash, v2script)
|
|
149
|
+
elif script_type == "plutusV3":
|
|
150
|
+
v3script = PlutusV3Script(
|
|
151
|
+
bytes.fromhex(self.api.script_cbor(script_hash).cbor)
|
|
152
|
+
)
|
|
153
|
+
return _try_fix_script(script_hash, v3script)
|
|
154
|
+
else:
|
|
155
|
+
script_json: JsonDict = self.api.script_json(
|
|
156
|
+
script_hash, return_type="json"
|
|
157
|
+
)["json"]
|
|
158
|
+
return NativeScript.from_dict(script_json)
|
|
159
|
+
|
|
160
|
+
def _utxos(self, address: str) -> List[UTxO]:
|
|
161
|
+
try:
|
|
162
|
+
results = self.api.address_utxos(address, gather_pages=True)
|
|
163
|
+
except ApiError as e:
|
|
164
|
+
if e.status_code == 404:
|
|
165
|
+
return []
|
|
166
|
+
else:
|
|
167
|
+
raise e
|
|
168
|
+
|
|
169
|
+
utxos = []
|
|
170
|
+
|
|
171
|
+
for result in results:
|
|
172
|
+
tx_in = TransactionInput.from_primitive(
|
|
173
|
+
[result.tx_hash, result.output_index]
|
|
174
|
+
)
|
|
175
|
+
amount = result.amount
|
|
176
|
+
lovelace_amount = 0
|
|
177
|
+
multi_assets = MultiAsset()
|
|
178
|
+
for item in amount:
|
|
179
|
+
if item.unit == "lovelace":
|
|
180
|
+
lovelace_amount = int(item.quantity)
|
|
181
|
+
else:
|
|
182
|
+
# The utxo contains Multi-asset
|
|
183
|
+
data = bytes.fromhex(item.unit)
|
|
184
|
+
policy_id = ScriptHash(data[:SCRIPT_HASH_SIZE])
|
|
185
|
+
asset_name = AssetName(data[SCRIPT_HASH_SIZE:])
|
|
186
|
+
|
|
187
|
+
if policy_id not in multi_assets:
|
|
188
|
+
multi_assets[policy_id] = Asset()
|
|
189
|
+
multi_assets[policy_id][asset_name] = int(item.quantity)
|
|
190
|
+
|
|
191
|
+
amount = Value(lovelace_amount, multi_assets)
|
|
192
|
+
|
|
193
|
+
datum_hash = (
|
|
194
|
+
DatumHash.from_primitive(result.data_hash)
|
|
195
|
+
if result.data_hash and result.inline_datum is None
|
|
196
|
+
else None
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
datum = None
|
|
200
|
+
|
|
201
|
+
if hasattr(result, "inline_datum") and result.inline_datum is not None:
|
|
202
|
+
datum = RawCBOR(bytes.fromhex(result.inline_datum))
|
|
203
|
+
|
|
204
|
+
script = None
|
|
205
|
+
|
|
206
|
+
if (
|
|
207
|
+
hasattr(result, "reference_script_hash")
|
|
208
|
+
and result.reference_script_hash
|
|
209
|
+
):
|
|
210
|
+
script = self._get_script(result.reference_script_hash)
|
|
211
|
+
|
|
212
|
+
tx_out = TransactionOutput(
|
|
213
|
+
Address.from_primitive(address),
|
|
214
|
+
amount=amount,
|
|
215
|
+
datum_hash=datum_hash,
|
|
216
|
+
datum=datum,
|
|
217
|
+
script=script,
|
|
218
|
+
)
|
|
219
|
+
utxos.append(UTxO(tx_in, tx_out))
|
|
220
|
+
|
|
221
|
+
return utxos
|
|
222
|
+
|
|
223
|
+
def submit_tx_cbor(self, cbor: Union[bytes, str]) -> str:
|
|
224
|
+
"""Submit a transaction.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
cbor (Union[bytes, str]): The serialized transaction to be submitted.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
str: The transaction hash.
|
|
231
|
+
|
|
232
|
+
Raises:
|
|
233
|
+
:class:`TransactionFailedException`: When fails to submit the transaction.
|
|
234
|
+
"""
|
|
235
|
+
if isinstance(cbor, str):
|
|
236
|
+
cbor = bytes.fromhex(cbor)
|
|
237
|
+
with tempfile.NamedTemporaryFile(delete=False) as f:
|
|
238
|
+
f.write(cbor)
|
|
239
|
+
try:
|
|
240
|
+
response = self.api.transaction_submit(f.name)
|
|
241
|
+
except ApiError as e:
|
|
242
|
+
os.remove(f.name)
|
|
243
|
+
raise TransactionFailedException(
|
|
244
|
+
f"Failed to submit transaction. Error code: {e.status_code}. Error message: {e.message}"
|
|
245
|
+
) from e
|
|
246
|
+
os.remove(f.name)
|
|
247
|
+
return response
|
|
248
|
+
|
|
249
|
+
def evaluate_tx_cbor(self, cbor: Union[bytes, str]) -> Dict[str, ExecutionUnits]:
|
|
250
|
+
"""Evaluate execution units of a transaction.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
cbor (Union[bytes, str]): The serialized transaction to be evaluated.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
Dict[str, ExecutionUnits]: A list of execution units calculated for each of the transaction's redeemers
|
|
257
|
+
|
|
258
|
+
Raises:
|
|
259
|
+
:class:`TransactionFailedException`: When fails to evaluate the transaction.
|
|
260
|
+
"""
|
|
261
|
+
if isinstance(cbor, bytes):
|
|
262
|
+
cbor = cbor.hex()
|
|
263
|
+
with tempfile.NamedTemporaryFile(delete=False, mode="w") as f:
|
|
264
|
+
f.write(cbor)
|
|
265
|
+
result = self.api.transaction_evaluate(f.name).result
|
|
266
|
+
os.remove(f.name)
|
|
267
|
+
return_val = {}
|
|
268
|
+
if not hasattr(result, "EvaluationResult"):
|
|
269
|
+
raise TransactionFailedException(result)
|
|
270
|
+
else:
|
|
271
|
+
for k in vars(result.EvaluationResult):
|
|
272
|
+
return_val[k] = ExecutionUnits(
|
|
273
|
+
getattr(result.EvaluationResult, k).memory,
|
|
274
|
+
getattr(result.EvaluationResult, k).steps,
|
|
275
|
+
)
|
|
276
|
+
return return_val
|
|
277
|
+
|
|
278
|
+
def stake_address_info(self, stake_address: str) -> List[StakeAddressInfo]:
|
|
279
|
+
"""Get the stake address information.
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
stake_address (str): The stake address.
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
List[StakeAddressInfo]: The stake address information.
|
|
286
|
+
"""
|
|
287
|
+
rewards_state = self.api.accounts(stake_address)
|
|
288
|
+
|
|
289
|
+
return [
|
|
290
|
+
StakeAddressInfo(
|
|
291
|
+
address=rewards_state.get("stake_address", None),
|
|
292
|
+
stake_delegation=rewards_state.get("pool_id", None),
|
|
293
|
+
reward_account_balance=rewards_state.get("withdrawable_amount", None),
|
|
294
|
+
delegate_representative=rewards_state.get("drep_id", None),
|
|
295
|
+
)
|
|
296
|
+
]
|